mirror of
https://github.com/git-for-windows/git.git
synced 2026-06-14 04:57:32 -05:00
Merge branch 'sn/rebase-update-refs-symrefs' into seen
"git rebase --update-refs" has been taught to resolve local branch symrefs to their referents before queuing updates. This correctly skips aliases of the current branch and avoids duplicate updates for underlying real branches, fixing failures when branch aliases (like a default branch rename) are present. * sn/rebase-update-refs-symrefs: rebase: skip branch symref aliases
This commit is contained in:
43
sequencer.c
43
sequencer.c
@@ -6460,28 +6460,46 @@ static int add_decorations_to_list(const struct commit *commit,
|
||||
struct todo_add_branch_context *ctx)
|
||||
{
|
||||
const struct name_decoration *decoration = get_name_decoration(&commit->object);
|
||||
const char *head_ref = refs_resolve_ref_unsafe(get_main_ref_store(the_repository),
|
||||
"HEAD",
|
||||
RESOLVE_REF_READING,
|
||||
NULL,
|
||||
NULL);
|
||||
struct ref_store *refs = get_main_ref_store(the_repository);
|
||||
char *head_ref = refs_resolve_refdup(refs, "HEAD",
|
||||
RESOLVE_REF_READING,
|
||||
NULL, NULL);
|
||||
|
||||
while (decoration) {
|
||||
struct todo_item *item;
|
||||
const char *path;
|
||||
const char *resolved_ref;
|
||||
int flags = 0;
|
||||
size_t base_offset = ctx->buf->len;
|
||||
|
||||
/*
|
||||
* If the branch is the current HEAD, then it will be
|
||||
* updated by the default rebase behavior.
|
||||
* Exclude it from the list of refs to update,
|
||||
* as well as any non-branch decorations.
|
||||
* Non-branch decorations may be present if the pretty format
|
||||
* includes "%d", which would have loaded all refs
|
||||
* into the global decoration table.
|
||||
*/
|
||||
if ((head_ref && !strcmp(head_ref, decoration->name)) ||
|
||||
(decoration->type != DECORATION_REF_LOCAL)) {
|
||||
if (decoration->type != DECORATION_REF_LOCAL) {
|
||||
decoration = decoration->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
path = branch_checked_out(decoration->name);
|
||||
|
||||
/*
|
||||
* If the branch is the current HEAD, then it will be
|
||||
* updated by the default rebase behavior. Exclude it from
|
||||
* the list of refs to update, unless it is checked out and
|
||||
* needs a comment in the todo list.
|
||||
*/
|
||||
if (!path && head_ref && !strcmp(head_ref, decoration->name)) {
|
||||
decoration = decoration->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
resolved_ref = refs_resolve_ref_unsafe(refs, decoration->name,
|
||||
RESOLVE_REF_READING,
|
||||
NULL, &flags);
|
||||
if (!path && resolved_ref && (flags & REF_ISSYMREF) &&
|
||||
starts_with(resolved_ref, "refs/heads/")) {
|
||||
decoration = decoration->next;
|
||||
continue;
|
||||
}
|
||||
@@ -6493,7 +6511,7 @@ static int add_decorations_to_list(const struct commit *commit,
|
||||
memset(item, 0, sizeof(*item));
|
||||
|
||||
/* If the branch is checked out, then leave a comment instead. */
|
||||
if ((path = branch_checked_out(decoration->name))) {
|
||||
if (path) {
|
||||
item->command = TODO_COMMENT;
|
||||
strbuf_commented_addf(ctx->buf, comment_line_str,
|
||||
"Ref %s checked out at '%s'\n",
|
||||
@@ -6516,6 +6534,7 @@ static int add_decorations_to_list(const struct commit *commit,
|
||||
decoration = decoration->next;
|
||||
}
|
||||
|
||||
free(head_ref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1979,11 +1979,18 @@ test_expect_success '--update-refs ignores non-branch decorations' '
|
||||
'
|
||||
|
||||
test_expect_success '--update-refs updates refs correctly' '
|
||||
test_when_finished "
|
||||
test_might_fail git symbolic-ref -d refs/heads/no-conflict-branch-alias &&
|
||||
test_might_fail git symbolic-ref -d refs/heads/second-alias
|
||||
" &&
|
||||
git checkout -B update-refs no-conflict-branch &&
|
||||
git branch -f base HEAD~4 &&
|
||||
git branch -f first HEAD~3 &&
|
||||
git branch -f second HEAD~3 &&
|
||||
git branch -f third HEAD~1 &&
|
||||
git symbolic-ref refs/heads/no-conflict-branch-alias \
|
||||
refs/heads/no-conflict-branch &&
|
||||
git symbolic-ref refs/heads/second-alias refs/heads/second &&
|
||||
test_commit extra2 fileX &&
|
||||
git commit --amend --fixup=L &&
|
||||
|
||||
@@ -1991,8 +1998,16 @@ test_expect_success '--update-refs updates refs correctly' '
|
||||
|
||||
test_cmp_rev HEAD~3 refs/heads/first &&
|
||||
test_cmp_rev HEAD~3 refs/heads/second &&
|
||||
test_cmp_rev HEAD~3 refs/heads/second-alias &&
|
||||
test_cmp_rev HEAD~1 refs/heads/third &&
|
||||
test_cmp_rev HEAD refs/heads/no-conflict-branch &&
|
||||
test_cmp_rev HEAD refs/heads/no-conflict-branch-alias &&
|
||||
test_write_lines refs/heads/no-conflict-branch >expect &&
|
||||
git symbolic-ref refs/heads/no-conflict-branch-alias >actual &&
|
||||
test_cmp expect actual &&
|
||||
test_write_lines refs/heads/second >expect &&
|
||||
git symbolic-ref refs/heads/second-alias >actual &&
|
||||
test_cmp expect actual &&
|
||||
|
||||
q_to_tab >expect <<-\EOF &&
|
||||
Successfully rebased and updated refs/heads/update-refs.
|
||||
|
||||
Reference in New Issue
Block a user