6 useful and lesser-known git commands
Git is such a complex tool that I often feel as if I'm barely using 10% of it's complete functionality. The various commands range from the absolutely essential (commit
, push
, pull
) to the more exotic (cherry-pick
, rebase
), to the downright obscure or scary (fsck
, merge-octopus
, quiltimport
). You can generally get by with knowing the basic functions of a small set of commands, that allow you to push, pull, commit, change branches and merge. However, this list compiles 6 commands that you may not know about that have seriously improved the way in which I use git.
1. git log -p <path>
I recently came across this as I was searching for an easy way of tracking a file's changes over time. git log
is git's way of showing you the history of your codebase, and adding a path to the command will limit the log to the changes in that one file. Finally, the -p
flag includes the diff on the file at each commit, so you can see exactly how the file has changed at each point in the history of the code. Example:
It's worth getting to grips with diff formatting, as git uses it extensively.
2. git checkout <commit>
If you want to see the state of your code at a particular point in history, git makes this trivial. Just run this command with a commit hash as the argument (you can use git log
to find the hash you want to revert to). For example:
As shown above, git will tell you that you're in a "'detached HEAD' state". This means that any changes won't affect the state of your code before you checked out. To get back to your original state, just run git checkout master
(replace master with whichever branch you were on, if different).
3. git checkout <tree-ish> -- <path>
Surprisingly unrelated to the command above (a bug-bear of some git critics), this command allows you to pull a file at a given commit into your current workspace. This is useful in the case when you need to restore a deleted file, or restore a file to a previous state.
Here, <tree-ish>
refers to a commit hash, tag or branch, and <path>
is the path of the file relative to the top directory of the project. Here's an example:
Note that this will overwrite any existing file at the same path in your working tree.
4. git stash
This is an extremely useful command that isn't as well known as it should be. If you have uncommitted changes in your tree (i.e. it's "dirty", in git language) that you want to temporarily undo, then this command allows you to stash them for later. This is particularly useful if you want to check the state of your code before your changes, or if you want to merge in someone elses code but aren't yet ready to commit your code as it is.
Stashed changes go into a list, or stack. You can then re-apply these changes when you want, in any order you choose. Here's an example:
So I made a change to a file (one that was already tracked by git), which made my working tree dirty, and then used stash to restore my tree to how it was at the previous commit.
I can see the stash list with git stash list
and restore the changes by using git stash apply
:
If you have multiple items in your stash list, you can specify the stash to restore by using the full name when applying, e.g. git stash apply stash@{1}
.
Using stash is a handy way of temporarily reverting and re-applying changes to your working tree.
5. git cherry-pick <commit>
This command allows you to apply a single commit to your working tree. For example, if there's a commit in another branch that you want to apply but the branch isn't ready to fully merge, you can use this command to grab that commit and drop it in to your current branch. Here's an example, merging a single commit from master
to random-branch
:
The tricky thing with this is that you can easily end up with merge conflicts. The trouble with picking a commit out of nowhere is that it may relate to files that don't exist in your working tree, or are very different to the existing files.
One very useful application of this is when you have a project with a separate production and staging branch. For example, if something gets fixed on the staging branch, alongside some new features being developed, and the fix needs to be applied to the production branch, cherry-pick can be used to apply only those fixes.
6. git annotate <file>
This handy command shows each line of a file next to information about which commit last changed that line, when it changed and who changed it. Example:
And so on
These are just a few commands that will help you with your git knowledge. I'd encourage you to take a look at the full list of commands (git help -a
), and also to read the man pages for the individual commands (git <command> --help
), as certain options can affect the output of commands in very helpful ways.