Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
81cf6cc
line-log: fix crash when combined with pickaxe options
mmontalbo Mar 17, 2026
86e986f
line-log: route -L output through the standard diff pipeline
mmontalbo Mar 17, 2026
0e51f7a
t4211: add tests for -L with standard diff options
mmontalbo Mar 17, 2026
512536a
doc: note that -L supports patch formatting and pickaxe options
mmontalbo Mar 17, 2026
3cfe355
add-patch: use repository instance from add_i_state instead of the_re…
shreyp135 Mar 17, 2026
afdb4c6
apply: fix new-style empty context line triggering incomplete-line check
gitster Mar 17, 2026
753ecf4
path-walk: fix NULL pointer dereference in error message
ysinghc Mar 20, 2026
17cabd3
fetch-pack: move fsck options into function scope
pks-t Mar 23, 2026
f223609
fsck: initialize fsck options via a function
pks-t Mar 23, 2026
3749853
fsck: store repository in fsck options
pks-t Mar 23, 2026
fe5f16e
fsck: drop USE_THE_REPOSITORY
pks-t Mar 23, 2026
da3ead3
builtin/fsck: fix trivial dependence on `the_repository`
pks-t Mar 23, 2026
4c44db7
builtin/fsck: stop using `the_repository` when snapshotting refs
pks-t Mar 23, 2026
3ea7794
builtin/fsck: stop using `the_repository` when checking refs
pks-t Mar 23, 2026
38e09eb
builtin/fsck: stop using `the_repository` when checking reflogs
pks-t Mar 23, 2026
2b2287c
builtin/fsck: stop using `the_repository` with loose objects
pks-t Mar 23, 2026
1c5f77b
builtin/fsck: stop using `the_repository` when checking packed objects
pks-t Mar 23, 2026
cc050f0
builtin/fsck: stop using `the_repository` when marking objects
pks-t Mar 23, 2026
6fea405
builtin/fsck: stop using `the_repository` in error reporting
pks-t Mar 23, 2026
04c9c5e
commit-graph: fix writing generations with dates exceeding 34 bits
pks-t Mar 24, 2026
6d35cc4
fast-export: check for unsupported signing modes earlier
jltobler Mar 26, 2026
4c36345
fast-import: add 'abort-if-invalid' mode to '--signed-commits=<mode>'
jltobler Mar 26, 2026
817b042
fast-import: add 'strip-if-invalid' mode to '--signed-tags=<mode>'
jltobler Mar 26, 2026
2b1546c
fast-import: add 'sign-if-invalid' mode to '--signed-tags=<mode>'
jltobler Mar 26, 2026
ddd7c7a
fast-import: add 'abort-if-invalid' mode to '--signed-tags=<mode>'
jltobler Mar 26, 2026
80871f3
t5516: test updateInstead with worktree and unborn bare HEAD
runxiyu Mar 30, 2026
b310755
t5516: clean up cloned and new-wt in denyCurrentBranch and worktrees …
pabloosabaterr Mar 30, 2026
8151f4f
receive-pack: use worktree HEAD for updateInstead
pabloosabaterr Mar 30, 2026
a7aca15
read-cache: use istate->repo for trace2 logging
jayesh0104 Mar 30, 2026
339eba6
backfill: auto-detect sparse-checkout from config
trieu1162000 Apr 4, 2026
26b9946
history: fix short help for argument of --update-refs
rscharfe Apr 6, 2026
716b9db
Merge branch 'jd/read-cache-trace-wo-the-repository'
gitster Apr 7, 2026
d88c8ba
Merge branch 'ps/commit-graph-overflow-fix'
gitster Apr 7, 2026
55d867c
Merge branch 'jc/whitespace-incomplete-line'
gitster Apr 7, 2026
59063fe
Merge branch 'yc/path-walk-fix-error-reporting'
gitster Apr 7, 2026
7b6d0cd
Merge branch 'ps/fsck-wo-the-repository'
gitster Apr 7, 2026
fb55169
Merge branch 'sp/add-patch-with-fewer-the-repository'
gitster Apr 7, 2026
1678b7d
Merge branch 'mm/line-log-use-standard-diff-output'
gitster Apr 7, 2026
f1edda9
Merge branch 'jt/fast-import-signed-modes'
gitster Apr 7, 2026
b66c97c
Merge branch 'ps/receive-pack-updateinstead-in-worktree'
gitster Apr 7, 2026
f1743ad
Merge branch 'th/backfill-auto-detect-sparseness-fix'
gitster Apr 7, 2026
6c9fbf4
Merge branch 'rs/history-short-help-fix'
gitster Apr 7, 2026
7c4e9e9
A bit more before -rc1
gitster Apr 7, 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
31 changes: 31 additions & 0 deletions Documentation/RelNotes/2.54.0.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ UI, Workflows & Features

