 8a78e4d615
			
		
	
	8a78e4d615
	
	
	
		
			
			The documentation and some tests have been adjusted for the recent renaming of "pu" branch to "seen". * js/pu-to-seen: tests: reference `seen` wherever `pu` was referenced docs: adjust the technical overview for the rename `pu` -> `seen` docs: adjust for the recent rename of `pu` to `seen`
		
			
				
	
	
		
			476 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			476 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| From: Junio C Hamano <gitster@pobox.com>
 | |
| Date: Wed, 21 Nov 2007 16:32:55 -0800
 | |
| Subject: Addendum to "MaintNotes"
 | |
| Abstract: Imagine that Git development is racing along as usual, when our friendly
 | |
|  neighborhood maintainer is struck down by a wayward bus. Out of the
 | |
|  hordes of suckers (loyal developers), you have been tricked (chosen) to
 | |
|  step up as the new maintainer. This howto will show you "how to" do it.
 | |
| Content-type: text/asciidoc
 | |
| 
 | |
| How to maintain Git
 | |
| ===================
 | |
| 
 | |
| Activities
 | |
| ----------
 | |
| 
 | |
| The maintainer's Git time is spent on three activities.
 | |
| 
 | |
|  - Communication (45%)
 | |
| 
 | |
|    Mailing list discussions on general design, fielding user
 | |
|    questions, diagnosing bug reports; reviewing, commenting on,
 | |
|    suggesting alternatives to, and rejecting patches.
 | |
| 
 | |
|  - Integration (50%)
 | |
| 
 | |
|    Applying new patches from the contributors while spotting and
 | |
|    correcting minor mistakes, shuffling the integration and
 | |
|    testing branches, pushing the results out, cutting the
 | |
|    releases, and making announcements.
 | |
| 
 | |
|  - Own development (5%)
 | |
| 
 | |
|    Scratching my own itch and sending proposed patch series out.
 | |
| 
 | |
| The Policy
 | |
| ----------
 | |
| 
 | |
| The policy on Integration is informally mentioned in "A Note
 | |
| from the maintainer" message, which is periodically posted to
 | |
| this mailing list after each feature release is made.
 | |
| 
 | |
|  - Feature releases are numbered as vX.Y.0 and are meant to
 | |
|    contain bugfixes and enhancements in any area, including
 | |
|    functionality, performance and usability, without regression.
 | |
| 
 | |
|  - One release cycle for a feature release is expected to last for
 | |
|    eight to ten weeks.
 | |
| 
 | |
|  - Maintenance releases are numbered as vX.Y.Z and are meant
 | |
|    to contain only bugfixes for the corresponding vX.Y.0 feature
 | |
|    release and earlier maintenance releases vX.Y.W (W < Z).
 | |
| 
 | |
|  - 'master' branch is used to prepare for the next feature
 | |
|    release. In other words, at some point, the tip of 'master'
 | |
|    branch is tagged with vX.Y.0.
 | |
| 
 | |
|  - 'maint' branch is used to prepare for the next maintenance
 | |
|    release.  After the feature release vX.Y.0 is made, the tip
 | |
|    of 'maint' branch is set to that release, and bugfixes will
 | |
|    accumulate on the branch, and at some point, the tip of the
 | |
|    branch is tagged with vX.Y.1, vX.Y.2, and so on.
 | |
| 
 | |
|  - 'next' branch is used to publish changes (both enhancements
 | |
|    and fixes) that (1) have worthwhile goal, (2) are in a fairly
 | |
|    good shape suitable for everyday use, (3) but have not yet
 | |
|    demonstrated to be regression free.  New changes are tested
 | |
|    in 'next' before merged to 'master'.
 | |
| 
 | |
|  - 'seen' branch is used to publish other proposed changes that do
 | |
|    not yet pass the criteria set for 'next'.
 | |
| 
 | |
|  - The tips of 'master' and 'maint' branches will not be rewound to
 | |
