Commit Graph

13963 Commits (aae63be1d8391401e0ad1663ed159bcd03326b0a)

Author SHA1 Message Date
Junio C Hamano a2ef06b1ef Merge branch 'ps/odb-streams'
The 'struct odb_read_stream' and 'struct odb_write_stream'
structures have been consolidated into a single unified 'struct
odb_stream' structure, simplifying object database streaming APIs
and enabling streaming of arbitrary object types.

* ps/odb-streams:
  odb/streaming: unify function names to create new streams
  odb/streaming: rename `struct input_zstream_data`
  odb/streaming: rename `struct read_object_fd_data`
  odb/streaming: consolidate read and write streams
  odb/streaming: rename `struct odb_read_stream`
  odb/streaming: support streaming arbitrary object types
  odb/streaming: drop `is_finished` field
  odb/streaming: track write stream size in the structure
2026-08-23 18:01:43 -07:00
Junio C Hamano 10d3ea2469 Merge branch 'cc/fast-import-usage'
The usage string of 'git fast-import' has been updated to use the
parse_options() API for displaying help, and its SYNOPSIS in the
documentation has been standardized to match.

* cc/fast-import-usage:
  fast-import: remove useless from_stream argument
  fast-import: use parse_options() for command line options
  fast-import: use callbacks to parse some options
  fast-import: use struct option for usage string
  fast-import: move command state globals into 'struct fast_import_state'
  fast-import: introduce 'struct fast_import_state'
  fast-import: factor out option_*() functions
  fast-import: use int for some bool flags
  fast-import: localize 'i' into the 'for' loops using it
  api-parse-options.adoc: document hidden and OPT_*_F option macros
  api-parse-options.adoc: document per-option flags
  parse-options: introduce OPT_HIDDEN_GROUP
2026-08-23 18:01:42 -07:00
Junio C Hamano 4b27b7c707 Merge branch 'ps/cat-file-remote-object-info-type'
The 'remote-object-info' command for 'git cat-file --batch-command'
has been extended to support the '%(objecttype)' placeholder.

* ps/cat-file-remote-object-info-type:
  cat-file: unify default format
  serve: advertise type capability
  fetch-object-info: parse type from server response
  protocol-caps: add type support to object-info
  transport: drop remote object-info fields from transport struct
  fetch-object-info: die() on the remaining error path
  fetch-object-info: use dedicated struct for the results
  fetch-object-info: pass arguments directly instead of a struct
  fetch-object-info: detect malformed server responses
  t5701: use test_file_size() to get the size of a file
2026-08-23 18:01:42 -07:00
Junio C Hamano 006933a32c Merge branch 'hn/branch-delete-merged'
The 'git branch' command has been taught the '--delete-merged' option
to remove local branches that are already merged into their tracked
remote-tracking branches.

* hn/branch-delete-merged:
  branch: add --dry-run for --delete-merged
  branch: add branch.<name>.deleteMerged opt-out
  branch: add --delete-merged <pattern>
  branch: prepare delete_branches for a bulk caller
  branch: let delete_branches skip unmerged branches on bulk refusal
  branch: convert delete_branches() to a flags argument
  branch: add --forked filter for --list mode
2026-08-20 07:30:51 -07:00
Junio C Hamano e23356ae1a Merge branch 'hn/bisect-reset-when-found'
The 'git bisect' command has been taught a
'--reset-when-found[=<where>]' option that tells the command to
automatically run 'git bisect reset' to jump back to the original
state or to the found culprit.

* hn/bisect-reset-when-found:
  bisect: add --reset-when-found to leave when done
  bisect: let bisect_reset() optionally check out quietly
2026-08-18 09:31:36 -07:00
Junio C Hamano 3beb8bb742 Merge branch 'ps/writev'
A compatibility wrapper for writev(3p) has been reintroduced,
including fixes for CMake build and 'MAX_IO_SIZE' limits on NonStop.
Calls to write(3p) in send_sideband() and cat_blob() have been
refactored to use writev(3p) wrappers to reduce syscall overhead.

* ps/writev:
  fast-import: use writev(3p) to send cat-blob responses
  sideband: use writev(3p) to send pktlines
  wrapper: properly handle MAX_IO_SIZE in writev(3p)
  wrapper: introduce writev(3p) wrappers
  compat/posix: introduce writev(3p) wrapper
2026-08-18 09:31:36 -07:00
Junio C Hamano 230296d560 Merge branch 'jc/add-resolved'
'git add' has been taught a new '--resolved' option to stage
conflict-resolved paths, while leaving unrelated local changes
unstaged.  It scans the unmerged paths for leftover conflict
markers and aborts if any are found.

* jc/add-resolved:
  add: introduce '--resolved' option
  read-cache: add remove_file_from_index_with_flags()
  merge-ll: consolidate conflict marker scanning logic
  read-cache: reindent
2026-08-15 09:20:27 -07:00
Junio C Hamano 4753128b86 Merge branch 'lo/mv-missing-dest-dir-check'
'git mv' has been updated to check for a missing destination
leading directory during the checking phase, allowing 'git mv -n'
to report the failure.  The error message when the rename(2)
syscall fails has also been improved to name both the source and
the destination.

* lo/mv-missing-dest-dir-check:
  mv: reject a destination whose leading path is missing or a symlink
  mv: name both source and destination when rename fails
2026-08-11 10:07:00 -07:00
Christian Couder a09c2f2c70 fast-import: remove useless from_stream argument
Now that a previous commit has removed a call to parse_one_feature()
from parse_argv(), the former is always called with its `from_stream`
argument set to 1.

Let's take advantage of that to simplify and cleanup the code a bit.

Signed-off-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:33:17 -07:00
Christian Couder 863937696e fast-import: use parse_options() for command line options
Previous commits have started to use the parse-options API to display
output from `git fast-import -h` and `git fast-import --help-all` and
to prepare for parsing the command line options using this API.

Let's now actually use the API to parse command line options.

This brings a number of changes that are mostly beneficial:

  - The `--alias`, `--get-mark`, `--cat-blob`, `--ls` and `--notes`
    options are no longer accepted on the command line. They were
    previously accepted as no-ops because parse_argv() fell through to
    parse_one_feature(). They are not documented in the OPTIONS section
    and are only meaningful as in-stream feature assertions, so
    accepting them on the command line was an accident of code sharing
    dating back to 9c8398f0c9 (fast-import: add option command,
    2009-12-04).

  - Abbreviated options like `--dep=5` now work since parse_options()
    allows unambiguous prefixes.

  - As `--cat-blob` is an abbreviation of `--cat-blob-fd`, using the
    former on the command line will fail with "option `cat-blob-fd'
    requires a value" unlike the other four options that are not
    accepted anymore on the command line (see above).

  - Value-taking options now also accept the space-separated
    `--opt value` form, like `--depth 5`, in addition to the
    `--opt=value` form.

  - A bare or trailing `--` is now accepted and the stream is read
    normally, while it used to be a usage error.

  - The error messages for some options might differ a bit.

  - The code is shorter and more standard.

Note that parse_one_feature() is now always called with its
`from_stream` argument set to 1, but the code simplifications that
can be made are left for a following clean-up commit.

Signed-off-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:33:17 -07:00
Christian Couder 87cf4d7299 fast-import: use callbacks to parse some options
A previous commit started using the parse-option API to generate proper
`git fast-import -h` and `git fast-import --help-all` output.

Let's prepare for when we can use that API to also parse the options by
using OPT_CALLBACK for some options that require special processing of
their arguments.

A following commit will actually parse the options using these
callbacks.

Signed-off-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:33:17 -07:00
Christian Couder 27ab5815f7 fast-import: use struct option for usage string
Currently `git fast-import -h` shows the following on a single line:

  usage : git fast-import [--date-format=<f>] [--max-pack-size=<n>] \
                          [--big-file-threshold=<n>] [--depth=<n>] \
                          [--active-branches=<n>] \
                          [--export-marks=<marks.file>]

This output has a number of issues like:

  - It's missing a lot of options.
  - It's not consistent with the SYNOPSIS section of the doc.
  - With `--help-all` instead of `-h` additional hidden options should
    be shown, but that's not the case.
  - It's not standard style anymore.
  - Most other Git commands show additional lines for most of the
    options they support.

Also while most commands use the parse-options API to handle their
options, "builtin/fast-import.c" still doesn't use it.

Let's improve on that by using the parse-options API to display the
options when `-h` and `--help-all` are used.

While at it, let's make the SYNOPSIS section of
"Documentation/git-fast-import.adoc" consistent with the new usage
string.

This deliberately leaves it to future work to also use the
parse-options API to actually parse the options.

Signed-off-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:33:17 -07:00
Christian Couder ee996af567 fast-import: move command state globals into 'struct fast_import_state'
A previous commit introduced 'struct fast_import_state' to hold some
command state, and reduce the need for global variables.

