Skip to content

Commit c042c45

Browse files
committed
Merge branch 'pw/rebase-i-orig-head'
"git rebase -i" did not store ORIG_HEAD correctly. * pw/rebase-i-orig-head: rebase -i: simplify get_revision_ranges() rebase -i: use struct object_id when writing state rebase -i: use struct object_id rather than looking up commit rebase -i: stop overwriting ORIG_HEAD buffer
2 parents ede4d63 + 8843302 commit c042c45

File tree

4 files changed

+31
-22
lines changed

4 files changed

+31
-22
lines changed

builtin/rebase.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -270,15 +270,14 @@ static int edit_todo_file(unsigned flags)
270270
}
271271

272272
static int get_revision_ranges(struct commit *upstream, struct commit *onto,
273-
struct object_id *orig_head, const char **head_hash,
274-
char **revisions, char **shortrevisions)
273+
struct object_id *orig_head, char **revisions,
274+
char **shortrevisions)
275275
{
276276
struct commit *base_rev = upstream ? upstream : onto;
277277
const char *shorthead;
278278

279-
*head_hash = find_unique_abbrev(orig_head, GIT_MAX_HEXSZ);
280279
*revisions = xstrfmt("%s...%s", oid_to_hex(&base_rev->object.oid),
281-
*head_hash);
280+
oid_to_hex(orig_head));
282281

283282
shorthead = find_unique_abbrev(orig_head, DEFAULT_ABBREV);
284283

@@ -296,7 +295,8 @@ static int get_revision_ranges(struct commit *upstream, struct commit *onto,
296295
}
297296

298297
static int init_basic_state(struct replay_opts *opts, const char *head_name,
299-
struct commit *onto, const char *orig_head)
298+
struct commit *onto,
299+
const struct object_id *orig_head)
300300
{
301301
FILE *interactive;
302302

@@ -327,20 +327,19 @@ static void split_exec_commands(const char *cmd, struct string_list *commands)
327327
static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
328328
{
329329
int ret;
330-
const char *head_hash = NULL;
331330
char *revisions = NULL, *shortrevisions = NULL;
332331
struct strvec make_script_args = STRVEC_INIT;
333332
struct todo_list todo_list = TODO_LIST_INIT;
334333
struct replay_opts replay = get_replay_opts(opts);
335334
struct string_list commands = STRING_LIST_INIT_DUP;
336335

337336
if (get_revision_ranges(opts->upstream, opts->onto, &opts->orig_head,
338-
&head_hash, &revisions, &shortrevisions))
337+
&revisions, &shortrevisions))
339338
return -1;
340339

341340
if (init_basic_state(&replay,
342341
opts->head_name ? opts->head_name : "detached HEAD",
343-
opts->onto, head_hash)) {
342+
opts->onto, &opts->orig_head)) {
344343
free(revisions);
345344
free(shortrevisions);
346345

@@ -370,8 +369,9 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
370369

371370
split_exec_commands(opts->cmd, &commands);
372371
ret = complete_action(the_repository, &replay, flags,
373-
shortrevisions, opts->onto_name, opts->onto, head_hash,
374-
&commands, opts->autosquash, &todo_list);
372+
shortrevisions, opts->onto_name, opts->onto,
373+
&opts->orig_head, &commands, opts->autosquash,
374+
&todo_list);
375375
}
376376

377377
string_list_clear(&commands, 0);

sequencer.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2690,15 +2690,16 @@ static void write_strategy_opts(struct replay_opts *opts)
26902690
}
26912691

