When there is a conflict sometimes we did not set the stage of the conflict entries properly for the STAGE_1 entry. Change-Id: I1c28ff6251fdbc95f7c40fc3e401f1b41157a9f6tags/v2.0.0.201206130900-r
@@ -51,6 +51,7 @@ import static org.junit.Assert.fail; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.FileMode; | |||
import org.eclipse.jgit.lib.ObjectId; | |||
import org.junit.Test; | |||
public class DirCacheEntryTest { | |||
@@ -164,4 +165,53 @@ public class DirCacheEntryTest { | |||
assertEquals("Invalid mode 40000 for path a", err.getMessage()); | |||
} | |||
} | |||
@Test | |||
public void testCopyMetaDataWithStage() { | |||
copyMetaDataHelper(false); | |||
} | |||
@Test | |||
public void testCopyMetaDataWithoutStage() { | |||
copyMetaDataHelper(true); | |||
} | |||
private void copyMetaDataHelper(final boolean keepStage) { | |||
DirCacheEntry e = new DirCacheEntry("some/path", DirCacheEntry.STAGE_2); | |||
e.setAssumeValid(false); | |||
e.setCreationTime(2L); | |||
e.setFileMode(FileMode.EXECUTABLE_FILE); | |||
e.setLastModified(3L); | |||
e.setLength(100L); | |||
e.setObjectId(ObjectId | |||
.fromString("0123456789012345678901234567890123456789")); | |||
e.setUpdateNeeded(true); | |||
DirCacheEntry f = new DirCacheEntry("someother/path", | |||
DirCacheEntry.STAGE_1); | |||
f.setAssumeValid(true); | |||
f.setCreationTime(10L); | |||
f.setFileMode(FileMode.SYMLINK); | |||
f.setLastModified(20L); | |||
f.setLength(100000000L); | |||
f.setObjectId(ObjectId | |||
.fromString("1234567890123456789012345678901234567890")); | |||
f.setUpdateNeeded(true); | |||
e.copyMetaData(f, keepStage); | |||
assertTrue(e.isAssumeValid()); | |||
assertEquals(10L, e.getCreationTime()); | |||
assertEquals( | |||
ObjectId.fromString("1234567890123456789012345678901234567890"), | |||
e.getObjectId()); | |||
assertEquals(FileMode.SYMLINK, e.getFileMode()); | |||
assertEquals(20L, e.getLastModified()); | |||
assertEquals(100000000L, e.getLength()); | |||
if (keepStage) | |||
assertEquals(DirCacheEntry.STAGE_2, e.getStage()); | |||
else | |||
assertEquals(DirCacheEntry.STAGE_1, e.getStage()); | |||
assertTrue(e.isUpdateNeeded()); | |||
assertEquals("some/path", e.getPathString()); | |||
} | |||
} |
@@ -795,7 +795,7 @@ public class DirCacheCheckout { | |||
DirCacheEntry entry; | |||
if (e != null) { | |||
entry = new DirCacheEntry(e.getPathString(), DirCacheEntry.STAGE_1); | |||
entry.copyMetaData(e); | |||
entry.copyMetaData(e, true); | |||
builder.add(entry); | |||
} | |||
@@ -641,10 +641,33 @@ public class DirCacheEntry { | |||
* the entry to copy ObjectId and meta fields from. | |||
*/ | |||
public void copyMetaData(final DirCacheEntry src) { | |||
final int pLen = NB.decodeUInt16(info, infoOffset + P_FLAGS) & NAME_MASK; | |||
copyMetaData(src, false); | |||
} | |||
/** | |||
* Copy the ObjectId and other meta fields from an existing entry. | |||
* <p> | |||
* This method copies everything except the path and possibly stage from one | |||
* entry to another, supporting renaming. | |||
* | |||
* @param src | |||
* the entry to copy ObjectId and meta fields from. | |||
* @param keepStage | |||
* if true, the stage attribute will not be copied | |||
*/ | |||
void copyMetaData(final DirCacheEntry src, boolean keepStage) { | |||
int origflags = NB.decodeUInt16(info, infoOffset + P_FLAGS); | |||
int newflags = NB.decodeUInt16(src.info, src.infoOffset + P_FLAGS); | |||
System.arraycopy(src.info, src.infoOffset, info, infoOffset, INFO_LEN); | |||
NB.encodeInt16(info, infoOffset + P_FLAGS, pLen | |||
| NB.decodeUInt16(info, infoOffset + P_FLAGS) & ~NAME_MASK); | |||
final int pLen = origflags & NAME_MASK; | |||
final int SHIFTED_STAGE_MASK = 0x3 << 12; | |||
final int pStageShifted; | |||
if (keepStage) | |||
pStageShifted = origflags & SHIFTED_STAGE_MASK; | |||
else | |||
pStageShifted = newflags & SHIFTED_STAGE_MASK; | |||
NB.encodeInt16(info, infoOffset + P_FLAGS, pStageShifted | pLen | |||
| (newflags & ~NAME_MASK & ~SHIFTED_STAGE_MASK)); | |||
} | |||
/** |