Merge branch 'vd/scalar-to-main'

Hoist the remainder of "scalar" out of contrib/ to the main part of
the codebase.

* vd/scalar-to-main:
  Documentation/technical: include Scalar technical doc
  t/perf: add 'GIT_PERF_USE_SCALAR' run option
  t/perf: add Scalar performance tests
  scalar-clone: add test coverage
  scalar: add to 'git help -a' command list
  scalar: implement the `help` subcommand
  git help: special-case `scalar`
  scalar: include in standard Git build & installation
  scalar: fix command documentation section header
This commit is contained in:
Junio C Hamano 2022-09-19 14:35:25 -07:00
commit 42bf77c7d0
19 changed files with 264 additions and 207 deletions

1
.gitignore vendored
View file

@ -185,6 +185,7 @@
/git-whatchanged
/git-worktree
/git-write-tree
/scalar
/git-core-*/?*
/git.res
/gitweb/GITWEB-BUILD-OPTIONS

View file

@ -21,6 +21,7 @@ MAN1_TXT += $(filter-out \
MAN1_TXT += git.txt
MAN1_TXT += gitk.txt
MAN1_TXT += gitweb.txt
MAN1_TXT += scalar.txt
# man5 / man7 guides (note: new guides should also be added to command-list.txt)
MAN5_TXT += gitattributes.txt
@ -116,6 +117,7 @@ TECH_DOCS += technical/parallel-checkout
TECH_DOCS += technical/partial-clone
TECH_DOCS += technical/racy-git
TECH_DOCS += technical/reftable
TECH_DOCS += technical/scalar
TECH_DOCS += technical/send-pack-pipeline
TECH_DOCS += technical/shallow
TECH_DOCS += technical/trivial-merge

View file

@ -10,7 +10,7 @@ sub format_one {
$state = 0;
open I, '<', "$name.txt" or die "No such file $name.txt";
while (<I>) {
if (/^git[a-z0-9-]*\(([0-9])\)$/) {
if (/^(git|scalar)[a-z0-9-]*\(([0-9])\)$/) {
$mansection = $1;
next;
}

View file

@ -161,6 +161,6 @@ SEE ALSO
--------
linkgit:git-clone[1], linkgit:git-maintenance[1].
Scalar
GIT
---
Associated with the linkgit:git[1] suite
Part of the linkgit:git[1] suite

View file

@ -64,64 +64,3 @@ some "global" `git` options (e.g., `-c` and `-C`).
Because `scalar` is not invoked as a Git subcommand (like `git scalar`), it is
built and installed as its own executable in the `bin/` directory, alongside
`git`, `git-gui`, etc.
Roadmap
-------
NOTE: this section will be removed once the remaining tasks outlined in this
roadmap are complete.
Scalar is a large enough project that it is being upstreamed incrementally,
living in `contrib/` until it is feature-complete. So far, the following patch
series have been accepted:
- `scalar-the-beginning`: The initial patch series which sets up
`contrib/scalar/` and populates it with a minimal `scalar` command that
demonstrates the fundamental ideas.
- `scalar-c-and-C`: The `scalar` command learns about two options that can be
specified before the command, `-c <key>=<value>` and `-C <directory>`.
- `scalar-diagnose`: The `scalar` command is taught the `diagnose` subcommand.
- `scalar-generalize-diagnose`: Move the functionality of `scalar diagnose`
into `git diagnose` and `git bugreport --diagnose`.
- 'scalar-add-fsmonitor: Enable the built-in FSMonitor in Scalar
enlistments. At the end of this series, Scalar should be feature-complete
from the perspective of a user.
Roughly speaking (and subject to change), the following series are needed to
"finish" this initial version of Scalar:
- Move Scalar to toplevel: Move Scalar out of `contrib/` and into the root of
`git`. This includes a variety of related updates, including:
- building & installing Scalar in the Git root-level 'make [install]'.
- builing & testing Scalar as part of CI.
- moving and expanding test coverage of Scalar (including perf tests).
- implementing 'scalar help'/'git help scalar' to display scalar
documentation.
Finally, there are two additional patch series that exist in Microsoft's fork of
Git, but there is no current plan to upstream them. There are some interesting
ideas there, but the implementation is too specific to Azure Repos and/or VFS
for Git to be of much help in general.
These still exist mainly because the GVFS protocol is what Azure Repos has
instead of partial clone, while Git is focused on improving partial clone:
- `scalar-with-gvfs`: The primary purpose of this patch series is to support
existing Scalar users whose repositories are hosted in Azure Repos (which does
not support Git's partial clones, but supports its predecessor, the GVFS
protocol, which is used by Scalar to emulate the partial clone).
Since the GVFS protocol will never be supported by core Git, this patch series
will remain in Microsoft's fork of Git.
- `run-scalar-functional-tests`: The Scalar project developed a quite
comprehensive set of integration tests (or, "Functional Tests"). They are the
sole remaining part of the original C#-based Scalar project, and this patch
adds a GitHub workflow that runs them all.
Since the tests partially depend on features that are only provided in the
`scalar-with-gvfs` patch series, this patch cannot be upstreamed.

View file

@ -605,7 +605,9 @@ FUZZ_OBJS =
FUZZ_PROGRAMS =
GIT_OBJS =
LIB_OBJS =
SCALAR_OBJS =
OBJECTS =
OTHER_PROGRAMS =
PROGRAM_OBJS =
PROGRAMS =
EXCLUDED_PROGRAMS =
@ -819,10 +821,12 @@ BUILT_INS += git-switch$X
BUILT_INS += git-whatchanged$X
# what 'all' will build but not install in gitexecdir
OTHER_PROGRAMS = git$X
OTHER_PROGRAMS += git$X
OTHER_PROGRAMS += scalar$X
# what test wrappers are needed and 'install' will install, in bindir
BINDIR_PROGRAMS_NEED_X += git
BINDIR_PROGRAMS_NEED_X += scalar
BINDIR_PROGRAMS_NEED_X += git-receive-pack
BINDIR_PROGRAMS_NEED_X += git-shell
BINDIR_PROGRAMS_NEED_X += git-upload-archive
@ -2220,7 +2224,7 @@ profile-fast: profile-clean
all:: $(ALL_COMMANDS_TO_INSTALL) $(SCRIPT_LIB) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS
ifneq (,$X)
$(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_COMMANDS_TO_INSTALL) git$X)), test -d '$p' -o '$p' -ef '$p$X' || $(RM) '$p';)
$(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_COMMANDS_TO_INSTALL) $(OTHER_PROGRAMS))), test -d '$p' -o '$p' -ef '$p$X' || $(RM) '$p';)
endif
all::
@ -2543,7 +2547,12 @@ GIT_OBJS += git.o
.PHONY: git-objs
git-objs: $(GIT_OBJS)
SCALAR_OBJS += scalar.o
.PHONY: scalar-objs
scalar-objs: $(SCALAR_OBJS)
OBJECTS += $(GIT_OBJS)
OBJECTS += $(SCALAR_OBJS)
OBJECTS += $(PROGRAM_OBJS)
OBJECTS += $(TEST_OBJS)
OBJECTS += $(XDIFF_OBJS)
@ -2554,10 +2563,6 @@ ifndef NO_CURL
OBJECTS += http.o http-walker.o remote-curl.o
endif
SCALAR_SOURCES := contrib/scalar/scalar.c
SCALAR_OBJECTS := $(SCALAR_SOURCES:c=o)
OBJECTS += $(SCALAR_OBJECTS)
.PHONY: objects
objects: $(OBJECTS)
@ -2683,7 +2688,7 @@ $(REMOTE_CURL_PRIMARY): remote-curl.o http.o http-walker.o GIT-LDFLAGS $(GITLIBS
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(CURL_LIBCURL) $(EXPAT_LIBEXPAT) $(LIBS)
contrib/scalar/scalar$X: $(SCALAR_OBJECTS) GIT-LDFLAGS $(GITLIBS)
scalar$X: scalar.o GIT-LDFLAGS $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \
$(filter %.o,$^) $(LIBS)
@ -2739,8 +2744,7 @@ XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell \
XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \
--keyword=__ --keyword=N__ --keyword="__n:1,2"
MSGMERGE_FLAGS = --add-location --backup=off --update
LOCALIZED_C = $(sort $(FOUND_C_SOURCES) $(FOUND_H_SOURCES) $(SCALAR_SOURCES) \
$(GENERATED_H))
LOCALIZED_C = $(sort $(FOUND_C_SOURCES) $(FOUND_H_SOURCES) $(GENERATED_H))
LOCALIZED_SH = $(sort $(SCRIPT_SH) git-sh-setup.sh)
LOCALIZED_PERL = $(sort $(SCRIPT_PERL))
@ -3054,7 +3058,7 @@ bin-wrappers/%: wrap-for-bin.sh
$(call mkdir_p_parent_template)
$(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
-e 's|@@BUILD_DIR@@|$(shell pwd)|' \
-e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%$(X),$(@F))$(patsubst git%,$(X),$(filter $(@F),$(BINDIR_PROGRAMS_NEED_X)))|' < $< > $@ && \
-e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%,$(@F))$(if $(filter-out $(BINDIR_PROGRAMS_NO_X),$(@F)),$(X),)|' < $< > $@ && \
chmod +x $@
# GNU make supports exporting all variables by "export" without parameters.
@ -3268,14 +3272,14 @@ ifndef NO_TCLTK
$(MAKE) -C git-gui gitexecdir='$(gitexec_instdir_SQ)' install
endif
ifneq (,$X)
$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_COMMANDS_TO_INSTALL) git$X)), test '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p' -ef '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p$X' || $(RM) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p';)
$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_COMMANDS_TO_INSTALL) $(OTHER_PROGRAMS))), test '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p' -ef '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p$X' || $(RM) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p';)
endif
bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
destdir_from_execdir_SQ=$$(echo '$(gitexecdir_relative_SQ)' | sed -e 's|[^/][^/]*|..|g') && \
{ test "$$bindir/" = "$$execdir/" || \
for p in git$X $(filter $(install_bindir_programs),$(ALL_PROGRAMS)); do \
for p in $(OTHER_PROGRAMS) $(filter $(install_bindir_programs),$(ALL_PROGRAMS)); do \
$(RM) "$$execdir/$$p" && \
test -n "$(INSTALL_SYMLINKS)" && \
ln -s "$$destdir_from_execdir_SQ/$(bindir_relative_SQ)/$$p" "$$execdir/$$p" || \
@ -3450,7 +3454,7 @@ clean: profile-clean coverage-clean cocciclean
$(RM) git.res
$(RM) $(OBJECTS)
$(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(REFTABLE_TEST_LIB)
$(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git$X
$(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) $(OTHER_PROGRAMS)
$(RM) $(TEST_PROGRAMS)
$(RM) $(FUZZ_PROGRAMS)
$(RM) $(SP_OBJ)
@ -3501,6 +3505,7 @@ ALL_COMMANDS += git-citool
ALL_COMMANDS += git-gui
ALL_COMMANDS += gitk
ALL_COMMANDS += gitweb
ALL_COMMANDS += scalar
.PHONY: check-docs
check-docs::

View file

@ -440,6 +440,8 @@ static const char *cmd_to_page(const char *git_cmd)
return git_cmd;
else if (is_git_command(git_cmd))
return xstrfmt("git-%s", git_cmd);
else if (!strcmp("scalar", git_cmd))
return xstrdup(git_cmd);
else
return xstrfmt("git%s", git_cmd);
}

View file

@ -235,3 +235,4 @@ gittutorial guide
gittutorial-2 guide
gitweb ancillaryinterrogators
gitworkflows guide
scalar mainporcelain

View file

@ -610,7 +610,7 @@ unset(CMAKE_REQUIRED_INCLUDES)
#programs
set(PROGRAMS_BUILT
git git-daemon git-http-backend git-sh-i18n--envsubst
git-shell)
git-shell scalar)
if(NOT CURL_FOUND)
list(APPEND excluded_progs git-http-fetch git-http-push)
@ -757,6 +757,9 @@ target_link_libraries(git-sh-i18n--envsubst common-main)
add_executable(git-shell ${CMAKE_SOURCE_DIR}/shell.c)
target_link_libraries(git-shell common-main)
add_executable(scalar ${CMAKE_SOURCE_DIR}/scalar.c)
target_link_libraries(scalar common-main)
if(CURL_FOUND)
add_library(http_obj OBJECT ${CMAKE_SOURCE_DIR}/http.c)
@ -903,7 +906,7 @@ list(TRANSFORM git_perl_scripts PREPEND "${CMAKE_BINARY_DIR}/")
#install
foreach(program ${PROGRAMS_BUILT})
if(program STREQUAL "git" OR program STREQUAL "git-shell")
if(program MATCHES "^(git|git-shell|scalar)$")
install(TARGETS ${program}
RUNTIME DESTINATION bin)
else()
@ -977,7 +980,7 @@ endif()
#wrapper scripts
set(wrapper_scripts
git git-upload-pack git-receive-pack git-upload-archive git-shell git-remote-ext)
git git-upload-pack git-receive-pack git-upload-archive git-shell git-remote-ext scalar)
set(wrapper_test_scripts
test-fake-ssh test-tool)