Let's continue in the same direction and move two more global variables
that describe the command state into it: 'seen_data_command' and
'allow_unsafe_features'.

All the sites accessing these variables are already in functions that
receive the 'state' parameter (or in cmd_fast_import() which owns the
struct), so no additional threading is needed.

As 'state->allow_unsafe_features' is now dereferenced in
check_unsafe_feature(), its 'state' parameter is no longer unused, so
the UNUSED marker is removed.

The fast_import_state_init() call is moved up before the early
command-line scan for '--allow-unsafe-features', so that this option
can be recorded directly into the struct without being clobbered by
the memset() in fast_import_state_init().

This is a mechanical refactoring with no intended behavior change.

Signed-off-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:33:17 -07:00
Christian Couder 417afb2b4d fast-import: introduce 'struct fast_import_state'
"builtin/fast-import.c" uses a large number of global variables. This
makes it harder than necessary to reason about and improve. Especially
adding new features requires adding more global variables, while
modernizing and eventually libifying the code becomes more and more
difficult.

To start reverting the sad trend to more and more globals and to start
cleaning things up, let's introduce a 'struct fast_import_state' and
pass an instance of it as the first argument to many functions.

This is similar to what was done for "builtin/apply.c" by introducing a
'struct apply_state', see 07d7e290ff (apply: move 'struct apply_state'
to a header file, 2016-08-11) and related commits.

As a first step only the 'global_argc', 'global_argv' and
'global_prefix' variables are moved into the new struct. More variables
will be moved into it in the following commits.

Some functions receive the new 'state' parameter only to pass it
along or for future use, so they are marked with UNUSED for now to
satisfy '-Werror=unused-parameter'.

This is a mostly mechanical refactoring with no intended behavior
change.

Signed-off-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:33:17 -07:00
Christian Couder 63112e71a3 fast-import: factor out option_*() functions
In a following commit we are going to use the parse-options API to
start parsing options. Some options will have to be parsed using
OPT_CALLBACK as they process their arguments in special ways.

When the processing code is already factored out in an option_*()
function, like for `--date-format`, we can reuse that function.
Unfortunately for other options the processing code has not been
factored out yet.

Let's do it now and factor out the code that handles the following
options:

  - `--max-pack-size=<n>`
  - `--big-file-threshold=<n>`
  - `--signed-commits=<mode>`
  - `--signed-tags=<mode>`
  - `--quiet`

into new option_*() functions:

  - option_max_pack_size()
  - option_big_file_threshold()
  - option_signed_commits()
  - option_signed_tags()
  - option_quiet()

so that we can reuse these functions in following commits when the
parse-option API will be used.

Note that there are some behavior changes as we now die() with a
proper error message when git_parse_ulong() cannot parse the argument
from --max-pack-size or from --big-file-threshold. Previously we would
end up calling die("unknown option") instead.

Signed-off-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:33:17 -07:00
Christian Couder a895a37c1b fast-import: use int for some bool flags
The `show_stats` and `quiet` flags are meant to be parsed and used as
boolean flags.

To easily parse them using OPT_BOOL in a following commit, let's change
their type from 'unsigned int' to just 'int'.

Signed-off-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:33:17 -07:00
Christian Couder 62c1a58eeb fast-import: localize 'i' into the 'for' loops using it
In cmd_fast_import(), a	local variable 'i' is defined as an
`unsigned int` and then used as a loop counter in four different
`for (i = ...; i < ...; i++) { ... }` loops.

But in three out of the four cases, `unsigned int` isn't the best type
to use.

To give each loop counter the type matching its bound
(int/unsigned/size_t), let's localize 'i' into each loop that uses it.

Signed-off-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:33:16 -07:00
Pablo Sabater 245f2a8b2e cat-file: unify default format
%(objecttype) is supported both by the client and by the server.
Change the temporary default format to the unified version that the
other commands use.

Update documentation to remove %(objecttype) from the caveats of
remote-object-info and show %(objecttype) support.

Now that type is supported and the default format unified, update the
tests to expect the new default format.

Mentored-by: Karthik Nayak <karthik.188@gmail.com>
Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-07 18:50:08 -07:00
Pablo Sabater afa4ea56fe fetch-object-info: parse type from server response
The server can handle type requests but does not advertise the
capability yet. Prepare the client to know how to parse the server
response once the server advertises the type capability.

