Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java72
1 files changed, 65 insertions, 7 deletions
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 308d4d168f..defab97a08 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
@@ -62,6 +62,7 @@ import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.util.IO;
+import org.eclipse.jgit.util.MutableInteger;
import org.eclipse.jgit.util.NB;
/**
@@ -108,12 +109,19 @@ public class DirCacheEntry {
private static final int P_OBJECTID = 40;
private static final int P_FLAGS = 60;
+ private static final int P_FLAGS2 = 62;
/** Mask applied to data in {@link #P_FLAGS} to get the name length. */
private static final int NAME_MASK = 0xfff;
- static final int INFO_LEN = 62;
+ private static final int INTENT_TO_ADD = 0x20000000;
+ private static final int SKIP_WORKTREE = 0x40000000;
+ private static final int EXTENDED_FLAGS = (INTENT_TO_ADD | SKIP_WORKTREE);
+ private static final int INFO_LEN = 62;
+ private static final int INFO_LEN_EXTENDED = 64;
+
+ private static final int EXTENDED = 0x40;
private static final int ASSUME_VALID = 0x80;
/** In-core flag signaling that the entry should be considered as modified. */
@@ -131,13 +139,26 @@ public class DirCacheEntry {
/** Flags which are never stored to disk. */
private byte inCoreFlags;
- DirCacheEntry(final byte[] sharedInfo, final int infoAt,
+ DirCacheEntry(final byte[] sharedInfo, final MutableInteger infoAt,
final InputStream in, final MessageDigest md) throws IOException {
info = sharedInfo;
- infoOffset = infoAt;
+ infoOffset = infoAt.value;
IO.readFully(in, info, infoOffset, INFO_LEN);
- md.update(info, infoOffset, INFO_LEN);
+
+ final int len;
+ if (isExtended()) {
+ len = INFO_LEN_EXTENDED;
+ IO.readFully(in, info, infoOffset + INFO_LEN, INFO_LEN_EXTENDED - INFO_LEN);
+
+ if ((getExtendedFlags() & ~EXTENDED_FLAGS) != 0)
+ throw new IOException(MessageFormat.format(JGitText.get()
+ .DIRCUnrecognizedExtendedFlags, String.valueOf(getExtendedFlags())));
+ } else
+ len = INFO_LEN;
+
+ infoAt.value += len;
+ md.update(info, infoOffset, len);
int pathLen = NB.decodeUInt16(info, infoOffset + P_FLAGS) & NAME_MASK;
int skipped = 0;
@@ -170,7 +191,7 @@ public class DirCacheEntry {
// Index records are padded out to the next 8 byte alignment
// for historical reasons related to how C Git read the files.
//
- final int actLen = INFO_LEN + pathLen;
+ final int actLen = len + pathLen;
final int expLen = (actLen + 8) & ~7;
final int padLen = expLen - actLen - skipped;
if (padLen > 0) {
@@ -258,14 +279,15 @@ public class DirCacheEntry {
}
void write(final OutputStream os) throws IOException {
+ final int len = isExtended() ? INFO_LEN_EXTENDED : INFO_LEN;
final int pathLen = path.length;
- os.write(info, infoOffset, INFO_LEN);
+ os.write(info, infoOffset, len);
os.write(path, 0, pathLen);
// Index records are padded out to the next 8 byte alignment
// for historical reasons related to how C Git read the files.
//
- final int actLen = INFO_LEN + pathLen;
+ final int actLen = len + pathLen;
final int expLen = (actLen + 8) & ~7;
if (actLen != expLen)
os.write(nullpad, 0, expLen - actLen);
@@ -401,6 +423,24 @@ public class DirCacheEntry {
}
/**
+ * Returns whether this entry should be skipped from the working tree.
+ *
+ * @return true if this entry should be skipepd.
+ */
+ public boolean isSkipWorkTree() {
+ return (getExtendedFlags() & SKIP_WORKTREE) != 0;
+ }
+
+ /**
+ * Returns whether this entry is intent to be added to the Index.
+ *
+ * @return true if this entry is intent to add.
+ */
+ public boolean isIntentToAdd() {
+ return (getExtendedFlags() & INTENT_TO_ADD) != 0;
+ }
+
+ /**
* Obtain the raw {@link FileMode} bits for this entry.
*
* @return mode bits for the entry.
@@ -575,6 +615,13 @@ public class DirCacheEntry {
| NB.decodeUInt16(info, infoOffset + P_FLAGS) & ~NAME_MASK);
}
+ /**
+ * @return true if the entry contains extended flags.
+ */
+ boolean isExtended() {
+ return (info[infoOffset + P_FLAGS] & EXTENDED) != 0;
+ }
+
private long decodeTS(final int pIdx) {
final int base = infoOffset + pIdx;
final int sec = NB.decodeInt32(info, base);
@@ -588,6 +635,13 @@ public class DirCacheEntry {
NB.encodeInt32(info, base + 4, ((int) (when % 1000)) * 1000000);
}
+ private int getExtendedFlags() {
+ if (isExtended())
+ return NB.decodeUInt16(info, infoOffset + P_FLAGS2) << 16;
+ else
+ return 0;
+ }
+
private static String toString(final byte[] path) {
return Constants.CHARSET.decode(ByteBuffer.wrap(path)).toString();
}
@@ -615,4 +669,8 @@ public class DirCacheEntry {
}
return componentHasChars;
}
+
+ static int getMaximumInfoLength(boolean extended) {
+ return extended ? INFO_LEN_EXTENDED : INFO_LEN;
+ }
}

Back to the top