Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
9ebc19b
Merge branch 'ps/odb-in-memory' into ps/odb-source-loose
gitster May 21, 2026
8c84e68
t3070: skip ls-files tests with backslash patterns on Windows
spkrka May 28, 2026
1ec041b
doc: clarify that --word-diff operates on line-level hunks
mmontalbo May 28, 2026
558057c
revision: move -L setup before output_format-to-diff derivation
mmontalbo May 28, 2026
42d9607
line-log: integrate -L output with the standard log-tree pipeline
mmontalbo May 28, 2026
4b5d8a0
line-log: allow non-patch diff formats with -L
mmontalbo May 28, 2026
b8cda12
daemon: fix IPv6 address corruption in lookup_hostname()
SebTardif May 28, 2026
30c8fda
daemon: fix IPv6 address truncation in ip2str()
SebTardif May 28, 2026
422a5bf
daemon: guard NULL REMOTE_PORT in execute() logging
SebTardif May 28, 2026
514f039
odb/source-loose: move loose source into "odb/" subsystem
pks-t Jun 1, 2026
1d451ba
odb/source-loose: store pointer to "files" instead of generic source
pks-t Jun 1, 2026
ead6919
odb/source-loose: start converting to a proper `struct odb_source`
pks-t Jun 1, 2026
a2b7db9
odb/source-loose: wire up `reprepare()` callback
pks-t Jun 1, 2026
337b7fc
odb/source-loose: wire up `close()` callback
pks-t Jun 1, 2026
584338e
odb/source-loose: wire up `read_object_info()` callback
pks-t Jun 1, 2026
727a935
odb/source-loose: wire up `read_object_stream()` callback
pks-t Jun 1, 2026
e4f1d9b
odb/source-loose: wire up `for_each_object()` callback
pks-t Jun 1, 2026
8a6da81
odb/source-loose: wire up `find_abbrev_len()` callback
pks-t Jun 1, 2026
2ade08a
odb/source-loose: wire up `count_objects()` callback
pks-t Jun 1, 2026
86f7ab5
odb/source-loose: drop `odb_source_loose_has_object()`
pks-t Jun 1, 2026
d8b9e8b
odb/source-loose: wire up `freshen_object()` callback
pks-t Jun 1, 2026
87588db
loose: refactor object map to operate on `struct odb_source_loose`
pks-t Jun 1, 2026
04a6e84
odb/source-loose: wire up `write_object()` callback
pks-t Jun 1, 2026
b9906a6
object-file: refactor writing objects to use loose source
pks-t Jun 1, 2026
e6a39bb
odb/source-loose: wire up `write_object_stream()` callback
pks-t Jun 1, 2026
87af3bb
odb/source-loose: stub out remaining callbacks
pks-t Jun 1, 2026
ef4778b
odb/source-loose: drop pointer to the "files" source
pks-t Jun 1, 2026
96ee7f1
http: cleanup function fetch_and_setup_pack_index()
LorenzoPegorari Jun 1, 2026
18decad
http: fix memory leak in fetch_and_setup_pack_index()
LorenzoPegorari Jun 1, 2026
5cd4d0d
config.mak.uname: avoid macOS linker warning on Xcode 16.3+
HaraldNordgren Jun 2, 2026
f0e24cc
Merge branch 'st/daemon-sockaddr-fixes'
gitster Jun 11, 2026
53ff393
Merge branch 'mm/line-log-cleanup'
gitster Jun 11, 2026
06f63df
Merge branch 'ps/odb-source-loose'
gitster Jun 11, 2026
31291f5
Merge branch 'lp/http-fetch-pack-index-leak-fix'
gitster Jun 11, 2026
2bf8abc
Merge branch 'mm/doc-word-diff'
gitster Jun 11, 2026
15acf6d
Merge branch 'kk/wildmatch-windows-ls-files-prereq'
gitster Jun 11, 2026
4b94bf9
Merge branch 'hn/macos-linker-warning'
gitster Jun 11, 2026
3e65291
Git 2.55-rc0
gitster Jun 11, 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
28 changes: 28 additions & 0 deletions Documentation/RelNotes/2.55.0.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ UI, Workflows & Features
current branch to a same-named branch on the remote, and detailing
the upstream requirements for centralized workflows.

