summaryrefslogtreecommitdiff
path: root/negotiator/skipping.c
diff options
context:
space:
mode:
Diffstat (limited to 'negotiator/skipping.c')
-rw-r--r--negotiator/skipping.c48
1 files changed, 32 insertions, 16 deletions
diff --git a/negotiator/skipping.c b/negotiator/skipping.c
index 1236e79..5b91520 100644
--- a/negotiator/skipping.c
+++ b/negotiator/skipping.c
@@ -1,9 +1,11 @@
-#include "cache.h"
+#include "git-compat-util.h"
#include "skipping.h"
#include "../commit.h"
#include "../fetch-negotiator.h"
+#include "../hex.h"
#include "../prio-queue.h"
#include "../refs.h"
+#include "../repository.h"
#include "../tag.h"
/* Remember to update object flag allocation in object.h */
@@ -50,7 +52,7 @@ struct data {
int non_common_revs;
};
-static int compare(const void *a_, const void *b_, void *unused)
+static int compare(const void *a_, const void *b_, void *data UNUSED)
{
const struct entry *a = a_;
const struct entry *b = b_;
@@ -72,7 +74,8 @@ static struct entry *rev_list_push(struct data *data, struct commit *commit, int
}
static int clear_marks(const char *refname, const struct object_id *oid,
- int flag, void *cb_data)
+ int flag UNUSED,
+ void *cb_data UNUSED)
{
struct object *o = deref_tag(the_repository, parse_object(the_repository, oid), refname, 0);
@@ -83,24 +86,37 @@ static int clear_marks(const char *refname, const struct object_id *oid,
}
/*
- * Mark this SEEN commit and all its SEEN ancestors as COMMON.
+ * Mark this SEEN commit and all its parsed SEEN ancestors as COMMON.
*/
-static void mark_common(struct data *data, struct commit *c)
+static void mark_common(struct data *data, struct commit *seen_commit)
{
- struct commit_list *p;
+ struct prio_queue queue = { NULL };
+ struct commit *c;
- if (c->object.flags & COMMON)
+ if (seen_commit->object.flags & COMMON)
return;
- c->object.flags |= COMMON;
- if (!(c->object.flags & POPPED))
- data->non_common_revs--;
- if (!c->object.parsed)
- return;
- for (p = c->parents; p; p = p->next) {
- if (p->item->object.flags & SEEN)
- mark_common(data, p->item);
+ prio_queue_put(&queue, seen_commit);
+ seen_commit->object.flags |= COMMON;
+ while ((c = prio_queue_get(&queue))) {
+ struct commit_list *p;
+
+ if (!(c->object.flags & POPPED))
+ data->non_common_revs--;
+
+ if (!c->object.parsed)
+ continue;
+ for (p = c->parents; p; p = p->next) {
+ if (!(p->item->object.flags & SEEN) ||
+ (p->item->object.flags & COMMON))
+ continue;
+
+ p->item->object.flags |= COMMON;
+ prio_queue_put(&queue, p->item);
+ }
}
+
+ clear_prio_queue(&queue);
}
/*
@@ -177,7 +193,7 @@ static const struct object_id *get_rev(struct data *data)
if (!(commit->object.flags & COMMON) && !entry->ttl)
to_send = commit;
- parse_commit(commit);
+ repo_parse_commit(the_repository, commit);
for (p = commit->parents; p; p = p->next)
parent_pushed |= push_parent(data, entry, p->item);