0

I want to do some funky stuff with a project on github (not mine). So I want to basically clone it but I don't want to have a working tree... so this is what I do: I create a bare repo locally, then I added a remote to the github repo. I fetched, I get all the stuff that that repo contains.... I am a happy guy..... until I want to check the branches that are available:

$ git branch -a
$

Ok... that is not what I was expecting. If I try to check any branch from the repo (that I know is there), I just get git to tell me the reference doesn't exist:

$ git show --summary origin/master
fatal: ambiguous argument 'origin/master': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

How do I address branches (or actually anything) from the remote repo from my bare repo?

Update

My assumptions that git should be able to handle this is actually correct. It does manage it correctly... however, because it is a big project, git failed while running the fetch after adding the remote... and that error message I did not catch before. :-O

$ git fetch upstream
remote: Enumerating objects: 60400, done.
remote: Counting objects: 100% (60400/60400), done.
remote: Compressing objects: 100% (32/32), done.
Receiving objects: 100% (4133663/4133663), 1.41 GiB | 12.29 MiB/s, done.
remote: Total 4133663 (delta 60370), reused 60389 (delta 60368), pack-reused 4073263
Connection to github.com closed by remote host.
Resolving deltas: 100% (3134856/3134856), done.

So... all in all, it's my fault, apparently.

eftshift0
  • 26,375
  • 3
  • 36
  • 60
  • 1
    You know more about this than I do, but I wonder: if you are going to fetch, what was the point of the bare repo? You have, as you said, all that the remote repo contains — so it cannot be that you are trying to save space. The reason to have "no working tree" would presumably be so that you can use _this_ repo as a remote? Is that the point? Thx – matt Feb 25 '21 at 02:46
  • Use `git show --summary master`. A remote tracking branch is not necessary in a bare repository, so there's no branch like `origin/master` by default. – ElpieKay Feb 25 '21 at 02:49
  • @matt I just want to have some fun with it and don't intend to actually work on any files.... in my case, I want to generate a video using gource. – eftshift0 Feb 25 '21 at 03:34
  • @ElpieKay That doesn't work either... same error as if when checking with `origin/master`. – eftshift0 Feb 25 '21 at 03:35
  • 1
    @eftshift0 Try `git remote update` first. – ElpieKay Feb 25 '21 at 03:36
  • 1
    @ElpieKay, `git remote update` actually pulled it off and created remote branches and tags. Can you add it as an answer and, if possible, explain why running `git remote update`is necessary after the initial fetch? I would have expected the fetch to generate those references... actually in my case, instead of doing `git remote add; git fetch`, running `git remote add; git update` would pull it off? Should I run `git update` instead of running `git fetch`? – eftshift0 Feb 25 '21 at 03:43
  • @eftshift0 Then I'm afraid `git remote update` is not the proper command. A bare repository mostly serves as a server repository instead of a client repository. If we use `git clone --bare` to create a bare repository, there are only branches and tags, without any remote tracking branches. For a bare repository initialized by `git init --bare` and `git remote add origin xxxx`, the corresponding command should be `git fetch origin refs/heads/*:refs/heads/* refs/tags/*:refs/tags/*` instead of `git remote update`. And later, we can use `git remote udpate` to update branches and tags. – ElpieKay Feb 25 '21 at 03:56
  • OK.... so it sounds like I am kind of stretching the whole purpose of a bare repo to do something it is not intended to in the first place. – eftshift0 Feb 25 '21 at 05:03
  • @eftshift0 If you don't want a working tree and still want it to behave like a non-bare repository, you could try `git clone -n`. `-n` instructs it not to checkout any revision after the clone is done. – ElpieKay Feb 25 '21 at 06:11

3 Answers3

4

I create a bare repo locally

It's important to describe the exact commands used here.

Typically, one would create a bare mirror clone with:

git clone --mirror <url> foo.git

One would create a bare clone intended for receiving git push operations with:

mkdir foo.git && cd foo.git && git init --bare

