Re: Feature Request: `git commit --amend-to`

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 29/09/2021 17:55, Glen Choo wrote:
Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> 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





[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux