return true;
if (isIndexDirty())
return false;
DirCacheEntry ourDce = null;
if (index == null || index.getDirCacheEntry() == null) {
// create a fake DCE, but only if ours is valid. ours is kept only
// in case it is valid, so a null ourDce is ok in all other cases.
if (nonTree(modeO)) {
ourDce = new DirCacheEntry(tw.getRawPath());
ourDce.setObjectId(tw.getObjectId(T_OURS));
ourDce.setFileMode(tw.getFileMode(T_OURS));
}
} else {
ourDce = index.getDirCacheEntry();
}
if (nonTree(modeO) && nonTree(modeT) && tw.idEqual(T_OURS, T_THEIRS)) {
// OURS and THEIRS have equal content. Check the file mode
if (modeO == modeT) {
// content and mode of OURS and THEIRS are equal: it doesn't
// matter which one we choose. OURS is chosen. Since the index
// is clean (the index matches already OURS) we can keep the existing one
keep(ourDce);
// no checkout needed!
return true;
} else {
// same content but different mode on OURS and THEIRS.
// Try to merge the mode and report an error if this is
// not possible.
int newMode = mergeFileModes(modeB, modeO, modeT);
if (newMode != FileMode.MISSING.getBits()) {
if (newMode == modeO)
// ours version is preferred
keep(ourDce);
else {
// the preferred version THEIRS has a different mode
// than ours. Check it out!
if (isWorktreeDirty(work))
return false;
// we know about length and lastMod only after we have written the new content.
// This will happen later. Set these values to 0 for know.
DirCacheEntry e = add(tw.getRawPath(), theirs,
DirCacheEntry.STAGE_0, 0, 0);
toBeCheckedOut.put(tw.getPathString(), e);
}
return true;
} else {
// FileModes are not mergeable. We found a conflict on modes.
// For conflicting entries we don't know lastModified and length.
add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0);
add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, 0, 0);
add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, 0, 0);
unmergedPaths.add(tw.getPathString());
mergeResults.put(
tw.getPathString(),
new MergeResult<RawText>(Collections
.<RawText> emptyList()));
}
return true;
}
}
if (nonTree(modeO) && modeB == modeT && tw.idEqual(T_BASE, T_THEIRS)) {
// THEIRS was not changed compared to BASE. All changes must be in
// OURS. OURS is chosen. We can keep the existing entry.
keep(ourDce);
// no checkout needed!
return true;
}
if (modeB == modeO && tw.idEqual(T_BASE, T_OURS)) {
// OURS was not changed compared to BASE. All changes must be in
// THEIRS. THEIRS is chosen.
// Check worktree before checking out THEIRS
if (isWorktreeDirty(work))
return false;
if (nonTree(modeT)) {
// we know about length and lastMod only after we have written
// the new content.
// This will happen later. Set these values to 0 for know.
DirCacheEntry e = add(tw.getRawPath(), theirs,
DirCacheEntry.STAGE_0, 0, 0);
if (e != null)
toBeCheckedOut.put(tw.getPathString(), e);
return true;
} else if (modeT == 0 && modeB != 0) {
// we want THEIRS ... but THEIRS contains the deletion of the
// file
toBeDeleted.add(tw.getPathString());
return true;
}
}
if (tw.isSubtree()) {
// file/folder conflicts: here I want to detect only file/folder
// conflict between ours and theirs. file/folder conflicts between
// base/index/workingTree and something else are not relevant or
// detected later
if (nonTree(modeO) && !nonTree(modeT)) {
if (nonTree(modeB))
add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0);
add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, 0, 0);
unmergedPaths.add(tw.getPathString());
enterSubtree = false;
return true;
}
if (nonTree(modeT) && !nonTree(modeO)) {
if (nonTree(modeB))
add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0);
add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, 0, 0);
unmergedPaths.add(tw.getPathString());
enterSubtree = false;
return true;
}
// ours and theirs are both folders or both files (and treewalk
// tells us we are in a subtree because of index or working-dir).
// If they are both folders no content-merge is required - we can
// return here.
if (!nonTree(modeO))
return true;
// ours and theirs are both files, just fall out of the if block
// and do the content merge
}
if (nonTree(modeO) && nonTree(modeT)) {
// Check worktree before modifying files
if (isWorktreeDirty(work))
return false;
// Don't attempt to resolve submodule link conflicts
if (isGitLink(modeO) || isGitLink(modeT)) {
add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0);
add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, 0, 0);
add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, 0, 0);
unmergedPaths.add(tw.getPathString());
return true;
}
MergeResult<RawText> result = contentMerge(base, ours, theirs);
File of = writeMergedFile(result);
updateIndex(base, ours, theirs, result, of);
if (result.containsConflicts())
unmergedPaths.add(tw.getPathString());
modifiedFiles.add(tw.getPathString());
} else if (modeO != modeT) {
// OURS or THEIRS has been deleted
if (((modeO != 0 && !tw.idEqual(T_BASE, T_OURS)) || (modeT != 0 && !tw
.idEqual(T_BASE, T_THEIRS)))) {
add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0);
add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, 0, 0);
DirCacheEntry e = add(tw.getRawPath(), theirs,
DirCacheEntry.STAGE_3, 0, 0);
// OURS was deleted checkout THEIRS
if (modeO == 0) {
// Check worktree before checking out THEIRS