예제 #1
0
        /// <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);
                }
            }
        }
예제 #2
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);
        }
예제 #3
0
파일: IndexDiff.cs 프로젝트: shoff/ngit
        /// <summary>Run the diff operation.</summary>
        /// <remarks>
        /// Run the diff operation. Until this is called, all lists will be empty.
        /// <p>
        /// The operation may be aborted by the progress monitor. In that event it
        /// will report what was found before the cancel operation was detected.
        /// Callers should ignore the result if monitor.isCancelled() is true. If a
        /// progress monitor is not needed, callers should use
        /// <see cref="Diff()">Diff()</see>
        /// instead. Progress reporting is crude and approximate and only intended
        /// for informing the user.
        /// </remarks>
        /// <param name="monitor">for reporting progress, may be null</param>
        /// <param name="estWorkTreeSize">number or estimated files in the working tree</param>
        /// <param name="estIndexSize">number of estimated entries in the cache</param>
        /// <param name="title"></param>
        /// <returns>if anything is different between index, tree, and workdir</returns>
        /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
        public virtual bool Diff(ProgressMonitor monitor, int estWorkTreeSize, int estIndexSize
                                 , string title)
        {
            dirCache = repository.ReadDirCache();
            TreeWalk treeWalk = new TreeWalk(repository);

            treeWalk.Recursive = true;
            // add the trees (tree, dirchache, workdir)
            if (tree != null)
            {
                treeWalk.AddTree(tree);
            }
            else
            {
                treeWalk.AddTree(new EmptyTreeIterator());
            }
            treeWalk.AddTree(new DirCacheIterator(dirCache));
            treeWalk.AddTree(initialWorkingTreeIterator);
            ICollection <TreeFilter> filters = new AList <TreeFilter>(4);

            if (monitor != null)
            {
                // Get the maximum size of the work tree and index
                // and add some (quite arbitrary)
                if (estIndexSize == 0)
                {
                    estIndexSize = dirCache.GetEntryCount();
                }
                int total = Math.Max(estIndexSize * 10 / 9, estWorkTreeSize * 10 / 9);
                monitor.BeginTask(title, total);
                filters.AddItem(new IndexDiff.ProgressReportingFilter(monitor, total));
            }
            if (filter != null)
            {
                filters.AddItem(filter);
            }
            filters.AddItem(new SkipWorkTreeFilter(INDEX));
            filters.AddItem(new IndexDiffFilter(INDEX, WORKDIR));
            treeWalk.Filter = AndTreeFilter.Create(filters);
            while (treeWalk.Next())
            {
                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)
                    {
                        conflicts.AddItem(treeWalk.PathString);
                        continue;
                    }
                }
                if (treeIterator != null)
                {
                    if (dirCacheIterator != null)
                    {
                        if (!treeIterator.IdEqual(dirCacheIterator) || treeIterator.EntryRawMode != dirCacheIterator
                            .EntryRawMode)
                        {
                            // in repo, in index, content diff => changed
                            changed.AddItem(treeWalk.PathString);
                        }
                    }
                    else
                    {
                        // in repo, not in index => removed
                        removed.AddItem(treeWalk.PathString);
                        if (workingTreeIterator != null)
                        {
                            untracked.AddItem(treeWalk.PathString);
                        }
                    }
                }
                else
                {
                    if (dirCacheIterator != null)
                    {
                        // not in repo, in index => added
                        added.AddItem(treeWalk.PathString);
                    }
                    else
                    {
                        // not in repo, not in index => untracked
                        if (workingTreeIterator != null && !workingTreeIterator.IsEntryIgnored())
                        {
                            untracked.AddItem(treeWalk.PathString);
                        }
                    }
                }
                if (dirCacheIterator != null)
                {
                    if (workingTreeIterator == null)
                    {
                        // in index, not in workdir => missing
                        missing.AddItem(treeWalk.PathString);
                    }
                    else
                    {
                        if (workingTreeIterator.IsModified(dirCacheIterator.GetDirCacheEntry(), true))
                        {
                            // in index, in workdir, content differs => modified
                            modified.AddItem(treeWalk.PathString);
                        }
                    }
                }
            }
            // consume the remaining work
            if (monitor != null)
            {
                monitor.EndTask();
            }
            if (added.IsEmpty() && changed.IsEmpty() && removed.IsEmpty() && missing.IsEmpty(
                    ) && modified.IsEmpty() && untracked.IsEmpty())
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }