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

Re: Gerrit, GitButler, and Jujutsu projects collaborating on change-id commit footer

From
Remo Senekowitsch <remo@buenzli.dev>
Date
Apr 7, 2025, 22:51 UTC
Message-ID
<D90RWL4FEBQA.1UNOR59T3U98R@buenzli.dev>
In-Reply-To
<xmqq4iyzn0vn.fsf@gitster.g>
On Mon Apr 7, 2025 at 10:59 PM CEST, Junio C Hamano wrote:
Show 10 quoted lines
> Martin von Zweigbergk <martinvonz@google.com> writes:
>
>> For example, it enables
>> `git rebase main <change ID>; git switch <change ID>` without
>> requiring the user to look up the hash of the rewritten commit.
>
> I do not quite see why this can be listed even as an advantage,
> unless you are going to allow end users to name the changes, instead
> of using auto-generated impossible-to-remember hexadecimal string
> (perhaps prefixed with a single "I" or something).

Since the change-id will use a "reverse-hex" alphabet (z-k instead of 0-f), prefixing an "I" won't be necessary for disambiguation.

In the case of Jujutsu, there is a configurable "immutable revset", which represents the idea that people usually don't want to force-push over the master branch. If the user specifies a change-id prefix that's ambiguous, but only one of the commits it could refer to is "mutable", that one takes precedence. So in practice, the commits one is currently working on can be identified with 1-3 characters, which fit comfortably into short-term memory.

While that feature isn't implemented in Git (yet), it shows how such a usage pattern can be very ergonomic.

Show 18 quoted lines
>> If the change id also transferred between repos and preserved by
>> a forge (such as Gerrit), it enables the change id to be used to
>> identify a code review.
>
> People often talk about rebasing and rewriting in the context of
> discussing "change IDs", and for 80% of the use cases where a simple
> single-commit topic is involved, it would perfectly work fine.
> After making a new commit C0 on top of 'main', updating 'main' with
> others' changes, and then rebasing that C0 on top of updated 'main'
> to produce C1, you would expect that C0 and C1 are moral equivalents
> so it is natural that you wish there is a name to give to these
> moral equivalents.
>
> But stepping back a bit, if they are not just moral equivalents but
> record identical changes that are so same that an earlier review of
> C0 makes it unnecessary to review C1, why are you even rebasing in
> the first place?  Just merging C0 to the updated 'main' would retain
> the earlier review made on C0 and things should merge just fine.

Some people (including me) like to / are used to rebasing often and keeping a linear history on master as possible. I'm not aware that there's anything wrong with that.

In practice, I don't think this will cause any problems. The change-id will help the code review tool to identify the commits as morally equivalent. After checking that the other review-relevant data (patch, message, author...) is identical, the review tool may choose to mark the commit C1 as "already reviewed" without any user intervention.

And if the data has somehow changed, only the interdiff of that can be shown for review, which is precisely the kind of benefit we're aiming for with this header. It has been pointed out that git-range-diff can do this in a limited fashion already, which we can hopefully expand upon.

Show 23 quoted lines
> I have more problems with the remaining 20% use case, where you need
> to deal with multiple commits.
>
> Perhaps your initial changeset is a single commit C0 that is so
> large and does too many things at once, and reviewers would
> naturally advise you to split things up.  You'll come up with a
> series of commits, C1_0 and C1_1.  The net effect of applying these
> two patches may be the same as applying the original C0, but each of
> them is more cleanly separated to address one issue at a time, and
> the explanation given in the proposed log message more clearly
> describes the issue each of them addresses.  Now you gave a change ID
> to C0, and want to somehow relate C1_0 and C1_1 to the original C0.
> Which one gets the same change ID?  Earlier one?  The last one?
> Both gets the same change ID?
>
> Or your initial changeset is a two-commit series, C0_0 and C0_1, but
> reviewers find that each one of them alone is not complete, and
> because the issue addressed by these two is small and isolated
> enough, you are advised to make them into a single commit C1.  Did
> you start with two change IDs for these two original commits?  If
> so, whose change ID the updated commit C1 inherit?  Or does C1 have
> two change IDs now?  Or did you start with a single change ID
> assigned to both of these two original commits?

These are good descriptions of realistic scenarios. At a high level, I'd say change-ids don't help much with these problems. But that's OK, they don't need to solve all problems to be worthwhile.

A commit only ever has one change-id. (Other headers may be useful, but they should have another name and should be disussed separately IMO.)

In both of the described scenarios, it doesn't matter which one inherits the previous one. When a commit is split into two, the one that inherits the change-id will show up in review tools with half of its patch deleted, the other commit will show up as new. When two commits are combined into one, any one of the change-ids is inherited. Review tools will show the patch from the commit the ID was inherited from as preserved (maybe even hidden) while the patches from the other commits will show up as added. If they were previously reviewed, those reviews will be "lost".

So, while these scenarios are not ideal and somehow ambiguous, the ambiguity doesn't present any real problems in practice.

More importantly, I disagree with the 80%-20% split between these scenarios. There is another one that comes up a lot, and that scenario is the one that benefits the most from change-ids. Namely, when multiple commits are carried together as a patchset. These commits can split out into little subtrees that are constantly rebased to keep up with upstream, while the commits are amended, reworded and so on. They can sometimes be reviewed as a whole, where people are generally looking at all commits at once. But they can also represent dependencies between entirely different features. For example, bugfixes will often be at the base of this tree / patchset, while features that depend on it fan out from there. Here is where the change-id shines: As commits are amended, reordered, rebased and reworded, their evolution can be trivially tracked. There are discussions around the topic of "stacked PRs", which is basically this exact scenario, just managed in a specific way.

I find myself working this way a lot.
> Quite frankly, I think the concept of "change ID" is nice but it is
> not mechanically trustable.  Recording them in the trailers is fine,
> but I somehow feel that they have a clear-cut semantics everybody
> can agree on to deserve to be in the header part of commit objects.

I think the concrete examples above show that while change-ids don't solve all version control problems, these remaining problems don't diminish the value of change-ids either. I also don't see any potential for different tools in the ecosystem to disagree about the semantics so profoundly that interoperability would be hampered.

