Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2b9665c
convert: add const to fix strchr() warnings
peff Apr 2, 2026
2fb6a18
http: add const to fix strchr() warnings
peff Apr 2, 2026
eedc7ec
transport-helper: drop const to fix strchr() warnings
peff Apr 2, 2026
031d29d
pager: explicitly cast away strchr() constness
peff Apr 2, 2026
21c57ef
run-command: explicitly cast away constness when assigning to void
peff Apr 2, 2026
bc4fd55
find_last_dir_sep(): convert inline function to macro
peff Apr 2, 2026
25e5ceb
pseudo-merge: fix disk reads from find_pseudo_merge()
peff Apr 2, 2026
cefb8b7
skip_prefix(): check const match between in and out params
peff Apr 2, 2026
d3cd819
pkt-line: make packet_reader.line non-const
peff Apr 2, 2026
c395126
range-diff: drop const to fix strstr() warnings
peff Apr 2, 2026
8a0566b
http: drop const to fix strstr() warning
peff Apr 2, 2026
f1b8a4d
refs/files-backend: drop const to fix strchr() warning
peff Apr 2, 2026
58589c2
git-compat-util: fix CONST_OUTPARAM typo and indentation
peff Apr 4, 2026
5bdb988
doc: replace git config --list/-l with `list`
LemmingAvalanche Apr 5, 2026
57177ad
doc: gitcvs-migration: rephrase “man page”
LemmingAvalanche Apr 5, 2026
295fb82
t6600: test --maximal-only and --independent
derrickstolee Apr 6, 2026
e8e5453
p6011: add perf test for rev-list --maximal-only
derrickstolee Apr 6, 2026
b0ba57d
rev-list: use reduce_heads() for --maximal-only
derrickstolee Apr 6, 2026
3eabc35
Merge branch 'jk/c23-const-preserving-fixes-more'
gitster Apr 9, 2026
8e04162
Merge branch 'kh/doc-config-list'
gitster Apr 9, 2026
c343f9c
Merge branch 'ds/rev-list-maximal-only-optim'
gitster Apr 9, 2026
60f07c4
A bit more for -rc2
gitster Apr 9, 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
11 changes: 11 additions & 0 deletions Documentation/RelNotes/2.54.0.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ UI, Workflows & Features
* Handling of signed commits and tags in fast-import has been made more
configurable.

* "git config list" is the official way to spell "git config -l" and
"git config --list". Use it to update the documentation.


Performance, Internal Implementation, Development Support etc.
--------------------------------------------------------------
Expand Down Expand Up @@ -316,6 +319,14 @@ Performance, Internal Implementation, Development Support etc.
log/diff machinery is being reworked a bit to make the feature
compatible with more diff options, like -S/G.
* Further work to adjust the codebase for C23 that changes functions
like strchr() that discarded constness when they return a pointer into
a const string to preserve constness.
* "git rev-list --maximal-only" has been optimized by borrowing the
logic used by "git show-branch --independent", which computes the
same kind of information much more efficiently.
Fixes since v2.53
-----------------
Expand Down
2 changes: 1 addition & 1 deletion Documentation/git-var.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ OPTIONS
Display the logical variables. In addition, all the
variables of the Git configuration file .git/config are listed
as well. (However, the configuration variables listing functionality
is deprecated in favor of `git config -l`.)
is deprecated in favor of `git config list`.)

EXAMPLES
--------
Expand Down
3 changes: 1 addition & 2 deletions Documentation/gitcvs-migration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ them first before running git pull.
================================
The 'pull' command knows where to get updates from because of certain
configuration variables that were set by the first 'git clone'
command; see `git config -l` and the linkgit:git-config[1] man
page for details.
command; see the subcommand `list` in linkgit:git-config[1] for details.
================================

