22

I don't have a local code copy/etc, I just want to download a single specific git commit so I can view it. I have the url for the git repository:

git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git

and the commit hash:

ee9c5cfad29c8a13199962614b9b16f1c4137ac9

How can I download just this commit using git (I don't want the whole repo, just the one commit patch)? I have read the man pages for git-pull and git-cherry-pick and fiddled with the commands with no luck.

Cloning the repo really isn't an option because some of the Kernel repositories are exceedingly large and slow to download (hours).

bigredbob
  • 1,847
  • 4
  • 19
  • 19
  • Have you tried browsing [this repo via the web](http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=commit;h=ee9c5cfad29c8a13199962614b9b16f1c4137ac9)? – bstpierre Sep 14 '10 at 21:34
  • 1
    I'd like to do it from the command line for a variety of reasons (speed/efficiency and scripting being primary ones). – bigredbob Sep 18 '10 at 08:34
  • 3
    A commit is essentially a diff. Do you want to view the diff or view the tree? – Daenyth Sep 25 '10 at 18:38
  • 3
    @Daenyth: That's actually not true. In git, commits reflect a complete tree not just the diff to the parent. – poke Sep 27 '10 at 22:14
  • 1
    @poke: Actually, as I understand it, the commit object does indeed refer to the diff -- but it also refers to the tree object after the diff is applied. My knowledge of git internals is not perfect though, so I'm not sure. Regardless, the question is still relevant for the OP to answer. – Daenyth Sep 27 '10 at 23:58
  • 4
    @Daenyth: git does not store diffs (also, it does not use *delta storage*), only snapshots of the resulting tree. Diffs are computed on the fly when you request changes between two commits. – André Caron Sep 28 '10 at 02:38

9 Answers9

24

This would appear to be impossible. According to a discussion on kernel.org, the protocol will only allow named refs to be fetched. If you don't wish to download the snapshot from the git website, you'll have to clone the entire repo.

(You may wish to read the manuals for git-fetch and git-ls-remote.)

Josh Lee
  • 171,072
  • 38
  • 269
  • 275
13

In the general case, you can do this using the --remote flag to git archive, like so:

$ git archive -o repo.tar --remote=<repo url> <commit id>

So in your example, you'd use:

$ git archive -o repo.tar --remote=git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git ee9c5cfad29c8a13199962614b9b16f1c4137ac9

That'll give you the state of the repo at that point in time. Note that you won't get the whole repo, so you can't actually interact with the upstream repo with what you've downloaded.

However, using git archive remotely has to be enabled server-side, and it isn't on the Linux kernel's Git server. You can, however, grab a copy by using a URL of the form http://git.kernel.org/?p=<path to repo>;a=snapshot;h=<commit id>;sf=tgz. So for your repo, you could use, say, wget or curl to grab the file using that URL.

mipadi
  • 398,885
  • 90
  • 523
  • 479
  • 2
    Unfortunately this method isn't reliable/scriptable (and some git repos don't have easily found web interfaces if at all). – bigredbob Sep 25 '10 at 17:10
  • 1
    It should work, except that the web stuff is generated on the fly. The results of `curl http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=snapshot;h=ee9c5cfad29c8a13199962614b9b16f1c4137ac9;sf=tgz` are `Generating...` – wlangstroth Sep 27 '10 at 16:03
  • 1
    @Will: You'll have to handle that response in a script or whatnot, or just paste the link into a browser. It is obtuse, but Git doesn't provide a simple way to grab just one commit. – mipadi Sep 27 '10 at 16:19
2

I know this works when you have a clone of the repo (or a similar repo)..

git fetch git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
git cherry-pick ee9c5cfad29c8a13199962614b9b16f1c4137ac9

Fetch downloads the remote refs (but not the whole repo, I don't think) so that you can reference them with the other commands. Then you cherry-pick that one commit, and it attempts to apply the diff to your local tree.

I haven't tried it without a git repo locally, but I have tried it on repos that are not forks of eachother. you may get merge conflicts, but you can clean those up manually.

araemo
  • 29
  • 1
1
git show COMMITID

But you have to clone the repo. No way around that, I think. But you can do a shallow clone using the --depth arg.

Also, found a good SO post that covers this topic in greater depth Browse and display files in a git repo without cloning

Community
  • 1
  • 1
Joshua Smith
  • 6,561
  • 1
  • 30
  • 28
1

As correctly stated in @Josh Lee answer short answer is not possible.

Nevertheless for not non-real-life situation when you are the owner of big repo and need some commit at new location and save some bandwidth/time to fetch you can create named ref (branch or tag) at specific commit using web-interface and then clone it, eg. if you marked your commit with temp/1 branch:

git clone --branch=temp/1 --depth=1 http://example.com/your-repo

This seems to be the cheapest way (in terms of download size) to fetch some commit provided that you have "create reference" access right to remote repository

maoizm
  • 682
  • 13
  • 17
0

I was in the same need. I need to download a patch of a specific commit which I need to apply onto another branch.

I used: git format-patch sha-id

Just specify the sha-id which is just older than the required commit. It will give .patch files corresponding to the all commits.

kenorb
  • 155,785
  • 88
  • 678
  • 743
minhas23
  • 9,291
  • 3
  • 58
  • 40
0

I ran in to this problem today, and have found a way to download archives for a specific commit. If you go to a repository on git.kernel.org there is a clone section on the bottom. The bottom url is a google git mirror. You will be able do download archives for specific commits from here.

-1

In this case, if all you want is the diff, you can download it from the web frontend for the kernel repo at this url:

http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=commitdiff_plain;h=ee9c5cfad29c8a13199962614b9b16f1c4137ac9

You can play with the url to get other commits.

kenorb
  • 155,785
  • 88
  • 678
  • 743
Daenyth
  • 35,856
  • 13
  • 85
  • 124
-1

There is a way to do this:

git show ee9c5cfad29c8a13199962614b9b16f1c4137ac9 > myCommittedCode.txt
David
  • 1
  • 1
  • 1
    The question is a bit ambiguous, but "downloading a commit" is usually about download the files in the commit (which `git show` does not do if it gives you just a single file). – toolforger Sep 13 '20 at 06:59
  • I have to downvote this as this answer is plainly wrong. @toolforger - OP says in clear text that 'he does not have local code yet', so it is not ambiguous – maoizm Dec 27 '20 at 11:12