trunk holds the main source code with features for the next major version
2.7 (in instance) holds the source code of the current major version, only bug fixes and minor features are pushed to this branch
As the SVN concept of branches is very loose we used to develop either on master or 2.7 and then merge specific commits to the other branch if needed. This concept is totally applicable in Git, it's called cherry pick.
But this is not how Git is supposed to work. Git tends to track every changes, and links them to others, and because cherry pick basically forge a new commit from another one, a part of the history is lost.
The workflow we follow is based on Git flow as described by Vincent Driessen in his excellent article A successful Git branching model. But with important changes because of our way to work and the translation process.
Contain the code of a specific major version and all its minor versions. It is initiated by a single commit making necessary changes (version change, production config, etc.). Like masterit's advised to only make small commits on this branch.
Remember that we NEVER make database changes in minor releases, neither we add translatable strings.
Minor releases are tagged on the release branch.
The current release branch is merged into master just after a new release.
Are used to… fix bugs. Create one bug branch by bug. It should be named after a specific issue number (eg: bug/1324).
If the bug has to be ported to the current release branch, then you must init the bug branch from the release branch, and NOT from master, otherwise you won't be able to merge it.
Once the fix is ready, merge it to the branch from where you started (master on release branch).
You notice that, unlike Vincent Dressen, we do not always merge bug fixes in master but in the current branch, which is then merged back into master when ready.
Don't forget to delete the branch locally and remotely when finished.
This branch is only used for translations committed by Lexiglot and has a special behaviour.
Most importantly the translation branch tracks the master branch. Which means you have to merge master to translation after merging a feature which add new language strings.
Because translation is tracking master, it cannot be merged to the current release branch. It's the only case where we use cherry-picking (kinda) to apply new translations to the release branch. This is only done before a release.
When merging a branch into another, the default behaviour of Git is to fast-forward it, that means if no changes has been made on the target branch, the source branch will simply disappear from the tree, making it difficult to localize merging point.
By adding the –no-ff option to git merge you will force Git to create an technical commit when merging.
This is of course not always required, it's up to you to evaluate if a specific set of commits belongs to a separated branch, but don't forget than the branch will still be visible if someone else committed in the mean time.
Say you commit on branch A, and Bob also committed on branch A, and he pushed the branch to the central server. Then you want tu push your commit: Git will refuse to it, he will ask you to pull the remote branch. Ok so you do a git pull. If you are lucky there won't be any merge conflict and you will be able to push.
But this will create a one-shot branch, and a new commit “Merge branch 'master' on 'master'”. And this is a complete mess!
1. merge translations as described in "My feature changes the translations"
2. apply translations to release branch
git checkout 2.7
git checkout translation -- language/**
git stage -A language/
git commit -m "Merge branch 'translation'"
3. prepare the release
git stage ...
git commit ...
4. merge to master
git checkout master
git merge --no-commit 2.7
##### RESTORE development version constant (eg: 2.8.0beta1)
git stage include/constants.inc.php
git commit # no need for message)
5. tag (on 2.7)
git checkout 2.7
git tag -a 2.7.5 -m "Release 2.7.5"