public override void skipEntriesEqual() { AbstractTreeIterator ch = CurrentHead; for (int i = 0; i < Trees.Length; i++) { AbstractTreeIterator t = Trees[i]; if (t.Matches != ch) { continue; } if (t.MatchShift == 0) { t.skip(); } else { t.back(t.MatchShift); t.MatchShift = 0; } t.Matches = null; } }
/// <summary>A conflict is detected - add the three different stages to the index</summary> /// <param name="path">the path of the conflicting entry</param> /// <param name="e">the previous index entry</param> /// <param name="h">the first tree you want to merge (the HEAD)</param> /// <param name="m">the second tree you want to merge</param> private void Conflict(string path, DirCacheEntry e, AbstractTreeIterator h, AbstractTreeIterator m) { conflicts.AddItem(path); DirCacheEntry entry; if (e != null) { entry = new DirCacheEntry(e.PathString, DirCacheEntry.STAGE_1); entry.CopyMetaData(e); builder.Add(entry); } if (h != null && !FileMode.TREE.Equals(h.EntryFileMode)) { entry = new DirCacheEntry(h.EntryPathString, DirCacheEntry.STAGE_2); entry.FileMode = h.EntryFileMode; entry.SetObjectId(h.EntryObjectId); builder.Add(entry); } if (m != null && !FileMode.TREE.Equals(m.EntryFileMode)) { entry = new DirCacheEntry(m.EntryPathString, DirCacheEntry.STAGE_3); entry.FileMode = m.EntryFileMode; entry.SetObjectId(m.EntryObjectId); builder.Add(entry); } }
public override AbstractTreeIterator min() { while (true) { AbstractTreeIterator minRef = FastMin(); if (_fastMinHasMatch) { return(minRef); } if (IsTree(minRef)) { if (SkipEntry(minRef)) { foreach (AbstractTreeIterator t in Trees) { if (t.Matches != minRef) { continue; } t.next(1); t.Matches = null; } continue; } return(minRef); } return(CombineDF(minRef)); } }
/// <summary> /// Set the tree used by this walk for finding /// <code>.gitmodules</code> /// . /// <p> /// The root tree is not read until the first submodule is encountered by the /// walk. /// <p> /// This method need only be called if constructing a walk manually instead of /// with one of the static factory methods above. /// </summary> /// <param name="tree">tree containing .gitmodules</param> /// <returns>this generator</returns> public virtual NGit.Submodule.SubmoduleWalk SetRootTree(AbstractTreeIterator tree ) { rootTree = tree; modulesConfig = null; return(this); }
/// <summary>Would unstashing overwrite local changes?</summary> /// <param name="stashIndexIter"></param> /// <param name="stashWorkingTreeIter"></param> /// <param name="headIter"></param> /// <param name="indexIter"></param> /// <param name="workingTreeIter"></param> /// <returns>true if unstash conflict, false otherwise</returns> private bool IsConflict(AbstractTreeIterator stashIndexIter, AbstractTreeIterator stashWorkingTreeIter, AbstractTreeIterator headIter, AbstractTreeIterator indexIter , AbstractTreeIterator workingTreeIter) { // Is the current index dirty? bool indexDirty = indexIter != null && (headIter == null || !IsEqualEntry(indexIter , headIter)); // Is the current working tree dirty? bool workingTreeDirty = workingTreeIter != null && (headIter == null || !IsEqualEntry (workingTreeIter, headIter)); // Would unstashing overwrite existing index changes? if (indexDirty && stashIndexIter != null && indexIter != null && !IsEqualEntry(stashIndexIter , indexIter)) { return(true); } // Would unstashing overwrite existing working tree changes? if (workingTreeDirty && stashWorkingTreeIter != null && workingTreeIter != null && !IsEqualEntry(stashWorkingTreeIter, workingTreeIter)) { return(true); } return(false); }
/// <summary> /// Create a generator and advance it to the submodule entry at the given /// path /// </summary> /// <param name="repository"></param> /// <param name="iterator"> /// the root of a tree containing both a submodule at the given path /// and .gitmodules at the root. /// </param> /// <param name="path"></param> /// <returns>generator at given path, null if no submodule at given path</returns> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public static NGit.Submodule.SubmoduleWalk ForPath(Repository repository, AbstractTreeIterator iterator, string path) { NGit.Submodule.SubmoduleWalk generator = new NGit.Submodule.SubmoduleWalk(repository ); try { generator.SetTree(iterator); PathFilter filter = PathFilter.Create(path); generator.SetFilter(filter); generator.SetRootTree(iterator); while (generator.Next()) { if (filter.IsDone(generator.walk)) { return(generator); } } } catch (IOException e) { generator.Release(); throw; } generator.Release(); return(null); }
private ContentSource Source(AbstractTreeIterator iterator) { if (iterator is WorkingTreeIterator) { return(ContentSource.Create((WorkingTreeIterator)iterator)); } return(ContentSource.Create(reader)); }
/// <summary> /// Set the tree used by this walk for finding /// <code>.gitmodules</code> /// . /// <p> /// The root tree is not read until the first submodule is encountered by the /// walk. /// <p> /// This method need only be called if constructing a walk manually instead of /// with one of the static factory methods above. /// </summary> /// <param name="id">ID of a tree containing .gitmodules</param> /// <returns>this generator</returns> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> public virtual NGit.Submodule.SubmoduleWalk SetRootTree(AnyObjectId id) { CanonicalTreeParser p = new CanonicalTreeParser(); p.Reset(walk.ObjectReader, id); rootTree = p; modulesConfig = null; return(this); }
public virtual void testCreateSubtreeIterator() { EmptyTreeIterator etp = new EmptyTreeIterator(); AbstractTreeIterator sub = etp.createSubtreeIterator(db); Assert.IsNotNull(sub); Assert.IsTrue(sub.first()); Assert.IsTrue(sub.eof()); Assert.IsTrue(sub is EmptyTreeIterator); }
private bool IsEqualEntry(AbstractTreeIterator iter1, AbstractTreeIterator iter2) { if (!iter1.EntryFileMode.Equals(iter2.EntryFileMode)) { return(false); } ObjectId id1 = iter1.EntryObjectId; ObjectId id2 = iter2.EntryObjectId; return(id1 != null?id1.Equals(id2) : id2 == null); }
/// <summary>Determine the differences between two trees.</summary> /// <remarks> /// Determine the differences between two trees. /// No output is created, instead only the file paths that are different are /// returned. Callers may choose to format these paths themselves, or convert /// them into /// <see cref="NGit.Patch.FileHeader">NGit.Patch.FileHeader</see> /// instances with a complete edit list by /// calling /// <see cref="ToFileHeader(DiffEntry)">ToFileHeader(DiffEntry)</see> /// . /// </remarks> /// <param name="a">the old (or previous) side.</param> /// <param name="b">the new (or updated) side.</param> /// <returns>the paths that are different.</returns> /// <exception cref="System.IO.IOException">trees cannot be read or file contents cannot be read. /// </exception> public virtual IList <DiffEntry> Scan(AbstractTreeIterator a, AbstractTreeIterator b) { AssertHaveRepository(); TreeWalk walk = new TreeWalk(reader); walk.AddTree(a); walk.AddTree(b); walk.Recursive = true; TreeFilter filter = GetDiffTreeFilterFor(a, b); if (pathFilter is FollowFilter) { walk.Filter = AndTreeFilter.Create(PathFilter.Create(((FollowFilter)pathFilter).GetPath ()), filter); } else { walk.Filter = AndTreeFilter.Create(pathFilter, filter); } source = new ContentSource.Pair(Source(a), Source(b)); IList <DiffEntry> files = DiffEntry.Scan(walk); if (pathFilter is FollowFilter && IsAdd(files)) { // The file we are following was added here, find where it // came from so we can properly show the rename or copy, // then continue digging backwards. // a.Reset(); b.Reset(); walk.Reset(); walk.AddTree(a); walk.AddTree(b); walk.Filter = filter; if (renameDetector == null) { SetDetectRenames(true); } files = UpdateFollowFilter(DetectRenames(DiffEntry.Scan(walk))); } else { if (renameDetector != null) { files = DetectRenames(files); } } return(files); }
public void testSimpleIterate() { var top = new FileTreeIterator(trash); Assert.IsTrue(top.first()); Assert.IsFalse(top.eof()); Assert.IsTrue(FileMode.RegularFile == top.EntryFileMode); Assert.AreEqual(Paths[0], NameOf(top)); Assert.AreEqual(Paths[0].Length, top.getEntryLength()); Assert.AreEqual(_mtime[0], top.getEntryLastModified()); top.next(1); Assert.IsFalse(top.first()); Assert.IsFalse(top.eof()); Assert.IsTrue(FileMode.RegularFile == top.EntryFileMode); Assert.AreEqual(Paths[1], NameOf(top)); Assert.AreEqual(Paths[1].Length, top.getEntryLength()); Assert.AreEqual(_mtime[1], top.getEntryLastModified()); top.next(1); Assert.IsFalse(top.first()); Assert.IsFalse(top.eof()); Assert.IsTrue(FileMode.Tree == top.EntryFileMode); AbstractTreeIterator sub = top.createSubtreeIterator(db); Assert.IsTrue(sub is FileTreeIterator); var subfti = (FileTreeIterator)sub; Assert.IsTrue(sub.first()); Assert.IsFalse(sub.eof()); Assert.AreEqual(Paths[2], NameOf(sub)); Assert.AreEqual(Paths[2].Length, subfti.getEntryLength()); Assert.AreEqual(_mtime[2], subfti.getEntryLastModified()); sub.next(1); Assert.IsTrue(sub.eof()); top.next(1); Assert.IsFalse(top.first()); Assert.IsFalse(top.eof()); Assert.IsTrue(FileMode.RegularFile == top.EntryFileMode); Assert.AreEqual(Paths[3], NameOf(top)); Assert.AreEqual(Paths[3].Length, top.getEntryLength()); Assert.AreEqual(_mtime[3], top.getEntryLastModified()); top.next(1); Assert.IsTrue(top.eof()); }
/// <exception cref="System.IO.IOException"></exception> private void ApplyChanges(TreeWalk treeWalk, DirCache cache, DirCacheEditor editor ) { FilePath workingTree = repo.WorkTree; while (treeWalk.Next()) { string path = treeWalk.PathString; FilePath file = new FilePath(workingTree, path); // State of the stashed HEAD, index, and working directory AbstractTreeIterator stashHeadIter = treeWalk.GetTree <AbstractTreeIterator>(0); AbstractTreeIterator stashIndexIter = treeWalk.GetTree <AbstractTreeIterator>(1); AbstractTreeIterator stashWorkingIter = treeWalk.GetTree <AbstractTreeIterator>(2); if (stashWorkingIter != null && stashIndexIter != null) { // Checkout index change DirCacheEntry entry = cache.GetEntry(path); if (entry == null) { entry = new DirCacheEntry(treeWalk.RawPath); } entry.FileMode = stashIndexIter.EntryFileMode; entry.SetObjectId(stashIndexIter.EntryObjectId); DirCacheCheckout.CheckoutEntry(repo, file, entry, treeWalk.ObjectReader); DirCacheEntry updatedEntry = entry; editor.Add(new _PathEdit_270(updatedEntry, path)); // Checkout working directory change if (!stashWorkingIter.IdEqual(stashIndexIter)) { entry = new DirCacheEntry(treeWalk.RawPath); entry.SetObjectId(stashWorkingIter.EntryObjectId); DirCacheCheckout.CheckoutEntry(repo, file, entry, treeWalk.ObjectReader); } } else { if (stashIndexIter == null || (stashHeadIter != null && !stashIndexIter.IdEqual(stashHeadIter ))) { editor.Add(new DirCacheEditor.DeletePath(path)); } FileUtils.Delete(file, FileUtils.RETRY | FileUtils.SKIP_MISSING); } } }
/// <exception cref="System.IO.IOException"></exception> private void ResetIndex(RevCommit commit) { DirCache dc = repo.LockDirCache(); TreeWalk walk = null; try { DirCacheEditor editor = dc.Editor(); walk = new TreeWalk(repo); walk.AddTree(commit.Tree); walk.AddTree(new DirCacheIterator(dc)); walk.Recursive = true; while (walk.Next()) { AbstractTreeIterator cIter = walk.GetTree <AbstractTreeIterator>(0); if (cIter == null) { editor.Add(new DirCacheEditor.DeletePath(walk.PathString)); continue; } DirCacheEntry entry = new DirCacheEntry(walk.RawPath); entry.FileMode = cIter.EntryFileMode; entry.SetObjectIdFromRaw(cIter.IdBuffer, cIter.IdOffset); DirCacheIterator dcIter = walk.GetTree <DirCacheIterator>(1); if (dcIter != null && dcIter.IdEqual(cIter)) { DirCacheEntry indexEntry = dcIter.GetDirCacheEntry(); entry.LastModified = indexEntry.LastModified; entry.SetLength(indexEntry.Length); } editor.Add(new _PathEdit_356(entry, entry)); } editor.Commit(); } finally { dc.Unlock(); if (walk != null) { walk.Release(); } } }
private bool SkipEntry(AbstractTreeIterator minRef) { // A tree D/F may have been handled earlier. We need to // not report this path if it has already been reported. // foreach (AbstractTreeIterator t in Trees) { if (t.Matches == minRef || t.first()) { continue; } int stepsBack = 0; while (true) { stepsBack++; t.back(1); int cmp = t.pathCompare(minRef, 0); if (cmp == 0) { // We have already seen this "$path" before. Skip it. // t.next(stepsBack); return(true); } if (cmp >= 0 && !t.first()) { continue; } // We cannot find "$path" in t; it will never appear. // t.next(stepsBack); break; } } // We have never seen the current path before. // return(false); }
/// <exception cref="System.IO.IOException"></exception> private void Add(int tree, int stage) { AbstractTreeIterator i = GetTree(tree); if (i != null) { if (FileMode.TREE.Equals(tw.GetRawMode(tree))) { builder.AddTree(tw.RawPath, stage, reader, tw.GetObjectId(tree)); } else { DirCacheEntry e; e = new DirCacheEntry(tw.RawPath, stage); e.SetObjectIdFromRaw(i.IdBuffer, i.IdOffset); e.FileMode = tw.GetFileMode(tree); builder.Add(e); } } }
private void Add(int tree, int stage) { AbstractTreeIterator i = GetTree(tree); if (i == null) { return; } if (FileMode.Tree.Equals(_tw.getRawMode(tree))) { _builder.addTree(_tw.getRawPath(), stage, Repository, _tw.getObjectId(tree)); } else { var e = new DirCacheEntry(_tw.getRawPath(), stage); e.setObjectIdFromRaw(i.idBuffer(), i.idOffset()); e.setFileMode(_tw.getFileMode(tree)); _builder.add(e); } }
/// <exception cref="System.IO.IOException"></exception> private void ScanForConflicts(TreeWalk treeWalk) { FilePath workingTree = repo.WorkTree; while (treeWalk.Next()) { // State of the stashed index and working directory AbstractTreeIterator stashIndexIter = treeWalk.GetTree <AbstractTreeIterator>(1); AbstractTreeIterator stashWorkingIter = treeWalk.GetTree <AbstractTreeIterator>(2); // State of the current HEAD, index, and working directory AbstractTreeIterator headIter = treeWalk.GetTree <AbstractTreeIterator>(3); AbstractTreeIterator indexIter = treeWalk.GetTree <AbstractTreeIterator>(4); AbstractTreeIterator workingIter = treeWalk.GetTree <AbstractTreeIterator>(5); if (IsConflict(stashIndexIter, stashWorkingIter, headIter, indexIter, workingIter )) { string path = treeWalk.PathString; FilePath file = new FilePath(workingTree, path); throw new NGit.Errors.CheckoutConflictException(file.GetAbsolutePath()); } } }
public override void popEntriesEqual() { AbstractTreeIterator ch = CurrentHead; for (int i = 0; i < Trees.Length; i++) { AbstractTreeIterator t = Trees[i]; if (t.Matches == ch) { if (t.MatchShift == 0) { t.next(1); } else { t.back(t.MatchShift); t.MatchShift = 0; } t.Matches = null; } } }
private static TreeFilter GetDiffTreeFilterFor(AbstractTreeIterator a, AbstractTreeIterator b) { if (a is DirCacheIterator && b is WorkingTreeIterator) { return(new IndexDiffFilter(0, 1)); } if (a is WorkingTreeIterator && b is DirCacheIterator) { return(new IndexDiffFilter(1, 0)); } TreeFilter filter = TreeFilter.ANY_DIFF; if (a is WorkingTreeIterator) { filter = AndTreeFilter.Create(new NotIgnoredFilter(0), filter); } if (b is WorkingTreeIterator) { filter = AndTreeFilter.Create(new NotIgnoredFilter(1), filter); } return(filter); }
private static string NameOf(AbstractTreeIterator i) { return(RawParseUtils.decode(Constants.CHARSET, i.Path, 0, i.PathLen)); }
/// <summary>Format the differences between two trees.</summary> /// <remarks> /// Format the differences between two trees. /// The patch is expressed as instructions to modify /// <code>a</code> /// to make it /// <code>b</code> /// . /// </remarks> /// <param name="a">the old (or previous) side.</param> /// <param name="b">the new (or updated) side.</param> /// <exception cref="System.IO.IOException"> /// trees cannot be read, file contents cannot be read, or the /// patch cannot be output. /// </exception> public virtual void Format(AbstractTreeIterator a, AbstractTreeIterator b) { Format(Scan(a, b)); }
public EmptyTreeIterator(AbstractTreeIterator p) : base(p) { pathLen = pathOffset; }
/// <summary> /// Create an iterator for a subtree of an existing iterator. /// The caller is responsible for setting up the path of the child iterator. /// </summary> /// <param name="parentIterator">Parent tree iterator.</param> public EmptyTreeIterator(AbstractTreeIterator parentIterator) : base(parentIterator) { PathLen = PathOffset; }
/// <summary> /// Create an iterator for a subtree of an existing iterator. /// The caller is responsible for setting up the path of the child iterator. /// </summary> /// <param name="parent">Parent tree iterator.</param> /// <param name="childPath"> /// Path array to be used by the child iterator. This path must /// contain the path from the top of the walk to the first child /// and must end with a '/'. /// </param> /// <param name="childPathOffset"> /// position within <paramref name="childPath"/> where the child can /// insert its data. The value at /// <code><paramref name="childPath"/>[<paramref name="childPathOffset"/>-1]</code> /// must be '/'. /// </param> public EmptyTreeIterator(AbstractTreeIterator parent, byte[] childPath, int childPathOffset) : base(parent, childPath, childPathOffset) { PathLen = childPathOffset - 1; }
private AbstractTreeIterator CombineDF(AbstractTreeIterator minRef) { // Look for a possible D/F conflict forward in the tree(s) // as there may be a "$path/" which matches "$path". Make // such entries match this entry. // AbstractTreeIterator treeMatch = null; foreach (AbstractTreeIterator t in Trees) { if (t.Matches == minRef || t.eof()) { continue; } for (; ;) { int cmp = t.pathCompare(minRef, TreeMode); if (cmp < 0) { // The "$path/" may still appear later. // t.MatchShift++; t.next(1); if (t.eof()) { t.back(t.MatchShift); t.MatchShift = 0; break; } } else if (cmp == 0) { // We have a conflict match here. // t.Matches = minRef; treeMatch = t; break; } else { // A conflict match is not possible. // if (t.MatchShift != 0) { t.back(t.MatchShift); t.MatchShift = 0; } break; } } } if (treeMatch != null) { // If we do have a conflict use one of the directory // matching iterators instead of the file iterator. // This way isSubtree is true and isRecursive works. // foreach (AbstractTreeIterator t in Trees) { if (t.Matches == minRef) { t.Matches = treeMatch; } } return(treeMatch); } return(minRef); }
private static bool IsTree(AbstractTreeIterator p) { return FileMode.Tree == p.EntryFileMode; }
private static bool nameEqual(AbstractTreeIterator a, AbstractTreeIterator b) { return a.pathCompare(b, TREE_MODE) == 0; }
private GitFileStatus GetFileStatus(TreeWalk treeWalk) { AbstractTreeIterator treeIterator = treeWalk.GetTree <AbstractTreeIterator>(TREE); DirCacheIterator dirCacheIterator = treeWalk.GetTree <DirCacheIterator>(INDEX); WorkingTreeIterator workingTreeIterator = treeWalk.GetTree <WorkingTreeIterator>(WORKDIR); if (dirCacheIterator != null) { DirCacheEntry dirCacheEntry = dirCacheIterator.GetDirCacheEntry(); if (dirCacheEntry != null && dirCacheEntry.Stage > 0) { return(GitFileStatus.Conflict); } if (workingTreeIterator == null) { // in index, not in workdir => missing return(GitFileStatus.Deleted); } else { if (workingTreeIterator.IsModified(dirCacheIterator.GetDirCacheEntry(), true)) { // in index, in workdir, content differs => modified return(GitFileStatus.Modified); } } } if (treeIterator != null) { if (dirCacheIterator != null) { if (!treeIterator.IdEqual(dirCacheIterator) || treeIterator.EntryRawMode != dirCacheIterator.EntryRawMode) { // in repo, in index, content diff => changed return(GitFileStatus.Staged); } } else { return(GitFileStatus.Removed); } } else { if (dirCacheIterator != null) { // not in repo, in index => added return(GitFileStatus.Added); } else { // not in repo, not in index => untracked if (workingTreeIterator != null) { return(!workingTreeIterator.IsEntryIgnored() ? GitFileStatus.New : GitFileStatus.Ignored); } } } return(GitFileStatus.NotControlled); }
private AbstractTreeIterator CombineDF(AbstractTreeIterator minRef) { // Look for a possible D/F conflict forward in the tree(s) // as there may be a "$path/" which matches "$path". Make // such entries match this entry. // AbstractTreeIterator treeMatch = null; foreach (AbstractTreeIterator t in Trees) { if (t.Matches == minRef || t.eof()) continue; for (; ; ) { int cmp = t.pathCompare(minRef, TreeMode); if (cmp < 0) { // The "$path/" may still appear later. // t.MatchShift++; t.next(1); if (t.eof()) { t.back(t.MatchShift); t.MatchShift = 0; break; } } else if (cmp == 0) { // We have a conflict match here. // t.Matches = minRef; treeMatch = t; break; } else { // A conflict match is not possible. // if (t.MatchShift != 0) { t.back(t.MatchShift); t.MatchShift = 0; } break; } } } if (treeMatch != null) { // If we do have a conflict use one of the directory // matching iterators instead of the file iterator. // This way isSubtree is true and isRecursive works. // foreach (AbstractTreeIterator t in Trees) { if (t.Matches == minRef) { t.Matches = treeMatch; } } return treeMatch; } return minRef; }
private static bool NameEqual(AbstractTreeIterator a, AbstractTreeIterator b) { return a.pathCompare(b, TreeMode) == 0; }
/// <summary> /// Run the diff operation. Until this is called, all lists will be empty /// </summary> /// <returns>true if anything is different between index, tree, and workdir</returns> private void UpdateDirectory(IEnumerable <string> paths, bool recursive) { RevWalk rw = new RevWalk(Repository); ObjectId id = Repository.Resolve(Constants.HEAD); var commit = id != null?rw.ParseCommit(id) : null; TreeWalk treeWalk = new TreeWalk(Repository); treeWalk.Reset(); treeWalk.Recursive = false; if (commit != null) { treeWalk.AddTree(commit.Tree); } else { treeWalk.AddTree(new EmptyTreeIterator()); } DirCache dc = Repository.ReadDirCache(); treeWalk.AddTree(new DirCacheIterator(dc)); FileTreeIterator workTree = new FileTreeIterator(Repository.WorkTree, Repository.FileSystem, WorkingTreeOptions.KEY.Parse(Repository.GetConfig())); treeWalk.AddTree(workTree); List <TreeFilter> filters = new List <TreeFilter> (); filters.Add(new SkipWorkTreeFilter(1)); var pathFilters = paths.Where(p => p != ".").Select(p => PathFilter.Create(p)).ToArray(); if (pathFilters.Length > 1) { filters.Add(OrTreeFilter.Create(pathFilters)); // Use an OR to join all path filters } else if (pathFilters.Length == 1) { filters.Add(pathFilters[0]); } if (filters.Count > 1) { treeWalk.Filter = AndTreeFilter.Create(filters); } else { treeWalk.Filter = filters[0]; } while (treeWalk.Next()) { AbstractTreeIterator treeIterator = treeWalk.GetTree <AbstractTreeIterator>(0); DirCacheIterator dirCacheIterator = treeWalk.GetTree <DirCacheIterator>(1); WorkingTreeIterator workingTreeIterator = treeWalk.GetTree <WorkingTreeIterator>(2); NGit.FileMode fileModeTree = treeWalk.GetFileMode(0); if (treeWalk.IsSubtree) { treeWalk.EnterSubtree(); continue; } int stage = dirCacheIterator != null?dirCacheIterator.GetDirCacheEntry().Stage : 0; if (stage > 1) { continue; } else if (stage == 1) { MergeConflict.Add(dirCacheIterator.EntryPathString); changesExist = true; continue; } if (treeIterator != null) { if (dirCacheIterator != null) { if (!treeIterator.EntryObjectId.Equals(dirCacheIterator.EntryObjectId)) { // in repo, in index, content diff => changed Modified.Add(dirCacheIterator.EntryPathString); changesExist = true; } } else { // in repo, not in index => removed if (!fileModeTree.Equals(NGit.FileMode.TYPE_TREE)) { Removed.Add(treeIterator.EntryPathString); changesExist = true; } } } else { if (dirCacheIterator != null) { // not in repo, in index => added Added.Add(dirCacheIterator.EntryPathString); changesExist = true; } else { // not in repo, not in index => untracked if (workingTreeIterator != null && !workingTreeIterator.IsEntryIgnored()) { Untracked.Add(workingTreeIterator.EntryPathString); changesExist = true; } } } if (dirCacheIterator != null) { if (workingTreeIterator == null) { // in index, not in workdir => missing Missing.Add(dirCacheIterator.EntryPathString); changesExist = true; } else { // Workaround to file time resolution issues long itime = dirCacheIterator.GetDirCacheEntry().LastModified; long ftime = workingTreeIterator.GetEntryLastModified(); if (itime / 1000 != ftime / 1000) { if (!dirCacheIterator.IdEqual(workingTreeIterator)) { // in index, in workdir, content differs => modified Modified.Add(dirCacheIterator.EntryPathString); changesExist = true; } } } } } }
private bool SkipEntry(AbstractTreeIterator minRef) { // A tree D/F may have been handled earlier. We need to // not report this path if it has already been reported. // foreach (AbstractTreeIterator t in Trees) { if (t.Matches == minRef || t.first()) continue; int stepsBack = 0; while (true) { stepsBack++; t.back(1); int cmp = t.pathCompare(minRef, 0); if (cmp == 0) { // We have already seen this "$path" before. Skip it. // t.next(stepsBack); return true; } if (cmp >= 0 && !t.first()) continue; // We cannot find "$path" in t; it will never appear. // t.next(stepsBack); break; } } // We have never seen the current path before. // return false; }
private AbstractTreeIterator FastMin() { _fastMinHasMatch = true; int i = 0; AbstractTreeIterator minRef = Trees[i]; while (minRef.eof() && ++i < Trees.Length) { minRef = Trees[i]; } if (minRef.eof()) { return(minRef); } minRef.Matches = minRef; while (++i < Trees.Length) { AbstractTreeIterator t = Trees[i]; if (t.eof()) { continue; } int cmp = t.pathCompare(minRef); if (cmp < 0) { if (_fastMinHasMatch && IsTree(minRef) && !IsTree(t) && NameEqual(minRef, t)) { // We used to be at a tree, but now we are at a file // with the same name. Allow the file to match the // tree anyway. // t.Matches = minRef; } else { _fastMinHasMatch = false; t.Matches = t; minRef = t; } } else if (cmp == 0) { // Exact name/mode match is best. // t.Matches = minRef; } else if (_fastMinHasMatch && IsTree(t) && !IsTree(minRef) && NameEqual(t, minRef)) { // The minimum is a file (non-tree) but the next entry // of this iterator is a tree whose name matches our file. // This is a classic D/F conflict and commonly occurs like // this, with no gaps in between the file and directory. // // Use the tree as the minimum instead (see CombineDF). // for (int k = 0; k < i; k++) { AbstractTreeIterator p = Trees[k]; if (p.Matches == minRef) { p.Matches = t; } } t.Matches = t; minRef = t; } else { _fastMinHasMatch = false; } } return(minRef); }
private static bool NameEqual(AbstractTreeIterator a, AbstractTreeIterator b) { return(a.pathCompare(b, TreeMode) == 0); }
private static bool IsTree(AbstractTreeIterator p) { return(FileMode.Tree == p.EntryFileMode); }
private static bool isTree(AbstractTreeIterator p) { return FileMode.Tree.Equals(p.mode); }