git - Checkout only one file from one remote revision (branch, tag, or short or long commit hash)? - Stack Overflow

admin2025-02-03  6

I want to checkout a specific version of a specific file from a remote git repo, without downloading other unnecessary files or history.

Given a $URL in the format .git, and a $REVISION which should accept a branch name, a tag name, or a short or long commit hash, I have this solution:

git clone --depth 1 --no-checkout $URL .
git fetch origin $REVISION
git checkout FETCH_HEAD -- foo.txt

but it does not work on short commit hashes. The fetch step fails with fatal: couldn't find remote ref, but works with the full-length hash. Is there a general solution that also works on short hashes?

The solution here, using git show, does not work because it assumes that the revision already exists locally.

I want to checkout a specific version of a specific file from a remote git repo, without downloading other unnecessary files or history.

Given a $URL in the format https://github.com/foo/bar.git, and a $REVISION which should accept a branch name, a tag name, or a short or long commit hash, I have this solution:

git clone --depth 1 --no-checkout $URL .
git fetch origin $REVISION
git checkout FETCH_HEAD -- foo.txt

but it does not work on short commit hashes. The fetch step fails with fatal: couldn't find remote ref, but works with the full-length hash. Is there a general solution that also works on short hashes?

The solution here, using git show, does not work because it assumes that the revision already exists locally.

Share Improve this question asked Jan 22 at 0:48 em_lyem_ly 991 silver badge8 bronze badges 2
  • Is it ok for a Github specific solution? – Schwern Commented Jan 22 at 0:57
  • Ideally it should work for any git server, but if that's not possible, a Github specific solution might be helpful to someone – em_ly Commented Jan 22 at 3:59
Add a comment  | 

1 Answer 1

Reset to default 3

Expanding a short commit hash to its full hash requires already having that commit locally (on the system doing the expansion) as otherwise the hashes aren't known at all. Since you're only trying to git fetch it just now, that means Git can't expand it to a full hash locally – and unfortunately, it also cannot ask the server to expand it, either, as the protocol requires full-length hashes or refs.

So you will have to fetch all commits first, or otherwise discover the full hash and specify that.

Instead of a shallow clone, I would suggest cloning with --filter=tree:0 or blob:none (filtered clone) so that all commit objects will be available locally even though their contents are not. This will allow Git to locally expand the short commit IDs and will even make it automatically fetch the necessary individual objects when you try to checkout them.

Non-GitHub hosted repositories need both capabilities enabled manually (on the server side, i.e. the repository that you're cloning from):

git config uploadpack.allowFilter true
git config uploadpack.allowReachableSHA1InWant true
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1738591856a81134.html

最新回复(0)