Give yourself as many chances as you can to catch your mistakes before you push them:
- Use an editor plugin like Sublime Text's GitGutter so you can always see which parts of a file you've changed. (More precisely, it shows the diff of the file between the working directory and HEAD.)
- Not sure whether to stage your unstaged changes? Use
git diff
with no arguments. It shows the difference between your working directory and the index. - Not sure whether to commit your staged changes? Use
git diff --staged
. It shows the difference between your index and HEAD. - When you decide to commit, use
git commit --verbose
, no-m
, and take one last look at the changes in your editor. (Make sure it's got a nice Git Commit Message syntax, like the one in the Sublime Text Git package, so the list of changes is nice and colorized.) You can't edit the changes directly, but you can close the editor without saving to abort the commit. - Not sure that last commit was such a good idea? Use
git show
to review it. If you want to change it, just stage some changes and then usegit commit --verbose --amend
. (Don't do this if you've already pushed, though! Commits are immutable, so you're rewriting the branch's history.) - Want to pretend that last commit never happened?
git reset --hard HEAD~1
will move your branch head to the previous commit, orphaning the HEAD commit. (Again, this is rewriting history, so if you've already pushed, swallow your pride and rungit revert <commit-sha>
.
- Your
HEAD
is still what it was before the merge, so you cangit reset --hard HEAD
to abort.
git diff
will show you all of the conflicts, right in your console.- When a conflict isn't self-explanatory,
git log --merge --left-right -p
will show you where those conflicts came from (that is, which commits were responsible for the conflicting lines). The--left-right
flag prefixes each SHA with a<
if it came from your branch and a>
if it came from the other one. You can pass a filename to that command to narrow it down. - Want to just choose your version of a file as the conflict resolution? Use
git checkout --ours <file>
. Greedy, right? If you want to be more generous:git checkout --theirs <file>
.