This document serves the purpose of listing some GIT commands that I find hard to remember, hard to find information about, hard to use or any combination thereof.
How to use this document
The best way to use this is to CTR+F you way through it.
Table Of Contents
- GIT Concepts
- Discard changes for a given file
- GIT ADD and REMOVE
- GIT RESET Explained
- GIT IGNORE file
- Save password
- GIT GLOBAL file
- Make a local branch track a specific remote branch
- Rename commit message | Re-write last commit
- Make "branch" point to commit | Move branch
- Update domain password
- Stash only some files
- Search Stuff
- Show staged or unstaged differences
- Squash Commits
How does Git know what branch you’re currently on? It keeps a special pointer called HEAD.
Means "what commit is my repository currently at?" Most of the time HEAD points to the latest commit in your branch, but that doesn't have to be the case.
In the event that the commit HEAD refers to, is not the tip of any branch this is called a "detached head".
Where you place files you want committed to the git repository.
Put files with "git add" and remove with "git reset".
Many names to the same thing:
- Current directory cache
- Staging area
- Staged files
All these names refer to the Index.
Discard changes for a given file
git checkout -- filename
GIT ADD and REMOVE
Undo git add (yes its reset)
git reset -- <file>
Or, "git add" for "file deletions" is not "git add" but "git rm":
git rm --cached -- <file> git rm -r --cached -- <directory>
GIT RESET Explained
With a file-path:
unstages the file (as explained above, undo's git add)
Without a file-path provided, 3 modes:
--soft just move the branch --mixed (default) move the branch and the index --hard move the branch and the index and the working copy
This will destroy the last commit and set all changes back into the working-copy and the index (
git add is "preserved").
So that you can resume work (edit, commit, add, undo add, break the comit in several comits, etc).
git reset --soft HEAD
This will be the same as above, but the index is not preserved so all changes will show as "unstaged". This is also the default behaviour, so not seeting the reset mode is the same as setting mixed.
git reset HEAD git reset --mixed HEAD
This will completly delete the previous commit, changes are lost forever. Done, Hard and simple.
git reset --hard HEAD
GIT IGNORE file
Show files being ignored
git status --ignored
Search for the
.gitignore line that matches a give file.
git check-ignore --verbose <path>
If the specified line by this command points to an empty line on
.gitignore, it means that the path provided is NOT being ignored.
Like a boss:
git log --pretty=format:"%h - %an, %ar : %s" --graph --abbrev-commit -45 git log --graph --pretty=format:'%C(yellow)%h%Creset - %C(bold blue)%an%Creset, %Cgreen%ar%Creset : %s' --abbrev-commit git log -p -2 -p show the difference for each commit -N show only N commits
Abbreviated statistics for each commit:
$ git log --stat -1 commit ca82a6dff817ec66f44342007202690a93763949 Author: Scott Chacon <email@example.com> Date: Mon Mar 17 21:52:11 2008 -0700 changed the version number Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
History for a given file or directory
git log -- C git log -- A B # where A B or C are the PATHs to a file or directory
Add an Alias
git config --global alias.st "status"
List configured alias
git config --get-regexp alias
Save alias on dropbox ('>' is replace '>>' is append to file, I always confuse teh two)
git config --get-regexp alias > ~/Dropbox/Software/notepad\ files/git_alias.txt
Execute this cmd for git in windows. It ask the password next time and then its saved. Magic.
git config --global credential.helper wincred
GIT GLOBAL file
Export git configuration:
git config --list
Edit manually the global config file (defaults to vim)
git config --global --edit
Basic Git global configuration
git config --global user.name "Firstname Lastname" git config --global user.email "your_email" git config --global color.ui true
Make a local branch track a specific remote branch
git push -u origin master
Merge OTHER into current branch
--no-fast-forward so that the "history line is kept separate"
git merge --no-ff <other>
Merge dry run OTHER into current branch(if not ok, we can abort and nothing happened)
git merge --no-commit --no-ff <other>
Cancel the ongoing merge (merge pauses on conflicts)
git merge --abort
Preview a merge: Will list all the commits that will be brought to the current branch
git log ..otherbranch
Merge without checkout
Yes, fecth does merge (ff only). With this line we can update/pull changes into a branch without checking it out first. Usefull while working on something not ready to commit.
# From any branch do: git fetch origin develop:develop
Resolving Merge conflicts "automatically"
When you just want what is upstream (before you're in a conflict state):
git pull -X theirs
rebase the flag is
The meaning of
theirs changes within a rebase.
git rebase -s theirs master # --strategy or -s | theirs/ours # 'theirs' is taking the current branch's changes, not master changes git merge -s theirs master # --strategy or -s | theirs/ours # 'theirs' is taking the master's changes, not the current_branch changes
Show the last person to make changes for a given file, on lines A to B (stops on the first commit)
git blame -L A,B -- path/to/file
Same as above, but keeps scrolling back on history
git log -L A,B:<file>
Search All commits where file X was changed (also on the 'Search' Section)
git log --follow -- path/to/X
Rename commit message | Re-write last commit
This will open the editor pre-populated with your previous commit message, so you can change it. (-c is: replace with/pre-populate)
Be carefull if all you want is to rename the commit message. Existing changes will be added to the existing commit.
Always have a clean state before renaming commit messages.
git commit --amend -c HEAD
WARNNING: dont rename commits already pushed or all others who have them checked-out will need to execute:
git pull --force
For older commits than the last one see this:
Make "branch" point to commit | Move branch
git branch -f <branch> <desired-commit> (cannot be on <branch>) git reset --hard <desired-commit> (must be on <branch>)
WARNING: may loose commits if there are commits without a branch (due to blobs clean up).
Update domain password
After updating the windows domain password git DOES NOT ask for the new password. To solve this:
git config --global credential.helper erase git config --global credential.helper store git pull
Now it asked for the new password.
Stash only some files
git stash -p
This way you can select which hunks should be added to stash, whole files can be selected as well. You'll be prompted with a few actions for each hunk:
y - stash this hunk n - do not stash this hunk q - quit; do not stash this hunk or any of the remaining ones **a - stash this hunk and all later hunks in the file** **d - do not stash this hunk or any of the later hunks in the file** g - select a hunk to go to / - search for a hunk matching the given regex j - leave this hunk undecided, see next undecided hunk J - leave this hunk undecided, see next hunk k - leave this hunk undecided, see previous undecided hunk K - leave this hunk undecided, see previous hunk s - split the current hunk into smaller hunks e - manually edit the current hunk **? - print help**
Alternatively we can first move the changes (or hunks) we do not want to stash to the index (git add) and then do
git stash --keep-index
This will only stash what is on the working copy but not on the index.
Search for a string in code history
whatever with the string to seach for.
--source --all uses all branches.
This will search all the code base for changes where the string
whatever was either added or removed.
git log -Swhatever --source --all
Search for a string in commit messages
git log --all --grep='whatever'
It can be useful to define the following git alias for searching:
git config --global alias.find "log --graph --pretty=format:'%Cred%h %Cgreen%s' --grep"
Search current modifications for all files of a given extension
.cs files and NOT
.css on the current working copy that have un-commited changes:
git status | grep .cs | grep -v .css
Search all commits where file X was changed
Search all commits where file X was changed (This is also on the 'Blame' Section):
git log --follow -- path/to/X
Show staged or unstaged differences
Show unstaged differences:
git diff -- *path to file*
Show staged differences:
git diff --cached -- *path to file*
The difference between staged and unstaged is the following:
- modified a file: change is unstaged
- modified a file: executed:
git add -- filechange is staged
git diff <sha1> <sha2> -- *path to file* # diff <sha1> to <sha2>
If you omit one of the commit-hash the diff is from 'working-copy-changes' to the other commit. Example:
git diff <sha1> -- *path to file* # diff current-changes to sha1
More info at:
# use bc3 even for bc4 git config --global diff.tool bc3
Alternatively, paste this on git config:
[diff] tool = bc3 [difftool "sourcetree"] cmd = /usr/local/bin/bcomp -ro $LOCAL $REMOTE path = [mergetool "sourcetree"] cmd = /usr/local/bin/bcomp $LOCAL $REMOTE $BASE $MERGED trustExitCode = true
git difftool --dir-diff
Sometimes, source tree does not pick/see beyond compare as installed. We can manually set this on SourceTree configuration and it will work:
- From BC4 menu, run "install cmd line tools"
- sourcetree settings / diff / mode custom
-ro $LOCAL $REMOTE
$LOCAL $REMOTE $BASE $MERGED
Never squash or rebase pushed changes
Always have a clean state before squash or rebase
Checkout the most recent commit of the branch we are going to squash
git rebase -i HEAD~3where 3 is the number of commits you want squash
Git will open vi with something like:
pick f392171 oldest commit pick ba9dd9a the one before pick df71a27 most recent commit
edit to this:
pick f392171 oldest commit s ba9dd9a the one before s df71a27 most recent commit
save the file and quit:
Git will squash all the commits with
f392171creating a new commit (so a new hash)
- find a working commit hash (can be a tag or branch name) --
- (optional) find a non-working commit hash (can be a tag or branch name) --
git bisect start
git bisect bad <h2>-- no providing h2 will assume HEAD
git bisect good <h1>-- after this git will checkout a commit for you to test
- Re-build. Test the issue. Does it work?
git bisect good
git bisect bad
- repeat until git tells you the commit that introduced the problem
git bisect resetto put everything back on the original state