2021-12-03 13:34:18 +00:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='test the `scalar` command'
|
|
|
|
|
scalar: include in standard Git build & installation
Move 'scalar' out of 'contrib/' and into the root of the Git tree. The goal
of this change is to build 'scalar' as part of the standard Git build &
install processes.
This patch includes both the physical move of Scalar's files out of
'contrib/' ('scalar.c', 'scalar.txt', and 't9xxx-scalar.sh'), and the
changes to the build definitions in 'Makefile' and 'CMakelists.txt' to
accommodate the new program.
At a high level, Scalar is built so that:
- there is a 'scalar-objs' target (similar to those created in 029bac01a8
(Makefile: add {program,xdiff,test,git,fuzz}-objs & objects targets,
2021-02-23)) for debugging purposes.
- it appears in the root of the install directory (rather than the
gitexecdir).
- it is included in the 'bin-wrappers/' directory for use in tests.
- it receives a platform-specific executable suffix (e.g., '.exe'), if
applicable.
- 'scalar.txt' is installed as 'man1' documentation.
- the 'clean' target removes the 'scalar' executable.
Additionally, update the root level '.gitignore' file to ignore the Scalar
executable.
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-09-02 15:56:43 +00:00
|
|
|
. ./test-lib.sh
|
2021-12-03 13:34:18 +00:00
|
|
|
|
scalar: include in standard Git build & installation
Move 'scalar' out of 'contrib/' and into the root of the Git tree. The goal
of this change is to build 'scalar' as part of the standard Git build &
install processes.
This patch includes both the physical move of Scalar's files out of
'contrib/' ('scalar.c', 'scalar.txt', and 't9xxx-scalar.sh'), and the
changes to the build definitions in 'Makefile' and 'CMakelists.txt' to
accommodate the new program.
At a high level, Scalar is built so that:
- there is a 'scalar-objs' target (similar to those created in 029bac01a8
(Makefile: add {program,xdiff,test,git,fuzz}-objs & objects targets,
2021-02-23)) for debugging purposes.
- it appears in the root of the install directory (rather than the
gitexecdir).
- it is included in the 'bin-wrappers/' directory for use in tests.
- it receives a platform-specific executable suffix (e.g., '.exe'), if
applicable.
- 'scalar.txt' is installed as 'man1' documentation.
- the 'clean' target removes the 'scalar' executable.
Additionally, update the root level '.gitignore' file to ignore the Scalar
executable.
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-09-02 15:56:43 +00:00
|
|
|
GIT_TEST_MAINT_SCHEDULER="crontab:test-tool crontab cron.txt,launchctl:true,schtasks:true"
|
2021-12-03 13:34:23 +00:00
|
|
|
export GIT_TEST_MAINT_SCHEDULER
|
|
|
|
|
2021-12-03 13:34:18 +00:00
|
|
|
test_expect_success 'scalar shows a usage' '
|
|
|
|
test_expect_code 129 scalar -h
|
|
|
|
'
|
|
|
|
|
scalar: constrain enlistment search
Make the search for repository and enlistment root in
'setup_enlistment_directory()' more constrained to simplify behavior and
adhere to 'GIT_CEILING_DIRECTORIES'.
Previously, 'setup_enlistment_directory()' would check whether the provided
path (or current working directory) '<dir>' or its subdirectory '<dir>/src'
was a repository root. If not, the process would repeat on the parent of
'<dir>' until the repository was found or it reached the root of the
filesystem. This meant that a user could specify a path *anywhere* inside an
enlistment (including paths not in the repository contained within the
enlistment) and it would be found.
The downside to this process is that the search would not account for
'GIT_CEILING_DIRECTORIES', so the upward search could result in modifying
repository contents past 'GIT_CEILING_DIRECTORIES'. Similarly, operations
like 'scalar delete' could end up unintentionally deleting the parent of a
repo if its root was named 'src'.
To make this 'setup_enlistment_directory()' both adhere to
'GIT_CEILING_DIRECTORIES' and avoid unwanted deletions, the search for an
enlistment directory is simplified to:
- if '<dir>/src' is a repository root, '<dir>' is the enlistment root
- if '<dir>' is either the repository root or contained within a repository,
the repository root is the enlistment root
Now, only 'setup_git_directory()' (called by 'setup_enlistment_directory()')
searches upwards from the 'scalar' specified path, enforcing
'GIT_CEILING_DIRECTORIES' in the process. Additionally, 'scalar delete
<dir>/src' will not delete '<dir>' (if users would like to delete it, they
can still specify the enlistment root with 'scalar delete <dir>'). This is
true of any 'scalar' operation; users can invoke 'scalar' on the enlistment
root, but paths must otherwise be inside the repository to be valid.
To help clarify the updated behavior, new tests are added to
't9099-scalar.sh'.
Finally, this change leaves 'strbuf_parent_directory()' with only a single,
WIN32-specific caller in 'delete_enlistment()'. Rather than wrap
'strbuf_parent_directory()' in '#ifdef WIN32' to avoid the "unused function"
compiler error, move the contents of 'strbuf_parent_directory()' into
'delete_enlistment()' and remove the function.
Helped-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-08-18 21:40:46 +00:00
|
|
|
test_expect_success 'scalar invoked on enlistment root' '
|
|
|
|
test_when_finished rm -rf test src deeper &&
|
|
|
|
|
|
|
|
for enlistment_root in test src deeper/test
|
|
|
|
do
|
|
|
|
git init ${enlistment_root}/src &&
|
|
|
|
|
|
|
|
# Register
|
|
|
|
scalar register ${enlistment_root} &&
|
|
|
|
scalar list >out &&
|
|
|
|
grep "$(pwd)/${enlistment_root}/src\$" out &&
|
|
|
|
|
|
|
|
# Delete (including enlistment root)
|
|
|
|
scalar delete $enlistment_root &&
|
|
|
|
test_path_is_missing $enlistment_root &&
|
|
|
|
scalar list >out &&
|
|
|
|
! grep "^$(pwd)/${enlistment_root}/src\$" out || return 1
|
|
|
|
done
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'scalar invoked on enlistment src repo' '
|
|
|
|
test_when_finished rm -rf test src deeper &&
|
|
|
|
|
|
|
|
for enlistment_root in test src deeper/test
|
|
|
|
do
|
|
|
|
git init ${enlistment_root}/src &&
|
|
|
|
|
|
|
|
# Register
|
|
|
|
scalar register ${enlistment_root}/src &&
|
|
|
|
scalar list >out &&
|
|
|
|
grep "$(pwd)/${enlistment_root}/src\$" out &&
|
|
|
|
|
|
|
|
# Delete (will not include enlistment root)
|
|
|
|
scalar delete ${enlistment_root}/src &&
|
|
|
|
test_path_is_dir $enlistment_root &&
|
|
|
|
scalar list >out &&
|
|
|
|
! grep "^$(pwd)/${enlistment_root}/src\$" out || return 1
|
|
|
|
done
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'scalar invoked when enlistment root and repo are the same' '
|
|
|
|
test_when_finished rm -rf test src deeper &&
|
|
|
|
|
|
|
|
for enlistment_root in test src deeper/test
|
|
|
|
do
|
|
|
|
git init ${enlistment_root} &&
|
|
|
|
|
|
|
|
# Register
|
|
|
|
scalar register ${enlistment_root} &&
|
|
|
|
scalar list >out &&
|
|
|
|
grep "$(pwd)/${enlistment_root}\$" out &&
|
|
|
|
|
|
|
|
# Delete (will not include enlistment root)
|
|
|
|
scalar delete ${enlistment_root} &&
|
|
|
|
test_path_is_missing $enlistment_root &&
|
|
|
|
scalar list >out &&
|
|
|
|
! grep "^$(pwd)/${enlistment_root}\$" out &&
|
|
|
|
|
|
|
|
# Make sure we did not accidentally delete the trash dir
|
|
|
|
test_path_is_dir "$TRASH_DIRECTORY" || return 1
|
|
|
|
done
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'scalar repo search respects GIT_CEILING_DIRECTORIES' '
|
|
|
|
test_when_finished rm -rf test &&
|
|
|
|
|
|
|
|
git init test/src &&
|
|
|
|
mkdir -p test/src/deep &&
|
|
|
|
GIT_CEILING_DIRECTORIES="$(pwd)/test/src" &&
|
|
|
|
! scalar register test/src/deep 2>err &&
|
|
|
|
grep "not a git repository" err
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'scalar enlistments need a worktree' '
|
|
|
|
test_when_finished rm -rf bare test &&
|
|
|
|
|
|
|
|
git init --bare bare/src &&
|
|
|
|
! scalar register bare/src 2>err &&
|
|
|
|
grep "Scalar enlistments require a worktree" err &&
|
|
|
|
|
|
|
|
git init test/src &&
|
|
|
|
! scalar register test/src/.git 2>err &&
|
|
|
|
grep "Scalar enlistments require a worktree" err
|
|
|
|
'
|
|
|
|
|
2022-08-18 21:40:51 +00:00
|
|
|
test_expect_success FSMONITOR_DAEMON 'scalar register starts fsmon daemon' '
|
|
|
|
git init test/src &&
|
|
|
|
test_must_fail git -C test/src fsmonitor--daemon status &&
|
|
|
|
scalar register test/src &&
|
|
|
|
git -C test/src fsmonitor--daemon status &&
|
|
|
|
test_cmp_config -C test/src true core.fsmonitor
|
|
|
|
'
|
|
|
|
|
2023-01-27 20:06:03 +00:00
|
|
|
test_expect_success 'scalar register warns when background maintenance fails' '
|
2023-01-27 20:06:02 +00:00
|
|
|
git init register-repo &&
|
|
|
|
GIT_TEST_MAINT_SCHEDULER="crontab:false,launchctl:false,schtasks:false" \
|
2023-01-27 20:06:03 +00:00
|
|
|
scalar register register-repo 2>err &&
|
2023-01-27 20:06:02 +00:00
|
|
|
grep "could not turn on maintenance" err
|
|
|
|
'
|
|
|
|
|
2021-12-03 13:34:21 +00:00
|
|
|
test_expect_success 'scalar unregister' '
|
|
|
|
git init vanish/src &&
|
|
|
|
scalar register vanish/src &&
|
|
|
|
git config --get --global --fixed-value \
|
|
|
|
maintenance.repo "$(pwd)/vanish/src" &&
|
|
|
|
scalar list >scalar.repos &&
|
|
|
|
grep -F "$(pwd)/vanish/src" scalar.repos &&
|
|
|
|
rm -rf vanish/src/.git &&
|
|
|
|
scalar unregister vanish &&
|
|
|
|
test_must_fail git config --get --global --fixed-value \
|
|
|
|
maintenance.repo "$(pwd)/vanish/src" &&
|
|
|
|
scalar list >scalar.repos &&
|
2022-09-27 13:56:59 +00:00
|
|
|
! grep -F "$(pwd)/vanish/src" scalar.repos &&
|
|
|
|
|
|
|
|
# scalar unregister should be idempotent
|
|
|
|
scalar unregister vanish
|
2021-12-03 13:34:21 +00:00
|
|
|
'
|
|
|
|
|
2021-12-03 13:34:23 +00:00
|
|
|
test_expect_success 'set up repository to clone' '
|
|
|
|
test_commit first &&
|
|
|
|
test_commit second &&
|
|
|
|
test_commit third &&
|
|
|
|
git switch -c parallel first &&
|
|
|
|
mkdir -p 1/2 &&
|
|
|
|
test_commit 1/2/3 &&
|
|
|
|
git config uploadPack.allowFilter true &&
|
|
|
|
git config uploadPack.allowAnySHA1InWant true
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'scalar clone' '
|
|
|
|
second=$(git rev-parse --verify second:second.t) &&
|
2021-12-03 13:34:24 +00:00
|
|
|
scalar clone "file://$(pwd)" cloned --single-branch &&
|
2021-12-03 13:34:23 +00:00
|
|
|
(
|
|
|
|
cd cloned/src &&
|
|
|
|
|
|
|
|
git config --get --global --fixed-value maintenance.repo \
|
|
|
|
"$(pwd)" &&
|
|
|
|
|
2021-12-03 13:34:24 +00:00
|
|
|
git for-each-ref --format="%(refname)" refs/remotes/origin/ >actual &&
|
|
|
|
echo "refs/remotes/origin/parallel" >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
2021-12-03 13:34:23 +00:00
|
|
|
test_path_is_missing 1/2 &&
|
|
|
|
test_must_fail git rev-list --missing=print $second &&
|
|
|
|
git rev-list $second &&
|
|
|
|
git cat-file blob $second >actual &&
|
|
|
|
echo "second" >expect &&
|
|
|
|
test_cmp expect actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2021-12-03 13:34:26 +00:00
|
|
|
test_expect_success 'scalar reconfigure' '
|
|
|
|
git init one/src &&
|
|
|
|
scalar register one &&
|
|
|
|
git -C one/src config core.preloadIndex false &&
|
|
|
|
scalar reconfigure one &&
|
2021-12-03 13:34:27 +00:00
|
|
|
test true = "$(git -C one/src config core.preloadIndex)" &&
|
|
|
|
git -C one/src config core.preloadIndex false &&
|
|
|
|
scalar reconfigure -a &&
|
2021-12-03 13:34:26 +00:00
|
|
|
test true = "$(git -C one/src config core.preloadIndex)"
|
|
|
|
'
|
|
|
|
|
2022-11-07 18:25:01 +00:00
|
|
|
test_expect_success '`reconfigure -a` removes stale config entries' '
|
|
|
|
git init stale/src &&
|
|
|
|
scalar register stale &&
|
|
|
|
scalar list >scalar.repos &&
|
|
|
|
grep stale scalar.repos &&
|
2022-11-10 07:28:47 +00:00
|
|
|
|
|
|
|
grep -v stale scalar.repos >expect &&
|
|
|
|
|
2022-11-07 18:25:01 +00:00
|
|
|
rm -rf stale &&
|
|
|
|
scalar reconfigure -a &&
|
|
|
|
scalar list >scalar.repos &&
|
2022-11-10 07:28:47 +00:00
|
|
|
test_cmp expect scalar.repos
|
2022-11-07 18:25:01 +00:00
|
|
|
'
|
|
|
|
|
2021-12-03 13:34:28 +00:00
|
|
|
test_expect_success 'scalar delete without enlistment shows a usage' '
|
|
|
|
test_expect_code 129 scalar delete
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'scalar delete with enlistment' '
|
|
|
|
scalar delete cloned &&
|
|
|
|
test_path_is_missing cloned
|
|
|
|
'
|
|
|
|
|
2022-01-28 14:31:57 +00:00
|
|
|
test_expect_success 'scalar supports -c/-C' '
|
|
|
|
test_when_finished "scalar delete sub" &&
|
|
|
|
git init sub &&
|
|
|
|
scalar -C sub -c status.aheadBehind=bogus register &&
|
|
|
|
test -z "$(git -C sub config --local status.aheadBehind)" &&
|
|
|
|
test true = "$(git -C sub config core.preloadIndex)"
|
|
|
|
'
|
|
|
|
|
2022-05-28 23:11:14 +00:00
|
|
|
test_expect_success '`scalar [...] <dir>` errors out when dir is missing' '
|
|
|
|
! scalar run config cloned 2>err &&
|
|
|
|
grep "cloned. does not exist" err
|
|
|
|
'
|
|
|
|
|
scalar: implement `scalar diagnose`
Over the course of Scalar's development, it became obvious that there is
a need for a command that can gather all kinds of useful information
that can help identify the most typical problems with large
worktrees/repositories.
The `diagnose` command is the culmination of this hard-won knowledge: it
gathers the installed hooks, the config, a couple statistics describing
the data shape, among other pieces of information, and then wraps
everything up in a tidy, neat `.zip` archive.
Note: originally, Scalar was implemented in C# using the .NET API, where
we had the luxury of a comprehensive standard library that includes
basic functionality such as writing a `.zip` file. In the C version, we
lack such a commodity. Rather than introducing a dependency on, say,
libzip, we slightly abuse Git's `archive` machinery: we write out a
`.zip` of the empty try, augmented by a couple files that are added via
the `--add-file*` options. We are careful trying not to modify the
current repository in any way lest the very circumstances that required
`scalar diagnose` to be run are changed by the `diagnose` run itself.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-05-28 23:11:15 +00:00
|
|
|
SQ="'"
|
|
|
|
test_expect_success UNZIP 'scalar diagnose' '
|
|
|
|
scalar clone "file://$(pwd)" cloned --single-branch &&
|
2022-05-28 23:11:17 +00:00
|
|
|
git repack &&
|
|
|
|
echo "$(pwd)/.git/objects/" >>cloned/src/.git/objects/info/alternates &&
|
2022-05-28 23:11:18 +00:00
|
|
|
test_commit -C cloned/src loose &&
|
scalar: implement `scalar diagnose`
Over the course of Scalar's development, it became obvious that there is
a need for a command that can gather all kinds of useful information
that can help identify the most typical problems with large
worktrees/repositories.
The `diagnose` command is the culmination of this hard-won knowledge: it
gathers the installed hooks, the config, a couple statistics describing
the data shape, among other pieces of information, and then wraps
everything up in a tidy, neat `.zip` archive.
Note: originally, Scalar was implemented in C# using the .NET API, where
we had the luxury of a comprehensive standard library that includes
basic functionality such as writing a `.zip` file. In the C version, we
lack such a commodity. Rather than introducing a dependency on, say,
libzip, we slightly abuse Git's `archive` machinery: we write out a
`.zip` of the empty try, augmented by a couple files that are added via
the `--add-file*` options. We are careful trying not to modify the
current repository in any way lest the very circumstances that required
`scalar diagnose` to be run are changed by the `diagnose` run itself.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-05-28 23:11:15 +00:00
|
|
|
scalar diagnose cloned >out 2>err &&
|
2022-05-28 23:11:16 +00:00
|
|
|
grep "Available space" out &&
|
scalar: implement `scalar diagnose`
Over the course of Scalar's development, it became obvious that there is
a need for a command that can gather all kinds of useful information
that can help identify the most typical problems with large
worktrees/repositories.
The `diagnose` command is the culmination of this hard-won knowledge: it
gathers the installed hooks, the config, a couple statistics describing
the data shape, among other pieces of information, and then wraps
everything up in a tidy, neat `.zip` archive.
Note: originally, Scalar was implemented in C# using the .NET API, where
we had the luxury of a comprehensive standard library that includes
basic functionality such as writing a `.zip` file. In the C version, we
lack such a commodity. Rather than introducing a dependency on, say,
libzip, we slightly abuse Git's `archive` machinery: we write out a
`.zip` of the empty try, augmented by a couple files that are added via
the `--add-file*` options. We are careful trying not to modify the
current repository in any way lest the very circumstances that required
`scalar diagnose` to be run are changed by the `diagnose` run itself.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-05-28 23:11:15 +00:00
|
|
|
sed -n "s/.*$SQ\\(.*\\.zip\\)$SQ.*/\\1/p" <err >zip_path &&
|
|
|
|
zip_path=$(cat zip_path) &&
|
|
|
|
test -n "$zip_path" &&
|
2022-08-12 20:10:09 +00:00
|
|
|
"$GIT_UNZIP" -v "$zip_path" &&
|
scalar: implement `scalar diagnose`
Over the course of Scalar's development, it became obvious that there is
a need for a command that can gather all kinds of useful information
that can help identify the most typical problems with large
worktrees/repositories.
The `diagnose` command is the culmination of this hard-won knowledge: it
gathers the installed hooks, the config, a couple statistics describing
the data shape, among other pieces of information, and then wraps
everything up in a tidy, neat `.zip` archive.
Note: originally, Scalar was implemented in C# using the .NET API, where
we had the luxury of a comprehensive standard library that includes
basic functionality such as writing a `.zip` file. In the C version, we
lack such a commodity. Rather than introducing a dependency on, say,
libzip, we slightly abuse Git's `archive` machinery: we write out a
`.zip` of the empty try, augmented by a couple files that are added via
the `--add-file*` options. We are careful trying not to modify the
current repository in any way lest the very circumstances that required
`scalar diagnose` to be run are changed by the `diagnose` run itself.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-05-28 23:11:15 +00:00
|
|
|
folder=${zip_path%.zip} &&
|
|
|
|
test_path_is_missing "$folder" &&
|
2022-08-12 20:10:09 +00:00
|
|
|
"$GIT_UNZIP" -p "$zip_path" diagnostics.log >out &&
|
2022-05-28 23:11:17 +00:00
|
|
|
test_file_not_empty out &&
|
2022-08-12 20:10:09 +00:00
|
|
|
"$GIT_UNZIP" -p "$zip_path" packs-local.txt >out &&
|
2022-05-28 23:11:18 +00:00
|
|
|
grep "$(pwd)/.git/objects" out &&
|
2022-08-12 20:10:09 +00:00
|
|
|
"$GIT_UNZIP" -p "$zip_path" objects-local.txt >out &&
|
2022-05-28 23:11:18 +00:00
|
|
|
grep "^Total: [1-9]" out
|
scalar: implement `scalar diagnose`
Over the course of Scalar's development, it became obvious that there is
a need for a command that can gather all kinds of useful information
that can help identify the most typical problems with large
worktrees/repositories.
The `diagnose` command is the culmination of this hard-won knowledge: it
gathers the installed hooks, the config, a couple statistics describing
the data shape, among other pieces of information, and then wraps
everything up in a tidy, neat `.zip` archive.
Note: originally, Scalar was implemented in C# using the .NET API, where
we had the luxury of a comprehensive standard library that includes
basic functionality such as writing a `.zip` file. In the C version, we
lack such a commodity. Rather than introducing a dependency on, say,
libzip, we slightly abuse Git's `archive` machinery: we write out a
`.zip` of the empty try, augmented by a couple files that are added via
the `--add-file*` options. We are careful trying not to modify the
current repository in any way lest the very circumstances that required
`scalar diagnose` to be run are changed by the `diagnose` run itself.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-05-28 23:11:15 +00:00
|
|
|
'
|
|
|
|
|
2021-12-03 13:34:18 +00:00
|
|
|
test_done
|