From: Junio C Hamano <gitster@pobox.com>
To: Eric Blake <ebb9@byu.net>
Cc: Bruno Haible <bruno@clisp.org>, git@vger.kernel.org
Subject: Re: gnulib-tool --version
Date: Fri, 14 Mar 2008 23:08:11 -0700 [thread overview]
Message-ID: <7vabl0o6yc.fsf@gitster.siamese.dyndns.org> (raw)
In-Reply-To: <47DB5295.9080005@byu.net> (Eric Blake's message of "Fri, 14 Mar 2008 22:37:41 -0600")
Eric Blake <ebb9@byu.net> writes:
> What is really needed is a method in git where once a SHA1 prefix becomes
> ambiguous, you can still easily choose to resolve the ambiguity in favor
> of the oldest commit that matches the prefix.
"Oldest commit" does not make much sense in a distributed environment. In
git.git, I tend to have many objects in my primary repository that nobody
else has, and other people would probably have many objects that I do not
have. "Oldest among the ones reachable from these heads" and specifying
only the ones that are publicly available may have some value, though.
I agree that we would want a reverse operation of find_unique_abbrev();
here is a quick and dirty one.
$ git rev-parse --disamb=aba1 |
git name-rev --stdin
aba14750f47700b8923b411a9348fb251b788967 tree
aba15f7f592c302196401d17a42c772d744555b4 (tags/gitgui-0.9.3~5) commit
aba16b190c54a107521801ad77ab66586553ba69 blob
aba170cdb4874b72dd619e6f7bbc13c33295f831 (tags/v1.5.2^0) commit
It is very tempting to say that we should favor commits over other types,
but at the "extended sha1 expression" level, we traditionally haven't
favored one type over others, so it has to wait until 1.6.0 at least.
---
builtin-rev-parse.c | 13 +++++++++++++
cache.h | 3 +++
sha1_name.c | 37 +++++++++++++++++++++++++++++++++++++
3 files changed, 53 insertions(+), 0 deletions(-)
diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c
index 0351d54..c64b43e 100644
--- a/builtin-rev-parse.c
+++ b/builtin-rev-parse.c
@@ -365,6 +365,15 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
return 0;
}
+static void disamb_show(const unsigned char *sha1, void *cb_data)
+{
+ char *orig = cb_data;
+ enum object_type type;
+
+ type = sha1_object_info(sha1, NULL);
+ printf("%s %s %s\n", sha1_to_hex(sha1), typename(type), orig);
+}
+
int cmd_rev_parse(int argc, const char **argv, const char *prefix)
{
int i, as_is = 0, verify = 0;
@@ -548,6 +557,10 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
show_datestring("--min-age=", arg+8);
continue;
}
+ if (!prefixcmp(arg, "--disamb=")) {
+ for_each_sha1(arg + 9, disamb_show, NULL);
+ continue;
+ }
if (show_flag(arg) && verify)
die("Needed a single revision");
continue;
diff --git a/cache.h b/cache.h
index 2a1e7ec..fa15140 100644
--- a/cache.h
+++ b/cache.h
@@ -454,6 +454,9 @@ extern char *sha1_file_name(const unsigned char *sha1);
extern char *sha1_pack_name(const unsigned char *sha1);
extern char *sha1_pack_index_name(const unsigned char *sha1);
extern const char *find_unique_abbrev(const unsigned char *sha1, int);
+typedef void for_each_sha1_fn(const unsigned char *sha1, void *);
+int for_each_sha1(const char *prefix, for_each_sha1_fn fn, void *cb_data);
+
extern const unsigned char null_sha1[20];
static inline int is_null_sha1(const unsigned char *sha1)
{
diff --git a/sha1_name.c b/sha1_name.c
index 8b6c76f..2703831 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -213,6 +213,43 @@ const char *find_unique_abbrev(const unsigned char *sha1, int len)
return hex;
}
+static int for_each_sha1_rec(char *prefix, int len, for_each_sha1_fn fn, void *cb_data)
+{
+ unsigned char sha1[20];
+ int status, i, found;
+
+ if (40 <= len)
+ return 0;
+ status = get_short_sha1(prefix, len, sha1, 1);
+ if (status == SHORT_NAME_NOT_FOUND)
+ return 0;
+ if (!status) {
+ fn(sha1, cb_data);
+ return 1;
+ }
+ /* Ambiguous */
+ found = 0;
+ for (i = 0; i < 16; i++) {
+ prefix[len] = "0123456789abcdef"[i];
+ prefix[len+1] = '\0';
+ found += for_each_sha1_rec(prefix, len + 1, fn, cb_data);
+ }
+ return found;
+}
+
+int for_each_sha1(const char *prefix, for_each_sha1_fn fn, void *cb_data)
+{
+ int len;
+ char hex[41];
+
+ len = strlen(prefix);
+ if (40 <= len)
+ return 0;
+ memcpy(hex, prefix, len+1);
+
+ return for_each_sha1_rec(hex, len, fn, cb_data);
+}
+
static int ambiguous_path(const char *path, int len)
{
int slash = 1;
prev parent reply other threads:[~2008-03-15 6:09 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <910CF843580B3C40A25CD0D04B3908E286A29C@exchange4.comune.prato.local>
[not found] ` <200803150052.44573.bruno@clisp.org>
[not found] ` <47DB12F3.8020504@byu.net>
[not found] ` <200803150512.53166.bruno@clisp.org>
2008-03-15 4:37 ` gnulib-tool --version Eric Blake
2008-03-15 6:08 ` Junio C Hamano [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7vabl0o6yc.fsf@gitster.siamese.dyndns.org \
--to=gitster@pobox.com \
--cc=bruno@clisp.org \
--cc=ebb9@byu.net \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).