use of org.eclipse.jgit.dircache.DirCache in project gerrit by GerritCodeReview.
the class SubmoduleOp method composeGitlinksCommit.
/** Create a separate gitlink commit */
public CodeReviewCommit composeGitlinksCommit(final Branch.NameKey subscriber) throws IOException, SubmoduleException {
OpenRepo or;
try {
or = orm.getRepo(subscriber.getParentKey());
} catch (NoSuchProjectException | IOException e) {
throw new SubmoduleException("Cannot access superproject", e);
}
CodeReviewCommit currentCommit;
if (branchTips.containsKey(subscriber)) {
currentCommit = branchTips.get(subscriber);
} else {
Ref r = or.repo.exactRef(subscriber.get());
if (r == null) {
throw new SubmoduleException("The branch was probably deleted from the subscriber repository");
}
currentCommit = or.rw.parseCommit(r.getObjectId());
addBranchTip(subscriber, currentCommit);
}
StringBuilder msgbuf = new StringBuilder("");
PersonIdent author = null;
DirCache dc = readTree(or.rw, currentCommit);
DirCacheEditor ed = dc.editor();
for (SubmoduleSubscription s : targets.get(subscriber)) {
RevCommit newCommit = updateSubmodule(dc, ed, msgbuf, s);
if (newCommit != null) {
if (author == null) {
author = newCommit.getAuthorIdent();
} else if (!author.equals(newCommit.getAuthorIdent())) {
author = myIdent;
}
}
}
ed.finish();
ObjectId newTreeId = dc.writeTree(or.ins);
// Gitlinks are already in the branch, return null
if (newTreeId.equals(currentCommit.getTree())) {
return null;
}
CommitBuilder commit = new CommitBuilder();
commit.setTreeId(newTreeId);
commit.setParentId(currentCommit);
StringBuilder commitMsg = new StringBuilder("Update git submodules\n\n");
if (verboseSuperProject != VerboseSuperprojectUpdate.FALSE) {
commitMsg.append(msgbuf);
}
commit.setMessage(commitMsg.toString());
commit.setAuthor(author);
commit.setCommitter(myIdent);
ObjectId id = or.ins.insert(commit);
return or.rw.parseCommit(id);
}
use of org.eclipse.jgit.dircache.DirCache in project gerrit by GerritCodeReview.
the class TreeCreator method readBaseTree.
private DirCache readBaseTree(Repository repository) throws IOException {
try (ObjectReader objectReader = repository.newObjectReader()) {
DirCache dirCache = DirCache.newInCore();
DirCacheBuilder dirCacheBuilder = dirCache.builder();
dirCacheBuilder.addTree(new byte[0], DirCacheEntry.STAGE_0, objectReader, baseCommit.getTree());
dirCacheBuilder.finish();
return dirCache;
}
}
use of org.eclipse.jgit.dircache.DirCache in project gerrit by GerritCodeReview.
the class AutoMerger method merge.
/**
* Perform an auto-merge of the parents of the given merge commit.
*
* @return auto-merge commit or {@code null} if an auto-merge commit couldn't be created. Headers
* of the returned RevCommit are parsed.
*/
public RevCommit merge(Repository repo, RevWalk rw, final ObjectInserter ins, RevCommit merge, ThreeWayMergeStrategy mergeStrategy) throws IOException {
checkArgument(rw.getObjectReader().getCreatedFromInserter() == ins);
InMemoryInserter tmpIns = null;
if (ins instanceof InMemoryInserter) {
// Caller gave us an in-memory inserter, so ensure anything we write from
// this method is visible to them.
tmpIns = (InMemoryInserter) ins;
} else if (!save) {
// If we don't plan on saving results, use a fully in-memory inserter.
// Using just a non-flushing wrapper is not sufficient, since in
// particular DfsInserter might try to write to storage after exceeding an
// internal buffer size.
tmpIns = new InMemoryInserter(rw.getObjectReader());
}
rw.parseHeaders(merge);
String refName = RefNames.refsCacheAutomerge(merge.name());
Ref ref = repo.getRefDatabase().exactRef(refName);
if (ref != null && ref.getObjectId() != null) {
RevObject obj = rw.parseAny(ref.getObjectId());
if (obj instanceof RevCommit) {
return (RevCommit) obj;
}
return commit(repo, rw, tmpIns, ins, refName, obj, merge);
}
ResolveMerger m = (ResolveMerger) mergeStrategy.newMerger(repo, true);
DirCache dc = DirCache.newInCore();
m.setDirCache(dc);
m.setObjectInserter(tmpIns == null ? new NonFlushingWrapper(ins) : tmpIns);
boolean couldMerge;
try {
couldMerge = m.merge(merge.getParents());
} catch (IOException e) {
// It is not safe to continue further down in this method as throwing
// an exception most likely means that the merge tree was not created
// and m.getMergeResults() is empty. This would mean that all paths are
// unmerged and Gerrit UI would show all paths in the patch list.
log.warn("Error attempting automerge " + refName, e);
return null;
}
ObjectId treeId;
if (couldMerge) {
treeId = m.getResultTreeId();
} else {
RevCommit ours = merge.getParent(0);
RevCommit theirs = merge.getParent(1);
rw.parseBody(ours);
rw.parseBody(theirs);
String oursMsg = ours.getShortMessage();
String theirsMsg = theirs.getShortMessage();
String oursName = String.format("HEAD (%s %s)", ours.abbreviate(6).name(), oursMsg.substring(0, Math.min(oursMsg.length(), 60)));
String theirsName = String.format("BRANCH (%s %s)", theirs.abbreviate(6).name(), theirsMsg.substring(0, Math.min(theirsMsg.length(), 60)));
MergeFormatter fmt = new MergeFormatter();
Map<String, MergeResult<? extends Sequence>> r = m.getMergeResults();
Map<String, ObjectId> resolved = new HashMap<>();
for (Map.Entry<String, MergeResult<? extends Sequence>> entry : r.entrySet()) {
MergeResult<? extends Sequence> p = entry.getValue();
try (TemporaryBuffer buf = new TemporaryBuffer.LocalFile(null, 10 * 1024 * 1024)) {
fmt.formatMerge(buf, p, "BASE", oursName, theirsName, UTF_8.name());
buf.close();
try (InputStream in = buf.openInputStream()) {
resolved.put(entry.getKey(), ins.insert(Constants.OBJ_BLOB, buf.length(), in));
}
}
}
DirCacheBuilder builder = dc.builder();
int cnt = dc.getEntryCount();
for (int i = 0; i < cnt; ) {
DirCacheEntry entry = dc.getEntry(i);
if (entry.getStage() == 0) {
builder.add(entry);
i++;
continue;
}
int next = dc.nextEntry(i);
String path = entry.getPathString();
DirCacheEntry res = new DirCacheEntry(path);
if (resolved.containsKey(path)) {
// For a file with content merge conflict that we produced a result
// above on, collapse the file down to a single stage 0 with just
// the blob content, and a randomly selected mode (the lowest stage,
// which should be the merge base, or ours).
res.setFileMode(entry.getFileMode());
res.setObjectId(resolved.get(path));
} else if (next == i + 1) {
// If there is exactly one stage present, shouldn't be a conflict...
res.setFileMode(entry.getFileMode());
res.setObjectId(entry.getObjectId());
} else if (next == i + 2) {
// Two stages suggests a delete/modify conflict. Pick the higher
// stage as the automatic result.
entry = dc.getEntry(i + 1);
res.setFileMode(entry.getFileMode());
res.setObjectId(entry.getObjectId());
} else {
// 3 stage conflict, no resolve above
// Punt on the 3-stage conflict and show the base, for now.
res.setFileMode(entry.getFileMode());
res.setObjectId(entry.getObjectId());
}
builder.add(res);
i = next;
}
builder.finish();
treeId = dc.writeTree(ins);
}
return commit(repo, rw, tmpIns, ins, refName, treeId, merge);
}
use of org.eclipse.jgit.dircache.DirCache in project zeppelin by apache.
the class GitNotebookRepo method checkpoint.
/* implemented as git add+commit
* @param pattern is the noteId
* @param commitMessage is a commit message (checkpoint message)
* (non-Javadoc)
* @see org.apache.zeppelin.notebook.repo.VFSNotebookRepo#checkpoint(String, String)
*/
@Override
public Revision checkpoint(String pattern, String commitMessage, AuthenticationInfo subject) {
Revision revision = Revision.EMPTY;
try {
List<DiffEntry> gitDiff = git.diff().call();
if (!gitDiff.isEmpty()) {
LOG.debug("Changes found for pattern '{}': {}", pattern, gitDiff);
DirCache added = git.add().addFilepattern(pattern).call();
LOG.debug("{} changes are about to be commited", added.getEntryCount());
RevCommit commit = git.commit().setMessage(commitMessage).call();
revision = new Revision(commit.getName(), commit.getShortMessage(), commit.getCommitTime());
} else {
LOG.debug("No changes found {}", pattern);
}
} catch (GitAPIException e) {
LOG.error("Failed to add+comit {} to Git", pattern, e);
}
return revision;
}
use of org.eclipse.jgit.dircache.DirCache in project che by eclipse.
the class JGitConnection method cloneWithSparseCheckout.
@Override
public void cloneWithSparseCheckout(String directory, String remoteUrl) throws GitException, UnauthorizedException {
//TODO rework this code when jgit will support sparse-checkout. Tracked issue: https://bugs.eclipse.org/bugs/show_bug.cgi?id=383772
if (directory == null) {
throw new GitException("Subdirectory for sparse-checkout is not specified");
}
clone(CloneParams.create(remoteUrl));
final String sourcePath = getWorkingDir().getPath();
final String keepDirectoryPath = sourcePath + "/" + directory;
IOFileFilter folderFilter = new DirectoryFileFilter() {
public boolean accept(File dir) {
String directoryPath = dir.getPath();
return !(directoryPath.startsWith(keepDirectoryPath) || directoryPath.startsWith(sourcePath + "/.git"));
}
};
Collection<File> files = org.apache.commons.io.FileUtils.listFilesAndDirs(getWorkingDir(), TrueFileFilter.INSTANCE, folderFilter);
try {
DirCache index = getRepository().lockDirCache();
int sourcePathLength = sourcePath.length() + 1;
files.stream().filter(File::isFile).forEach(file -> index.getEntry(file.getPath().substring(sourcePathLength)).setAssumeValid(true));
index.write();
index.commit();
for (File file : files) {
if (keepDirectoryPath.startsWith(file.getPath())) {
continue;
}
if (file.exists()) {
FileUtils.delete(file, FileUtils.RECURSIVE);
}
}
} catch (IOException exception) {
String message = generateExceptionMessage(exception);
throw new GitException(message, exception);
}
}
Aggregations