Commit Graph

24409 Commits

Author SHA1 Message Date
Patrick Steinhardt
bc77fc6e15 t6500: explicitly use "gc" strategy
The test in t6500 explicitly wants to exercise git-gc(1) and is thus
highly specific to the actual on-disk state of the repository and
specifically of the object database. An upcoming change modifies the
default maintenance strategy to be the "geometric" strategy though,
which breaks a couple of assumptions.

One fix would arguably be to disable auto-maintenance altogether, as we
do want to explicitly verify git-gc(1) anyway. But as the whole test
suite is about git-gc(1) in the first place it feels more sensible to
configure the default maintenance strategy to be "gc".

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-20 10:07:55 -08:00
Patrick Steinhardt
cddd4a7466 t5510: explicitly use "gc" strategy
One of the tests in t5510 wants to verify that auto-gc does not lock up
when fetching into a repository. Adapt it to explicitly pick the "gc"
strategy for auto-maintenance.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-20 10:07:55 -08:00
Patrick Steinhardt
e151f0790b t5400: explicitly use "gc" strategy
In t5400 we verify that git-receive-pack(1) runs automated repository
maintenance in the remote repository. The check is performed indirectly
by observing an effect that git-gc(1) would have, namely to prune a
temporary object from the object database. In a subsequent commit we're
about to switch to the "geometric" strategy by default though, and here
we stop observing that effect.

Adapt the test to explicitly use the "gc" strategy to prepare for that
upcoming change.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-20 10:07:55 -08:00
Patrick Steinhardt
c9114c9762 t34xx: don't expire reflogs where it matters
We have a couple of tests in the t34xx range that rely on reflogs. This
never really used to be a problem, but in a subsequent commit we will
change the default maintenance strategy from "gc" to "geometric", and
this will cause us to drop all reflogs in these tests.

This may seem surprising and like a bug at first, but it's actually not.
The main difference between these two strategies is that the "gc"
strategy will skip all maintenance in case the object database is in a
well-optimized state. The "geometric" strategy has separate subtasks
though, and the conditions for each of these tasks is evaluated on a
case by case basis. This means that even if the object database is in
good shape, we may still decide to expire reflogs.

So why is that a problem? The issue is that Git's test suite hardcodes
the committer and author dates to a date in 2005. Interestingly though,
these hardcoded dates not only impact the commits, but also the reflog
entries. The consequence is that all newly written reflog entries are
immediately considered stale as our reflog expiration threshold is in
the range of weeks, only. It follows that executing `git reflog expire`
will thus immediately purge all reflog entries.

This hasn't been a problem in our test suite by pure chance, as the
repository shapes simply didn't cause us to perform actual garbage
collection. But with the upcoming "geometric" strategy we _will_ start
to execute `git reflog expire`, thus surfacing this issue.

Prepare for this by explicitly disabling reflog expiration in tests
impacted by this upcoming change.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-20 10:07:54 -08:00
Patrick Steinhardt
0c8409793a t: disable maintenance where we verify object database structure
We have a couple of tests that explicitly verify the structure of the
object database. Naturally, this structure is dependent on whether or
not we run repository maintenance: if it decides to optimize the object
database the expected structure is likely to not materialize.

Explicitly disable auto-maintenance in such tests so that we are not
dependent on decisions made by our maintenance.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-20 10:07:54 -08:00
Patrick Steinhardt
226f66ae94 t: fix races caused by background maintenance
Many Git commands spawn git-maintenance(1) to optimize the repository in
the background. By default, performing the maintenance is for most of
the part asynchronous: we fork the executable and then continue with the
rest of our business logic.

This is working as expected for our users, but this behaviour is
somewhat problematic for our test suite as this is inherently racy. We
have many tests that verify the on-disk state of repositories, and those
tests may easily race with our background maintenance. In a similar
fashion, we may end up with processes that "leak" out of a current test
case.

Until now this tends to not be much of a problem. Our maintenance uses
git-gc(1) by default, which knows to bail out in case there aren't
either too many packfiles or too many loose objects. So even if other
data structures would need to be optimized, we won't do so unless the
object database also needs optimizations.

This is about to change though, as a subsequent commit will switch to
the "geometric" maintenance strategy as a default. The consequence is
that we will run required optimizations even if the object database is
well-optimized. And this uncovers races between our test suite and
background maintenance all over the place.

