Fix merge/cherry-picking in CRLF mode
This fixes a case where we have CRLF in the repo but LF in the worktree and are in autocrlf mode. Change-Id: I0388270c1cf0fd22dfd513bcaa404eb97268d39d Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
parent
31aeaa0931
commit
fd62a45649
|
@ -53,6 +53,7 @@
|
|||
import org.eclipse.jgit.api.MergeResult;
|
||||
import org.eclipse.jgit.api.MergeResult.MergeStatus;
|
||||
import org.eclipse.jgit.api.errors.CheckoutConflictException;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.api.errors.JGitInternalException;
|
||||
import org.eclipse.jgit.dircache.DirCache;
|
||||
import org.eclipse.jgit.errors.NoMergeBaseException;
|
||||
|
@ -264,6 +265,37 @@ public void checkUntrackedEmpytFolderIsNotAConflictWithFile(
|
|||
indexState(CONTENT));
|
||||
}
|
||||
|
||||
@Theory
|
||||
public void mergeWithCrlfInWT(MergeStrategy strategy) throws IOException,
|
||||
GitAPIException {
|
||||
Git git = Git.wrap(db);
|
||||
db.getConfig().setString("core", null, "autocrlf", "false");
|
||||
db.getConfig().save();
|
||||
writeTrashFile("crlf.txt", "some\r\ndata\r\n");
|
||||
git.add().addFilepattern("crlf.txt").call();
|
||||
git.commit().setMessage("base").call();
|
||||
|
||||
git.branchCreate().setName("brancha").call();
|
||||
|
||||
writeTrashFile("crlf.txt", "some\r\nmore\r\ndata\r\n");
|
||||
git.add().addFilepattern("crlf.txt").call();
|
||||
git.commit().setMessage("on master").call();
|
||||
|
||||
git.checkout().setName("brancha").call();
|
||||
writeTrashFile("crlf.txt", "some\r\ndata\r\ntoo\r\n");
|
||||
git.add().addFilepattern("crlf.txt").call();
|
||||
git.commit().setMessage("on brancha").call();
|
||||
|
||||
db.getConfig().setString("core", null, "autocrlf", "input");
|
||||
db.getConfig().save();
|
||||
|
||||
MergeResult mergeResult = git.merge().setStrategy(strategy)
|
||||
.include(db.resolve("master"))
|
||||
.call();
|
||||
assertEquals(MergeResult.MergeStatus.MERGED,
|
||||
mergeResult.getMergeStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* Merging two equal subtrees when the index does not contain any file in
|
||||
* that subtree should lead to a merged state.
|
||||
|
|
|
@ -439,7 +439,7 @@ private boolean processEntry(CanonicalTreeParser base,
|
|||
else {
|
||||
// the preferred version THEIRS has a different mode
|
||||
// than ours. Check it out!
|
||||
if (isWorktreeDirty(work))
|
||||
if (isWorktreeDirty(work, ourDce))
|
||||
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.
|
||||
|
@ -477,7 +477,7 @@ private boolean processEntry(CanonicalTreeParser base,
|
|||
// THEIRS. THEIRS is chosen.
|
||||
|
||||
// Check worktree before checking out THEIRS
|
||||
if (isWorktreeDirty(work))
|
||||
if (isWorktreeDirty(work, ourDce))
|
||||
return false;
|
||||
if (nonTree(modeT)) {
|
||||
// we know about length and lastMod only after we have written
|
||||
|
@ -535,7 +535,7 @@ private boolean processEntry(CanonicalTreeParser base,
|
|||
|
||||
if (nonTree(modeO) && nonTree(modeT)) {
|
||||
// Check worktree before modifying files
|
||||
if (isWorktreeDirty(work))
|
||||
if (isWorktreeDirty(work, ourDce))
|
||||
return false;
|
||||
|
||||
// Don't attempt to resolve submodule link conflicts
|
||||
|
@ -566,7 +566,7 @@ private boolean processEntry(CanonicalTreeParser base,
|
|||
// OURS was deleted checkout THEIRS
|
||||
if (modeO == 0) {
|
||||
// Check worktree before checking out THEIRS
|
||||
if (isWorktreeDirty(work))
|
||||
if (isWorktreeDirty(work, ourDce))
|
||||
return false;
|
||||
if (nonTree(modeT)) {
|
||||
if (e != null)
|
||||
|
@ -625,7 +625,8 @@ private boolean isIndexDirty() {
|
|||
return isDirty;
|
||||
}
|
||||
|
||||
private boolean isWorktreeDirty(WorkingTreeIterator work) {
|
||||
private boolean isWorktreeDirty(WorkingTreeIterator work,
|
||||
DirCacheEntry ourDce) throws IOException {
|
||||
if (work == null)
|
||||
return false;
|
||||
|
||||
|
@ -633,9 +634,15 @@ private boolean isWorktreeDirty(WorkingTreeIterator work) {
|
|||
final int modeO = tw.getRawMode(T_OURS);
|
||||
|
||||
// Worktree entry has to match ours to be considered clean
|
||||
boolean isDirty = work.isModeDifferent(modeO);
|
||||
if (!isDirty && nonTree(modeF))
|
||||
isDirty = !tw.idEqual(T_FILE, T_OURS);
|
||||
boolean isDirty;
|
||||
if (ourDce != null)
|
||||
isDirty = work.isModified(ourDce, true, reader);
|
||||
else {
|
||||
isDirty = work.isModeDifferent(modeO);
|
||||
if (!isDirty && nonTree(modeF))
|
||||
isDirty = !tw.idEqual(T_FILE, T_OURS);
|
||||
}
|
||||
|
||||
// Ignore existing empty directories
|
||||
if (isDirty && modeF == FileMode.TYPE_TREE
|
||||
&& modeO == FileMode.TYPE_MISSING)
|
||||
|
|
Loading…
Reference in New Issue