Make git-name-rev a builtin
authorMatthias Kestenholz <matthias@spinlock.ch>
Thu, 3 Aug 2006 15:24:35 +0000 (17:24 +0200)
committerJunio C Hamano <junkio@cox.net>
Fri, 4 Aug 2006 06:15:11 +0000 (23:15 -0700)
Signed-off-by: Matthias Kestenholz <matthias@spinlock.ch>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Makefile
builtin-name-rev.c [new file with mode: 0644]
builtin.h
git.c
name-rev.c [deleted file]
index 700c77f5643f9250fc8b41371071bc9871294fb3..132c9cf012c02647399b47890d67f64acb3ff1f5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -185,7 +185,7 @@ PROGRAMS = \
        git-unpack-objects$X git-update-server-info$X \
        git-upload-pack$X git-verify-pack$X \
        git-symbolic-ref$X \
-       git-name-rev$X git-pack-redundant$X git-var$X \
+       git-pack-redundant$X git-var$X \
        git-describe$X git-merge-tree$X git-blame$X git-imap-send$X
 
 BUILT_INS = git-log$X git-whatchanged$X git-show$X git-update-ref$X \
@@ -198,7 +198,7 @@ BUILT_INS = git-log$X git-whatchanged$X git-show$X git-update-ref$X \
        git-apply$X git-show-branch$X git-diff-files$X git-update-index$X \
        git-diff-index$X git-diff-stages$X git-diff-tree$X git-cat-file$X \
        git-fmt-merge-msg$X git-prune$X git-mv$X git-prune-packed$X \
-       git-repo-config$X
+       git-repo-config$X git-name-rev$X
 
 # what 'all' will build and 'install' will install, in gitexecdir
 ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@@ -255,7 +255,8 @@ BUILTIN_OBJS = \
        builtin-diff-index.o builtin-diff-stages.o builtin-diff-tree.o \
        builtin-cat-file.o builtin-mailsplit.o builtin-stripspace.o \
        builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o \
-       builtin-mv.o builtin-prune-packed.o builtin-repo-config.o
+       builtin-mv.o builtin-prune-packed.o builtin-repo-config.o \
+       builtin-name-rev.o
 
 GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
 LIBS = $(GITLIBS) -lz
diff --git a/builtin-name-rev.c b/builtin-name-rev.c
new file mode 100644 (file)
index 0000000..571bba4
--- /dev/null
@@ -0,0 +1,256 @@
+#include <stdlib.h>
+#include "builtin.h"
+#include "cache.h"
+#include "commit.h"
+#include "tag.h"
+#include "refs.h"
+
+static const char name_rev_usage[] =
+       "git-name-rev [--tags] ( --all | --stdin | committish [committish...] )\n";
+
+typedef struct rev_name {
+       const char *tip_name;
+       int merge_traversals;
+       int generation;
+} rev_name;
+
+static long cutoff = LONG_MAX;
+
+static void name_rev(struct commit *commit,
+               const char *tip_name, int merge_traversals, int generation,
+               int deref)
+{
+       struct rev_name *name = (struct rev_name *)commit->util;
+       struct commit_list *parents;
+       int parent_number = 1;
+
+       if (!commit->object.parsed)
+               parse_commit(commit);
+
+       if (commit->date < cutoff)
+               return;
+
+       if (deref) {
+               char *new_name = xmalloc(strlen(tip_name)+3);
+               strcpy(new_name, tip_name);
+               strcat(new_name, "^0");
+               tip_name = new_name;
+
+               if (generation)
+                       die("generation: %d, but deref?", generation);
+       }
+
+       if (name == NULL) {
+               name = xmalloc(sizeof(rev_name));
+               commit->util = name;
+               goto copy_data;
+       } else if (name->merge_traversals > merge_traversals ||
+                       (name->merge_traversals == merge_traversals &&
+                        name->generation > generation)) {
+copy_data:
+               name->tip_name = tip_name;
+               name->merge_traversals = merge_traversals;
+               name->generation = generation;
+       } else
+               return;
+
+       for (parents = commit->parents;
+                       parents;
+                       parents = parents->next, parent_number++) {
+               if (parent_number > 1) {
+                       char *new_name = xmalloc(strlen(tip_name)+8);
+
+                       if (generation > 0)
+                               sprintf(new_name, "%s~%d^%d", tip_name,
+                                               generation, parent_number);
+                       else
+                               sprintf(new_name, "%s^%d", tip_name, parent_number);
+
+                       name_rev(parents->item, new_name,
+                               merge_traversals + 1 , 0, 0);
+               } else {
+                       name_rev(parents->item, tip_name, merge_traversals,
+                               generation + 1, 0);
+               }
+       }
+}
+
+static int tags_only = 0;
+
+static int name_ref(const char *path, const unsigned char *sha1)
+{
+       struct object *o = parse_object(sha1);
+       int deref = 0;
+
+       if (tags_only && strncmp(path, "refs/tags/", 10))
+               return 0;
+
+       while (o && o->type == OBJ_TAG) {
+               struct tag *t = (struct tag *) o;
+               if (!t->tagged)
+                       break; /* broken repository */
+               o = parse_object(t->tagged->sha1);
+               deref = 1;
+       }
+       if (o && o->type == OBJ_COMMIT) {
+               struct commit *commit = (struct commit *)o;
+
+               if (!strncmp(path, "refs/heads/", 11))
+                       path = path + 11;
+               else if (!strncmp(path, "refs/", 5))
+                       path = path + 5;
+
+               name_rev(commit, strdup(path), 0, 0, deref);
+       }
+       return 0;
+}
+
+/* returns a static buffer */
+static const char* get_rev_name(struct object *o)
+{
+       static char buffer[1024];
+       struct rev_name *n;
+       struct commit *c;
+
+       if (o->type != OBJ_COMMIT)
+               return "undefined";
+       c = (struct commit *) o;
+       n = c->util;
+       if (!n)
+               return "undefined";
+
+       if (!n->generation)
+               return n->tip_name;
+
+       snprintf(buffer, sizeof(buffer), "%s~%d", n->tip_name, n->generation);
+
+       return buffer;
+}
+
+int cmd_name_rev(int argc, const char **argv, const char *prefix)
+{
+       struct object_array revs = { 0, 0, NULL };
+       int as_is = 0, all = 0, transform_stdin = 0;
+
+       git_config(git_default_config);
+
+       if (argc < 2)
+               usage(name_rev_usage);
+
+       for (--argc, ++argv; argc; --argc, ++argv) {
+               unsigned char sha1[20];
+               struct object *o;
+               struct commit *commit;
+
+               if (!as_is && (*argv)[0] == '-') {
+                       if (!strcmp(*argv, "--")) {
+                               as_is = 1;
+                               continue;
+                       } else if (!strcmp(*argv, "--tags")) {
+                               tags_only = 1;
+                               continue;
+                       } else if (!strcmp(*argv, "--all")) {
+                               if (argc > 1)
+                                       die("Specify either a list, or --all, not both!");
+                               all = 1;
+                               cutoff = 0;
+                               continue;
+                       } else if (!strcmp(*argv, "--stdin")) {
+                               if (argc > 1)
+                                       die("Specify either a list, or --stdin, not both!");
+                               transform_stdin = 1;
+                               cutoff = 0;
+                               continue;
+                       }
+                       usage(name_rev_usage);
+               }
+
+               if (get_sha1(*argv, sha1)) {
+                       fprintf(stderr, "Could not get sha1 for %s. Skipping.\n",
+                                       *argv);
+                       continue;
+               }
+
+               o = deref_tag(parse_object(sha1), *argv, 0);
+               if (!o || o->type != OBJ_COMMIT) {
+                       fprintf(stderr, "Could not get commit for %s. Skipping.\n",
+                                       *argv);
+                       continue;
+               }
+
+               commit = (struct commit *)o;
+
+               if (cutoff > commit->date)
+                       cutoff = commit->date;
+
+               add_object_array((struct object *)commit, *argv, &revs);
+       }
+
+       for_each_ref(name_ref);
+
+       if (transform_stdin) {
+               char buffer[2048];
+               char *p, *p_start;
+
+               while (!feof(stdin)) {
+                       int forty = 0;
+                       p = fgets(buffer, sizeof(buffer), stdin);
+                       if (!p)
+                               break;
+
+                       for (p_start = p; *p; p++) {
+#define ishex(x) (isdigit((x)) || ((x) >= 'a' && (x) <= 'f'))
+                               if (!ishex(*p))
+                                       forty = 0;
+                               else if (++forty == 40 &&
+                                               !ishex(*(p+1))) {
+                                       unsigned char sha1[40];
+                                       const char *name = "undefined";
+                                       char c = *(p+1);
+
+                                       forty = 0;
+
+                                       *(p+1) = 0;
+                                       if (!get_sha1(p - 39, sha1)) {
+                                               struct object *o =
+                                                       lookup_object(sha1);
+                                               if (o)
+                                                       name = get_rev_name(o);
+                                       }
+                                       *(p+1) = c;
+
+                                       if (!strcmp(name, "undefined"))
+                                               continue;
+
+                                       fwrite(p_start, p - p_start + 1, 1,
+                                              stdout);
+                                       printf(" (%s)", name);
+                                       p_start = p + 1;
+                               }
+                       }
+
+                       /* flush */
+                       if (p_start != p)
+                               fwrite(p_start, p - p_start, 1, stdout);
+               }
+       } else if (all) {
+               int i, max;
+
+               max = get_max_object_index();
+               for (i = 0; i < max; i++) {
+                       struct object * obj = get_indexed_object(i);
+                       if (!obj)
+                               continue;
+                       printf("%s %s\n", sha1_to_hex(obj->sha1), get_rev_name(obj));
+               }
+       } else {
+               int i;
+               for (i = 0; i < revs.nr; i++)
+                       printf("%s %s\n",
+                               revs.objects[i].name,
+                               get_rev_name(revs.objects[i].item));
+       }
+
+       return 0;
+}
+
index 26ebcaf213111724e8131e9edc8eeb8672e8071e..d1d9dc14f9ea688ef0a924f08e094f33b0ae0d5f 100644 (file)
--- a/builtin.h
+++ b/builtin.h
@@ -49,6 +49,7 @@ extern int cmd_update_ref(int argc, const char **argv, const char *prefix);
 extern int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix);
 extern int cmd_mv(int argc, const char **argv, const char *prefix);
 extern int cmd_repo_config(int argc, const char **argv, const char *prefix);
