Asked  6 Months ago    Answers:  5   Viewed   53 times

How can I convert a 'normal' Git repository to a bare one?

The main difference seems to be:

  • in the normal Git repository, you have a .git folder inside the repository containing all relevant data and all other files making up your working copy

  • in a bare Git repository, there is no working copy and the folder (let's call it repo.git) contains the actual repository data

 Answers

84

In short: replace the contents of repo with the contents of repo/.git, then tell the repository that it is now a bare repository.

To do this, execute the following commands:

cd repo
mv .git ../repo.git # renaming just for clarity
cd ..
rm -fr repo
cd repo.git
git config --bool core.bare true

Note that this is different from doing a git clone --bare to a new location (see below).

Tuesday, June 1, 2021
 
Precastic
answered 6 Months ago
25

"Conflicts" mean "parallel evolutions of a same content". So if it goes "all to hell" during a merge, it means you have massive evolutions on the same set of files.

The reason why a rebase is then better than a merge is that:

  • you rewrite your local commit history with the one of the master (and then reapply your work, resolving any conflict then)
  • the final merge will certainly be a "fast forward" one, because it will have all the commit history of the master, plus only your changes to reapply.

I confirm that the correct workflow in that case (evolutions on common set of files) is rebase first, then merge.

However, that means that, if you push your local branch (for backup reason), that branch should not be pulled (or at least used) by anyone else (since the commit history will be rewritten by the successive rebase).


On that topic (rebase then merge workflow), barraponto mentions in the comments two interesting posts, both from randyfay.com:

  • A Rebase Workflow for Git: reminds us to fetch first, rebase:

Using this technique, your work always goes on top of the public branch like a patch that is up-to-date with current HEAD.

(a similar technique exists for bazaar)

  • Avoiding Git Disasters: A Gory Story: about the dangers of git push --force (instead of a git pull --rebase for instance)
Tuesday, June 1, 2021
 
o_flyer
answered 6 Months ago
74

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.

Wednesday, June 2, 2021
 
Kenny
answered 6 Months ago
96

I think you make a bare repository on the remote side, git init --bare, add the remote side as the push/pull tracker for your local repository (git remote add origin URL), and then locally you just say git push origin master. Now any other repository can pull from the remote repository.

Tuesday, June 15, 2021
 
ramdemon
answered 6 Months ago
23

My preferred method is to stick a label on the thing you want to get back, like a branch:

git branch recover 705736f

At this point you can check it out (it's a new local branch) and make sure you've recovered what you wanted:

git checkout recover
git log    # or gitk, or whatever

This is a new branch label, pointing at the old (pre-rebase-attempt) commits.

Your new commit (Decorator demo added) will be on the other branch, which (in a graph log viewer, like gitk --branches or git log with --graph) forks off after the Early version of the decorators demo commit.


If you're willing to "lose" (except for in the reflog) the new commit, you can force-reset your current branch back to the old commit in the reflog:

git reset --hard 705736f

(instead of creating a new branch to point to 705736f). Again, run git log to see if that's where you want (you can even git log 705736f first!).

Thursday, November 18, 2021
 
josi
answered 2 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share