git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/9] Extending the shelf life of "git describe" output
@ 2012-06-18 22:05 Junio C Hamano
  2012-06-18 22:05 ` [PATCH 1/9] sha1_name.c: indentation fix Junio C Hamano
                   ` (10 more replies)
  0 siblings, 11 replies; 14+ messages in thread
From: Junio C Hamano @ 2012-06-18 22:05 UTC (permalink / raw)
  To: git

The output from "git describe" is a tagname, dash, number, dash, and
'g' followed by an abbreviated commit object name, and it can be
used anywhere we expect an object name.  This is so that people can
use it to name an exact commit in the inter-human communication. The
recipients are expected to be able to cut & paste it to their
command line.

Because it uses an abbreviated commit object name, it is possible
that a "git describe" name taken earlier can become ambiguous over
time, even though "git describe" ensures the uniqueness of its
output in the repository when it runs.

This series teaches the sha1_name machinery to only look for
unambigous commit object names when the caller knows that the name
must refer to a commit object.  By taking advantage of the fact that
there are more trees and blobs in a project's history than commits
by definition, this reduces the potential of collisions, extending
the shelf life of "git describe" output by a little bit.

Building on the foundation this series lays, I can see two separate
avenues to further extend this work:

 - You will further be able to extend the lifetime of uniqueness of
   "git describe" output if you take advantage of the "tagname" or
   "number". The current parser does not do this.

   There are a number of ways to do this, but probably the cleanest
   would be to (you only can do this when you have "tagname" tag
   locally; you may not have it) pass the tag and the number down to
   the find_short_*() routines with commit_only set, and when they
   find a commit that match the prefix, inside is_commit_object()
   test, check also that the commit reaches the given tag object in
   the given number steps (otherwise discard it as it is not the one
   you are looking for).

 - Some callers that are involved in the get_sha1_1() callpath know
   that the name they have must be referring to commit objects (e.g.
   get_parent() and get_nth_ancestor()).  It might be worthwhile to
   let get_sha1_1() know that the caller knows the name it is
   feeding must refer to a commit object, and have the uniqueness
   logic take advantage of it.

   I think that most of these callers are expecting to parse a
   committish and the user may have given them the name of a a tag
   object that peels to a commit, so you would need to add a new
   GET_SHORT_COMMITTISH that allows any committish, in addition to
   the GET_SHORT_COMMIT_ONLY this series adds, if you want to do
   this.

I do not claim the ownership rights on either of the above ideas;
people who find them interesting are welcome to pursue them (hint,
hint).

Junio C Hamano (9):
  sha1_name.c: indentation fix
  sha1_name.c: clarify what "fake" is for in find_short_object_filename()
  sha1_name.c: rename "now" to "current"
  sha1_name.c: refactor find_short_packed_object()
  sha1_name.c: teach find_short_object_filename() a commit-only option
  sha1_name.c: teach find_short_packed_object() a commit-only option
  sha1_name.c: allow get_short_sha1() to take other flags
  sha1_name.c: teach get_short_sha1() a commit-only option
  sha1_name.c: get_describe_name() by definition groks only commits

 sha1_name.c | 157 ++++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 101 insertions(+), 56 deletions(-)

-- 
1.7.11

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/9] sha1_name.c: indentation fix
  2012-06-18 22:05 [PATCH 0/9] Extending the shelf life of "git describe" output Junio C Hamano
