| 1 | From: Junio C Hamano <gitster@pobox.com> |
| 2 | Date: Wed, 21 Nov 2007 16:32:55 -0800 |
| 3 | Subject: Addendum to "MaintNotes" |
| 4 | Abstract: Imagine that Git development is racing along as usual, when our friendly |
| 5 | neighborhood maintainer is struck down by a wayward bus. Out of the |
| 6 | hordes of suckers (loyal developers), you have been tricked (chosen) to |
| 7 | step up as the new maintainer. This howto will show you "how to" do it. |
| 8 | Content-type: text/asciidoc |
| 9 | |
| 10 | How to maintain Git |
| 11 | =================== |
| 12 | |
| 13 | Activities |
| 14 | ---------- |
| 15 | |
| 16 | The maintainer's Git time is spent on three activities. |
| 17 | |
| 18 | - Communication (45%) |
| 19 | |
| 20 | Mailing list discussions on general design, fielding user |
| 21 | questions, diagnosing bug reports; reviewing, commenting on, |
| 22 | suggesting alternatives to, and rejecting patches. |
| 23 | |
| 24 | - Integration (50%) |
| 25 | |
| 26 | Applying new patches from the contributors while spotting and |
| 27 | correcting minor mistakes, shuffling the integration and |
| 28 | testing branches, pushing the results out, cutting the |
| 29 | releases, and making announcements. |
| 30 | |
| 31 | - Own development (5%) |
| 32 | |
| 33 | Scratching my own itch and sending proposed patch series out. |
| 34 | |
| 35 | The Policy |
| 36 | ---------- |
| 37 | |
| 38 | The policy on Integration is informally mentioned in "A Note |
| 39 | from the maintainer" message, which is periodically posted to |
| 40 | the mailing list after each feature release is made: |
| 41 | |
| 42 | - Feature releases are numbered as vX.Y.0 and are meant to |
| 43 | contain bugfixes and enhancements in any area, including |
| 44 | functionality, performance and usability, without regression. |
| 45 | |
| 46 | - Maintenance releases are numbered as vX.Y.Z (0 < Z) and are meant |
| 47 | to contain only bugfixes for the corresponding vX.Y.0 feature |
| 48 | release and earlier maintenance releases vX.Y.W (W < Z). |
| 49 | |
| 50 | - The 'master' branch is used to prepare for the next feature |
| 51 | release. In other words, at some point, the tip of 'master' |
| 52 | branch is tagged as vX.(Y+1).0, when vX.Y.0 is the latest |
| 53 | feature release. |
| 54 | |
| 55 | - 'maint' branch is used to prepare for the next maintenance |
| 56 | release. After the feature release vX.Y.0 is made, the tip |
| 57 | of 'maint' branch is set to that release, and bugfixes will |
| 58 | accumulate on the branch, and at some point, the tip of the |
| 59 | branch is tagged with vX.Y.1, vX.Y.2, and so on. |
| 60 | |
| 61 | - 'next' branch is used to publish changes (both enhancements |
| 62 | and fixes) that (1) have worthwhile goal, (2) are in a fairly |
| 63 | good shape suitable for everyday use, (3) but have not yet |
| 64 | demonstrated to be regression free. Reviews from contributors on |
| 65 | the mailing list help to make the determination. After a topic |
| 66 | is merged to 'next', it is tested for at least 7 calendar days |
| 67 | before getting merged to 'master'. |
| 68 | |
| 69 | - 'seen' branch is used to publish other proposed changes that do |
| 70 | not yet pass the criteria set for 'next' (see above), but there |
| 71 | is no promise that 'seen' will contain everything. A topic that |
| 72 | had no reviewer reaction may not be picked up. |
| 73 | |
| 74 | - A new topic will first get merged to 'seen', unless it is |
| 75 | trivially correct and clearly urgent, in which case it may be |
| 76 | directly merged to 'next' or even to 'master'. |
| 77 | |
| 78 | - If a topic that was picked up to 'seen' becomes and stays |
| 79 | inactive for 3 calendar weeks without having seen a clear |
| 80 | consensus that it is good enough to be moved to 'next', the |
| 81 | topic may be discarded from 'seen'. Interested parties are |
| 82 | still free to revive the topic. For the purpose of this |
| 83 | guideline, the definition of being "inactive" is that nobody |
| 84 | has discussed the topic, no new iteration of the topic was |
| 85 | posted, and no responses to the review comments were given. |
| 86 | |
| 87 | - The tips of 'master' and 'maint' branches will not be rewound to |
| 88 | allow people to build their own customization on top of them. |
| 89 | Early in a new development cycle, 'next' is rewound to the tip of |
| 90 | 'master' once, but otherwise it will not be rewound until the end |
| 91 | of the cycle. |
| 92 | |
| 93 | - Usually 'master' contains all of 'maint' and 'next' contains all |
| 94 | of 'master'. 'seen' contains all the topics merged to 'next', but |
| 95 | is rebuilt directly on 'master'. |
| 96 | |
| 97 | - The tip of 'master' is meant to be more stable than any |
| 98 | tagged releases, and the users are encouraged to follow it. |
| 99 | |
| 100 | - The 'next' branch is where new action takes place, and the |
| 101 | users are encouraged to test it so that regressions and bugs |
| 102 | are found before new topics are merged to 'master'. |
| 103 | |
| 104 | - When a problem is found in a topic in 'next', the topic is marked |
| 105 | not to be merged to 'master'. Follow-up patches are discussed on |
| 106 | the mailing list and applied to the topic after being reviewed and |
| 107 | then the topic is merged (again) to 'next'. After going through |
| 108 | the usual testing in 'next', the entire (fixed) topic is merged |
| 109 | to 'master'. |
| 110 | |
| 111 | - One release cycle for a feature release is expected to last for |
| 112 | eight to ten weeks. A few "release candidate" releases are |
| 113 | expected to be tagged about a week apart before the final |
| 114 | release, and a "preview" release is tagged about a week before |
| 115 | the first release candidate gets tagged. |
| 116 | |
| 117 | - After the preview release is tagged, topics that were well |
| 118 | reviewed may be merged to 'master' before spending the usual 7 |
| 119 | calendar days in 'next', with the expectation that any bugs in |
| 120 | them can be caught and fixed in the release candidates before |
| 121 | the final release. |
| 122 | |
| 123 | - After the first release candidate is tagged, the contributors are |
| 124 | strongly encouraged to focus on finding and fixing new regressions |
| 125 | introduced during the cycle, over addressing old bugs and any new |
| 126 | features. Topics stop getting merged down from 'next' to 'master', |
| 127 | and new topics stop getting merged to 'next'. Unless they are fixes |
| 128 | to new regressions in the cycle, that is. |
| 129 | |
| 130 | - Soon after a feature release is made, the tip of 'maint' gets |
| 131 | fast-forwarded to point at the release. Topics that have been |
| 132 | kept in 'next' are merged down to 'master' and a new development |
| 133 | cycle starts. |
| 134 | |
| 135 | |
| 136 | Note that before v1.9.0 release, the version numbers used to be |
| 137 | structured slightly differently. vX.Y.Z were feature releases while |
| 138 | vX.Y.Z.W were maintenance releases for vX.Y.Z. |
| 139 | |
| 140 | Because most of the lines of code in Git are written by individual |
| 141 | contributors, and contributions come in the form of e-mailed patches |
| 142 | published on the mailing list, the project maintains a mapping from |
| 143 | individual commits to the Message-Id of the e-mail that resulted in |
| 144 | the commit, to help tracking the origin of the changes. The notes |
| 145 | in "refs/notes/amlog" are used for this purpose, and are published |
| 146 | along with the broken-out branches to the maintainer's repository. |
| 147 | |
| 148 | A Typical Git Day |
| 149 | ----------------- |
| 150 | |
| 151 | A typical Git day for the maintainer implements the above policy |
| 152 | by doing the following: |
| 153 | |
| 154 | - Scan mailing list. Respond with review comments, suggestions |
| 155 | etc. Kibitz. Collect potentially usable patches from the |
| 156 | mailing list. Patches about a single topic go to one mailbox (I |
| 157 | read my mail in Gnus, and type \C-o to save/append messages in |
| 158 | files in mbox format). |
| 159 | |
| 160 | - Write his own patches to address issues raised on the list but |
| 161 | nobody has stepped up to solve. Send it out just like other |
| 162 | contributors do, and pick them up just like patches from other |
| 163 | contributors (see above). |
| 164 | |
| 165 | - Review the patches in the saved mailboxes. Edit proposed log |
| 166 | message for typofixes and clarifications, and add Acks |
| 167 | collected from the list. Edit patch to incorporate "Oops, |
| 168 | that should have been like this" fixes from the discussion. |
| 169 | |
| 170 | - Classify the collected patches and handle 'master' and |
| 171 | 'maint' updates: |
| 172 | |
| 173 | - Obviously correct fixes that pertain to the tip of 'maint' |
| 174 | are directly applied to 'maint'. |
| 175 | |
| 176 | - Obviously correct fixes that pertain to the tip of 'master' |
| 177 | are directly applied to 'master'. |
| 178 | |
| 179 | - Other topics are not handled in this step. |
| 180 | |
| 181 | This step is done with "git am". |
| 182 | |
| 183 | $ git checkout master ;# or "git checkout maint" |
| 184 | $ git am -sc3 mailbox |
| 185 | $ make test |
| 186 | |
| 187 | In practice, almost no patch directly goes to 'master' or |
| 188 | 'maint'. |
| 189 | |
| 190 | Applying the e-mailed patches using "git am" automatically records |
| 191 | the mappings from 'Message-Id' to the applied commit in the "amlog" |
| 192 | notes. Periodically check that this is working with "git show -s |
| 193 | --notes=amlog $commit". |
| 194 | |
| 195 | This mapping is maintained with the aid of the "post-applypatch" |
| 196 | hook found in the 'todo' branch. That hook should be installed |
| 197 | before applying patches. It is also helpful to carry forward any |
| 198 | relevant amlog entries when rebasing, so the following config may |
| 199 | be useful: |
| 200 | |
| 201 | [notes] |
| 202 | rewriteRef = refs/notes/amlog |
| 203 | |
| 204 | Avoid "cherry-pick", as it does not propagate notes by design. Use |
| 205 | either "git commit --amend" or "git rebase" to make corrections to |
| 206 | an existing commit, even for a single-patch topic. |
| 207 | |
| 208 | Make sure that a push refspec for 'refs/notes/amlog' is in the |
| 209 | remote configuration for publishing repositories. A few sample |
| 210 | configurations look like the following: |
| 211 | |
| 212 | [remote "github"] |
| 213 | url = https://github.com/gitster/git |
| 214 | pushurl = github.com:gitster/git.git |
| 215 | mirror |
| 216 | |
| 217 | [remote "github2"] |
| 218 | url = https://github.com/git/git |
| 219 | fetch = +refs/heads/*:refs/remotes/github2/* |
| 220 | pushurl = github.com:git/git.git |
| 221 | push = refs/heads/maint:refs/heads/maint |
| 222 | push = refs/heads/master:refs/heads/master |
| 223 | push = refs/heads/next:refs/heads/next |
| 224 | push = +refs/heads/seen:refs/heads/seen |
| 225 | push = +refs/notes/amlog |
| 226 | |
| 227 | - Review the last issue of "What's cooking" message, review the |
| 228 | topics ready for merging (topic->master and topic->maint). Use |
| 229 | "Meta/cook -w" script (where Meta/ contains a checkout of the |
| 230 | 'todo' branch) to aid this step. |
| 231 | |
| 232 | And perform the merge. Use "Meta/Reintegrate -e" script (see |
| 233 | later) to aid this step. |
| 234 | |
| 235 | $ Meta/cook -w last-issue-of-whats-cooking.mbox |
| 236 | |
| 237 | $ git checkout master ;# or "git checkout maint" |
| 238 | $ echo ai/topic | Meta/Reintegrate -e ;# "git merge ai/topic" |
| 239 | $ git log -p ORIG_HEAD.. ;# final review |
| 240 | $ git diff ORIG_HEAD.. ;# final review |
| 241 | $ make test ;# final review |
| 242 | |
| 243 | If the tip of 'master' is updated, also generate the preformatted |
| 244 | documentation and push the out result to git-htmldocs and |
| 245 | git-manpages repositories. |
| 246 | |
| 247 | - Handle the remaining patches: |
| 248 | |
| 249 | - Anything unobvious that is applicable to 'master' (in other |
| 250 | words, does not depend on anything that is still in 'next' |
| 251 | and not in 'master') is applied to a new topic branch that |
| 252 | is forked from the tip of 'master' (or the last feature release, |
| 253 | which is a bit older than 'master'). This includes both |
| 254 | enhancements and unobvious fixes to 'master'. A topic |
| 255 | branch is named as ai/topic where "ai" is two-letter string |
| 256 | named after author's initial and "topic" is a descriptive name |
| 257 | of the topic (in other words, "what's the series is about"). |
| 258 | |
| 259 | - An unobvious fix meant for 'maint' is applied to a new |
| 260 | topic branch that is forked from the tip of 'maint' (or the |
| 261 | oldest and still relevant maintenance branch). The |
| 262 | topic may be named as ai/maint-topic. |
| 263 | |
| 264 | - Changes that pertain to an existing topic are applied to |
| 265 | the branch, but: |
| 266 | |
| 267 | - obviously correct ones are applied first; |
| 268 | |
| 269 | - questionable ones are discarded or applied to near the tip; |
| 270 | |
| 271 | - Replacement patches to an existing topic are accepted only |
| 272 | for commits not in 'next'. |
| 273 | |
| 274 | The initial round is done with: |
| 275 | |
| 276 | $ git checkout ai/topic ;# or "git checkout -b ai/topic master" |
| 277 | $ git am -sc3 --whitespace=warn mailbox |
| 278 | |
| 279 | and replacing an existing topic with subsequent round is done with: |
| 280 | |
| 281 | $ git checkout master...ai/topic ;# try to reapply to the same base |
| 282 | $ git am -sc3 --whitespace=warn mailbox |
| 283 | |
| 284 | to prepare the new round on a detached HEAD, and then |
| 285 | |
| 286 | $ git range-diff @{-1}... |
| 287 | $ git diff @{-1} |
| 288 | |
| 289 | to double check what changed since the last round, and finally |
| 290 | |
| 291 | $ git checkout -B @{-1} |
| 292 | |
| 293 | to conclude (the last step is why a topic already in 'next' is |
| 294 | not replaced but updated incrementally). |
| 295 | |
| 296 | Whether it is the initial round or a subsequent round, the topic |
| 297 | may not build even in isolation, or may break the build when |
| 298 | merged to integration branches due to bugs. There may already |
| 299 | be obvious and trivial improvements suggested on the list. The |
| 300 | maintainer often adds an extra commit, with "SQUASH???" in its |
| 301 | title, to fix things up, before publishing the integration |
| 302 | branches to make it usable by other developers for testing. |
| 303 | These changes are what the maintainer is not 100% committed to |
| 304 | (trivial typofixes etc. are often squashed directly into the |
| 305 | patches that need fixing, without being applied as a separate |
| 306 | "SQUASH???" commit), so that they can be removed easily as needed. |
| 307 | The expectation is that the original author will make corrections |
| 308 | in a reroll. |
| 309 | |
| 310 | - By now, new topic branches are created and existing topic |
| 311 | branches are updated. The integration branches 'next', 'jch', |
| 312 | and 'seen' need to be updated to contain them. |
| 313 | |
| 314 | - If there are topics that have been merged to 'master' and should |
| 315 | be merged to 'maint', merge them to 'maint', and update the |
| 316 | release notes to the next maintenance release. |
| 317 | |
| 318 | - Review the latest issue of "What's cooking" again. Are topics |
| 319 | that have been sufficiently long in 'next' ready to be merged to |
| 320 | 'master'? Are topics we saw earlier and are in 'seen' now got |
| 321 | positive reviews and are ready to be merged to 'next'? |
| 322 | |
| 323 | - If there are topics that have been cooking in 'next' long enough |
| 324 | and should be merged to 'master', merge them to 'master', and |
| 325 | update the release notes to the next feature release. |
| 326 | |
| 327 | - If there were patches directly made on 'maint', merge 'maint' to |
| 328 | 'master'; make sure that the result is what you want. |
| 329 | |
| 330 | $ git checkout master |
| 331 | $ git merge -m "Sync with 'maint'" --no-log maint |
| 332 | $ git log -p --first-parent ORIG_HEAD.. |
| 333 | $ make test |
| 334 | |
| 335 | - Prepare to update the 'jch' branch, which is used to represent |
| 336 | somewhere between 'master' and 'seen' and often is slightly ahead |
| 337 | of 'next', and the 'seen' branch, which is used to hold the rest. |
| 338 | |
| 339 | $ Meta/Reintegrate master..jch >Meta/redo-jch.sh |
| 340 | |
| 341 | The result is a script that lists topics to be merged in order to |
| 342 | rebuild the current 'jch'. Do the same for 'seen'. |
| 343 | |
| 344 | - Review the Meta/redo-jch.sh and Meta/redo-seen.sh scripts. The |
| 345 | former should have a line '### match next'---the idea is that |
| 346 | merging the topics listed before the line on top of 'master' |
| 347 | should result in a tree identical to that of 'next'. |
| 348 | |
| 349 | - As newly created topics are usually merged near the tip of |
| 350 | 'seen', add them to the end of the Meta/redo-seen.sh script. |
| 351 | Among the topics that were in 'seen', there may be ones that |
| 352 | are not quite ready for 'next' but are getting there. Move |
| 353 | them from Meta/redo-seen.sh to the end of Meta/redo-jch.sh. |
| 354 | The expectation is that you'd use 'jch' as your daily driver |
| 355 | as the first guinea pig, so you should choose carefully. |
| 356 | |
| 357 | - Now we are ready to start rebuilding 'jch' and merging topics to |
| 358 | 'next'. For each branch whose tip is not merged to 'next', one |
| 359 | of three things can happen: |
| 360 | |
| 361 | - The commits are all next-worthy; merge the topic to next; |
| 362 | - The new parts are of mixed quality, but earlier ones are |
| 363 | next-worthy; merge the early parts to next; |
| 364 | - Nothing is next-worthy; do not do anything. |
| 365 | |
| 366 | This step is aided with Meta/redo-jch.sh script created earlier. |
| 367 | If a topic that was already in 'next' gained a patch, the script |
| 368 | would list it as "ai/topic~1". To include the new patch to the |
| 369 | updated 'next', drop the "~1" part; to keep it excluded, do not |
| 370 | touch the line. |
| 371 | |
| 372 | If a topic that was not in 'next' should be merged to 'next', add |
| 373 | it before the '### match next' line. Then: |
| 374 | |
| 375 | $ git checkout --detach master |
| 376 | $ sh Meta/redo-jch.sh -c1 |
| 377 | |
| 378 | to rebuild the 'jch' branch from scratch. "-c1" tells the script |
| 379 | to stop merging at the first line that begins with '###' |
| 380 | (i.e. the "### match next" line you added earlier). |
| 381 | |
| 382 | At this point, build-test the result. It may reveal semantic |
| 383 | conflicts (e.g. a topic renamed a variable, another added a new |
| 384 | reference to the variable under its old name), in which case |
| 385 | prepare an appropriate merge-fix first (see appendix), and |
| 386 | rebuild the 'jch' branch from scratch, starting at the tip of |
| 387 | 'master', this time without using "-c1" to merge all topics. |
| 388 | |
| 389 | Then do the same to 'next'. |
| 390 | |
| 391 | $ git checkout next |
| 392 | $ sh Meta/redo-jch.sh -c1 -e |
| 393 | |
| 394 | The "-e" option allows the merge message that comes from the |
| 395 | history of the topic and the comments in the "What's cooking" to |
| 396 | be edited. The resulting tree should match 'jch^{/^### match next'}' |
| 397 | as the same set of topics are merged on 'master'; otherwise there |
| 398 | is a mismerge. Investigate why and do not proceed until the mismerge |
| 399 | is found and rectified. |
| 400 | |
| 401 | If 'master' was updated before you started redoing 'next', then |
| 402 | |
| 403 | $ git diff 'jch^{/^### match next}' next |
| 404 | |
| 405 | would show differences that went into 'master' (which 'jch' has, |
| 406 | but 'next' does not yet---often it is updates to the release |
| 407 | notes). Merge 'master' back to 'next' if that is the case. |
| 408 | |
| 409 | $ git merge -m "Sync with 'master'" --no-log master |
| 410 | |
| 411 | When all is well, clean up the redo-jch.sh script with |
| 412 | |
| 413 | $ sh Meta/redo-jch.sh -u |
| 414 | |
| 415 | This removes topics listed in the script that have already been |
| 416 | merged to 'master'. This may lose '### match next' marker; |
| 417 | add it again to the appropriate place when it happens. |
| 418 | |
| 419 | - Rebuild 'seen' on top of 'jch'. |
| 420 | |
| 421 | $ git checkout -B seen jch |
| 422 | $ sh Meta/redo-seen.sh |
| 423 | |
| 424 | When all is well, clean up the redo-seen.sh script with |
| 425 | |
| 426 | $ sh Meta/redo-seen.sh -u |
| 427 | |
| 428 | Double check by running |
| 429 | |
| 430 | $ git branch --no-merged seen '??/*' |
| 431 | |
| 432 | to see there is no unexpected leftover topics. |
| 433 | |
| 434 | At this point, build-test the result for semantic conflicts, and |
| 435 | if there are, prepare an appropriate merge-fix first (see |
| 436 | appendix), and rebuild the 'seen' branch from scratch, starting at |
| 437 | the tip of 'jch'. |
| 438 | |
| 439 | - Update "What's cooking" message to review the updates to |
| 440 | existing topics, newly added topics and graduated topics. |
| 441 | |
| 442 | This step is helped with Meta/cook script. |
| 443 | |
| 444 | $ Meta/cook |
| 445 | |
| 446 | This script inspects the history between master..seen, finds tips |
| 447 | of topic branches, compares what it found with the current |
| 448 | contents in Meta/whats-cooking.txt, and updates that file. |
| 449 | Topics not listed in the file but are found in master..seen are |
| 450 | added to the "New topics" section, topics listed in the file that |
| 451 | are no longer found in master..seen are moved to the "Graduated to |
| 452 | master" section, and topics whose commits changed their states |
| 453 | (e.g. used to be only in 'seen', now merged to 'next') are updated |
| 454 | with change markers "<<" and ">>". |
| 455 | |
| 456 | Look for lines enclosed in "<<" and ">>"; they hold contents from |
| 457 | old file that are replaced by this integration round. After |
| 458 | verifying them, remove the old part. Review the description for |
| 459 | each topic and update its doneness and plan as needed. To review |
| 460 | the updated plan, run |
| 461 | |
| 462 | $ Meta/cook -w |
| 463 | |
| 464 | which will pick up comments given to the topics, such as "Will |
| 465 | merge to 'next'", etc. (see Meta/cook script to learn what kind |
| 466 | of phrases are supported). |
| 467 | |
| 468 | - Compile, test and install all four (five) integration branches; |
| 469 | Meta/Dothem script may aid this step. |
| 470 | |
| 471 | - Format documentation if the 'master' branch was updated; |
| 472 | Meta/dodoc.sh script may aid this step. |
| 473 | |
| 474 | - Push the integration branches out to public places; Meta/pushall |
| 475 | script may aid this step. |
| 476 | |
| 477 | Observations |
| 478 | ------------ |
| 479 | |
| 480 | Some observations to be made. |
| 481 | |
| 482 | * Each topic is tested individually, and also together with other |
| 483 | topics cooking first in 'seen', then in 'jch' and then in 'next'. |
| 484 | Until it matures, no part of it is merged to 'master'. |
| 485 | |
| 486 | * A topic already in 'next' can get fixes while still in |
| 487 | 'next'. Such a topic will have many merges to 'next' (in |
| 488 | other words, "git log --first-parent next" will show many |
| 489 | "Merge branch 'ai/topic' to next" for the same topic. |
| 490 | |
| 491 | * An unobvious fix for 'maint' is cooked in 'next' and then |
| 492 | merged to 'master' to make extra sure it is Ok and then |
| 493 | merged to 'maint'. |
| 494 | |
| 495 | * Even when 'next' becomes empty (in other words, all topics |
| 496 | prove stable and are merged to 'master' and "git diff master |
| 497 | next" shows empty), it has tons of merge commits that will |
| 498 | never be in 'master'. |
| 499 | |
| 500 | * In principle, "git log --first-parent master..next" should |
| 501 | show nothing but merges (in practice, there are fixup commits |
| 502 | and reverts that are not merges). |
| 503 | |
| 504 | * Commits near the tip of a topic branch that are not in 'next' |
| 505 | are fair game to be discarded, replaced or rewritten. |
| 506 | Commits already merged to 'next' will not be. |
| 507 | |
| 508 | * Being in the 'next' branch is not a guarantee for a topic to |
| 509 | be included in the next feature release. Being in the |
| 510 | 'master' branch typically is. |
| 511 | |
| 512 | * Due to the nature of "SQUASH???" fix-ups, if the original author |
| 513 | agrees with the suggested changes, it is OK to squash them to |
| 514 | appropriate patches in the next round (when the suggested change |
| 515 | is small enough, the author should not even bother with |
| 516 | "Helped-by"). It is also OK to drop them from the next round |
| 517 | when the original author does not agree with the suggestion, but |
| 518 | the author is expected to say why somewhere in the discussion. |
| 519 | |
| 520 | |
| 521 | Appendix |
| 522 | -------- |
| 523 | |
| 524 | Preparing a "merge-fix" |
| 525 | ~~~~~~~~~~~~~~~~~~~~~~~ |
| 526 | |
| 527 | A merge of two topics may not textually conflict but still have |
| 528 | conflict at the semantic level. A classic example is for one topic |
| 529 | to rename a variable and all its uses, while another topic adds a |
| 530 | new use of the variable under its old name. When these two topics |
| 531 | are merged together, the reference to the variable newly added by |
| 532 | the latter topic will still use the old name in the result. |
| 533 | |
| 534 | The Meta/Reintegrate script that is used by redo-jch and redo-seen |
| 535 | scripts implements a crude but usable way to work around this issue. |
| 536 | When the script merges branch $X, it checks if "refs/merge-fix/$X" |
| 537 | exists, and if so, the effect of it is squashed into the result of |
| 538 | the mechanical merge. In other words, |
| 539 | |
| 540 | $ echo $X | Meta/Reintegrate |
| 541 | |
| 542 | is roughly equivalent to this sequence: |
| 543 | |
| 544 | $ git merge --rerere-autoupdate $X |
| 545 | $ git commit |
| 546 | $ git cherry-pick -n refs/merge-fix/$X |
| 547 | $ git commit --amend |
| 548 | |
| 549 | The goal of this "prepare a merge-fix" step is to come up with a |
| 550 | commit that can be squashed into a result of mechanical merge to |
| 551 | correct semantic conflicts. |
| 552 | |
| 553 | After finding that the result of merging branch "ai/topic" to an |
| 554 | integration branch had such a semantic conflict, say seen~4, check the |
| 555 | problematic merge out on a detached HEAD, edit the working tree to |
| 556 | fix the semantic conflict, and make a separate commit to record the |
| 557 | fix-up: |
| 558 | |
| 559 | $ git checkout seen~4 |
| 560 | $ git show -s --pretty=%s ;# double check |
| 561 | Merge branch 'ai/topic' to seen |
| 562 | $ edit |
| 563 | $ git commit -m 'merge-fix/ai/topic' -a |
| 564 | |
| 565 | Then make a reference "refs/merge-fix/ai/topic" to point at this |
| 566 | result: |
| 567 | |
| 568 | $ git update-ref refs/merge-fix/ai/topic HEAD |
| 569 | |
| 570 | Then double check the result by asking Meta/Reintegrate to redo the |
| 571 | merge: |
| 572 | |
| 573 | $ git checkout seen~5 ;# the parent of the problem merge |
| 574 | $ echo ai/topic | Meta/Reintegrate |
| 575 | $ git diff seen~4 |
| 576 | |
| 577 | This time, because you prepared refs/merge-fix/ai/topic, the |
| 578 | resulting merge should have been tweaked to include the fix for the |
| 579 | semantic conflict. |
| 580 | |
| 581 | Note that this assumes that the order in which conflicting branches |
| 582 | are merged does not change. If the reason why merging ai/topic |
| 583 | branch needs this merge-fix is because another branch merged earlier |
| 584 | to the integration branch changed the underlying assumption ai/topic |
| 585 | branch made (e.g. ai/topic branch added a site to refer to a |
| 586 | variable, while the other branch renamed that variable and adjusted |
| 587 | existing use sites), and if you changed redo-jch (or redo-seen) script |
| 588 | to merge ai/topic branch before the other branch, then the above |
| 589 | merge-fix should not be applied while merging ai/topic, but should |
| 590 | instead be applied while merging the other branch. You would need |
| 591 | to move the fix to apply to the other branch, perhaps like this: |
| 592 | |
| 593 | $ mf=refs/merge-fix |
| 594 | $ git update-ref $mf/$the_other_branch $mf/ai/topic |
| 595 | $ git update-ref -d $mf/ai/topic |