git/list[1] front-page[2] threads[3] people[4] search[5] about
 

equal-tree-merges as way to make rebases fast-forward-able

From
BLBernhard R. Link <brlink@debian.org>
Date
Nov 30, 2009, 14:43 UTC
Message-ID
<cover.1259524136.git.brlink@debian.org>

The itch this idea is supposed to scratch is the problem that a rebase or a amended commit is no longer a fast-forward, so cannot be easily pulled. While this is not a problem in most workflows, as one can either merge or keep everything private and rebase until published, it would be nice to have a way for cases in between, where both a clean presentable commit order is to be maintained and people (or yourself from different repositories) should be able to easily upgrade to newer versions without an error-prone not-fast-forward.

My idea to solve this is combining both histories, the rebased/revised history and the actualy history, marking with some "equal-tree-merge" the point where they have the same result. The following mails show some patches to implement this by means of a merge where all parents have the same tree and some special casing when encountering such a thing. This has the advantage that older git version will just see strange merges and may present both histories, but otherwise just work.

Example 1:

Let's assume you maintain such a regularily-rebased branch that you want to be able to publish (or pull from other repositories for example on your laptop):

o=m=o=o=master
   \
    a=b=c=d=e=feature
with this patch you can do "git rebase -eqt master" and get:
              a'=b'=c'=d'=e'=feature'=eqt
             /                       /
o=m=o=o=master--------              /
   \                  \            /
    a=b=c=d=e=feature--merge-------
i.e: the new feature branch has both histories:
  - "feature'" where everything is cleanly rebased and in a form where
               format-patch is suitable to send it upstream
  - "merge" which is both a descendant from feature (so one can see what
    changed since that time and can just pull when one had had cloned feature)
Example 2:
Let's assume you have a feature branch like
o=master
   \
    a=b=c=d=e=f

Assume you just commited "f" which fixes a bug introduced by "b". Now you of course do not want to send it that way upstream (as it will make reviewing harder, may force people bisecting to skip some versions every time they hit this region and so on), so you want to bisect -i and squash "f" into "b".

o=master
   \
    a=b+f=c'=d'=e'

But if you had already cloned at state "d" to your laptop (or made a backup of that branch at some server, or published it for use of some collegues) it will not be a fast-forward, so you have to be very carefull to not accidentially lose a commit that is already there.

So with this patches you can do "git rebase -i --eqt" and squash f into b and get:

o=master
   \
    a=b=c=d=e=f---
     \            \
      b+f=c'=d'=e'=eqt

which means that you can just pull from your laptop and get the new head as fast-forward, but still have a proper history ready for submitting.

The only downsize of this approach is that an unpatched/old git of course does not know about that it can just choose one of both histories but think it has to look at both, so git-format-patch will return patches multiple times and git-rebase will also try to apply both branches, which the patched version no longer does, only showing the 'presentable' in this case.

Those patches are a bit rough and mostly intended to show how it could work and to allow experimenting with it. I think the biggest thing still missing (apart from documentation, error handling, better commit messages) is making git bisect take advantage of this and only looking at the nice branch.

Bernhard R. Link (7):
  add new command git equal-tree-marker
  add option to only visit the first parent of a equal tree merge
  format-patch defaults to --first-equal-tree-only
  support equal tree merges in interactive rebase
  make rebase -m equal tree marker aware
  add support for creating equal tree markers after rebase
  add support for creating equal tree markers to rebase -i
 .gitignore                 |    1 +
 Makefile                   |    1 +
 builtin-log.c              |    1 +
 git-equal-tree-marker.sh   |   50 ++++++++++++++++++++++++++++++++++++++
 git-rebase--interactive.sh |   33 +++++++++++++++++++++++++
 git-rebase.sh              |   35 ++++++++++++++++++++++++--
 revision.c                 |   57 +++++++++++++++++++++++++++++++++++++-------
 revision.h                 |    1 +
 8 files changed, 167 insertions(+), 12 deletions(-)
 create mode 100644 git-equal-tree-marker.sh
Hochachtungsvoll,
	Bernhard R. Link
-- 
"Never contain programs so few bugs, as when no debugging tools are available!"
	Niklaus Wirth
Next: Bernhard R. Link
Message 1 of 29 in “equal-tree-merges as way to make rebases fast-forward-able”
  1. Bernhard R. LinkNov 30, 2009
  2. 1/7 add new command git equal-tree-markerBernhard R. Link, Nov 30, 2009
  3. Michael J GruberNov 30, 2009
  4. 2/7 add option to only visit the first parent of a equal tree mergeBernhard R. Link, Nov 30, 2009
  5. 3/7 format-patch defaults to --first-equal-tree-onlyBernhard R. Link, Nov 30, 2009
  6. 4/7 support equal tree merges in interactive rebaseBernhard R. Link, Nov 30, 2009
  7. 5/7 make rebase -m equal tree marker awareBernhard R. Link, Nov 30, 2009
  8. 6/7 add support for creating equal tree markers after rebaseBernhard R. Link, Nov 30, 2009
  9. 7/7 add support for creating equal tree markers to rebase -iBernhard R. Link, Nov 30, 2009
  10. Sverre RabbelierNov 30, 2009
  11. Paolo BonziniNov 30, 2009
  12. Bernhard R. LinkNov 30, 2009
  13. Michael J GruberNov 30, 2009
  14. Michael J GruberNov 30, 2009
  15. Bernhard R. LinkNov 30, 2009
  16. Johannes SchindelinNov 30, 2009
  17. Junio C HamanoNov 30, 2009
  18. Bernhard R. LinkNov 30, 2009
  19. Junio C HamanoDec 1, 2009
  20. Johannes SixtNov 30, 2009
  21. Junio C HamanoNov 30, 2009
  22. Nanako ShiraishiNov 30, 2009
  23. Junio C HamanoDec 1, 2009
  24. git-merge: a deprecation notice of the ancient command line syntaxJunio C Hamano, Dec 1, 2009
  25. Nicolas PitreDec 1, 2009
  26. Junio C HamanoDec 1, 2009
  27. Nanako ShiraishiDec 2, 2009
  28. Junio C HamanoDec 2, 2009
  29. Michael HaggertyDec 1, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.