19

I would like to create the following setup for my git repos:

I currently have a local git repo with all my working files. I would like to be able to setup a central bare repository, and two other non-bare repositories -- one for a live application and one for a testing version.

I would like to be able to push changes from local to the central bare repo on a testing branch. Then, on my testing repo, always pull from the testing branch of the bare repository.

When ready to go live with the changes, I would like to be able to merge my testing branch and my master branch in the central bare repository. Then the live repo could pull from the master branch.

So in this scheme, testing repo will always pull from testing branch, and live repo will always pull from the master branch.

I can't figure out how to merge branches in a bare repository though. git-merge and git-checkout don't seem to work without the working tree.

So, my question is two-fold:

  1. Is there a standard way to merge branches in a bare repo?
  2. Is this not straight-forward because the setup of my repos is poor? (In which case, how would you modify this architecture for best practices?)
2
  • This is exactly where I am, the scenario that you describe is the most common one. Commented Sep 14, 2016 at 13:28
  • Yes, this question is definitely a good one. Although merging without checking can be a dangerous method, there are cases of automatic branch handling where you know there won't be any conflict, neither technical nor functional. And that can be done on a server, that has no need to have a non-bare repository. Commented Aug 9, 2024 at 7:55

3 Answers 3

21

Note, this can actually be done on a bare repo, but you have to work around the normal interface.

$ git read-tree -i -m branch1 branch2 $ COMMIT=$(git commit-tree $(git write-tree) -p branch1 -p branch2 < commit message) $ git update-ref mergedbranch $COMMIT 

Update: since git 2.38, "git merge-tree" has a new mode to do this, using the same machinery as "git merge". From the usage section of the manpage:

NEWTREE=$(git merge-tree --write-tree $BRANCH1 $BRANCH2) test $? -eq 0 || die "There were conflicts..." NEWCOMMIT=$(git commit-tree $NEWTREE -p $BRANCH1 -p $BRANCH2) git update-ref $BRANCH1 $NEWCOMMIT 
Sign up to request clarification or add additional context in comments.

1 Comment

This answer looks very useful but it's also very obfuscated what it does. What's the high-level explanation of what happens when you run that? What is branch1, branch2, -i, -m, -p and mergedbranch?
16

git checkout checks out a branch into the working tree – how do you think this should have worked without a working tree? And git merge and most other commands don’t work, because there is no HEAD inside of a bare repository.

To answer your question: You don’t work within the bare repository. A bare repository is only there to keep the data; if you want to work with it, use a clone which is not bare.

So from any other repository, you pull from the bare repository, merge locally and push your changes back to it. You should do this from your development repository btw. so that the live and test repositories only pull from their branch.

2 Comments

Thanks! I will do the merging in my local repo.
Actually there is a HEAD in a bare repository: it's used to recommend the branch name to other git clone commands. But otherwise, yes.
2

You must first clone from bare repository, merge your branch, then push to bare repository again. Because you haven't any working tree on bare repositories for solve conflict.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.