summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 8c599c7)
raw | patch | inline | side by side (parent: 8c599c7)
author | Shawn O. Pearce <spearce@spearce.org> | |
Wed, 10 Jan 2007 11:36:36 +0000 (06:36 -0500) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Wed, 10 Jan 2007 16:27:01 +0000 (08:27 -0800) |
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Makefile | patch | blob | history | |
builtin-describe.c | [new file with mode: 0644] | patch | blob |
builtin.h | patch | blob | history | |
describe.c | [deleted file] | patch | blob | history |
git.c | patch | blob | history |
diff --git a/Makefile b/Makefile
index 43113e9e16937899332bcd24a88a2ae78ce65c97..e4f520ac9d96a211e86fd9c65c922a7543db9034 100644 (file)
--- a/Makefile
+++ b/Makefile
git-update-server-info$X \
git-upload-pack$X git-verify-pack$X \
git-pack-redundant$X git-var$X \
- git-describe$X git-merge-tree$X git-imap-send$X \
+ git-merge-tree$X git-imap-send$X \
git-merge-recursive$X \
$(EXTRA_PROGRAMS)
builtin-check-ref-format.o \
builtin-commit-tree.o \
builtin-count-objects.o \
+ builtin-describe.o \
builtin-diff.o \
builtin-diff-files.o \
builtin-diff-index.o \
diff --git a/builtin-describe.c b/builtin-describe.c
--- /dev/null
+++ b/builtin-describe.c
@@ -0,0 +1,176 @@
+#include "cache.h"
+#include "commit.h"
+#include "tag.h"
+#include "refs.h"
+#include "builtin.h"
+
+#define SEEN (1u << 0)
+
+static const char describe_usage[] =
+"git-describe [--all] [--tags] [--abbrev=<n>] <committish>*";
+
+static int all; /* Default to annotated tags only */
+static int tags; /* But allow any tags if --tags is specified */
+
+static int abbrev = DEFAULT_ABBREV;
+
+static int names, allocs;
+static struct commit_name {
+ const struct commit *commit;
+ int prio; /* annotated tag = 2, tag = 1, head = 0 */
+ char path[FLEX_ARRAY]; /* more */
+} **name_array = NULL;
+
+static struct commit_name *match(struct commit *cmit)
+{
+ int i = names;
+ struct commit_name **p = name_array;
+
+ while (i-- > 0) {
+ struct commit_name *n = *p++;
+ if (n->commit == cmit)
+ return n;
+ }
+ return NULL;
+}
+
+static void add_to_known_names(const char *path,
+ const struct commit *commit,
+ int prio)
+{
+ int idx;
+ int len = strlen(path)+1;
+ struct commit_name *name = xmalloc(sizeof(struct commit_name) + len);
+
+ name->commit = commit;
+ name->prio = prio;
+ memcpy(name->path, path, len);
+ idx = names;
+ if (idx >= allocs) {
+ allocs = (idx + 50) * 3 / 2;
+ name_array = xrealloc(name_array, allocs*sizeof(*name_array));
+ }
+ name_array[idx] = name;
+ names = ++idx;
+}
+
+static int get_name(const char *path, const unsigned char *sha1, int flag, void *cb_data)
+{
+ struct commit *commit = lookup_commit_reference_gently(sha1, 1);
+ struct object *object;
+ int prio;
+
+ if (!commit)
+ return 0;
+ object = parse_object(sha1);
+ /* If --all, then any refs are used.
+ * If --tags, then any tags are used.
+ * Otherwise only annotated tags are used.
+ */
+ if (!strncmp(path, "refs/tags/", 10)) {
+ if (object->type == OBJ_TAG)
+ prio = 2;
+ else
+ prio = 1;
+ }
+ else
+ prio = 0;
+
+ if (!all) {
+ if (!prio)
+ return 0;
+ if (!tags && prio < 2)
+ return 0;
+ }
+ add_to_known_names(all ? path + 5 : path + 10, commit, prio);
+ return 0;
+}
+
+static int compare_names(const void *_a, const void *_b)
+{
+ struct commit_name *a = *(struct commit_name **)_a;
+ struct commit_name *b = *(struct commit_name **)_b;
+ unsigned long a_date = a->commit->date;
+ unsigned long b_date = b->commit->date;
+
+ if (a->prio != b->prio)
+ return b->prio - a->prio;
+ return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
+}
+
+static void describe(const char *arg, int last_one)
+{
+ unsigned char sha1[20];
+ struct commit *cmit;
+ struct commit_list *list;
+ static int initialized = 0;
+ struct commit_name *n;
+
+ if (get_sha1(arg, sha1))
+ die("Not a valid object name %s", arg);
+ cmit = lookup_commit_reference(sha1);
+ if (!cmit)
+ die("%s is not a valid '%s' object", arg, commit_type);
+
+ if (!initialized) {
+ initialized = 1;
+ for_each_ref(get_name, NULL);
+ qsort(name_array, names, sizeof(*name_array), compare_names);
+ }
+
+ n = match(cmit);
+ if (n) {
+ printf("%s\n", n->path);
+ return;
+ }
+
+ list = NULL;
+ commit_list_insert(cmit, &list);
+ while (list) {
+ struct commit *c = pop_most_recent_commit(&list, SEEN);
+ n = match(c);
+ if (n) {
+ printf("%s-g%s\n", n->path,
+ find_unique_abbrev(cmit->object.sha1, abbrev));
+ if (!last_one)
+ clear_commit_marks(cmit, SEEN);
+ return;
+ }
+ }
+ die("cannot describe '%s'", sha1_to_hex(cmit->object.sha1));
+}
+
+int cmd_describe(int argc, const char **argv, const char *prefix)
+{
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ const char *arg = argv[i];
+
+ if (*arg != '-')
+ break;
+ else if (!strcmp(arg, "--all"))
+ all = 1;
+ else if (!strcmp(arg, "--tags"))
+ tags = 1;
+ else if (!strncmp(arg, "--abbrev=", 9)) {
+ abbrev = strtoul(arg + 9, NULL, 10);
+ if (abbrev < MINIMUM_ABBREV || 40 < abbrev)
+ abbrev = DEFAULT_ABBREV;
+ }
+ else
+ usage(describe_usage);
+ }
+
+ save_commit_buffer = 0;
+
+ if (argc <= i)
+ describe("HEAD", 1);
+ else
+ while (i < argc) {
+ describe(argv[i], (i == argc - 1));
+ i++;
+ }
+
+ return 0;
+}
diff --git a/builtin.h b/builtin.h
index df72d09447d0edd17d07eb97a9b3b36fa4b57531..0b3c9f62efed895bcfebe31f1164ac991ee01d41 100644 (file)
--- a/builtin.h
+++ b/builtin.h
extern int cmd_cherry(int argc, const char **argv, const char *prefix);
extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
+extern int cmd_describe(int argc, const char **argv, const char *prefix);
extern int cmd_diff_files(int argc, const char **argv, const char *prefix);
extern int cmd_diff_index(int argc, const char **argv, const char *prefix);
extern int cmd_diff(int argc, const char **argv, const char *prefix);
diff --git a/describe.c b/describe.c
--- a/describe.c
+++ /dev/null
@@ -1,176 +0,0 @@
-#include "cache.h"
-#include "commit.h"
-#include "tag.h"
-#include "refs.h"
-
-#define SEEN (1u << 0)
-
-static const char describe_usage[] =
-"git-describe [--all] [--tags] [--abbrev=<n>] <committish>*";
-
-static int all; /* Default to annotated tags only */
-static int tags; /* But allow any tags if --tags is specified */
-
-static int abbrev = DEFAULT_ABBREV;
-
-static int names, allocs;
-static struct commit_name {
- const struct commit *commit;
- int prio; /* annotated tag = 2, tag = 1, head = 0 */
- char path[FLEX_ARRAY]; /* more */
-} **name_array = NULL;
-
-static struct commit_name *match(struct commit *cmit)
-{
- int i = names;
- struct commit_name **p = name_array;
-
- while (i-- > 0) {
- struct commit_name *n = *p++;
- if (n->commit == cmit)
- return n;
- }
- return NULL;
-}
-
-static void add_to_known_names(const char *path,
- const struct commit *commit,
- int prio)
-{
- int idx;
- int len = strlen(path)+1;
- struct commit_name *name = xmalloc(sizeof(struct commit_name) + len);
-
- name->commit = commit;
- name->prio = prio;
- memcpy(name->path, path, len);
- idx = names;
- if (idx >= allocs) {
- allocs = (idx + 50) * 3 / 2;
- name_array = xrealloc(name_array, allocs*sizeof(*name_array));
- }
- name_array[idx] = name;
- names = ++idx;
-}
-
-static int get_name(const char *path, const unsigned char *sha1, int flag, void *cb_data)
-{
- struct commit *commit = lookup_commit_reference_gently(sha1, 1);
- struct object *object;
- int prio;
-
- if (!commit)
- return 0;
- object = parse_object(sha1);
- /* If --all, then any refs are used.
- * If --tags, then any tags are used.
- * Otherwise only annotated tags are used.
- */
- if (!strncmp(path, "refs/tags/", 10)) {
- if (object->type == OBJ_TAG)
- prio = 2;
- else
- prio = 1;
- }
- else
- prio = 0;
-
- if (!all) {
- if (!prio)
- return 0;
- if (!tags && prio < 2)
- return 0;
- }
- add_to_known_names(all ? path + 5 : path + 10, commit, prio);
- return 0;
-}
-
-static int compare_names(const void *_a, const void *_b)
-{
- struct commit_name *a = *(struct commit_name **)_a;
- struct commit_name *b = *(struct commit_name **)_b;
- unsigned long a_date = a->commit->date;
- unsigned long b_date = b->commit->date;
-
- if (a->prio != b->prio)
- return b->prio - a->prio;
- return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
-}
-
-static void describe(const char *arg, int last_one)
-{
- unsigned char sha1[20];
- struct commit *cmit;
- struct commit_list *list;
- static int initialized = 0;
- struct commit_name *n;
-
- if (get_sha1(arg, sha1))
- die("Not a valid object name %s", arg);
- cmit = lookup_commit_reference(sha1);
- if (!cmit)
- die("%s is not a valid '%s' object", arg, commit_type);
-
- if (!initialized) {
- initialized = 1;
- for_each_ref(get_name, NULL);
- qsort(name_array, names, sizeof(*name_array), compare_names);
- }
-
- n = match(cmit);
- if (n) {
- printf("%s\n", n->path);
- return;
- }
-
- list = NULL;
- commit_list_insert(cmit, &list);
- while (list) {
- struct commit *c = pop_most_recent_commit(&list, SEEN);
- n = match(c);
- if (n) {
- printf("%s-g%s\n", n->path,
- find_unique_abbrev(cmit->object.sha1, abbrev));
- if (!last_one)
- clear_commit_marks(cmit, SEEN);
- return;
- }
- }
- die("cannot describe '%s'", sha1_to_hex(cmit->object.sha1));
-}
-
-int main(int argc, char **argv)
-{
- int i;
-
- for (i = 1; i < argc; i++) {
- const char *arg = argv[i];
-
- if (*arg != '-')
- break;
- else if (!strcmp(arg, "--all"))
- all = 1;
- else if (!strcmp(arg, "--tags"))
- tags = 1;
- else if (!strncmp(arg, "--abbrev=", 9)) {
- abbrev = strtoul(arg + 9, NULL, 10);
- if (abbrev < MINIMUM_ABBREV || 40 < abbrev)
- abbrev = DEFAULT_ABBREV;
- }
- else
- usage(describe_usage);
- }
-
- setup_git_directory();
- save_commit_buffer = 0;
-
- if (argc <= i)
- describe("HEAD", 1);
- else
- while (i < argc) {
- describe(argv[i], (i == argc - 1));
- i++;
- }
-
- return 0;
-}
index bf55499dc3d555dfaa853b0c6e4aec5439c3532e..9ce545d67693c8713b4254d5fa0e186723e348c2 100644 (file)
--- a/git.c
+++ b/git.c
{ "cherry", cmd_cherry, RUN_SETUP },
{ "commit-tree", cmd_commit_tree, RUN_SETUP },
{ "count-objects", cmd_count_objects, RUN_SETUP },
+ { "describe", cmd_describe, RUN_SETUP },
{ "diff", cmd_diff, RUN_SETUP | USE_PAGER },
{ "diff-files", cmd_diff_files, RUN_SETUP },
{ "diff-index", cmd_diff_index, RUN_SETUP },