summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java13
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java40
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java28
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java7
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java32
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java18
6 files changed, 129 insertions, 9 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java
index e0a1c1d61b..f52b715d39 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, Kevin Sawicki <kevin@github.com> and others
+ * Copyright (C) 2011, 2020 Kevin Sawicki <kevin@github.com> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -24,6 +24,7 @@ import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.RepositoryState;
import org.eclipse.jgit.lib.StoredConfig;
@@ -310,6 +311,16 @@ public class PathCheckoutCommandTest extends RepositoryTestCase {
}
@Test
+ public void testCheckoutFileWithConflict() throws Exception {
+ setupConflictingState();
+ assertEquals('[' + FILE1 + ']',
+ git.status().call().getConflicting().toString());
+ git.checkout().setStartPoint(Constants.HEAD).addPath(FILE1).call();
+ assertEquals("3", read(FILE1));
+ assertTrue(git.status().call().isClean());
+ }
+
+ @Test
public void testCheckoutOursWhenNoBase() throws Exception {
String file = "added.txt";
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java
index 5477f565f4..8e84dfa318 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java
@@ -242,6 +242,46 @@ public class DirCacheEntryTest {
}
@Test
+ public void testSetStage() {
+ DirCacheEntry e = new DirCacheEntry("some/path", DirCacheEntry.STAGE_1);
+ e.setAssumeValid(true);
+ e.setCreationTime(2L);
+ e.setFileMode(FileMode.EXECUTABLE_FILE);
+ e.setLastModified(EPOCH.plusMillis(3L));
+ e.setLength(100L);
+ e.setObjectId(ObjectId
+ .fromString("0123456789012345678901234567890123456789"));
+ e.setUpdateNeeded(true);
+ e.setStage(DirCacheEntry.STAGE_2);
+
+ assertTrue(e.isAssumeValid());
+ assertEquals(2L, e.getCreationTime());
+ assertEquals(
+ ObjectId.fromString("0123456789012345678901234567890123456789"),
+ e.getObjectId());
+ assertEquals(FileMode.EXECUTABLE_FILE, e.getFileMode());
+ assertEquals(EPOCH.plusMillis(3L), e.getLastModifiedInstant());
+ assertEquals(100L, e.getLength());
+ assertEquals(DirCacheEntry.STAGE_2, e.getStage());
+ assertTrue(e.isUpdateNeeded());
+ assertEquals("some/path", e.getPathString());
+
+ e.setStage(DirCacheEntry.STAGE_0);
+
+ assertTrue(e.isAssumeValid());
+ assertEquals(2L, e.getCreationTime());
+ assertEquals(
+ ObjectId.fromString("0123456789012345678901234567890123456789"),
+ e.getObjectId());
+ assertEquals(FileMode.EXECUTABLE_FILE, e.getFileMode());
+ assertEquals(EPOCH.plusMillis(3L), e.getLastModifiedInstant());
+ assertEquals(100L, e.getLength());
+ assertEquals(DirCacheEntry.STAGE_0, e.getStage());
+ assertTrue(e.isUpdateNeeded());
+ assertEquals("some/path", e.getPathString());
+ }
+
+ @Test
public void testCopyMetaDataWithStage() {
copyMetaDataHelper(false);
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java
index 39a1f01803..5778d28d6f 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, Robin Rosenberg and others
+ * Copyright (C) 2011, 2020 Robin Rosenberg and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -124,6 +124,32 @@ public class DirCachePathEditTest {
}
@Test
+ public void testPathEditWithStagesAndReset() throws Exception {
+ DirCache dc = DirCache.newInCore();
+ DirCacheBuilder builder = new DirCacheBuilder(dc, 3);
+ builder.add(createEntry("a", DirCacheEntry.STAGE_1));
+ builder.add(createEntry("a", DirCacheEntry.STAGE_2));
+ builder.add(createEntry("a", DirCacheEntry.STAGE_3));
+ builder.finish();
+
+ DirCacheEditor editor = dc.editor();
+ PathEdit edit = new PathEdit("a") {
+
+ @Override
+ public void apply(DirCacheEntry ent) {
+ ent.setStage(DirCacheEntry.STAGE_0);
+ }
+ };
+ editor.add(edit);
+ editor.finish();
+
+ assertEquals(1, dc.getEntryCount());
+ DirCacheEntry entry = dc.getEntry(0);
+ assertEquals("a", entry.getPathString());
+ assertEquals(DirCacheEntry.STAGE_0, entry.getStage());
+ }
+
+ @Test
public void testFileReplacesTree() throws Exception {
DirCache dc = DirCache.newInCore();
DirCacheEditor editor = dc.editor();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
index 0dc5d5e7f7..847ab0a9a8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com>
- * Copyright (C) 2011, Matthias Sohn <matthias.sohn@sap.com> and others
+ * Copyright (C) 2011, 2020 Matthias Sohn <matthias.sohn@sap.com> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -503,6 +503,11 @@ public class CheckoutCommand extends GitCommand<Ref> {
editor.add(new PathEdit(path) {
@Override
public void apply(DirCacheEntry ent) {
+ if (ent.getStage() != DirCacheEntry.STAGE_0) {
+ // A checkout on a conflicting file stages the checked
+ // out file and resolves the conflict.
+ ent.setStage(DirCacheEntry.STAGE_0);
+ }
ent.setObjectId(blobId);
ent.setFileMode(mode);
checkoutPath(ent, r,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java
index 73d2807eaf..8c342e267d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2008-2009, Google Inc.
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
+ * Copyright (C) 2008, 2009, Google Inc.
+ * Copyright (C) 2008, 2020 Shawn O. Pearce <spearce@spearce.org> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -139,10 +139,28 @@ public class DirCacheEditor extends BaseDirCacheEditor {
: eIdx;
fastAdd(ent);
} else {
- // Apply to all entries of the current path (different stages)
lastIdx = cache.nextEntry(eIdx);
- for (int i = eIdx; i < lastIdx; i++) {
- final DirCacheEntry ent = cache.getEntry(i);
+ if (lastIdx > eIdx + 1) {
+ // Apply to all entries of the current path (different
+ // stages). If any apply() resets the stage to STAGE_0, take
+ // only that entry and omit all others.
+ DirCacheEntry[] tmp = new DirCacheEntry[lastIdx - eIdx];
+ int n = 0;
+ for (int i = eIdx; i < lastIdx; i++) {
+ DirCacheEntry ent = cache.getEntry(i);
+ e.apply(ent);
+ if (ent.getStage() == DirCacheEntry.STAGE_0) {
+ fastAdd(ent);
+ n = 0;
+ break;
+ }
+ tmp[n++] = ent;
+ }
+ for (int i = 0; i < n; i++) {
+ fastAdd(tmp[i]);
+ }
+ } else {
+ DirCacheEntry ent = cache.getEntry(eIdx);
e.apply(ent);
fastAdd(ent);
}
@@ -257,7 +275,9 @@ public class DirCacheEditor extends BaseDirCacheEditor {
* {@link #apply(DirCacheEntry)} method. The editor will invoke apply once
* for each record in the index which matches the path name. If there are
* multiple records (for example in stages 1, 2 and 3), the edit instance
- * will be called multiple times, once for each stage.
+ * will be called multiple times, once for each stage. If any of these calls
+ * resets the stage to 0, only this entry will be taken and entries for
+ * other stages are discarded.
*/
public abstract static class PathEdit {
final byte[] path;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
index dcb84825fe..67edf50f44 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
@@ -542,6 +542,24 @@ public class DirCacheEntry {
}
/**
+ * Sets the stage of an entry.
+ *
+ * @param stage
+ * to set, in the range [0..3]
+ * @throws IllegalArgumentException
+ * if the stage is outside the range [0..3]
+ * @since 5.10
+ */
+ public void setStage(int stage) {
+ if ((stage & ~0x3) != 0) {
+ throw new IllegalArgumentException(
+ "Invalid stage, must be in range [0..3]"); //$NON-NLS-1$
+ }
+ byte flags = info[infoOffset + P_FLAGS];
+ info[infoOffset + P_FLAGS] = (byte) ((flags & 0xCF) | (stage << 4));
+ }
+
+ /**
* Returns whether this entry should be skipped from the working tree.
*
* @return true if this entry should be skipepd.