Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate Scalar (ported to C) into vfs-2.32.0 #366

Merged
merged 68 commits into from
Jun 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
62ad225
maintenance: create `launchctl` configuration using a lock file
dscho May 21, 2021
b0d6bb0
maintenance: skip bootout/bootstrap when plist is registered
derrickstolee May 21, 2021
3bcddb1
Implement `scalar diagnose`
dscho Apr 16, 2021
8a9e4a3
scalar register: set recommended config settings
derrickstolee Apr 12, 2021
e7477ac
scalar: implement the `clone` subcommand
dscho Apr 12, 2021
c2306db
scalar diagnose: include disk space information
dscho Apr 22, 2021
f92504f
scalar register/unregister: start/stop maintenance on repository
derrickstolee Apr 12, 2021
0edd647
scalar: test `scalar clone`
dscho Apr 14, 2021
7741495
scalar: allow reconfiguring an existing enlistment
dscho May 27, 2021
1241cb4
scalar: teach `diagnose` to gather packfile info
mjcheetham May 19, 2021
c5c35ed
Start porting `scalar.exe` to C
dscho Apr 10, 2021
d8e544d
scalar: implement 'scalar list'
derrickstolee Apr 12, 2021
d71a56e
scalar clone: suppress warning about `init.defaultBranch`
dscho Apr 14, 2021
ab55d0b
scalar reconfigure: optionally handle all registered enlistments
dscho May 27, 2021
c21a90d
scalar: teach `diagnose` to gather loose objs info
mjcheetham May 19, 2021
341fa3d
scalar: add a test script
dscho Apr 14, 2021
2babaf1
scalar unregister: handle deleted enlistment directory gracefully
dscho May 14, 2021
ab69d1c
scalar clone: respect --single-branch
dscho Apr 16, 2021
778b629
scalar: implement the `run` command
derrickstolee Apr 14, 2021
36f29e7
scalar: support the `config` command for backwards compatibility
dscho May 27, 2021
7b2e9bc
scalar diagnose: show a spinner while staging content
dscho Apr 28, 2021
8ea46dc
scalar: start documenting the command
dscho May 3, 2021
1db27f0
scalar: document the `clone` subcommand
dscho Apr 27, 2021
397fd90
git help: special-case `scalar`
dscho May 4, 2021
ca842cc
scalar: enable built-in FSMonitor on `register`
mjcheetham May 19, 2021
bd3f8db
scalar: document `list`, `register` and `unregister`
dscho Apr 27, 2021
6333d1a
git_config_set_multivar_in_file_gently(): add a lock timeout
dscho May 18, 2021
74a7916
scalar: implement the `help` subcommand
dscho May 18, 2021
a138542
NOT-TO-UPSTREAM: ci: build `scalar.exe`, too
dscho Apr 14, 2021
e564a25
scalar: implement a minimal JSON parser
dscho Apr 26, 2021
4a6af34
scalar: implement the `delete` command
mjcheetham May 12, 2021
04dc1c2
scalar: implement the `version` command
dscho May 10, 2021
436b5b3
scalar: accept -C and -c options before the subcommand
dscho Apr 29, 2021
ac40574
scalar unregister: stop FSMonitor daemon
dscho Apr 22, 2021
466e62a
scalar: document the remaining subcommands
dscho May 3, 2021
e002d4f
scalar: set the config write-lock timeout to 150ms
dscho May 18, 2021
c1d1d7b
Optionally include `scalar` when building/testing Git
dscho May 4, 2021
4bc32bc
ci(windows): also run `scalar` tests
dscho Apr 14, 2021
6791e65
scalar clone: support GVFS-enabled remote repositories
dscho Apr 16, 2021
e19274c
test-gvfs-protocol: also serve smart protocol
dscho Apr 16, 2021
fe67f85
gvfs-helper: add the `endpoint` command
dscho Apr 26, 2021
16f782d
dir_inside_of(): handle directory separators correctly
dscho May 14, 2021
5446f83
scalar: disable authentication in unattended mode
dscho May 6, 2021
b654d0a
scalar: do initialize `gvfs.sharedCache`
dscho May 3, 2021
054bb04
scalar diagnose: include shared cache info
dscho Jun 1, 2021
53e1800
scalar: only try GVFS protocol on https:// URLs
dscho Apr 28, 2021
1c60e62
scalar: verify that we can use a GVFS-enabled repository
dscho Apr 16, 2021
4d7e399
scalar: add the `cache-server` command
dscho Apr 23, 2021
80f416d
scalar: add a test toggle to skip accessing the vsts/info endpoint
dscho May 12, 2021
6a12c58
Merge pull request #358: maintenance: skip bootout/bootstrap when pli…
derrickstolee May 21, 2021
4262e70
Merge branch 'barebones-scalar'
dscho May 3, 2021
5dab8f4
Merge branch 'scalar-register-unregister-list'
dscho May 3, 2021
e8ea5b2
Merge branch 'scalar-clone'
dscho May 3, 2021
93e114a
Merge branch 'scalar-run'
dscho May 3, 2021
836243f
Merge branch 'scalar-reconfigure'
dscho Jun 1, 2021
50d4255
Merge branch 'scalar-diagnose'
dscho May 3, 2021
716389c
Merge branch 'scalar-delete'
dscho May 19, 2021
a33bfc3
Merge branch 'scalar-version'
dscho May 21, 2021
ceff7a3
Merge branch 'scalar-c-and-C'
dscho May 3, 2021
2636cdf
Merge branch 'scalar-and-builtin-fsmonitor'
dscho May 3, 2021
e4b71c8
Merge branch 'scalar-docs'
dscho May 3, 2021
e5cc0f9
Merge branch 'scalar-gentler-config-locking'
dscho May 19, 2021
af8add0
Merge branch 'include-scalar-in-build'
dscho May 4, 2021
85aa097
Merge branch 'scalar-ci'
dscho May 3, 2021
c7ce1a9
Merge branch 'scalar-with-gvfs'
dscho May 3, 2021
5f9e8da
fixup! ci: run Scalar's Functional Tests
dscho Jun 9, 2021
244d94a
fixup! ci: run Scalar's Functional Tests
dscho Jun 9, 2021
00377dc
fixup! ci: run Scalar's Functional Tests
dscho Jun 9, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on: [push, pull_request]