Did you do one of these two sequences, or something else?

then I added a remote to the github repo

Again, we'd need the exact operations. I don't think git remote add respects core.bare (it didn't in my test locally), but this could be Git-version-dependent as well, so the Git version could be of interest.

I fetched ...

Here's the result of my test:

$ mkdir tbare
$ git init --bare
Initialized empty Git repository in ...
$ git remote add foo ssh://git@github.com/chris3torek/scripts
$ cat config
[core]
        repositoryformatversion = 0
        filemode = true
        bare = true
[remote "foo"]
        url = ssh://git@github.com/chris3torek/scripts
        fetch = +refs/heads/*:refs/remotes/foo/*

Interestingly, fetching without naming a remote now did nothing. Renaming foo to origin, then fetching, got stuff:

$ git remote rename foo origin
$ git fetch -v
remote: Enumerating objects: 35, done.
[the usual, snipped]
 * [new branch]      master     -> origin/master

This is presumably because git fetch normally picks the name of the remote based on the name of the current branch and then its upstream setting. Since there is no current branch, there is no upstream, which causes git fetch to fall back on the hardcoded origin. (And: the Git on this particular system is 2.27.0.)

A mirror clone, created with git clone --mirror, would have the default fetch refspec set to +refs/*:refs/*. Note that --mirror implies --bare.

torek
  • 448,244
  • 59
  • 642
  • 775
  • Well.... this is interesting. I did just like you did with the `mkdir; git init --bare`.... _and_ I provided a non-origin name to the new remote..... but as @ElpieKay said, if you run `git remote update` instead of `git fetch`, it works. The part about `if the remote's name is origin then fetch works` sounds like a very unlikely bug (as in I am trying a very unlikely setup to start with). – eftshift0 Feb 25 '21 at 13:59
  • What I don't get at the moment is why your answer got 2 points (well deserved, don't get me wrong), but my question is stuck at 0. :-D – eftshift0 Feb 25 '21 at 14:00
  • It would still help if you provided a reproducer ("[mcve]"). – torek Feb 25 '21 at 20:48
  • I think I hit a bug... a different one from the one we described before. Let me dig further and then I will come back (It won't happen in a few minutes so don't hold your breath... it might take me a few days to see what is going on) – eftshift0 Feb 25 '21 at 21:23
  • Oh.... I see what's going on. There is no bug. It's a big repo and github closed the connection before it finished (I had failed to see the error message before). Let me post an update – eftshift0 Feb 25 '21 at 21:51
0

When you clone the bare git repository the references are updated. Thus you get the existing upstream branches and tags. But not if you do a plain git fetch in the existing bare repository with a remote configured.

That as a bare repository does not have refspec in their git config for the remote. You have to add the refspec explicitly in the git call (which I sorted out from the Ansible git module code):

git fetch origin '+refs/heads/*:refs/heads/*' '+refs/tags/*:refs/tags/*'

this is instead of the non-bare repository fetch config for a remote:

        fetch = +refs/heads/*:refs/remotes/origin/*
-1

So, what you're doing is trying to manually go through the steps of setting up a clone. It seems the comments discussion led you to a command that patched up something that had been missed up to that point, which is good... but why not just use the command that directly gives you what you want?

git clone --bare remote-url
Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
  • Sure.... I realized that.... but that still doesn't help me figure out what's wrong with what I attempted. – eftshift0 Feb 25 '21 at 05:02
  • "This command is the simple, intended way to do what you want" doesn't help with "my complex attempt to get a result didn't work?" No worries, then; since you don't want practial help, you won't get it from me again. – Mark Adelsberger Feb 25 '21 at 14:07
  • hahaha hey, don't take it personal. If you take a look at @torek's thread, you will see that actually we hit something funky. So, I know what you tipped works, I know what a bare repo is used for... and I understand I am stretching the concept a little bit. But the way I am trying (even if cumbersome) should work. – eftshift0 Feb 25 '21 at 14:27