@matheusbsbs / matheus-bagliano / commits / 90d1c08efc
Fork 0

Documentation: new upstream rebase recovery section in git-rebase

Document how to recover if the upstream that you pull from has rebased the branches you depend your work on. Hopefully this can also serve as a warning to potential rebasers. Signed-off-by: Thomas Rast <trast@student.ethz.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Thomas Rast committed Sep 13, 2008 at 18:11 UTC 90d1c08efcf9c688df207588d9b72178524a62b6
1 file changed +125 -5
Documentation/git-rebase.txt
+125 -5
@@ -257,11 +257,10 @@ include::merge-strategies.txt[]
257
258 NOTES
259 -----
260 -When you rebase a branch, you are changing its history in a way that
261 -will cause problems for anyone who already has a copy of the branch
262 -in their repository and tries to pull updates from you. You should
263 -understand the implications of using 'git-rebase' on a repository that
264 -you share.
260 +
261 +You should understand the implications of using 'git-rebase' on a
262 +repository that you share. See also RECOVERING FROM UPSTREAM REBASE
263 +below.
264
265 When the git-rebase command is run, it will first execute a "pre-rebase"
266 hook if one exists. You can use this hook to do sanity checks and
@@ -396,6 +395,127 @@ consistent (they compile, pass the testsuite, etc.) you should use
395 after each commit, test, and amend the commit if fixes are necessary.
396
397
398 +RECOVERING FROM UPSTREAM REBASE
399 +-------------------------------
400 +
401 +Rebasing (or any other form of rewriting) a branch that others have
402 +based work on is a bad idea: anyone downstream of it is forced to
403 +manually fix their history. This section explains how to do the fix
404 +from the downstream's point of view. The real fix, however, would be
405 +to avoid rebasing the upstream in the first place.
406 +
407 +To illustrate, suppose you are in a situation where someone develops a
408 +'subsystem' branch, and you are working on a 'topic' that is dependent
409 +on this 'subsystem'. You might end up with a history like the
410 +following:
411 +
412 +------------
413 + o---o---o---o---o---o---o---o---o master
414 + \
415 + o---o---o---o---o subsystem
416 + \
417 + *---*---* topic
418 +------------
419 +
420 +If 'subsystem' is rebased against 'master', the following happens:
421 +
422 +------------
423 + o---o---o---o---o---o---o---o master
424 + \ \
425 + o---o---o---o---o o'--o'--o'--o'--o' subsystem
426 + \
427 + *---*---* topic
428 +------------
429 +
430 +If you now continue development as usual, and eventually merge 'topic'
431 +to 'subsystem', the commits from 'subsystem' will remain duplicated forever:
432 +
433 +------------
434 + o---o---o---o---o---o---o---o master
435 + \ \
436 + o---o---o---o---o o'--o'--o'--o'--o'--M subsystem
437 + \ /
438 + *---*---*-..........-*--* topic
439 +------------
440 +
441 +Such duplicates are generally frowned upon because they clutter up
442 +history, making it harder to follow. To clean things up, you need to
443 +transplant the commits on 'topic' to the new 'subsystem' tip, i.e.,
444 +rebase 'topic'. This becomes a ripple effect: anyone downstream from
445 +'topic' is forced to rebase too, and so on!
446 +
447 +There are two kinds of fixes, discussed in the following subsections:
448 +
449 +Easy case: The changes are literally the same.::
450 +
451 + This happens if the 'subsystem' rebase was a simple rebase and
452 + had no conflicts.
453 +
454 +Hard case: The changes are not the same.::
455 +
456 + This happens if the 'subsystem' rebase had conflicts, or used
457 + `\--interactive` to omit, edit, or squash commits; or if the
458 + upstream used one of `commit \--amend`, `reset`, or
459 + `filter-branch`.
460 +
461 +
462 +The easy case
463 +~~~~~~~~~~~~~
464 +
465 +Only works if the changes (patch IDs based on the diff contents) on
466 +'subsystem' are literally the same before and after the rebase
467 +'subsystem' did.
468 +
469 +In that case, the fix is easy because 'git-rebase' knows to skip
470 +changes that are already present in the new upstream. So if you say
471 +(assuming you're on 'topic')
472 +------------
473 + $ git rebase subsystem
474 +------------
475 +you will end up with the fixed history
476 +------------
477 + o---o---o---o---o---o---o---o master
478 + \
479 + o'--o'--o'--o'--o' subsystem
480 + \
481 + *---*---* topic
482 +------------
483 +
484 +
485 +The hard case
486 +~~~~~~~~~~~~~
487 +
488 +Things get more complicated if the 'subsystem' changes do not exactly
489 +correspond to the ones before the rebase.
490 +
491 +NOTE: While an "easy case recovery" sometimes appears to be successful
492 + even in the hard case, it may have unintended consequences. For
493 + example, a commit that was removed via `git rebase
494 + \--interactive` will be **resurrected**!
495 +
496 +The idea is to manually tell 'git-rebase' "where the old 'subsystem'
497 +ended and your 'topic' began", that is, what the old merge-base
498 +between them was. You will have to find a way to name the last commit
499 +of the old 'subsystem', for example:
500 +
501 +* With the 'subsystem' reflog: after 'git-fetch', the old tip of
502 + 'subsystem' is at `subsystem@\{1}`. Subsequent fetches will
503 + increase the number. (See linkgit:git-reflog[1].)
504 +
505 +* Relative to the tip of 'topic': knowing that your 'topic' has three
506 + commits, the old tip of 'subsystem' must be `topic~3`.
507 +
508 +You can then transplant the old `subsystem..topic` to the new tip by
509 +saying (for the reflog case, and assuming you are on 'topic' already):
510 +------------
511 + $ git rebase --onto subsystem subsystem@{1}
512 +------------
513 +
514 +The ripple effect of a "hard case" recovery is especially bad:
515 +'everyone' downstream from 'topic' will now have to perform a "hard
516 +case" recovery too!
517 +
518 +
519 Authors
520 ------
521 Written by Junio C Hamano <gitster@pobox.com> and