/* * Copyright (c) 2011, 2012 Roberto Tyley * * This file is part of 'Agit' - an Android Git client. * * Agit is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Agit is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/ . */ package com.madgag.agit.diff; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Lists.transform; import android.util.Log; import com.google.common.base.Function; import java.io.IOException; import java.util.List; import org.eclipse.jgit.diff.DiffEntry; import org.eclipse.jgit.diff.RenameDetector; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.filter.TreeFilter; public class CommitDiffer { private static final String TAG = "CommitDiffer"; public List<FileDiff> calculateCommitDiffs(Repository repo, RevCommit beforeCommit, RevCommit afterCommit) throws IOException { Log.d(TAG, "calculateCommitDiffs"); RevWalk revWalk = new RevWalk(repo); final TreeWalk tw = new TreeWalk(revWalk.getObjectReader()); tw.setRecursive(true); tw.reset(); addTree(tw, revWalk, beforeCommit); addTree(tw, revWalk, afterCommit); tw.setFilter(TreeFilter.ANY_DIFF); List<DiffEntry> files = detectRenames(repo, DiffEntry.scan(tw)); final LineContextDiffer lineContextDiffer = new LineContextDiffer(revWalk.getObjectReader()); return newArrayList(transform(files, new Function<DiffEntry, FileDiff>() { // transform IS JUST A VIEW public FileDiff apply(DiffEntry d) { return new FileDiff(lineContextDiffer, d); } })); } private void addTree(TreeWalk tw, RevWalk revWalk, RevCommit commit) throws IOException { RevTree tree = commit.getTree(); Log.d(TAG, "Adding "+commit+" with tree "+tree); tw.addTree(revWalk.parseTree(tree)); } private List<DiffEntry> detectRenames(Repository repo, List<DiffEntry> files) throws IOException { RenameDetector rd = new RenameDetector(repo); rd.setRenameLimit(200); // 200^2 ain't so bad... ok, yep, totally arbitrary rd.addAll(files); return rd.compute(); } }