Collection of some useful scenarios in GIT and commands to deal with them.
Last Updated: March 30, 2018Git is a powerful source version system, and I firmly believe that using the command line to control it is the best way to master this tool. Although there are various UI tools, there is a tool specific learning curve, which makes it difficult for people used to two different GIT tools to communicate. Moreover, learning the command line for GIT to me is the best way to learning it. Command line also gives a unified way of web searching, and finding the appropriate command for your problem at hand.
I started putting together a cheatsheet for GIT, when I first started learning it. Over the period of time, I have shared it with multiple team members, and also used it to conduct sessions for my teams. I had kept it all this while on my private notes. I am now sharing this on my site so that it can benefit more people.
Instead of describing what each command does, I have reversed it to help find the commands that are required for your task at hand. This in no way is a complete guide to GIT, but you will find the most common scenarios here. If you like something to be added, please let me know through the comments, or give me a pull request.
I want to … | then use … |
---|---|
create a new repository |
git init – OR – git init --bare (if the repository has to act as a server where you will not work directly) |
clone a repository (similar to checkout in SVN) |
git clone URL e.g. git clone https://github.com/ethomasjoseph/ethomasjoseph.com.git
|
create a new local branch and work on it |
git checkout -b new_branch_name – OR – git branch new_branch_name git checkout new_branch_name
|
add a new remote repository |
git remote add upstream NEW_REPO_URL - add a new repository alias ‘upstream’ with given URL |
push a new local branch into remote repo | git push -u origin fea_branch_name |
update my current branch “feat_branch” with latest changes from other developers |
git pull --rebase - pulls in changes from the current branches and keep your own modifications in line.This is a much better and cleaner option than a simple git pull which tries to merge the changes from the remote repository with your own. |
update my feature branch “feat_branch” with latest changes from branch “develop” |
git checkout develop (go to develop)git pull (sych with remote repo)git checkout feat_branch (go to fea_branch)git merge --no-ff develop (bring changes from develop to current branch)– OR – git checkout develop (go to develop)git pull (sych with remote repo)git merge --no-ff develop feat_branch (merge changes from develop into feat_branch)NOTE: The option --no-ff ensures that there is always a merge commit even if if it detects that your current HEAD is an ancestor of the commit you’re trying to merge. This is especially useful to revert any merges.– OR – Using git rebase option:git checkout develop (go to develop)git pull (sych with remote repo)git checkout feat_branch (go to fea_branch)git rebase develop (bring changes from develop to current branch - rebase rewrite history to make it neatly tucked in)WARNING This option of git rebase should be used only with team consensus. Otherwise it annoys others, when they see that their master history is rewritten. Use it along with git pull --rebase . The command git rebase -i turns you into a ninja. Do not try at home
|
update all my locally tracked branches with latest changes from remote | git pull --all |
view all the local branches (includes local only & synced remote branches) | git branch |
view all the remote branches | git branch -r |
point the feat_branch branch to point to a particular commit |
git branch -f feat_branch COMMITHASH - make the branch feat_branch to point to the COMMITHASH commit. |
rename the local branch (current branch) | git branch -m new_name |
delete a local branch |
git branch -d local_branch unstages commits |
delete a remote branch |
git push origin :remote_branch – OR – git push origin --delete remote_branch
|
push changes after a conflict which gives [rejected] “non-fastforward” error |
git add /path/to/conflictedfile commit -m "your comment" git pull origin branch_name git push
|
discard local changes | There could be only three categories of files when we make local changes: 1. Staged Tracked files (added, not modified) 2. Unstaged Tracked files (added in index, but later modified) 3. Unstaged Untracked files a.k.a Untracked files + Staged - Those that are moved to staging area/ Added to index + Tracked - modified files + Untracked - new files. Always unstaged. If staged, that means they are tracked. Here is what you can do depending on the type of local change. 1. git checkout - Removes Unstaged Tracked files ONLY [Type 2]– git checkout /path/to/filename/or/pattern - reverts the specified file(s) of local changes.2. git clean -f - Removes Unstaged Untracked files ONLY [Type 3].– flags i (interactive), f (files), d (directory) 3. git reset --hard - Removes Tracked files only (Staged and Unstaged) files ONLY[Type 1, Type 2]– git reset will move the branch backwords as if the commit had never been made at the first places.4. git stash -u - Removes all changes [Type 1, Type 2, Type 3] (comitted unpushed changes will also be removed) |
reverse changes made |
git reset HEAD~1 - go back one commit. Applies for local commits only.DANGEROUS - as there is no way to retrieve the original copy, and is a permanent UNDO. NEVER git reset on commits from remote repo. – OR – git revert HEAD - reverts the changes which were pointed to by HEAD. HEAD could be replaced by any commit. In effect, it produces another commit which reverts the changes made in the HEAD (or the other commit specified). |
reverse a branch merge (eg, pull out a feature from the main branch) (in effect is reversing the changes made as above) |
git revert -m 1 [sha_of_merge_commit] This will create a new commit (say abcd1234 ) |
reverse a reversal of the branch merge (eg, you suddenly realized that actually the feature branch can go into the main branch, which you had pulled out as described above) |
git revert abcd1234 (where abcd1234 is the commit hash of the merge reversal made earlier)Once you revert a change, merging the feature branch to main branch again will not work. You will have to revert the revert commit. |
merge conflicts when I want to accept theirs | git merge --strategy-option theirs branch_name_to_merge |
Save my current work without committing (hmm, the guest came in while having my dinner) |
git stash save "my lovely message" git stash list - list the stashes (as a stack - LIFO)git stash apply - applies the latest stash (leaves the stack intact)git stash pop - applies the latest stash and deletes it from the stack!git stash apply stash@{2} - applies the specified stashgit stash drop stash@{0} - removes the specified stashPsst… and if your stash stays stale… git stash branch testchanges which creates a new branch for you, checks out the commit you were on when you stashed your work, reapplies your work there, and then drops the stash if it applies successfully |
select few commits from elsewhere to current branch |
git cherry-pick C1 C2 C3 - plops C1 C2 and C3 commits in that order to the current branch.– OR – git rebase -i C1 - gives an interactive dialog to rebase commits of the current branch to be attached in sequence to the specified branch or commit. We can drop a commit or option of reordering and squashing commits. |
If you are new to GIT, I would recommend Peter Cottle’s “hands-on” tutorial on GIT, or GitHub’s Try Git.
There are a few other references as well, which will be very useful for overall GIT concepts as well as wading through some simple and complex use cases.