* The documentation for "--word-diff" has been extended with a bit of
implementation detail of where these different words come from.


Performance, Internal Implementation, Development Support etc.
--------------------------------------------------------------
Expand Down Expand Up @@ -160,6 +163,14 @@ Performance, Internal Implementation, Development Support etc.

* Encourage original authors to monitor the CI status.

* The `git log -L` implementation has been refactored to use the
standard diff output pipeline, enabling pickaxe and diff-filter to
work as expected. Additionally, metadata-only diff formats like
--raw and --name-only are now supported with -L.

* The loose object source has been refactored into a proper `struct
odb_source`.


Fixes since v2.54
-----------------
Expand Down Expand Up @@ -294,6 +305,23 @@ Fixes since v2.54
triggered a lazy fetch, which has been corrected.
(merge fa1468a1f7 th/promisor-quiet-per-repo later to maint).

* Correct use of sockaddr API in "git daemon".
(merge 422a5bf575 st/daemon-sockaddr-fixes later to maint).

* A memory leak in `fetch_and_setup_pack_index()` when verification of
the downloaded pack index fails has been plugged. Also an obsolete
`unlink()` call on parse failure has been cleaned up.

* In t3070-wildmatch, "via ls-files" test variants with patterns
containing backslash escapes are now skipped on Windows, avoiding 36
test failures caused by pathspec separator conversion.
(merge 8c84e6802c kk/wildmatch-windows-ls-files-prereq later to maint).

* A linker warning on macOS when building with Xcode 16.3 or newer has
been avoided by passing -fno-common to the compiler when a
sufficiently new linker is detected.
(merge 5cd4d0d850 hn/macos-linker-warning later to maint).

* Other code cleanup, docfix, build fix, etc.
(merge 80f4b802e9 ja/doc-difftool-synopsis-style later to maint).
(merge b96490241e jc/doc-timestamps-in-stat later to maint).
Expand Down
8 changes: 8 additions & 0 deletions Documentation/diff-options.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,14 @@ endif::git-diff[]
+
Note that despite the name of the first mode, color is used to
highlight the changed parts in all modes if enabled.
+
The `--word-diff` option operates by taking the same line-by-line
diff that is produced without the option and computing
word-by-word changes within each hunk. This may produce a
larger diff than a dedicated word-diff tool would. If Git
acquires a different implementation in the future, the output
may change. Note that this is similar to the `--diff-algorithm`
option, which may also change the output.

