All of lore.kernel.org
 help / color / mirror / Atom feed
* Feature Request: `git commit --amend-to`
       [not found] <CAENgTz2DoStQEqoKYKa-qMcyaez64u55mnv1HHOzDm392fuEqQ@mail.gmail.com>
@ 2021-09-24 16:04 ` Aidan Gallagher
  2021-09-24 17:15   ` Carlo Arenas
  0 siblings, 1 reply; 7+ messages in thread
From: Aidan Gallagher @ 2021-09-24 16:04 UTC (permalink / raw)
  To: git

`git commit --amend` is very useful for adding changes to the previous
commit quickly.

Unfortunately, it is more difficult to add changes to older commits.
To do so I have to enter interactive rebase, mark the commit to
change, make the changes, amend the previous commit, and continue the
interactive rebase.

It would be nice if there was a single command to do this like `git
commit --amend-to SHA`

I have solved this issue for myself with this handy alias I found online
```
git config --global alias.amend-to '!f() { SHA=`git rev-parse "$1"`;
git commit --fixup "$SHA" && GIT_SEQUENCE_EDITOR=true git rebase
--interactive --autosquash "$SHA^"; }; f'
```

I think it would be beneficial if a command `git commit --amend-to`
could be officially added.

Thanks,
Aidan Gallagher

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Feature Request: `git commit --amend-to`
  2021-09-24 16:04 ` Feature Request: `git commit --amend-to` Aidan Gallagher
@ 2021-09-24 17:15   ` Carlo Arenas
  2021-09-28 16:52     ` Glen Choo
  0 siblings, 1 reply; 7+ messages in thread
From: Carlo Arenas @ 2021-09-24 17:15 UTC (permalink / raw)
  To: Aidan Gallagher; +Cc: git

On Fri, Sep 24, 2021 at 9:08 AM Aidan Gallagher <aidgal2@gmail.com> wrote:
> I have solved this issue for myself with this handy alias I found online
> ```
> git config --global alias.amend-to '!f() { SHA=`git rev-parse "$1"`;
> git commit --fixup "$SHA" && GIT_SEQUENCE_EDITOR=true git rebase
> --interactive --autosquash "$SHA^"; }; f'
> ```

since v2.31.0 you can do instead :

  git commit --fixup reword:$SHA && EDITOR=true git rebase
--interactive --autosquash "$SHA^"

granted it is not 1 command, but usually I find it useful to do
several of those and then one single
rebase at the end.

Carlo

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Feature Request: `git commit --amend-to`
  2021-09-24 17:15   ` Carlo Arenas
@ 2021-09-28 16:52     ` Glen Choo
  2021-09-28 19:54       ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 7+ messages in thread
From: Glen Choo @ 2021-09-28 16:52 UTC (permalink / raw)
  To: Carlo Arenas, Aidan Gallagher; +Cc: git

Carlo Arenas <carenas@gmail.com> writes:
>   git commit --fixup reword:$SHA && EDITOR=true git rebase
> --interactive --autosquash "$SHA^"
>
> granted it is not 1 command, but usually I find it useful to do
> several of those and then one single
> rebase at the end.

This is fairly similar to what I use, though I use this through the
Magit Emacs plugin.

My concern with "--amend-to" is that the semantics aren't as simple as
--amend.

With --amend, you know you're working on the branch tip, so
it's relatively simple to discard the last commit and create a new one.

With something like --amend-to, you aren't just modifying a single
commit, you are also introducing a potential merge conflict with every
commit after that. You would have to provide some kind of facility for
users to fix the merge conflicts. A command like git rebase --autosquash
does a good job at communicating to users that they are actually doing a
rebase and they need to be prepared to fix problems through a rebase UX.
However, git commit --amend-to communicates none of that. A user who
takes a cursory glance at git commit --amend-to has no idea that they
are potentially comitting to a rebase.

I personally think the current UI makes sense given how Git works. I
also wish that it were easier to do --amend-to, but I think the problem
has more to do with how Git manages merges and conflicts and less to do
with having shortcuts in the CLI.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Feature Request: `git commit --amend-to`
  2021-09-28 16:52     ` Glen Choo
@ 2021-09-28 19:54       ` Ævar Arnfjörð Bjarmason
  2021-09-29 16:55         ` Glen Choo
  0 siblings, 1 reply; 7+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-09-28 19:54 UTC (permalink / raw)
  To: Glen Choo; +Cc: Carlo Arenas, Aidan Gallagher, git


On Tue, Sep 28 2021, Glen Choo wrote:

