Merge with staged and unstaged changes

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

 



Hi-

I've been investigating the cases where merge is allowed to proceed when
there are staged changes in the index or unstaged files in the working
directory.  There are cases where I find the behavior surprising and I
hope I can get clarification.  There are also two cases that I will report
as bugs, where it appears that the unstaged file contents are deleted.

For these cases below, please consider the contents of a single path.
In the tables below, we will show the contents of a file across each input
and output of the merge - consider that we're merging a single file in
some branch "theirs" into the current branch "ours" and that these two
branches have a common ancestor "anc".  The state of that file in our
index and workdir are represented by "idx" and "wd", respectively.
Unless otherwise noted, these cases are true for both git-merge-resolve
and git-merge-recursive.


For completeness and illustration purposes, I'll included the cases where
there are no changes staged or unstaged.  These succeed, as expected:

   input                                 result
   anc ours theirs idx wd  merge result  idx wd
1  A   A    B      A   A   take B        B   B
2  A   B    A      B   B   take A        A   A

Merge is also expected to proceed if the contents of our branch are the
merge result, and there are unstaged changes for that file in the workdir.
In this case, the file remains unstaged:

   input                                 result
   anc ours theirs idx wd  merge result  idx wd
3  A   B    A      B   C   take B        B   C


What was surprising to me was that my merge can proceed if I stage a change
that is identical to the merge result.  That is, if my merge result would
be to take the contents from "theirs", then my merge can proceed if I've
already staged the same contents:

   input                                 result
   anc ours theirs idx wd  merge result  idx wd
4  A   A    B      B   B   take B        B   B
5  A   A    B      B   C   take B        B   C

This seems unexpected - is there a use-case that this enables or is
this accidental?


Another surprising result was that if I have deleted a file (and staged
the deletion or not) then the merge will proceed and the file in question
will be recreated.  Consider "X" to be a missing file:

   input                                 result
   anc ours theirs idx wd  merge result  idx wd
6  A   A    B      A   X   take B        B   B
7  A   A    B      X   X   take B        B   B

I wouldn't have expected a file I deleted to be recreated with the other
branch's contents.  Is this behavior also intentional?


Finally, there are cases when you have staged a deletion of the file and
you have unstaged changes in your workdir where the merge will silently
delete the unstaged data.  If there is a conflict, the xdiff output will
overwrite the unstaged file:

   input                                 result
   anc ours theirs idx wd  merge result  idx wd
8  A   B    C      X   D   conflict      X   diff3_file

And similarly, while git-merge-recursive (only) will also remove my
untracked file when there are no changes in our branch but the file was
deleted in their branch:

   input                                 result
   anc ours theirs idx wd  merge result  idx wd
9  A   A    X      X   B   delete file   X   X


I trust the last two cases, where data is lost, are bugs to report, but
could I get clarification on the other situations?

Thanks-

-ed

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[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]