Mentored-by: Karthik Nayak <karthik.188@gmail.com>
Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-07 18:50:08 -07:00
Jeff King 567e62b1b9 transport: drop remote object-info fields from transport struct
A remote object-info request needs three things: the transport for
contacting the remote, the list of oids to request, and a place to store
the output.

Rather than take these as function parameters, we take only the
transport object, and expect the caller to have placed the other two
into special fields in the transport struct. But this doesn't make much
sense. The set of oids and results are really only valid for one
request. There is no reason the transport would need to hang on to them
outside of the single function call.

Even though we save a few lines passing the parameters around through
the various vtable functions, the result is harder to understand (for
example, who is responsible for cleaning up results, and when should it
happen?). It also opens up the possibility of a subtle bug. A caller is
likely to point those fields to stack variables which could go out of
scope, and the transport struct would be left holding invalid pointers.

This is mostly harmless now, as we disconnect the transport immediately
after the sole caller of transport_fetch_object_info(). But conceptually
we could keep the transport open and make multiple fetch calls (and
reuse the same connection to the helper, to a remote HTTP server, and so
on).

So let's pull these out of the struct and pass them as function
parameters. It's a little more verbose, but I think more clearly
illustrates the intent. I've also tweaked a few function signatures to
mark the input oid array as const, since it is purely an input to the
function.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-07 18:50:08 -07:00
Pablo Sabater c5c971d967 fetch-object-info: use dedicated struct for the results
fetch_object_info() collects information about N objects, but it stores
the results in an array of object_info. That struct holds the extended
parameters of read_object_info() (The optional outputs the caller wants
filled). Its pointers tell that function where to write the answers for
a single object. object_info is not meant to be the final storage, and
since fetch_object_info() does not call read_object_info(), there is no
reason to use it. Using it means allocating one scalar per object per
attribute just to have those pointers somewhere to point at.

Add struct fetch_object_info_results. The caller sets the wants_* flags
to say what it is interested in, and fetch_object_info() allocates one
array per attribute. A set wants_* flag means "asked for", while a
non-NULL array means "available". The caller releases the arrays with
free_fetch_object_info_results().

The object_info_options string list is no longer needed. Filtering
against the server's advertisement now sets local ask_* flags, and
send_object_info_request() turns those into the v2 protocol option
strings. remote_atom_map[] existed only to map those strings back into
atom names, so drop it and build remote_allowed_atoms from the result
arrays.

Currently for wants_* and ask_* there is only the 'size' variant but a
subsequent commit will add '*_type'.

free_object_info_contents() loses its only caller and is dropped.

Dropping the allow-list check makes the final else reachable from the
wire, so die() instead of BUG(): an unknown attribute is the server's
error, not ours.

Helped-by: Jeff King <peff@peff.net>
Helped-by: Junio C Hamano <gitster@pobox.com>
Mentored-by: Karthik Nayak <karthik.188@gmail.com>
Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-07 18:50:08 -07:00
Junio C Hamano aa2932aedd Merge branch 'tc/merge-default-to-upstream-leakfix'
A memory leak in 'git merge' when run without arguments (which
triggers the default-to-upstream path) has been fixed.  A test has
been added to cover this case.

* tc/merge-default-to-upstream-leakfix:
  merge: fix leak with merge.defaultToUpstream
2026-08-07 14:48:01 -07:00
Junio C Hamano 93a85701ab Merge branch 'jk/cat-file-batch-wo-type-fix'
'git cat-file --batch-command' that asked for 'contents' without
'type' segfaults, which has been corrected.

* jk/cat-file-batch-wo-type-fix:
  cat-file: handle content request for --batch-command without type
2026-08-07 14:48:00 -07:00
Patrick Steinhardt 5bd4f43456 fast-import: use writev(3p) to send cat-blob responses
When answering a `cat-blob` command, `cat_blob()` issues three separate
calls to write(3p) on the cat-blob fd: one for the header line, one for
the full blob payload, and one for the trailing newline. Frontends like
git-filter-repo issue these commands in bulk, once per rewritten blob,
so the syscall overhead adds up.

Use `writev_in_full()` to send all three parts with a single syscall.

This can be benchmarked with the following setup:

    $ git cat-file --unordered --filter=object:type=blob
        --batch-check='cat-blob %(objectname)' --batch-all-objects >request
    $ git fast-import --cat-blob-fd=3 <request

