blob: 14c47e6b06644500fa4e7ac080d4e3e479e31592 [file] [log] [blame]
// Copyright (C) 2009 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.patch;
import com.google.gerrit.server.GerritServer;
import org.spearce.jgit.lib.ObjectId;
import org.spearce.jgit.lib.Repository;
import org.spearce.jgit.patch.FileHeader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
final class DiffCacheEntryFactory {
private final GerritServer server;
DiffCacheEntryFactory(final GerritServer gs) {
server = gs;
}
DiffCacheContent createEntry(final DiffCacheKey key) throws Exception {
final Repository db = server.openRepository(key.getProjectKey().get());
try {
return createEntry(key, db);
} finally {
db.close();
}
}
private DiffCacheContent createEntry(final DiffCacheKey key,
final Repository db) throws Exception {
final ObjectId newId = key.getNewId();
final List<String> args = new ArrayList<String>();
args.add("git");
args.add("--git-dir=.");
args.add("diff-tree");
if (key.getSourceFileName() != null) {
args.add("-M");
}
switch (key.getWhitespace()) {
case IGNORE_NONE:
break;
case IGNORE_SPACE_AT_EOL:
args.add("--ignore-space-at-eol");
break;
case IGNORE_SPACE_CHANGE:
args.add("--ignore-space-change");
break;
case IGNORE_ALL_SPACE:
args.add("--ignore-all-space");
break;
default:
throw new IOException("Unsupported whitespace " + key.getWhitespace());
}
args.add("--full-index");
if (key.getOldId() == null) {
args.add("--cc");
} else {
args.add("--unified=1");
args.add(key.getOldId().name());
}
args.add(newId.name());
args.add("--");
args.add(key.getFileName());
if (key.getSourceFileName() != null) {
args.add(key.getSourceFileName());
}
final Process proc =
Runtime.getRuntime().exec(args.toArray(new String[args.size()]), null,
db.getDirectory());
final FileHeader file;
try {
final org.spearce.jgit.patch.Patch p = new org.spearce.jgit.patch.Patch();
proc.getOutputStream().close();
proc.getErrorStream().close();
p.parse(proc.getInputStream());
proc.getInputStream().close();
if (p.getFiles().isEmpty()) {
return DiffCacheContent.createEmpty();
} else if (p.getFiles().size() != 1) {
throw new IOException("unexpected file count: " + key);
}
file = p.getFiles().get(0);
} finally {
try {
if (proc.waitFor() != 0) {
throw new IOException("git diff-tree exited abnormally: " + key);
}
} catch (InterruptedException ie) {
}
}
return DiffCacheContent.create(file);
}
}