From 26a8ad25b28a1cb906c88bdf539d840774ca5aeb Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 16 Jul 2006 00:00:09 -0700 Subject: [PATCH 1/3] show-branch: fix performance problem. The core function used in show-branch, join_revs(), was supposed to be exactly the same algorithm as merge_bases(), except that it was a version enhanced for use with more than two heads. However, it needed to mark and keep a list of all the commits it has seen, because it needed them for its semi-graphical output. The function to implement this list, mark_seen(), stupidly used insert_by_date(), when it did not need to keep the list sorted during its processing. This made "show-branch --merge-base" more than 20x slower compared to "merge-base --all" in some cases (e.g. between b5032a5 and 48ce8b0 in the Linux 2.6 kernel archive). The performance of "show-branch --independent" suffered from the same reason. This patch sorts the resulting list after the list traversal just once to fix these problems. Signed-off-by: Junio C Hamano --- builtin-show-branch.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/builtin-show-branch.c b/builtin-show-branch.c index 260cb221b9..3d240ca435 100644 --- a/builtin-show-branch.c +++ b/builtin-show-branch.c @@ -172,7 +172,7 @@ static void name_commits(struct commit_list *list, static int mark_seen(struct commit *commit, struct commit_list **seen_p) { if (!commit->object.flags) { - insert_by_date(commit, seen_p); + commit_list_insert(commit, seen_p); return 1; } return 0; @@ -218,9 +218,8 @@ static void join_revs(struct commit_list **list_p, * Postprocess to complete well-poisoning. * * At this point we have all the commits we have seen in - * seen_p list (which happens to be sorted chronologically but - * it does not really matter). Mark anything that can be - * reached from uninteresting commits not interesting. + * seen_p list. Mark anything that can be reached from + * uninteresting commits not interesting. */ for (;;) { int changed = 0; @@ -701,6 +700,8 @@ int cmd_show_branch(int ac, const char **av, char **envp) if (0 <= extra) join_revs(&list, &seen, num_rev, extra); + sort_by_date(&seen); + if (merge_base) return show_merge_base(seen, num_rev); From 7b520e62a2738ce776d1c9f11144021ff1fc63b6 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 15 Jul 2006 07:10:56 -0700 Subject: [PATCH 2/3] git-svn: don't check for migrations/upgrades on commit-diff Unlike other git-svn commands, commit-diff is intended to operate without needing any additional metadata inside .git Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- git-svn.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-svn.perl b/git-svn.perl index 4530ffe42c..89ad840dbf 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -147,7 +147,7 @@ init_vars(); load_authors() if $_authors; load_all_refs() if $_branch_all_refs; svn_compat_check() unless $_use_lib; -migration_check() unless $cmd =~ /^(?:init|rebuild|multi-init)$/; +migration_check() unless $cmd =~ /^(?:init|rebuild|multi-init|commit-diff)$/; $cmd{$cmd}->[0]->(@ARGV); exit 0; From f8f0b1f0e7e96bf996c657d2c5c15e0ba3a4eeac Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 16 Jul 2006 23:25:12 -0700 Subject: [PATCH 3/3] checkout -f failed to check out a file if an existing directory interfered. When path foo/bar existed in the working tree, checkout -f to switch to a branch that has a file foo silently did a wrong thing. It failed to remove the directory foo, did not check out the file foo, and the worst of all it did not report any errors. Signed-off-by: Junio C Hamano --- builtin-read-tree.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builtin-read-tree.c b/builtin-read-tree.c index 6df5d7c5cb..122b6f130b 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -507,7 +507,7 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old) } merge->ce_flags &= ~htons(CE_STAGEMASK); - add_cache_entry(merge, ADD_CACHE_OK_TO_ADD); + add_cache_entry(merge, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); return 1; } @@ -518,7 +518,7 @@ static int deleted_entry(struct cache_entry *ce, struct cache_entry *old) else verify_absent(ce->name, "removed"); ce->ce_mode = 0; - add_cache_entry(ce, ADD_CACHE_OK_TO_ADD); + add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); invalidate_ce_path(ce); return 1; }