Create one replacement commit from the resolved range when --no-edit is
selected. Preserve the authorship and all parents of the oldest commit,
use the tip tree, and replay descendants through the existing history
rewrite machinery. Record the complete revision expression in the
reflog and retain dry-run and update-refs behavior.
Resolve fixup!, squash! and amend! subjects while walking the range.
Reject markers whose targets are not selected and refuse any no-edit
fold that would discard a squash! or amend! message. A range made
entirely from related markers can still be consolidated, with the last
applicable amend! body supplying the message.
Inspired-by: Sergey Chernov <serega.morph@gmail.com>
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
A local branch that descends from the selected graph without containing
its tip cannot be replayed as a descendant of the squashed commit. Find
those branches with ref-filter before creating any replacement objects
and refuse the operation unless --update-refs=head was requested.
Limit this protection to local branches, matching the refs that the
default history rewrite mode updates; tags and remote-tracking refs
remain untouched. Sort the blocking refs and print their short branch
names so the user can decide whether to move them or leave them behind.
Add advice.historyUpdateRefs for the hint that points to
--update-refs=head.
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Walk the selected commits in topological order from oldest to newest and
mark each one as it is seen. Every parent after the oldest commit must
already be selected or also be a parent of the oldest commit. This
accepts merges contained by the range while rejecting a merge arm that
entered it from elsewhere.
Track the remaining graph tips during the same walk and require exactly
one. Also reject empty and single-commit ranges and any selection that
reaches a root commit. These checks identify the oldest commit whose
parents will be preserved and the single tip whose tree will be used by
the rewrite.
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Add the entry point and option parsing for "git history squash". Pass
the remaining arguments through setup_revisions() so the command accepts
revision ranges and rev-list options, while restoring the ordering and
simplification settings required by the fold if an option changes them.
Require at least one BOTTOM revision. The squashed commit needs a commit
outside the selected range to serve as its base, so a single positive
revision is not a sufficient range.
Keep this step limited to defining the revision input contract so graph
validation and the rewrite can be added independently.
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When "git rebase -i" squashes commits it builds an editor template with a
"This is a combination of N commits." banner, a "This is the 1st/Nth
commit message:" header above each kept message (or a "will be skipped"
header for a dropped one), and a commented-out subject for any fixup!,
squash! or amend! commit. The banner, the headers and the
subject-commenting all live in static helpers in sequencer.c wired to the
rebase state, so no other command can present a squash the same way.
Pull the three pieces out into add_squash_combination_header(),
add_squash_message_header() (which takes a flag for the "will be skipped"
variant) and squash_subject_comment_len(), and use them from
update_squash_messages() and append_squash_message(). Also move the
todo_item_flags enum to the header, so a caller reading the output of
todo_list_rearrange_squash() can tell an amend! (TODO_REPLACE_FIXUP_MSG)
from a plain fixup!. A later change reuses all of this to give "git
history squash" the same template.
No change in behavior.
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
commit_tree_ext() reuses the message of the commit it is handed. A
caller that folds several commits together wants to seed the message
from more than that single commit, so add an optional message_template
parameter. When NULL, the behavior is unchanged.
Pass NULL from the existing fixup and split callers.
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Three places resolve the tree of a commit's first parent, falling back
to the empty tree for a root commit, each repeating the same parse and
oidcpy dance. Extract a first_parent_tree_oid() helper and route the
existing callers through it.
No change in behavior.
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Various code paths have been hardened against potential NULL-pointer
dereferences and invalid file descriptor accesses flagged by
Coverity.
* js/coverity-fixes-null-safety:
shallow: give write_one_shallow() its own hex buffer
shallow: fix NULL dereference
bisect: ensure non-NULL `head` before using it
pack-bitmap: handle missing bitmap for base MIDX
revision: avoid dereferencing NULL in `add_parents_only()`
replay: die when --onto does not peel to a commit
bisect: handle NULL commit in `bisect_successful()`
mailsplit: move NULL check before first use of file handle
reftable/stack: guard against NULL list_file in stack_destroy
remote: guard `remote_tracking()` against NULL remote
diff: handle NULL return from repo_get_commit_tree()
diffcore-break: guard against NULLed queue entries in merge loop
The performance of ref updates and reads using the 'reftable' backend
in the presence of many deletion tombstone records has been optimized
by removing the tombstone suppression flag from the merged iterator
and instead skipping tombstones at higher-level call sites where
iteration bounds are known.
* kk/reftable-tombstone-quadratic-fix:
reftable: fix quadratic behavior in the presence of tombstones
t/perf: add perf test for ref tombstone scenarios
The 'topo_levels' slab was propagated only to the topmost layer of a
split commit-graph chain, causing topological levels for commits in
base layers to be recomputed during incremental writes. This has been
corrected.
* kk/commit-graph-topo-levels-fix:
commit-graph: propagate topo_levels slab to all chain layers
commit-graph: add trace2 instrumentation for generation DFS
The global configuration variable 'ignore_case' (representing the
'core.ignorecase' configuration) has been migrated into 'struct
repo_config_values' to tie it to a specific repository instance.
* ty/migrate-ignorecase:
config: use repo_ignore_case() to access core.ignorecase
environment: move ignore_case into repo_config_values
The client-side parser of the server-advertised bundle-URI list has
been updated to drain the remaining response in order to avoid
protocol desynchronization when the server sends a misconfigured list.
Also, the server-side has been taught to omit empty configuration
values instead of sending invalid key-value lines.
* tc/bundle-uri-empty-fix:
bundle-uri: stop sending invalid bundle configuration
bundle-uri: drain remaining response on invalid bundle-uri lines
The cache-scanning loop in 'next_cache_entry()' has been optimized
to avoid rescanning already-unpacked index entries, preventing a
quadratic performance slow-down when diffing the working tree
against a commit with a pathspec matching early index entries.
* hf/unpack-trees-quadratic-scan:
unpack-trees: avoid quadratic index scan in next_cache_entry()
The contributor guide has been updated to advise new contributors to
trim irrelevant quoted text when replying to review comments, matching
the existing advice given to reviewers.
* wy/doc-myfirstcontribution-trim-quotes:
MyFirstContribution: mention trimming quoted text in replies
The pipelines in 't1410-reflog.sh' have been replaced with the
'test_stdout_line_count' helper to avoid suppressing the exit code of
'git' commands, ensuring failures are not hidden from the test suite.
* gr/t1410-reflog-exit-code:
t1410-reflog.sh: avoid suppressing git's exit code in pipelines
The test suite has been updated to use the 'test_grep' helper instead
of bare 'grep' for test assertions, allowing file contents to be
printed on failure for easier debugging. A new 'greplint' linter has
been introduced to detect and prevent new bare 'grep' assertions from
being added to the test suite.
* mm/test-grep-lint:
t: add greplint to detect bare grep assertions
t: convert grep assertions to test_grep
t: fix Lexer line count for $() inside double-quoted strings
t: extract chainlint's parser into shared module
t: fix grep assertions missing file arguments
t/README: document test_grep helper
The build system has been updated to support building universal macOS
binaries when 'Rust' is enabled, by compiling separate static archives
for each target triple listed in 'RUST_TARGETS' and combining them
using the macOS 'lipo' tool. The 'git-credential-osxkeychain' helper
has been updated to link against '$(RUST_LIB)' when 'Rust' is enabled.
* sn/osxkeychain-rust-universal:
contrib: wire up osxkeychain in contrib/Makefile on macOS
Makefile: support universal macOS builds via RUST_TARGETS
Makefile: add $(RUST_LIB) prerequisite to osxkeychain
Option parsing with 'git rev-parse --parseopt' and in most 'git'
subcommands has been updated to exit with 0 (instead of 129) when the
help option ('-h' or '--help') is requested directly by the user,
aligning with standard Unix convention.
* bc/parse-options-exit-0-on-help:
parse-options: exit 0 on -h
rev-parse: have --parseopt callers exit 0 on --help
parse-options: add a separate case for help output on error
t1517: skip svn tests if svn is not installed
The 'SubmittingPatches' document has been updated to explicitly
describe the expectation for contributors to retract or abandon their
patch series when they are no longer pursuing it.
* jc/submitting-patches-abandoning:
SubmittingPatches: document how to retract a topic
The early-exit optimization in 'paint_down_to_common()' has been
gated on the queue being generation-ordered, fixing a bug where
'git merge-base' (without '--all') could return incorrect results
on repositories with v1 commit graphs and clock skew.
* kk/commit-reach-find-all-fix:
commit-reach: guard !FIND_ALL early exit with generation ordering check
t6600: add test for merge-base early exit with clock skew
A description in the release notes for Git 2.55.0 has been
retroactively updated to clarify that Rust support is enabled by
default, but still optional, and will become mandatory in Git 3.0.
* jc/relnotes-2.55-rust-fix:
Rust: fix description in Release Notes to 2.55
The repository discovery and repository configuration phases, which
were previously intertwined in 'setup.c', have been split. Repository
discovery has been updated to populate a 'struct repo_discovery'
without modifying the repository state, which is then taken by
repository configuration to initialize the repository, paving the way
for clean unification of repository configuration.
* ps/setup-split-discovery-and-setup:
setup: mark `set_git_work_tree()` as file-local
setup: pass worktree to `init_db()`
setup: drop redundant configuration of `startup_info->have_repository`
setup: make repository discovery self-contained
setup: propagate prefix via repository discovery
setup: drop static `cwd` variable
setup: move prefix into repository
setup: embed repository format in discovery
setup: introduce explicit repository discovery
setup: split up concerns of `setup_git_env_internal()`
setup: unify setup of shallow file
setup: mark bogus worktree in `apply_repository_format()`
setup: rename `check_repository_format_gently()`
The 'reftable' code has been hardened against corrupted tables by
fixing out-of-bounds writes, out-of-bounds reads, and abort calls
during parsing.
* ps/reftable-hardening:
reftable/table: fix OOB read on truncated table
reftable/table: fix NULL pointer access when seeking to bogus offsets
reftable/block: fix OOB read with bogus restart offset
reftable/block: fix use of uninitialized memory when binsearch fails
reftable/block: fix OOB read with bogus restart count
reftable/block: fix OOB read with bogus block size
reftable/block: fix OOB write with bogus inflated log size
t/unit-tests: introduce test helper to write reftable blocks
reftable/record: don't abort when decoding invalid ref value type
reftable/basics: fix OOB read on binary search of empty range
oss-fuzz: add fuzzer for parsing reftables
meson: support building fuzzers with libFuzzer
The sideband demultiplexer has been updated to recognize ANSI SGR
escape sequences that use colon-separated subfields (e.g., for
256-color or true-color codes).
* mm/sideband-ansi-sgr-colon-fix:
sideband: allow ANSI SGR with colon-separated subfields
The 'git_hash_*()' wrappers have been updated to be used consistently
across the codebase instead of direct calls to members of 'struct
git_hash_algo', and 'git_hash_discard()' has been made idempotent to
simplify cleanups.
* jk/git-hash-cleanups:
hash: check ctx->active flag in all wrapper functions
http: use idempotent git_hash_discard()
csum-file: use idempotent git_hash_discard()
hash: make git_hash_discard() idempotent
hash: document function pointers and wrappers
hash: convert remaining direct function calls
hash: use git_hash_init() consistently
The UTF-8 precomposition wrapper on macOS has been updated to use a
flexible array member to represent the name of a directory entry,
preventing fortified libc checks from failing when the name is
reallocated to be larger than 'NAME_MAX' bytes.
* ih/precompose-flex-array:
precompose_utf8: use a flex array for d_name
Various test scripts have been updated to clean up large temporary
files and repositories, reducing peak disk usage during testing.
Also, expensive tests have been disabled on platforms that lack
sufficient resources (like 32-bit platforms and Windows CI runners),
and the long test suite has been enabled in GitLab CI.
* ps/t-fixes-for-git-test-long:
gitlab-ci: enable "GIT_TEST_LONG"
gitlab-ci: disable RAM disk on macOS jobs
t: use `test_bool_env` to parse GIT_TEST_LONG
t7900: clean up large EXPENSIVE repository
t7508: skip EXPENSIVE test that is broken without SIZE_T_IS_64BIT
t5608: reduce maximum disk usage
t4141: fix inefficient use of dd(1)
t0021: skip EXPENSIVE test that is broken without SIZE_T_IS_64BIT
README: add GitLab CI badge to make it more discoverable
Dockerized CI jobs running in private GitHub repositories have been
adjusted to use explicit process and file limits, preventing resource
exhaustion errors on private runners.
* js/ci-dockerized-pid-limit:
ci(dockerized): raise the PID limit for private repositories
Various resource leaks, invalid file descriptor closures, and process
handle ownership issues flagged by Coverity have been fixed.
* js/coverity-fixes:
mingw: make `exit_process()` own the process handle on all paths
fsmonitor: plug token-data leak on early daemon-startup failures
reftable/table: release filter on error path
imap-send: avoid leaking the IMAP upload buffer
worktree: fix resource leaks when branch creation fails
submodule: fix cwd leak in `get_superproject_working_tree()`
dir: free allocations on parse-error paths in `read_one_dir()`
line-log: avoid redundant copy that leaks in process_ranges
run-command: avoid `close(-1)` in `start_command()` error paths
download_https_uri_to_file(): do not leak fd upon failure
loose: avoid closing invalid fd on error path
load_one_loose_object_map(): fix resource leak
Various code paths that initialize a cryptographic hash context but
bail out or finish without calling 'git_hash_final()' have been taught
to call 'git_hash_discard()' to release allocated resources, fixing
memory leaks when Git is built with non-default backends like
'OpenSSL' or 'libgcrypt'.
* jk/hash-algo-leak-fixes:
hash: add platform-specific discard functions
hash: fix memory leak copying sha256 gcrypt handles
http: discard hash in dumb-http http_object_request
check_stream_oid(): discard hash on read error
patch-id: discard hash when done
csum-file: provide a function to release checkpoints
csum-file: always finalize or discard hash
hash: add discard primitive
csum-file: drop discard_hashfile()
The wincred credential helper has been updated to avoid memory
corruption when erasing credentials and to prevent silent
credential loss when storing OAuth tokens, by correcting buffer
allocations and arguments passed to safe-CRT APIs.
* js/wincred-fixes:
wincred: prevent silent credential loss when storing OAuth tokens
wincred: avoid memory corruption when erasing a credential
When `git credential approve` hands the wincred helper a password
together with an `oauth_refresh_token`, the OAuth branch of
`store_credential()` writes one WCHAR past the allocation while
formatting both fields into a single `CredentialBlob`. On Windows
this trips heap verification and tears the helper down with status
`0xC0000374`; `approve` masks the failure, so the credential the
user meant to save never reaches `CredWriteW()` and the next
session prompts for it again.
The bug has the same shape as the one fixed in the previous commit:
the allocation leaves no room for the terminating NUL, and the
`sizeOfBuffer` argument to `_snwprintf_s()` is a byte count where
the API expects a WCHAR count, which lets the safe-CRT runtime
write the terminator out of bounds.
Apply the same remedy d22a488482 (wincred: avoid memory corruption,
2025-11-17) applied in `get_credential()`: allocate `(wlen + 1) *
sizeof(WCHAR)` bytes and pass `wlen + 1` as the destination
capacity in WCHARs.
This closes the second of the two heap writes tracked under
GHSA-rxqw-wxqg-g7hw.
Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The earlier d22a488482 (wincred: avoid memory corruption, 2025-11-17)
repaired only get_credential(); match_cred_password() has the same
defect and is reached on `git credential reject`. When Git asks the
helper to erase a stored credential whose password was supplied by
the caller, the helper copies the candidate's password into a freshly
allocated buffer for comparison. That copy overruns the allocation
by one WCHAR of NUL, which on uninstrumented Windows manifests as
process termination with status 0xC0000374. Because the helper can
die before reaching CredDeleteW(), `git credential reject` masks the
failure and the rejected credential remains stored.
CredentialBlobSize is documented as a byte count, so for an N-WCHAR
blob it equals N * sizeof(WCHAR). The pre-fix code allocated that
many bytes and asked wcsncpy_s to copy N wide characters, but
wcsncpy_s always appends a terminating NUL WCHAR, writing one WCHAR
past the allocation. The destination-capacity argument was also
passed in bytes rather than in WCHAR elements as the API requires,
so the safe-CRT runtime never rejected the copy.
See GHSA-rxqw-wxqg-g7hw.
Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
* 'master' of https://github.com/j6t/git-gui:
git-gui: allow larger width for the commit message field
git-gui: reduce complexity of the quiet msgfmt rule
git-gui: drop msgfmt --statistics output
git-gui i18n: Update Bulgarian translation (562t)
The alignment of commit object name abbreviations in 'git blame'
output has been optimized to reserve a column for marks (caret,
question mark, or asterisk) only when such marks are actually shown.
* rs/blame-abbrev-marks:
blame: reserve mark column only if necessary
A racy build failure under Meson has been corrected by ensuring that
the generated header file 'hook-list.h' is built before compiling
files in 'builtin_sources' that depend on it.
* mg/meson-hook-list-buildfix:
meson: restore hook-list.h to builtin_sources
Various memory leaks in the Bloom-filter code paths that are exposed
when running tests with the 'GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS=1'
environment variable have been plugged.
* jk/bloom-leak-fixes:
line-log: drop extra copy of range with bloom filters
revision: avoid leaking bloom keyvecs with multiple traversals
bloom: make bloom-filter slab initialization idempotent
The experimental 'git history' command has been taught a new 'drop'
subcommand to remove a commit, with its descendants replayed onto its
parent.
* ps/history-drop:
builtin/history: implement "drop" subcommand
builtin/history: split handling of ref updates into two phases
replay: expose `replay_result_queue_update()`
reset: stop assuming that the caller passes in a clean index
reset: allow the caller to specify the current HEAD object
reset: introduce ability to skip updating HEAD
reset: introduce dry-run mode
reset: modernize flags passed to `reset_working_tree()`
reset: rename `reset_head()`
reset: drop `USE_THE_REPOSITORY_VARIABLE`
read-cache: split out function to drop unmerged entries to stage 0
The 'whence' field in 'struct object_info' has been removed. The
backend-specific object information retrieval has been refactored into
an opt-in 'struct object_info_source' structure.
* ps/odb-drop-whence:
odb: document object info fields
odb: drop `whence` field from object info
treewide: convert users of `whence` to the new source field
odb: add `source` field to struct object_info_source
odb: make backend-specific fields optional
packfile: thread odb_source_packed through packed_object_info()
The 'git refs' toolbox has been extended with new 'create', 'delete',
'update', and 'rename' subcommands to create, delete, update, and
rename references, respectively.
* ps/refs-writing-subcommands:
builtin/refs: add "rename" subcommand
builtin/refs: add "create" subcommand
builtin/refs: add "update" subcommand
builtin/refs: add "delete" subcommand
builtin/refs: drop `the_repository`
A write file stream resource leak has been fixed as part of a code
cleanup.
* jc/history-message-prep-fix:
history: streamline message preparation and plug file stream leak
The 'reprepare()' callback for object database sources has been
generalized into a 'prepare()' callback with an optional flush cache
flag, and a new 'odb_prepare()' wrapper has been introduced to allow
pre-opening object database sources.
* ps/odb-generalize-prepare:
odb: introduce `odb_prepare()`
odb/source: generalize `reprepare()` callback