gitgit-clonegit-archive

Git: get specific revision from remote server


I'm setting up a test-architecture. In this system a VM has to test a specific revision of the code. The VM is completely clean, and does not have a local (updatable) version of the repo. The code is being hosted on an on-site git server, over ssh with a user named git. I have full control over both machines.

The easy solution is:

git clone --no-checkout git@gitserver:reponame.git
git checkout 8e8fdea8f8367f4a179d2faddbaadba495d6bc12

This works, but does too much: It transfers the full history over the network, something I want to avoid if at all possible.

It seems to me from the documentation that git clone can take a --branch option, but this doesn't allow me to specify a particular revision. If it would, this in combination with --depth 1 would work for me.

The alternative is to use git archive --remote. I understand the security implications of allowing this to get arbitrary revisions, and that is not a problem in this case, so I run

git config --global --bool --add uploadArchive.allowUnreachable 1

on the git server as the git user.

Now on the shell of the git user, I can do

git archive --format tar.gz --remote reponame.git 8e8fdea8f8367f4a179d2faddbaadba495d6bc12

Also, from my VM I can run

git archive --format tar.gz --remote git@gitserver:reponame.git master

However not working is:

git archive --format tar.gz --remote git@gitserver:reponame.git 8e8fdea8f8367f4a179d2faddbaadba495d6bc12

remote: fatal: no such ref: 8e8fdea8f8367f4a179d2faddbaadba495d6bc12
remote: git upload-archive: archiver died with error
fatal: sent error to the client: git upload-archive: archiver died with error

And yes, I'm pointing to the same repo, that revision definitely is in the repo, it will just not work with revision number. One thing that may be the case is that if the commands are executed over ssh, the default ~/.gitconfig file is not being read, although I could not find any information on this.

Currently I'm using bash as shell for the git user. It will work in the future with a restricted shell, but to show the basic problem, I wanted to use a normal shell.

I'm interested in both general remarks in how I should be getting a single revision to a clean machine, and a solution to the particular problem of not being able to use git archive with a revision.


EDIT: torek gave me some ideas about versions (I run on OSX, with git 1.8.5.2 stock, and 2.0.1 installed through brew), and I made a small wrapper script around git-upload-archive to figure out what was going on. The wrapper script:

/usr/local/bin/git --version > /tmp/version
tee /tmp/stdin | /usr/local/bin/git-upload-archive "$1" | tee /tmp/stdout

and calling the git-archive with the --exec option to run this script.

The version written is 2.0.1. The same problem persists however... From locally I can call git-archive with -remote and sha1 iff uploadarchive.allowunreachable is set, remotely I can't. Interestingly the request (in /tmp/stdin) is exactly the same in both cases, the reply is different. As far as I can see, this is because git-upload-archive is not picking up the correct config if started over ssh; this can be shown by using a local config in the repo, in which case it does work (my remark in the comments that this didn't work was because I was indeed picking up /usr/bin/git-upload-archive; the old version that doesn't allow this config flag).

The problem can actually be solved by calling /usr/local/bin/git upload-archive instead of /usr/local/bin/git-upload-archive. This can even be supplied as argument to git-archive: --exec='/usr/local/bin/git-upload-archive' doesn't work, --exec='/usr/local/bin/git upload-archive' does.

So problem works now. I would still be interested (from an academic point of view) in why git-upload-archive doesn't pick up the config. Possibly this is a bug that should be reported to the git project.


Solution

  • Just in case someone else runs into this issue: 90% of the answer is defined in the question under the EDIT part. The last 10% is probably not worth really diving into. The important points I repeat here: