{"thread":{"id":"2227","subject":"[PATCH] Add git-name-rev","startedAt":"2005-10-25T23:05:59Z","lastAt":"2005-10-27T08:53:19Z","messageCount":4,"participants":["Johannes Schindelin","Petr Baudis","Matthias Urlichs"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"10620","messageId":"Pine.LNX.4.63.0510260103570.27364@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2227","inReplyTo":null,"subject":"[PATCH] Add git-name-rev","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-10-25T23:05:59Z","receivedAt":"2005-10-25T23:05:59Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"git-name-rev tries to find nice symbolic names for commits. It does so by \nwalking the commits from the refs. When the symbolic name is ambiguous, \nthe following heuristic is applied: Try to avoid too many ~'s, and if two \nambiguous names have the same count of ~'s, take the one whose last number \nis smaller.\n\nSigned-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n\n---\n\n\tThis is a toy which may help you, too. In case it is still not \n\tclear what it does:\n\n\t$ git-name-rev 33db5f4d9027a10e477ccf054b2c1ab94f74c85a\n\n\t33db5f4d9027a10e477ccf054b2c1ab94f74c85a v0.99^0~940\n\n\tA thing like this is very useful for debugging git-fetch-pack: If \n\tyou see that a certain rev is common, you can now understand in \n\tmore detail where this rev is.\n\n .gitignore                     |    1 \n Documentation/git-name-rev.txt |   47 ++++++++++++\n Makefile                       |    2 \n name-rev.c                     |  162 ++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 211 insertions(+), 1 deletions(-)\n create mode 100644 Documentation/git-name-rev.txt\n create mode 100644 name-rev.c\n\napplies-to: 2152f0960114f638d74c4919a850dd597963ac52\nbc2caae16f461e3b496d27e3f038cbb6d141706c\ndiff --git a/.gitignore b/.gitignore\nindex 52cb9e2..fe16651 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -54,6 +54,7 @@ git-merge-recursive\n git-merge-resolve\n git-merge-stupid\n git-mktag\n+git-name-rev\n git-octopus\n git-pack-objects\n git-parse-remote\ndiff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.txt\nnew file mode 100644\nindex 0000000..6a7bb07\n--- /dev/null\n+++ b/Documentation/git-name-rev.txt\n@@ -0,0 +1,47 @@\n+git-name-rev(1)\n+===============\n+\n+NAME\n+----\n+git-name-rev - Find symbolic names for given revs.\n+\n+\n+SYNOPSIS\n+--------\n+'git-name-rev' <commitish>...\n+\n+DESCRIPTION\n+-----------\n+Finds symbolic names suitable for human digestion for revisions given in any\n+format parsable by git-rev-parse.\n+\n+\n+EXAMPLE\n+-------\n+\n+Given a commit, find out where it is relative to the local refs. Say somebody\n+wrote you about that phantastic commit 33db5f4d9027a10e477ccf054b2c1ab94f74c85a.\n+Of course, you look into the commit, but that only tells you what happened, but\n+not the context.\n+\n+Enter git-name-rev:\n+\n+------------\n+% git name-rev 33db5f4d9027a10e477ccf054b2c1ab94f74c85a\n+------------\n+\n+Now you are wiser, because you know that it happened 940 revisions before v0.99.\n+\n+\n+Author\n+------\n+Written by Johannes Schindelin <Johannes.Schindelin@gmx.de>\n+\n+Documentation\n+--------------\n+Documentation by Johannes Schindelin.\n+\n+GIT\n+---\n+Part of the gitlink:git[7] suite\n+\ndiff --git a/Makefile b/Makefile\nindex d6fd706..4877abb 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -122,7 +122,7 @@ PROGRAMS = \\\n \tgit-unpack-objects$X git-update-index$X git-update-server-info$X \\\n \tgit-upload-pack$X git-verify-pack$X git-write-tree$X \\\n \tgit-update-ref$X git-symbolic-ref$X git-check-ref-format$X \\\n-\t$(SIMPLE_PROGRAMS)\n+\tgit-name-rev$X $(SIMPLE_PROGRAMS)\n \n # Backward compatibility -- to be removed after 1.0\n PROGRAMS += git-ssh-pull$X git-ssh-push$X\ndiff --git a/name-rev.c b/name-rev.c\nnew file mode 100644\nindex 0000000..a3a095e\n--- /dev/null\n+++ b/name-rev.c\n@@ -0,0 +1,162 @@\n+#include <stdlib.h>\n+#include \"cache.h\"\n+#include \"commit.h\"\n+#include \"tag.h\"\n+#include \"refs.h\"\n+\n+static const char name_rev_usage[] =\n+\t\"git-name-rev commitish [commitish...]\\n\";\n+\n+typedef struct rev_name {\n+\tconst char *tip_name;\n+\tint merge_traversals;\n+\tint generation;\n+} rev_name;\n+\n+static long cutoff = LONG_MAX;\n+\n+static void name_rev(struct commit *commit,\n+\t\tconst char *tip_name, int merge_traversals, int generation,\n+\t\tint deref)\n+{\n+\tstruct rev_name *name = (struct rev_name *)commit->object.util;\n+\tstruct commit_list *parents;\n+\tint parent_number = 0;\n+\n+\tif (!commit->object.parsed)\n+\t\tparse_commit(commit);\n+\n+\tif (commit->date < cutoff)\n+\t\treturn;\n+\n+\tif (deref) {\n+\t\tchar *new_name = xmalloc(strlen(tip_name)+3);\n+\t\tstrcpy(new_name, tip_name);\n+\t\tstrcat(new_name, \"^0\");\n+\t\ttip_name = new_name;\n+\n+\t\tif (generation)\n+\t\t\tdie(\"generation: %d, but deref?\", generation);\n+\t}\n+\n+\tif (name == NULL) {\n+\t\tname = xmalloc(sizeof(rev_name));\n+\t\tcommit->object.util = name;\n+\t\tgoto copy_data;\n+\t} else if (name->merge_traversals > merge_traversals ||\n+\t\t\t(name->merge_traversals == merge_traversals &&\n+\t\t\t name->generation > generation)) {\n+copy_data:\n+\t\tname->tip_name = tip_name;\n+\t\tname->merge_traversals = merge_traversals;\n+\t\tname->generation = generation;\n+\t} else\n+\t\treturn;\n+\n+\tfor (parents = commit->parents;\n+\t\t\tparents;\n+\t\t\tparents = parents->next, parent_number++) {\n+\t\tif (parent_number > 0) {\n+\t\t\tchar *new_name = xmalloc(strlen(tip_name)+8);\n+\n+\t\t\tif (generation > 0)\n+\t\t\t\tsprintf(new_name, \"%s~%d^%d\", tip_name,\n+\t\t\t\t\t\tgeneration, parent_number);\n+\t\t\telse\n+\t\t\t\tsprintf(new_name, \"%s^%d\", tip_name, parent_number);\n+\n+\t\t\tname_rev(parents->item, new_name,\n+\t\t\t\tmerge_traversals + 1 , 0, 0);\n+\t\t} else {\n+\t\t\tname_rev(parents->item, tip_name, merge_traversals,\n+\t\t\t\tgeneration + 1, 0);\n+\t\t}\n+\t}\n+}\n+\n+static int name_ref(const char *path, const unsigned char *sha1)\n+{\n+\tstruct object *o = parse_object(sha1);\n+\tint deref = 0;\n+\n+\twhile (o && o->type == tag_type) {\n+\t\tstruct tag *t = (struct tag *) o;\n+\t\tif (!t->tagged)\n+\t\t\tbreak; /* broken repository */\n+\t\to = parse_object(t->tagged->sha1);\n+\t\tderef = 1;\n+\t}\n+\tif (o && o->type == commit_type) {\n+\t\tstruct commit *commit = (struct commit *)o;\n+\t\tconst char *p;\n+\n+\t\twhile ((p = strchr(path, '/')))\n+\t\t\tpath = p+1;\n+\n+\t\tname_rev(commit, strdup(path), 0, 0, deref);\n+\t}\n+\treturn 0;\n+}\n+\n+int main(int argc, char **argv)\n+{\n+\tstruct object_list *revs = NULL;\n+\tstruct object_list **walker = &revs;\n+\tint as_is = 0;\n+\n+\tsetup_git_directory();\n+\n+\tif (argc < 2)\n+\t\tusage(name_rev_usage);\n+\n+\tfor (--argc, ++argv; argc; --argc, ++argv) {\n+\t\tunsigned char sha1[20];\n+\t\tstruct object *o;\n+\t\tstruct commit *commit;\n+\n+\t\tif (!as_is && (*argv)[0] == '-') {\n+\t\t\tif (!strcmp(*argv, \"--\")) {\n+\t\t\t\tas_is = 1;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\tusage(name_rev_usage);\n+\t\t}\n+\n+\t\tif (get_sha1(*argv, sha1)) {\n+\t\t\tfprintf(stderr, \"Could not get sha1 for %s. Skipping.\\n\",\n+\t\t\t\t\t*argv);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\to = deref_tag(parse_object(sha1));\n+\t\tif (!o || o->type != commit_type) {\n+\t\t\tfprintf(stderr, \"Could not get commit for %s. Skipping.\\n\",\n+\t\t\t\t\t*argv);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tcommit = (struct commit *)o;\n+\n+\t\tif (cutoff > commit->date)\n+\t\t\tcutoff = commit->date;\n+\n+\t\tobject_list_append((struct object *)commit, walker);\n+\t\t(*walker)->name = *argv;\n+\t\twalker = &((*walker)->next);\n+\t}\n+\n+\tfor_each_ref(name_ref);\n+\n+\tfor ( ; revs; revs = revs->next) {\n+\t\tstruct rev_name *n = (struct rev_name *)revs->item->util;\n+\n+\t\tprintf(\"%s %s\", revs->name, n->tip_name);\n+\t\tif (n->generation)\n+\t\t\tprintf(\"~%d\", n->generation);\n+\t\tprintf(\"\\n\");\n+\t}\n+\n+\treturn 0;\n+}\n+\n---\n0.99.8.GIT\n"},{"id":"10644","messageId":"20051026083625.GD30889@pasky.or.cz","threadId":"2227","inReplyTo":"Pine.LNX.4.63.0510260103570.27364@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] Add git-name-rev","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2005-10-26T08:36:25Z","receivedAt":"2005-10-26T08:36:25Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Wed, Oct 26, 2005 at 01:05:59AM CEST, I got a letter\nwhere Johannes Schindelin <Johannes.Schindelin@gmx.de> told me that...\n> git-name-rev tries to find nice symbolic names for commits. It does so by \n> walking the commits from the refs. When the symbolic name is ambiguous, \n> the following heuristic is applied: Try to avoid too many ~'s, and if two \n> ambiguous names have the same count of ~'s, take the one whose last number \n> is smaller.\n> \n> Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n\nI think you should either add this to git-findtags.perl or (better) add\ngit-findtags.perl's functionality (i.e. a switch to search only in the\ntags) to this and obsolete/kill git-findtags.perl. It is pretty new\n(from Oct 13) so killing it shouldn't break anything.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nVI has two modes: the one in which it beeps and the one in which\nit doesn't.\n"},{"id":"10656","messageId":"Pine.LNX.4.63.0510261509060.31868@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2227","inReplyTo":"20051026083625.GD30889@pasky.or.cz","subject":"Re: [PATCH] Add git-name-rev","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-10-26T13:10:20Z","receivedAt":"2005-10-26T13:10:20Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"[PATCH] Add git-name-rev\n\ngit-name-rev tries to find nice symbolic names for commits. It does so by\nwalking the commits from the refs. When the symbolic name is ambiguous, the\nfollowing heuristic is applied: Try to avoid too many ~'s, and if two ambiguous\nnames have the same count of ~'s, take the one whose last number is smaller.\n\nWith \"--tags\", the names are derived only from tags.\n\nWith \"--stdin\", the stdin is parsed, and after every sha1 for which a name\ncould be found, the name is appended. (Try \"git log | git name-rev --stdin\".)\n\nSigned-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n---\n\n\tOn Wed, 26 Oct 2005, Petr Baudis wrote:\n\n\t> I think you should either add this to git-findtags.perl or \n\t> (better) add git-findtags.perl's functionality (i.e. a switch to \n\t> search only in the tags) to this and obsolete/kill \n\t> git-findtags.perl. It is pretty new (from Oct 13) so killing it \n\t> shouldn't break anything.\n\n\tAsk, and it shall be given you.\n\n Documentation/git-name-rev.txt |   66 +++++++++++\n Makefile                       |    2 \n name-rev.c                     |  246 ++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 313 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.txt\nnew file mode 100644\nindex 0000000..e37b0b8\n--- /dev/null\n+++ b/Documentation/git-name-rev.txt\n@@ -0,0 +1,66 @@\n+git-name-rev(1)\n+===============\n+\n+NAME\n+----\n+git-name-rev - Find symbolic names for given revs.\n+\n+\n+SYNOPSIS\n+--------\n+'git-name-rev' [--tags] ( --all | --stdin | <commitish>... )\n+\n+DESCRIPTION\n+-----------\n+Finds symbolic names suitable for human digestion for revisions given in any\n+format parsable by git-rev-parse.\n+\n+\n+OPTIONS\n+-------\n+\n+--tags::\n+\tDo not use branch names, but only tags to name the commits\n+\n+--all::\n+\tList all commits reachable from all refs\n+\n+--stdin::\n+\tRead from stdin, append \"(<rev_name>)\" to all sha1's of name'able\n+\tcommits, and pass to stdout\n+\n+EXAMPLE\n+-------\n+\n+Given a commit, find out where it is relative to the local refs. Say somebody\n+wrote you about that phantastic commit 33db5f4d9027a10e477ccf054b2c1ab94f74c85a.\n+Of course, you look into the commit, but that only tells you what happened, but\n+not the context.\n+\n+Enter git-name-rev:\n+\n+------------\n+% git name-rev 33db5f4d9027a10e477ccf054b2c1ab94f74c85a\n+------------\n+\n+Now you are wiser, because you know that it happened 940 revisions before v0.99.\n+\n+Another nice thing you can do is:\n+\n+------------\n+% git log | git name-rev --stdin\n+------------\n+\n+\n+Author\n+------\n+Written by Johannes Schindelin <Johannes.Schindelin@gmx.de>\n+\n+Documentation\n+--------------\n+Documentation by Johannes Schindelin.\n+\n+GIT\n+---\n+Part of the gitlink:git[7] suite\n+\ndiff --git a/Makefile b/Makefile\n--- a/Makefile\n+++ b/Makefile\n@@ -122,7 +122,7 @@ PROGRAMS = \\\n \tgit-unpack-objects$X git-update-index$X git-update-server-info$X \\\n \tgit-upload-pack$X git-verify-pack$X git-write-tree$X \\\n \tgit-update-ref$X git-symbolic-ref$X git-check-ref-format$X \\\n-\t$(SIMPLE_PROGRAMS)\n+\tgit-name-rev$X $(SIMPLE_PROGRAMS)\n \n # Backward compatibility -- to be removed after 1.0\n PROGRAMS += git-ssh-pull$X git-ssh-push$X\ndiff --git a/name-rev.c b/name-rev.c\nnew file mode 100644\nindex 0000000..21fecdf\n--- /dev/null\n+++ b/name-rev.c\n@@ -0,0 +1,246 @@\n+#include <stdlib.h>\n+#include \"cache.h\"\n+#include \"commit.h\"\n+#include \"tag.h\"\n+#include \"refs.h\"\n+\n+static const char name_rev_usage[] =\n+\t\"git-name-rev [--tags] ( --all | --stdin | commitish [commitish...] )\\n\";\n+\n+typedef struct rev_name {\n+\tconst char *tip_name;\n+\tint merge_traversals;\n+\tint generation;\n+} rev_name;\n+\n+static long cutoff = LONG_MAX;\n+\n+static void name_rev(struct commit *commit,\n+\t\tconst char *tip_name, int merge_traversals, int generation,\n+\t\tint deref)\n+{\n+\tstruct rev_name *name = (struct rev_name *)commit->object.util;\n+\tstruct commit_list *parents;\n+\tint parent_number = 0;\n+\n+\tif (!commit->object.parsed)\n+\t\tparse_commit(commit);\n+\n+\tif (commit->date < cutoff)\n+\t\treturn;\n+\n+\tif (deref) {\n+\t\tchar *new_name = xmalloc(strlen(tip_name)+3);\n+\t\tstrcpy(new_name, tip_name);\n+\t\tstrcat(new_name, \"^0\");\n+\t\ttip_name = new_name;\n+\n+\t\tif (generation)\n+\t\t\tdie(\"generation: %d, but deref?\", generation);\n+\t}\n+\n+\tif (name == NULL) {\n+\t\tname = xmalloc(sizeof(rev_name));\n+\t\tcommit->object.util = name;\n+\t\tgoto copy_data;\n+\t} else if (name->merge_traversals > merge_traversals ||\n+\t\t\t(name->merge_traversals == merge_traversals &&\n+\t\t\t name->generation > generation)) {\n+copy_data:\n+\t\tname->tip_name = tip_name;\n+\t\tname->merge_traversals = merge_traversals;\n+\t\tname->generation = generation;\n+\t} else\n+\t\treturn;\n+\n+\tfor (parents = commit->parents;\n+\t\t\tparents;\n+\t\t\tparents = parents->next, parent_number++) {\n+\t\tif (parent_number > 0) {\n+\t\t\tchar *new_name = xmalloc(strlen(tip_name)+8);\n+\n+\t\t\tif (generation > 0)\n+\t\t\t\tsprintf(new_name, \"%s~%d^%d\", tip_name,\n+\t\t\t\t\t\tgeneration, parent_number);\n+\t\t\telse\n+\t\t\t\tsprintf(new_name, \"%s^%d\", tip_name, parent_number);\n+\n+\t\t\tname_rev(parents->item, new_name,\n+\t\t\t\tmerge_traversals + 1 , 0, 0);\n+\t\t} else {\n+\t\t\tname_rev(parents->item, tip_name, merge_traversals,\n+\t\t\t\tgeneration + 1, 0);\n+\t\t}\n+\t}\n+}\n+\n+static int tags_only = 0;\n+\n+static int name_ref(const char *path, const unsigned char *sha1)\n+{\n+\tstruct object *o = parse_object(sha1);\n+\tint deref = 0;\n+\n+\tif (tags_only && strncmp(path, \"refs/tags/\", 10))\n+\t\treturn 0;\n+\n+\twhile (o && o->type == tag_type) {\n+\t\tstruct tag *t = (struct tag *) o;\n+\t\tif (!t->tagged)\n+\t\t\tbreak; /* broken repository */\n+\t\to = parse_object(t->tagged->sha1);\n+\t\tderef = 1;\n+\t}\n+\tif (o && o->type == commit_type) {\n+\t\tstruct commit *commit = (struct commit *)o;\n+\t\tconst char *p;\n+\n+\t\twhile ((p = strchr(path, '/')))\n+\t\t\tpath = p+1;\n+\n+\t\tname_rev(commit, strdup(path), 0, 0, deref);\n+\t}\n+\treturn 0;\n+}\n+\n+/* returns a static buffer */\n+static const char* get_rev_name(struct object *o)\n+{\n+\tstatic char buffer[1024];\n+\tstruct rev_name *n = (struct rev_name *)o->util;\n+\tif (!n)\n+\t\treturn \"undefined\";\n+\n+\tif (!n->generation)\n+\t\treturn n->tip_name;\n+\n+\tsnprintf(buffer, sizeof(buffer), \"%s~%d\", n->tip_name, n->generation);\n+\n+\treturn buffer;\n+}\n+\t\n+int main(int argc, char **argv)\n+{\n+\tstruct object_list *revs = NULL;\n+\tstruct object_list **walker = &revs;\n+\tint as_is = 0, all = 0, transform_stdin = 0;\n+\n+\tsetup_git_directory();\n+\n+\tif (argc < 2)\n+\t\tusage(name_rev_usage);\n+\n+\tfor (--argc, ++argv; argc; --argc, ++argv) {\n+\t\tunsigned char sha1[20];\n+\t\tstruct object *o;\n+\t\tstruct commit *commit;\n+\n+\t\tif (!as_is && (*argv)[0] == '-') {\n+\t\t\tif (!strcmp(*argv, \"--\")) {\n+\t\t\t\tas_is = 1;\n+\t\t\t\tcontinue;\n+\t\t\t} else if (!strcmp(*argv, \"--tags\")) {\n+\t\t\t\ttags_only = 1;\n+\t\t\t\tcontinue;\n+\t\t\t} else if (!strcmp(*argv, \"--all\")) {\n+\t\t\t\tif (argc > 1)\n+\t\t\t\t\tdie(\"Specify either a list, or --all, not both!\");\n+\t\t\t\tall = 1;\n+\t\t\t\tcutoff = 0;\n+\t\t\t\tcontinue;\n+\t\t\t} else if (!strcmp(*argv, \"--stdin\")) {\n+\t\t\t\tif (argc > 1)\n+\t\t\t\t\tdie(\"Specify either a list, or --stdin, not both!\");\n+\t\t\t\ttransform_stdin = 1;\n+\t\t\t\tcutoff = 0;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\tusage(name_rev_usage);\n+\t\t}\n+\n+\t\tif (get_sha1(*argv, sha1)) {\n+\t\t\tfprintf(stderr, \"Could not get sha1 for %s. Skipping.\\n\",\n+\t\t\t\t\t*argv);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\to = deref_tag(parse_object(sha1));\n+\t\tif (!o || o->type != commit_type) {\n+\t\t\tfprintf(stderr, \"Could not get commit for %s. Skipping.\\n\",\n+\t\t\t\t\t*argv);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tcommit = (struct commit *)o;\n+\n+\t\tif (cutoff > commit->date)\n+\t\t\tcutoff = commit->date;\n+\n+\t\tobject_list_append((struct object *)commit, walker);\n+\t\t(*walker)->name = *argv;\n+\t\twalker = &((*walker)->next);\n+\t}\n+\n+\tfor_each_ref(name_ref);\n+\n+\tif (transform_stdin) {\n+\t\tchar buffer[2048];\n+\t\tchar *p, *p_start;\n+\n+\t\twhile (!feof(stdin)) {\n+\t\t\tint forty = 0;\n+\t\t\tp = fgets(buffer, sizeof(buffer), stdin);\n+\t\t\tif (!p)\n+\t\t\t\tbreak;\n+\n+\t\t\tfor (p_start = p; *p; p++) {\n+#define ishex(x) (isdigit((x)) || ((x) >= 'a' && (x) <= 'f'))\n+\t\t\t\tif (!ishex(*p))\n+\t\t\t\t\tforty = 0;\n+\t\t\t\telse if (++forty == 40 &&\n+\t\t\t\t\t\t!ishex(*(p+1))) {\n+\t\t\t\t\tunsigned char sha1[40];\n+\t\t\t\t\tconst char *name = \"undefined\";\n+\t\t\t\t\tchar c = *(p+1);\n+\n+\t\t\t\t\tforty = 0;\n+\n+\t\t\t\t\t*(p+1) = 0;\n+\t\t\t\t\tif (!get_sha1(p - 39, sha1)) {\n+\t\t\t\t\t\tstruct object *o =\n+\t\t\t\t\t\t\tlookup_object(sha1);\n+\t\t\t\t\t\tif (o)\n+\t\t\t\t\t\t\tname = get_rev_name(o);\n+\t\t\t\t\t}\n+\t\t\t\t\t*(p+1) = c;\n+\n+\t\t\t\t\tif (!strcmp(name, \"undefined\"))\n+\t\t\t\t\t\tcontinue;\n+\n+\t\t\t\t\tfwrite(p_start, p - p_start, 1, stdout);\n+\t\t\t\t\tfputc('(', stdout);\n+\t\t\t\t\tfputs(name, stdout);\n+\t\t\t\t\tfputc(')', stdout);\n+\t\t\t\t\tp_start = p + 1;\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\t/* flush */\n+\t\t\tif (p_start != p)\n+\t\t\t\tfwrite(p_start, p - p_start, 1, stdout);\n+\t\t}\n+\t} else if (all) {\n+\t\textern struct object **objs;\n+\t\textern int nr_objs;\n+\t\tint i;\n+\n+\t\tfor (i = 0; i < nr_objs; i++)\n+\t\t\tprintf(\"%s %s\\n\", sha1_to_hex(objs[i]->sha1),\n+\t\t\t\t\tget_rev_name(objs[i]));\n+\t} else\n+\t\tfor ( ; revs; revs = revs->next)\n+\t\t\tprintf(\"%s %s\\n\", revs->name, get_rev_name(revs->item));\n+\n+\treturn 0;\n+}\n+\n"},{"id":"10697","messageId":"pan.2005.10.27.08.53.17.258926@smurf.noris.de","threadId":"2227","inReplyTo":"Pine.LNX.4.63.0510261509060.31868@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] Add git-name-rev","fromName":"Matthias Urlichs","fromEmail":"smurf@smurf.noris.de","sentAt":"2005-10-27T08:53:19Z","receivedAt":"2005-10-27T08:53:19Z","isPatch":true,"sender":{"key":"matthias@urlichs.de","avatar":"https://gravatar.com/avatar/2708905af227313eba6f2b2ae0f7d0259b5ac5d71baef58fe5a13c699ce0bbf0?d=mp&s=160"},"body":"Hi, Johannes Schindelin wrote:\n\n> [PATCH] Add git-name-rev\n\nPlease update the \"git\" manpage when you add a new command.\n(I bet that others are missing too..?)\n\n-- \nMatthias Urlichs   |   {M:U} IT Design @ m-u-it.de   |  smurf@smurf.noris.de\nDisclaimer: The quote was selected randomly. Really. | http://smurf.noris.de\n - -\nLet the machine do the dirty work.\n\t\t-- \"Elements of Programming Style\", Kernighan and Ritchie\n"}]}