Re: [BUG] Symbolic links break "git fast-export"?

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

 



On Sun, Jun 30, 2019 at 12:28 PM Johannes Sixt <j6t@xxxxxxxx> wrote:
>
> Am 30.06.19 um 15:05 schrieb Lars Schneider:
> >> On Jun 24, 2019, at 11:58 AM, Jeff King <peff@xxxxxxxx> wrote:
> >> You'd have to split the renames into separate delete/adds, since they
> >> can have a circular dependency. E.g. renaming "foo" to "bar" and "bar"
> >> to "foo", you must remove "foo" and "bar" both, and then add them back
> >> in.
> >
> > @peff: Can you give me a hint how one would perform this circular
> > dependency in a single commit? I try to write a test case for this.
>
> git mv Makefile foo
> git mv COPYING Makefile
> git mv foo COPYING
> git diff -B HEAD
>
> -- Hannes

Interestingly, fast-export has special code to handle cases like this;
possibly due to the understanding of how all
filemodify/filedelete/filerename commands take effect immediately (see
below for more on that).  If I make the above changes in git.git and
commit them, then:

$ git diff --name-status -B HEAD~1 HEAD
R100    Makefile        COPYING
R100    COPYING Makefile

BUT:

$ git fast-export -B -M --no-data HEAD~2..HEAD | tail -n 10
commit refs/heads/master
mark :7
author Elijah Newren <newren@xxxxxxxxx> 1562000065 -0600
committer Elijah Newren <newren@xxxxxxxxx> 1562000065 -0600
data 8
Testing
from :6
R COPYING Makefile
M 100644 8a7e2353520ddd7e0c8074d2b32d0441d97c1597 COPYING

I.e. fast-export breaks the rename and translates it into a modify
instead.  This comes from here:

        case DIFF_STATUS_COPIED:
        case DIFF_STATUS_RENAMED:
                /*
                 * If a change in the file corresponding to ospec->path
                 * has been observed, we cannot trust its contents
                 * because the diff is calculated based on the prior
                 * contents, not the current contents.  So, declare a
                 * copy or rename only if there was no change observed.
                 */
                if (!string_list_has_string(changed, ospec->path)) {
                        <snipped code for handling rename/copy>
                }
                /* fallthrough */
        case DIFF_STATUS_TYPE_CHANGED:
        case DIFF_STATUS_MODIFIED:
        case DIFF_STATUS_ADDED:

There is a question of whether fast-import should try to handle
different exporters that aren't as careful; e.g. if one gets a stream
like:

commit refs/heads/master
mark :4
author Me My <self@xxxxxxx> 110000000 -0700
committer Me My <self@xxxxxxx> 110000000 -0700
data 11
correction
R letters numbers
R numbers letters

Should git-fast-import attempt to divine the user's intent to swap
these two files (though it's not clear if that is the intent; see
below), or would that violate the documented behavior:

           A filerename command takes effect immediately. Once the source
           location has been renamed to the destination any future commands
           applied to the source location will create new files there and not
           impact the destination of the rename.

(I'm pretty sure Shawn would have said the latter; see e.g.
https://public-inbox.org/git/20100706193455.GA19476@xxxxxxxxxxx/ and
the follow-ups.)  I think the view of "immediately taking effect"
implies that this is a rename of 'letters' to 'numbers' which deletes
'numbers', and that the subsequent entry just renames the file back,
making it an expensive almost no-op; almost because it has the
side-effect of deleting the original 'numbers' file.  This is
certainly what fast-import does right now.

Elijah



[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