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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Pratyush Yadav <me@xxxxxxxxxxxxxxxxx> writes:

> Hi,
>

Hello,

> 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].

> 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'.

> 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

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux