Support for the Git dircache (aka index file). The index file keeps track of which objects are currently checked out in the working directory, and the last modified time of those working files. Changes in the working directory can be detected by comparing the modification times to the cached modification time within the index file. Index files are also used during merges, where the merge happens within the index file first, and the working directory is updated as a post-merge step. Conflicts are stored in the index file to allow tool (and human) based resolutions to be easily performed.
        /// <summary>
        /// Create a new iterator for an already loaded DirCache instance.
        /// <para/>
        /// The iterator implementation may copy part of the cache's data during
        /// construction, so the cache must be Read in prior to creating the
        /// iterator.
        /// </summary>
        /// <param name="dc">
        /// The cache to walk. It must be already loaded into memory.
        /// </param>
        public DirCacheIterator(DirCache dc)
        {
            Cache = dc;
            Tree = dc.getCacheTree(true);
            TreeStart = 0;
            TreeEnd = Tree.getEntrySpan();
            SubtreeId = new byte[Constants.OBJECT_ID_LENGTH];

            if (!eof())
            {
                ParseEntry();
            }
        }
 public void testCorruptChecksumAtFooter()
 {
     var dc = new DirCache(pathOf("gitgit.index.badchecksum"));
     try
     {
         dc.read();
         Assert.Fail("Cache loaded despite corrupt checksum");
     }
     catch (CorruptObjectException err)
     {
         Assert.AreEqual("DIRC checksum mismatch", err.Message);
     }
 }
Example #3
0
        /// <summary>
        /// Create a new iterator for an already loaded DirCache instance.
        /// <para/>
        /// The iterator implementation may copy part of the cache's data during
        /// construction, so the cache must be Read in prior to creating the
        /// iterator.
        /// </summary>
        /// <param name="dc">
        /// The cache to walk. It must be already loaded into memory.
        /// </param>
        public DirCacheIterator(DirCache dc)
        {
            Cache     = dc;
            Tree      = dc.getCacheTree(true);
            TreeStart = 0;
            TreeEnd   = Tree.getEntrySpan();
            SubtreeId = new byte[Constants.OBJECT_ID_LENGTH];

            if (!eof())
            {
                ParseEntry();
            }
        }
        public void testReadIndex_LsFiles()
        {
            List<CGitIndexRecord> ls = ReadLsFiles();
            var dc = new DirCache(_index);
            Assert.AreEqual(0, dc.getEntryCount());
            dc.read();
            Assert.AreEqual(ls.Count, dc.getEntryCount());

            int i = 0;
            foreach (var val in ls)
            {
                AssertAreEqual(val, dc.getEntry(i));
                i++;
            }
        }
Example #5
0
        private void BeforeAdd(DirCacheEntry newEntry)
        {
            if (FileMode.Tree.Equals(newEntry.getRawMode()))
            {
                throw Bad(newEntry, "Adding subtree not allowed");
            }

            if (_sorted && EntryCnt > 0)
            {
                DirCacheEntry lastEntry = Entries[EntryCnt - 1];
                int           cr        = DirCache.Compare(lastEntry, newEntry);
                if (cr > 0)
                {
                    // The new entry sorts before the old entry; we are
                    // no longer sorted correctly. We'll need to redo
                    // the sorting before we can close out the build.
                    //
                    _sorted = false;
                }
                else if (cr == 0)
                {
                    // Same file path; we can only insert this if the
                    // stages won't be violated.
                    //
                    int peStage  = lastEntry.getStage();
                    int dceStage = newEntry.getStage();
                    if (peStage == dceStage)
                    {
                        throw Bad(newEntry, "Duplicate stages not allowed");
                    }
                    if (peStage == 0 || dceStage == 0)
                    {
                        throw Bad(newEntry, "Mixed stages not allowed");
                    }
                    if (peStage > dceStage)
                    {
                        _sorted = false;
                    }
                }
            }
        }