+extern int cmd_name_rev(int argc, const char **argv, const char *prefix);
 
 extern int cmd_write_tree(int argc, const char **argv, const char *prefix);
 extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix);
diff --git a/git.c b/git.c
index 6e72a893b71129702551eca56c8221110286f14d..501a7815fce71c3bd3368d1b4afc4f540ddfbc64 100644 (file)
--- a/git.c
+++ b/git.c
@@ -265,6 +265,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
                { "mv", cmd_mv, NEEDS_PREFIX },
                { "prune-packed", cmd_prune_packed, NEEDS_PREFIX },
                { "repo-config", cmd_repo_config },
+               { "name-rev", cmd_name_rev, NEEDS_PREFIX },
        };
        int i;
 
diff --git a/name-rev.c b/name-rev.c
deleted file mode 100644 (file)
index f92f14e..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-#include <stdlib.h>
-#include "cache.h"
-#include "commit.h"
-#include "tag.h"
-#include "refs.h"
-
-static const char name_rev_usage[] =
-       "git-name-rev [--tags] ( --all | --stdin | committish [committish...] )\n";
-
-typedef struct rev_name {
-       const char *tip_name;
-       int merge_traversals;
-       int generation;
-} rev_name;
-
-static long cutoff = LONG_MAX;
-
-static void name_rev(struct commit *commit,
-               const char *tip_name, int merge_traversals, int generation,
-               int deref)
-{
-       struct rev_name *name = (struct rev_name *)commit->util;
-       struct commit_list *parents;
-       int parent_number = 1;
-
-       if (!commit->object.parsed)
-               parse_commit(commit);
-
-       if (commit->date < cutoff)
-               return;
-
-       if (deref) {
-               char *new_name = xmalloc(strlen(tip_name)+3);
-               strcpy(new_name, tip_name);
-               strcat(new_name, "^0");
-               tip_name = new_name;
-
-               if (generation)
-                       die("generation: %d, but deref?", generation);
-       }
-
-       if (name == NULL) {
-               name = xmalloc(sizeof(rev_name));
-               commit->util = name;
-               goto copy_data;
-       } else if (name->merge_traversals > merge_traversals ||
-                       (name->merge_traversals == merge_traversals &&
-                        name->generation > generation)) {
-copy_data:
-               name->tip_name = tip_name;
-               name->merge_traversals = merge_traversals;
-               name->generation = generation;
-       } else
-               return;
-
-       for (parents = commit->parents;
-                       parents;
-                       parents = parents->next, parent_number++) {
-               if (parent_number > 1) {
-                       char *new_name = xmalloc(strlen(tip_name)+8);
-
-                       if (generation > 0)
-                               sprintf(new_name, "%s~%d^%d", tip_name,
-                                               generation, parent_number);
-                       else
-                               sprintf(new_name, "%s^%d", tip_name, parent_number);
-
-                       name_rev(parents->item, new_name,
-                               merge_traversals + 1 , 0, 0);
-               } else {
-                       name_rev(parents->item, tip_name, merge_traversals,
-                               generation + 1, 0);
-               }
-       }
-}
-
-static int tags_only = 0;
-
-static int name_ref(const char *path, const unsigned char *sha1)
-{
-       struct object *o = parse_object(sha1);
-       int deref = 0;
-
-       if (tags_only && strncmp(path, "refs/tags/", 10))
-               return 0;
-
-       while (o && o->type == OBJ_TAG) {
-               struct tag *t = (struct tag *) o;
-               if (!t->tagged)
-                       break; /* broken repository */
-               o = parse_object(t->tagged->sha1);
-               deref = 1;
-       }
-       if (o && o->type == OBJ_COMMIT) {
-               struct commit *commit = (struct commit *)o;
-
-               if (!strncmp(path, "refs/heads/", 11))
-                       path = path + 11;
-               else if (!strncmp(path, "refs/", 5))
-                       path = path + 5;
-
-               name_rev(commit, strdup(path), 0, 0, deref);
-       }
-       return 0;
-}
-
-/* returns a static buffer */
-static const char* get_rev_name(struct object *o)
-{
-       static char buffer[1024];
-       struct rev_name *n;
-       struct commit *c;
-
-       if (o->type != OBJ_COMMIT)
-               return "undefined";
-       c = (struct commit *) o;
-       n = c->util;
-       if (!n)
-               return "undefined";
-
-       if (!n->generation)
-               return n->tip_name;
-
-       snprintf(buffer, sizeof(buffer), "%s~%d", n->tip_name, n->generation);
-
-       return buffer;
-}
-
-int main(int argc, char **argv)
-{
-       struct object_array revs = { 0, 0, NULL };
-       int as_is = 0, all = 0, transform_stdin = 0;
-
-       setup_git_directory();
-       git_config(git_default_config);
-
-       if (argc < 2)
-               usage(name_rev_usage);
-
-       for (--argc, ++argv; argc; --argc, ++argv) {
-               unsigned char sha1[20];
-               struct object *o;
-               struct commit *commit;
-
-               if (!as_is && (*argv)[0] == '-') {
-                       if (!strcmp(*argv, "--")) {
-                               as_is = 1;
-                               continue;
-                       } else if (!strcmp(*argv, "--tags")) {
-                               tags_only = 1;
-                               continue;
-                       } else if (!strcmp(*argv, "--all")) {
-                               if (argc > 1)
-                                       die("Specify either a list, or --all, not both!");
-                               all = 1;
-                               cutoff = 0;
-                               continue;
-                       } else if (!strcmp(*argv, "--stdin")) {
-                               if (argc > 1)
-                                       die("Specify either a list, or --stdin, not both!");
-                               transform_stdin = 1;
-                               cutoff = 0;
-                               continue;
-                       }
-                       usage(name_rev_usage);
-               }
-
-               if (get_sha1(*argv, sha1)) {
-                       fprintf(stderr, "Could not get sha1 for %s. Skipping.\n",
-                                       *argv);
-                       continue;
-               }
-
-               o = deref_tag(parse_object(sha1), *argv, 0);
-               if (!o || o->type != OBJ_COMMIT) {
-                       fprintf(stderr, "Could not get commit for %s. Skipping.\n",
-                                       *argv);
-                       continue;
-               }
-
-               commit = (struct commit *)o;
-
-               if (cutoff > commit->date)
-                       cutoff = commit->date;
-
-               add_object_array((struct object *)commit, *argv, &revs);
-       }
-
-       for_each_ref(name_ref);
-
-       if (transform_stdin) {
-               char buffer[2048];
-               char *p, *p_start;
-
-               while (!feof(stdin)) {
-                       int forty = 0;
-                       p = fgets(buffer, sizeof(buffer), stdin);
-                       if (!p)
-                               break;
-
-                       for (p_start = p; *p; p++) {
-#define ishex(x) (isdigit((x)) || ((x) >= 'a' && (x) <= 'f'))
-                               if (!ishex(*p))
-                                       forty = 0;
-                               else if (++forty == 40 &&
-                                               !ishex(*(p+1))) {
-                                       unsigned char sha1[40];
-                                       const char *name = "undefined";
-                                       char c = *(p+1);
-
-                                       forty = 0;
-
-                                       *(p+1) = 0;
-                                       if (!get_sha1(p - 39, sha1)) {
-                                               struct object *o =
-                                                       lookup_object(sha1);
-                                               if (o)
-                                                       name = get_rev_name(o);
-                                       }
-                                       *(p+1) = c;
-
-                                       if (!strcmp(name, "undefined"))
-                                               continue;
-
-                                       fwrite(p_start, p - p_start + 1, 1,
-                                              stdout);
-                                       printf(" (%s)", name);
-                                       p_start = p + 1;
-                               }
-                       }
-
-                       /* flush */
-                       if (p_start != p)
-                               fwrite(p_start, p - p_start, 1, stdout);
-               }
-       } else if (all) {
-               int i, max;
-
-               max = get_max_object_index();
-               for (i = 0; i < max; i++) {
-                       struct object * obj = get_indexed_object(i);
-                       if (!obj)
-                               continue;
-                       printf("%s %s\n", sha1_to_hex(obj->sha1), get_rev_name(obj));
-               }
-       } else {
-               int i;
-               for (i = 0; i < revs.nr; i++)
-                       printf("%s %s\n",
-                               revs.objects[i].name,
-                               get_rev_name(revs.objects[i].item));
-       }
-
-       return 0;
-}
-