Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2e60aab
name-hash: don't add sparse directories in threaded lazy init
alexandrfox May 21, 2025
b103881
midx repack: avoid integer overflow on 32 bit systems
phillipwood May 22, 2025
f874c0e
midx repack: avoid potential integer overflow on 64 bit systems
phillipwood May 22, 2025
3aa98a6
midx: avoid negative array index
phillipwood May 22, 2025
70b128c
midx docs: clarify tie breaking
phillipwood May 22, 2025
2cc8c17
t4129: test that git apply warns for unexpected mode changes
markmentovai May 24, 2025
1d9a664
apply: set file mode when --reverse creates a deleted file
markmentovai May 24, 2025
67cae84
cvsserver: remove unused escapeRefName function
opohorel May 26, 2025
e2de9b3
doc: stripspace: mention where the default comes from
LemmingAvalanche May 27, 2025
e2971d6
doc: config: mention core.commentChar on commit.cleanup
LemmingAvalanche May 27, 2025
37dd51a
doc: notes: split out options with negated forms
LemmingAvalanche May 27, 2025
6521ca8
doc: notes: rework --[no-]stripspace
LemmingAvalanche May 27, 2025
159c42a
doc: notes: remove stripspace discussion from other options
LemmingAvalanche May 27, 2025
5471b19
doc: notes: clearly state that --stripspace is the default
LemmingAvalanche May 27, 2025
6dcec89
doc: notes: point out copy --stdin use with argv
LemmingAvalanche May 27, 2025
45113e1
doc: notes: treat --stdin equally between copy/remove
LemmingAvalanche May 27, 2025
806337c
doc: notes: use stuck form throughout
LemmingAvalanche May 27, 2025
320572c
packfile: explain ordering of how we look up auxiliary pack files
pks-t May 28, 2025
1f34bf3
midx: stop repeatedly looking up nonexistent packfiles
pks-t May 28, 2025
f1228cd
reftable: make REFTABLE_UNUSED C99 compatible
carenas May 29, 2025
277064b
Merge branch 'cb/reftable-unused-portability-fix'
gitster May 30, 2025
48a25bb
Merge branch 'pw/midx-repack-overflow-fix'
gitster May 30, 2025
8ddea85
Merge branch 'am/sparse-index-name-hash-fix'
gitster May 30, 2025
5cde0d7
Merge branch 'op/cvsserver-perl-warning'
gitster May 30, 2025
5d2812f
Merge branch 'mm/apply-reverse-mode-of-deleted-path'
gitster May 30, 2025
1a140c8
Merge branch 'kh/notes-doc-fixes'
gitster May 30, 2025
9a43523
Merge branch 'ps/midx-negative-packfile-cache'
gitster May 30, 2025
7014b55
A bit more topics for -rc1
gitster May 30, 2025
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
22 changes: 22 additions & 0 deletions Documentation/RelNotes/2.50.0.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ UI, Workflows & Features
check, which can be useful when the repository arranges to ensure
connectivity by some other means.

* "git notes --help" documentation updates.


Performance, Internal Implementation, Development Support etc.
--------------------------------------------------------------
Expand Down Expand Up @@ -193,6 +195,10 @@ Performance, Internal Implementation, Development Support etc.
do not pass the leak checker tests, as they should no longer be
needed.

* When a stale .midx file refers to .pack files that no longer exist,
we ended up checking for these non-existent files repeatedly, which
has been optimized by memoizing the non-existence.


Fixes since v2.49
-----------------
Expand Down Expand Up @@ -355,6 +361,22 @@ Fixes since v2.49
expand sparse-index while working.
(merge ecf9ba20e3 ds/sparse-apply-add-p later to maint).

* Avoid adding directory path to a sparse-index tree entries to the
name-hash, since they would bloat the hashtable without anybody
querying for them. This was done already for a single threaded
part of the code, but now the multi-threaded code also does the
same.
(merge 2e60aabc75 am/sparse-index-name-hash-fix later to maint).

* Recent versions of Perl started warning against "! A =~ /pattern/"
which does not negate the result of the matching. As it turns out
that the problematic function is not even called, it was removed.
(merge 67cae845d2 op/cvsserver-perl-warning later to maint).

* "git apply --index/--cached" when applying a deletion patch in
reverse failed to give the mode bits of the path "removed" by the
patch to the file it creates, which has been corrected.

