This post is meant to sum up the most useful things I have learnt about the
line from many years of adventures in the source control world. I will probably update
this page as and when I learn any new tricks.
Simplest primer if you’ve never used git before.
# Create a new local repository - this creates a branch called master git init # Setup a local repository based on an existing remote one git clone https://github.com/someone/some-project # Create / edit your files echo "Hello" > myfile.txt # Stage your files to be committed git add myfile.txt # or just git add * if you're lazy # Gets the status of changes in the local repository git status # Commit whatever you've staged git commit -m "My commit message" # Add a remote repository git remote add origin https://github.com/my-username/my-project # Push your local commits to the remote repository git push # Get newer commits from remote repository into your local one git pull
One of the most important things to setup on new repositories is the
Its name is quite self-explanatory and it prevents accidental commits of temporary / IDE /
environment / OS files. There’s a website called gitignore.io that
helps you generate a good sample
.gitignore based on your project’s language, the IDE
you use and your OS.
Viewing the git log is often not trivial if you don’t have a fancy IDE. I usually just
want to see a couple of attributes across a number of commits, so the default
representation is not helpful. I have a custom view for the last 20 commits, each on a
single line with their hashes, dates, authors and comments in colours. This allows me to
git config --global alias.work 'log -n 20 --pretty=format:"%C(yellow)%h%Creset %ai %<(15) %Cblue%aN %Creset %s"'
b62eee6 2020-03-22 16:10:02 +0800 John Doe Added new feature 8dc0dcc 2020-03-21 16:09:28 +0800 Jane Smith Fixed bug: xyz f683f5d 2020-03-20 13:44:19 +0800 Joe Schmoe Bumped version db158f4 2020-03-19 13:43:13 +0800 Jake Gold Upgraded dependency
If you’re even lazier, use a shorter shell alias in your
are some git commands that I use too often like
git status so they end up in here to
save me lots of key strokes as well.
alias gw="git log -n 20 --pretty=format:'%C(yellow)%h%Creset %ai %<(15) %Cblue%aN %Creset %s'" alias gs="git status"
List branches and find out which one you’re in
git branch git branch -r # includes remote branches that don't exist locally
git checkout an-existing-branch
Create a new branch based on the current branch you’re in
git checkout -b my-new-branch-name
Delete a branch
git branch -D branch-i-do-not-like-anymore
git status to quickly list the files that have changed, but to review the
changes made side-by-side with the original, you can use the
git difftool path/to/file # Review changes for a specific file git difftool # Cycle through all changed files
Tip: if using a
vim-based difftool, you can exit all windows using
If you’re working on a collaborative project, every person should be working on a
different feature branch that merges back into
master. Once you’ve added more commits to
your feature branch and
master has also received newer commits, the branches would now
have diverged. If you would like to apply those newer commits from
master onto your
branch, you can do a rebase. Note that your newer commits will always be stacked later
than those you are rebasing from
master, so the commit log still makes sense when you
eventually merge your branch into
git rebase master
Rebasing also has a very different ability that allows you to rewrite history using the interactive mode. You can either choose how many previous commits to work with or if your commit history doesn’t go very far back, use the entire history.
git rebase -i HEAD~5 # last 5 commits git rebase -i --root # beginning of time
You will then be brought to your git text editor showing the list of commits and an option prefixing each commit.
pick 06cfc71 Added EUR support pick 33b09f4 Changed FX rates API pick 3e6a5ef Allow CreditCardAccount to be paymentAccount pick 4c174ce Revise CashServices pick 6487b61 Fixed historical download
You can read the bunch of comments in the block below the commit list, but essentially
what you need to do is change the prefix for any commit from
pick to one of the
operations and save the file. You can use the first letter of the operation instead of
typing the entire thing out. e.g. just
f instead of
fixup. The most common operations
I use are:
drop: Remove the commit(s) from history
fixup: Join multiple commits into a single one: all consecutive commits prefixed with
fixupwill be merged into the most previous commit prefixed with
pickand retain that commit’s message and timestamp
fixup, but allows changing which commit message to use
reword: To change the commit message
Best practice for rewriting history is to only do it if your branch has not been pushed to remote or if you are sure that you will be the only person pulling that branch.
Never rewrite history on a shared branch, especially master.
That being said, you can if you really want to. Your
git push will be rejected by the
remote for good reason, but you can force it through using
git push -f, which I repeat,
is not recommended.
git commit --amend
If you already know you’re going to do a
fixup rebase later, you can save time by just
adding new changes directly into a previous commit.
git add my-changed-file git commit --amend --no-edit
Elegant way of crediting someone else for a fix or helping someone else fix a merge conflict without adding commits under your own name.
git commit --amend --no-edit --author="John Doe <firstname.lastname@example.org>"
If you’ve done a
fixup rebase, you’ll notice that the commit time uses the
oldest commit. Assuming the squashed commit is the most recent commit, you can reset the
commit time to the current time using:
git commit --amend --no-edit --reset-author
You can also change the commit time to a specific time using:
git commit --amend --no-edit --date "Fri Mar 16 21:48:09 2020 +0800"
In the event you find yourself in this position with your team mad at you and not knowing what to do, go to their workstations individually and fix their local repositories using these steps:
- Store their changes in a safe place (separate branch pushed to remote)
- Create a temporary branch (
git checkout -b temp)
- Delete the corrupted branch (
git branch -D master)
- Pull changes (
- Restore the branch with your rewritten history (
git checkout master)
- Dump the temporary branch (
git branch -D temp)
- Buy them a coffee / meal
Useful for backing up your current branch to the remote without having to clone the branch locally and switch back.
git push origin local-branch-1:remote-branch-2
Create a branch from a pull request for reviewing. This example creates a branch called
pr79 from pull request #79.
git fetch origin pull/79/head:pr79
Any other git cheats you’ve found useful? Let me know on twitter.