|    allow people to build their own customization on top of them.
 | |
|    Early in a new development cycle, 'next' is rewound to the tip of
 | |
|    'master' once, but otherwise it will not be rewound until the end
 | |
|    of the cycle.
 | |
| 
 | |
|  - Usually 'master' contains all of 'maint' and 'next' contains all
 | |
|    of 'master'.  'seen' contains all the topics merged to 'next', but
 | |
|    is rebuilt directly on 'master'.
 | |
| 
 | |
|  - The tip of 'master' is meant to be more stable than any
 | |
|    tagged releases, and the users are encouraged to follow it.
 | |
| 
 | |
|  - The 'next' branch is where new action takes place, and the
 | |
|    users are encouraged to test it so that regressions and bugs
 | |
|    are found before new topics are merged to 'master'.
 | |
| 
 | |
| Note that before v1.9.0 release, the version numbers used to be
 | |
| structured slightly differently.  vX.Y.Z were feature releases while
 | |
| vX.Y.Z.W were maintenance releases for vX.Y.Z.
 | |
| 
 | |
| 
 | |
| A Typical Git Day
 | |
| -----------------
 | |
| 
 | |
| A typical Git day for the maintainer implements the above policy
 | |
| by doing the following:
 | |
| 
 | |
|  - Scan mailing list.  Respond with review comments, suggestions
 | |
|    etc.  Kibitz.  Collect potentially usable patches from the
 | |
|    mailing list.  Patches about a single topic go to one mailbox (I
 | |
|    read my mail in Gnus, and type \C-o to save/append messages in
 | |
|    files in mbox format).
 | |
| 
 | |
|  - Write his own patches to address issues raised on the list but
 | |
|    nobody has stepped up solving.  Send it out just like other
 | |
|    contributors do, and pick them up just like patches from other
 | |
|    contributors (see above).
 | |
| 
 | |
|  - Review the patches in the saved mailboxes.  Edit proposed log
 | |
|    message for typofixes and clarifications, and add Acks
 | |
|    collected from the list.  Edit patch to incorporate "Oops,
 | |
|    that should have been like this" fixes from the discussion.
 | |
| 
 | |
|  - Classify the collected patches and handle 'master' and
 | |
|    'maint' updates:
 | |
| 
 | |
|    - Obviously correct fixes that pertain to the tip of 'maint'
 | |
|      are directly applied to 'maint'.
 | |
| 
 | |
|    - Obviously correct fixes that pertain to the tip of 'master'
 | |
|      are directly applied to 'master'.
 | |
| 
 | |
|    - Other topics are not handled in this step.
 | |
| 
 | |
|    This step is done with "git am".
 | |
| 
 | |
|      $ git checkout master    ;# or "git checkout maint"
 | |
|      $ git am -sc3 mailbox
 | |
|      $ make test
 | |
| 
 | |
|    In practice, almost no patch directly goes to 'master' or
 | |
|    'maint'.
 | |
| 
 | |
|  - Review the last issue of "What's cooking" message, review the
 | |
|    topics ready for merging (topic->master and topic->maint).  Use
 | |
|    "Meta/cook -w" script (where Meta/ contains a checkout of the
 | |
|    'todo' branch) to aid this step.
 | |
| 
 | |
|    And perform the merge.  Use "Meta/Reintegrate -e" script (see
 | |
|    later) to aid this step.
 | |
| 
 | |
|      $ Meta/cook -w last-issue-of-whats-cooking.mbox
 | |
| 
 | |
|      $ git checkout master    ;# or "git checkout maint"
 | |
|      $ echo ai/topic | Meta/Reintegrate -e ;# "git merge ai/topic"
 | |
|      $ git log -p ORIG_HEAD.. ;# final review
 | |
|      $ git diff ORIG_HEAD..   ;# final review
 | |
|      $ make test              ;# final review
 | |
| 
 | |
|  - Handle the remaining patches:
 | |
| 
 | |
|    - Anything unobvious that is applicable to 'master' (in other
 | |
|      words, does not depend on anything that is still in 'next'
 | |
|      and not in 'master') is applied to a new topic branch that
 | |
|      is forked from the tip of 'master' (or the last feature release,
 | |
|      which is a bit older than 'master').  This includes both
 | |
|      enhancements and unobvious fixes to 'master'.  A topic
 | |
|      branch is named as ai/topic where "ai" is two-letter string
 | |
|      named after author's initial and "topic" is a descriptive name
 | |
|      of the topic (in other words, "what's the series is about").
 | |
| 
 | |
|    - An unobvious fix meant for 'maint' is applied to a new
 | |
|      topic branch that is forked from the tip of 'maint' (or the
 | |
|      oldest and still relevant maintenance branch).  The
 | |
|      topic may be named as ai/maint-topic.
 | |
| 
 | |
|    - Changes that pertain to an existing topic are applied to
 | |
|      the branch, but:
 | |
| 
 | |
|      - obviously correct ones are applied first;
 | |
| 
 | |
|      - questionable ones are discarded or applied to near the tip;
 | |
| 
 | |
|    - Replacement patches to an existing topic are accepted only
 | |
|      for commits not in 'next'.
 | |
| 
 | |
|    The initial round is done with:
 | |
| 
 | |
|      $ git checkout ai/topic ;# or "git checkout -b ai/topic master"
 | |
|      $ git am -sc3 mailbox
 | |
| 
 | |
|    and replacing an existing topic with subsequent round is done with:
 | |
| 
 | |
|      $ git checkout master...ai/topic ;# try to reapply to the same base
 | |
|      $ git am -sc3 mailbox
 | |
| 
 | |
|    to prepare the new round on a detached HEAD, and then
 | |
| 
 | |
|      $ git range-diff @{-1}...
 | |
|      $ git diff @{-1}
 | |
| 
 | |
|    to double check what changed since the last round, and finally
 | |
| 
 | |
|      $ git checkout -B @{-1}
 | |
| 
 | |
|    to conclude (the last step is why a topic already in 'next' is
 | |
|    not replaced but updated incrementally).
 | |
| 
 | |
|    Whether it is the initial round or a subsequent round, the topic
 | |
|    may not build even in isolation, or may break the build when
 | |
|    merged to integration branches due to bugs.  There may already
 | |
|    be obvious and trivial improvements suggested on the list.  The
 | |
|    maintainer often adds an extra commit, with "SQUASH???" in its
 | |
|    title, to fix things up, before publishing the integration
 | |
|    branches to make it usable by other developers for testing.
 | |
|    These changes are what the maintainer is not 100% committed to
 | |
|    (trivial typofixes etc. are often squashed directly into the
 | |
|    patches that need fixing, without being applied as a separate
 | |
|    "SQUASH???" commit), so that they can be removed easily as needed.
 | |
| 
 | |
| 
 | |
|  - Merge maint to master as needed:
 | |
| 
 | |
|      $ git checkout master
 | |
|      $ git merge maint
 | |
|      $ make test
 | |
| 
 | |
|  - Merge master to next as needed:
 | |
| 
 | |
|      $ git checkout next
 | |
|      $ git merge master
 | |
|      $ make test
 | |
| 
 | |
|  - Review the last issue of "What's cooking" again and see if topics
 | |
|    that are ready to be merged to 'next' are still in good shape
 | |
|    (e.g. has there any new issue identified on the list with the
 | |
|    series?)
 | |
| 
 | |
|  - Prepare 'jch' branch, which is used to represent somewhere
 | |
|    between 'master' and 'seen' and often is slightly ahead of 'next'.
 | |
| 
 | |
|      $ Meta/Reintegrate master..seen >Meta/redo-jch.sh
 | |
| 
 | |