`--word-diff-regex=<regex>`::
Use _<regex>_ to decide what a word is, instead of considering
Expand Down
10 changes: 6 additions & 4 deletions Documentation/line-range-options.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
give zero or one positive revision arguments, and
_<start>_ and _<end>_ (or _<funcname>_) must exist in the starting revision.
You can specify this option more than once. Implies `--patch`.
Patch output can be suppressed using `--no-patch`, but other diff formats
(namely `--raw`, `--numstat`, `--shortstat`, `--dirstat`, `--summary`,
`--name-only`, `--name-status`, `--check`) are not currently implemented.
Patch output can be suppressed using `--no-patch`.
Non-patch diff formats `--raw`, `--name-only`, `--name-status`,
and `--summary` are supported. Diff stat formats
(`--stat`, `--numstat`, `--shortstat`, `--dirstat`) 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`).
as are pickaxe options (`-S`, `-G`) and `--diff-filter`.
+
include::line-range-format.adoc[]
2 changes: 1 addition & 1 deletion GIT-VERSION-GEN
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/sh

DEF_VER=v2.54.0
DEF_VER=v2.55.0-rc0

LF='
'
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,7 @@ LIB_OBJS += odb.o
LIB_OBJS += odb/source.o
LIB_OBJS += odb/source-files.o
LIB_OBJS += odb/source-inmemory.o
LIB_OBJS += odb/source-loose.o
LIB_OBJS += odb/streaming.o
LIB_OBJS += odb/transaction.o
LIB_OBJS += oid-array.o
Expand Down
5 changes: 3 additions & 2 deletions builtin/cat-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -890,8 +890,9 @@ static void batch_each_object(struct batch_options *opt,
*/
odb_prepare_alternates(the_repository->objects);
for (source = the_repository->objects->sources; source; source = source->next) {
int ret = odb_source_loose_for_each_object(source, NULL, batch_one_object_oi,
&payload, &opts);
struct odb_source_files *files = odb_source_files_downcast(source);
int ret = odb_source_for_each_object(&files->loose->base, NULL, batch_one_object_oi,
&payload, &opts);
if (ret)
break;
}
Expand Down
6 changes: 3 additions & 3 deletions builtin/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ static int rerere_gc_condition(struct gc_config *cfg UNUSED)

static int too_many_loose_objects(int limit)
{
struct odb_source_files *files = odb_source_files_downcast(the_repository->objects->sources);
/*
* This is weird, but stems from legacy behaviour: the GC auto
* threshold was always essentially interpreted as if it was rounded up
Expand All @@ -474,9 +475,8 @@ static int too_many_loose_objects(int limit)
int auto_threshold = DIV_ROUND_UP(limit, 256) * 256;
unsigned long loose_count;

if (odb_source_loose_count_objects(the_repository->objects->sources,
ODB_COUNT_OBJECTS_APPROXIMATE,
&loose_count) < 0)
if (odb_source_count_objects(&files->loose->base, ODB_COUNT_OBJECTS_APPROXIMATE,
&loose_count) < 0)
return 0;

return loose_count > auto_threshold;
Expand Down
12 changes: 8 additions & 4 deletions builtin/pack-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -1750,9 +1750,11 @@ static int want_object_in_pack_mtime(const struct object_id *oid,
* skip the local object source.
*/
struct odb_source *source = the_repository->objects->sources->next;
for (; source; source = source->next)
if (odb_source_loose_has_object(source, oid))
for (; source; source = source->next) {
struct odb_source_files *files = odb_source_files_downcast(source);
if (!odb_source_read_object_info(&files->loose->base, oid, NULL, 0))
return 0;
}
}

/*
Expand Down Expand Up @@ -4135,9 +4137,11 @@ static void add_cruft_object_entry(const struct object_id *oid, enum object_type
struct odb_source *source = the_repository->objects->sources;
int found = 0;

for (; !found && source; source = source->next)
if (odb_source_loose_has_object(source, oid))
for (; !found && source; source = source->next) {
struct odb_source_files *files = odb_source_files_downcast(source);
if (!odb_source_read_object_info(&files->loose->base, oid, NULL, 0))
found = 1;
}

/*
* If a traversed tree has a missing blob then we want
Expand Down
6 changes: 6 additions & 0 deletions config.mak.uname
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,12 @@ ifeq ($(uname_S),Darwin)
NEEDS_GOOD_LIBICONV = UnfortunatelyYes
endif

# Silence Xcode 16.3+ linker warning about __DATA,__common alignment.
LD_MAJOR_VERSION = $(shell ld -v 2>&1 | sed -n 's/.*PROJECT:ld-\([0-9]*\).*/\1/p')
ifeq ($(shell test -n "$(LD_MAJOR_VERSION)" && test "$(LD_MAJOR_VERSION)" -ge 1167 && echo 1),1)
BASIC_CFLAGS += -fno-common
endif

# The builtin FSMonitor on MacOS builds upon Simple-IPC. Both require
# Unix domain sockets and PThreads.
ifndef NO_PTHREADS
Expand Down
31 changes: 21 additions & 10 deletions daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -674,9 +674,20 @@ static void lookup_hostname(struct hostinfo *hi)

gai = getaddrinfo(hi->hostname.buf, NULL, &hints, &ai);
if (!gai) {
struct sockaddr_in *sin_addr = (void *)ai->ai_addr;
void *addr;

if (ai->ai_family == AF_INET) {
struct sockaddr_in *sa = (void *)ai->ai_addr;
addr = &sa->sin_addr;
} else if (ai->ai_family == AF_INET6) {
struct sockaddr_in6 *sa6 = (void *)ai->ai_addr;
addr = &sa6->sin6_addr;
} else {
die("unexpected address family: %d",
ai->ai_family);
}

inet_ntop(AF_INET, &sin_addr->sin_addr,
inet_ntop(ai->ai_family, addr,
addrbuf, sizeof(addrbuf));
strbuf_addstr(&hi->ip_address, addrbuf);

Expand Down Expand Up @@ -742,7 +753,7 @@ static int execute(void)
struct strvec env = STRVEC_INIT;

if (addr)
loginfo("Connection from %s:%s", addr, port);
loginfo("Connection from %s:%s", addr, port ? port : "?");

set_keep_alive(0);
alarm(init_timeout ? init_timeout : timeout);
Expand Down Expand Up @@ -936,7 +947,7 @@ struct socketlist {
size_t alloc;
};

static const char *ip2str(int family, struct sockaddr *sin, socklen_t len)
static const char *ip2str(int family, struct sockaddr *sin)
{
#ifdef NO_IPV6
static char ip[INET_ADDRSTRLEN];
Expand All @@ -947,11 +958,11 @@ static const char *ip2str(int family, struct sockaddr *sin, socklen_t len)
switch (family) {
#ifndef NO_IPV6
case AF_INET6:
inet_ntop(family, &((struct sockaddr_in6*)sin)->sin6_addr, ip, len);
inet_ntop(family, &((struct sockaddr_in6*)sin)->sin6_addr, ip, sizeof(ip));
break;
#endif
case AF_INET:
inet_ntop(family, &((struct sockaddr_in*)sin)->sin_addr, ip, len);
inet_ntop(family, &((struct sockaddr_in*)sin)->sin_addr, ip, sizeof(ip));
break;
default:
xsnprintf(ip, sizeof(ip), "<unknown>");
Expand Down Expand Up @@ -1008,14 +1019,14 @@ static int setup_named_sock(char *listen_addr, int listen_port, struct socketlis

if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
logerror("Could not bind to %s: %s",
ip2str(ai->ai_family, ai->ai_addr, ai->ai_addrlen),
ip2str(ai->ai_family, ai->ai_addr),
strerror(errno));
close(sockfd);
continue; /* not fatal */
}
if (listen(sockfd, 5) < 0) {
logerror("Could not listen to %s: %s",
ip2str(ai->ai_family, ai->ai_addr, ai->ai_addrlen),
ip2str(ai->ai_family, ai->ai_addr),
strerror(errno));
close(sockfd);
continue; /* not fatal */
Expand Down Expand Up @@ -1069,15 +1080,15 @@ static int setup_named_sock(char *listen_addr, int listen_port, struct socketlis

if ( bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0 ) {
logerror("Could not bind to %s: %s",
ip2str(AF_INET, (struct sockaddr *)&sin, sizeof(sin)),
ip2str(AF_INET, (struct sockaddr *)&sin),
strerror(errno));
close(sockfd);
return 0;
}

if (listen(sockfd, 5) < 0) {
logerror("Could not listen to %s: %s",
ip2str(AF_INET, (struct sockaddr *)&sin, sizeof(sin)),
ip2str(AF_INET, (struct sockaddr *)&sin),
strerror(errno));
close(sockfd);
return 0;
Expand Down
3 changes: 2 additions & 1 deletion http-walker.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,8 +539,9 @@ static int fetch_object(struct walker *walker, const struct object_id *oid)
} else if (!oideq(&obj_req->oid, &req->real_oid)) {
ret = error("File %s has bad hash", hex);
} else if (req->rename < 0) {
struct odb_source_files *files = odb_source_files_downcast(the_repository->objects->sources);
struct strbuf buf = STRBUF_INIT;
odb_loose_path(the_repository->objects->sources, &buf, &req->oid);
odb_loose_path(files->loose, &buf, &req->oid);
ret = error("unable to write sha1 filename %s", buf.buf);
strbuf_release(&buf);
}
Expand Down
16 changes: 9 additions & 7 deletions http.c
Original file line number Diff line number Diff line change
Expand Up @@ -2609,18 +2609,18 @@ static int fetch_and_setup_pack_index(struct packfile_list *packs,

new_pack = parse_pack_index(the_repository, sha1, tmp_idx);
if (!new_pack) {
unlink(tmp_idx);
free(tmp_idx);

return -1; /* parse_pack_index() already issued error message */
}

ret = verify_pack_index(new_pack);
if (!ret)
close_pack_index(new_pack);

close_pack_index(new_pack);
free(tmp_idx);
if (ret)
if (ret) {
free(new_pack);
return -1;
}

packfile_list_prepend(packs, new_pack);
return 0;
Expand Down Expand Up @@ -2826,6 +2826,7 @@ static size_t fwrite_sha1_file(char *ptr, size_t eltsize, size_t nmemb,
struct http_object_request *new_http_object_request(const char *base_url,
const struct object_id *oid)
{
struct odb_source_files *files = odb_source_files_downcast(the_repository->objects->sources);
char *hex = oid_to_hex(oid);
struct strbuf filename = STRBUF_INIT;
struct strbuf prevfile = STRBUF_INIT;
Expand All @@ -2840,7 +2841,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
oidcpy(&freq->oid, oid);
freq->localfile = -1;

odb_loose_path(the_repository->objects->sources, &filename, oid);
odb_loose_path(files->loose, &filename, oid);
strbuf_addf(&freq->tmpfile, "%s.temp", filename.buf);

strbuf_addf(&prevfile, "%s.prev", filename.buf);
Expand Down Expand Up @@ -2966,6 +2967,7 @@ void process_http_object_request(struct http_object_request *freq)

int finish_http_object_request(struct http_object_request *freq)
{
struct odb_source_files *files = odb_source_files_downcast(the_repository->objects->sources);
struct stat st;
struct strbuf filename = STRBUF_INIT;

Expand All @@ -2992,7 +2994,7 @@ int finish_http_object_request(struct http_object_request *freq)
unlink_or_warn(freq->tmpfile.buf);
return -1;
}
odb_loose_path(the_repository->objects->sources, &filename, &freq->oid);
odb_loose_path(files->loose, &filename, &freq->oid);
freq->rename = finalize_object_file(the_repository, freq->tmpfile.buf, filename.buf);
strbuf_release(&filename);

Expand Down
30 changes: 9 additions & 21 deletions line-log.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "revision.h"
#include "xdiff-interface.h"
#include "strbuf.h"
#include "log-tree.h"
#include "line-log.h"
#include "setup.h"
#include "strvec.h"
Expand Down Expand Up @@ -1004,29 +1003,18 @@ static int process_all_files(struct line_log_data **range_out,
return changed;
}

int line_log_print(struct rev_info *rev, struct commit *commit)
void line_log_queue_pairs(struct rev_info *rev, struct commit *commit)
{
show_log(rev);
if (!(rev->diffopt.output_format & DIFF_FORMAT_NO_OUTPUT)) {
struct line_log_data *range = lookup_line_range(rev, commit);
struct line_log_data *r;
const char *prefix = diff_line_prefix(&rev->diffopt);

fprintf(rev->diffopt.file, "%s\n", prefix);

for (r = range; r; r = r->next) {
if (r->pair) {
struct diff_filepair *p =
diff_filepair_dup(r->pair);
p->line_ranges = &r->ranges;
diff_q(&diff_queued_diff, p);
}
}
struct line_log_data *range = lookup_line_range(rev, commit);
struct line_log_data *r;

diffcore_std(&rev->diffopt);
diff_flush(&rev->diffopt);
for (r = range; r; r = r->next) {
if (r->pair) {
struct diff_filepair *p = diff_filepair_dup(r->pair);
p->line_ranges = &r->ranges;
diff_q(&diff_queued_diff, p);
}
}
return 1;
}

static int bloom_filter_check(struct rev_info *rev,
Expand Down
2 changes: 1 addition & 1 deletion line-log.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ int line_log_filter(struct rev_info *rev);
int line_log_process_ranges_arbitrary_commit(struct rev_info *rev,
struct commit *commit);

int line_log_print(struct rev_info *rev, struct commit *commit);
void line_log_queue_pairs(struct rev_info *rev, struct commit *commit);

void line_log_free(struct rev_info *rev);

Expand Down
Loading