Disabling maintenance outright in our test suite is not really an
option, as it would result in significantly divergence from the "real
world" and reduce our test coverage. But we've got an alternative up our
sleeves: we can ensure that garbage collection runs synchronously by
overriding the "maintenance.autoDetach" configuration.

Of course that also diverges from the real world, as we now stop testing
that background maintenance interacts in a benign way with normal Git
commands. But on the other hand this ensures that the maintenance itself
does not for example lead to data loss in a more reproducible way.

Another concern is that this would make execution of the test suite much
slower. But a quick benchmark on my machine demonstrates that this does
not seem to be the case:

    Benchmark 1: meson test (revision = HEAD~)
      Time (mean ± σ):     131.182 s ±  1.293 s    [User: 853.737 s, System: 1160.479 s]
      Range (min … max):   130.001 s … 132.563 s    3 runs

    Benchmark 2: meson test (revision = HEAD)
      Time (mean ± σ):     129.554 s ±  0.507 s    [User: 849.040 s, System: 1152.664 s]
      Range (min … max):   129.000 s … 129.994 s    3 runs

    Summary
      meson test (revision = HEAD) ran
        1.01 ± 0.01 times faster than meson test (revision = HEAD~)

Funny enough, it even seems as if this speeds up test execution ever so
slightly, but that may just as well be noise.

Introduce a new `GIT_TEST_MAINT_AUTO_DETACH` environment variable that
allows us to override the auto-detach behaviour and set that varibale in
our tests.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-20 10:07:54 -08:00
Junio C Hamano
11294bb0fa Merge branch 'sd/t7003-test-path-is-helpers'
Test updates.

* sd/t7003-test-path-is-helpers:
  t7003: modernize path existence checks using test helpers
2026-02-17 13:30:43 -08:00
Junio C Hamano
70d3916a7d Merge branch 'bk/t2003-modernise'
Test update.

* bk/t2003-modernise:
  t2003: modernize path existence checks using test helpers
2026-02-17 13:30:43 -08:00
Junio C Hamano
73f29c8ca9 Merge branch 'yt/merge-file-outside-a-repository'
"git merge-file" can be run outside a repository, but it ignored
all configuration, even the per-user ones.  The command now uses
available configuration files to find its customization.

* yt/merge-file-outside-a-repository:
  merge-file: honor merge.conflictStyle outside of a repository
2026-02-17 13:30:41 -08:00
Junio C Hamano
5779c47fa0 Merge branch 'pc/lockfile-pid'
Allow recording process ID of the process that holds the lock next
to a lockfile for diagnosis.

* pc/lockfile-pid:
  lockfile: add PID file for debugging stale locks
2026-02-17 13:30:41 -08:00
Junio C Hamano
03dfe4e1af Merge branch 'sb/merge-ours-sparse'
"git merge-ours" is taught to work better in a sparse checkout.

* sb/merge-ours-sparse:
  merge-ours: integrate with sparse-index
  merge-ours: drop USE_THE_REPOSITORY_VARIABLE
2026-02-13 13:39:26 -08:00
Junio C Hamano
5288202433 Merge branch 'ps/commit-list-functions-renamed'
Rename three functions around the commit_list data structure.

* ps/commit-list-functions-renamed:
  commit: rename `free_commit_list()` to conform to coding guidelines
  commit: rename `reverse_commit_list()` to conform to coding guidelines
  commit: rename `copy_commit_list()` to conform to coding guidelines
2026-02-13 13:39:25 -08:00
Junio C Hamano
70cc3bca87 Merge branch 'tc/last-modified-not-a-tree'
Giving "git last-modified" a tree (not a commit-ish) died an
uncontrolled death, which has been corrected.

* tc/last-modified-not-a-tree:
  last-modified: verify revision argument is a commit-ish
  last-modified: remove double error message
  last-modified: fix memory leak when more than one commit is given
  last-modified: rewrite error message when more than one commit given
2026-02-13 13:39:25 -08:00
Junio C Hamano
7855effc95 Merge branch 'cf/c23-const-preserving-strchr-updates-0'
ISO C23 redefines strchr and friends that tradiotionally took
a const pointer and returned a non-const pointer derived from it to
preserve constness (i.e., if you ask for a substring in a const
string, you get a const pointer to the substring).  Update code
paths that used non-const pointer to receive their results that did
not have to be non-const to adjust.

