Git Survival Guide
I think the git UI is pretty awful, and encourages using Git in ways that
will screw you. Here are a few things I've picked up that have saved my bacon.
- You will inevitably need to understand Git's “internals” to make use of it
as an SCM tool. Accept this early. If you think your SCM tool should not
expose you to so much plumbing, don't
use Git.
- Git weenies will claim that this plumbing is what gives Git all of its extra power. This is true; it gives Git the power to get you out of situations you wouldn't be in without Git.
git log --graph --decorate --oneline --color --all- Run
git fetchhabitually. Stale remote-tracking branches lead to sadness. git pushandgit pullare not symmetric.git push's opposite operation isgit fetch. (git pullis equivalent togit fetchfollowed bygit merge, more or less).- Git configuration values don't always have the best defaults.
- The upstream branch of
fooisfoo@{u}. The upstream branch of your checked-out branch isHEAD@{u}or@{u}. This is documented ingit help revisions. - You probably don't want to use a merge operation (such as
git pull) to integrate upstream changes into topic branches. The resulting history can be very confusing to follow, especially if you integrate upstream changes frequently.- You can leave topic branches “real” relatively safely. You can do a test merge to see if they still work cleanly post-integration without actually integrating upstream into the branch permanently.
- You can use
git rebaseorgit pull --rebaseto transplant your branch to a new, more recent starting point that includes the changes you want to integrate. This makes the upstream changes a permanent part of your branch, just likegit mergeorgit pullwould, but generates an easier-to-follow history. Conflict resolution will happen as normal.
-
Example test merge, using
origin/masteras the upstream branch andfooas the candidate for integration:git fetch origin git checkout origin/master -b test-merge-foo git merge foo # run tests, examine files git diff origin/master..HEADTo discard the test merge, delete the branch after checking out some other branch:
git checkout foo git branch -D test-merge-fooYou can combine this with
git rerereto save time resolving conflicts in a later “real,” permanent merge. -
You can use
git checkout -pto build new, tidy commits out of a branch laden with “wip” commits:git fetch git checkout $(git merge-base origin/master foo) -b foo-cleaner-history git checkout -p foo -- paths/to/files # pick out changes from the presented patch that form a coherent commit # repeat 'git checkout -p foo --' steps for related files to build up # the new commit git commit # repeat 'git checkout -p foo --' and 'git commit' steps until no diffs remain- Gotcha:
git checkout -pwill do nothing for files that are being created. Usegit checkout, instead, and edit the file if necessary. Thanks, Git. - Gotcha: The new, clean branch must diverge from its upstream branch
(
origin/master, in the example above) at exactly the same point, or the diffs presented bygit checkout -p foowill include chunks that revert changes on the upstream branch since the “dirty” branch was created. The easiest way to find this point is withgit merge-base.
- Gotcha:
Useful Resources
That is, resoures that can help you solve problems or understand things, not resources that reiterate the man pages for you.
- Sitaram Chamarty's git concepts simplified
- Tv's Git for Computer Scientists