env:
DEVELOPER: 1
INCLUDE_SCALAR: YesPlease

jobs:
ci-config:
Expand Down
27 changes: 16 additions & 11 deletions .github/workflows/scalar-functional-tests.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
name: Scalar Functional Tests

env:
SCALAR_REPOSITORY: dscho/scalar
SCALAR_REF: vfs-2.32.0
SCALAR_REPOSITORY: derrickstolee/scalar
SCALAR_REF: test-scalar-in-c
dscho marked this conversation as resolved.
Show resolved Hide resolved
DEBUG_WITH_TMATE: false
SCALAR_TEST_SKIP_VSTS_INFO: true
dscho marked this conversation as resolved.
Show resolved Hide resolved

on:
push:
Expand All @@ -20,7 +21,10 @@ jobs:
matrix:
# Order by runtime (in descending order)
os: [windows-2019, macos-10.15, ubuntu-16.04, ubuntu-18.04, ubuntu-20.04]
features: [false, experimental]
# Scalar.NET used to be tested using `features: [false, experimental]`
# But currently, Scalar/C ignores `feature.scalar` altogether, so let's
# save some electrons and run only one of them...
features: [ignored]
exclude:
# The built-in FSMonitor is not (yet) supported on Linux
- os: ubuntu-16.04
Expand Down Expand Up @@ -102,15 +106,17 @@ jobs:
;;
esac

$SUDO make -j5 $extra install
$SUDO make -j5 INCLUDE_SCALAR=AbsolutelyYes $extra install

- name: Ensure that we use the built Git (Windows)
if: runner.os == 'Windows'
shell: powershell
- name: Ensure that we use the built Git and Scalar
shell: bash
run: |
cmd /c where git
type -p git
git version
if ((git version) -like "*.vfs.*") { echo Good } else { exit 1 }
case "$(git version)" in *.vfs.*) echo Good;; *) exit 1;; esac
type -p scalar
scalar version
case "$(scalar version 2>&1)" in *.vfs.*) echo Good;; *) exit 1;; esac

