From patchwork Mon Apr 8 17:38:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Cai X-Patchwork-Id: 13621444 Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C12451428EE for ; Mon, 8 Apr 2024 17:38:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712597901; cv=none; b=nk4nFDxBxDTaeUGuAEFx7GcD+BHE3pZfK9ybbuGxakesLqaho/27HQYe2pfOMzXI/z+or03HSQkUWAHfBq9w7xExRWO3fP76KXjziNtb/mZ4XqsTmZm4VAcdYpBI2CRWCpHkBCsHThCHeWwPH3JYYneU/4WO4xPGP1A0hsSAscw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712597901; c=relaxed/simple; bh=m4a/LFpPnZf76EWTT6kJ1dpDszrwzJRWye0ISP5cHZA=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=O4lceNRTyfokvYWztHcn/asUdy8lXIa8gMZFTidrA8gvdINBKh8w41pf9o5IleDbuHF+4rvGgDpSZcuEQVMQ3Y1MBgjxD0tc+sTmH7vSrty6+O0T5NLQXuLsAHs2wpo3HxnNaF8EAvsorS9WmhVSvXdl1iqAY2DM4w1MwAdYTf4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=asD+1Ro4; arc=none smtp.client-ip=209.85.221.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="asD+1Ro4" Received: by mail-wr1-f49.google.com with SMTP id ffacd0b85a97d-345e1c645c4so522607f8f.0 for ; Mon, 08 Apr 2024 10:38:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1712597896; x=1713202696; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=SV8q6rJXq1eh5Uu1B7laT+K51IcOaJVQ7JywKtBbkbA=; b=asD+1Ro4cx/t+GCf9ZgogFvBHEO7qrAt2yyEBUCWIa11adbJ0bk4j1qvxbYgxF2sBi fBQTqW3F2MjqzOQUTu28FJlIJlSHtj/vNqhnsdgVE3brKc3oiXAGSCUEGLz9yVGJ58CT ZU+cL8vKZ9mSP/hujpFcQCmujyyQxdd0/a8BoD2HcmHWkJ/h2AtGav/JBX7Xmu2jqrZr 5gIh/ufnQ9k5pN4BPiBSD9Hwd3es9s840FplkrtQz+pmI0TR5xbxES8bBIQ8YYqOMtHt JY+zaVihRwiKEadmjWremxekOuTG8lfiYdoddt8IkXEpjej5sHHwWj992pY3ECEV2nYn 89aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712597896; x=1713202696; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=SV8q6rJXq1eh5Uu1B7laT+K51IcOaJVQ7JywKtBbkbA=; b=svBphHG1+/DiPV95o5bon/2c/FDpIbbYtjTRLQ6zuINxHb+DAKFE0XNCwM67LRA6Y+ RMdUN1TQfdkzVTvLl9sH+zO3fpRNBZrouV2i9M1RJGsgE1cFuoYVcEnzg+HojU29rG00 FgvQMQvImf39WqUQwekO4f6kYxRpvWuTRwAz08tE+lksE7fS3ONw4hKimd2dw9SZKheg NxFzaIECbmK4nFebYg0uAASslVfbe2JnaNqlz8/L6a4m/3FcWsCa6+ur+PO687Z0r1Yw 540AfR0exSPN8hKogN+aLbIq7NyzEjSGK8XMtCFKstSUq4NCgoX07mPUByb7QqXCKncX Pe8g== X-Gm-Message-State: AOJu0YwIZVJObw2DdAjSKCvzhEPCuwepXq11/hfkI0Obnq+c7tFRefC6 i5d1EE78EHsX073Z7JfSm0z9JzCFq9xmzJk8E0RA/c68JOaLxD4JV3ep3e66 X-Google-Smtp-Source: AGHT+IGQOnzLENxm9HNV/rkPaWSVblTpAPIXqJmlgaKHg2SDeyiQtwd3zUQ01XKRLxYK+jPSns72OA== X-Received: by 2002:adf:e4c9:0:b0:343:68ea:c0a3 with SMTP id v9-20020adfe4c9000000b0034368eac0a3mr6008494wrm.54.1712597896321; Mon, 08 Apr 2024 10:38:16 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id k4-20020a5d4284000000b0033e7603987dsm9535846wrq.12.2024.04.08.10.38.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Apr 2024 10:38:15 -0700 (PDT) Message-Id: <6adc9dd26da4459d246591ce148c960b33bde336.1712597893.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Mon, 08 Apr 2024 17:38:11 +0000 Subject: [PATCH v2 1/3] refs: keep track of unresolved reference value in iterator Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: Phillip Wood , Kristoffer Haugsbakk , Jeff King , Patrick Steinhardt , =?utf-8?q?Jean-No=C3=ABl?= Avila , John Cai , John Cai From: John Cai From: John Cai Since ref iterators do not hold onto the direct value of a reference without resolving it, the only way to get ahold of a direct value of a symbolic ref is to make a separate call to refs_read_symbolic_ref. To make accessing the direct value of a symbolic ref more efficient, let's save the direct value of the ref in the iterator for both the files backend and reftable backend. To do so, we also need to add an argument to refs_resolve_ref_unsafe to save the direct value of the reference somewhere. Signed-off-by: John Cai --- builtin/submodule--helper.c | 2 +- refs.c | 23 +++++++++++++---------- refs.h | 3 ++- refs/files-backend.c | 20 +++++++++++--------- refs/iterator.c | 1 + refs/ref-cache.c | 3 +++ refs/ref-cache.h | 2 ++ refs/refs-internal.h | 1 + refs/reftable-backend.c | 13 +++++++++---- remote.c | 2 +- sequencer.c | 4 ++-- t/helper/test-ref-store.c | 2 +- worktree.c | 4 +++- 13 files changed, 50 insertions(+), 30 deletions(-) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index fda50f2af1e..cf9966b7827 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -45,7 +45,7 @@ static int repo_get_default_remote(struct repository *repo, char **default_remot char *dest = NULL; struct strbuf sb = STRBUF_INIT; struct ref_store *store = get_main_ref_store(repo); - const char *refname = refs_resolve_ref_unsafe(store, "HEAD", 0, NULL, + const char *refname = refs_resolve_ref_unsafe(store, "HEAD", NULL, 0, NULL, NULL); if (!refname) diff --git a/refs.c b/refs.c index 55d2e0b2cb9..b87a680249e 100644 --- a/refs.c +++ b/refs.c @@ -379,7 +379,7 @@ char *refs_resolve_refdup(struct ref_store *refs, { const char *result; - result = refs_resolve_ref_unsafe(refs, refname, resolve_flags, + result = refs_resolve_ref_unsafe(refs, refname, NULL, resolve_flags, oid, flags); return xstrdup_or_null(result); } @@ -404,7 +404,7 @@ int read_ref_full(const char *refname, int resolve_flags, struct object_id *oid, { struct ref_store *refs = get_main_ref_store(the_repository); - if (refs_resolve_ref_unsafe(refs, refname, resolve_flags, + if (refs_resolve_ref_unsafe(refs, refname, NULL, resolve_flags, oid, flags)) return 0; return -1; @@ -417,7 +417,7 @@ int read_ref(const char *refname, struct object_id *oid) int refs_ref_exists(struct ref_store *refs, const char *refname) { - return !!refs_resolve_ref_unsafe(refs, refname, RESOLVE_REF_READING, + return !!refs_resolve_ref_unsafe(refs, refname, NULL, RESOLVE_REF_READING, NULL, NULL); } @@ -773,7 +773,7 @@ int expand_ref(struct repository *repo, const char *str, int len, this_result = refs_found ? &oid_from_ref : oid; strbuf_reset(&fullref); strbuf_addf(&fullref, *p, len, str); - r = refs_resolve_ref_unsafe(refs, fullref.buf, + r = refs_resolve_ref_unsafe(refs, fullref.buf, NULL, RESOLVE_REF_READING, this_result, &flag); if (r) { @@ -807,7 +807,7 @@ int repo_dwim_log(struct repository *r, const char *str, int len, strbuf_reset(&path); strbuf_addf(&path, *p, len, str); - ref = refs_resolve_ref_unsafe(refs, path.buf, + ref = refs_resolve_ref_unsafe(refs, path.buf, NULL, RESOLVE_REF_READING, oid ? &hash : NULL, NULL); if (!ref) @@ -876,7 +876,7 @@ int is_pseudoref(struct ref_store *refs, const char *refname) return 0; if (ends_with(refname, "_HEAD")) { - refs_resolve_ref_unsafe(refs, refname, + refs_resolve_ref_unsafe(refs, refname, NULL, RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE, &oid, NULL); return !is_null_oid(&oid); @@ -884,7 +884,7 @@ int is_pseudoref(struct ref_store *refs, const char *refname) for (i = 0; i < ARRAY_SIZE(irregular_pseudorefs); i++) if (!strcmp(refname, irregular_pseudorefs[i])) { - refs_resolve_ref_unsafe(refs, refname, + refs_resolve_ref_unsafe(refs, refname, NULL, RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE, &oid, NULL); return !is_null_oid(&oid); @@ -1590,7 +1590,7 @@ int refs_head_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data) struct object_id oid; int flag; - if (refs_resolve_ref_unsafe(refs, "HEAD", RESOLVE_REF_READING, + if (refs_resolve_ref_unsafe(refs, "HEAD", NULL, RESOLVE_REF_READING, &oid, &flag)) return fn("HEAD", &oid, flag, cb_data); @@ -1928,6 +1928,7 @@ int refs_read_symbolic_ref(struct ref_store *ref_store, const char *refname, const char *refs_resolve_ref_unsafe(struct ref_store *refs, const char *refname, + char **referent, int resolve_flags, struct object_id *oid, int *flags) @@ -1989,6 +1990,8 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs, } *flags |= read_flags; + if (referent && read_flags & REF_ISSYMREF && sb_refname.len > 0) + *referent = sb_refname.buf; if (!(read_flags & REF_ISSYMREF)) { if (*flags & REF_BAD_NAME) { @@ -2024,7 +2027,7 @@ int refs_init_db(struct ref_store *refs, int flags, struct strbuf *err) const char *resolve_ref_unsafe(const char *refname, int resolve_flags, struct object_id *oid, int *flags) { - return refs_resolve_ref_unsafe(get_main_ref_store(the_repository), refname, + return refs_resolve_ref_unsafe(get_main_ref_store(the_repository), refname, NULL, resolve_flags, oid, flags); } @@ -2039,7 +2042,7 @@ int resolve_gitlink_ref(const char *submodule, const char *refname, if (!refs) return -1; - if (!refs_resolve_ref_unsafe(refs, refname, 0, oid, &flags) || + if (!refs_resolve_ref_unsafe(refs, refname, NULL, 0, oid, &flags) || is_null_oid(oid)) return -1; return 0; diff --git a/refs.h b/refs.h index 298caf6c618..2e740c692ac 100644 --- a/refs.h +++ b/refs.h @@ -71,9 +71,10 @@ struct pack_refs_opts { struct ref_exclusions *exclusions; struct string_list *includes; }; - const char *refs_resolve_ref_unsafe(struct ref_store *refs, + const char *refname, + char **referent, int resolve_flags, struct object_id *oid, int *flags); diff --git a/refs/files-backend.c b/refs/files-backend.c index a098d14ea00..90342549af9 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -235,8 +235,9 @@ static void loose_fill_ref_dir_regular_file(struct files_ref_store *refs, { struct object_id oid; int flag; + char *referent; - if (!refs_resolve_ref_unsafe(&refs->base, refname, RESOLVE_REF_READING, + if (!refs_resolve_ref_unsafe(&refs->base, refname, &referent, RESOLVE_REF_READING, &oid, &flag)) { oidclr(&oid); flag |= REF_ISBROKEN; @@ -258,7 +259,7 @@ static void loose_fill_ref_dir_regular_file(struct files_ref_store *refs, oidclr(&oid); flag |= REF_BAD_NAME | REF_ISBROKEN; } - add_entry_to_dir(dir, create_ref_entry(refname, &oid, flag)); + add_entry_to_dir(dir, create_ref_entry(refname, referent, &oid, flag)); } /* @@ -843,6 +844,7 @@ static int files_ref_iterator_advance(struct ref_iterator *ref_iterator) continue; iter->base.refname = iter->iter0->refname; + iter->base.referent = iter->iter0->referent; iter->base.oid = iter->iter0->oid; iter->base.flags = iter->iter0->flags; return ITER_OK; @@ -1109,7 +1111,7 @@ static struct ref_lock *lock_ref_oid_basic(struct files_ref_store *refs, goto error_return; } - if (!refs_resolve_ref_unsafe(&refs->base, lock->ref_name, 0, + if (!refs_resolve_ref_unsafe(&refs->base, lock->ref_name, NULL, 0, &lock->old_oid, NULL)) oidclr(&lock->old_oid); goto out; @@ -1444,7 +1446,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store, goto out; } - if (!refs_resolve_ref_unsafe(&refs->base, oldrefname, + if (!refs_resolve_ref_unsafe(&refs->base, oldrefname, NULL, RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE, &orig_oid, &flag)) { ret = error("refname %s not found", oldrefname); @@ -1490,7 +1492,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store, * the safety anyway; we want to delete the reference whatever * its current value. */ - if (!copy && refs_resolve_ref_unsafe(&refs->base, newrefname, + if (!copy && refs_resolve_ref_unsafe(&refs->base, newrefname, NULL, RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE, NULL, NULL) && refs_delete_ref(&refs->base, NULL, newrefname, @@ -1863,7 +1865,7 @@ static int commit_ref_update(struct files_ref_store *refs, int head_flag; const char *head_ref; - head_ref = refs_resolve_ref_unsafe(&refs->base, "HEAD", + head_ref = refs_resolve_ref_unsafe(&refs->base, "HEAD", NULL, RESOLVE_REF_READING, NULL, &head_flag); if (head_ref && (head_flag & REF_ISSYMREF) && @@ -1911,7 +1913,7 @@ static void update_symref_reflog(struct files_ref_store *refs, struct object_id new_oid; if (logmsg && - refs_resolve_ref_unsafe(&refs->base, target, + refs_resolve_ref_unsafe(&refs->base, target, NULL, RESOLVE_REF_READING, &new_oid, NULL) && files_log_ref_write(refs, refname, &lock->old_oid, &new_oid, logmsg, 0, &err)) { @@ -2505,7 +2507,7 @@ static int lock_ref_for_update(struct files_ref_store *refs, * to record and possibly check old_oid: */ if (!refs_resolve_ref_unsafe(&refs->base, - referent.buf, 0, + referent.buf, NULL, 0, &lock->old_oid, NULL)) { if (update->flags & REF_HAVE_OLD) { strbuf_addf(err, "cannot lock ref '%s': " @@ -3200,7 +3202,7 @@ static int files_reflog_expire(struct ref_store *ref_store, int type; const char *ref; - ref = refs_resolve_ref_unsafe(&refs->base, refname, + ref = refs_resolve_ref_unsafe(&refs->base, refname, NULL, RESOLVE_REF_NO_RECURSE, NULL, &type); update = !!(ref && !(type & REF_ISSYMREF)); diff --git a/refs/iterator.c b/refs/iterator.c index 9db8b056d56..26ca6f645ee 100644 --- a/refs/iterator.c +++ b/refs/iterator.c @@ -199,6 +199,7 @@ static int merge_ref_iterator_advance(struct ref_iterator *ref_iterator) } if (selection & ITER_YIELD_CURRENT) { + iter->base.referent = (*iter->current)->referent; iter->base.refname = (*iter->current)->refname; iter->base.oid = (*iter->current)->oid; iter->base.flags = (*iter->current)->flags; diff --git a/refs/ref-cache.c b/refs/ref-cache.c index 9f9797209a4..4c23b92414a 100644 --- a/refs/ref-cache.c +++ b/refs/ref-cache.c @@ -34,12 +34,14 @@ struct ref_dir *get_ref_dir(struct ref_entry *entry) } struct ref_entry *create_ref_entry(const char *refname, + const char *referent, const struct object_id *oid, int flag) { struct ref_entry *ref; FLEX_ALLOC_STR(ref, name, refname); oidcpy(&ref->u.value.oid, oid); + ref->u.value.referent = referent; ref->flag = flag; return ref; } @@ -428,6 +430,7 @@ static int cache_ref_iterator_advance(struct ref_iterator *ref_iterator) level->prefix_state = entry_prefix_state; level->index = -1; } else { + iter->base.referent = entry->u.value.referent; iter->base.refname = entry->name; iter->base.oid = &entry->u.value.oid; iter->base.flags = entry->flag; diff --git a/refs/ref-cache.h b/refs/ref-cache.h index 95c76e27c83..12ddee4fddc 100644 --- a/refs/ref-cache.h +++ b/refs/ref-cache.h @@ -42,6 +42,7 @@ struct ref_value { * referred to by the last reference in the symlink chain. */ struct object_id oid; + const char *referent; }; /* @@ -173,6 +174,7 @@ struct ref_entry *create_dir_entry(struct ref_cache *cache, const char *dirname, size_t len); struct ref_entry *create_ref_entry(const char *refname, + const char *referent, const struct object_id *oid, int flag); /* diff --git a/refs/refs-internal.h b/refs/refs-internal.h index 56641aa57a1..a10363eccf4 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -319,6 +319,7 @@ enum do_for_each_ref_flags { struct ref_iterator { struct ref_iterator_vtable *vtable; const char *refname; + const char *referent; const struct object_id *oid; unsigned int flags; }; diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index e206d5a073c..7e8d15cc6a0 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -342,6 +342,7 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator) while (!iter->err) { int flags = 0; + char **symref = NULL; iter->err = reftable_iterator_next_ref(&iter->iter, &iter->ref); if (iter->err) @@ -377,7 +378,10 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator) oidread(&iter->oid, iter->ref.value.val2.value); break; case REFTABLE_REF_SYMREF: - if (!refs_resolve_ref_unsafe(&iter->refs->base, iter->ref.refname, + if (!iter->ref.value.symref) + symref = &iter->ref.value.symref; + + if (!refs_resolve_ref_unsafe(&iter->refs->base, iter->ref.refname, symref, RESOLVE_REF_READING, &iter->oid, &flags)) oidclr(&iter->oid); break; @@ -406,6 +410,7 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator) continue; iter->base.refname = iter->ref.refname; + iter->base.referent = iter->ref.value.symref; iter->base.oid = &iter->oid; iter->base.flags = flags; @@ -877,7 +882,7 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, * so it is safe to call `refs_resolve_ref_unsafe()` * here without causing races. */ - const char *resolved = refs_resolve_ref_unsafe(&refs->base, u->refname, 0, + const char *resolved = refs_resolve_ref_unsafe(&refs->base, u->refname, NULL, 0, ¤t_oid, NULL); if (u->flags & REF_NO_DEREF) { @@ -1252,7 +1257,7 @@ static int write_create_symref_table(struct reftable_writer *writer, void *cb_da * never happens. */ if (!create->logmsg || - !refs_resolve_ref_unsafe(&create->refs->base, create->target, + !refs_resolve_ref_unsafe(&create->refs->base, create->target, NULL, RESOLVE_REF_READING, &new_oid, NULL) || !should_write_log(&create->refs->base, create->refname)) return 0; @@ -1263,7 +1268,7 @@ static int write_create_symref_table(struct reftable_writer *writer, void *cb_da log.value.update.message = xstrndup(create->logmsg, create->refs->write_options.block_size / 2); memcpy(log.value.update.new_hash, new_oid.hash, GIT_MAX_RAWSZ); - if (refs_resolve_ref_unsafe(&create->refs->base, create->refname, + if (refs_resolve_ref_unsafe(&create->refs->base, create->refname, NULL, RESOLVE_REF_READING, &old_oid, NULL)) memcpy(log.value.update.old_hash, old_oid.hash, GIT_MAX_RAWSZ); diff --git a/remote.c b/remote.c index 2b650b813b7..36525451e9c 100644 --- a/remote.c +++ b/remote.c @@ -518,7 +518,7 @@ static void read_config(struct repository *repo, int early) repo->remote_state->current_branch = NULL; if (startup_info->have_repository && !early) { const char *head_ref = refs_resolve_ref_unsafe( - get_main_ref_store(repo), "HEAD", 0, NULL, &flag); + get_main_ref_store(repo), "HEAD", NULL, 0, NULL, &flag); if (head_ref && (flag & REF_ISSYMREF) && skip_prefix(head_ref, "refs/heads/", &head_ref)) { repo->remote_state->current_branch = make_branch( diff --git a/sequencer.c b/sequencer.c index fa838f264f5..e9cc2a4fdf4 100644 --- a/sequencer.c +++ b/sequencer.c @@ -1430,7 +1430,7 @@ void print_commit_summary(struct repository *r, diff_setup_done(&rev.diffopt); refs = get_main_ref_store(r); - head = refs_resolve_ref_unsafe(refs, "HEAD", 0, NULL, NULL); + head = refs_resolve_ref_unsafe(refs, "HEAD", NULL, 0, NULL, NULL); if (!head) die(_("unable to resolve HEAD after creating commit")); if (!strcmp(head, "HEAD")) @@ -4651,7 +4651,7 @@ static int apply_save_autostash_ref(struct repository *r, const char *refname, if (!refs_ref_exists(get_main_ref_store(r), refname)) return 0; - if (!refs_resolve_ref_unsafe(get_main_ref_store(r), refname, + if (!refs_resolve_ref_unsafe(get_main_ref_store(r), refname, NULL, RESOLVE_REF_READING, &stash_oid, &flag)) return -1; if (flag & REF_ISSYMREF) diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c index 7a0f6cac53d..bc501c5253c 100644 --- a/t/helper/test-ref-store.c +++ b/t/helper/test-ref-store.c @@ -203,7 +203,7 @@ static int cmd_resolve_ref(struct ref_store *refs, const char **argv) int flags; const char *ref; - ref = refs_resolve_ref_unsafe(refs, refname, resolve_flags, + ref = refs_resolve_ref_unsafe(refs, refname, NULL, resolve_flags, &oid, &flags); printf("%s %s 0x%x\n", oid_to_hex(&oid), ref ? ref : "(null)", flags); return ref ? 0 : 1; diff --git a/worktree.c b/worktree.c index b02a05a74a3..1fb865c2ae7 100644 --- a/worktree.c +++ b/worktree.c @@ -42,6 +42,7 @@ static void add_head_info(struct worktree *wt) target = refs_resolve_ref_unsafe(get_worktree_ref_store(wt), "HEAD", + NULL, 0, &wt->head_oid, &flags); if (!target) @@ -446,7 +447,7 @@ int is_shared_symref(const struct worktree *wt, const char *symref, } refs = get_worktree_ref_store(wt); - symref_target = refs_resolve_ref_unsafe(refs, symref, 0, + symref_target = refs_resolve_ref_unsafe(refs, symref, NULL, 0, NULL, &flags); if ((flags & REF_ISSYMREF) && symref_target && !strcmp(symref_target, target)) @@ -547,6 +548,7 @@ int other_head_refs(each_ref_fn fn, void *cb_data) strbuf_worktree_ref(wt, &refname, "HEAD"); if (refs_resolve_ref_unsafe(get_main_ref_store(the_repository), refname.buf, + NULL, RESOLVE_REF_READING, &oid, &flag)) ret = fn(refname.buf, &oid, flag, cb_data); From patchwork Mon Apr 8 17:38:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Cai X-Patchwork-Id: 13621443 Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0B30814389F for ; Mon, 8 Apr 2024 17:38:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712597900; cv=none; b=epcbzavpCOpyXMHDLXxy8T8dD+TJnJQ84lSr5vZ+zqgL1xlZ859JEcqt0ZleJCjxmlaz7QOcggBwv9v0n9CITIXsAj2+OG7C019n7xjUDGI1iw42qbL+S6PDAhHcR5gZOG9EKU6d9xyhn7dwkCN2skqKbnN/13wlSn84Xh9Dp2w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712597900; c=relaxed/simple; bh=AYFOAjNP7kiQu9E60UJHthh6gMnXH3t0au1kBx9xIVY=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=qd2HvsQV0x/9AkKK8M51/vOKBQy3+SeGVRiGzdLM8CcaqAB1Uq253BeeZc9FfEoy3J9qxNFYBERacFiOr+4vkLIl69PPzfic18K2arG0fu6H9LzJw3ZrHn2RHEWbkgSgV0T6EjIX4RSgGFx4IIsOk9dIz7rHxWO6HmCFN4jYmAE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=FjnaHAs7; arc=none smtp.client-ip=209.85.128.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FjnaHAs7" Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-4155819f710so36562445e9.2 for ; Mon, 08 Apr 2024 10:38:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1712597897; x=1713202697; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=GS3YMLTjG2glNKxi8gdoSRFcUTCgNpFtSNNNRvAuF8w=; b=FjnaHAs7p8+ddvr/XiCOU9ZuiyyysdGXJZ9mAOmkqgAjd0LbZ1WfSFmVqwcDszHbwH mh4clHg6HlkERXj3uLX76jFZFDYxH9B+yNuvG9j4ugqtEXjTCIIVuASNG6/dwtcJxxw/ Kt6ZlPR9woYVpgrSQjPXXqUaTM7tIkd8QKiZv9cb1MJ1Ngis6pBv9feAUlDZJfzpH8pW IuQk9n19aw+AoLoWZ+nkBX4Hk1VfxmfqKe+hIXVgp3bC6cLcyU/zxGnu4SCqoh9UE3ON gAkhAb6r5tMN5vGlEifQFWhq56B8tPmyiic9v8inwDX8i4ynivodGCy1Ab7fLSTWKhkd bfeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712597897; x=1713202697; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GS3YMLTjG2glNKxi8gdoSRFcUTCgNpFtSNNNRvAuF8w=; b=Rl/cmYUgjuspROJSilbkmzmfBYQB9SY6FASQQT08VEwQCwmJHP8eECPmTSjsIuau4j O3E0CFaTfgb73KWNt9TLMexM6Z3T1du7ajOhGBB5YxK/MQAuqtBuG3Jmzk/hO2mHdGaq hTDzwcCc2kfPat0WrgqUEAmjtSR5hMlT6di2tVhBSBUjebN3f+JWfYTyVpdEkKhLXrSM aJGP2drajIZAzkv+pKA4LjweSKNmezGdZtMd5HB57Q6lI6ijaV0+jbVDEcvLkmMLWdJa Nl5E9aVdYPRCd1rJlvUYnDwE/dAbFPQL2vTT4VHpKMrYDtk9nPFIr8atHJ46hhPfn31S DAhA== X-Gm-Message-State: AOJu0Yy1LZxaOtJVGpvcMYvTiqqN9QYMkU4Z6T4zB+qNLCG3LDMwDglg XO5/vbxU4SaaegahQ22OXmJvMC21NthCcrusDa/mbXyvGU3/5wio4hMz8W5v X-Google-Smtp-Source: AGHT+IEzlFHqYycIgjsJCeE1v5CxszBiHTrbcPJa+N/kINCSD8zItdm7VwpdTtI5p5fH+iLJaaSJHA== X-Received: by 2002:a05:600c:a019:b0:414:726:87d9 with SMTP id jg25-20020a05600ca01900b00414072687d9mr9274947wmb.12.1712597897088; Mon, 08 Apr 2024 10:38:17 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id l8-20020a1c7908000000b00416838eeda7sm1261443wme.1.2024.04.08.10.38.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Apr 2024 10:38:16 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Mon, 08 Apr 2024 17:38:12 +0000 Subject: [PATCH v2 2/3] refs: add referent to each_repo_ref_fn Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: Phillip Wood , Kristoffer Haugsbakk , Jeff King , Patrick Steinhardt , =?utf-8?q?Jean-No=C3=ABl?= Avila , John Cai , John Cai From: John Cai From: John Cai There is no way for callers of the refs api functions that use iterators to get a hold of a direct value of a symbolic ref before its resolved in the callback functions, as either each_ref_fn nor each_repo_ref_fn have an argument for this. This did not matter since the iterators did not hold onto the direct value of a reference anyway. But, the previous commit started to save the value of the direct reference in the iterator. Add an argument to each_repo_ref_fn that gets passed the direct value of a reference. Signed-off-by: John Cai --- builtin/replace.c | 1 + refs.c | 2 ++ refs.h | 1 + refs/iterator.c | 2 +- replace-object.c | 1 + 5 files changed, 6 insertions(+), 1 deletion(-) diff --git a/builtin/replace.c b/builtin/replace.c index da59600ad22..36fa58db82c 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -48,6 +48,7 @@ struct show_data { }; static int show_reference(struct repository *r, const char *refname, + const char *referent UNUSED, const struct object_id *oid, int flag UNUSED, void *cb_data) { diff --git a/refs.c b/refs.c index b87a680249e..77ae38ea214 100644 --- a/refs.c +++ b/refs.c @@ -1664,6 +1664,7 @@ struct do_for_each_ref_help { static int do_for_each_ref_helper(struct repository *r UNUSED, const char *refname, + const char *referent, const struct object_id *oid, int flags, void *cb_data) @@ -2565,6 +2566,7 @@ struct do_for_each_reflog_help { static int do_for_each_reflog_helper(struct repository *r UNUSED, const char *refname, + const char *referent, const struct object_id *oid UNUSED, int flags, void *cb_data) diff --git a/refs.h b/refs.h index 2e740c692ac..23e5aaba2e9 100644 --- a/refs.h +++ b/refs.h @@ -311,6 +311,7 @@ typedef int each_ref_fn(const char *refname, */ typedef int each_repo_ref_fn(struct repository *r, const char *refname, + const char *referent, const struct object_id *oid, int flags, void *cb_data); diff --git a/refs/iterator.c b/refs/iterator.c index 26ca6f645ee..7e04d8427a9 100644 --- a/refs/iterator.c +++ b/refs/iterator.c @@ -449,7 +449,7 @@ int do_for_each_repo_ref_iterator(struct repository *r, struct ref_iterator *ite current_ref_iter = iter; while ((ok = ref_iterator_advance(iter)) == ITER_OK) { - retval = fn(r, iter->refname, iter->oid, iter->flags, cb_data); + retval = fn(r, iter->refname, iter->referent, iter->oid, iter->flags, cb_data); if (retval) { /* * If ref_iterator_abort() returns ITER_ERROR, diff --git a/replace-object.c b/replace-object.c index 523215589de..32d90f35327 100644 --- a/replace-object.c +++ b/replace-object.c @@ -10,6 +10,7 @@ static int register_replace_ref(struct repository *r, const char *refname, + const char *referent UNUSED, const struct object_id *oid, int flag UNUSED, void *cb_data UNUSED) From patchwork Mon Apr 8 17:38:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Cai X-Patchwork-Id: 13621445 Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 69EEA143C7A for ; Mon, 8 Apr 2024 17:38:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712597902; cv=none; b=nY9cIpiNV56XIzREJDZQMkgJvwMs0usMA8yCcNmbjNOcs1RyScL/uXakk4d7sezOqJD8umZGY3M4oFb45TF8Ty6H7Ixr2r4Tba1ol2lrZaMH5WBoCFIIc371ZvLsVHy4xOnBgL/7lAIzsLNTu1YytZR+WvxTfkA3eUEFrJT9kjI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712597902; c=relaxed/simple; bh=/nhm+s7f1P1m28C0DtHBDHCUpkO1tSWGgxiTbAdHXdc=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=iv9GzbxB95oiRhvObPpu8vvnGKewUXUftl6jpo40SrN2YfJ/NqZuZa8/jKCC3Xd130ACZahR6m0C8GkBYjC9Ec6hMl2sapo+L0FwTUoQ5qS4Fr4pUHXvRby+Q4ijOL7dijjiUjwGLHnpQsXTTyuqh1DVSmGx0CTGTwrwAvOZoIw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jCrb9AKa; arc=none smtp.client-ip=209.85.128.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jCrb9AKa" Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-4168a5d7564so4873445e9.3 for ; Mon, 08 Apr 2024 10:38:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1712597898; x=1713202698; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=0PRkSSHBQX/w3a87xkqplaj0Azw+bUkiUbKAG4NbSjQ=; b=jCrb9AKaNPHtT2malmVfq/0OyKmBIkuGeFqlqQLRYomir6sWLOkvtBTseG4kxKnK4O h2ZWiLxjG47Iyigro2Pa60e3dIGyVOwtithQ9vb9uiRp6oh32sIUFwTA47PCHBIARiXe 38k4er8FpryBNqX4+61qiUn4rKRQ+LCZNRlhmTMLOHwZ/hBS/pFOrk8smFbyhnRIz5Ui SDHJyZrAM30a/JBWaHjvkKtPhe7No0BmNrKsM0TRlke37EGrbqTiVNl54EyYnbiHpK8W 8oE2XL/pVhw7yb0a03OEQEdD76ZCaNAYLIMKAjfWLWnRXsnlT2lmg8CUHaTN7gqhElN/ vy+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712597898; x=1713202698; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0PRkSSHBQX/w3a87xkqplaj0Azw+bUkiUbKAG4NbSjQ=; b=u9FwZObQ78wUoIPs9tq9DVUhoKkaFdWvDb6lVaflbsIPncKr7pc8nOdIG1jLNwo/zw wOKOhlSnjay94yB4E9IwTbv01s0ySnTL1IK/UFGdR+OnE571mPvgTrjnP/sFpHHxQC/N 8Ey2kQU/tAXxBFj2mqEX41ReUogvHdfCLpcu4ZYDVO4UYn/I5AdsKbTdcVRuRkoS61At 3dgKu/XO3ldiDrxdM6s2pxLtwvSlS1Hnia7Yeat6yZmSWJqdJ2OT8LiwezSuIkEneWC1 H0U2UkG1wn40AFmnsYzeD0C7vQ8ZCsXsqc5ZZe5BAdrBQmR0xVOqGcKB2wPkwLUPfpYg gikQ== X-Gm-Message-State: AOJu0YxJ0AQaUEuJu8WpjMEr1ZY/YsuTnw3WlKWvDXrF/ng5uZYuFS4o zY6LGA5HjtmiFFmtjlAlPVxVzr++TyhyUiHNMi6uZDLjqkTFeXYspx1YUJfy X-Google-Smtp-Source: AGHT+IELd8JdCK/KOYTukSeNXpt1f7FuIWE2kBW2zJhpeA1c4uQ51+S+qyA1mqiFGrylE5wrbRX8XA== X-Received: by 2002:a05:600c:4fc2:b0:414:8e02:e432 with SMTP id o2-20020a05600c4fc200b004148e02e432mr8176143wmq.7.1712597898151; Mon, 08 Apr 2024 10:38:18 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id m6-20020a05600c3b0600b0041668162b45sm5194429wms.26.2024.04.08.10.38.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 08 Apr 2024 10:38:17 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Mon, 08 Apr 2024 17:38:13 +0000 Subject: [PATCH v2 3/3] show-ref: add --symbolic-name option Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: Phillip Wood , Kristoffer Haugsbakk , Jeff King , Patrick Steinhardt , =?utf-8?q?Jean-No=C3=ABl?= Avila , John Cai , John Cai From: John Cai From: John Cai For reftable development, it would be handy to have a tool to provide the direct value of any ref whether it be a symbolic ref or not. Currently there is git-symbolic-ref, which only works for symbolic refs, and git-rev-parse, which will resolve the ref. Let's teach show-ref a --symbolic-name option that will cause git-show-ref(1) to print out the value symbolic references points to. Signed-off-by: John Cai --- Documentation/git-show-ref.txt | 21 ++++++++++++++++++- builtin/show-ref.c | 38 ++++++++++++++++++++++++---------- refs.c | 6 ++++++ refs.h | 2 +- t/t1403-show-ref.sh | 20 ++++++++++++++++++ 5 files changed, 74 insertions(+), 13 deletions(-) diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt index ba757470059..9627b34b37f 100644 --- a/Documentation/git-show-ref.txt +++ b/Documentation/git-show-ref.txt @@ -10,7 +10,7 @@ SYNOPSIS [verse] 'git show-ref' [--head] [-d | --dereference] [-s | --hash[=]] [--abbrev[=]] [--tags] - [--heads] [--] [...] + [--heads] [--symbolic-name] [--] [...] 'git show-ref' --verify [-q | --quiet] [-d | --dereference] [-s | --hash[=]] [--abbrev[=]] [--] [...] @@ -58,6 +58,11 @@ OPTIONS Dereference tags into object IDs as well. They will be shown with `^{}` appended. +--symbolic-name:: + + Print out the value the reference points to without dereferencing. This + is useful to know the reference that a symbolic ref is pointing to. + -s:: --hash[=]:: @@ -146,6 +151,20 @@ $ git show-ref --heads --hash ... ----------------------------------------------------------------------------- +When using `--symbolic-name`, the output is in the format: + +----------- + SP SP +----------- + +For example, + +----------------------------------------------------------------------------- +$ git show-ref --symbolic-name +b75428bae1d090f60bdd4b67185f814bc8f0819d refs/heads/SYMBOLIC_REF ref:refs/heads/main +... +----------------------------------------------------------------------------- + EXAMPLES -------- diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 1c15421e600..1d681505eac 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -12,7 +12,7 @@ static const char * const show_ref_usage[] = { N_("git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=]] [--abbrev[=]] [--tags]\n" - " [--heads] [--] [...]"), + " [--heads] [--symbolic-name] [--] [...]"), N_("git show-ref --verify [-q | --quiet] [-d | --dereference]\n" " [-s | --hash[=]] [--abbrev[=]]\n" " [--] [...]"), @@ -26,10 +26,13 @@ struct show_one_options { int hash_only; int abbrev; int deref_tags; + int symbolic_name; }; static void show_one(const struct show_one_options *opts, - const char *refname, const struct object_id *oid) + const char *refname, + const char *referent, + const struct object_id *oid, const int is_symref) { const char *hex; struct object_id peeled; @@ -44,7 +47,9 @@ static void show_one(const struct show_one_options *opts, hex = repo_find_unique_abbrev(the_repository, oid, opts->abbrev); if (opts->hash_only) printf("%s\n", hex); - else + else if (opts->symbolic_name & is_symref) { + printf("%s %s ref:%s\n", hex, refname, referent); + } else printf("%s %s\n", hex, refname); if (!opts->deref_tags) @@ -63,8 +68,11 @@ struct show_ref_data { int show_head; }; -static int show_ref(const char *refname, const struct object_id *oid, - int flag UNUSED, void *cbdata) +static int show_ref_referent(struct repository *repo UNUSED, + const char *refname, + const char *referent, + const struct object_id *oid, + int flag, void *cbdata) { struct show_ref_data *data = cbdata; @@ -91,11 +99,17 @@ static int show_ref(const char *refname, const struct object_id *oid, match: data->found_match++; - show_one(data->show_one_opts, refname, oid); + show_one(data->show_one_opts, refname, referent, oid, flag & REF_ISSYMREF); return 0; } +static int show_ref(const char *refname, const struct object_id *oid, + int flag, void *cbdata) +{ + return show_ref_referent(NULL, refname, NULL, oid, flag, cbdata); +} + static int add_existing(const char *refname, const struct object_id *oid UNUSED, int flag UNUSED, void *cbdata) @@ -171,10 +185,11 @@ static int cmd_show_ref__verify(const struct show_one_options *show_one_opts, while (*refs) { struct object_id oid; + int flags = 0; if ((starts_with(*refs, "refs/") || refname_is_safe(*refs)) && - !read_ref(*refs, &oid)) { - show_one(show_one_opts, *refs, &oid); + !read_ref_full(*refs, 0, &oid, &flags)) { + show_one(show_one_opts, *refs, NULL, &oid, flags & REF_ISSYMREF); } else if (!show_one_opts->quiet) die("'%s' - not a valid ref", *refs); @@ -208,11 +223,11 @@ static int cmd_show_ref__patterns(const struct patterns_options *opts, head_ref(show_ref, &show_ref_data); if (opts->heads_only || opts->tags_only) { if (opts->heads_only) - for_each_fullref_in("refs/heads/", show_ref, &show_ref_data); + for_each_ref_all("refs/heads/", show_ref_referent, &show_ref_data); if (opts->tags_only) - for_each_fullref_in("refs/tags/", show_ref, &show_ref_data); + for_each_ref_all("refs/tags/", show_ref_referent, &show_ref_data); } else { - for_each_ref(show_ref, &show_ref_data); + for_each_ref_all("", show_ref_referent, &show_ref_data); } if (!show_ref_data.found_match) return 1; @@ -289,6 +304,7 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix) OPT_BOOL(0, "tags", &patterns_opts.tags_only, N_("only show tags (can be combined with heads)")), OPT_BOOL(0, "heads", &patterns_opts.heads_only, N_("only show heads (can be combined with tags)")), OPT_BOOL(0, "exists", &exists, N_("check for reference existence without resolving")), + OPT_BOOL(0, "symbolic-name", &show_one_opts.symbolic_name, N_("print out symbolic reference values")), OPT_BOOL(0, "verify", &verify, N_("stricter reference checking, " "requires exact ref path")), OPT_HIDDEN_BOOL('h', NULL, &patterns_opts.show_head, diff --git a/refs.c b/refs.c index 77ae38ea214..9488ad9594d 100644 --- a/refs.c +++ b/refs.c @@ -1734,6 +1734,12 @@ int for_each_replace_ref(struct repository *r, each_repo_ref_fn fn, void *cb_dat DO_FOR_EACH_INCLUDE_BROKEN, cb_data); } +int for_each_ref_all(const char *prefix, each_repo_ref_fn fn, void *cb_data) +{ + return do_for_each_repo_ref(the_repository, prefix, fn, 0, + 0, cb_data); +} + int for_each_namespaced_ref(const char **exclude_patterns, each_ref_fn fn, void *cb_data) { diff --git a/refs.h b/refs.h index 23e5aaba2e9..54b459375be 100644 --- a/refs.h +++ b/refs.h @@ -337,7 +337,6 @@ int refs_for_each_branch_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data); int refs_for_each_remote_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data); - /* just iterates the head ref. */ int head_ref(each_ref_fn fn, void *cb_data); @@ -381,6 +380,7 @@ int for_each_tag_ref(each_ref_fn fn, void *cb_data); int for_each_branch_ref(each_ref_fn fn, void *cb_data); int for_each_remote_ref(each_ref_fn fn, void *cb_data); int for_each_replace_ref(struct repository *r, each_repo_ref_fn fn, void *cb_data); +int for_each_ref_all(const char *prefix, each_repo_ref_fn fn, void *cb_data); /* iterates all refs that match the specified glob pattern. */ int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data); diff --git a/t/t1403-show-ref.sh b/t/t1403-show-ref.sh index 33fb7a38fff..0aebe709dca 100755 --- a/t/t1403-show-ref.sh +++ b/t/t1403-show-ref.sh @@ -286,4 +286,24 @@ test_expect_success '--exists with existing special ref' ' git show-ref --exists FETCH_HEAD ' +test_expect_success '--symbolic-name with a non symbolic ref' ' + commit_oid=$(git rev-parse refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME) && + cat >expect <<-EOF && + $commit_oid refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + EOF + git show-ref --symbolic-name refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME >actual && + test_cmp expect actual +' + +test_expect_success '--symbolic-name with symbolic ref' ' + test_when_finished "git symbolic-ref -d refs/heads/SYMBOLIC_REF_A" && + commit_oid=$(git rev-parse refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME) && + cat >expect <<-EOF && + $commit_oid refs/heads/SYMBOLIC_REF_A ref:refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + EOF + git symbolic-ref refs/heads/SYMBOLIC_REF_A refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME && + git show-ref --symbolic-name SYMBOLIC_REF_A >actual && + test_cmp expect actual +' + test_done