Example #6
0
        ///	<summary>
        /// Create a new in-core index representation, lock it, and read from disk.
        /// <para />
        /// The new index will be locked and then read before it is returned to the
        /// caller. Read failures are reported as exceptions and therefore prevent
        /// the method from returning a partially populated index.  On read failure,
        /// the lock is released.
        /// </summary>
        /// <param name="indexLocation">
        /// location of the index file on disk.
        /// </param>
        /// <returns>
        /// A cache representing the contents of the specified index file (if
        /// it exists) or an empty cache if the file does not exist.
        /// </returns>
        /// <exception cref="IOException">
        /// The index file is present but could not be read, or the lock
        /// could not be obtained.
        /// </exception>
        /// <exception cref="CorruptObjectException">
        /// the index file is using a format or extension that this
        /// library does not support.
        /// </exception>
        public static DirCache Lock(FileInfo indexLocation)
        {
            var c = new DirCache(indexLocation);

            if (!c.Lock())
            {
                throw new IOException("Cannot lock " + indexLocation);
            }

            try
            {
                c.read();
            }
            catch (Exception)
            {
                c.unlock();
                throw;
            }

            return(c);
        }
        public void testTreeWalk_LsFiles()
        {
            global::GitSharp.Core.Repository db = createBareRepository();
            List<CGitIndexRecord> ls = ReadLsFiles();
            var dc = new DirCache(_index);
            Assert.AreEqual(0, dc.getEntryCount());
            dc.read();
            Assert.AreEqual(ls.Count, dc.getEntryCount());

            var rItr = ls.GetEnumerator();
            var tw = new TreeWalk(db);
            tw.reset();
            tw.Recursive = true;
            tw.addTree(new DirCacheIterator(dc));
            while (rItr.MoveNext())
            {
                Assert.IsTrue(tw.next());
                var dcItr = tw.getTree<DirCacheIterator>(0, typeof(DirCacheIterator));
                Assert.IsNotNull(dcItr);
                AssertAreEqual(rItr.Current, dcItr.getDirCacheEntry());
            }
        }
        public void testReadIndex_DirCacheTree()
        {
            List<CGitIndexRecord> cList = ReadLsFiles();
            List<CGitLsTreeRecord> cTree = ReadLsTree();
            var dc = new DirCache(_index);
            Assert.AreEqual(0, dc.getEntryCount());
            dc.read();
            Assert.AreEqual(cList.Count, dc.getEntryCount());

            DirCacheTree jTree = dc.getCacheTree(false);
            Assert.IsNotNull(jTree);
            Assert.AreEqual(string.Empty, jTree.getNameString());
            Assert.AreEqual(string.Empty, jTree.getPathString());
            Assert.IsTrue(jTree.isValid());
            Assert.AreEqual(ObjectId
                    .FromString("698dd0b8d0c299f080559a1cffc7fe029479a408"), jTree
                    .getObjectId());
            Assert.AreEqual(cList.Count, jTree.getEntrySpan());

            var subtrees = new List<CGitLsTreeRecord>();
            foreach (CGitLsTreeRecord r in cTree)
            {
                if (FileMode.Tree.Equals(r.Mode))
                    subtrees.Add(r);
            }
            Assert.AreEqual(subtrees.Count, jTree.getChildCount());

            for (int i = 0; i < jTree.getChildCount(); i++)
            {
                DirCacheTree sj = jTree.getChild(i);
                CGitLsTreeRecord sc = subtrees[i];
                Assert.AreEqual(sc.Path, sj.getNameString());
                Assert.AreEqual(sc.Path + "/", sj.getPathString());
                Assert.IsTrue(sj.isValid());
                Assert.AreEqual(sc.Id, sj.getObjectId());
            }
        }
Example #9
0
 private ObjectId Commit(ObjectWriter ow, DirCache treeB, ObjectId[] parentIds)
 {
     var c = new Commit(db) { TreeId = treeB.writeTree(ow), Author = new PersonIdent("A U Thor", "a.u.thor", 1L, 0) };
     c.Committer = c.Author;
     c.ParentIds = parentIds;
     c.Message = "Tree " + c.TreeId.Name;
     return ow.WriteCommit(c);
 }
Example #10
0
 private static void AssertCorrectId(DirCache treeT, GitSharp.Core.TreeWalk.TreeWalk tw)
 {
     Assert.AreEqual(treeT.getEntry(tw.getPathString()).getObjectId(), tw.getObjectId(0));
 }
Example #11
0
 /// <summary>
 /// Construct a new builder.
 /// </summary>
 /// <param name="dc">
 /// the cache this builder will eventually update.
 /// </param>
 /// <param name="ecnt">
 /// Estimated number of entries the builder will have upon
 /// completion. This sizes the initial entry table.
 /// </param>
 public DirCacheBuilder(DirCache dc, int ecnt)
     : base(dc, ecnt)
 {
 }
 public InCoreMerger(Repository local)
     : base(local)
 {
     _tw = new NameConflictTreeWalk(Repository);
     _cache = DirCache.newInCore();
 }
Example #13
0
 ///	<summary>
 /// Construct a new editor.
 ///	</summary>
 /// <param name="dc">
 /// the cache this editor will eventually update.
 /// </param>
 ///	<param name="ecnt">
 /// estimated number of entries the editor will have upon
 /// completion. This sizes the initial entry table.
 /// </param>
 protected BaseDirCacheEditor(DirCache dc, int ecnt)
 {
     _cache   = dc;
     _entries = new DirCacheEntry[ecnt];
 }
        public void testReadIndex_LsFiles()
        {
            List<CGitIndexRecord> ls = ReadLsFiles();
            var dc = new DirCache(_index);
            Assert.AreEqual(0, dc.getEntryCount());
            dc.read();
            Assert.AreEqual(ls.Count, dc.getEntryCount());

            var cache = new List<DirCacheEntry>();

            for (int i = 0; i < dc.getEntryCount(); i++)
            {
                cache.Add(dc.getEntry(i));
            }

            ls.Sort((x, y) => x.Path.CompareTo(y.Path));
            cache.Sort((x, y) => x.getPathString().CompareTo(y.getPathString()));

            int j = 0;
            foreach (var val in ls)
            {
                AssertAreEqual(val, cache[j]);
                j++;
            }
        }
Example #15
0
		///	<summary>
		/// Create a new in-core index representation and read an index from disk.
		///	<para />
		///	The new index will be read before it is returned to the caller. Read
		/// failures are reported as exceptions and therefore prevent the method from
		/// returning a partially populated index.
		/// </summary>
		/// <param name="indexLocation">Location of the index file on disk.</param>
		/// <returns> a cache representing the contents of the specified index file (if
		/// it exists) or an empty cache if the file does not exist.
		/// </returns>
		/// <exception cref="IOException">
		/// The index file is present but could not be read.
		/// </exception>
		/// <exception cref="CorruptObjectException">
		/// The index file is using a format or extension that this
		/// library does not support.
		/// </exception>
		public static DirCache read(FileInfo indexLocation)
		{
			var c = new DirCache(indexLocation);
			c.read();
			return c;
		}
Example #16
0
 /// <summary>
 /// Construct a new editor.
 /// </summary>
 /// <param name="dirCache">
 /// The cache this editor will eventually update.
 /// </param>
 /// <param name="entryCount">
 /// Estimated number of entries the editor will have upon
 /// completion. This sizes the initial entry table.
 /// </param>
 public DirCacheEditor(DirCache dirCache, int entryCount)
     : base(dirCache, entryCount)
 {
     _edits = new List <PathEdit>();
 }
 public void testUnsupportedRequiredExtension()
 {
     var dc = new DirCache(pathOf("gitgit.index.aaaa"));
     try
     {
         dc.read();
         Assert.Fail("Cache loaded an unsupported extension");
     }
     catch (CorruptObjectException err)
     {
         Assert.AreEqual("DIRC extension 'aaaa'"
                 + " not supported by this version.", err.Message);
     }
 }
 public void testUnsupportedOptionalExtension()
 {
     var dc = new DirCache(pathOf("gitgit.index.ZZZZ"));
     dc.read();
     Assert.AreEqual(1, dc.getEntryCount());
     Assert.AreEqual("A", dc.getEntry(0).getPathString());
 }
Example #19
0
 /// <summary>
 /// Construct a new editor.
 /// </summary>
 /// <param name="dirCache">
 /// The cache this editor will eventually update.
 /// </param>
 /// <param name="entryCount">
 /// Estimated number of entries the editor will have upon
 /// completion. This sizes the initial entry table.
 /// </param>
 public DirCacheEditor(DirCache dirCache, int entryCount)
     : base(dirCache, entryCount)
 {
     _edits = new List<PathEdit>();
 }
Example #20
0
 /// <summary>
 /// Construct a new builder.
 /// </summary>
 /// <param name="dc">
 /// the cache this builder will eventually update.
 /// </param>
 /// <param name="ecnt">
 /// Estimated number of entries the builder will have upon
 /// completion. This sizes the initial entry table.
 /// </param>
 public DirCacheBuilder(DirCache dc, int ecnt)
     : base(dc, ecnt)
 {
 }
Example #21
0
		///	<summary>
		/// Create a new in-core index representation, lock it, and read from disk.
		/// <para />
		/// The new index will be locked and then read before it is returned to the
		/// caller. Read failures are reported as exceptions and therefore prevent
		/// the method from returning a partially populated index.  On read failure,
		/// the lock is released.
		/// </summary>
		/// <param name="indexLocation">
		/// location of the index file on disk.
		/// </param>
		/// <returns>
		/// A cache representing the contents of the specified index file (if
		/// it exists) or an empty cache if the file does not exist.
		/// </returns>
		/// <exception cref="IOException">
		/// The index file is present but could not be read, or the lock
		/// could not be obtained.
		/// </exception>
		/// <exception cref="CorruptObjectException">
		/// the index file is using a format or extension that this
		/// library does not support.
		/// </exception>
		public static DirCache Lock(FileInfo indexLocation)
		{
			var c = new DirCache(indexLocation);
			if (!c.Lock())
			{
				throw new IOException("Cannot lock " + indexLocation);
			}

			try
			{
				c.read();
			}
			catch (Exception)
			{
				c.unlock();
				throw;
			}

			return c;
		}
 ///	<summary>
 /// Construct a new editor.
 ///	</summary>
 /// <param name="dc">
 /// the cache this editor will eventually update.
 /// </param>
 ///	<param name="ecnt">
 /// estimated number of entries the editor will have upon
 /// completion. This sizes the initial entry table.
 /// </param>
 protected BaseDirCacheEditor(DirCache dc, int ecnt)
 {
     _cache = dc;
     _entries = new DirCacheEntry[ecnt];
 }