Fábio
Fábio

Reputation: 193

List remote changes in git repository using JGit (a real diff)

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?

Upvotes: 2

Views: 1598

Answers (2)

F&#225;bio
F&#225;bio

Reputation: 193

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.

Upvotes: 1

Ajay
Ajay

Reputation: 3096

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.

Upvotes: 1

Related Questions