Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

git clone - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:

  • Take care that on OSX Mevericks the default GIT version is <2.0, and therefore doesn't support the uploadarchive.allowunreachable tag. When accessing git over SSH, it may select a different version depending on whether you start an interactive SSH session or not (your path may be different).
  • git-upload-archive doesn't check for the uploadarchive.allowunreachable flag in the global git config. This seems to be a bug in GIT. The solution is to not use git-upload-archive, but git upload-archive (i.e. use the git script, with upload-archive as first argument). One way to do this is to supply --exec='/usr/local/bin/git upload-archive' to the git archive call.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...