* cf/c23-const-preserving-strchr-updates-0:
  gpg-interface: remove an unnecessary NULL initialization
  global: constify some pointers that are not written to
2026-02-13 13:39:25 -08:00
Junio C Hamano
06cef761b1 Merge branch 'rs/blame-ignore-colors-fix'
"git blame --ignore-revs=... --color-lines" did not account for
ignored revisions passing blame to the same commit an adjacent line
gets blamed for.

* rs/blame-ignore-colors-fix:
  blame: fix coloring for repeated suspects
2026-02-11 12:29:08 -08:00
Junio C Hamano
ea03b35bb5 Merge branch 'hs/t9160-test-paths'
Test update.

* hs/t9160-test-paths:
  t9160:modernize test path checking
2026-02-11 12:29:07 -08:00
Junio C Hamano
6a3c66d72e Merge branch 'ty/perf-3400-optim'
Improve set-up time of a perf test.

* ty/perf-3400-optim:
  t/perf/p3400: speed up setup using fast-import
2026-02-09 12:09:10 -08:00
Junio C Hamano
35e17b2526 Merge branch 'ac/string-list-sort-u-and-tests'
The string_list API gains a new helper, string_list_sort_u(), and
new unit tests to extend coverage.

* ac/string-list-sort-u-and-tests:
  string-list: add string_list_sort_u() that mimics "sort -u"
  u-string-list: add unit tests for string-list methods
2026-02-09 12:09:10 -08:00
Junio C Hamano
6176ee2349 Merge branch 'kn/ref-batch-output-error-reporting-fix'
A handful of code paths that started using batched ref update API
(after Git 2.51 or so) lost detailed error output, which have been
corrected.

* kn/ref-batch-output-error-reporting-fix:
  fetch: delay user information post committing of transaction
  receive-pack: utilize rejected ref error details
  fetch: utilize rejected ref error details
  update-ref: utilize rejected error details if available
  refs: add rejection detail to the callback function
  refs: skip to next ref when current ref is rejected
2026-02-09 12:09:10 -08:00
Junio C Hamano
8087aae540 Merge branch 'pw/replay-drop-empty'
"git replay" is taught to drop commits that become empty (not the
ones that are empty in the original).

* pw/replay-drop-empty:
  replay: drop commits that become empty
2026-02-09 12:09:09 -08:00
Junio C Hamano
7bf3785d09 Merge branch 'ps/history'
"git history" history rewriting UI.

* ps/history:
  builtin/history: implement "reword" subcommand
  builtin: add new "history" command
  wt-status: provide function to expose status for trees
  replay: support updating detached HEAD
  replay: support empty commit ranges
  replay: small set of cleanups
  builtin/replay: move core logic into "libgit.a"
  builtin/replay: extract core logic to replay revisions
2026-02-09 12:09:09 -08:00
SoutrikDas
aaf3cc3d8d t7003: modernize path existence checks using test helpers
Replace direct uses of 'test -f' and 'test -d' with
git's helper functions 'test_path_is_file' ,
'test_path_is_missing' and 'test_path_is_dir'

Signed-off-by: SoutrikDas <valusoutrik@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-09 10:16:01 -08:00
Burak Kaan Karaçay
168d575719 t2003: modernize path existence checks using test helpers
The old style 'test -f' and 'test -d' checks are silent on failure,
which makes debugging difficult.

Replace them with the 'test_path_is_*' helpers which provide verbose
error messages when a test fails.

Signed-off-by: Burak Kaan Karaçay <bkkaracay@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-09 09:46:49 -08:00
Yannik Tausch
8600b4ec9e merge-file: honor merge.conflictStyle outside of a repository
When running outside a repository, git merge-file ignores the
merge.conflictStyle configuration variable entirely. Since the
function receives `repo` from the caller (which is NULL outside a
repository), and repo_config() falls back to reading system and user
configuration when passed NULL, pass `repo` to repo_config()
unconditionally.

Also document that merge.conflictStyle is honored.

Signed-off-by: Yannik Tausch <dev@ytausch.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-07 17:04:26 -08:00
Sam Bostock
fb1b786ebf merge-ours: integrate with sparse-index
The merge-ours built-in opens the index to compare it against HEAD.
The machinery used to do this (i.e. run_diff_index()) is capable of
working with a sparse index, but the start-up sequence of this
command does not take the necessary steps, so we end up expanding the
index fully before doing the comparison.

