* [PATCH] First cut at libifying revlist generation
@ 2006-02-26 0:19 Linus Torvalds
2006-02-26 3:40 ` Junio C Hamano
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Linus Torvalds @ 2006-02-26 0:19 UTC (permalink / raw
To: Junio C Hamano, Git Mailing List
This really just splits things up partially, and creates the
interface to set things up by parsign the command line.
No real code changes so far, although the parsing of filenames is a bit
stricter. In particular, if there is a "--", then we do not accept any
filenames before it, and if there isn't any "--", then we check that _all_
paths listed are valid, not just the first one.
The new argument parsing automatically also gives us "--default" and
"--not" handling as in git-rev-parse.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
The path checking just makes sense.
This also makes git-rev-list handle "--all" and "--not" correctly (before,
it wouldn't handle "--not"), and teaches it to handle "--default". I
didn't do "--since" and "--before", but I will eventually. The final end
result is that we won't need git-rev-parse for most things.
But basically there should be no code changes, and this is just a mid-way
point where a _partial_ set of routines from "git-rev-list" has been moved
into a library files - revision.c. The half-way point has some ugly
interfaces, but I don't want to do it all in one go.
The _plan_ is to:
- move the actual history traversal into revision.c too
- leave all the git-rev-list -specific stuff (the "--bisect" logic,
the print-out logic etc) in rev-list.c
- make it trivial to make a small C version of "git diff" that just uses
the same "setup_revisions()" interface and then looks at
"revs->commits" to see what revisions were passed in (the library
interface is already at the point where that should work)
- when the actual history _traversal_ is moved into "revision.c" too, it
should then be possible to make an equally small "git log" and friends
(whatchanged etc) into C using the revision.c code.
Comments? I think this is safe to apply, because I've done a diff of the
old non-split rev-list.c against both the new rev-list.c and revision.c,
and all the changes _look_ like just moving things around and taking the
new "struct rev_info" into account.
It also passes all the tests, and in general seems straightforward enough.
HOEVER, I'd still like to point out that I could have screwed something
up, and this is just about the most core program in all of git, so it
would make a lot of sense if more people double-checked my "trivial"
split-up.
Linus
diff --git a/Makefile b/Makefile
index 6c59cee..3575489 100644
--- a/Makefile
+++ b/Makefile
@@ -192,7 +192,7 @@ LIB_FILE=libgit.a
LIB_H = \
blob.h cache.h commit.h count-delta.h csum-file.h delta.h \
diff.h epoch.h object.h pack.h pkt-line.h quote.h refs.h \
- run-command.h strbuf.h tag.h tree.h git-compat-util.h
+ run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h
DIFF_OBJS = \
diff.o diffcore-break.o diffcore-order.o diffcore-pathspec.o \
@@ -205,7 +205,7 @@ LIB_OBJS = \
quote.o read-cache.o refs.o run-command.o \
server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
- fetch-clone.o \
+ fetch-clone.o revision.o \
$(DIFF_OBJS)
LIBS = $(LIB_FILE)
diff --git a/epoch.c b/epoch.c
index 3a76748..0f37492 100644
--- a/epoch.c
+++ b/epoch.c
@@ -15,6 +15,7 @@
#include "cache.h"
#include "commit.h"
+#include "revision.h"
#include "epoch.h"
struct fraction {
diff --git a/epoch.h b/epoch.h
index 7493d5a..3756009 100644
--- a/epoch.h
+++ b/epoch.h
@@ -11,7 +11,6 @@ typedef int (*emitter_func) (struct comm
int sort_list_in_merge_order(struct commit_list *list, emitter_func emitter);
/* Low bits are used by rev-list */
-#define UNINTERESTING (1u<<10)
#define BOUNDARY (1u<<11)
#define VISITED (1u<<12)
#define DISCONTINUITY (1u<<13)
diff --git a/rev-list.c b/rev-list.c
index 67d2a48..d1c52a6 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -6,9 +6,10 @@
#include "blob.h"
#include "epoch.h"
#include "diff.h"
+#include "revision.h"
+
+/* bits #0 and #1 in revision.h */
-#define SEEN (1u << 0)
-#define INTERESTING (1u << 1)
#define COUNTED (1u << 2)
#define SHOWN (1u << 3)
#define TREECHANGE (1u << 4)
@@ -38,60 +39,20 @@ static const char rev_list_usage[] =
" --bisect"
;
-static int dense = 1;
+struct rev_info revs;
+
static int unpacked = 0;
static int bisect_list = 0;
-static int tag_objects = 0;
-static int tree_objects = 0;
-static int blob_objects = 0;
-static int edge_hint = 0;
static int verbose_header = 0;
static int abbrev = DEFAULT_ABBREV;
static int show_parents = 0;
static int hdr_termination = 0;
static const char *commit_prefix = "";
-static unsigned long max_age = -1;
-static unsigned long min_age = -1;
-static int max_count = -1;
static enum cmit_fmt commit_format = CMIT_FMT_RAW;
static int merge_order = 0;
static int show_breaks = 0;
static int stop_traversal = 0;
-static int topo_order = 0;
-static int lifo = 1;
static int no_merges = 0;
-static const char **paths = NULL;
-static int remove_empty_trees = 0;
-
-struct name_path {
- struct name_path *up;
- int elem_len;
- const char *elem;
-};
-
-static char *path_name(struct name_path *path, const char *name)
-{
- struct name_path *p;
- char *n, *m;
- int nlen = strlen(name);
- int len = nlen + 1;
-
- for (p = path; p; p = p->up) {
- if (p->elem_len)
- len += p->elem_len + 1;
- }
- n = xmalloc(len);
- m = n + len - (nlen + 1);
- strcpy(m, name);
- for (p = path; p; p = p->up) {
- if (p->elem_len) {
- m -= p->elem_len + 1;
- memcpy(m, p->elem, p->elem_len);
- m[p->elem_len] = '/';
- }
- }
- return n;
-}
static void show_commit(struct commit *commit)
{
@@ -168,15 +129,15 @@ static int filter_commit(struct commit *
return STOP;
if (commit->object.flags & (UNINTERESTING|SHOWN))
return CONTINUE;
- if (min_age != -1 && (commit->date > min_age))
+ if (revs.min_age != -1 && (commit->date > revs.min_age))
return CONTINUE;
- if (max_age != -1 && (commit->date < max_age)) {
+ if (revs.max_age != -1 && (commit->date < revs.max_age)) {
stop_traversal=1;
return CONTINUE;
}
if (no_merges && (commit->parents && commit->parents->next))
return CONTINUE;
- if (paths && dense) {
+ if (revs.paths && revs.dense) {
if (!(commit->object.flags & TREECHANGE))
return CONTINUE;
rewrite_parents(commit);
@@ -196,7 +157,7 @@ static int process_commit(struct commit
return CONTINUE;
}
- if (max_count != -1 && !max_count--)
+ if (revs.max_count != -1 && !revs.max_count--)
return STOP;
show_commit(commit);
@@ -204,19 +165,6 @@ static int process_commit(struct commit
return CONTINUE;
}
-static struct object_list **add_object(struct object *obj,
- struct object_list **p,
- struct name_path *path,
- const char *name)
-{
- struct object_list *entry = xmalloc(sizeof(*entry));
- entry->item = obj;
- entry->next = *p;
- entry->name = path_name(path, name);
- *p = entry;
- return &entry->next;
-}
-
static struct object_list **process_blob(struct blob *blob,
struct object_list **p,
struct name_path *path,
@@ -224,7 +172,7 @@ static struct object_list **process_blob
{
struct object *obj = &blob->object;
- if (!blob_objects)
+ if (!revs.blob_objects)
return p;
if (obj->flags & (UNINTERESTING | SEEN))
return p;
@@ -241,7 +189,7 @@ static struct object_list **process_tree
struct tree_entry_list *entry;
struct name_path me;
- if (!tree_objects)
+ if (!revs.tree_objects)
return p;
if (obj->flags & (UNINTERESTING | SEEN))
return p;
@@ -314,75 +262,6 @@ static void show_commit_list(struct comm
}
}
-static void mark_blob_uninteresting(struct blob *blob)
-{
- if (!blob_objects)
- return;
- if (blob->object.flags & UNINTERESTING)
- return;
- blob->object.flags |= UNINTERESTING;
-}
-
-static void mark_tree_uninteresting(struct tree *tree)
-{
- struct object *obj = &tree->object;
- struct tree_entry_list *entry;
-
- if (!tree_objects)
- return;
- if (obj->flags & UNINTERESTING)
- return;
- obj->flags |= UNINTERESTING;
- if (!has_sha1_file(obj->sha1))
- return;
- if (parse_tree(tree) < 0)
- die("bad tree %s", sha1_to_hex(obj->sha1));
- entry = tree->entries;
- tree->entries = NULL;
- while (entry) {
- struct tree_entry_list *next = entry->next;
- if (entry->directory)
- mark_tree_uninteresting(entry->item.tree);
- else
- mark_blob_uninteresting(entry->item.blob);
- free(entry);
- entry = next;
- }
-}
-
-static void mark_parents_uninteresting(struct commit *commit)
-{
- struct commit_list *parents = commit->parents;
-
- while (parents) {
- struct commit *commit = parents->item;
- commit->object.flags |= UNINTERESTING;
-
- /*
- * Normally we haven't parsed the parent
- * yet, so we won't have a parent of a parent
- * here. However, it may turn out that we've
- * reached this commit some other way (where it
- * wasn't uninteresting), in which case we need
- * to mark its parents recursively too..
- */
- if (commit->parents)
- mark_parents_uninteresting(commit);
-
- /*
- * A missing commit is ok iff its parent is marked
- * uninteresting.
- *
- * We just mark such a thing parsed, so that when
- * it is popped next time around, we won't be trying
- * to parse it and get an error.
- */
- if (!has_sha1_file(commit->object.sha1))
- commit->object.parsed = 1;
- parents = parents->next;
- }
-}
-
static int everybody_uninteresting(struct commit_list *orig)
{
struct commit_list *list = orig;
@@ -413,7 +292,7 @@ static int count_distance(struct commit_
if (commit->object.flags & (UNINTERESTING | COUNTED))
break;
- if (!paths || (commit->object.flags & TREECHANGE))
+ if (!revs.paths || (commit->object.flags & TREECHANGE))
nr++;
commit->object.flags |= COUNTED;
p = commit->parents;
@@ -447,7 +326,7 @@ static struct commit_list *find_bisectio
nr = 0;
p = list;
while (p) {
- if (!paths || (p->item->object.flags & TREECHANGE))
+ if (!revs.paths || (p->item->object.flags & TREECHANGE))
nr++;
p = p->next;
}
@@ -457,7 +336,7 @@ static struct commit_list *find_bisectio
for (p = list; p; p = p->next) {
int distance;
- if (paths && !(p->item->object.flags & TREECHANGE))
+ if (revs.paths && !(p->item->object.flags & TREECHANGE))
continue;
distance = count_distance(p);
@@ -483,7 +362,7 @@ static void mark_edge_parents_uninterest
if (!(parent->object.flags & UNINTERESTING))
continue;
mark_tree_uninteresting(parent->tree);
- if (edge_hint && !(parent->object.flags & SHOWN)) {
+ if (revs.edge_hint && !(parent->object.flags & SHOWN)) {
parent->object.flags |= SHOWN;
printf("-%s\n", sha1_to_hex(parent->object.sha1));
}
@@ -613,7 +492,7 @@ static void try_to_simplify_commit(struc
return;
case TREE_NEW:
- if (remove_empty_trees && same_tree_as_empty(p->tree)) {
+ if (revs.remove_empty_trees && same_tree_as_empty(p->tree)) {
*pp = parent->next;
continue;
}
@@ -664,7 +543,7 @@ static void add_parents_to_list(struct c
* simplify the commit history and find the parent
* that has no differences in the path set if one exists.
*/
- if (paths)
+ if (revs.paths)
try_to_simplify_commit(commit);
parent = commit->parents;
@@ -693,7 +572,7 @@ static struct commit_list *limit_list(st
list = list->next;
free(entry);
- if (max_age != -1 && (commit->date < max_age))
+ if (revs.max_age != -1 && (commit->date < revs.max_age))
obj->flags |= UNINTERESTING;
if (unpacked && has_sha1_pack(obj->sha1))
obj->flags |= UNINTERESTING;
@@ -704,155 +583,40 @@ static struct commit_list *limit_list(st
break;
continue;
}
- if (min_age != -1 && (commit->date > min_age))
+ if (revs.min_age != -1 && (commit->date > revs.min_age))
continue;
p = &commit_list_insert(commit, p)->next;
}
- if (tree_objects)
+ if (revs.tree_objects)
mark_edges_uninteresting(newlist);
if (bisect_list)
newlist = find_bisection(newlist);
return newlist;
}
-static void add_pending_object(struct object *obj, const char *name)
-{
- add_object(obj, &pending_objects, NULL, name);
-}
-
-static struct commit *get_commit_reference(const char *name, const unsigned char *sha1, unsigned int flags)
-{
- struct object *object;
-
- object = parse_object(sha1);
- if (!object)
- die("bad object %s", name);
-
- /*
- * Tag object? Look what it points to..
- */
- while (object->type == tag_type) {
- struct tag *tag = (struct tag *) object;
- object->flags |= flags;
- if (tag_objects && !(object->flags & UNINTERESTING))
- add_pending_object(object, tag->tag);
- object = parse_object(tag->tagged->sha1);
- if (!object)
- die("bad object %s", sha1_to_hex(tag->tagged->sha1));
- }
-
- /*
- * Commit object? Just return it, we'll do all the complex
- * reachability crud.
- */
- if (object->type == commit_type) {
- struct commit *commit = (struct commit *)object;
- object->flags |= flags;
- if (parse_commit(commit) < 0)
- die("unable to parse commit %s", name);
- if (flags & UNINTERESTING)
- mark_parents_uninteresting(commit);
- return commit;
- }
-
- /*
- * Tree object? Either mark it uniniteresting, or add it
- * to the list of objects to look at later..
- */
- if (object->type == tree_type) {
- struct tree *tree = (struct tree *)object;
- if (!tree_objects)
- return NULL;
- if (flags & UNINTERESTING) {
- mark_tree_uninteresting(tree);
- return NULL;
- }
- add_pending_object(object, "");
- return NULL;
- }
-
- /*
- * Blob object? You know the drill by now..
- */
- if (object->type == blob_type) {
- struct blob *blob = (struct blob *)object;
- if (!blob_objects)
- return NULL;
- if (flags & UNINTERESTING) {
- mark_blob_uninteresting(blob);
- return NULL;
- }
- add_pending_object(object, "");
- return NULL;
- }
- die("%s is unknown object", name);
-}
-
-static void handle_one_commit(struct commit *com, struct commit_list **lst)
-{
- if (!com || com->object.flags & SEEN)
- return;
- com->object.flags |= SEEN;
- commit_list_insert(com, lst);
-}
-
-/* for_each_ref() callback does not allow user data -- Yuck. */
-static struct commit_list **global_lst;
-
-static int include_one_commit(const char *path, const unsigned char *sha1)
-{
- struct commit *com = get_commit_reference(path, sha1, 0);
- handle_one_commit(com, global_lst);
- return 0;
-}
-
-static void handle_all(struct commit_list **lst)
-{
- global_lst = lst;
- for_each_ref(include_one_commit);
- global_lst = NULL;
-}
-
int main(int argc, const char **argv)
{
- const char *prefix = setup_git_directory();
- struct commit_list *list = NULL;
+ struct commit_list *list;
int i, limited = 0;
+ argc = setup_revisions(argc, argv, &revs);
+
for (i = 1 ; i < argc; i++) {
- int flags;
const char *arg = argv[i];
- char *dotdot;
- struct commit *commit;
- unsigned char sha1[20];
/* accept -<digit>, like traditilnal "head" */
if ((*arg == '-') && isdigit(arg[1])) {
- max_count = atoi(arg + 1);
+ revs.max_count = atoi(arg + 1);
continue;
}
if (!strcmp(arg, "-n")) {
if (++i >= argc)
die("-n requires an argument");
- max_count = atoi(argv[i]);
+ revs.max_count = atoi(argv[i]);
continue;
}
if (!strncmp(arg,"-n",2)) {
- max_count = atoi(arg + 2);
- continue;
- }
- if (!strncmp(arg, "--max-count=", 12)) {
- max_count = atoi(arg + 12);
- continue;
- }
- if (!strncmp(arg, "--max-age=", 10)) {
- max_age = atoi(arg + 10);
- limited = 1;
- continue;
- }
- if (!strncmp(arg, "--min-age=", 10)) {
- min_age = atoi(arg + 10);
- limited = 1;
+ revs.max_count = atoi(arg + 2);
continue;
}
if (!strcmp(arg, "--header")) {
@@ -893,23 +657,6 @@ int main(int argc, const char **argv)
bisect_list = 1;
continue;
}
- if (!strcmp(arg, "--all")) {
- handle_all(&list);
- continue;
- }
- if (!strcmp(arg, "--objects")) {
- tag_objects = 1;
- tree_objects = 1;
- blob_objects = 1;
- continue;
- }
- if (!strcmp(arg, "--objects-edge")) {
- tag_objects = 1;
- tree_objects = 1;
- blob_objects = 1;
- edge_hint = 1;
- continue;
- }
if (!strcmp(arg, "--unpacked")) {
unpacked = 1;
limited = 1;
@@ -923,100 +670,42 @@ int main(int argc, const char **argv)
show_breaks = 1;
continue;
}
- if (!strcmp(arg, "--topo-order")) {
- topo_order = 1;
- lifo = 1;
- limited = 1;
- continue;
- }
- if (!strcmp(arg, "--date-order")) {
- topo_order = 1;
- lifo = 0;
- limited = 1;
- continue;
- }
- if (!strcmp(arg, "--dense")) {
- dense = 1;
- continue;
- }
- if (!strcmp(arg, "--sparse")) {
- dense = 0;
- continue;
- }
- if (!strcmp(arg, "--remove-empty")) {
- remove_empty_trees = 1;
- continue;
- }
- if (!strcmp(arg, "--")) {
- i++;
- break;
- }
-
- if (show_breaks && !merge_order)
- usage(rev_list_usage);
+ usage(rev_list_usage);
- flags = 0;
- dotdot = strstr(arg, "..");
- if (dotdot) {
- unsigned char from_sha1[20];
- char *next = dotdot + 2;
- *dotdot = 0;
- if (!*next)
- next = "HEAD";
- if (!get_sha1(arg, from_sha1) && !get_sha1(next, sha1)) {
- struct commit *exclude;
- struct commit *include;
-
- exclude = get_commit_reference(arg, from_sha1, UNINTERESTING);
- include = get_commit_reference(next, sha1, 0);
- if (!exclude || !include)
- die("Invalid revision range %s..%s", arg, next);
- limited = 1;
- handle_one_commit(exclude, &list);
- handle_one_commit(include, &list);
- continue;
- }
- *dotdot = '.';
- }
- if (*arg == '^') {
- flags = UNINTERESTING;
- arg++;
- limited = 1;
- }
- if (get_sha1(arg, sha1) < 0) {
- struct stat st;
- if (lstat(arg, &st) < 0)
- die("'%s': %s", arg, strerror(errno));
- break;
- }
- commit = get_commit_reference(arg, sha1, flags);
- handle_one_commit(commit, &list);
}
+ list = revs.commits;
+ if (list && list->next)
+ limited = 1;
+
+ if (revs.topo_order)
+ limited = 1;
+
if (!list &&
- (!(tag_objects||tree_objects||blob_objects) && !pending_objects))
+ (!(revs.tag_objects||revs.tree_objects||revs.blob_objects) && !revs.pending_objects))
usage(rev_list_usage);
- paths = get_pathspec(prefix, argv + i);
- if (paths) {
+ if (revs.paths) {
limited = 1;
- diff_tree_setup_paths(paths);
+ diff_tree_setup_paths(revs.paths);
}
+ if (revs.max_age || revs.min_age)
+ limited = 1;
save_commit_buffer = verbose_header;
track_object_refs = 0;
if (!merge_order) {
sort_by_date(&list);
- if (list && !limited && max_count == 1 &&
- !tag_objects && !tree_objects && !blob_objects) {
+ if (list && !limited && revs.max_count == 1 &&
+ !revs.tag_objects && !revs.tree_objects && !revs.blob_objects) {
show_commit(list->item);
return 0;
}
if (limited)
list = limit_list(list);
- if (topo_order)
- sort_in_topological_order(&list, lifo);
+ if (revs.topo_order)
+ sort_in_topological_order(&list, revs.lifo);
show_commit_list(list);
} else {
#ifndef NO_OPENSSL
diff --git a/revision.c b/revision.c
new file mode 100644
index 0000000..17dbf9a
--- /dev/null
+++ b/revision.c
@@ -0,0 +1,370 @@
+#include "cache.h"
+#include "tag.h"
+#include "blob.h"
+#include "tree.h"
+#include "commit.h"
+#include "refs.h"
+#include "revision.h"
+
+static char *path_name(struct name_path *path, const char *name)
+{
+ struct name_path *p;
+ char *n, *m;
+ int nlen = strlen(name);
+ int len = nlen + 1;
+
+ for (p = path; p; p = p->up) {
+ if (p->elem_len)
+ len += p->elem_len + 1;
+ }
+ n = xmalloc(len);
+ m = n + len - (nlen + 1);
+ strcpy(m, name);
+ for (p = path; p; p = p->up) {
+ if (p->elem_len) {
+ m -= p->elem_len + 1;
+ memcpy(m, p->elem, p->elem_len);
+ m[p->elem_len] = '/';
+ }
+ }
+ return n;
+}
+
+struct object_list **add_object(struct object *obj,
+ struct object_list **p,
+ struct name_path *path,
+ const char *name)
+{
+ struct object_list *entry = xmalloc(sizeof(*entry));
+ entry->item = obj;
+ entry->next = *p;
+ entry->name = path_name(path, name);
+ *p = entry;
+ return &entry->next;
+}
+
+static void mark_blob_uninteresting(struct blob *blob)
+{
+ if (blob->object.flags & UNINTERESTING)
+ return;
+ blob->object.flags |= UNINTERESTING;
+}
+
+void mark_tree_uninteresting(struct tree *tree)
+{
+ struct object *obj = &tree->object;
+ struct tree_entry_list *entry;
+
+ if (obj->flags & UNINTERESTING)
+ return;
+ obj->flags |= UNINTERESTING;
+ if (!has_sha1_file(obj->sha1))
+ return;
+ if (parse_tree(tree) < 0)
+ die("bad tree %s", sha1_to_hex(obj->sha1));
+ entry = tree->entries;
+ tree->entries = NULL;
+ while (entry) {
+ struct tree_entry_list *next = entry->next;
+ if (entry->directory)
+ mark_tree_uninteresting(entry->item.tree);
+ else
+ mark_blob_uninteresting(entry->item.blob);
+ free(entry);
+ entry = next;
+ }
+}
+
+void mark_parents_uninteresting(struct commit *commit)
+{
+ struct commit_list *parents = commit->parents;
+
+ while (parents) {
+ struct commit *commit = parents->item;
+ commit->object.flags |= UNINTERESTING;
+
+ /*
+ * Normally we haven't parsed the parent
+ * yet, so we won't have a parent of a parent
+ * here. However, it may turn out that we've
+ * reached this commit some other way (where it
+ * wasn't uninteresting), in which case we need
+ * to mark its parents recursively too..
+ */
+ if (commit->parents)
+ mark_parents_uninteresting(commit);
+
+ /*
+ * A missing commit is ok iff its parent is marked
+ * uninteresting.
+ *
+ * We just mark such a thing parsed, so that when
+ * it is popped next time around, we won't be trying
+ * to parse it and get an error.
+ */
+ if (!has_sha1_file(commit->object.sha1))
+ commit->object.parsed = 1;
+ parents = parents->next;
+ }
+}
+
+static void add_pending_object(struct rev_info *revs, struct object *obj, const char *name)
+{
+ add_object(obj, &revs->pending_objects, NULL, name);
+}
+
+static struct commit *get_commit_reference(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags)
+{
+ struct object *object;
+
+ object = parse_object(sha1);
+ if (!object)
+ die("bad object %s", name);
+
+ /*
+ * Tag object? Look what it points to..
+ */
+ while (object->type == tag_type) {
+ struct tag *tag = (struct tag *) object;
+ object->flags |= flags;
+ if (revs->tag_objects && !(object->flags & UNINTERESTING))
+ add_pending_object(revs, object, tag->tag);
+ object = parse_object(tag->tagged->sha1);
+ if (!object)
+ die("bad object %s", sha1_to_hex(tag->tagged->sha1));
+ }
+
+ /*
+ * Commit object? Just return it, we'll do all the complex
+ * reachability crud.
+ */
+ if (object->type == commit_type) {
+ struct commit *commit = (struct commit *)object;
+ object->flags |= flags;
+ if (parse_commit(commit) < 0)
+ die("unable to parse commit %s", name);
+ if (flags & UNINTERESTING)
+ mark_parents_uninteresting(commit);
+ return commit;
+ }
+
+ /*
+ * Tree object? Either mark it uniniteresting, or add it
+ * to the list of objects to look at later..
+ */
+ if (object->type == tree_type) {
+ struct tree *tree = (struct tree *)object;
+ if (!revs->tree_objects)
+ return NULL;
+ if (flags & UNINTERESTING) {
+ mark_tree_uninteresting(tree);
+ return NULL;
+ }
+ add_pending_object(revs, object, "");
+ return NULL;
+ }
+
+ /*
+ * Blob object? You know the drill by now..
+ */
+ if (object->type == blob_type) {
+ struct blob *blob = (struct blob *)object;
+ if (!revs->blob_objects)
+ return NULL;
+ if (flags & UNINTERESTING) {
+ mark_blob_uninteresting(blob);
+ return NULL;
+ }
+ add_pending_object(revs, object, "");
+ return NULL;
+ }
+ die("%s is unknown object", name);
+}
+
+static void add_one_commit(struct commit *commit, struct rev_info *revs)
+{
+ if (!commit || (commit->object.flags & SEEN))
+ return;
+ commit->object.flags |= SEEN;
+ commit_list_insert(commit, &revs->commits);
+}
+
+static int all_flags;
+static struct rev_info *all_revs;
+
+static int handle_one_ref(const char *path, const unsigned char *sha1)
+{
+ struct commit *commit = get_commit_reference(all_revs, path, sha1, all_flags);
+ add_one_commit(commit, all_revs);
+ return 0;
+}
+
+static void handle_all(struct rev_info *revs, unsigned flags)
+{
+ all_revs = revs;
+ all_flags = flags;
+ for_each_ref(handle_one_ref);
+}
+
+/*
+ * Parse revision information, filling in the "rev_info" structure,
+ * and removing the used arguments from the argument list.
+ *
+ * Returns the number of arguments left ("new argc").
+ */
+int setup_revisions(int argc, const char **argv, struct rev_info *revs)
+{
+ int i, flags, seen_dashdash;
+ const char *def = NULL;
+ const char **unrecognized = argv+1;
+ int left = 1;
+
+ memset(revs, 0, sizeof(*revs));
+ revs->lifo = 1;
+ revs->dense = 1;
+ revs->prefix = setup_git_directory();
+ revs->max_age = -1;
+ revs->min_age = -1;
+ revs->max_count = -1;
+
+ /* First, search for "--" */
+ seen_dashdash = 0;
+ for (i = 1; i < argc; i++) {
+ const char *arg = argv[i];
+ if (strcmp(arg, "--"))
+ continue;
+ argv[i] = NULL;
+ argc = i;
+ revs->paths = get_pathspec(revs->prefix, argv + i + 1);
+ seen_dashdash = 1;
+ break;
+ }
+
+ flags = 0;
+ for (i = 1; i < argc; i++) {
+ struct commit *commit;
+ const char *arg = argv[i];
+ unsigned char sha1[20];
+ char *dotdot;
+ int local_flags;
+
+ if (*arg == '-') {
+ if (!strncmp(arg, "--max-count=", 12)) {
+ revs->max_count = atoi(arg + 12);
+ continue;
+ }
+ if (!strncmp(arg, "--max-age=", 10)) {
+ revs->max_age = atoi(arg + 10);
+ continue;
+ }
+ if (!strncmp(arg, "--min-age=", 10)) {
+ revs->min_age = atoi(arg + 10);
+ continue;
+ }
+ if (!strcmp(arg, "--all")) {
+ handle_all(revs, flags);
+ continue;
+ }
+ if (!strcmp(arg, "--not")) {
+ flags ^= UNINTERESTING;
+ continue;
+ }
+ if (!strcmp(arg, "--default")) {
+ if (++i >= argc)
+ die("bad --default argument");
+ def = argv[i];
+ continue;
+ }
+ if (!strcmp(arg, "--topo-order")) {
+ revs->topo_order = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--date-order")) {
+ revs->lifo = 0;
+ revs->topo_order = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--dense")) {
+ revs->dense = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--sparse")) {
+ revs->dense = 0;
+ continue;
+ }
+ if (!strcmp(arg, "--remove-empty")) {
+ revs->remove_empty_trees = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--objects")) {
+ revs->tag_objects = 1;
+ revs->tree_objects = 1;
+ revs->blob_objects = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--objects-edge")) {
+ revs->tag_objects = 1;
+ revs->tree_objects = 1;
+ revs->blob_objects = 1;
+ revs->edge_hint = 1;
+ continue;
+ }
+ *unrecognized++ = arg;
+ left++;
+ continue;
+ }
+ dotdot = strstr(arg, "..");
+ if (dotdot) {
+ unsigned char from_sha1[20];
+ char *next = dotdot + 2;
+ *dotdot = 0;
+ if (!*next)
+ next = "HEAD";
+ if (!get_sha1(arg, from_sha1) && !get_sha1(next, sha1)) {
+ struct commit *exclude;
+ struct commit *include;
+
+ exclude = get_commit_reference(revs, arg, from_sha1, flags ^ UNINTERESTING);
+ include = get_commit_reference(revs, next, sha1, flags);
+ if (!exclude || !include)
+ die("Invalid revision range %s..%s", arg, next);
+ add_one_commit(exclude, revs);
+ add_one_commit(include, revs);
+ continue;
+ }
+ *dotdot = '.';
+ }
+ local_flags = 0;
+ if (*arg == '^') {
+ local_flags = UNINTERESTING;
+ arg++;
+ }
+ if (get_sha1(arg, sha1) < 0) {
+ struct stat st;
+ int j;
+
+ if (seen_dashdash || local_flags)
+ die("bad revision '%s'", arg);
+
+ /* If we didn't have a "--", all filenames must exist */
+ for (j = i; j < argc; j++) {
+ if (lstat(argv[j], &st) < 0)
+ die("'%s': %s", arg, strerror(errno));
+ }
+ revs->paths = get_pathspec(revs->prefix, argv + i);
+ break;
+ }
+ commit = get_commit_reference(revs, arg, sha1, flags ^ local_flags);
+ add_one_commit(commit, revs);
+ }
+ if (def && !revs->commits) {
+ unsigned char sha1[20];
+ struct commit *commit;
+ if (get_sha1(def, sha1) < 0)
+ die("bad default revision '%s'", def);
+ commit = get_commit_reference(revs, def, sha1, 0);
+ add_one_commit(commit, revs);
+ }
+ *unrecognized = NULL;
+ return left;
+}
diff --git a/revision.h b/revision.h
new file mode 100644
index 0000000..5170ac4
--- /dev/null
+++ b/revision.h
@@ -0,0 +1,48 @@
+#ifndef REVISION_H
+#define REVISION_H
+
+#define SEEN (1u<<0)
+#define UNINTERESTING (1u<<1)
+
+struct rev_info {
+ /* Starting list */
+ struct commit_list *commits;
+ struct object_list *pending_objects;
+
+ /* Basic information */
+ const char *prefix;
+ const char **paths;
+
+ /* Traversal flags */
+ unsigned int dense:1,
+ remove_empty_trees:1,
+ lifo:1,
+ topo_order:1,
+ tag_objects:1,
+ tree_objects:1,
+ blob_objects:1,
+ edge_hint:1;
+
+ /* special limits */
+ int max_count;
+ unsigned long max_age;
+ unsigned long min_age;
+};
+
+/* revision.c */
+extern int setup_revisions(int argc, const char **argv, struct rev_info *revs);
+extern void mark_parents_uninteresting(struct commit *commit);
+extern void mark_tree_uninteresting(struct tree *tree);
+
+struct name_path {
+ struct name_path *up;
+ int elem_len;
+ const char *elem;
+};
+
+extern struct object_list **add_object(struct object *obj,
+ struct object_list **p,
+ struct name_path *path,
+ const char *name);
+
+#endif
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] First cut at libifying revlist generation
2006-02-26 0:19 [PATCH] First cut at libifying revlist generation Linus Torvalds
@ 2006-02-26 3:40 ` Junio C Hamano
2006-02-27 1:57 ` Johannes Schindelin
2006-02-27 3:11 ` Junio C Hamano
2 siblings, 0 replies; 12+ messages in thread
From: Junio C Hamano @ 2006-02-26 3:40 UTC (permalink / raw
To: Linus Torvalds; +Cc: Git Mailing List
Linus Torvalds <torvalds@osdl.org> writes:
> This really just splits things up partially, and creates the
> interface to set things up by parsign the command line.
Sorry, I'll keep this but I ended up wasting the whole day
setting up a new machine for my wife (a windows box). The next
task would be to install Cygwin so I can have fun with git...
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] First cut at libifying revlist generation
2006-02-26 0:19 [PATCH] First cut at libifying revlist generation Linus Torvalds
2006-02-26 3:40 ` Junio C Hamano
@ 2006-02-27 1:57 ` Johannes Schindelin
2006-02-27 3:05 ` Linus Torvalds
2006-02-27 3:11 ` Junio C Hamano
2 siblings, 1 reply; 12+ messages in thread
From: Johannes Schindelin @ 2006-02-27 1:57 UTC (permalink / raw
To: Linus Torvalds; +Cc: Junio C Hamano, Git Mailing List
Hi,
beware of that patch. It breaks at least one thing: cloning a repository
with a tag pointing to a tag object (the tag is cloned, but not the tag
object).
Sorry to not fix it right away, but I am just too tired.
By way of figuring this out, I just found a (warning: irony) "cute
feature" of git-bisect. I needed to apply a certain patch to trigger a
certain bug. So I always applied that patch after bisect chose the next
rev, and of course committed it so that bisect could continue.
(In hindsight, I probably should've applied the patch,
git-update-index'ed the file, and hoped that the merge mechanism take care
of it.)
Now, short of finding the correct commit, bisect would loop endlessly,
giving me the same rev to test over and over again (saying "2 revs to go
after this"), because I would label the current rev (which was the applied
patch, not the bad rev) as bad.
So, in a very real sense, it might not be such a phantastic idea as was
suggested earlier on this list, that you are able to commit on top of a
bisected rev.
Good night and good luck,
Dscho
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] First cut at libifying revlist generation
2006-02-27 1:57 ` Johannes Schindelin
@ 2006-02-27 3:05 ` Linus Torvalds
0 siblings, 0 replies; 12+ messages in thread
From: Linus Torvalds @ 2006-02-27 3:05 UTC (permalink / raw
To: Johannes Schindelin; +Cc: Junio C Hamano, Git Mailing List
On Mon, 27 Feb 2006, Johannes Schindelin wrote:
>
> beware of that patch. It breaks at least one thing: cloning a repository
> with a tag pointing to a tag object (the tag is cloned, but not the tag
> object).
>
> Sorry to not fix it right away, but I am just too tired.
Ahh. I know what it is.
I'm pretty sure this trivial and stupid patch on top of the patch I sent
out should fix it.
Duh. I moved "pending_objects" into the "revs" structure, but didn't
remove the stale one, along with its use.
Linus
---
diff --git a/rev-list.c b/rev-list.c
index d1c52a6..e9e371c 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -214,8 +214,6 @@ static struct object_list **process_tree
return p;
}
-static struct object_list *pending_objects = NULL;
-
static void show_commit_list(struct commit_list *list)
{
struct object_list *objects = NULL, **p = &objects, *pending;
@@ -226,7 +224,7 @@ static void show_commit_list(struct comm
if (process_commit(commit) == STOP)
break;
}
- for (pending = pending_objects; pending; pending = pending->next) {
+ for (pending = revs.pending_objects; pending; pending = pending->next) {
struct object *obj = pending->item;
const char *name = pending->name;
if (obj->flags & (UNINTERESTING | SEEN))
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] First cut at libifying revlist generation
2006-02-26 0:19 [PATCH] First cut at libifying revlist generation Linus Torvalds
2006-02-26 3:40 ` Junio C Hamano
2006-02-27 1:57 ` Johannes Schindelin
@ 2006-02-27 3:11 ` Junio C Hamano
2006-02-27 3:19 ` Linus Torvalds
2006-02-27 9:00 ` Johannes Schindelin
2 siblings, 2 replies; 12+ messages in thread
From: Junio C Hamano @ 2006-02-27 3:11 UTC (permalink / raw
To: Linus Torvalds; +Cc: Git Mailing List
Linus Torvalds <torvalds@osdl.org> writes:
> Comments? I think this is safe to apply, because I've done a diff of the
> old non-split rev-list.c against both the new rev-list.c and revision.c,
> and all the changes _look_ like just moving things around and taking the
> new "struct rev_info" into account.
I think you would need something the attached patch, at least.
I have a suspicion that this was your easter egg to see how
careful I am reading what I apply -- and I failed. Johannes
gets a test-pilot star for this. This also means we need a bit
better set of tests.
The diff between old rev-list.c and new split files would not
have caught the static variable gotcha.
I am clueless about the "limited = (list && list->next)" part,
but there is only one commit involved hence the test is false
with my testcase "git-rev-list --objects v1.0.0^0..v1.0.0"; I
think the old code said dotdot is a limited case.
---
diff --git a/rev-list.c b/rev-list.c
index d1c52a6..630626e 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -214,8 +214,6 @@ static struct object_list **process_tree
return p;
}
-static struct object_list *pending_objects = NULL;
-
static void show_commit_list(struct commit_list *list)
{
struct object_list *objects = NULL, **p = &objects, *pending;
@@ -226,7 +224,7 @@ static void show_commit_list(struct comm
if (process_commit(commit) == STOP)
break;
}
- for (pending = pending_objects; pending; pending = pending->next) {
+ for (pending = revs.pending_objects; pending; pending = pending->next) {
struct object *obj = pending->item;
const char *name = pending->name;
if (obj->flags & (UNINTERESTING | SEEN))
@@ -675,7 +673,7 @@ int main(int argc, const char **argv)
}
list = revs.commits;
- if (list && list->next)
+ if (list)
limited = 1;
if (revs.topo_order)
@@ -689,7 +687,7 @@ int main(int argc, const char **argv)
limited = 1;
diff_tree_setup_paths(revs.paths);
}
- if (revs.max_age || revs.min_age)
+ if (revs.max_age != -1 || revs.min_age != -1)
limited = 1;
save_commit_buffer = verbose_header;
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] First cut at libifying revlist generation
2006-02-27 3:11 ` Junio C Hamano
@ 2006-02-27 3:19 ` Linus Torvalds
2006-02-27 5:09 ` Junio C Hamano
2006-02-27 9:00 ` Johannes Schindelin
1 sibling, 1 reply; 12+ messages in thread
From: Linus Torvalds @ 2006-02-27 3:19 UTC (permalink / raw
To: Junio C Hamano; +Cc: Git Mailing List
On Sun, 26 Feb 2006, Junio C Hamano wrote:
>
> I am clueless about the "limited = (list && list->next)" part,
> but there is only one commit involved hence the test is false
> with my testcase "git-rev-list --objects v1.0.0^0..v1.0.0"; I
> think the old code said dotdot is a limited case.
dotdot should insert _two_ commits onto the list - the positive and
the negative one. Doesn't it?
So the
if (list && list->next)
check should be correct. If we have just one entry, there's no reason to
do everything up-front, we can just run with it (and get the nice
streaming behaviour).
> -static struct object_list *pending_objects = NULL;
> -
> - for (pending = pending_objects; pending; pending = pending->next) {
> + for (pending = revs.pending_objects; pending; pending = pending->next) {
But this part is obviously correct. I already sent out the same patch a
minute ago ;)
> - if (revs.max_age || revs.min_age)
> + if (revs.max_age != -1 || revs.min_age != -1)
As is this. I for a while had zero meaning "no age", and I actually think
it probably should be that way, but then we'd have to switch the
date-related functions around, which is why I decided not to do it after
all (but missed this one that I had already written for that case).
Linus
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] First cut at libifying revlist generation
2006-02-27 3:19 ` Linus Torvalds
@ 2006-02-27 5:09 ` Junio C Hamano
2006-02-27 5:20 ` Linus Torvalds
0 siblings, 1 reply; 12+ messages in thread
From: Junio C Hamano @ 2006-02-27 5:09 UTC (permalink / raw
To: Linus Torvalds; +Cc: Git Mailing List
Linus Torvalds <torvalds@osdl.org> writes:
> On Sun, 26 Feb 2006, Junio C Hamano wrote:
>>
>> I am clueless about the "limited = (list && list->next)" part,
>> but there is only one commit involved hence the test is false
>> with my testcase "git-rev-list --objects v1.0.0^0..v1.0.0"; I
>> think the old code said dotdot is a limited case.
>
> dotdot should insert _two_ commits onto the list - the positive and
> the negative one. Doesn't it?
Not really, because the second invocation of add_one_commit()
says "I've seen that *commit*", which is correct. And the story
is obviously the same if you used longhand "^v1.0.0^0 v1.0.0".
As a symbolic notation v1.0.0^0..v1.0.0 may not make much sense,
but the point is "the other end says he has that commit object,
but now he wants the tag we later attached to that commit
object; let's list the objects we need to send him". This is
what upload-pack does.
A bad consequence of not limiting is that:
git-rev-list ^v1.0.0^0 v1.0.0 | tail -n 1
gives this commit ;-):
e83c5163316f89bfbde7d9ab23ca2e25604af290
Argh.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] First cut at libifying revlist generation
2006-02-27 5:09 ` Junio C Hamano
@ 2006-02-27 5:20 ` Linus Torvalds
2006-02-27 16:54 ` Linus Torvalds
0 siblings, 1 reply; 12+ messages in thread
From: Linus Torvalds @ 2006-02-27 5:20 UTC (permalink / raw
To: Junio C Hamano; +Cc: Git Mailing List
On Sun, 26 Feb 2006, Junio C Hamano wrote:
>
> Not really, because the second invocation of add_one_commit()
> says "I've seen that *commit*", which is correct. And the story
> is obviously the same if you used longhand "^v1.0.0^0 v1.0.0".
Ok.
I suspect that the simplest fix is to just move "limited" into the "revs"
structure, the way I did pretty much everything else. That way nothing
really changes: we'll have the exact same logic, the flag just moved
around.
Linus
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] First cut at libifying revlist generation
2006-02-27 5:20 ` Linus Torvalds
@ 2006-02-27 16:54 ` Linus Torvalds
2006-02-27 23:55 ` Junio C Hamano
0 siblings, 1 reply; 12+ messages in thread
From: Linus Torvalds @ 2006-02-27 16:54 UTC (permalink / raw
To: Junio C Hamano; +Cc: Git Mailing List
On Sun, 26 Feb 2006, Linus Torvalds wrote:
>
> I suspect that the simplest fix is to just move "limited" into the "revs"
> structure, the way I did pretty much everything else. That way nothing
> really changes: we'll have the exact same logic, the flag just moved
> around.
Here's a cleanup patch that does that. It also moves "unpacked" (and the
flag parsing) into rev_info, since that actually does affect the revision
walker too, and thus logically belongs there.
If you prefer, I can generate a totally re-done patch that combines all
the fixes so far.
Linus
----
diff-tree d33c6e5017d52d36f8da44162c0d87899efd247c (from 4b0fd13e13f49fa73ddd03a69f7d2ad1109139d4)
Author: Linus Torvalds <torvalds@osdl.org>
Date: Mon Feb 27 08:50:26 2006 -0800
Fix rev-list "limited" handling
Also, move "unpacked" into the rev_info structure, where it logically belongs.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/rev-list.c b/rev-list.c
index e9e371c..2e80930 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -41,7 +41,6 @@ static const char rev_list_usage[] =
struct rev_info revs;
-static int unpacked = 0;
static int bisect_list = 0;
static int verbose_header = 0;
static int abbrev = DEFAULT_ABBREV;
@@ -572,7 +571,7 @@ static struct commit_list *limit_list(st
if (revs.max_age != -1 && (commit->date < revs.max_age))
obj->flags |= UNINTERESTING;
- if (unpacked && has_sha1_pack(obj->sha1))
+ if (revs.unpacked && has_sha1_pack(obj->sha1))
obj->flags |= UNINTERESTING;
add_parents_to_list(commit, &list);
if (obj->flags & UNINTERESTING) {
@@ -595,7 +594,7 @@ static struct commit_list *limit_list(st
int main(int argc, const char **argv)
{
struct commit_list *list;
- int i, limited = 0;
+ int i;
argc = setup_revisions(argc, argv, &revs);
@@ -655,11 +654,6 @@ int main(int argc, const char **argv)
bisect_list = 1;
continue;
}
- if (!strcmp(arg, "--unpacked")) {
- unpacked = 1;
- limited = 1;
- continue;
- }
if (!strcmp(arg, "--merge-order")) {
merge_order = 1;
continue;
@@ -673,34 +667,25 @@ int main(int argc, const char **argv)
}
list = revs.commits;
- if (list && list->next)
- limited = 1;
-
- if (revs.topo_order)
- limited = 1;
if (!list &&
(!(revs.tag_objects||revs.tree_objects||revs.blob_objects) && !revs.pending_objects))
usage(rev_list_usage);
- if (revs.paths) {
- limited = 1;
+ if (revs.paths)
diff_tree_setup_paths(revs.paths);
- }
- if (revs.max_age || revs.min_age)
- limited = 1;
save_commit_buffer = verbose_header;
track_object_refs = 0;
if (!merge_order) {
sort_by_date(&list);
- if (list && !limited && revs.max_count == 1 &&
+ if (list && !revs.limited && revs.max_count == 1 &&
!revs.tag_objects && !revs.tree_objects && !revs.blob_objects) {
show_commit(list->item);
return 0;
}
- if (limited)
+ if (revs.limited)
list = limit_list(list);
if (revs.topo_order)
sort_in_topological_order(&list, revs.lifo);
diff --git a/revision.c b/revision.c
index 17dbf9a..0422593 100644
--- a/revision.c
+++ b/revision.c
@@ -143,8 +143,10 @@ static struct commit *get_commit_referen
object->flags |= flags;
if (parse_commit(commit) < 0)
die("unable to parse commit %s", name);
- if (flags & UNINTERESTING)
+ if (flags & UNINTERESTING) {
mark_parents_uninteresting(commit);
+ revs->limited = 1;
+ }
return commit;
}
@@ -255,10 +257,12 @@ int setup_revisions(int argc, const char
}
if (!strncmp(arg, "--max-age=", 10)) {
revs->max_age = atoi(arg + 10);
+ revs->limited = 1;
continue;
}
if (!strncmp(arg, "--min-age=", 10)) {
revs->min_age = atoi(arg + 10);
+ revs->limited = 1;
continue;
}
if (!strcmp(arg, "--all")) {
@@ -277,11 +281,13 @@ int setup_revisions(int argc, const char
}
if (!strcmp(arg, "--topo-order")) {
revs->topo_order = 1;
+ revs->limited = 1;
continue;
}
if (!strcmp(arg, "--date-order")) {
revs->lifo = 0;
revs->topo_order = 1;
+ revs->limited = 1;
continue;
}
if (!strcmp(arg, "--dense")) {
@@ -309,6 +315,11 @@ int setup_revisions(int argc, const char
revs->edge_hint = 1;
continue;
}
+ if (!strcmp(arg, "--unpacked")) {
+ revs->unpacked = 1;
+ revs->limited = 1;
+ continue;
+ }
*unrecognized++ = arg;
left++;
continue;
@@ -365,6 +376,8 @@ int setup_revisions(int argc, const char
commit = get_commit_reference(revs, def, sha1, 0);
add_one_commit(commit, revs);
}
+ if (revs->paths)
+ revs->limited = 1;
*unrecognized = NULL;
return left;
}
diff --git a/revision.h b/revision.h
index 5170ac4..a22f198 100644
--- a/revision.h
+++ b/revision.h
@@ -21,7 +21,9 @@ struct rev_info {
tag_objects:1,
tree_objects:1,
blob_objects:1,
- edge_hint:1;
+ edge_hint:1,
+ limited:1,
+ unpacked:1;
/* special limits */
int max_count;
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] First cut at libifying revlist generation
2006-02-27 3:11 ` Junio C Hamano
2006-02-27 3:19 ` Linus Torvalds
@ 2006-02-27 9:00 ` Johannes Schindelin
2006-02-28 1:13 ` Junio C Hamano
1 sibling, 1 reply; 12+ messages in thread
From: Johannes Schindelin @ 2006-02-27 9:00 UTC (permalink / raw
To: Junio C Hamano; +Cc: Git Mailing List
Hi,
On Sun, 26 Feb 2006, Junio C Hamano wrote:
> Johannes gets a test-pilot star for this. This also means we need a bit
> better set of tests.
Well, I don't deserve this. I cheated.
In my personal version of git, there are a few subtle things different
than in the official version. Most of them, I sent out already, and they
were rejected, such as
http://article.gmane.org/gmane.comp.version-control.git/10718, which
helped me tremendously in identyfing the bug.
But there is also a test case in my version, which was a failure,
originally. I wrote it to demonstrate that the stupid version of
git-fetch was stupid. It did not demonstrate that, but rather quite a bit
of (my) normal usage. That is the reason it takes a really long time for a
test case, and that in turn is the reason I did not dare to submit it.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2006-02-28 1:13 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-02-26 0:19 [PATCH] First cut at libifying revlist generation Linus Torvalds
2006-02-26 3:40 ` Junio C Hamano
2006-02-27 1:57 ` Johannes Schindelin
2006-02-27 3:05 ` Linus Torvalds
2006-02-27 3:11 ` Junio C Hamano
2006-02-27 3:19 ` Linus Torvalds
2006-02-27 5:09 ` Junio C Hamano
2006-02-27 5:20 ` Linus Torvalds
2006-02-27 16:54 ` Linus Torvalds
2006-02-27 23:55 ` Junio C Hamano
2006-02-27 9:00 ` Johannes Schindelin
2006-02-28 1:13 ` Junio C Hamano
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
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 read-only IMAP folder(s) and NNTP newsgroup(s).