Exemplo n.º 1
0
        /// <exception cref="System.Exception"></exception>
        private DirCacheEntry MakeEntry(string path, FileMode mode)
        {
            DirCacheEntry ent = new DirCacheEntry(path);

            ent.FileMode = mode;
            ent.SetObjectId(new ObjectInserter.Formatter().IdFor(Constants.OBJ_BLOB, Constants
                                                                 .Encode(path)));
            return(ent);
        }
Exemplo n.º 2
0
        /// <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);
        }
Exemplo n.º 3
0
 public override void Apply(DirCacheEntry ent)
 {
     ent.SetObjectId(blobId);
     ent.FileMode = mode;
     try
     {
         DirCacheCheckout.CheckoutEntry(this._enclosing.repo, new FilePath(workTree, ent.PathString
                                                                           ), ent, r);
     }
     catch (IOException e)
     {
         throw new JGitInternalException(MessageFormat.Format(JGitText.Get().checkoutConflictWithFile
                                                              , ent.PathString), e);
     }
 }
Exemplo n.º 4
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);
                }
            }
        }
Exemplo n.º 5
0
        private void ResetIndexForPaths(RevCommit commit)
        {
            DirCache dc = null;

            try
            {
                dc = repo.LockDirCache();
                DirCacheBuilder builder = dc.Builder();
                TreeWalk        tw      = new TreeWalk(repo);
                tw.AddTree(new DirCacheBuildIterator(builder));
                tw.AddTree(commit.Tree);
                tw.Filter    = PathFilterGroup.CreateFromStrings(filepaths);
                tw.Recursive = true;
                while (tw.Next())
                {
                    CanonicalTreeParser tree = tw.GetTree <CanonicalTreeParser>(1);
                    // only keep file in index if it's in the commit
                    if (tree != null)
                    {
                        // revert index to commit
                        DirCacheEntry entry = new DirCacheEntry(tw.RawPath);
                        entry.FileMode = tree.EntryFileMode;
                        entry.SetObjectId(tree.EntryObjectId);
                        builder.Add(entry);
                    }
                }
                builder.Commit();
            }
            catch (IOException e)
            {
                throw new RuntimeException(e);
            }
            finally
            {
                if (dc != null)
                {
                    dc.Unlock();
                }
            }
        }
Exemplo n.º 6
0
            public override void Apply(DirCacheEntry ent)
            {
                if (checkoutIndex && ent.Stage > DirCacheEntry.STAGE_0)
                {
                    UnmergedPathException e = new UnmergedPathException(ent);
                    throw new JGitInternalException(e.Message, e);
                }
                ent.SetObjectId(blobId);
                ent.FileMode = mode;
                FilePath file      = new FilePath(workTree, ent.PathString);
                FilePath parentDir = file.GetParentFile();

                try
                {
                    FileUtils.Mkdirs(parentDir, true);
                    DirCacheCheckout.CheckoutEntry(this._enclosing.repo, file, ent, r);
                }
                catch (IOException e)
                {
                    throw new JGitInternalException(MessageFormat.Format(JGitText.Get().checkoutConflictWithFile
                                                                         , ent.PathString), e);
                }
            }
