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;
+ 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;
+ }
+
+ resolved_ref = refs_resolve_refdup(refs, decoration->name,
+ RESOLVE_REF_READING,
+ NULL, &flags);
+ if (resolved_ref && (flags & REF_ISSYMREF) &&
+ starts_with(resolved_ref, "refs/heads/")) {
+ free(resolved_ref);
+ decoration = decoration->next;
+ continue;
+ }
+
+ /*
+ * If the branch is the current HEAD, then it will be
+ * updated by the default rebase behavior.
+ */
+ if (head_ref && !strcmp(head_ref, decoration->name)) {
+ free(resolved_ref);
decoration = decoration->next;
continue;
}
+ path = branch_checked_out(decoration->name);
+
ALLOC_GROW(ctx->items,
ctx->items_nr + 1,
ctx->items_alloc);
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",
item->arg_len = ctx->buf->len - base_offset;
ctx->items_nr++;
+ free(resolved_ref);
decoration = decoration->next;
}
+ free(head_ref);
return 0;
}
) &&
grep ^update-ref todo >actual &&
test_write_lines "update-ref refs/heads/no-conflict-branch" >expect &&
+ test_grep ! "^# Ref refs/heads/update-refs checked out" todo &&
test_cmp expect actual
'
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 &&
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.