Re: Files different for me

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

 



"John Dlugosz" <JDlugosz@xxxxxxxxxxxxxxxx> writes:

> You will be left with:
>
>  - Paths that have local changes (index matches HEAD but work tree does
>    not match the index --- like your Makefile);
>
>  - Paths cleanly merged (index and HEAD are different but work tree
>    already matches the index);
>
>  - Unmerged paths (index has higher stage entries with <<</===/>>> files
>    in the work tree);
>
> You, I and experienced users know what to do.  Deal *only* with the last
> kind, mark them with "git add" after you are done with each of them, and
> make sure you do not say "-a" when committing the result, to exclude the
> first kind from the merge result.
>
> I've been wondering if we can make this safer for others.
>
> ===end===
>
> I've gone over that carefully and I understand (I think) what you are
> saying.  The first two are things that were not committed, and should
> stay that way (added or not) if they did not conflict.  But they can get
> in the way if a merge (on other files) is needed.

No, the latter two *should* be committed.  The first one *must* be
excluded.

"merge" (and "git am" with or without "-3" for patch application) are
carefully written in such a way that:

 (1) They do not tolerate a dirty index.  They stop without touching
     anything if you have *any* staged changes.

 (2) As long as your index is clean, i.e. matches HEAD, there are two
     cases.

     (2-a) They add cleanly merged paths to the index and write the result
           out in the work tree.

     (2-b) They leave unclean merges as unmerged entries in the index and
           write the conflicted merge result in the work tree.

     (2-c) If all paths cleanly merge, then the index is written out as a
           tree and a merge commit is created.

     However, neither of the above happens when you have local changes to
     the paths they need to do so.

     Your local changes to the paths that "merge" (and "git am") does not
     have to touch are tolerated.

Unlike CVS/SVN, you do not merge when you are in the middle of doing
something, potentially risking a huge merge conflict that you are unable
to resolve and redo, and (1) and "However" in (2) are both safety against
such "Merge conflicts between my HEAD and the other branch are intermixed
with my still uncommitted changes, and I am lost" disaster.  You get a
chance to finish what you started working with your index first before
continuing with the merge.

We were discussing something very different.

In the case (2) where your local changes do not interact with the merge,
the merge as the whole can fail due to conflicts in some paths.  If you
ran "git add" before starting this merge, you wouldn't have come this far
but would have been dealt with by the safety of (1).

Now, in such a case, you have:

 - Files you had modifications before starting this merge.  Because we are
   talking about case (2), by definition, you haven't done "git add" to
   them.  The index entries are at stage 0 and match HEAD for these paths.

 - Files cleanly merged.  In the index, they are at stage 0 and may be
   different from HEAD.  The difference from HEAD comes from the changes
   in the branch being merged (or in the case of "am -3", the change the
   patch introduces).  It can never come from your local changes, because
   we are talking about case (2), and you couldn't have done "git add"
   them before you started this merge.

 - Files with conflicts.  These conflict come from changes committed to
   your HEAD and the branch being merged (or in the case of "am -3", the
   change the patch introduces).  You can never have had local changes to
   these paths (see "However" in (2) above).

That means:

 - The paths at stage 0 in the index can and should be committed without
   any further "git add" when recording this merge.  Doing "git add" for
   paths in the first category among the three will include your unrelated
   local changes in the result which is not what you want.  And doing "git
   add" for the paths in the second category is unnecessary; "merge" (and
   "git am") have already updated the index with the merge result.

 - The paths at higher stages (i.e. unmerged) come from the merge, and you
   must resolve them (either in vi or mergetool) and "git add" them.

So the short rule is "resolve and 'git add' to mark the resolution only
for paths with conflicts.  Never 'git add' anything else before making
your commit.  And do not say 'git commit -a' because that is part of the
previous rule."

> In an effort to "wonder" out loud, can you explain how to handle that
> with "mergetool"?  For a dumb user like me, it just fixes some files
> itself (I guess kdiff is smarter than the normal merge logic) and
> presents me with a GUI for things I need to specify.  This should
> naturally only go through files with conflicts because of those
> "<<</===/>>>" files present.
>
> So, what should I know/do?  "Don't use -a"?  If the idea is to commit
> the merged stuff but preserve the status of what I've added but don't
> want to commit yet,

You do not have to worry about that, because you don't "merge" (or "am")
when you already have changes that are "git add"ed to the index.  These
tools correctly detect this case that you are in the middle of something
and refuse to touch neither your index nor your work tree(see (1) above).
--
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]

  Powered by Linux