Isaac.Truett.info
How to Use Git
- command-line
- know-your-tools
My opinionated guide to using git for version control.
Principles
-  Developers are stewards of history - Keep the log clean; protect its integrity
 
- What goes on master stays on master - Never force push
 
- Tags are like photographs; snapshots of a moment in time - Tag things you want to remember and remove them from HEAD – don’t leave them there “just in case” – it’ll last longer
 
- Branches are short and sweet, like a limerick - … unless you maintain multiple versions of your product, in which case some of your branches are main-line for those versions
- All other branches: git in, make your changes, and git out
 
- Rebase is your friend - No merge commits
- Fast-forward merging only
 
Open all sections
- Start in the right place
-  Howgit checkout master git pull --rebaseWhyThis will make sure that you're on the master branch, that master is up-to-date, and that any stray commits you have lying around in your local repository's master branch are placed on top of the remote version of history, as is Good and Proper in the stewardship of your code's history. git config --global pull.rebase trueThis config setting will make rebase the default behavior for pull, in case you forget to add the--rebaseflag.
- Make a branch
-  Howgit checkout -b {branch name}WhyMaking changes on a separate branch helps history stay clean by keeping all of your changes for a specific feature or bugfix together, giving you a place to amend or revert commits without leaving a trace in history, and finally submitting your changes for a review as part of a pull request process. 
- Stage your changes for commiting
-  Howgit add one/path/at/a/timeWhyA quick shortcut to recursively add all of the changes in the current directory is git all ., but, by adding files individually, you have a chance to be thoughtful and make a deliberate decision about whether each file belongs in the commit. It can be tempting to take all of the changes at once, but we often end up touching many files during the development process and making changes that are not required in the final solution. These changes may be good changes to make, but if they aren't required for the current issue you're working on, it's probably best to make a separate commit.
- Do a self-review
-  Howgit diff --cachedWhydiffwith the--cachedoption will show you all of your staged (added), but not yet committed, changes. This is a good opportunity to review what you've done, and make sure that each line that changed is correct and appropriate to be committed at this time.
- Commit your changes
-  Howgit commitWhyBe sure to add a thoughtful comment about the changes you are making. If you have a ticket tracking system, it can be very helpful to include a reference to the ticket you are working on at the start of the comment, like this: [issue-123] Adds a third solo to correct for insufficient cowbell
- Add the one little change you missed
-  Howgit commit --amendWhySometimes, immediately after commiting changes, despite all the reviews, I do a git statusand see a file I missed. Or I flip back to my editor and realize "Oh, if I change this, then I'm going to have to change that too." In these cases, there's no harm in modifying the commit I just made. I'lladdthe additonal changes and then use--amendto alter the previous commit, combining my staged but uncommitted changes with the changes in the previous commit. So if my last commit added two files and I have one more file staged, then the commit with two files is replaced by a commit with all three. In the commit history it now looks like I committed all three at once. My intent is clear, and the history reflects that intent. No need for a commit that just says "oops, I missed one."
- Catch up on changes in master
-  HowMake sure you have all of your changes committed, then: git checkout master git pull --rebase git checkout {branch} git rebase masterResolve merge conflicts during the rebase, if any, and then you're all caught up with master. WhyThis process first takes you back to the master branch, pulls and updates your local master branch with any changes from origin, then switches back to your branch and rebases, applying your changes on top of the new master history. 
- See everything you've changed compared with master
-  Howgit diff master..{branch}WhyThis is especially handy after you've rebased on top of a new master branch HEAD to do a sanity check before submitting changes for a peer review. My branch may contain a number of separate commits, and this lets me see the changes holisticly 
- Recovering a lost commit
-  Howgit reflogSearch the reflog for your missing commit. It helps if you remember the message, or date and time of the commit. When you think you've found it, check out that commit: git checkout {SHA1 hash}Be careful! You are now "detached," meaning you are not at the HEAD of a branch. Commits made from here are not part of a branch. (Becoming detached is a common way of losing commits, in fact). Review the code at this point. If you've found your missing changes, then create a branch: git checkout -b {branch name}Now you can continue working from your recovered commit, merge those changes into another branch, or just leave the branch as it is, safe in the knowledge that your changes were not permanently lost. WhyThe reflog is similar to a branch's log. The commit log you get from git logshows the ancestry of the branch, the changes that incrementally brought it to this point. Instead of a sequential list of changes to files, the reflog shows the sequence of git commands that got you to the current state. The commit information (e.g., author, message, hash) is also there, and that's what helps us find our lost commits. We can narrow down the reflog further by piping the output intogrepto filter it down to just the commits:git reflog | grep "commit:"
- Share your changes
-  Howgit push origin {branch}WhyAll of your commits happen in your local repository. To share changes with anyone else, they have to be pushed or pulled from one repository to another. The way this typically works is that each developer pulls from a shared remote repository, refered to as origin, and then pushes their changes back to origin where others can then pull them down. 
Need to see it in pictures? You can see branching in action with this interactive visual tutorial.