* Problem with git merge/rebase with conflicts
@ 2010-05-06 10:06 Eli Barzilay
2010-05-06 19:13 ` Junio C Hamano
0 siblings, 1 reply; 5+ messages in thread
From: Eli Barzilay @ 2010-05-06 10:06 UTC (permalink / raw)
To: git
I'm writing about merging and rebasing with conflicts, and there's
something weird with it -- after this setup:
mkdir /tmp/r1; cd /tmp/r1; git init
echo foo > file; git add file; git commit -m first
cd /tmp; git clone r1 r2
cd /tmp/r1; echo abc > file; git commit -m abc file
cd /tmp/r2; echo xyz > file; git commit -m xyz file
git fetch
1. I get this:
$ git merge origin
...CONFLICT...
$ git status -s
UU file
$ echo xyz > file
$ git add file
$ git status -s
and there's nothing -- it's all clean after that `add', without
committing and without anything said. If this is intentional, it
would be nice if there was some message from `git add'... And it
would also be nice if I'd seen it mentioned anywhere, but
practically everything I've read said the same: `git add' and then
`git commit', no mention of that second step being optional.
2. I have some other sample repository that exhibits the behavior with
the "resolution" going the other way, but here -- starting from the
same setup:
$ git merge origin
...CONFLICT...
$ echo abc > file
$ git add file
$ git status -s
M file
$ git commit
...get an editor without the conflict resolution template thing...
$ git log --graph --all --oneline
* 2d3744b Huh?
* 98c46da xyz
| * 4744b19 abc
|/
* c8915c2 first
This looks like I never did any merge.
$ git merge origin
Merge made by recursive.
$ git log --graph --all --oneline
* 94e69e9 Merge remote branch 'origin'
|\
| * 4744b19 abc
* | 2d3744b Huh?
* | 98c46da xyz
|/
* c8915c2 first
And this looks even more wrong...
3. Again, starting from the same setup:
$ git rebase origin
...CONFLICT...
$ git status -s
UU file
$ echo abc > file
$ git add file
$ git status -s
<- nothing
$ git rebase --continue
Applying: xyz
No changes - did you forget to use 'git add'?
which is probably related to the above. I could use --skip, but
now that I edited it manually I can't remember that --skip does
what I already did.
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Problem with git merge/rebase with conflicts
2010-05-06 10:06 Problem with git merge/rebase with conflicts Eli Barzilay
@ 2010-05-06 19:13 ` Junio C Hamano
2010-05-06 20:45 ` Eli Barzilay
0 siblings, 1 reply; 5+ messages in thread
From: Junio C Hamano @ 2010-05-06 19:13 UTC (permalink / raw)
To: Eli Barzilay; +Cc: git
Eli Barzilay <eli@barzilay.org> writes:
> 1. I get this:
> 3. Again, starting from the same setup:
I don't have time to look at the second one, but these are quite obvious
and natural. "status" in these cases notices that you haven't made any
change relative to HEAD (in either the index nor in the working tree)
after all, and that is what is being reported.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Problem with git merge/rebase with conflicts
2010-05-06 19:13 ` Junio C Hamano
@ 2010-05-06 20:45 ` Eli Barzilay
2010-05-08 5:20 ` Jeff King
0 siblings, 1 reply; 5+ messages in thread
From: Eli Barzilay @ 2010-05-06 20:45 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On May 6, Junio C Hamano wrote:
> Eli Barzilay <eli@barzilay.org> writes:
>
> > 1. I get this:
> > 3. Again, starting from the same setup:
>
> I don't have time to look at the second one,
(FWIW, I can't recreate it now -- very weird since when I sent that
message it was definitely repeatable.)
> but these are quite obvious and natural. "status" in these cases
> notices that you haven't made any change relative to HEAD (in either
> the index nor in the working tree) after all, and that is what is
> being reported.
Yes, I agree that they're doing "obviously" doing the right thing, but
I don't think that they're natural enough... I'm not saying that it's
doing something broken, just that some of the interface (=> printouts)
could eliminate surprises. Here are some problems that I've seen,
IMO, some of them are indications that this is not natural. I'll
prefix each one with the false belief that I had (and that I didn't
see any text that would correct it...).
1. False belief: After you edit and `git add' a file, you will need to
commit it to make the change part of your history.
Obvious counter example: edit a file and `git add' it; undo the
edit in the file and `git add' again -- you now have nothing to
commit.
A way that I think will solve this: make `git add' notify you that
the changes that you just added canceled earlier changes and you're
back to a clean state.
2. False belief: If you have a completely clear working directory and
index, then there's nothing for you to commit. (At least without
forcing an empty commit.)
Counter example: run this (simplified example)
rm -rf /tmp/test; mkdir /tmp/test; cd /tmp/test; git init
echo foo > file; git add file; git commit -m first
git branch a-branch; echo abc > file; git commit -m abc file
git checkout a-branch; echo xyz > file; git commit -m xyz file
git merge master; echo xyz > file; git add file
git status
That last `status' will happily tell you that "nothing to commit
(working directory clean)" -- but `git commit' *will* commit the
merge.
A way that I think will solve this: clearly there is somewhere
something that makes the commit possible (probably .git/MERGE*
files) -- so make `git status' inspect these and say something
about it instead of saying that there's nothing to commit. (The
other option would be to make `git add' clear out the merge state
too, but this is probably very broken.)
2a. A related problem: usually when I try to checkout a different
branch when I have changes, git barfs at me. But after that script
is run, I can `git checkout master' with no errors or warnings, and
the merge commit is gone. It looks like checkout is even careful
enough to remove the .git/MERGE* files, so making it barf (or at
least spit out some warning) is probably easy...
3. False belief: if your working directory and your index are dirty,
then there *is* something for you to commit.
Obvious counter example: edit a file and `git add' it; undo the
edit in the file but *don't* `git add' again -- `git status -s'
will now say:
MM file
And now:
$ git commit .
# On branch master
nothing to commit (working directory clean)
but the status is still not cleared. Trying to checkout a
different branch gives me the barf.
A way that I think will solve this: make `git commit <path>' add
the paths before committing -- and if `add' says something, it will
say that here and clarify what happened. But this is probably too
much of a change, so alternatively `git commit' would notice that
there was nothing to commit because of this state, and `add' the
right files to clear out the status (after saying something about
it).
4. `git rebase' issues -- I've sent a separate message about that, and
IMO adding those notes to what rebase says would clear up most of
the confusion, and probably if the above are done then it will also
help rebase to be more robust.
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Re: Problem with git merge/rebase with conflicts
2010-05-06 20:45 ` Eli Barzilay
@ 2010-05-08 5:20 ` Jeff King
2010-05-08 5:52 ` Eli Barzilay
0 siblings, 1 reply; 5+ messages in thread
From: Jeff King @ 2010-05-08 5:20 UTC (permalink / raw)
To: Eli Barzilay; +Cc: Junio C Hamano, git
On Thu, May 06, 2010 at 04:45:44PM -0400, Eli Barzilay wrote:
> 1. False belief: After you edit and `git add' a file, you will need to
> commit it to make the change part of your history.
>
> Obvious counter example: edit a file and `git add' it; undo the
> edit in the file and `git add' again -- you now have nothing to
> commit.
>
> A way that I think will solve this: make `git add' notify you that
> the changes that you just added canceled earlier changes and you're
> back to a clean state.
I don't understand how this is a false belief. You _haven't_ made
anything a part of your history. It was already there, and you've done
nothing to the history.
But I thought your original question started out with a conflicted
merge:
> mkdir /tmp/r1; cd /tmp/r1; git init
> echo foo > file; git add file; git commit -m first
> cd /tmp; git clone r1 r2
> cd /tmp/r1; echo abc > file; git commit -m abc file
> cd /tmp/r2; echo xyz > file; git commit -m xyz file
> git fetch
> git merge origin
> echo xyz > file
> git add file
> git status -s
In that case you _do_ have to commit, or your history will not contain
the merge! Even though you happened to reject the other sides changes,
you still want to generate a merge commit showing that in your history
you have examined and rejected the other side's changes.
The only failing here, if any, is that "git status" does not say "you
are in the middle of a merge, and should commit it".
> 2. False belief: If you have a completely clear working directory and
> index, then there's nothing for you to commit. (At least without
> forcing an empty commit.)
>
> Counter example: run this (simplified example)
>
> rm -rf /tmp/test; mkdir /tmp/test; cd /tmp/test; git init
> echo foo > file; git add file; git commit -m first
> git branch a-branch; echo abc > file; git commit -m abc file
> git checkout a-branch; echo xyz > file; git commit -m xyz file
> git merge master; echo xyz > file; git add file
> git status
>
> That last `status' will happily tell you that "nothing to commit
> (working directory clean)" -- but `git commit' *will* commit the
> merge.
Yeah, probably it should detect the presence of .git/MERGE_HEAD and
print a different message.
> 3. False belief: if your working directory and your index are dirty,
> then there *is* something for you to commit.
>
> Obvious counter example: edit a file and `git add' it; undo the
> edit in the file but *don't* `git add' again -- `git status -s'
> will now say:
>
> MM file
>
> And now:
>
> $ git commit .
> # On branch master
> nothing to commit (working directory clean)
>
> but the status is still not cleared. Trying to checkout a
> different branch gives me the barf.
I think you misunderstand how "git commit ." works. It already means
"git add . && git commit". So you are actually _removing_ the thing to
commit in the first step. Running "git commit" would work.
Which is what you suggest:
> A way that I think will solve this: make `git commit <path>' add
> the paths before committing -- and if `add' says something, it will
> say that here and clarify what happened. But this is probably too
> much of a change, so alternatively `git commit' would notice that
> there was nothing to commit because of this state, and `add' the
> right files to clear out the status (after saying something about
> it).
Except that I guess you want the add process to say "the thing you added
is the same as HEAD, so you just reverted the original thing you added".
Personally I would find such a notification annoying.
-Peff
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Re: Problem with git merge/rebase with conflicts
2010-05-08 5:20 ` Jeff King
@ 2010-05-08 5:52 ` Eli Barzilay
0 siblings, 0 replies; 5+ messages in thread
From: Eli Barzilay @ 2010-05-08 5:52 UTC (permalink / raw)
To: Jeff King; +Cc: Junio C Hamano, git
On May 8, Jeff King wrote:
> On Thu, May 06, 2010 at 04:45:44PM -0400, Eli Barzilay wrote:
>
> > 1. False belief: After you edit and `git add' a file, you will
> > need to commit it to make the change part of your history.
> >
> > Obvious counter example: edit a file and `git add' it; undo the
> > edit in the file and `git add' again -- you now have nothing to
> > commit.
> >
> > A way that I think will solve this: make `git add' notify you
> > that the changes that you just added canceled earlier changes
> > and you're back to a clean state.
>
> I don't understand how this is a false belief. You _haven't_ made
> anything a part of your history. It was already there, and you've
> done nothing to the history.
Well, the false belief here is following every text that (very
reasonably) tells you that you should `git add' the file and then `git
commit' it. Obviously, with a cooked example like that things are
made very clear -- but what if I worked on something for a while
(adding stuff to the index as I go), and missed the fact that the file
is eventually at exactly where it started? Even with this it's
probably not too bad as is, but with merges it gets even more
potential to be confusing. In any case, I'm not saying that anything
is wrong -- just that it would be nice if `git add' told me about it,
so I can never see a transcript that ends with:
$ git add foo
$ git commit
... nothing to commit
since that canceling add will tell me explicitly that this addition
got things back to a state of having no changes. (And I don't see any
harm in that -- if you want to explicitly revert things back you'd use
reset or something, so this change is something that you'd only see if
you were confused as above.)
> But I thought your original question started out with a conflicted
> merge:
>
> > mkdir /tmp/r1; cd /tmp/r1; git init
> > echo foo > file; git add file; git commit -m first
> > cd /tmp; git clone r1 r2
> > cd /tmp/r1; echo abc > file; git commit -m abc file
> > cd /tmp/r2; echo xyz > file; git commit -m xyz file
> > git fetch
> > git merge origin
> > echo xyz > file
> > git add file
> > git status -s
>
> In that case you _do_ have to commit, or your history will not
> contain the merge! Even though you happened to reject the other
> sides changes, you still want to generate a merge commit showing
> that in your history you have examined and rejected the other side's
> changes.
>
> The only failing here, if any, is that "git status" does not say
> "you are in the middle of a merge, and should commit it".
Yes, that was exactly the conclusion of my following point. Well,
even more than that -- if `git add' will tell you about getting into a
clean state, then you'd get this for the first case above:
$ git add foo
note: this addition canceled out all changes
$ git commit
... nothing to commit # <-- this is obvious now
$ git status -s
# <-- as is the lack of output here
and for the merge case, `git add' could note that, in addition to a
clean state, you still have a merge to finish, so it could say this:
$ git merge blah
...
$ git add foo
note: this addition canceled out all changes,
but you still have a pending merge to commit
$ git status -s
(merge pending) # <-- this is my item#2 suggestion
> > 3. False belief: if your working directory and your index are dirty,
> > then there *is* something for you to commit.
> >
> > Obvious counter example: edit a file and `git add' it; undo the
> > edit in the file but *don't* `git add' again -- `git status -s'
> > will now say:
> >
> > MM file
> >
> > And now:
> >
> > $ git commit .
> > # On branch master
> > nothing to commit (working directory clean)
> >
> > but the status is still not cleared. Trying to checkout a
> > different branch gives me the barf.
>
> I think you misunderstand how "git commit ." works. It already means
> "git add . && git commit". So you are actually _removing_ the thing to
> commit in the first step. Running "git commit" would work.
>
> Which is what you suggest:
>
> > A way that I think will solve this: make `git commit <path>'
> > add the paths before committing -- and if `add' says something,
> > it will say that here and clarify what happened. But this is
> > probably too much of a change, so alternatively `git commit'
> > would notice that there was nothing to commit because of this
> > state, and `add' the right files to clear out the status (after
> > saying something about it).
>
> Except that I guess you want the add process to say "the thing you
> added is the same as HEAD, so you just reverted the original thing
> you added".
Yes.
> Personally I would find such a notification annoying.
Isn't this something that you'd never do intentionally? I'm not
talking about doing this for any specific file in the commit (actually
the `add' part of the commit) -- I'm suggesting that it will say that
only if the result of adding stuff made the following commit do
nothing. So this message would only annoy you if you've done some
changes and added them, then you edit the files back to the original
state, and then use `git add' or `git commit <paths>' (!) to add the
changes so you're back to a clean state. This sounds like a very odd
way of undoing changes (especially with git that gives me about 200
ways to undo changes more directly...).
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-05-08 5:54 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-06 10:06 Problem with git merge/rebase with conflicts Eli Barzilay
2010-05-06 19:13 ` Junio C Hamano
2010-05-06 20:45 ` Eli Barzilay
2010-05-08 5:20 ` Jeff King
2010-05-08 5:52 ` Eli Barzilay
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).