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

Rebase to v2.48.1 #725

Merged
merged 250 commits into from
Feb 13, 2025
Merged

Rebase to v2.48.1 #725

merged 250 commits into from
Feb 13, 2025

Conversation

dscho
Copy link
Member

@dscho dscho commented Feb 10, 2025

Over at git-for-windows#5411, I am still doing the Git for Windows v2.48.1 release (which is held up essentially by git-for-windows/build-extra#591). Once that is done, this here PR can be "merged" via pushing.

jeffhostetler and others added 30 commits February 10, 2025 08:26
Calculate the number of symrefs, loose vs packed, and the
maximal/accumulated length of local vs remote branches.

Signed-off-by: Jeff Hostetler <[email protected]>
Signed-off-by: Johannes Schindelin <[email protected]>
In ac8acb4 (sparse-index: complete partial expansion, 2022-05-23),
'expand_index()' was updated to expand the index to a given pathspec.
However, the 'path_matches_pattern_list()' method used to facilitate this
has the side effect of initializing or updating the index hash variables
('name_hash', 'dir_hash', and 'name_hash_initialized'). This operation is
performed on 'istate', though, not 'full'; as a result, the initialized
hashes are later overwritten when copied from 'full'. To ensure the correct
hashes are in 'istate' after the index expansion, change the arg used in
'path_matches_pattern_list()' from 'istate' to 'full'.

Note that this does not fully solve the problem. If 'istate' does not have
an initialized 'name_hash' when its contents are copied to 'full',
initialized hashes will be copied back into 'istate' but
'name_hash_initialized' will be 0. Therefore, we also need to copy
'full->name_hash_initialized' back to 'istate' after the index expansion is
complete.

Signed-off-by: Victoria Dye <[email protected]>
Add test case to demonstrate that `git index-pack -o <idx-path> pack-path`
fails if <idx-path> does not end in ".idx" when `--rev-index` is
enabled.

In e37d0b8 (builtin/index-pack.c: write reverse indexes, 2021-01-25)
we learned to create `.rev` reverse indexes in addition to `.idx` index
files.  The `.rev` file pathname is constructed by replacing the suffix
on the `.idx` file.  The code assumes a hard-coded "idx" suffix.

In a8dd7e0 (config: enable `pack.writeReverseIndex` by default, 2023-04-12)
reverse indexes were enabled by default.

If the `-o <idx-path>` argument is used, the index file may have a
different suffix.  This causes an error when it tries to create the
reverse index pathname.

The test here demonstrates the failure.  (The test forces `--rev-index`
to avoid interaction with `GIT_TEST_NO_WRITE_REV_INDEX` during CI runs.)

Signed-off-by: Jeff Hostetler <[email protected]>
With this commit, we gather statistics about the sizes of commits,
trees, and blobs in the repository, and then present them in the form
of "hexbins", i.e. log(16) histograms that show how many objects fall
into the 0..15 bytes range, the 16..255 range, the 256..4095 range, etc.

For commits, we also show the total count grouped by the number of
parents, and for trees we additionally show the total count grouped by
number of entries in the form of "qbins", i.e. log(4) histograms.

Signed-off-by: Jeff Hostetler <[email protected]>
Signed-off-by: Johannes Schindelin <[email protected]>
These seem to be custom tests to microsoft/git as they break without
these changes, but these changes are not needed upstream.

Signed-off-by: Derrick Stolee <[email protected]>
Add a test verifying that sparse-checkout (with and without sparse index
enabled) treat untracked files & directories correctly when changing sparse
patterns. Specifically, it ensures that 'git sparse-checkout set'

* deletes empty directories outside the sparse cone
* does _not_ delete untracked files outside the sparse cone

Signed-off-by: Victoria Dye <[email protected]>
Teach index-pack to silently omit the reverse index if the
index file does not have the standard ".idx" suffix.

In e37d0b8 (builtin/index-pack.c: write reverse indexes, 2021-01-25)
we learned to create `.rev` reverse indexes in addition to `.idx` index
files.  The `.rev` file pathname is constructed by replacing the suffix
on the `.idx` file.  The code assumes a hard-coded "idx" suffix.

In a8dd7e0 (config: enable `pack.writeReverseIndex` by default, 2023-04-12)
reverse indexes were enabled by default.

If the `-o <idx-path>` argument is used, the index file may have a
different suffix.  This causes an error when it tries to create the
reverse index pathname.

Since we do not know why the user requested a non-standard suffix for
the index, we cannot guess what the proper corresponding suffix should
be for the reverse index.  So we disable it.

The t5300 test has been updated to verify that we no longer error
out and that the .rev file is not created.

TODO We could warn the user that we skipped it (perhaps only if they
TODO explicitly requested `--rev-index` on the command line).
TODO
TODO Ideally, we should add an `--rev-index-path=<path>` argument
TODO or change `--rev-index` to take a pathname.
TODO
TODO I'll leave these questions for a future series.

Signed-off-by: Jeff Hostetler <[email protected]>
Prefetch the value of GIT_TRACE2_DST_DEBUG during startup and before
we try to open any Trace2 destination pathnames.

Normally, Trace2 always silently fails if a destination target
cannot be opened so that it doesn't affect the execution of a
Git command.  The command should run normally, but just not
generate any trace data.  This can make it difficult to debug
a telemetry setup, since the user doesn't know why telemetry
isn't being generated.  If the environment variable
GIT_TRACE2_DST_DEBUG is true, the Trace2 startup will print
a warning message with the `errno` to make debugging easier.

However, on Windows, looking up the env variable resets `errno`
so the warning message always ends with `...tracing: No error`
which is not very helpful.

Prefetch the env variable at startup.  This avoids the need
to update each call-site to capture `errno` in the usual
`saved-errno` variable.

Signed-off-by: Jeff Hostetler <[email protected]>
Create `struct large_item` and `struct large_item_vec` to capture the
n largest commits, trees, and blobs under various scaling dimensions,
such as size in bytes, number of commit parents, or number of entries
in a tree.

Each of these have a command line option to set them independently.

Signed-off-by: Jeff Hostetler <[email protected]>
Include the pathname of each blob or tree in the large_item_vec
to help identify the file or directory associated with the OID
and size information.

This pathname is computed during the path walk, so it reflects the
first observed pathname seen for that OID during the traversal over
all of the refs.  Since the file or directory could have moved
(without being modified), there may be multiple "correct" pathnames
for a particular OID.  Since we do not control the ref traversal
order, we should consider it to be a "suggested pathname" for the OID.

Signed-off-by: Jeff Hostetler <[email protected]>
Computing `git name-rev` on each commit, tree, and blob in each
of the various large_item_vec can be very expensive if there are
too many refs, especially if the user doesn't need the result.
Lets make it optional.

The `--no-name-rev` option can save 50 calls to `git name-rev`
since we have 5 large_item_vec's and each defaults to 10 items.

Signed-off-by: Jeff Hostetler <[email protected]>
This topic branch brings in a new, experimental built-in command to
assess the dimensions of a local repository.

It is experimental and subject to change! It might grow new options,
change its output, or even be moved into `git diagnose --analyze` or
something like that.