- name: Check out Scalar's source code
uses: actions/checkout@v2
Expand Down Expand Up @@ -172,11 +178,10 @@ jobs:
mkdir -p "$TRACE2_BASENAME/Perf"
git version --build-options
cd ../out
PATH="$PWD/Scalar/$BUILD_FRAGMENT:$PWD/Scalar.Service/$BUILD_FRAGMENT:$PATH"
Scalar.FunctionalTests/$BUILD_FRAGMENT/Scalar.FunctionalTests$BUILD_FILE_EXT --test-scalar-on-path --test-git-on-path --timeout=300000 --full-suite

- name: Force-stop FSMonitor daemons and Git processes (Windows)
if: runner.os == 'Windows' && matrix.features == 'experimental' && (success() || failure())
if: runner.os == 'Windows' && (success() || failure())
shell: bash
run: |
set -x
Expand Down
9 changes: 9 additions & 0 deletions Documentation/config/core.txt
Original file line number Diff line number Diff line change
Expand Up @@ -726,3 +726,12 @@ core.abbrev::
If set to "no", no abbreviation is made and the object names
are shown in their full length.
The minimum length is 4.

core.configWriteLockTimeoutMS::
When processes try to write to the config concurrently, it is likely
that one process "wins" and the other process(es) fail to lock the
config file. By configuring a timeout larger than zero, Git can be
told to try to lock the config again a couple times within the
specified timeout. If the timeout is configure to zero (which is the
default), Git will fail immediately when the config is already
locked.
45 changes: 45 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1966,6 +1966,10 @@ ifndef PAGER_ENV
PAGER_ENV = LESS=FRX LV=-c
endif

ifneq (,$(INCLUDE_SCALAR))
EXTRA_PROGRAMS += contrib/scalar/scalar$X
endif

QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir
QUIET_SUBDIR1 =

Expand Down Expand Up @@ -2471,6 +2475,10 @@ endif
.PHONY: objects
objects: $(OBJECTS)

SCALAR_SOURCES := contrib/scalar/scalar.c contrib/scalar/json-parser.c
SCALAR_OBJECTS := $(SCALAR_SOURCES:c=o)
OBJECTS += $(SCALAR_OBJECTS)

dep_files := $(foreach f,$(OBJECTS),$(dir $f).depend/$(notdir $f).d)
dep_dirs := $(addsuffix .depend,$(sort $(dir $(OBJECTS))))

Expand Down Expand Up @@ -2617,6 +2625,13 @@ $(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)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \
$(filter %.o,$^) $(LIBS)

bin-wrappers/scalar: contrib/scalar/Makefile
$(QUIET_SUBDIR0)contrib/scalar $(QUIET_SUBDIR1) ../../bin-wrappers/scalar

git-gvfs-helper$X: gvfs-helper.o http.o GIT-LDFLAGS $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(CURL_LIBCURL) $(EXPAT_LIBEXPAT) $(LIBS)
Expand All @@ -2640,14 +2655,23 @@ Documentation/GIT-EXCLUDED-PROGRAMS: FORCE
.PHONY: doc man man-perl html info pdf
doc: man-perl
$(MAKE) -C Documentation all
ifneq (,$(INCLUDE_SCALAR))
$(QUIET_SUBDIR0)contrib/scalar $(QUIET_SUBDIR1) scalar.html scalar.1
endif

man: man-perl
$(MAKE) -C Documentation man
ifneq (,$(INCLUDE_SCALAR))
$(QUIET_SUBDIR0)contrib/scalar $(QUIET_SUBDIR1) scalar.1
endif

man-perl: perl/build/man/man3/Git.3pm

html:
$(MAKE) -C Documentation html
ifneq (,$(INCLUDE_SCALAR))
$(QUIET_SUBDIR0)contrib/scalar $(QUIET_SUBDIR1) scalar.html
endif

info:
$(MAKE) -C Documentation info
Expand Down Expand Up @@ -2886,6 +2910,10 @@ endif

test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(BINDIR_PROGRAMS_NO_X) $(TEST_PROGRAMS_NEED_X))

ifneq (,$(INCLUDE_SCALAR))
test_bindir_programs += bin-wrappers/scalar
endif

all:: $(TEST_PROGRAMS) $(test_bindir_programs)

