On Mon, Mar 18, 2019 at 10:58 AM Junio C Hamano <gitster@xxxxxxxxx> wrote: > > Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> 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. > > > > 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 > > +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