Skip to content

MissingObjectException when formatting diff with working directory #233

@xcq1

Description

@xcq1

Version

7.5.0

Operating System

MacOS

Bug description

I'm trying to do a diff in a repository from the index with the things that were only changed on the file system.
I have started to write a simple test case like this:

	val repo = createTempDirectory()
    val git = Git.init().setDirectory(repo.toFile()).call()

    repo.resolve("file.txt").createFile().writeText("Hello World")
    git.commit().setMessage("Test").call()
    repo.resolve("file.txt").writeText("Modified")

    val diff = git.diff()
		.setOldTree(DirCacheIterator(git.repository.readDirCache()))
		.setNewTree(FileTreeIterator(git.repository))
		.call()
    diff.forEach { println(it) }

    val diffString = ByteArrayOutputStream().use { baos ->
        DiffFormatter(baos).use { fmt ->
            fmt.setRepository(git.repository)
            fmt.format(diff)
        }

        baos.toString(Charsets.UTF_8)
    }
    println(diffString)

But when executing this, I'm not getting the results I expect. I see only DiffEntry[ADD file.txt] as log output, but no diff is reported due to a MissingObjectException.

Actual behavior

A MissingObjectException is thrown. I assume the DiffFormatter is looking for an object that does not yet exist in the index?

Expected behavior

The code to complete without exception and returning a valid diff. To illustrate, consider the same workflow on the shell:

tmp.Y5n222eC68 on  main [!]
➜ cd $(mktemp -d)

3yl0tbgs25j7gdl2ttgclmsw54gtc3/T/tmp.HRxmal1kE9
➜ git init
Initialized empty Git repository in /private/var/folders/j9/3yl0tbgs25j7gdl2ttgclmsw54gtc3/T/tmp.HRxmal1kE9/.git/

tmp.HRxmal1kE9 on  main
➜ echo "Hello World" > file.txt

tmp.HRxmal1kE9 on  main [?]
➜ git add file.txt

tmp.HRxmal1kE9 on  main [+]
➜ git commit -m "Test"
[main (root-commit) 559d728] Test
 1 file changed, 1 insertion(+)
 create mode 100644 file.txt

tmp.HRxmal1kE9 on  main
➜ echo "Modified" > file.txt

tmp.HRxmal1kE9 on  main [!]
➜ git diff
diff --git a/file.txt b/file.txt
index 557db03..a07e6a9 100644
--- a/file.txt
+++ b/file.txt
@@ -1 +1 @@
-Hello World
+Modified

Relevant log output

org.eclipse.jgit.errors.MissingObjectException: Missing blob da6fda422c3d917e2a85b30d06686b1c0a990785
	at org.eclipse.jgit.internal.storage.file.WindowCursor.open(WindowCursor.java:151)
	at org.eclipse.jgit.diff.ContentSource$ObjectReaderSource.open(ContentSource.java:135)
	at org.eclipse.jgit.diff.ContentSource$Pair.open(ContentSource.java:302)
	at org.eclipse.jgit.diff.DiffFormatter.open(DiffFormatter.java:1156)
	at org.eclipse.jgit.diff.DiffFormatter.createFormatResult(DiffFormatter.java:1084)
	at org.eclipse.jgit.diff.DiffFormatter.format(DiffFormatter.java:707)
	at org.eclipse.jgit.diff.DiffFormatter.format(DiffFormatter.java:694)
	...

Other information

I tried to see if I can compare with a ref instead by using this code:

    val ref = git.repository.exactRef("HEAD")
    val tree = RevWalk(git.repository).use { walk ->
        val commit = walk.parseCommit(ref.objectId)
        walk.parseTree(commit.tree.id)
    }

    val diff = git.diff()
        .setOldTree(CanonicalTreeParser().also { treeParser ->
            treeParser.reset(git.repository.newObjectReader(), tree.id)
        })
        .setNewTree(FileTreeIterator(git.repository))
        .call()

But this results in the same exception, if the ref exists. (If the ref does not exist, then ref is null and I'm getting an NPE)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions