Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
09d86a3
diff: fix out-of-bounds reads and NULL deref in diffstat UTF-8 trunca…
newren Apr 20, 2026
21186cf
alias: restore support for simple dotted aliases
jonatan-holmgren Apr 24, 2026
8e61175
test-lib: allow bare repository access when breaking changes are enabled
dscho Apr 26, 2026
a27fec3
t7900: do not let `$HOME/.gitconfig` interfere with XDG tests
dscho Apr 26, 2026
5fe676f
t1300: remove global config settings injected by test-lib.sh
dscho Apr 26, 2026
59227c0
t1305: use `--git-dir=.` for bare repo in include cycle test
dscho Apr 26, 2026
d97f27b
t5601: restore `.gitconfig` after includeIf test
dscho Apr 26, 2026
83228f1
ls-files tests: filter `.gitconfig` from `--others` output
dscho Apr 26, 2026
a09d2b2
status tests: filter `.gitconfig` from status output
dscho Apr 26, 2026
985b38c
safe.bareRepository: default to "explicit" with WITH_BREAKING_CHANGES
dscho Apr 26, 2026
0cf4ad7
replay: allow callers to control what happens with empty commits
pks-t Apr 27, 2026
88191ea
builtin/history: generalize function to commit trees
pks-t Apr 27, 2026
c6c2257
builtin/history: introduce "fixup" subcommand
pks-t Apr 27, 2026
1ddc048
commit: name UTF-8 function appropriately
bk2204 Apr 27, 2026
7735d7e
commit: sign commit after mutating buffer
bk2204 Apr 27, 2026
007062a
index-pack, unpack-objects: increase input buffer from 4 KiB to 128 KiB
sbauersfeld Apr 28, 2026
c9eb040
mingw: stop using nedmalloc
dscho May 8, 2026
cefcada
mingw: drop the build-system plumbing for nedmalloc
dscho May 8, 2026
0b72550
mingw: remove the vendored compat/nedmalloc/ subtree
dscho May 8, 2026
f206385
index-pack, unpack-objects: use size_t for object size
dscho May 8, 2026
d05d666
git-zlib: handle data streams larger than 4GB
dscho May 8, 2026
606c192
odb, packfile: use size_t for streaming object sizes
dscho May 8, 2026
17fa077
delta, packfile: use size_t for delta header sizes
dscho May 8, 2026
438886a
test-tool: add a helper to synthesize large packfiles
dscho May 8, 2026
4b220ca
t5608: add regression test for >4GB object clone
dscho May 8, 2026
3857ca9
test-tool synthesize: use the unsafe hash for speed
dscho May 8, 2026
ad6ae36
test-tool synthesize: precompute pack for 4 GiB + 1
dscho May 8, 2026
f549253
test-tool synthesize: add precomputed SHA-256 pack for 4 GiB + 1
dscho May 8, 2026
3f4f644
t5608: mark >4GB tests as EXPENSIVE
dscho May 8, 2026
7a094d6
ci: run expensive tests on push builds to integration branches
dscho May 8, 2026
a6876b2
Merge branch 'js/objects-larger-than-4gb-on-windows'
gitster May 20, 2026
91ddfe3
Merge branch 'js/mingw-no-nedmalloc'
gitster May 20, 2026
3b3a3ef
Merge branch 'en/diffstat-utf8-truncation-fix'
gitster May 20, 2026
18581f8
Merge branch 'js/adjust-tests-to-explicitly-access-bare-repo'
gitster May 20, 2026
cf71511
Merge branch 'bc/sign-commit-with-custom-encoding'
gitster May 20, 2026
345bc60
Merge branch 'jh/alias-i18n-fixes'
gitster May 20, 2026
ca7d7d6
Merge branch 'ps/history-fixup'
gitster May 20, 2026
f5fc0f5
Merge branch 'sb/unpack-index-pack-buffer-resize'
gitster May 20, 2026
1c00d2d
The 5th batch
gitster May 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions Documentation/BreakingChanges.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,30 @@ would be significant, we may decide to defer this change to a subsequent minor
release. This evaluation will also take into account our own experience with
how painful it is to keep Rust an optional component.

