0

I like a way to copy repo via clone --mirror as it copies all branches. However, it results in config that still AFAIK not ready for pull/push etc.:

[core]
    bare = true
[remote "origin"]
    fetch = +refs/*:refs/*
    mirror = true

Using --mirror posted e.g. here Move git repo with git clone --mirror and git push --mirror, I've tried to add

git remote set-url origin my-url (two tries: where target was - current, and new empty folder)
git push --mirror

But still same config, however in answers I have not found mentioning of similar issue.

Maybe it is so easy to fix it was omitted? How to make target to track repo the source is tracking? Just remove mirror = true and edit fetch = +refs/heads/*:refs/remotes/origin/* by hand? TIA

Martian2020
  • 307
  • 3
  • 12
  • Sandboxes are cheap, just make another one. Mirrors are useful for some things, but it's best to make a regular clone for development work. – joanis Dec 13 '22 at 02:20
  • But, my real question is, *why* do you want to convert your mirror to a regular clone? Is there something important in this particular mirror you don't want to lose? – joanis Dec 13 '22 at 02:21
  • @joanis, I want to clone all local branches of remote. Maybe now there is a command in git to do that? IIRC people suggested scripts to loop all branches. Other solution was to use `clone --mirror`. Now I realized there is something important to be done after cloning. – Martian2020 Dec 13 '22 at 02:23
  • When I do `git clone `, I get all branches, so I'm not sure yet what you're trying to solve that a regular clone does not do. – joanis Dec 13 '22 at 02:24
  • By the way, short answer to the question as asked: while I'm sure it's possible to convert a mirror clone to a regular clone, it would be a fair amount of finicky work that would require a very good understanding of how Git stores information. That's a job for an advanced user, so it's best you find a different solution for what you're really trying to accomplish. – joanis Dec 13 '22 at 02:27
  • @joanis. `man git clone` "and creates and checks out an initial branch that is forked from the cloned repository’s currently active branch.". So it creates only one branch. – Martian2020 Dec 13 '22 at 02:28
  • @joanis, writing scripts to loop branches IMO is also advanced. I still wonder why not have option to create all branches by `git clone` but only one? – Martian2020 Dec 13 '22 at 02:30
  • Oh, well, yes, only one branch is *checked out*, but all branches are fetched. Run `git branch -a` to see them all. Or `git log --all` to see their graphs. Then you can check out any branch you want locally from there. – joanis Dec 13 '22 at 02:30
  • Please spell out more precisely what you are actually trying to accomplish. It's not clear yet. What's your end goal? – joanis Dec 13 '22 at 02:30
  • @joanis. I'd like those newly checked out branches to be properly set to track remote origin. I doubt `checkout` does that. – Martian2020 Dec 13 '22 at 02:32
  • @joanis, "all branches are fetched". fetched but not pulled. I recall clone of linux kernel is times more on disk when ` --mirror ` added. – Martian2020 Dec 13 '22 at 02:33
  • @joanis, some people like to be able to work off-line sometimes. – Martian2020 Dec 13 '22 at 02:35
  • So you mean you want a local `my_branch` set up from each `origin/my_branch` on the remote? Again, why? From a clone, you will already have all those `origin/my_branch` fetched on your local computer. Note: "pull" is just fetch + merge. It's the fetch part of that operation that downloads the branch to your computer. – joanis Dec 13 '22 at 02:35
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/250361/discussion-between-joanis-and-martian2020). – joanis Dec 13 '22 at 02:36

2 Answers2

1

Posting an answer here to summarize the long chat:

In order to have all the branches downloaded locally for doing development (possibly) offline from a repo, you should use a regular clone rather than a mirror clone. It downloads all the remote-tracking branches from the remote, and Git can then create local branches from them whenever you need them.

A mirror clone is useful for other situations, like mirroring a whole repo (as the name says), uploading the mirror elsewhere, possibly backups, but not for use as a sandbox.

Converting between types would not be easy, it's best to make the right kind of clone in the first place.

Something I learned from the discussion: a mirror clone from GitHub (and possibly other Git servers with PRs or MRs) includes the refs to the PR head and merge commits, in packed_refs, while a regular clone does not include them.

joanis
  • 10,635
  • 14
  • 30
  • 40
  • Thanks again for the discussion. Later I recalled that w/out `--mirror` in cloned linux kernel repo one can see only current kerkel, , with `--mirror` repo gives also previous versions (accessed via tags). I have a guess now old commits were merged and deleted, only recent left, that is why previous kernel versions are not available w/out `--mirror` . Does above make sense? – Martian2020 Dec 14 '22 at 05:38
  • @Martian2020 Not to me, no. Regular and mirror clones both include all the tags. – joanis Dec 14 '22 at 13:07
0

That answer is based on comment by @torek in Why line with "fetch" in git config effects how `git branch --set-upstream-to` work?

  1. change the fetch URL in .git/config from fetch = +refs/*:refs/* to fetch = +refs/heads/*:refs/remotes/origin/*
  2. git config --bool core.bare=false (or edit .git/config)
  3. create .git folder and move everything there (I usually do clone so that this step in not needed, via git clone --mirror "$1" "./.git")
  4. remove mirror=true line from .git/config (the line is initially in config, but it was not in @tokek comment and I don't know if it effects git work)
Martian2020
  • 307
  • 3
  • 12