In order to convince sparse-index.c:is_sparse_index_allowed() to
return true, we need to:

 - Read basic configuration with git_default_config so that global
   variables like core_apply_sparse_checkout are populated.
   merge-ours currently does not read configuration at all.

 - Set command_requires_full_index to 0.

With that, the command can work without expanding the index fully
before doing its work.

Signed-off-by: Sam Bostock <sam@sambostock.ca>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-06 11:45:33 -08:00
Collin Funk
4ac4705afa global: constify some pointers that are not written to
The recent glibc 2.43 release had the following change listed in its
NEWS file:

    For ISO C23, the functions bsearch, memchr, strchr, strpbrk, strrchr,
    strstr, wcschr, wcspbrk, wcsrchr, wcsstr and wmemchr that return
    pointers into their input arrays now have definitions as macros that
    return a pointer to a const-qualified type when the input argument is
    a pointer to a const-qualified type.

When compiling with GCC 15, which defaults to -std=gnu23, this causes
many warnings like this:

    merge-ort.c: In function ‘apply_directory_rename_modifications’:
    merge-ort.c:2734:36: warning: initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
     2734 |                 char *last_slash = strrchr(cur_path, '/');
          |                                    ^~~~~~~

This patch fixes the more obvious ones by making them const when we do
not write to the returned pointer.

Signed-off-by: Collin Funk <collin.funk1@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-05 17:52:49 -08:00
Junio C Hamano
96614e799c Merge branch 'sp/t5500-cleanup'
Test clean-up.

* sp/t5500-cleanup:
  t5500: simplify test implementation and fix git exit code suppression
2026-02-05 15:42:01 -08:00
Junio C Hamano
7758f84682 Merge branch 'tc/last-modified-options-cleanup'
The "-z" and "--max-depth" documentation (and implementation of
"-z") in the "git last-modified" command have been updated.

* tc/last-modified-options-cleanup:
  last-modified: change default max-depth to 0
  last-modified: document option '--max-depth'
  last-modified: document option '-z'
  last-modified: clarify in the docs the command takes a pathspec
2026-02-05 15:42:01 -08:00
Junio C Hamano
1f17604ce4 Merge branch 'lp/diff-stat-utf8-display-width-fix'
The computation of column width made by "git diff --stat" was
confused when pathnames contain non-ASCII characters.

* lp/diff-stat-utf8-display-width-fix:
  t4073: add test for diffstat paths length when containing UTF-8 chars
  diff: improve scaling of filenames in diffstat to handle UTF-8 chars
2026-02-05 15:42:01 -08:00
Junio C Hamano
d83491aeba Merge branch 'ac/sparse-checkout-string-list-cleanup'
Code clean-up.

* ac/sparse-checkout-string-list-cleanup:
  sparse-checkout: optimize string_list construction and add tests to verify deduplication.
2026-02-05 15:42:00 -08:00
Junio C Hamano
d62717b182 Merge branch 'dd/t5403-modernise'
Test clean-up.

* dd/t5403-modernise:
  t5403: use test_cmp for post-checkout argument checks
  t5403: introduce check_post_checkout helper function
2026-02-05 15:42:00 -08:00
Junio C Hamano
4ae96a4c0e Merge branch 'ap/http-probe-rpc-use-auth'
HTTP transport failed to authenticate in some code paths, which has
been corrected.

* ap/http-probe-rpc-use-auth:
  remote-curl: use auth for probe_rpc() requests too
2026-02-05 15:41:58 -08:00
Junio C Hamano
c3a5261dc0 Merge branch 'ar/submodule-gitdir-tweak'
Avoid local submodule repository directory paths overlapping with
each other by encoding submodule names before using them as path
components.

* ar/submodule-gitdir-tweak:
  submodule: detect conflicts with existing gitdir configs
  submodule: hash the submodule name for the gitdir path
  submodule: fix case-folding gitdir filesystem collisions
  submodule--helper: fix filesystem collisions by encoding gitdir paths
  builtin/credential-store: move is_rfc3986_unreserved to url.[ch]
  submodule--helper: add gitdir migration command
  submodule: allow runtime enabling extensions.submodulePathConfig
  submodule: introduce extensions.submodulePathConfig
  builtin/submodule--helper: add gitdir command
  submodule: always validate gitdirs inside submodule_name_to_gitdir
  submodule--helper: use submodule_name_to_gitdir in add_submodule
