From: Jeff King <peff@peff.net>
To: Aghiles <aghilesk@gmail.com>
Cc: Nicolas Sebrecht <nicolas.s.dev@gmx.fr>,
Thomas Rast <trast@student.ethz.ch>,
git list <git@vger.kernel.org>
Subject: Re: git pull suggestion
Date: Thu, 8 Apr 2010 23:49:11 -0400 [thread overview]
Message-ID: <20100409034911.GA4020@coredump.intra.peff.net> (raw)
In-Reply-To: <v2r3abd05a91004082006v74e243f2x33b500f2f6dadc9f@mail.gmail.com>
On Thu, Apr 08, 2010 at 11:06:42PM -0400, Aghiles wrote:
> Kind of ! 'git status' will effectively tell you what files are
> modified but not in the index. The problem is that there is no way to
> know what files are in potential conflict with what is coming from
> 'git pull'. So basically, you can have as many dirty files as you want
> in your working directory as long as they are not conflicting with
> what's coming.
> If dirty files are in conflict, then 'git pull' will complain, but
> slowly ... :)
I think I get what you are talking about now. Consider the following
example script, and let me know if it illustrates your problem:
# define some handy functions
content() {
echo 1 $1 >file1
echo 2 $1 >file2
}
commit() {
git add file1 file2
git commit -m "$1"
}
# make a new repo
mkdir repo && cd repo && git init
# make two diverged branches
content one; commit one
git checkout -b other
content two; commit two
git checkout master
content three; commit three
# now give us dirty working tree state on both files
content four
# and try to merge
git merge other
I get:
$ git merge other
error: Your local changes to 'file1' would be overwritten by merge. Aborting.
Please, commit your changes or stash them before you can merge.
But that's not the whole story. Once you fix that, you will see that
your local changes to 'file2' would be overwritten by the merge:
$ git commit -m "commit file1" file1
$ git merge other
error: Your local changes to 'file2' would be overwritten by merge. Aborting.
Please, commit your changes or stash them before you can merge.
And so on.
Notice that I didn't use "pull", but pull should invoke git-merge after
fetching from the remote. I assume this is the same message you are
talking about?
I agree it would be nicer if, on the error case, we kept going through
the index to find all of the other error cases, and printed them all.
The code for that is a bit tricky, though, as the unpack-trees merging
code which produces that message is a callback, and only sees one cache
entry at a time.
It is possible to manually get the answer you want, or close to it. You
are looking for the intersection of files modified by you and files
modified by the upstream. So:
# unique list of modified working tree files and index entries
$ (git diff-files --name-only;
git diff-index --name-only HEAD
) | sort -u >us
# files that will be changing as part of merge
$ git diff-tree --name-only $HEAD_TO_MERGE_FROM | sort >them
$ comm -12 us them
where $HEAD_TO_MERGE_FROM in my example would be "other", but in the
case of a pull, would probably be FETCH_HEAD.
It isn't 100% accurate, as there are some special cases that the merging
code handles (e.g., I think if the remote changed a file and we have the
same uncommitted change in our working tree, we may still allow that.
There are probably others, too). But it should give a general idea of
what is in conflict.
In practice, I have never actually wanted to this. The workflow goes
something like:
(1) Run git merge foo (or git pull)
(2) Oops, I have cruft in my working tree. What was it? Run git
status.
(3a) Oh, that cruft should have been committed. Make a commit (or
commits). Go to (1), possibly still with some changes in
the working tree.
or
(3b) Oh, that cruft is some change I want to carry forward in the
working directory. Run git stash, repeat the pull, fix any
merge conflicts, and then git stash apply.
So it doesn't really matter to me if there is 1 conflicting file or 100.
In most cases, the commits in (3a) will clean up all of it in one go.
Otherwise, I'll just stash it all and come back to it.
-Peff
next prev parent reply other threads:[~2010-04-09 3:49 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-04-07 23:17 git pull suggestion Aghiles
2010-04-08 15:54 ` Thomas Rast
2010-04-08 19:33 ` Aghiles
2010-04-08 23:11 ` Nicolas Sebrecht
2010-04-09 3:06 ` Aghiles
2010-04-09 3:49 ` Jeff King [this message]
2010-04-09 19:33 ` Aghiles
2010-04-10 4:35 ` Jeff King
2010-04-10 4:40 ` Junio C Hamano
2010-04-11 6:01 ` Aghiles
2010-04-11 7:37 ` Junio C Hamano
2010-04-11 16:33 ` Matthieu Moy
2010-04-12 20:18 ` Aghiles
2010-04-12 21:35 ` Junio C Hamano
2010-04-09 20:54 ` Aghiles
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=20100409034911.GA4020@coredump.intra.peff.net \
--to=peff@peff.net \
--cc=aghilesk@gmail.com \
--cc=git@vger.kernel.org \
--cc=nicolas.s.dev@gmx.fr \
--cc=trast@student.ethz.ch \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.