Executing this with 100,000 objects in linux.git:

  Benchmark 1: HEAD~
    Time (mean ± σ):      1.320 s ±  0.003 s    [User: 1.154 s, System: 0.161 s]
    Range (min … max):    1.314 s …  1.324 s    10 runs

  Benchmark 2: HEAD
    Time (mean ± σ):      1.270 s ±  0.022 s    [User: 1.133 s, System: 0.132 s]
    Range (min … max):    1.209 s …  1.282 s    10 runs

  Summary
    HEAD ran
      1.04 ± 0.02 times faster than HEAD~

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-07 08:57:26 -07:00
Junio C Hamano 67b1d2fa43 Merge branch 'rs/branch-delete-bisect-warning'
'git branch -d' has been taught to report when a branch cannot be
deleted because it is being used in an active bisect run.

* rs/branch-delete-bisect-warning:
  branch: report active bisect run when rejecting delete
2026-08-05 11:10:51 -07:00
Junio C Hamano 82c48eae1f Merge branch 'ps/odb-pluggable-housekeeping'
Object database housekeeping in 'git gc' and 'git maintenance' has
been refactored to be pluggable.  The files-backend-specific logic,
including incremental and geometric repacking as well as object
pruning, has been moved out of the command implementation and into the
files object database source, enabling future alternative object
database backends to implement their own housekeeping services.

* ps/odb-pluggable-housekeeping:
  odb: make optimizations pluggable
  builtin/gc: fix signedness issues in ODB-related functionality
  builtin/gc: refactor ODB optimizations to operate on "files" source
  builtin/gc: introduce `odb_optimize_required()`
  builtin/gc: move geometric repacking into `odb_optimize()`
  builtin/gc: introduce object database optimization options
  builtin/gc: inline config values specific to the "files" backend
  builtin/gc: make repack arguments self-contained
  builtin/gc: extract object database optimizations into separate function
  builtin/gc: move worktree and rerere tasks before object optimizations
  odb: run "pre-auto-gc" hook for all maintenance tasks
  t7900: simplify how we check for maintenance tasks
2026-08-05 11:10:51 -07:00
Harald Nordgren 25285a6763 branch: add --dry-run for --delete-merged
"git branch --dry-run --delete-merged ..." prints one line per ref that
would be deleted without modifying refs or branch configuration.

--dry-run is only meaningful together with --delete-merged and is
rejected otherwise.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-05 10:08:28 -07:00
Harald Nordgren 3d1f0df6e4 branch: add branch.<name>.deleteMerged opt-out
Setting branch.<name>.deleteMerged=false exempts that branch from
"git branch --delete-merged", which is useful for a topic you want
to keep developing after an early round of it has been merged
upstream. Unless --quiet is given, each skip is reported so the
user knows why their topic was kept.

Explicit deletion with "git branch -d" still uses the normal merge
check and ignores this setting.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-05 10:08:28 -07:00
Harald Nordgren 15bcdf43bb branch: add --delete-merged <pattern>
git branch (--delete-merged <pattern>)... [<branch-pattern>...]

deletes local branches matching the optional branch patterns when their
configured upstream matches one of the --delete-merged arguments and
their tip is reachable from that upstream. The work has already landed
on the upstream they track, so the local copy is no longer needed.

Each <pattern> may name a ref, a remote, or a shell glob. The option can
be repeated to widen the upstream match. Keeping the candidate patterns
as positional arguments lets users bound the set of local branches that
may be deleted independently of the upstream selection.

A branch is not deleted when:

  * it is checked out in any worktree
  * its configured upstream ref no longer exists, since a missing
    upstream is not by itself a sign of integration
  * pushing it to the remote configured by branch.<name>.remote would
    update its upstream, as determined by that remote's configured push
    and fetch refspecs. For example, a local "main" that tracks
    "origin/main" is kept even when remote.pushDefault names a fork.
    Right after a pull it merely looks fully merged.
  * it is the local upstream of a branch that is not being deleted, so
    no branch is deleted out from under stacked work.

A branch whose work is not yet merged into its upstream is silently
skipped, so one unmerged topic does not abort the whole sweep.

Collect protected local upstreams without changing the candidate set
during ref iteration, then remove them after iteration. This makes the
result independent of ref iteration order. If a protected branch's own
upstream is deleted by the same sweep, clear its upstream configuration.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-05 10:08:28 -07:00
Harald Nordgren 5e528a36d2 branch: prepare delete_branches for a bulk caller
Teach delete_branches() a new mode for the upcoming --delete-merged
caller that checks whether a branch is merged into its upstream without
falling back to HEAD when there is no upstream. Existing callers keep
their current behavior.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-05 10:08:27 -07:00
Harald Nordgren cdbcde91be branch: let delete_branches skip unmerged branches on bulk refusal
Add a skip-unmerged mode to delete_branches() and check_branch_commit()
so a bulk caller can silently skip branches that are not fully merged
and carry on, rather than erroring with the "use 'git branch -D'"
advice that the plain "git branch -d" path emits. Existing callers are
unaffected.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-05 10:08:27 -07:00
Harald Nordgren 7969faaf9b branch: convert delete_branches() to a flags argument
delete_branches() takes separate force and quiet parameters, while
check_branch_commit() takes force. The next commits would grow this
collection further. Replace them with a single unsigned flags argument
and an enum.

Test the FORCE and QUIET bits directly from flags at each use site so
that mutating or forwarding flags cannot leave cached values stale.

No change in behavior.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-05 10:08:27 -07:00
Harald Nordgren 876029beca branch: add --forked filter for --list mode
Add a --forked option to "git branch" list mode that lists only
branches whose configured upstream matches <branch>. The argument
can be a ref (e.g. "origin/main", "master"), a remote name like
"origin" for the branch its origin/HEAD points at, or a shell glob
(e.g. "origin/*"), and may be repeated to widen the filter.

It is an ordinary list filter, so it combines with the others:

    git branch --merged origin/main --forked 'origin/*'

lists branches forked from origin that are already merged into
origin/main, and --no-merged inverts the question.

This is the building block for --delete-merged, which deletes the
listed branches once they have landed on their upstream.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-05 10:08:27 -07:00
Patrick Steinhardt ebdd7e10d6 odb/streaming: unify function names to create new streams
Unify the function names to create new streams from different sources so
that they follow a common schema. While at it, document the ownership of
the file descriptor passed to `odb_stream_from_fd()`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-05 09:42:50 -07:00
Patrick Steinhardt 3f8290ea85 odb/streaming: rename `struct input_zstream_data`
With the preceding refactorings the `struct input_zstream_data` is now
somewhat misnamed, as it doesn't only contain the data anymore, but also
the stream itself. Rename the structure to `struct zlib_stream` to
better match the new structure.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-05 09:42:50 -07:00
Patrick Steinhardt e837b812fe odb/streaming: consolidate read and write streams
The `struct odb_read_stream` and `struct odb_write_stream` both provide
the same functionality: they allow a caller to read object data from an
arbitrary source. Historically, the only difference was that the read
stream was used to read data out of the object database, whereas the
write stream was used to write data into the object database, but the
interfaces were mostly the same.

Over the preceding commits we have refactored the write stream to have
almost exactly the same interface as the read stream. With these
refactorings we can now easily merge those two streams into a single
interface that's used for both use cases.

While most of the changes are mechanical, there are two sites that need
special mention:

  - "builtin/unpack-objects.c" creates a write stream from compressed
    object data.

  - "odb/streaming.c" creates a write stream from a file descriptor.

Adapting these sites to yield the new stream type requires a couple more
changes. Most importantly, instead of embedding the pointer to the data
in `struct odb_write_stream`, we now allocate a structure that wraps the
new `struct odb_stream` base. Other than that though, the changes are
rather straight forward.

Some of the structures and functions are now somewhat misnamed. These
will be fixed in subsequent commits.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-05 09:42:50 -07:00
Patrick Steinhardt a59e4798f0 odb/streaming: rename `struct odb_read_stream`
Rename `struct odb_read_stream` to just `struct odb_stream`. This
prepares for unification of the two different types of streams, as these
provide the same functionality with the preceding refactorings.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-05 09:42:50 -07:00
Patrick Steinhardt 8a51f6e8c5 odb/streaming: support streaming arbitrary object types
The object database supports the ability to write object streams into
it. This functionality is used when we encounter a blob that is larger
than "core.bigFileThreshold" so that we don't have to soak large files
into memory.

As we only ever write large files, the infrastructure doesn't support
specifying any other object type than "blob". This limitation is quite
artificial though: there is no reason why we shouldn't support writing
arbitrary large objects with a stream. While it's very unlikely that we
encounter a huge object other than a blob, users are known to be
creative and sometimes like to inflict pain on themselves by creating
commits or trees that are huge.

Extend the infrastructure to support streaming arbitrary object types.
For now we don't use this functionality anywhere, but it brings us a bit
closer to unify `struct odb_read_stream` and `struct odb_write_stream`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-05 09:42:50 -07:00
Patrick Steinhardt 7267822542 odb/streaming: drop `is_finished` field
The `is_finished` field is used to track whether a write stream is done
writing all of its data. Tracking this field as part of the stream
itself shouldn't be required though: callers will already know when the
stream is done when the stream's read function returns zero bytes, same
as when reading from a file descriptor.

There is one exception where it gets a bit more complicated: when
consuming data in "builtin/unpack-objects.c" it may happen that we don't
yield any new bytes after reading from the pipe. This is addressed by
looping until we have produced at least a single byte of output.

Drop the field from `struct odb_write_stream`. Again, same as in the
preceding commit, this brings the structure a bit closer to its sibling
`struct odb_read_stream`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-05 09:42:50 -07:00
Patrick Steinhardt b1b008fa2b odb/streaming: track write stream size in the structure
When passing around a `struct odb_write_stream` we typically also have
to pass the number of bytes that the stream will yield. This is required
because the object header itself contains that size, and consequently we
cannot write the header without that information.

Move this information into the stream itself so that it becomes self-
describing. In addition to that, this also brings the `struct
odb_write_stream` a bit closer to the `struct odb_read_stream` so that
we can eventually merge both stream types.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-05 09:42:49 -07:00
Junio C Hamano ffdf498492 Merge branch 'af/clone-revision-v0-segfault-fix'
A segfault when 'git clone --revision' talks to a server that does not
support protocol v2 (falling back to protocol v0) has been corrected.

* af/clone-revision-v0-segfault-fix:
  builtin/clone: fix segfault when using --revision with protocol v0
2026-08-03 09:31:29 -07:00
Harald Nordgren f70281521a bisect: add --reset-when-found to leave when done
When a bisection finishes, "git bisect" reports the first bad commit
but leaves the session active until "git bisect reset" is run by hand.

Add a "--reset-when-found[=<where>]" option, accepted by both "git
bisect start" and "git bisect run", that resets as soon as the first
bad commit is found. The "original" value returns to the commit checked
out before "git bisect start", while "found" leaves the first bad commit
checked out; omitting the value defaults to "original".

Persist the selected target in a BISECT_RESET_WHEN_FOUND state file
and perform the reset quietly.

Let the internal first-bad result propagate to cmd_bisect(), which
performs the reset using the existing bad bisect ref after the
subcommand has returned. For "git bisect run", this means BISECT_RUN
has been printed and closed before cleanup, which also works on systems
that cannot unlink an open file.

Reject this option together with "--no-checkout", since that mode must
not check out either target.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-02 16:34:36 -07:00
Harald Nordgren 2e59acb77d bisect: let bisect_reset() optionally check out quietly
Add a "quiet" parameter to bisect_reset() that passes "--quiet" to the
checkout restoring the original HEAD, suppressing its progress and
branch-status output.

No caller sets the flag yet, so behavior is unchanged.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-02 16:34:36 -07:00
Junio C Hamano 94cf62176e add: introduce '--resolved' option
During a conflicted merge, rebase, or cherry-pick, 'git add -u' is a
handy way to add modified paths to the index.  However, '-u'
indiscriminately adds all modified tracked paths, including unmerged
paths that may still contain unresolved conflict markers.  It also
adds tracked files modified in the worktree that are not involved in
the ongoing merge.

The latter is not a huge problem for "git rebase", which refuses to
start with any local changes, but is a problem for "git merge",
which is often run with local changes in maintainer workflows.

Introduce 'git add --resolved' to add only unmerged paths, limited
by an optional pathspec, where no conflict markers remain in the
working tree.

Before modifying the index, scan unmerged regular files for leftover
conflict markers using a new helper, has_conflict_markers(), defined
in merge-ll.c in terms of the is_conflict_marker_line() helper we
introduced earlier.  If any unmerged path still contains conflict
markers, show an error listing the conflicted paths and abort
without updating the index.  Otherwise, add these unmerged paths
that do not have conflict markers to the index.

Note that unmerged paths without conflict markers (such as binary
files and deletions) are added as resolved using add_file_to_index()
and remove_file_from_index_with_flags().  Tracked files that were
not in a conflicted state are ignored by '--resolved'.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-31 08:52:16 -07:00
Junio C Hamano d407e69787 Merge branch 'ps/odb-move-loose-object-writing'
The logic to write loose objects has been refactored and moved from
'object-file.c' to the loose backend source file 'odb/source-loose.c',
making the loose backend more self-contained.  This is achieved by
first refactoring force_object_loose() to use generic ODB write
interfaces instead of loose-backend internals.

