rebase: Handle cases where format-patch fails
'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 Instead of using a pipe, we separate 'format-patch' and 'am' by using an intermediate file. This gurantees that we can invoke 'am' with the complete input, or not invoking 'am' at all if 'format-patch' failed. Also remove the use of '&&' at the end of the if-block, and rearrange the 'write_basic_state' and 'move_to_original_branch' to make the logic flow a bit better and easier to read. Signed-off-by: Andrew Wong <andrew.kw.w@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Andrew Wong committed
Oct 10, 2012 at 23:54 UTC
e481af06be6fa112cec9f53fabd51d3b4cc6c64d
1 file changed
+43
-6
git-rebase--am.sh
+43
-6
@@ -18,6 +18,7 @@ esac
18
19
test -n "$rebase_root" && root_flag=--root
20
21
+ret=0
22
if test -n "$keep_empty"
23
then
24
# we have to do this the hard way. git format-patch completely squashes
@@ -25,13 +26,49 @@ then
26
# itself well to recording empty patches. fortunately, cherry-pick
27
# makes this easy
28
git cherry-pick --allow-empty "$revisions"
29
+ ret=$?
30
else
31
+ rm -f "$GIT_DIR/rebased-patches"
32
+
33
git format-patch -k --stdout --full-index --ignore-if-in-upstream \
34
--src-prefix=a/ --dst-prefix=b/ \
31
- --no-renames $root_flag "$revisions" |
32
- git am $git_am_opt --rebasing --resolvemsg="$resolvemsg"
33
-fi && move_to_original_branch
35
+ --no-renames $root_flag "$revisions" >"$GIT_DIR/rebased-patches"
36
+ ret=$?
37
+
38
+ if test 0 != $ret
39
+ then
40
+ rm -f "$GIT_DIR/rebased-patches"
41
+ case "$head_name" in
42
+ refs/heads/*)
43
+ git checkout -q "$head_name"
44
+ ;;
45
+ *)
46
+ git checkout -q "$orig_head"
47
+ ;;
48
+ esac
49
+
50
+ cat >&2 <<-EOF
51
+
52
+ git encountered an error while preparing the patches to replay
53
+ these revisions:
54
+
55
+ $revisions
56
+
57
+ As a result, git cannot rebase them.
58
+ EOF
59
+ exit $?
60
+ fi
61
+
62
+ git am $git_am_opt --rebasing --resolvemsg="$resolvemsg" <"$GIT_DIR/rebased-patches"
63
+ ret=$?
64
+
65
+ rm -f "$GIT_DIR/rebased-patches"
66
+fi
67
+
68
+if test 0 != $ret
69
+then
70
+ test -d "$state_dir" && write_basic_state
71
+ exit $ret
72
+fi
73
35
-ret=$?
36
-test 0 != $ret -a -d "$state_dir" && write_basic_state
37
-exit $ret
74
+move_to_original_branch