Re: Rebase doesn't restore branch pointer back on out of memory

7 messages, 3 authors, 2016-06-15 · open the first message on its own page

Re: Rebase doesn't restore branch pointer back on out of memory

From: Andrew Wong <hidden>
Date: 2016-06-15 22:54:56

On 10/03/2012 06:35 PM, Alexander Kostikov wrote:
quoted
That allows you can go back to the pre-rebase state by
"rebase --abort".
rebase --abort command were not available. I guess rebase file was not created.
I meant "rebase --abort" would be available *if* the error was caught by 
"rebase". But in your case, "rebase" is probably dying somewhere and the 
error was not caught, causing "rebase" to think that everything 
completed successfully, and go ahead to update the branch.
Is there a way to include some log verbose mode to detect where
exactly error happens?
There isn't any built-in to git itself. But one way to get more info is 
running the rebase command this way:
     env SHELLOPTS="verbose" git rebase <your arguments>

That should print out every shell command that rebase executes. Having 
the last page of that output should give us enough context as to where 
it's failing.

Just a wild guess: rebase is probably failing at the "format-patch" command.
It'd also be interesting to see if "rebase -i" will also workaround the 
issue. But like you said, there's no way set "-i" or "-m" as the default.

Re: Rebase doesn't restore branch pointer back on out of memory

From: Alexander Kostikov <hidden>
Date: 2016-06-15 22:54:56

rebase -i fails with different error:
Also in case of rebase -i the branch pointer is not changed. Thus
nothing to fix there.

-- Alexander

On Thu, Oct 4, 2012 at 2:09 PM, Alexander Kostikov
[off-list ref] wrote:
quoted
Having the
last page of that output should give us enough context as to where it's
failing.
Full script is uploaded to
https://dl.dropbox.com/u/10828740/rebase.log Here is the last page:

-----------------------------------[code]
if test -s "$dotest"/rewritten; then
    git notes copy --for-rewrite=rebase < "$dotest"/rewritten
    if test -x "$GIT_DIR"/hooks/post-rewrite; then
        "$GIT_DIR"/hooks/post-rewrite rebase < "$dotest"/rewritten
    fi
fi

rm -fr "$dotest"
git gc --auto
git rev-parse HEAD

ret=$?
test 0 != $ret -a -d "$state_dir" && write_basic_state
exit $ret
-----------------------------------[/code]

quoted
It'd also be interesting to see if "rebase -i" will also workaround the
issue.
rebase -i fails with different error:

» git rebase -i master rebase_debug
fatal: Out of memory, malloc failed (tried to allocate 458753 bytes)

Do you need verbose log for it as well?

-- Alexander


On Thu, Oct 4, 2012 at 8:13 AM, Andrew Wong [off-list ref] wrote:
quoted
On 10/03/2012 06:35 PM, Alexander Kostikov wrote:
quoted
quoted
That allows you can go back to the pre-rebase state by
"rebase --abort".
rebase --abort command were not available. I guess rebase file was not
created.
I meant "rebase --abort" would be available *if* the error was caught by
"rebase". But in your case, "rebase" is probably dying somewhere and the
error was not caught, causing "rebase" to think that everything completed
successfully, and go ahead to update the branch.

quoted
Is there a way to include some log verbose mode to detect where
exactly error happens?
There isn't any built-in to git itself. But one way to get more info is
running the rebase command this way:
    env SHELLOPTS="verbose" git rebase <your arguments>

That should print out every shell command that rebase executes. Having the
last page of that output should give us enough context as to where it's
failing.

Just a wild guess: rebase is probably failing at the "format-patch" command.
It'd also be interesting to see if "rebase -i" will also workaround the
issue. But like you said, there's no way set "-i" or "-m" as the default.


--
Alexander Kostikov


-- 
Alexander Kostikov

Re: Rebase doesn't restore branch pointer back on out of memory

From: Alexander Kostikov <hidden>
Date: 2016-06-15 22:54:56

Having the
last page of that output should give us enough context as to where it's
failing.
Full script is uploaded to
https://dl.dropbox.com/u/10828740/rebase.log Here is the last page:

-----------------------------------[code]
if test -s "$dotest"/rewritten; then
    git notes copy --for-rewrite=rebase < "$dotest"/rewritten
    if test -x "$GIT_DIR"/hooks/post-rewrite; then
        "$GIT_DIR"/hooks/post-rewrite rebase < "$dotest"/rewritten
    fi
fi

rm -fr "$dotest"
git gc --auto
git rev-parse HEAD

ret=$?
test 0 != $ret -a -d "$state_dir" && write_basic_state
exit $ret
-----------------------------------[/code]

It'd also be interesting to see if "rebase -i" will also workaround the
issue.
rebase -i fails with different error:

» git rebase -i master rebase_debug
fatal: Out of memory, malloc failed (tried to allocate 458753 bytes)

Do you need verbose log for it as well?

-- Alexander


On Thu, Oct 4, 2012 at 8:13 AM, Andrew Wong [off-list ref] wrote:
On 10/03/2012 06:35 PM, Alexander Kostikov wrote:
quoted
quoted
That allows you can go back to the pre-rebase state by
"rebase --abort".
rebase --abort command were not available. I guess rebase file was not
created.
I meant "rebase --abort" would be available *if* the error was caught by
"rebase". But in your case, "rebase" is probably dying somewhere and the
error was not caught, causing "rebase" to think that everything completed
successfully, and go ahead to update the branch.

quoted
Is there a way to include some log verbose mode to detect where
exactly error happens?
There isn't any built-in to git itself. But one way to get more info is
running the rebase command this way:
    env SHELLOPTS="verbose" git rebase <your arguments>