* The default value of `safe.bareRepository` will change from `all` to
`explicit`. It is all too easy for an attacker to trick a user into cloning a
repository that contains an embedded bare repository with malicious hooks
configured. If the user enters that subdirectory and runs any Git command, Git
discovers the bare repository and the hooks fire. The user does not even need
to run a Git command explicitly: many shell prompts run `git status` in the
background to display branch and dirty state information, and `git status` in
turn may invoke the fsmonitor hook if so configured, making the user
vulnerable the moment they `cd` into the directory. The `safe.bareRepository`
configuration variable was introduced in 8959555cee (setup_git_directory():
add an owner check for the top-level directory, 2022-03-02) with a default of
`all` to preserve backwards compatibility.
+
Changing the default to `explicit` means that Git will refuse to work with bare
repositories that are discovered implicitly by walking up the directory tree.
Bare repositories specified explicitly via the `--git-dir` command-line option
or the `GIT_DIR` environment variable continue to work regardless of this
setting. Repositories that look like a `.git` directory, a worktree, or a
submodule directory are also unaffected.
+
Users who rely on implicit discovery of bare repositories can restore the
previous behavior by setting `safe.bareRepository=all` in their global or
system configuration.

=== Removals

* Support for grafting commits has long been superseded by git-replace(1).
Expand Down
30 changes: 30 additions & 0 deletions Documentation/RelNotes/2.55.0.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ UI, Workflows & Features
one revision expression per line or commit object names found in
running text.

* "git history" learned "fixup" command.


Performance, Internal Implementation, Development Support etc.
--------------------------------------------------------------
Expand All @@ -37,6 +39,8 @@ Performance, Internal Implementation, Development Support etc.

* Preparation of the xdiff/ codebase to work with Rust.

* Use a larger buffer size in the code paths to ingest pack stream.


Fixes since v2.54
-----------------
Expand Down Expand Up @@ -106,6 +110,32 @@ Fixes since v2.54
which has been corrected.
(merge aa45a5902f sj/submodule-update-clone-config-fix later to maint).

* Update code paths that assumed "unsigned long" was long enough for
"size_t".
(merge 7a094d68a2 js/objects-larger-than-4gb-on-windows later to maint).

* Stop using unmaintained custom allocator in Windows build which was
the last user of the code.
(merge 0b72550110 js/mingw-no-nedmalloc later to maint).

* The computation to shorten the filenames shown in diffstat measured
width of individual UTF-8 characters to add up, but forgot to take
into account error cases (e.g., an invalid UTF-8 sequence, or a
control character).
(merge 09d86a3b98 en/diffstat-utf8-truncation-fix later to maint).

* Some tests assume that bare repository accesses are by default
allowed; rewrite some of them to avoid the assumption, rewrite
others to explicitly set safe.bareRepository to allow them.
(merge 985b38ca6c js/adjust-tests-to-explicitly-access-bare-repo later to maint).

* Signing commit with custom encoding was passing the data to be
signed at a wrong stage in the pipeline, which has been corrected.
(merge 7735d7eee3 bc/sign-commit-with-custom-encoding later to maint).

* Further update to the i18n alias support to avoid regressions.
(merge 21186cf9bb jh/alias-i18n-fixes later to maint).

* Other code cleanup, docfix, build fix, etc.
(merge 80f4b802e9 ja/doc-difftool-synopsis-style later to maint).
(merge b96490241e jc/doc-timestamps-in-stat later to maint).
Expand Down
10 changes: 8 additions & 2 deletions Documentation/config/safe.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@ safe.bareRepository::
Specifies which bare repositories Git will work with. The currently
supported values are:
+
* `all`: Git works with all bare repositories. This is the default.
* `all`: Git works with all bare repositories. This is the default in
Git 2.x.
* `explicit`: Git only works with bare repositories specified via
the top-level `--git-dir` command-line option, or the `GIT_DIR`
environment variable (see linkgit:git[1]).
environment variable (see linkgit:git[1]). This will be the default
in Git 3.0.
+
If you do not use bare repositories in your workflow, then it may be
beneficial to set `safe.bareRepository` to `explicit` in your global
config. This will protect you from attacks that involve cloning a
repository that contains a bare repository and running a Git command
within that directory.
+
If you use bare repositories regularly and want to preserve the current
behavior after upgrading to Git 3.0, set `safe.bareRepository` to `all`
in your global or system config.
+
This config setting is only respected in protected configuration (see
<<SCOPES>>). This prevents untrusted repositories from tampering with
this value.
Expand Down
78 changes: 76 additions & 2 deletions Documentation/git-history.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ git-history - EXPERIMENTAL: Rewrite history
SYNOPSIS
--------
[synopsis]
git history fixup <commit> [--dry-run] [--update-refs=(branches|head)] [--reedit-message] [--empty=(drop|keep|abort)]
git history reword <commit> [--dry-run] [--update-refs=(branches|head)]
git history split <commit> [--dry-run] [--update-refs=(branches|head)] [--] [<pathspec>...]

