Thread (1 message) 1 message, 1 author, 2016-06-15

Re: git pull takes ~8 seconds on up-to-date Linux git tree

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:54:56

Junio C Hamano [off-list ref] writes:
Junio C Hamano [off-list ref] writes:
quoted
Jeff King [off-list ref] writes:
quoted
On Thu, Oct 04, 2012 at 04:14:54PM +0200, Markus Trippelsdorf wrote:
quoted
with current trunk I get the following on an up-to-date Linux tree:

markus@x4 linux % time git pull
Already up-to-date.
git pull  7.84s user 0.26s system 92% cpu 8.743 total

git version 1.7.12 is much quicker:

markus@x4 linux % time git pull
Already up-to-date.
git pull  0.10s user 0.02s system 16% cpu 0.740 total
Yikes. I can easily reproduce here. Bisecting between master and
v1.7.12 gives a curious result: the slowdown first occurs with the merge
commit 34f5130 (Merge branch 'jc/merge-bases', 2012-09-11). But neither
of its parents is slow. I don't see anything obviously suspect in the
merge, though.
I think the following is likely to be the correct solution to this.
No, it is not.  Sorry for the noise.
Here is a tested (in the sense that it passes the test suite, and
also in the sense that an empty pull in the kernel history gives
quick turnaround) patch.  As I do not think we would want to revert
5802f81 (fmt-merge-msg: discard needless merge parents, 2012-04-18)
which was a correctness fix, I think we would rather want to do
something like this.

-- >8 --
Subject: paint_down_to_common(): parse commit before relying on its timestamp

When refactoring the merge-base computation to reduce the pairwise
O(n*(n-1)) traversals to parallel O(n) traversals, the code forgot
that timestamp based heuristics needs each commit to have been
parsed.  This caused an empty "git pull" to spend cycles, traversing
the history all the way down to 0 (because an unparsed commit object
has 0 timestamp, and any other commit object with positive timestamp
will be processed for its parents, all getting parsed), only to come
up with a merge message to be used.

Signed-off-by: Junio C Hamano <redacted>
---
 commit.c | 5 +++++
 1 file changed, 5 insertions(+)
diff --git i/commit.c w/commit.c
index 0246767..213bc98 100644
--- i/commit.c
+++ w/commit.c
@@ -609,6 +609,7 @@ static struct commit *interesting(struct commit_list *list)
 	return NULL;
 }
 
+/* all input commits in one and twos[] must have been parsed! */
 static struct commit_list *paint_down_to_common(struct commit *one, int n, struct commit **twos)
 {
 	struct commit_list *list = NULL;
@@ -617,6 +618,8 @@ static struct commit_list *paint_down_to_common(struct commit *one, int n, struc
 
 	one->object.flags |= PARENT1;
 	commit_list_insert_by_date(one, &list);
+	if (!n)
+		return list;
 	for (i = 0; i < n; i++) {
 		twos[i]->object.flags |= PARENT2;
 		commit_list_insert_by_date(twos[i], &list);
@@ -737,6 +740,8 @@ static int remove_redundant(struct commit **array, int cnt)
 	redundant = xcalloc(cnt, 1);
 	filled_index = xmalloc(sizeof(*filled_index) * (cnt - 1));
 
+	for (i = 0; i < cnt; i++)
+		parse_commit(array[i]);
 	for (i = 0; i < cnt; i++) {
 		struct commit_list *common;
 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help