Re: git merge -s subtree seems to be broken.

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

 



On Tue, Jul 31, 2018 at 11:03:17AM -0400, George Shammas wrote:

> Bisecting around, this might be the commit that introduced the breakage.
> 
> https://github.com/git/git/commit/d8febde
> 
> I really hope that it hasn't been broken for 5 years and I am just doing
> something wrong.

Unfortunately, I think it has been broken for five years.

The problem introduced in that commit is that each iteration through the
loop advances the tree pointers. But when we're walking two lists and
see that one omits an entry the other has, we have to advance _one_ list
and keep the other where it is. So if we instrument the score_*
functions to see which ones trigger, your reproduction gives this with
the original code:

  warning: scoring trees:
    8e12d9b6bc57fe6308315914628dd4fd7665ca59
    aed1d7c5809e53d49b52c43a6103827046d60286
  warning: score_matches: .bookignore
  warning: score_matches: .gitignore
  warning: score_matches: .mailmap
  warning: score_differs: .travis.yml
  warning: score_matches: COPYING
  warning: score_differs: INSTALL.adoc
  warning: score_differs: Makefile
  warning: score_differs: NEWS.adoc
  warning: score_differs: README.adoc
  warning: score_missing: appveyor.yml
  warning: score_matches: autogen.sh
  warning: score_matches: book.json
  [...]

and the new one does:

  warning: scoring trees:
    8e12d9b6bc57fe6308315914628dd4fd7665ca59
    aed1d7c5809e53d49b52c43a6103827046d60286
  warning: score_matches: .bookignore
  warning: score_matches: .gitignore
  warning: score_matches: .mailmap
  warning: score_differs: .travis.yml
  warning: score_matches: COPYING
  warning: score_differs: INSTALL.adoc
  warning: score_differs: Makefile
  warning: score_differs: NEWS.adoc
  warning: score_differs: README.adoc
  warning: score_missing: appveyor.yml
  warning: score_missing: autogen.sh
  warning: score_missing: book.json

We're fine at first, but as soon as one tree has appveyor.yml and the
other doesn't, we get out of sync. We compare "autogen" and "appveyor",
and realize that they do not match. But then we need to increment
pointer for the tree with "appveyor" only, and leave the other in place,
at which point we'd realize that they both have "autogen". Instead, we
increment both, and after that we compare "autogen.sh" to "book.json",
and so on.

So the assertion in that commit message that "the calls to
update_tree_entry() are not needed any more" is just wrong. We have
decide whether to call it based on the "cmp" value.

I quoted your original reproduction below for the benefit of René
(cc'd).

-Peff

> On Tue, Jul 31, 2018 at 10:09 AM George Shammas <georgyo@xxxxxxxxx> wrote:
> 
> > At work, we recently updated from a massively old version of git (1.7.10)
> > to 2.18. There are a few code bases that use subtrees, and they seem to
> > have completely broke when trying to merge in updates.
> >
> > I have confirmed that it works correctly in 1.7.10.  The 2.18 behavior is
> > clearly incorrect.
> >
> > git init
> > echo init > test
> > git add test
> > git commit -m init
> >
> > git remote add tig https://github.com/jonas/tig.git
> > git fetch tig
> > git merge -s ours --no-commit --allow-unrelated-histories tig-2.3.0
> > git read-tree --prefix=src/ -u tig-2.3.0
> > git commit -m "Get upstream tig-2.3.0"
> > # Notice how the history are merged, and that the source from the upstream
> > repo is in src
> >
> > echo update > test
> > git commit -a -m "test"
> >
> > git merge -s subtree tig-2.4.0
> > # Boom, in 2.18 instead of merging into the subtree, it just deletes
> > everything in the repository, which is clearly the wrong behavior.
> >



[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