Expand All @@ -22,8 +23,9 @@ THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.
This command is related to linkgit:git-rebase[1] in that both commands can be
used to rewrite history. There are a couple of major differences though:

* linkgit:git-history[1] can work in a bare repository as it does not need to
touch either the index or the worktree.
* Most subcommands of linkgit:git-history[1] can work in a bare repository as
they do not need to touch either the index or the worktree. The `fixup`
subcommand is an exception to this, as it reads staged changes from the index.
* linkgit:git-history[1] does not execute any linkgit:githooks[5] at the
current point in time. This may change in the future.
* linkgit:git-history[1] by default updates all branches that are descendants
Expand All @@ -48,11 +50,28 @@ conflicts. This limitation is by design as history rewrites are not intended to
be stateful operations. The limitation can be lifted once (if) Git learns about
first-class conflicts.

When using `fixup` with `--empty=drop`, dropping the root commit is not yet
supported.

COMMANDS
--------

The following commands are available to rewrite history in different ways:

`fixup <commit>`::
Apply the currently staged changes to the specified commit. This is
similar in nature to `git commit --fixup=<commit>` followed by `git
rebase --autosquash <commit>~`. Changes are applied to the target
commit by performing a three-way merge between the HEAD commit, the
target commit and the tree generated from staged changes.
+
The commit message and authorship of the target commit are preserved by
default, unless you specify `--reedit-message`.
+
If applying the staged changes would result in a conflict, the command
aborts with an error. All branches that are descendants of the original
commit are updated to point to the rewritten history.

`reword <commit>`::
Rewrite the commit message of the specified commit. All the other
details of this commit remain unchanged. This command will spawn an
Expand Down Expand Up @@ -87,6 +106,31 @@ OPTIONS
objects will be written into the repository, so applying these printed
ref updates is generally safe.

`--reedit-message`::
Open an editor to modify the target commit's message.

`--empty=(drop|keep|abort)`::
Control what happens when a commit becomes empty as a result of the
fixup. This can happen in two situations:
+
--
* The fixup target itself becomes empty because the staged changes exactly
cancel out all changes introduced by that commit.

* A descendant commit becomes empty during replay because it introduced the
same change that was just fixed up into an ancestor.
--
+
With `drop` (the default), empty commits are removed from the rewritten
history. Descendants of a dropped target commit are replayed directly onto
the target's parent. Note that dropping the root commit is not supported;
see LIMITATIONS.
+
With `keep`, empty commits are retained in the rewritten history as-is.
+
With `abort`, the command stops with an error if any commit would become
empty.

`--update-refs=(branches|head)`::
Control which references will be updated by the command, if any. With
`branches`, all local branches that point to commits which are
Expand All @@ -96,6 +140,36 @@ OPTIONS
EXAMPLES
--------

Fixup a commit
~~~~~~~~~~~~~~

----------
$ git log --oneline --stat
abc1234 (HEAD -> main) third
third.txt | 1 +
def5678 second
second.txt | 1 +
ghi9012 first
first.txt | 1 +

$ echo "change" >>unrelated.txt
$ git add unrelated.txt
$ git history fixup ghi9012

$ git log --oneline --stat
jkl3456 (HEAD -> main) third
third.txt | 1 +
mno7890 second
second.txt | 1 +
pqr1234 first
first.txt | 1 +
unrelated.txt | 1 +
----------

The staged addition of `unrelated.txt` has been incorporated into the `first`
commit. All descendant commits have been replayed on top of the rewritten
history.

