Dmitriy
Dmitriy

Reputation: 5487

How to find path to unmodified file in git repository?

I've modified a binary file. The path to modified binary file is textures/concrete01.tex. I want to open the unmodified version and compare them visually. Where can I find the unmodified file?

Upvotes: 0

Views: 352

Answers (2)

Roland Smith
Roland Smith

Reputation: 43523

Copy the modified textures/concrete01.tex somewhere out of your repo. Then git checkout textures/concrete01.tex to get the unmodified version.

Now you can load both into a viewer and compare.

If you want to keep the changes, copy the modified texture back into the repo and commit.


If you often have these differences, you could set up a custom diff filter as explained below.

There is a mechanism for generating diffs for binary files. The diff attribute. You could put the following in .gitattributes:

*.tex binary
*.tex diff=texture

Then in .gitconfig you could define a filter.

[diff "texture"]
    command = texture_differ

The texture_differ program will be called with seven parameters including the old and new file. See GIT_EXTERNAL_DIFF in the git manual.

It should output a textual difference between the file. But I guess it would also be possible to e.g. show both files side-by-side in a viewer.

Upvotes: 1

torek
torek

Reputation: 489073

There are multiple ways to extract any particular file(s) from any particular commit(s), in Git.

The simplest and most straightforward is using git checkout, but git checkout writes its result to the index and/or the work-tree. Since your existing, modified but not yet committed, file is already in the work-tree, you would, as Roland Smith notes in his answer, need to save that file elsewhere before overwriting it in the work-tree.

There is a very easy way to extract or view any file, including binary files, from a commit without using git checkout, though. Simply use git show to name both the commit and the path, using shell redirection if desired to make the resulting output go to some arbitrary path:

git show HEAD:textures/concrete01.tex > /tmp/original

for instance. You can then use whatever tools you have available to compare the two. Note that HEAD names, as always, the current commit. Should you wish to obtain the version found in commit badf00d, or in the commit at the tip of branch zorg, you could use git show badf00d:textures/concrete01.tex or git show zorg:textures/concrete01.tex respectively.

There is one caveat that does not apply in your particular case: Using git show this way skips any filtering (smudge filters and end-of-line conversions) that git checkout would apply based on a .gitattributes entry for the file. Given that the file is binary, you almost certainly neither have nor want any such filtering. If there is no filter, skipping it—i.e., obtaining the raw file contents unmodified—obviously has the same effect as not skipping it, which also obtains the raw file contents unmodified.

(Besides this git show technique, you can also use a temporary work-tree, or git cat-file -p, for instance, to extract arbitrary files. But git show is the command intended for use by humans rather than automated scripts.)

Upvotes: 2

Related Questions