* Other code cleanup, docfix, build fix, etc.
(merge 227c4f33a0 ja/doc-block-delimiter-markup-fix later to maint).
(merge 2bfd3b3685 ab/decorate-code-cleanup later to maint).
Expand Down
7 changes: 4 additions & 3 deletions Documentation/config/commit.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ endif::git-commit[]
This setting overrides the default of the `--cleanup` option in
`git commit`. {see-git-commit} Changing the default can be useful
when you always want to keep lines that begin
with the comment character `#` in your log message, in which case you
with the comment character (`core.commentChar`, default `#`)
in your log message, in which case you
would do `git config commit.cleanup whitespace` (note that you will
have to remove the help lines that begin with `#` in the commit log
template yourself, if you do this).
have to remove the help lines that begin with the comment character
in the commit log template yourself, if you do this).

`commit.gpgSign`::
A boolean to specify whether all commits should be GPG signed.
Expand Down
11 changes: 7 additions & 4 deletions Documentation/git-multi-pack-index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@ write::
+
--
--preferred-pack=<pack>::
Optionally specify the tie-breaking pack used when
multiple packs contain the same object. `<pack>` must
contain at least one object. If not given, ties are
broken in favor of the pack with the lowest mtime.
When specified, break ties in favor of this pack when
there are additional copies of its objects in other
packs. Ties for objects not found in the preferred
pack are always resolved in favor of the copy in the
pack with the highest mtime. If unspecified, the pack
with the lowest mtime is used by default. The
preferred pack must have at least one object.

--[no-]bitmap::
Control whether or not a multi-pack bitmap is written.
Expand Down
54 changes: 32 additions & 22 deletions Documentation/git-notes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ In `--stdin` mode, take lines in the format
on standard input, and copy the notes from each _<from-object>_ to its
corresponding _<to-object>_. (The optional _<rest>_ is ignored so that
the command can read the input given to the `post-rewrite` hook.)
+
`--stdin` cannot be combined with object names given on the command
line.

`append`::
Append new message(s) given by `-m` or `-F` options to an
Expand Down Expand Up @@ -124,6 +127,10 @@ When done, the user can either finalize the merge with
giving zero or one object from the command line, this is
equivalent to specifying an empty note message to
the `edit` subcommand.
+
In `--stdin` mode, also remove the object names given on standard
input. In other words, `--stdin` can be combined with object names from
the command line.

`prune`::
Remove all notes for non-existing/unreachable objects.
Expand All @@ -144,26 +151,18 @@ OPTIONS
Use the given note message (instead of prompting).
If multiple `-m` options are given, their values
are concatenated as separate paragraphs.
Lines starting with `#` and empty lines other than a
single line between paragraphs will be stripped out.
If you wish to keep them verbatim, use `--no-stripspace`.

`-F <file>`::
`--file=<file>`::
Take the note message from the given file. Use `-` to
read the note message from the standard input.
Lines starting with `#` and empty lines other than a
single line between paragraphs will be stripped out.
If you wish to keep them verbatim, use `--no-stripspace`.

`-C <object>`::
`--reuse-message=<object>`::
Take the given blob object (for example, another note) as the
note message. (Use `git notes copy <object>` instead to
copy notes between objects.). By default, message will be
copied verbatim, but if you wish to strip out the lines
starting with `#` and empty lines other than a single line
between paragraphs, use with `--stripspace` option.
copy notes between objects.) Implies `--no-stripspace` since
the default behavior is to copy the message verbatim.

`-c <object>`::
`--reedit-message=<object>`::
Expand All @@ -174,21 +173,34 @@ OPTIONS
Allow an empty note object to be stored. The default behavior is
to automatically remove empty notes.

`--[no-]separator`::
`--separator=<paragraph-break>`::
`--separator`::
`--no-separator`::
Specify a string used as a custom inter-paragraph separator
(a newline is added at the end as needed). If `--no-separator`, no
separators will be added between paragraphs. Defaults to a blank
line.

`--[no-]stripspace`::
Strip leading and trailing whitespace from the note message.
Also strip out empty lines other than a single line between
paragraphs. Lines starting with `#` will be stripped out
in non-editor cases like `-m`, `-F` and `-C`, but not in
editor case like `git notes edit`, `-c`, etc.

`--ref <ref>`::
`--stripspace`::
`--no-stripspace`::
Clean up whitespace. Specifically (see
linkgit:git-stripspace[1]):
+
--
- remove trailing whitespace from all lines
- collapse multiple consecutive empty lines into one empty line
- remove empty lines from the beginning and end of the input
- add a missing `\n` to the last line if necessary.
--
+
`--stripspace` is the default except for
`-C`/`--reuse-message`. However, keep in mind that this depends on the
order of similar options. For example, for `-C <object> -m<message>`,
`--stripspace` will be used because the default for `-m` overrides the
previous `-C`. This is a known limitation that may be fixed in the
future.

