Differences

This shows you the differences between two versions of the page.

Link to this comparison view

dev:core:git [2015/07/28 16:44]
mistic100 [Create a new release]
— (current)
Line 1: Line 1:
-<WRAP round tip> 
-This is a work in progress, all concepts exposed here are susceptible to change. 
-</WRAP> 
- 
-====== Git workflow and best pratices ====== 
- 
-===== Reminder ===== 
- 
-On Piwigo we typically have two active branches: 
-  * ''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. 
- 
-===== Workflow ===== 
- 
-The workflow we follow is based on Git flow as described by Vincent Driessen in his excellent article [[http://nvie.com/posts/a-successful-git-branching-model|A successful Git branching model]]. But with important changes because of our way to work and the translation process. 
- 
-{{http://nvie.com/img/git-model@2x.png?575}} 
- 
-**Don't worry** it's actually simple. 
- 
-===''master''== 
-Contains the latest **stable** version of the source code. Production tags are created on this branch. **Never commit on this branch.** 
- 
-===''develop''== 
-Contains the latest **development** code. It's like the ''trunk'' on Subversion. **It is advised to only make small commits on this branch**, prefer using a ''bug/'' or ''feature/'' branch. 
- 
-''develop'' is merged into ''master'' just after a new release. 
- 
-=== Release branches (''2.7'' for instance) === 
-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 ''develop'' **it'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 ''develop'' just after a new release. 
- 
-===''bug/''=== 
-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 ''develop'', otherwise you won't be able to merge it. 
- 
-Once the fix is ready merge it to ''develop'' and to the current release branch if needed.\\ 
-You notice that, unlike Vincent Dressen, we don't 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. 
- 
-===''feature/''=== 
-Almost the same as ''bug/'' but for new features. It can be named after a specific issue number, or an arbitrary name for unlisted features. 
- 
-Once the feature is ready, merge it too ''develop'' and in the current release branch **only** if it's a minor feature. 
- 
-Like bugs, feature branches that will be merges to the release branch must be init from the release branch, and not from ''develop''. 
- 
-Don't forget to delete the branch locally and remotely when finished. 
- 
-===''translation''=== 
-This branch is only used for translations committed by Lexiglot and has a special behavior. 
- 
-Most importantly the ''translation'' branch tracks the ''develop'' branch. Which means you have to merge ''develop'' to ''translation'' after merging a feature which add new language strings. 
- 
-Because ''translation'' is tracking ''develop'', it cannot be merged to the current release branch. It's the only case where we use cherry-picking to apply new translations to the release branch. This is only done before a release. 
- 
- 
-===== Best practices ===== 
- 
-These are some random advices you **should** really apply in order to have a clean Git history. 
- 
-==== No fast-forward ==== 
-When merging a branch into another, the default behavior 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 empty technical commit when merging. 
- 
-{{http://nvie.com/img/merge-without-ff@2x.png?478}} 
- 
-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. 
- 
-==== Rebase when pulling ==== 
-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! 
- 
-{{http://gitready.com/images/pull4.png}} 
-(from [[http://gitready.com/advanced/2009/02/11/pull-with-rebase.html|gitready.com]]) 
- 
-The fact is ''pull'' is a shorthand for ''fetch & merge''. But you don't want a merge, you want to apply your modifications after the ones of Bob. 
- 
-The solution is to use the ''--rebase'' switch, which will try to reapply your commits at the end of the tree. 
- 
-Say we are working on the branch 2.7, the command is: 
-''git pull --rebase origin 2.7'' 
- 
-{{http://gitready.com/images/pull3.png}} 
- 
-And that's it! Much cleaner. 
- 
-Of course you may have conflicts during the rebase and have to manually solve them, like a normal merge. 
- 
-==== Atomistic commits ==== 
-A golden rule is "commit often, push once". That mean you should make very small commits, assigning a very single issue, and push everything when you are really sure it's ready. 
- 
-You can even pause your work on a branch, go to another one, commit a bit more, return to the first one, finish your work, and finally push everything. 
- 
-Don't forget some very handy tools of git to help you to craft "perfect" commits: 
-  * ''stash'' to store your current modifications and clean your working copy 
-  * ''add -p'' to stage only some parts of a file 
-  * ''squash'' to regroup sequential commits into one 
-  * ''commit --ammend'' to modify your latest commit 
- 
-(You must not abuse of these last two, only use them for correcting typos, and this kind of things;) 
- 
-All this "rewriting history" can be done when you work locally, once you pushed everything on Github, it's too late. Hence the "push once". 
- 
-===== Examples ===== 
- 
-==== I want to fix a bug / add a new feature ==== 
- 
-Also read [[#my_feature_changes_the_translations|My feature changes the translations]]. 
- 
-=== The bug is small and does not require a branch === 
- 
-<code> 
-1. switch to current release branch 
-git checkout 2.7 
- 
-2. commit things 
-git stage ... 
-git commit ... 
- 
-3. merge to develop 
-git checkout develop 
-git merge 2.7 
-</code> 
- 
-=== The bug/feature will be available in the current release === 
- 
-<code> 
-1. switch to current release branch 
-git checkout 2.7 
- 
-2. start the new branch 
-git checkout -b bug/1234 
- 
-3. commit things 
-git stage ... 
-git commit ... 
- 
-4. merge to current release 
-git checkout 2.7 
-git merge bug/1234 --no-ff 
- 
-5. merge to develop 
-git checkout develop 
-git merge bug/1234 --no-ff 
- 
-6. delete the branch 
-git branch -d bug/1234 
-</code> 
- 
-=== The feature will only be available on develop === 
- 
-<code> 
-1. switch to develop 
-git checkout develop 
- 
-2. start the new branch 
-git checkout -b bug/1234 
- 
-3. commit things 
-git stage ... 
-git commit ... 
- 
-4. merge to develop 
-git checkout develop 
-git merge bug/1234 --no-ff 
- 
-5. delete the branch 
-git branch -d bug/1234 
-</code> 
- 
-=== My feature changes the translations === 
- 
-**Note :** if possible, don't add new translatable strings to the current release branch. 
- 
-Once the feature has been merged to ''develop'' : 
-<code> 
-1. merge develop into translation 
-git checkout translation 
-git merge develop --no-ff 
- 
-# DO NOT merge translation into develop 
-</code> 
- 
-==== Create a new release ==== 
- 
-<code> 
-1. merge translations as described in "My feature changes the translations" 
- 
-2. apply translations to release branch 
-git checkout 2.7 
-git cherry-pick -n COMMIT1..COMMIT2 # important -n switch 
-# COMMIT1 and COMMIT2 are the bounds of the translation branch since last release 
-git stage -A language/ 
-git commit -m "Merge branch 'translation' into '2.7'" 
- 
-3. prepare the release 
-git stage ... 
-git commit ... 
- 
-4. merge to develop and master 
-git checkout develop 
-git merge 2.7 --no-ff 
- 
-git checkout master 
-git merge 2.7 --no-ff 
- 
-5. tag (on 2.7) 
-git checkout 2.7 
-git tag -a '2.7.5' -m 'Release 2.7.5' 
-</code> 
  
 
Back to top
dev/core/git.1438101841.txt.gz · Last modified: 2015/07/28 16:44 by mistic100
 
 
github twitter newsletter Donate Piwigo.org © 2002-2024 · Contact