Instead of a custom commit walker like get_shallow_commits(), this new function uses rev-list to mark SHALLOW to all reachable commits. The definition of reachable is to be defined by the protocol later. This makes it more flexible to define shallow boundary. Note: if a commit has one not_shallow parent and one shallow parent, then it's considered the boundary. Which means in the client side, this commit has _no_ parents. This could lead to surprising cuts if we're not careful. Another option is to include more commits and only mark commits whose all parents are not-shallow as boundary. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- commit.h | 2 ++ shallow.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/commit.h b/commit.h index 9f189cb..5c80eea 100644 --- a/commit.h +++ b/commit.h @@ -254,6 +254,8 @@ extern int for_each_commit_graft(each_commit_graft_fn, void *); extern int is_repository_shallow(void); extern struct commit_list *get_shallow_commits(struct object_array *heads, int depth, int shallow_flag, int not_shallow_flag); +extern struct commit_list *get_shallow_commits_by_rev_list( + int ac, const char **av, int shallow_flag, int not_shallow_flag); extern void set_alternate_shallow_file(const char *path, int override); extern int write_shallow_commits(struct strbuf *out, int use_pack_protocol, const struct sha1_array *extra); diff --git a/shallow.c b/shallow.c index d8bf40a..1db2768 100644 --- a/shallow.c +++ b/shallow.c @@ -10,6 +10,8 @@ #include "revision.h" #include "commit-slab.h" #include "sigchain.h" +#include "revision.h" +#include "list-objects.h" static int is_shallow = -1; static struct stat_validity shallow_stat; @@ -137,6 +139,69 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth, return result; } +static void show_commit(struct commit *commit, void *data) +{ + commit->object.flags |= *(int *)data; +} + +struct commit_list *get_shallow_commits_by_rev_list(int ac, const char **av, + int shallow_flag, int not_shallow_flag) +{ + struct commit_list *result = NULL; + struct rev_info revs; + unsigned int i, nr; + + /* + * SHALLOW and NOT_SHALLOW should not be set at this + * point. But better be safe than sorry. + */ + nr = get_max_object_index(); + for (i = 0; i < nr; i++) { + struct object *o = get_indexed_object(i); + o->flags &= ~(shallow_flag | not_shallow_flag); + } + + is_repository_shallow(); /* make sure shallows are read */ + + init_revisions(&revs, NULL); + save_commit_buffer = 0; + setup_revisions(ac, av, &revs, NULL); + + /* mark all reachable commits as SHALLOW */ + if (prepare_revision_walk(&revs)) + die("revision walk setup failed"); + traverse_commit_list(&revs, show_commit, NULL, &shallow_flag); + + nr = get_max_object_index(); + for (i = 0; i < nr; i++) { + struct object *o = get_indexed_object(i); + struct commit *c = (struct commit *)o; + struct commit_list *p; + int parent_is_not_shallow = 0; + + if (o->type != OBJ_COMMIT || !(o->flags & shallow_flag)) + continue; + + if (parse_commit(c)) + die("unable to parse commit %s", + sha1_to_hex(c->object.sha1)); + + for (p = c->parents; p; p = p->next) { + if (p->item->object.flags & shallow_flag) + continue; + parent_is_not_shallow = 1; + if (p->item->object.flags & not_shallow_flag) + continue; + p->item->object.flags |= not_shallow_flag; + commit_list_insert(p->item, &result); + } + + if (parent_is_not_shallow) + commit_list_insert(c, &result); + } + return result; +} + static void check_shallow_file_for_update(void) { if (is_shallow == -1) -- 2.3.0.rc1.137.g477eb31 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html