Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git: definition of upward/downward directions between branches feels counterintuitive

Tags:

git

merge

I am reading the gitworkflows documentation at https://git-scm.com/docs/gitworkflows (can be also read in "man gitworkflows"), but the definition of the upward/downward directions between branches feels counterintuitive to me. I failed to make sense of it, so I am wondering if there is anything that I am missing.

Specifically, the "Managing Branches > Graduation" section of the above linked documentation says

Graduation

As a given feature goes from experimental to stable, it also "graduates" between the corresponding branches of the software. git.git uses the following integration branches:

  • maint tracks the commits that should go into the next "maintenance release", i.e., update of the last released stable version;

  • master tracks the commits that should go into the next release;

  • next is intended as a testing branch for topics being tested for stability for master.

There is a fourth official branch that is used slightly differently:

  • seen is an integration branch for things that are not quite ready for inclusion yet (see "Integration Branches" below).

UPDATE: seen was originally named pu (proposed updates) at time of posting.

Each of the four branches is usually a direct descendant of the one above it.

The last sentence seems to imply that maint > master > next > seen is the downward direction (because master is the descendent of maint, etc).

However, the documentation goes on to say

Conceptually, the feature enters at an unstable branch (usually next or pu), and "graduates" to master for the next release once it is considered stable enough.

Merging upwards

The "downwards graduation" discussed above [...]

So, in the last sentence, the documentation actually defines the propagation of new features in the direction of next > master as "downward graduation". This is the opposite to my earlier impression that master > next is the downward direction.

To me, defining maint > master > next > seen as the downward direction feels not only more natural, but also more consistent with the definition of upstream/downstream repositories. We usually clone a remote "upstream" repository to a local repository, implement new features, and push them "upwards" to the remote repository. (Note that the last step here is called "pushing upwards".) This overall procedure is parallel to branching next from master, implement new features in next, and merging them to master. Therefore, I think the propagation of new features from next to master should be called "upwards graduation" as well (in parallel to "pushing upwards" from the local to remote repository). Yet, it is called "downwards graduation" in the documentation.

Why does Git use this counterintuitive definition of the upward/downward directions between branches? How can I make sense of it? Or, is there anything critical that I am missing to understand this definition?

like image 515
dashmile Avatar asked Feb 16 '16 00:02

dashmile


1 Answers

Since 2009, all those downwards/upwards merges are automated by the Reintegrate script used by Junio C. Hamano (explained in commit cc1b258) to manage the git branches from gitster/git (which has a lot of branches)

But back in 2007, the first revision of Documentation/howto/maintain-git.txt was more explicit (and manual)

I think the propagation of new features from next to master should be called the "upward graduation"

I agree, the original file showed:

Merge downwards (master->next) if needed:

$ git checkout next
$ git merge master
$ make test

By that case, if you merge next to master (in order to graduate next to the new git release in master), you do merge upward.

There was an interesting discussion around the more modern form of Documentation/gitworkflows.txt introduced in 2008 by Thomas Rast (trast)

Junio C. Hamano mentioned there:

This description misses the most important reason why merging into topic branches is not a good idea. Once you merge a general purpose integration branch such as master into a topic branch, the branch ceases to be about the single topic.
It becomes: "the topic and other unrelated changes mixed together".

Always merging upward is a good rule, and this is when used with topic branches, there is one twist you did not mention but is worth knowing about.
A topic that is meant to eventually merge into older integration branch (e.g. maint) does not necessarily have to be merged to its final destination branch first.
I often do this:

   git checkout tr/maint-fix-bla maint
   git am -s fix-mail-from-thomas.txt
   git checkout next
   git merge tr/maint-fix-bla
   ... cook further, perhaps adding more commits to
   ... tr/maint-fix-bla topic and merging the result to next;
   ... and then when the topic appears to be stable do:
   git checkout master
   git merge tr/maint-fix-bla
   
   vvvvvvvvvvvvvvvvvvvvvvvvv
   ... and later
   git checkout maint
   git merge tr/maint-fix-bla
   git branch -d tr/maint-fix-bla

This keeps older integration branches stale, until the topic really gets proven to be regression-free in the field.
This workflow is safer and more suitable for a final integration branch to which a known breakage is better than an unintended regression.

An alternative would be what the reader would assume from your description of merging upwards, which would look like this:

   git checkout tr/maint-fix-bla maint
   git am -s fix-mail-from-thomas.txt
   git checkout maint
   git merge tr/maint-fix-bla
   git checkout master
   git merge maint
   git checkout next
   git merge master

This can regress maint unintentionally and then the regression is propagated upwards to contaminate all integration branches.

With:

we use the word "integration branches" to mean the stable branches such as maint/master/next.


Note that, with Git 2.28 (Q3 2020), the documentation and some tests have been adjusted for the recent renaming of "pu" branch to "seen".

See commit 6dca5db, commit 77dc604, commit 828197d (25 Jun 2020) by Johannes Schindelin (dscho).
(Merged by Junio C Hamano -- gitster -- in commit 8a78e4d, 06 Jul 2020)

docs: adjust for the recent rename of pu to seen

Signed-off-by: Johannes Schindelin

As of "What's cooking in git.git (Jun 2020, #04; Mon, 22)", there is no longer any pu branch, but a seen branch.

While we technically do not even need to update the manual pages, it makes sense to update them because they clearly talk about branches in git.git.

Please note that in two instances, this patch not only updates the branch name, but also the description "(proposed updates)".

Where appropriate, quotes have been added for readability.

And:

tests: reference seen wherever pu was referenced

Signed-off-by: Johannes Schindelin

As our test suite partially reflects how we work in the Git project, it is natural that the branch name pu was used in a couple places.

Since that branch was renamed to seen, let's use the new name consistently.

From the mailing list:

The 'pu' (proposed updates) branch has been renamed to 'seen' to use a more meaningful name (after all, the purpose of it is not to contain all proposals, but to merely serve as a place to park what the maintainer happened to have seen) and more importantly, to make room for topics from those contributors whose two-letter name abbreviation needs to be 'pu' under 'pu/$topicName'.

You can find the changes described here in the integration branches of the repositories.

like image 120
VonC Avatar answered Nov 02 '22 05:11

VonC