`--ref=<ref>`::
Manipulate the notes tree in _<ref>_. This overrides
`GIT_NOTES_REF` and the `core.notesRef` configuration. The ref
specifies the full refname when it begins with `refs/notes/`; when it
Expand All @@ -200,9 +212,7 @@ OPTIONS
object that does not have notes attached to it.

`--stdin`::
Also read the object names to remove notes from the standard
input (there is no reason you cannot combine this with object
names from the command line).
Only valid for `remove` and `copy`. See the respective subcommands.

`-n`::
`--dry-run`::
Expand Down
3 changes: 2 additions & 1 deletion Documentation/git-stripspace.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ OPTIONS
-------
-s::
--strip-comments::
Skip and remove all lines starting with a comment character (default '#').
Skip and remove all lines starting with a comment character
(`core.commentChar`, default `#`).

-c::
--comment-lines::
Expand Down
2 changes: 1 addition & 1 deletion apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -2219,7 +2219,7 @@ static void reverse_patches(struct patch *p)
struct fragment *frag = p->fragments;

SWAP(p->new_name, p->old_name);
if (p->new_mode)
if (p->new_mode || p->is_delete)
SWAP(p->new_mode, p->old_mode);
SWAP(p->is_new, p->is_delete);
SWAP(p->lines_added, p->lines_deleted);
Expand Down
16 changes: 16 additions & 0 deletions git-compat-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,22 @@ static inline int cast_size_t_to_int(size_t a)
return (int)a;
}

static inline uint64_t u64_mult(uint64_t a, uint64_t b)
{
if (unsigned_mult_overflows(a, b))
die("uint64_t overflow: %"PRIuMAX" * %"PRIuMAX,
(uintmax_t)a, (uintmax_t)b);
return a * b;
}

static inline uint64_t u64_add(uint64_t a, uint64_t b)
{
if (unsigned_add_overflows(a, b))
die("uint64_t overflow: %"PRIuMAX" + %"PRIuMAX,
(uintmax_t)a, (uintmax_t)b);
return a + b;
}

/*
* Limit size of IO chunks, because huge chunks only cause pain. OS X
* 64-bit is buggy, returning EINVAL if len >= INT_MAX; and even in
Expand Down
27 changes: 3 additions & 24 deletions git-cvsserver.perl
Original file line number Diff line number Diff line change
Expand Up @@ -4986,13 +4986,13 @@ sub gethistorydense
return $result;
}

=head2 escapeRefName
=head2 unescapeRefName

Apply an escape mechanism to compensate for characters that
Undo an escape mechanism to compensate for characters that
git ref names can have that CVS tags can not.

=cut
sub escapeRefName
sub unescapeRefName
{
my($self,$refName)=@_;

Expand All @@ -5009,27 +5009,6 @@ sub escapeRefName
# = "_-xx-" Where "xx" is the hexadecimal representation of the
# desired ASCII character byte. (for anything else)

if(! $refName=~/^[1-9][0-9]*(\.[1-9][0-9]*)*$/)
{
$refName=~s/_-/_-u--/g;
$refName=~s/\./_-p-/g;
$refName=~s%/%_-s-%g;
$refName=~s/[^-_a-zA-Z0-9]/sprintf("_-%02x-",$1)/eg;
}
}

=head2 unescapeRefName

Undo an escape mechanism to compensate for characters that
git ref names can have that CVS tags can not.

=cut
sub unescapeRefName
{
my($self,$refName)=@_;

# see escapeRefName() for description of escape mechanism.

$refName=~s/_-([spu]|[0-9a-f][0-9a-f])-/unescapeRefNameChar($1)/eg;

# allowed tag names
Expand Down
22 changes: 16 additions & 6 deletions midx-write.c
Original file line number Diff line number Diff line change
Expand Up @@ -1566,7 +1566,7 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla
_("Counting referenced objects"),
m->num_objects);
for (i = 0; i < m->num_objects; i++) {
int pack_int_id = nth_midxed_pack_int_id(m, i);
uint32_t pack_int_id = nth_midxed_pack_int_id(m, i);
count[pack_int_id]++;
display_progress(progress, i + 1);
}
Expand Down Expand Up @@ -1697,21 +1697,31 @@ static void fill_included_packs_batch(struct repository *r,

total_size = 0;
for (i = 0; total_size < batch_size && i < m->num_packs; i++) {
int pack_int_id = pack_info[i].pack_int_id;
uint32_t pack_int_id = pack_info[i].pack_int_id;
struct packed_git *p = m->packs[pack_int_id];
size_t expected_size;
uint64_t expected_size;

if (!want_included_pack(r, m, pack_kept_objects, pack_int_id))
continue;

expected_size = st_mult(p->pack_size,
pack_info[i].referenced_objects);
/*
* Use shifted integer arithmetic to calculate the
* expected pack size to ~4 significant digits without
* overflow for packsizes less that 1PB.
*/
expected_size = (uint64_t)pack_info[i].referenced_objects << 14;
expected_size /= p->num_objects;
expected_size = u64_mult(expected_size, p->pack_size);
expected_size = u64_add(expected_size, 1u << 13) >> 14;

