On Jul 11, 5:46 am, Shawn Pearce <
s...@google.com> wrote:
> On Sun, Jul 10, 2011 at 04:18, Gal Hammer <
gham...@redhat.com> wrote:
> > Rather than having just the total of insert and deleted lines, is it
> > possible to see the actual change in lines (e.g. "git diff") in the
> > "NewChange" mail template?
>
> Not currently... though most of the data you need is already in
> memory, so it wouldn't be that expensive to add this. Patches are
> welcome. :-)
Do you mean a patch like this? :-)
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/
NewChangeSender.java b/gerrit-server/src/main/java/com/google/gerrit/
server/mail/NewChangeSender.java
index 186f57a..2374daf 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/
NewChangeSender.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/
NewChangeSender.java
@@ -16,10 +16,33 @@ package com.google.gerrit.server.mail;
import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.Change;
+import com.google.gerrit.reviewdb.Patch;
+import com.google.gerrit.server.patch.PatchList;
+import com.google.gerrit.server.patch.PatchListEntry;
+import com.google.gerrit.server.patch.Text;
import com.google.gerrit.server.ssh.SshInfo;
import com.jcraft.jsch.HostKey;
+import org.eclipse.jgit.diff.DiffFormatter;
+import org.eclipse.jgit.diff.Edit;
+import org.eclipse.jgit.diff.EditList;
+import org.eclipse.jgit.diff.RawText;
+import org.eclipse.jgit.errors.CorruptObjectException;
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevTree;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.TreeWalk;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -31,6 +54,8 @@ public abstract class NewChangeSender extends
ChangeEmail {
private final SshInfo sshInfo;
private final Set<Account.Id> reviewers = new
HashSet<Account.Id>();
private final Set<Account.Id> extraCC = new HashSet<Account.Id>();
+ private Repository db;
+ private ObjectReader reader;
protected NewChangeSender(EmailArguments ea, SshInfo sshInfo,
Change c) {
super(ea, c, "newchange");
@@ -84,4 +109,87 @@ public abstract class NewChangeSender extends
ChangeEmail {
}
return host;
}
+
+ /** Show patch set as unified difference. */
+ public String getUnifiedDiff() {
+ StringBuilder detail = new StringBuilder();
+ if (patchSet != null) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ DiffFormatter df = new DiffFormatter(out);
+ db = openRepository();
+ reader = db.newObjectReader();
+ PatchList patchList = getPatchList();
+ for (PatchListEntry p : patchList.getPatches()) {
+ if (Patch.COMMIT_MSG.equals(p.getNewName())) {
+ continue;
+ }
+ detail.append("\n");
+ List<String> headers = p.getHeaderLines();
+ for (String hdr : headers) {
+ detail.append(hdr);
+ }
+ try {
+ String filename = p.getNewName();
+ RawText aText = resolve(patchList.getOldId(), filename);
+ RawText bText = resolve(patchList.getNewId(), filename);
+ df.format(toEditList(p.getEdits()), aText, bText);
+ detail.append(out.toString());
+ } catch (IOException err) {
+
+ }
+ }
+ detail.append("\n");
+ }
+ return detail.toString();
+ }
+
+ private Text resolve(final ObjectId objId, String path) throws
IOException {
+ Text text;
+ try {
+ final TreeWalk tw = find(objId, reader, path);
+ ObjectId id;
+ FileMode mode;
+
+ if (tw != null) {
+ id = tw.getObjectId(0);
+ mode = tw.getFileMode(0);
+ } else {
+ id = ObjectId.zeroId();
+ mode = FileMode.MISSING;
+ }
+
+ if (mode.getObjectType() == Constants.OBJ_BLOB) {
+ text = new Text(Text.asByteArray(db.open(id,
Constants.OBJ_BLOB)));
+ } else {
+ text = Text.EMPTY;
+ }
+ }
+ catch (IOException err) {
+ throw new IOException("Cannot read " + objId.name() + ":" +
path, err);
+ }
+ return text;
+ }
+
+ private TreeWalk find(final ObjectId objId, ObjectReader reader,
String path) throws
+ MissingObjectException, IncorrectObjectTypeException,
CorruptObjectException, IOException {
+ final RevWalk rw = new RevWalk(reader);
+ final RevTree tree = rw.parseTree(objId);
+ return TreeWalk.forPath(reader, path, tree);
+ }
+
+ private EditList toEditList(List<Edit> edits) {
+ EditList editList = new EditList(edits.size());
+ for (int i = 0; i < edits.size(); ++i) {
+ editList.add(edits.get(i));
+ }
+ return editList;
+ }
+
+ private Repository openRepository() {
+ try {
+ return args.server.openRepository(change.getProject());
+ } catch (RepositoryNotFoundException e) {
+ return null;
+ }
+ }
}