> Carlo Arenas <carenas@gmail.com> writes:
>>   git commit --fixup reword:$SHA && EDITOR=true git rebase
>> --interactive --autosquash "$SHA^"
>>
>> granted it is not 1 command, but usually I find it useful to do
>> several of those and then one single
>> rebase at the end.
>
> This is fairly similar to what I use, though I use this through the
> Magit Emacs plugin.
>
> My concern with "--amend-to" is that the semantics aren't as simple as
> --amend.
>
> With --amend, you know you're working on the branch tip, so
> it's relatively simple to discard the last commit and create a new one.
>
> With something like --amend-to, you aren't just modifying a single
> commit, you are also introducing a potential merge conflict with every
> commit after that. You would have to provide some kind of facility for
> users to fix the merge conflicts. A command like git rebase --autosquash
> does a good job at communicating to users that they are actually doing a
> rebase and they need to be prepared to fix problems through a rebase UX.
> However, git commit --amend-to communicates none of that. A user who
> takes a cursory glance at git commit --amend-to has no idea that they
> are potentially comitting to a rebase.
>
> I personally think the current UI makes sense given how Git works. I
> also wish that it were easier to do --amend-to, but I think the problem
> has more to do with how Git manages merges and conflicts and less to do
> with having shortcuts in the CLI.

I think that users who'd like an --amend-to would probably be happy with
or might want to try out something like "hg absorb", which is something
I think we should have stolen in git already, but it's never too late.

I.e. it's a "git commit --squash" on steroids, which tries to find what
commit to amend things into.

See [1] (and [2] for an archive of the linked PDF) for a past
reference. There's a "git absorb" in Rust that I haven't tried out, but
seems interesting[3]. It looks like "absorb" is now part of "hg"
itself[4], but I'd looked at & tried it back when it was part of the
Facebook-specific patchset to "hg", which I understand has then mostly
or entirely gotten upstreamed in some way.

I'd think that for a git implementation we'd want to re-use the engine
we've got in range-diff.c, i.e. consider each unstaged hunk and find
which hunk/commit in say @{u}.. to squash it into.

1. https://lore.kernel.org/git/877ej0iuhc.fsf@evledraar.gmail.com
2. https://web.archive.org/web/20181003211051/http://files.lihdd.net/hgabsorb-note.pdf
3. https://crates.io/crates/git-absorb
4. https://gregoryszorc.com/blog/2018/11/05/absorbing-commit-changes-in-mercurial-4.8/

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Feature Request: `git commit --amend-to`
  2021-09-28 19:54       ` Ævar Arnfjörð Bjarmason
@ 2021-09-29 16:55         ` Glen Choo
  2021-09-30  8:05           ` Fabian Stelzer
  2021-09-30 13:56           ` Phillip Wood
  0 siblings, 2 replies; 7+ messages in thread
From: Glen Choo @ 2021-09-29 16:55 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: Carlo Arenas, Aidan Gallagher, git

Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

>> [...] I think the problem
>> has more to do with how Git manages merges and conflicts and less to do
>> with having shortcuts in the CLI.
>
> I think that users who'd like an --amend-to would probably be happy with
> or might want to try out something like "hg absorb", which is something
> I think we should have stolen in git already, but it's never too late.

Agree. I think some "hg absorb" features get at the heart of what I
meant, which is that users would benefit from making this merge conflict
resolution a lot simpler.

> I.e. it's a "git commit --squash" on steroids, which tries to find what
> commit to amend things into.

But this is an even bigger step up from what I was suggesting. I blame
my own lack of imagination for not even considering this possibility.

To me, what really sells the feature is the "history of lines" approach
cited in
https://gregoryszorc.com/blog/2018/11/05/absorbing-commit-changes-in-mercurial-4.8/:

  The automatic rewriting logic of hg absorb is implemented by following
  the history of lines. This is fundamentally different from the approach
  taken by hg histedit or git rebase, which tend to rely on merge
  strategies based on the 3-way merge to derive a new version of a file
  given multiple input versions.

Traditional 3-way merge is extremely frustrating when you find yourself
touching the same lines over and over in a rebase, and I think "history
of lines" maps quite cleanly to how humans think of lines. However I'm
not sure if Git has any machinery for doing this.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Feature Request: `git commit --amend-to`
  2021-09-29 16:55         ` Glen Choo
@ 2021-09-30  8:05           ` Fabian Stelzer
  2021-09-30 13:56           ` Phillip Wood
  1 sibling, 0 replies; 7+ messages in thread
From: Fabian Stelzer @ 2021-09-30  8:05 UTC (permalink / raw)
  To: Glen Choo, Ævar Arnfjörð Bjarmason
  Cc: Carlo Arenas, Aidan Gallagher, git

On 29.09.21 18:55, Glen Choo wrote:
> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> 
>>> [...] I think the problem
>>> has more to do with how Git manages merges and conflicts and less to do
>>> with having shortcuts in the CLI.
>>
>> I think that users who'd like an --amend-to would probably be happy with
>> or might want to try out something like "hg absorb", which is something
>> I think we should have stolen in git already, but it's never too late.
> 
> Agree. I think some "hg absorb" features get at the heart of what I
> meant, which is that users would benefit from making this merge conflict
> resolution a lot simpler.
> 

I have never used hg absorb but after reading about its concepts i think
it best maps to something like git automatically creating fixup commits
for you. I also found https://github.com/tummychow/git-absorb (also
untested by me) which claims to do exactly this.

Something like having "git commit -a --fixup" (without any commit hash)
create matching fixup commits for all changes i made would already be
quite cool.

From what i see from our corporate environments and github/bitbucket
workflows though i think most users never even heard about fixup commits
or ever did an interactive rebase (this is totally a view from my
corporate bubble and might not really represent the average git userbase).
Most code review workflows i see don't focus on individual commits and
only present the complete final patch (some at least allow you to view
individual commits but not much more) and therefore users have no big
incentive during review to shape their changes into proper commits.
Some tools (like phabricator) even squash the final patch into a single
commit by default which i think is a good idea if single commits are of
no concern during review anyway.

I wonder if something like an easy to use "absorb" feature (without
fixups, rebases) might encourage and produce more clean commit histories
even for the mentioned workflows.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Feature Request: `git commit --amend-to`
  2021-09-29 16:55         ` Glen Choo
  2021-09-30  8:05           ` Fabian Stelzer
@ 2021-09-30 13:56           ` Phillip Wood
  1 sibling, 0 replies; 7+ messages in thread
