Skip to content

Commit

Permalink
Apply some v2.48 regression bugfixes (#5376)
Browse files Browse the repository at this point in the history
Now that most of the Git contributors are back from the holidays, there
is an influx of bug fixes. This is precisely why I held off from rushing
Git for Windows v2.48.0 out the door.

These bug fixes are mostly taken from upstream's branches; In some
cases, though, I had to apply them directly from the Git mailing list
because they did not make it into git/git yet.

I deem those bug fixes necessary to get Git for Windows into a somewhat
healthy state again.
  • Loading branch information
dscho authored Jan 23, 2025
2 parents f045ed3 + 290ad15 commit 0c796d3
Show file tree
Hide file tree
Showing 44 changed files with 519 additions and 236 deletions.
2 changes: 1 addition & 1 deletion Documentation/git-show-index.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ git-show-index - Show packed archive index
SYNOPSIS
--------
[verse]
'git show-index' [--object-format=<hash-algorithm>]
'git show-index' [--object-format=<hash-algorithm>] < <pack-idx-file>


DESCRIPTION
Expand Down
3 changes: 1 addition & 2 deletions builtin/branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
if (verify_ref_format(format))
die(_("unable to parse format string"));

filter_ahead_behind(the_repository, format, &array);
filter_ahead_behind(the_repository, &array);
ref_array_sort(sorting, &array);

if (column_active(colopts)) {
Expand Down Expand Up @@ -884,7 +884,6 @@ int cmd_branch(int argc,
string_list_clear(&output, 0);
ref_sorting_release(sorting);
ref_filter_clear(&filter);
ref_format_clear(&format);

ret = 0;
goto out;
Expand Down
4 changes: 2 additions & 2 deletions builtin/credential-cache--daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,9 @@ static void serve_one_client(FILE *in, FILE *out)
fprintf(out, "username=%s\n", e->item.username);
if (e->item.password)
fprintf(out, "password=%s\n", e->item.password);
if (credential_has_capability(&c.capa_authtype, CREDENTIAL_OP_HELPER) && e->item.authtype)
if (credential_has_capability(&c.capa_authtype, CREDENTIAL_OP_RESPONSE) && e->item.authtype)
fprintf(out, "authtype=%s\n", e->item.authtype);
if (credential_has_capability(&c.capa_authtype, CREDENTIAL_OP_HELPER) && e->item.credential)
if (credential_has_capability(&c.capa_authtype, CREDENTIAL_OP_RESPONSE) && e->item.credential)
fprintf(out, "credential=%s\n", e->item.credential);
if (e->item.password_expiry_utc != TIME_MAX)
fprintf(out, "password_expiry_utc=%"PRItime"\n",
Expand Down
15 changes: 8 additions & 7 deletions builtin/fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -1618,9 +1618,9 @@ static void report_set_head(const char *remote, const char *head_name,
}

static int set_head(const struct ref *remote_refs, int follow_remote_head,
const char *no_warn_branch)
const char *no_warn_branch, int mirror)
{
int result = 0, create_only, is_bare, was_detached;
int result = 0, create_only, baremirror, was_detached;
struct strbuf b_head = STRBUF_INIT, b_remote_head = STRBUF_INIT,
b_local_head = STRBUF_INIT;
const char *remote = gtransport->remote->name;
Expand Down Expand Up @@ -1655,17 +1655,17 @@ static int set_head(const struct ref *remote_refs, int follow_remote_head,

if (!head_name)
goto cleanup;
is_bare = is_bare_repository();
create_only = follow_remote_head == FOLLOW_REMOTE_ALWAYS ? 0 : !is_bare;
if (is_bare) {
baremirror = is_bare_repository() && mirror;
create_only = follow_remote_head == FOLLOW_REMOTE_ALWAYS ? 0 : !baremirror;
if (baremirror) {
strbuf_addstr(&b_head, "HEAD");
strbuf_addf(&b_remote_head, "refs/heads/%s", head_name);
} else {
strbuf_addf(&b_head, "refs/remotes/%s/HEAD", remote);
strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", remote, head_name);
}
/* make sure it's valid */
if (!is_bare && !refs_ref_exists(refs, b_remote_head.buf)) {
if (!baremirror && !refs_ref_exists(refs, b_remote_head.buf)) {
result = 1;
goto cleanup;
}
Expand Down Expand Up @@ -1925,7 +1925,8 @@ static int do_fetch(struct transport *transport,
}
}
if (set_head(remote_refs, transport->remote->follow_remote_head,
transport->remote->no_warn_branch))
transport->remote->no_warn_branch,
transport->remote->mirror))
;
/*
* Way too many cases where this can go wrong
Expand Down
1 change: 0 additions & 1 deletion builtin/for-each-ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ int cmd_for_each_ref(int argc,
filter_and_format_refs(&filter, flags, sorting, &format);

ref_filter_clear(&filter);
ref_format_clear(&format);
ref_sorting_release(sorting);
strvec_clear(&vec);
return 0;
Expand Down
30 changes: 12 additions & 18 deletions builtin/index-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,16 +379,18 @@ static const char *open_pack_file(const char *pack_name)

static void parse_pack_header(void)
{
struct pack_header *hdr = fill(sizeof(struct pack_header));
unsigned char *hdr = fill(sizeof(struct pack_header));

/* Header consistency check */
if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
if (get_be32(hdr) != PACK_SIGNATURE)
die(_("pack signature mismatch"));
if (!pack_version_ok(hdr->hdr_version))
hdr += 4;
if (!pack_version_ok_native(get_be32(hdr)))
die(_("pack version %"PRIu32" unsupported"),
ntohl(hdr->hdr_version));
get_be32(hdr));
hdr += 4;

nr_objects = ntohl(hdr->hdr_entries);
nr_objects = get_be32(hdr);
use(sizeof(struct pack_header));
}

Expand Down Expand Up @@ -1954,19 +1956,11 @@ int cmd_index_pack(int argc,
warning(_("no threads support, ignoring %s"), arg);
nr_threads = 1;
}
} else if (starts_with(arg, "--pack_header=")) {
struct pack_header *hdr;
char *c;

hdr = (struct pack_header *)input_buffer;
hdr->hdr_signature = htonl(PACK_SIGNATURE);
hdr->hdr_version = htonl(strtoul(arg + 14, &c, 10));
if (*c != ',')
die(_("bad %s"), arg);
hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10));
if (*c)
die(_("bad %s"), arg);
input_len = sizeof(*hdr);
} else if (skip_prefix(arg, "--pack_header=", &arg)) {
if (parse_pack_header_option(arg,
input_buffer,
&input_len) < 0)
die(_("bad --pack_header: %s"), arg);
} else if (!strcmp(arg, "-v")) {
verbose = 1;
} else if (!strcmp(arg, "--progress-title")) {
Expand Down
2 changes: 1 addition & 1 deletion builtin/show-index.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "parse-options.h"

static const char *const show_index_usage[] = {
"git show-index [--object-format=<hash-algorithm>]",
"git show-index [--object-format=<hash-algorithm>] < <pack-idx-file>",
NULL
};

Expand Down
1 change: 0 additions & 1 deletion builtin/tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,6 @@ int cmd_tag(int argc,
cleanup:
ref_sorting_release(sorting);
ref_filter_clear(&filter);
ref_format_clear(&format);
strbuf_release(&buf);
strbuf_release(&ref);
strbuf_release(&reflog_msg);
Expand Down
31 changes: 12 additions & 19 deletions builtin/unpack-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "progress.h"
#include "decorate.h"
#include "fsck.h"
#include "packfile.h"

static int dry_run, quiet, recover, has_errors, strict;
static const char unpack_usage[] = "git unpack-objects [-n] [-q] [-r] [--strict]";
Expand Down Expand Up @@ -578,15 +579,16 @@ static void unpack_one(unsigned nr)
static void unpack_all(void)
{
int i;
struct pack_header *hdr = fill(sizeof(struct pack_header));
unsigned char *hdr = fill(sizeof(struct pack_header));

nr_objects = ntohl(hdr->hdr_entries);

if (ntohl(hdr->hdr_signature) != PACK_SIGNATURE)
if (get_be32(hdr) != PACK_SIGNATURE)
die("bad pack file");
if (!pack_version_ok(hdr->hdr_version))
hdr += 4;
if (!pack_version_ok_native(get_be32(hdr)))
die("unknown pack file version %"PRIu32,
ntohl(hdr->hdr_version));
get_be32(hdr));
hdr += 4;
nr_objects = get_be32(hdr);
use(sizeof(struct pack_header));

if (!quiet)
Expand Down Expand Up @@ -644,19 +646,10 @@ int cmd_unpack_objects(int argc,
fsck_set_msg_types(&fsck_options, arg);
continue;
}
if (starts_with(arg, "--pack_header=")) {
struct pack_header *hdr;
char *c;

hdr = (struct pack_header *)buffer;
hdr->hdr_signature = htonl(PACK_SIGNATURE);
hdr->hdr_version = htonl(strtoul(arg + 14, &c, 10));
if (*c != ',')
die("bad %s", arg);
hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10));
if (*c)
die("bad %s", arg);
len = sizeof(*hdr);
if (skip_prefix(arg, "--pack_header=", &arg)) {
if (parse_pack_header_option(arg,
buffer, &len) < 0)
die(_("bad --pack_header: %s"), arg);
continue;
}
if (skip_prefix(arg, "--max-input-size=", &arg)) {
Expand Down
1 change: 0 additions & 1 deletion builtin/verify-tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,5 @@ int cmd_verify_tag(int argc,
if (format.format)
pretty_print_ref(name, &oid, &format);
}
ref_format_clear(&format);
return had_error;
}
24 changes: 12 additions & 12 deletions compat/bswap.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,23 +183,23 @@ static inline uint64_t get_be64(const void *ptr)
static inline void put_be32(void *ptr, uint32_t value)
{
unsigned char *p = ptr;
p[0] = value >> 24;
p[1] = value >> 16;
p[2] = value >> 8;
p[3] = value >> 0;
p[0] = (value >> 24) & 0xff;
p[1] = (value >> 16) & 0xff;
p[2] = (value >> 8) & 0xff;
p[3] = (value >> 0) & 0xff;
}

static inline void put_be64(void *ptr, uint64_t value)
{
unsigned char *p = ptr;
p[0] = value >> 56;
p[1] = value >> 48;
p[2] = value >> 40;
p[3] = value >> 32;
p[4] = value >> 24;
p[5] = value >> 16;
p[6] = value >> 8;
p[7] = value >> 0;
p[0] = (value >> 56) & 0xff;
p[1] = (value >> 48) & 0xff;
p[2] = (value >> 40) & 0xff;
p[3] = (value >> 32) & 0xff;
p[4] = (value >> 24) & 0xff;
p[5] = (value >> 16) & 0xff;
p[6] = (value >> 8) & 0xff;
p[7] = (value >> 0) & 0xff;
}

#endif /* COMPAT_BSWAP_H */
2 changes: 2 additions & 0 deletions grep.c
Original file line number Diff line number Diff line change
Expand Up @@ -1646,6 +1646,8 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle

bol = gs->buf;
left = gs->size;
if (left && gs->buf[left-1] == '\n')
left--;
while (left) {
const char *eol;
int hit;
Expand Down
66 changes: 42 additions & 24 deletions object-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1970,54 +1970,59 @@ static void write_object_file_prepare_literally(const struct git_hash_algo *algo
hash_object_body(algo, &c, buf, len, oid, hdr, hdrlen);
}

static int check_collision(const char *filename_a, const char *filename_b)
#define CHECK_COLLISION_DEST_VANISHED -2

static int check_collision(const char *source, const char *dest)
{
char buf_a[4096], buf_b[4096];
int fd_a = -1, fd_b = -1;
char buf_source[4096], buf_dest[4096];
int fd_source = -1, fd_dest = -1;
int ret = 0;

fd_a = open(filename_a, O_RDONLY);
if (fd_a < 0) {
ret = error_errno(_("unable to open %s"), filename_a);
fd_source = open(source, O_RDONLY);
if (fd_source < 0) {
ret = error_errno(_("unable to open %s"), source);
goto out;
}

fd_b = open(filename_b, O_RDONLY);
if (fd_b < 0) {
ret = error_errno(_("unable to open %s"), filename_b);
fd_dest = open(dest, O_RDONLY);
if (fd_dest < 0) {
if (errno != ENOENT)
ret = error_errno(_("unable to open %s"), dest);
else
ret = CHECK_COLLISION_DEST_VANISHED;
goto out;
}

while (1) {
ssize_t sz_a, sz_b;

sz_a = read_in_full(fd_a, buf_a, sizeof(buf_a));
sz_a = read_in_full(fd_source, buf_source, sizeof(buf_source));
if (sz_a < 0) {
ret = error_errno(_("unable to read %s"), filename_a);
ret = error_errno(_("unable to read %s"), source);
goto out;
}

sz_b = read_in_full(fd_b, buf_b, sizeof(buf_b));
sz_b = read_in_full(fd_dest, buf_dest, sizeof(buf_dest));
if (sz_b < 0) {
ret = error_errno(_("unable to read %s"), filename_b);
ret = error_errno(_("unable to read %s"), dest);
goto out;
}

if (sz_a != sz_b || memcmp(buf_a, buf_b, sz_a)) {
if (sz_a != sz_b || memcmp(buf_source, buf_dest, sz_a)) {
ret = error(_("files '%s' and '%s' differ in contents"),
filename_a, filename_b);
source, dest);
goto out;
}

if (sz_a < sizeof(buf_a))
if (sz_a < sizeof(buf_source))
break;
}

out:
if (fd_a > -1)
close(fd_a);
if (fd_b > -1)
close(fd_b);
if (fd_source > -1)
close(fd_source);
if (fd_dest > -1)
close(fd_dest);
return ret;
}

Expand All @@ -2032,8 +2037,11 @@ int finalize_object_file(const char *tmpfile, const char *filename)
int finalize_object_file_flags(const char *tmpfile, const char *filename,
enum finalize_object_file_flags flags)
{
struct stat st;
int ret = 0;
unsigned retries = 0;
int ret;

retry:
ret = 0;

if (object_creation_mode == OBJECT_CREATION_USES_RENAMES)
goto try_rename;
Expand All @@ -2054,6 +2062,8 @@ int finalize_object_file_flags(const char *tmpfile, const char *filename,
* left to unlink.
*/
if (ret && ret != EEXIST) {
struct stat st;

try_rename:
if (!stat(filename, &st))
ret = EEXIST;
Expand All @@ -2069,9 +2079,17 @@ int finalize_object_file_flags(const char *tmpfile, const char *filename,
errno = saved_errno;
return error_errno(_("unable to write file %s"), filename);
}
if (!(flags & FOF_SKIP_COLLISION_CHECK) &&
check_collision(tmpfile, filename))
if (!(flags & FOF_SKIP_COLLISION_CHECK)) {
ret = check_collision(tmpfile, filename);
if (ret == CHECK_COLLISION_DEST_VANISHED) {
if (retries++ > 5)
return error(_("unable to write repeatedly vanishing file %s"),
filename);
goto retry;
}
else if (ret)
return -1;
}
unlink_or_warn(tmpfile);
}

Expand Down
Loading

0 comments on commit 0c796d3

Please sign in to comment.