Re: [PATCH] apply: fix delete-then-new patch fail with 3way

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

 



On Sat, Oct 16, 2021 at 11:08 PM Junio C Hamano <gitster@xxxxxxxxx> wrote:
>
> "Hongren (Zenithal) Zheng" <i@xxxxxxxxxxx> writes:
>
> > On Sun, Oct 03, 2021 at 07:25:29PM +0800, Hongren (Zenithal) Zheng wrote:
> >> For one single patch FILE containing both deletion and creation
> >> of the same file, applying with three way would fail, which should not.
> >>  ...
>
> Sigh.
>
> Jerry, it seems that the earlier "let's be more aggressive to use
> --3way, instead of using it as a fallback" is turning out to be more
> and more trouble than we hoped.
>
> One thing to notice about the patch used for this test is that ...
>
> >> +test_expect_success 'apply delete then new patch with 3way' '
> >> +    git reset --hard main &&
> >> +    test_write_lines 1 > delnew &&
> >> +    git add delnew &&
> >> +    git commit -m "delnew" &&
> >> +    cat >delete-then-new.patch <<-\EOF &&
> >> +    --- a/delnew
> >> +    +++ /dev/null
> >> +    @@ -1 +0,0 @@
> >> +    -1
> >> +    --- /dev/null
> >> +    +++ b/delnew
> >> +    @@ -0,0 +1 @@
> >> +    +2
> >> +    EOF
>
> ... this is clearly not a patch that was generated by Git.  We do
> not show two separate patches, to delete and then to create, the
> same path to express a file modification, and that is true even when
> we are showing a total-rewrite patch.
>
> In addition, the above set of two patches lack the "index" header
> that records the old and new blob object name, because it is not a
> patch generated by Git.  Whether 3-way is attempted before or after
> the normal application, because the object names there are a crucial
> ingredient for the 3-way merge logic, there is no way for it to work
> at all.
>
>
> >> +    # Apply must succeed.
> >> +    git apply --3way delete-then-new.patch
>
> So, one simple and safe answer would be "Don't do it, --3way is only
> about Git patches."  IOW, the command is failing as designed.
Yeah I do wonder why one would specify "--3way" when the behavior that
they want is actually "direct application". Maybe the OP can elaborate on their
use case?

Part of my original assumption was that "--3way" users actually *want* 3way,
and thus the behavior change wouldn't be too controversial. Of course since
git has so many users, it shouldn't be that surprising that there are many use
patterns out there.

One possible fix-all solution would just be to back out the original change and
move the behavior into a new flag "--actually-3way" (name tbd) that will apply
this behavior and "--3way" would keep the old behavior. The downside here
would be proliferating more flags that would complicate the api and require
maintenance. And of course if users depended on the *new* behavior in the
meantime, then we'd be stuck.

Back to the patch at hand, it does seem like it would work, however I
notice that
if a modification patch were added to the end of the file such that it were
deleted -> add -> modify, that modify wouldn't benefit from actually
doing a 3way
since the file would not be in the index due to this short-cut. The
more general approach
of refactoring to write out results after each patch instead of at the
end *would* fix
both things. I guess this goes back to the larger issue of the
threeway implementation
not being well suited to non-git patches.


>
> To extend and automate the solution would be to see, just before
> attempting to do the 3-way, if the incoming patch is a Git generated
> one, and do not even bother using the 3-way logic if it is not.
>



[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