Remo
Previous: Toon ClaesNext: Junio C Hamano
Message 84 of 118 in “Gerrit, GitButler, and Jujutsu projects collaborating on change-id commit footer”
  1. Martin von ZweigbergkApr 2, 2025
  2. Remo SenekowitschApr 2, 2025
  3. Konstantin RyabitsevApr 2, 2025
  4. Konstantin RyabitsevApr 2, 2025
  5. Martin von ZweigbergkApr 2, 2025
  6. Patrick SteinhardtApr 3, 2025
  7. Remo SenekowitschApr 3, 2025
  8. Patrick SteinhardtApr 3, 2025
  9. Elijah NewrenApr 3, 2025
  10. Remo SenekowitschApr 3, 2025
  11. Elijah NewrenApr 3, 2025
  12. Martin von ZweigbergkApr 3, 2025
  13. Patrick SteinhardtApr 4, 2025
  14. Elijah NewrenApr 3, 2025
  15. Remo SenekowitschApr 3, 2025
  16. Kane YorkApr 3, 2025
  17. Elijah NewrenApr 4, 2025
  18. Elijah NewrenApr 4, 2025
  19. Martin von ZweigbergkApr 4, 2025
  20. Nico WilliamsApr 4, 2025
  21. Elijah NewrenApr 4, 2025
  22. Martin von ZweigbergkApr 4, 2025
  23. Patrick SteinhardtApr 4, 2025
  24. Theodore Ts'oApr 3, 2025
  25. Remo SenekowitschApr 3, 2025
  26. Theodore Ts'oApr 5, 2025
  27. Nico WilliamsApr 3, 2025
  28. Remo SenekowitschApr 3, 2025
  29. Martin von ZweigbergkApr 3, 2025
  30. Nico WilliamsApr 3, 2025
  31. Martin von ZweigbergkApr 3, 2025
  32. Elijah NewrenApr 4, 2025
  33. Nico WilliamsApr 4, 2025
  34. Martin von ZweigbergkApr 4, 2025
  35. Nico WilliamsApr 4, 2025
  36. Patrick SteinhardtApr 4, 2025
  37. Nico WilliamsApr 4, 2025
  38. Patrick SteinhardtApr 7, 2025
  39. Junio C HamanoApr 7, 2025
  40. Nico WilliamsApr 7, 2025
  41. Theodore Ts'oApr 8, 2025
  42. Nico WilliamsApr 8, 2025
  43. Theodore Ts'oApr 9, 2025
  44. Junio C HamanoApr 9, 2025
  45. Nico WilliamsApr 9, 2025
  46. Junio C HamanoApr 10, 2025
  47. Martin von ZweigbergkApr 10, 2025
  48. Semantics of change IDs (Re: Gerrit, GitButler, and Jujutsu projects collaborating on change-id commit footer)Nico Williams, Apr 9, 2025
  49. Junio C HamanoApr 9, 2025
  50. Nico WilliamsApr 9, 2025
  51. Eric SunshineApr 9, 2025
  52. Nico WilliamsApr 9, 2025
  53. Theodore Ts'oApr 10, 2025
  54. Junio C HamanoApr 10, 2025
  55. Theodore Ts'oApr 11, 2025
  56. Konstantin RyabitsevApr 11, 2025
  57. Junio C HamanoApr 11, 2025
  58. Theodore Ts'oApr 12, 2025
  59. Junio C HamanoApr 14, 2025
  60. Remo SenekowitschApr 15, 2025
  61. Junio C HamanoApr 16, 2025
  62. Jacob KellerApr 16, 2025
  63. Jacob KellerApr 15, 2025
  64. D. Ben KnobleApr 14, 2025
  65. Nico WilliamsApr 14, 2025
  66. Jacob KellerApr 15, 2025
  67. Remo SenekowitschApr 16, 2025
  68. D. Ben KnobleApr 22, 2025
  69. Remo SenekowitschApr 22, 2025
  70. Junio C HamanoApr 22, 2025
  71. Remo SenekowitschApr 22, 2025
  72. Nico WilliamsApr 22, 2025
  73. Remo SenekowitschApr 22, 2025
  74. Nico WilliamsApr 23, 2025
  75. Remo SenekowitschApr 23, 2025
  76. Nico WilliamsApr 23, 2025
  77. Junio C HamanoApr 22, 2025
  78. Nico WilliamsApr 23, 2025
  79. Nico WilliamsApr 23, 2025
  80. Martin von ZweigbergkApr 23, 2025
  81. Junio C HamanoApr 23, 2025
  82. Martin von ZweigbergkApr 23, 2025
  83. Toon ClaesJun 6, 2025
  84. Remo SenekowitschApr 7, 2025
  85. Junio C HamanoApr 8, 2025
  86. Martin von ZweigbergkApr 8, 2025
  87. Junio C HamanoApr 8, 2025
  88. Phillip WoodApr 8, 2025
  89. Nico WilliamsApr 8, 2025
  90. Junio C HamanoApr 12, 2025
  91. Jacob KellerApr 16, 2025
  92. Kristoffer HaugsbakkMay 14, 2025
  93. Junio C HamanoApr 8, 2025
  94. Askar SafinAug 19, 2025
  95. Ben KnobleAug 19, 2025
  96. Remo SenekowitschApr 4, 2025
  97. Nico WilliamsApr 4, 2025
  98. Remo SenekowitschApr 4, 2025
  99. Nico WilliamsApr 4, 2025
  100. Remo SenekowitschApr 23, 2025
  101. Nico WilliamsApr 23, 2025
  102. How GitLab does/doesn't need change IDs (was Re: Semantics of change IDs)Toon Claes, Apr 23, 2025
  103. Nico WilliamsApr 23, 2025
  104. D. Ben KnobleMay 10, 2025
  105. D. Ben KnobleMay 10, 2025
  106. Martin von ZweigbergkMay 10, 2025
  107. Junio C HamanoMay 12, 2025
  108. Martin von ZweigbergkMay 12, 2025
  109. Junio C HamanoMay 14, 2025
  110. Oswald BuddenhagenMay 15, 2025
  111. Jacob KellerMay 15, 2025
  112. Junio C HamanoMay 15, 2025
  113. Nico WilliamsMay 15, 2025
  114. Martin von ZweigbergkMay 12, 2025
  115. brian m. carlsonMay 12, 2025
  116. Toon ClaesJun 6, 2025
  117. Junio C HamanoJun 6, 2025
  118. D. Ben KnobleMay 13, 2025

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.