summaryrefslogtreecommitdiffstats
AgeCommit message (Collapse)AuthorFilesLines
2025-08-22The second batchJunio C Hamano1-0/+23
2025-08-22Merge branch 'ly/diff-name-only-with-diff-from-content'Junio C Hamano5-23/+70
Various options to "git diff" that makes comparison ignore certain aspects of the differences (like "space changes are ignored", "differences in lines that match these regular expressions are ignored") did not work well with "--name-only" and friends. * ly/diff-name-only-with-diff-from-content: diff: ensure consistent diff behavior with ignore options
2025-08-22Merge branch 'kr/clone-synopsis-fix'Junio C Hamano1-1/+1
Doc fix. * kr/clone-synopsis-fix: docs: remove stray bracket from git-clone synopsis
2025-08-22Merge branch 'ac/deglobal-fmt-merge-log-config'Junio C Hamano6-10/+18
Code clean-up. * ac/deglobal-fmt-merge-log-config: builtin/fmt-merge-msg: stop depending on 'the_repository' environment: remove the global variable 'merge_log_config'
2025-08-22Merge branch 'jc/diff-no-index-in-subdir'Junio C Hamano2-0/+32
"git diff --no-index" run inside a subdirectory under control of a Git repository operated at the top of the working tree and stripped the prefix from the output, and oddballs like "-" (stdin) did not work correctly because of it. Correct the set-up by undoing what the set-up sequence did to cwd and prefix. * jc/diff-no-index-in-subdir: diff: --no-index should ignore the worktree
2025-08-22Merge branch 'gh/git-jump-pathname-with-sp'Junio C Hamano1-1/+1
"git jump" (in contrib/) fails to parse the diff header correctly when a file has a space in its name, which has been corrected. * gh/git-jump-pathname-with-sp: git-jump: make `diff` work with filenames containing spaces
2025-08-22Merge branch 'ms/refs-list'Junio C Hamano11-2244/+2316
The "list" subcommand of "git refs" acts as a front-end for "git for-each-ref". * ms/refs-list: t: add test for git refs list subcommand t6300: refactor tests to be shareable builtin/refs: add list subcommand builtin/for-each-ref: factor out core logic into a helper builtin/for-each-ref: align usage string with the man page doc: factor out common option
2025-08-22doc: interpret-trailers: close all pairs of single quotesKristoffer Haugsbakk1-4/+4
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-21Start 2.52 cycle, the first batchJunio C Hamano3-2/+60
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-21Merge branch 'ly/changed-path-traversal-with-magic-pathspec'Junio C Hamano2-17/+56
Revision traversal limited with pathspec, like "git log dir/*", used to ignore changed-paths Bloom filter when the pathspec contained wildcards; now they take advantage of the filter when they can. * ly/changed-path-traversal-with-magic-pathspec: bloom: enable bloom filter with wildcard pathspec in revision traversal
2025-08-21Merge branch 'en/ort-rename-fixes'Junio C Hamano2-30/+544
Various bugs about rename handling in "ort" merge strategy have been fixed. * en/ort-rename-fixes: merge-ort: fix directory rename on top of source of other rename/delete merge-ort: fix incorrect file handling merge-ort: clarify the interning of strings in opt->priv->path t6423: fix missed staging of file in testcases 12i,12j,12k t6423: document two bugs with rename-to-self testcases merge-ort: drop unnecessary temporary in check_for_directory_rename() merge-ort: update comments to modern testfile location
2025-08-21Merge branch 'ua/t1517-short-help-tests'Junio C Hamano3-13/+37
Test shuffling. * ua/t1517-short-help-tests: t5304: move `prune -h` test from t1517 t5200: move `update-server-info -h` test from t1517 t/t1517: automate `git subcmd -h` tests outside a repository
2025-08-21Merge branch 'rj/t6137-cygwin-fix'Junio C Hamano1-6/+6
Test fix for breakage introduced in Git 2.50. * rj/t6137-cygwin-fix: t6137-*.sh: fix test failure on cygwin
2025-08-21Merge branch 'kh/doc-git-log-markup-fix'Junio C Hamano1-2/+2
Doc update. * kh/doc-git-log-markup-fix: doc: git-log: fix description list
2025-08-21Merge branch 'dl/push-missing-object-error'Junio C Hamano2-59/+19
"git push" had a code path that led to BUG() but it should have been a die(), as it is a response to a usual but invalid end-user action to attempt pushing an object that does not exist. * dl/push-missing-object-error: remote.c: convert if-else ladder to switch remote.c: remove BUG in show_push_unqualified_ref_name_error() t5516: remove surrounding empty lines in test bodies
2025-08-21Merge branch 'jc/strbuf-split'Junio C Hamano8-166/+129
Arrays of strbuf is often a wrong data structure to use, and strbuf_split*() family of functions that create them often have better alternatives. Update several code paths and replace strbuf_split*(). * jc/strbuf-split: trace2: do not use strbuf_split*() trace2: trim_trailing_newline followed by trim is a no-op sub-process: do not use strbuf_split*() environment: do not use strbuf_split*() config: do not use strbuf_split() notes: do not use strbuf_split*() merge-tree: do not use strbuf_split*() clean: do not use strbuf_split*() [part 2] clean: do not pass the whole structure when it is not necessary clean: do not use strbuf_split*() [part 1] clean: do not pass strbuf by value wt-status: avoid strbuf_split*()
2025-08-21Merge branch 'jc/string-list-split'Junio C Hamano21-90/+225
string_list_split*() family of functions have been extended to simplify common use cases. * jc/string-list-split: string-list: split-then-remove-empty can be done while splitting string-list: optionally omit empty string pieces in string_list_split*() diff: simplify parsing of diff.colormovedws string-list: optionally trim string pieces split by string_list_split*() string-list: unify string_list_split* functions string-list: align string_list_split() with its _in_place() counterpart string-list: report programming error with BUG
2025-08-21Merge branch 'rs/describe-with-prio-queue'Junio C Hamano1-24/+63
"git describe" has been optimized by using better data structure. * rs/describe-with-prio-queue: describe: use prio_queue_replace() describe: use prio_queue
2025-08-21Merge branch 'ps/remote-rename-fix'Junio C Hamano19-200/+372
"git remote rename origin upstream" failed to move origin/HEAD to upstream/HEAD when origin/HEAD is unborn and performed other renames extremely inefficiently, which has been corrected. * ps/remote-rename-fix: builtin/remote: only iterate through refs that are to be renamed builtin/remote: rework how remote refs get renamed builtin/remote: determine whether refs need renaming early on builtin/remote: fix sign comparison warnings refs: simplify logic when migrating reflog entries refs: pass refname when invoking reflog entry callback
2025-08-21Merge branch 'ps/reflog-migrate-fixes'Junio C Hamano12-117/+413
"git refs migrate" to migrate the reflog entries from a refs backend to another had a handful of bugs squashed. * ps/reflog-migrate-fixes: refs: fix invalid old object IDs when migrating reflogs refs: stop unsetting REF_HAVE_OLD for log-only updates refs/files: detect race when generating reflog entry for HEAD refs: fix identity for migrated reflogs ident: fix type of string length parameter builtin/reflog: implement subcommand to write new entries refs: export `ref_transaction_update_reflog()` builtin/reflog: improve grouping of subcommands Documentation/git-reflog: convert to use synopsis type
2025-08-21Merge branch 'js/rebase-i-allow-drop-on-a-merge'Junio C Hamano2-0/+2
During interactive rebase, using 'drop' on a merge commit lead to an error, which was incorrect. * js/rebase-i-allow-drop-on-a-merge: rebase -i: permit 'drop' of a merge commit
2025-08-21git-gui: simplify using nice(1)Mark Levedahl1-23/+7
git-gui invokes some long running commands using "nice git $cmd" if nice is found and works, otherwise just "git $cmd". The current code is more complex than needed; let's simplify it. Signed-off-by: Mark Levedahl <mlevedahl@gmail.com> Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2025-08-21git-gui: simplify PATH de-duplicationMark Levedahl1-5/+1
git-gui since 8fe7861c51 ("git-gui: assure PATH has only absolute elements.", 2025-04-11) uses a list to maintain order and a dict to detect duplicated elements without quadratic complexity. But, Tcl's dict explicitly maintains keys in the order first added, thus the list is not needed. Simplify the code. Signed-off-by: Mark Levedahl <mlevedahl@gmail.com> Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2025-08-21config: document includeIf conditions consistentlyJunio C Hamano1-5/+4
When 399b1984 (config: include file if remote URL matches a glob, 2022-01-18) added the 'hasconfig:remote.*.url:<URL>' condition to be used in the "includeIf.<condition>.path" configuration, the keyword was added with an extra colon in the documentation. The section that documents these condition begins with this preamble: The condition starts with a keyword followed by a colon and some data whose format and meaning depends on the keyword. Supported keywords are: which makes it clear that the colon that comes between the condition keyword (e.g. "gitdir") and the parameter (aka "some data") is not a part of the keyword. Lose the extra colon. Also rewrite description of all keywords to clarify that "some data" does not directly follow "keyword", and the colon is not a part of keyword. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-20Merge branch 'lo/repo-info' into lo/repo-info-step-2Junio C Hamano11-0/+337
* lo/repo-info: repo: add the --format flag repo: add the field layout.shallow repo: add the field layout.bare repo: add the field references.format repo: declare the repo command
2025-08-20doc: fix asciidoc format compatibility in pretty-formats.adocJean-Noël Avila1-2/+2
Asciidoc.py and Asciidoctor do not process the '+' verbatim the same way. A span is detected when the format sign (here '+')is preceded by a non-word character. It seems that '{nbsp}' is considered a non-word sign by Asciidoc.py, but not by Asciidoctor. Using a double format-sign opens 'unconstrained' span, independent on the preceding character in both engines. The '+' sign is used instead of the backtick '`' because it is not processed as synopsis in asciidoc.py. Unfortunately, the post-processing of verbatim synopsis in asciidoctor cannot be bypassed and formatting of the parentheses is forced in syntax sign instead of keywords, unless a proper grammar analyzer is used. Signed-off-by: Jean-Noël Avila <jn.avila@free.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-20line-log: show all line ranges touched by the same diff rangeSZEDER Gábor5-0/+33
When line-level log is invoked with more than one disjoint line range in the same file, and one of the commits happens to change that file such that one diff range modifies more than one line range, then changes to all modified line ranges should be shown, but only the changes in the first modified line range are: $ git log --oneline -p 80ca903 (HEAD -> master) Initial diff --git a/file b/file new file mode 100644 index 0000000..00935f1 --- /dev/null +++ b/file @@ -0,0 +1,10 @@ +Line 1 +Line 2 +Line 3 +Line 4 +Line 5 +Line 6 +Line 7 +Line 8 +Line 9 +Line 10 $ git log --oneline -L1,2:file -L4,5:file -L7,8:file 80ca903 (HEAD -> master) Initial diff --git a/file b/file --- /dev/null +++ b/file @@ -0,0 +1,2 @@ +Line 1 +Line 2 The line-log-specific diff printer is already clever enough to handle the case when one line range covers multiple diff ranges, but the possibility of one diff range touching multiple disjoint line ranges was apparently overlooked. Add the necessary condition to dump_diff_hacky_one() to handle this case as well, and show all modified line ranges: $ git log --oneline -L1,2:file -L4,5:file -L7,8:file 0f9a5b4 (HEAD -> master) Initial diff --git a/file b/file --- /dev/null +++ b/file @@ -0,0 +1,2 @@ +Line 1 +Line 2 @@ -0,0 +4,2 @@ +Line 4 +Line 5 @@ -0,0 +7,2 @@ +Line 7 +Line 8 This bug was already present in the initial line-log implementation added in 2da1d1f6f (Implement line-history search (git log -L), 2013-03-28). Interestingly, that commit already contained a canned test case covering a similar scenario: "-L '/long f/',/^}/:a.c -L /main/,/^}/:a.c simple" This test case looks for two line ranges in the same file, and both trace back disjointly to the test repository's inital commit, therefore changes to both line ranges should have been shown for the initial commit, but only changes for the first line range are shown. So this test case should have failed from the very beginning, but it never did, because, unfortunately, the canned expected result is incorrect, as it doesn't include changes for the second line range. A similar test with a similarly incorrect canned expected result was added later in 209618860c (log -L: fix overlapping input ranges, 2013-04-05). Correct these two canned expected results to contain the changes for the second line range for the initial commit as well. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-20line-log: fix assertion errorSZEDER Gábor4-3/+185
When line-level log is invoked with more than one disjoint line range in the same file, and one of the commits happens to change that file such that: - the last line of a line range R(n) immediately preceeds the first line modified or added by a hunk H, and - subtracting the number of lines added by hunk H from the start and end of the subsequent line range R(n+1) would result in a range overlapping with line range R(n), then git aborts with an assertion error, because those overlapping line ranges violate the invariants: $ git log --oneline -p 73e4e2f (HEAD -> master) Add lines 6 7 8 9 10 diff --git a/file b/file index 572d5d9..00935f1 100644 --- a/file +++ b/file @@ -3,3 +3,8 @@ Line 2 Line 3 Line 4 Line 5 +Line 6 +Line 7 +Line 8 +Line 9 +Line 10 66e3561 Add lines 1 2 3 4 5 diff --git a/file b/file new file mode 100644 index 0000000..572d5d9 --- /dev/null +++ b/file @@ -0,0 +1,5 @@ +Line 1 +Line 2 +Line 3 +Line 4 +Line 5 $ git log --oneline -L3,5:file -L7,8:file git: line-log.c:73: range_set_append: Assertion `rs->nr == 0 || rs->ranges[rs->nr-1].end <= a' failed. Aborted (core dumped) The line-log machinery encodes line and diff ranges internally as [start, end) pairs, i.e. include 'start' but exclude 'end', and line numbering starts at 0 (as opposed to the -LX,Y option, where it starts at 1, IOW the parameter -L3,5 is represented internally as { start = 2, end = 5 }). The reason for this assertion error and some related issues is that there are a couple of places where 'end' is mistakenly considered to be part of the range: - When a commit modifies an interesting path, the line-log machinery first checks which diff range (i.e. hunk) modify any line ranges. This is done in diff_ranges_filter_touched(), where the outer loop iterates over the diff ranges, and in each iteration the inner loop advances the line ranges supposedly until the current line range ends at or after the current diff range starts, and then the current diff and line ranges are checked for overlap. For HEAD in the above example the first line range [2, 5) ends just before the diff range [5, 10) starts, so the inner loop should advance, and then the second line range [6, 8) and the diff range should be checked for overlap. Unfortunately, the condition of the inner loop mistakenly considers 'end' as part of the line range, and, seeing the diff range starting at 5 and the line range ending at 5, it doesn't skip the first range. Consequently, the diff range and the first line range are checked for overlap, and after that the outer loop runs out of diff ranges, and then the processing goes on in the false belief that this commit didn't touch any of the interesting line ranges. The line-log machinery later shifts the line ranges to account for any added/removed lines in the diff ranges preceeding each line range. This leaves the first line range intact, but attempts to shift the second line range [6, 8) by 5 lines towards the beginning of the file, resulting in [1, 3), triggering the assertion error, because the two overlapping line ranges violate the invariants. Fix that loop condition in diff_ranges_filter_touched() to not treat 'end' as part of the line range. - With the above fix the assertion error is gone... but, alas, we now get stuck in an endless loop! This happens in range_set_difference(), where a couple of nested loops iterate over the line and diff ranges, and a condition is supposed to break the middle loop when the current line range ends before the current diff range, so processing could continue with the next line range. For HEAD in the above example the first line range [2, 5) ends just before the diff range [5, 10) starts, so this condition should trigger and break the middle loop. Unfortunately, just like in the case of the assertion error, this conditions mistakenly considers 'end' as part of the line range, and, seeing the line range ending at 5 and the diff range starting at 5, it doesn't break the loop, which will then go on and on. Fix this condition in range_set_difference() to not treat 'end' as part of the line range. - With the above fix the endless loop is gone... but, alas, the output is now wrong, as it shows both line ranges for HEAD, even though the first line range is not modified by that commit: $ git log --oneline -L3,5:file -L7,8:file 73e4e2f (HEAD -> master) Add lines 6 7 8 9 10 diff --git a/file b/file --- a/file +++ b/file @@ -3,3 +3,3 @@ Line 3 Line 4 Line 5 @@ -6,0 +7,2 @@ +Line 7 +Line 8 66e3561 Add lines 1 2 3 4 5 diff --git a/file b/file --- /dev/null +++ b/file @@ -0,0 +3,3 @@ +Line 3 +Line 4 +Line 5 In dump_diff_hacky_one() a couple of nested loops are responsible for finding and printing the modified line ranges: the big outer loop iterates over all line ranges, and the first inner loop skips over the diff ranges that end before the start of the current line range. This is followed by a condition checking whether the current diff range starts after the end of the current line range, which, when fulfilled, continues and advances the outer loop to the next line range. For HEAD in the above example the first line range [2, 5) ends just before the diff range [5, 10), so this condition should trigger, and the outer loop should advance to the second line range. Unfortunately, just like in the previous cases, this condition mistakenly considers 'end' as part of the line range, and, seeing the first line range ending at 5 and the diff range starting at 5, it doesn't continue to advance the outher loop, but goes on to show the (unmodified) first line range. Fix this condition to not treat 'end' as part of the line range, just like in the previous cases. After all this the command in the above example finally finishes and produces the right output: $ git log --oneline -L3,5:file -L7,8:file 73e4e2f (HEAD -> master) Add lines 6 7 8 9 10 diff --git a/file b/file --- a/file +++ b/file @@ -6,0 +7,2 @@ +Line 7 +Line 8 66e3561 Add lines 1 2 3 4 5 diff --git a/file b/file --- /dev/null +++ b/file @@ -0,0 +3,3 @@ +Line 3 +Line 4 +Line 5 Add a canned test similar to the above example, with the line ranges adjusted to the test repository's history. Reported-by: Evgeni Chasnovski <evgeni.chasnovski@gmail.com> Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-20doc: add discord to ways of getting helpDaniele Sassoli1-0/+9
Discord is a great way of receiving help for members of the community that are not on the mailing list or not familiar with Libera. Adding it to the official documentation will aid discoverability of it. The link is the same as the one at https://git-scm.com/community. Signed-off-by: Daniele Sassoli <danielesassoli@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-20describe: pass commit to describe_commit()Jeff King1-11/+9
There's a call in describe_commit() to lookup_commit_reference(), but we don't check the return value. If it returns NULL, we'll segfault as we immediately dereference the result. In practice this can never happen, since all callers pass an oid which came from a "struct commit" already. So we can make this more obvious by just taking that commit struct in the first place. Reported-by: Cheng <prophecheng@stu.pku.edu.cn> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-20describe: handle blob traversal with no commitsJeff King2-2/+20
When describing a blob, we traverse from HEAD, remembering each commit we saw, and then checking each blob to report the containing commit. But if we haven't seen any commits at all, we'll segfault (we store the "current" commit as an oid initialized to the null oid, causing lookup_commit_reference() to return NULL). This shouldn't be able to happen normally. We always start our traversal at HEAD, which must be a commit (a property which is enforced by the refs code). But you can trigger the segfault like this: blob=$(echo foo | git hash-object -w --stdin) echo $blob >.git/HEAD git describe $blob We can instead catch this case and return an empty result, which hits the usual "we didn't find $blob while traversing HEAD" error. This is a minor lie in that we did "find" the blob. And this even hints at a bigger problem in this code: what if the traversal pointed to the blob as _not_ part of a commit at all, but we had previously filled in the recorded "current commit"? One could imagine this happening due to a tag pointing directly to the blob in question. But that can't happen, because we only traverse from HEAD, never from any other refs. And the intent of the blob-describing code is to find blobs within commits. So I think this matches the original intent as closely as we can (and again, this segfault cannot be triggered without corrupting your repository!). The test here does not use the formula above, which works only for the files backend (and not reftables). Instead we use another loophole to create the bogus state using only Git commands. See the comment in the test for details. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-20doc/gitk: update reference to the external projectJohannes Sixt1-4/+4
Gitk is now maintained by Johannes Sixt and the repository can be cloned from a new URL. b59358100c20 (Update the official repo of gitk, 2024-12-24) could have updated this instance in the manual, too, but the opportunity was missed. Update it now. Do give credit to Paul Mackerras as the inventor of the program. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-19refs: do not clobber dangling symrefsJeff King4-7/+87
When given an expected "before" state, the ref-writing code will avoid overwriting any ref that does not match that expected state. We use the null oid as a sentinel value for "nothing should exist", and likewise that is the sentinel value we get when trying to read a ref that does not exist. But there's one corner case where this is ambiguous: dangling symrefs. Trying to read them will yield the null oid, but there is potentially something of value there: the dangling symref itself. For a normal recursive write, this is OK. Imagine we have a symref "FOO_HEAD" that points to a ref "refs/heads/bar" that does not exist, and we try to write to it with a create operation like: oid=$(git rev-parse HEAD) ;# or whatever git symbolic-ref FOO_HEAD refs/heads/bar echo "create FOO_HEAD $oid" | git update-ref --stdin The attempt to resolve FOO_HEAD will actually resolve "bar", yielding the null oid. That matches our expectation, and the write proceeds. This is correct, because we are not writing FOO_HEAD at all, but writing its destination "bar", which in fact does not exist. But what if the operation asked not to dereference symrefs? Like this: echo "create FOO_HEAD $oid" | git update-ref --no-deref --stdin Resolving FOO_HEAD would still result in a null oid, and the write will proceed. But it will overwrite FOO_HEAD itself, removing the fact that it ever pointed to "bar". This case is a little esoteric; we are clobbering a symref with a no-deref write of a regular ref value. But the same problem occurs when writing symrefs. For example: echo "symref-create FOO_HEAD refs/heads/other" | git update-ref --no-deref --stdin The "create" operation asked us to create FOO_HEAD only if it did not exist. But we silently overwrite the existing value. You can trigger this without using update-ref via the fetch followRemoteHEAD code. In "create" mode, it should not overwrite an existing value. But if you manually create a symref pointing to a value that does not yet exist (either via symbolic-ref or with "remote add -m"), create mode will happily overwrite it. Instead, we should detect this case and refuse to write. The correct specification to overwrite FOO_HEAD in this case is to provide an expected target ref value, like: echo "symref-update FOO_HEAD refs/heads/other ref refs/heads/bar" | git update-ref --no-deref --stdin Note that the non-symref "update" directive does not allow you to do this (you can only specify an oid). This is a weakness in the update-ref interface, and you'd have to overwrite unconditionally, like: echo "update FOO_HEAD $oid" | git update-ref --no-deref --stdin Likewise other symref operations like symref-delete do not accept the "ref" keyword. You should be able to do: echo "symref-delete FOO_HEAD ref refs/heads/bar" but cannot (and can only delete unconditionally). This patch doesn't address those gaps. We may want to do so in a future patch for completeness, but it's not clear if anybody actually wants to perform those operations. The symref update case (specifically, via followRemoteHEAD) is what I ran into in the wild. The code for the fix is relatively straight-forward given the discussion above. But note that we have to implement it independently for the files and reftable backends. The "old oid" checks happen as part of the locking process, which is implemented separately for each system. We may want to factor this out somehow, but it's beyond the scope of this patch. (Another curiosity is that the messages in the reftable code are marked for translation, but the ones in the files backend are not. I followed local convention in each case, but we may want to harmonize this at some point). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-19t5510: prefer "git -C" to subshell for followRemoteHEAD testsJeff King1-119/+83
These tests set config within a sub-repo using (cd two && git config), and then a separate test_when_finished outside the subshell to clean it up. We can't use test_config to do this, because the cleanup command it registers inside the subshell would be lost. Nor can we do it before entering the subshell, because the config has to be set after some other commands are run. Let's switch these tests to use "git -C" for each command instead of a subshell. That lets us use test_config (with -C also) at the appropriate part of the test. And we no longer need the manual cleanup command. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-19t5510: stop changing top-level working directoryJeff King1-195/+161
Several tests in t5510 do a bare "cd subrepo", not in a subshell. This changes the working directory for subsequent tests. As a result, almost every test has to start with "cd $D" to go back to the top-level. Our usual style is to do per-test environment changes like this in a subshell, so that tests can assume they are starting at the top-level $TRASH_DIRECTORY. Let's switch to that style, which lets us drop all of that extra path-handling. Most cases can switch to using a subshell, but in a few spots we can simplify by doing "git init foo && git -C foo ...". We do have to make sure that we weren't intentionally touching the environment in any code which was moved into a subshell (e.g., with a test_when_finished), but that isn't the case for any of these tests. All of the references to the $D variable can go away, replaced generally with $PWD or $TRASH_DIRECTORY (if we use it inside a chdir'd subshell). Note in one test, "fetch --prune prints the remotes url", we make sure to use $(pwd) to get the Windows-style path on that platform (for the other tests, the exact form doesn't matter). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-19t5510: make confusing config cleanup more explicitJeff King1-9/+9
Several tests set a config variable in a sub-repo we chdir into via a subshell, like this: ( cd "$D" && cd two && git config foo.bar baz ) But they also clean up the variable with a when_finished directive outside of the subshell, like this: test_when_finished "git config unset foo.bar" At first glance, this shouldn't work! The cleanup clause cannot be run from the subshell (since environment changes there are lost by the time the test snippet finishes). But since the cleanup command runs outside the subshell, our working directory will not have been switched into "two". But it does work. Why? The answer is that an earlier test does a "cd two" that moves the whole test's working directory out of $TRASH_DIRECTORY and into "two". So the subshell is a bit of a red herring; we are already in the right directory! That's why we need the "cd $D" at the top of the shell, to put us back to a known spot. Let's make this cleanup code more explicitly specify where we expect the config command to run. That makes the script more robust against running a subset of the tests, and ultimately will make it easier to refactor the script to avoid these top-level chdirs. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-19doc: git-add: simplify discussion of ignored filesJulia Evans1-6/+4
- Mention the --force option earlier - Remove the explanation of shell globbing vs git's internal glob system, since users are confused by it and there's a clearer discussion in the EXAMPLES section. Signed-off-by: Julia Evans <julia@jvns.ca> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-19doc: git-add: clarify intro & add an exampleJulia Evans1-12/+12
- Add a basic example of how "git add" is normally used - It's not technically true that you *must* use the `add` command to add changes before running `git commit`, because `git commit -a` exists. Instead say that you *can* use the `add` command. - Mention early on that "index" is another word for "staging area", since Git very rarely uses the word "index" in its output (`git status`) uses the term "staged", and many Git users are unfamiliar with the term "index" - Remove "It typically adds" (it's not clear what "typically" means), and instead mention that `git add -p` can be used to add partial contents - Currently the introduction is somewhat repetitive ("to prepare the content staged for the next commit" ... "this snapshot that is taken as the contents of the next commit."), replace with a single sentence ("The "index" [...] is where Git stores the contents of the next commit.") Signed-off-by: Julia Evans <julia@jvns.ca> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-19t/t1517: mark tests that fail with GIT_TEST_INSTALLEDAdam Dinwoodie1-1/+4
The changes added by 39fc408562 (t/t1517: automate `git subcmd -h` tests outside a repository, 2025-08-08) to automatically loop over all "main" Git commands will, when run against an installed build using GIT_TEST_INSTALLED rather than the build in the build directory, include some extra git-gui commands that are installed by `make install`, or credential helpers that might be installed manually from the contrib directories. These fail the test, so record them as such. Signed-off-by: Adam Dinwoodie <adam@dinwoodie.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-18describe: catch unborn branch in describe_blob()Jeff King2-1/+15
When describing a blob, we search for it by traversing from HEAD. We do this by feeding the name HEAD to setup_revisions(). But if we are on an unborn branch, this will fail with a confusing message: $ git describe $blob fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git <command> [<revision>...] -- [<file>...]' It is OK for this to be an error (we cannot find $blob in an empty traversal, so we'd eventually complain about that). But the error message could be more helpful. Let's resolve HEAD ourselves and pass the resolved object id to setup_revisions(). If resolving fails, then we can print a more useful message. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-18describe: error if blob not foundJeff King2-0/+9
If describe_blob() does not find the blob in question, it returns an empty strbuf, and we print an empty line. This differs from describe_commit(), which always either returns an answer or calls die() itself. As the blob function was bolted onto the command afterwards, I think its behavior is not intentional, and it is just a bug that it does not report an error. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-18describe: pass oid struct by const pointerJeff King1-4/+4
We pass a "struct object_id" to describe_blob() by value. This isn't wrong, as an oid is composed only of copy-able values. But it's unusual; typically we pass structs by const pointer, including object_ids. Let's do so. It similarly makes sense for us to hold that pointer in the callback data (rather than yet another copy of the oid). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-18xdiff: optimize xdl_hash_record_verbatimAlexander Monakov1-4/+55
xdl_hash_record_verbatim uses modified djb2 hash with XOR instead of ADD for combining. The ADD-based variant is used as the basis of the modern ("GNU") symbol lookup scheme in ELF. Glibc dynamic loader received an optimized version of this hash function thanks to Noah Goldstein [1]. Switch xdl_hash_record_verbatim to additive hashing and implement an optimized loop following the scheme suggested by Noah. Timing 'git log --oneline --shortstat v2.0.0..v2.5.0' under perf, I got version | cycles, bn | instructions, bn --------------------------------------- A 6.38 11.3 B 6.21 10.89 C 5.80 9.95 D 5.83 8.74 --------------------------------------- A: baseline (git master at e4ef0485fd78) B: plus 'xdiff: refactor xdl_hash_record()' C: and plus this patch D: with 'xdiff: use xxhash' by Phillip Wood The resulting speedup for xdl_hash_record_verbatim itself is about 1.5x. [1] https://inbox.sourceware.org/libc-alpha/20220519221803.57957-6-goldstein.w.n@gmail.com/ Signed-off-by: Alexander Monakov <amonakov@ispras.ru> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-17Git 2.51v2.51.0Junio C Hamano1-1/+1
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-17Merge tag 'l10n-2.51.0-2' of https://github.com/git-l10n/git-poJunio C Hamano10-4029/+6223
l10n-2.51.0-2 * tag 'l10n-2.51.0-2' of https://github.com/git-l10n/git-po: l10n: Update Catalan Translation for Git 2.51-rc2 l10n: zh_CN: updated translation for 2.51 l10n: uk: add 2.51 translation l10n: zh_TW: Git 2.51 l10n: po-id for 2.51 l10n: fr translation update for v2.51.0 l10n: tr: Update Turkish translations for 2.51.0 l10n: Updated translation for vi-2.51 l10n: sv.po: Update Swedish translation l10n: bg.po: Updated Bulgarian translation (5856t)
2025-08-17repo: add the --format flagLucas Seiki Oshiro3-16/+88
Add the --format flag to git-repo-info. By using this flag, the users can choose the format for obtaining the data they requested. Given that this command can be used for generating input for other applications and for being read by end users, it requires at least two formats: one for being read by humans and other for being read by machines. Some other Git commands also have two output formats, notably git-config which was the inspiration for the two formats that were chosen here: - keyvalue, where the retrieved data is printed one per line, using = for delimiting the key and the value. This is the default format, targeted for end users. - nul, where the retrieved data is separated by NUL characters, using the newline character for delimiting the key and the value. This format is targeted for being read by machines. Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk> Helped-by: Junio C Hamano <gitster@pobox.com> Helped-by: Justin Tobler <jltobler@gmail.com> Helped-by: Eric Sunshine <sunshine@sunshineco.com> Mentored-by: Karthik Nayak <karthik.188@gmail.com> Mentored-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-17repo: add the field layout.shallowLucas Seiki Oshiro3-0/+25
This commit is part of the series that introduces the new subcommand git-repo-info. The flag `--is-shallow-repository` from git-rev-parse is used for retrieving whether the repository is shallow. This way, it is used for querying repository metadata, fitting in the purpose of git-repo-info. Then, add a new field `layout.shallow` to the git-repo-info subcommand containing that information. Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk> Helped-by: Junio C Hamano <gitster@pobox.com> Helped-by: Justin Tobler <jltobler@gmail.com> Helped-by: Eric Sunshine <sunshine@sunshineco.com> Mentored-by: Karthik Nayak <karthik.188@gmail.com> Mentored-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-17repo: add the field layout.bareLucas Seiki Oshiro3-0/+30
This commit is part of the series that introduces the new subcommand git-repo-info. The flag --is-bare-repository from git-rev-parse is used for retrieving whether the current repository is bare. This way, it is used for querying repository metadata, fitting in the purpose of git-repo-info. Then, add a new field layout.bare to the git-repo-info subcommand containing that information. Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk> Helped-by: Junio C Hamano <gitster@pobox.com> Helped-by: Justin Tobler <jltobler@gmail.com> Helped-by: Eric Sunshine <sunshine@sunshineco.com> Mentored-by: Karthik Nayak <karthik.188@gmail.com> Mentored-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-17repo: add the field references.formatLucas Seiki Oshiro4-2/+146
This commit is part of the series that introduces the new subcommand git-repo-info. The flag `--show-ref-format` from git-rev-parse is used for retrieving the reference format (i.e. `files` or `reftable`). This way, it is used for querying repository metadata, fitting in the purpose of git-repo-info. Add a new field `references.format` to the repo-info subcommand containing that information. Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk> Helped-by: Junio C Hamano <gitster@pobox.com> Helped-by: Justin Tobler <jltobler@gmail.com> Helped-by: Eric Sunshine <sunshine@sunshineco.com> Mentored-by: Karthik Nayak <karthik.188@gmail.com> Mentored-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-08-17repo: declare the repo commandLucas Seiki Oshiro9-0/+66
Currently, `git rev-parse` covers a wide range of functionality not directly related to parsing revisions, as its name suggests. Over time, many features like parsing datestrings, options, paths, and others were added to it because there wasn't a more appropriate command to place them. Create a new Git command called `repo`. `git repo` will be the main command for obtaining the information about a repository (such as metadata and metrics). Also declare a subcommand for `repo` called `info`. `git repo info` will bring the functionality of retrieving repository-related information currently returned by `rev-parse`. Add the required documentation and build changes to enable usage of this subcommand. Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk> Helped-by: Junio C Hamano <gitster@pobox.com> Helped-by: Justin Tobler <jltobler@gmail.com> Helped-by: Eric Sunshine <sunshine@sunshineco.com> Mentored-by: Karthik Nayak <karthik.188@gmail.com> Mentored-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>