* 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).