3

I am doing a backup script for a local git repo. I looked through the possibilities, and chose bundle to do the task. The steps I have taken:

  1. Create a new repo, do the initial commits

    When i inspect the repo with git branch -a i get the following: * master

  2. git bundle create ./test.bundle --all

By now when i inspect the bundle with git bundle list-heads I get 2 references: 1 for HEAD and the other for refs/heads/master.

When I pull this bundle into a new repository with git clone, the branches look like this:

*master
remotes/origin/HEAD -> remotes/origin/master
remotes/origin/master

Why does this happen? Is there a way to import only branches that where in the first repository without the remotes?

EDIT:

My question could have been a bit unclear. Here is what I would want to achieve:

  1. Have a repo with 2 branches, master and test.
  2. bundle all the branches (done with git bundle --branches as suggested)
  3. rm the whole repo
  4. Restore the repo with git clone. Unfortunately I have to give a branch parameter since I get the following error without it: warning: remote HEAD refers to nonexistent ref, unable to checkout.

The only problem that arises is that I get the following branches after clone:

*master
remotes/origin/master
remotes/origin/test

Upon switching to test, I get a message that a new branch has been made. Is there a way to clone all branches so that it could look like the original repo?

*master
test
Bartlomiej Lewandowski
  • 10,771
  • 14
  • 44
  • 75

2 Answers2

1

When you clone from the bundle, the branches in the bundle will look like remotes in your clone. That's normal.

Although git bundle list-heads shows the remote refs of the original repository, you won't see them in the new clone. I mean for example:

$ git bundle list-heads test.bundle
a742ee94e8fcef80eb5619f76674bb79d7011742 refs/heads/test2
a8bf0cf603a686ccb75179c64b3392d50ff2f4af refs/heads/master
a8bf0cf603a686ccb75179c64b3392d50ff2f4af refs/remotes/origin/HEAD
a8bf0cf603a686ccb75179c64b3392d50ff2f4af refs/remotes/origin/master
a8bf0cf603a686ccb75179c64b3392d50ff2f4af refs/remotes/origin/test1
a8bf0cf603a686ccb75179c64b3392d50ff2f4af HEAD

Then clone from this:

$ git clone test.bundle clone2
$ cd clone2
$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/test2

That is, there's no sign of the original remote with its test1 branch.

You could create a bundle without the remote references like this:

$ git bundle create test.bundle --branches HEAD

But I'm not sure if that will make a big difference. I've never worked with bundles though, so maybe this answer can be improved.

UPDATE

When you clone from the bundle, the bundle is seen as a remote, the new origin, from the point of view of your new clone. When you clone, a local branch is created for HEAD only, the other branches are left at origin. If you want to get rid of the bundle completely, you can create local branches for all the branches in the bundle remote (= origin), and then drop the remote and delete the bundle, with something like this:

for b in $(git branch -r  | grep -v HEAD | cut -f2 -d/); do
    git show-ref --verify --quiet refs/heads/$b || git checkout $b
done

Before you run this, make sure you are in a clean state with no pending or staged changes.

janos
  • 120,954
  • 29
  • 226
  • 236
  • but isn't --branches HEAD just storing the head in the bundle? I would want to store all the branches in the bundle. – Bartlomiej Lewandowski Dec 07 '13 at 21:17
  • `--branches` will add all the `refs/heads/*`, so all the branches. So that sounds like what you want to do. Have you tried it? – janos Dec 07 '13 at 21:21
  • this creates a bundle with 2 remote references - one to master and the other one to the test branch i made. – Bartlomiej Lewandowski Dec 07 '13 at 21:34
  • @BartlomiejLewandowski you seem a bit confused. When you clone from the bundle, the bundle is seen as a remote, the new `origin`, from the point of view of your new clone. When you clone, a local branch is created for `HEAD` only, the other branches are left at `origin`. If you want those branches as local branches, you have to create local branches as usual with any remote. Also it seems you overlooked the `HEAD` parameter in my suggested command, that way you don't get HEAD-less state you mention in your update. – janos Dec 08 '13 at 08:53
1

I managed to find the answer. Here is what I did:

As janos suggested, I made a bundle with all the branches. Made a git clone, on the resulting bundle. Now for each ref, I checked out the branch, and removed the remote branch.

At the end I removed the remote HEAD reference.

I found this question quite useful: How to clone all remote branches in Git?

Community
  • 1
  • 1
Bartlomiej Lewandowski
  • 10,771
  • 14
  • 44
  • 75
  • It seems you overlooked the `HEAD` parameter in the command I gave you: `git bundle create test.bundle --branches HEAD`. It was there so you don't get the warning you mentioned in your update. I also updated my post with a script to checkout all remote branches. An upvote and accepting would be nice... – janos Dec 08 '13 at 09:08