Split a commit
~~~~~~~~~~~~~~

Expand Down
18 changes: 1 addition & 17 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -283,13 +283,9 @@ include shared.mak
# Define SKIP_DASHED_BUILT_INS if you do not need the dashed versions of the
# built-ins to be linked/copied at all.
#
# Define USE_NED_ALLOCATOR if you want to replace the platforms default
# memory allocators with the nedmalloc allocator written by Niall Douglas.
#
# Define OVERRIDE_STRDUP to override the libc version of strdup(3).
# This is necessary when using a custom allocator in order to avoid
# crashes due to allocation and free working on different 'heaps'.
# It's defined automatically if USE_NED_ALLOCATOR is set.
#
# Define NO_REGEX if your C library lacks regex support with REG_STARTEND
# feature.
Expand Down Expand Up @@ -872,6 +868,7 @@ TEST_BUILTINS_OBJS += test-submodule-config.o
TEST_BUILTINS_OBJS += test-submodule-nested-repo-config.o
TEST_BUILTINS_OBJS += test-submodule.o
TEST_BUILTINS_OBJS += test-subprocess.o
TEST_BUILTINS_OBJS += test-synthesize.o
TEST_BUILTINS_OBJS += test-trace2.o
TEST_BUILTINS_OBJS += test-truncate.o
TEST_BUILTINS_OBJS += test-userdiff.o
Expand Down Expand Up @@ -1512,7 +1509,6 @@ BUILTIN_OBJS += builtin/write-tree.o
# upstream unnecessarily (making merging in future changes easier).
THIRD_PARTY_SOURCES += compat/inet_ntop.c
THIRD_PARTY_SOURCES += compat/inet_pton.c
THIRD_PARTY_SOURCES += compat/nedmalloc/%
THIRD_PARTY_SOURCES += compat/obstack.%
THIRD_PARTY_SOURCES += compat/poll/%
THIRD_PARTY_SOURCES += compat/regex/%
Expand Down Expand Up @@ -2268,12 +2264,6 @@ ifdef NATIVE_CRLF
BASIC_CFLAGS += -DNATIVE_CRLF
endif

ifdef USE_NED_ALLOCATOR
COMPAT_CFLAGS += -Icompat/nedmalloc
COMPAT_OBJS += compat/nedmalloc/nedmalloc.o
OVERRIDE_STRDUP = YesPlease
endif

ifdef OVERRIDE_STRDUP
COMPAT_CFLAGS += -DOVERRIDE_STRDUP
COMPAT_OBJS += compat/strdup.o
Expand Down Expand Up @@ -2984,12 +2974,6 @@ compat/regex/regex.sp compat/regex/regex.o: EXTRA_CPPFLAGS = \
-DGAWK -DNO_MBSUPPORT
endif

ifdef USE_NED_ALLOCATOR
compat/nedmalloc/nedmalloc.sp compat/nedmalloc/nedmalloc.o: EXTRA_CPPFLAGS = \
-DNDEBUG -DREPLACE_SYSTEM_ALLOCATOR
compat/nedmalloc/nedmalloc.sp: SP_EXTRA_FLAGS += -Wno-non-pointer-null
endif

headless-git.o: compat/win32/headless.c GIT-CFLAGS
$(QUIET_CC)$(CC) $(ALL_CFLAGS) $(COMPAT_CFLAGS) \
-fno-stack-protector -o $@ -c -Wall -Wwrite-strings $<
Expand Down
16 changes: 14 additions & 2 deletions alias.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,20 @@ static int config_alias_cb(const char *var, const char *value,
if (subsection && !subsection_len)
subsection = NULL;

if (subsection && strcmp(key, "command"))
return 0;
if (subsection && strcmp(key, "command")) {
/*
* We have historically supported the "alias.name" form when
* "name" happens to contain dots (e.g., alias.foo.bar to allow
* "git foo.bar". But our parsing above would split that into
* subsection "foo".
*
* If we do not understand the final key in a subsection-style
* variable, fall back to treating it as a two-level alias.
*/
key = var + strlen("alias.");
subsection = NULL;
subsection_len = 0;
}

if (data->alias) {
int match;
Expand Down
Loading