-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 According to Eric Blake on 4/8/2009 7:19 AM: > OK, I'll take some time today to mock up an approach, taking notes of what > I did to make explaining it easier, and post the results to my clone at > http://repo.or.cz/w/bison/ericb.git for review. If you like how it looks, > we can then push it to savannah.
First, I made sure I was up-to-date, and created three tracking branches, one for each active upstream branch: $ git remote update ... $ git pull ... $ git branch * master $ git checkout -t origin/branch-2.4.2 -b branch-2.4.2 Branch branch-2.4.2 set up to track remote branch refs/remotes/origin/branch-2.4.2. Switched to a new branch "branch-2.4.2" $ git checkout -t origin/branch-2.5 -b branch-2.5 Branch branch-2.5 set up to track remote branch refs/remotes/origin/branch-2.5. Switched to a new branch "branch-2.5" Next, the workflow that lends itself best to topic branches is to prepare your patch for the oldest branch that needs the patch, then make sure that all newer branches include the tip of the older branch any time you make a release. Try 'man gitworkflows' for more details. The idea is that the topic will go beyond the tip of the older branch, where you can merge it into the newer branch and test it out. When it is finally ready, you merge it into the older branch, but since the newer branch already includes the topic, you have succeeded in merging the older branch back into the newer branch. But to date, we haven't done that. So we need a one-time merge to establish that each older branch is a subset of the newer; here, the merge --strategy=ours says to make the merge but change no file contents (otherwise we would get merge conflicts). This is a one-time operation, if we subsequently follow the branch paradigm. $ git merge --strategy=ours branch-2.4.2 Already up-to-date. $ git checkout master Switched to branch "master" $ git merge --strategy=ours branch-2.5 Merge made by ours. Now, time to apply the patch series of my proposed patch. The original patch was just one commit, but I'm adding an additional commit to update the autoconf submodule to the latest, to show how a multi-commit sequence is easier to merge (one operation) than to cherry-pick or rebase (N operations for a topic of N commits). Note that I am creating a topic branch, but will not be merging it in at this time. $ git checkout -b m4-update Switched to a new branch "m4-update" $ git am bison.patch Applying: Work around autoconf 2.63b bug in testsuite. $ cd submodules/autoconf $ git pull origin master ... $ cd - $ git submodule summary | head -n1 * submodules/autoconf fb069dd...34163e5 (68): $ # edit ChangeLog $ git commit -a [m4-update]: created a731a4b: "submodules: update to latest" 2 files changed, 6 insertions(+), 1 deletions(-) Oops - notice that I branched off of master (well, actually I did it on for purposes of this exposition); but since we want the patch to apply even to 2.4.2, now is the time to rebase it to the oldest branch. Since I haven't pushed the topic branch anywhere yet, I'm free to rewrite it at will. This is where git-merge-changelog comes in handy. $ git rebase --onto branch-2.4.2 master First, rewinding head to replay your work on top of it... Applying: Work around autoconf 2.63b bug in testsuite. error: patch failed: ChangeLog:1 error: ChangeLog: patch does not apply Using index info to reconstruct a base tree... Falling back to patching base and 3-way merge... Auto-merging ChangeLog Auto-merging tests/output.at Applying: submodules: update to latest error: submodules/autoconf: does not exist in index Using index info to reconstruct a base tree... Falling back to patching base and 3-way merge... fatal: cannot read object 34163e58d4112ac86640a26fc8bb7bc7a69c9846 'submodules/autoconf': It is a submodule! Failed to merge in the changes. Patch failed at 0002. Ah - only branch-2.5 and master have autoconf.git as a submodule. So the best thing in this case will be doing the submodule update in a separate topic branch; here, I actually needed a cherry-pick, because I'm separating the commit I created earlier into a new topic. $ git rebase --skip HEAD is now at ab3a683 Work around autoconf 2.63b bug in testsuite. Nothing to do. $ git describe v2.4.1-20-gab3a683 $ git checkout -b autoconf-submodule branch-2.5 M submodules/autoconf Switched to a new branch "autoconf-submodule" $ git cherry-pick a731a4b Finished one cherry-pick. [autoconf-submodule]: created f03ce98: "submodules: update to latest" 2 files changed, 6 insertions(+), 1 deletions(-) Now for the fun of merging. I'll merge master first, even though my m4-update topic is hanging off branch-2.4.2, and my autoconf-submodule topic off branch-2.5. Notice that by merging two independent topic branches, I only have to push one branch (master) to a public repository, rather than each topic branch. There's discussion on the git list that 'git checkout' should handle submodules better, but my version of git doesn't quite manage. $ git checkout master M submodules/autoconf Switched to branch "master" $ git merge m4-update git merge aut Auto-merging ChangeLog Auto-merging tests/output.at Merge made by recursive. ChangeLog | 6 ++++++ tests/output.at | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) $ git merge autoconf-submodule Auto-merging ChangeLog Merge made by recursive. ChangeLog | 5 +++++ submodules/autoconf | 2 +- 2 files changed, 6 insertions(+), 1 deletions(-) And since I like how it behaved on master (the m4-update topic doesn't need any more commits to make it usable), I can now graduate it to older branches. I even did the merge in a different order, just to show that things still work. $ git merge autoconf-submodule Updating 4ecd368..f03ce98 Fast forward ChangeLog | 5 +++++ submodules/autoconf | 2 +- 2 files changed, 6 insertions(+), 1 deletions(-) $ git merge m4-update Auto-merging ChangeLog Merge made by recursive. ChangeLog | 6 ++++++ tests/output.at | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) $ git checkout branch-2.4.2 Switched to branch "branch-2.4.2" $ git merge m4-update Updating ecd1b61..ab3a683 Fast forward ChangeLog | 6 ++++++ tests/output.at | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) As long as merges were done consistently, I don't have to merge up. But since I merged on branch-2.5 in a different order than on branch, I get a slight rewrite during the merge (basically, one ChangeLog entry swapped order, to match the order it was written in branch-2.5). Unless you frequently merge multiple branches, you won't see this as often (and if you want, I can clean things up to do this in the same order before pushing anything to savannah). $ git checkout branch-2.5 Switched to branch "branch-2.5" Your branch is ahead of 'origin/branch-2.5' by 3 commits. $ git merge branch-2.4.2 Already up-to-date. $ git checkout master Switched to branch "master" Your branch is ahead of 'origin/master' by 58 commits. $ git merge branch-2.5 Auto-merging ChangeLog Merge made by recursive. ChangeLog | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) Now to publish my work (I used 'git remote' to create repo as a shortcut to git://repo.or.cz/bison/ericb.git). I intentionally omit my topic branches, because you can still get to their contents by looking at the appropriate parents of each merge commit. $ git push repo branch-2.4.2 branch-2.5 master Counting objects: 37, done. Compressing objects: 100% (24/24), done. Writing objects: 100% (25/25), 3.17 KiB, done. Total 25 (delta 17), reused 0 (delta 0) To [email protected]:/srv/git/bison/ericb.git 8dce387..b20614e master -> master * [new branch] branch-2.4.2 -> branch-2.4.2 * [new branch] branch-2.5 -> branch-2.5 And what's more, I could even delete my topic branches if I wanted, now that their contents have been folded into the mainline integration branches. At this point, you may want to use gitk to view my master branch, to see how all this merging looks graphically. - -- Don't work too hard, make some time for fun as well! Eric Blake [email protected] -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAknddmoACgkQ84KuGfSFAYCU5gCePDM7UnuljkR4jvuHONKta0fX N+YAn1tbTLX2WPSCk6CfOUqoJD82yEev =zK85 -----END PGP SIGNATURE-----