* git replay now supports replaying down to the root commit.

* Handling of signed commits and tags in fast-import has been made more
configurable.


Performance, Internal Implementation, Development Support etc.
--------------------------------------------------------------
Expand Down Expand Up @@ -300,6 +303,19 @@ Performance, Internal Implementation, Development Support etc.
that discarded constness when they return a pointer into a const
string to preserve constness.

* A handful of inappropriate uses of the_repository have been
rewritten to use the right repository structure instance in the
read-cache.c codepath.

* Internals of "git fsck" have been refactored to not depend on the
global `the_repository` variable.

* Reduce dependency on `the_repository` in add-patch.c file.

* The way the "git log -L<range>:<file>" feature is bolted onto the
log/diff machinery is being reworked a bit to make the feature
compatible with more diff options, like -S/G.


Fixes since v2.53
-----------------
Expand Down Expand Up @@ -478,6 +494,21 @@ Fixes since v2.53
refspec is a single-object refspec, which has been corrected.
(merge 4e5dc601dd kj/refspec-parsing-outside-repository later to maint).

* Fix a regression in writing the commit-graph where commits with dates
exceeding 34 bits (beyond year 2514) could cause an underflow and
crash Git during the generation data overflow chunk writing.

* The value of a wrong pointer variable was referenced in an error
message that reported that it shouldn't be NULL.
(merge 753ecf4205 yc/path-walk-fix-error-reporting later to maint).

* The check in "receive-pack" to prevent a checked out branch from
getting updated via updateInstead mechanism has been corrected.

* "git backfill" is capable of auto-detecting a sparsely checked out
working tree, which was broken.
(merge 339eba65a7 th/backfill-auto-detect-sparseness-fix later to maint).

* Other code cleanup, docfix, build fix, etc.
(merge d79fff4a11 jk/remote-tracking-ref-leakfix later to maint).
(merge 7a747f972d dd/t5403-modernise later to maint).
Expand Down
9 changes: 5 additions & 4 deletions Documentation/git-fast-import.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,10 @@ fast-import stream! This option is enabled automatically for
remote-helpers that use the `import` capability, as they are
already trusted to run their own code.

`--signed-tags=(verbatim|warn-verbatim|warn-strip|strip|abort)`::
`--signed-tags=<mode>`::
Specify how to handle signed tags. Behaves in the same way as
the `--signed-commits=<mode>` below, except that the
`strip-if-invalid` mode is not yet supported. Like for signed
commits, the default mode is `verbatim`.
the `--signed-commits=<mode>` below. Like for signed commits,
the default mode is `verbatim`.

`--signed-commits=<mode>`::
Specify how to handle signed commits. The following <mode>s
Expand All @@ -90,6 +89,8 @@ already trusted to run their own code.
commit signatures and replaces invalid signatures with newly created ones.
Valid signatures are left unchanged. If `<keyid>` is provided, that key is
used for signing; otherwise the configured default signing key is used.
* `abort-if-invalid` will make this program die when encountering a signed
commit that is unable to be verified.

Options for Frontends
~~~~~~~~~~~~~~~~~~~~~
Expand Down
4 changes: 4 additions & 0 deletions Documentation/line-range-options.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@
(namely `--raw`, `--numstat`, `--shortstat`, `--dirstat`, `--summary`,
`--name-only`, `--name-status`, `--check`) are not currently implemented.
+
Patch formatting options such as `--word-diff`, `--color-moved`,
`--no-prefix`, and whitespace options (`-w`, `-b`) are supported,
as are pickaxe options (`-S`, `-G`).
+
include::line-range-format.adoc[]
8 changes: 4 additions & 4 deletions add-patch.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,8 +558,8 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
strvec_push(&args,
/* could be on an unborn branch */
!strcmp("HEAD", s->revision) &&
repo_get_oid(the_repository, "HEAD", &oid) ?
empty_tree_oid_hex(the_repository->hash_algo) : s->revision);
repo_get_oid(s->r, "HEAD", &oid) ?
empty_tree_oid_hex(s->r->hash_algo) : s->revision);
}
color_arg_index = args.nr;
/* Use `--no-color` explicitly, just in case `diff.color = always`. */
Expand Down Expand Up @@ -1271,7 +1271,7 @@ static int edit_hunk_manually(struct add_p_state *s, struct hunk *hunk)
"removed, then the edit is\n"
"aborted and the hunk is left unchanged.\n"));

if (strbuf_edit_interactively(the_repository, &s->buf,
if (strbuf_edit_interactively(s->r, &s->buf,
"addp-hunk-edit.diff", NULL) < 0)
return -1;

Expand Down Expand Up @@ -1679,7 +1679,7 @@ static size_t patch_update_file(struct add_p_state *s,
if (file_diff->hunk_nr) {
if (rendered_hunk_index != hunk_index) {
if (use_pager) {
setup_pager(the_repository);
setup_pager(s->r);
sigchain_push(SIGPIPE, SIG_IGN);
}
render_hunk(s, hunk, 0, colored, &s->buf);
Expand Down
12 changes: 10 additions & 2 deletions apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -1840,8 +1840,16 @@ static int parse_fragment(struct apply_state *state,
trailing++;
check_old_for_crlf(patch, line, len);
if (!state->apply_in_reverse &&
state->ws_error_action == correct_ws_error)
check_whitespace(state, line, len, patch->ws_rule);
state->ws_error_action == correct_ws_error) {
const char *test_line = line;
int test_len = len;
if (*line == '\n') {
test_line = " \n";
test_len = 2;
}
check_whitespace(state, test_line, test_len,
patch->ws_rule);
}
break;
case '-':
if (!state->apply_in_reverse)
Expand Down
2 changes: 1 addition & 1 deletion builtin/backfill.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ int cmd_backfill(int argc, const char **argv, const char *prefix, struct reposit
.repo = repo,
.current_batch = OID_ARRAY_INIT,
.min_batch_size = 50000,
.sparse = 0,
.sparse = -1,
.revs = REV_INFO_INIT,
};
struct option options[] = {
Expand Down
15 changes: 2 additions & 13 deletions builtin/fast-export.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ static int parse_opt_sign_mode(const struct option *opt,
if (unset)
return 0;

if (parse_sign_mode(arg, val, NULL))
if (parse_sign_mode(arg, val, NULL) || (*val == SIGN_STRIP_IF_INVALID) ||
(*val == SIGN_SIGN_IF_INVALID) || (*val == SIGN_ABORT_IF_INVALID))
return error(_("unknown %s mode: %s"), opt->long_name, arg);

return 0;
Expand Down Expand Up @@ -822,12 +823,6 @@ static void handle_commit(struct commit *commit, struct rev_info *rev,
die(_("encountered signed commit %s; use "
"--signed-commits=<mode> to handle it"),
oid_to_hex(&commit->object.oid));
case SIGN_STRIP_IF_INVALID:
die(_("'strip-if-invalid' is not a valid mode for "
"git fast-export with --signed-commits=<mode>"));
case SIGN_SIGN_IF_INVALID:
die(_("'sign-if-invalid' is not a valid mode for "
"git fast-export with --signed-commits=<mode>"));
default:
BUG("invalid signed_commit_mode value %d", signed_commit_mode);
}
Expand Down Expand Up @@ -970,12 +965,6 @@ static void handle_tag(const char *name, struct tag *tag)
die(_("encountered signed tag %s; use "
"--signed-tags=<mode> to handle it"),
oid_to_hex(&tag->object.oid));
case SIGN_STRIP_IF_INVALID:
die(_("'strip-if-invalid' is not a valid mode for "
"git fast-export with --signed-tags=<mode>"));
case SIGN_SIGN_IF_INVALID:
die(_("'sign-if-invalid' is not a valid mode for "
"git fast-export with --signed-tags=<mode>"));
default:
BUG("invalid signed_commit_mode value %d", signed_commit_mode);
}
Expand Down
71 changes: 60 additions & 11 deletions builtin/fast-import.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ static const char *global_prefix;
static enum sign_mode signed_tag_mode = SIGN_VERBATIM;
static enum sign_mode signed_commit_mode = SIGN_VERBATIM;
static const char *signed_commit_keyid;
static const char *signed_tag_keyid;

/* Memory pools */
static struct mem_pool fi_mem_pool = {
Expand Down Expand Up @@ -2892,6 +2893,9 @@ static void handle_signature_if_invalid(struct strbuf *new_data,
ret = verify_commit_buffer(tmp_buf.buf, tmp_buf.len, &signature_check);

if (ret) {
if (mode == SIGN_ABORT_IF_INVALID)
die(_("aborting due to invalid signature"));

warn_invalid_signature(&signature_check, msg->buf, mode);

if (mode == SIGN_SIGN_IF_INVALID) {
Expand Down Expand Up @@ -2983,6 +2987,7 @@ static void parse_new_commit(const char *arg)
case SIGN_VERBATIM:
case SIGN_STRIP_IF_INVALID:
case SIGN_SIGN_IF_INVALID:
case SIGN_ABORT_IF_INVALID:
import_one_signature(&sig_sha1, &sig_sha256, v);
break;

Expand Down Expand Up @@ -3068,7 +3073,8 @@ static void parse_new_commit(const char *arg)
encoding);

if ((signed_commit_mode == SIGN_STRIP_IF_INVALID ||
signed_commit_mode == SIGN_SIGN_IF_INVALID) &&
signed_commit_mode == SIGN_SIGN_IF_INVALID ||
signed_commit_mode == SIGN_ABORT_IF_INVALID) &&
(sig_sha1.hash_algo || sig_sha256.hash_algo))
handle_signature_if_invalid(&new_data, &sig_sha1, &sig_sha256,
&msg, signed_commit_mode);
Expand All @@ -3084,7 +3090,50 @@ static void parse_new_commit(const char *arg)
b->last_commit = object_count_by_type[OBJ_COMMIT];
}

static void handle_tag_signature(struct strbuf *msg, const char *name)
static void handle_tag_signature_if_invalid(struct strbuf *buf,
struct strbuf *msg,
size_t sig_offset)
{
struct strbuf signature = STRBUF_INIT;
struct strbuf payload = STRBUF_INIT;
struct signature_check sigc = { 0 };

strbuf_addbuf(&payload, buf);
strbuf_addch(&payload, '\n');
strbuf_add(&payload, msg->buf, sig_offset);
strbuf_add(&signature, msg->buf + sig_offset, msg->len - sig_offset);

sigc.payload_type = SIGNATURE_PAYLOAD_TAG;
sigc.payload = strbuf_detach(&payload, &sigc.payload_len);

if (!check_signature(&sigc, signature.buf, signature.len))
goto out;

if (signed_tag_mode == SIGN_ABORT_IF_INVALID)
die(_("aborting due to invalid signature"));

strbuf_setlen(msg, sig_offset);

if (signed_tag_mode == SIGN_SIGN_IF_INVALID) {
strbuf_attach(&payload, sigc.payload, sigc.payload_len,
sigc.payload_len + 1);
sigc.payload = NULL;
strbuf_reset(&signature);

if (sign_buffer(&payload, &signature, signed_tag_keyid,
SIGN_BUFFER_USE_DEFAULT_KEY))
die(_("failed to sign tag object"));

strbuf_addbuf(msg, &signature);
}

out:
signature_check_clear(&sigc);
strbuf_release(&signature);
strbuf_release(&payload);
}

static void handle_tag_signature(struct strbuf *buf, struct strbuf *msg, const char *name)
{
size_t sig_offset = parse_signed_buffer(msg->buf, msg->len);

Expand All @@ -3110,17 +3159,16 @@ static void handle_tag_signature(struct strbuf *msg, const char *name)
/* Truncate the buffer to remove the signature */
strbuf_setlen(msg, sig_offset);
break;
case SIGN_ABORT_IF_INVALID:
case SIGN_SIGN_IF_INVALID:
case SIGN_STRIP_IF_INVALID:
handle_tag_signature_if_invalid(buf, msg, sig_offset);
break;

/* Third, aborting modes */
case SIGN_ABORT:
die(_("encountered signed tag; use "
"--signed-tags=<mode> to handle it"));
case SIGN_STRIP_IF_INVALID:
die(_("'strip-if-invalid' is not a valid mode for "
"git fast-import with --signed-tags=<mode>"));
case SIGN_SIGN_IF_INVALID:
die(_("'sign-if-invalid' is not a valid mode for "
"git fast-import with --signed-tags=<mode>"));
default:
BUG("invalid signed_tag_mode value %d from tag '%s'",
signed_tag_mode, name);
Expand Down Expand Up @@ -3190,8 +3238,6 @@ static void parse_new_tag(const char *arg)
/* tag payload/message */
parse_data(&msg, 0, NULL);

handle_tag_signature(&msg, t->name);

/* build the tag object */
strbuf_reset(&new_data);

Expand All @@ -3203,6 +3249,9 @@ static void parse_new_tag(const char *arg)
if (tagger)
strbuf_addf(&new_data,
"tagger %s\n", tagger);

handle_tag_signature(&new_data, &msg, t->name);

strbuf_addch(&new_data, '\n');
strbuf_addbuf(&new_data, &msg);
free(tagger);
Expand Down Expand Up @@ -3713,7 +3762,7 @@ static int parse_one_option(const char *option)
if (parse_sign_mode(option, &signed_commit_mode, &signed_commit_keyid))
usagef(_("unknown --signed-commits mode '%s'"), option);
} else if (skip_prefix(option, "signed-tags=", &option)) {
if (parse_sign_mode(option, &signed_tag_mode, NULL))
if (parse_sign_mode(option, &signed_tag_mode, &signed_tag_keyid))
usagef(_("unknown --signed-tags mode '%s'"), option);
} else if (!strcmp(option, "quiet")) {
show_stats = 0;
Expand Down
Loading