Skip to content

Commit 47978e8

Browse files
committed
rebase: copy extra commit headers
1 parent a36e024 commit 47978e8

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

sequencer.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,9 @@ static int parse_head(struct repository *r, struct commit **head)
15271527
return 0;
15281528
}
15291529

1530+
/* Headers to exclude when copying extra commit headers */
1531+
const char *exclude_gpgsig[] = { "gpgsig", "gpgsig-sha256", NULL };
1532+
15301533
/*
15311534
* Try to commit without forking 'git commit'. In some cases we need
15321535
* to run 'git commit' to display an error message
@@ -1538,14 +1541,15 @@ static int parse_head(struct repository *r, struct commit **head)
15381541
*/
15391542
static int try_to_commit(struct repository *r,
15401543
struct strbuf *msg, const char *author,
1544+
struct commit_extra_header *extra_header,
15411545
struct replay_opts *opts, unsigned int flags,
15421546
struct object_id *oid)
15431547
{
15441548
struct replay_ctx *ctx = opts->ctx;
15451549
struct object_id tree;
15461550
struct commit *current_head = NULL;
15471551
struct commit_list *parents = NULL;
1548-
struct commit_extra_header *extra = NULL;
1552+
struct commit_extra_header *extra = extra_header;
15491553
struct strbuf err = STRBUF_INIT;
15501554
struct strbuf commit_msg = STRBUF_INIT;
15511555
char *amend_author = NULL;
@@ -1561,7 +1565,6 @@ static int try_to_commit(struct repository *r,
15611565
return -1;
15621566

15631567
if (flags & AMEND_MSG) {
1564-
const char *exclude_gpgsig[] = { "gpgsig", "gpgsig-sha256", NULL };
15651568
const char *out_enc = get_commit_output_encoding();
15661569
const char *message = repo_logmsg_reencode(r, current_head,
15671570
NULL, out_enc);
@@ -1714,7 +1717,8 @@ static int try_to_commit(struct repository *r,
17141717
commit_post_rewrite(r, current_head, oid);
17151718

17161719
out:
1717-
free_commit_extra_headers(extra);
1720+
if (extra != extra_header)
1721+
free_commit_extra_headers(extra);
17181722
free_commit_list(parents);
17191723
strbuf_release(&err);
17201724
strbuf_release(&commit_msg);
@@ -1734,6 +1738,7 @@ static int write_rebase_head(struct object_id *oid)
17341738

17351739
static int do_commit(struct repository *r,
17361740
const char *msg_file, const char *author,
1741+
struct commit_extra_header *extra_header,
17371742
struct replay_opts *opts, unsigned int flags,
17381743
struct object_id *oid)
17391744
{
@@ -1749,7 +1754,7 @@ static int do_commit(struct repository *r,
17491754
msg_file);
17501755

17511756
res = try_to_commit(r, msg_file ? &sb : NULL,
1752-
author, opts, flags, &oid);
1757+
author, extra_header, opts, flags, &oid);
17531758
strbuf_release(&sb);
17541759
if (!res) {
17551760
refs_delete_ref(get_main_ref_store(r), "",
@@ -2251,6 +2256,7 @@ static int do_pick_commit(struct repository *r,
22512256
int res, unborn = 0, reword = 0, allow, drop_commit;
22522257
enum todo_command command = item->command;
22532258
struct commit *commit = item->commit;
2259+
struct commit_extra_header *extra_header;
22542260

22552261
if (opts->no_commit) {
22562262
/*
@@ -2311,6 +2317,8 @@ static int do_pick_commit(struct repository *r,
23112317
return error(_("cannot get commit message for %s"),
23122318
oid_to_hex(&commit->object.oid));
23132319

2320+
extra_header = read_commit_extra_headers(commit, exclude_gpgsig);
2321+
23142322
if (opts->allow_ff && !is_fixup(command) &&
23152323
((parent && oideq(&parent->object.oid, &head)) ||
23162324
(!parent && unborn))) {
@@ -2503,8 +2511,8 @@ static int do_pick_commit(struct repository *r,
25032511
} /* else allow == 0 and there's nothing special to do */
25042512
if (!opts->no_commit && !drop_commit) {
25052513
if (author || command == TODO_REVERT || (flags & AMEND_MSG))
2506-
res = do_commit(r, msg_file, author, opts, flags,
2507-
commit? &commit->object.oid : NULL);
2514+
res = do_commit(r, msg_file, author, extra_header, opts,
2515+
flags, commit? &commit->object.oid : NULL);
25082516
else
25092517
res = error(_("unable to parse commit author"));
25102518
*check_todo = !!(flags & EDIT_MSG);
@@ -2535,6 +2543,7 @@ static int do_pick_commit(struct repository *r,
25352543
leave:
25362544
free_message(commit, &msg);
25372545
free(author);
2546+
free_commit_extra_headers(extra_header);
25382547
update_abort_safety_file();
25392548

25402549
return res;

t/t3404-rebase-interactive.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2297,6 +2297,25 @@ test_expect_success 'non-merge commands reject merge commits' '
22972297
test_cmp expect actual
22982298
'
22992299

2300+
test_expect_success 'unconflicted pick copies extra commit headers' '
2301+
cat >commit <<-EOF &&
2302+
tree $(git rev-parse C^{tree})
2303+
parent $(git rev-parse C^{commit})
2304+
author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> $GIT_AUTHOR_DATE
2305+
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2306+
x-extra-header some value
2307+
2308+
An empty commit with an extra header
2309+
EOF
2310+
2311+
oid=$(git hash-object -t commit -w commit) &&
2312+
git rebase -i --onto A $oid^ $oid &&
2313+
git cat-file commit HEAD >actual &&
2314+
sed -e /^parent/d -e /^tree/d actual >actual.trimmed &&
2315+
sed -e /^parent/d -e /^tree/d commit >expect &&
2316+
test_cmp expect actual.trimmed
2317+
'
2318+
23002319
# This must be the last test in this file
23012320
test_expect_success '$EDITOR and friends are unchanged' '
23022321
test_editor_unchanged

0 commit comments

Comments
 (0)