* 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
* [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: 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
* 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-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-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 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 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-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
* 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
* [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).