From: Phillip Wood @ 2021-09-30 13:56 UTC (permalink / raw)
  To: Glen Choo, Ævar Arnfjörð Bjarmason
  Cc: Carlo Arenas, Aidan Gallagher, git

On 29/09/2021 17:55, Glen Choo wrote:
> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> 
>>> [...] I think the problem
>>> has more to do with how Git manages merges and conflicts and less to do
>>> with having shortcuts in the CLI.
>>
>> I think that users who'd like an --amend-to would probably be happy with
>> or might want to try out something like "hg absorb", which is something
>> I think we should have stolen in git already, but it's never too late.
> 
> Agree. I think some "hg absorb" features get at the heart of what I
> meant, which is that users would benefit from making this merge conflict
> resolution a lot simpler.
> 
>> I.e. it's a "git commit --squash" on steroids, which tries to find what
>> commit to amend things into.
> 
> But this is an even bigger step up from what I was suggesting. I blame
> my own lack of imagination for not even considering this possibility.
> 
> To me, what really sells the feature is the "history of lines" approach
> cited in
> https://gregoryszorc.com/blog/2018/11/05/absorbing-commit-changes-in-mercurial-4.8/:

Thanks for the link, I had not realized absorb did not use a 3-way merge.

>    The automatic rewriting logic of hg absorb is implemented by following
>    the history of lines. This is fundamentally different from the approach
>    taken by hg histedit or git rebase, which tend to rely on merge
>    strategies based on the 3-way merge to derive a new version of a file
>    given multiple input versions.
> 
> Traditional 3-way merge is extremely frustrating when you find yourself
> touching the same lines over and over in a rebase, and I think "history
> of lines" maps quite cleanly to how humans think of lines. 

I agree that conflicts get frustrating with fixups but having just 
played with hg absorb it seems a bit too cavalier to me. The test script 
at the end of this email sets up the history below. I was surprised it 
applied the fixup as to my mind it is ambiguous whether 'z' should go 
before of after 'x' in HEAD~1 and whether 'p' should go before or after 
'e' in HEAD~2.

Worktree HEAD HEAD~1 HEAD~2       HEAD HEAD~1 HEAD~2
    a       a    a     +a            a    a     +a
    b       b    b     +b            b    b     +b
   +z      -x   +x     +c      =>   -x   +x     +z
    c       c    c     +d            z    z     +c
    d       d    d     +e            c    d     +d
   +p       f   -e     +f            d   -e     +e
    f            f                   p    p     +p
                                     f    f     +f

> However I'm not sure if Git has any machinery for doing this.

I think we could use a modified version of blame to find which commit a 
line comes from, but bail out in cases where it is ambiguous such as my 
example above (I think we'd want to require that the two context lines 
either side of an insertion remain adjacency as we track backwards 
through the history, and that a group of modified lines remain 
contiguous). The commits could be rewritten by applying zero context 
patches taking care to adjust the offsets where the fixup adds or 
deletes lines (similar to what add -p does)

Best Wishes

Phillip

----- >8 -----
write_lines() {
     printf '%s\n' "$@"
}

repo="$(mktemp -d)" &&
     cd "$repo" &&
     hg init &&
     write_lines >file a b c d e f &&
     hg add file &&
     hg commit -m initial &&
     write_lines >file a b x c d f &&
     hg commit -m one &&
     write_lines >file a b c d f &&
     hg commit -m two &&
     write_lines >file a b z c d p f &&
     hg absorb &&
     hg log -p



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-09-30 13:56 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CAENgTz2DoStQEqoKYKa-qMcyaez64u55mnv1HHOzDm392fuEqQ@mail.gmail.com>
2021-09-24 16:04 ` Feature Request: `git commit --amend-to` Aidan Gallagher
2021-09-24 17:15   ` Carlo Arenas
2021-09-28 16:52     ` Glen Choo
2021-09-28 19:54       ` Ævar Arnfjörð Bjarmason
2021-09-29 16:55         ` Glen Choo
2021-09-30  8:05           ` Fabian Stelzer
2021-09-30 13:56           ` Phillip Wood

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.