From: Derrick Stolee <dstolee@microsoft.com>
To: "git@vger.kernel.org" <git@vger.kernel.org>
Cc: "peff@peff.net" <peff@peff.net>,
"sbeller@google.com" <sbeller@google.com>,
"jnareb@gmail.com" <jnareb@gmail.com>,
Derrick Stolee <dstolee@microsoft.com>
Subject: [RFC PATCH 12/13] commit-reach: use is_descendant_of for ref_newer
Date: Fri, 29 Jun 2018 16:13:01 +0000 [thread overview]
Message-ID: <20180629161223.229661-13-dstolee@microsoft.com> (raw)
In-Reply-To: <20180629161223.229661-1-dstolee@microsoft.com>
The ref_newer method is used by 'git push' to detect if a force-push is
requried. This method does not use any kind of cutoff when walking, so
in the case of a force-push will walk all reachable commits.
The is_descendant_of method already uses paint_down_to_common along with
cutoffs. By translating the ref_newer arguments into the commit and
commit_list required by is_descendant_of, we can have one fewer commit
walk and also improve our performance!
For a copy of the Linux repository, 'test-tool reach ref_newer' presents
the following improvements with the specified input.
Input
-----
A:v4.9
B:v3.19
Before: 0.11 s
After: 0.10 s
To test the negative case, add a new commit with parent v3.19,
regenerate the commit-graph, and then run with B pointing at that
commit.
Before: 0.52 s
After: 0.12 s
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
---
commit-reach.c | 17 ++++-------------
commit.c | 7 +++++--
commit.h | 6 +++++-
fetch-pack.c | 3 ++-
sha1-name.c | 3 ++-
walker.c | 3 ++-
6 files changed, 20 insertions(+), 19 deletions(-)
diff --git a/commit-reach.c b/commit-reach.c
index 8e24455d9f..249e9a4fac 100644
--- a/commit-reach.c
+++ b/commit-reach.c
@@ -376,7 +376,7 @@ int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid)
{
struct object *o;
struct commit *old_commit, *new_commit;
- struct commit_list *list, *used;
+ struct commit_list *list = NULL;
int found = 0;
/*
@@ -396,18 +396,9 @@ int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid)
if (parse_commit(new_commit) < 0)
return 0;
- used = list = NULL;
- commit_list_insert(new_commit, &list);
- while (list) {
- new_commit = pop_most_recent_commit(&list, TMP_MARK);
- commit_list_insert(new_commit, &used);
- if (new_commit == old_commit) {
- found = 1;
- break;
- }
- }
- unmark_and_free(list, TMP_MARK);
- unmark_and_free(used, TMP_MARK);
+ commit_list_insert(old_commit, &list);
+ found = is_descendant_of(new_commit, list);
+ free_commit_list(list);
return found;
}
diff --git a/commit.c b/commit.c
index d4ddaf4879..9870682673 100644
--- a/commit.c
+++ b/commit.c
@@ -556,7 +556,8 @@ void commit_list_sort_by_date(struct commit_list **list)
}
struct commit *pop_most_recent_commit(struct commit_list **list,
- unsigned int mark)
+ unsigned int mark,
+ uint32_t min_generation)
{
struct commit *ret = pop_commit(list);
struct commit_list *parents = ret->parents;
@@ -565,7 +566,9 @@ struct commit *pop_most_recent_commit(struct commit_list **list,
struct commit *commit = parents->item;
if (!parse_commit(commit) && !(commit->object.flags & mark)) {
commit->object.flags |= mark;
- commit_list_insert_by_date(commit, list);
+
+ if (commit->generation >= min_generation)
+ commit_list_insert_by_date(commit, list);
}
parents = parents->next;
}
diff --git a/commit.h b/commit.h
index 7e0f273720..5eaeded5e2 100644
--- a/commit.h
+++ b/commit.h
@@ -159,9 +159,13 @@ extern const char *skip_blank_lines(const char *msg);
/** Removes the first commit from a list sorted by date, and adds all
* of its parents.
+ *
+ * The parents are not added if their generation number is strictly
+ * lower than min_generation.
**/
struct commit *pop_most_recent_commit(struct commit_list **list,
- unsigned int mark);
+ unsigned int mark,
+ uint32_t min_generation);
struct commit *pop_commit(struct commit_list **stack);
diff --git a/fetch-pack.c b/fetch-pack.c
index a320ce9872..351e3d4bcd 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -600,7 +600,8 @@ static void mark_recent_complete_commits(struct fetch_pack_args *args,
while (complete && cutoff <= complete->item->date) {
print_verbose(args, _("Marking %s as complete"),
oid_to_hex(&complete->item->object.oid));
- pop_most_recent_commit(&complete, COMPLETE);
+ pop_most_recent_commit(&complete, COMPLETE,
+ GENERATION_NUMBER_ZERO);
}
}
diff --git a/sha1-name.c b/sha1-name.c
index 60d9ef3c7e..471a54464d 100644
--- a/sha1-name.c
+++ b/sha1-name.c
@@ -1141,7 +1141,8 @@ static int get_oid_oneline(const char *prefix, struct object_id *oid,
struct commit *commit;
int matches;
- commit = pop_most_recent_commit(&list, ONELINE_SEEN);
+ commit = pop_most_recent_commit(&list, ONELINE_SEEN,
+ GENERATION_NUMBER_ZERO);
if (!parse_object(&commit->object.oid))
continue;
buf = get_commit_buffer(commit, NULL);
diff --git a/walker.c b/walker.c
index 0b162a09b9..e243fc8768 100644
--- a/walker.c
+++ b/walker.c
@@ -78,7 +78,8 @@ static int process_commit(struct walker *walker, struct commit *commit)
return -1;
while (complete && complete->item->date >= commit->date) {
- pop_most_recent_commit(&complete, COMPLETE);
+ pop_most_recent_commit(&complete, COMPLETE,
+ GENERATION_NUMBER_ZERO);
}
if (commit->object.flags & COMPLETE)
--
2.18.0.118.gd4f65b8d14
next prev parent reply other threads:[~2018-06-29 16:13 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-29 16:12 [RFC PATCH 00/13] Consolidate reachability logic Derrick Stolee
2018-06-29 16:12 ` [RFC PATCH 01/13] commit-reach: move walk methods from commit.c Derrick Stolee
2018-06-29 21:35 ` Stefan Beller
2018-06-29 21:52 ` Junio C Hamano
2018-06-29 16:12 ` [RFC PATCH 02/13] commit-reach: move ref_newer from remote.c Derrick Stolee
2018-06-29 16:12 ` [RFC PATCH 03/13] commit-reach: move commit_contains from ref-filter Derrick Stolee
2018-06-29 21:38 ` Stefan Beller
2018-06-30 1:32 ` Derrick Stolee
2018-06-29 22:00 ` Junio C Hamano
2018-06-29 16:12 ` [RFC PATCH 04/13] upload-pack: make reachable() more generic Derrick Stolee
2018-06-29 22:05 ` Junio C Hamano
2018-06-29 16:12 ` [RFC PATCH 05/13] upload-pack: refactor ok_to_give_up() Derrick Stolee
2018-06-29 21:44 ` Stefan Beller
2018-06-29 16:12 ` [RFC PATCH 06/13] commit-reach: move can_all_from_reach_with_flag() Derrick Stolee
2018-06-29 21:47 ` Stefan Beller
2018-06-30 1:35 ` Derrick Stolee
2018-06-29 16:12 ` [RFC PATCH 07/13] test-reach Derrick Stolee
2018-06-29 21:54 ` Stefan Beller
2018-06-30 1:40 ` Derrick Stolee
2018-06-29 16:12 ` [RFC PATCH 08/13] test-reach: test reduce_heads() Derrick Stolee
2018-06-29 22:06 ` Stefan Beller
2018-06-29 16:12 ` [RFC PATCH 09/13] commit-reach: test can_all_from_reach Derrick Stolee
2018-06-29 16:12 ` [RFC PATCH 10/13] commit-reach: test is_descendant_of Derrick Stolee
2018-06-29 16:13 ` [RFC PATCH 11/13] commit-reach: make can_all_from_reach... linear Derrick Stolee
2018-06-29 23:18 ` Stefan Beller
2018-06-29 16:13 ` Derrick Stolee [this message]
2018-06-29 16:13 ` [RFC PATCH 13/13] commit-reach: use can_all_from_reach Derrick Stolee
2018-06-29 23:21 ` Stefan Beller
2018-06-29 17:33 ` [RFC PATCH 00/13] Consolidate reachability logic Derrick Stolee
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=20180629161223.229661-13-dstolee@microsoft.com \
--to=dstolee@microsoft.com \
--cc=git@vger.kernel.org \
--cc=jnareb@gmail.com \
--cc=peff@peff.net \
--cc=sbeller@google.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.