Skip to content

Commit

Permalink
show-branch: optionally use unique prefix as name.
Browse files Browse the repository at this point in the history
git-show-branch acquires two new options. --sha1-name to name
commits using the unique prefix of their object names, and
--no-name to not to show names at all.

This was outlined in <7vk6gpyuyr.fsf@assigned-by-dhcp.cox.net>

Signed-off-by: Junio C Hamano <junkio@cox.net>
  • Loading branch information
Junio C Hamano committed Oct 11, 2005
1 parent f2d6a25 commit 013f276
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 44 deletions.
26 changes: 10 additions & 16 deletions Documentation/git-show-branch.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ git-show-branch - Show branches and their commits.

SYNOPSIS
--------
'git-show-branch [--all] [--heads] [--tags] [--more=<n> | --list | --independent | --merge-base] <reference>...'
'git-show-branch [--all] [--heads] [--tags] [--more=<n> | --list | --independent | --merge-base] [--no-name | --sha1-name] <reference>...'

DESCRIPTION
-----------
Expand Down Expand Up @@ -44,6 +44,15 @@ OPTIONS
Among the <reference>s given, display only the ones that
cannot be reached from any other <reference>.

--no-name::
Do not show naming strings for each commit.

--sha1-name::
Instead of naming the commits using the path to reach
them from heads (e.g. "master~2" to mean the grandparent
of "master"), name them with the unique prefix of their
object names.

Note that --more, --list, --independent and --merge-base options
are mutually exclusive.

Expand Down Expand Up @@ -88,21 +97,6 @@ whose commit message is "Add 'git show-branch'. "fixes" branch
adds one commit 'Introduce "reset type"'. "mhf" branch has many
other commits.

When only one head is given, the output format changes slightly
to conserve space. The '+' sign to show which commit is
reachable from which head and the first N lines to show the list
of heads being displayed are both meaningless so they are
omitted. Also the label given to each commit does not repeat
the name of the branch because it is obvious.

------------------------------------------------
$ git show-branch --more=4 master
[master] Add 'git show-branch'.
[~1] Add a new extended SHA1 syntax <name>~<num>
[~2] Fix "git-diff A B"
[~3] git-ls-files: generalized pathspecs
[~4] Make "git-ls-files" work in subdirectories
------------------------------------------------

Author
------
Expand Down
1 change: 1 addition & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ extern char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)
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);
extern const unsigned char null_sha1[20];

int git_mkstemp(char *path, size_t n, const char *template);
Expand Down
40 changes: 33 additions & 7 deletions sha1_name.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne
return found;
}

#define SHORT_NAME_NOT_FOUND (-1)
#define SHORT_NAME_AMBIGUOUS (-2)

static int find_unique_short_object(int len, char *canonical,
unsigned char *res, unsigned char *sha1)
{
Expand All @@ -128,23 +131,24 @@ static int find_unique_short_object(int len, char *canonical,
has_unpacked = find_short_object_filename(len, canonical, unpacked_sha1);
has_packed = find_short_packed_object(len, res, packed_sha1);
if (!has_unpacked && !has_packed)
return -1;
return SHORT_NAME_NOT_FOUND;
if (1 < has_unpacked || 1 < has_packed)
return error("short SHA1 %.*s is ambiguous.", len, canonical);
return SHORT_NAME_AMBIGUOUS;
if (has_unpacked != has_packed) {
memcpy(sha1, (has_packed ? packed_sha1 : unpacked_sha1), 20);
return 0;
}
/* Both have unique ones -- do they match? */
if (memcmp(packed_sha1, unpacked_sha1, 20))
return error("short SHA1 %.*s is ambiguous.", len, canonical);
return -2;
memcpy(sha1, packed_sha1, 20);
return 0;
}

static int get_short_sha1(const char *name, int len, unsigned char *sha1)
static int get_short_sha1(const char *name, int len, unsigned char *sha1,
int quietly)
{
int i;
int i, status;
char canonical[40];
unsigned char res[20];

Expand All @@ -171,7 +175,29 @@ static int get_short_sha1(const char *name, int len, unsigned char *sha1)
res[i >> 1] |= val;
}

return find_unique_short_object(i, canonical, res, sha1);
status = find_unique_short_object(i, canonical, res, sha1);
if (!quietly && (status == SHORT_NAME_AMBIGUOUS))
return error("short SHA1 %.*s is ambiguous.", len, canonical);
return status;
}

const char *find_unique_abbrev(const unsigned char *sha1, int len)
{
int status;
static char hex[41];
memcpy(hex, sha1_to_hex(sha1), 40);
while (len < 40) {
unsigned char sha1_ret[20];
status = get_short_sha1(hex, len, sha1_ret, 1);
if (!status) {
hex[len] = 0;
return hex;
}
if (status != SHORT_NAME_AMBIGUOUS)
return NULL;
len++;
}
return NULL;
}

static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
Expand Down Expand Up @@ -292,7 +318,7 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1)
ret = get_sha1_basic(name, len, sha1);
if (!ret)
return 0;
return get_short_sha1(name, len, sha1);
return get_short_sha1(name, len, sha1, 0);
}

/*
Expand Down
59 changes: 38 additions & 21 deletions show-branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,25 +133,28 @@ static void name_commits(struct commit_list *list,
nth = 0;
while (parents) {
struct commit *p = parents->item;
char newname[1000];
char newname[1000], *en;
parents = parents->next;
nth++;
if (p->object.util)
continue;
en = newname;
switch (n->generation) {
case 0:
sprintf(newname, "%s^%d",
n->head_name, nth);
en += sprintf(en, "%s", n->head_name);
break;
case 1:
sprintf(newname, "%s^^%d",
n->head_name, nth);
en += sprintf(en, "%s^", n->head_name);
break;
default:
sprintf(newname, "%s~%d^%d",
n->head_name, n->generation,
nth);
en += sprintf(en, "%s~%d",
n->head_name, n->generation);
break;
}
if (nth == 1)
en += sprintf(en, "^");
else
en += sprintf(en, "^%d", nth);
name_commit(p, strdup(newname), 0);
i++;
name_first_parent_chain(p);
Expand Down Expand Up @@ -205,7 +208,7 @@ static void join_revs(struct commit_list **list_p,
}
}

static void show_one_commit(struct commit *commit)
static void show_one_commit(struct commit *commit, int no_name)
{
char pretty[128], *cp;
struct commit_name *name = commit->object.util;
Expand All @@ -218,11 +221,21 @@ static void show_one_commit(struct commit *commit)
cp = pretty + 8;
else
cp = pretty;
if (name && name->head_name) {
printf("[%s", name->head_name);
if (name->generation)
printf("~%d", name->generation);
printf("] ");

if (!no_name) {
if (name && name->head_name) {
printf("[%s", name->head_name);
if (name->generation) {
if (name->generation == 1)
printf("^");
else
printf("~%d", name->generation);
}
printf("] ");
}
else
printf("[%s] ",
find_unique_abbrev(commit->object.sha1, 7));
}
puts(cp);
}
Expand Down Expand Up @@ -354,7 +367,8 @@ int main(int ac, char **av)
unsigned char head_sha1[20];
int merge_base = 0;
int independent = 0;
char **label;
int no_name = 0;
int sha1_name = 0;

setup_git_directory();

Expand All @@ -370,6 +384,10 @@ int main(int ac, char **av)
extra = 1;
else if (!strcmp(arg, "--list"))
extra = -1;
else if (!strcmp(arg, "--no-name"))
no_name = 1;
else if (!strcmp(arg, "--sha1-name"))
sha1_name = 1;
else if (!strncmp(arg, "--more=", 7))
extra = atoi(arg + 7);
else if (!strcmp(arg, "--merge-base"))
Expand Down Expand Up @@ -465,7 +483,8 @@ int main(int ac, char **av)
printf("%c [%s] ",
is_head ? '*' : '!', ref_name[i]);
}
show_one_commit(rev[i]);
/* header lines never need name */
show_one_commit(rev[i], 1);
}
if (0 <= extra) {
for (i = 0; i < num_rev; i++)
Expand All @@ -480,7 +499,8 @@ int main(int ac, char **av)
sort_in_topological_order(&seen);

/* Give names to commits */
name_commits(seen, rev, ref_name, num_rev);
if (!sha1_name && !no_name)
name_commits(seen, rev, ref_name, num_rev);

all_mask = ((1u << (REV_SHIFT + num_rev)) - 1);
all_revs = all_mask & ~((1u << REV_SHIFT) - 1);
Expand All @@ -490,7 +510,6 @@ int main(int ac, char **av)
struct commit *commit = pop_one_commit(&seen);
int this_flag = commit->object.flags;
int is_merge_point = (this_flag & all_revs) == all_revs;
static char *obvious[] = { "" };

if (is_merge_point)
shown_merge_point = 1;
Expand All @@ -501,9 +520,7 @@ int main(int ac, char **av)
? '+' : ' ');
putchar(' ');
}
show_one_commit(commit);
if (num_rev == 1)
label = obvious;
show_one_commit(commit, no_name);
if (shown_merge_point && is_merge_point)
if (--extra < 0)
break;
Expand Down

0 comments on commit 013f276

Please sign in to comment.