|    The result is a script that lists topics to be merged in order to
 | |
|    rebuild 'seen' as the input to Meta/Reintegrate script.  Remove
 | |
|    later topics that should not be in 'jch' yet.  Add a line that
 | |
|    consists of '### match next' before the name of the first topic
 | |
|    in the output that should be in 'jch' but not in 'next' yet.
 | |
| 
 | |
|  - Now we are ready to start merging topics to 'next'.  For each
 | |
|    branch whose tip is not merged to 'next', one of three things can
 | |
|    happen:
 | |
| 
 | |
|    - The commits are all next-worthy; merge the topic to next;
 | |
|    - The new parts are of mixed quality, but earlier ones are
 | |
|      next-worthy; merge the early parts to next;
 | |
|    - Nothing is next-worthy; do not do anything.
 | |
| 
 | |
|    This step is aided with Meta/redo-jch.sh script created earlier.
 | |
|    If a topic that was already in 'next' gained a patch, the script
 | |
|    would list it as "ai/topic~1".  To include the new patch to the
 | |
|    updated 'next', drop the "~1" part; to keep it excluded, do not
 | |
|    touch the line.  If a topic that was not in 'next' should be
 | |
|    merged to 'next', add it at the end of the list.  Then:
 | |
| 
 | |
|      $ git checkout -B jch master
 | |
|      $ Meta/redo-jch.sh -c1
 | |
| 
 | |
|    to rebuild the 'jch' branch from scratch.  "-c1" tells the script
 | |
|    to stop merging at the first line that begins with '###'
 | |
|    (i.e. the "### match next" line you added earlier).
 | |
| 
 | |
|    At this point, build-test the result.  It may reveal semantic
 | |
|    conflicts (e.g. a topic renamed a variable, another added a new
 | |
|    reference to the variable under its old name), in which case
 | |
|    prepare an appropriate merge-fix first (see appendix), and
 | |
|    rebuild the 'jch' branch from scratch, starting at the tip of
 | |
|    'master'.
 | |
| 
 | |
|    Then do the same to 'next'
 | |
| 
 | |
|      $ git checkout next
 | |
|      $ sh Meta/redo-jch.sh -c1 -e
 | |
| 
 | |
|    The "-e" option allows the merge message that comes from the
 | |
|    history of the topic and the comments in the "What's cooking" to
 | |
|    be edited.  The resulting tree should match 'jch' as the same set
 | |
|    of topics are merged on 'master'; otherwise there is a mismerge.
 | |
|    Investigate why and do not proceed until the mismerge is found
 | |
|    and rectified.
 | |
| 
 | |
|      $ git diff jch next
 | |
| 
 | |
|    When all is well, clean up the redo-jch.sh script with
 | |
| 
 | |
|      $ sh Meta/redo-jch.sh -u
 | |
| 
 | |
|    This removes topics listed in the script that have already been
 | |
|    merged to 'master'.  This may lose '### match next' marker;
 | |
|    add it again to the appropriate place when it happens.
 | |
| 
 | |
|  - Rebuild 'seen'.
 | |
| 
 | |
|      $ Meta/Reintegrate master..seen >Meta/redo-seen.sh
 | |
| 
 | |
|    Edit the result by adding new topics that are not still in 'seen'
 | |
|    in the script.  Then
 | |
| 
 | |
|      $ git checkout -B seen jch
 | |
|      $ sh Meta/redo-seen.sh
 | |
| 
 | |
|    When all is well, clean up the redo-seen.sh script with
 | |
| 
 | |
|      $ sh Meta/redo-seen.sh -u
 | |
| 
 | |
|    Double check by running
 | |
| 
 | |
|      $ git branch --no-merged seen
 | |
| 
 | |
|    to see there is no unexpected leftover topics.
 | |
| 
 | |
|    At this point, build-test the result for semantic conflicts, and
 | |
