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:
commit
42bf77c7d0
1
.gitignore
vendored
1
.gitignore
vendored
@ -185,6 +185,7 @@
|
|||||||
/git-whatchanged
|
/git-whatchanged
|
||||||
/git-worktree
|
/git-worktree
|
||||||
/git-write-tree
|
/git-write-tree
|
||||||
|
/scalar
|
||||||
/git-core-*/?*
|
/git-core-*/?*
|
||||||
/git.res
|
/git.res
|
||||||
/gitweb/GITWEB-BUILD-OPTIONS
|
/gitweb/GITWEB-BUILD-OPTIONS
|
||||||
|
@ -21,6 +21,7 @@ MAN1_TXT += $(filter-out \
|
|||||||
MAN1_TXT += git.txt
|
MAN1_TXT += git.txt
|
||||||
MAN1_TXT += gitk.txt
|
MAN1_TXT += gitk.txt
|
||||||
MAN1_TXT += gitweb.txt
|
MAN1_TXT += gitweb.txt
|
||||||
|
MAN1_TXT += scalar.txt
|
||||||
|
|
||||||
# man5 / man7 guides (note: new guides should also be added to command-list.txt)
|
# man5 / man7 guides (note: new guides should also be added to command-list.txt)
|
||||||
MAN5_TXT += gitattributes.txt
|
MAN5_TXT += gitattributes.txt
|
||||||
@ -116,6 +117,7 @@ TECH_DOCS += technical/parallel-checkout
|
|||||||
TECH_DOCS += technical/partial-clone
|
TECH_DOCS += technical/partial-clone
|
||||||
TECH_DOCS += technical/racy-git
|
TECH_DOCS += technical/racy-git
|
||||||
TECH_DOCS += technical/reftable
|
TECH_DOCS += technical/reftable
|
||||||
|
TECH_DOCS += technical/scalar
|
||||||
TECH_DOCS += technical/send-pack-pipeline
|
TECH_DOCS += technical/send-pack-pipeline
|
||||||
TECH_DOCS += technical/shallow
|
TECH_DOCS += technical/shallow
|
||||||
TECH_DOCS += technical/trivial-merge
|
TECH_DOCS += technical/trivial-merge
|
||||||
|
@ -10,7 +10,7 @@ sub format_one {
|
|||||||
$state = 0;
|
$state = 0;
|
||||||
open I, '<', "$name.txt" or die "No such file $name.txt";
|
open I, '<', "$name.txt" or die "No such file $name.txt";
|
||||||
while (<I>) {
|
while (<I>) {
|
||||||
if (/^git[a-z0-9-]*\(([0-9])\)$/) {
|
if (/^(git|scalar)[a-z0-9-]*\(([0-9])\)$/) {
|
||||||
$mansection = $1;
|
$mansection = $1;
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
@ -161,6 +161,6 @@ SEE ALSO
|
|||||||
--------
|
--------
|
||||||
linkgit:git-clone[1], linkgit:git-maintenance[1].
|
linkgit:git-clone[1], linkgit:git-maintenance[1].
|
||||||
|
|
||||||
Scalar
|
GIT
|
||||||
---
|
---
|
||||||
Associated with the linkgit:git[1] suite
|
Part of the linkgit:git[1] suite
|
@ -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
|
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
|
built and installed as its own executable in the `bin/` directory, alongside
|
||||||
`git`, `git-gui`, etc.
|
`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.
|
|
||||||
|
31
Makefile
31
Makefile
@ -605,7 +605,9 @@ FUZZ_OBJS =
|
|||||||
FUZZ_PROGRAMS =
|
FUZZ_PROGRAMS =
|
||||||
GIT_OBJS =
|
GIT_OBJS =
|
||||||
LIB_OBJS =
|
LIB_OBJS =
|
||||||
|
SCALAR_OBJS =
|
||||||
OBJECTS =
|
OBJECTS =
|
||||||
|
OTHER_PROGRAMS =
|
||||||
PROGRAM_OBJS =
|
PROGRAM_OBJS =
|
||||||
PROGRAMS =
|
PROGRAMS =
|
||||||
EXCLUDED_PROGRAMS =
|
EXCLUDED_PROGRAMS =
|
||||||
@ -819,10 +821,12 @@ BUILT_INS += git-switch$X
|
|||||||
BUILT_INS += git-whatchanged$X
|
BUILT_INS += git-whatchanged$X
|
||||||
|
|
||||||
# what 'all' will build but not install in gitexecdir
|
# 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
|
# what test wrappers are needed and 'install' will install, in bindir
|
||||||
BINDIR_PROGRAMS_NEED_X += git
|
BINDIR_PROGRAMS_NEED_X += git
|
||||||
|
BINDIR_PROGRAMS_NEED_X += scalar
|
||||||
BINDIR_PROGRAMS_NEED_X += git-receive-pack
|
BINDIR_PROGRAMS_NEED_X += git-receive-pack
|
||||||
BINDIR_PROGRAMS_NEED_X += git-shell
|
BINDIR_PROGRAMS_NEED_X += git-shell
|
||||||
BINDIR_PROGRAMS_NEED_X += git-upload-archive
|
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
|
all:: $(ALL_COMMANDS_TO_INSTALL) $(SCRIPT_LIB) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS
|
||||||
ifneq (,$X)
|
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
|
endif
|
||||||
|
|
||||||
all::
|
all::
|
||||||
@ -2543,7 +2547,12 @@ GIT_OBJS += git.o
|
|||||||
.PHONY: git-objs
|
.PHONY: git-objs
|
||||||
git-objs: $(GIT_OBJS)
|
git-objs: $(GIT_OBJS)
|
||||||
|
|
||||||
|
SCALAR_OBJS += scalar.o
|
||||||
|
.PHONY: scalar-objs
|
||||||
|
scalar-objs: $(SCALAR_OBJS)
|
||||||
|
|
||||||
OBJECTS += $(GIT_OBJS)
|
OBJECTS += $(GIT_OBJS)
|
||||||
|
OBJECTS += $(SCALAR_OBJS)
|
||||||
OBJECTS += $(PROGRAM_OBJS)
|
OBJECTS += $(PROGRAM_OBJS)
|
||||||
OBJECTS += $(TEST_OBJS)
|
OBJECTS += $(TEST_OBJS)
|
||||||
OBJECTS += $(XDIFF_OBJS)
|
OBJECTS += $(XDIFF_OBJS)
|
||||||
@ -2554,10 +2563,6 @@ ifndef NO_CURL
|
|||||||
OBJECTS += http.o http-walker.o remote-curl.o
|
OBJECTS += http.o http-walker.o remote-curl.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SCALAR_SOURCES := contrib/scalar/scalar.c
|
|
||||||
SCALAR_OBJECTS := $(SCALAR_SOURCES:c=o)
|
|
||||||
OBJECTS += $(SCALAR_OBJECTS)
|
|
||||||
|
|
||||||
.PHONY: objects
|
.PHONY: objects
|
||||||
objects: $(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,$^) \
|
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
|
||||||
$(CURL_LIBCURL) $(EXPAT_LIBEXPAT) $(LIBS)
|
$(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) \
|
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \
|
||||||
$(filter %.o,$^) $(LIBS)
|
$(filter %.o,$^) $(LIBS)
|
||||||
|
|
||||||
@ -2739,8 +2744,7 @@ XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell \
|
|||||||
XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \
|
XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \
|
||||||
--keyword=__ --keyword=N__ --keyword="__n:1,2"
|
--keyword=__ --keyword=N__ --keyword="__n:1,2"
|
||||||
MSGMERGE_FLAGS = --add-location --backup=off --update
|
MSGMERGE_FLAGS = --add-location --backup=off --update
|
||||||
LOCALIZED_C = $(sort $(FOUND_C_SOURCES) $(FOUND_H_SOURCES) $(SCALAR_SOURCES) \
|
LOCALIZED_C = $(sort $(FOUND_C_SOURCES) $(FOUND_H_SOURCES) $(GENERATED_H))
|
||||||
$(GENERATED_H))
|
|
||||||
LOCALIZED_SH = $(sort $(SCRIPT_SH) git-sh-setup.sh)
|
LOCALIZED_SH = $(sort $(SCRIPT_SH) git-sh-setup.sh)
|
||||||
LOCALIZED_PERL = $(sort $(SCRIPT_PERL))
|
LOCALIZED_PERL = $(sort $(SCRIPT_PERL))
|
||||||
|
|
||||||
@ -3054,7 +3058,7 @@ bin-wrappers/%: wrap-for-bin.sh
|
|||||||
$(call mkdir_p_parent_template)
|
$(call mkdir_p_parent_template)
|
||||||
$(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
|
$(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
|
||||||
-e 's|@@BUILD_DIR@@|$(shell pwd)|' \
|
-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 $@
|
chmod +x $@
|
||||||
|
|
||||||
# GNU make supports exporting all variables by "export" without parameters.
|
# 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
|
$(MAKE) -C git-gui gitexecdir='$(gitexec_instdir_SQ)' install
|
||||||
endif
|
endif
|
||||||
ifneq (,$X)
|
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
|
endif
|
||||||
|
|
||||||
bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
|
bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
|
||||||
execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
|
execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
|
||||||
destdir_from_execdir_SQ=$$(echo '$(gitexecdir_relative_SQ)' | sed -e 's|[^/][^/]*|..|g') && \
|
destdir_from_execdir_SQ=$$(echo '$(gitexecdir_relative_SQ)' | sed -e 's|[^/][^/]*|..|g') && \
|
||||||
{ test "$$bindir/" = "$$execdir/" || \
|
{ 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" && \
|
$(RM) "$$execdir/$$p" && \
|
||||||
test -n "$(INSTALL_SYMLINKS)" && \
|
test -n "$(INSTALL_SYMLINKS)" && \
|
||||||
ln -s "$$destdir_from_execdir_SQ/$(bindir_relative_SQ)/$$p" "$$execdir/$$p" || \
|
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) git.res
|
||||||
$(RM) $(OBJECTS)
|
$(RM) $(OBJECTS)
|
||||||
$(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(REFTABLE_TEST_LIB)
|
$(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) $(TEST_PROGRAMS)
|
||||||
$(RM) $(FUZZ_PROGRAMS)
|
$(RM) $(FUZZ_PROGRAMS)
|
||||||
$(RM) $(SP_OBJ)
|
$(RM) $(SP_OBJ)
|
||||||
@ -3501,6 +3505,7 @@ ALL_COMMANDS += git-citool
|
|||||||
ALL_COMMANDS += git-gui
|
ALL_COMMANDS += git-gui
|
||||||
ALL_COMMANDS += gitk
|
ALL_COMMANDS += gitk
|
||||||
ALL_COMMANDS += gitweb
|
ALL_COMMANDS += gitweb
|
||||||
|
ALL_COMMANDS += scalar
|
||||||
|
|
||||||
.PHONY: check-docs
|
.PHONY: check-docs
|
||||||
check-docs::
|
check-docs::
|
||||||
|
@ -440,6 +440,8 @@ static const char *cmd_to_page(const char *git_cmd)
|
|||||||
return git_cmd;
|
return git_cmd;
|
||||||
else if (is_git_command(git_cmd))
|
else if (is_git_command(git_cmd))
|
||||||
return xstrfmt("git-%s", git_cmd);
|
return xstrfmt("git-%s", git_cmd);
|
||||||
|
else if (!strcmp("scalar", git_cmd))
|
||||||
|
return xstrdup(git_cmd);
|
||||||
else
|
else
|
||||||
return xstrfmt("git%s", git_cmd);
|
return xstrfmt("git%s", git_cmd);
|
||||||
}
|
}
|
||||||
|
@ -235,3 +235,4 @@ gittutorial guide
|
|||||||
gittutorial-2 guide
|
gittutorial-2 guide
|
||||||
gitweb ancillaryinterrogators
|
gitweb ancillaryinterrogators
|
||||||
gitworkflows guide
|
gitworkflows guide
|
||||||
|
scalar mainporcelain
|
||||||
|
@ -610,7 +610,7 @@ unset(CMAKE_REQUIRED_INCLUDES)
|
|||||||
#programs
|
#programs
|
||||||
set(PROGRAMS_BUILT
|
set(PROGRAMS_BUILT
|
||||||
git git-daemon git-http-backend git-sh-i18n--envsubst
|
git git-daemon git-http-backend git-sh-i18n--envsubst
|
||||||
git-shell)
|
git-shell scalar)
|
||||||
|
|
||||||
if(NOT CURL_FOUND)
|
if(NOT CURL_FOUND)
|
||||||
list(APPEND excluded_progs git-http-fetch git-http-push)
|
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)
|
add_executable(git-shell ${CMAKE_SOURCE_DIR}/shell.c)
|
||||||
target_link_libraries(git-shell common-main)
|
target_link_libraries(git-shell common-main)
|
||||||
|
|
||||||
|
add_executable(scalar ${CMAKE_SOURCE_DIR}/scalar.c)
|
||||||
|
target_link_libraries(scalar common-main)
|
||||||
|
|
||||||
if(CURL_FOUND)
|
if(CURL_FOUND)
|
||||||
add_library(http_obj OBJECT ${CMAKE_SOURCE_DIR}/http.c)
|
add_library(http_obj OBJECT ${CMAKE_SOURCE_DIR}/http.c)
|
||||||
|
|
||||||
@ -903,7 +906,7 @@ list(TRANSFORM git_perl_scripts PREPEND "${CMAKE_BINARY_DIR}/")
|
|||||||
|
|
||||||
#install
|
#install
|
||||||
foreach(program ${PROGRAMS_BUILT})
|
foreach(program ${PROGRAMS_BUILT})
|
||||||
if(program STREQUAL "git" OR program STREQUAL "git-shell")
|
if(program MATCHES "^(git|git-shell|scalar)$")
|
||||||
install(TARGETS ${program}
|
install(TARGETS ${program}
|
||||||
RUNTIME DESTINATION bin)
|
RUNTIME DESTINATION bin)
|
||||||
else()
|
else()
|
||||||
@ -977,7 +980,7 @@ endif()
|
|||||||
|
|
||||||
#wrapper scripts
|
#wrapper scripts
|
||||||
set(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
|
set(wrapper_test_scripts
|
||||||
test-fake-ssh test-tool)
|
test-fake-ssh test-tool)
|
||||||
|
2
contrib/scalar/.gitignore
vendored
2
contrib/scalar/.gitignore
vendored
@ -1,2 +0,0 @@
|
|||||||
/*.exe
|
|
||||||
/scalar
|
|
@ -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
|
|
@ -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
|
|
@ -819,6 +819,25 @@ static int cmd_delete(int argc, const char **argv)
|
|||||||
return res;
|
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)
|
static int cmd_version(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
int verbose = 0, build_options = 0;
|
int verbose = 0, build_options = 0;
|
||||||
@ -858,6 +877,7 @@ static struct {
|
|||||||
{ "run", cmd_run },
|
{ "run", cmd_run },
|
||||||
{ "reconfigure", cmd_reconfigure },
|
{ "reconfigure", cmd_reconfigure },
|
||||||
{ "delete", cmd_delete },
|
{ "delete", cmd_delete },
|
||||||
|
{ "help", cmd_help },
|
||||||
{ "version", cmd_version },
|
{ "version", cmd_version },
|
||||||
{ "diagnose", cmd_diagnose },
|
{ "diagnose", cmd_diagnose },
|
||||||
{ NULL, NULL},
|
{ NULL, NULL},
|
@ -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
|
Git (e.g., performance of index-pack as the number of threads
|
||||||
changes). These can be enabled with GIT_PERF_EXTRA.
|
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
|
You can also pass the options taken by ordinary git tests; the most
|
||||||
useful one is:
|
useful one is:
|
||||||
|
|
||||||
|
39
t/perf/p9210-scalar.sh
Executable file
39
t/perf/p9210-scalar.sh
Executable 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
|
@ -49,6 +49,9 @@ export TEST_DIRECTORY TRASH_DIRECTORY GIT_BUILD_DIR GIT_TEST_CMP
|
|||||||
MODERN_GIT=$GIT_BUILD_DIR/bin-wrappers/git
|
MODERN_GIT=$GIT_BUILD_DIR/bin-wrappers/git
|
||||||
export MODERN_GIT
|
export MODERN_GIT
|
||||||
|
|
||||||
|
MODERN_SCALAR=$GIT_BUILD_DIR/bin-wrappers/scalar
|
||||||
|
export MODERN_SCALAR
|
||||||
|
|
||||||
perf_results_dir=$TEST_RESULTS_DIR
|
perf_results_dir=$TEST_RESULTS_DIR
|
||||||
test -n "$GIT_PERF_SUBSECTION" && perf_results_dir="$perf_results_dir/$GIT_PERF_SUBSECTION"
|
test -n "$GIT_PERF_SUBSECTION" && perf_results_dir="$perf_results_dir/$GIT_PERF_SUBSECTION"
|
||||||
mkdir -p "$perf_results_dir"
|
mkdir -p "$perf_results_dir"
|
||||||
@ -120,6 +123,10 @@ test_perf_create_repo_from () {
|
|||||||
# status" due to a locked index. Since we have
|
# status" due to a locked index. Since we have
|
||||||
# a copy it's fine to remove the lock.
|
# a copy it's fine to remove the lock.
|
||||||
rm .git/index.lock
|
rm .git/index.lock
|
||||||
|
fi &&
|
||||||
|
if test_bool_env GIT_PERF_USE_SCALAR false
|
||||||
|
then
|
||||||
|
"$MODERN_SCALAR" register
|
||||||
fi
|
fi
|
||||||
) || error "failed to copy repository '$source' to '$repo'"
|
) || error "failed to copy repository '$source' to '$repo'"
|
||||||
}
|
}
|
||||||
@ -130,7 +137,11 @@ test_perf_fresh_repo () {
|
|||||||
"$MODERN_GIT" init -q "$repo" &&
|
"$MODERN_GIT" init -q "$repo" &&
|
||||||
(
|
(
|
||||||
cd "$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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_COMMAND" "perf" "makeCommand"
|
||||||
get_var_from_env_or_config "GIT_PERF_MAKE_OPTS" "perf" "makeOpts"
|
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"
|
get_var_from_env_or_config "GIT_PERF_REPO_NAME" "perf" "repoName"
|
||||||
export GIT_PERF_REPO_NAME
|
export GIT_PERF_REPO_NAME
|
||||||
|
|
||||||
|
@ -2,15 +2,9 @@
|
|||||||
|
|
||||||
test_description='test the `scalar` command'
|
test_description='test the `scalar` command'
|
||||||
|
|
||||||
TEST_DIRECTORY=$PWD/../../../t
|
. ./test-lib.sh
|
||||||
export TEST_DIRECTORY
|
|
||||||
|
|
||||||
# Make it work with --no-bin-wrappers
|
GIT_TEST_MAINT_SCHEDULER="crontab:test-tool crontab cron.txt,launchctl:true,schtasks:true"
|
||||||
PATH=$PWD/..:$PATH
|
|
||||||
|
|
||||||
. ../../../t/test-lib.sh
|
|
||||||
|
|
||||||
GIT_TEST_MAINT_SCHEDULER="crontab:test-tool crontab ../cron.txt,launchctl:true,schtasks:true"
|
|
||||||
export GIT_TEST_MAINT_SCHEDULER
|
export GIT_TEST_MAINT_SCHEDULER
|
||||||
|
|
||||||
test_expect_success 'scalar shows a usage' '
|
test_expect_success 'scalar shows a usage' '
|
151
t/t9211-scalar-clone.sh
Executable file
151
t/t9211-scalar-clone.sh
Executable 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
|
Loading…
Reference in New Issue
Block a user