Git Playbook
Git is a free and open source version control system that is widely used in the open source community, including well known git repositories such as GitHub and GitLab. If you are unfamiliar with Git, it’s worth taking a few moments to familiarize yourself with it. A simple guide can be found at http://rogerdudler.github.io/git-guide/.
Gitflow
Gitflow enables you to work on your own feature branch in isolation before committing to the main project branches, i.e. develop and master. Features may be driven from your preferred project planning tool as assigned tasks. Gitflow helps manage the Git history to reflect the progress against specific issues.
Install GitFlow
brew install gitflow
apt-get install gitflow
Note: wget
and util-linux
are required to install gitflow. For more detailed instructions see https://github.com/nvie/gitflow/wiki/Windows
wget -q -O - --no-check-certificate https://github.com/nvie/gitflow/raw/develop/contrib/gitflow-installer.sh | bash
GitFlow initialization and settings
- From the local repository directory (e.g. /universal-imports),
git flow init
- Use the following settings when prompted for the gitflow prefixes,
master = master
develop = develop
feature = feature/
release = release/
hotfix = hotfix/
support = support/
versiontag = -v
GitFlow workflow
- Before starting a feature branch ensure that you have the latest code from the
develop
branch,
git checkout develop
git pull
- Start a feature branch by typing,
git flow *feature identifier*
For example, if your feature has an ID of 007, you would execute:
git flow feature start 007
-
Now, start committing changes to your feature.
- You can propose changes (add it to the Index) using,
git add <filename>
or
git add *
- To commit these changes to your local repository:
git commit -m "#007 Commit message"
(Be sure to start the message with your feature ID or feature name.)
-
Refer to the following guidelines for writing commit messages. For example,
> PSE-007: Summarize clearly in one line what the commit is about > > Describe the problem the commit solves or the use > case for a new feature. Justify why you chose > the particular solution.
-
Optionally, publish a feature branch to the remote server so it can be used by other users,
git flow feature publish 007
-
When done with the feature, use:
git flow feature finish 007 git push
-
Then delete the remote feature branch (if it was created):
git push origin :feature/007
-
Then delete the local branch (if it still exists. git flow will usually delete it for you):
git branch -d feature/007
Resolve Unstaged Change Warnings
Resolve unstaged change warnings using:
git stash
git push (i.e. push your staged commits)
You can switch to another branch to work on another feature, etc. To bring back your stashed changes:
git stash pop
Avoid Fast-forward Merges
Suppose you are working on “feature/007” and there have been changes in the meantime to the “develop” branch.
Approach 1 - Pre-sync the target branch
git checkout develop
git pull
git checkout feature/007
git flow feature finish 007
Approach 2 - Merge the branches with the “no fast-forward” flag
git flow feature start 007
git flow feature publish 007
Instead of using “git flow feature finish 007” (because it causes a fast forward at this point)
git checkout develop
git pull
git merge --no-ff feature/007
git push origin develop
Git Tips and Tricks
Checkout a specific tag
This can be useful if you want to use a specific tagged version for a deployment:
-
List the available tags:
git tag -l ... v3.10.0 v3.11.0 v3.14.0 v3.15.0 v3.16.0 v3.17.0
-
Checkout a specific tag:
git checkout tags/v3.16.0 M /universal-imports/modules Note: checking out 'tags/v3.16.0'. ...
Undo or rollback a Git commit
Assuming you have not yet pushed commits to the remote repository, you can rollback to the previous commit:
git reset --soft HEAD^
To rollback the last three commits,
git reset --hard HEAD~3
Resetting a local branch to exactly match a remote branch
Set your local branch to exactly match the remote branch:
git fetch origin
git reset --hard origin/develop
If you want to save your current branch’s state before doing this (just in case),
git commit -a -m "Saving my work, just in case"
git branch my-saved-work
Rollback a release in the Master branch to a previous tag
WARNING: This alters history. Do not try this on the DEVELOP branch.
-
Ensure that you are on the MASTER branch,
git checkout master
-
Find the commit number of the previous tag (e.g. dc7e7b5 3.15.0.RELEASE),
git log --oneline ecdd645 Merge branch 'release-3.16.0' c023314 3.16.0.RELEASE 72a9524 Added some changes f2e68e5 3.16.0.SNAPSHOT 3414a30 Merge branch 'release-3.15.0' into develop 5078f25 Merge branch 'release-3.15.0' dc7e7b5 3.15.0.RELEASE 9e5c0d2 Updated some other changes ...
-
Make the previous tag commit the current one (e.g. 3.15.0.RELEASE),
git reset --hard dc7e7b5
-
Remove the other release’s now uncommitted changes locally:
git reset HEAD^
-
Force push the new HEAD commit to the remote repository:
git push origin +HEAD
-
If you want to still have it in your local repository and only remove it from the remote, instead use:
git push origin +HEAD^:master
Merging
-
Open the Git merge tool:
git mergetool
Fix any merge issues…
-
Execute the merge:
git merge
This merges resolved conflicts and resets the merge head appropriately…
Undo a failed merge
If you see something like the following Git error/warning message: You have not concluded your merge (MERGE_HEAD exists). Please, commit your changes before you can merge.
git merge --abort
Keep Learning
If you’re just getting familiar with git and related tools, you may also want to check out the blog How and Why to Write Commit Messages First, and you’ll find more tips in this blog on Git Switch and Restore.
To learn how to take the next steps when your code is ready, check out From Code to Container.