2

I'm trying to list all changes that occurred remotely without computing changes made in local. In this post its demonstrated how to do a diff against remote, like the code below:

git.fetch().call();
Repository repo = git.getRepository();      
ObjectId fetchHead = repo.resolve("FETCH_HEAD^{tree}");
ObjectId head = repo.resolve("HEAD^{tree}");

ObjectReader reader = repo.newObjectReader();
CanonicalTreeParser oldTreeIter = new CanonicalTreeParser();
oldTreeIter.reset(reader, head);
CanonicalTreeParser newTreeIter = new CanonicalTreeParser();
newTreeIter.reset(reader, fetchHead);
List<DiffEntry> diffs= git.diff().setShowNameAndStatusOnly(true)
                        .setNewTree(newTreeIter)
                        .setOldTree(oldTreeIter)
                        .call();
for(DiffEntry entry : diffs) {
    System.out.println(entry.toString());
}

The problem is that if we use a diff, local changes are computed as "reverse" remote changes. For example, if we add a file in local, it's computed as deleted from remote, since it doesn't exist there. In the same way, if I delete a file locally it's listed as a remote addition. How do you ignore this cases? Actually it's not exactly an issue of jgit, if you show me how to do using git commands I can find a way with jgit myself...

Edit: The triple dot is the solution in raw git, like this:

git diff --name-status HEAD...origin/master

Now I need to represent this command in JGit. Any suggestion?

Community
  • 1
  • 1
Fábio
  • 193
  • 12

2 Answers2

1

I thought may be we can reference the remote branch's head before we do a git fetch. as shown below

Repository repository = git.getRepository();
    String branch = repository.getBranch();
    ObjectId head = repository.resolve("refs/heads/"+branch+"^{tree}");
    git.fetch();
    System.out.println(branch);

    Config storedConfig = repository.getConfig();

    Set<String> remotes = storedConfig.getSubsections("remote");

    System.out.println(remotes);

    ObjectId fetchHead = repository.resolve("FETCH_HEAD^{tree}");

    ObjectReader reader = repository.newObjectReader();
    CanonicalTreeParser oldTreeIter = new CanonicalTreeParser();
    oldTreeIter.reset(reader, head);
    CanonicalTreeParser newTreeIter = new CanonicalTreeParser();
    newTreeIter.reset(reader, fetchHead);
    List<DiffEntry> diffs= git.diff().setShowNameAndStatusOnly(true)
            .setNewTree(newTreeIter)
            .setOldTree(oldTreeIter)
            .call();
    for(DiffEntry entry : diffs) {
        System.out.println(entry.toString());
    }

Hope this helps.

Ajay
  • 2,976
  • 2
  • 28
  • 35
1

I have figured out the answer after asking at he EGit forum. Here you can find more details. Basically, the triple dot notation in diff means git diff $(git-merge-base A B) B, that is, diff between (merge-base of A and B) and B

So, the solution is to take the base of "head" and "fetch_head" and then perform a diff of base and fetch_head.

To get the base commit, take a look at the project gitective.

Fábio
  • 193
  • 12