|    if there are, prepare an appropriate merge-fix first (see
 | |
|    appendix), and rebuild the 'seen' branch from scratch, starting at
 | |
|    the tip of 'jch'.
 | |
| 
 | |
|  - Update "What's cooking" message to review the updates to
 | |
|    existing topics, newly added topics and graduated topics.
 | |
| 
 | |
|    This step is helped with Meta/cook script.
 | |
| 
 | |
|      $ Meta/cook
 | |
| 
 | |
|    This script inspects the history between master..seen, finds tips
 | |
|    of topic branches, compares what it found with the current
 | |
|    contents in Meta/whats-cooking.txt, and updates that file.
 | |
|    Topics not listed in the file but are found in master..seen are
 | |
|    added to the "New topics" section, topics listed in the file that
 | |
|    are no longer found in master..seen are moved to the "Graduated to
 | |
|    master" section, and topics whose commits changed their states
 | |
|    (e.g. used to be only in 'seen', now merged to 'next') are updated
 | |
|    with change markers "<<" and ">>".
 | |
| 
 | |
|    Look for lines enclosed in "<<" and ">>"; they hold contents from
 | |
|    old file that are replaced by this integration round.  After
 | |
|    verifying them, remove the old part.  Review the description for
 | |
|    each topic and update its doneness and plan as needed.  To review
 | |
|    the updated plan, run
 | |
| 
 | |
|      $ Meta/cook -w
 | |
| 
 | |
|    which will pick up comments given to the topics, such as "Will
 | |
|    merge to 'next'", etc. (see Meta/cook script to learn what kind
 | |
|    of phrases are supported).
 | |
| 
 | |
|  - Compile, test and install all four (five) integration branches;
 | |
|    Meta/Dothem script may aid this step.
 | |
| 
 | |
|  - Format documentation if the 'master' branch was updated;
 | |
|    Meta/dodoc.sh script may aid this step.
 | |
| 
 | |
|  - Push the integration branches out to public places; Meta/pushall
 | |
|    script may aid this step.
 | |
| 
 | |
| Observations
 | |
| ------------
 | |
| 
 | |
| Some observations to be made.
 | |
| 
 | |
|  * Each topic is tested individually, and also together with other
 | |
|    topics cooking first in 'seen', then in 'jch' and then in 'next'.
 | |
|    Until it matures, no part of it is merged to 'master'.
 | |
| 
 | |
|  * A topic already in 'next' can get fixes while still in
 | |
