Cache `oid_type` in `transport_local` struct during `connect()`
so `git_remote_oid_type()` keeps working after disconnect.
This matches the smart transport behavior.
Exercise git_remote_oid_type on a SHA256 local transport.
The after-disconnect assertion is commented out because
local_oid_type dereferences `t->repo`, which local_close
has already freed (SIGSEGV).
I ran these commands to test btw:
```
cmake .. -DGIT_EXPERIMENTAL_SHA256=ON -DBUILD_TESTS=ON
cmake --build .
./libgit2_tests -snetwork::remote::local::sha256_oid_type
```
Detached remotes already read global/system config for http proxy
settings, but did not apply url.*.insteadOf or url.*.pushInsteadOf
rules. This inconsistency meant that `git_remote_create_detached`
behaved differently from git's `ls-remote`, which was the primary
use case for detached remotes.
This fixes it by loading the default config when no repository is
provided and apply insteadOf rules consistently.
While this is a behavior change, it still respects
`GIT_REMOTE_CREATE_SKIP_INSTEADOF`, meaning that user can restore
the previous behavior with minimal effort
Fixes https://github.com/libgit2/libgit2/issues/5469
`git_remote_create_detached` does not apply
`url.*.insteadOf` or url.*.pushInsteadOf from global config.
These tests currently pass, asserting the buggy behavior
and serving as a minimal reproduction.
The assertions will be updated when the fix is applied.
See <https://github.com/libgit2/libgit2/issues/5469>
Pseudoref lookup now reads `FETCH_HEAD` directly as a loose ref,
but callers still expect looked-up references to know their owning
repository.
Attach the repo's refdb after the loose pseudoref is read so
owner-dependent ops such as peeling can safely resolve objects.
b17ecb23e changed pseudoref lookup to read loose refs directly,
bypassing refdb lookup.
This documents the resulting buggy behavior:
a looked-up `FETCH_HEAD` pseudoref has no owning refdb attached.
`clone_local_into()` copies objects from the source repository
but does not set the destination's object format.
This cause SHA256 repositories to be unreadable after a local clone
because the destination defaults to SHA1.
The remote clone path already handles this correctly
so local clone path follows suite.
See: <https://github.com/libgit2/libgit2/blob/1f34e2a57/src/libgit2/clone.c#L448-L450>
Local clone, both hardlink and copy paths, does not propagate
the source repository's object format to the destination.
A SHA256 repository cloned locally is initialized as SHA1
and caused object lookup failures.
These tests are added as reproducible examples,
and will be fixed in the next commit
* `sha256_via_no_local`
* `file://` URL + `GIT_CLONE_NO_LOCAL` -> remote code path
* `sha256_object_format_is_propagated`
* `file://` URL + `GIT_CLONE_LOCAL` -> local code path with hardlinks
* `sha256_no_links_object_format_is_propagated`
* `file://` URL + `GIT_CLONE_LOCAL_NO_LINKS` -> local code path with copy
We have a bunch of checks for properties of the "files" reference
backend:
- Whether a specific reference has been packed or whether it still
exists as a loose reference.
- Whether empty ref directories get pruned.
- Whether we properly fsync data to disk.
These checks continue to be sensible for that backend, but for any other
backend they plain don't work. Adapt the tests so that we only run them
in case the repository uses the "files" backend.
When testing conditional includes we overwrite the repository's config
file with the relevant conditions. This causes us to fully overwrite all
repository configuration, including the repository format version and
any extensions. While the test repository used in this test does not
have any extensions, we will add a reftable-enabled repository that does
rely on the "refStorage" extension eventually.
Fix this by only modifying the relevant config keys.
There are a bunch of tests where we read or write references via the
filesystem directly. This only works with the "files" backend, but
naturally breaks if we supported any other reference format.
Refactor these tests to instead use the refdb to access those.
At present, the library's oid manipulation functions are slower when
built in SHA256 mode than when not. Add some microbenchmarks around the
oid compare and copy functions to understand this better.
The expression (c & 0x7f) << shift in hdr_sz() causes undefined
behavior when shift >= 32, because (c & 0x7f) is an unsigned int
(32-bit type). A malicious delta with a long varint can trigger this.
Fix by:
1. Casting to size_t before shifting to support 64-bit shifts
2. Adding a shift limit check to reject overlong varints
This patch makes two improvements:
1. In case of LIBSSH2_ERROR_TIMEOUT, don't loop forever
2. Enable TCP keepalive on all sockets to detect dead connections
The added test demonstrates the hang without the patch.
Introduce the GIT_HEAD_REF define so that we can clearly indicate that
we're talking about the "HEAD" reference and not necessarily a file.
Note that there still are a couple of places where GIT_HEAD_FILE is
being used:
- `git_repository_create_head()`: This function is used to create HEAD
when initializing a new repository. This should get fixed eventually
so that we create HEAD via the refdb, but this is a more involved
refactoring that will be handled in a separate patch series.
- `repo_init_head()`: Likewise.
- `conditional_match_onbranch()`: This function is used to decide
whether or not an `includeIf.onbranch` condition matches. This will
be fixed in subsequent commits.
Other than that there shouldn't be any more references to GIT_HEAD_FILE.
The GIT_STASH_FILE define contains the path to the stash reference.
While we know that this used to be a file with the "files" backend, it's
not a standalone file with the "reftable" backend anymore.
Rename the macro to GIT_STASH_REF to indicate that this is a proper ref.
We have a bunch of references that we treat like pseudo-refs. Those
references are (sometimes) read and written by going to the filesystem
directly, at other times they are read and written via the refdb. This
works alright with the "files" ref storage format given that any root
reference never gets packed into the "packed-refs" file, and thus they
would always be accessible a loose ref if present.
The behaviour is wrong though when considering alternate backends like
the "reftable" backend. All references except for pseudo-refs must be
read via the backend, and that includes root refs.
Historically this part of Git has been ill-defined, and it wasn't quite
clear which refs are considered pseudo-refs in the first place. This was
clarified in 6fd80375640 (Documentation/glossary: redefine pseudorefs as
special refs, 2024-05-15): there only are two pseudorefs, "FETCH_HEAD"
and "MERGE_HEAD". The reason why those two references are considered
special is that they may contain additional data that doesn't fit into
the normal reference format.
In any case, our current handling of a couple of root references is
broken in this new world.
Fix this for "ORIG_HEAD" by exclusively going through the refdb to read
and write that reference. Rename the define accordingly to clarify that
it is a reference and not a file.
Allow `git_str_puts_escaped` to take an escaping prefix and an escaping
suffix; this allows for more options, including the ability to better
support escaping executed paths.
When using `git_process_new` on win32, resolve the path to the
application in the same way that we do on POSIX.
Search `PATH` for command to execute (unless the given executable is
fully qualified). In addition, better match Windows executable lookup
behavior itself (allowing the command to be `foo`, and looking for a
matching `foo.exe` or `foo.cmd`.)
Ensure that our `find_executable` behaves as expected:
* When the executable contains a fully- or partially-qualified filename
component (eg, `foo/bar`) that `PATH` is not searched; these paths are
relative to the current working directory.
* An empty segment in `PATH` (on POSIX systems) is treated as the
current directory; this is for compatibility with Bourne shells.
* When a file exists in `PATH`, it is actually executable (on POSIX)
It's certainly possible for the root filesystem to be case-sensitive
while /tmp is not, or vice versa. One example where this might happen
is when running Docker containers (like ci/docker/fedora) on macOS with
the repository checkout on AppleFS (not case sensitive) while the
container's /tmp is case sensitive.
This fix allows the test to pass under those circumstances as well.