Exemplo n.º 7
0
        /// <summary>Processes one path and tries to merge.</summary>
        /// <remarks>
        /// Processes one path and tries to merge. This method will do all do all
        /// trivial (not content) merges and will also detect if a merge will fail.
        /// The merge will fail when one of the following is true
        /// <ul>
        /// <li>the index entry does not match the entry in ours. When merging one
        /// branch into the current HEAD, ours will point to HEAD and theirs will
        /// point to the other branch. It is assumed that the index matches the HEAD
        /// because it will only not match HEAD if it was populated before the merge
        /// operation. But the merge commit should not accidentally contain
        /// modifications done before the merge. Check the &lt;a href=
        /// "http://www.kernel.org/pub/software/scm/git/docs/git-read-tree.html#_3_way_merge"
        /// &gt;git read-tree</a> documentation for further explanations.</li>
        /// <li>A conflict was detected and the working-tree file is dirty. When a
        /// conflict is detected the content-merge algorithm will try to write a
        /// merged version into the working-tree. If the file is dirty we would
        /// override unsaved data.</li>
        /// </remarks>
        /// <param name="base">the common base for ours and theirs</param>
        /// <param name="ours">
        /// the ours side of the merge. When merging a branch into the
        /// HEAD ours will point to HEAD
        /// </param>
        /// <param name="theirs">
        /// the theirs side of the merge. When merging a branch into the
        /// current HEAD theirs will point to the branch which is merged
        /// into HEAD.
        /// </param>
        /// <param name="index">the index entry</param>
        /// <param name="work">the file in the working tree</param>
        /// <returns>
        /// <code>false</code> if the merge will fail because the index entry
        /// didn't match ours or the working-dir file was dirty and a
        /// conflict occurred
        /// </returns>
        /// <exception cref="NGit.Errors.MissingObjectException">NGit.Errors.MissingObjectException
        ///     </exception>
        /// <exception cref="NGit.Errors.IncorrectObjectTypeException">NGit.Errors.IncorrectObjectTypeException
        ///     </exception>
        /// <exception cref="NGit.Errors.CorruptObjectException">NGit.Errors.CorruptObjectException
        ///     </exception>
        /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
        private bool ProcessEntry(CanonicalTreeParser @base, CanonicalTreeParser ours, CanonicalTreeParser
                                  theirs, DirCacheBuildIterator index, WorkingTreeIterator work)
        {
            enterSubtree = true;
            int modeO = tw.GetRawMode(T_OURS);
            int modeT = tw.GetRawMode(T_THEIRS);
            int modeB = tw.GetRawMode(T_BASE);

            if (modeO == 0 && modeT == 0 && modeB == 0)
            {
                // File is either untracked or new, staged but uncommitted
                return(true);
            }
            if (IsIndexDirty())
            {
                return(false);
            }
            DirCacheEntry ourDce = null;

            if (index == null || index.GetDirCacheEntry() == null)
            {
                // create a fake DCE, but only if ours is valid. ours is kept only
                // in case it is valid, so a null ourDce is ok in all other cases.
                if (NonTree(modeO))
                {
                    ourDce = new DirCacheEntry(tw.RawPath);
                    ourDce.SetObjectId(tw.GetObjectId(T_OURS));
                    ourDce.FileMode = tw.GetFileMode(T_OURS);
                }
            }
            else
            {
                ourDce = index.GetDirCacheEntry();
            }
            if (NonTree(modeO) && NonTree(modeT) && tw.IdEqual(T_OURS, T_THEIRS))
            {
                // OURS and THEIRS have equal content. Check the file mode
                if (modeO == modeT)
                {
                    // content and mode of OURS and THEIRS are equal: it doesn't
                    // matter which one we choose. OURS is chosen. Since the index
                    // is clean (the index matches already OURS) we can keep the existing one
                    Keep(ourDce);
                    // no checkout needed!
                    return(true);
                }
                else
                {
                    // same content but different mode on OURS and THEIRS.
                    // Try to merge the mode and report an error if this is
                    // not possible.
                    int newMode = MergeFileModes(modeB, modeO, modeT);
                    if (newMode != FileMode.MISSING.GetBits())
                    {
                        if (newMode == modeO)
                        {
                            // ours version is preferred
                            Keep(ourDce);
                        }
                        else
                        {
                            // the preferred version THEIRS has a different mode
                            // than ours. Check it out!
                            if (IsWorktreeDirty(work))
                            {
                                return(false);
                            }
                            // we know about length and lastMod only after we have written the new content.
                            // This will happen later. Set these values to 0 for know.
                            DirCacheEntry e = Add(tw.RawPath, theirs, DirCacheEntry.STAGE_0, 0, 0);
                            toBeCheckedOut.Put(tw.PathString, e);
                        }
                        return(true);
                    }
                    else
                    {
                        // FileModes are not mergeable. We found a conflict on modes.
                        // For conflicting entries we don't know lastModified and length.
                        Add(tw.RawPath, @base, DirCacheEntry.STAGE_1, 0, 0);
                        Add(tw.RawPath, ours, DirCacheEntry.STAGE_2, 0, 0);
                        Add(tw.RawPath, theirs, DirCacheEntry.STAGE_3, 0, 0);
                        unmergedPaths.AddItem(tw.PathString);
                        mergeResults.Put(tw.PathString, new MergeResult <RawText>(Sharpen.Collections.EmptyList
                                                                                  <RawText>()).Upcast());
                    }
                    return(true);
                }
            }
            if (NonTree(modeO) && modeB == modeT && tw.IdEqual(T_BASE, T_THEIRS))
            {
                // THEIRS was not changed compared to BASE. All changes must be in
                // OURS. OURS is chosen. We can keep the existing entry.
                Keep(ourDce);
                // no checkout needed!
                return(true);
            }
            if (modeB == modeO && tw.IdEqual(T_BASE, T_OURS))
            {
                // OURS was not changed compared to BASE. All changes must be in
                // THEIRS. THEIRS is chosen.
                // Check worktree before checking out THEIRS
                if (IsWorktreeDirty(work))
                {
                    return(false);
                }
                if (NonTree(modeT))
                {
                    // we know about length and lastMod only after we have written
                    // the new content.
                    // This will happen later. Set these values to 0 for know.
                    DirCacheEntry e = Add(tw.RawPath, theirs, DirCacheEntry.STAGE_0, 0, 0);
                    if (e != null)
                    {
                        toBeCheckedOut.Put(tw.PathString, e);
                    }
                    return(true);
                }
                else
                {
                    if (modeT == 0 && modeB != 0)
                    {
                        // we want THEIRS ... but THEIRS contains the deletion of the
                        // file
                        toBeDeleted.AddItem(tw.PathString);
                        return(true);
                    }
                }
            }
            if (tw.IsSubtree)
            {
                // file/folder conflicts: here I want to detect only file/folder
                // conflict between ours and theirs. file/folder conflicts between
                // base/index/workingTree and something else are not relevant or
                // detected later
                if (NonTree(modeO) && !NonTree(modeT))
                {
                    if (NonTree(modeB))
                    {
                        Add(tw.RawPath, @base, DirCacheEntry.STAGE_1, 0, 0);
                    }
                    Add(tw.RawPath, ours, DirCacheEntry.STAGE_2, 0, 0);
                    unmergedPaths.AddItem(tw.PathString);
                    enterSubtree = false;
                    return(true);
                }
                if (NonTree(modeT) && !NonTree(modeO))
                {
                    if (NonTree(modeB))
                    {
                        Add(tw.RawPath, @base, DirCacheEntry.STAGE_1, 0, 0);
                    }
                    Add(tw.RawPath, theirs, DirCacheEntry.STAGE_3, 0, 0);
                    unmergedPaths.AddItem(tw.PathString);
                    enterSubtree = false;
                    return(true);
                }
                // ours and theirs are both folders or both files (and treewalk
                // tells us we are in a subtree because of index or working-dir).
                // If they are both folders no content-merge is required - we can
                // return here.
                if (!NonTree(modeO))
                {
                    return(true);
                }
            }
            // ours and theirs are both files, just fall out of the if block
            // and do the content merge
            if (NonTree(modeO) && NonTree(modeT))
            {
                // Check worktree before modifying files
                if (IsWorktreeDirty(work))
                {
                    return(false);
                }
                // Don't attempt to resolve submodule link conflicts
                if (IsGitLink(modeO) || IsGitLink(modeT))
                {
                    Add(tw.RawPath, @base, DirCacheEntry.STAGE_1, 0, 0);
                    Add(tw.RawPath, ours, DirCacheEntry.STAGE_2, 0, 0);
                    Add(tw.RawPath, theirs, DirCacheEntry.STAGE_3, 0, 0);
                    unmergedPaths.AddItem(tw.PathString);
                    return(true);
                }
                MergeResult <RawText> result = ContentMerge(@base, ours, theirs);
                FilePath of = WriteMergedFile(result);
                UpdateIndex(@base, ours, theirs, result, of);
                if (result.ContainsConflicts())
                {
                    unmergedPaths.AddItem(tw.PathString);
                }
                modifiedFiles.AddItem(tw.PathString);
            }
            else
            {
                if (modeO != modeT)
                {
                    // OURS or THEIRS has been deleted
                    if (((modeO != 0 && !tw.IdEqual(T_BASE, T_OURS)) || (modeT != 0 && !tw.IdEqual(T_BASE
                                                                                                   , T_THEIRS))))
                    {
                        Add(tw.RawPath, @base, DirCacheEntry.STAGE_1, 0, 0);
                        Add(tw.RawPath, ours, DirCacheEntry.STAGE_2, 0, 0);
                        DirCacheEntry e = Add(tw.RawPath, theirs, DirCacheEntry.STAGE_3, 0, 0);
                        // OURS was deleted checkout THEIRS
                        if (modeO == 0)
                        {
                            // Check worktree before checking out THEIRS
                            if (IsWorktreeDirty(work))
                            {
                                return(false);
                            }
                            if (NonTree(modeT))
                            {
                                if (e != null)
                                {
                                    toBeCheckedOut.Put(tw.PathString, e);
                                }
                            }
                        }
                        unmergedPaths.AddItem(tw.PathString);
                        // generate a MergeResult for the deleted file
                        mergeResults.Put(tw.PathString, ContentMerge(@base, ours, theirs).Upcast());
                    }
                }
            }
            return(true);
        }
 public override void Apply(DirCacheEntry ent)
 {
     ent.FileMode = FileMode.REGULAR_FILE;
     ent.SetLength(f.Length());
     ent.SetObjectId(id);
 }
Exemplo n.º 9
0
 public override void Apply(DirCacheEntry ent)
 {
     ent.FileMode = FileMode.REGULAR_FILE;
     ent.SetObjectId(id);
     ent.IsUpdateNeeded = false;
 }
Exemplo n.º 10
0
 public override void Apply(DirCacheEntry ent)
 {
     ent.SetObjectId(blobId);
 }