bin-wrappers/%: wrap-for-bin.sh
Expand All @@ -2906,6 +2934,9 @@ export TEST_NO_MALLOC_CHECK

test: all
$(MAKE) -C t/ all
ifneq (,$(INCLUDE_SCALAR))
$(MAKE) -C contrib/scalar/t
endif

perf: all
$(MAKE) -C t/perf/ all
Expand Down Expand Up @@ -3031,6 +3062,9 @@ install: all
$(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) -m 644 $(SCRIPT_LIB) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) $(install_bindir_programs) '$(DESTDIR_SQ)$(bindir_SQ)'
ifneq (,$(INCLUDE_SCALAR))
$(INSTALL) contrib/scalar/scalar$X '$(DESTDIR_SQ)$(bindir_SQ)'
endif
ifdef MSVC
# We DO NOT install the individual foo.o.pdb files because they
# have already been rolled up into the exe's pdb file.
Expand Down Expand Up @@ -3124,6 +3158,10 @@ install-doc: install-man-perl

install-man: install-man-perl
$(MAKE) -C Documentation install-man
ifneq (,$(INCLUDE_SCALAR))
$(MAKE) -C contrib/scalar scalar.1
$(INSTALL) contrib/scalar/scalar.1 '$(DESTDIR_SQ)$(mandir_SQ)/man1'
endif

install-man-perl: man-perl
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(mandir_SQ)/man3'
Expand All @@ -3132,6 +3170,10 @@ install-man-perl: man-perl

install-html:
$(MAKE) -C Documentation install-html
ifneq (,$(INCLUDE_SCALAR))
$(MAKE) -C contrib/scalar scalar.html
$(INSTALL) contrib/scalar/scalar.html '$(DESTDIR_SQ)$(htmldir)'
endif

install-info:
$(MAKE) -C Documentation install-info
Expand Down Expand Up @@ -3269,6 +3311,9 @@ endif
ifndef NO_TCLTK
$(MAKE) -C gitk-git clean
$(MAKE) -C git-gui clean
endif
ifneq (,$(INCLUDE_SCALAR))
$(MAKE) -C contrib/scalar clean
endif
$(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-LDFLAGS GIT-BUILD-OPTIONS
$(RM) GIT-USER-AGENT GIT-PREFIX
Expand Down
91 changes: 70 additions & 21 deletions builtin/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1619,18 +1619,40 @@ static int launchctl_remove_plists(const char *cmd)
launchctl_remove_plist(SCHEDULE_WEEKLY, cmd);
}

static int launchctl_list_contains_plist(const char *name, const char *cmd)
{
int result;
struct child_process child = CHILD_PROCESS_INIT;
char *uid = launchctl_get_uid();

strvec_split(&child.args, cmd);
strvec_pushl(&child.args, "list", name, NULL);

child.no_stderr = 1;
child.no_stdout = 1;

if (start_command(&child))
die(_("failed to start launchctl"));

result = finish_command(&child);

free(uid);

/* Returns failure if 'name' doesn't exist. */
return !result;
}

