f3xy
f3xy

Reputation: 775

Search git for a specific version of a file

I have a file that was copied from a git repository at some point. I want to find what SHA the file was copied at.

Currently I'm going get a list of all the SHA's and diff the file for each SHA with the file I have, but I was hoping for a better way.

Upvotes: 2

Views: 221

Answers (3)

jthill
jthill

Reputation: 60255

git hash-object path/to/file will show you the blob id for a file in your work tree.

git log --no-abbrev --full-history --cc --raw --pretty=format:%H -- path/to/file will dump the old and new blob ids at every change to that file in your history.

git log --no-abbrev --full-history --cc --raw --pretty=format:%H -- path/to/file \
| awk '$5==blob' RS='' blob=`git hash-object path/to/file`

will show you the commit(s) that produced the file you've got.

Upvotes: 1

Mark Bramnik
Mark Bramnik

Reputation: 42441

To me it looks like the following situation:

Say, we are talking about file foo.txt that was added to git repository (say, empty) at some point:

touch foo.txt
git add foo.txt
git commit -m "added foo.txt"
// commit '123'

Then it was changed a couple of times:

// add "hello" to foo.txt
git add foo.txt
git commit -m "Added 'hello'"
// commit '456'
// add "world" to foo.txt
git add foo.txt
git commit -m "Added 'world'"
// commit '789'

At this point the file (that contains 'hello world') gets copied aside (cp foo.txt /tmp/foo.txt) and its the reference copy.

Afterwards there were other commits that altered the content of foo.txt, say commits abc, def) so that the file now actually looks in git like:

Hello world
How are you doing?
I'm fine, and you?
I'm Ok too

So the question that is actually asked is how to find the commit after which the file foo.txt looks exactly like a reference copy, as its stored in /tmp/foo.txt: it contains only "Hello world" (commit 789 in my example)

In this case I believe you should use git bisect command, give it boundaries of the last commit and the first (initial commit) and, if there are were many commits in the project, running a binary search will be much faster than iterating over all the commits in the history of the file.

Read about it here

You should know how to take a decision whether the commit is 'good' or 'bad' in terms of git bisest (e.g. whether it contains the words 'hello' and 'world' for example)

Upvotes: 3

oyvind
oyvind

Reputation: 1539

It seems you can use git describe for this.

git describe <sha>

From the git describe man page:

If the given object refers to a blob, it will be described as <commit-ish>:<path>, such that the blob can be found at <path> in the <commit-ish>, which itself describes the first commit in which this blob occurs in a reverse revision walk from HEAD.

To get the <sha> of the file, use

git ls-files -s <file>

Like Adrian Shum points out in the comments, this will only give you the first commit the file is in. You can use git log to help you find the next commit at which the file changes, giving you a range of possible commits.

For more info:

Upvotes: 0

Related Questions