Branches in git are "cheap" and easy, they allow to help maintain the information, both locally and remotely.
This work flow is based on Vicent Driessen and Marcus Geelnard branch strategies, it defines rules how branches are forked, merged and tagged. By having well defined set of branches, the project structure is used as a communication tool, allowing to work simultaneously on different stages of the development.
Main Branches;
___A___________AB_____ Master \___B_____/ \____ Develop
A represents a commit, then code forked into develop and a commit B was made, develop was the merged back to master AB.
Development branches;
_A_______________________AF_______________ Master \ / \_AFHBH_/ Hotfix __AFHB_/ Release \__________/___________________________ Develop \_F_/ Feature
Code support branches;
_______________________________AFHB___ Stable-X.Y __AF_________________________/________ Master \_AFH_/ \ /\ Hotfix \ __AFHB_/ \ Release _________________\_/___________\______ Develop
Create a branch featurex from develop and checkout;
$ git checkout -b featurex develop
Initial feature commit;
$ git commit -m "added new feature X"
Other feature commit;
$ git commit -m "better implementation and tests."
Prepare for testing and merge back;
$ git checkout featurex $ git rebase -i develop
Run test's, fixes are implemented;
$ git commit -m "feature X tests fix's."
Rebase strategy is cleaner than merge. When pushed to remotes merge strategy can be used or use force push. To run remote tests, code review etc, push branch to server;
$ git push -u origin featurex
Rename a branch, if all feature branches start by "f-" is easy and quick to type and easy to spot;
$ git branch -m featurex f-xpto
Rename remote branch;
$ git push origin :featurex f-xpto $ git push origin -u f-xpto
Merge branch feature into develop, first make sure is update with develop and history is clean;
$ git checkout featurex $ git rebase -i develop
$ git checkout develop Switched to branch 'develop' $ git merge --no-ff f-xpto Updating ea1b82a..05e9557 (Summary of changes) $ git push origin develop
Delete Remote
$ git push origin :f-xpto
Delete Local;
$ git branch -D f-xpto
Software release numbers follow Tom Preston-Werner description;
projectname-X.Y.Z.tar.xz
There are patch level or minor new features and major releases. New features releases and major releases fork from develop, code is freeze to let keep adding new features to develop while preparing the code to merge to master and back to develop.
$ git checkout -b r-1.2.0 develop Switched to a new branch "release-1.2.0" $ ./bump-version.sh 1.2.0 Files modified successfully, version bumped to 1.2.0. $ git commit -a -m "Bumped version number to 1.2.0" [release-1.2 74d9424] Bumped version number to 1.2.0 1 files changed, 1 insertions(+), 1 deletions(-)
Only documentation or bugfixes are allowed in this branch. When release is ready for production tests merge and push to master;
$ git checkout master Switched to branch 'master' $ git merge --no-ff r-1.2.0 Merge made by recursive.
There are two main types of tags, lightweight and annotated. Lightweight tag is a pointer to a specific commit, much like cheap branches. Annotated tags are stored as full objects and allow to sign with gnupg, making it ideal for distributing releases.
Tags are used to mark patch releases, get back in time to make security patches or to mark a new major or minor new release. Tag new release with projectname-version, this allows meaningful ports distfiles when downloading releases from git archives;
$ git tag -a projectname-1.2.0 -m "project 1.2.0 release" $ git push origin projectname-1.2.0
To push all local tags;
$ git push --follow-tags
Update branch develop with bugfixes from last release, conflict will happen in next step
$ git checkout develop Switched to branch 'develop' $ git merge --no-ff r-1.2.0 Merge made by recursive. (Summary of changes) $ git push
Delete local and remote;
$ git tag -d projectname-0.0.12 $ git push origin :refs/tags/software-name-0.8
List local tags;
$ git tag --list
Hotfix are done in master, the only exceptions are release and stable branches. When hot fix is applied to a stable branch is not included in future releases, only needed when cherry pick is hard or impossible. When hot fixes are done on release branches, as described on this document, they have short duration, hot fixes should relate only to new code. To create a hot/bug fix;
$ git checkout -b h-error-name master
Merge the branches with bug fixes;
$ git merge --no-ff b-error-xpto ... $ git commit -m "Commit severe fix" ... $ git merge --no-ff b-error-xpto ... $ git commit -m "Commit severe fix" ... $ git rebase -i master
Merge the hotfix back to master;
$ git checkout master Switched to branch 'master' $ git merge --no-ff h-error-name Merge made by recursive.
On stable branches cherry pick the commit;
$ git checkout stable-1.1 $ git checkout -b r-1.1.2 $ ./bump-version.sh 1.1.2 Files modified successfully, version bumped to 1.1.2 $ git commit -a -m "Bumped version number to 1.1.2" $ git cherry-pick h-error-name $ git checkout stable-1.1 $ git merge --no-ff r-1.1.2 $ git tag -a projectname-1.1.2
Conflicts happen in previews and next step;
$ git checkout develop Switched to branch 'develop' $ git merge --no-ff h-error-name Merge made by recursive. (Summary of changes)
$ git -D r-1.1.2 $ git -D h-error-name
Some times is useful to pick the last commit that affected a path on other branch. To achieve this first get last commit that affected the path;
$ git checkout upstream $ git log -n 1 -- path/dir/or/file.c $ git checkout stable-3.4 $ git cherry-pick 9ce8b280e7081ec3c122b228cfa76600251ea6c9Git Index
This is part of the Tribu System Documentation. Copyright (C) 2020 Tribu Team. See the file Gnu Free Documentation License for copying conditions.