rebase: add --show-current-patch

It is useful to see the full patch while resolving conflicts in a rebase. The only way to do it now is less .git/rebase-*/patch which could turn out to be a lot longer to type if you are in a linked worktree, or not at top-dir. On top of that, an ordinary user should not need to peek into .git directory. The new option is provided to examine the patch. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Feb 11, 2018 at 16:43 UTC 66335298a47032267edd6d6e7a71cc337e46e995
9 files changed +71 -4
Documentation/git-rebase.txt
+5 -1
@@ -12,7 +12,7 @@ SYNOPSIS
12 [<upstream> [<branch>]]
13 'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
14 --root [<branch>]
15 -'git rebase' --continue | --skip | --abort | --quit | --edit-todo
15 +'git rebase' --continue | --skip | --abort | --quit | --edit-todo | --show-current-patch
16
17 DESCRIPTION
18 -----------
@@ -250,6 +250,10 @@ leave out at most one of A and B, in which case it defaults to HEAD.
250 --edit-todo::
251 Edit the todo list during an interactive rebase.
252
253 +--show-current-patch::
254 + Show the current patch in an interactive rebase or when rebase
255 + is stopped because of conflicts.
256 +
257 -m::
258 --merge::
259 Use merging strategies to rebase. When the recursive (default) merge
builtin/am.c
+11
@@ -2126,6 +2126,17 @@ static int show_patch(struct am_state *state)
2126 const char *patch_path;
2127 int len;
2128
2129 + if (!is_null_oid(&state->orig_commit)) {
2130 + const char *av[4] = { "show", NULL, "--", NULL };
2131 + char *new_oid_str;
2132 + int ret;
2133 +
2134 + av[1] = new_oid_str = xstrdup(oid_to_hex(&state->orig_commit));
2135 + ret = run_command_v_opt(av, RUN_GIT_CMD);
2136 + free(new_oid_str);
2137 + return ret;
2138 + }
2139 +
2140 patch_path = am_path(state, msgnum(state));
2141 len = strbuf_read_file(&sb, patch_path, 0);
2142 if (len < 0)
contrib/completion/git-completion.bash
+2 -2
@@ -1992,11 +1992,11 @@ _git_rebase ()
1992 {
1993 __git_find_repo_path
1994 if [ -f "$__git_repo_path"/rebase-merge/interactive ]; then
1995 - __gitcomp "--continue --skip --abort --quit --edit-todo"
1995 + __gitcomp "--continue --skip --abort --quit --edit-todo --show-current-patch"
1996 return
1997 elif [ -d "$__git_repo_path"/rebase-apply ] || \
1998 [ -d "$__git_repo_path"/rebase-merge ]; then
1999 - __gitcomp "--continue --skip --abort --quit"
1999 + __gitcomp "--continue --skip --abort --quit --show-current-patch"
2000 return
2001 fi
2002 __git_complete_strategy && return
git-rebase--am.sh
+3
@@ -27,6 +27,9 @@ skip)
27 move_to_original_branch
28 return
29 ;;
30 +show-current-patch)
31 + exec git am --show-current-patch
32 + ;;
33 esac
34
35 if test -z "$rebase_root"
git-rebase--interactive.sh
+3
@@ -840,6 +840,9 @@ To continue rebase after editing, run:
840
841 exit
842 ;;
843 +show-current-patch)
844 + exec git show "$(cat "$state_dir/stopped-sha")" --
845 + ;;
846 esac
847
848 comment_for_reflog start
git-rebase--merge.sh
+3
@@ -137,6 +137,9 @@ skip)
137 finish_rb_merge
138 return
139 ;;
140 +show-current-patch)
141 + exec git show "$(cat "$state_dir/current")" --
142 + ;;
143 esac
144
145 mkdir -p "$state_dir"
git-rebase.sh
+6 -1
@@ -45,6 +45,7 @@ abort! abort and check out the original branch
45 skip! skip current patch and continue
46 edit-todo! edit the todo list during an interactive rebase
47 quit! abort but keep HEAD where it is
48 +show-current-patch! show the patch file being applied or merged
49 "
50 . git-sh-setup
51 set_reflog_action rebase
@@ -245,7 +246,7 @@ do
246 --verify)
247 ok_to_skip_pre_rebase=
248 ;;
248 - --continue|--skip|--abort|--quit|--edit-todo)
249 + --continue|--skip|--abort|--quit|--edit-todo|--show-current-patch)
250 test $total_argc -eq 2 || usage
251 action=${1##--}
252 ;;
@@ -412,6 +413,10 @@ quit)
413 edit-todo)
414 run_specific_rebase
415 ;;
416 +show-current-patch)
417 + run_specific_rebase
418 + die "BUG: run_specific_rebase is not supposed to return here"
419 + ;;
420 esac
421
422 # Make sure no rebase is in progress
t/t3400-rebase.sh
+33
@@ -277,4 +277,37 @@ EOF
277 test_cmp From_.msg out
278 '
279
280 +test_expect_success 'rebase--am.sh and --show-current-patch' '
281 + test_create_repo conflict-apply &&
282 + (
283 + cd conflict-apply &&
284 + test_commit init &&
285 + echo one >>init.t &&
286 + git commit -a -m one &&
287 + echo two >>init.t &&
288 + git commit -a -m two &&
289 + git tag two &&
290 + test_must_fail git rebase --onto init HEAD^ &&
291 + GIT_TRACE=1 git rebase --show-current-patch >/dev/null 2>stderr &&
292 + grep "show.*$(git rev-parse two)" stderr
293 + )
294 +'
295 +
296 +test_expect_success 'rebase--merge.sh and --show-current-patch' '
297 + test_create_repo conflict-merge &&
298 + (
299 + cd conflict-merge &&
300 + test_commit init &&
301 + echo one >>init.t &&
302 + git commit -a -m one &&
303 + echo two >>init.t &&
304 + git commit -a -m two &&
305 + git tag two &&
306 + test_must_fail git rebase --merge --onto init HEAD^ &&
307 + git rebase --show-current-patch >actual.patch &&
308 + GIT_TRACE=1 git rebase --show-current-patch >/dev/null 2>stderr &&
309 + grep "show.*$(git rev-parse two)" stderr
310 + )
311 +'
312 +
313 test_done
t/t3404-rebase-interactive.sh
+5
@@ -225,6 +225,11 @@ test_expect_success 'stop on conflicting pick' '
225 test 0 = $(grep -c "^[^#]" < .git/rebase-merge/git-rebase-todo)
226 '
227
228 +test_expect_success 'show conflicted patch' '
229 + GIT_TRACE=1 git rebase --show-current-patch >/dev/null 2>stderr &&
230 + grep "show.*$(cat "$state_dir/stopped-sha")" stderr
231 +'
232 +
233 test_expect_success 'abort' '
234 git rebase --abort &&
235 test $(git rev-parse new-branch1) = $(git rev-parse HEAD) &&