git-fu
The art of version control
Jeff Schomay
- programmer
- game designer
- screenwriter
- git fan
Appreciating your tools
Software development is organic.
We need a tool for non-linear development.
"Git is the magic sauce that bridges the linear process of writing code in the text editor, with the organic process of software development."
1. History
A good git history tells the story of how ideas turned into software.
2. Parallel development
Explore many solutions to the same problem. Work on multiple things at once.
3. Collaboration
The closest thing to a "hive mind"
Making git in the command line better
- Put git info in your command line prompt:
- https://github.com/git/git/blob/master/contrib/completion/git-prompt.sh
- Use git auto completion:
https://github.com/git/git/blob/master/contrib/completion/git-completion.bash -
git config --global color.ui true
Git-fu discipline #1: Git forensics
git forensics: comparisons
Graphing -------- Option 1: use external software like SourceTree or Tower Option 2: `gitk` Option 3 (the cool way): `git log --graph --all --oneline --decorate` (you might want an alias) Bonus: try adding `--simplify-by-decoration` to the above Tip: add `-- path/to/file.ext` to any git log command to only see commits that changed that file (even if the file isn't in your working tree!)
Understanding Branches
Q: Which colour line represents the "dev" branch?
A: Trick question! Branches are pointers to a single commit only.
Git graphs aren't trees, they are more like linked-lists.
Branches are merely references to the "loose ends."
The correct question is: "Which commits are down-stream from the commit referenced by the dev branch?"
(A: ALL of them, except fix_hook and forgery)
git forensics: comparisons
Comparing commits (.. vs ...) ----------------------------- `git log master..dev` = "What commits are unique to dev?" --or-- "What commits are reachable from dev, but not from master?" `git log featureA...featureB` = "What commits are reachable from either featureA or featureB, but not both?" Bonus: * Use `--left-right with` ... * Use `-p` or `--stat` to see changes by commit * Use `git merge-base A B` to find the common commit between branches * Use `..remote-name/branch-name` to compare to remotes * Leave out either side of the ... to mean "use HEAD" * Use `branchX..abc123` to find out if a branch has a specific commit in it (an empty result means it does, otherwise it doesn't) Gotcha: git diff is different (see next slide)
git forensics: comparisons
Comparing code -------------- `git diff A B` (or `git diff A..B`) to diff revisions `git diff A...B` to see only diffs added by B `git diff` to see diffs between working directory and index `git diff --cached` to see diffs between staged files and index Tip: use `git diff` and `git diff --cached` before a git commit Tip: git pipes its output through less, so you can search with `/pattern<enter>` and use `n/N` for next/previous.
git forensics: searching
grep in git! ------------ `git log --grep pattern` to search commit messages `git grep -n pattern` to search index Bonus: `git grep --help` for advanced searching `git log -Spattern` to search diffs (see when you made changes to 'pattern')
git forensics: searching
Tracking down where things went wrong ------------------------------------- git bisect to the rescue! `git bisect --help`
git forensics: searching
git knows what you've done -------------------------- Have you ever lost your commits after a rebase, reset, stash, etc? The good news: No, you have not. `git reflog` There they are :)
Git-fu discipline #2: Manipulating state
manipulating state: changing code
You can change the state of your code in 2 ways:
1. Move yourself to the code
2. Bring the code to you
Move yourself to the code: * `git checkout branchName`
Tip: relative refs are useful.
* `git reset HEAD~3` to go back 3 commits (brings your working directory with you unless you add `--hard`)
Bring the code to you:
* `git merge branchName` (add `--no-commit` to make edits first)
Tip: `git add -i` or `git add -i` for partial committing.
Tip: `git mergetool` makes resolving merge conflicts much more fun. Tip: Remember you can grab code from different remotes too.
* `git checkout abc123 -- path/to/file.ext` (add `-p` for super fine control extra awesomeness)
manipulating state: changing history
Why change history? To clarify your story of development. * Clarify commits * Clarify messy branches Warning! Do not change history of public commits. * `git commit src/fileIForgotToAdd.js --amend` (plus you can edit the commit message) * `git reset HEAD~`, then `git add -i` if you commit too much * `git reset ref` to change where your branch references (like resetting your messed up local branch to the version on the remote) And of course, our good friend, Mr. Rebase! (He's not so scary)
manipulating state: changing code
(maybe a little scary)
manipulating state: changing history
Rebasing: moving branches around -------------------------------- Who cares?: I do!! Why?: They keep the history nice and flat: * Avoid unintentional and unnecessary merge commits * Correct haphazard branching-off points Simply defined: `git rebase master feature` = "Remake all of the commits in `git log master..feature`, in order, one by one, off of the tip of master." (Remember the warning: no rebasing public commits)
manipulating state: changing code
Neat Rebase tricks ------------------ * `git rebase --onto X A B` to rebase A..B onto X instead of the tip of A. This is useful if you branched a feature off of a feature and want to move it to the main trunk (`git rebase --onto master featureA featureB`). * Add `-i` for interactive rebasing (you get a chance to massage each commit before it gets remade). Great for commits like "wip", "oops, forgot to update README" and "spelling fix." But also: `git rebase HEAD~5 -i` to clean up the last 5 commits. * `git pull --rebase` instead of git pull if your local branch has diverged from its upstream tracking branch. Instead of creating a "merge origin/dev" commit, it will pull in the remote branch and rebase your local commits onto the tip of it.
Git resources
-
http://pcottle.github.io/learnGitBranching/
Indispensable interactive game for visually learning to master branches, an absolute must! -
http://justinhileman.info/article/git-pretty/
Superb flow chart detailing what to do when you have a git mess on your hands, definitely check it out! -
http://justinhileman.info/article/changing-history/
Good "best practices" when committing (scroll down about half way)
Review: git is awesome!
- Why use git? It helps us develop organically
- Understanding branches is the path to mastering git
- 2 disciplines of git-fu: git forensics & changing code state
- Git is powerful, learn it, use it (`git command --help`)
Thank you
Git-fu
By Jeff Schomay
Git-fu
- 4,037