* fatal: Not a valid object name HEAD
@ 2025-01-11 19:26 Christian Hesse
2025-01-12 14:17 ` Bence Ferdinandy
2025-01-12 16:51 ` [PATCH] fetch set_head: fix non-mirror remotes in bare repositories Bence Ferdinandy
0 siblings, 2 replies; 18+ messages in thread
From: Christian Hesse @ 2025-01-11 19:26 UTC (permalink / raw)
To: Git Mailing List; +Cc: Christian Hesse
[-- Attachment #1: Type: text/plain, Size: 1871 bytes --]
Hello everybody,
starting with Git 2.48.0 I see some trouble with some mirrored bare
repositories. Try this:
box ~ % git clone --mirror https://github.com/codership/galera.git
Cloning into bare repository 'galera.git'...
remote: Enumerating objects: 49768, done.
remote: Counting objects: 100% (2251/2251), done.
remote: Compressing objects: 100% (553/553), done.
remote: Total 49768 (delta 1986), reused 1716 (delta 1698), pack-reused 47517 (from 3)
Receiving objects: 100% (49768/49768), 25.20 MiB | 4.92 MiB/s, done.
Resolving deltas: 100% (37386/37386), done.
box ~ % cd galera.git
box ~/galera.git (git)-[4.x] % git describe
release_26.4.5-345-gd811a577
box ~/galera.git (git)-[4.x] % git remote add mariadb https://github.com/MariaDB/galera.git
box ~/galera.git (git)-[4.x] % git fetch --all
Fetching origin
Fetching mariadb
remote: Enumerating objects: 638, done.
remote: Counting objects: 100% (517/517), done.
remote: Compressing objects: 100% (125/125), done.
remote: Total 638 (delta 415), reused 454 (delta 392), pack-reused 121 (from 3)
Receiving objects: 100% (638/638), 386.30 KiB | 5.08 MiB/s, done.
Resolving deltas: 100% (440/440), completed with 105 local objects.
From https://github.com/MariaDB/galera
* [new branch] 0.6 -> mariadb/0.6
[ snipped some more branches and tags ]
box ~/galera.git (git)-[mariadb-4.x] % git describe
fatal: Not a valid object name HEAD
Guess that's not expected... Why does that happen?
Possibly fallout caused by https://github.com/git/git/commit/5f212684abb66c9604e745a2296af8c4bb99961c
--
main(a){char*c=/* Schoene Gruesse */"B?IJj;MEH"
"CX:;",b;for(a/* Best regards my address: */=0;b=c[a++];)
putchar(b-1/(/* Chris cc -ox -xc - && ./x */b/42*2-3)*42);}
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: fatal: Not a valid object name HEAD 2025-01-11 19:26 fatal: Not a valid object name HEAD Christian Hesse @ 2025-01-12 14:17 ` Bence Ferdinandy 2025-01-13 16:30 ` Junio C Hamano 2025-01-12 16:51 ` [PATCH] fetch set_head: fix non-mirror remotes in bare repositories Bence Ferdinandy 1 sibling, 1 reply; 18+ messages in thread From: Bence Ferdinandy @ 2025-01-12 14:17 UTC (permalink / raw) To: Christian Hesse, Git Mailing List; +Cc: Christian Hesse On Sat Jan 11, 2025 at 20:26, Christian Hesse <list@eworm.de> wrote: > Hello everybody, > > starting with Git 2.48.0 I see some trouble with some mirrored bare > repositories. Try this: > > box ~ % git clone --mirror https://github.com/codership/galera.git > Cloning into bare repository 'galera.git'... > remote: Enumerating objects: 49768, done. > remote: Counting objects: 100% (2251/2251), done. > remote: Compressing objects: 100% (553/553), done. > remote: Total 49768 (delta 1986), reused 1716 (delta 1698), pack-reused 47517 (from 3) > Receiving objects: 100% (49768/49768), 25.20 MiB | 4.92 MiB/s, done. > Resolving deltas: 100% (37386/37386), done. > box ~ % cd galera.git > box ~/galera.git (git)-[4.x] % git describe > release_26.4.5-345-gd811a577 > box ~/galera.git (git)-[4.x] % git remote add mariadb https://github.com/MariaDB/galera.git > box ~/galera.git (git)-[4.x] % git fetch --all > Fetching origin > Fetching mariadb > remote: Enumerating objects: 638, done. > remote: Counting objects: 100% (517/517), done. > remote: Compressing objects: 100% (125/125), done. > remote: Total 638 (delta 415), reused 454 (delta 392), pack-reused 121 (from 3) > Receiving objects: 100% (638/638), 386.30 KiB | 5.08 MiB/s, done. > Resolving deltas: 100% (440/440), completed with 105 local objects. > From https://github.com/MariaDB/galera > * [new branch] 0.6 -> mariadb/0.6 > [ snipped some more branches and tags ] > box ~/galera.git (git)-[mariadb-4.x] % git describe > fatal: Not a valid object name HEAD > > Guess that's not expected... Why does that happen? > > Possibly fallout caused by https://github.com/git/git/commit/5f212684abb66c9604e745a2296af8c4bb99961c More specifically: https://github.com/git/git/commit/b1b713f722894d7f66e9ec64bc934ca32004d3d1 So what happened before the series is that HEAD was set on cloning to ref: refs/heads/4.x and the adding the new remote did not change this. After the series fetching the new remote will overwrite HEAD to ref: refs/heads/mariadb-4.x which does not exist in the repository. Note that the older version does not set up `refs/remotes/mariadb/HEAD` which is interesting? I think the correct way to handle this would be to check if the remote has `mirror=true` set, and if we're running in a bare repository we should overwrite HEAD and if it's not a mirror we should instead set up `refs/remotes/nonmirrorremote/HEAD`. (I think a remote can be a mirror without the repository being bare, I'm not sure.) I can probably send a patch late next week to fix this. Best, Bence ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: fatal: Not a valid object name HEAD 2025-01-12 14:17 ` Bence Ferdinandy @ 2025-01-13 16:30 ` Junio C Hamano 0 siblings, 0 replies; 18+ messages in thread From: Junio C Hamano @ 2025-01-13 16:30 UTC (permalink / raw) To: Bence Ferdinandy; +Cc: Christian Hesse, Git Mailing List, Christian Hesse "Bence Ferdinandy" <bence@ferdinandy.com> writes: > I think the correct way to handle this would be to check if the remote has > `mirror=true` set, and if we're running in a bare repository we should overwrite > HEAD and if it's not a mirror we should instead set up > `refs/remotes/nonmirrorremote/HEAD`. (I think a remote can be a mirror without > the repository being bare, I'm not sure.) A non-bare repository can technically be a mirror but such a thing is only useful when (1) it never fetches from anywhere afterwards, (2) it stays on a branch that never changes by convention, or (3) it stays on a detached HEAD. Otherwise "git fetch" in it would almost always fail. Practically (1) and (2) are not all that useful---such a static checkout does not even have to be a Git repository but a tarball extract. If you overwrite HEAD upon fetch, you will render the last remaining useful usage, (3), also useless. Thanks. ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH] fetch set_head: fix non-mirror remotes in bare repositories 2025-01-11 19:26 fatal: Not a valid object name HEAD Christian Hesse 2025-01-12 14:17 ` Bence Ferdinandy @ 2025-01-12 16:51 ` Bence Ferdinandy 2025-01-23 21:00 ` Junio C Hamano 2025-01-24 5:56 ` Patrick Steinhardt 1 sibling, 2 replies; 18+ messages in thread From: Bence Ferdinandy @ 2025-01-12 16:51 UTC (permalink / raw) To: git; +Cc: Christian Hesse, Christian Hesse, Bence Ferdinandy In b1b713f722 (fetch set_head: handle mirrored bare repositories, 2024-11-22) it was implicitly assumed that all remotes will be mirrors in a bare repository, thus fetching a non-mirrored remote could lead to HEAD pointing to a non-existent reference. Make sure we only overwrite HEAD if we are in a bare repository and fetching from a mirror. Otherwise, proceed as normally, and create refs/remotes/<nonmirrorremote>/HEAD instead. Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com> Reported-by: Christian Hesse <list@eworm.de> --- builtin/fetch.c | 15 ++++++++------- t/t5505-remote.sh | 10 ++++++++++ t/t5510-fetch.sh | 13 +++++++++++++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/builtin/fetch.c b/builtin/fetch.c index fe2b26c74a..625d45be8b 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -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; @@ -1655,9 +1655,9 @@ 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 { @@ -1665,7 +1665,7 @@ static int set_head(const struct ref *remote_refs, int follow_remote_head, 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; } @@ -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 diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 519f7973e3..c75cfe968f 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -589,6 +589,16 @@ test_expect_success 'add --mirror setting HEAD' ' ) ' +test_expect_success 'non-mirror fetch does not interfere with mirror' ' + mkdir headnotmain && + ( + cd headnotmain && + git init --bare -b notmain && + git remote add -f other ../two && + test "$(git symbolic-ref HEAD)" = "refs/heads/notmain" + ) +' + test_expect_success 'add --mirror=fetch' ' mkdir mirror-fetch && git init -b main mirror-fetch/parent && diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 2d9587059f..cfa63ae086 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -84,6 +84,19 @@ test_expect_success "fetch test remote HEAD" ' branch=$(git rev-parse refs/remotes/origin/main) && test "z$head" = "z$branch"' +test_expect_success "fetch test remote HEAD in bare repository" ' + cd "$D" && + git init --bare barerepo && + cd barerepo && + git remote add upstream ../two && + git fetch upstream && + git rev-parse --verify refs/remotes/upstream/HEAD && + git rev-parse --verify refs/remotes/upstream/main && + head=$(git rev-parse refs/remotes/upstream/HEAD) && + branch=$(git rev-parse refs/remotes/upstream/main) && + test "z$head" = "z$branch"' + + test_expect_success "fetch test remote HEAD change" ' cd "$D" && cd two && base-commit: fbe8d3079d4a96aeb4e4529cc93cc0043b759a05 -- 2.48.0.1.g32c193c8ca ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH] fetch set_head: fix non-mirror remotes in bare repositories 2025-01-12 16:51 ` [PATCH] fetch set_head: fix non-mirror remotes in bare repositories Bence Ferdinandy @ 2025-01-23 21:00 ` Junio C Hamano 2025-01-23 21:42 ` Bence Ferdinandy 2025-01-24 14:07 ` Christian Hesse 2025-01-24 5:56 ` Patrick Steinhardt 1 sibling, 2 replies; 18+ messages in thread From: Junio C Hamano @ 2025-01-23 21:00 UTC (permalink / raw) To: Christian Hesse, Christian Hesse, Bence Ferdinandy; +Cc: git Bence Ferdinandy <bence@ferdinandy.com> writes: > In b1b713f722 (fetch set_head: handle mirrored bare repositories, > 2024-11-22) it was implicitly assumed that all remotes will be mirrors > in a bare repository, thus fetching a non-mirrored remote could lead to > HEAD pointing to a non-existent reference. Make sure we only overwrite > HEAD if we are in a bare repository and fetching from a mirror. > Otherwise, proceed as normally, and create > refs/remotes/<nonmirrorremote>/HEAD instead. > > Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com> > Reported-by: Christian Hesse <list@eworm.de> These should be chronological; somebody reports an issue, the patch gets written, and finally it is sent out with a Sign-off to certify that the patch is not a stolen property. > --- > builtin/fetch.c | 15 ++++++++------- > t/t5505-remote.sh | 10 ++++++++++ > t/t5510-fetch.sh | 13 +++++++++++++ > 3 files changed, 31 insertions(+), 7 deletions(-) We haven't heard from Chritian; has this been tested OK? What the patch does does look sensible. Thanks. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] fetch set_head: fix non-mirror remotes in bare repositories 2025-01-23 21:00 ` Junio C Hamano @ 2025-01-23 21:42 ` Bence Ferdinandy 2025-01-23 22:00 ` Eric Sunshine 2025-01-24 14:07 ` Christian Hesse 1 sibling, 1 reply; 18+ messages in thread From: Bence Ferdinandy @ 2025-01-23 21:42 UTC (permalink / raw) To: Junio C Hamano, Christian Hesse, Christian Hesse; +Cc: git On Thu Jan 23, 2025 at 22:00, Junio C Hamano <gitster@pobox.com> wrote: > Bence Ferdinandy <bence@ferdinandy.com> writes: > >> In b1b713f722 (fetch set_head: handle mirrored bare repositories, >> 2024-11-22) it was implicitly assumed that all remotes will be mirrors >> in a bare repository, thus fetching a non-mirrored remote could lead to >> HEAD pointing to a non-existent reference. Make sure we only overwrite >> HEAD if we are in a bare repository and fetching from a mirror. >> Otherwise, proceed as normally, and create >> refs/remotes/<nonmirrorremote>/HEAD instead. >> >> Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com> >> Reported-by: Christian Hesse <list@eworm.de> > > These should be chronological; somebody reports an issue, the patch > gets written, and finally it is sent out with a Sign-off to certify > that the patch is not a stolen property. Makes sense, I'll send a v2 in that case. > >> --- >> builtin/fetch.c | 15 ++++++++------- >> t/t5505-remote.sh | 10 ++++++++++ >> t/t5510-fetch.sh | 13 +++++++++++++ >> 3 files changed, 31 insertions(+), 7 deletions(-) > > We haven't heard from Chritian; has this been tested OK? To the extent of the tests I've added, but I'm not aware of anybody else, especially Christian trying it out. > > What the patch does does look sensible. Thanks. Thanks, Bence ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] fetch set_head: fix non-mirror remotes in bare repositories 2025-01-23 21:42 ` Bence Ferdinandy @ 2025-01-23 22:00 ` Eric Sunshine 0 siblings, 0 replies; 18+ messages in thread From: Eric Sunshine @ 2025-01-23 22:00 UTC (permalink / raw) To: Bence Ferdinandy; +Cc: Junio C Hamano, Christian Hesse, Christian Hesse, git On Thu, Jan 23, 2025 at 4:48 PM Bence Ferdinandy <bence@ferdinandy.com> wrote: > On Thu Jan 23, 2025 at 22:00, Junio C Hamano <gitster@pobox.com> wrote: > > Bence Ferdinandy <bence@ferdinandy.com> writes: > >> Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com> > >> Reported-by: Christian Hesse <list@eworm.de> > > > > These should be chronological; somebody reports an issue, the patch > > gets written, and finally it is sent out with a Sign-off to certify > > that the patch is not a stolen property. > > Makes sense, I'll send a v2 in that case. It's a good idea to check whether Junio has himself fixed this sort of thing when queuing your patch. (In this case, it appears that he has.) ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] fetch set_head: fix non-mirror remotes in bare repositories 2025-01-23 21:00 ` Junio C Hamano 2025-01-23 21:42 ` Bence Ferdinandy @ 2025-01-24 14:07 ` Christian Hesse 2025-01-24 17:17 ` Junio C Hamano 1 sibling, 1 reply; 18+ messages in thread From: Christian Hesse @ 2025-01-24 14:07 UTC (permalink / raw) To: Junio C Hamano; +Cc: Christian Hesse, Bence Ferdinandy, git [-- Attachment #1: Type: text/plain, Size: 1554 bytes --] Junio C Hamano <gitster@pobox.com> on Thu, 2025/01/23 13:00: > Bence Ferdinandy <bence@ferdinandy.com> writes: > > > In b1b713f722 (fetch set_head: handle mirrored bare repositories, > > 2024-11-22) it was implicitly assumed that all remotes will be mirrors > > in a bare repository, thus fetching a non-mirrored remote could lead to > > HEAD pointing to a non-existent reference. Make sure we only overwrite > > HEAD if we are in a bare repository and fetching from a mirror. > > Otherwise, proceed as normally, and create > > refs/remotes/<nonmirrorremote>/HEAD instead. > > > > Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com> > > Reported-by: Christian Hesse <list@eworm.de> > > These should be chronological; somebody reports an issue, the patch > gets written, and finally it is sent out with a Sign-off to certify > that the patch is not a stolen property. > > > --- > > builtin/fetch.c | 15 ++++++++------- > > t/t5505-remote.sh | 10 ++++++++++ > > t/t5510-fetch.sh | 13 +++++++++++++ > > 3 files changed, 31 insertions(+), 7 deletions(-) > > We haven't heard from Chritian; has this been tested OK? Sorry for the late reply... Yes, with this patch applied git behaves as expected for me. Thanks a lot! > What the patch does does look sensible. Thanks. -- main(a){char*c=/* Schoene Gruesse */"B?IJj;MEH" "CX:;",b;for(a/* Best regards my address: */=0;b=c[a++];) putchar(b-1/(/* Chris cc -ox -xc - && ./x */b/42*2-3)*42);} [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] fetch set_head: fix non-mirror remotes in bare repositories 2025-01-24 14:07 ` Christian Hesse @ 2025-01-24 17:17 ` Junio C Hamano 0 siblings, 0 replies; 18+ messages in thread From: Junio C Hamano @ 2025-01-24 17:17 UTC (permalink / raw) To: Christian Hesse; +Cc: Christian Hesse, Bence Ferdinandy, git Christian Hesse <list@eworm.de> writes: >> > --- >> > builtin/fetch.c | 15 ++++++++------- >> > t/t5505-remote.sh | 10 ++++++++++ >> > t/t5510-fetch.sh | 13 +++++++++++++ >> > 3 files changed, 31 insertions(+), 7 deletions(-) >> >> We haven't heard from Chritian; has this been tested OK? > > Sorry for the late reply... > > Yes, with this patch applied git behaves as expected for me. > Thanks a lot! Thanks. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] fetch set_head: fix non-mirror remotes in bare repositories 2025-01-12 16:51 ` [PATCH] fetch set_head: fix non-mirror remotes in bare repositories Bence Ferdinandy 2025-01-23 21:00 ` Junio C Hamano @ 2025-01-24 5:56 ` Patrick Steinhardt 2025-01-24 10:30 ` Eric Sunshine ` (3 more replies) 1 sibling, 4 replies; 18+ messages in thread From: Patrick Steinhardt @ 2025-01-24 5:56 UTC (permalink / raw) To: Bence Ferdinandy; +Cc: git, Christian Hesse, Christian Hesse On Sun, Jan 12, 2025 at 05:51:22PM +0100, Bence Ferdinandy wrote: > diff --git a/builtin/fetch.c b/builtin/fetch.c > index fe2b26c74a..625d45be8b 100644 > --- a/builtin/fetch.c > +++ b/builtin/fetch.c > @@ -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 Nit: At this point it might be sensible to simply pass in the remote itself, which would allow for an easier callsite and less risk of getting the order of parameters wrong. > diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh > index 519f7973e3..c75cfe968f 100755 > --- a/t/t5505-remote.sh > +++ b/t/t5505-remote.sh > @@ -589,6 +589,16 @@ test_expect_success 'add --mirror setting HEAD' ' > ) > ' > > +test_expect_success 'non-mirror fetch does not interfere with mirror' ' > + mkdir headnotmain && Nit: this can be simplified into `git init --bare -b notmain headnotmain` so that you don't have to create an empty directory first. Also, do we want to `test_when_finished rm -rf headnotmain` to clean up after ourselves? > + ( > + cd headnotmain && > + git init --bare -b notmain && > + git remote add -f other ../two && > + test "$(git symbolic-ref HEAD)" = "refs/heads/notmain" > + ) > +' > + > test_expect_success 'add --mirror=fetch' ' > mkdir mirror-fetch && > git init -b main mirror-fetch/parent && > diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh > index 2d9587059f..cfa63ae086 100755 > --- a/t/t5510-fetch.sh > +++ b/t/t5510-fetch.sh > @@ -84,6 +84,19 @@ test_expect_success "fetch test remote HEAD" ' > branch=$(git rev-parse refs/remotes/origin/main) && > test "z$head" = "z$branch"' > > +test_expect_success "fetch test remote HEAD in bare repository" ' > + cd "$D" && > + git init --bare barerepo && > + cd barerepo && The `cd` needs to happen in a subshell. ALso, the same comment here regarding whether we want to have `test_when_finished` to clean up state. > + git remote add upstream ../two && > + git fetch upstream && > + git rev-parse --verify refs/remotes/upstream/HEAD && > + git rev-parse --verify refs/remotes/upstream/main && > + head=$(git rev-parse refs/remotes/upstream/HEAD) && > + branch=$(git rev-parse refs/remotes/upstream/main) && > + test "z$head" = "z$branch"' The closing single-quote should be on its own line. I see though that you simply follow existing code style, both for the call to cd(1) and for the single-quote, so these are fine. This test file could use a makeover, but that is obviously outside of the scope of this patch series. Patrick ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] fetch set_head: fix non-mirror remotes in bare repositories 2025-01-24 5:56 ` Patrick Steinhardt @ 2025-01-24 10:30 ` Eric Sunshine 2025-01-24 16:07 ` Junio C Hamano ` (2 subsequent siblings) 3 siblings, 0 replies; 18+ messages in thread From: Eric Sunshine @ 2025-01-24 10:30 UTC (permalink / raw) To: Patrick Steinhardt Cc: Bence Ferdinandy, git, Christian Hesse, Christian Hesse On Fri, Jan 24, 2025 at 12:56 AM Patrick Steinhardt <ps@pks.im> wrote: > On Sun, Jan 12, 2025 at 05:51:22PM +0100, Bence Ferdinandy wrote: > > +test_expect_success "fetch test remote HEAD in bare repository" ' > > + cd "$D" && > > + git init --bare barerepo && > > + cd barerepo && > > The `cd` needs to happen in a subshell. ALso, the same comment here > regarding whether we want to have `test_when_finished` to clean up > state. By way of explanation regarding `cd` in a subshell, see [*]. [*]: https://lore.kernel.org/git/CAPig+cRsAPp1APNJ7W337UNtunETr+Lnn-RcGrAXEFUhN1APyA@mail.gmail.com/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] fetch set_head: fix non-mirror remotes in bare repositories 2025-01-24 5:56 ` Patrick Steinhardt 2025-01-24 10:30 ` Eric Sunshine @ 2025-01-24 16:07 ` Junio C Hamano 2025-01-26 22:01 ` Bence Ferdinandy 2025-01-26 22:01 ` Bence Ferdinandy 2025-01-26 22:02 ` [PATCH v2 1/2] fetch set_head: refactor to use remote directly Bence Ferdinandy 3 siblings, 1 reply; 18+ messages in thread From: Junio C Hamano @ 2025-01-24 16:07 UTC (permalink / raw) To: Patrick Steinhardt Cc: Bence Ferdinandy, git, Christian Hesse, Christian Hesse Patrick Steinhardt <ps@pks.im> writes: >> diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh >> index 2d9587059f..cfa63ae086 100755 >> --- a/t/t5510-fetch.sh >> +++ b/t/t5510-fetch.sh >> @@ -84,6 +84,19 @@ test_expect_success "fetch test remote HEAD" ' >> branch=$(git rev-parse refs/remotes/origin/main) && >> test "z$head" = "z$branch"' >> >> +test_expect_success "fetch test remote HEAD in bare repository" ' >> + cd "$D" && >> + git init --bare barerepo && >> + cd barerepo && > > The `cd` needs to happen in a subshell. ALso, the same comment here > regarding whether we want to have `test_when_finished` to clean up > state. Yes, indeed. The change to another script we saw earlier followed the "chdir around only in a subshell" pattern. > I see though that you simply follow existing code style, both for the > call to cd(1) and for the single-quote, so these are fine. This test > file could use a makeover, but that is obviously outside of the scope of > this patch series. Terminating quote can stay, but chdir is a correctness issue that may want to be addressed minimally (i.e. not making things worse, while leaving it for later to clean up the existing ones). Thanks. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] fetch set_head: fix non-mirror remotes in bare repositories 2025-01-24 16:07 ` Junio C Hamano @ 2025-01-26 22:01 ` Bence Ferdinandy 0 siblings, 0 replies; 18+ messages in thread From: Bence Ferdinandy @ 2025-01-26 22:01 UTC (permalink / raw) To: Junio C Hamano, Patrick Steinhardt; +Cc: git, Christian Hesse, Christian Hesse On Fri Jan 24, 2025 at 17:07, Junio C Hamano <gitster@pobox.com> wrote: > Patrick Steinhardt <ps@pks.im> writes: > >>> diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh >>> index 2d9587059f..cfa63ae086 100755 >>> --- a/t/t5510-fetch.sh >>> +++ b/t/t5510-fetch.sh >>> @@ -84,6 +84,19 @@ test_expect_success "fetch test remote HEAD" ' >>> branch=$(git rev-parse refs/remotes/origin/main) && >>> test "z$head" = "z$branch"' >>> >>> +test_expect_success "fetch test remote HEAD in bare repository" ' >>> + cd "$D" && >>> + git init --bare barerepo && >>> + cd barerepo && >> >> The `cd` needs to happen in a subshell. ALso, the same comment here >> regarding whether we want to have `test_when_finished` to clean up >> state. > > Yes, indeed. The change to another script we saw earlier followed > the "chdir around only in a subshell" pattern. > >> I see though that you simply follow existing code style, both for the >> call to cd(1) and for the single-quote, so these are fine. This test >> file could use a makeover, but that is obviously outside of the scope of >> this patch series. > > Terminating quote can stay, but chdir is a correctness issue that > may want to be addressed minimally (i.e. not making things worse, > while leaving it for later to clean up the existing ones). I'll be sending the fix with also the terminating quote fixed as well. Actually tests after this which I added for followremotehead followed the correct style so why not here as well ... 5505 remote also has some style issues that came up before so if I find some time I'll probably send a patches cleaning the up both. > > Thanks. -- bence.ferdinandy.com ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH] fetch set_head: fix non-mirror remotes in bare repositories 2025-01-24 5:56 ` Patrick Steinhardt 2025-01-24 10:30 ` Eric Sunshine 2025-01-24 16:07 ` Junio C Hamano @ 2025-01-26 22:01 ` Bence Ferdinandy 2025-01-26 22:02 ` [PATCH v2 1/2] fetch set_head: refactor to use remote directly Bence Ferdinandy 3 siblings, 0 replies; 18+ messages in thread From: Bence Ferdinandy @ 2025-01-26 22:01 UTC (permalink / raw) To: Patrick Steinhardt; +Cc: git, Christian Hesse, Christian Hesse On Fri Jan 24, 2025 at 06:56, Patrick Steinhardt <ps@pks.im> wrote: > On Sun, Jan 12, 2025 at 05:51:22PM +0100, Bence Ferdinandy wrote: >> diff --git a/builtin/fetch.c b/builtin/fetch.c >> index fe2b26c74a..625d45be8b 100644 >> --- a/builtin/fetch.c >> +++ b/builtin/fetch.c >> @@ -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 > > Nit: At this point it might be sensible to simply pass in the remote > itself, which would allow for an easier callsite and less risk of > getting the order of parameters wrong. Thanks, that's a really good point, not to mention inside set_head gtransport is used to also access remote, which seems a bit of an oversight. > >> diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh >> index 519f7973e3..c75cfe968f 100755 >> --- a/t/t5505-remote.sh >> +++ b/t/t5505-remote.sh >> @@ -589,6 +589,16 @@ test_expect_success 'add --mirror setting HEAD' ' >> ) >> ' >> >> +test_expect_success 'non-mirror fetch does not interfere with mirror' ' >> + mkdir headnotmain && > > Nit: this can be simplified into `git init --bare -b notmain > headnotmain` so that you don't have to create an empty directory first. > Also, do we want to `test_when_finished rm -rf headnotmain` to clean up > after ourselves? > >> + ( >> + cd headnotmain && >> + git init --bare -b notmain && >> + git remote add -f other ../two && >> + test "$(git symbolic-ref HEAD)" = "refs/heads/notmain" >> + ) >> +' >> + >> test_expect_success 'add --mirror=fetch' ' >> mkdir mirror-fetch && >> git init -b main mirror-fetch/parent && >> diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh >> index 2d9587059f..cfa63ae086 100755 >> --- a/t/t5510-fetch.sh >> +++ b/t/t5510-fetch.sh >> @@ -84,6 +84,19 @@ test_expect_success "fetch test remote HEAD" ' >> branch=$(git rev-parse refs/remotes/origin/main) && >> test "z$head" = "z$branch"' >> >> +test_expect_success "fetch test remote HEAD in bare repository" ' >> + cd "$D" && >> + git init --bare barerepo && >> + cd barerepo && > > The `cd` needs to happen in a subshell. ALso, the same comment here > regarding whether we want to have `test_when_finished` to clean up > state. > >> + git remote add upstream ../two && >> + git fetch upstream && >> + git rev-parse --verify refs/remotes/upstream/HEAD && >> + git rev-parse --verify refs/remotes/upstream/main && >> + head=$(git rev-parse refs/remotes/upstream/HEAD) && >> + branch=$(git rev-parse refs/remotes/upstream/main) && >> + test "z$head" = "z$branch"' > > The closing single-quote should be on its own line. > > I see though that you simply follow existing code style, both for the > call to cd(1) and for the single-quote, so these are fine. This test > file could use a makeover, but that is obviously outside of the scope of > this patch series. > > Patrick -- bence.ferdinandy.com ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 1/2] fetch set_head: refactor to use remote directly 2025-01-24 5:56 ` Patrick Steinhardt ` (2 preceding siblings ...) 2025-01-26 22:01 ` Bence Ferdinandy @ 2025-01-26 22:02 ` Bence Ferdinandy 2025-01-26 22:02 ` [PATCH v2 2/2] fetch set_head: fix non-mirror remotes in bare repositories Bence Ferdinandy 3 siblings, 1 reply; 18+ messages in thread From: Bence Ferdinandy @ 2025-01-26 22:02 UTC (permalink / raw) To: git; +Cc: Christian Hesse, Christian Hesse, Patrick Steinhardt, Bence Ferdinandy As a preparatory step to use even more properties from the remote struct, refactor set_head to take the entire struct as a parameter, instead of the necessary bits. This also allows consolidating the use of gtransport->remote in set_head, making the access of the remote's properties consistent in the function. Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com> --- Notes: v2: - new patch builtin/fetch.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/builtin/fetch.c b/builtin/fetch.c index fe2b26c74a..3167b055d1 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1617,13 +1617,13 @@ static void report_set_head(const char *remote, const char *head_name, strbuf_release(&buf_prefix); } -static int set_head(const struct ref *remote_refs, int follow_remote_head, - const char *no_warn_branch) +static int set_head(const struct ref *remote_refs, struct remote *remote) { int result = 0, create_only, is_bare, was_detached; struct strbuf b_head = STRBUF_INIT, b_remote_head = STRBUF_INIT, b_local_head = STRBUF_INIT; - const char *remote = gtransport->remote->name; + int follow_remote_head = remote->follow_remote_head; + const char *no_warn_branch = remote->no_warn_branch; char *head_name = NULL; struct ref *ref, *matches; struct ref *fetch_map = NULL, **fetch_map_tail = &fetch_map; @@ -1661,8 +1661,8 @@ static int set_head(const struct ref *remote_refs, int follow_remote_head, 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); + strbuf_addf(&b_head, "refs/remotes/%s/HEAD", remote->name); + strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", remote->name, head_name); } /* make sure it's valid */ if (!is_bare && !refs_ref_exists(refs, b_remote_head.buf)) { @@ -1678,7 +1678,7 @@ static int set_head(const struct ref *remote_refs, int follow_remote_head, if (verbosity >= 0 && follow_remote_head == FOLLOW_REMOTE_WARN && (!no_warn_branch || strcmp(no_warn_branch, head_name))) - report_set_head(remote, head_name, &b_local_head, was_detached); + report_set_head(remote->name, head_name, &b_local_head, was_detached); cleanup: free(head_name); @@ -1924,8 +1924,7 @@ static int do_fetch(struct transport *transport, "you need to specify exactly one branch with the --set-upstream option")); } } - if (set_head(remote_refs, transport->remote->follow_remote_head, - transport->remote->no_warn_branch)) + if (set_head(remote_refs, transport->remote)) ; /* * Way too many cases where this can go wrong -- 2.48.1.93.g276f59c085 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 2/2] fetch set_head: fix non-mirror remotes in bare repositories 2025-01-26 22:02 ` [PATCH v2 1/2] fetch set_head: refactor to use remote directly Bence Ferdinandy @ 2025-01-26 22:02 ` Bence Ferdinandy 2025-01-27 7:30 ` Patrick Steinhardt 0 siblings, 1 reply; 18+ messages in thread From: Bence Ferdinandy @ 2025-01-26 22:02 UTC (permalink / raw) To: git; +Cc: Christian Hesse, Christian Hesse, Patrick Steinhardt, Bence Ferdinandy In b1b713f722 (fetch set_head: handle mirrored bare repositories, 2024-11-22) it was implicitly assumed that all remotes will be mirrors in a bare repository, thus fetching a non-mirrored remote could lead to HEAD pointing to a non-existent reference. Make sure we only overwrite HEAD if we are in a bare repository and fetching from a mirror. Otherwise, proceed as normally, and create refs/remotes/<nonmirrorremote>/HEAD instead. Reported-by: Christian Hesse <list@eworm.de> Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com> --- Notes: v2: - fixed too many parameters to set_head - cleaned up the style of tests builtin/fetch.c | 10 +++++----- t/t5505-remote.sh | 10 ++++++++++ t/t5510-fetch.sh | 17 +++++++++++++++++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/builtin/fetch.c b/builtin/fetch.c index 3167b055d1..1c740d5aac 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1619,7 +1619,7 @@ static void report_set_head(const char *remote, const char *head_name, static int set_head(const struct ref *remote_refs, struct remote *remote) { - 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; int follow_remote_head = remote->follow_remote_head; @@ -1655,9 +1655,9 @@ static int set_head(const struct ref *remote_refs, struct remote *remote) 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() && remote->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 { @@ -1665,7 +1665,7 @@ static int set_head(const struct ref *remote_refs, struct remote *remote) strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", remote->name, 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; } diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 519f7973e3..66e373f71d 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -589,6 +589,16 @@ test_expect_success 'add --mirror setting HEAD' ' ) ' +test_expect_success 'non-mirror fetch does not interfere with mirror' ' + test_when_finished rm -rf headnotmain && + ( + git init --bare -b notmain headnotmain && + cd headnotmain && + git remote add -f other ../two && + test "$(git symbolic-ref HEAD)" = "refs/heads/notmain" + ) +' + test_expect_success 'add --mirror=fetch' ' mkdir mirror-fetch && git init -b main mirror-fetch/parent && diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 2d9587059f..c9d7b46c87 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -84,6 +84,23 @@ test_expect_success "fetch test remote HEAD" ' branch=$(git rev-parse refs/remotes/origin/main) && test "z$head" = "z$branch"' +test_expect_success "fetch test remote HEAD in bare repository" ' + test_when_finished rm -rf barerepo && + ( + cd "$D" && + git init --bare barerepo && + cd barerepo && + git remote add upstream ../two && + git fetch upstream && + git rev-parse --verify refs/remotes/upstream/HEAD && + git rev-parse --verify refs/remotes/upstream/main && + head=$(git rev-parse refs/remotes/upstream/HEAD) && + branch=$(git rev-parse refs/remotes/upstream/main) && + test "z$head" = "z$branch" + ) +' + + test_expect_success "fetch test remote HEAD change" ' cd "$D" && cd two && -- 2.48.1.93.g276f59c085 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v2 2/2] fetch set_head: fix non-mirror remotes in bare repositories 2025-01-26 22:02 ` [PATCH v2 2/2] fetch set_head: fix non-mirror remotes in bare repositories Bence Ferdinandy @ 2025-01-27 7:30 ` Patrick Steinhardt 2025-01-27 20:18 ` Junio C Hamano 0 siblings, 1 reply; 18+ messages in thread From: Patrick Steinhardt @ 2025-01-27 7:30 UTC (permalink / raw) To: Bence Ferdinandy; +Cc: git, Christian Hesse, Christian Hesse On Sun, Jan 26, 2025 at 11:02:11PM +0100, Bence Ferdinandy wrote: > In b1b713f722 (fetch set_head: handle mirrored bare repositories, > 2024-11-22) it was implicitly assumed that all remotes will be mirrors > in a bare repository, thus fetching a non-mirrored remote could lead to > HEAD pointing to a non-existent reference. Make sure we only overwrite > HEAD if we are in a bare repository and fetching from a mirror. > Otherwise, proceed as normally, and create > refs/remotes/<nonmirrorremote>/HEAD instead. > > Reported-by: Christian Hesse <list@eworm.de> > Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com> Thanks, both of these patches look sensible to me. Patrick ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 2/2] fetch set_head: fix non-mirror remotes in bare repositories 2025-01-27 7:30 ` Patrick Steinhardt @ 2025-01-27 20:18 ` Junio C Hamano 0 siblings, 0 replies; 18+ messages in thread From: Junio C Hamano @ 2025-01-27 20:18 UTC (permalink / raw) To: Patrick Steinhardt Cc: Bence Ferdinandy, git, Christian Hesse, Christian Hesse Patrick Steinhardt <ps@pks.im> writes: > On Sun, Jan 26, 2025 at 11:02:11PM +0100, Bence Ferdinandy wrote: >> In b1b713f722 (fetch set_head: handle mirrored bare repositories, >> 2024-11-22) it was implicitly assumed that all remotes will be mirrors >> in a bare repository, thus fetching a non-mirrored remote could lead to >> HEAD pointing to a non-existent reference. Make sure we only overwrite >> HEAD if we are in a bare repository and fetching from a mirror. >> Otherwise, proceed as normally, and create >> refs/remotes/<nonmirrorremote>/HEAD instead. >> >> Reported-by: Christian Hesse <list@eworm.de> >> Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com> > > Thanks, both of these patches look sensible to me. Yeah, they read quite well. Thanks, all. Will queue. ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2025-01-27 20:18 UTC | newest] Thread overview: 18+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-01-11 19:26 fatal: Not a valid object name HEAD Christian Hesse 2025-01-12 14:17 ` Bence Ferdinandy 2025-01-13 16:30 ` Junio C Hamano 2025-01-12 16:51 ` [PATCH] fetch set_head: fix non-mirror remotes in bare repositories Bence Ferdinandy 2025-01-23 21:00 ` Junio C Hamano 2025-01-23 21:42 ` Bence Ferdinandy 2025-01-23 22:00 ` Eric Sunshine 2025-01-24 14:07 ` Christian Hesse 2025-01-24 17:17 ` Junio C Hamano 2025-01-24 5:56 ` Patrick Steinhardt 2025-01-24 10:30 ` Eric Sunshine 2025-01-24 16:07 ` Junio C Hamano 2025-01-26 22:01 ` Bence Ferdinandy 2025-01-26 22:01 ` Bence Ferdinandy 2025-01-26 22:02 ` [PATCH v2 1/2] fetch set_head: refactor to use remote directly Bence Ferdinandy 2025-01-26 22:02 ` [PATCH v2 2/2] fetch set_head: fix non-mirror remotes in bare repositories Bence Ferdinandy 2025-01-27 7:30 ` Patrick Steinhardt 2025-01-27 20:18 ` Junio C Hamano
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).