public virtual void TestPathsReset() { SetupRepository(); DirCacheEntry preReset = DirCache.Read(db.GetIndexFile(), db.FileSystem).GetEntry (indexFile.GetName()); NUnit.Framework.Assert.IsNotNull(preReset); git.Add().AddFilepattern(untrackedFile.GetName()).Call(); // 'a.txt' has already been modified in setupRepository // 'notAddedToIndex.txt' has been added to repository git.Reset().AddPath(indexFile.GetName()).AddPath(untrackedFile.GetName()).Call(); DirCacheEntry postReset = DirCache.Read(db.GetIndexFile(), db.FileSystem).GetEntry (indexFile.GetName()); NUnit.Framework.Assert.IsNotNull(postReset); NUnit.Framework.Assert.AreNotSame(preReset.GetObjectId(), postReset.GetObjectId() ); NUnit.Framework.Assert.AreEqual(prestage.GetObjectId(), postReset.GetObjectId()); // check that HEAD hasn't moved ObjectId head = db.Resolve(Constants.HEAD); NUnit.Framework.Assert.AreEqual(secondCommit, head); // check if files still exist NUnit.Framework.Assert.IsTrue(untrackedFile.Exists()); NUnit.Framework.Assert.IsTrue(indexFile.Exists()); NUnit.Framework.Assert.IsTrue(InHead(indexFile.GetName())); NUnit.Framework.Assert.IsTrue(InIndex(indexFile.GetName())); NUnit.Framework.Assert.IsFalse(InIndex(untrackedFile.GetName())); }
/// <summary>Reverts the worktree after an unsuccessful merge.</summary> /// <remarks> /// Reverts the worktree after an unsuccessful merge. We know that for all /// modified files the old content was in the old index and the index /// contained only stage 0. In case if inCore operation just clear /// the history of modified files. /// </remarks> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> /// <exception cref="NGit.Errors.CorruptObjectException">NGit.Errors.CorruptObjectException /// </exception> /// <exception cref="NGit.Errors.NoWorkTreeException">NGit.Errors.NoWorkTreeException /// </exception> private void CleanUp() { if (inCore) { modifiedFiles.Clear(); return; } DirCache dc = db.ReadDirCache(); ObjectReader or = db.ObjectDatabase.NewReader(); Iterator <string> mpathsIt = modifiedFiles.Iterator(); while (mpathsIt.HasNext()) { string mpath = mpathsIt.Next(); DirCacheEntry entry = dc.GetEntry(mpath); FileOutputStream fos = new FileOutputStream(new FilePath(db.WorkTree, mpath)); try { or.Open(entry.GetObjectId()).CopyTo(fos); } finally { fos.Close(); } mpathsIt.Remove(); } }
/// <summary>Represent the state of the index in one String.</summary> /// <remarks> /// Represent the state of the index in one String. This representation is /// useful when writing tests which do assertions on the state of the index. /// By default information about path, mode, stage (if different from 0) is /// included. A bitmask controls which additional info about /// modificationTimes, smudge state and length is included. /// <p> /// The format of the returned string is described with this BNF: /// <pre> /// result = ( "[" path mode stage? time? smudge? length? sha1? content? "]" )* . /// mode = ", mode:" number . /// stage = ", stage:" number . /// time = ", time:t" timestamp-index . /// smudge = "" | ", smudged" . /// length = ", length:" number . /// sha1 = ", sha1:" hex-sha1 . /// content = ", content:" blob-data . /// </pre> /// 'stage' is only presented when the stage is different from 0. All /// reported time stamps are mapped to strings like "t0", "t1", ... "tn". The /// smallest reported time-stamp will be called "t0". This allows to write /// assertions against the string although the concrete value of the time /// stamps is unknown. /// </remarks> /// <param name="repo">the repository the index state should be determined for</param> /// <param name="includedOptions"> /// a bitmask constructed out of the constants /// <see cref="MOD_TIME">MOD_TIME</see> /// , /// <see cref="SMUDGE">SMUDGE</see> /// , /// <see cref="LENGTH">LENGTH</see> /// , /// <see cref="CONTENT_ID">CONTENT_ID</see> /// and /// <see cref="CONTENT">CONTENT</see> /// controlling which info is present in the /// resulting string. /// </param> /// <returns>a string encoding the index state</returns> /// <exception cref="System.InvalidOperationException">System.InvalidOperationException /// </exception> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual string IndexState(Repository repo, int includedOptions) { DirCache dc = repo.ReadDirCache(); StringBuilder sb = new StringBuilder(); TreeSet <long> timeStamps = null; // iterate once over the dircache just to collect all time stamps if (0 != (includedOptions & MOD_TIME)) { timeStamps = new TreeSet <long>(); for (int i = 0; i < dc.GetEntryCount(); ++i) { timeStamps.AddItem(Sharpen.Extensions.ValueOf(dc.GetEntry(i).LastModified)); } } // iterate again, now produce the result string for (int i_1 = 0; i_1 < dc.GetEntryCount(); ++i_1) { DirCacheEntry entry = dc.GetEntry(i_1); sb.Append("[" + entry.PathString + ", mode:" + entry.FileMode); int stage = entry.Stage; if (stage != 0) { sb.Append(", stage:" + stage); } if (0 != (includedOptions & MOD_TIME)) { sb.Append(", time:t" + timeStamps.HeadSet(Sharpen.Extensions.ValueOf(entry.LastModified )).Count); } if (0 != (includedOptions & SMUDGE)) { if (entry.IsSmudged) { sb.Append(", smudged"); } } if (0 != (includedOptions & LENGTH)) { sb.Append(", length:" + Sharpen.Extensions.ToString(entry.Length)); } if (0 != (includedOptions & CONTENT_ID)) { sb.Append(", sha1:" + ObjectId.ToString(entry.GetObjectId())); } if (0 != (includedOptions & CONTENT)) { sb.Append(", content:" + Sharpen.Runtime.GetStringForBytes(db.Open(entry.GetObjectId (), Constants.OBJ_BLOB).GetCachedBytes(), "UTF-8")); } if (0 != (includedOptions & ASSUME_UNCHANGED)) { sb.Append(", assume-unchanged:" + entry.IsAssumeValid.ToString().ToLower()); } sb.Append("]"); } return(sb.ToString()); }
ObjectId WriteWorkingDirectoryTree(RevTree headTree, DirCache index) { DirCache dc = DirCache.NewInCore(); DirCacheBuilder cb = dc.Builder(); ObjectInserter oi = _repo.NewObjectInserter(); try { TreeWalk tw = new TreeWalk(_repo); tw.Reset(); tw.AddTree(new FileTreeIterator(_repo)); tw.AddTree(headTree); tw.AddTree(new DirCacheIterator(index)); while (tw.Next()) { // Ignore untracked files if (tw.IsSubtree) { tw.EnterSubtree(); } else if (tw.GetFileMode(0) != NGit.FileMode.MISSING && (tw.GetFileMode(1) != NGit.FileMode.MISSING || tw.GetFileMode(2) != NGit.FileMode.MISSING)) { WorkingTreeIterator f = tw.GetTree <WorkingTreeIterator>(0); DirCacheIterator dcIter = tw.GetTree <DirCacheIterator>(2); DirCacheEntry currentEntry = dcIter.GetDirCacheEntry(); DirCacheEntry ce = new DirCacheEntry(tw.PathString); if (!f.IsModified(currentEntry, true)) { ce.SetLength(currentEntry.Length); ce.LastModified = currentEntry.LastModified; ce.FileMode = currentEntry.FileMode; ce.SetObjectId(currentEntry.GetObjectId()); } else { long sz = f.GetEntryLength(); ce.SetLength(sz); ce.LastModified = f.GetEntryLastModified(); ce.FileMode = f.EntryFileMode; var data = f.OpenEntryStream(); try { ce.SetObjectId(oi.Insert(Constants.OBJ_BLOB, sz, data)); } finally { data.Close(); } } cb.Add(ce); } } cb.Finish(); return(dc.WriteTree(oi)); } finally { oi.Release(); } }
/// <summary> /// adds a entry to the index builder which is a copy of the specified /// DirCacheEntry /// </summary> /// <param name="e">the entry which should be copied</param> /// <returns>the entry which was added to the index</returns> private DirCacheEntry Keep(DirCacheEntry e) { DirCacheEntry newEntry = new DirCacheEntry(e.PathString, e.Stage); newEntry.FileMode = e.FileMode; newEntry.SetObjectId(e.GetObjectId()); newEntry.LastModified = e.LastModified; newEntry.SetLength(e.Length); builder.Add(newEntry); return(newEntry); }
/// <summary>Compares the entries content with the content in the filesystem.</summary> /// <remarks> /// Compares the entries content with the content in the filesystem. /// Unsmudges the entry when it is detected that it is clean. /// </remarks> /// <param name="entry">the entry to be checked</param> /// <returns> /// <code>true</code> if the content matches, <code>false</code> /// otherwise /// </returns> private bool ContentCheck(DirCacheEntry entry) { if (EntryObjectId.Equals(entry.GetObjectId())) { // Content has not changed // We know the entry can't be racily clean because it's still clean. // Therefore we unsmudge the entry! // If by any chance we now unsmudge although we are still in the // same time-slot as the last modification to the index file the // next index write operation will smudge again. // Caution: we are unsmudging just by setting the length of the // in-memory entry object. It's the callers task to detect that we // have modified the entry and to persist the modified index. entry.SetLength((int)GetEntryLength()); return(false); } else { // Content differs: that's a real change! return(true); } }
/// <exception cref="NGit.Errors.NoWorkTreeException"></exception> /// <exception cref="System.IO.IOException"></exception> public static void ValidateIndex(Git git) { DirCache dc = git.GetRepository().LockDirCache(); ObjectReader r = git.GetRepository().ObjectDatabase.NewReader(); try { for (int i = 0; i < dc.GetEntryCount(); ++i) { DirCacheEntry entry = dc.GetEntry(i); if (entry.Length > 0) { NUnit.Framework.Assert.AreEqual(entry.Length, r.GetObjectSize(entry.GetObjectId() , ObjectReader.OBJ_ANY)); } } } finally { dc.Unlock(); r.Release(); } }
public virtual void TestFindObjects() { DirCache tree0 = DirCache.NewInCore(); DirCacheBuilder b0 = tree0.Builder(); ObjectReader or = db.NewObjectReader(); ObjectInserter oi = db.NewObjectInserter(); DirCacheEntry aDotB = MakeEntry("a.b", EXECUTABLE_FILE); b0.Add(aDotB); DirCacheEntry aSlashB = MakeEntry("a/b", REGULAR_FILE); b0.Add(aSlashB); DirCacheEntry aSlashCSlashD = MakeEntry("a/c/d", REGULAR_FILE); b0.Add(aSlashCSlashD); DirCacheEntry aZeroB = MakeEntry("a0b", SYMLINK); b0.Add(aZeroB); b0.Finish(); NUnit.Framework.Assert.AreEqual(4, tree0.GetEntryCount()); ObjectId tree = tree0.WriteTree(oi); // Find the directories that were implicitly created above. TreeWalk tw = new TreeWalk(or); tw.AddTree(tree); ObjectId a = null; ObjectId aSlashC = null; while (tw.Next()) { if (tw.PathString.Equals("a")) { a = tw.GetObjectId(0); tw.EnterSubtree(); while (tw.Next()) { if (tw.PathString.Equals("a/c")) { aSlashC = tw.GetObjectId(0); break; } } break; } } NUnit.Framework.Assert.AreEqual(a, TreeWalk.ForPath(or, "a", tree).GetObjectId(0) ); NUnit.Framework.Assert.AreEqual(a, TreeWalk.ForPath(or, "a/", tree).GetObjectId(0 )); NUnit.Framework.Assert.AreEqual(null, TreeWalk.ForPath(or, "/a", tree)); NUnit.Framework.Assert.AreEqual(null, TreeWalk.ForPath(or, "/a/", tree)); NUnit.Framework.Assert.AreEqual(aDotB.GetObjectId(), TreeWalk.ForPath(or, "a.b", tree).GetObjectId(0)); NUnit.Framework.Assert.AreEqual(null, TreeWalk.ForPath(or, "/a.b", tree)); NUnit.Framework.Assert.AreEqual(null, TreeWalk.ForPath(or, "/a.b/", tree)); NUnit.Framework.Assert.AreEqual(aDotB.GetObjectId(), TreeWalk.ForPath(or, "a.b/", tree).GetObjectId(0)); NUnit.Framework.Assert.AreEqual(aZeroB.GetObjectId(), TreeWalk.ForPath(or, "a0b", tree).GetObjectId(0)); NUnit.Framework.Assert.AreEqual(aSlashB.GetObjectId(), TreeWalk.ForPath(or, "a/b" , tree).GetObjectId(0)); NUnit.Framework.Assert.AreEqual(aSlashB.GetObjectId(), TreeWalk.ForPath(or, "b", a).GetObjectId(0)); NUnit.Framework.Assert.AreEqual(aSlashC, TreeWalk.ForPath(or, "a/c", tree).GetObjectId (0)); NUnit.Framework.Assert.AreEqual(aSlashC, TreeWalk.ForPath(or, "c", a).GetObjectId (0)); NUnit.Framework.Assert.AreEqual(aSlashCSlashD.GetObjectId(), TreeWalk.ForPath(or, "a/c/d", tree).GetObjectId(0)); NUnit.Framework.Assert.AreEqual(aSlashCSlashD.GetObjectId(), TreeWalk.ForPath(or, "c/d", a).GetObjectId(0)); or.Release(); oi.Release(); }