How Do I __________ in Git

This is a compilation of common questions about git that I’ve seen online or have encountered myself. This is a work in progress, so organization isn’t that great.

For all of these, it’s a very good idea to read the man pages before running them to ensure it will do exactly what you need done.

Undo a merge

git reset --hard ORIG_HEAD

Explanation: git reset will reset the HEAD to the specified commit, which in this case is ORIG_HEAD. This will be a reference to the commit right before the merge since git merge saves the old HEAD into ORIG_HEAD before performing the merge. Most importantly here is --hard which will reset the index and working tree so it’s as if the merge never happened; if you use --soft it’ll just change the HEAD reference.

Discard local uncommitted changes

git checkout -- FILENAME

Explanation: git checkout will change the working tree to match the index or whichever branch/commit you’ve specified. In this case, you haven’t specified anything so it’ll update FILENAME to match what’s in the index for the current branch.

Modify the last commit

git commit --amend

Explanation: This will open up $EDITOR to let you edit your last commit message. As with regular git commit it’ll take the -m flag. Most importantly, if you have used git add right before the amend, it’ll add those changes into the commit.

See the original version during a merge conflict

git config merge.conflictstyle diff3

Explanation: This will show changes in the current branch, then changes from the common ancestor, and then the branch you’re merging in. You’ll need to have this in your config before you try to merge, but I can’t think of a time when you wouldn’t want this, so I keep it in my global ~/.gitconfig.

Avoid ‘merge origin/master into master’ commits

git pull --rebase

Explanation: When your master branch and the remote’s master branch have diverted, git pull will try to merge the remote one into your local one. Unfortunately, this creates an unnecessary merge commit which can be avoided by simply replaying your commits on top of the remote’s master branch (which is what --rebase does).

Note that this is dependent on your workflow, and you probably shouldn’t use it for every pull. If you’re finding your changes often conflict with other people’s, it’s a good idea to find a workflow that keeps people from stepping on each other’s toes. See Atlassian’s Comparing Workflows tutorial for ideas.

Undo the last commit

git reset --soft HEAD~

Explanation: This will reset the HEAD to point to HEAD~ which is its first ancestor (i.e. parent), while leaving your working tree unchanged. Since reset saves the old HEAD to ORIG_HEAD, you can then use git commit -c ORIG_HEAD to reuse the old commit message along with the authorship information.

Discard local commits when pulling

git fetch --all
git reset --hard origin/branchname

Explanation: git fetch will download all the commits from the remote without trying to merge them into your local branch. Then the git reset will reset your current branch head to origin/branchname. Remember, branches and heads are really only references to specific commit objects.

Add only part of a file

git add -p FILENAME

Explanation: This will present the diff between the index and the working tree version of the file, and will ask you which sections of the diff you want to stage. You can use y to stage, n to skip it, s to split the given section, q to skip the rest of the diff, and ? to print the help. Read about the patch subcommand in the “Interactive mode” section of the man page for git-add for more details.

Delete a remote branch

git push origin --delete BRANCH     # >=1.7.0
git push origin :BRANCH             # <1.7.0

Explanation: The first version is fairly self-explanatory. The older version makes sense when you think that you can push using git push origin LOCAL:REMOTE where LOCAL is the local branch name and REMOTE is the remote branch name; then omitting LOCAL is like pushing nothing to the remote branch.

Remove untracked files from the working tree

git clean -- .      # OR
git clean -d -- .   # include directories

Clean up the commits in the current branch

git rebase -i

Explanation: git rebase reapplies commits to a different base. For example, you can use it to change the base of the current branch to be the current master instead of merging master into the current branch (thus keeping your history a bit cleaner). When passing -i or --interactive, git gives you a list of commits in the current branch (from when it diverged) which you can reorder, squash, or delete by modifying the lines in the opened file. A comment at the bottom explains which actions are available.

Apply chain of commits from a different branch

git cherry-pick <commit1>^1..<commit2>

Explanation: This will cherry-pick all the commits in the range and apply them on top of the current HEAD. Note that .. notation will not include the first commit, so we use ^1 to get the first parent of commit1.