2026-02-05 15:41:58 -08:00
Junio C Hamano
ae78735c4b Merge branch 'aa/add-p-previous-decisions'
"git add -p" and friends note what the current status of the hunk
being shown is.

* aa/add-p-previous-decisions:
  add -p: show user's hunk decision when selecting hunks
2026-02-05 15:41:58 -08:00
Junio C Hamano
2b53e8b3ee Merge branch 'jk/remote-tracking-ref-leakfix'
Leakfix.

* jk/remote-tracking-ref-leakfix:
  remote: always allocate branch.push_tracking_ref
  remote: fix leak in branch_get_push_1() with invalid "simple" config
  remote: drop const return of tracking_for_push_dest()
  remote: return non-const pointer from error_buf()
2026-02-05 15:41:57 -08:00
René Scharfe
d519082d4e blame: fix coloring for repeated suspects
The option --ignore-rev passes the blame to an older commit.  This can
cause adjacent scoreboard entries to blame the same commit.  Currently
we only look at the present entry when determining whether a line needs
to be colored for --color-lines.  Check the previous entry as well.

Reported-by: Seth McDonald <sethmcmail@pm.me>
Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-02 13:48:13 -08:00
HodaSalim
68060b9262 t9160:modernize test path checking
Replace old-style path checks with Git's dedicated test helpers:
- test -f → test_path_is_file
- test -d → test_path_is_dir
- test -s → test_file_not_empty

Fix typos with the word "subsequent"

Found using: git grep "test -[efd]" t/

This improves test readability and provides better error messages
when path checks fail.

Signed-off-by: HodaSalim <hoda.s.salim@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-02-02 11:00:30 -08:00
Tian Yuchen
8466efa4bd t/perf/p3400: speed up setup using fast-import
The setup phase in 't/perf/p3400-rebase.sh' generates 100 commits to
simulate a noisy history. It currently uses a shell loop that invokes
'git add', 'git commit', 'test_seq', and 'sort' in each iteration.
This incurs significant overhead due to repeated process spawning.

Optimize the setup by using 'git fast-import' to generate the commit
history. Additionally, pre-compute the forward and reversed file contents
to avoid repetitive execution of 'seq' and 'sort'.

To ensure the test measures rebase performance against a consistent
object layout (rather than the suboptimal pack/loose objects created
by the raw import), perform a full repack (`git repack -a -d`) at the
end of the setup.

This reduces the setup time significantly while maintaining the validity
of the subsequent performance tests.

Performance enhancement (Average value of 5 tests):
            Real        Rebase
  Before:  29.045s      13.34s
   After:  21.989s      12.84s

Measured on Lenovo Yoga 2020, Ubuntu 24.04.

Signed-off-by: Tian Yuchen <a3205153416@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-30 09:13:47 -08:00
Toon Claes
525ef52301 last-modified: verify revision argument is a commit-ish
Passing a non-committish revision to git-last-modified(1) triggers the
following BUG:

    git last-modified HEAD^{tree}
    BUG: builtin/last-modified.c:456: paths remaining beyond boundary in last-modified

Fix this error by ensuring that the given revision peels to a commit.

This change also adds a test to verify git-last-modified(1) can operate
on an annotated tag. For this an annotated tag is added that points to
the second commit. But this causes ambiguous results when calling
git-name-rev(1) with `--tags`, because now two tags point to the same
commit. To remove this ambiguity, pass `--exclude=<tag>` to
git-name-rev(1) to exclude the new annotated tag.

Reported-by: Gusted <gusted@codeberg.org>
Signed-off-by: Toon Claes <toon@iotcl.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-30 08:57:01 -08:00
Toon Claes
85329e31dd last-modified: rewrite error message when more than one commit given
When more than one commit is passed to the git-last-modified(1) command,
this error message was printed:

    error: last-modified can only operate on one tree at a time

Calling these a "tree" is technically not correct. git-last-modified(1)
expects revisions that peel to a commit.

Rephrase the error message to:

    error: last-modified can only operate on one commit at a time

While at it, modify the test to ensure the correct error message is
printed.