View file

@ -1,2 +0,0 @@
/*.exe
/scalar

View file

@ -1,35 +0,0 @@
# The default target of this Makefile is...
all::
# Import tree-wide shared Makefile behavior and libraries
include ../../shared.mak
include ../../config.mak.uname
-include ../../config.mak.autogen
-include ../../config.mak
TARGETS = scalar$(X) scalar.o
GITLIBS = ../../common-main.o ../../libgit.a ../../xdiff/lib.a
all:: scalar$(X) ../../bin-wrappers/scalar
$(GITLIBS):
$(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) $(subst ../../,,$@)
$(TARGETS): $(GITLIBS) scalar.c
$(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) $(patsubst %,contrib/scalar/%,$@)
clean:
$(RM) $(TARGETS) ../../bin-wrappers/scalar
../../bin-wrappers/scalar: ../../wrap-for-bin.sh Makefile
@mkdir -p ../../bin-wrappers
$(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
-e 's|@@BUILD_DIR@@|$(shell cd ../.. && pwd)|' \
-e 's|@@PROG@@|contrib/scalar/scalar$(X)|' < $< > $@ && \
chmod +x $@
test: all
$(MAKE) -C t
.PHONY: $(GITLIBS) all clean test FORCE

View file

@ -1,81 +0,0 @@
# Import tree-wide shared Makefile behavior and libraries
include ../../../shared.mak
# Run scalar tests
#
# Copyright (c) 2005,2021 Junio C Hamano, Johannes Schindelin
#
-include ../../../config.mak.autogen
-include ../../../config.mak
SHELL_PATH ?= $(SHELL)
PERL_PATH ?= /usr/bin/perl
RM ?= rm -f
PROVE ?= prove
DEFAULT_TEST_TARGET ?= test
TEST_LINT ?= test-lint
ifdef TEST_OUTPUT_DIRECTORY
TEST_RESULTS_DIRECTORY = $(TEST_OUTPUT_DIRECTORY)/test-results
else
TEST_RESULTS_DIRECTORY = ../../../t/test-results
endif
# Shell quote;
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
TEST_RESULTS_DIRECTORY_SQ = $(subst ','\'',$(TEST_RESULTS_DIRECTORY))
T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))
all: $(DEFAULT_TEST_TARGET)
test: $(TEST_LINT)
$(MAKE) aggregate-results-and-cleanup
prove: $(TEST_LINT)
@echo "*** prove ***"; GIT_CONFIG=.git/config $(PROVE) --exec '$(SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)
$(MAKE) clean-except-prove-cache
$(T):
@echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)
clean-except-prove-cache:
$(RM) -r 'trash directory'.*
$(RM) -r valgrind/bin
clean: clean-except-prove-cache
$(RM) .prove
test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax
test-lint-duplicates:
@dups=`echo $(T) | tr ' ' '\n' | sed 's/-.*//' | sort | uniq -d` && \
test -z "$$dups" || { \
echo >&2 "duplicate test numbers:" $$dups; exit 1; }
test-lint-executable:
@bad=`for i in $(T); do test -x "$$i" || echo $$i; done` && \
test -z "$$bad" || { \
echo >&2 "non-executable tests:" $$bad; exit 1; }
test-lint-shell-syntax:
@'$(PERL_PATH_SQ)' ../../../t/check-non-portable-shell.pl $(T)
aggregate-results-and-cleanup: $(T)
$(MAKE) aggregate-results
$(MAKE) clean
aggregate-results:
for f in '$(TEST_RESULTS_DIRECTORY_SQ)'/t*-*.counts; do \
echo "$$f"; \
done | '$(SHELL_PATH_SQ)' ../../../t/aggregate-results.sh
valgrind:
$(MAKE) GIT_TEST_OPTS="$(GIT_TEST_OPTS) --valgrind"
test-results:
mkdir -p test-results
.PHONY: $(T) aggregate-results clean valgrind