You can update the shared repository with your changes by first committing
Expand Down
2 changes: 1 addition & 1 deletion Documentation/gitprotocol-v2.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ use by the client, MUST indicate prerequisites (in any) with standard
applicable.
+
The advertised URI may alternatively contain a plaintext file that `git
config --list` would accept (with the `--file` option). The key-value
config list` would accept (with the `--file` option). The key-value
pairs in this list are in the `bundle.*` namespace (see
linkgit:git-config[1]).

Expand Down
2 changes: 1 addition & 1 deletion Documentation/gittutorial.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ bob$ git config --get remote.origin.url
-------------------------------------

(The complete configuration created by `git clone` is visible using
`git config -l`, and the linkgit:git-config[1] man page
`git config list`, and the linkgit:git-config[1] man page
explains the meaning of each option.)

Git also keeps a pristine copy of Alice's `master` branch under the
Expand Down
2 changes: 1 addition & 1 deletion Documentation/technical/api-trace2.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1253,7 +1253,7 @@ it.
$ git config --system color.ui never
$ git config --global color.ui always
$ git config --local color.ui auto
$ git config --list --show-scope | grep 'color.ui'
$ git config list --show-scope | grep 'color.ui'
system color.ui=never
global color.ui=always
local color.ui=auto
Expand Down
2 changes: 1 addition & 1 deletion Documentation/user-manual.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2865,7 +2865,7 @@ stored in Git configuration variables, which you can see using
linkgit:git-config[1]:

-------------------------------------------------
$ git config -l
$ git config list
core.repositoryformatversion=0
core.filemode=true
core.logallrefupdates=true
Expand Down
7 changes: 4 additions & 3 deletions builtin/receive-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -1029,8 +1029,8 @@ static int read_proc_receive_report(struct packet_reader *reader,

for (;;) {
struct object_id old_oid, new_oid;
const char *head;
const char *refname;
char *head;
char *refname;
char *p;
enum packet_read_status status;

Expand All @@ -1054,7 +1054,8 @@ static int read_proc_receive_report(struct packet_reader *reader,
}
*p++ = '\0';
if (!strcmp(head, "option")) {
const char *key, *val;
char *key;
const char *val;

if (!hint || !(report || new_report)) {
if (!once++)
Expand Down
59 changes: 59 additions & 0 deletions builtin/rev-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "oidset.h"
#include "oidmap.h"
#include "packfile.h"
#include "commit-reach.h"
#include "quote.h"
#include "strbuf.h"

Expand Down Expand Up @@ -633,6 +634,61 @@ static int try_bitmap_disk_usage(struct rev_info *revs,
return 0;
}

/*
* If revs->maximal_only is set and no other walk modifiers are provided,
* run a faster computation to filter the independent commits and prepare
* them for output. Set revs->no_walk to prevent later walking.
*
* If this algorithm doesn't apply, then no changes are made to revs.
*/
static void prepare_maximal_independent(struct rev_info *revs)
{
struct commit_list *c;

if (!revs->maximal_only)
return;

for (c = revs->commits; c; c = c->next) {
if (c->item->object.flags & UNINTERESTING)
return;
}

if (revs->limited ||
revs->topo_order ||
revs->first_parent_only ||
revs->reverse ||
revs->max_count >= 0 ||
revs->skip_count >= 0 ||
revs->min_age != (timestamp_t)-1 ||
revs->max_age != (timestamp_t)-1 ||
revs->min_parents > 0 ||
revs->max_parents >= 0 ||
revs->prune_data.nr ||
revs->count ||
revs->left_right ||
revs->boundary ||
revs->tag_objects ||
revs->tree_objects ||
revs->blob_objects ||
revs->filter.choice ||
revs->reflog_info ||
revs->diff ||
revs->grep_filter.pattern_list ||
revs->grep_filter.header_list ||
revs->verbose_header ||
revs->print_parents ||
revs->edge_hint ||
revs->unpacked ||
revs->no_kept_objects ||
revs->line_level_traverse)
return;

reduce_heads_replace(&revs->commits);

/* Modify 'revs' to only output this commit list. */
revs->no_walk = 1;
}

int cmd_rev_list(int argc,
const char **argv,
const char *prefix,
Expand Down Expand Up @@ -875,6 +931,9 @@ int cmd_rev_list(int argc,

if (prepare_revision_walk(&revs))
die("revision walk setup failed");

prepare_maximal_independent(&revs);

if (revs.tree_objects)
mark_edges_uninteresting(&revs, show_edge, 0);

Expand Down
3 changes: 2 additions & 1 deletion convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -1168,7 +1168,8 @@ static int ident_to_worktree(const char *src, size_t len,
struct strbuf *buf, int ident)
{
struct object_id oid;
char *to_free = NULL, *dollar, *spc;
char *to_free = NULL;
const char *dollar, *spc;
int cnt;

if (!ident)
Expand Down
33 changes: 24 additions & 9 deletions git-compat-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,11 +335,7 @@ static inline int is_path_owned_by_current_uid(const char *path,
#endif

#ifndef find_last_dir_sep
static inline char *git_find_last_dir_sep(const char *path)
{
return strrchr(path, '/');
}
#define find_last_dir_sep git_find_last_dir_sep
#define find_last_dir_sep(path) strrchr((path), '/')
#endif

#ifndef has_dir_sep
Expand Down Expand Up @@ -467,6 +463,21 @@ void set_warn_routine(report_fn routine);
report_fn get_warn_routine(void);
void set_die_is_recursing_routine(int (*routine)(void));

/*
* Check that an out-parameter is "at least as const as" a matching
* in-parameter. For example, skip_prefix() will return "out" that is a subset
* of "str". So:
*
* const str, const out: ok
* non-const str, const out: ok
* non-const str, non-const out: ok
* const str, non-const out: compile error
*
* See the skip_prefix macro below for an example of use.
*/
#define CONST_OUTPARAM(in, out) \
((const char **)(0 ? ((*(out) = (in)),(out)) : (out)))

/*
* If the string "str" begins with the string found in "prefix", return true.
* The "out" parameter is set to "str + strlen(prefix)" (i.e., to the point in
Expand All @@ -483,8 +494,10 @@ void set_die_is_recursing_routine(int (*routine)(void));
* [skip prefix if present, otherwise use whole string]
* skip_prefix(name, "refs/heads/", &name);
*/
static inline bool skip_prefix(const char *str, const char *prefix,
const char **out)
#define skip_prefix(str, prefix, out) \
skip_prefix_impl((str), (prefix), CONST_OUTPARAM((str), (out)))
static inline bool skip_prefix_impl(const char *str, const char *prefix,
const char **out)
{
do {
if (!*prefix) {
Expand Down Expand Up @@ -889,8 +902,10 @@ static inline size_t xsize_t(off_t len)
* is done via tolower(), so it is strictly ASCII (no multi-byte characters or
* locale-specific conversions).
*/
static inline bool skip_iprefix(const char *str, const char *prefix,
const char **out)
#define skip_iprefix(str, prefix, out) \
skip_iprefix_impl((str), (prefix), CONST_OUTPARAM((str), (out)))
static inline bool skip_iprefix_impl(const char *str, const char *prefix,
const char **out)
{
do {
if (!*prefix) {
Expand Down
6 changes: 3 additions & 3 deletions hex.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ int get_oid_hex(const char *hex, struct object_id *oid)
return get_oid_hex_algop(hex, oid, the_hash_algo);
}

int parse_oid_hex_algop(const char *hex, struct object_id *oid,
const char **end,
const struct git_hash_algo *algop)
int parse_oid_hex_algop_impl(const char *hex, struct object_id *oid,
const char **end,
const struct git_hash_algo *algop)
{
int ret = get_oid_hex_algop(hex, oid, algop);
if (!ret)
Expand Down
6 changes: 4 additions & 2 deletions hex.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ char *oid_to_hex(const struct object_id *oid); /* same static buffer */
* other invalid character. end is only updated on success; otherwise, it is
* unmodified.
*/
int parse_oid_hex_algop(const char *hex, struct object_id *oid, const char **end,
const struct git_hash_algo *algo);
#define parse_oid_hex_algop(hex, oid, end, algo) \
parse_oid_hex_algop_impl((hex), (oid), CONST_OUTPARAM((hex), (end)), (algo))
int parse_oid_hex_algop_impl(const char *hex, struct object_id *oid, const char **end,
const struct git_hash_algo *algo);

/*
* These functions work like get_oid_hex and parse_oid_hex, but they will parse
Expand Down
2 changes: 1 addition & 1 deletion http-push.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ static struct object_list *objects;

struct repo {
char *url;
char *path;
const char *path;
int path_len;
int has_info_refs;
int can_update_info_refs;
Expand Down
4 changes: 2 additions & 2 deletions http.c
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,7 @@ static int has_proxy_cert_password(void)
static int redact_sensitive_header(struct strbuf *header, size_t offset)
{
int ret = 0;
const char *sensitive_header;
char *sensitive_header;

if (trace_curl_redact &&
(skip_iprefix(header->buf + offset, "Authorization:", &sensitive_header) ||
Expand All @@ -765,7 +765,7 @@ static int redact_sensitive_header(struct strbuf *header, size_t offset)
} else if (trace_curl_redact &&
skip_iprefix(header->buf + offset, "Cookie:", &sensitive_header)) {
struct strbuf redacted_header = STRBUF_INIT;
const char *cookie;
char *cookie;

while (isspace(*sensitive_header))
sensitive_header++;
Expand Down
5 changes: 3 additions & 2 deletions pager.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,11 @@ const char *git_pager(struct repository *r, int stdout_is_tty)

static void setup_pager_env(struct strvec *env)
{
const char **argv;
char **argv;
int i;
char *pager_env = xstrdup(PAGER_ENV);
int n = split_cmdline(pager_env, &argv);
/* split_cmdline splits in place, so we know the result is writable */
int n = split_cmdline(pager_env, (const char ***)&argv);

if (n < 0)
die("malformed build-time PAGER_ENV: %s",
Expand Down
2 changes: 1 addition & 1 deletion pkt-line.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ struct packet_reader {
int pktlen;

/* the last line read */
const char *line;
char *line;

/* indicates if a line has been peeked */
int line_peeked;
Expand Down
32 changes: 19 additions & 13 deletions pseudo-merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,31 +638,37 @@ static int pseudo_merge_commit_cmp(const void *va, const void *vb)
return 0;
}

static struct pseudo_merge_commit *find_pseudo_merge(const struct pseudo_merge_map *pm,
uint32_t pos)
static int find_pseudo_merge(const struct pseudo_merge_map *pm, uint32_t pos,
struct pseudo_merge_commit *out)
{
const unsigned char *at;

if (!pm->commits_nr)
return NULL;
return 0;

return bsearch(&pos, pm->commits, pm->commits_nr,
PSEUDO_MERGE_COMMIT_RAWSZ, pseudo_merge_commit_cmp);
at = bsearch(&pos, pm->commits, pm->commits_nr,
PSEUDO_MERGE_COMMIT_RAWSZ, pseudo_merge_commit_cmp);
if (!at)
return 0;

read_pseudo_merge_commit_at(out, at);
return 1;
}

int apply_pseudo_merges_for_commit(const struct pseudo_merge_map *pm,
struct bitmap *result,
struct commit *commit, uint32_t commit_pos)
{
struct pseudo_merge *merge;
struct pseudo_merge_commit *merge_commit;
struct pseudo_merge_commit merge_commit;
int ret = 0;

merge_commit = find_pseudo_merge(pm, commit_pos);
if (!merge_commit)
if (!find_pseudo_merge(pm, commit_pos, &merge_commit))
return 0;

if (merge_commit->pseudo_merge_ofs & ((uint64_t)1<<63)) {
if (merge_commit.pseudo_merge_ofs & ((uint64_t)1<<63)) {
struct pseudo_merge_commit_ext ext = { 0 };
off_t ofs = merge_commit->pseudo_merge_ofs & ~((uint64_t)1<<63);
off_t ofs = merge_commit.pseudo_merge_ofs & ~((uint64_t)1<<63);
uint32_t i;

if (pseudo_merge_ext_at(pm, &ext, ofs) < -1) {
Expand All @@ -673,11 +679,11 @@ int apply_pseudo_merges_for_commit(const struct pseudo_merge_map *pm,
}

for (i = 0; i < ext.nr; i++) {
if (nth_pseudo_merge_ext(pm, &ext, merge_commit, i) < 0)
if (nth_pseudo_merge_ext(pm, &ext, &merge_commit, i) < 0)
return ret;

merge = pseudo_merge_at(pm, &commit->object.oid,
merge_commit->pseudo_merge_ofs);
merge_commit.pseudo_merge_ofs);

if (!merge)
return ret;
Expand All @@ -687,7 +693,7 @@ int apply_pseudo_merges_for_commit(const struct pseudo_merge_map *pm,
}
} else {
merge = pseudo_merge_at(pm, &commit->object.oid,
merge_commit->pseudo_merge_ofs);
merge_commit.pseudo_merge_ofs);

if (!merge)
return ret;
Expand Down
Loading