Signed-off-by: Toon Claes <toon@iotcl.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-30 08:57:00 -08:00
Amisha Chhajed
2e711acfbd string-list: add string_list_sort_u() that mimics "sort -u"
Many callsites of string_list_remove_duplicates() call it
immdediately after calling string_list_sort(), understandably
as the former requires string-list to be sorted, it is clear
that these places are sorting only to remove duplicates and
for no other reason.

Introduce a helper function string_list_sort_u that combines
these two calls that often appear together, to simplify
these callsites. Replace the current calls of those methods with
string_list_sort_u().

Signed-off-by: Amisha Chhajed <amishhhaaaa@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-29 09:32:50 -08:00
Amisha Chhajed
208642cfbb u-string-list: add unit tests for string-list methods
Unit tests in u-string-list.c does not cover several methods
in string-list, this gap in coverage makes it difficult to
ensure no regressions are introduced in future changes.

Add unit tests for the following methods to enhance coverage:
string_list_remove_empty_items()
unsorted_string_list_has_string()
unsorted_string_list_delete_item()
string_list_has_string()
string_list_insert()
string_list_sort()
string_list_remove()

Signed-off-by: Amisha Chhajed <amishhhaaaa@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-29 09:32:50 -08:00
Karthik Nayak
eff9299eac fetch: delay user information post committing of transaction
In Git 2.50 and earlier, we would display failure codes and error
message as part of the status display:

  $ git fetch . v1.0.0:refs/heads/foo
    error: cannot update ref 'refs/heads/foo': trying to write non-commit object f665776185 to branch 'refs/heads/foo'
    From .
     ! [new tag]               v1.0.0     -> foo  (unable to update local ref)

With the addition of batched updates, this information is no longer
shown to the user:

  $ git fetch . v1.0.0:refs/heads/foo
    From .
     * [new tag]               v1.0.0     -> foo
    error: cannot update ref 'refs/heads/foo': trying to write non-commit object f665776185 to branch 'refs/heads/foo'

Since reference updates are batched and processed together at the end,
information around the outcome is not available during individual
reference parsing.

To overcome this, collate and delay the output to the end. Introduce
`ref_update_display_info` which will hold individual update's
information and also whether the update failed or succeeded. This
finally allows us to iterate over all such updates and print them to the
user.

Using an dynamic array and strmap does add some overhead to
'git-fetch(1)', but from benchmarking this seems to be not too bad:

  Benchmark 1: fetch: many refs (refformat = files, refcount = 1000, revision = master)
    Time (mean ± σ):      42.6 ms ±   1.2 ms    [User: 13.1 ms, System: 29.8 ms]
    Range (min … max):    40.1 ms …  45.8 ms    47 runs

  Benchmark 2: fetch: many refs (refformat = files, refcount = 1000, revision = HEAD)
    Time (mean ± σ):      43.1 ms ±   1.2 ms    [User: 12.7 ms, System: 30.7 ms]
    Range (min … max):    40.5 ms …  45.8 ms    48 runs

  Summary
    fetch: many refs (refformat = files, refcount = 1000, revision = master) ran
      1.01 ± 0.04 times faster than fetch: many refs (refformat = files, refcount = 1000, revision = HEAD)

Another approach would be to move the status printing logic to be
handled post the transaction being committed. That however would require
adding an iterator to the ref transaction that tracks both the outcome
(success/failure) and the original refspec information for each update,
which is more involved infrastructure work compared to the strmap
approach here.

Helped-by: Phillip Wood <phillip.wood123@gmail.com>
Reported-by: Jeff King <peff@peff.net>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-25 22:27:34 -08:00
Karthik Nayak
2ea49f21e3 receive-pack: utilize rejected ref error details
In 9d2962a7c4 (receive-pack: use batched reference updates, 2025-05-19),
git-receive-pack(1) switched to using batched reference updates. This also
introduced a regression wherein instead of providing detailed error
messages for failed referenced updates, the users were provided generic
error messages based on the error type.

Now that the updates also contain detailed error message, propagate
those to the client via 'rp_error'. The detailed error messages can be
very verbose, for e.g. in the files backend, when trying to write a
non-commit object to a branch, you would see:

   ! [remote rejected] 3eaec9ccf3a53f168362a6b3fdeb73426fb9813d ->
   branch (cannot update ref 'refs/heads/branch': trying to write
   non-commit object 3eaec9ccf3a53f168362a6b3fdeb73426fb9813d to branch
   'refs/heads/branch')