* ps/odb-move-loose-object-writing:
  object-file: move logic to write loose objects
  object-file: move `force_object_loose()`
  object-file: force objects loose via generic interface
  object-file: fix memory leak in `force_object_loose()`
  odb: support setting mtime when writing objects
  odb: lift object existence check out of the "loose" backend
  odb: compute object hash in `odb_write_object_ext()`
  t/u-odb-inmemory: implement wrapper for writing objects
  odb: compute compat object ID in `odb_write_object_ext()`
2026-07-30 10:32:05 -07:00
Junio C Hamano e1fb641cfa Merge branch 'ps/cat-file-remote-object-info'
The 'remote-object-info' command has been added to 'git cat-file
--batch-command', allowing clients to request object metadata
(currently size) from a remote server via protocol v2 without
downloading the entire object.  Format placeholders are dynamically
filtered on the client based on server-advertised capabilities,
returning empty strings for inapplicable or unsupported fields.

* ps/cat-file-remote-object-info:
  cat-file: make remote-object-info allow-list adapt to the server
  cat-file: add remote-object-info to batch-command
  transport: add client support for object-info
  serve: advertise object-info feature
  protocol-caps: check object existence regardless of the attributes requested
  fetch-pack: move fetch initialization
  connect: make write_fetch_command_and_capabilities() more generic
  fetch-pack: move write_fetch_command_and_capabilities() to connect.c
  fetch-pack: use unsigned int for hash_algo variable
  fetch-pack: drop the static advertise_sid variable
  t1006: extract helper functions into new 'lib-cat-file.sh'
  cat-file: declare loop counter inside for()
  transport-helper: fix memory leak of helper on disconnect
2026-07-30 10:32:04 -07:00
Junio C Hamano 50f7f93213 Merge branch 'tn/stash-avoid-sparse-index-expansion'
The 'git stash push' command has been optimized to avoid unnecessary
sparse index expansion when pathspecs are wholly inside the
sparse-checkout cone.  Also, a potential out-of-bounds read in the
sparse-index expansion check helper pathspec_needs_expanded_index()
has been fixed by consistently using the parsed, prefixed path.

* tn/stash-avoid-sparse-index-expansion:
  stash: avoid sparse-index expansion for in-cone paths
  pathspec: use match for sparse-index expansion checks
2026-07-30 10:32:03 -07:00
Junio C Hamano fc1e7582e6 Merge branch 'ty/migrate-excludes-file'
The 'excludes_file' and various other global configuration variables
(including 'editor_program', 'pager_program', 'askpass_program', and
'push_default') have been migrated into the per-repository structure.

* ty/migrate-excludes-file:
  repository: adjust the comment of config_values_private_
  environment: move object_creation_mode into repo_config_values
  environment: move autorebase into repo_config_values
  environment: move push_default into repo_config_values
  environment: migrate apply_default_whitespace and apply_default_ignorewhitespace
  environment: move askpass_program into repo_config_values
  environment: move pager_program into repo_config_values
  environment: move editor_program into repo_config_values
  environment: move excludes_file into repo_config_values
  repository: introduce repo_config_values_clear()
2026-07-30 10:32:03 -07:00
Junio C Hamano 48d45c7a41 Merge branch 'ty/migrate-trust-executable-bit'
The 'trust_executable_bit' (coming from the 'core.filemode'
configuration) has been migrated into 'struct repo_config_values' to
tie it to a specific repository instance.

* ty/migrate-trust-executable-bit:
  environment: move has_symlinks into repo_config_values
  environment: move trust_executable_bit into repo_config_values
  read-cache: pass 'repo' to 'ce_mode_from_stat()'
  read-cache: remove redundant extern declarations
2026-07-30 10:32:02 -07:00
Junio C Hamano 818eb57007 Merge branch 'rs/tempfile-wo-the-repository'
The tempfile and lockfile APIs have been refactored to stop depending
on the 'the_repository' global variable, and their callers have been
updated to use the repository-aware variants.

* rs/tempfile-wo-the-repository:
  use repo_hold_lock_file_for_update{,_mode,_timeout}() with custom repos
  tempfile: stop using the_repository
  lockfile: add repo_hold_lock_file_for_update{,_timeout}{,_mode}()
  refs/packed: use repo_create_tempfile()
  tempfile: add repo_create_tempfile{,_mode}()
2026-07-30 10:32:02 -07:00