From: Junio C Hamano <gitster@pobox.com>
To: "John Dlugosz" <JDlugosz@TradeStation.com>
Cc: "Linus Torvalds" <torvalds@linux-foundation.org>, <git@vger.kernel.org>
Subject: Re: Files different for me
Date: Wed, 25 Feb 2009 12:04:13 -0800 [thread overview]
Message-ID: <7vocwq1dxe.fsf@gitster.siamese.dyndns.org> (raw)
In-Reply-To: <450196A1AAAE4B42A00A8B27A59278E709E048CB@EXCHANGE.trad.tradestation.com> (John Dlugosz's message of "Wed, 25 Feb 2009 14:23:29 -0500")
"John Dlugosz" <JDlugosz@TradeStation.com> 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).
prev parent reply other threads:[~2009-02-25 20:05 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-25 16:11 Files different for me John Dlugosz
[not found] ` <16946e800902250840o677f8708x7c0bf8980e004b91@mail.gmail.com>
2009-02-25 16:42 ` Feanil Patel
2009-02-25 17:05 ` Brian Gernhardt
2009-02-25 18:02 ` John Dlugosz
2009-02-25 18:38 ` Brian Gernhardt
2009-02-25 19:01 ` John Dlugosz
2009-02-25 18:44 ` Matthieu Moy
2009-02-25 17:55 ` Junio C Hamano
2009-02-25 18:04 ` Linus Torvalds
2009-02-25 18:51 ` Junio C Hamano
2009-02-25 19:12 ` Linus Torvalds
2009-02-25 20:06 ` Junio C Hamano
2009-02-25 20:14 ` Linus Torvalds
2009-02-25 19:16 ` Jay Soffian
2009-02-25 19:38 ` John Dlugosz
2009-02-25 19:23 ` John Dlugosz
2009-02-25 20:04 ` Junio C Hamano [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7vocwq1dxe.fsf@gitster.siamese.dyndns.org \
--to=gitster@pobox.com \
--cc=JDlugosz@TradeStation.com \
--cc=git@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).