Skip to content

Commit fbd7a23

Browse files
pcloudsgitster
authored andcommitted
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>
1 parent 6633529 commit fbd7a23

File tree

9 files changed

+25
-6
lines changed

9 files changed

+25
-6
lines changed

Documentation/git-rebase.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,8 @@ leave out at most one of A and B, in which case it defaults to HEAD.
252252

253253
--show-current-patch::
254254
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`.
256257

257258
-m::
258259
--merge::

builtin/am.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,7 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
10111011

10121012
if (mkdir(state->dir, 0777) < 0 && errno != EEXIST)
10131013
die_errno(_("failed to create directory '%s'"), state->dir);
1014+
delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);
10141015

10151016
if (split_mail(state, patch_format, paths, keep_cr) < 0) {
10161017
am_destroy(state);
@@ -1110,6 +1111,7 @@ static void am_next(struct am_state *state)
11101111

11111112
oidclr(&state->orig_commit);
11121113
unlink(am_path(state, "original-commit"));
1114+
delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);
11131115

11141116
if (!get_oid("HEAD", &head))
11151117
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)
14411443

14421444
oidcpy(&state->orig_commit, &commit_oid);
14431445
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);
14441448

14451449
return 0;
14461450
}

contrib/completion/git-completion.bash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ __git_refs ()
439439
track=""
440440
;;
441441
*)
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
443443
case "$i" in
444444
$match*)
445445
if [ -e "$dir/$i" ]; then

git-rebase--interactive.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,12 +199,14 @@ make_patch () {
199199

200200
die_with_patch () {
201201
echo "$1" > "$state_dir"/stopped-sha
202+
git update-ref REBASE_HEAD "$1"
202203
make_patch "$1"
203204
die "$2"
204205
}
205206

206207
exit_with_patch () {
207208
echo "$1" > "$state_dir"/stopped-sha
209+
git update-ref REBASE_HEAD "$1"
208210
make_patch $1
209211
git rev-parse --verify HEAD > "$amend"
210212
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:
841843
exit
842844
;;
843845
show-current-patch)
844-
exec git show "$(cat "$state_dir/stopped-sha")" --
846+
exec git show REBASE_HEAD --
845847
;;
846848
esac
847849

@@ -858,6 +860,7 @@ fi
858860

859861
orig_head=$(git rev-parse --verify HEAD) || die "$(gettext "No HEAD?")"
860862
mkdir -p "$state_dir" || die "$(eval_gettext "Could not create temporary \$state_dir")"
863+
rm -f "$(git rev-parse --git-path REBASE_HEAD)"
861864

862865
: > "$state_dir"/interactive || die "$(gettext "Could not mark as interactive")"
863866
write_basic_state

git-rebase--merge.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ call_merge () {
5757
echo "$msgnum" >"$state_dir/msgnum"
5858
cmt="$(cat "$state_dir/cmt.$msgnum")"
5959
echo "$cmt" > "$state_dir/current"
60+
git update-ref REBASE_HEAD "$cmt"
6061
hd=$(git rev-parse --verify HEAD)
6162
cmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD)
6263
eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"'
@@ -138,13 +139,14 @@ skip)
138139
return
139140
;;
140141
show-current-patch)
141-
exec git show "$(cat "$state_dir/current")" --
142+
exec git show REBASE_HEAD --
142143
;;
143144
esac
144145

145146
mkdir -p "$state_dir"
146147
echo "$onto_name" > "$state_dir/onto_name"
147148
write_basic_state
149+
rm -f "$(git rev-parse --git-path REBASE_HEAD)"
148150

149151
msgnum=0
150152
for cmt in $(git rev-list --reverse --no-merges "$revisions")

git-rebase.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ You can run "git stash pop" or "git stash drop" at any time.
182182
}
183183

184184
finish_rebase () {
185+
rm -f "$(git rev-parse --git-path REBASE_HEAD)"
185186
apply_autostash &&
186187
{ git gc --auto || true; } &&
187188
rm -rf "$state_dir"

sequencer.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,6 +1792,9 @@ static int make_patch(struct commit *commit, struct replay_opts *opts)
17921792
p = short_commit_name(commit);
17931793
if (write_message(p, strlen(p), rebase_path_stopped_sha(), 1) < 0)
17941794
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");
17951798

17961799
strbuf_addf(&buf, "%s/patch", get_dir(opts));
17971800
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)
20432046
unlink(rebase_path_author_script());
20442047
unlink(rebase_path_stopped_sha());
20452048
unlink(rebase_path_amend());
2049+
delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);
20462050
}
20472051
if (item->command <= TODO_SQUASH) {
20482052
if (is_rebase_i(opts))

t/t3400-rebase.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,8 @@ test_expect_success 'rebase--merge.sh and --show-current-patch' '
306306
test_must_fail git rebase --merge --onto init HEAD^ &&
307307
git rebase --show-current-patch >actual.patch &&
308308
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)"
310311
)
311312
'
312313

t/t3404-rebase-interactive.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,10 @@ test_expect_success 'stop on conflicting pick' '
227227

228228
test_expect_success 'show conflicted patch' '
229229
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"
231234
'
232235

233236
test_expect_success 'abort' '

0 commit comments

Comments
 (0)