Ian
Ian

Reputation: 11850

In git, is there a SHA1 that refers to a combination of path and revision?

I want a plain-text pointer to a file in a git repository, at a particular revision -- specifically, a revision that modified the file in question.

One way that I can do this is to use a tuple of (path/to/file, revision) where the revision is something I can get from git log --format=oneline path/to/file.

Is there a more efficient way to achieve this?

I know that git's object database stores filenames separately from file data, but is there a way to convert from a filename to that object ID and back again?

Upvotes: 2

Views: 181

Answers (2)

Ajedi32
Ajedi32

Reputation: 48428

Yes. Well, sort of. In git, files are stored internally as something called a blob. Blobs are identified by a SHA-1 in a manner very similar to that of a commit. You can find the SHA-1 of any file based on its contents using git hash-object:

git hash-object -- <path>

If you want to find the hash for a file at a specific revision, git hash-object also accepts file contents from standard input:

git show <revision>:<path> | git hash-object --stdin

Then you can retrieve the text of that file with git show:

git show <blob sha-1>

Going from a blob id to a path and revision is a lot harder. Blobs can be stored at multiple paths across multiple revisions, so there's really no single definitive path/revision combination that a blob is stored at. It's possible to find a list of which revisions and paths contain a given blob (see Which commit has this blob?) but that's farily complicated and doesn't really sound like what you want anyway.

If you really want a textual representation of a file at a specific revision, then your original idea of (<path>, <revision>) seems perfectly reasonable to me. <revision>:<path> would also work well, as that's the format accepted by git show (as demonstrated in the example above).

Upvotes: 3

torek
torek

Reputation: 489638

git rev-parse turns the apparently-difficult part easy:

$ git rev-parse ace6325:Documentation/RelNotes/2.5.0.txt
994b113178d966f7044ebe7b17d981df26ecd022

You don't need a raw SHA-1, any parse-able revision will do:

$ git rev-parse HEAD~5:Documentation/RelNotes/2.5.0.txt
994b113178d966f7044ebe7b17d981df26ecd022

Given the SHA-1, git cat-file -p will extract its contents (or you can use git show as well; git show may try to apply smudge filters; I'm not entirely sure about using git show).

Note that this SHA-1 is a checksum of the actual contents of the file, i.e., if the file is changed in one commit, then changed back in a later commit, the SHA-1 will revert back to the old SHA-1.

Upvotes: 4

Related Questions