git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Strange behaviour when pushing a commit object to remote's refs/HEAD

From
Karthik Nayak <karthik.188@gmail.com>
Date
Jan 16, 2024, 09:54 UTC
Message-ID
<CAOLa=ZS8YBhzaYx=9016KxErsMsazsF09rcuPs=-WpEGjV+ruw@mail.gmail.com>
In-Reply-To
<mafs0fryypg82.fsf@yadavpratyush.com>
Pratyush Yadav <me@yadavpratyush.com> writes:
> Hi,
>
Hello,
Show 18 quoted lines
> I ran into a strange Magit bug, where when I ran magit-show-refs on a
> particular repo it threw an error. The details of the Magit bug are not
> very interesting, but when attempting to reproduce it, I also saw git
> misbehaving for such repos.
>
> The strange behaviour happens when you push a commit object to remote's
> refs/HEAD instead of pushing a symbolic ref. Such a repository can be
> found at https://github.com/prati0100/magit-reproducer. I roughly used
> the below steps to create such a repo:
>
>     $ git init
>     $ echo 1 > foo && git add foo && git commit
>     $ echo 2 > bar && git add bar && git commit
>     $ git push
>     $ git checkout 79264c3
>     $ echo 2.1 > bar && git add bar && git commit
>     $ git push origin 707a3d5:refs/heads/HEAD
>

Just to note here that pushing to "refs/heads/HEAD" is not actually updating the remote repositories $GIT_DIR/HEAD file, rather it creates a new reference $GIT_DIR/refs/heads/HEAD.

With this understanding you'll see that this is not a bug, because the remote HEAD was never updated, but only a new branch called HEAD was created [0].

Show 18 quoted lines
> Now with such a repo, if you do `git log --all --oneline` it would look
> something like:
>
>     707a3d5 (origin/HEAD) 2.1
>     86e1c97 (HEAD -> main, origin/main) 2
>     79264c3 1
>
> And running `git for-each-ref --format='%(symref:short),%(refname:short),%(refname),%(subject)' refs/remotes/origin` gives:
>
>     ,origin,refs/remotes/origin/HEAD,2.1
>     ,origin/main,refs/remotes/origin/main,2
>
> All well and good so far. Now delete the repo and attempt to clone it.
> This time `git log --all --oneline` gives:
>
>     86e1c97 (HEAD -> main, origin/main, origin/HEAD) 2
>     79264c3 1
>

This is expected since you cloned the repository and you got the default branch 'main'.

Show 9 quoted lines
> And running `git for-each-ref --format='%(symref:short),%(refname:short),%(refname),%(subject)' refs/remotes/origin` gives:
>
>     origin/main,origin,refs/remotes/origin/HEAD,2
>     ,origin/main,refs/remotes/origin/main,2
>
> So suddenly the remote's HEAD becomes origin/main (symbolic ref) and the
> commit (707a3d5, "2.1") is nowhere to be found. It neither shows up in
> `git rev-list --all` nor in `git log --all`. The files and trees
> associated with it also do not show up in `git rev-list --all --object`.

Because rev-list's `--all`, iterates over all refs. Since you only cloned, the HEAD branch is not pulled.

Everything else is a consequence of the subtle but important difference between updating $GIT_DIR/HEAD vs creating $GIT_DIR/refs/heads/HEAD.

[0]: https://github.com/prati0100/magit-reproducer/branches/all

Thanks, Karthik

Previous: Pratyush YadavNext: Pratyush Yadav
Message 2 of 5 in “Strange behaviour when pushing a commit object to remote's refs/HEAD”
  1. Pratyush YadavJan 15, 2024
  2. Karthik NayakJan 16, 2024
  3. Pratyush YadavJan 16, 2024
  4. Karthik NayakJan 16, 2024
  5. Jeff KingJan 16, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.