]> source.dussan.org Git - jgit.git/commitdiff
Smudge racily clean index entries by truncating length (like git.git) 42/1142/2
authorChristian Halstrick <christian.halstrick@sap.com>
Thu, 15 Jul 2010 11:36:11 +0000 (13:36 +0200)
committerChristian Halstrick <christian.halstrick@sap.com>
Tue, 20 Jul 2010 19:54:36 +0000 (21:54 +0200)
To mark an entry racily clean we set its length to 0 (like native git
does). Entries which are not racily clean and have zero length can be
distinguished from racily clean entries by checking P_OBJECTID
against the SHA1 of empty content. When length is 0 and P_OBJECTID is
different from SHA1 of empty content we know the entry is marked
racily clean.

See http://dev.eclipse.org/mhonarc/lists/jgit-dev/msg00488.html

Change-Id: I689552931441ab51964b430b303160c9126b66af
Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java

index 7cb1472e46409472fcc4a18979f60c8682bc2ffb..909729d6c641fe9ff11adc659c2436dcd23df3d7 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (C) 2008-2009, Google Inc.
  * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
  * Copyright (C) 2010, Matthias Sohn <matthias.sohn@sap.com>
+ * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com>
  * and other copyright owners as documented in the project's IP log.
  *
  * This program and the accompanying materials are made available
@@ -282,7 +283,7 @@ public class DirCacheEntry {
         *            nanoseconds component of the index's last modified time.
         * @return true if extra careful checks should be used.
         */
-       final boolean mightBeRacilyClean(final int smudge_s, final int smudge_ns) {
+       public final boolean mightBeRacilyClean(final int smudge_s, final int smudge_ns) {
                // If the index has a modification time then it came from disk
                // and was not generated from scratch in memory. In such cases
                // the entry is 'racily clean' if the entry's cached modification
@@ -292,8 +293,6 @@ public class DirCacheEntry {
                //
                final int base = infoOffset + P_MTIME;
                final int mtime = NB.decodeInt32(info, base);
-               if (smudge_s < mtime)
-                       return true;
                if (smudge_s == mtime)
                        return smudge_ns <= NB.decodeInt32(info, base + 4);
                return false;
@@ -306,21 +305,30 @@ public class DirCacheEntry {
         * match the file in the working directory. Later git will be forced to
         * compare the file content to ensure the file matches the working tree.
         */
-       final void smudgeRacilyClean() {
-               // We don't use the same approach as C Git to smudge the entry,
-               // as we cannot compare the working tree file to our SHA-1 and
-               // thus cannot use the "size to 0" trick without accidentally
-               // thinking a zero length file is clean.
-               //
-               // Instead we force the mtime to the largest possible value, so
-               // it is certainly after the index's own modification time and
-               // on a future read will cause mightBeRacilyClean to say "yes!".
-               // It is also unlikely to match with the working tree file.
-               //
-               // I'll see you again before Jan 19, 2038, 03:14:07 AM GMT.
-               //
-               final int base = infoOffset + P_MTIME;
-               Arrays.fill(info, base, base + 8, (byte) 127);
+       public final void smudgeRacilyClean() {
+               // To mark an entry racily clean we set its length to 0 (like native git
+               // does). Entries which are not racily clean and have zero length can be
+               // distinguished from racily clean entries by checking P_OBJECTID
+               // against the SHA1 of empty content. When length is 0 and P_OBJECTID is
+               // different from SHA1 of empty content we know the entry is marked
+               // racily clean
+               final int base = infoOffset + P_SIZE;
+               Arrays.fill(info, base, base + 4, (byte) 0);
+       }
+
+       /**
+        * Check whether this entry has been smudged or not
+        * <p>
+        * If a blob has length 0 we know his id see {@link Constants#EMPTY_BLOB_ID}. If an entry
+        * has length 0 and an ID different from the one for empty blob we know this
+        * entry was smudged.
+        *
+        * @return <code>true</code> if the entry is smudged, <code>false</code>
+        *         otherwise
+        */
+       public final boolean isSmudged() {
+               final int base = infoOffset + P_OBJECTID;
+               return (getLength() == 0) && (Constants.EMPTY_BLOB_ID.compareTo(info, base) != 0);
        }
 
        final byte[] idBuffer() {
index a5b3d95d76f9a21ea9c5d07d0dd46ef56a4dccf4..2269655cf524dc3932d7b4e9a954c2a8838ff0a9 100644 (file)
@@ -527,6 +527,10 @@ public final class Constants {
        /** name of the file containing the IDs of the parents of a merge commit */
        public static final String MERGE_HEAD = "MERGE_HEAD";
 
+       /** objectid for the empty blob */
+       public static final ObjectId EMPTY_BLOB_ID = ObjectId
+                       .fromString("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391");
+
        private Constants() {
                // Hide the default constructor
        }