* Dangerous "git am --abort" behavior
@ 2010-12-20 18:31 Linus Torvalds
2010-12-20 19:35 ` Adam Monsen
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Linus Torvalds @ 2010-12-20 18:31 UTC (permalink / raw)
To: Junio C Hamano, Git Mailing List
I just noticed this, and I wonder if it has bitten me before without
me noticing: "git am --abort" can be really dangerous.
What happened today was that I had been doing a pull or two, and then
applied an emailed patch with "git am" as usual. But as sometimes
happens, I actually had a previous "git am" that had failed - in fact,
it was the same patch that I applied today that had had an earlier
version that no longer applied.
So I just did "git am --abort" to get rid of the old stale 'am' state,
but that actually also ended up aborting my "git pull". Oops.
Happily, I noticed, and did a "git reset --hard @{1}" to get things
back, but at no point did "git am" warn about the implicit "reset" it
did, that threw away non-am state.
I suspect I've avoided this in the past because my normal approach to
getting rid of stale am state tends to be just the manual "rm -rf
.git/rebase-apply", but it's also possible that I've simply not
noticed before.
Maybe "git am" should actually save the last commit ID that it did,
and only do the "reset" if the current HEAD matches the rebase-apply
state and warns if it doesn't? Or maybe we could just introduce a new
"git am --clean" that just flushes any old pending state (ie does that
"clean_abort" thing, which is basically just the "rm -rf" I've done by
hand). Or both?
Comments?
Linus
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Dangerous "git am --abort" behavior
2010-12-20 18:31 Dangerous "git am --abort" behavior Linus Torvalds
@ 2010-12-20 19:35 ` Adam Monsen
2010-12-20 21:52 ` Drew Northup
2010-12-21 0:30 ` Junio C Hamano
2010-12-22 9:49 ` Peter Krefting
2 siblings, 1 reply; 12+ messages in thread
From: Adam Monsen @ 2010-12-20 19:35 UTC (permalink / raw)
To: git
Linus Torvalds writes:
> What happened today was that I had been doing a pull or two, and then
> applied an emailed patch with "git am" as usual. But as sometimes
> happens, I actually had a previous "git am" that had failed - in fact,
> it was the same patch that I applied today that had had an earlier
> version that no longer applied.
It would be helpful if "git status" mentioned if a rebase or am operation is in
progress... this might have helped you avoid the situation described.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Dangerous "git am --abort" behavior
2010-12-20 19:35 ` Adam Monsen
@ 2010-12-20 21:52 ` Drew Northup
2010-12-20 22:04 ` Adam Monsen
0 siblings, 1 reply; 12+ messages in thread
From: Drew Northup @ 2010-12-20 21:52 UTC (permalink / raw)
To: Adam Monsen; +Cc: git, Junio C Hamano, Linus Torvalds
On Mon, 2010-12-20 at 19:35 +0000, Adam Monsen wrote:
> Linus Torvalds writes:
> > What happened today was that I had been doing a pull or two, and then
> > applied an emailed patch with "git am" as usual. But as sometimes
> > happens, I actually had a previous "git am" that had failed - in fact,
> > it was the same patch that I applied today that had had an earlier
> > version that no longer applied.
>
> It would be helpful if "git status" mentioned if a rebase or am operation is in
> progress... this might have helped you avoid the situation described.
Adam,
Please don't cull the CC list...
In any case, are there any other mult-part operations for which we might
want to report "In Progress" in the "git status" output? How do we best
harvest and present this information to the user? This sounds like a
more general-purpose project than Linus' original scope.
--
-Drew Northup N1XIM
AKA RvnPhnx on OPN
________________________________________________
"As opposed to vegetable or mineral error?"
-John Pescatore, SANS NewsBites Vol. 12 Num. 59
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Dangerous "git am --abort" behavior
2010-12-20 21:52 ` Drew Northup
@ 2010-12-20 22:04 ` Adam Monsen
2010-12-23 22:06 ` Steven E. Harris
0 siblings, 1 reply; 12+ messages in thread
From: Adam Monsen @ 2010-12-20 22:04 UTC (permalink / raw)
To: Drew Northup; +Cc: git, Junio C Hamano, Linus Torvalds
Another thing a pal just showed me is the awesome Git Bash/Zsh
completion stuff in contrib/completion/ . That's a good way to keep
tabs on whether you're in the middle of a rebase or am (as well as
many other statuses).
Drew Northup wrote:
> Please don't cull the CC list...
I didn't, I replied at
http://thread.gmane.org/gmane.comp.version-control.git/164002 (by
clicking "--Action--" and selecting "Followup".
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Dangerous "git am --abort" behavior
2010-12-20 18:31 Dangerous "git am --abort" behavior Linus Torvalds
2010-12-20 19:35 ` Adam Monsen
@ 2010-12-21 0:30 ` Junio C Hamano
2010-12-21 18:29 ` Junio C Hamano
2010-12-22 9:49 ` Peter Krefting
2 siblings, 1 reply; 12+ messages in thread
From: Junio C Hamano @ 2010-12-21 0:30 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
Linus Torvalds <torvalds@linux-foundation.org> writes:
> I just noticed this, and I wonder if it has bitten me before without
> me noticing: "git am --abort" can be really dangerous.
>
> What happened today was that I had been doing a pull or two, and then
> applied an emailed patch with "git am" as usual. But as sometimes
> happens, I actually had a previous "git am" that had failed - in fact,
> it was the same patch that I applied today that had had an earlier
> version that no longer applied.
I never got into this as I use bash completion in my PS1 in the real life,
but I've seen this happen while playing around, and I can see myself
easily getting hurt by this behaviour without status in PS1.
> Maybe "git am" should actually save the last commit ID that it did,
> and only do the "reset" if the current HEAD matches the rebase-apply
> state and warns if it doesn't? Or maybe we could just introduce a new
> "git am --clean" that just flushes any old pending state (ie does that
> "clean_abort" thing, which is basically just the "rm -rf" I've done by
> hand). Or both?
I sometimes wanted "--clean" myself, so it is a no-brainer to decide that
it would be a good thing to add.
The last time I thought about this issue, I wasn't sure about "compare
with the last commit"---mostly because it wasn't clear what ramifications
it would have. When you get refusal from "am --abort", how would you
recover from it?
Back then my tentative conclusion was actually to get rid of "am --abort"
and give "am --clean", making the final "reset HEAD~$n" the responsiblity
of the user. But I forgot to pursue it.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Dangerous "git am --abort" behavior
2010-12-21 0:30 ` Junio C Hamano
@ 2010-12-21 18:29 ` Junio C Hamano
2010-12-21 18:46 ` Linus Torvalds
2010-12-21 18:47 ` Junio C Hamano
0 siblings, 2 replies; 12+ messages in thread
From: Junio C Hamano @ 2010-12-21 18:29 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
Junio C Hamano <gitster@pobox.com> writes:
> Linus Torvalds <torvalds@linux-foundation.org> writes:
> ...
>> Maybe "git am" should actually save the last commit ID that it did,
>> and only do the "reset" if the current HEAD matches the rebase-apply
>> state and warns if it doesn't? Or maybe we could just introduce a new
>> "git am --clean" that just flushes any old pending state (ie does that
>> "clean_abort" thing, which is basically just the "rm -rf" I've done by
>> hand). Or both?
> ...
> Back then my tentative conclusion was actually to get rid of "am --abort"
> and give "am --clean", making the final "reset HEAD~$n" the responsiblity
> of the user. But I forgot to pursue it.
So here is the first step in that direction. I suspect that stop_here
should also record what the current branch is, and safe_to_abort should
check it (the potentially risky sequence is "after a failed am, check out
a different branch and then realize you need to 'am --abort'"), but that
is left to interested others ;-) or a later round.
-- >8 --
Subject: am --abort: keep unrelated commits since the last failure and warn
After making commits (either by pulling or doing their own work) after a
failed "am", the user will be reminded by next "am" invocation that there
was a failed "am" that the user needs to decide to resolve or to get rid
of the old "am" attempt. The "am --abort" option was meant to help the
latter. However, it rewinded the HEAD back to the beginning of the failed
"am" attempt, discarding commits made (perhaps by mistake) since.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
git-am.sh | 27 +++++++++++++++++++++++++--
t/t4151-am-abort.sh | 9 +++++++++
2 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/git-am.sh b/git-am.sh
index df09b42..cf1f64b 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -68,9 +68,31 @@ sq () {
stop_here () {
echo "$1" >"$dotest/next"
+ git rev-parse --verify -q HEAD >"$dotest/abort-safety"
exit 1
}
+safe_to_abort () {
+ if test -f "$dotest/dirtyindex"
+ then
+ return 1
+ fi
+
+ if ! test -s "$dotest/abort-safety"
+ then
+ return 0
+ fi
+
+ abort_safety=$(cat "$dotest/abort-safety")
+ if test "z$(git rev-parse --verify -q HEAD)" = "z$abort_safety"
+ then
+ return 0
+ fi
+ echo >&2 "You seem to have moved HEAD since the last 'am' failure."
+ echo >&2 "Not rewinding to ORIG_HEAD"
+ return 1
+}
+
stop_here_user_resolve () {
if [ -n "$resolvemsg" ]; then
printf '%s\n' "$resolvemsg"
@@ -419,10 +441,11 @@ then
exec git rebase --abort
fi
git rerere clear
- test -f "$dotest/dirtyindex" || {
+ if safe_to_abort
+ then
git read-tree --reset -u HEAD ORIG_HEAD
git reset ORIG_HEAD
- }
+ fi
rm -fr "$dotest"
exit ;;
esac
diff --git a/t/t4151-am-abort.sh b/t/t4151-am-abort.sh
index b55c411..001b1e3 100755
--- a/t/t4151-am-abort.sh
+++ b/t/t4151-am-abort.sh
@@ -62,4 +62,13 @@ do
done
+test_expect_success 'am --abort will keep the local commits' '
+ test_must_fail git am 0004-*.patch &&
+ test_commit unrelated &&
+ git rev-parse HEAD >expect &&
+ git am --abort &&
+ git rev-parse HEAD >actual &&
+ test_cmp expect actual
+'
+
test_done
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: Dangerous "git am --abort" behavior
2010-12-21 18:29 ` Junio C Hamano
@ 2010-12-21 18:46 ` Linus Torvalds
2010-12-21 18:47 ` Junio C Hamano
1 sibling, 0 replies; 12+ messages in thread
From: Linus Torvalds @ 2010-12-21 18:46 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
On Tue, Dec 21, 2010 at 10:29 AM, Junio C Hamano <gitster@pobox.com> wrote:
>
> So here is the first step in that direction. I suspect that stop_here
> should also record what the current branch is, and safe_to_abort should
> check it (the potentially risky sequence is "after a failed am, check out
> a different branch and then realize you need to 'am --abort'"), but that
> is left to interested others ;-) or a later round.
Yeah, this patch looks good to me.
And if you've switched branches, and do a "git am --abort" which still
sees the expected commit, I actually think your patch does the right
thing: we will rewind that new branch to ORIG_HEAD, and I think that
is actually the semantics we want.
So what you can do with this is:
- "git am <mbox-file>" fails in the middle
- you go "hmm. I'm happy with what we did so far, but let's go back
to check what's up"
- "git checkout -b test-branch ; git am --abort"
- work on the original base and maybe try to re-apply the mbox with
soem manual editing or whatever...
and that's exactly the semantics that your patch allows, which seems
to be very flexible and useful. No?
So the only thing it disallows is having "git am --abort" actually
abort some unrelated commit, which is I think the exact behavior we
want. In fact, if somebody has done a "git pull" or something, then
"ORIG_HEAD" really doesn't mean what git am thinks it means. So I
wonder if we should check ORIG_HEAD against "beginning of 'git am'"
too, the way you check HEAD against the "abort-safely" point?
Again, if ORIG_HEAD doesn't match (for whatever reason - maybe
somebody switched branches and did a 'git reset --hard" in that other
branch, and then switched back?), then "git am --abort" shouldn't
abort to some random point that came from some non-am workflow, no?
But with the HEAD check, you'd really have to _work_ at screwing up,
so the ORIG_HEAD check seems to be much less important.
Linus
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Dangerous "git am --abort" behavior
2010-12-21 18:29 ` Junio C Hamano
2010-12-21 18:46 ` Linus Torvalds
@ 2010-12-21 18:47 ` Junio C Hamano
1 sibling, 0 replies; 12+ messages in thread
From: Junio C Hamano @ 2010-12-21 18:47 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List
Junio C Hamano <gitster@pobox.com> writes:
> So here is the first step in that direction. I suspect that stop_here
> should also record what the current branch is, and safe_to_abort should
> check it (the potentially risky sequence is "after a failed am, check out
> a different branch and then realize you need to 'am --abort'"), but that
> is left to interested others ;-) or a later round.
And here is that later round...
-- >8 --
Subject: [PATCH] am --abort: also check the current branch
If the user checks out another branch after an "am" failure, am --abort
would have rewound the tip of that branch back to where the last failed
"am" started from, which would not be fun.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
git-am.sh | 10 +++++++---
t/t4151-am-abort.sh | 17 +++++++++++++++++
2 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/git-am.sh b/git-am.sh
index e5671f6..ca3f910 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -68,7 +68,9 @@ sq () {
stop_here () {
echo "$1" >"$dotest/next"
- git rev-parse --verify -q HEAD >"$dotest/abort-safety"
+ head=$(git rev-parse --verify -q HEAD)
+ branch=$(git symbolic-ref -q HEAD)
+ echo "$head,$branch" >"$dotest/abort-safety"
exit 1
}
@@ -84,11 +86,13 @@ safe_to_abort () {
fi
abort_safety=$(cat "$dotest/abort-safety")
- if test "z$(git rev-parse --verify -q HEAD)" = "z$abort_safety"
+ head=$(git rev-parse --verify -q HEAD)
+ branch=$(git symbolic-ref -q HEAD)
+ if test "z$head,$branch" = "z$abort_safety"
then
return 0
fi
- echo >&2 "You seem to have moved HEAD since the last 'am' failure."
+ echo >&2 "You seem to have done some other things since the last 'am' failure."
echo >&2 "Not rewinding to ORIG_HEAD"
return 1
}
diff --git a/t/t4151-am-abort.sh b/t/t4151-am-abort.sh
index 001b1e3..23a9fb0 100755
--- a/t/t4151-am-abort.sh
+++ b/t/t4151-am-abort.sh
@@ -71,4 +71,21 @@ test_expect_success 'am --abort will keep the local commits' '
test_cmp expect actual
'
+test_expect_success 'am --abort will keep unrelated branch' '
+ git reset --hard &&
+ test_commit foo &&
+ test_must_fail git am 0004-*.patch &&
+ git checkout -b unrelated HEAD^ &&
+ (
+ git rev-parse HEAD
+ git symbolic-ref HEAD
+ ) >expect &&
+ git am --abort &&
+ (
+ git rev-parse HEAD
+ git symbolic-ref HEAD
+ ) >actual &&
+ test_cmp expect actual
+'
+
test_done
--
1.7.3.4.768.g2fa91
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: Dangerous "git am --abort" behavior
2010-12-20 18:31 Dangerous "git am --abort" behavior Linus Torvalds
2010-12-20 19:35 ` Adam Monsen
2010-12-21 0:30 ` Junio C Hamano
@ 2010-12-22 9:49 ` Peter Krefting
2 siblings, 0 replies; 12+ messages in thread
From: Peter Krefting @ 2010-12-22 9:49 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, Git Mailing List
Linus Torvalds:
> I just noticed this, and I wonder if it has bitten me before without
> me noticing: "git am --abort" can be really dangerous.
Indeed, I have been bitten by that several times, having worked heavily on
applying patches at $dayjob for a while now. I have taken to habit to always
do the same "rm -rf .git/rebase-apply" that you mention before doing anything
involving am or rebase...
> Or maybe we could just introduce a new "git am --clean" that just flushes
> any old pending state (ie does that "clean_abort" thing, which is
> basically just the "rm -rf" I've done by hand).
That would be very helpful, as manually doing a "rm -rf" inside the .git
directory does make me nervous each time I do it...
--
\\// Peter - http://www.softwolves.pp.se/
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Dangerous "git am --abort" behavior
2010-12-20 22:04 ` Adam Monsen
@ 2010-12-23 22:06 ` Steven E. Harris
2010-12-23 22:32 ` Junio C Hamano
0 siblings, 1 reply; 12+ messages in thread
From: Steven E. Harris @ 2010-12-23 22:06 UTC (permalink / raw)
To: git
Adam Monsen <haircut@gmail.com> writes:
> That's a good way to keep tabs on whether you're in the middle of a
> rebase or am (as well as many other statuses).
How so? How are you using it for this purpose?
--
Steven E. Harris
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Dangerous "git am --abort" behavior
2010-12-23 22:06 ` Steven E. Harris
@ 2010-12-23 22:32 ` Junio C Hamano
2010-12-24 0:24 ` Steven E. Harris
0 siblings, 1 reply; 12+ messages in thread
From: Junio C Hamano @ 2010-12-23 22:32 UTC (permalink / raw)
To: Steven E. Harris; +Cc: git
"Steven E. Harris" <seh@panix.com> writes:
> Adam Monsen <haircut@gmail.com> writes:
>
>> That's a good way to keep tabs on whether you're in the middle of a
>> rebase or am (as well as many other statuses).
>
> How so? How are you using it for this purpose?
There is this gem in the completion script:
# 3) Consider changing your PS1 to also show the current branch:
# PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
With this, you will see something like:
[junio@alter git.git (master|AM)]$
as your prompt while you are working to fix corrupt patch you tried but
failed to apply.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Dangerous "git am --abort" behavior
2010-12-23 22:32 ` Junio C Hamano
@ 2010-12-24 0:24 ` Steven E. Harris
0 siblings, 0 replies; 12+ messages in thread
From: Steven E. Harris @ 2010-12-24 0:24 UTC (permalink / raw)
To: git
Junio C Hamano <gitster@pobox.com> writes:
> There is this gem in the completion script:
Thanks. I use zsh, and didn't want to force zsh to load the bash
completion scripts. After fumbling around first with the "vcs_info"
facility from zshcontrib, which worked acceptably, I found the
"zsh-git-prompt" project¹, integrated that, and am now amazed.
Footnotes:
¹ https://github.com/olivierverdier/zsh-git-prompt
--
Steven E. Harris
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2010-12-24 0:25 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-20 18:31 Dangerous "git am --abort" behavior Linus Torvalds
2010-12-20 19:35 ` Adam Monsen
2010-12-20 21:52 ` Drew Northup
2010-12-20 22:04 ` Adam Monsen
2010-12-23 22:06 ` Steven E. Harris
2010-12-23 22:32 ` Junio C Hamano
2010-12-24 0:24 ` Steven E. Harris
2010-12-21 0:30 ` Junio C Hamano
2010-12-21 18:29 ` Junio C Hamano
2010-12-21 18:46 ` Linus Torvalds
2010-12-21 18:47 ` Junio C Hamano
2010-12-22 9:49 ` Peter Krefting
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.