summaryrefslogtreecommitdiff
path: root/wiki/git/survival.md
blob: 79f10d0cf6032e95089f2bee2626970028fa0b4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# 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.

* `git log --graph --decorate --oneline --color --all`
* Run `git fetch` habitually. Stale remote-tracking branches lead to sadness.
* `git push` and `git pull` are **not symmetric**. `git push`'s
  opposite operation is `git fetch`. (`git pull` is equivalent to `git fetch`
  followed by `git merge`, more or less).
* 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 "out of date" 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 rebase` or `git pull --rebase` to 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 like `git merge` or `git pull` would, but generates
      an easier-to-follow history. Conflict resolution will happen as normal.
* Example test merge, using `origin/master` as the upstream branch and `foo`
  as 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..HEAD

    To discard the test merge, delete the branch after checking out some other
    branch:

        git checkout foo
        git branch -D test-merge-foo

* You can use `git checkout -p` to 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 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 -p` will do nothing for files that are being
      created. Use `git checkout`, instead, and edit the file if necessary.
      Thanks, Git.

## 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](http://sitaramc.github.com/gcs/)
* Tv's [Git for Computer
  Scientists](http://eagain.net/articles/git-for-computer-scientists)