View file

@ -819,6 +819,25 @@ static int cmd_delete(int argc, const char **argv)
return res;
}
static int cmd_help(int argc, const char **argv)
{
struct option options[] = {
OPT_END(),
};
const char * const usage[] = {
"scalar help",
NULL
};
argc = parse_options(argc, argv, NULL, options,
usage, 0);
if (argc != 0)
usage_with_options(usage, options);
return run_git("help", "scalar", NULL);
}
static int cmd_version(int argc, const char **argv)
{
int verbose = 0, build_options = 0;
@ -858,6 +877,7 @@ static struct {
{ "run", cmd_run },
{ "reconfigure", cmd_reconfigure },
{ "delete", cmd_delete },
{ "help", cmd_help },
{ "version", cmd_version },
{ "diagnose", cmd_diagnose },
{ NULL, NULL},

View file

@ -95,6 +95,10 @@ You can set the following variables (also in your config.mak):
Git (e.g., performance of index-pack as the number of threads
changes). These can be enabled with GIT_PERF_EXTRA.
GIT_PERF_USE_SCALAR
Boolean indicating whether to register test repo(s) with Scalar
before executing tests.
You can also pass the options taken by ordinary git tests; the most
useful one is:

39
t/perf/p9210-scalar.sh Executable file
View file

@ -0,0 +1,39 @@
#!/bin/sh
test_description='test scalar performance'
. ./perf-lib.sh
test_perf_large_repo "$TRASH_DIRECTORY/to-clone"
test_expect_success 'enable server-side partial clone' '
git -C to-clone config uploadpack.allowFilter true &&
git -C to-clone config uploadpack.allowAnySHA1InWant true
'
test_perf 'scalar clone' '
rm -rf scalar-clone &&
scalar clone "file://$(pwd)/to-clone" scalar-clone
'
test_perf 'git clone' '
rm -rf git-clone &&
git clone "file://$(pwd)/to-clone" git-clone
'
test_compare_perf () {
command=$1
shift
args=$*
test_perf "$command $args (scalar)" "
$command -C scalar-clone/src $args
"
test_perf "$command $args (non-scalar)" "
$command -C git-clone $args
"
}
test_compare_perf git status
test_compare_perf test_commit --append --no-tag A
test_done

View file

@ -49,6 +49,9 @@ export TEST_DIRECTORY TRASH_DIRECTORY GIT_BUILD_DIR GIT_TEST_CMP
MODERN_GIT=$GIT_BUILD_DIR/bin-wrappers/git
export MODERN_GIT
MODERN_SCALAR=$GIT_BUILD_DIR/bin-wrappers/scalar
export MODERN_SCALAR
perf_results_dir=$TEST_RESULTS_DIR
test -n "$GIT_PERF_SUBSECTION" && perf_results_dir="$perf_results_dir/$GIT_PERF_SUBSECTION"
mkdir -p "$perf_results_dir"
@ -120,6 +123,10 @@ test_perf_create_repo_from () {
# status" due to a locked index. Since we have
# a copy it's fine to remove the lock.
rm .git/index.lock
fi &&
if test_bool_env GIT_PERF_USE_SCALAR false
then
"$MODERN_SCALAR" register
fi
) || error "failed to copy repository '$source' to '$repo'"
}
@ -130,7 +137,11 @@ test_perf_fresh_repo () {
"$MODERN_GIT" init -q "$repo" &&
(
cd "$repo" &&
test_perf_do_repo_symlink_config_
test_perf_do_repo_symlink_config_ &&
if test_bool_env GIT_PERF_USE_SCALAR false
then
"$MODERN_SCALAR" register
fi
)
}

View file

@ -171,6 +171,9 @@ run_subsection () {
get_var_from_env_or_config "GIT_PERF_MAKE_COMMAND" "perf" "makeCommand"
get_var_from_env_or_config "GIT_PERF_MAKE_OPTS" "perf" "makeOpts"
get_var_from_env_or_config "GIT_PERF_USE_SCALAR" "perf" "useScalar" "--bool"
export GIT_PERF_USE_SCALAR
get_var_from_env_or_config "GIT_PERF_REPO_NAME" "perf" "repoName"
export GIT_PERF_REPO_NAME

View file

@ -2,15 +2,9 @@
test_description='test the `scalar` command'
TEST_DIRECTORY=$PWD/../../../t
export TEST_DIRECTORY
. ./test-lib.sh
# Make it work with --no-bin-wrappers
PATH=$PWD/..:$PATH
. ../../../t/test-lib.sh
GIT_TEST_MAINT_SCHEDULER="crontab:test-tool crontab ../cron.txt,launchctl:true,schtasks:true"
GIT_TEST_MAINT_SCHEDULER="crontab:test-tool crontab cron.txt,launchctl:true,schtasks:true"
export GIT_TEST_MAINT_SCHEDULER
test_expect_success 'scalar shows a usage' '

151
t/t9211-scalar-clone.sh Executable file
View file

@ -0,0 +1,151 @@
#!/bin/sh
test_description='test the `scalar clone` subcommand'
. ./test-lib.sh
GIT_TEST_MAINT_SCHEDULER="crontab:test-tool crontab cron.txt,launchctl:true,schtasks:true"
export GIT_TEST_MAINT_SCHEDULER
test_expect_success 'set up repository to clone' '
rm -rf .git &&
git init to-clone &&
(
cd to-clone &&
git branch -m base &&
test_commit first &&
test_commit second &&
test_commit third &&
git switch -c parallel first &&
mkdir -p 1/2 &&
test_commit 1/2/3 &&
git switch base &&
# By default, permit
git config uploadpack.allowfilter true &&
git config uploadpack.allowanysha1inwant true
)
'
cleanup_clone () {
rm -rf "$1"
}
test_expect_success 'creates content in enlistment root' '
enlistment=cloned &&
scalar clone "file://$(pwd)/to-clone" $enlistment &&
ls -A $enlistment >enlistment-root &&
test_line_count = 1 enlistment-root &&
test_path_is_dir $enlistment/src &&
test_path_is_dir $enlistment/src/.git &&
cleanup_clone $enlistment
'
test_expect_success 'with spaces' '
enlistment="cloned with space" &&
scalar clone "file://$(pwd)/to-clone" "$enlistment" &&
test_path_is_dir "$enlistment" &&
test_path_is_dir "$enlistment/src" &&
test_path_is_dir "$enlistment/src/.git" &&
cleanup_clone "$enlistment"
'
test_expect_success 'partial clone if supported by server' '
enlistment=partial-clone &&
scalar clone "file://$(pwd)/to-clone" $enlistment &&
(
cd $enlistment/src &&
# Two promisor packs: one for refs, the other for blobs
ls .git/objects/pack/pack-*.promisor >promisorlist &&
test_line_count = 2 promisorlist
) &&
cleanup_clone $enlistment
'
test_expect_success 'fall back on full clone if partial unsupported' '
enlistment=no-partial-support &&
test_config -C to-clone uploadpack.allowfilter false &&
test_config -C to-clone uploadpack.allowanysha1inwant false &&
scalar clone "file://$(pwd)/to-clone" $enlistment 2>err &&
grep "filtering not recognized by server, ignoring" err &&
(
cd $enlistment/src &&
# Still get a refs promisor file, but none for blobs
ls .git/objects/pack/pack-*.promisor >promisorlist &&
test_line_count = 1 promisorlist
) &&
cleanup_clone $enlistment
'
test_expect_success 'initializes sparse-checkout by default' '
enlistment=sparse &&
scalar clone "file://$(pwd)/to-clone" $enlistment &&
(
cd $enlistment/src &&
test_cmp_config true core.sparseCheckout &&
test_cmp_config true core.sparseCheckoutCone
) &&
cleanup_clone $enlistment
'
test_expect_success '--full-clone does not create sparse-checkout' '
enlistment=full-clone &&
scalar clone --full-clone "file://$(pwd)/to-clone" $enlistment &&
(
cd $enlistment/src &&
test_cmp_config "" --default "" core.sparseCheckout &&
test_cmp_config "" --default "" core.sparseCheckoutCone
) &&
cleanup_clone $enlistment
'
test_expect_success '--single-branch clones HEAD only' '
enlistment=single-branch &&
scalar clone --single-branch "file://$(pwd)/to-clone" $enlistment &&
(
cd $enlistment/src &&
git for-each-ref refs/remotes/origin >out &&
test_line_count = 1 out &&
grep "refs/remotes/origin/base" out
) &&
cleanup_clone $enlistment
'
test_expect_success '--no-single-branch clones all branches' '
enlistment=no-single-branch &&
scalar clone --no-single-branch "file://$(pwd)/to-clone" $enlistment &&
(
cd $enlistment/src &&
git for-each-ref refs/remotes/origin >out &&
test_line_count = 2 out &&
grep "refs/remotes/origin/base" out &&
grep "refs/remotes/origin/parallel" out
) &&
cleanup_clone $enlistment
'
test_done