Here the refname is repeated multiple times due to how error messages
are propagated and filled over the code stack. This potentially can be
cleaned up in a future commit.

Reported-by: Elijah Newren <newren@gmail.com>
Co-authored-by: Jeff King <peff@peff.net>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-25 22:27:34 -08:00
Karthik Nayak
274f435552 fetch: utilize rejected ref error details
In 0e358de64a (fetch: use batched reference updates, 2025-05-19),
git-fetch(1) switched to using batched reference updates. This also
introduced a regression wherein instead of providing detailed error
messages for failed referenced updates, the users were provided generic
error messages based on the error type.

Similar to the previous commit, switch to using detailed error messages
if present for failed reference updates to fix this regression.

Reported-by: Elijah Newren <newren@gmail.com>
Co-authored-by: Jeff King <peff@peff.net>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-25 22:27:33 -08:00
Karthik Nayak
a366bdec0f update-ref: utilize rejected error details if available
When git-update-ref(1) received the '--update-ref' flag, the error
details generated in the refs namespace wasn't propagated with failed
updates. Instead only an error code pertaining to the type of rejection
was noted.

This missed detailed error message which the user can act upon. The
previous commits added the required code to propagate these detailed
error messages from the refs namespace. Now that additional details are
available, let's output this additional details to stderr. This allows
users to have additional information over the already present machine
parsable output.

While we're here, improve the existing tests for the machine parsable
output by checking for the entire output string and not just the
rejection reason.

Reported-by: Elijah Newren <newren@gmail.com>
Co-authored-by: Jeff King <peff@peff.net>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-25 22:27:33 -08:00
Junio C Hamano
1f047a6fba Merge branch 'js/ci-leak-skip-svn'
Dscho observed that SVN tests are taking too much time in CI leak
checking tasks, but most time is spent not in our code but in libsvn
code (which happen to be written in Perl), whose leaks have little
value to discover for us.  Skip SVN, P4, and CVS tests in the leak
checking tasks.

* js/ci-leak-skip-svn:
  ci: skip CVS and P4 tests in leaks job, too
  ci(*-leaks): skip the git-svn tests to save time
2026-01-23 13:34:36 -08:00
Junio C Hamano
62627a3484 Merge branch 'ty/t1005-test-path-is-helpers'
Test clean-up.

* ty/t1005-test-path-is-helpers:
  t1005: modernize "! test -f" to "test_path_is_missing"
2026-01-23 13:34:36 -08:00
Junio C Hamano
cd8b8cba47 Merge branch 'rj/cygwin-test-fixes-for-2.53'
Test fixup.

* rj/cygwin-test-fixes-for-2.53:
  t0610-reftable-basics: mitigate a flaky test on cygwin
  t9700/test.pl: fix path type expectation on cygwin
2026-01-23 13:34:36 -08:00
Paulo Casaretto
dbdcab6b89 lockfile: add PID file for debugging stale locks
When a lock file is held, it can be helpful to know which process owns
it, especially when debugging stale locks left behind by crashed
processes. Add an optional feature that creates a companion PID file
alongside each lock file, containing the PID of the lock holder.

For a lock file "foo.lock", the PID file is named "foo~pid.lock". The
tilde character is forbidden in refnames and allowed in Windows
filenames, which guarantees no collision with the refs namespace
(e.g., refs "foo" and "foo~pid" cannot both exist). The file contains
a single line in the format "pid <value>" followed by a newline.

The PID file is created when a lock is acquired (if enabled), and
automatically cleaned up when the lock is released (via commit or
rollback). The file is registered as a tempfile so it gets cleaned up
by signal and atexit handlers if the process terminates abnormally.

When a lock conflict occurs, the code checks for an existing PID file
and, if found, uses kill(pid, 0) to determine if the process is still
running. This allows providing context-aware error messages:

  Lock is held by process 12345. Wait for it to finish, or remove
  the lock file to continue.

Or for a stale lock:

  Lock was held by process 12345, which is no longer running.
  Remove the stale lock file to continue.

The feature is controlled via core.lockfilePid configuration (boolean).
Defaults to false. When enabled, PID files are created for all lock
operations.

Existing PID files are always read when displaying lock errors,
regardless of the core.lockfilePid setting. This ensures helpful
diagnostics even when the feature was previously enabled and later
disabled.

Signed-off-by: Paulo Casaretto <pcasaretto@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-22 12:15:46 -08:00