|    'next'.  Such a topic will have many merges to 'next' (in
 | |
|    other words, "git log --first-parent next" will show many
 | |
|    "Merge branch 'ai/topic' to next" for the same topic.
 | |
| 
 | |
|  * An unobvious fix for 'maint' is cooked in 'next' and then
 | |
|    merged to 'master' to make extra sure it is Ok and then
 | |
|    merged to 'maint'.
 | |
| 
 | |
|  * Even when 'next' becomes empty (in other words, all topics
 | |
|    prove stable and are merged to 'master' and "git diff master
 | |
|    next" shows empty), it has tons of merge commits that will
 | |
|    never be in 'master'.
 | |
| 
 | |
|  * In principle, "git log --first-parent master..next" should
 | |
|    show nothing but merges (in practice, there are fixup commits
 | |
|    and reverts that are not merges).
 | |
| 
 | |
|  * Commits near the tip of a topic branch that are not in 'next'
 | |
|    are fair game to be discarded, replaced or rewritten.
 | |
|    Commits already merged to 'next' will not be.
 | |
| 
 | |
|  * Being in the 'next' branch is not a guarantee for a topic to
 | |
|    be included in the next feature release.  Being in the
 | |
|    'master' branch typically is.
 | |
| 
 | |
|  * Due to the nature of "SQUASH???" fix-ups, if the original author
 | |
|    agrees with the suggested changes, it is OK to squash them to
 | |
|    appropriate patches in the next round (when the suggested change
 | |
|    is small enough, the author should not even bother with
 | |
|    "Helped-by").  It is also OK to drop them from the next round
 | |
|    when the original author does not agree with the suggestion, but
 | |
|    the author is expected to say why somewhere in the discussion.
 | |
| 
 | |
| 
 | |
| Appendix
 | |
| --------
 | |
| 
 | |
| Preparing a "merge-fix"
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| A merge of two topics may not textually conflict but still have
 | |
| conflict at the semantic level. A classic example is for one topic
 | |
| to rename an variable and all its uses, while another topic adds a
 | |
| new use of the variable under its old name. When these two topics
 | |
| are merged together, the reference to the variable newly added by
 | |
| the latter topic will still use the old name in the result.
 | |
| 
 | |
| The Meta/Reintegrate script that is used by redo-jch and redo-seen
 | |
| scripts implements a crude but usable way to work this issue around.
 | |
| When the script merges branch $X, it checks if "refs/merge-fix/$X"
 | |
| exists, and if so, the effect of it is squashed into the result of
 | |
| the mechanical merge.  In other words,
 | |
| 
 | |
|      $ echo $X | Meta/Reintegrate
 | |
| 
 | |
| is roughly equivalent to this sequence:
 | |
| 
 | |
|      $ git merge --rerere-autoupdate $X
 | |
|      $ git commit
 | |
|      $ git cherry-pick -n refs/merge-fix/$X
 | |
|      $ git commit --amend
 | |
| 
 | |
| The goal of this "prepare a merge-fix" step is to come up with a
 | |
| commit that can be squashed into a result of mechanical merge to
 | |
| correct semantic conflicts.
 | |
| 
 | |
| After finding that the result of merging branch "ai/topic" to an
 | |
| integration branch had such a semantic conflict, say seen~4, check the
 | |
| problematic merge out on a detached HEAD, edit the working tree to
 | |
| fix the semantic conflict, and make a separate commit to record the
 | |
| fix-up:
 | |
| 
 | |
|      $ git checkout seen~4
 | |
|      $ git show -s --pretty=%s ;# double check
 | |
|      Merge branch 'ai/topic' to seen
 | |
|      $ edit
 | |
|      $ git commit -m 'merge-fix/ai/topic' -a
 | |
| 
 | |
| Then make a reference "refs/merge-fix/ai/topic" to point at this
 | |
| result:
 | |
| 
 | |
|      $ git update-ref refs/merge-fix/ai/topic HEAD
 | |
| 
 | |
| Then double check the result by asking Meta/Reintegrate to redo the
 | |
| merge:
 | |
| 
 | |
|      $ git checkout seen~5 ;# the parent of the problem merge
 | |
|      $ echo ai/topic | Meta/Reintegrate
 | |
|      $ git diff seen~4
 | |
| 
 | |
| This time, because you prepared refs/merge-fix/ai/topic, the
 | |
| resulting merge should have been tweaked to include the fix for the
 | |
| semantic conflict.
 | |
| 
 | |
| Note that this assumes that the order in which conflicting branches
 | |
| are merged does not change.  If the reason why merging ai/topic
 | |
| branch needs this merge-fix is because another branch merged earlier
 | |
| to the integration branch changed the underlying assumption ai/topic
 | |
| branch made (e.g. ai/topic branch added a site to refer to a
 | |
| variable, while the other branch renamed that variable and adjusted
 | |
| existing use sites), and if you changed redo-jch (or redo-seen) script
 | |
| to merge ai/topic branch before the other branch, then the above
 | |
| merge-fix should not be applied while merging ai/topic, but should
 | |
| instead be applied while merging the other branch.  You would need
 | |
| to move the fix to apply to the other branch, perhaps like this:
 | |
| 
 | |
|       $ mf=refs/merge-fix
 | |
|       $ git update-ref $mf/$the_other_branch $mf/ai/topic
 | |
|       $ git update-ref -d $mf/ai/topic
 |