Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I convert a bare git repository into a normal one (in-place)?

Tags:

git

git-bare

I have a bare git repository, but need to access and browse its contents over ssh (in a file manager like user experience).

I assume I could clone it:

git clone -l <path_to_bare_repo> <new_normal_repo> 

However, my repository is about 20GB in size and I don't have the space to duplicate it. Is there a way to convert the bare repository in-place to end up with a working copy in it?

like image 474
nyi Avatar asked May 17 '12 14:05

nyi


People also ask

How do I create a non bare repository in git?

A non-bare repository doesn't necessarily have a default remote "origin", either. You can create a Git repository simply with git init , which will create a non-bare repo with no remote specified.

What is git bare repository?

What is a bare repository? A bare repository is the same as default, but no commits can be made in a bare repository. The changes made in projects cannot be tracked by a bare repository as it doesn't have a working tree. A working tree is a directory in which all the project files/sub-directories reside.


2 Answers

Note: I tested this on a very simple 1-commit repository. Double-check this, read the man pages, and always be happy you've backed up before following advice you found on StackOverflow. (You do back up, right?)

To convert a --bare repository to a non-bare:

  1. Make a .git folder in the top-level of your repository.
  2. Move the repository management things (HEAD branches config description hooks info objects refs etc.) into the .git you just created.
  3. Run git config --local --bool core.bare false to convert the local git-repository to non-bare.
  4. (via comment by Tamás Pap) After step #3 you will see that you are on branch master (or whichever your main branch is) and all your files are deleted and the deletion is staged. That's normal. Just manually checkout master, or do a git reset --hard, and you are done.
  5. (to resolve issue reported by Royi) Edit .git/config file adding line fetch = +refs/heads/*:refs/remotes/origin/* after url = <...> in [remote "origin"] section. Otherwise git fetch will not see origin/master and other origin's branches.

These steps are in the opposite direction of this question, "git-convert normal to bare repository" - in particular note this answer, which states that the above steps (in, I presume, either direction) is different from doing a git-clone. Not sure if that's relevant to you, though, but you mentioned git clone in the question.

like image 151
simont Avatar answered Sep 22 '22 18:09

simont


I had a slightly different scenario:

  • a non-repo (get through a tarball from github)
  • the need to restore a full repo from that content.

Solution:

  • clone a bare repo in that content, in a .git dir:
    git clone --bare https://github.com/user/project .git
  • Mark it as a non-bare repo:
    git config --local --bool core.bare false
  • reset the index (otherwise, it believes everything has been deleted, since a .git bare repo doesn't include a file 'index'.)
    git reset HEAD -- .
    That restores the .git/index.

I have effectively transformed a bare repo into a non-bare one, while preserving the content I had previously got.
The full script I have been using for years involves the steps:

cd /path/to/current/worktree  # That creates a .git directly at the right place git clone --bare /url/of/repo .git  # restore the link between the local repo and its upstream remote repo git config --local --bool core.bare false git config --local remote.origin.fetch +refs/heads/*:refs/remotes/origin/* git fetch origin git branch -u origin/master master  # reset the index (not the working tree) git reset HEAD -- . 

But I do recon the accepted solution (with the helpful git reset step added by ADTC) is simpler.

like image 25
VonC Avatar answered Sep 24 '22 18:09

VonC