[BUG?] shallow-since can't handle merges

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

 



I came across an interesting case where the shallow code doesn't do do
the right thing. From my reading, it doesn't look like it could possibly
work, but I also don't understand the shallow feature very well, so here
we are. :)

To reproduce:

  # make a copy of the "upstream" repo; you can also fetch directly from
  # it, but having it locally lets you poke at both sides of the
  # conversation
  git clone --bare https://github.com/DefinitelyTyped/DefinitelyTyped upstream.git

  # now make a local copy of a related repo
  git clone --bare --depth=1 https://github.com/Maxim-Mazurok/DefinitelyTyped --no-single-branch repo.git
  cd repo.git

  # and then try to deepen down to this date. This is early morning on
  # May 9 2020.
  git remote add upstream ../upstream.git
  git fetch upstream master --shallow-since=1589000000

The resulting history you get is cut off at May 12, even though there
are parent commits between May 9 and May 12 that should be included.

Here's what the graph in upstream.git looks like:

  $ git log --all --graph --format='%cd %h' --date=iso-local
  * 2020-07-21 13:31:19 +0000 3e7ef84b0a
  * 2020-07-21 02:15:25 +0000 97f6a9df78
  [...]
  * 2020-05-12 23:57:33 +0000 9a0645f52a
  *   2020-05-12 23:55:43 +0000 c7883f4581
  |\
  | * 2020-04-28 17:17:56 +0000 a4b68cbe3a
  * |   2020-05-12 23:50:34 +0000 9d282b0d7d
  |\ \
  | * | 2020-05-05 23:53:20 +0000 daf04e0dcb
  | * | 2020-05-05 23:53:18 +0000 4b2129de54
  * | | 2020-05-12 22:56:55 +0000 c599db54c9
  * | | 2020-05-12 22:04:29 +0000 5bf87114a9
  [...]
  * | | 2020-05-09 09:25:35 +0000 f258742372
  * | | 2020-05-09 08:55:55 +0000 9c96a1cd72
  * | | 2020-05-08 19:55:36 +0000 77f55bc175
  [...]

So the actual "bottom" that we should send is 9c96a1cd72. But the
history we get only goes down to c7883f4581. The tricky thing, though,
is that that commit is a merge. The first parent is still something we
want to send, but the second parent is too old. And then the merge at
9d282b0d7d has the same thing. The first parent is recent, but the
second parent is old.

I walked through upload-pack in a debugger, and its procedure looks
sane. It does a revision walk with --max-age to come up with a list of
"not shallow" commits, which include all three of those, as well as the
commits in between. And then for each not-shallow commit, it sees if any
parents weren't visited, in which case we know we have a boundary. So
that commit gets marked as "shallow", to indicate that it will have its
parents truncated. In this case, all three of the commits I mentioned
get this. And indeed, if we use GIT_TRACE_PACKET, we can see that it
mentions them (and only them):

  packet:  upload-pack> shallow c7883f4581688909baf65c1219a8e842e369150b
  packet:  upload-pack> shallow 9d282b0d7d2e05d7324e70afa66c4ff1306e67b7
  packet:  upload-pack> shallow 9c96a1cd729d0209ba696f225b42d8aafd27295b

But here's the thing. We _don't_ want to mark those first two merges as
fully shallow. We only want to ignore their second parents, but let them
continue to traverse the first parents.

I'm not sure if the shallow mechanism or protocol is even capable of
representing a partial graft like that. Maybe somebody who's more
familiar with the shallow system can comment?

-Peff



[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