rebase: introduce and use pseudo-ref REBASE_HEAD
The new command `git rebase --show-current-patch` is useful for seeing the commit related to the current rebase state. Some however may find the "git show" command behind it too limiting. You may want to increase context lines, do a diff that ignores whitespaces... For these advanced use cases, the user can execute any command they want with the new pseudo ref REBASE_HEAD. This also helps show where the stopped commit is from, which is hard to see from the previous patch which implements --show-current-patch. Helped-by: Tim Landscheidt <tim@tim-landscheidt.de> 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
fbd7a23237094c3fb2e249bbcacbbf1e858e79c9
9 files changed
+25
-6
Documentation/git-rebase.txt
+2
-1
@@ -252,7 +252,8 @@ leave out at most one of A and B, in which case it defaults to HEAD.
252
253
--show-current-patch::
254
Show the current patch in an interactive rebase or when rebase
255
- is stopped because of conflicts.
255
+ is stopped because of conflicts. This is the equivalent of
256
+ `git show REBASE_HEAD`.
257
258
-m::
259
--merge::
builtin/am.c
+4
@@ -1011,6 +1011,7 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
1011
1012
if (mkdir(state->dir, 0777) < 0 && errno != EEXIST)
1013
die_errno(_("failed to create directory '%s'"), state->dir);
1014
+ delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);
1015
1016
if (split_mail(state, patch_format, paths, keep_cr) < 0) {
1017
am_destroy(state);
@@ -1110,6 +1111,7 @@ static void am_next(struct am_state *state)
1111
1112
oidclr(&state->orig_commit);
1113
unlink(am_path(state, "original-commit"));
1114
+ delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);
1115
1116
if (!get_oid("HEAD", &head))
1117
write_state_text(state, "abort-safety", oid_to_hex(&head));
@@ -1441,6 +1443,8 @@ static int parse_mail_rebase(struct am_state *state, const char *mail)
1443
1444
oidcpy(&state->orig_commit, &commit_oid);
1445
write_state_text(state, "original-commit", oid_to_hex(&commit_oid));
1446
+ update_ref("am", "REBASE_HEAD", &commit_oid,
1447
+ NULL, REF_NO_DEREF, UPDATE_REFS_DIE_ON_ERR);
1448
1449
return 0;
1450
}
contrib/completion/git-completion.bash
+1
-1
@@ -439,7 +439,7 @@ __git_refs ()
439
track=""
440
;;
441
*)
442
- for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
442
+ for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD REBASE_HEAD; do
443
case "$i" in
444
$match*)
445
if [ -e "$dir/$i" ]; then
git-rebase--interactive.sh
+4
-1
@@ -199,12 +199,14 @@ make_patch () {
199
200
die_with_patch () {
201
echo "$1" > "$state_dir"/stopped-sha
202
+ git update-ref REBASE_HEAD "$1"
203
make_patch "$1"
204
die "$2"
205
}
206
207
exit_with_patch () {
208
echo "$1" > "$state_dir"/stopped-sha
209
+ git update-ref REBASE_HEAD "$1"
210
make_patch $1
211
git rev-parse --verify HEAD > "$amend"
212
gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")}
@@ -841,7 +843,7 @@ To continue rebase after editing, run:
843
exit
844
;;
845
show-current-patch)
844
- exec git show "$(cat "$state_dir/stopped-sha")" --
846
+ exec git show REBASE_HEAD --
847
;;
848
esac
849
@@ -858,6 +860,7 @@ fi
860
861
orig_head=$(git rev-parse --verify HEAD) || die "$(gettext "No HEAD?")"
862
mkdir -p "$state_dir" || die "$(eval_gettext "Could not create temporary \$state_dir")"
863
+rm -f "$(git rev-parse --git-path REBASE_HEAD)"
864
865
: > "$state_dir"/interactive || die "$(gettext "Could not mark as interactive")"
866
write_basic_state
git-rebase--merge.sh
+3
-1
@@ -57,6 +57,7 @@ call_merge () {
57
echo "$msgnum" >"$state_dir/msgnum"
58
cmt="$(cat "$state_dir/cmt.$msgnum")"
59
echo "$cmt" > "$state_dir/current"
60
+ git update-ref REBASE_HEAD "$cmt"
61
hd=$(git rev-parse --verify HEAD)
62
cmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD)
63
eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"'
@@ -138,13 +139,14 @@ skip)
139
return
140
;;
141
show-current-patch)
141
- exec git show "$(cat "$state_dir/current")" --
142
+ exec git show REBASE_HEAD --
143
;;
144
esac
145
146
mkdir -p "$state_dir"
147
echo "$onto_name" > "$state_dir/onto_name"
148
write_basic_state
149
+rm -f "$(git rev-parse --git-path REBASE_HEAD)"
150
151
msgnum=0
152
for cmt in $(git rev-list --reverse --no-merges "$revisions")
git-rebase.sh
+1
@@ -182,6 +182,7 @@ You can run "git stash pop" or "git stash drop" at any time.
182
}
183
184
finish_rebase () {
185
+ rm -f "$(git rev-parse --git-path REBASE_HEAD)"
186
apply_autostash &&
187
{ git gc --auto || true; } &&
188
rm -rf "$state_dir"
sequencer.c
+4
@@ -1792,6 +1792,9 @@ static int make_patch(struct commit *commit, struct replay_opts *opts)
1792
p = short_commit_name(commit);
1793
if (write_message(p, strlen(p), rebase_path_stopped_sha(), 1) < 0)
1794
return -1;
1795
+ if (update_ref("rebase", "REBASE_HEAD", &commit->object.oid,
1796
+ NULL, REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR))
1797
+ res |= error(_("could not update %s"), "REBASE_HEAD");
1798
1799
strbuf_addf(&buf, "%s/patch", get_dir(opts));
1800
memset(&log_tree_opt, 0, sizeof(log_tree_opt));
@@ -2043,6 +2046,7 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
2046
unlink(rebase_path_author_script());
2047
unlink(rebase_path_stopped_sha());
2048
unlink(rebase_path_amend());
2049
+ delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);
2050
}
2051
if (item->command <= TODO_SQUASH) {
2052
if (is_rebase_i(opts))
t/t3400-rebase.sh
+2
-1
@@ -306,7 +306,8 @@ test_expect_success 'rebase--merge.sh and --show-current-patch' '
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
309
+ grep "show.*REBASE_HEAD" stderr &&
310
+ test "$(git rev-parse REBASE_HEAD)" = "$(git rev-parse two)"
311
)
312
'
313
t/t3404-rebase-interactive.sh
+4
-1
@@ -227,7 +227,10 @@ test_expect_success 'stop on conflicting pick' '
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
230
+ grep "show.*REBASE_HEAD" stderr &&
231
+ # the original stopped-sha1 is abbreviated
232
+ stopped_sha1="$(git rev-parse $(cat ".git/rebase-merge/stopped-sha"))" &&
233
+ test "$(git rev-parse REBASE_HEAD)" = "$stopped_sha1"
234
'
235
236
test_expect_success 'abort' '