@ 2012-06-18 22:05 ` Junio C Hamano
  2012-06-18 22:05 ` [PATCH 2/9] sha1_name.c: clarify what "fake" is for in find_short_object_filename() Junio C Hamano
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Junio C Hamano @ 2012-06-18 22:05 UTC (permalink / raw)
  To: git

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 sha1_name.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index 03ffc2c..5b0c845 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -103,10 +103,10 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne
 		}
 		if (first < num) {
 			const unsigned char *now, *next;
-		       now = nth_packed_object_sha1(p, first);
+			now = nth_packed_object_sha1(p, first);
 			if (match_sha(len, match, now)) {
 				next = nth_packed_object_sha1(p, first+1);
-			       if (!next|| !match_sha(len, match, next)) {
+				if (!next|| !match_sha(len, match, next)) {
 					/* unique within this pack */
 					if (!found) {
 						found_sha1 = now;
-- 
1.7.11

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/9] sha1_name.c: clarify what "fake" is for in find_short_object_filename()
  2012-06-18 22:05 [PATCH 0/9] Extending the shelf life of "git describe" output Junio C Hamano
  2012-06-18 22:05 ` [PATCH 1/9] sha1_name.c: indentation fix Junio C Hamano
@ 2012-06-18 22:05 ` Junio C Hamano
  2012-06-18 22:05 ` [PATCH 3/9] sha1_name.c: rename "now" to "current" Junio C Hamano
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Junio C Hamano @ 2012-06-18 22:05 UTC (permalink / raw)
  To: git

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 sha1_name.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/sha1_name.c b/sha1_name.c
index 5b0c845..4cbca34 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -17,6 +17,13 @@ static int find_short_object_filename(int len, const char *name, unsigned char *
 	static struct alternate_object_database *fakeent;
 
 	if (!fakeent) {
+		/*
+		 * Create a "fake" alternate object database that
+		 * points to our own object database, to make it
+		 * easier to get a temporary working space in
+		 * alt->name/alt->base while iterating over the
+		 * object databases including our own.
+		 */
 		const char *objdir = get_object_directory();
 		int objdir_len = strlen(objdir);
 		int entlen = objdir_len + 43;
-- 
1.7.11

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/9] sha1_name.c: rename "now" to "current"
  2012-06-18 22:05 [PATCH 0/9] Extending the shelf life of "git describe" output Junio C Hamano
  2012-06-18 22:05 ` [PATCH 1/9] sha1_name.c: indentation fix Junio C Hamano
  2012-06-18 22:05 ` [PATCH 2/9] sha1_name.c: clarify what "fake" is for in find_short_object_filename() Junio C Hamano
@ 2012-06-18 22:05 ` Junio C Hamano
  2012-06-18 22:05 ` [PATCH 4/9] sha1_name.c: refactor find_short_packed_object() Junio C Hamano
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Junio C Hamano @ 2012-06-18 22:05 UTC (permalink / raw)
  To: git

This variable points at the element we are currently looking at, and
does not have anything to do with the current time which the name
"now" implies.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 sha1_name.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index 4cbca34..5224f39 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -93,11 +93,11 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne
 		last = num;
 		while (first < last) {
 			uint32_t mid = (first + last) / 2;
-			const unsigned char *now;
+			const unsigned char *current;
 			int cmp;
 
-			now = nth_packed_object_sha1(p, mid);
-			cmp = hashcmp(match, now);
+			current = nth_packed_object_sha1(p, mid);
+			cmp = hashcmp(match, current);
 			if (!cmp) {
 				first = mid;
 				break;
@@ -109,17 +109,17 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne
 			last = mid;
 		}
 		if (first < num) {
-			const unsigned char *now, *next;
-			now = nth_packed_object_sha1(p, first);
-			if (match_sha(len, match, now)) {
+			const unsigned char *current, *next;
+			current = nth_packed_object_sha1(p, first);
+			if (match_sha(len, match, current)) {
 				next = nth_packed_object_sha1(p, first+1);
 				if (!next|| !match_sha(len, match, next)) {
 					/* unique within this pack */
 					if (!found) {
-						found_sha1 = now;
+						found_sha1 = current;
 						found++;
 					}
-					else if (hashcmp(found_sha1, now)) {
+					else if (hashcmp(found_sha1, current)) {
 						found = 2;
 						break;
 					}
-- 
1.7.11

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/9] sha1_name.c: refactor find_short_packed_object()
  2012-06-18 22:05 [PATCH 0/9] Extending the shelf life of "git describe" output Junio C Hamano
                   ` (2 preceding siblings ...)
  2012-06-18 22:05 ` [PATCH 3/9] sha1_name.c: rename "now" to "current" Junio C Hamano
@ 2012-06-18 22:05 ` Junio C Hamano
  2012-06-18 22:05 ` [PATCH 5/9] sha1_name.c: teach find_short_object_filename() a commit-only option Junio C Hamano
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Junio C Hamano @ 2012-06-18 22:05 UTC (permalink / raw)
  To: git

Extract the logic to find object(s) that match a given prefix inside
a single pack into a separate helper function, and give it a bit more
comment.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 sha1_name.c | 103 +++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 56 insertions(+), 47 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index 5224f39..e03992c 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -78,6 +78,59 @@ static int match_sha(unsigned len, const unsigned char *a, const unsigned char *
 	return 1;
 }
 
+static int unique_in_pack(int len,
+			  const unsigned char *match,
+			  struct packed_git *p,
+			  const unsigned char **found_sha1,
+			  int seen_so_far)
+{
+	uint32_t num, last, i, first = 0;
+	const unsigned char *current = NULL;
+
+	open_pack_index(p);
+	num = p->num_objects;
+	last = num;
+	while (first < last) {
+		uint32_t mid = (first + last) / 2;
+		const unsigned char *current;
+		int cmp;
+
+		current = nth_packed_object_sha1(p, mid);
+		cmp = hashcmp(match, current);
+		if (!cmp) {
+			first = mid;
+			break;
+		}
+		if (cmp > 0) {
+			first = mid+1;
+			continue;
+		}
+		last = mid;
+	}
+
+	/*
+	 * At this point, "first" is the location of the lowest object
+	 * with an object name that could match "match".  See if we have
+	 * 0, 1 or more objects that actually match(es).
+	 */
+	for (i = first; i < num; i++) {
+		current = nth_packed_object_sha1(p, first);
+		if (!match_sha(len, match, current))
+			break;
+
+		/* current matches */
+		if (!seen_so_far) {
+			*found_sha1 = current;
+			seen_so_far++;
+		} else if (seen_so_far) {
+			/* is it the same as the one previously found elsewhere? */
+			if (hashcmp(*found_sha1, current))
+				return 2; /* definitely not unique */
+		}
+	}
+	return seen_so_far;
+}
+
 static int find_short_packed_object(int len, const unsigned char *match, unsigned char *sha1)
 {
 	struct packed_git *p;
@@ -85,53 +138,9 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne
 	int found = 0;
 
 	prepare_packed_git();
-	for (p = packed_git; p && found < 2; p = p->next) {
-		uint32_t num, last;
-		uint32_t first = 0;
-		open_pack_index(p);
-		num = p->num_objects;
-		last = num;
-		while (first < last) {
-			uint32_t mid = (first + last) / 2;
-			const unsigned char *current;
-			int cmp;
-
-			current = nth_packed_object_sha1(p, mid);
-			cmp = hashcmp(match, current);
-			if (!cmp) {
-				first = mid;
-				break;
-			}
-			if (cmp > 0) {
-				first = mid+1;
-				continue;
-			}
-			last = mid;
-		}
-		if (first < num) {
-			const unsigned char *current, *next;
-			current = nth_packed_object_sha1(p, first);
-			if (match_sha(len, match, current)) {
-				next = nth_packed_object_sha1(p, first+1);
-				if (!next|| !match_sha(len, match, next)) {
-					/* unique within this pack */
-					if (!found) {
-						found_sha1 = current;
-						found++;
-					}
-					else if (hashcmp(found_sha1, current)) {
-						found = 2;
-						break;
-					}
-				}
-				else {
-					/* not even unique within this pack */
-					found = 2;
-					break;
-				}
-			}
-		}
-	}
+	for (p = packed_git; p && found < 2; p = p->next)
+		found = unique_in_pack(len, match, p, &found_sha1, found);
+
 	if (found == 1)
 		hashcpy(sha1, found_sha1);
 	return found;
-- 
1.7.11

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 5/9] sha1_name.c: teach find_short_object_filename() a commit-only option
  2012-06-18 22:05 [PATCH 0/9] Extending the shelf life of "git describe" output Junio C Hamano
                   ` (3 preceding siblings ...)
  2012-06-18 22:05 ` [PATCH 4/9] sha1_name.c: refactor find_short_packed_object() Junio C Hamano
@ 2012-06-18 22:05 ` Junio C Hamano
  2012-06-18 22:05 ` Junio C Hamano
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Junio C Hamano @ 2012-06-18 22:05 UTC (permalink / raw)
  To: git

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 sha1_name.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index e03992c..a283c85 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -9,7 +9,14 @@
 
 static int get_sha1_oneline(const char *, unsigned char *, struct commit_list *);
 
-static int find_short_object_filename(int len, const char *name, unsigned char *sha1)
+static int is_commit_object(const unsigned char *sha1)
+{
+	int kind = sha1_object_info(sha1, NULL);
+	return (kind == OBJ_COMMIT);
+}
+
+static int find_short_object_filename(int len, const char *name, unsigned char *sha1,
+				      int commit_only)
 {
 	struct alternate_object_database *alt;
 	char hex[40];
@@ -47,6 +54,14 @@ static int find_short_object_filename(int len, const char *name, unsigned char *
 				continue;
 			if (memcmp(de->d_name, name + 2, len - 2))
 				continue;
+			if (commit_only) {
+				char found_name[40];
+				unsigned char found_bin[20];
+				sprintf(found_name, "%.2s%s", name, de->d_name);
+				if (get_sha1_hex(found_name, found_bin) ||
+				    !is_commit_object(found_bin))
+					continue; /* not a commit object name */
+			}
 			if (!found) {
 				memcpy(hex + 2, de->d_name, 38);
 				found++;
@@ -156,7 +171,7 @@ static int find_unique_short_object(int len, char *canonical,
 	unsigned char unpacked_sha1[20], packed_sha1[20];
 
 	prepare_alt_odb();
-	has_unpacked = find_short_object_filename(len, canonical, unpacked_sha1);
+	has_unpacked = find_short_object_filename(len, canonical, unpacked_sha1, 0);
 	has_packed = find_short_packed_object(len, res, packed_sha1);
 	if (!has_unpacked && !has_packed)
 		return SHORT_NAME_NOT_FOUND;
-- 
1.7.11

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 5/9] sha1_name.c: teach find_short_object_filename() a commit-only option
  2012-06-18 22:05 [PATCH 0/9] Extending the shelf life of "git describe" output Junio C Hamano
                   ` (4 preceding siblings ...)
  2012-06-18 22:05 ` [PATCH 5/9] sha1_name.c: teach find_short_object_filename() a commit-only option Junio C Hamano
@ 2012-06-18 22:05 ` Junio C Hamano
  2012-06-18 22:05 ` [PATCH 6/9] sha1_name.c: teach find_short_packed_object() " Junio C Hamano
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Junio C Hamano @ 2012-06-18 22:05 UTC (permalink / raw)
  To: git

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 sha1_name.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index e03992c..a283c85 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -9,7 +9,14 @@
 
 static int get_sha1_oneline(const char *, unsigned char *, struct commit_list *);
 
-static int find_short_object_filename(int len, const char *name, unsigned char *sha1)
+static int is_commit_object(const unsigned char *sha1)
+{
+	int kind = sha1_object_info(sha1, NULL);
+	return (kind == OBJ_COMMIT);
+}
+
+static int find_short_object_filename(int len, const char *name, unsigned char *sha1,
+				      int commit_only)
 {
 	struct alternate_object_database *alt;
 	char hex[40];
@@ -47,6 +54,14 @@ static int find_short_object_filename(int len, const char *name, unsigned char *
 				continue;
 			if (memcmp(de->d_name, name + 2, len - 2))
 				continue;
+			if (commit_only) {
+				char found_name[40];
+				unsigned char found_bin[20];
+				sprintf(found_name, "%.2s%s", name, de->d_name);
+				if (get_sha1_hex(found_name, found_bin) ||
+				    !is_commit_object(found_bin))
+					continue; /* not a commit object name */
+			}
 			if (!found) {
 				memcpy(hex + 2, de->d_name, 38);
 				found++;
@@ -156,7 +171,7 @@ static int find_unique_short_object(int len, char *canonical,
 	unsigned char unpacked_sha1[20], packed_sha1[20];
 
 	prepare_alt_odb();
-	has_unpacked = find_short_object_filename(len, canonical, unpacked_sha1);
+	has_unpacked = find_short_object_filename(len, canonical, unpacked_sha1, 0);
 	has_packed = find_short_packed_object(len, res, packed_sha1);
 	if (!has_unpacked && !has_packed)
 		return SHORT_NAME_NOT_FOUND;
-- 
1.7.11

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 6/9] sha1_name.c: teach find_short_packed_object() a commit-only option
  2012-06-18 22:05 [PATCH 0/9] Extending the shelf life of "git describe" output Junio C Hamano
                   ` (5 preceding siblings ...)
  2012-06-18 22:05 ` Junio C Hamano
@ 2012-06-18 22:05 ` Junio C Hamano
  2012-06-18 22:05 ` [PATCH 7/9] sha1_name.c: allow get_short_sha1() to take other flags Junio C Hamano
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Junio C Hamano @ 2012-06-18 22:05 UTC (permalink / raw)
  To: git

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 sha1_name.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index a283c85..262d7e1 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -97,6 +97,7 @@ static int unique_in_pack(int len,
 			  const unsigned char *match,
 			  struct packed_git *p,
 			  const unsigned char **found_sha1,
+			  int commit_only,
 			  int seen_so_far)
 {
 	uint32_t num, last, i, first = 0;
@@ -134,6 +135,8 @@ static int unique_in_pack(int len,
 			break;
 
 		/* current matches */
+		if (commit_only && !is_commit_object(current))
+			continue;
 		if (!seen_so_far) {
 			*found_sha1 = current;
 			seen_so_far++;
@@ -146,7 +149,8 @@ static int unique_in_pack(int len,
 	return seen_so_far;
 }
 
-static int find_short_packed_object(int len, const unsigned char *match, unsigned char *sha1)
+static int find_short_packed_object(int len, const unsigned char *match,
+				    unsigned char *sha1, int commit_only)
 {
 	struct packed_git *p;
 	const unsigned char *found_sha1 = NULL;
@@ -154,7 +158,8 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne
 
 	prepare_packed_git();
 	for (p = packed_git; p && found < 2; p = p->next)
-		found = unique_in_pack(len, match, p, &found_sha1, found);
+		found = unique_in_pack(len, match, p, &found_sha1,
+				       commit_only, found);
 
 	if (found == 1)
 		hashcpy(sha1, found_sha1);
@@ -172,7 +177,7 @@ static int find_unique_short_object(int len, char *canonical,
 
 	prepare_alt_odb();
 	has_unpacked = find_short_object_filename(len, canonical, unpacked_sha1, 0);
-	has_packed = find_short_packed_object(len, res, packed_sha1);
+	has_packed = find_short_packed_object(len, res, packed_sha1, 0);
 	if (!has_unpacked && !has_packed)
 		return SHORT_NAME_NOT_FOUND;
 	if (1 < has_unpacked || 1 < has_packed)
-- 
1.7.11

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 7/9] sha1_name.c: allow get_short_sha1() to take other flags
  2012-06-18 22:05 [PATCH 0/9] Extending the shelf life of "git describe" output Junio C Hamano
                   ` (6 preceding siblings ...)
  2012-06-18 22:05 ` [PATCH 6/9] sha1_name.c: teach find_short_packed_object() " Junio C Hamano
@ 2012-06-18 22:05 ` Junio C Hamano
  2012-06-18 22:05 ` [PATCH 8/9] sha1_name.c: teach get_short_sha1() a commit-only option Junio C Hamano
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Junio C Hamano @ 2012-06-18 22:05 UTC (permalink / raw)
  To: git

Instead of a separate "int quietly" argument, make it take "unsigned flags"
so that we can pass other options to it.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 sha1_name.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index 262d7e1..df11ded 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -193,12 +193,15 @@ static int find_unique_short_object(int len, char *canonical,
 	return 0;
 }
 
+#define GET_SHORT_QUIETLY 01
+
 static int get_short_sha1(const char *name, int len, unsigned char *sha1,
-			  int quietly)
+			  unsigned flags)
 {
 	int i, status;
 	char canonical[40];
 	unsigned char res[20];
+	int quietly = !!(flags & GET_SHORT_QUIETLY);
 
 	if (len < MINIMUM_ABBREV || len > 40)
 		return -1;
@@ -240,7 +243,7 @@ const char *find_unique_abbrev(const unsigned char *sha1, int len)
 		return hex;
 	while (len < 40) {
 		unsigned char sha1_ret[20];
-		status = get_short_sha1(hex, len, sha1_ret, 1);
+		status = get_short_sha1(hex, len, sha1_ret, GET_SHORT_QUIETLY);
 		if (exists
 		    ? !status
 		    : status == SHORT_NAME_NOT_FOUND) {
@@ -571,7 +574,7 @@ static int get_describe_name(const char *name, int len, unsigned char *sha1)
 			if (ch == 'g' && cp[-1] == '-') {
 				cp++;
 				len -= cp - name;
-				return get_short_sha1(cp, len, sha1, 1);
+				return get_short_sha1(cp, len, sha1, GET_SHORT_QUIETLY);
 			}
 		}
 	}
-- 
1.7.11

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 8/9] sha1_name.c: teach get_short_sha1() a commit-only option
  2012-06-18 22:05 [PATCH 0/9] Extending the shelf life of "git describe" output Junio C Hamano
                   ` (7 preceding siblings ...)
  2012-06-18 22:05 ` [PATCH 7/9] sha1_name.c: allow get_short_sha1() to take other flags Junio C Hamano
@ 2012-06-18 22:05 ` Junio C Hamano
  2012-06-18 22:05 ` [PATCH 9/9] sha1_name.c: get_describe_name() by definition groks only commits Junio C Hamano
  2012-06-19  7:14 ` [PATCH 0/9] Extending the shelf life of "git describe" output Thomas Rast
  10 siblings, 0 replies; 14+ messages in thread
From: Junio C Hamano @ 2012-06-18 22:05 UTC (permalink / raw)
  To: git

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 sha1_name.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index df11ded..4a0fefd 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -170,14 +170,17 @@ static int find_short_packed_object(int len, const unsigned char *match,
 #define SHORT_NAME_AMBIGUOUS (-2)
 
 static int find_unique_short_object(int len, char *canonical,
-				    unsigned char *res, unsigned char *sha1)
+				    unsigned char *res, unsigned char *sha1,
+				    int commit_only)
 {
 	int has_unpacked, has_packed;
 	unsigned char unpacked_sha1[20], packed_sha1[20];
 
 	prepare_alt_odb();
-	has_unpacked = find_short_object_filename(len, canonical, unpacked_sha1, 0);
-	has_packed = find_short_packed_object(len, res, packed_sha1, 0);
+	has_unpacked = find_short_object_filename(len, canonical, unpacked_sha1,
+						  commit_only);
+	has_packed = find_short_packed_object(len, res, packed_sha1,
+					      commit_only);
 	if (!has_unpacked && !has_packed)
 		return SHORT_NAME_NOT_FOUND;
 	if (1 < has_unpacked || 1 < has_packed)
@@ -194,6 +197,7 @@ static int find_unique_short_object(int len, char *canonical,
 }
 
 #define GET_SHORT_QUIETLY 01
+#define GET_SHORT_COMMIT_ONLY 02
 
 static int get_short_sha1(const char *name, int len, unsigned char *sha1,
 			  unsigned flags)
@@ -226,7 +230,8 @@ static int get_short_sha1(const char *name, int len, unsigned char *sha1,
 		res[i >> 1] |= val;
 	}
 
-	status = find_unique_short_object(i, canonical, res, sha1);
+	status = find_unique_short_object(i, canonical, res, sha1,
+					  !!(flags & GET_SHORT_COMMIT_ONLY));
 	if (!quietly && (status == SHORT_NAME_AMBIGUOUS))
 		return error("short SHA1 %.*s is ambiguous.", len, canonical);
 	return status;
-- 
1.7.11

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 9/9] sha1_name.c: get_describe_name() by definition groks only commits
  2012-06-18 22:05 [PATCH 0/9] Extending the shelf life of "git describe" output Junio C Hamano
                   ` (8 preceding siblings ...)
  2012-06-18 22:05 ` [PATCH 8/9] sha1_name.c: teach get_short_sha1() a commit-only option Junio C Hamano
@ 2012-06-18 22:05 ` Junio C Hamano
  2012-06-19  7:14 ` [PATCH 0/9] Extending the shelf life of "git describe" output Thomas Rast
  10 siblings, 0 replies; 14+ messages in thread
From: Junio C Hamano @ 2012-06-18 22:05 UTC (permalink / raw)
  To: git

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 sha1_name.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sha1_name.c b/sha1_name.c
index 4a0fefd..b09a23e 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -569,6 +569,7 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
 static int get_describe_name(const char *name, int len, unsigned char *sha1)
 {
 	const char *cp;
+	unsigned flags = GET_SHORT_QUIETLY | GET_SHORT_COMMIT_ONLY;
 
 	for (cp = name + len - 1; name + 2 <= cp; cp--) {
 		char ch = *cp;
@@ -579,7 +580,7 @@ static int get_describe_name(const char *name, int len, unsigned char *sha1)
 			if (ch == 'g' && cp[-1] == '-') {
 				cp++;
 				len -= cp - name;
-				return get_short_sha1(cp, len, sha1, GET_SHORT_QUIETLY);
+				return get_short_sha1(cp, len, sha1, flags);
 			}
 		}
 	}
-- 
1.7.11

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 0/9] Extending the shelf life of "git describe" output
  2012-06-18 22:05 [PATCH 0/9] Extending the shelf life of "git describe" output Junio C Hamano
                   ` (9 preceding siblings ...)
  2012-06-18 22:05 ` [PATCH 9/9] sha1_name.c: get_describe_name() by definition groks only commits Junio C Hamano
@ 2012-06-19  7:14 ` Thomas Rast
  2012-06-19 23:08   ` Junio C Hamano
  10 siblings, 1 reply; 14+ messages in thread
From: Thomas Rast @ 2012-06-19  7:14 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Junio C Hamano <gitster@pobox.com> writes:

> This series teaches the sha1_name machinery to only look for
> unambigous commit object names when the caller knows that the name
> must refer to a commit object.
[...]
>  - You will further be able to extend the lifetime of uniqueness of
>    "git describe" output if you take advantage of the "tagname" or
>    "number". The current parser does not do this.
>
>    There are a number of ways to do this, but probably the cleanest
>    would be to (you only can do this when you have "tagname" tag
>    locally; you may not have it) pass the tag and the number down to
>    the find_short_*() routines with commit_only set, and when they
>    find a commit that match the prefix, inside is_commit_object()
>    test, check also that the commit reaches the given tag object in
>    the given number steps (otherwise discard it as it is not the one
>    you are looking for).
>
>  - Some callers that are involved in the get_sha1_1() callpath know
>    that the name they have must be referring to commit objects (e.g.
>    get_parent() and get_nth_ancestor()).  It might be worthwhile to
>    let get_sha1_1() know that the caller knows the name it is
>    feeding must refer to a commit object, and have the uniqueness
>    logic take advantage of it.
>
>    I think that most of these callers are expecting to parse a
>    committish and the user may have given them the name of a a tag
>    object that peels to a commit, so you would need to add a new
>    GET_SHORT_COMMITTISH that allows any committish, in addition to
>    the GET_SHORT_COMMIT_ONLY this series adds, if you want to do
>    this.

Two random thoughts:

* The commit_only flag is only one thing you may "know" about the
  parsing, as you state above.  E.g., we may know the distance from a
  certain tag.  Given this, wouldn't it be cleaner to patch a struct
  things_we_know into the call chain instead of only a flag?

* The treeish:path syntax also "knows" that the left side must be or
  peel to a tree, so it makes no sense to go looking for a blob.

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 0/9] Extending the shelf life of "git describe" output
  2012-06-19  7:14 ` [PATCH 0/9] Extending the shelf life of "git describe" output Thomas Rast
@ 2012-06-19 23:08   ` Junio C Hamano
  2012-06-20  7:40     ` Thomas Rast
  0 siblings, 1 reply; 14+ messages in thread
From: Junio C Hamano @ 2012-06-19 23:08 UTC (permalink / raw)
  To: Thomas Rast; +Cc: git

Thomas Rast <trast@student.ethz.ch> writes:

> Two random thoughts:
>
> * The commit_only flag is only one thing you may "know" about the
>   parsing, as you state above.  E.g., we may know the distance from a
>   certain tag.  Given this, wouldn't it be cleaner to patch a struct
>   things_we_know into the call chain instead of only a flag?
>
> * The treeish:path syntax also "knows" that the left side must be or
>   peel to a tree, so it makes no sense to go looking for a blob.

Both good.  I take it to mean that we found a volunteer to take the
ownership of the second idea to build on top of the series ;-)

Thanks.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 0/9] Extending the shelf life of "git describe" output
  2012-06-19 23:08   ` Junio C Hamano
@ 2012-06-20  7:40     ` Thomas Rast
  0 siblings, 0 replies; 14+ messages in thread
From: Thomas Rast @ 2012-06-20  7:40 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Junio C Hamano <gitster@pobox.com> writes:

> Thomas Rast <trast@student.ethz.ch> writes:
>
>> Two random thoughts:
>>
>> * The commit_only flag is only one thing you may "know" about the
>>   parsing, as you state above.  E.g., we may know the distance from a
>>   certain tag.  Given this, wouldn't it be cleaner to patch a struct
>>   things_we_know into the call chain instead of only a flag?
>>
>> * The treeish:path syntax also "knows" that the left side must be or
>>   peel to a tree, so it makes no sense to go looking for a blob.
>
> Both good.  I take it to mean that we found a volunteer to take the
> ownership of the second idea to build on top of the series ;-)

Does the idea come with round tuits included? :-)

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2012-06-20  7:40 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-18 22:05 [PATCH 0/9] Extending the shelf life of "git describe" output Junio C Hamano
2012-06-18 22:05 ` [PATCH 1/9] sha1_name.c: indentation fix Junio C Hamano
2012-06-18 22:05 ` [PATCH 2/9] sha1_name.c: clarify what "fake" is for in find_short_object_filename() Junio C Hamano
2012-06-18 22:05 ` [PATCH 3/9] sha1_name.c: rename "now" to "current" Junio C Hamano
2012-06-18 22:05 ` [PATCH 4/9] sha1_name.c: refactor find_short_packed_object() Junio C Hamano
2012-06-18 22:05 ` [PATCH 5/9] sha1_name.c: teach find_short_object_filename() a commit-only option Junio C Hamano
2012-06-18 22:05 ` Junio C Hamano
2012-06-18 22:05 ` [PATCH 6/9] sha1_name.c: teach find_short_packed_object() " Junio C Hamano
2012-06-18 22:05 ` [PATCH 7/9] sha1_name.c: allow get_short_sha1() to take other flags Junio C Hamano
2012-06-18 22:05 ` [PATCH 8/9] sha1_name.c: teach get_short_sha1() a commit-only option Junio C Hamano
2012-06-18 22:05 ` [PATCH 9/9] sha1_name.c: get_describe_name() by definition groks only commits Junio C Hamano
2012-06-19  7:14 ` [PATCH 0/9] Extending the shelf life of "git describe" output Thomas Rast
2012-06-19 23:08   ` Junio C Hamano
2012-06-20  7:40     ` Thomas Rast

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).