sendemail.maximumDiffSize: Limit the size of diffs sent by email

If a unified diff included in an email will exceed the limit
configured by the system administrator, only the affected file
paths are listed in the email instead. This gives interested parties
some context on the size and scope of the change, without killing
their inbox.

Change-Id: I93c6068e9fd04095b6ad353b736126b29c4ed4fc
This commit is contained in:
Shawn O. Pearce
2012-06-12 14:36:34 -07:00
parent 390eff94c9
commit 28a950b75f
3 changed files with 49 additions and 35 deletions

View File

@@ -1882,11 +1882,19 @@ By default, unset, permitting delivery to any email address.
[[sendemail.includeDiff]]sendemail.includeDiff::
+
If true, new change emails from Gerrit will include the complete
unified diff of the change. There is no upper limit on how large
the email can get when this option is enabled.
unified diff of the change. Variable maxmimumDiffSize places an upper
limit on how large the email can get when this option is enabled.
+
By default, false.
[[sendemail.maximumDiffSize]]sendemail.maximumDiffSize::
+
Largest size of unified diff output to include in an email. When
the diff exceeds this size the file paths will be listed instead.
Standard byte unit suffixes are supported.
+
By default, 256 KiB.
[[sendemail.importance]]sendemail.importance::
+
If present, emails sent from Gerrit will have the given level

View File

@@ -23,9 +23,11 @@ import org.eclipse.jgit.lib.Config;
@Singleton
class EmailSettings {
final boolean includeDiff;
final int maximumDiffSize;
@Inject
EmailSettings(@GerritServerConfig Config cfg) {
includeDiff = cfg.getBoolean("sendemail", "includeDiff", false);
maximumDiffSize = cfg.getInt("sendemail", "maximumDiffSize", 256 << 10);
}
}

View File

@@ -23,14 +23,13 @@ import com.google.gerrit.server.ssh.SshInfo;
import com.jcraft.jsch.HostKey;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.util.RawParseUtils;
import org.eclipse.jgit.util.TemporaryBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@@ -107,38 +106,43 @@ public abstract class NewChangeSender extends ChangeEmail {
/** Show patch set as unified difference. */
public String getUnifiedDiff() {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Repository repo = getRepository();
if (repo != null) {
DiffFormatter df = new DiffFormatter(out);
PatchList patchList;
try {
PatchList patchList = getPatchList();
if (patchList.getOldId() != null) {
df.setRepository(repo);
df.setDetectRenames(true);
df.format(patchList.getOldId(), patchList.getNewId());
patchList = getPatchList();
if (patchList.getOldId() == null) {
// Octopus merges are not well supported for diff output by Gerrit.
// Currently these always have a null oldId in the PatchList.
return "";
}
} catch (PatchListNotAvailableException e) {
log.error("Cannot format patch", e);
} catch (IOException e) {
log.error("Cannot format patch", e);
} finally {
df.release();
repo.close();
}
}
return RawParseUtils.decode(out.toByteArray());
return "";
}
private Repository getRepository() {
TemporaryBuffer.Heap buf =
new TemporaryBuffer.Heap(args.settings.maximumDiffSize);
DiffFormatter fmt = new DiffFormatter(buf);
Repository git;
try {
return args.server.openRepository(change.getProject());
} catch (RepositoryNotFoundException e) {
log.error("Cannot open repository", e);
return null;
git = args.server.openRepository(change.getProject());
} catch (IOException e) {
log.error("Cannot open repository", e);
return null;
log.error("Cannot open repository to format patch", e);
return "";
}
try {
fmt.setRepository(git);
fmt.setDetectRenames(true);
fmt.format(patchList.getOldId(), patchList.getNewId());
return RawParseUtils.decode(buf.toByteArray());
} catch (IOException e) {
if (JGitText.get().inMemoryBufferLimitExceeded.equals(e.getMessage())) {
return "";
}
log.error("Cannot format patch", e);
return "";
} finally {
fmt.release();
git.close();
}
}
}