26922692
int write_basic_state(struct replay_opts *opts, const char *head_name,
2693-
struct commit *onto, const char *orig_head)
2693+
struct commit *onto, const struct object_id *orig_head)
26942694
{
26952695
if (head_name)
26962696
write_file(rebase_path_head_name(), "%s\n", head_name);
26972697
if (onto)
26982698
write_file(rebase_path_onto(), "%s\n",
26992699
oid_to_hex(&onto->object.oid));
27002700
if (orig_head)
2701-
write_file(rebase_path_orig_head(), "%s\n", orig_head);
2701+
write_file(rebase_path_orig_head(), "%s\n",
2702+
oid_to_hex(orig_head));
27022703

27032704
if (opts->quiet)
27042705
write_file(rebase_path_quiet(), "%s", "");
@@ -3964,21 +3965,17 @@ static int run_git_checkout(struct repository *r, struct replay_opts *opts,
39643965

39653966
static int checkout_onto(struct repository *r, struct replay_opts *opts,
39663967
const char *onto_name, const struct object_id *onto,
3967-
const char *orig_head)
3968+
const struct object_id *orig_head)
39683969
{
3969-
struct object_id oid;
39703970
const char *action = reflog_message(opts, "start", "checkout %s", onto_name);
39713971

3972-
if (get_oid(orig_head, &oid))
3973-
return error(_("%s: not a valid OID"), orig_head);
3974-
39753972
if (run_git_checkout(r, opts, oid_to_hex(onto), action)) {
39763973
apply_autostash(rebase_path_autostash());
39773974
sequencer_remove_state(opts);
39783975
return error(_("could not detach HEAD"));
39793976
}
39803977

3981-
return update_ref(NULL, "ORIG_HEAD", &oid, NULL, 0, UPDATE_REFS_MSG_ON_ERR);
3978+
return update_ref(NULL, "ORIG_HEAD", orig_head, NULL, 0, UPDATE_REFS_MSG_ON_ERR);
39823979
}
39833980

39843981
static int stopped_at_head(struct repository *r)
@@ -5294,7 +5291,7 @@ static int skip_unnecessary_picks(struct repository *r,
52945291

52955292
int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags,
52965293
const char *shortrevisions, const char *onto_name,
5297-
struct commit *onto, const char *orig_head,
5294+
struct commit *onto, const struct object_id *orig_head,
52985295
struct string_list *commands, unsigned autosquash,
52995296
struct todo_list *todo_list)
53005297
{

sequencer.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,9 @@ void todo_list_add_exec_commands(struct todo_list *todo_list,
161161
struct string_list *commands);
162162
int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags,
163163
const char *shortrevisions, const char *onto_name,
164-
struct commit *onto, const char *orig_head, struct string_list *commands,
165-
unsigned autosquash, struct todo_list *todo_list);
164+
struct commit *onto, const struct object_id *orig_head,
165+
struct string_list *commands, unsigned autosquash,
166+
struct todo_list *todo_list);
166167
int todo_list_rearrange_squash(struct todo_list *todo_list);
167168

168169
/*
@@ -224,7 +225,7 @@ int read_author_script(const char *path, char **name, char **email, char **date,
224225
int allow_missing);
225226
void parse_strategy_opts(struct replay_opts *opts, char *raw_opts);
226227
int write_basic_state(struct replay_opts *opts, const char *head_name,
227-
struct commit *onto, const char *orig_head);
228+
struct commit *onto, const struct object_id *orig_head);
228229
void sequencer_post_commit_cleanup(struct repository *r, int verbose);
229230
int sequencer_get_last_command(struct repository* r,
230231
enum replay_action *action);

t/t3404-rebase-interactive.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,17 @@ test_expect_success 'todo has correct onto hash' '
17971797
test_i18ngrep "^# Rebase ..* onto $onto" actual
17981798
'
17991799

1800+
test_expect_success 'ORIG_HEAD is updated correctly' '
1801+
test_when_finished "git checkout master && git branch -D test-orig-head" &&
1802+
git checkout -b test-orig-head A &&
1803+
git commit --allow-empty -m A1 &&
1804+
git commit --allow-empty -m A2 &&
1805+
git commit --allow-empty -m A3 &&
1806+
git commit --allow-empty -m A4 &&
1807+
git rebase master &&
1808+
test_cmp_rev ORIG_HEAD test-orig-head@{1}
1809+
'
1810+
18001811
# This must be the last test in this file
18011812
test_expect_success '$EDITOR and friends are unchanged' '
18021813
test_editor_unchanged

0 commit comments

Comments
 (0)