I have been using Git now for a couple of years, and have struggled to understand what it does. I get the basic concept (that it keeps a record of the changes I make to my code) but it also sometimes seems to get in the way. I have read Think like (a) Git and The thing about git in the last couple of days and learned a few really useful things.
In no particular order …
- the idea that git commits can be ‘wasted’ – you don’t need to keep everything or worry about a commit being perfect. Commit if you feel like it.
- think of branches as save points (via Think like (a) git)
Crafting a committ (or not)
- in contrast, you can also ‘craft’ a commit: this is the idea behind the staging area (or index), and is nicely covered in The Thing About Git. Here you can almost imagine writing your git commit message before you commit (i.e. I fixed problem X). Then simply add those files (or parts of files — aka ‘hunks’). Adding ‘hunks’ is the task of …
git add --patch– this is genius. When you are preparing a commit then you don’t need to commit an entire file. Running
git add --patch myfilename.hereallows you to run through the diffs in the file and only stage those parts you wish to. You can also think of this as a bit of a backwards solution to the classic
git commit --ammendwhich allows you to add things you forgot to the previous commit.
Git patch options
y - stage this hunk n - do not stage this hunk a - stage this and all the remaining hunks in the file d - do not stage this hunk nor any of the remaining hunks in the file j - leave this hunk undecided, see next undecided hunk J - leave this hunk undecided, see next hunk k - leave this hunk undecided, see previous undecided hunk K - leave this hunk undecided, see previous hunk s - split the current hunk into smaller hunks
Selectively applying changes from one branch to another
Common scenario: work in one branch would be useful in another but you don’t want to merge the branches.
If current branch is
this_branch and the branch with the changes you want to pull is called
To pull across a specific commit:
Git cherry pick will pull just a specific commit, but not necessarily a whole file.
To pull across specific file(s):
git checkout that_branch path/to/myfile1 path/to/myfile2
An interactive patch from your current branch.
git checkout this_branch git checkout -p that_branch
Using Git for writing
git diff --word-diff=color… wow! A way to inspect word by word changes in the file. Much better suited to using Git when writing. I should write more about this whole topic! In the meantime, also note
-Swhile viewing the diff to wrap wrong lines and make everything more readable (via someone45 at StackOverflow … Thanks!).
Visualising your commits
- a free git visualization tool called GitX
- the command line version of the above is
git log --graph --decorate --oneline
Finding and restoring something you deleted
git log --diff-filter=D --summary
then restore it
git checkout <deleting_commit>^ -- <file_path>
Things I still need to get my head around
- cherry picking
- the rebase command
Early notes: imagine a development branch, and a feature branch. While your working on the new feature, you also make (possibly) separate changes to the development branch. You don’t want to destroy the feature (it’s not done yet), but you want these recent changes on the development branch in your feature. Then rebase. ‘Rebasing’ refers to moving the point where your feature branch separated from the development branch forward in time. In fact, you move it forward to the ‘capture’ as many of the recent changes on development as you like.
And if it turns out that there are conflicts between your feature branch and the development branch then you can either manually resolve them or do an ‘interactive’ rebase.
A re-read of Think like (a) Git is in order!