name-rev: allow converting the exact object name at the tip of a ref
"git name-rev" is supposed to convert given object names into strings that name the same objects based on refs, that can be fed to "git rev-parse" to get the same object names back, so the output for the commit object v1.8.3^0 (i.e. the commit tagged as v1.8.3) $ git rev-parse v1.8.3 v1.8.3^0 | git name-rev --stdinmaint8af06057d0
edca415256
(tags/v1.8.3^0) has to have "^0" at the end, as "edca41" is a commit, not the tag that references it. But we do not get anything for the tag object (8af0605
) itself. This is because the command however did not bother to see if the object is at the tip of some ref, and failed to convert a tag object. Teach it to show this instead: $ git rev-parse v1.8.3 v1.8.3^0 | git name-rev --stdin8af06057d0
(tags/v1.8.3)edca415256
(tags/v1.8.3^0) Signed-off-by: Junio C Hamano <gitster@pobox.com>
parent
9608a190c0
commit
b23e0b9353
|
@ -4,6 +4,7 @@
|
|||
#include "tag.h"
|
||||
#include "refs.h"
|
||||
#include "parse-options.h"
|
||||
#include "sha1-lookup.h"
|
||||
|
||||
#define CUTOFF_DATE_SLOP 86400 /* one day */
|
||||
|
||||
|
@ -113,6 +114,34 @@ struct name_ref_data {
|
|||
const char *ref_filter;
|
||||
};
|
||||
|
||||
static struct tip_table {
|
||||
struct tip_table_entry {
|
||||
unsigned char sha1[20];
|
||||
const char *refname;
|
||||
} *table;
|
||||
int nr;
|
||||
int alloc;
|
||||
int sorted;
|
||||
} tip_table;
|
||||
|
||||
static void add_to_tip_table(const unsigned char *sha1, const char *refname,
|
||||
int shorten_unambiguous)
|
||||
{
|
||||
refname = name_ref_abbrev(refname, shorten_unambiguous);
|
||||
|
||||
ALLOC_GROW(tip_table.table, tip_table.nr + 1, tip_table.alloc);
|
||||
hashcpy(tip_table.table[tip_table.nr].sha1, sha1);
|
||||
tip_table.table[tip_table.nr].refname = xstrdup(refname);
|
||||
tip_table.nr++;
|
||||
tip_table.sorted = 0;
|
||||
}
|
||||
|
||||
static int tipcmp(const void *a_, const void *b_)
|
||||
{
|
||||
const struct tip_table_entry *a = a_, *b = b_;
|
||||
return hashcmp(a->sha1, b->sha1);
|
||||
}
|
||||
|
||||
static int name_ref(const char *path, const unsigned char *sha1, int flags, void *cb_data)
|
||||
{
|
||||
struct object *o = parse_object(sha1);
|
||||
|
@ -135,6 +164,8 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void
|
|||
}
|
||||
}
|
||||
|
||||
add_to_tip_table(sha1, path, can_abbreviate_output);
|
||||
|
||||
while (o && o->type == OBJ_TAG) {
|
||||
struct tag *t = (struct tag *) o;
|
||||
if (!t->tagged)
|
||||
|
@ -151,6 +182,32 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const unsigned char *nth_tip_table_ent(size_t ix, void *table_)
|
||||
{
|
||||
struct tip_table_entry *table = table_;
|
||||
return table[ix].sha1;
|
||||
}
|
||||
|
||||
static const char *get_exact_ref_match(const struct object *o)
|
||||
{
|
||||
int found;
|
||||
|
||||
if (!tip_table.table || !tip_table.nr)
|
||||
return NULL;
|
||||
|
||||
if (!tip_table.sorted) {
|
||||
qsort(tip_table.table, tip_table.nr, sizeof(*tip_table.table),
|
||||
tipcmp);
|
||||
tip_table.sorted = 1;
|
||||
}
|
||||
|
||||
found = sha1_pos(o->sha1, tip_table.table, tip_table.nr,
|
||||
nth_tip_table_ent);
|
||||
if (0 <= found)
|
||||
return tip_table.table[found].refname;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* returns a static buffer */
|
||||
static const char *get_rev_name(const struct object *o)
|
||||
{
|
||||
|
@ -159,7 +216,7 @@ static const char *get_rev_name(const struct object *o)
|
|||
struct commit *c;
|
||||
|
||||
if (o->type != OBJ_COMMIT)
|
||||
return NULL;
|
||||
return get_exact_ref_match(o);
|
||||
c = (struct commit *) o;
|
||||
n = c->util;
|
||||
if (!n)
|
||||
|
|
Loading…
Reference in New Issue