Add support for %(objectname:short,<length>) which would print the
abbreviated unique objectname of given length. When no length is
specified 7 is used. The minimum length is 4.

Add tests and documentation for the same.

Mentored-by: Christian Couder <[email protected]>
Mentored-by: Matthieu Moy <[email protected]>
Signed-off-by: Karthik Nayak <[email protected]>
---
 Documentation/git-for-each-ref.txt |  2 ++
 ref-filter.c                       | 39 ++++++++++++++++++++++++++++++--------
 t/t6300-for-each-ref.sh            | 22 +++++++++++++++++++++
 3 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/Documentation/git-for-each-ref.txt 
b/Documentation/git-for-each-ref.txt
index 6a476ba..5097915 100644
--- a/Documentation/git-for-each-ref.txt
+++ b/Documentation/git-for-each-ref.txt
@@ -103,6 +103,8 @@ objectsize::
 objectname::
        The object name (aka SHA-1).
        For a non-ambiguous abbreviation of the object name append `:short`.
+       The length can be explicitly specified by appending either
+       `:short,<length>` or `:<length>,short`.  Minimum length is 4.
 
 upstream::
        The name of a local ref which can be considered ``upstream''
diff --git a/ref-filter.c b/ref-filter.c
index b0e86ae..223daeb 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -454,14 +454,37 @@ static void *get_obj(const unsigned char *sha1, struct 
object **obj, unsigned lo
 static int grab_objectname(const char *name, const unsigned char *sha1,
                            struct atom_value *v)
 {
-       if (!strcmp(name, "objectname")) {
-               char *s = xmalloc(41);
-               strcpy(s, sha1_to_hex(sha1));
-               v->s = s;
-               return 1;
-       }
-       if (!strcmp(name, "objectname:short")) {
-               v->s = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV));
+       const char *p;
+
+       if (match_atom_name(name, "objectname", &p)) {
+               struct strbuf **s, **to_free;
+               int length = DEFAULT_ABBREV;
+
+               /*  No arguments given, copy the entire objectname */
+               if (!p) {
+                       char *s = xmalloc(41);
+                       strcpy(s, sha1_to_hex(sha1));
+                       v->s = s;
+               } else {
+                       s = to_free = strbuf_split_str(p, ',', 0);
+                       while (*s) {
+                               /*  Strip trailing comma */
+                               if (s[1])
+                                       strbuf_setlen(s[0], s[0]->len - 1);
+                               if (!strtoul_ui(s[0]->buf, 10, (unsigned int 
*)&length))
+                                       ;
+                               /*  The `short` argument uses the default 
length */
+                               else if (!strcmp("short", s[0]->buf))
+                                       ;
+                               else
+                                       die(_("format: unknown option entered 
with objectname:%s"), s[0]->buf);
+                               s++;
+                       }
+                       if (length < MINIMUM_ABBREV)
+                               length = MINIMUM_ABBREV;
+                       v->s = xstrdup(find_unique_abbrev(sha1, length));
+                       free(to_free);
+               }
                return 1;
        }
        return 0;
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index 7c9bec7..7f675d2 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -385,6 +385,28 @@ test_expect_success 'Check short objectname format' '
        test_cmp expected actual
 '
 
+cat >expected <<EOF
+$(git rev-parse --short=1 HEAD)
+EOF
+
+test_expect_success 'Check objectname:short format when size is less than 
MINIMUM_ABBREV' '
+       git for-each-ref --format="%(objectname:short,1)" refs/heads >actual &&
+       test_cmp expected actual
+'
+
+cat >expected <<EOF
+$(git rev-parse --short=10 HEAD)
+EOF
+
+test_expect_success 'Check objectname:short format' '
+       git for-each-ref --format="%(objectname:short,10)" refs/heads >actual &&
+       test_cmp expected actual
+'
+
+test_expect_success 'Check objectname:short format for invalid input' '
+       test_must_fail git for-each-ref --format="%(objectname:short,-1)" 
refs/heads
+'
+
 test_expect_success 'Check for invalid refname format' '
        test_must_fail git for-each-ref --format="%(refname:INVALID)"
 '
-- 
2.6.0

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to