* Git Evolve @ 2018-09-29 23:00 Stefan Xenos 2018-09-30 0:55 ` Junio C Hamano ` (2 more replies) 0 siblings, 3 replies; 13+ messages in thread From: Stefan Xenos @ 2018-09-29 23:00 UTC (permalink / raw) To: git Hello, List! I'm interested in porting something like Mercurial's evolve command to Git. I'll be following up with a formal proposal shortly, but before I do I thought I'd introduce myself to the list and find out if anyone else is interested in this topic. What is the evolve command? Imagine you have three dependent changes up for review and you receive feedback that requires editing all three changes. While you're editing one, more feedback arrives on one of the others. What do you do? The evolve command is a convenient way to work with chains of commits that are under review. Whenever you rebase or amend a commit, the repository remembers that the old commit is obsolete and has been replaced by the new one. Then, at some point in the future, you can run "git evolve" and the correct sequence of rebases will occur in the correct order such that no commit has an obsolete parent. Part of making the "evolve" command work involves tracking the edits to a commit over time, which could provide a lot of other benefits: - Systems like gerrit would no longer need to rely on "change-id" tags in commit comments to associate commits with the change that they edit, since git itself would have that information. - You could directly view the history of a commit over time (ie: the sequence of amends and rebases that occurred with that commit, orthogonal to the history of the branch it is on). If you've used mercurial, this would be a git equivalent to "hg obslog". If you've used gerrit, this would be like the gerrit "change log" but it would work for all commits and work offline. - You can easily list all the changes that you have as works-in progress. If you've used gerrit, this would be an offline equivalent to the gerrit dashboard. - You could choose to share the history of a commit with others, or collaborate on and merge different variants of the same change. Some information about Mercurial's evolve command can be found here: https://www.mercurial-scm.org/doc/evolution/ Other similar technologies: rebase -i can be used to solve the same problem, but you can't easily switch tasks midway through an interactive rebase or have more than one interactive rebase going on at the same time. It also can't handle the case where you have multiple changes sharing the same parent that needs to be rebased and won't let you collaborate with others on resolving a complicated interactive rebase. patch queues (topgit, stgit, quilt) address a very similar problem, however since they're built on top of git rather than integrated with it, most of them end up managing extra state that can get easily damaged whenever you run a native git command that doesn't know about the patch queue. Most of them also have various workflow problems that aren't present in hg evolve. Is anyone else interested in this? Please email me directly or on this list. Let's chat: I want to make sure that whatever we come up with is at least as good as any similar technology that has come before. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Git Evolve 2018-09-29 23:00 Git Evolve Stefan Xenos @ 2018-09-30 0:55 ` Junio C Hamano 2018-09-30 20:17 ` Stefan Xenos 2018-10-04 16:05 ` Jakub Narebski 2018-10-01 12:37 ` Derrick Stolee 2018-10-02 1:23 ` Taylor Blau 2 siblings, 2 replies; 13+ messages in thread From: Junio C Hamano @ 2018-09-30 0:55 UTC (permalink / raw) To: Stefan Xenos; +Cc: git Stefan Xenos <sxenos@google.com> writes: > What is the evolve command? > ... > - Systems like gerrit would no longer need to rely on "change-id" tags > in commit comments to associate commits with the change that they > edit, since git itself would have that information. > ... > Is anyone else interested in this? Please email me directly or on this > list. Let's chat: I want to make sure that whatever we come up with is > at least as good as any similar technology that has come before. As you listed in the related technologies section, I think the underlying machinery that supports "rebase -i", especially with the recent addition of redoing the existing merges (i.e. "rebase -i -r"), may be enough to rewrite the histories that were built on top of a commit that has been obsoleted by amending. I would imagine that the main design effort you would need to make is to figure out a good way to (1) keep track of which commits are obsoleted by which other ones [*1*], and (2) to figure out what histories are still to be rebuilt in what order on top of what commit efficiently. Once these are done, you should be able to write out the sequence of instructions to feed the same sequencer machinery used by the "rebase -i" command. [Side note] *1* It is very desirable to keep track of the evolution of a change without polluting the commit object with things like Change-Id: and other cruft, either in the body or in the header. If we lose the Change-Id: footer without adding any new cruft in the commit object header, that would be a great success. It would be a failure if we end up touching the object header. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Git Evolve 2018-09-30 0:55 ` Junio C Hamano @ 2018-09-30 20:17 ` Stefan Xenos 2018-10-04 16:05 ` Jakub Narebski 1 sibling, 0 replies; 13+ messages in thread From: Stefan Xenos @ 2018-09-30 20:17 UTC (permalink / raw) To: Junio C Hamano; +Cc: git > If we lose the Change-Id: footer without adding any new cruft in the > commit object header, that would be a great success. It would > be a failure if we end up touching the object header. Yes, I was thinking along the same lines. If obsolescence graph is stored as part of the commit header, it would get unconditionally shared whenever that commit is pushed, and I would consider it a desirable property if users could choose whether to push just a commit or a the obsolescence graph that contains the commit. Sometimes the reason you're amending a commit may be because the original contained content that shouldn't be pushed. Putting it in the header would also either cause it to get retained forever by git gc or create a situation where we permit dangling references - and neither seem desirable to me. It would be nice if users could retain the obsolescence graph for stuff a user is actively working on, but we could discard it (with 0 cost) for commits they're done with or were never interested in editing. On Sat, Sep 29, 2018 at 5:55 PM, Junio C Hamano <gitster@pobox.com> wrote: > Stefan Xenos <sxenos@google.com> writes: > >> What is the evolve command? >> ... >> - Systems like gerrit would no longer need to rely on "change-id" tags >> in commit comments to associate commits with the change that they >> edit, since git itself would have that information. >> ... >> Is anyone else interested in this? Please email me directly or on this >> list. Let's chat: I want to make sure that whatever we come up with is >> at least as good as any similar technology that has come before. > > As you listed in the related technologies section, I think the > underlying machinery that supports "rebase -i", especially with the > recent addition of redoing the existing merges (i.e. "rebase -i > -r"), may be enough to rewrite the histories that were built on top > of a commit that has been obsoleted by amending. > > I would imagine that the main design effort you would need to make > is to figure out a good way to > > (1) keep track of which commits are obsoleted by which other ones > [*1*], and > > (2) to figure out what histories are still to be rebuilt in what > order on top of what commit efficiently. > > Once these are done, you should be able to write out the sequence of > instructions to feed the same sequencer machinery used by the > "rebase -i" command. > > [Side note] > > *1* It is very desirable to keep track of the evolution of a change > without polluting the commit object with things like Change-Id: > and other cruft, either in the body or in the header. If we > lose the Change-Id: footer without adding any new cruft in the > commit object header, that would be a great success. It would > be a failure if we end up touching the object header. > > > > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Git Evolve 2018-09-30 0:55 ` Junio C Hamano 2018-09-30 20:17 ` Stefan Xenos @ 2018-10-04 16:05 ` Jakub Narebski 2018-10-04 17:29 ` Stefan Xenos 1 sibling, 1 reply; 13+ messages in thread From: Jakub Narebski @ 2018-10-04 16:05 UTC (permalink / raw) To: Junio C Hamano; +Cc: Stefan Xenos, git Junio C Hamano <gitster@pobox.com> writes: > Stefan Xenos <sxenos@google.com> writes: > >> What is the evolve command? >> ... >> - Systems like gerrit would no longer need to rely on "change-id" tags >> in commit comments to associate commits with the change that they >> edit, since git itself would have that information. >> ... >> Is anyone else interested in this? Please email me directly or on this >> list. Let's chat: I want to make sure that whatever we come up with is >> at least as good as any similar technology that has come before. > > As you listed in the related technologies section, I think the > underlying machinery that supports "rebase -i", especially with the > recent addition of redoing the existing merges (i.e. "rebase -i > -r"), may be enough to rewrite the histories that were built on top > of a commit that has been obsoleted by amending. > > I would imagine that the main design effort you would need to make > is to figure out a good way to > > (1) keep track of which commits are obsoleted by which other ones > [*1*], and > > (2) to figure out what histories are still to be rebuilt in what > order on top of what commit efficiently. > > Once these are done, you should be able to write out the sequence of > instructions to feed the same sequencer machinery used by the > "rebase -i" command. Well, that assumes that "rebase -i" can correctly recreate merges, if needed. > [Side note] > > *1* It is very desirable to keep track of the evolution of a change > without polluting the commit object with things like Change-Id: > and other cruft, either in the body or in the header. If we > lose the Change-Id: footer without adding any new cruft in the > commit object header, that would be a great success. It would > be a failure if we end up touching the object header. Doesn't Gerrit use git-notes instead of 'Change-Id:' trailer nowadays? Notes transport is quite easily controlled; the problem with notes merge does not matter for this use. Best, -- Jakub Narębski ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Git Evolve 2018-10-04 16:05 ` Jakub Narebski @ 2018-10-04 17:29 ` Stefan Xenos 0 siblings, 0 replies; 13+ messages in thread From: Stefan Xenos @ 2018-10-04 17:29 UTC (permalink / raw) To: Jakub Narebski; +Cc: Junio C Hamano, git Gerrit uses notes and branches of meta-commits internally for its database, but it still uses the change-id footers to associate an uploaded commit with a change within its database. On Thu, Oct 4, 2018 at 9:05 AM, Jakub Narebski <jnareb@gmail.com> wrote: > Junio C Hamano <gitster@pobox.com> writes: >> Stefan Xenos <sxenos@google.com> writes: >> >>> What is the evolve command? >>> ... >>> - Systems like gerrit would no longer need to rely on "change-id" tags >>> in commit comments to associate commits with the change that they >>> edit, since git itself would have that information. >>> ... >>> Is anyone else interested in this? Please email me directly or on this >>> list. Let's chat: I want to make sure that whatever we come up with is >>> at least as good as any similar technology that has come before. >> >> As you listed in the related technologies section, I think the >> underlying machinery that supports "rebase -i", especially with the >> recent addition of redoing the existing merges (i.e. "rebase -i >> -r"), may be enough to rewrite the histories that were built on top >> of a commit that has been obsoleted by amending. >> >> I would imagine that the main design effort you would need to make >> is to figure out a good way to >> >> (1) keep track of which commits are obsoleted by which other ones >> [*1*], and >> >> (2) to figure out what histories are still to be rebuilt in what >> order on top of what commit efficiently. >> >> Once these are done, you should be able to write out the sequence of >> instructions to feed the same sequencer machinery used by the >> "rebase -i" command. > > Well, that assumes that "rebase -i" can correctly recreate merges, if > needed. > >> [Side note] >> >> *1* It is very desirable to keep track of the evolution of a change >> without polluting the commit object with things like Change-Id: >> and other cruft, either in the body or in the header. If we >> lose the Change-Id: footer without adding any new cruft in the >> commit object header, that would be a great success. It would >> be a failure if we end up touching the object header. > > Doesn't Gerrit use git-notes instead of 'Change-Id:' trailer nowadays? > Notes transport is quite easily controlled; the problem with notes merge > does not matter for this use. > > Best, > -- > Jakub Narębski ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Git Evolve 2018-09-29 23:00 Git Evolve Stefan Xenos 2018-09-30 0:55 ` Junio C Hamano @ 2018-10-01 12:37 ` Derrick Stolee 2018-10-31 21:12 ` Stefan Xenos 2018-10-02 1:23 ` Taylor Blau 2 siblings, 1 reply; 13+ messages in thread From: Derrick Stolee @ 2018-10-01 12:37 UTC (permalink / raw) To: Stefan Xenos, git, Stefan Beller, Jonathan Nieder On 9/29/2018 7:00 PM, Stefan Xenos wrote: > Hello, List! Hello! Welcome. > I'm interested in porting something like Mercurial's evolve command to > Git. I'll be following up with a formal proposal shortly, but before I > do I thought I'd introduce myself to the list and find out if anyone > else is interested in this topic. I'm CC'ing some contributors who have also expressed interest in this topic. > What is the evolve command? I'm snipping the rest of your thread because I'm vaguely familiar with how this is used in hg, but I haven't used it myself. Instead, I'm going to ask you the same questions I asked the last time I had a conversation about this with someone. In my opinion, these questions should have good answers before we start working on the solution, or else we could paint ourselves into a corner as we build the first pieces. --- What would the command-line experience look like for this workflow? Be specific, including examples! How does one create a commit that obsoletes another? Are we in the middle of an interactive rebase, or are we simply checking out the commit? How does a use keep track of their progress in a topic? How do I view which commits in my topic are obsolete, and to what commits? If I want to obsolete commits on one machine and then finish the work on another machine, how do I do that? Similarly: how can I share obsolete commits with other users so they can apply them (or not)? Do obsolescence markers live in the ref space? (This is one way to help answer the question above.) Can I make multiple commits obsolete into one commit (merge patches)? Can I make my commit obsolete in multiple ways (split a patch)? How is this communicated to the user? --- In my opinion, a good way to move forward is to create a patch that adds a design document to Documentation/technical that answers these questions. Then we can dig in more to make the vision clearer. I'm not a UX expert, but this seems like a place where we could use someone with expertise in the area. If we are not careful, we could end up with something even harder to use than interactive rebase. The main goal here is to make it easy to rewrite a topic (plus, the ability to do so in stages). I look forward to see what goes on in this space. Count me in to review the technical details. Thanks, -Stolee ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Git Evolve 2018-10-01 12:37 ` Derrick Stolee @ 2018-10-31 21:12 ` Stefan Xenos 0 siblings, 0 replies; 13+ messages in thread From: Stefan Xenos @ 2018-10-31 21:12 UTC (permalink / raw) To: Derrick Stolee; +Cc: git, Stefan Beller, Jonathan Nieder Sorry it's taken awhile for me to get back to this thread. I've been keeping my open source contributions timeboxed, and had to work through a bit of a backlog before this email thread got back to the front of the queue. > What would the command-line experience look like for this workflow? Be specific, including examples! Yes, I agree that's critical. I'm not going to try to improvise an answer over email, but I will be sure to include such examples when I submit the patch to Documentation/technical, after some careful thought. > How does one create a commit that obsoletes another? I was planning to classify all git commands that create commits as either "modifications" or "clones". Modification commands (such as rebase or commit --amend) would automatically obsolete their predecessors. Clone commands (such as cherry-pick) would create copies without obsoleting the original. > Are we in the middle of an interactive rebase, or are we simply checking out the commit? To obsolete a commit, you'd just check it out and amend. You really wouldn't want to have to do anything extra or put yourself in a special mode to mark things as obsolete or they wouldn't be much of a convenience. However, if you were to run the "evolve" command (the thing that reads the obsolescence markers) and it encountered errors, you'd be in the middle of something very much like an interactive rebase. > How does a use keep track of their progress in a topic? > How do I view which commits in my topic are obsolete, and to what commits? > Do obsolescence markers live in the ref space? (This is one way to help answer the question above.) The answers to these questions are more complicated. I'll be sure to address them in the technical proposal, but I wouldn't want create a misunderstanding with an incomplete explanation. > Can I make multiple commits obsolete into one commit (merge patches)? Can I make my commit obsolete in multiple ways (split a patch)? How is this communicated to the user? Yes and yes. When a single commit is obsoleted by one or more non-obsolete commits, this is called divergence and it needs to be resolved by the user (the evolve command will stop when it encounters divergence, much like a rebase will stop when it encounters a merge conflict). Possible resolutions are to discard one of the two non-obsolete commits by marking them as obsolete, merge the two, or keep both by cloning one of them and marking it as no longer obsoleting its predecessor. Unnecessary divergence isn't a good thing since it requires user intervention to resolve. Splitting a patch doesn't need to create divergence (and probably shouldn't). If you split a commit, the earlier one would be a completely new commit and the latter one would obsolete the original. Doing it the other way around creates a merge conflict between the later commit and anything that followed the original. If both commits obsolete the original, it creates divergence - and either divergence or a merge would get the user involved unnecessarily. A more likely scenario where divergence would occur is of two different users try to amend the same commit and then share their results -- or if a user amends a commit, resets back to the original, and then amends it again. > Count me in to review the technical details. Will do! On Mon, Oct 1, 2018 at 5:37 AM, Derrick Stolee <stolee@gmail.com> wrote: > On 9/29/2018 7:00 PM, Stefan Xenos wrote: >> >> Hello, List! > > > Hello! Welcome. > >> I'm interested in porting something like Mercurial's evolve command to >> Git. I'll be following up with a formal proposal shortly, but before I >> do I thought I'd introduce myself to the list and find out if anyone >> else is interested in this topic. > > > I'm CC'ing some contributors who have also expressed interest in this topic. > >> What is the evolve command? > > > I'm snipping the rest of your thread because I'm vaguely familiar with how > this is used in hg, but I haven't used it myself. Instead, I'm going to ask > you the same questions I asked the last time I had a conversation about this > with someone. In my opinion, these questions should have good answers before > we start working on the solution, or else we could paint ourselves into a > corner as we build the first pieces. > > --- > > What would the command-line experience look like for this workflow? Be > specific, including examples! > > How does one create a commit that obsoletes another? Are we in the middle of > an interactive rebase, or are we simply checking out the commit? How does a > use keep track of their progress in a topic? > > How do I view which commits in my topic are obsolete, and to what commits? > > If I want to obsolete commits on one machine and then finish the work on > another machine, how do I do that? Similarly: how can I share obsolete > commits with other users so they can apply them (or not)? > > Do obsolescence markers live in the ref space? (This is one way to help > answer the question above.) > > Can I make multiple commits obsolete into one commit (merge patches)? Can I > make my commit obsolete in multiple ways (split a patch)? How is this > communicated to the user? > > --- > > In my opinion, a good way to move forward is to create a patch that adds a > design document to Documentation/technical that answers these questions. > Then we can dig in more to make the vision clearer. > > I'm not a UX expert, but this seems like a place where we could use someone > with expertise in the area. If we are not careful, we could end up with > something even harder to use than interactive rebase. The main goal here is > to make it easy to rewrite a topic (plus, the ability to do so in stages). > > I look forward to see what goes on in this space. Count me in to review the > technical details. > > Thanks, > -Stolee ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Git Evolve 2018-09-29 23:00 Git Evolve Stefan Xenos 2018-09-30 0:55 ` Junio C Hamano 2018-10-01 12:37 ` Derrick Stolee @ 2018-10-02 1:23 ` Taylor Blau 2018-10-02 9:11 ` Ævar Arnfjörð Bjarmason 2 siblings, 1 reply; 13+ messages in thread From: Taylor Blau @ 2018-10-02 1:23 UTC (permalink / raw) To: Stefan Xenos; +Cc: git Hi Stefan, On Sat, Sep 29, 2018 at 04:00:04PM -0700, Stefan Xenos wrote: > Hello, List! > > I'm interested in porting something like Mercurial's evolve command to > Git. Welcome to Git :-). I think that the discussion in this thread is good, but it's not why I'm replying. I have also wanted a Mercurial feature in Git, but a different one than yours. Specifically, I've wanted the 'hg absorb' command. My understanding of the commands functionality is that it builds a sort of flamegraph-esque view of the blame, and then cascades downwards parts of a change. I am sure that I'm not doing the command justice, so I'll defer to [1] where it is explained in more detail. The benefit of this command is that it gives you a way to--without ambiguity--absorb changes into earlier commits, and in fact, the earliest commit that they make sense to belong to. This would simplify my workflow greatly when re-rolling patches, as I often want to rewrite a part of an earlier commit. This is certainly possible by a number of different `git rebase` invocations (e.g., (1) create fixup commits, and then re-order them, or (2) mark points in your history as 'edit', and rewrite them in a detached state, and I'm sure many more). I'm curious if you or anyone else has thought about how this might work in Git. Thanks, Taylor [1]: http://files.lihdd.net/hgabsorb-note.pdf ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Git Evolve 2018-10-02 1:23 ` Taylor Blau @ 2018-10-02 9:11 ` Ævar Arnfjörð Bjarmason 2018-10-02 19:35 ` Stefan Xenos ` (3 more replies) 0 siblings, 4 replies; 13+ messages in thread From: Ævar Arnfjörð Bjarmason @ 2018-10-02 9:11 UTC (permalink / raw) To: Taylor Blau; +Cc: Stefan Xenos, git On Tue, Oct 02 2018, Taylor Blau wrote: > Hi Stefan, > > On Sat, Sep 29, 2018 at 04:00:04PM -0700, Stefan Xenos wrote: >> Hello, List! >> >> I'm interested in porting something like Mercurial's evolve command to >> Git. > > Welcome to Git :-). I think that the discussion in this thread is good, > but it's not why I'm replying. I have also wanted a Mercurial feature in > Git, but a different one than yours. > > Specifically, I've wanted the 'hg absorb' command. My understanding of > the commands functionality is that it builds a sort of flamegraph-esque > view of the blame, and then cascades downwards parts of a change. I am > sure that I'm not doing the command justice, so I'll defer to [1] where > it is explained in more detail. > > The benefit of this command is that it gives you a way to--without > ambiguity--absorb changes into earlier commits, and in fact, the > earliest commit that they make sense to belong to. > > This would simplify my workflow greatly when re-rolling patches, as I > often want to rewrite a part of an earlier commit. This is certainly > possible by a number of different `git rebase` invocations (e.g., (1) > create fixup commits, and then re-order them, or (2) mark points in your > history as 'edit', and rewrite them in a detached state, and I'm sure > many more). > > I'm curious if you or anyone else has thought about how this might work > in Git. I've wanted a "git absorb" for a while, but have done no actual work on it, I just found out about it. I think a combination of these two heuristics would probably do the trick: 1. If a change in your "git diff" output has a hunk whose lines overlap with an earlier commit in the @{u}.. range, we do the equivalent of "git add -p", select that hunk, and "git commit --fixup <that commit>". We fixup the most recent commit that matches (otherwise commit>we'd conflict). 2. Have some mode where we fall back from #1 and consider changes to entire files, if that's unambiguous. The neat thing about this would be that you could tweak how promiscuous #1 would be via the -U option to git-diff, and #2 would just be a special case of -U9999999999999 (we should really add a -Uinf...). Then once you ran this you could run "git rebase -i --autosquash" to see how the TODO list would look, and optionally have some "git absorb --now" or whatever to do the "git add -p", "git commit --fixup" and "git rebase --autosquash" all in one go. > [1]: http://files.lihdd.net/hgabsorb-note.pdf ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Git Evolve 2018-10-02 9:11 ` Ævar Arnfjörð Bjarmason @ 2018-10-02 19:35 ` Stefan Xenos 2018-10-02 22:25 ` Kyle Meyer ` (2 subsequent siblings) 3 siblings, 0 replies; 13+ messages in thread From: Stefan Xenos @ 2018-10-02 19:35 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason; +Cc: Taylor Blau, git If you're curious how the Mercurial absorb command works, here's the code: https://www.mercurial-scm.org/repo/hg/file/tip/hgext/absorb.py It's GPL 2: https://www.mercurial-scm.org/repo/hg/file/tip/COPYING On Tue, Oct 2, 2018 at 2:11 AM, Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote: > > On Tue, Oct 02 2018, Taylor Blau wrote: > >> Hi Stefan, >> >> On Sat, Sep 29, 2018 at 04:00:04PM -0700, Stefan Xenos wrote: >>> Hello, List! >>> >>> I'm interested in porting something like Mercurial's evolve command to >>> Git. >> >> Welcome to Git :-). I think that the discussion in this thread is good, >> but it's not why I'm replying. I have also wanted a Mercurial feature in >> Git, but a different one than yours. >> >> Specifically, I've wanted the 'hg absorb' command. My understanding of >> the commands functionality is that it builds a sort of flamegraph-esque >> view of the blame, and then cascades downwards parts of a change. I am >> sure that I'm not doing the command justice, so I'll defer to [1] where >> it is explained in more detail. >> >> The benefit of this command is that it gives you a way to--without >> ambiguity--absorb changes into earlier commits, and in fact, the >> earliest commit that they make sense to belong to. >> >> This would simplify my workflow greatly when re-rolling patches, as I >> often want to rewrite a part of an earlier commit. This is certainly >> possible by a number of different `git rebase` invocations (e.g., (1) >> create fixup commits, and then re-order them, or (2) mark points in your >> history as 'edit', and rewrite them in a detached state, and I'm sure >> many more). >> >> I'm curious if you or anyone else has thought about how this might work >> in Git. > > I've wanted a "git absorb" for a while, but have done no actual work on > it, I just found out about it. > > I think a combination of these two heuristics would probably do the > trick: > > 1. If a change in your "git diff" output has a hunk whose lines overlap > with an earlier commit in the @{u}.. range, we do the equivalent of > "git add -p", select that hunk, and "git commit --fixup <that > commit>". We fixup the most recent commit that matches (otherwise > commit>we'd conflict). > > 2. Have some mode where we fall back from #1 and consider changes to > entire files, if that's unambiguous. > > The neat thing about this would be that you could tweak how promiscuous > #1 would be via the -U option to git-diff, and #2 would just be a > special case of -U9999999999999 (we should really add a -Uinf...). > > Then once you ran this you could run "git rebase -i --autosquash" to see > how the TODO list would look, and optionally have some "git absorb > --now" or whatever to do the "git add -p", "git commit --fixup" and "git > rebase --autosquash" all in one go. > >> [1]: http://files.lihdd.net/hgabsorb-note.pdf ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Git Evolve 2018-10-02 9:11 ` Ævar Arnfjörð Bjarmason 2018-10-02 19:35 ` Stefan Xenos @ 2018-10-02 22:25 ` Kyle Meyer 2018-10-02 23:09 ` Taylor Blau 2018-11-09 13:06 ` Johannes Schindelin 3 siblings, 0 replies; 13+ messages in thread From: Kyle Meyer @ 2018-10-02 22:25 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason Cc: Taylor Blau, Stefan Xenos, git, Jordan Torbiak Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes: > On Tue, Oct 02 2018, Taylor Blau wrote: [...] >> Specifically, I've wanted the 'hg absorb' command. My understanding of >> the commands functionality is that it builds a sort of flamegraph-esque >> view of the blame, and then cascades downwards parts of a change. I am >> sure that I'm not doing the command justice, so I'll defer to [1] where >> it is explained in more detail. >> >> The benefit of this command is that it gives you a way to--without >> ambiguity--absorb changes into earlier commits, and in fact, the >> earliest commit that they make sense to belong to. >> >> This would simplify my workflow greatly when re-rolling patches, as I >> often want to rewrite a part of an earlier commit. This is certainly >> possible by a number of different `git rebase` invocations (e.g., (1) >> create fixup commits, and then re-order them, or (2) mark points in your >> history as 'edit', and rewrite them in a detached state, and I'm sure >> many more). >> >> I'm curious if you or anyone else has thought about how this might work >> in Git. > > I've wanted a "git absorb" for a while, but have done no actual work on > it, I just found out about it. It may be worth looking into git-autofixup [0] (author cc'd). I learned about it when Magit used it in its magit-commit-absorb command, but I haven't used it yet myself. [0] https://github.com/torbiak/git-autofixup -- Kyle ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Git Evolve 2018-10-02 9:11 ` Ævar Arnfjörð Bjarmason 2018-10-02 19:35 ` Stefan Xenos 2018-10-02 22:25 ` Kyle Meyer @ 2018-10-02 23:09 ` Taylor Blau 2018-11-09 13:06 ` Johannes Schindelin 3 siblings, 0 replies; 13+ messages in thread From: Taylor Blau @ 2018-10-02 23:09 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason; +Cc: Taylor Blau, Stefan Xenos, git On Tue, Oct 02, 2018 at 11:11:11AM +0200, Ævar Arnfjörð Bjarmason wrote: You timed this email quite well ;-). > On Tue, Oct 02 2018, Taylor Blau wrote: > > > Hi Stefan, > > > > On Sat, Sep 29, 2018 at 04:00:04PM -0700, Stefan Xenos wrote: > >> Hello, List! > >> > >> I'm interested in porting something like Mercurial's evolve command to > >> Git. > > > > Welcome to Git :-). I think that the discussion in this thread is good, > > but it's not why I'm replying. I have also wanted a Mercurial feature in > > Git, but a different one than yours. > > > > Specifically, I've wanted the 'hg absorb' command. My understanding of > > the commands functionality is that it builds a sort of flamegraph-esque > > view of the blame, and then cascades downwards parts of a change. I am > > sure that I'm not doing the command justice, so I'll defer to [1] where > > it is explained in more detail. > > > > The benefit of this command is that it gives you a way to--without > > ambiguity--absorb changes into earlier commits, and in fact, the > > earliest commit that they make sense to belong to. > > > > This would simplify my workflow greatly when re-rolling patches, as I > > often want to rewrite a part of an earlier commit. This is certainly > > possible by a number of different `git rebase` invocations (e.g., (1) > > create fixup commits, and then re-order them, or (2) mark points in your > > history as 'edit', and rewrite them in a detached state, and I'm sure > > many more). > > > > I'm curious if you or anyone else has thought about how this might work > > in Git. > > I've wanted a "git absorb" for a while, but have done no actual work on > it, I just found out about it. > > I think a combination of these two heuristics would probably do the > trick: > > 1. If a change in your "git diff" output has a hunk whose lines overlap > with an earlier commit in the @{u}.. range, we do the equivalent of > "git add -p", select that hunk, and "git commit --fixup <that > commit>". We fixup the most recent commit that matches (otherwise > commit>we'd conflict). I had imagined this working slightly differently. I think about it in terms of a flamegraph-shape, where each line is affected by gravity. Consider this: [---------------] L0 L1 L2 L3 L4 L5 L6 L7 Here's a line in a diff that affects L1-L4. Were we to create a ``fixup'' to L3-L4, it would look like this: [-----] --| [---------|-----] <-| L0 L1 L2 L3 L4 L5 L6 L7 The commit owning the adjacent edit hunk is the one that gets the changes applied to it. Consider instead the case where we have two overlapping parts of a change: [-----|----] [---------|-----] L0 L1 L2 L3 L4 L5 L6 L7 The left-hand side of the top-most hunk belongs to the hunk below it, but the right-hand side is ``affected by gravity'' down to the base: [-----| [---------|-----]|---] L0 L1 L2 L3 L4 L5 L6 L7 And thus could be reapplied anywhere. I have not spent time proving this, but I believe that this resolves appropriate bases without ambiguity (or, at least can detect when finding a base introduces ambiguity). > 2. Have some mode where we fall back from #1 and consider changes to > entire files, if that's unambiguous. > > The neat thing about this would be that you could tweak how promiscuous > #1 would be via the -U option to git-diff, and #2 would just be a > special case of -U9999999999999 (we should really add a -Uinf...). > > Then once you ran this you could run "git rebase -i --autosquash" to see > how the TODO list would look, and optionally have some "git absorb > --now" or whatever to do the "git add -p", "git commit --fixup" and "git > rebase --autosquash" all in one go. That's cool. I hadn't known about '--autosquash' before, but it now makes sense to me why I have often seen patches that begin with "fixup!". Another thought that I am reminded of was an off-list discussion with Peff, where we thought that a particularly Git-like way to implement something like this would be to generate a set of commits that would be immediately '--autosquash'-able. > > [1]: http://files.lihdd.net/hgabsorb-note.pdf Thanks, Taylor ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Git Evolve 2018-10-02 9:11 ` Ævar Arnfjörð Bjarmason ` (2 preceding siblings ...) 2018-10-02 23:09 ` Taylor Blau @ 2018-11-09 13:06 ` Johannes Schindelin 3 siblings, 0 replies; 13+ messages in thread From: Johannes Schindelin @ 2018-11-09 13:06 UTC (permalink / raw) To: Ævar Arnfjörð Bjarmason; +Cc: Taylor Blau, Stefan Xenos, git [-- Attachment #1: Type: text/plain, Size: 4217 bytes --] Hi, On Tue, 2 Oct 2018, Ævar Arnfjörð Bjarmason wrote: > On Tue, Oct 02 2018, Taylor Blau wrote: > > > Hi Stefan, > > > > On Sat, Sep 29, 2018 at 04:00:04PM -0700, Stefan Xenos wrote: > >> Hello, List! > >> > >> I'm interested in porting something like Mercurial's evolve command to > >> Git. > > > > Welcome to Git :-). I think that the discussion in this thread is good, > > but it's not why I'm replying. I have also wanted a Mercurial feature in > > Git, but a different one than yours. > > > > Specifically, I've wanted the 'hg absorb' command. My understanding of > > the commands functionality is that it builds a sort of flamegraph-esque > > view of the blame, and then cascades downwards parts of a change. I am > > sure that I'm not doing the command justice, so I'll defer to [1] where > > it is explained in more detail. > > > > The benefit of this command is that it gives you a way to--without > > ambiguity--absorb changes into earlier commits, and in fact, the > > earliest commit that they make sense to belong to. > > > > This would simplify my workflow greatly when re-rolling patches, as I > > often want to rewrite a part of an earlier commit. This is certainly > > possible by a number of different `git rebase` invocations (e.g., (1) > > create fixup commits, and then re-order them, or (2) mark points in your > > history as 'edit', and rewrite them in a detached state, and I'm sure > > many more). > > > > I'm curious if you or anyone else has thought about how this might work > > in Git. > > I've wanted a "git absorb" for a while, but have done no actual work on > it, I just found out about it. > > I think a combination of these two heuristics would probably do the > trick: > > 1. If a change in your "git diff" output has a hunk whose lines overlap > with an earlier commit in the @{u}.. range, we do the equivalent of > "git add -p", select that hunk, and "git commit --fixup <that > commit>". We fixup the most recent commit that matches (otherwise > commit>we'd conflict). > > 2. Have some mode where we fall back from #1 and consider changes to > entire files, if that's unambiguous. > > The neat thing about this would be that you could tweak how promiscuous > #1 would be via the -U option to git-diff, and #2 would just be a > special case of -U9999999999999 (we should really add a -Uinf...). > > Then once you ran this you could run "git rebase -i --autosquash" to see > how the TODO list would look, and optionally have some "git absorb > --now" or whatever to do the "git add -p", "git commit --fixup" and "git > rebase --autosquash" all in one go. This is essentially what the script does that I sent to this here mailing list back in May: https://public-inbox.org/git/nycvar.QRO.7.76.6.1805052220360.77@tvgsbejvaqbjf.bet/ I used this quite a lot, but I still find it slow (especially on Windows), so I am still in search for a better solution. And yes, I was intrigued by `hg absorb` when it was presented at GitMerge last year, and wanted to have the same. In the meantime, what I often do is to call `git log -L <range>:<file>` where <range> and <file> are taken from the hunk(s) of the current diff. Actually, I have a script to do that, hidden behind a Git alias. Then I inspect the diffs in that log and call `git commit --fixup` with the one I deem most appropriate. Note that it sometimes fails because of semantic dependencies. That is, even if my current change overlaps with an earlier change, it may be too early to be squashed in. As an example: imagine that I moved a git_config() call from some function into the cmd_<command>() function. Only: I intended to move it, but in fact, I just added the call to the latter function. Eventually, I figure it out! So I want to make a fixup! commit. My script, as well as Ævar's suggestion, as well as literally all the other attempts to solve this that I am aware of, would try to squash this change into whichever commit introduced the function that originally called git_config(). But that is wrong. It should be squashed into the commit that added the git_config() call to the cmd_<command>() function. Ciao, Dscho > > > [1]: http://files.lihdd.net/hgabsorb-note.pdf > ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2018-11-09 13:06 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-09-29 23:00 Git Evolve Stefan Xenos 2018-09-30 0:55 ` Junio C Hamano 2018-09-30 20:17 ` Stefan Xenos 2018-10-04 16:05 ` Jakub Narebski 2018-10-04 17:29 ` Stefan Xenos 2018-10-01 12:37 ` Derrick Stolee 2018-10-31 21:12 ` Stefan Xenos 2018-10-02 1:23 ` Taylor Blau 2018-10-02 9:11 ` Ævar Arnfjörð Bjarmason 2018-10-02 19:35 ` Stefan Xenos 2018-10-02 22:25 ` Kyle Meyer 2018-10-02 23:09 ` Taylor Blau 2018-11-09 13:06 ` Johannes Schindelin
Code repositories for project(s) associated with this public inbox https://80x24.org/mirrors/git.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).