There are various different workflow strategies for git but I will try to limit this discussion to useful commands to help you get up and running with git!
Amending the previous commit
To simply amend the previous commit you can git commit --amend
. Note that
this will include anything that was added or removed via git add
or
git rm
and it can mostly be used to update the commit message or include
missing files.
Git branch workflow
Branching in git is a very straight-forward operation: git checkout -b <branch-name>
. Once you are done with your branch you can use git rebase
which re-applies commits, one by one, in order, from your current branch onto another. For example, suppose there was a branch feature-cool
and we wanted to pull in changes from master prior to merging the feature back we could run:
git rebase origin/master
At this point git mergetool
is your friend if you need to resolve any merge
conflicts. I can highly recommend meld
. Note that if you ran the command as above
then local
is the master branch, and remote
here means your feature branch / changes.
Once you have resolved all conflicts, you can simply continue rebasing via git rebase --continue
. It would be good at this point to rerun all tests to make sure that the feature is working as expected without any problems and we are then ready to merge it back into master via:
git checkout master
git merge feature-cool
Finally we can git push --force
to force the master branch to accept our conflict resolved commit.
Interactive rebase
Rebase is also very useful when run in interactive mode, git rebase -i <branch>
,
which will then open up an editor to allow squashing and rewording of previous commits.
When rebasing, the number of commits in history to rebase need to be provided:
git rebase --interactive HEAD~3
This opens up an editor window as follows with the oldest commit on top:
pick 07c5aba git amend, rebase, interactive, log
pick de9b1fb a
pick 3e73336 b
pick fa20ff3 c
# Rebase 8da7e8b..fa20ff3 onto 8da7e8b
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
The default option is pick
or p
which leaves the commit as is. The other options are:
reword
- Edit the commit message only
squash
- This melds the commit into the previous commit. We can thus squash multiple commits into one for a cleaner concise history.
fixup
- As the description says, this works like squash but it auto comments the commit message out.
git push --force
to update git history.
Open source workflow
Similar to the above rebase workflow, this is a quick primer on getting started with open source contribution:
# Point our `upstream` remote to the original fork
git remote add upstream https://github.com/thoughtbot/factory_girl.git
# Fetch latest commits from `upstream` (the original fork)
git fetch upstream
# Checkout our feature branch
git checkout feature
# Reapply it onto upstream's master
git rebase upstream/master
# Fix conflicts, then `git rebase --continue`, repeat until done
# Push to our fork
git push --force origin feature
Git history
Viewing git history like a champion:
git log --pretty=format:"%h - %an, %ar : %s"
Undo a successful rebase
The simplest way to do this to find the head commit that was directly before the rebase via git reflog
and then reset to it via git reset --hard HEAD@{XX}
where XX
is the commit number