The hope is that this command, which was inspired by `git sizer`
(https://github.com/github/git-sizer), will be helpful not only in
diagnosing issues with large repositories, but also in modeling what
shapes and sizes of repositories can be handled by Git (and as a
corollary: where Git needs to improve to be able to accommodate the
natural growth of repositories).

Signed-off-by: Johannes Schindelin <[email protected]>
This backports the `ds/advice-sparse-index-expansion` patches into
`microsoft/git` which _just_ missed the v2.46.0 window.

Signed-off-by: Johannes Schindelin <[email protected]>
Cherry-pick rev-index fixes from v2.41.0.vfs.0.5 into v2.42.0.*
While using the reset --stdin feature on windows path added may have a
\r at the end of the path that wasn't getting removed so didn't match
the path in the index and wasn't reset.

Signed-off-by: Kevin Willford <[email protected]>
Prefetch the value of GIT_TRACE2_DST_DEBUG during startup and before we
try to open any Trace2 destination pathnames.

Normally, Trace2 always silently fails if a destination target cannot be
opened so that it doesn't affect the execution of a Git command. The
command should run normally, but just not generate any trace data. This
can make it difficult to debug a telemetry setup, since the user doesn't
know why telemetry isn't being generated. If the environment variable
GIT_TRACE2_DST_DEBUG is true, the Trace2 startup will print a warning
message with the `errno` to make debugging easier.

However, on Windows, looking up the env variable resets `errno` so the
warning message always ends with `...tracing: No error` which is not
very helpful.

Prefetch the env variable at startup. This avoids the need to update
each call-site to capture `errno` in the usual `saved-errno` variable.
It has been a long-standing practice in Git for Windows to append
`.windows.<n>`, and in microsoft/git to append `.vfs.0.0`. Let's keep
doing that.

Signed-off-by: Johannes Schindelin <[email protected]>
…sitories (#667)

This command is inspired by [`git
sizer`](https://github.com/github/git-sizer), having the advantage of
being much closer to the internals of Git.

The intention is to provide a built-in command that can be used to
analyze large repositories for performance and scaling problems, for
growth over time, and to correlate with other measurements (in
particular with Trace2 data collected e.g. via
https://github.com/git-ecosystem/trace2receiver/).
Since we really want to be based on a `.vfs.*` tag, let's make sure that
there was a new-enough one, i.e. one that agrees with the first three
version numbers of the recorded default version.

This prevents e.g. v2.22.0.vfs.0.<some-huge-number>.<commit> from being
used when the current release train was not yet tagged.

It is important to get the first three numbers of the version right
because e.g. Scalar makes decisions depending on those (such as assuming
that the `git maintenance` built-in is not available, even though it
actually _is_ available).

Signed-off-by: Johannes Schindelin <[email protected]>
This header file will accumulate GVFS-specific definitions.

Signed-off-by: Kevin Willford <[email protected]>
This does not do anything yet. The next patches will add various values
for that config setting that correspond to the various features
offered/required by GVFS.

Signed-off-by: Kevin Willford <[email protected]>

gvfs: refactor loading the core.gvfs config value

This code change makes sure that the config value for core_gvfs
is always loaded before checking it.

Signed-off-by: Kevin Willford <[email protected]>
This takes a substantial amount of time, and if the user is reasonably
sure that the files' integrity is not compromised, that time can be saved.

Git no longer verifies the SHA-1 by default, anyway.

Signed-off-by: Kevin Willford <[email protected]>

Update for 2023-02-27: This feature was upstreamed as the index.skipHash
config option. This resulted in some changes to the struct and some of
the setup code. In particular, the config reading was moved to
prepare_repo_settings(), so the core.gvfs bit check was moved there,
too.

Signed-off-by: Kevin Willford <[email protected]>
Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Johannes Schindelin <[email protected]>
Prevent the sparse checkout to delete files that were marked with
skip-worktree bit and are not in the sparse-checkout file.

This is because everything with the skip-worktree bit turned on is being
virtualized and will be removed with the change of HEAD.

There was only one failing test when running with these changes that was
checking to make sure the worktree narrows on checkout which was
expected since we would no longer be narrowing the worktree.

Update 2022-04-05: temporarily set 'sparse.expectfilesoutsideofpatterns' in
test (until we start disabling the "remove present-despite-SKIP_WORKTREE"
behavior with 'core.virtualfilesystem' in a later commit).

Signed-off-by: Kevin Willford <[email protected]>
dscho and others added 22 commits February 10, 2025 08:50
I will intend to send this upstream after the 2.47.0 release cycle, but
this should get to our microsoft/git users for maximum impact.

Customers have been struggling with explaining why the sparse index
expansion advice message is showing up. The advice to run 'git clean'
has not always helped folks, and sometimes it is very unclear why we are
running into trouble.

These changes introduce a way to log a reason for the expansion into the
trace2 logs so it can be found by requesting that a user enable tracing.

While testing this, I created the most standard case that happens, which
is to have an existing directory match a sparse directory in the index.
In this case, it showed that two log messages were required. See the
last commit for this new log message. Together, these two places show
this kind of message in the `GIT_TRACE2_PERF` output (trimmed for
clarity):

```
region_enter | index        | label:clear_skip_worktree_from_present_files_sparse
data         | sparse-index | ..skip-worktree sparsedir:<my-sparse-path>/
data         | index        | ..sparse_path_count:362
data         | index        | ..sparse_lstat_count:732
region_leave | index        | label:clear_skip_worktree_from_present_files_sparse
data         | sparse-index | expansion-reason:failed to clear skip-worktree while sparse
```

I added some tests to demonstrate that these logs are recorded, but it
also seems difficult to hit some of these cases.
These two tests in t5616-partial-clone.sh are actually already broken
and there are comments supporting that. Those comments were focused on
the GIT_TEST_FULL_NAME_HASH variable, but they also apply to this one.
We will want to avoid issues here.

Signed-off-by: Derrick Stolee <[email protected]>
In preparation for allowing both the --shallow and --path-walk options
in the 'git pack-objects' builtin, create a new 'edge_aggressive' option
in the path-walk API. This option will help walk the boundary more
thoroughly and help avoid sending extra objects during fetches and
pushes.

The only use of the 'edge_hint_aggressive' option in the revision API is
within mark_edges_uninteresting(), which is usually called before
between prepare_revision_walk() and before visiting commits with
get_revision(). In prepare_revision_walk(), the UNINTERESTING commits
are walked until a boundary is found.

We didn't use this in the past because we would mark objects
UNINTERESTING after doing the initial commit walk to the boundary. While
we should be marking these objects as UNINTERESTING, we shouldn't _emit_
them all via the path-walk algorithm or else our delta calculations will
get really slow.

Based on these observations, the way we were handling the UNINTERESTING
flag in walk_objects_by_path() was overly complicated and buggy. A lot
of it can be removed and simplified to work with this new approach.

It also means that we will see the UNINTERESTING boundaries of paths
when doing a default path-walk call, changing some existing test cases.

Signed-off-by: Derrick Stolee <[email protected]>
In some instances (particularly the `read_object` hook), the `cmd`
attribute is set to an `strdup()`ed value. This value needs to be
released in the end!

Since other users assign a non-`strdup()`ed value, be careful to add
_another_ attribute (called `to_free`) that can hold a reference to such
a string that needs to be released once the sub process is done.

Signed-off-by: Johannes Schindelin <[email protected]>
There does not appear to be anything particularly incompatible about the
--shallow and --path-walk options of 'git pack-objects'. If shallow
commits are to be handled differently, then it is by the revision walk
that defines the commit set and which are interesting or uninteresting.

However, before the previous change, a trivial removal of the warning
would cause a failure in t5500-fetch-pack.sh when
GIT_TEST_PACK_PATH_WALK is enabled. The shallow fetch would provide more
objects than we desired, due to some incorrect behavior of the path-walk
API, especially around walking uninteresting objects.

To also cover the symmetrical case of pushing from a shallow clone, add
a new test to t5538-push-shallow.sh that confirms the correct behavior
of pushing only the new object. This works to validate both the
--path-walk and --no-path-walk case when toggling the
GIT_TEST_PACK_PATH_WALK environment variable. This test would have
failed in the --path-walk case if we created it before the previous
change.

Signed-off-by: Derrick Stolee <[email protected]>
This fixes a leak that is not detected by Git's test suite (but by
microsoft/git's).

Signed-off-by: Johannes Schindelin <[email protected]>
It can be notoriously difficult to detect if delta bases are being
computed properly during 'git push'. Construct an example where it will
make a kilobyte worth of difference when a delta base is not found. We
can then use the progress indicators to distinguish between bytes and
KiB depending on whether the delta base is found and used.

Signed-off-by: Derrick Stolee <[email protected]>
An internal customer reported a segfault when running `git
sparse-checkout set` with the `index.sparse` config enabled. I was
unable to reproduce it locally, but with their help we debugged into the
failing process and discovered the following stacktrace:

```
#0  0x00007ff6318fb7b0 in rehash (map=0x3dfb00d0440, newsize=1048576) at hashmap.c:125
#1  0x00007ff6318fbc66 in hashmap_add (map=0x3dfb00d0440, entry=0x3dfb5c58bc8) at hashmap.c:247
#2  0x00007ff631937a70 in hash_index_entry (istate=0x3dfb00d0400, ce=0x3dfb5c58bc8) at name-hash.c:122
#3  0x00007ff631938a2f in add_name_hash (istate=0x3dfb00d0400, ce=0x3dfb5c58bc8) at name-hash.c:638
#4  0x00007ff631a064de in set_index_entry (istate=0x3dfb00d0400, nr=8291, ce=0x3dfb5c58bc8) at sparse-index.c:255
#5  0x00007ff631a06692 in add_path_to_index (oid=0x5ff130, base=0x5ff580, path=0x3dfb4b725da "<redacted>", mode=33188, context=0x5ff570)    at sparse-index.c:307
#6  0x00007ff631a3b48c in read_tree_at (r=0x7ff631c026a0 <the_repo>, tree=0x3dfb5b41f60, base=0x5ff580, depth=2, pathspec=0x5ff5a0,    fn=0x7ff631a064e5 <add_path_to_index>, context=0x5ff570) at tree.c:46
#7  0x00007ff631a3b60b in read_tree_at (r=0x7ff631c026a0 <the_repo>, tree=0x3dfb5b41e80, base=0x5ff580, depth=1, pathspec=0x5ff5a0,    fn=0x7ff631a064e5 <add_path_to_index>, context=0x5ff570) at tree.c:80
#8  0x00007ff631a3b60b in read_tree_at (r=0x7ff631c026a0 <the_repo>, tree=0x3dfb5b41ac8, base=0x5ff580, depth=0, pathspec=0x5ff5a0,    fn=0x7ff631a064e5 <add_path_to_index>, context=0x5ff570) at tree.c:80
#9  0x00007ff631a06a95 in expand_index (istate=0x3dfb00d0100, pl=0x0) at sparse-index.c:422
#10 0x00007ff631a06cbd in ensure_full_index (istate=0x3dfb00d0100) at sparse-index.c:456
#11 0x00007ff631990d08 in index_name_stage_pos (istate=0x3dfb00d0100, name=0x3dfb0020080 "algorithm/levenshtein", namelen=21, stage=0,    search_mode=EXPAND_SPARSE) at read-cache.c:556
#12 0x00007ff631990d6c in index_name_pos (istate=0x3dfb00d0100, name=0x3dfb0020080 "algorithm/levenshtein", namelen=21) at read-cache.c:566
#13 0x00007ff63180dbb5 in sanitize_paths (argc=185, argv=0x3dfb0030018, prefix=0x0, skip_checks=0) at builtin/sparse-checkout.c:756
#14 0x00007ff63180de50 in sparse_checkout_set (argc=185, argv=0x3dfb0030018, prefix=0x0) at builtin/sparse-checkout.c:860
#15 0x00007ff63180e6c5 in cmd_sparse_checkout (argc=186, argv=0x3dfb0030018, prefix=0x0) at builtin/sparse-checkout.c:1063
#16 0x00007ff6317234cb in run_builtin (p=0x7ff631ad9b38 <commands+2808>, argc=187, argv=0x3dfb0030018) at git.c:548
#17 0x00007ff6317239c0 in handle_builtin (argc=187, argv=0x3dfb0030018) at git.c:808
#18 0x00007ff631723c7d in run_argv (argcp=0x5ffdd0, argv=0x5ffd78) at git.c:877
#19 0x00007ff6317241d1 in cmd_main (argc=187, argv=0x3dfb0030018) at git.c:1017
#20 0x00007ff631838b60 in main (argc=190, argv=0x3dfb0030000) at common-main.c:64 
```

The very bottom of the stack being the `rehash()` method from
`hashmap.c` as called within the `name-hash` API made me look at where
these hashmaps were being used in the sparse index logic. These were
being copied across indexes, which seems dangerous. Indeed, clearing
these hashmaps and setting them as not initialized fixes the segfault.

The second commit is a response to a test failure that happens in
`t1092-sparse-checkout-compatibility.sh` where `git stash pop` starts to
fail because the underlying `git checkout-index` process fails due to
colliding files. Passing the `-f` flag appears to work, but it's unclear
why this name-hash change causes that change in behavior.
This fixes a leak that is not detected by Git's own test suite (but by
microsoft/git's, in the t9210-scalar.sh test).

Signed-off-by: Johannes Schindelin <[email protected]>
This pull request aims to correct a pretty big issue when dealing with
UNINTERESTING objects in the path-walk API. They somehow were only
exposed when trying to perform a push from a shallow clone.

This will require rewriting the upstream version so this is avoided from
the start, but we can do a forward fix for now.

The key issue is that the path-walk API was not walking UNINTERESTING
trees at the right time, and the way it was being done was more
complicated than it needed to be. This changes some of the way the
path-walk API works in the presence of UNINTERSTING commits, but these
are good changes to make.

I had briefly attempted to remove the use of the `edge_aggressive`
option in `struct path_walk_info` in favor of using the
`--objects-edge-aggressive` option in the revision struct. When I
started down that road, though, I somehow got myself into a bind of
things not working correctly. I backed out to this version that is
working with our test cases.

I tested this using the thin and big pack tests in `p5313` which had the
same performance as before this change.

The new change is that in a shallow clone we can get the same `git push`
improvements.

I was hung up on testing this for a long time as I wasn't getting the
same results in my shallow clone as in my regular clones. It turns out
that I had forgotten to use `--no-reuse-delta` in my test command, so it
was picking the deltas that were given by the initial clone instead of
picking new ones per the algorithm. 🤦🏻
Git v2.48.0 has become even more stringent about leaks.

Signed-off-by: Johannes Schindelin <[email protected]>
The check for dubious ownership has one particular quirk on Windows: if
running as an administrator, files owned by the Administrators _group_
are considered owned by the user.

The rationale for that is: When running in elevated mode, Git creates
files that aren't owned by the individual user but by the Administrators
group.

There is yet another quirk, though: The check I introduced to determine
whether the current user is an administrator uses the
`CheckTokenMembership()` function with the current process token. And
that check only succeeds when running in elevated mode!

Let's be a bit more lenient here and look harder whether the current
user is an administrator. We do this by looking for a so-called "linked
token". That token exists when administrators run in non-elevated mode,
and can be used to create a new process in elevated mode. And feeding
_that_ token to the `CheckTokenMembership()` function succeeds!

Signed-off-by: Johannes Schindelin <[email protected]>
This adds a new sub-sub-command for `test-tool`, simply passing through
the command-line arguments to the `is_path_owned_by_current_user()`
function.

Signed-off-by: Johannes Schindelin <[email protected]>
The --path-walk option in `git pack-objects` is implied by the
pack.usePathWalk=true config value. This is intended to help the
packfile generation within `git push` specifically.

While this config does enable the path-walk feature, it does not lead to
the expected levels of compression in the cases it was designed to
handle. This is due to the default implication of the --reuse-delta
option as well as auto-GC.

In the performance tests used to evaluate the --path-walk option, such
as those in p5313, the --no-reuse-delta option is used to ensure that
deltas are recomputed according to the new object walk. However, it was
assumed (I assumed this) that when the objects were loose from
client-side operations that better deltas would be computed during this
operation. This wasn't confirmed because the test process used data that
was fetched from real repositories and thus existed in packed form only.

I was able to confirm that this does not reproduce when the objects to
push are loose. Careful use of making the pushed commit unreachable and
loosening the objects via `git repack -Ad` helps to confirm my
suspicions here. Independent of this change, I'm pushing for these
pipeline agents to set `gc.auto=0` before creating their Git objects. In
the current setup, the repo is adding objects and then incrementally
repacking them and ending up with bad cross-path deltas. This approach
can help scenarios where that makes sense, but will not cover all of our
users without them choosing to opt-in to background maintenance (and
even then, an incremental repack could cost them efficiency).

In order to make sure we are getting the intended compression in `git
push`, this change enforces the spawned `git pack-objects` process to
use `--no-reuse-delta`.

As far as I can tell, the main motivation for implying the --reuse-delta
option by default is two-fold:

 1. The code in send-pack.c that executes 'git pack-objects' is ignorant
    of whether the current process is a client pushing to a remote or a
    remote sending a fetch or clone to a client.

 2. For servers, it is critical that they trust the previously computed
    deltas whenever possible, or they could overload their CPU
    resources.

There's also the side that most servers use repacking logic that will
replace any bad deltas that are sent by clients (or at least, that's the
hope; we've seen that repacks can also pick bad deltas).

This commit also adds a test case that demonstrates that `git -c
pack.usePathWalk=true push` now avoids reusing deltas.

To do this, the test case constructs a pack with a horrendously
inefficient delta object, then verifies that the pack on the receiving
side of the `push` fails to have such an inefficient delta.

The test case would probably be a lot more readable if hex numbers were
used instead of octal numbers, but alas, `printf "\x<hex>"` is not
portable, only `printf "\<octal>"` is. For example, dash's built-in
`printf` function simply prints `\x` verbatim while bash's built-in
happily converts this construct to the corresponding byte.

Signed-off-by: Derrick Stolee <[email protected]>
Signed-off-by: Johannes Schindelin <[email protected]>
The check for dubious ownership has one particular quirk on Windows: if
running as an administrator, files owned by the Administrators _group_
are considered owned by the user.

The rationale for that is: When running in elevated mode, Git creates
files that aren't owned by the individual user but by the Administrators
group.

There is yet another quirk, though: The check I introduced to determine
whether the current user is an administrator uses the
`CheckTokenMembership()` function with the current process token. And
that check only succeeds when running in elevated mode!

Let's be a bit more lenient here and look harder whether the current
user is an administrator. We do this by looking for a so-called "linked
token". That token exists when administrators run in non-elevated mode,
and can be used to create a new process in elevated mode. And feeding
_that_ token to the `CheckTokenMembership()` function succeeds!
Update the WinGet release workflow to match the updating manifest in
`microsoft/winget-pkgs`, where there are now four installation options:

- x86_64 / x64 with machine scope
- x86_64 / x64 with user scope
- aarch64 / arm64 with machine scope
- aarch64 / arm64 with user scope

Signed-off-by: Matthew John Cheetham <[email protected]>
The --path-walk option in 'git pack-objects' is implied by the
pack.usePathWalk=true config value. This is intended to help the
packfile generation within 'git push' specifically.

While this config does enable the path-walk feature, it does not lead
the expected levels of compression in the cases it was designed to
handle. This is due to the default implication of the --reuse-delta
option as well as auto-GC.

In the performance tests used to evaluate the --path-walk option, such
as those in p5313, the --no-reuse-delta option is used to ensure that
deltas are recomputed according to the new object walk. However, it was
assumed (I assumed this) that when the objects were loose from
client-side operations that better deltas would be computed during this
operation. This wasn't confirmed because the test process used data that
was fetched from real repositories and thus existed in packed form only.

I was able to confirm that this does not reproduce when the objects to
push are loose. Careful use of making the pushed commit unreachable and
loosening the objects via 'git repack -Ad' helps to confirm my
suspicions here. Independent of this change, I'm pushing for these
pipeline agents to set 'gc.auto=0' before creating their Git objects. In
the current setup, the repo is adding objects and then incrementally
repacking them and ending up with bad cross-path deltas. This approach
can help scenarios where that makes sense, but will not cover all of our
users without them choosing to opt-in to background maintenance (and
even then, an incremental repack could cost them efficiency).

In order to make sure we are getting the intended compression in 'git
push', this change makes the --path-walk option imply --no-reuse-delta
when the --reuse-delta option is not provided.

As far as I can tell, the main motivation for implying the --reuse-delta
option by default is two-fold:

1. The code in send-pack.c that executes 'git pack-objects' is ignorant
of whether the current process is a client pushing to a remote or a
remote sending a fetch or clone to a client.

2. For servers, it is critical that they trust the previously computed
deltas whenever possible, or they could overload their CPU resources.

There's also the side that most servers use repacking logic that will
replace any bad deltas that are sent by clients (or at least, that's the
hope; we've seen that repacks can also pick bad deltas).

The --path-walk option at the moment is not compatible with reachability
bitmaps, so is not planned to be used by Git servers. Thus, we can
reasonably assume (for now) that the --path-walk option is assuming a
client-side scenario, either a push or a repack. The repack option will
be explicit about the --reuse-delta option or not.

One thing to be careful about is background maintenance, which uses a
list of objects instead of refs, so we condition this on the case where
the --path-walk option will be effective by checking that the --revs
option was provided.

Alternative options considered included:

* Adding _another_ config ('pack.reuseDelta=false') to opt-in to this
choice. However, we already have pack.usePathWalk=true as an opt-in to
"do the right thing to make my data small" as far as our internal users
are concerned.

* Modify the chain between builtin/push.c, transport.c, and
builtin/send-pack.c to communicate that we are in "push" mode, not
within a fetch or clone. However, this seemed like overkill. It may be
beneficial in the future to pass through a mode like this, but it does
not meet the bar for the immediate need.

Reviewers, please see git-for-windows#5171 for the baseline
implementation of this feature within Git for Windows and thus
microsoft/git. This feature is still under review upstream.
Tests in t7900 assume the state of the `maintenance.strategy`
config setting; set/unset by previous tests. Correct this by
explictly unsetting and re-setting the config at the start of the
tests.

Signed-off-by: Matthew John Cheetham <[email protected]>
)

Update the WinGet release workflow to match the updating manifest in
`microsoft/winget-pkgs`, where there are now four installation options:

- x86_64 / x64 with machine scope
- x86_64 / x64 with user scope
- aarch64 / arm64 with machine scope
- aarch64 / arm64 with user scope
Introduce a new maintenance task, `cache-local-objects`, that operates
on Scalar or VFS for Git repositories with a per-volume, shared object
cache (specified by `gvfs.sharedCache`) to migrate packfiles and loose
objects from the repository object directory to the shared cache.

Older versions of `microsoft/git` incorrectly placed packfiles in the
repository object directory instead of the shared cache; this task will
help clean up existing clones impacted by that issue.

Migration of packfiles involves the following steps for each pack:

1. Hardlink (or copy):
   a. the .pack file
   b. the .keep file
   c. the .rev file
2. Move (or copy + delete) the .idx file
3. Delete/unlink:
   a. the .pack file
   b. the .keep file
   c. the .rev file

Moving the index file after the others ensures the pack is not read
from the new cache directory until all associated files (rev, keep)
exist in the cache directory also.

Moving loose objects operates as a move, or copy + delete.

Signed-off-by: Matthew John Cheetham <[email protected]>
Add the `cache-local-objects` maintenance task to the list of tasks run
by the `scalar run` command. It's often easier for users to run the
shorter `scalar run` command than the equivalent `git maintenance`
command.

Signed-off-by: Matthew John Cheetham <[email protected]>
Introduce a new maintenance task, `cache-local-objects`, that operates
on Scalar or VFS for Git repositories with a per-volume, shared object
cache (specified by `gvfs.sharedCache`) to migrate packfiles and loose
objects from the repository object directory to the shared cache.

Older versions of `microsoft/git` incorrectly placed packfiles in the
repository object directory instead of the shared cache; this task will
help clean up existing clones impacted by that issue.

Fixes #716
@dscho dscho requested a review from mjcheetham February 10, 2025 12:30
@dscho dscho self-assigned this Feb 10, 2025
@dscho
Copy link
Member Author

dscho commented Feb 10, 2025

Range-diff relative to tentative/vfs-2.48.0
  • 7: 0679936 = 1: 84ba3bb survey: calculate more stats on refs

  • 1: d43df21 = 2: 132ad6a sparse-index.c: fix use of index hashes in expand_index

  • 4: d5da60b = 3: 6309b70 t5300: confirm failure of git index-pack when non-idx suffix requested

  • 12: 97b6900 = 4: 3bd3d96 survey: show some commits/trees/blobs histograms

  • 2: ed3fe89 = 5: 2c03380 t: remove advice from some tests

  • 3: 9a3602c = 6: 6a53749 t1092: add test for untracked files and directories

  • 5: f27fd55 = 7: 2a08f0a index-pack: disable rev-index if index file has non .idx suffix

  • 6: a83676d = 8: be2f825 trace2: prefetch value of GIT_TRACE2_DST_DEBUG at startup

  • 13: 73e6cd5 = 9: a6bdfa4 survey: add vector of largest objects for various scaling dimensions

  • 14: f35a2a1 = 10: 32189b9 survey: add pathname of blob or tree to large_item_vec

  • 15: 0fb037f = 11: 9399a12 survey: add commit-oid to large_item detail

  • 16: ba10649 = 12: c8be55d survey: add commit name-rev lookup to each large_item

  • 17: fcd1416 = 13: f36fb84 survey: add --no-name-rev option

  • 18: f9c6bad = 14: 5d11a62 survey: started TODO list at bottom of source file

  • 19: cce6824 = 15: 0c02488 survey: expanded TODO list at the bottom of the source file

  • 20: 7a088c0 = 16: 7758c74 survey: expanded TODO with more notes

  • 21: 752c2bd = 17: 26214f4 Merge branch 'jh/experimental-survey'

  • 8: 2bf0aed = 18: e537289 Merge branch 'backport-sparse-index-advice'

  • 9: 2321ad9 = 19: ebc48c4 Fix sparse-checkout set crashes (Fix sparse-checkout set crashes #607)

  • 10: 1b13a22 = 20: 75a12c9 Fix rev index in 2.42.0 series (Fix rev index in 2.42.0 series #600)

  • 11: dc12607 = 21: 8434111 trace2: prefetch value of GIT_TRACE2_DST_DEBUG at startup (trace2: prefetch value of GIT_TRACE2_DST_DEBUG at startup #663)

  • 22: 1f96323 = 22: 2d2d322 Add the experimental git survey command to analyze (large) local repositories (Add the experimental git survey command to analyze (large) local repositories #667)

  • 23: 6109cfb = 23: 2785521 reset --stdin: trim carriage return from the paths

  • 24: 031198e ! 24: 82a9afa Identify microsoft/git via a distinct version suffix

    @@ Commit message
      ## GIT-VERSION-GEN ##
     @@
      
    - DEF_VER=v2.48.0-rc1
    + DEF_VER=v2.48.1
      
     +# Identify microsoft/git via a distinct version suffix
     +DEF_VER=$DEF_VER.vfs.0.0
  • 25: 16d3fb1 = 25: 9d182fd gvfs: ensure that the version is based on a GVFS tag

  • 26: afa9508 = 26: 33a8988 gvfs: add a GVFS-specific header file

  • 36: be3b3ac = 27: e781a50 gvfs: add the core.gvfs config setting

  • 37: 6f9fb79 = 28: 22583f7 gvfs: add the feature to skip writing the index' SHA-1

  • 38: af0d380 = 29: eca6d35 gvfs: add the feature that blobs may be missing

  • 39: 8acc66f = 30: ad33b6a gvfs: prevent files to be deleted outside the sparse checkout

  • 40: 2a0ce9b = 31: dc7f44e gvfs: optionally skip reachability checks/upload pack during fetch

  • 41: e44a53b = 32: d13ff90 gvfs: ensure all filters and EOL conversions are blocked

  • 42: 6e17496 = 33: 767a6ba gvfs: allow "virtualizing" objects

  • 43: 933af84 = 34: d0f04ac Hydrate missing loose objects in check_and_freshen()

  • 44: 00a11f2 = 35: d5b9f91 sha1_file: when writing objects, skip the read_object_hook

  • 45: d16546c = 36: bf15ebc gvfs: add global command pre and post hook procs

  • 46: 89ea17f = 37: f3b6bd1 t0400: verify that the hook is called correctly from a subdirectory

  • 47: 9d4b2f7 = 38: 506300a Pass PID of git process to hooks.

  • 48: f3e6f6d = 39: b5e57ab pre-command: always respect core.hooksPath

  • 49: ace01dd = 40: aacfa5b sparse-checkout: update files with a modify/delete conflict

  • 50: 26ed740 = 41: 51da332 sparse-checkout: avoid writing entries with the skip-worktree bit

  • 51: 7a6f583 = 42: 5357567 Do not remove files outside the sparse-checkout

  • 52: f117f50 = 43: 60e7946 send-pack: do not check for sha1 file when GVFS_MISSING_OK set

  • 53: 719b9ea = 44: bf32c09 cache-tree: remove use of strbuf_addf in update_one

  • 54: ebba63f = 45: d66a1dc gvfs: block unsupported commands when running in a GVFS repo

  • 55: 50b45b6 = 46: c918116 worktree: allow in Scalar repositories

  • 56: e4cd5d2 = 47: b62a93d gvfs: allow overriding core.gvfs

  • 57: 0029f6e = 48: 4bde6ad BRANCHES.md: Add explanation of branches and using forks

  • 58: 839a737 = 49: 225a9aa Add virtual file system settings and hook proc

  • 59: 747db26 = 50: dafd0c9 virtualfilesystem: don't run the virtual file system hook if the index has been redirected

  • 60: 98fabc5 = 51: c127664 virtualfilesystem: check if directory is included

  • 61: 31d0210 = 52: caddbc7 backwards-compatibility: support the post-indexchanged hook

  • 62: e326cdd = 53: bd95866 gvfs: verify that the built-in FSMonitor is disabled

  • 63: ae8b8ed = 54: e47db22 wt-status: add trace2 data for sparse-checkout percentage

  • 64: 627045e = 55: 7ee6b9c wt-status: add VFS hydration percentage to normal git status output

  • 65: 213f295 = 56: 6d18e4d status: add status serialization mechanism

  • 66: 0221115 = 57: 049317d Teach ahead-behind and serialized status to play nicely together

  • 67: 760d513 = 58: dce73bd status: serialize to path

  • 68: 2acf45f = 59: d621a28 status: reject deserialize in V2 and conflicts

  • 69: 42e8e53 = 60: a55ed71 serialize-status: serialize global and repo-local exclude file metadata

  • 73: b2024bb = 61: 602ba37 status: deserialization wait

  • 74: e9a6fe0 = 62: 4d09641 merge-recursive: avoid confusing logic in was_dirty()

  • 75: cd46651 = 63: d1af813 merge-recursive: add some defensive coding to was_dirty()

  • 76: f326c70 = 64: 6ca188e merge-recursive: teach was_dirty() about the virtualfilesystem

  • 77: 2d8e853 = 65: e4da5b0 status: deserialize with -uno does not print correct hint

  • 78: 19a8a31 = 66: 39943b3 fsmonitor: check CE_FSMONITOR_VALID in ce_uptodate

  • 79: 4781219 = 67: 5398a74 fsmonitor: add script for debugging and update script for tests

  • 80: 48a225f = 68: 3e1eb2b status: disable deserialize when verbose output requested.

  • 81: 4b0c554 = 69: 05b0721 t7524: add test for verbose status deserialzation

  • 82: 82cbf98 = 70: 665e1b4 deserialize-status: silently fallback if we cannot read cache file

  • 83: c9cee1c = 71: 207b578 gvfs:trace2:data: add trace2 tracing around read_object_process

  • 84: 4b24b82 = 72: 6ce1dc2 gvfs:trace2:data: status deserialization information

  • 85: 05bee9e = 73: 875d110 gvfs:trace2:data: status serialization

  • 86: d03100d = 74: 450ff3e gvfs:trace2:data: add vfs stats

  • 87: b311685 = 75: 2854a6d trace2: refactor setting process starting time

  • 88: acc3200 = 76: 1736ae9 trace2:gvfs:experiment: clear_ce_flags_1

  • 89: a38eaec = 77: e425e7b trace2:gvfs:experiment: report_tracking

  • 90: 95e2952 = 78: 7e0b32f trace2:gvfs:experiment: read_cache: annotate thread usage in read-cache

  • 91: 8c0fd3c = 79: c5285f0 trace2:gvfs:experiment: read-cache: time read/write of cache-tree extension

  • 92: 6eaefc6 = 80: 0ed8665 trace2:gvfs:experiment: add region to apply_virtualfilesystem()

  • 93: cd1ce85 = 81: b8fef43 trace2:gvfs:experiment: add region around unpack_trees()

  • 94: 3692982 = 82: b31529b trace2:gvfs:experiment: add region to cache_tree_fully_valid()

  • 95: 4629b89 ! 83: aff9def trace2:gvfs:experiment: add unpack_entry() counter to unpack_trees() and report_tracking()

    @@ packfile.c: void *unpack_entry(struct repository *r, struct packed_git *p, off_t
      	write_pack_access_log(p, obj_offset);
     
      ## packfile.h ##
    -@@ packfile.h: int is_promisor_object(struct repository *r, const struct object_id *oid);
    - int load_idx(const char *path, const unsigned int hashsz, void *idx_map,
    - 	     size_t idx_size, struct packed_git *p);
    +@@ packfile.h: int load_idx(const char *path, const unsigned int hashsz, void *idx_map,
    +  */
    + int parse_pack_header_option(const char *in, unsigned char *out, unsigned int *len);
      
     +/*
     + * Return the number of objects fetched from a packfile.
  • 96: 384f7b4 = 84: a5e0b36 trace2:gvfs:experiment: increase default event depth for unpack-tree data

  • 97: 1489a11 = 85: 3ccceea trace2:gvfs:experiment: add data for check_updates() in unpack_trees()

  • 98: ed48c16 = 86: 2be5e4d Trace2:gvfs:experiment: capture more 'tracking' details

  • 99: aefc9ae = 87: c50cb77 credential: set trace2_child_class for credential manager children

  • 100: 9a9734b = 88: dcf71fa sub-process: do not borrow cmd pointer from caller

  • 101: 87d4eb2 = 89: 166067a sub-process: add subprocess_start_argv()

  • 102: 0a0520d = 90: 2f3b474 sha1-file: add function to update existing loose object cache

  • 103: b7c6146 = 91: 345431b packfile: add install_packed_git_and_mru()

  • 104: 79bf2b6 = 92: 0a0f5f0 index-pack: avoid immediate object fetch while parsing packfile

  • 105: 0df6c63 = 93: 317d0a7 gvfs-helper: create tool to fetch objects using the GVFS Protocol

  • 106: d1c3e0a = 94: f046226 sha1-file: create shared-cache directory if it doesn't exist

  • 107: dcccb28 = 95: a90d8ca gvfs-helper: better handling of network errors

  • 108: 947384c = 96: c3d896a gvfs-helper-client: properly update loose cache with fetched OID

  • 109: 0b58c53 = 97: 55b1c71 gvfs-helper: V2 robust retry and throttling

  • 110: 4817b74 = 98: a22ab61 gvfs-helper: expose gvfs/objects GET and POST semantics

  • 111: 40ae3a9 = 99: 7a54bac gvfs-helper: dramatically reduce progress noise

  • 112: 78c7efc = 100: 50ca17c gvfs-helper-client.h: define struct object_id

  • 113: 3fcc433 = 101: f394fd7 gvfs-helper: handle pack-file after single POST request

  • 114: eb9422f = 102: d3a0365 test-gvfs-prococol, t5799: tests for gvfs-helper

  • 115: acdaf94 = 103: 2f81d39 gvfs-helper: move result-list construction into install functions

  • 116: cbb7d83 = 104: 21e7f37 t5799: add support for POST to return either a loose object or packfile

  • 117: 9cd5daa = 105: d87f0c7 t5799: cleanup wc-l and grep-c lines

  • 118: e086b2a = 106: 45e6315 gvfs-helper: verify loose objects after write

  • 119: 17cb428 = 107: 24a1c1d t7599: create corrupt blob test

  • 120: b2626ef = 108: ecb818e gvfs-helper: add prefetch support

  • 121: 0288b11 = 109: 1909ee1 gvfs-helper: add prefetch .keep file for last packfile

  • 122: d535853 = 110: e92cd75 gvfs-helper: do one read in my_copy_fd_len_tail()

  • 123: 0733f30 = 111: afdd8ea gvfs-helper: move content-type warning for prefetch packs

  • 124: 809e8e3 = 112: 41e4d0c fetch: use gvfs-helper prefetch under config

  • 125: 37848f1 = 113: 9bb58b4 gvfs-helper: better support for concurrent packfile fetches

  • 126: 4aa479d = 114: c5a4a8f remote-curl: do not call fetch-pack when using gvfs-helper

  • 127: ef7be83 = 115: 8d2fdbb fetch: reprepare packs before checking connectivity

  • 128: 904aa60 = 116: 7c8e98a gvfs-helper: retry when creating temp files

  • 129: 806116a = 117: a0c0c62 sparse: avoid warnings about known cURL issues in gvfs-helper.c

  • 130: 7f9bc3c = 118: d1efc18 gvfs-helper: add --max-retries to prefetch verb

  • 131: b282ae7 = 119: 8aa590a t5799: add tests to detect corrupt pack/idx files in prefetch

  • 132: aa86eeb = 120: e64962e gvfs-helper: ignore .idx files in prefetch multi-part responses

  • 133: 53c764a = 121: 90b1c78 t5799: explicitly test gvfs-helper --fallback and --no-fallback

  • 134: 76af555 = 122: c70e49f gvfs-helper: don't fallback with new config

  • 136: b668c69 = 123: 07e0f90 test-gvfs-protocol: add cache_http_503 to mayhem

  • 138: aba1c2f = 124: 0598e5f t5799: add unit tests for new gvfs.fallback config setting

  • 135: 9a6ebd7 ! 125: 920d3f7 maintenance: care about gvfs.sharedCache config

    @@ builtin/gc.c: static int write_loose_object_to_stdin(const struct object_id *oid
      	return ++(d->count) > d->batch_size;
      }
      
    -+static const char *object_dir = NULL;
    ++static const char *shared_object_dir = NULL;
     +
      static int pack_loose(struct maintenance_run_opts *opts)
      {
      	struct repository *r = the_repository;
    -@@ builtin/gc.c: static int pack_loose(struct maintenance_run_opts *opts)
    + 	int result = 0;
      	struct write_loose_object_data data;
      	struct child_process pack_proc = CHILD_PROCESS_INIT;
    - 
    -+	if (!object_dir)
    -+		object_dir = r->objects->odb->path;
    ++	const char *object_dir = r->objects->odb->path;
     +
    ++	/* If set, use the shared object directory. */
    ++	if (shared_object_dir)
    ++		object_dir = shared_object_dir;
    + 
      	/*
      	 * Do not start pack-objects process
      	 * if there are no loose objects.
    @@ builtin/gc.c: static int maintenance_run(int argc, const char **argv, const char
     +	 */
     +	if (!git_config_get_value("gvfs.sharedcache", &tmp_obj_dir) &&
     +	    tmp_obj_dir) {
    -+		object_dir = xstrdup(tmp_obj_dir);
    -+		setenv(DB_ENVIRONMENT, object_dir, 1);
    ++		shared_object_dir = xstrdup(tmp_obj_dir);
    ++		setenv(DB_ENVIRONMENT, shared_object_dir, 1);
     +	}
     +
      	ret = maintenance_run_tasks(&opts, &cfg);
  • 137: 32ab787 = 126: b6749e0 unpack-trees:virtualfilesystem: Improve efficiency of clear_ce_flags

  • 139: 254cf44 = 127: 7592c76 homebrew: add GitHub workflow to release Cask

  • 140: 0d57536 = 128: 7e56c23 Adding winget workflows

  • 141: a717435 = 129: 34700f6 Disable the monitor-components workflow in msft-git

  • 142: 02182c4 = 130: bc62204 .github: enable windows builds on microsoft fork

  • 143: 3a82d29 ! 131: 716a315 release: create initial Windows installer build workflow

    @@ .github/workflows/build-git-installers.yml (new)
     +  # Check prerequisites for the workflow
     +  prereqs:
     +    runs-on: ubuntu-latest
    -+    environment: release
     +    outputs:
     +      tag_name: ${{ steps.tag.outputs.name }}           # The full name of the tag, e.g. v2.32.0.vfs.0.0
     +      tag_version: ${{ steps.tag.outputs.version }}     # The version number (without preceding "v"), e.g. 2.32.0.vfs.0.0
  • 144: 4758384 = 132: 43b4d91 help: special-case HOST_CPU universal

  • 145: 35f2aa5 = 133: a9af4ad release: add Mac OSX installer build

  • 146: d682d30 ! 134: f6400e6 release: build unsigned Ubuntu .deb package

    @@ .github/workflows/build-git-installers.yml: jobs:
        # End build and sign Mac OSX installers
     +
     +  # Build unsigned Ubuntu package
    -+  create-linux-artifacts:
    ++  create-linux-unsigned-artifacts:
     +    runs-on: ubuntu-latest
    ++    container:
    ++      image: ubuntu:16.04 # expanded security maintenance until 04/02/2026, according to https://endoflife.date/ubuntu
    ++      volumes:
    ++        # override /__e/node20 because GitHub Actions uses a version that requires too-recent glibc, see "Install dependencies" below
    ++        - /tmp:/__e/node20
     +    needs: prereqs
     +    steps:
    -+      - name: Install git dependencies
    ++      - name: Install dependencies
     +        run: |
     +          set -ex
    -+          sudo apt-get update -q
    -+          sudo apt-get install -y -q --no-install-recommends gettext libcurl4-gnutls-dev libpcre3-dev asciidoc xmlto
    ++          apt-get update -q
    ++          apt-get install -y -q --no-install-recommends \
    ++            build-essential \
    ++            tcl tk gettext asciidoc xmlto \
    ++            libcurl4-gnutls-dev libpcre2-dev zlib1g-dev libexpat-dev \
    ++            curl ca-certificates
    ++
    ++          # Install a Node.js version that works in older Ubuntu containers (read: does not require very recent glibc)
    ++          NODE_VERSION=v20.18.1 &&
    ++          NODE_URL=https://unofficial-builds.nodejs.org/download/release/$NODE_VERSION/node-$NODE_VERSION-linux-x64-glibc-217.tar.gz &&
    ++          curl -Lo /tmp/node.tar.gz $NODE_URL &&
    ++          tar -C /__e/node20 -x --strip-components=1 -f /tmp/node.tar.gz
     +
     +      - name: Clone git
     +        uses: actions/checkout@v4
    @@ .github/workflows/build-git-installers.yml: jobs:
     +
     +          DESTDIR="$PKGDIR" make -C git -j5 V=1 DEVELOPER=1 \
     +            USE_LIBPCRE=1 \
    ++            USE_CURL_FOR_IMAP_SEND=1 NO_OPENSSL=1 \
     +            NO_CROSS_DIRECTORY_HARDLINKS=1 \
     +            ASCIIDOC8=1 ASCIIDOC_NO_ROFF=1 \
     +            ASCIIDOC='TZ=UTC asciidoc' \
  • 147: 93a5901 ! 135: 4ebc418 release: add signing step for .deb package

    @@ .github/workflows/build-git-installers.yml: jobs:
      
     -  # Build unsigned Ubuntu package
     +  # Build and sign Debian package
    -   create-linux-artifacts:
    +   create-linux-unsigned-artifacts:
          runs-on: ubuntu-latest
    -     needs: prereqs
    -+    environment: release
    -     steps:
    -       - name: Install git dependencies
    -         run: |
    +     container:
     @@ .github/workflows/build-git-installers.yml: jobs:
                # Move Debian package for later artifact upload
                mv "$PKGNAME.deb" "$GITHUB_WORKSPACE"
      
    ++      - name: Upload artifacts
    ++        uses: actions/upload-artifact@v4
    ++        with:
    ++          name: linux-unsigned-artifacts
    ++          path: |
    ++            *.deb
    ++
    ++  create-linux-artifacts:
    ++    runs-on: ubuntu-latest
    ++    needs: [prereqs, create-linux-unsigned-artifacts]
    ++    environment: release
    ++    steps:
     +      - name: Log into Azure
     +        uses: azure/login@v2
     +        with:
    @@ .github/workflows/build-git-installers.yml: jobs:
     +          GPG_KEYGRIP_SECRET_NAME: ${{ secrets.GPG_KEYGRIP_SECRET_NAME }}
     +        run: |
     +          # Install debsigs
    -+          sudo apt install debsigs
    ++          sudo apt-get install -y debsigs
     +
     +          # Download GPG key, passphrase, and keygrip from Azure Key Vault
    -+          key=$(az keyvault secret show --name $GPG_KEY_SECRET_NAME --vault-name $AZURE_VAULT --query "value")
    -+          passphrase=$(az keyvault secret show --name $GPG_PASSPHRASE_SECRET_NAME --vault-name $AZURE_VAULT --query "value")
    -+          keygrip=$(az keyvault secret show --name $GPG_KEYGRIP_SECRET_NAME --vault-name $AZURE_VAULT --query "value")
    -+
    -+          # Remove quotes from downloaded values
    -+          key=$(sed -e 's/^"//' -e 's/"$//' <<<"$key")
    -+          passphrase=$(sed -e 's/^"//' -e 's/"$//' <<<"$passphrase")
    -+          keygrip=$(sed -e 's/^"//' -e 's/"$//' <<<"$keygrip")
    ++          key="$(az keyvault secret show --name "$GPG_KEY_SECRET_NAME" --vault-name "$AZURE_VAULT" --query "value" --output tsv)"
    ++          passphrase="$(az keyvault secret show --name "$GPG_PASSPHRASE_SECRET_NAME" --vault-name "$AZURE_VAULT" --query "value" --output tsv)"
    ++          keygrip="$(az keyvault secret show --name "$GPG_KEYGRIP_SECRET_NAME" --vault-name "$AZURE_VAULT" --query "value" --output tsv)"
     +
     +          # Import GPG key
     +          echo "$key" | base64 -d | gpg --import --no-tty --batch --yes
    @@ .github/workflows/build-git-installers.yml: jobs:
     +          gpg-connect-agent RELOADAGENT /bye
     +          /usr/lib/gnupg2/gpg-preset-passphrase --preset "$keygrip" <<<"$passphrase"
     +
    ++      - name: Download artifacts
    ++        uses: actions/download-artifact@v4
    ++        with:
    ++          name: linux-unsigned-artifacts
    ++
     +      - name: Sign Debian package
     +        run: |
     +          # Sign Debian package
  • 148: 69ebf5f = 136: 1f99600 release: create draft GitHub release with packages & installers

  • 149: 191b4e2 = 137: 07f6052 build-git-installers: publish gpg public key

  • 150: 85c997a = 138: 8c886c0 release: continue pestering until user upgrades

  • 151: 6619583 = 139: 4e30bb0 dist: archive HEAD instead of HEAD^{tree}

  • 152: 075aaa8 = 140: 8a24a5f release: include GIT_BUILT_FROM_COMMIT in MacOS build

  • 153: 131fbe8 = 141: 7363256 release: add installer validation

  • 154: 6e75105 = 142: bea6180 update-microsoft-git: create barebones builtin

  • 155: 09c4420 = 143: c567faa update-microsoft-git: Windows implementation

  • 156: 09d17b9 = 144: 13f763c update-microsoft-git: use brew on macOS

  • 157: bf7295e = 145: 512dfbd .github: update ISSUE_TEMPLATE.md for microsoft/git

  • 158: 99cb2d1 = 146: 6a8250f .github: update PULL_REQUEST_TEMPLATE.md

  • 159: a375236 = 147: 676c07e Adjust README.md for microsoft/git

  • 27: 79b9257 = 148: 1526f65 git_config_set_multivar_in_file_gently(): add a lock timeout

  • 28: 3a6101a = 149: 469b549 scalar: set the config write-lock timeout to 150ms

  • 29: eaf0859 = 150: 4a81210 scalar: add docs from microsoft/scalar

  • 30: 56152d2 = 151: 55c0cef Merge branch 'scalar-gentler-config-locking'

  • 31: 5ab0645 = 152: 6ec5a0d Merge branch 'scalar-extra-docs'

  • 32: d28ad03 = 153: 298b29b scalar (Windows): use forward slashes as directory separators

  • 33: 1f2506f = 154: 9ad768c scalar: add retry logic to run_git()

  • 34: 50c4260 = 155: 4a09510 scalar: support the config command for backwards compatibility

  • 160: 334a31e = 156: f20b0a4 Merge branch 'microsoft/vfs-2.35.0'

  • 161: 07e8277 = 157: 63dfa6e Merge branch 'scalar'

  • 162: 7c04284 = 158: 5a5e189 scalar: implement a minimal JSON parser

  • 163: 864da76 = 159: 2e80737 scalar clone: support GVFS-enabled remote repositories

  • 164: fb522a1 = 160: 49102f6 test-gvfs-protocol: also serve smart protocol

  • 165: 8668424 = 161: 1fa4f46 gvfs-helper: add the endpoint command

  • 166: 3028c8c = 162: a8a4485 dir_inside_of(): handle directory separators correctly

  • 167: 500c10a = 163: 0f4bc44 scalar: disable authentication in unattended mode

  • 168: 42d4138 = 164: c270115 scalar: do initialize gvfs.sharedCache

  • 169: 9be5a2c = 165: b636dc0 scalar diagnose: include shared cache info

  • 170: 7b43037 = 166: 91ffe1a scalar: only try GVFS protocol on https:// URLs

  • 171: a3d1380 = 167: df4f0a6 scalar: verify that we can use a GVFS-enabled repository

  • 172: 5ab2cbf = 168: 1db87ec scalar: add the cache-server command

  • 173: 0f6df8b = 169: 380bb89 scalar: add a test toggle to skip accessing the vsts/info endpoint

  • 174: 31d933b = 170: 54783df scalar: adjust documentation to the microsoft/git fork

  • 175: 30c8cc6 = 171: 22e1322 scalar: enable untracked cache unconditionally

  • 176: 9ae4ebe = 172: 8116d20 scalar: parse clone --no-fetch-commits-and-trees for backwards compatibility

  • 177: c7989a2 = 173: 21fa0fd scalar: make GVFS Protocol a forced choice

  • 178: 12d9968 = 174: becf22c scalar diagnose: accommodate Scalar's Functional Tests

  • 179: 0ca5b50 ! 175: efd5b8f ci: run Scalar's Functional Tests

    @@ .github/workflows/scalar-functional-tests.yml (new)
     +
     +      - name: Archive Trace2 Logs
     +        if: ( success() || failure() ) && ( steps.trace2_zip_unix.conclusion == 'success' || steps.trace2_zip_windows.conclusion == 'success' )
    -+        uses: actions/upload-artifact@v3
    ++        uses: actions/upload-artifact@v4
     +        with:
     +          name: ${{ env.TRACE2_BASENAME }}.zip
     +          path: scalar/${{ env.TRACE2_BASENAME }}.zip
  • 181: e74dc57 = 176: aae1e8f scalar: upgrade to newest FSMonitor config setting

  • 180: 17a9dc5 = 177: 93b7999 Merge branch 'scalar-with-gvfs'

  • 182: 3afffc9 = 178: eb80bf4 Merge branch 'run-scalar-functional-tests'

  • 183: d7579e0 = 179: aa3fed6 abspath: make strip_last_path_component() global

  • 184: 1eb82d1 = 180: 19134cb scalar: configure maintenance during 'reconfigure'

  • 185: 1d1eb95 = 181: e4deb5b Merge branch 'scalar-reconfigure'

  • 186: 5073191 = 182: b47a29c scalar: .scalarCache should live above enlistment

  • 187: 850cf4d = 183: 6b8f6c9 Merge branch 'scalar-and-non-interactive-authentication-in-maintenance'

  • 194: 99de5bf = 184: 5f1b33c Merge pull request Allow --no-src during clones and git worktree after clones #536: Allow --no-src during clones and git worktree after clones

  • 188: 47db922 = 185: 4250d6d add/rm: allow adding sparse entries when virtual

  • 189: 32ef1f4 = 186: a133894 sparse-checkout: add config to disable deleting dirs

  • 190: 6ea1db9 = 187: f053ba3 diff: ignore sparse paths in diffstat

  • 191: 4f83c50 = 188: 73b88a1 Merge pull request add: allow adding sparse entries when virtual #392: add: allow adding sparse entries when virtual

  • 192: 5ac80b9 = 189: 6e6b8fc repo-settings: enable sparse index by default

  • 193: 4870467 = 190: c44ea83 Merge pull request Sparse Index: latest integrations #410: Sparse Index: latest integrations

  • 195: 5980fb0 = 191: 4081322 Merge pull request Make sparse index the default #414: Make sparse index the default

  • 196: 8df952e = 192: 8fff938 diff(sparse-index): verify with partially-sparse

  • 197: 953c027 = 193: 22bca7b Merge pull request diff: enable and test the sparse index #419 from ldennington/sparse-index-diff

  • 198: c66ff5c = 194: d6f8f4c stash: expand testing for git stash -u

  • 35: 4da0568 = 195: 1df7b6f sequencer: avoid progress when stderr is redirected

  • 199: 40a22ef = 196: 2278619 Merge pull request Sparse index: integrate with clean and stash -u #430 from vdye/sparse-index/clean

  • 200: 8ed262d = 197: 4198780 Merge pull request sequencer: avoid progress when stderr is redirected #432: sequencer: avoid progress when stderr is redirected

  • 201: 52c6b5d = 198: 528521c sparse: add vfs-specific precautions

  • 202: 375acdd = 199: 8b4a143 reset: fix mixed reset when using virtual filesystem

  • 203: 8c3bc69 = 200: 15b2ab7 Merge pull request reset: fix mixed reset when using virtual filesystem #494: reset: fix mixed reset when using virtual filesystem

  • 70: 23bb81d = 201: 6259631 Merge core VFS features

  • 71: 668aeb8 = 202: fbc2654 Merge advanced VFS-specific features

  • 72: 996d0fe = 203: 58b90d9 Merge virtualfilesystem hook

  • 204: 478e8de = 204: ff2be29 Merge updates to serialized status

  • 205: 98bfe82 = 205: a25cba0 Merge trace2 experimental regions

  • 206: 980f6c4 = 206: bcaafd5 Merge first wave of gvfs-helper feature

  • 207: 4324052 = 207: 9198c57 Merge gvfs-helper prefetch feature

  • 208: 182c009 = 208: e762b95 Harden gvfs-helper to validate the packfiles in a multipart prefetch response (Harden gvfs-helper to validate the packfiles in a multipart prefetch response #571)

  • 209: b60466a = 209: dc7e291 gvfs-helper: add gvfs.fallback and unit tests (gvfs-helper: add gvfs.fallback and unit tests #665)

  • 210: a67e821 = 210: c186248 Merge pull request Update 'git maintenance' to match upstream #301: Update 'git maintenance' to match upstream

  • 211: ae08c5b = 211: 942a819 Merge pull request unpack-trees:virtualfilesystem: Improve efficiency of clear_ce_flags #315: unpack-trees:virtualfilesystem: Improve efficiency of clear_ce_flags

  • 212: ca356d1 = 212: 8a6c649 Merge branch 'add-workflows'

  • 213: 165f0fb = 213: 7b9bec2 Merge branch 'adjust-g4w-workflows'

  • 214: 096f1c8 = 214: 070cffc Merge pull request Implement workflow to create GitHub release with attached git installers #399 from vdye/feature/build-installers

  • 215: 8bc95e9 = 215: 4e29e60 Merge pull request Fixes for MacOS release build & build options #472 from vdye/ms/macos-build-options

  • 216: 07ed991 = 216: e338839 Merge pull request Add git update-microsoft-git #329: Add git update-microsoft-git

  • 217: 1fc1680 = 217: 59c47e1 Merge pull request Giving microsoft/git it's own README #333: update microsoft/git README

  • 218: 16b21b2 = 218: 6c4bdc1 Merge pull request Fix the built-in FSMonitor, and run Scalar's Functional Tests as part of the automated builds #371 from dscho/run-scalar-functional-tests-and-fix-built-in-fsmonitor

  • 219: 5d7750d = 219: 8f6e9ca Merge branch 'sparse-index-stuff'

  • 220: 19c0322 = 220: 1991d52 sparse-index: add ensure_full_index_with_reason()

  • 221: 9cb2790 = 221: 7a919dc treewide: add reasons for expanding index

  • 222: 2332092 = 222: 74f0e1c treewide: custom reasons for expanding index

  • 223: e6220cf = 223: d89823c sparse-index: add macro for unaudited expansions

  • 224: 1c7e787 = 224: 82f663a Docs: update sparse index plan with logging

  • 225: c69d14f = 225: d86e967 sparse-index: log failure to clear skip-worktree

  • 226: bd9a755 = 226: 9311bde Sparse Index: log why the index is being expanded (Sparse Index: log why the index is being expanded #691)

  • 227: b210e77 = 227: d4f8e8c stash: use -f in checkout-index child process

  • 228: 9d5c423 = 228: 05dca1b sparse-index: do not copy hashtables during expansion

  • 229: b6c9927 = 229: 51f47a6 Fix rare segfault in sparse-index (Fix rare segfault in sparse-index #690)

  • 230: 6548dbd = 230: 501634b t5616: mark tests as bogus with --path-walk

  • 231: 93178ea = 231: 2e31da5 path-walk: add new 'edge_aggressive' option

  • 232: 9f0c7c7 = 232: 4a7f1dd pack-objects: allow --shallow and --path-walk

  • 233: 2cd3a3f = 233: 19094f4 t5538: add test to confirm deltas in shallow pushes

  • 234: 04428e4 = 234: 6eb3258 pack-objects: allow --path-walk with --shallow (pack-objects: allow --path-walk with --shallow #699)

  • 235: 05c4c1d = 235: 71e11fb sub-process: avoid leaking cmd

  • 236: ce632e9 = 236: 78daa0b remote-curl: release filter options before re-setting them

  • 237: 2955dc8 = 237: 4d43345 transport: release object filter options

  • 238: 344af5c = 238: dea383c Merge branch 'leak-fixes'

  • 239: 7e6ed7f = 239: 9551455 mingw: special-case administrators even more

  • 240: eb1cff5 = 240: be80005 test-tool path-utils: support debugging "dubious ownership" issues

  • 241: 2c95417 = 241: 39b94fd mingw: special-case administrators even more (mingw: special-case administrators even more #712)

  • 242: 87a4fa3 = 242: c775ce5 push: don't reuse deltas with path walk

  • 243: 27273ae = 243: e67bc8e pack-objects: don't reuse deltas with path walk (pack-objects: don't reuse deltas with path walk #707)

  • 244: 0908f83 = 244: 134fb83 release-winget.yml: update command to include ARM installers

  • 245: c40fd26 = 245: e4074b2 Fix WinGet release workflow to account for new installation matrix (Fix WinGet release workflow to account for new installation matrix #718)

  • 246: 2651f3f < -: ------------ fixup! release: create initial Windows installer build workflow

  • 247: f1efa3d < -: ------------ fixup! release: build unsigned Ubuntu .deb package

  • 248: 0d2447e < -: ------------ fixup! release: build unsigned Ubuntu .deb package

  • 249: 25afe33 < -: ------------ fixup! release: build unsigned Ubuntu .deb package

  • 250: a678566 < -: ------------ fixup! release: build unsigned Ubuntu .deb package

  • 251: ba48074 < -: ------------ build-git-installers: target an older Ubuntu version (build-git-installers: target an older Ubuntu version #719)

  • 252: ee8f79c < -: ------------ fixup! maintenance: care about gvfs.sharedCache config

  • 253: 4afc5ec = 246: 63d80ba t7900-maintenance.sh: reset config between tests

  • 254: adc9200 = 247: 7c53544 maintenance: add cache-local-objects maintenance task

  • 255: 510b7d4 = 248: d0967a3 scalar.c: add cache-local-objects task

  • 256: f6f1dad = 249: 21e22b9 maintenance: add new cache-local-objects maintenance task (maintenance: add new cache-local-objects maintenance task #720)

  • 257: e762f1e < -: ------------ fixup! ci: run Scalar's Functional Tests

No big surprises there, basically a lot of fixup! stuff getting squashed. The most important part is that git diff microsoft/tentative/vfs-2.48.0 tentative/vfs-2.48.1 -- .github/workflows/build-git-installers.yml is empty, i.e. I did not mess up with the merge-conflict resolution.

Ah, Meson. You again.

Signed-off-by: Johannes Schindelin <[email protected]>
@dscho dscho changed the title [DO NOT MERGE YET] Rebase to v2.48.1 Rebase to v2.48.1 Feb 13, 2025
@dscho dscho marked this pull request as ready for review February 13, 2025 15:03
@dscho dscho merged commit bda3f91 into vfs-2.48.1 Feb 13, 2025
104 checks passed
@dscho dscho deleted the tentative/vfs-2.48.1 branch February 13, 2025 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.