Announcement

  •  » Engine
  •  » Git workflow

#1 2016-11-27 18:01:44

plg
Piwigo Team
Nantes, France, Europe
2002-04-05
13789

Git workflow

Hello coders,

We have been using Git and Github for a year now. My personal opinion is that Git is great because it's much faster than SVN, modern, very documented, highly powerful and with a wide ecosystem. The simple fact that now we can receive Pull-Requests is a great improvement :-) I also think it is more complicated to use than SVN.

I would like to open a discussion about our workflow.

What we currently do is:

* branch "master" where we commit changes for future versions
* branch "2.8" where we fix bugs
* nearly on each commit on branch 2.8, we merge branch 2.8 on master (and *never* master on 2.8)
* specific case for the commit changing the version (from 2.8.2 to 2.8.3 for instance), which is merge with the "ours" strategy : "git checkout master && git merge -s ours 2.8" which produced a fake merge.

We can say that "it works", but I don't find it optimal at all. The fact that we have to use such a trick as "merge -s ours" may mean we don't do things the right way. I have been discussing with some other people using Git (on other software projects) and here is how they do:

* branch "master" where they commit changes for future version + any bug fix (all commits actually)
* branch "2.8" where they cherry-pick the bug fixes from master (can be done by the "release manager", ie someone responsible for the stable branch)
* no merge from 2.8 to master, cleaner (easier to read) commit history log on both master and 2.8

OK, some of you may immediately think "that's simply the way SVN used to work". They may be right. That's also much simpler and less "error prone" in my opinion, without removing the improvements brought by Git.

With a year of experience, I think "merge" on Git is great, but it's a different kind of operation compared to SVN. On a given branch, merge is designed to be done only once and then the branch is deleted, ie only exists on the commit history (or not, depends on fast-forward). The "git merge" operation is for small "feature branches", not "release branches". This is not the "unique truth", it's simply the way I understand it after 1 year of experience with it :-)

Do you have an opinion about that? I would like to test this workflow for 2.9.

Offline

 

#2 2016-11-27 18:30:57

mmoy
Member
France
2014-08-18
85

Re: Git workflow

Cherry-picking from master to the stable branch works too, but you'll loose a few benefits of using "merge":

1) With the current flow, at any time you can checkout master and run "git merge 2.8". You'll get all unmerged commits, and merge will tell you if there's nothing to merge. No risk of forgetting to forward-port the commit from the stable branch to master.

2) If you ever need several maintenance branches, it'll be much easier to commit to branch 2.8 and merge 2.8 into 2.9, 2.10 and 2.11.

3) With cherry-pick, the same commit (in the sense, same commit message, same change introduced) appears in several places in the history. On may find it dirty or confusing. One fundamental difference between merge and cherry-pick is that merge keeps track of what was merge (through multiple parents in the merge commit) while cherry-pick doesn't (well, the id of the cherry-picked commit is kept in the commit message, but that's only for human beings, Git itself doesn't use this information).

Now, 1) is debatable. In any case, you may realize after the fact that a commit was meant for 2.8 and commit it to master. So, even if the rule is to commit to stable and to merge to master, cherry-pick is also needed sometimes. 2) is purely hypothetical, it's a very strong requirement for some people but piwigo probably won't ever need it. 3) is highly subjective: I find merge commits cleaner than cherry-pick, but lots of people may disagree, with good reasons.

There's another option: don't ever mention the current version number in the source code, and use tags to do this. When running the PHP code right out of the Git repository, let the PHP code find out which version is used (run "git describe HEAD" for example). When distributing a tarball without the git history, let the code generating the tarball hardcode the version number in the code.

Advantages:

* Compared to your current flow, you wouldn't need this "merge -s ours" anymore: a plain merge does the right thing (bring the bugfix, without changing the version number since this version number doesn't appear in the source).

* When running a non-tagged version, you get a version number like v2.11.0-rc0-7-gbe5a750939 which contains both the human-readable version and the Git commit id.

Now, this isn't perfect either. Among the drawbacks:

* One day, someone will run the code without the git history and without the version number exported. That guy wasn't supposed to do this, but s/he'll still complain ;-).

* Not mentioning the version number in the code does not work if you maintain an in-code changelog for example.

In any case, there's no "right" thing to do, the best workflow is the one you like best ;-).

Offline

 

#3 2016-11-27 19:20:43

plg
Piwigo Team
Nantes, France, Europe
2002-04-05
13789

Re: Git workflow

Hi mmoy, and thank you for your feedback on this case :-)

Just to make things clearer about what I call a "lack of readibility" on commit logs... Here is what we currently have:

Code:

*   508ca3c - (HEAD, master) Merge branch 'feature/123-nice-feature'
|\  
| * be987a9 - (feature/123-nice-feature) commit 2 on feature/123-nice-feature
| * 5302435 - commit 1 on feature/123-nice-feature
* | a524bf7 - commit 5 on master
|/  
*   444724d - Merge branch '2.8'
|\  
| * 20d175b - (2.8) commit 4 on 2.8
| * 26fbb8b - commit 3 on 2.8
* | 554e687 - commit 4 on master
* | dc88bca - commit 3 on master
* |   24812d6 - Merge branch '2.8'
|\ \  
| |/  
| * 616df69 - commit 2 on 2.8
| * bc9f6f3 - commit 1 on 2.8
* | 4013a97 - commit 2 on master
|/  
* 745008c - first commit

And with a "cherry-pick workflow", what we could have on branch master :

Code:

*   d51de93 - (HEAD, master) Merge branch 'feature/123-nice-feature'
|\  
| * 0167a7b - commit 2 on feature/123-nice-feature
| * bd1cf01 - commit 1 on feature/123-nice-feature
* | 42f27f7 - commit 5 on master
|/  
* 7014883 - commit 4 on master
* 370019a - commit 3 on master
* 4f12ce8 - commit 2 on master
* 91a578a - commit 1 on master

+ on branch 2.8:

Code:

* cd87eb7 - (HEAD, 2.8) commit 3 on master (coming from cherry-pick)
* 52aba00 - commit 3 on 2.8
* 43977d2 - commit 2 on master (coming from cherry-pick)
* d234f1a - commit 2 on 2.8
* f48f7fa - commit 1 on 2.8
* 91a578a - commit 1 on master

In my opinion, one is much more "readable" than the other, and that's important :-)

(I will also reply to your points)

Offline

 

#4 2016-11-28 08:42:50

mmoy
Member
France
2014-08-18
85

Re: Git workflow

"Readable" depends on your use-case. I rarely look at the output of "git log --graph --oneline" just for the pleasure of seeing a nice graph ;-). My main use-cases are: blame or bisect to find a particular commit, then if needed look at the parents or descendants of this commit. Sometimes some statistics on history (count commits per author, ...).

For these use-cases, having a nice graph is absolutely useless, but having commits duplicated by cherry-pick it clearly a drawback. So, for my use-case, I agree that one history is more "readable" than the other, but we probably disagree about which is which ;-).

But again, all this is very subjective. I'm not arguing against a cherry-pick workflow, just giving you more elements to choose.

Offline

 
  •  » Engine
  •  » Git workflow

Board footer

Powered by FluxBB

github twitter newsletter Donate Piwigo.org © 2002-2024 · Contact