if (expected_size >= batch_size)
continue;

total_size += expected_size;
if (unsigned_add_overflows(total_size, (size_t)expected_size))
total_size = SIZE_MAX;
else
total_size += expected_size;

include_pack[pack_int_id] = 1;
}

Expand Down
12 changes: 10 additions & 2 deletions midx.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "pack-bitmap.h"
#include "pack-revindex.h"

#define MIDX_PACK_ERROR ((void *)(intptr_t)-1)

int midx_checksum_valid(struct multi_pack_index *m);
void clear_midx_files_ext(const char *object_dir, const char *ext,
const char *keep_hash);
Expand Down Expand Up @@ -405,7 +407,7 @@ void close_midx(struct multi_pack_index *m)
munmap((unsigned char *)m->data, m->data_len);

for (i = 0; i < m->num_packs; i++) {
if (m->packs[i])
if (m->packs[i] && m->packs[i] != MIDX_PACK_ERROR)
m->packs[i]->multi_pack_index = 0;
}
FREE_AND_NULL(m->packs);
Expand Down Expand Up @@ -458,6 +460,8 @@ int prepare_midx_pack(struct repository *r, struct multi_pack_index *m,

pack_int_id = midx_for_pack(&m, pack_int_id);

if (m->packs[pack_int_id] == MIDX_PACK_ERROR)
return 1;
if (m->packs[pack_int_id])
return 0;

Expand All @@ -482,8 +486,10 @@ int prepare_midx_pack(struct repository *r, struct multi_pack_index *m,
strbuf_release(&pack_name);
strbuf_release(&key);

if (!p)
if (!p) {
m->packs[pack_int_id] = MIDX_PACK_ERROR;
return 1;
}

p->multi_pack_index = 1;
m->packs[pack_int_id] = p;
Expand All @@ -495,6 +501,8 @@ struct packed_git *nth_midxed_pack(struct multi_pack_index *m,
uint32_t pack_int_id)
{
uint32_t local_pack_int_id = midx_for_pack(&m, pack_int_id);
if (m->packs[local_pack_int_id] == MIDX_PACK_ERROR)
return NULL;
return m->packs[local_pack_int_id];
}

Expand Down
6 changes: 4 additions & 2 deletions name-hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,8 +492,10 @@ static void *lazy_name_thread_proc(void *_data)
for (k = 0; k < d->istate->cache_nr; k++) {
struct cache_entry *ce_k = d->istate->cache[k];
ce_k->ce_flags |= CE_HASHED;
hashmap_entry_init(&ce_k->ent, d->lazy_entries[k].hash_name);
hashmap_add(&d->istate->name_hash, &ce_k->ent);
if (!S_ISSPARSEDIR(ce_k->ce_mode)) {
hashmap_entry_init(&ce_k->ent, d->lazy_entries[k].hash_name);
hashmap_add(&d->istate->name_hash, &ce_k->ent);
}
}

return NULL;
Expand Down
11 changes: 11 additions & 0 deletions packfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,17 @@ struct packed_git *add_packed_git(struct repository *r, const char *path,
p = alloc_packed_git(r, alloc);
memcpy(p->pack_name, path, path_len);

/*
* Note that we have to check auxiliary data structures before we check
* for the ".pack" file to exist to avoid races with a packfile that is
* in the process of being deleted. The ".pack" file is unlinked before
* its auxiliary data structures, so we know that we either get a
* consistent snapshot of all data structures or that we'll fail to
* stat(3p) the packfile itself and thus return `NULL`.
*
* As such, we cannot bail out before the access(3p) calls in case the
* packfile doesn't exist without doing two stat(3p) calls for it.
*/
xsnprintf(p->pack_name + path_len, alloc - path_len, ".keep");
if (!access(p->pack_name, F_OK))
p->pack_keep = 1;
Expand Down
Loading