8

Our goal is to do internal development based on a project hosted on an external repo (github) using git and gerrit. We would pull from the external repo periodically to bring in new changes and branches, and use gerrit to manage the review process (and Jenkins to build it all).

Our initial process is to clone from the external repo to a local repo via git, then create an empty project in gerrit, and finally push the local clone to gerrit.

At that point, however, we see no branches in the gerrit repo! Right now we're working around that by manually adding the branched and refids, but that seems convoluted and fragile. I'd think the external branches would come in by default, without extra contortions. They are certainly in the clone made from the github repo.

Ideally, it'd be nice to be able to clone straight from github to gerrit and have it just work... it's not clear why the extra local repo is necessary simply to transfer things, or why branches aren't appearing in the gerrit clone when the local clone is pushed to it. Suggestions?

MartyMacGyver
  • 9,483
  • 11
  • 47
  • 67

2 Answers2

4

When you perform a git push, it only pushes the active branch (HEAD). If you wish to push all branches and tags, do something like git push origin refs/heads/* --tags

It isn't technically required to have a local copy of the repository before pushing to Gerrit, but it is probably the easiest method.

Brad
  • 5,492
  • 23
  • 34
  • I'll give that a try and follow up. In what way is having the extra local repo copy easier than having only one for gerrit? (I realize there must be a non-trivial reason - I simply want to understand better what it is.) – MartyMacGyver Sep 04 '12 at 21:31
  • I took a different approach that appears to solve this more directly, but I do appreciate your answering! – MartyMacGyver Sep 05 '12 at 00:29
  • The main reason to use a local copy of the repository is so that you don't have to log in to the server to update any upstream changes - it can all be done from a client machine. – Brad Sep 05 '12 at 01:39
  • Basically your client then acts as a proxy between the server housing gerrit and the repos and the external repo (whether pulling from it or pushing to it). Is that accurate? – MartyMacGyver Sep 05 '12 at 03:33
  • Yep that is correct. It is generally bad form to do any day-to-day activities on the server itself, especially behind Gerrit's back. You lose any security checking, logging, auditing, etc features which Gerrit provides. You also have way more power to mess things up - a `rm` command would cause havok if ran on the server, but is easily recoverable from a client. – Brad Sep 05 '12 at 16:35
  • Agreed. That said, it's certainly a challenge. We're just trying to get a local gerrit instance set up and working, and it appears that --mirror isn't exactly ideal either. You'd think this had been done before, with github and gerrit and all... (obviously it has but how?) – MartyMacGyver Sep 05 '12 at 17:56
  • We do it quite a bit at my dayjob, using the method I described above... have a client pull down the code from upstream and push to our server using `git push $server refs/heads/*` – Brad Sep 06 '12 at 18:11
  • That's pretty much what we ended up doing, with the addition of refs/tags/*. I went ahead and marked your answer as the answer since you covered the main problem I was having. – MartyMacGyver Sep 06 '12 at 23:07
  • Thanks, I'm glad you got it figured out. Good call with refs/tags/* - I should have mentioned that as well. There is a `git push --tags` option which does the same thing - I'll update my answer to help others with this problem. – Brad Sep 07 '12 at 14:54
  • Thanks again! I have a followup question posted now. In short, it mirroring preferable / common when initializing a gerrit repo from an external source like github? Or is fetching into a bare repo and using that to push to gerrit preferable? http://stackoverflow.com/questions/12398700/initializing-a-local-git-gerrit-repository-whats-the-optimal-way-to-do-this – MartyMacGyver Sep 13 '12 at 05:13
4

I believe I've found the answer for myself. It boils down to how you create the repository (and is my formal introduction to bare repos).

In short, you can clone a repo the default way:

git clone https://github.com/foobar/myrepo.git

Which yields a local clone with working directory myrepo, within which is the myrepo/.git directory tree.

Or you can clone it bare. There are a couple of ways to do this, but the --mirror option appears to yields the most complete replica:

git clone --mirror https://github.com/foobar/myrepo.git

This produces the myrepo.git directory (as one might see in gerrit or in gitolite) which has the same structure as the myrepo/.git directory above, but without the working directory bits.

Note: I'll add that I'm not sure now whether a mirror is preferable to a bare clone with remote refs for the branches... I've got another thread going that inquires about this. For completeness, then, here's a way to create a bare clone with remote refs (the key being no working directory):

git init --bare ${LOCAL_REPO}
cd ${LOCAL_REPO}
git remote add origin ${REMOTE_URL}
git fetch origin --tags
git fetch origin

I tested the mirror idea as a one-off, cloning a repo straight into the local gerrit installation folder where All-Projects.git also lives, restarted gerrit and it sees the repo as well as all its branches. However, it's not the ideal way for gerrit. You should instead push from a local clone (preferably a bare one).

So in gerrit, create a new empty project via the web admin interface (I didn't put an initial empty commit into it - not sure if that would cause problems), then from within a local mirror of the repo you're trying to replicate, push it to the new, empty gerrit repo along with the branches and tags:

git push <gerrit_repo> refs/heads/* refs/tags/*
Community
  • 1
  • 1
MartyMacGyver
  • 9,483
  • 11
  • 47
  • 67