summaryrefslogtreecommitdiff
path: root/wiki/git/survival.md
diff options
context:
space:
mode:
Diffstat (limited to 'wiki/git/survival.md')
-rw-r--r--wiki/git/survival.md62
1 files changed, 62 insertions, 0 deletions
diff --git a/wiki/git/survival.md b/wiki/git/survival.md
new file mode 100644
index 0000000..79f10d0
--- /dev/null
+++ b/wiki/git/survival.md
@@ -0,0 +1,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)