Re: [PATCH] unpack-trees: fix oneway_merge accidentally carry over stage index
- From
Duy Nguyen <pclouds@gmail.com>
- Date
- Mar 18, 2019, 09:24 UTC
- Message-ID
- <CACsJy8CdS1oHt__SzgOxnoD=0h=iN51SWm3YjkOwYGkbzb4o9A@mail.gmail.com>
- In-Reply-To
- <xmqqh8c06dgq.fsf@gitster-ct.c.googlers.com>
On Mon, Mar 18, 2019 at 10:58 AM Junio C Hamano <gitster@pobox.com> wrote:
Show 19 quoted lines
>
> Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
>
> > One-way merge is supposed to take stat info from the index and
> > everything else from the given tree. This implies stage 0 because trees
> > can't have non-zero stages. The add_entry(.., old, ...) call however
> > will keep stage index from the index.
> >
> > This is normally not a problem if the entry from the index is
> > normal (stage #0). But if there is a conflict, we'll get stage #1 entry
> > as "old" and it gets recorded in the final index. Fix it by clearing
> > stage mask.
> >
> > This bug probably comes from b5b425074e (git-read-tree: make one-way
> > merge also honor the "update" flag, 2005-06-07). Before this commit, we
> > may create the final ("dst") index entry from the one in index, but we
> > do clear CE_STAGEMASK.
>
> Wow, good find. That's an old one.Credit goes to Phillip for such attention to detail. If I tested this, I would have stopped after seeing conflict stages collapsed into one and missed the stage index. In fact I was swearing "what the hell did he complain about" when looking at his test script's result, until I realized stage #1 was indeed wrong.
Show 6 quoted lines
> > > > t/t2026-checkout-force.sh (new +x) | 26 ++++++++++++++++++++++++++ > > This makes it cumbersome to have the same fix in the maintenance track > as t2026 is already in use over there. Do we need an entirely new test > just to house this new single test?
I could not find any right file to put it in. I guess I could stick it in t2023-checkout-m.sh
Show 24 quoted lines
> > +test_expect_success 'force checking out a conflict' ' > > + echo a >a && > > + git add a && > > + git commit -ama && > > + A_OBJ=$(git rev-parse :a) && > > + git branch topic && > > + echo b >a && > > + git commit -amb && > > + B_OBJ=$(git rev-parse :a) && > > + git checkout topic && > > + echo c >a && > > + C_OBJ=$(git hash-object a) && > > + git checkout -m master && > > + test_cmp_rev :1:a $A_OBJ && > > + test_cmp_rev :2:a $B_OBJ && > > + test_cmp_rev :3:a $C_OBJ && > > + git checkout -f topic && > > + test_cmp_rev :a $A_OBJ > > So in short, "checkout -f" should have given us an entry for path > "a", taken from the tip of the 'topic' branch, at stage #0 while > switching to that branch, but it didn't? That would be a nice > summary to have at the beginning of the log message before going > into the implementation detail of how that happens.
OK. And the last line probably should be :0:a to make it clear we're looking for stage #0.
-- Duy