0

I made some changes to a file in a git repository but didn't git add it yet. Then I tried to view the diff using jgit (via rjgit).

Without asking for the patch, this works fine:

> repo = RJGit::Repo.new('/path/to/repo', git_dir: '/path/to/repo/.git')
> RJGit::Porcelain.diff(repo, file_path: 'some_file')
[{:changetype=>"MODIFY",
  :oldpath=>"some_file",
  :newpath=>"some_file",
  :oldmode=>33188,
  :newmode=>33188,
  :score=>0,
  :oldid=>"9ace5cb286c3030f4ce67f30e62e1ae3da6b0152",
  :newid=>"8131e7090f2ff0026149db01a6cc892df8c27793"}]

But when I ask to see the patch, I get an exception:

> repo = RJGit::Repo.new('/path/to/repo', git_dir: '/path/to/repo/.git')
> RJGit::Porcelain.diff(repo, patch: true, file_path: 'some_file')
Java::OrgEclipseJgitErrors::MissingObjectException: Missing blob 8131e7090f2ff0026149db01a6cc892df8c27793
from org.eclipse.jgit.internal.storage.file.WindowCursor.open(org/eclipse/jgit/internal/storage/file/WindowCursor.java:170)
org.eclipse.jgit.diff.ContentSource$ObjectReaderSource.open(org/eclipse/jgit/diff/ContentSource.java:145)
org.eclipse.jgit.diff.ContentSource$Pair.open(org/eclipse/jgit/diff/ContentSource.java:282)
org.eclipse.jgit.diff.DiffFormatter.open(org/eclipse/jgit/diff/DiffFormatter.java:1065)
org.eclipse.jgit.diff.DiffFormatter.createFormatResult(org/eclipse/jgit/diff/DiffFormatter.java:993)
org.eclipse.jgit.diff.DiffFormatter.format(org/eclipse/jgit/diff/DiffFormatter.java:698)

Jgit is correct--the object doesn't exist:

$ ls .git/objects/81/31e7090f2ff0026149db01a6cc892df8c27793
ls: cannot access '.git/objects/81/31e7090f2ff0026149db01a6cc892df8c27793': No such file or directory

However, git diff is able to show me the patch just fine, without the object existing. If I git add the file, it creates the object and even if I then git reset, jgit no longer throws the exception since the object now exists.

1) How is git diff able to do show a patch for an object that doesn't exist yet? 2) How can I make jgit either show me the patch without creating an object, or create the object without adding the file to the index?

(Note: I found some similar questions at https://www.eclipse.org/forums/index.php/t/268050/ and https://www.eclipse.org/forums/index.php/t/1086495/, but neither one contains a solution.)

UPDATE: I found a solution to my second question ("How can I make jgit either show me the patch without creating an object, or create the object without adding the file to the index?"):

RJGit::Blob.new_from_string(repo, File.read('some_file'))

This creates the object without adding it the file to the index. This seems less than ideal, as this should be possible without touching the filesystem.

Isaac Betesh
  • 2,935
  • 28
  • 37
  • Objects in a Git repository may be *packed*, in which case there is no `.git/objects/ab/cdef...` file. The object is embedded in a `.git/objects/pack/...` file instead. Presumably anything that pretends to be Git should already be capable of reading pack files, though. – torek Jul 26 '19 at 16:05
  • In JGit, you can diff the working directory with a commit (that's what I understand you want to do) with API from the plumbing layer (see here: https://stackoverflow.com/questions/23486483/file-diff-against-the-last-commit-with-jgit). Maybe rjgit does not support this or you need to use its lower level API, assuming that there is. – Rüdiger Herrmann Jul 26 '19 at 16:18

0 Answers0