From: "René Scharfe" <rene.scharfe@lsrfire.ath.cx>
To: Junio C Hamano <junkio@cox.net>
Cc: Git Mailing List <git@vger.kernel.org>
Subject: [PATCH 3/5] pretty describe: move library functions to the new file describe.c
Date: Sun, 04 Nov 2007 12:48:41 +0100 [thread overview]
Message-ID: <472DB199.2040305@lsrfire.ath.cx> (raw)
load_commit_names(), describe_commit() et. al. are moved out to their
own file and properly exported. There are no code changes inside the
functions.
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
Makefile | 2 +-
builtin-describe.c | 202 ---------------------------------------------------
cache.h | 5 ++
describe.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 210 insertions(+), 203 deletions(-)
create mode 100644 describe.c
diff --git a/Makefile b/Makefile
index 042f79e..afdd847 100644
--- a/Makefile
+++ b/Makefile
@@ -312,7 +312,7 @@ LIB_OBJS = \
alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \
convert.o attr.o decorate.o progress.o mailmap.o symlinks.o remote.o \
- transport.o bundle.o walker.o parse-options.o
+ transport.o bundle.o walker.o parse-options.o describe.o
BUILTIN_OBJS = \
builtin-add.o \
diff --git a/builtin-describe.c b/builtin-describe.c
index e68a3d0..fcd93f4 100644
--- a/builtin-describe.c
+++ b/builtin-describe.c
@@ -1,14 +1,9 @@
#include "cache.h"
#include "commit.h"
-#include "tag.h"
-#include "refs.h"
#include "builtin.h"
#include "exec_cmd.h"
#include "parse-options.h"
-#define SEEN (1u<<0)
-#define MAX_TAGS (FLAG_BITS - 1)
-
static const char * const describe_usage[] = {
"git-describe [options] <committish>*",
NULL
@@ -20,203 +15,6 @@ static int tags; /* But allow any tags if --tags is specified */
static int abbrev = DEFAULT_ABBREV;
static int max_candidates = 10;
-static const char *prio_names[] = {
- "head", "lightweight", "annotated",
-};
-
-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 min_prio = *((int *)cb_data);
- int prio;
-
- if (!commit)
- return 0;
- object = parse_object(sha1);
-
- if (!prefixcmp(path, "refs/tags/")) {
- if (object->type == OBJ_TAG)
- prio = 2;
- else
- prio = 1;
- }
- else
- prio = 0;
- if (prio < min_prio)
- return 0;
-
- if (commit->name) {
- if (commit->name_prio >= prio)
- return 0;
- free(commit->name);
- }
- commit->name = xstrdup(path + 5);
- commit->name_prio = prio;
-
- return 0;
-}
-
-void load_commit_names(int min_prio)
-{
- for_each_ref(get_name, &min_prio);
-}
-
-struct possible_tag {
- char *name;
- int prio; /* annotated tag = 2, tag = 1, head = 0 */
- int depth;
- int found_order;
- unsigned flag_within;
-};
-
-static int compare_pt(const void *a_, const void *b_)
-{
- struct possible_tag *a = (struct possible_tag *)a_;
- struct possible_tag *b = (struct possible_tag *)b_;
- if (a->prio != b->prio)
- return b->prio - a->prio;
- if (a->depth != b->depth)
- return a->depth - b->depth;
- if (a->found_order != b->found_order)
- return a->found_order - b->found_order;
- return 0;
-}
-
-static unsigned long finish_depth_computation(
- struct commit_list **list,
- struct possible_tag *best)
-{
- unsigned long seen_commits = 0;
- while (*list) {
- struct commit *c = pop_commit(list);
- struct commit_list *parents = c->parents;
- seen_commits++;
- if (c->name_flags & best->flag_within) {
- struct commit_list *a = *list;
- while (a) {
- struct commit *i = a->item;
- if (!(i->name_flags & best->flag_within))
- break;
- a = a->next;
- }
- if (!a)
- break;
- } else
- best->depth++;
- while (parents) {
- struct commit *p = parents->item;
- parse_commit(p);
- if (!(p->name_flags & SEEN))
- insert_by_date(p, list);
- p->name_flags |= c->name_flags;
- parents = parents->next;
- }
- }
- return seen_commits;
-}
-
-char *describe_commit(struct commit *cmit, int max_candidates, int debug, int *depthp)
-{
- struct commit *gave_up_on = NULL;
- struct commit_list *list;
- struct possible_tag all_matches[MAX_TAGS];
- unsigned int match_cnt = 0, annotated_cnt = 0, cur_match;
- unsigned long seen_commits = 0;
-
- if (cmit->name) {
- *depthp = 0;
- return cmit->name;
- }
-
- if (debug)
- fprintf(stderr, "searching...\n");
-
- if (max_candidates < 1)
- max_candidates = 1;
- else if (max_candidates > MAX_TAGS)
- max_candidates = MAX_TAGS;
-
- list = NULL;
- cmit->name_flags = SEEN;
- commit_list_insert(cmit, &list);
- while (list) {
- struct commit *c = pop_commit(&list);
- struct commit_list *parents = c->parents;
- seen_commits++;
- if (c->name) {
- if (match_cnt < max_candidates) {
- struct possible_tag *t = &all_matches[match_cnt++];
- t->name = c->name;
- t->prio = c->name_prio;
- t->depth = seen_commits - 1;
- t->flag_within = 1u << match_cnt;
- t->found_order = match_cnt;
- c->name_flags |= t->flag_within;
- if (c->name_prio == 2)
- annotated_cnt++;
- }
- else {
- gave_up_on = c;
- break;
- }
- }
- for (cur_match = 0; cur_match < match_cnt; cur_match++) {
- struct possible_tag *t = &all_matches[cur_match];
- if (!(c->name_flags & t->flag_within))
- t->depth++;
- }
- if (annotated_cnt && !list) {
- if (debug)
- fprintf(stderr, "finished search at %s\n",
- sha1_to_hex(c->object.sha1));
- break;
- }
- while (parents) {
- struct commit *p = parents->item;
- parse_commit(p);
- if (!(p->name_flags & SEEN))
- insert_by_date(p, &list);
- p->name_flags |= c->name_flags;
- parents = parents->next;
- }
- }
-
- if (!match_cnt) {
- free_commit_list(list);
- *depthp = -1;
- return NULL;
- }
-
- qsort(all_matches, match_cnt, sizeof(all_matches[0]), compare_pt);
-
- if (gave_up_on) {
- insert_by_date(gave_up_on, &list);
- seen_commits--;
- }
- seen_commits += finish_depth_computation(&list, &all_matches[0]);
- free_commit_list(list);
-
- if (debug) {
- for (cur_match = 0; cur_match < match_cnt; cur_match++) {
- struct possible_tag *t = &all_matches[cur_match];
- fprintf(stderr, " %-11s %8d %s\n",
- prio_names[t->prio], t->depth, t->name);
- }
- fprintf(stderr, "traversed %lu commits\n", seen_commits);
- if (gave_up_on) {
- fprintf(stderr,
- "more than %i tags found; listed %i most recent\n"
- "gave up search at %s\n",
- max_candidates, max_candidates,
- sha1_to_hex(gave_up_on->object.sha1));
- }
- }
-
- *depthp = all_matches[0].depth;
- return all_matches[0].name;
-}
-
static void describe(const char *arg, int last_one)
{
unsigned char sha1[20];
diff --git a/cache.h b/cache.h
index bfffa05..84423a3 100644
--- a/cache.h
+++ b/cache.h
@@ -602,4 +602,9 @@ extern int diff_auto_refresh_index;
/* match-trees.c */
void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, int);
+/* describe.c */
+struct commit;
+extern void load_commit_names(int min_prio);
+extern char *describe_commit(struct commit *cmit, int max_candidates, int debug, int *depthp);
+
#endif /* CACHE_H */
diff --git a/describe.c b/describe.c
new file mode 100644
index 0000000..18c7abc
--- /dev/null
+++ b/describe.c
@@ -0,0 +1,204 @@
+#include "cache.h"
+#include "commit.h"
+#include "tag.h"
+#include "refs.h"
+
+#define SEEN (1u<<0)
+#define MAX_TAGS (FLAG_BITS - 1)
+
+static const char *prio_names[] = {
+ "head", "lightweight", "annotated",
+};
+
+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 min_prio = *((int *)cb_data);
+ int prio;
+
+ if (!commit)
+ return 0;
+ object = parse_object(sha1);
+
+ if (!prefixcmp(path, "refs/tags/")) {
+ if (object->type == OBJ_TAG)
+ prio = 2;
+ else
+ prio = 1;
+ }
+ else
+ prio = 0;
+ if (prio < min_prio)
+ return 0;
+
+ if (commit->name) {
+ if (commit->name_prio >= prio)
+ return 0;
+ free(commit->name);
+ }
+ commit->name = xstrdup(path + 5);
+ commit->name_prio = prio;
+
+ return 0;
+}
+
+void load_commit_names(int min_prio)
+{
+ for_each_ref(get_name, &min_prio);
+}
+
+struct possible_tag {
+ char *name;
+ int prio; /* annotated tag = 2, tag = 1, head = 0 */
+ int depth;
+ int found_order;
+ unsigned flag_within;
+};
+
+static int compare_pt(const void *a_, const void *b_)
+{
+ struct possible_tag *a = (struct possible_tag *)a_;
+ struct possible_tag *b = (struct possible_tag *)b_;
+ if (a->prio != b->prio)
+ return b->prio - a->prio;
+ if (a->depth != b->depth)
+ return a->depth - b->depth;
+ if (a->found_order != b->found_order)
+ return a->found_order - b->found_order;
+ return 0;
+}
+
+static unsigned long finish_depth_computation(
+ struct commit_list **list,
+ struct possible_tag *best)
+{
+ unsigned long seen_commits = 0;
+ while (*list) {
+ struct commit *c = pop_commit(list);
+ struct commit_list *parents = c->parents;
+ seen_commits++;
+ if (c->name_flags & best->flag_within) {
+ struct commit_list *a = *list;
+ while (a) {
+ struct commit *i = a->item;
+ if (!(i->name_flags & best->flag_within))
+ break;
+ a = a->next;
+ }
+ if (!a)
+ break;
+ } else
+ best->depth++;
+ while (parents) {
+ struct commit *p = parents->item;
+ parse_commit(p);
+ if (!(p->name_flags & SEEN))
+ insert_by_date(p, list);
+ p->name_flags |= c->name_flags;
+ parents = parents->next;
+ }
+ }
+ return seen_commits;
+}
+
+char *describe_commit(struct commit *cmit, int max_candidates, int debug, int *depthp)
+{
+ struct commit *gave_up_on = NULL;
+ struct commit_list *list;
+ struct possible_tag all_matches[MAX_TAGS];
+ unsigned int match_cnt = 0, annotated_cnt = 0, cur_match;
+ unsigned long seen_commits = 0;
+
+ if (cmit->name) {
+ *depthp = 0;
+ return cmit->name;
+ }
+
+ if (debug)
+ fprintf(stderr, "searching...\n");
+
+ if (max_candidates < 1)
+ max_candidates = 1;
+ else if (max_candidates > MAX_TAGS)
+ max_candidates = MAX_TAGS;
+
+ list = NULL;
+ cmit->name_flags = SEEN;
+ commit_list_insert(cmit, &list);
+ while (list) {
+ struct commit *c = pop_commit(&list);
+ struct commit_list *parents = c->parents;
+ seen_commits++;
+ if (c->name) {
+ if (match_cnt < max_candidates) {
+ struct possible_tag *t = &all_matches[match_cnt++];
+ t->name = c->name;
+ t->prio = c->name_prio;
+ t->depth = seen_commits - 1;
+ t->flag_within = 1u << match_cnt;
+ t->found_order = match_cnt;
+ c->name_flags |= t->flag_within;
+ if (c->name_prio == 2)
+ annotated_cnt++;
+ }
+ else {
+ gave_up_on = c;
+ break;
+ }
+ }
+ for (cur_match = 0; cur_match < match_cnt; cur_match++) {
+ struct possible_tag *t = &all_matches[cur_match];
+ if (!(c->name_flags & t->flag_within))
+ t->depth++;
+ }
+ if (annotated_cnt && !list) {
+ if (debug)
+ fprintf(stderr, "finished search at %s\n",
+ sha1_to_hex(c->object.sha1));
+ break;
+ }
+ while (parents) {
+ struct commit *p = parents->item;
+ parse_commit(p);
+ if (!(p->name_flags & SEEN))
+ insert_by_date(p, &list);
+ p->name_flags |= c->name_flags;
+ parents = parents->next;
+ }
+ }
+
+ if (!match_cnt) {
+ free_commit_list(list);
+ *depthp = -1;
+ return NULL;
+ }
+
+ qsort(all_matches, match_cnt, sizeof(all_matches[0]), compare_pt);
+
+ if (gave_up_on) {
+ insert_by_date(gave_up_on, &list);
+ seen_commits--;
+ }
+ seen_commits += finish_depth_computation(&list, &all_matches[0]);
+ free_commit_list(list);
+
+ if (debug) {
+ for (cur_match = 0; cur_match < match_cnt; cur_match++) {
+ struct possible_tag *t = &all_matches[cur_match];
+ fprintf(stderr, " %-11s %8d %s\n",
+ prio_names[t->prio], t->depth, t->name);
+ }
+ fprintf(stderr, "traversed %lu commits\n", seen_commits);
+ if (gave_up_on) {
+ fprintf(stderr,
+ "more than %i tags found; listed %i most recent\n"
+ "gave up search at %s\n",
+ max_candidates, max_candidates,
+ sha1_to_hex(gave_up_on->object.sha1));
+ }
+ }
+
+ *depthp = all_matches[0].depth;
+ return all_matches[0].name;
+}
--
1.5.3.5.529.ge3d6d
next reply other threads:[~2007-11-04 11:49 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-11-04 11:48 René Scharfe [this message]
2007-11-04 14:36 ` [PATCH 3/5] pretty describe: move library functions to the new file describe.c Johannes Schindelin
2007-11-04 14:56 ` René Scharfe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=472DB199.2040305@lsrfire.ath.cx \
--to=rene.scharfe@lsrfire.ath.cx \
--cc=git@vger.kernel.org \
--cc=junkio@cox.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).