Rebase to v2.55.0-rc0#936
Conversation
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Jeff Hostetler <jeffhostetler@github.com>
It is possible that a loose object that is written from a GVFS protocol "get object" request does not match the expected hash. Error out in this case. 2021-10-30: The prototype for read_loose_object() changed in 31deb28 (fsck: don't hard die on invalid object types, 2021-10-01) and 96e41f5 (fsck: report invalid object type-path combinations, 2021-10-01). Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
When we create temp files for downloading packs, we use a name based on the current timestamp. There is no randomness in the name, so we can have collisions in the same second. Retry the temp pack names using a new "-<retry>" suffix to the name before the ".temp". Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Add "mayhem" keys to generate corrupt packfiles and/or corrupt idx files in prefetch by trashing the trailing checksum SHA. Add unit tests to t5799 to verify that `gvfs-helper` detects these corrupt pack/idx files. Currently, only the (bad-pack, no-idx) case is correctly detected, Because `gvfs-helper` needs to locally compute the idx file itself. A test for the (bad-pack, any-idx) case was also added (as a known breakage) because `gvfs-helper` assumes that when the cache server provides both, it doesn't need to verify them. We will fix that assumption in the next commit. Signed-off-by: Jeff Hostetler <jeffhostetler@github.com>
Teach helper/test-gvfs-protocol to be able to send corrupted loose blobs. Add unit test for gvfs-helper to detect receipt of a corrupted loose blob. Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
`sparse` complains with an error message like this: gvfs-helper.c:2912:17: error: expression using sizeof on a function The culprit is this line: curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite); Similar lines exist in `http-push.c` and other files that are in upstream Git, and to avoid these bogus warnings, they are already exempted from `sparse`'s tender, loving care. We simply add `gvfs-helper.c` to that list. Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
The GVFS cache server can return multiple pairs of (.pack, .idx) files. If both are provided, `gvfs-helper` assumes that they are valid without any validation. This might cause problems if the .pack file is corrupt inside the data stream. (This might happen if the cache server sends extra unexpected STDERR data or if the .pack file is corrupt on the cache server's disk.) All of the .pack file verification logic is already contained within `git index-pack`, so let's ignore the .idx from the data stream and force compute it. This defeats the purpose of some of the data cacheing on the cache server, but safety is more important. Signed-off-by: Jeff Hostetler <jeffhostetler@github.com>
Add a new JavaScript GitHub Action to download secrets from Azure Key Vault using the `az` CLI, mask the secret values, and store them as: * outputs, * environment variables, or * files; Values are all masked for safe consumption by other steps in a workflow. Callers of this action can optionally perform base64 decoding of secret values using the syntax: `INPUT base64> OUTPUT`. It is assumed that the `az login` command has already been run prior to this action being invoked. Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
Add a manual-only GitHub Actions workflow for building the Windows installer (x86_64 plus portable Git), driven via `workflow_dispatch:`. The production release path for the official microsoft/git installers lives in .azure-pipelines/release.yml; this workflow is kept around as a fallback so the Windows installer can still be produced on demand for debugging or comparison. The build steps are pinned to `windows-2019` (rather than `windows-latest`) to ensure the correct Visual Studio version is used (verified in the pipeline via `type -p mspdb140.dll`), and the SDK used is the `full` flavor rather than `build-installers` due to a known (but not-yet-fixed) issue downloading the `build-installers` flavor with the `git-for-windows/setup-git-for-windows-sdk` Action. There is no code-signing certificate available to this workflow, so the artifacts it produces are unsigned and must not be published as releases; they are useful only for build-time debugging. Signed-off-by: Victoria Dye <vdye@github.com> Assisted-by: Claude Opus 4.7 Co-authored-by: Matthew John Cheetham <mjcheetham@outlook.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
When building Git as a universal binary on macOS, the binary supports more than one target architecture. This is a bit of a problem for the `HOST_CPU` setting that is woefully unprepared for such a situation, as it wants to show architecture hard-coded at build time. In preparation for releasing universal builds, work around this by special-casing `universal` and replacing it at run-time with the known values `x86_64` or `arm64`. Signed-off-by: Jeff Hostetler <jeffhostetler@github.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
- include `scalar` - build signed .dmg & .pkg for target OS version 10.6 - upload artifacts to workflow Co-authored-by: Lessley Dennington <ldennington@github.com>
Construct 2 new unit tests to explicitly verify the use of `--fallback` and `--no-fallback` arguments to `gvfs-helper`. When a cache-server is enabled, `gvfs-helper` will try to fetch objects from it rather than the origin server. If the cache-server fails (and all cache-server retry attempts have been exhausted), `gvfs-helper` can optionally "fallback" and try to fetch the objects from the origin server. (The retry logic is also applied to the origin server, if the origin server fails on the first request.) Add new unit tests to verify that `gvfs-helper` respects both the `--max-retries` and `--[no-]fallback` arguments. We use the "http_503" mayhem feature of the `test_gvfs_protocol` server to force a 503 response on all requests to the cache-server and the origin server end-points. We can then count the number of connection requests that `gvfs-helper` makes to the server and confirm both the per-server retries and whether fallback was attempted. Signed-off-by: Jeff Hostetler <jeffhostetler@github.com>
- include `scalar` - build & upload unsigned .deb package Co-authored-by: Lessley Dennington <ldennington@github.com> Co-authored-by: Sverre Johansen <sverre.johansen@gmail.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
By default, GVFS Protocol-enabled Scalar clones will fall back to the origin server if there is a network issue with the cache servers. However (and especially for the prefetch endpoint) this may be a very expensive operation for the origin server, leading to the user being throttled. This shows up later in cases such as 'git push' or other web operations. To avoid this, create a new config option, 'gvfs.fallback', which defaults to true. When set to 'false', pass '--no-fallback' from the gvfs-helper client to the child gvfs-helper server process. This will allow users who have hit this problem to avoid it in the future. In case this becomes a more widespread problem, engineering systems can enable the config option more broadly. Enabling the config will of course lead to immediate failures for users, but at least that will help diagnose the problem when it occurs instead of later when the throttling shows up and the server load has already passed, damage done. Signed-off-by: Derrick Stolee <stolee@gmail.com>
- sign using Azure-stored certificates & client - sign on Windows agent via python script - job skipped if credentials for accessing certificate aren't present Co-authored-by: Lessley Dennington <ldennington@github.com> Co-authored-by: Sverre Johansen <sverre.johansen@gmail.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Create new `cache_http_503` mayhem method where only the cache server sends a 503. The normal `http_503` directs both cache and origin server to send 503s. This will be used to help test fallback. Signed-off-by: Jeff Hostetler <jeffhostetler@github.com>
Add a GitHub workflow that is triggered on the `release` event to automatically update the `microsoft-git` Homebrew Cask on the `microsoft/git` Tap. A secret `HOMEBREW_TOKEN` with push permissions to the `microsoft/homebrew-git` repository must exist. A pull request will be created at the moment to allow for last minute manual verification. Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
It really does not make sense to run that workflow in any fork of git-for-windows/git. Typically, it is enough to simply disable it (since it is a scheduled workflow, it is disabled by default in any new fork). However, in microsoft/git, we switch the default branch whenever we rebase to a new upstream version, and every time we do so, this scheduled workflow gets re-enabled. Let's just delete it in microsoft/git and never be bothered by it again. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
- create release & uploads artifact using Octokit - use job "if" condition to handle uploading signed *or* unsigned .deb Co-authored-by: Lessley Dennington <ldennington@github.com>
Signed-off-by: Jeff Hostetler <jeffhostetler@github.com>
For Scalar and VFS for Git, we use an alternate as a shared object cache. We need to enable the maintenance builtin to work on that shared object cache, especially in the background. 'scalar run <task>' would set GIT_OBJECT_DIRECTORY to handle this. We set GIT_OBJECT_DIRECTORY based on the gvfs.sharedCache config, but we also need the checks in pack_loose() to look at that object directory instead of the current ODB's. Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
When the virtualfilesystem is enabled the previous implementation of clear_ce_flags would iterate all of the cache entries and query whether each one is in the virtual filesystem to determine whether to clear one of the SKIP_WORKTREE bits. For each cache entry, we would do a hash lookup for each parent directory in the is_included_in_virtualfilesystem function. The former approach is slow for a typical Windows OS enlistment with 3 million files where only a small percentage is in the virtual filesystem. The cost is O(n_index_entries * n_chars_per_path * n_parent_directories_per_path). In this change, we use the same approach as apply_virtualfilesystem, which iterates the set of entries in the virtualfilesystem and searches in the cache for the corresponding entries in order to clear their flags. This approach has a cost of O(n_virtual_filesystem_entries * n_chars_per_path * log(n_index_entries)). The apply_virtualfilesystem code was refactored a bit and modified to clear flags for all names that 'alias' a given virtual filesystem name when ignore_case is set. n_virtual_filesystem_entries is typically much less than n_index_entries, in which case the new approach is much faster. We wind up building the name hash for the index, but this occurs quickly thanks to the multi-threading. Signed-off-by: Neeraj Singh <neerajsi@ntdev.microsoft.com>
This was disabled by a0da6de (ci: only run win+VS build & tests in Git for Windows' fork, 2022-12-19) to avoid other forks doing too many builds. But we want to keep these builds for the microsoft/git fork. Signed-off-by: Derrick Stolee <derrickstolee@github.com>
Update `git archive` tree-ish argument from `HEAD^{tree}` to `HEAD`. By
using a commit (rather than tree) reference, the commit hash will be stored
as an extended pax header, extractable git `git get-tar-commit-id`.
The intended use-case for this change is building `git` from the output of
`make dist` - in combination with the ability to specify a fallback
`GIT_BUILT_FROM_COMMIT`, a user can extract the commit ID used to build the
archive and set it as `GIT_BUILT_FROM_COMMIT`. The result is fully-populated
information for the commit hash in `git version --build-options`.
Signed-off-by: Victoria Dye <vdye@github.com>
Just do the boilerplate stuff of making a new builtin, including documentation and integration with git.c. Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
We had been using the default issue template from git-for-windows/git, but we should ask different questions than Git for Windows. Update the issue template to ask these helpful questions. Signed-off-by: Derrick Stolee <derrickstolee@github.com>
In particular when multiple processes want to write to the config simultaneously, it would come in handy to not fail immediately when another process locked the config, but to gently try again. This will help with Scalar's functional test suite which wants to register multiple repositories for maintenance semi-simultaneously. As not all code paths calling this function read the config (e.g. `git config`), we have to read the config setting via `git_config_get_ulong()`. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Update build-git-installers workflow to publish `microsoft/git`'s GPG public key as part of each release. Add explanation for how to use this key to verify the Debian package's signature to the README.
It's now harder to get to the loose object cache, intentionally so, because it's somewhat of an internal implementation detail whether or not the ODB is backed (partially) by a loose object backend. For the time being, we're on the safe side, though: This functionality is required for the GVFS helper, and VFS for Git does not (yet) need to adapt to pluggable ODBs. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The test `'scalar clone: all verbs with different servers'` added by this commit registers `per_test_cleanup` as a `test_when_finished` hook and then starts gvfs-protocol server instances 1, 2, 3, *and 4*. However, `per_test_cleanup` in `t/lib-gvfs-helper.sh` only iterates over instances 0 through 3, so instance 4's pid file (`pid-file-4.pid`) is never deleted. The `test-gvfs-protocol.exe` that backs instance 4 watches its pid file and shuts down only when that file disappears, so it keeps running forever, listening on the shifted-by-40000 port. On Linux the leaked daemon is harmless: when its grandparent shell exits, the daemon is reparented to init and the test process tree is free to terminate. On Windows, however, the subshell that backgrounded the `test-gvfs-protocol.exe` inherits standard handles to the parent `prove` worker, and those handles keep the subshell alive as long as the daemon is alive. The end result is that `make test` for the slice containing `t9210-scalar.sh` never returns even after every individual test script has produced its exit code file: the parallel test runner is still waiting on the wedged subshell. This is exactly what we observed in https://github.com/microsoft/git/actions/runs/27409166978, where the three Windows test slices that contain `t9210-scalar.sh` (`win test (6)` and `win+VS test (6)` in prove-slice 7 of 10, plus `win+Meson test (7)` in meson-slice 8 of 10) were stuck for several hours while every other Windows test slice completed in five to twelve minutes. Extend the cleanup loop to also stop instance 4 so the daemon can exit and the subshell can drain. Assisted-by: Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The origin server's stderr log was placed at "OUT.server.$GIT_TEST_GVFS_PROTOCOL_ORIGIN_PORT.log", which matches the "OUT.*" glob that `per_test_cleanup` in `t/lib-gvfs-helper.sh` uses to wipe per-test output between tests. The shared lib's intent when it runs `rm -rf OUT.*` is to discard files like "OUT.gvfs.server.log" and "OUT.server-1.log" through "OUT.server-4.log" that it owns, plus per-test scratch like "OUT.output" and "OUT.stderr". It is not aware of t9210's separate "origin" server, so once any test in t9210 registers `per_test_cleanup` as a `test_when_finished` hook, the origin server's log gets blown away as a side effect. By the time `test_atexit` runs at the end of the script, it can still find the pid-file (which lives at "pid-file.$port.pid" and is outside the glob) and tear the origin server down, but the subsequent `grep "Starting graceful shutdown" "$ORIGIN_SERVER_LOG"` always fails because the log is gone, so the loop times out and `test_atexit` returns 1. That turns the whole script into a failure (`Wstat: 256 (exited 1) Tests: 37 Failed: 0`) even though every individual test passed. See for example https://github.com/microsoft/git/actions/runs/27424512013 where this exit-1 cleanup symptom shows up across `win test (6)`, `win+VS test (6)`, and every Linux containerized job once the unrelated hang fix unblocks them. The original intent of this commit was to namespace t9210's variables so they no longer collide with the shared lib's; the file name still collides with the shared lib's cleanup glob, which contradicts that intent. Move the log file out of the "OUT.*" glob by naming it "server-origin.$port.log" instead. The pid-file is already outside the glob, so no rename is needed there. Assisted-by: Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The test scripts `t7522-serialized-status.sh` and `t7523-status-complete-untracked.sh` introduced by this commit inspect `git status` output that includes the ignored section. Since the upstream change "test-lib: allow bare repository access when breaking changes are enabled", `test-lib.sh` writes a `$HOME/.gitconfig` (containing `safe.bareRepository = all`) and adds that file to `.git/info/exclude` whenever `WITH_BREAKING_CHANGES` is enabled. Because `$HOME` and the test repository's working tree share the same trash directory, the `.gitconfig` file shows up as `! .gitconfig` in any `git status --ignored` output. Upstream Git addressed this in its own status-related tests by filtering `.gitconfig` from comparison input via a new `test_filter_gitconfig` helper, but it did not (and could not) touch these microsoft/git downstream tests. In the `linux-breaking-changes (ubuntu:rolling)` CI job at https://github.com/microsoft/git/actions/runs/27434672980 this manifests as three failures in `t7522` (subtests 2, 4, and 5) and one failure in `t7523`, all with the same diff: +! .gitconfig ! ignored.ign ! ignored_dir/ Apply the same `test_filter_gitconfig` treatment to the four affected subtests here. Only the subtests whose expected output includes the ignored section need the filter; the remaining subtests in `t7522` either skip `--ignored` on the deserialize side or scope the output to a path that excludes `.gitconfig`, so they are unaffected. Verified in a WSL checkout of the branch tip (`9133d1cce3e2`) by building with `WITH_BREAKING_CHANGES=YesPlease` and running both scripts: before this change, `t7522` reports `# failed 3 among 16 test(s)` and `t7523` reports `not ok 2`; after this change, both scripts report `# passed all`. Assisted-by: Opus 4.7 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Now that Rust is opt-out in upstream Git, we better install `cargo` (or define `NO_RUST`, but the former will age better). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2828f27 to
25398eb
Compare
derrickstolee
left a comment
There was a problem hiding this comment.
Lots of squashes made the range-diff big, but things look good!
Right. I should have first squashed the fixups, created a |
…taller The macOS universal build compiles C code with `-arch arm64 -arch x86_64` but `cargo build --release` only targets the host architecture (arm64 on the Apple Silicon runner). The linker then ignores all arm64-only objects from libgitcore.a when linking the x86_64 slice, resulting in undefined symbols for `_decode_varint` and `_encode_varint`. Build the Rust static library for both targets explicitly and lipo them into a universal `target/release/libgitcore.a` before invoking `make payload`, mirroring how the pipeline already produces a universal libintl.a from two arch-specific Homebrew copies.
The Makefile now requires `cargo` to build `target/release/libgitcore.a`
(Rust is enabled by default since upstream's bc/rust-by-default topic),
but the 1ES Ubuntu build agents do not ship a Rust toolchain. The build
fails with:
make: cargo: No such file or directory
make: *** [Makefile:3057: target/release/libgitcore.a] Error 127
Add `cargo` to the apt-get install list, matching what was done for the
Scalar functional tests in 25398eb.
For now, we opt out of building with the Rust bits. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The version that is reported by the `git` executable on Linux does not replace `-rc` by `.rc`, for some reason. We're not going to ship any RC reason anyway, therefore this deviation from before does not matter. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
…cOS installer Need to pre-gemerate the build flags so that the `libgitcore.a` is not rebuilt. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
…taller Turns out that `make dist` _also_ builds Git. It's all a bit wasteful, still, even if a lot of wasteful bits have been removed since moving away from the original https://github.com/timcharper/git_osx_installer. So we need to build the universal ("fat") libgitcore.a _twice_, too. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
…taller Turns out that `libgit.a` is a dependency of `libgitcore.a`; If the former gets rebuilt, the latter is force-rebuilt. Strange but true. Therefore, if we want to have a universal version of the latter and do not want it to be overwritten with a non-universal one, we first have to build the former and then the universal variant of the latter. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
…taller I have no idea why things are so different in Azure Pipelines than they were in the GitHub workflow, but the `-rc` part of the file name generated via `make dist` and friends no longer is converted to `.rc`, as it had been before. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
…taller It looks as if even more places need to stop that `-rc` -> `.rc` business. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
…taller Okay, this pre-generation of the universal libgitcore.a did not work. Time for more invasive maneuvers. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
…taller Let's do this in one go, and fix the path to the x86_64 library. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Unless NO_RUST is defined, the varint encoder/decoder lives in the
RUST_LIB, which needs to be linked. Symptom:
cc [... -o contrib/credential/osxkeychain/git-credential-osxkeychain [...]
Undefined symbols for architecture x86_64:
"_decode_varint", referenced from:
_read_untracked_extension in libgit.a[x86_64][63](dir.o)
_read_untracked_extension in libgit.a[x86_64][63](dir.o)
_read_one_dir in libgit.a[x86_64][63](dir.o)
_read_one_dir in libgit.a[x86_64][63](dir.o)
_load_cache_entry_block in libgit.a[x86_64][174](read-cache.o)
"_encode_varint", referenced from:
_write_untracked_extension in libgit.a[x86_64][63](dir.o)
_write_untracked_extension in libgit.a[x86_64][63](dir.o)
_write_untracked_extension in libgit.a[x86_64][63](dir.o)
_write_one_dir in libgit.a[x86_64][63](dir.o)
_write_one_dir in libgit.a[x86_64][63](dir.o)
_do_write_index in libgit.a[x86_64][174](read-cache.o)
ld: symbol(s) not found for architecture x86_64
Instead of trying to play games to add `GITLIBS` while filtering out
`common-main.o`, replace the `$(LIB_FILE) $(EXTLIBS)` construct with the
much shorter `$(LIBS)` construct that _already_ filters out
`common-main.o` and adds the Rust library when needed.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
And here it is: https://github.com/microsoft/git/compare/vfs-2.55.0-rc0..microsoft:git:clean-vfs-2.55.0-rc0 |
Range-diff relative to vfs-2.54.0
1: a8452ef ! 1: e976362 survey: calculate more stats on refs
@@ builtin/survey.c: static void survey_report_plaintext_refs(struct survey_context } @@ builtin/survey.c: static void survey_phase_refs(struct survey_context *ctx) for (int i = 0; i < ctx->ref_array.nr; i++) { - unsigned long size; + size_t size; struct ref_array_item *item = ctx->ref_array.items[i]; + size_t len = strlen(item->refname);2: 2321fd6 ! 2: cfcc439 survey: show some commits/trees/blobs histograms
3: 6fdf945 = 3: 3ad2074 survey: add vector of largest objects for various scaling dimensions
4: 0ca3873 = 4: 6ba2177 survey: add pathname of blob or tree to large_item_vec
5: db1cdd0 = 5: ca28c42 survey: add commit-oid to large_item detail
6: e6ba70a = 6: bd06347 survey: add commit name-rev lookup to each large_item
7: 8534ebc = 7: 7e6152a survey: add --no-name-rev option
10: 891f70c = 8: e2461c2 sparse-index.c: fix use of index hashes in expand_index
8: cacaeb0 = 9: 4f0737c survey: started TODO list at bottom of source file
12: 71a54dc = 10: 5252692 t5300: confirm failure of git index-pack when non-idx suffix requested
11: 4cdb47d = 11: e55b8e0 t: remove advice from some tests
14: 411229f = 12: 6ca2226 t1092: add test for untracked files and directories
9: 84c21fb = 13: b55b3e8 survey: expanded TODO list at the bottom of the source file
15: d48ea40 = 14: f2debf2 index-pack: disable rev-index if index file has non .idx suffix
16: 7a375bf = 15: 101caff trace2: prefetch value of GIT_TRACE2_DST_DEBUG at startup
13: 4a3622e = 16: 39d9294 survey: expanded TODO with more notes
17: bfe187a = 17: d1e7207 reset --stdin: trim carriage return from the paths
18: b8ce767 ! 18: 4b60ba5 Identify microsoft/git via a distinct version suffix
19: 74aaaed = 19: 16135da gvfs: ensure that the version is based on a GVFS tag
20: 9037a12 = 20: ba57143 gvfs: add a GVFS-specific header file
21: 3bb5350 = 21: 48abb0e gvfs: add the core.gvfs config setting
22: 2e5589d = 22: f5c5222 gvfs: add the feature to skip writing the index' SHA-1
23: 8d12904 = 23: f21096b gvfs: add the feature that blobs may be missing
24: 1210bf1 = 24: 6e5b6c4 gvfs: prevent files to be deleted outside the sparse checkout
25: 2a26b3e = 25: 1527ed1 gvfs: optionally skip reachability checks/upload pack during fetch
26: 6c77873 = 26: f32c48f gvfs: ensure all filters and EOL conversions are blocked
27: 25b9de3 ! 27: 4a43cc3 gvfs: allow "virtualizing" objects
28: 397b60d ! 28: 776bc05 Hydrate missing loose objects in check_and_freshen()
29: e611a66 ! 29: 32db9e1 sha1_file: when writing objects, skip the read_object_hook
@@ Commit message Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> ## object-file.c ## -@@ object-file.c: int check_and_freshen_file(const char *fn, int freshen) - - static int check_and_freshen_source(struct odb_source *source, - const struct object_id *oid, -- int freshen) -+ int freshen, int skip_virtualized_objects) - { - static struct strbuf path = STRBUF_INIT; - int ret, tried_hook = 0; -@@ object-file.c: static int check_and_freshen_source(struct odb_source *source, - odb_loose_path(source, &path, oid); - retry: - ret = check_and_freshen_file(path.buf, freshen); -- if (!ret && gvfs_virtualize_objects(source->odb->repo) && !tried_hook) { -+ if (!ret && gvfs_virtualize_objects(source->odb->repo) && -+ !skip_virtualized_objects && !tried_hook) { - tried_hook = 1; - if (!read_object_process(source->odb->repo, oid)) - goto retry; -@@ object-file.c: static int check_and_freshen_source(struct odb_source *source, - int odb_source_loose_has_object(struct odb_source *source, - const struct object_id *oid) - { -- return check_and_freshen_source(source, oid, 0); -+ return check_and_freshen_source(source, oid, 0, 0); - } - - int format_object_header(char *str, size_t size, enum object_type type, -@@ object-file.c: static int write_loose_object(struct odb_source *source, - } - - int odb_source_loose_freshen_object(struct odb_source *source, -- const struct object_id *oid) -+ const struct object_id *oid, -+ int skip_virtualized_objects) - { -- return !!check_and_freshen_source(source, oid, 1); -+ return !!check_and_freshen_source(source, oid, 1, skip_virtualized_objects); - } - - int odb_source_loose_write_stream(struct odb_source *source, -@@ object-file.c: int odb_source_loose_write_stream(struct odb_source *source, +@@ object-file.c: int odb_source_loose_write_stream(struct odb_source_loose *loose, die(_("deflateEnd on stream object failed (%d)"), ret); - close_loose_object(source, fd, tmp_file.buf); + close_loose_object(loose, fd, tmp_file.buf); -- if (odb_freshen_object(source->odb, oid)) { -+ if (odb_freshen_object(source->odb, oid, 1)) { +- if (odb_freshen_object(loose->base.odb, oid)) { ++ if (odb_freshen_object(loose->base.odb, oid, 1)) { unlink_or_warn(tmp_file.buf); goto cleanup; } -@@ object-file.c: int odb_source_loose_write_object(struct odb_source *source, - * it out into .git/objects/??/?{38} file. - */ - write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen); -- if (odb_freshen_object(source->odb, oid)) -+ if (odb_freshen_object(source->odb, oid, 1)) - return 0; - if (write_loose_object(source, oid, hdr, hdrlen, buf, len, 0, flags)) - return -1; - - ## object-file.h ## -@@ object-file.h: int odb_source_loose_has_object(struct odb_source *source, - const struct object_id *oid); - - int odb_source_loose_freshen_object(struct odb_source *source, -- const struct object_id *oid); -+ const struct object_id *oid, -+ int skip_virtualized_objects); - - int odb_source_loose_write_object(struct odb_source *source, - const void *buf, size_t len, ## odb.c ## @@ odb.c: int odb_has_object(struct object_database *odb, const struct object_id *oid, @@ odb/source-files.c: static int odb_source_files_find_abbrev_len(struct odb_sourc { struct odb_source_files *files = odb_source_files_downcast(source); if (packfile_store_freshen_object(files->packed, oid) || -- odb_source_loose_freshen_object(source, oid)) -+ odb_source_loose_freshen_object(source, oid, skip_virtualized_objects)) +- odb_source_freshen_object(&files->loose->base, oid)) ++ odb_source_freshen_object(&files->loose->base, oid, skip_virtualized_objects)) return 1; return 0; } + ## odb/source-inmemory.c ## +@@ odb/source-inmemory.c: static int odb_source_inmemory_write_object_stream(struct odb_source *source, + } + + static int odb_source_inmemory_freshen_object(struct odb_source *source, +- const struct object_id *oid) ++ const struct object_id *oid, ++ int skip_virtualized_objects UNUSED) + { + struct odb_source_inmemory *inmemory = odb_source_inmemory_downcast(source); + if (find_cached_object(inmemory, oid)) + + ## odb/source-loose.c ## +@@ odb/source-loose.c: static int odb_source_loose_count_objects(struct odb_source *source, + } + + static int odb_source_loose_freshen_object(struct odb_source *source, +- const struct object_id *oid) ++ const struct object_id *oid, ++ int skip_virtualized_objects) + { + struct odb_source_loose *loose = odb_source_loose_downcast(source); + static struct strbuf path = STRBUF_INIT; +@@ odb/source-loose.c: static int odb_source_loose_freshen_object(struct odb_source *source, + odb_loose_path(loose, &path, oid); + retry: + ret = check_and_freshen_file(path.buf, 1); +- if (!ret && gvfs_virtualize_objects(source->odb->repo) && !tried_hook) { ++ if (!ret && gvfs_virtualize_objects(source->odb->repo) && ++ !skip_virtualized_objects && !tried_hook) { + tried_hook = 1; + if (!read_object_process(source->odb->repo, oid)) + goto retry; +@@ odb/source-loose.c: static int odb_source_loose_write_object(struct odb_source *source, + * it out into .git/objects/??/?{38} file. + */ + write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen); +- if (odb_freshen_object(source->odb, oid)) ++ if (odb_freshen_object(source->odb, oid, 1)) + return 0; + if (write_loose_object(loose, oid, hdr, hdrlen, buf, len, 0, flags)) + return -1; + ## odb/source.h ## @@ odb/source.h: struct odb_source { * has been freshened. @@ t/t0499-read-object.sh: test_expect_success 'invalid blobs generate errors' ' +' test_done + + ## t/unit-tests/u-odb-inmemory.c ## +@@ t/unit-tests/u-odb-inmemory.c: void test_odb_inmemory__freshen_object(void) + const char *end; + + cl_must_pass(parse_oid_hex_algop(RANDOM_OID, &oid, &end, repo.hash_algo)); +- cl_assert_equal_i(odb_source_freshen_object(&source->base, &oid), 0); ++ cl_assert_equal_i(odb_source_freshen_object(&source->base, &oid, 0), 0); + + cl_must_pass(odb_source_write_object(&source->base, "foobar", + strlen("foobar"), OBJ_BLOB, + &written_oid, NULL, 0)); + cl_assert_equal_i(odb_source_freshen_object(&source->base, +- &written_oid), 1); ++ &written_oid, 0), 1); + + odb_source_free(&source->base); + }30: ce00e56 ! 30: 50d1db2 gvfs: add global command pre and post hook procs
31: ee0ef83 = 31: f2b66b6 t0400: verify that the hook is called correctly from a subdirectory
32: e774e3b = 32: df50ef1 t0400: verify core.hooksPath is respected by pre-command
33: 9b93fc1 = 33: d2f23e0 Pass PID of git process to hooks.
34: 60b3b1a = 34: b74b724 sparse-checkout: make sure to update files with a modify/delete conflict
35: 5486f75 = 35: ca172b4 worktree: allow in Scalar repositories
36: 0142ed0 = 36: 5028c2a sparse-checkout: avoid writing entries with the skip-worktree bit
37: 4d5da32 = 37: b80f9a5 Do not remove files outside the sparse-checkout
38: da90ad3 = 38: db40a15 send-pack: do not check for sha1 file when GVFS_MISSING_OK set
39: 8581441 = 39: 52e78d9 gvfs: allow corrupt objects to be re-downloaded
40: 83160f2 = 40: 9e485b0 cache-tree: remove use of strbuf_addf in update_one
41: 2dd58ca ! 41: 9a24c61 gvfs: block unsupported commands when running in a GVFS repo
42: e0a2d36 = 42: 412e76a gvfs: allow overriding core.gvfs
43: 3378e7d = 43: c46d073 BRANCHES.md: Add explanation of branches and using forks
44: 0e19dd5 = 44: 1d12566 git.c: add VFS enabled cmd blocking
45: 4685c72 = 45: c5537b0 git.c: permit repack cmd in Scalar repos
50: 8c94b78 ! 46: 14fad46 Add virtual file system settings and hook proc
@@ virtualfilesystem.c (new) + +static void parent_directory_hashmap_add(struct hashmap *map, const char *pattern, const int patternlen) +{ -+ char *slash; ++ const char *slash; + struct virtualfilesystem *vfs; + + /*46: 6df5778 ! 47: 428d8b1 git.c: permit fsck cmd in Scalar repos
@@ Commit message ## git.c ## @@ git.c: static struct cmd_struct commands[] = { - { "for-each-ref", cmd_for_each_ref, RUN_SETUP }, { "for-each-repo", cmd_for_each_repo, RUN_SETUP_GENTLY }, { "format-patch", cmd_format_patch, RUN_SETUP }, + { "format-rev", cmd_format_rev, RUN_SETUP }, - { "fsck", cmd_fsck, RUN_SETUP | BLOCK_ON_GVFS_REPO}, + { "fsck", cmd_fsck, RUN_SETUP | BLOCK_ON_VFS_ENABLED }, { "fsck-objects", cmd_fsck, RUN_SETUP },51: a9491f2 = 48: f50a091 virtualfilesystem: don't run the virtual file system hook if the index has been redirected
47: fc28ad1 = 49: 6a164e5 git.c: permit prune cmd in Scalar repos
52: 969b601 = 50: 3d193f4 virtualfilesystem: check if directory is included
48: 467879d = 51: 95dc2f2 worktree: remove special case GVFS cmd blocking
53: 8299cb9 = 52: e866ac6 backwards-compatibility: support the post-indexchanged hook
49: ee1a38f ! 53: 5b1ba06 builtin/repack.c: emit warning when shared cache is present
@@ builtin/repack.c: int cmd_repack(int argc, + !repo_config_get_value(repo, "gvfs.sharedcache", &tmp_obj_dir)) + warning(_("shared object cache is configured but will not be repacked")); + - if (write_midx && write_bitmaps) { - struct strbuf path = STRBUF_INIT; - + if (config_ctx.midx_split_factor < 2) + die(_("invalid value for %s: %d"), "--midx-split-factor", + config_ctx.midx_split_factor); ## gvfs.h ## @@ gvfs.h: struct repository;54: 919620b = 54: de354cb gvfs: verify that the built-in FSMonitor is disabled
55: 710d5a7 = 55: 23beb1c wt-status: add trace2 data for sparse-checkout percentage
56: 5079d37 = 56: c5220bf status: add status serialization mechanism
57: 85d7f19 = 57: 9bf6ebb Teach ahead-behind and serialized status to play nicely together
58: be5fefb = 58: 2802c05 status: serialize to path
59: 008f2c5 = 59: 3a1d711 status: reject deserialize in V2 and conflicts
60: 185e4e7 = 60: cc627c7 serialize-status: serialize global and repo-local exclude file metadata
61: 1ae7a94 = 61: 28dfcd5 status: deserialization wait
62: bfa7736 = 62: f5f1046 status: deserialize with -uno does not print correct hint
63: e059869 = 63: c196940 fsmonitor: check CE_FSMONITOR_VALID in ce_uptodate
64: 9e9d115 = 64: 752fe86 fsmonitor: add script for debugging and update script for tests
65: eda895f = 65: fef7294 status: disable deserialize when verbose output requested.
66: 0ae8e59 = 66: 8621406 t7524: add test for verbose status deserialzation
67: ddea586 = 67: 547a913 deserialize-status: silently fallback if we cannot read cache file
68: 90e5e1e = 68: 6580151 gvfs:trace2:data: add trace2 tracing around read_object_process
69: e7cc49b = 69: ef6f7da gvfs:trace2:data: status deserialization information
70: b8030ad = 70: 0b52ddb gvfs:trace2:data: status serialization
71: 2e5f21e = 71: fca47cd gvfs:trace2:data: add vfs stats
72: ab6aaac = 72: b2571a7 trace2: refactor setting process starting time
73: 7cac489 = 73: fb668b3 trace2:gvfs:experiment: clear_ce_flags_1
74: db7a92d = 74: e84f185 trace2:gvfs:experiment: report_tracking
75: 4b307ec = 75: abb13c8 trace2:gvfs:experiment: read_cache: annotate thread usage in read-cache
76: f9a0cc7 = 76: f16700a trace2:gvfs:experiment: read-cache: time read/write of cache-tree extension
77: 5ccc665 = 77: 5dc7845 trace2:gvfs:experiment: add region to apply_virtualfilesystem()
78: a1c4e16 = 78: a9a8775 trace2:gvfs:experiment: add region around unpack_trees()
79: 3844304 ! 79: 48f6f56 trace2:gvfs:experiment: add region to cache_tree_fully_valid()
80: d2883d8 ! 80: a9ccacf trace2:gvfs:experiment: add unpack_entry() counter to unpack_trees() and report_tracking()
@@ builtin/checkout.c: static void update_refs_for_switch(const struct checkout_opt ## packfile.c ## @@ packfile.c: struct unpack_entry_stack_ent { - unsigned long size; + size_t size; }; +static unsigned long g_nr_unpack_entry; @@ packfile.c: struct unpack_entry_stack_ent { +} + void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset, - enum object_type *final_type, unsigned long *final_size) + enum object_type *final_type, size_t *final_size) { @@ packfile.c: void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset, int delta_stack_nr = 0, delta_stack_alloc = UNPACK_ENTRY_STACK_PREALLOC;81: c3f8841 = 81: b20970a trace2:gvfs:experiment: increase default event depth for unpack-tree data
82: 654a504 = 82: 3694625 trace2:gvfs:experiment: add data for check_updates() in unpack_trees()
83: 733d0f5 = 83: 8a72600 Trace2:gvfs:experiment: capture more 'tracking' details
84: c047e0a = 84: a99f420 credential: set trace2_child_class for credential manager children
85: 68b5bf2 = 85: 4fba917 sub-process: do not borrow cmd pointer from caller
86: a36b94d = 86: fe084d5 sub-process: add subprocess_start_argv()
87: f1d57cc < -: ------------ sha1-file: add function to update existing loose object cache
-: ------------ > 87: 969ad0f sha1-file: add function to update existing loose object cache
88: f431105 = 88: d0bb15a index-pack: avoid immediate object fetch while parsing packfile
89: 2467774 ! 89: 31c9a4e gvfs-helper: create tool to fetch objects using the GVFS Protocol
90: 5834c1e = 90: 523bd35 sha1-file: create shared-cache directory if it doesn't exist
91: 0d8ca0d ! 91: 1a24c7d gvfs-helper: better handling of network errors
@@ gvfs-helper.c: int cmd_main(int argc, const char **argv) trace2_cmd_name("gvfs-helper"); + packet_trace_identity("gvfs-helper"); - setup_git_directory_gently(NULL); + setup_git_directory_gently(the_repository, NULL);92: 5a42fd6 = 92: e86792f gvfs-helper-client: properly update loose cache with fetched OID
93: a4fa869 ! 93: 9554904 gvfs-helper: V2 robust retry and throttling
94: 30cc86b ! 94: 4d22a03 gvfs-helper: expose gvfs/objects GET and POST semantics
95: 8f5bfd7 = 95: 1cff3ec gvfs-helper: dramatically reduce progress noise
96: 4c4dd7f = 96: af1324f gvfs-helper: handle pack-file after single POST request
97: 01b2f6c ! 97: 0dfdfb0 test-gvfs-prococol, t5799: tests for gvfs-helper
@@ t/helper/test-gvfs-protocol.c (new) + int i; + + trace2_cmd_name("test-gvfs-protocol"); -+ setup_git_directory_gently(NULL); ++ setup_git_directory_gently(the_repository, NULL); + + for (i = 1; i < argc; i++) { + const char *arg = argv[i];98: aa254e6 = 98: 803741b gvfs-helper: move result-list construction into install functions
99: 22de5b3 = 99: 978fa8c t5799: add support for POST to return either a loose object or packfile
100: 693dcc9 = 100: 7b5308e t5799: cleanup wc-l and grep-c lines
101: 38dc180 = 101: e10006c gvfs-helper: verify loose objects after write
102: 9ebc0f3 = 102: 00da5b8 t7599: create corrupt blob test
103: 577aabd = 103: f6ba3f3 gvfs-helper: add prefetch support
104: 3ff796a = 104: cf3ca53 gvfs-helper: add prefetch .keep file for last packfile
105: 7c13748 = 105: 2d561af gvfs-helper: do one read in my_copy_fd_len_tail()
106: 3fb8569 = 106: 34d8b93 gvfs-helper: move content-type warning for prefetch packs
107: 9e95b97 = 107: 5765d2e fetch: use gvfs-helper prefetch under config
108: c44a206 = 108: a230cf5 gvfs-helper: better support for concurrent packfile fetches
109: 01a538f = 109: c6a70dd remote-curl: do not call fetch-pack when using gvfs-helper
110: 056bb72 = 110: 133d130 fetch: reprepare packs before checking connectivity
111: af57ac7 = 111: 6cfe2bb gvfs-helper: retry when creating temp files
112: 4742bc4 = 112: 863666e sparse: avoid warnings about known cURL issues in gvfs-helper.c
113: 9bf8e27 = 113: 81a2719 gvfs-helper: add --max-retries to prefetch verb
120: cf9dee3 = 114: a2b6c77 t5799: add tests to detect corrupt pack/idx files in prefetch
122: 6c82f84 = 115: 199a51f gvfs-helper: ignore .idx files in prefetch multi-part responses
114: 135eb5d = 116: 3fee605 maintenance: care about gvfs.sharedCache config
115: ed9fd0d = 117: cc81aec unpack-trees:virtualfilesystem: Improve efficiency of clear_ce_flags
116: 4dde591 < -: ------------ homebrew: add GitHub workflow to release Cask
305: abc77c4 ! 118: b11a8e1 homebrew: use Releases API digest for Cask checksum
117: b911fc3 = 119: ecf23dd Adding winget workflows
118: b16eb3e = 120: 1ab35db Disable the
monitor-componentsworkflow in msft-git119: dcf7a55 = 121: f631495 .github: enable windows builds on microsoft fork
121: 29c7f02 = 122: 1c9104a .github/actions/akv-secret: add action to get secrets
123: 39fdcb5 ! 123: 4428e85 release: create initial Windows installer build workflow
127: 66ce629 = 124: 33a635b help: special-case HOST_CPU
universal129: 3ba4ddb ! 125: 4003842 release: add Mac OSX installer build
124: 8626621 = 126: c71dbb5 t5799: explicitly test gvfs-helper --fallback and --no-fallback
125: 453f8c5 < -: ------------ release: create initial Windows installer build workflow
131: 2c1973d ! 127: 9ea3858 release: build unsigned Ubuntu .deb package
126: 91fbb99 = 128: 85e3dda gvfs-helper: don't fallback with new config
132: a63e353 ! 129: 121efe4 release: add signing step for .deb package
@@ Commit message Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> ## .github/workflows/build-git-installers.yml ## -@@ .github/workflows/build-git-installers.yml: on: - tags: - - 'v[0-9]*vfs*' # matches "v<number><any characters>vfs<any characters>" +@@ .github/workflows/build-git-installers.yml: name: build-git-installers + on: + workflow_dispatch: +permissions: + id-token: write # required for Azure login via OIDC @@ .github/workflows/build-git-installers.yml: jobs: strategy: @@ .github/workflows/build-git-installers.yml: jobs: - name: Upload artifacts - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: - name: linux-artifacts + name: linux-unsigned-${{ matrix.arch.name }} @@ .github/workflows/build-git-installers.yml: jobs: + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + - name: Check out repository (for akv-secret Action) -+ uses: actions/checkout@v4 ++ uses: actions/checkout@v6 + with: + path: git + @@ .github/workflows/build-git-installers.yml: jobs: + /usr/lib/gnupg2/gpg-preset-passphrase --preset '${{ steps.gpg-secrets.outputs.keygrip }}' <<<'${{ steps.gpg-secrets.outputs.passphrase }}' + + - name: Download artifacts -+ uses: actions/download-artifact@v4 ++ uses: actions/download-artifact@v8 + with: + name: linux-unsigned-${{ matrix.arch }} + @@ .github/workflows/build-git-installers.yml: jobs: + debsigs --sign=origin --verify --check microsoft-git_"$version"_${{ matrix.arch }}.deb + + - name: Upload artifacts -+ uses: actions/upload-artifact@v6 ++ uses: actions/upload-artifact@v7 + with: + name: linux-${{ matrix.arch }} path: |128: 51ffffe = 130: df4e01c test-gvfs-protocol: add cache_http_503 to mayhem
133: bad6926 ! 131: 2eb0fc1 release: create draft GitHub release with packages & installers
130: ffed10f = 132: ad9c258 t5799: add unit tests for new
gvfs.fallbackconfig setting135: 4f9ca28 = 133: 5f43759 update-microsoft-git: create barebones builtin
137: 0656543 = 134: 60a36e0 update-microsoft-git: Windows implementation
134: 6b1d000 ! 135: e77f72b build-git-installers: publish gpg public key
@@ .github/workflows/build-git-installers.yml: jobs: + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + - name: Check out repository (for akv-secret Action) -+ uses: actions/checkout@v4 ++ uses: actions/checkout@v6 + with: + path: git + @@ .github/workflows/build-git-installers.yml: jobs: + secrets: | + ${{ secrets.LINUX_GPG_PUBLIC_SECRET_NAME }} base64> deb-package/msft-git-public.asc + - - uses: actions/github-script@v6 + - uses: actions/github-script@v9 with: script: |139: 6fffe5a = 136: e84b19d update-microsoft-git: use brew on macOS
136: 9314704 = 137: edae852 release: continue pestering until user upgrades
144: 7cbeb9c = 138: 3bc1b1a git_config_set_multivar_in_file_gently(): add a lock timeout
141: d49fbb9 = 139: b58fe1a .github: reinstate ISSUE_TEMPLATE.md for microsoft/git
138: fb2ee4c = 140: 6a932d7 dist: archive HEAD instead of HEAD^{tree}
146: ef23cac = 141: b9adeee scalar: set the config write-lock timeout to 150ms
143: 3fafd11 = 142: f0a72d3 .github: update PULL_REQUEST_TEMPLATE.md
140: e107a79 = 143: ec3b2b8 release: include GIT_BUILT_FROM_COMMIT in MacOS build
147: 3356b30 = 144: f9bc0cf scalar: add docs from microsoft/scalar
145: 268e680 = 145: 9b8f89b Adjust README.md for microsoft/git
142: 8eba308 ! 146: 08c324f release: add installer validation
148: 0cedb2b = 147: 6c80e7d scalar (Windows): use forward slashes as directory separators
149: 4d5f852 = 148: fac07dc scalar: add retry logic to run_git()
150: 3804a81 = 149: 6143dc1 scalar: support the
configcommand for backwards compatibility151: c23a0f1 = 150: 9b691b9 scalar: implement a minimal JSON parser
152: 657cebb = 151: 42593de scalar clone: support GVFS-enabled remote repositories
153: 58da6b9 = 152: d928194 test-gvfs-protocol: also serve smart protocol
154: cd9da9c = 153: c7b53b1 gvfs-helper: add the
endpointcommand155: d7c9693 = 154: 85e7343 dir_inside_of(): handle directory separators correctly
156: 7937a58 = 155: e964e30 scalar: disable authentication in unattended mode
157: 4b26b6f = 156: 3aefdce abspath: make strip_last_path_component() global
158: 35d09df ! 157: 488d413 scalar: do initialize
gvfs.sharedCache159: 290228b = 158: 9e2509b scalar diagnose: include shared cache info
160: 62f99c5 = 159: ed82fd3 scalar: only try GVFS protocol on https:// URLs
161: 4b56f3f = 160: 5b47076 scalar: verify that we can use a GVFS-enabled repository
162: baf31be = 161: de5851e scalar: add the
cache-servercommand163: 6e44511 = 162: 50a5992 scalar: add a test toggle to skip accessing the vsts/info endpoint
164: 8b485bf = 163: db1e9da scalar: adjust documentation to the microsoft/git fork
165: 975b79e = 164: e6e1b6b scalar: enable untracked cache unconditionally
166: 82508f4 = 165: 40fee12 scalar: parse
clone --no-fetch-commits-and-treesfor backwards compatibility167: e56b327 = 166: 67f05a0 scalar: make GVFS Protocol a forced choice
168: 9878e92 = 167: 7995e59 scalar: work around GVFS Protocol HTTP/2 failures
169: 94a86dc = 168: 216c181 gvfs-helper-client: clean up server process(es)
170: 3fabf95 = 169: 7717e76 scalar diagnose: accommodate Scalar's Functional Tests
173: e70ed15 = 170: 853755f add/rm: allow adding sparse entries when virtual
171: 166ed4d ! 171: cef60b9 ci: run Scalar's Functional Tests
174: 0176b10 = 172: 656fb01 sparse-checkout: add config to disable deleting dirs
172: 3a0f593 = 173: 92f822d scalar: upgrade to newest FSMonitor config setting
175: 16d9542 = 174: 81ce624 diff: ignore sparse paths in diffstat
176: 34b71f5 = 175: d926318 repo-settings: enable sparse index by default
177: b56ca58 = 176: df922a6 TO-UPSTREAM: sequencer: avoid progress when stderr is redirected
178: 87b4a62 = 177: c8da0d2 TO-CHECK: t1092: use quiet mode for rebase tests
179: 51a3f58 = 178: 89b9ad0 reset: fix mixed reset when using virtual filesystem
180: 0d4c9a9 = 179: ed99b68 diff(sparse-index): verify with partially-sparse
181: 1e1c953 = 180: 341fc32 stash: expand testing for
git stash -u182: ba15888 = 181: bad405f sparse-index: add ensure_full_index_with_reason()
183: 28b8b1f ! 182: 27ba56c treewide: add reasons for expanding index
184: 0cba1c3 = 183: 18d2c13 treewide: custom reasons for expanding index
185: 095f791 = 184: 4c511cd sparse-index: add macro for unaudited expansions
186: f234ddc = 185: 836b74d Docs: update sparse index plan with logging
187: 3df78f8 = 186: c877295 sparse-index: log failure to clear skip-worktree
188: a310bcc = 187: c0684f1 stash: use -f in checkout-index child process
189: ed49c0e = 188: e490d06 sparse-index: do not copy hashtables during expansion
190: 3169ba3 = 189: 1b52838 TO-UPSTREAM: sub-process: avoid leaking
cmd191: 2a0d73e = 190: 76073be remote-curl: release filter options before re-setting them
192: 20aaf05 = 191: 96bb6e2 transport: release object filter options
193: e129f43 ! 192: 1b5d08d push: don't reuse deltas with path walk
194: a22c0b6 = 193: e9fc894 t7900-maintenance.sh: reset config between tests
195: a3d92a3 = 194: e2b5f45 maintenance: add cache-local-objects maintenance task
196: 27b19a5 = 195: 00f30c9 scalar.c: add cache-local-objects task
197: e2d5332 ! 196: fd725c3 hooks: add custom post-command hook config
@@ hook.c: void hook_free(void *p, const char *str UNUSED) +{ + struct strbuf path = STRBUF_INIT; + const char *sid = tr2_sid_get(); -+ char *slash = strchr(sid, '/'); -+ -+ /* -+ * Name is based on top-level SID, so children can indicate that -+ * the top-level process should run the post-command hook. -+ */ -+ if (slash) -+ *slash = 0; ++ const char *slash = strchrnul(sid, '/'); + + /* + * Do not write to hooks directory, as it could be redirected + * somewhere like the source tree. + */ -+ repo_git_path_replace(r, &path, "info/index-change-%s.snt", sid); ++ repo_git_path_replace(r, &path, "info/index-change-%.*s.snt", ++ (int)(slash - sid), sid); + + return strbuf_detach(&path, NULL); +}198: 67995b0 ! 197: 9200e24 TO-UPSTREAM: Docs: fix asciidoc failures from short delimiters
199: 1ef68d0 = 198: a4656ce hooks: make hook logic memory-leak free
201: f6bf764 = 199: e061100 t0401: test post-command for alias, version, typo
203: 885c9c6 = 200: eec6e46 hooks: better handle config without gitdir
200: c18f47b ! 201: cef18fa cat_one_file(): make it easy to see that the
sizevariable is initialized204: 09c8246 = 202: 7442ba8 revision: defensive programming
202: b7b0458 = 203: 5665bcc fsck: avoid using an uninitialized variable
205: 18eaf1a = 204: 756645e get_parent(): defensive programming
218: f38cce3 = 205: fa69a03 load_revindex_from_disk(): avoid accessing uninitialized data
206: 2e3161b = 206: 8a5f81c fetch-pack: defensive programming
222: 6184a4d = 207: 3513e5b load_pack_mtimes_file(): avoid accessing uninitialized data
209: 6ec7dc4 ! 208: bdd7bde codeql: run static analysis as part of CI builds
211: e149087 ! 209: ff1beac codeql: publish the sarif file as build artifact
207: b7cd525 = 210: 5028ac4 unparse_commit(): defensive programming
214: e277e03 ! 211: 5771b17 codeql: disable a couple of non-critical queries for now
208: 5b2b925 = 212: 81b8b5d verify_commit_graph(): defensive programming
217: ef097fa = 213: 72fc726 date: help CodeQL understand that there are no leap-year issues here
210: c559617 = 214: f8806f3 stash: defensive programming
221: c32c244 = 215: e7531c7 help: help CodeQL understand that consuming envvars is okay here
212: c43326c = 216: a068f57 stash: defensive programming
213: 3d1585f < -: ------------ fetch: silence a CodeQL alert about a local variable's address' use after release
225: 29e8ee6 = 217: a377224 ctype: help CodeQL understand that
sane_istest()does not access array past end215: 4634cc6 = 218: f0ef8e7 push: defensive programming
216: 8eac178 = 219: b57fa4c test-tool repository: check return value of
lookup_commit()226: ade505c = 220: bd2a9ee ctype: accommodate for CodeQL misinterpreting the
zinmallocz()219: d0b514e = 221: 9c9cb17 fetch: defensive programming
220: 61484c8 = 222: 94a832a shallow: handle missing shallow commits gracefully
227: ced0669 = 223: 356f748 strbuf_read: help with CodeQL misunderstanding that
strbuf_read()does NUL-terminate correctly223: e98e25b = 224: f7294be inherit_tracking(): defensive programming
224: 02dd28f = 225: 4d3fc58 commit-graph: suppress warning about using a stale stack addresses
228: 6ea08af ! 226: d3ca7f7 codeql: also check JavaScript code
@@ .github/workflows/codeql.yml: jobs: - name: Checkout repository @@ .github/workflows/codeql.yml: jobs: - name: publish sarif for debugging - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: - name: sarif-results + name: sarif-results-${{ matrix.language }}229: 079a4fd = 227: 13a254e scalar: add run_git_argv
230: 0be8fee = 228: e4449a3 scalar: add --ref-format option to scalar clone
231: 9efd894 = 229: e46a87e gvfs-helper: skip collision check for loose objects
232: 4fd0406 = 230: 572244c gvfs-helper: emit advice on transient errors
233: b73eb04 = 231: 43c901d gvfs-helper: avoid collision check for packfiles
234: 1fae09d = 232: c5642c8 t5799: update cache-server methods for multiple instances
235: 99f5a12 = 233: bf4c4f4 gvfs-helper: override cache server for prefetch
236: 56827ed = 234: 664df1b gvfs-helper: override cache server for get
237: c55b37c = 235: 662dc1a gvfs-helper: override cache server for post
238: 6f88546 = 236: d2c7cb5 t5799: add test for all verb-specific cache-servers together
239: 366d8b7 = 237: ce45a38 lib-gvfs-helper: create helper script for protocol tests
240: f959aa2 = 238: 311168e t579*: split t5799 into several parts
241: cc2c471 = 239: 72573c7 scalar: add ---cache-server-url options
242: 81888ba = 240: 89ad814 Restore previous errno after post command hook
243: df551f8 = 241: f09077f t9210: differentiate origin and cache servers
245: 4866686 = 242: f0e6c13 unpack-trees: skip lstats for deleted VFS entries in checkout
246: f4a85c5 = 243: bfc2145 worktree: conditionally allow worktree on VFS-enabled repos
244: 79c62b2 = 244: 885b65f gvfs-helper: send X-Session-Id headers
247: 7db55f9 = 245: 7465381 gvfs-helper: create shared object cache if missing
248: caf4f51 = 246: 177782f gvfs: add gvfs.sessionKey config
249: 2a24af5 = 247: 63c62f4 gvfs: clear DIE_IF_CORRUPT in streaming incore fallback
250: 1f90f17 ! 248: a22ad73 workflow: add release-vfsforgit to automate VFS for Git updates
@@ .github/workflows/release-vfsforgit.yml (new) + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + - name: Checkout (for akv-secret action) -+ uses: actions/checkout@v4 ++ uses: actions/checkout@v6 + with: + sparse-checkout: .github/actions +251: a485bab = 249: 8eb2b3a worktree remove: use GVFS_SUPPORTS_WORKTREES for skip-clean-check gate
252: b124df1 ! 250: 56eaa37 ci: add new VFS for Git functional tests workflow
253: 3282678 ! 251: 20399e3 azure-pipelines: add stub release pipeline for Azure
@@ Metadata ## Commit message ## azure-pipelines: add stub release pipeline for Azure - Add a stub pipeline for releases using Azure Pipelines. + Add a release-pipeline scaffold for microsoft/git on Azure + Pipelines, structured around a prereqs stage, a per-platform + build stage with placeholder jobs, and a release stage that + downloads the build artifacts and publishes them to a draft + GitHub release. The per-platform build, signing, and validation + logic lands in subsequent commits. - The pipeline runs on Microsoft internal images/runners across: - * Windows x64 - * Windows ARM64 - * macOS - * Ubuntu x64 - * Ubuntu ARM64 + The pipeline targets Microsoft-internal 1ES-hosted images + across Windows x64, Windows ARM64, macOS, Ubuntu x64, and + Ubuntu ARM64. Windows and Linux matrix entries carry a + `poolArch` dimension because the 1ES hosted pools select their + image from `hostArchitecture`; an arm64 entry on a default x64 + pool would silently grab the wrong image. macOS uses the same + matrix-parameter shape as Windows and Linux, so future macOS + variants drop in the same way an extra Windows toolchain would. - At the start of a run there is a prerequisite stage and pre-build - validation. Today this does nothing, and should be updated to: - * validate the current commit is tagged (annotated), and - * capture the Git version, tag name and SHA. - - Artifacts are uploaded from the build stage, and downloaded into the - release stage later for uploading to a draft GitHub release. + The prereqs stage derives the Git version, tag name, and tag + SHA via resolve-version.sh and exposes them as pipeline + variables for downstream stages to pick up. For that walk to + find tags at all, the prereqs checkout uses fetchDepth: 0 / + fetchTags: true. setup-git-bash.cmd is the Windows-side + prerequisite that prepends Git Bash to PATH, since the bare + hosted image does not provide a bash for Bash@3 tasks to find. ESRP signing to be added later. Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com> + Assisted-by: Claude Opus 4.7 + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> ## .azure-pipelines/release.yml (new) ## @@ @@ .azure-pipelines/release.yml (new) + - id: windows_x64 + jobName: 'Windows (x64)' + pool: GitClientPME-1ESHostedPool-intel-pc ++ poolArch: amd64 + image: win-x86_64-ado1es + os: windows + toolchain: x86_64 @@ .azure-pipelines/release.yml (new) + - id: windows_arm64 + jobName: 'Windows (ARM64)' + pool: GitClientPME-1ESHostedPool-arm64-pc ++ poolArch: arm64 + image: win-arm64-ado1es + os: windows + toolchain: clang-aarch64 + mingwprefix: clangarm64 + -+ # No matrix for macOS as we build both x64 and ARM64 in the same job -+ # and produce a universal binary. ++ - name: macos_matrix ++ type: object ++ default: ++ - id: macos_universal ++ jobName: 'macOS (x64 + ARM64)' ++ pool: 'Azure Pipelines' ++ # macOS-latest is an Intel x86_64 Mac Pro, which can't host the ++ # arm64 Homebrew the universal-binary build needs. We need to ++ # explictly target the newer Apple Silicon machines that can run ++ # both x86_64 and arm64 builds. ++ image: macOS-15-arm64 ++ os: macos + + - name: linux_matrix + type: object @@ .azure-pipelines/release.yml (new) + - id: linux_x64 + jobName: 'Linux (x64)' + pool: GitClientPME-1ESHostedPool-intel-pc ++ poolArch: amd64 + image: ubuntu-x86_64-ado1es + os: linux + cc_arch: x86_64 @@ .azure-pipelines/release.yml (new) + - id: linux_arm64 + jobName: 'Linux (ARM64)' + pool: GitClientPME-1ESHostedPool-arm64-pc ++ poolArch: arm64 + image: ubuntu-arm64-ado1es + os: linux + cc_arch: aarch64 @@ .azure-pipelines/release.yml (new) + image: ubuntu-x86_64-ado1es + os: linux + steps: ++ - checkout: self ++ fetchDepth: 0 ++ fetchTags: true + - task: Bash@3 + displayName: 'Resolve version and tag information' + name: info + inputs: -+ targetType: inline -+ script: | -+ # TODO: determine git_version, tag_name, and tag_sha -+ # TODO: error if the current commit is not an annotated tag -+ git_version=TODO_GITVER -+ tag_name=TODO_TAGNAME -+ tag_sha=TODO_TAGSHA -+ echo "##vso[task.setvariable variable=git_version;isOutput=true;isReadOnly=true]$git_version" -+ echo "##vso[task.setvariable variable=tag_name;isOutput=true;isReadOnly=true]$tag_name" -+ echo "##vso[task.setvariable variable=tag_sha;isOutput=true;isReadOnly=true]$tag_sha" ++ targetType: filePath ++ filePath: .azure-pipelines/scripts/resolve-version.sh + + - stage: build + displayName: 'Build' @@ .azure-pipelines/release.yml (new) + name: ${{ dim.pool }} + image: ${{ dim.image }} + os: ${{ dim.os }} ++ hostArchitecture: ${{ dim.poolArch }} + variables: + tag_name: $[stageDependencies.prereqs.prebuild.outputs['info.tag_name']] + tag_sha: $[stageDependencies.prereqs.prebuild.outputs['info.tag_sha']] @@ .azure-pipelines/release.yml (new) + artifactName: '${{ dim.id }}' + steps: + - checkout: self ++ # Add Git Bash to the PATH so Bash tasks can find it ++ - task: BatchScript@1 ++ displayName: 'Add Git Bash to PATH' ++ inputs: ++ filename: ./.azure-pipelines/scripts/windows/setup-git-bash.cmd + # TODO: add tasks to set up Git for Windows SDK + # TODO: add tasks to build Git and installers + - script: | + echo $(mingwprefix) + echo $(toolchain) ++ mkdir $(Build.ArtifactStagingDirectory)\app ++ copy C:\Windows\System32\calc.exe $(Build.ArtifactStagingDirectory)\app\example1.exe ++ copy C:\Windows\System32\calc.exe $(Build.ArtifactStagingDirectory)\app\example2.exe ++ copy C:\Windows\System32\calc.exe $(Build.ArtifactStagingDirectory)\app\example3.exe + displayName: 'Dummy build' + # TODO: put final artifacts under $(Build.ArtifactStagingDirectory)/_final + - script: | -+ echo "TODO" > $(Build.ArtifactStagingDirectory)/_final/placeholder.txt ++ mkdir $(Build.ArtifactStagingDirectory)\_final ++ xcopy /s /y $(Build.ArtifactStagingDirectory)\app $(Build.ArtifactStagingDirectory)\_final ++ displayName: 'Dummy collect artifacts' + + # -+ # macOS build job (universal) ++ # macOS build jobs + # -+ - job: macos_universal -+ displayName: 'macOS (x64 + ARM64)' -+ pool: -+ name: 'Azure Pipelines' -+ image: macOS-latest -+ os: macos -+ variables: -+ tag_name: $[stageDependencies.prereqs.prebuild.outputs['info.tag_name']] -+ tag_sha: $[stageDependencies.prereqs.prebuild.outputs['info.tag_sha']] -+ git_version: $[stageDependencies.prereqs.prebuild.outputs['info.git_version']] -+ templateContext: -+ outputs: -+ - output: pipelineArtifact -+ targetPath: '$(Build.ArtifactStagingDirectory)/_final' -+ artifactName: 'macos_universal' -+ steps: -+ - checkout: self -+ # TODO: add tasks to set up build environment -+ # TODO: add tasks to build Git and installers -+ - script: | -+ echo "Hello, Mac!" -+ displayName: 'Dummy build' -+ # TODO: put final artifacts under $(Build.ArtifactStagingDirectory)/_final -+ - script: | -+ echo "TODO" > $(Build.ArtifactStagingDirectory)/_final/placeholder.txt ++ - ${{ each dim in parameters.macos_matrix }}: ++ - job: ${{ dim.id }} ++ displayName: ${{ dim.jobName }} ++ pool: ++ name: ${{ dim.pool }} ++ image: ${{ dim.image }} ++ os: ${{ dim.os }} ++ variables: ++ tag_name: $[stageDependencies.prereqs.prebuild.outputs['info.tag_name']] ++ tag_sha: $[stageDependencies.prereqs.prebuild.outputs['info.tag_sha']] ++ git_version: $[stageDependencies.prereqs.prebuild.outputs['info.git_version']] ++ templateContext: ++ outputs: ++ - output: pipelineArtifact ++ targetPath: '$(Build.ArtifactStagingDirectory)/_final' ++ artifactName: '${{ dim.id }}' ++ steps: ++ - checkout: self ++ # TODO: add tasks to set up build environment ++ # TODO: add tasks to build Git and installers ++ - script: | ++ echo "Hello, Mac!" ++ mkdir -p $(Build.ArtifactStagingDirectory)/app ++ cp /bin/echo $(Build.ArtifactStagingDirectory)/app/example ++ displayName: 'Dummy build' ++ # TODO: put final artifacts under $(Build.ArtifactStagingDirectory)/_final ++ - script: | ++ mkdir -p $(Build.ArtifactStagingDirectory)/_final ++ cp -R $(Build.ArtifactStagingDirectory)/app/* $(Build.ArtifactStagingDirectory)/_final/ ++ displayName: 'Dummy collect artifacts' + + # + # Linux build jobs @@ .azure-pipelines/release.yml (new) + name: ${{ dim.pool }} + image: ${{ dim.image }} + os: ${{ dim.os }} ++ hostArchitecture: ${{ dim.poolArch }} + variables: + tag_name: $[stageDependencies.prereqs.prebuild.outputs['info.tag_name']] + tag_sha: $[stageDependencies.prereqs.prebuild.outputs['info.tag_sha']] @@ .azure-pipelines/release.yml (new) + - script: | + echo $(cc_arch) + echo $(deb_arch) ++ mkdir -p $(Build.ArtifactStagingDirectory)/app ++ debroot=$(Build.ArtifactStagingDirectory)/pkgroot ++ mkdir -p $debroot/DEBIAN ++ cat > $debroot/DEBIAN/control <<CTRL ++ Package: example ++ Version: 1.0 ++ Architecture: $(deb_arch) ++ Maintainer: test ++ Description: dummy ++ CTRL ++ dpkg-deb --build $debroot $(Build.ArtifactStagingDirectory)/app/example_$(deb_arch).deb + displayName: 'Dummy build' + # TODO: put final artifacts under $(Build.ArtifactStagingDirectory)/_final + - script: | -+ echo "TODO" > $(Build.ArtifactStagingDirectory)/_final/placeholder.txt ++ mkdir -p $(Build.ArtifactStagingDirectory)/_final ++ cp -R $(Build.ArtifactStagingDirectory)/app/* $(Build.ArtifactStagingDirectory)/_final/ ++ displayName: 'Dummy collect artifacts' + + - stage: release + displayName: 'Release' + dependsOn: [prereqs, build] + jobs: ++ # ++ # GitHub release publishing ++ # + - job: github + displayName: 'Publish GitHub release' + condition: and(succeeded(), eq('${{ parameters.github }}', true)) @@ .azure-pipelines/release.yml (new) + type: releaseJob + isProduction: true + inputs: -+ - input: pipelineArtifact -+ artifactName: 'windows_x64' -+ targetPath: $(Pipeline.Workspace)/assets/windows_x64 -+ - input: pipelineArtifact -+ artifactName: 'windows_arm64' -+ targetPath: $(Pipeline.Workspace)/assets/windows_arm64 -+ - input: pipelineArtifact -+ artifactName: 'macos_universal' -+ targetPath: $(Pipeline.Workspace)/assets/macos_universal -+ - input: pipelineArtifact -+ artifactName: 'linux_x64' -+ targetPath: $(Pipeline.Workspace)/assets/linux_x64 -+ - input: pipelineArtifact -+ artifactName: 'linux_arm64' -+ targetPath: $(Pipeline.Workspace)/assets/linux_arm64 ++ - ${{ each dim in parameters.windows_matrix }}: ++ - input: pipelineArtifact ++ artifactName: '${{ dim.id }}' ++ targetPath: $(Pipeline.Workspace)/assets/${{ dim.id }} ++ - ${{ each dim in parameters.macos_matrix }}: ++ - input: pipelineArtifact ++ artifactName: '${{ dim.id }}' ++ targetPath: $(Pipeline.Workspace)/assets/${{ dim.id }} ++ - ${{ each dim in parameters.linux_matrix }}: ++ - input: pipelineArtifact ++ artifactName: '${{ dim.id }}' ++ targetPath: $(Pipeline.Workspace)/assets/${{ dim.id }} + steps: + - task: GitHubRelease@1 + displayName: 'Create Draft GitHub Release' @@ .azure-pipelines/release.yml (new) + $(Pipeline.Workspace)/assets/linux_x64/*.tar.gz + $(Pipeline.Workspace)/assets/linux_arm64/*.deb + $(Pipeline.Workspace)/assets/linux_arm64/*.tar.gz + + ## .azure-pipelines/scripts/resolve-version.sh (new) ## +@@ ++#!/bin/bash ++# ++# Resolve version and tag information from the current HEAD commit. ++# Validates that HEAD is an annotated version tag matching GIT-VERSION-GEN. ++# ++# Sets the following ADO output variables (via ##vso): ++# git_version - Version string without "v" prefix (e.g., 2.53.0.vfs.0.0) ++# tag_name - Full tag name (e.g., v2.53.0.vfs.0.0) ++# tag_sha - Commit SHA of HEAD ++# ++# Also updates the build number to include the tag name. ++# ++set -euo pipefail ++ ++echo "HEAD: $(git rev-parse HEAD)" ++ ++# Determine the tag pointing at HEAD ++tag_name=$(git describe --exact-match --match "v[0-9]*vfs*" HEAD 2>/dev/null) || { ++ echo "##vso[task.logissue type=error]HEAD is not tagged with a version tag" ++ exit 1 ++} ++ ++# Verify the tag is annotated (not lightweight) ++tag_type=$(git cat-file -t "refs/tags/$tag_name") ++if [ "$tag_type" != "tag" ]; then ++ echo "##vso[task.logissue type=error]Tag $tag_name is not annotated (type: $tag_type)" ++ exit 1 ++fi ++ ++tag_sha=$(git rev-parse HEAD) ++git_version="${tag_name#v}" ++ ++# Verify the version matches GIT-VERSION-GEN ++make GIT-VERSION-FILE ++expected_version="${git_version//-rc/.rc}" ++actual_version=$(sed -n 's/^GIT_VERSION *= *//p' < GIT-VERSION-FILE) ++if [ "$expected_version" != "$actual_version" ]; then ++ echo "##vso[task.logissue type=error]GIT-VERSION-FILE ($actual_version) does not match tag $tag_name ($expected_version)" ++ exit 1 ++fi ++ ++echo "Git version: $git_version" ++echo "Tag name: $tag_name" ++echo "Tag SHA: $tag_sha" ++echo "##vso[task.setvariable variable=git_version;isOutput=true;isReadOnly=true]$git_version" ++echo "##vso[task.setvariable variable=tag_name;isOutput=true;isReadOnly=true]$tag_name" ++echo "##vso[task.setvariable variable=tag_sha;isOutput=true;isReadOnly=true]$tag_sha" ++echo "##vso[build.updatebuildnumber]${tag_name} (${BUILD_BUILDNUMBER:-unknown})" + + ## .azure-pipelines/scripts/windows/setup-git-bash.cmd (new) ## +@@ ++@echo off ++setlocal enabledelayedexpansion ++set "agentgit=%AGENT_HOMEDIRECTORY%\externals\git" ++set "gitcopy=%AGENT_TEMPDIRECTORY%\git" ++echo Copying !agentgit! to !gitcopy!... ++xcopy /E /I /Q "!agentgit!" "!gitcopy!" ++if not exist "!gitcopy!\usr\bin\sh.exe" ( ++ echo ##vso[task.logissue type=error]Could not find sh.exe at !gitcopy!\usr\bin\sh.exe ++ exit /b 1 ++) ++echo Copying !gitcopy!\usr\bin\sh.exe to !gitcopy!\usr\bin\bash.exe... ++copy /Y "!gitcopy!\usr\bin\sh.exe" "!gitcopy!\usr\bin\bash.exe" ++echo ##vso[task.prependpath]!gitcopy!\usr\bin254: ed5c15a ! 252: 6c70eb1 diff: add renameThreshold configuration option
@@ Commit message The value accepts the same format as -M: a percentage (e.g. 50%) or a fraction (e.g. 0.5). If unset, the default remains 50%. - This also gives git-blame users control over the rename threshold - for the first time, since blame has no -M threshold flag but inherits - diff.renameThreshold via repo_diff_setup(). - Assisted-by: Claude Opus 4.6 Signed-off-by: Tyrie Vella <tyrielv@gmail.com> + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> ## Documentation/config/diff.adoc ## @@ Documentation/config/diff.adoc: endif::git-diff[] @@ Documentation/config/diff.adoc: endif::git-diff[] + percentage (e.g. `50%`), or a fraction between 0 and 1 + (e.g. `0.5`). If not set, the default is 50%. This setting + has no effect if rename detection is turned off. -++ -+This config setting is also respected by linkgit:git-blame[1]; -+to limit blame to only consider exact renames, for example, set -+`diff.renameThreshold = 100%`. + `diff.renames`:: Whether and how Git detects renames. If set to `false`, @@ diff.c static int diff_suppress_blank_empty; static enum git_colorbool diff_use_color_default = GIT_COLOR_UNKNOWN; static int diff_color_moved_default; -@@ diff.c: int git_diff_ui_config(const char *var, const char *value, - diff_detect_rename_default = git_config_rename(var, value); +@@ diff.c: int git_diff_basic_config(const char *var, const char *value, return 0; } + + if (!strcmp(var, "diff.renamethreshold")) { + const char *arg = value; + if (!value) @@ diff.c: int git_diff_ui_config(const char *var, const char *value, + return error(_("invalid value for '%s': '%s'"), var, value); + return 0; + } - if (!strcmp(var, "diff.autorefreshindex")) { - diff_auto_refresh_index = git_config_bool(var, value); - return 0; ++ + if (userdiff_config(var, value) < 0) + return -1; + @@ diff.c: void repo_diff_setup(struct repository *r, struct diff_options *options) options->add_remove = diff_addremove; options->use_color = diff_use_color_default;255: 0d2fdc1 (upstream: 0d2fdc1) < -: ------------ ci: bump microsoft/setup-msbuild from v2 to v3
256: 5d719b3 (upstream: 5d719b3) < -: ------------ ci: bump actions/{upload,download}-artifact to v7 and v8
257: bfbe0db (upstream: bfbe0db) < -: ------------ ci: bump actions/github-script from v8 to v9
258: 5694ca1 (upstream: 5694ca1) < -: ------------ ci: bump actions/checkout from v5 to v6
259: cd920e9 (upstream: cd920e9) < -: ------------ Add an AGENTS.md file to help with AI-assisted debugging/development
260: b6ee11c (upstream: b6ee11c) < -: ------------ fixup! Add an AGENTS.md file to help with AI-assisted debugging/development
261: 448b5cf (upstream: 448b5cf) < -: ------------ fixup! Add an AGENTS.md file to help with AI-assisted debugging/development
262: 497ffcd (upstream: 497ffcd) < -: ------------ fixup! Add an AGENTS.md file to help with AI-assisted debugging/development
263: 46a110b (upstream: 46a110b) < -: ------------ fixup! Add an AGENTS.md file to help with AI-assisted debugging/development
264: 63f8b95 (upstream: 63f8b95) < -: ------------ fixup! Add an AGENTS.md file to help with AI-assisted debugging/development
265: 6713544 = 253: f0a7682 gvfs-helper: separate packfile extraction from indexing
268: b9b36ab = 254: df89047 blame: add blame.renames, blame.renameThreshold, blame.renameLimit
266: ae9e1e6 = 255: 941b447 gvfs-helper: run prefetch index-pack in parallel
267: 25cd276 < -: ------------ amend! diff: add renameThreshold configuration option
269: 21186cf (upstream: 21186cf) < -: ------------ alias: restore support for simple dotted aliases
270: 39ba52a (upstream: 39ba52a) < -: ------------ fixup! ci: work around a problem with HTTP/2 vs libcurl v8.10.0
271: c340e33 (upstream: c340e33) < -: ------------ fixup! revision: create mark_trees_uninteresting_dense()
272: 97508e9 (upstream: 97508e9) < -: ------------ mingw: optionally use legacy (non-POSIX) delete semantics
273: 12ebd5c (upstream: 12ebd5c) < -: ------------ maintenance(geometric): do release the
.idxfiles before repacking274: 0a32e7b (upstream: 0a32e7b) < -: ------------ fixup! add: use preload-index and fscache for performance
275: add7a58 (upstream: add7a58) < -: ------------ fixup! fscache: fscache takes an initial size
276: cdc2178 < -: ------------ fixup! hooks: add custom post-command hook config
277: 7b9a0a7 < -: ------------ fixup! Add virtual file system settings and hook proc
278: 0752978 = 256: b7043da gvfs-helper: add gvfs.prefetchThreads config for parallel prefetch
279: c6e8df1 (upstream: c6e8df1) < -: ------------ ci: bump git-for-windows/setup-git-for-windows-sdk from v1 to v2
280: b9ccb66 (upstream: b9ccb66) < -: ------------ l10n: bump mshick/add-pr-comment from v2 to v3
281: b797f03 (upstream: b797f03) < -: ------------ fixup! Add a GitHub workflow to verify that Git/Scalar work in Nano Server
282: 9fe9a58 < -: ------------ fixup! release: create initial Windows installer build workflow
283: 6d210a1 < -: ------------ fixup! codeql: run static analysis as part of CI builds
284: c50235a < -: ------------ fixup! workflow: add release-vfsforgit to automate VFS for Git updates
285: 90ef05b < -: ------------ fixup! ci: run Scalar's Functional Tests
286: 1383831 < -: ------------ fixup! ci: add new VFS for Git functional tests workflow
287: 251478a (upstream: 74c3ea9) < -: ------------ build: tolerate use of _Generic from glibc 2.43 with Clang
288: 2431f5e (upstream: 2431f5e) < -: ------------ shallow: fix relative deepen on non-shallow repositories
289: 6e95b07 (upstream: 6e95b07) < -: ------------ builtin/maintenance: fix locking with "--detach"
290: 29364f1 (upstream: 29364f1) < -: ------------ run-command: honor "gc.auto" for auto-maintenance
291: 79971fc < -: ------------ amend! azure-pipelines: add stub release pipeline for Azure
292: e782c90 = 257: bbc1404 azure-pipelines: add ESRP code signing
293: 938529c = 258: ceb76bb azure-pipelines: allow overriding Git version
294: 325ef64 = 259: 5338080 azure-pipelines: build, sign and stage the Linux Debian package
295: 7fa9458 = 260: b805ee4 azure-pipelines: build, sign, notarize and stage the macOS installer
296: 73af387 = 261: d0037b3 azure-pipelines: build, sign and stage the Windows installer
297: a652f28 = 262: 285ba23 azure-pipelines: enable on tag push, default ESRP and GitHub release on
298: 399666a < -: ------------ amend! release: create initial Windows installer build workflow
300: 5ebe6f6 ! 263: 18cc779 release: binskim for Windows
@@ Commit message build-extra git-wrapper launcher shims are all third-party content we cannot fix from this repo. + Since the baseline that is added automatically does not conform to Git's + whitespace rules, also add a `.config/.gitattributes` file to suppress + those checks. + Assisted-by: Claude Opus 4.7 Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com> + Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> ## .azure-pipelines/release.yml ## @@ .azure-pipelines/release.yml: extends: @@ .azure-pipelines/release.yml: extends: # Validate the freshly built installer in-place: silently # install Git-*.exe and assert that `git --version` reports # the version we resolved at the prereqs stage. Folded into + + ## .config/.gitattributes (new) ## +@@ ++* whitespace=-trail,-space,-incomplete301: e0445ac = 264: be3c793 release: suppress unfixable binskim findings
302: 4e19046 = 265: 8be7f3d binskim: add baseline
304: b6c0a4a ! 266: feab5d8 release: drop Azure CLI install on Windows/ARM64
299: 200b063 = 267: 776633a checkout: preserve skip-worktree for virtual filesystem paths
303: 6d20b6b < -: ------------ amend! release: binskim for Windows
-: ------------ > 268: 3a9d8f9 rust: pick a GCC-compatible Cargo target under MSYS2/MinGW
-: ------------ > 269: 55a3538 ci(vfs): install the GCC-compatible Rust target before building
-: ------------ > 270: e96b1d8 fixup! gvfs: add global command pre and post hook procs
-: ------------ > 271: 24ba8ba fixup! gvfs-helper: verify loose objects after write
-: ------------ > 272: e2a6129 fixup! t5799: add support for POST to return either a loose object or packfile
-: ------------ > 273: 5071116 amend! rust: pick a GCC-compatible Cargo target under MSYS2/MinGW
-: ------------ > 274: e69de00 fixup! sha1-file: add function to update existing loose object cache
-: ------------ > 275: 187e5b5 fixup! t9210: differentiate origin and cache servers
-: ------------ > 276: 9133d1c fixup! t9210: differentiate origin and cache servers
-: ------------ > 277: 94b5b6f fixup! status: add status serialization mechanism