summaryrefslogtreecommitdiffstats
path: root/builtin (follow)
AgeCommit message (Collapse)AuthorFilesLines
2024-05-24Merge branch 'jc/fix-2.45.1-and-friends-for-2.39' into fixes/2.45.1/2.40Junio C Hamano1-11/+2
Revert overly aggressive "layered defence" that went into 2.45.1 and friends, which broke "git-lfs", "git-annex", and other use cases, so that we can rebuild necessary counterparts in the open. * jc/fix-2.45.1-and-friends-for-2.39: Revert "fsck: warn about symlink pointing inside a gitdir" Revert "Add a helper function to compare file contents" clone: drop the protections where hooks aren't run tests: verify that `clone -c core.hooksPath=/dev/null` works again Revert "core.hooksPath: add some protection while cloning" init: use the correct path of the templates directory again hook: plug a new memory leak ci: stop installing "gcc-13" for osx-gcc ci: avoid bare "gcc" for osx-gcc job ci: drop mention of BREW_INSTALL_PACKAGES variable send-email: avoid creating more than one Term::ReadLine object send-email: drop FakeTerm hack
2024-05-21clone: drop the protections where hooks aren't runJohannes Schindelin1-11/+1
As part of the security bug-fix releases v2.39.4, ..., v2.45.1, I introduced logic to safeguard `git clone` from running hooks that were installed _during_ the clone operation. The rationale was that Git's CVE-2024-32002, CVE-2021-21300, CVE-2019-1354, CVE-2019-1353, CVE-2019-1352, and CVE-2019-1349 should have been low-severity vulnerabilities but were elevated to critical/high severity by the attack vector that allows a weakness where files inside `.git/` can be inadvertently written during a `git clone` to escalate to a Remote Code Execution attack by virtue of installing a malicious `post-checkout` hook that Git will then run at the end of the operation without giving the user a chance to see what code is executed. Unfortunately, Git LFS uses a similar strategy to install its own `post-checkout` hook during a `git clone`; In fact, Git LFS is installing four separate hooks while running the `smudge` filter. While this pattern is probably in want of being improved by introducing better support in Git for Git LFS and other tools wishing to register hooks to be run at various stages of Git's commands, let's undo the clone protections to unbreak Git LFS-enabled clones. This reverts commit 8db1e8743c0 (clone: prevent hooks from running during a clone, 2024-03-28). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-04-19Sync with 2.39.4Johannes Schindelin4-26/+135
* maint-2.39: (38 commits) Git 2.39.4 fsck: warn about symlink pointing inside a gitdir core.hooksPath: add some protection while cloning init.templateDir: consider this config setting protected clone: prevent hooks from running during a clone Add a helper function to compare file contents init: refactor the template directory discovery into its own function find_hook(): refactor the `STRIP_EXTENSION` logic clone: when symbolic links collide with directories, keep the latter entry: report more colliding paths t5510: verify that D/F confusion cannot lead to an RCE submodule: require the submodule path to contain directories only clone_submodule: avoid using `access()` on directories submodules: submodule paths must not contain symlinks clone: prevent clashing git dirs when cloning submodule in parallel t7423: add tests for symlinked submodule directories has_dir_name(): do not get confused by characters < '/' docs: document security issues around untrusted .git dirs upload-pack: disable lazy-fetching by default fetch/clone: detect dubious ownership of local repositories ...
2024-04-19Merge branch 'ownership-checks-in-local-clones'Johannes Schindelin1-5/+34
This topic addresses two CVEs: - CVE-2024-32020: Local clones may end up hardlinking files into the target repository's object database when source and target repository reside on the same disk. If the source repository is owned by a different user, then those hardlinked files may be rewritten at any point in time by the untrusted user. - CVE-2024-32021: When cloning a local source repository that contains symlinks via the filesystem, Git may create hardlinks to arbitrary user-readable files on the same filesystem as the target repository in the objects/ directory. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2024-04-19clone: prevent hooks from running during a cloneJohannes Schindelin1-1/+11
Critical security issues typically combine relatively common vulnerabilities such as case confusion in file paths with other weaknesses in order to raise the severity of the attack. One such weakness that has haunted the Git project in many a submodule-related CVE is that any hooks that are found are executed during a clone operation. Examples are the `post-checkout` and `fsmonitor` hooks. However, Git's design calls for hooks to be disabled by default, as only disabled example hooks are copied over from the templates in `<prefix>/share/git-core/templates/`. As a defense-in-depth measure, let's prevent those hooks from running. Obviously, administrators can choose to drop enabled hooks into the template directory, though, _and_ it is also possible to override `core.hooksPath`, in which case the new check needs to be disabled. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2024-04-17init: refactor the template directory discovery into its own functionJohannes Schindelin1-18/+4
We will need to call this function from `hook.c` to be able to prevent hooks from running that were written as part of a `clone` but did not originate from the template directory. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2024-04-17submodule: require the submodule path to contain directories onlyJohannes Schindelin1-1/+31
Submodules are stored in subdirectories of their superproject. When these subdirectories have been replaced with symlinks by a malicious actor, all kinds of mayhem can be caused. This _should_ not be possible, but many CVEs in the past showed that _when_ possible, it allows attackers to slip in code that gets executed during, say, a `git clone --recursive` operation. Let's add some defense-in-depth to disallow submodule paths to have anything except directories in them. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2024-04-17clone_submodule: avoid using `access()` on directoriesJohannes Schindelin1-1/+1
In 0060fd1511b (clone --recurse-submodules: prevent name squatting on Windows, 2019-09-12), I introduced code to verify that a git dir either does not exist, or is at least empty, to fend off attacks where an inadvertently (and likely maliciously) pre-populated git dir would be used while cloning submodules recursively. The logic used `access(<path>, X_OK)` to verify that a directory exists before calling `is_empty_dir()` on it. That is a curious way to check for a directory's existence and might well fail for unwanted reasons. Even the original author (it was I ;-) ) struggles to explain why this function was used rather than `stat()`. This code was _almost_ copypastad in the previous commit, but that `access()` call was caught during review. Let's use `stat()` instead also in the code that was almost copied verbatim. Let's not use `lstat()` because in the unlikely event that somebody snuck a symbolic link in, pointing to a crafted directory, we want to verify that that directory is empty. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2024-04-17submodules: submodule paths must not contain symlinksJohannes Schindelin1-0/+35
When creating a submodule path, we must be careful not to follow symbolic links. Otherwise we may follow a symbolic link pointing to a gitdir (which are valid symbolic links!) e.g. while cloning. On case-insensitive filesystems, however, we blindly replace a directory that has been created as part of the `clone` operation with a symlink when the path to the latter differs only in case from the former's path. Let's simply avoid this situation by expecting not ever having to overwrite any existing file/directory/symlink upon cloning. That way, we won't even replace a directory that we just created. This addresses CVE-2024-32002. Reported-by: Filip Hejsek <filip.hejsek@gmail.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2024-04-17clone: prevent clashing git dirs when cloning submodule in parallelFilip Hejsek1-0/+17
While it is expected to have several git dirs within the `.git/modules/` tree, it is important that they do not interfere with each other. For example, if one submodule was called "captain" and another submodule "captain/hooks", their respective git dirs would clash, as they would be located in `.git/modules/captain/` and `.git/modules/captain/hooks/`, respectively, i.e. the latter's files could clash with the actual Git hooks of the former. To prevent these clashes, and in particular to prevent hooks from being written and then executed as part of a recursive clone, we introduced checks as part of the fix for CVE-2019-1387 in a8dee3ca61 (Disallow dubiously-nested submodule git directories, 2019-10-01). It is currently possible to bypass the check for clashing submodule git dirs in two ways: 1. parallel cloning 2. checkout --recurse-submodules Let's check not only before, but also after parallel cloning (and before checking out the submodule), that the git dir is not clashing with another one, otherwise fail. This addresses the parallel cloning issue. As to the parallel checkout issue: It requires quite a few manual steps to create clashing git dirs because Git itself would refuse to initialize the inner one, as demonstrated by the test case. Nevertheless, let's teach the recursive checkout (namely, the `submodule_move_head()` function that is used by the recursive checkout) to be careful to verify that it does not use a clashing git dir, and if it does, disable it (by deleting the `HEAD` file so that subsequent Git calls won't recognize it as a git dir anymore). Note: The parallel cloning test case contains a `cat err` that proved to be highly useful when analyzing the racy nature of the operation (the operation can fail with three different error messages, depending on timing), and was left on purpose to ease future debugging should the need arise. Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2024-04-17upload-pack: disable lazy-fetching by defaultJeff King1-0/+2
The upload-pack command tries to avoid trusting the repository in which it's run (e.g., by not running any hooks and not using any config that contains arbitrary commands). But if the server side of a fetch or a clone is a partial clone, then either upload-pack or its child pack-objects may run a lazy "git fetch" under the hood. And it is very easy to convince fetch to run arbitrary commands. The "server" side can be a local repository owned by someone else, who would be able to configure commands that are run during a clone with the current user's permissions. This issue has been designated CVE-2024-32004. The fix in this commit's parent helps in this scenario, as well as in related scenarios using SSH to clone, where the untrusted .git directory is owned by a different user id. But if you received one as a zip file, on a USB stick, etc, it may be owned by your user but still untrusted. This has been designated CVE-2024-32465. To mitigate the issue more completely, let's disable lazy fetching entirely during `upload-pack`. While fetching from a partial repository should be relatively rare, it is certainly not an unreasonable workflow. And thus we need to provide an escape hatch. This commit works by respecting a GIT_NO_LAZY_FETCH environment variable (to skip the lazy-fetch), and setting it in upload-pack, but only when the user has not already done so (which gives us the escape hatch). The name of the variable is specifically chosen to match what has already been added in 'master' via e6d5479e7a (git: extend --no-lazy-fetch to work across subprocesses, 2024-02-27). Since we're building this fix as a backport for older versions, we could cherry-pick that patch and its earlier steps. However, we don't really need the niceties (like a "--no-lazy-fetch" option) that it offers. By using the same name, everything should just work when the two are eventually merged, but here are a few notes: - the blocking of the fetch in e6d5479e7a is incomplete! It sets fetch_if_missing to 0 when we setup the repository variable, but that isn't enough. pack-objects in particular will call prefetch_to_pack() even if that variable is 0. This patch by contrast checks the environment variable at the lowest level before we call the lazy fetch, where we can be sure to catch all code paths. Possibly the setting of fetch_if_missing from e6d5479e7a can be reverted, but it may be useful to have. For example, some code may want to use that flag to change behavior before it gets to the point of trying to start the fetch. At any rate, that's all outside the scope of this patch. - there's documentation for GIT_NO_LAZY_FETCH in e6d5479e7a. We can live without that here, because for the most part the user shouldn't need to set it themselves. The exception is if they do want to override upload-pack's default, and that requires a separate documentation section (which is added here) - it would be nice to use the NO_LAZY_FETCH_ENVIRONMENT macro added by e6d5479e7a, but those definitions have moved from cache.h to environment.h between 2.39.3 and master. I just used the raw string literals, and we can replace them with the macro once this topic is merged to master. At least with respect to CVE-2024-32004, this does render this commit's parent commit somewhat redundant. However, it is worth retaining that commit as defense in depth, and because it may help other issues (e.g., symlink/hardlink TOCTOU races, where zip files are not really an interesting attack vector). The tests in t0411 still pass, but now we have _two_ mechanisms ensuring that the evil command is not run. Let's beef up the existing ones to check that they failed for the expected reason, that we refused to run upload-pack at all with an alternate user id. And add two new ones for the same-user case that both the restriction and its escape hatch. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2024-04-17builtin/clone: refuse local clones of unsafe repositoriesPatrick Steinhardt1-0/+14
When performing a local clone of a repository we end up either copying or hardlinking the source repository into the target repository. This is significantly more performant than if we were to use git-upload-pack(1) and git-fetch-pack(1) to create the new repository and preserves both disk space and compute time. Unfortunately though, performing such a local clone of a repository that is not owned by the current user is inherently unsafe: - It is possible that source files get swapped out underneath us while we are copying or hardlinking them. While we do perform some checks here to assert that we hardlinked the expected file, they cannot reliably thwart time-of-check-time-of-use (TOCTOU) style races. It is thus possible for an adversary to make us copy or hardlink unexpected files into the target directory. Ideally, we would address this by starting to use openat(3P), fstatat(3P) and friends. Due to platform compatibility with Windows we cannot easily do that though. Furthermore, the scope of these fixes would likely be quite broad and thus not fit for an embargoed security release. - Even if we handled TOCTOU-style races perfectly, hardlinking files owned by a different user into the target repository is not a good idea in general. It is possible for an adversary to rewrite those files to contain whatever data they want even after the clone has completed. Address these issues by completely refusing local clones of a repository that is not owned by the current user. This reuses our existing infra we have in place via `ensure_valid_ownership()` and thus allows a user to override the safety guard by adding the source repository path to the "safe.directory" configuration. This addresses CVE-2024-32020. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2024-04-17builtin/clone: abort when hardlinked source and target file differPatrick Steinhardt1-1/+20
When performing local clones with hardlinks we refuse to copy source files which are symlinks as a mitigation for CVE-2022-39253. This check can be raced by an adversary though by changing the file to a symlink after we have checked it. Fix the issue by checking whether the hardlinked destination file matches the source file and abort in case it doesn't. This addresses CVE-2024-32021. Reported-by: Apple Product Security <product-security@apple.com> Suggested-by: Linus Torvalds <torvalds@linuxfoundation.org> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2024-04-17builtin/clone: stop resolving symlinks when copying filesPatrick Steinhardt1-5/+1
When a user performs a local clone without `--no-local`, then we end up copying the source repository into the target repository directly. To optimize this even further, we try to hardlink files into place instead of copying data over, which helps both disk usage and speed. There is an important edge case in this context though, namely when we try to hardlink symlinks from the source repository into the target repository. Depending on both platform and filesystem the resulting behaviour here can be different: - On macOS and NetBSD, calling link(3P) with a symlink target creates a hardlink to the file pointed to by the symlink. - On Linux, calling link(3P) instead creates a hardlink to the symlink itself. To unify this behaviour, 36596fd2df (clone: better handle symlinked files at .git/objects/, 2019-07-10) introduced logic to resolve symlinks before we try to link(3P) files. Consequently, the new behaviour was to always create a hard link to the target of the symlink on all platforms. Eventually though, we figured out that following symlinks like this can cause havoc when performing a local clone of a malicious repository, which resulted in CVE-2022-39253. This issue was fixed via 6f054f9fb3 (builtin/clone.c: disallow `--local` clones with symlinks, 2022-07-28), by refusing symlinks in the source repository. But even though we now shouldn't ever link symlinks anymore, the code that resolves symlinks still exists. In the best case the code does not end up doing anything because there are no symlinks anymore. In the worst case though this can be abused by an adversary that rewrites the source file after it has been checked not to be a symlink such that it actually is a symlink when we call link(3P). Thus, it is still possible to recreate CVE-2022-39253 due to this time-of-check-time-of-use bug. Remove the call to `realpath()`. This doesn't yet address the actual vulnerability, which will be handled in a subsequent commit. Reported-by: Apple Product Security <product-security@apple.com> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2023-02-27Merge branch 'jc/countermand-format-attach'Junio C Hamano1-0/+2
The format.attach configuration variable lacked a way to override a value defined in a lower-priority configuration file (e.g. the system one) by redefining it in a higher-priority configuration file. Now, setting format.attach to an empty string means show the patch inline in the e-mail message, without using MIME attachment. This is a backward incompatible change. * jc/countermand-format-attach: format.attach: allow empty value to disable multi-part messages
2023-02-27Merge branch 'mh/credential-password-expiry'Junio C Hamano1-0/+3
The credential subsystem learned that a password may have an explicit expiration. * mh/credential-password-expiry: credential: new attribute password_expiry_utc
2023-02-24Merge branch 'ma/fetch-parallel-use-online-cpus'Junio C Hamano1-0/+3
"git fetch --jobs=0" used to hit a BUG(), which has been corrected to use the available CPUs. * ma/fetch-parallel-use-online-cpus: fetch: choose a sensible default with --jobs=0 again
2023-02-22credential: new attribute password_expiry_utcM Hickford1-0/+3
Some passwords have an expiry date known at generation. This may be years away for a personal access token or hours for an OAuth access token. When multiple credential helpers are configured, `credential fill` tries each helper in turn until it has a username and password, returning early. If Git authentication succeeds, `credential approve` stores the successful credential in all helpers. If authentication fails, `credential reject` erases matching credentials in all helpers. Helpers implement corresponding operations: get, store, erase. The credential protocol has no expiry attribute, so helpers cannot store expiry information. Even if a helper returned an improvised expiry attribute, git credential discards unrecognised attributes between operations and between helpers. This is a particular issue when a storage helper and a credential-generating helper are configured together: [credential] helper = storage # eg. cache or osxkeychain helper = generate # eg. oauth `credential approve` stores the generated credential in both helpers without expiry information. Later `credential fill` may return an expired credential from storage. There is no workaround, no matter how clever the second helper. The user sees authentication fail (a retry will succeed). Introduce a password expiry attribute. In `credential fill`, ignore expired passwords and continue to query subsequent helpers. In the example above, `credential fill` ignores the expired password and a fresh credential is generated. If authentication succeeds, `credential approve` replaces the expired password in storage. If authentication fails, the expired credential is erased by `credential reject`. It is unnecessary but harmless for storage helpers to self prune expired credentials. Add support for the new attribute to credential-cache. Eventually, I hope to see support in other popular storage helpers. Example usage in a credential-generating helper https://github.com/hickford/git-credential-oauth/pull/16 Signed-off-by: M Hickford <mirth.hickford@gmail.com> Reviewed-by: Calvin Wan <calvinwan@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-22Merge branch 'ab/hook-api-with-stdin'Junio C Hamano2-17/+7
Extend the run-hooks API to allow feeding data from the standard input when running the hook script(s). * ab/hook-api-with-stdin: hook: support a --to-stdin=<path> option sequencer: use the new hook API for the simpler "post-rewrite" call hook API: support passing stdin to hooks, convert am's 'post-rewrite' run-command: allow stdin for run_processes_parallel run-command.c: remove dead assignment in while-loop
2023-02-22Merge branch 'ab/various-leak-fixes'Junio C Hamano12-53/+79
Leak fixes. * ab/various-leak-fixes: push: free_refs() the "local_refs" in set_refspecs() push: refactor refspec_append_mapped() for subsequent leak-fix receive-pack: release the linked "struct command *" list grep API: plug memory leaks by freeing "header_list" grep.c: refactor free_grep_patterns() builtin/merge.c: free "&buf" on "Your local changes..." error builtin/merge.c: use fixed strings, not "strbuf", fix leak show-branch: free() allocated "head" before return commit-graph: fix a parse_options_concat() leak http-backend.c: fix cmd_main() memory leak, refactor reg{exec,free}() http-backend.c: fix "dir" and "cmd_arg" leaks in cmd_main() worktree: fix a trivial leak in prune_worktrees() repack: fix leaks on error with "goto cleanup" name-rev: don't xstrdup() an already dup'd string various: add missing clear_pathspec(), fix leaks clone: use free() instead of UNLEAK() commit-graph: use free_commit_graph() instead of UNLEAK() bundle.c: don't leak the "args" in the "struct child_process" tests: mark tests as passing with SANITIZE=leak
2023-02-22Merge branch 'jk/doc-ls-remote-matching'Junio C Hamano1-1/+1
Doc update. * jk/doc-ls-remote-matching: doc/ls-remote: clarify pattern format doc/ls-remote: cosmetic cleanups for examples
2023-02-22Merge branch 'ab/the-index-compatibility'Junio C Hamano8-28/+34
Remove more remaining uses of macros that relies on the_index singleton instance without explicitly spelling it out. * ab/the-index-compatibility: cocci & cache.h: remove "USE_THE_INDEX_COMPATIBILITY_MACROS" cache-tree API: remove redundant update_main_cache_tree() cocci & cache-tree.h: migrate "write_cache_as_tree" to "*_index_*" cocci & cache.h: apply pending "index_cache_pos" rule cocci & cache.h: fully apply "active_nr" part of index-compatibility builtin/rm.c: use narrower "USE_THE_INDEX_VARIABLE"
2023-02-22Merge branch 'en/name-rev-make-taggerdate-much-less-important'Junio C Hamano1-11/+3
"git name-rev" heuristics update. * en/name-rev-make-taggerdate-much-less-important: name-rev: fix names by dropping taggerdate workaround
2023-02-21fetch: choose a sensible default with --jobs=0 againMatthias Aßhauer1-0/+3
prior to 51243f9 (run-command API: don't fall back on online_cpus(), 2022-10-12) `git fetch --multiple --jobs=0` would choose some default amount of jobs, similar to `git -c fetch.parallel=0 fetch --multiple`. While our documentation only ever promised that `fetch.parallel` would fall back to a "sensible default", it makes sense to do the same for `--jobs`. So fall back to online_cpus() and not BUG() out. This fixes https://github.com/git-for-windows/git/issues/4302 Reported-by: Drew Noakes <drnoakes@microsoft.com> Signed-off-by: Matthias Aßhauer <mha1993@live.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-17format.attach: allow empty value to disable multi-part messagesJunio C Hamano1-0/+2
When a lower precedence configuration file (e.g. /etc/gitconfig) defines format.attach in any way, there was no way to disable it in a more specific configuration file (e.g. $HOME/.gitconfig). Change the behaviour of setting it to an empty string. It used to mean that the result is still a multipart message with only dashes used as a multi-part separator, but now it resets the setting to the default (which would be to give an inline patch, unless other command line options are in effect). Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-15Merge branch 'ab/retire-scripted-add-p'Junio C Hamano5-60/+22
Finally retire the scripted "git add -p/-i" implementation and have everybody use the one reimplemented in C. * ab/retire-scripted-add-p: docs & comments: replace mentions of "git-add--interactive.perl" add API: remove run_add_interactive() wrapper function add: remove "add.interactive.useBuiltin" & Perl "git add--interactive"
2023-02-15Merge branch 'rs/size-t-fixes'Junio C Hamano1-8/+5
Type fixes. * rs/size-t-fixes: pack-objects: use strcspn(3) in name_cmp_len() read-cache: use size_t for {base,df}_name_compare()
2023-02-15Merge branch 'ab/sequencer-unleak'Junio C Hamano2-15/+15
Plug leaks in sequencer subsystem and its users. * ab/sequencer-unleak: commit.c: free() revs.commit in get_fork_point() builtin/rebase.c: free() "options.strategy_opts" sequencer.c: always free() the "msgbuf" in do_pick_commit() builtin/rebase.c: fix "options.onto_name" leak builtin/revert.c: move free-ing of "revs" to replay_opts_release() sequencer API users: fix get_replay_opts() leaks sequencer.c: split up sequencer_remove_state() rebase: use "cleanup" pattern in do_interactive_rebase()
2023-02-15Merge branch 'ds/bundle-uri-5'Junio C Hamano2-1/+11
The bundle-URI subsystem adds support for creation-token heuristics to help incremental fetches. * ds/bundle-uri-5: bundle-uri: test missing bundles with heuristic bundle-uri: store fetch.bundleCreationToken fetch: fetch from an external bundle URI bundle-uri: drop bundle.flag from design doc clone: set fetch.bundleURI if appropriate bundle-uri: download in creationToken order bundle-uri: parse bundle.<id>.creationToken values bundle-uri: parse bundle.heuristic=creationToken t5558: add tests for creationToken heuristic bundle: verify using check_connected() bundle: test unbundling with incomplete history
2023-02-14Merge branch 'rs/am-parse-options-cleanup' into maint-2.39Junio C Hamano1-1/+11
Code clean-up. * rs/am-parse-options-cleanup: am: don't pass strvec to apply_parse_options()
2023-02-14Merge branch 'jk/unused-post-2.39' into maint-2.39Junio C Hamano7-7/+8
Code clean-up around unused function parameters. * jk/unused-post-2.39: userdiff: mark unused parameter in internal callback list-objects-filter: mark unused parameters in virtual functions diff: mark unused parameters in callbacks xdiff: mark unused parameter in xdl_call_hunk_func() xdiff: drop unused parameter in def_ff() ws: drop unused parameter from ws_blank_line() list-objects: drop process_gitlink() function blob: drop unused parts of parse_blob_buffer() ls-refs: use repository parameter to iterate refs
2023-02-14Merge branch 'rj/branch-copy-and-rename' into maint-2.39Junio C Hamano1-3/+3
Fix a pair of bugs in 'git branch'. * rj/branch-copy-and-rename: branch: force-copy a branch to itself via @{-1} is a no-op
2023-02-14Merge branch 'rs/ls-tree-path-expansion-fix' into maint-2.39Junio C Hamano1-8/+5
"git ls-tree --format='%(path) %(path)' $tree $path" showed the path three times, which has been corrected. * rs/ls-tree-path-expansion-fix: ls-tree: remove dead store and strbuf for quote_c_style() ls-tree: fix expansion of repeated %(path)
2023-02-14Merge branch 'ab/bundle-wo-args' into maint-2.39Junio C Hamano1-5/+4
Fix to a small regression in 2.38 days. * ab/bundle-wo-args: bundle <cmd>: have usage_msg_opt() note the missing "<file>" builtin/bundle.c: remove superfluous "newargc" variable bundle: don't segfault on "git bundle <subcmd>"
2023-02-13Sync with Git 2.39.2Junio C Hamano1-4/+4
2023-02-10doc/ls-remote: clarify pattern formatJeff King1-1/+1
We document that you can specify "refs" to ls-remote, but we don't explain any further than that they are "matched" as patterns. Since this can be interpreted in a lot of ways, let's clarify that they are tail-matched globs. Likewise, let's use the word "patterns" to refer to them consistently, rather than "refs" (both here and in the quick "-h" help), and mention more explicitly that only one pattern needs to be matched (though there is also an example already that shows this in action). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-10cocci & cache.h: remove "USE_THE_INDEX_COMPATIBILITY_MACROS"Ævar Arnfjörð Bjarmason2-6/+6
Have the last users of "USE_THE_INDEX_COMPATIBILITY_MACROS" use the underlying *_index() variants instead. Now all previous users of "USE_THE_INDEX_COMPATIBILITY_MACROS" have been migrated away from the wrapper macros, and if applicable to use the "USE_THE_INDEX_VARIABLE" added in [1]. Let's leave the "index-compatibility.cocci" in place, even though it won't be doing anything on "master". It will benefit any out-of-tree code that need to use these compatibility macros. We can eventually remove it. 1. bdafeae0b9c (cache.h & test-tool.h: add & use "USE_THE_INDEX_VARIABLE", 2022-11-19) Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-10cache-tree API: remove redundant update_main_cache_tree()Ævar Arnfjörð Bjarmason1-5/+5
Remove the redundant update_main_cache_tree() function, and make its users use cache_tree_update() instead. The behavior of populating the "the_index.cache_tree" if it wasn't present already was needed when this function was introduced in [1], but it hasn't been needed since [2]; The "cache_tree_update()" will now lazy-allocate, so there's no need for the wrapper. 1. 996277c5206 (Refactor cache_tree_update idiom from commit, 2011-12-06) 2. fb0882648e0 (cache-tree: clean up cache_tree_update(), 2021-01-23) Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-10cocci & cache-tree.h: migrate "write_cache_as_tree" to "*_index_*"Ævar Arnfjörð Bjarmason4-10/+14
Add a trivial rule for "write_cache_as_tree" to "index-compatibility.cocci", and apply it. This was left out of the rules added in 0e6550a2c63 (cocci: add a index-compatibility.pending.cocci, 2022-11-19) because this compatibility wrapper lived in "cache-tree.h", not "cache.h" But it's like the other "USE_THE_INDEX_COMPATIBILITY_MACROS", so let's migrate it too. The replacement of "USE_THE_INDEX_COMPATIBILITY_MACROS" here with "USE_THE_INDEX_VARIABLE" is a manual change on top, now that these files only use "&the_index", and don't need any compatibility macros (or functions). The wrapping of some argument lists is likewise manual, as coccinelle would otherwise give us overly long argument lists. The reason for putting the "O" in the cocci rule on the "-" and "+" lines is because I couldn't get correct whitespacing otherwise, i.e. I'd end up with "oid,&the_index", not "oid, &the_index". Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-10cocci & cache.h: apply pending "index_cache_pos" ruleÆvar Arnfjörð Bjarmason2-5/+7
Apply the rule added in [1] to change "cache_name_pos" to "index_name_pos", which allows us to get rid of another "USE_THE_INDEX_COMPATIBILITY_MACROS" macro. The replacement of "USE_THE_INDEX_COMPATIBILITY_MACROS" here with "USE_THE_INDEX_VARIABLE" is a manual change on top, now that these files only use "&the_index", and don't need any compatibility macros (or functions). 1. 0e6550a2c63 (cocci: add a index-compatibility.pending.cocci, 2022-11-19) Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-10cocci & cache.h: fully apply "active_nr" part of index-compatibilityÆvar Arnfjörð Bjarmason1-1/+1
Apply the "active_nr" part of "index-compatibility.pending.cocci", which was left out in [1] due to an in-flight conflict. As of [2] the topic we conflicted with has been merged to "master", so we can fully apply this rule. 1. dc594180d9e (cocci & cache.h: apply variable section of "pending" index-compatibility, 2022-11-19) 2. 9ea1378d046 (Merge branch 'ab/various-leak-fixes', 2022-12-14) Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-10builtin/rm.c: use narrower "USE_THE_INDEX_VARIABLE"Ævar Arnfjörð Bjarmason1-1/+1
Replace the "USE_THE_INDEX_COMPATIBILITY_MACROS" define with the narrower "USE_THE_INDEX_VARIABLE". This could have been done in 07047d68294 (cocci: apply "pending" index-compatibility to some "builtin/*.c", 2022-11-19), but I missed it at the time. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-09Merge branch 'ew/free-island-marks'Junio C Hamano1-1/+3
"git pack-objects" learned to release delta-island bitmap data when it is done using it, saving peak heap memory usage. * ew/free-island-marks: delta-islands: free island_marks and bitmaps
2023-02-09name-rev: fix names by dropping taggerdate workaroundElijah Newren1-11/+3
Commit 7550424804 ("name-rev: include taggerdate in considering the best name", 2016-04-22) introduced the idea of using taggerdate in the criteria for selecting the best name. At the time, a certain commit in linux.git -- namely, aed06b9cfcab -- was being named by name-rev as v4.6-rc1~9^2~792 which, while correct, was very suboptimal. Some investigation found that tweaking the MERGE_TRAVERSAL_WEIGHT to lower it could give alternate answers such as v3.13-rc7~9^2~14^2~42 or v3.13~5^2~4^2~2^2~1^2~42 A manual solution involving looking at tagger dates came up with v3.13-rc1~65^2^2~42 which is much nicer. That workaround was then implemented in name-rev. Unfortunately, the taggerdate heuristic is causing bugs. I was pointed to a case in a private repository where name-rev reports a name of the form v2022.10.02~86 when users expected to see one of the form v2022.10.01~2 (I've modified the names and numbers a bit from the real testcase.) As you can probably guess, v2022.10.01 was created after v2022.10.02 (by a few hours), even though it pointed to an older commit. While the condition is unusual even in the repository in question, it is not the only problematic set of tags in that repository. The taggerdate logic is causing problems. Further, it turns out that this taggerdate heuristic isn't even helping anymore. Due to the fix to naming logic in 3656f84278 ("name-rev: prefer shorter names over following merges", 2021-12-04), we get improved names without the taggerdate heuristic. For the original commit of interest in linux.git, a modern git without the taggerdate heuristic still provides the same optimal answer of interest, namely: v3.13-rc1~65^2^2~42 So, the taggerdate is no longer providing benefit, and it is causing problems. Simply get rid of it. However, note that "taggerdate" as a variable is used to store things besides a taggerdate these days. Ever since commit ef1e74065c ("name-rev: favor describing with tags and use committer date to tiebreak", 2017-03-29), this has been used to store committer dates and there it is used as a fallback tiebreaker (as opposed to a primary criteria overriding effective distance calculations). We do not want to remove that fallback tiebreaker, so not all instances of "taggerdate" are removed in this change. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-08hook: support a --to-stdin=<path> optionEmily Shaffer1-1/+3
Expose the "path_to_stdin" API added in the preceding commit in the "git hook run" command. For now we won't be using this command interface outside of the tests, but exposing this functionality makes it easier to test the hook API. The plan is to use this to extend the "sendemail-validate" hook[1][2]. 1. https://lore.kernel.org/git/ad152e25-4061-9955-d3e6-a2c8b1bd24e7@amd.com 2. https://lore.kernel.org/git/20230120012459.920932-1-michael.strawbridge@amd.com Signed-off-by: Emily Shaffer <emilyshaffer@google.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-08hook API: support passing stdin to hooks, convert am's 'post-rewrite'Emily Shaffer1-16/+4
Convert the invocation of the 'post-rewrite' hook run by 'git am' to use the hook.h library. To do this we need to add a "path_to_stdin" member to "struct run_hooks_opt". In our API this is supported by asking for a file path, rather than by reading stdin. Reading directly from stdin would involve caching the entire stdin (to memory or to disk) once the hook API is made to support "jobs" larger than 1, along with support for executing N hooks at a time (i.e. the upcoming config-based hooks). Signed-off-by: Emily Shaffer <emilyshaffer@google.com> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-06builtin/rebase.c: free() "options.strategy_opts"Ævar Arnfjörð Bjarmason1-0/+1
When the "strategy_opts" member was added in ba1905a5fef (builtin rebase: add support for custom merge strategies, 2018-09-04) the corresponding free() for it at the end of cmd_rebase() wasn't added, let's do so. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-06builtin/rebase.c: fix "options.onto_name" leakÆvar Arnfjörð Bjarmason1-1/+3
Similar to the existing "squash_onto_name" added in [1] we need to free() the xstrdup()'d "options.onto.name" added for "--keep-base" in [2].. 1. 9dba809a69a (builtin rebase: support --root, 2018-09-04) 2. 414d924beb4 (rebase: teach rebase --keep-base, 2019-08-27) Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-06builtin/revert.c: move free-ing of "revs" to replay_opts_release()Ævar Arnfjörð Bjarmason1-6/+0
In [1] and [2] I added the code being moved here to cmd_revert() and cmd_cherry_pick(), now that we've got a "replay_opts_release()" for the "struct replay_opts" it should know how to free these "revs", rather than having these users reach into the struct to free its individual members. 1. d1ec656d68f (cherry-pick: free "struct replay_opts" members, 2022-11-08) 2. fd74ac95ac3 (revert: free "struct replay_opts" members, 2022-07-01) Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-06sequencer API users: fix get_replay_opts() leaksÆvar Arnfjörð Bjarmason2-0/+6
Make the replay_opts_release() function added in the preceding commit non-static, and use it for freeing the "struct replay_opts" constructed for "rebase" and "revert". To safely call our new replay_opts_release() we'll need to stop calling it in sequencer_remove_state(), and instead call it where we allocate the "struct replay_opts" itself. This is because in e.g. do_interactive_rebase() we construct a "struct replay_opts" with "get_replay_opts()", and then call "complete_action()". If we get far enough in that function without encountering errors we'll call "pick_commits()" which (indirectly) calls sequencer_remove_state() at the end. But if we encounter errors anywhere along the way we'd punt out early, and not free() the memory we allocated. Remembering whether we previously called sequencer_remove_state() would be a hassle. Using a FREE_AND_NULL() pattern would also work, as it would be safe to call replay_opts_release() repeatedly. But let's fix this properly instead, by having the owner of the data free() it. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>