Skip to content

Commit 85b87a5

Browse files
peffgitster
authored andcommitted
t/perf: handle worktrees as test repos
The perf suite gets confused when test_perf_default_repo is pointed at a worktree (which includes when it is run from within a worktree at all, since the default is to use the current repository). Here's an example: $ git worktree add ~/foo Preparing worktree (new branch 'foo') HEAD is now at 328c109 The eighth batch $ cd ~/foo $ make [...build output...] $ cd t/perf $ ./p0000-perf-lib-sanity.sh -v -i [...] perf 1 - test_perf_default_repo works: running: foo=$(git rev-parse HEAD) && test_export foo fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git <command> [<revision>...] -- [<file>...]' The problem is that we didn't copy all of the necessary files from the source repository (in this case we got HEAD, but we have no refs!). We discover the git-dir with "rev-parse --git-dir", but this points to the worktree's partial repository in .../.git/worktrees/foo. That partial repository has a "commondir" file which points to the main repository, where the actual refs are stored, but we don't copy it. This is the correct thing to do, though! If we did copy it, then our scratch test repo would be pointing back to the original main repo, and any ref updates we made in the tests would impact that original repo. Instead, we need to either: 1. Make a scratch copy of the original main repo (in addition to the worktree repo), and point the scratch worktree repo's commondir at it. This preserves the original relationship, but it's doubtful any script really cares (if they are testing worktree performance, they'd probably make their own worktrees). And it's trickier to get right. 2. Collapse the main and worktree repos into a single scratch repo. This can be done by copying everything from both, preferring any files from the worktree repo. This patch does the second one. With this applied, the example above results in p0000 running successfully. Reported-by: Derrick Stolee <[email protected]> Signed-off-by: Jeff King <[email protected]> Reviewed-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 225365f commit 85b87a5

File tree

1 file changed

+22
-9
lines changed

1 file changed

+22
-9
lines changed

t/perf/perf-lib.sh

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,27 +70,40 @@ test_perf_do_repo_symlink_config_ () {
7070
test_have_prereq SYMLINKS || git config core.symlinks false
7171
}
7272

73+
test_perf_copy_repo_contents () {
74+
for stuff in "$1"/*
75+
do
76+
case "$stuff" in
77+
*/objects|*/hooks|*/config|*/commondir)
78+
;;
79+
*)
80+
cp -R "$stuff" "$repo/.git/" || exit 1
81+
;;
82+
esac
83+
done
84+
}
85+
7386
test_perf_create_repo_from () {
7487
test "$#" = 2 ||
7588
BUG "not 2 parameters to test-create-repo"
7689
repo="$1"
7790
source="$2"
7891
source_git="$("$MODERN_GIT" -C "$source" rev-parse --git-dir)"
7992
objects_dir="$("$MODERN_GIT" -C "$source" rev-parse --git-path objects)"
93+
common_dir="$("$MODERN_GIT" -C "$source" rev-parse --git-common-dir)"
8094
mkdir -p "$repo/.git"
8195
(
8296
cd "$source" &&
8397
{ cp -Rl "$objects_dir" "$repo/.git/" 2>/dev/null ||
8498
cp -R "$objects_dir" "$repo/.git/"; } &&
85-
for stuff in "$source_git"/*; do
86-
case "$stuff" in
87-
*/objects|*/hooks|*/config|*/commondir)
88-
;;
89-
*)
90-
cp -R "$stuff" "$repo/.git/" || exit 1
91-
;;
92-
esac
93-
done
99+
100+
# common_dir must come first here, since we want source_git to
101+
# take precedence and overwrite any overlapping files
102+
test_perf_copy_repo_contents "$common_dir"
103+
if test "$source_git" != "$common_dir"
104+
then
105+
test_perf_copy_repo_contents "$source_git"
106+
fi
94107
) &&
95108
(
96109
cd "$repo" &&

0 commit comments

Comments
 (0)