summaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
7 hoursGit 2.56-rc0HEADv2.56.0-rc0mastermainJunio C Hamano2-1/+27
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 hoursMerge branch 'en/midx-missing-pack-fallback'Junio C Hamano10-20/+200
The object lookup machinery has been taught to gracefully recover when a multi-pack-index points to an owning pack that was removed during a concurrent geometric repack, and 'git replay' has been fixed to not segfault when reading such missing objects. * en/midx-missing-pack-fallback: packfile: recover when a multi-pack-index names a removed pack mktree: do not use OBJECT_INFO_QUICK when checking objects mktree: plug per-tree leak in --batch mode replay: fail gracefully when a merge input is unreadable
7 hoursMerge branch 'jk/rev-info-argv-to-free'Junio C Hamano3-11/+57
The memory ownership of argv elements passed to the revision machinery has been made more robust by keeping logically "freed" elements alive until the rev_info struct is released, preventing use-after-free bugs when options store references to them. * jk/rev-info-argv-to-free: revision: simplify mark_argv_for_free() callers revision: hang on to "freed" argv elements
7 hoursMerge branch 'tc/replay-linearize'Junio C Hamano5-28/+196
The 'git replay' command has been taught the '--linearize' option to drop merge commits and linearize the replayed history, mimicking 'git rebase --no-rebase-merges'. * tc/replay-linearize: replay: offer an option to linearize the commit topology replay: resolve the replay base outside pick_regular_commit() replay: add helper to put entry into replayed_commits
7 hoursMerge branch 'hk/typofix'Junio C Hamano2-2/+2
Various spelling mistakes in comments and test descriptions have been corrected. * hk/typofix: versioncmp: fix typo in versioncmp.c, t/t0022-crlf-rename.sh
7 hoursMerge branch 'rs/worktree-add-basename-fixes'Junio C Hamano2-19/+31
The string extraction logic for the branch name and worktree name from the given path in 'git worktree add' has been corrected and simplified to avoid out-of-bounds reads and improper handling of trailing slashes. * rs/worktree-add-basename-fixes: worktree add: let worktree_basename() return string copy worktree add: trim slashes when deriving branch name from path worktree add: reject separator-only path worktree add: don't read out of bounds in worktree_basename()
7 hoursMerge branch 'hn/ci-cancel-stale-pr-runs'Junio C Hamano1-9/+11
GitHub Actions CI workflow runs triggered by pull requests have been configured to cancel older runs when a new push is made to the same pull request. * hn/ci-cancel-stale-pr-runs: ci: cancel stale pull request workflow runs
7 hoursMerge branch 'ns/ref-symref-additional-tests'Junio C Hamano2-3/+18
A few tests for the reference handling subsystem have been added to exercise the handling of forbidden characters and symbolic references. * ns/ref-symref-additional-tests: t1402: test forbidden characters in refnames t1401: check symbolic-ref failure and --quiet silence on a non-symbolic ref
3 daysThe 23rd batchJunio C Hamano1-0/+31
Signed-off-by: Junio C Hamano <gitster@pobox.com>
3 daysMerge branch 'yn/worktree-repair-relative'Junio C Hamano4-50/+94
The git worktree repair command failed to rewrite the .git file of a working tree from a relative path to an absolute path when the command was run in the working tree itself. The read_gitfile_gently() function was modified to also return whether the path originally recorded in the file was absolute, and this new capability is used to correctly detect such mismatches. * yn/worktree-repair-relative: worktree repair: detect relative path in .git file correctly
3 daysMerge branch 'll/zsh-complete-git-potty-options'Junio C Hamano1-1/+24
The zsh completion script (in 'contrib/') has been updated to correctly locate the Git command after global options like '-C' by properly skipping them, similar to how the bash completion does. * ll/zsh-complete-git-potty-options: completion: zsh: support completion after "git -C <path>"
3 daysMerge branch 'gr/add-e-use-apply-api'Junio C Hamano2-7/+22
The application of the edited patch in 'git add -e' has been refactored to use the internal apply API directly, avoiding the need to spawn a 'git apply' subprocess. * gr/add-e-use-apply-api: builtin/add.c: replace run_command() with direct apply_all_patches() call
3 daysMerge branch 'jc/you-still-use-that'Junio C Hamano3-11/+9
The instructions for deprecated commands emitted by you_still_use_that() have been reworded to clarify that the removal decision is final and to provide more assertive guidance on finding a replacement. * jc/you-still-use-that: you_still_use_that(): reword the instructions
3 daysMerge branch 'yn/worktree-ambiguous-remote-advice'Junio C Hamano7-44/+133
'git checkout' and 'git worktree add' makes guesses based on a name of a remote-tracking branch, but does not give an error when such a remote-tracking branch cannot be uniquely identified, which has been corrected. * yn/worktree-ambiguous-remote-advice: worktree add: treat multiple matches with --guess-remote as an error worktree add: improve message for ambiguous remote branch name checkout: improve message for ambiguous remote branch name checkout: extract function to display advice for ambiguous remotes
3 daysMerge branch 'kn/reftable-optimize-reloading'Junio C Hamano5-110/+119
The reftable code has been optimized to avoid an unnecessary stat/reload of the stack when an addition already holds the list_file lock, reducing the number of newfstatat syscalls from linear to constant when writing refs. * kn/reftable-optimize-reloading: reftable/stack: avoid reloading the stack when already locked reftable/stack: move list lock to `struct reftable_stack` reftable/stack: rename reftable_stack_new_addition() reftable/stack: remove `REFTABLE_STACK_NEW_ADDITION_RELOAD`
8 daysThe 22nd batchJunio C Hamano1-0/+5
Signed-off-by: Junio C Hamano <gitster@pobox.com>
8 daysMerge branch 'jc/rerere-doc-typofix'Junio C Hamano1-1/+1
A missing preposition in the rerere technical documentation has been fixed. * jc/rerere-doc-typofix: rerere: technical documentation typofix
8 daysMerge branch 'ty/repository-fetch-if-missing'Junio C Hamano15-49/+51
The global variable 'fetch_if_missing' has been moved to a member in 'struct repository', continuing the libification process and allowing per-repository control (such as for submodules). * ty/repository-fetch-if-missing: repository: move fetch_if_missing into struct repository
9 daysrevision: simplify mark_argv_for_free() callersJeff King1-8/+8
You do not want to mark an argv element for freeing unless the caller has given us the free_removed_argv_elements flag. Originally we just called free() in this case, so each caller checked the flag itself. Now that we mark them via a helper function, we can push the check down into the helper. This saves a little bit of duplicated code, but also hopefully makes the result conceptually simpler. Every caller but one was already checking this flag. The exception is setup_revisions_from_strvec(), but it always sets the flag explicitly (since its whole purpose is managing argv memory). So even though it was not checking the flag, doing so is OK (it will always be set). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
9 daysrevision: hang on to "freed" argv elementsJeff King3-8/+54
In setup_revisions() we rewrite the incoming argv array, losing references to the strings it contains. For a synthetic argv array constructed from heap strings, that traditionally meant we leaked those allocated strings. We fixed the leak in cd43948798 (revision: manage memory ownership of argv in setup_revisions(), 2025-09-19). Now callers can tell the revision code that argv entries are allocated and should be freed, which it will do before overwriting them. But this introduced a new bug! The overwritten entries go away as soon as option parsing is finished, but a few options may actually create new references to those strings. And once we free the strings, those stale references become use-after-free bugs. For example, running: git stash show --src-prefix=foo/ demonstrates the problem: 1. The stash command generates its own synthetic argv (because it has to treat the stash specifiers specially) which it then passes to setup_revisions(). 2. Parsing will create a reference to the partial string "foo/" in revs.diffopt.a_prefix. 3. When setup_revisions() finishes, we rewrite argv to throw away parsed strings. This frees the entry holding "--src-prefix=foo", at which point we have a dangling reference in revs.diffopt. 4. We generate an actual diff, accessing garbage memory via revs.diffopt.a_prefix. The output is usually garbled, but ASan also detects this reliably. One obvious fix here is to allocate new strings when we pull data out of the argv array. But doing so is error prone (every string option must remember to do it or risk a subtle bug), and creates more questions about memory ownership (e.g., some callers assign string literals directly to a_prefix, and we would not want to free those). Instead we can fix this centrally by delaying the free() calls. We'll collect any "freed" strings in a new array, hold on to it for the life of the rev_info struct, and then release it at the end. We can easily use a strvec for this, since it handles growth and cleanup for us. This fixes the prefix case above (which is now tested in t3903), and should fix any other stray cases. Though I could not find any; we use OPT_STRING only in the prefix diff options, and very few revision opts store strings. Those that do (like --format and --encoding) already make a copy of the string. They do not need for us to hold on to the memory longer, but it does not hurt them if we do. One may note that combined with cd43948798 we have approached a simpler solution in a roundabout way. We are still hacking up argv, but now carefully constructing a parallel argv of old strings we've overwritten (and will eventually free). In an alternate universe, we could instead leave the original argv pristine and return a new reduced-size argv. This is conceptually simpler, though it does mean that every caller must free that new argv array itself (not the entries). That's not something they traditionally had to do, so it would mean tweaking every caller. So even though the combination of this cd43948798 and this patch is a little convoluted, it should make things just work (no leaks and no use-after-free) without modifying any callers. Reported-by: Nicolas Le Cam <niko.lecam@gmail.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
10 daysversioncmp: fix typo in versioncmp.c, t/t0022-crlf-rename.shHardik Kumar2-2/+2
The patch fixes two typos in two places. versioncmp.c: "fractionnal" -> "fractional" t/t0022-crlf-rename.sh: "similiarity" -> "similarity" No functional changes, only update a comment and a test_description. Signed-off-by: Hardik Kumar <hardikxk@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
10 daysci: cancel stale pull request workflow runsHarald Nordgren1-9/+11
The CI workflow groups all runs by commit hash using `group: ${{ github.sha }}`. This means every push to a pull request starts a separate workflow run, and all workflows triggered by the same commit share the same concurrency group. With this change, pull request runs are grouped by pull request number instead of commit hash, and runs superseded by a newer push are canceled. The concurrency group becomes `${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}` and `cancel-in-progress` is set to true for pull request events. For pull request events, the group is `<workflow>-<pull-request-number>` (e.g., "main-workflow-42"). If you push a new commit to an existing pull request before the CI working on it finishes, the new request will be placed in the same group and cancel the currently running run. For non-pull-request events, the group is `${{ github.workflow }}-${{ github.sha }}` and `cancel-in-progress` defaults to false, so there is no regression in behavior. Note that the previous configuration used `group: ${{ github.sha }}`, which meant all workflows sharing the same commit hash were in the same group. The new configuration includes the workflow name in the group, so each workflow has its own concurrency group per commit/PR. Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
10 daysreplay: offer an option to linearize the commit topologyToon Claes5-20/+171
One of the stated goals of git-replay(1) is to allow implementing the git-rebase(1) functionality on the server side. The default mode of git-rebase(1) is to act as if `--no-rebase-merges` was given. This mode drops merge commits instead of replaying them, and linearizes the history into a sequence of regular (single-parent) commits. Add option `--linearize` to git-replay(1) to do the same. Each replayed commit is stacked on top of the previously replayed one. When a merge is encountered, the commits reachable from all of its sides are replayed into the single line and the merge itself is dropped. If a ref was pointing to a merge commit, that ref is updated to the merge's last replayed ancestor. git-replay(1) accepts multiple branches, for example: $ git replay --onto main topic1 topic2 Without `--linearize` this replays 'topic1' and 'topic2' onto 'main' (keeping shared portions of history shared and divergent parts divergent) and updates both refs. Due to current implementation limitations, replaying multiple branches with `--linearize` is disallowed to avoid concatenating unrelated histories into a single line. For the same reason disallow the use of `--contained` with `--linearize`. Users who want to linearize multiple branches are advised to do this in separate git-replay(1) invocations. Linearizing multiple branches at once might be added later. Note that `--linearize` is not modeled after git-rebase(1)'s `--rebase-merges[=<mode>]` interface. Recreating merges, by preserving their topology, is a distinct operation that would be a separate mode. `--linearize` only drops merges and replays commits linearly. So git-replay(1) uses its own option rather than reusing that interface. Based-on-patches-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
10 daysreplay: resolve the replay base outside pick_regular_commit()Toon Claes1-13/+21
Depending on what gets passed into the function pick_regular_commit(), it decides the new base for the replayed commit. It first tries to find the replayed results of `pickme`'s parent in the `replayed_commits` map. If not found, it falls back to `onto`. When using git-replay(1) with --onto, the fallback is the revision passed in with this option, but when using --revert, the fallback is `last_commit`. It's rather confusing the base is decided partly inside pick_regular_commit() and partly by its caller. Move the base selection completely into the caller: replay_revisions(). This bundles all the logic of deciding on the base together. Also, this reduces the number of parameters of pick_regular_commit(), making its interface cleaner. This refactoring doesn't bring any behavior changes. Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
10 daysreplay: add helper to put entry into replayed_commitsToon Claes1-11/+20
The function replay_revisions() in replay.c is rather lengthy. Extract the logic to put a commit entry into a `struct mapped_commits` into a helper function put_mapped_commit(). While at it, rename mapped_commit() to get_mapped_commit() to pair with this new function. Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
10 daysThe 21st batchJunio C Hamano1-0/+45
Signed-off-by: Junio C Hamano <gitster@pobox.com>
10 daysMerge branch 'fr/pack-objects-trace-pack-bytes'Junio C Hamano2-0/+29
The pack-objects command has been updated to record the total bytes written to pack files in trace2 output, allowing performance analysis of different compression settings by comparing the resulting pack sizes. * fr/pack-objects-trace-pack-bytes: pack-objects: trace pack bytes written
10 daysMerge branch 'ps/odb-pluggable-pack-generation'Junio C Hamano10-218/+507
The mechanism to generate a packfile corresponding to the result of a fetch/push has been made pluggable through a set of object database callback functions, removing hardcoded references to 'pack-objects' and enabling alternative ODBs to serve packfiles themselves. * ps/odb-pluggable-pack-generation: bundle: generate packfiles via the object database bundle: get (mostly) rid of `the_repository` builtin/bundle: refactor option handling for progress meter send-pack: generate packfiles via the object database upload-pack: generate packfiles via the object database odb: introduce interface to generate packfiles
10 daysMerge branch 'jt/receive-pack-pluggable-writes'Junio C Hamano17-188/+399
The 'git receive-pack' command has been updated to use a new ODB transaction interface for writing incoming packfiles, making it more backend-agnostic. * jt/receive-pack-pluggable-writes: odb/transaction: add transaction interface to write packfiles odb: return temporary ODB source when set builtin/receive-pack: explicitly pass packfile fd builtin/receive-pack: report unpack errors via strbuf builtin/receive-pack: lift global state out of unpack() builtin/receive-pack: read unpack limit config lazily builtin/receive-pack: pass shallow file explicitly odb/transaction: add transaction finalize interface builtin/receive-pack: properly clean up keep files
10 daysMerge branch 'ps/odb-geometric-repack-loose-threshold'Junio C Hamano2-2/+2
The threshold for geometric repacking to trigger based on loose object count has been adjusted to match that of 'git gc --auto', preventing over-aggressive repacking during concurrent writes. * ps/odb-geometric-repack-loose-threshold: odb/files: be less aggressive with geometric repacking
10 daysMerge branch 'kh/trailers-no-urls'Junio C Hamano4-4/+86
The trailer parsing machinery has been updated to avoid mistaking lines that begin with a URL (e.g., 'https://...') as trailer lines. This prevents intended textual URLs from being mangled or mistakenly treated as metadata keys. * kh/trailers-no-urls: trailers: stop recognizing URLs as trailers
10 daysMerge branch 'ps/odb-eagerly-load-alternates'Junio C Hamano13-92/+91
The object database layer has been simplified by eagerly loading alternate object directories upon initialization, instead of deferring it to the first object lookup. This eliminates the need for scattered lazy-loading calls throughout the codebase and paves the way for integrating alternates with the pluggable backends. * ps/odb-eagerly-load-alternates: odb: drop `alternates_db` field odb: drop `loaded_alternates` field odb: eagerly initialize alternates odb: decouple source path comparisons from `the_repository` setup: create ref and object databases after config is written
10 daysMerge branch 'vm/complete-history'Junio C Hamano2-0/+115
The command line completion (in contrib/) has been taught to handle the experimental 'git history' command. * vm/complete-history: completion: complete 'git history split' pathspecs completion: complete 'git history --update-refs' values completion: complete 'git history --empty' values completion: add 'git history' subcommands
10 daysMerge branch 'ps/odb-generic-corrupt-objects'Junio C Hamano15-121/+224
The object database (odb) API has been refactored to distinguish between missing objects and corrupt ones by returning more descriptive error statuses. Both the packed and loose backends now faithfully propagate error details using a generic strbuf error mechanism, removing backend-specific leakage from central lookup paths. * ps/odb-generic-corrupt-objects: odb: handle `OBJECT_INFO_DIE_IF_CORRUPT` generically odb/source: allow `read_object_info()` to bubble up error messages odb/source: let callers discern missing and corrupt objects odb/source: introduce error status when reading objects odb/source-packed: flag known-bad objects as corrupt and not missing
10 daysMerge branch 'yn/worktree-add-no-dwim-with-b'Junio C Hamano2-0/+13
The DWIM logic in 'git worktree add' sometimes tried to infer a remote-tracking branch when an explicit '-b' or '-B' option was given to create a new branch, causing the explicit branch name to be ignored, which has been corrected. * yn/worktree-add-no-dwim-with-b: worktree add: shouldn't dwim if -b or -B is given
11 dayspackfile: recover when a multi-pack-index names a removed packElijah Newren6-19/+108
A geometric repack writes a new pack and multi-pack-index and then deletes the packs the new one subsumes. A process still using the previous MIDX keeps seeing a removed pack listed as the owner of some objects. Since a MIDX attributes each object to exactly one pack, such an object is served only through its recorded owner; if that owner was just removed, find_pack_entry() cannot serve it -- the MIDX lookup routes to the missing pack, and the regular pack fallback deliberately skips every MIDX-covered pack, so a surviving copy in another covered pack (e.g. a kept base pack) is never consulted. Unlike the ordinary "a pack's .idx is mapped but its .pack is gone" race, the second read does not rescue us. Reloading the on-disk pack set does not reload the borrowed, cached MIDX (freeing it under the code that caches the "struct multi_pack_index *" would be a use-after-free), so the stale MIDX keeps routing to the removed pack and the surviving copy stays hidden behind the covered-pack skip. cat-file, rev-list and pack-objects can thus all spuriously fail with "unable to read object". Teach find_pack_entry() to recover. The MIDX lookup now returns a tri-state, distinguishing an object absent from the MIDX from one it owns via a pack that can no longer be opened; in the latter case, once the regular fallback has also missed, scan the MIDX's packs directly for a surviving copy. Because the return value is no longer a boolean, rename fill_midx_entry() to midx_fill_entry() so callers must reckon with the new enum rather than silently treat MIDX_FILL_OWNER_UNAVAILABLE as a hit. Do the scan only on the second read (OBJECT_INFO_SECOND_READ): by then the cheaper on-disk reload has run, so an object merely relocated into a new (uncovered) pack has already been found by the regular fallback, and only a genuine hidden duplicate reaches the rescan. A QUICK caller that skips the second read simply accepts the false negative, as QUICK is designed to. Reloading the stale MIDX would be a more complete fix but is much more involved (the borrowers above need proper invalidation), so leave that for later. Assisted-by: Claude Opus 4.8 & GPT-5.6 Sol Helped-by: Jeff King <peff@peff.net> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
11 daysmktree: do not use OBJECT_INFO_QUICK when checking objectsElijah Newren2-1/+48
mktree_line() checks each referenced object's type with odb_read_object_info_extended() under OBJECT_INFO_QUICK. QUICK skips the reprepare-and-retry that reloads the on-disk pack set, so a resident "git mktree --batch" reader reports an object that a concurrent repack just relocated into a new pack as missing, and rejects the entry. QUICK entered this lookup in 817b0f602710 (mktree: do not check type of remote objects, 2022-06-21) only to avoid lazily fetching promisor objects; OBJECT_INFO_SKIP_FETCH_OBJECT already provides that. Drop OBJECT_INFO_QUICK and keep OBJECT_INFO_SKIP_FETCH_OBJECT, so mktree still avoids a promisor fetch but recovers an object that was merely repacked. Add a regression test driving a resident mktree --batch reader across a concurrent repack that retires a pack. Assisted-by: Claude Opus 4.8 & GPT-5.6 Sol Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
11 daysmktree: plug per-tree leak in --batch modeElijah Newren1-0/+3
In --batch mode "git mktree" reuses its entry buffer across trees, resetting `used` to 0 after writing each tree. It never frees the `treeent` structures the previous tree appended, though, so once the next tree overwrites those slots the earlier allocations are leaked. A single-tree invocation hides this, as the entries stay reachable through the `entries` global until exit. Free each entry when resetting the buffer, and free the buffer itself before returning. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
11 daysreplay: fail gracefully when a merge input is unreadableElijah Newren2-0/+41
When objects involved in the merge cannot be read, the merge machinery will return early with result.clean = -1, and result.tree left as NULL. pick_regular_commit() tested only "if (!result->clean)", ignoring the case where "clean < 0". That causes the code to try to use result->tree, resulting in a SIGSEGV. Handle clean < 0 explicitly; the merge machinery will already have printed messages such as "Could not read <object>" and "collecting merge info failed for trees...", so we don't need to add much detail beyond the fact that the merge failed. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
13 daysThe 20th batchJunio C Hamano1-3/+9
Signed-off-by: Junio C Hamano <gitster@pobox.com>
13 daysMerge branch 'sk/object-name-use-after-free'Junio C Hamano2-6/+19
A heap-use-after-free bug in the object name parsing code when reporting failures with a relative path to a sparse directory has been corrected. * sk/object-name-use-after-free: object-name: avoid use-after-free in get_oid_with_context_1()
13 daysMerge branch 'kh/format-rev-doc-synopsis'Junio C Hamano1-4/+5
The documentation for 'git format-rev' has been updated to use the [synopsis] block definition on code blocks to properly highlight placeholders, and a quoting inconsistency in the running text has been fixed. * kh/format-rev-doc-synopsis: doc: format-rev: use [synopsis] on code block doc: format-rev: quote subject placeholder before and after
13 daysworktree repair: detect relative path in .git file correctlyYoichi NAKAYAMA4-50/+94
Given a state in which the cross-references between the worktree and the repository (specifically worktree/id/gitdir in the main repository and the .git file in the worktree) are recorded using absolute paths, setting 'worktree.useRelativePaths=true' and running 'git worktree repair' within the main worktree converts them to relative paths. Conversely, given a state in which the cross-references are recorded using relative paths, one would expect that setting 'worktree.useRelativePaths=false' and running 'git worktree repair' would convert them to absolute paths. However, they remain as relative paths. This is because we incorrectly use read_gitfile_gently(), which always returns an absolute path. To fix this, introduce read_gitfile_raw(), which reads the path from the .git file without resolving it to an absolute path. Because read_gitfile_raw() does not validate the path with is_git_directory(), repair_gitfile() performs this validation to preserve the existing behavior. Signed-off-by: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-27you_still_use_that(): reword the instructionsJunio C Hamano3-11/+9
The message is overly long and may mislead readers into thinking there is recourse other than adopting the new workflow. Clarify that the message is there merely to help them find a replacement workflow, and is not offering to reconsider a decision that has already taken effect. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-27worktree add: treat multiple matches with --guess-remote as an errorYoichi NAKAYAMA4-6/+36
When 'git worktree add <path>' is invoked without <commit-ish> and with the --guess-remote option (or when worktree.guessRemote is set to true), it tries to find a remote-tracking branch matching the basename of <path>. Currently, the behavior when multiple matches are found is the same as when no match is found: it falls back to creating a branch from HEAD. This has been the behavior since 71d6682d8c (worktree: add --guess-remote option to add subcommand, 2017-11-29), when the option was first introduced. However, if the specified <path> matches any remote-tracking branch, we infer that the user intended to use one of the remote-tracking branches as the start-point rather than HEAD. So we abort the creation of the branch and worktree when there are multiple matches, and instruct the user to choose the start-point. Signed-off-by: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-27worktree add: improve message for ambiguous remote branch nameYoichi NAKAYAMA2-5/+36
When the user runs 'git worktree add ../foo-dir bar-topic' without specifying a remote, and there is no local branch named bar-topic, we try to guess which remote branch bar-topic refers to, then create a new branch named bar-topic that tracks the remote branch. If multiple remotes have a branch named bar-topic, we silently gave up, leaving the variable 'branch' intact. We then entered the conditional clause 'if (!opts.orphan && !lookup_commit_reference_by_name(branch))' and triggered an "invalid reference" error. This error message did not provide enough information to resolve the ambiguity. When multiple matching branches are found, display a hint and a descriptive error message and die immediately. Signed-off-by: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-27checkout: improve message for ambiguous remote branch nameYoichi NAKAYAMA4-13/+37
When the user runs 'git checkout bar-topic' without specifying a remote, and there is no local branch named bar-topic, we try to guess which remote branch bar-topic refers to, then create a new branch named bar-topic that tracks the remote branch. If multiple remotes have a branch named bar-topic, we cannot determine a single remote. To make it easier to resolve the ambiguity, provide the names of the matching remotes for the specified branch name. To achieve that, add an optional feature to the `unique_tracking_name()` function that allows the matching remote names to be exposed to the caller. Signed-off-by: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-27checkout: extract function to display advice for ambiguous remotesYoichi NAKAYAMA1-28/+32
Fix incorrect indentation and reduce nesting. We are going to extend this function in subsequent commits. Signed-off-by: Yoichi NAKAYAMA <yoichi.nakayama@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-26t1402: test forbidden characters in refnamesNikolaus Schuetz1-3/+6
git-check-ref-format(1) documents that a refname cannot contain a space, tilde, caret, colon, question-mark, asterisk, open-bracket or backslash, nor the sequence "..", and cannot be the single character "@". Of these, only "?", "\" and ".." were tested embedded in an otherwise-valid refname; "*" was checked only as a lone character or with --refspec-pattern. Test all of them in that embedded form with a single loop, and check that "@" alone is rejected even with --allow-onelevel -- where "@" is otherwise a valid refname component, as "refs/@" confirms. Signed-off-by: Nikolaus Schuetz <nikolauspschuetz@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-26t1401: check symbolic-ref failure and --quiet silence on a non-symbolic refNikolaus Schuetz1-0/+12
git-symbolic-ref(1) documents that reading a name that is not a symbolic ref fails, and that --quiet does so silently. Tests such as t2020 and t5621 already rely on "symbolic-ref -q HEAD" failing on a detached HEAD, but none checks that the plain form reports the error or that --quiet stays silent. Assert that a non-symbolic ref fails with the "is not a symbolic ref" message, and that --quiet fails with no output. Use test_must_fail rather than pinning the exact exit codes, which are documented but not worth freezing in the test. Signed-off-by: Nikolaus Schuetz <nikolauspschuetz@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>