static int launchctl_schedule_plist(const char *exec_path, enum schedule_priority schedule, const char *cmd)
{
FILE *plist;
int i;
int i, fd;
const char *preamble, *repeat;
const char *frequency = get_frequency(schedule);
char *name = launchctl_service_name(frequency);
char *filename = launchctl_service_filename(name);

if (safe_create_leading_directories(filename))
die(_("failed to create directories for '%s'"), filename);
plist = xfopen(filename, "w");
struct lock_file lk = LOCK_INIT;
static unsigned long lock_file_timeout_ms = ULONG_MAX;
struct strbuf plist = STRBUF_INIT, plist2 = STRBUF_INIT;
struct stat st;

preamble = "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
Expand All @@ -1649,7 +1671,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
"</array>\n"
"<key>StartCalendarInterval</key>\n"
"<array>\n";
fprintf(plist, preamble, name, exec_path, exec_path, frequency);
strbuf_addf(&plist, preamble, name, exec_path, exec_path, frequency);

switch (schedule) {
case SCHEDULE_HOURLY:
Expand All @@ -1658,7 +1680,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
"<key>Minute</key><integer>0</integer>\n"
"</dict>\n";
for (i = 1; i <= 23; i++)
fprintf(plist, repeat, i);
strbuf_addf(&plist, repeat, i);
break;

case SCHEDULE_DAILY:
Expand All @@ -1668,32 +1690,59 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
"<key>Minute</key><integer>0</integer>\n"
"</dict>\n";
for (i = 1; i <= 6; i++)
fprintf(plist, repeat, i);
strbuf_addf(&plist, repeat, i);
break;

case SCHEDULE_WEEKLY:
fprintf(plist,
"<dict>\n"
"<key>Day</key><integer>0</integer>\n"
"<key>Hour</key><integer>0</integer>\n"
"<key>Minute</key><integer>0</integer>\n"
"</dict>\n");
strbuf_addstr(&plist,
"<dict>\n"
"<key>Day</key><integer>0</integer>\n"
"<key>Hour</key><integer>0</integer>\n"
"<key>Minute</key><integer>0</integer>\n"
"</dict>\n");
break;

default:
/* unreachable */
break;
}
fprintf(plist, "</array>\n</dict>\n</plist>\n");
fclose(plist);
strbuf_addstr(&plist, "</array>\n</dict>\n</plist>\n");

if (safe_create_leading_directories(filename))
die(_("failed to create directories for '%s'"), filename);

if ((long)lock_file_timeout_ms < 0 &&
git_config_get_ulong("gc.launchctlplistlocktimeoutms",
&lock_file_timeout_ms))
lock_file_timeout_ms = 150;

fd = hold_lock_file_for_update_timeout(&lk, filename, LOCK_DIE_ON_ERROR,
lock_file_timeout_ms);

/* bootout might fail if not already running, so ignore */
launchctl_boot_plist(0, filename, cmd);
if (launchctl_boot_plist(1, filename, cmd))
die(_("failed to bootstrap service %s"), filename);
/*
* Does this file already exist? With the intended contents? Is it
* registered already? Then it does not need to be re-registered.
*/
if (!stat(filename, &st) && st.st_size == plist.len &&
strbuf_read_file(&plist2, filename, plist.len) == plist.len &&
!strbuf_cmp(&plist, &plist2) &&
launchctl_list_contains_plist(name, cmd))
rollback_lock_file(&lk);
else {
if (write_in_full(fd, plist.buf, plist.len) < 0 ||
commit_lock_file(&lk))
die_errno(_("could not write '%s'"), filename);

/* bootout might fail if not already running, so ignore */
launchctl_boot_plist(0, filename, cmd);
if (launchctl_boot_plist(1, filename, cmd))
die(_("failed to bootstrap service %s"), filename);
}

free(filename);
free(name);
strbuf_release(&plist);
strbuf_release(&plist2);
return 0;
}

Expand Down
2 changes: 2 additions & 0 deletions builtin/help.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,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);
}
Expand Down
5 changes: 5 additions & 0 deletions ci/run-test-slice.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,9 @@ make --quiet -C t T="$(cd t &&
./helper/test-tool path-utils slice-tests "$1" "$2" t[0-9]*.sh |
tr '\n' ' ')"

if test 0 = "$1" && test -n "$INCLUDE_SCALAR"
then
make -C contrib/scalar/t
fi

check_unignored_build_artifacts
8 changes: 7 additions & 1 deletion config.c
Original file line number Diff line number Diff line change
Expand Up @@ -3024,6 +3024,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
const char *value_pattern,
unsigned flags)
{
static unsigned long timeout_ms = ULONG_MAX;
int fd = -1, in_fd = -1;
int ret;
struct lock_file lock = LOCK_INIT;
Expand All @@ -3044,11 +3045,16 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
if (!config_filename)
config_filename = filename_buf = git_pathdup("config");

if ((long)timeout_ms < 0 &&
git_config_get_ulong("core.configWriteLockTimeoutMS", &timeout_ms))
timeout_ms = 0;

/*
* The lock serves a purpose in addition to locking: the new
* contents of .git/config will be written into it.
*/
fd = hold_lock_file_for_update(&lock, config_filename, 0);
fd = hold_lock_file_for_update_timeout(&lock, config_filename, 0,
timeout_ms);
if (fd < 0) {
error_errno(_("could not lock config file %s"), config_filename);
ret = CONFIG_NO_LOCK;
Expand Down
Loading