That should print out every shell command that rebase executes. Having the
last page of that output should give us enough context as to where it's
failing.

Just a wild guess: rebase is probably failing at the "format-patch" command.
It'd also be interesting to see if "rebase -i" will also workaround the
issue. But like you said, there's no way set "-i" or "-m" as the default.


-- 
Alexander Kostikov

Re: Rebase doesn't restore branch pointer back on out of memory

From: Andrew Wong <hidden>
Date: 2016-06-15 22:54:56

On 10/04/2012 05:09 PM, Alexander Kostikov wrote:
Full script is uploaded to
https://dl.dropbox.com/u/10828740/rebase.log  Here is the last page:
Judging from that log, I'm pretty sure "rebase" is failing at 
"format-patch". I was able to reproduce the issue you're having: 
"rebase" finished and modified the branch even though it actually failed.

"rebase" is not catching that error. I'll try to come up with a patch to 
fix it later tonight, so that "rebase" will fail correctly. And when it 
does, you'll be able to do "rebase --abort" to go back to your original 
state.

Re: Rebase doesn't restore branch pointer back on out of memory

From: Alexander Kostikov <hidden>
Date: 2016-06-15 22:54:56

Thanks, Andrew!
I'm looking forward for the patch.

On Thu, Oct 4, 2012 at 3:52 PM, Andrew Wong [off-list ref] wrote:
On 10/04/2012 05:09 PM, Alexander Kostikov wrote:
quoted
Full script is uploaded to
https://dl.dropbox.com/u/10828740/rebase.log  Here is the last page:
Judging from that log, I'm pretty sure "rebase" is failing at
"format-patch". I was able to reproduce the issue you're having: "rebase"
finished and modified the branch even though it actually failed.

"rebase" is not catching that error. I'll try to come up with a patch to fix
it later tonight, so that "rebase" will fail correctly. And when it does,
you'll be able to do "rebase --abort" to go back to your original state.


-- 
Alexander Kostikov

Re: Rebase doesn't restore branch pointer back on out of memory

From: Andrew Wong <hidden>
Date: 2016-06-15 22:54:57

'format-patch' is failing due to out of memory, and the error not being caught.
So 'rebase' thinks 'am' has completed successfully and continue on with
cleanup. i.e. move_to_original_branch
So the user loses commits from the original head, and have to rely on reflog to
return to the original head.

Since the exit status of 'format-patch' is not available, we have to use ||
with 'format-patch' to handle the error.  Also, when 'format-patch' fails, the
state_dir does not necessarily exist, so I'm putting the 'format-patch-failed'
file inside GIT_DIR. Is there a better location to put such a file?

The way I handle the error feels a bit bruteforced.  Any suggestions on a
better way to handle the error?

I also thought about separating 'format-patch' and 'am' into two separate
commands, and use an intermediate file to store the output of 'format-patch'.
But the intermediate file could get very big, so it didn't seem like a good
idea.

Andrew Wong (1):
  rebase: Handle cases where format-patch fails

 git-rebase--am.sh | 37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

-- 
1.8.0.rc0.18.gf84667d

[RFC] rebase: Handle cases where format-patch fails

From: Andrew Wong <hidden>
Date: 2016-06-15 22:54:57

'format-patch' could fail due to reasons such as out of memory. Such
failures are not detected or handled, which causes rebase to incorrectly
think that it completed successfully and continue with cleanup. i.e.
calling move_to_original_branch

Since only the exit status of the last command in the pipeline is
available, we rely on || to detect whether 'format-patch' has failed.

Also print messages to help user with how to recover from such failures.

Signed-off-by: Andrew Wong <redacted>
---
 git-rebase--am.sh | 37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/git-rebase--am.sh b/git-rebase--am.sh
index 392ebc9..8dae804 100644
--- a/git-rebase--am.sh
+++ b/git-rebase--am.sh
@@ -26,10 +26,43 @@ then
 	# makes this easy
 	git cherry-pick --allow-empty "$revisions"
 else
-	git format-patch -k --stdout --full-index --ignore-if-in-upstream \
+	( git format-patch -k --stdout --full-index --ignore-if-in-upstream \
 		--src-prefix=a/ --dst-prefix=b/ \
-		--no-renames $root_flag "$revisions" |
+		--no-renames $root_flag "$revisions" ||
+		echo $? > "$GIT_DIR"/format-patch-failed ) |
 	git am $git_am_opt --rebasing --resolvemsg="$resolvemsg"
+	ret=$?
+	if test -f "$GIT_DIR"/format-patch-failed
+	then
+		ret=1
+		rm -f "$GIT_DIR"/format-patch-failed
+		if test -d "$state_dir"
+		then
+			echo
+			echo "'git format-patch' seems to have failed in the middle of 'git am'."
+			echo "If you continue rebasing, you will likely be losing some commits."
+			echo "It is recommended that you abort rebasing by running:"
+			echo
+			echo "    git rebase --abort"
+			echo
+		else
+			echo
+			echo "'git format-patch' seems to have failed before 'git am' started."
+			echo "It is impossible to continue or abort rebasing."
+			echo "You have to use the following to return to your original head:"
+			echo
+			case "$head_name" in
+			refs/*)
+				echo "    git checkout $head_name"
+				;;
+			*)
+				echo "    git checkout $orig_head"
+				;;
+			esac
+			echo
+		fi
+	fi
+	test 0 != $ret && false
 fi && move_to_original_branch
 
 ret=$?
-- 
1.8.0.rc0.18.gf84667d
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help