Пример #1
0
        public virtual void TestCherryPickOverExecutableChangeOnNonExectuableFileSystem()
        {
            Git      git  = new Git(db);
            FilePath file = WriteTrashFile("test.txt", "a");

            NUnit.Framework.Assert.IsNotNull(git.Add().AddFilepattern("test.txt").Call());
            NUnit.Framework.Assert.IsNotNull(git.Commit().SetMessage("commit1").Call());
            NUnit.Framework.Assert.IsNotNull(git.Checkout().SetCreateBranch(true).SetName("a"
                                                                                          ).Call());
            WriteTrashFile("test.txt", "b");
            NUnit.Framework.Assert.IsNotNull(git.Add().AddFilepattern("test.txt").Call());
            RevCommit commit2 = git.Commit().SetMessage("commit2").Call();

            NUnit.Framework.Assert.IsNotNull(commit2);
            NUnit.Framework.Assert.IsNotNull(git.Checkout().SetName(Constants.MASTER).Call());
            DirCache cache = db.LockDirCache();

            cache.GetEntry("test.txt").FileMode = FileMode.EXECUTABLE_FILE;
            cache.Write();
            NUnit.Framework.Assert.IsTrue(cache.Commit());
            cache.Unlock();
            NUnit.Framework.Assert.IsNotNull(git.Commit().SetMessage("commit3").Call());
            git.GetRepository().GetConfig().SetBoolean(ConfigConstants.CONFIG_CORE_SECTION, null
                                                       , ConfigConstants.CONFIG_KEY_FILEMODE, false);
            CherryPickResult result = git.CherryPick().Include(commit2).Call();

            NUnit.Framework.Assert.IsNotNull(result);
            NUnit.Framework.Assert.AreEqual(CherryPickResult.CherryPickStatus.OK, result.GetStatus
                                                ());
        }
Пример #2
0
        private void ResetIndexForPaths(RevCommit commit)
        {
            DirCache       dc = null;
            DirCacheEditor edit;

            try
            {
                dc   = repo.LockDirCache();
                edit = dc.Editor();
                TreeWalk tw = new TreeWalk(repo);
                tw.AddTree(new DirCacheIterator(dc));
                tw.AddTree(commit.Tree);
                tw.Filter    = PathFilterGroup.CreateFromStrings(filepaths);
                tw.Recursive = true;
                while (tw.Next())
                {
                    string path = tw.PathString;
                    // DirCacheIterator dci = tw.getTree(0, DirCacheIterator.class);
                    CanonicalTreeParser tree = tw.GetTree <CanonicalTreeParser>(1);
                    if (tree == null)
                    {
                        // file is not in the commit, remove from index
                        edit.Add(new DirCacheEditor.DeletePath(path));
                    }
                    else
                    {
                        // revert index to commit
                        // it seams that there is concurrent access to tree
                        // variable, therefore we need to keep references to
                        // entryFileMode and entryObjectId in local
                        // variables
                        FileMode entryFileMode = tree.EntryFileMode;
                        ObjectId entryObjectId = tree.EntryObjectId;
                        edit.Add(new _PathEdit_305(entryFileMode, entryObjectId, path));
                    }
                }
                edit.Commit();
            }
            catch (IOException e)
            {
                throw new RuntimeException(e);
            }
            finally
            {
                if (dc != null)
                {
                    dc.Unlock();
                }
            }
        }
Пример #3
0
        /// <exception cref="System.InvalidOperationException"></exception>
        /// <exception cref="System.IO.IOException"></exception>
        public override void PrescanTwoTrees(Tree head, Tree merge)
        {
            DirCache dc = db.LockDirCache();

            try
            {
                dco = new DirCacheCheckout(db, head.GetId(), dc, merge.GetId());
                dco.PreScanTwoTrees();
            }
            finally
            {
                dc.Unlock();
            }
        }
Пример #4
0
        /// <exception cref="System.IO.IOException"></exception>
        private void Checkout()
        {
            DirCache dc = db.LockDirCache();

            try
            {
                dco = new DirCacheCheckout(db, theHead, dc, theMerge);
                dco.Checkout();
            }
            finally
            {
                dc.Unlock();
            }
        }
Пример #5
0
        /// <exception cref="System.IO.IOException"></exception>
        public override void Checkout()
        {
            DirCache dc = db.LockDirCache();

            try
            {
                dco = new DirCacheCheckout(db, theHead.GetId(), dc, theMerge.GetId());
                dco.Checkout();
            }
            finally
            {
                dc.Unlock();
            }
        }
Пример #6
0
        /// <exception cref="System.InvalidOperationException"></exception>
        /// <exception cref="System.IO.IOException"></exception>
        private void PrescanTwoTrees(ObjectId head, ObjectId merge)
        {
            DirCache dc = db.LockDirCache();

            try
            {
                dco = new DirCacheCheckout(db, head, dc, merge);
                dco.PreScanTwoTrees();
            }
            finally
            {
                dc.Unlock();
            }
        }
Пример #7
0
        /// <summary>Checkout paths into index and working directory</summary>
        /// <returns>this instance</returns>
        /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
        /// <exception cref="NGit.Api.Errors.RefNotFoundException">NGit.Api.Errors.RefNotFoundException
        ///     </exception>
        protected internal virtual NGit.Api.CheckoutCommand CheckoutPaths()
        {
            RevWalk  revWalk = new RevWalk(repo);
            DirCache dc      = repo.LockDirCache();

            try
            {
                DirCacheEditor editor    = dc.Editor();
                TreeWalk       startWalk = new TreeWalk(revWalk.GetObjectReader());
                startWalk.Recursive = true;
                if (!checkoutAllPaths)
                {
                    startWalk.Filter = PathFilterGroup.CreateFromStrings(paths);
                }
                bool checkoutIndex = startCommit == null && startPoint == null;
                if (!checkoutIndex)
                {
                    startWalk.AddTree(revWalk.ParseCommit(GetStartPoint()).Tree);
                }
                else
                {
                    startWalk.AddTree(new DirCacheIterator(dc));
                }
                FilePath     workTree = repo.WorkTree;
                ObjectReader r        = repo.ObjectDatabase.NewReader();
                try
                {
                    while (startWalk.Next())
                    {
                        ObjectId blobId = startWalk.GetObjectId(0);
                        FileMode mode   = startWalk.GetFileMode(0);
                        editor.Add(new _PathEdit_349(this, checkoutIndex, blobId, mode, workTree, r, startWalk
                                                     .PathString));
                    }
                    editor.Commit();
                }
                finally
                {
                    startWalk.Release();
                    r.Release();
                }
            }
            finally
            {
                dc.Unlock();
                revWalk.Release();
            }
            return(this);
        }
Пример #8
0
        /// <summary>Checkout paths into index and working directory</summary>
        /// <returns>this instance</returns>
        /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
        /// <exception cref="NGit.Api.Errors.RefNotFoundException">NGit.Api.Errors.RefNotFoundException
        ///     </exception>
        protected internal virtual NGit.Api.CheckoutCommand CheckoutPaths()
        {
            RevWalk  revWalk = new RevWalk(repo);
            DirCache dc      = repo.LockDirCache();

            try
            {
                TreeWalk treeWalk = new TreeWalk(revWalk.GetObjectReader());
                treeWalk.Recursive = true;
                treeWalk.AddTree(new DirCacheIterator(dc));
                treeWalk.Filter = PathFilterGroup.CreateFromStrings(paths);
                IList <string> files = new List <string>();
                while (treeWalk.Next())
                {
                    files.AddItem(treeWalk.PathString);
                }
                if (startCommit != null || startPoint != null)
                {
                    DirCacheEditor editor    = dc.Editor();
                    TreeWalk       startWalk = new TreeWalk(revWalk.GetObjectReader());
                    startWalk.Recursive = true;
                    startWalk.Filter    = treeWalk.Filter;
                    startWalk.AddTree(revWalk.ParseCommit(GetStartPoint()).Tree);
                    while (startWalk.Next())
                    {
                        ObjectId blobId = startWalk.GetObjectId(0);
                        editor.Add(new _PathEdit_258(blobId, startWalk.PathString));
                    }
                    editor.Commit();
                }
                FilePath workTree = repo.WorkTree;
                foreach (string file in files)
                {
                    DirCacheCheckout.CheckoutEntry(repo, new FilePath(workTree, file), dc.GetEntry(file
                                                                                                   ));
                }
            }
            finally
            {
                dc.Unlock();
                revWalk.Release();
            }
            return(this);
        }
Пример #9
0
        /// <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();
                }
            }
        }
        public static void HardReset(NGit.Repository repo, ObjectId newHead)
        {
            DirCache dc = null;

            try
            {
                // Reset head to upstream
                RefUpdate ru = repo.UpdateRef(Constants.HEAD);
                ru.SetNewObjectId(newHead);
                ru.SetForceUpdate(true);
                RefUpdate.Result rc = ru.Update();

                switch (rc)
                {
                case RefUpdate.Result.NO_CHANGE:
                case RefUpdate.Result.NEW:
                case RefUpdate.Result.FAST_FORWARD:
                case RefUpdate.Result.FORCED:
                    break;

                case RefUpdate.Result.REJECTED:
                case RefUpdate.Result.LOCK_FAILURE:
                    throw new ConcurrentRefUpdateException(JGitText.Get().couldNotLockHEAD, ru.GetRef(), rc);

                default:
                    throw new JGitInternalException("Reference update failed: " + rc);
                }

                dc = repo.LockDirCache();
                RevWalk          rw       = new RevWalk(repo);
                RevCommit        c        = rw.ParseCommit(newHead);
                DirCacheCheckout checkout = new DirCacheCheckout(repo, null, dc, c.Tree);
                checkout.Checkout();
            }
            catch
            {
                if (dc != null)
                {
                    dc.Unlock();
                }
                throw;
            }
        }
Пример #11
0
        private void ResetIndexForPaths(RevCommit commit)
        {
            DirCache       dc = null;
            DirCacheEditor edit;

            try
            {
                dc   = repo.LockDirCache();
                edit = dc.Editor();
                TreeWalk tw = new TreeWalk(repo);
                tw.AddTree(new DirCacheIterator(dc));
                tw.AddTree(commit.Tree);
                tw.Filter = PathFilterGroup.CreateFromStrings(filepaths);
                while (tw.Next())
                {
                    string path = tw.PathString;
                    // DirCacheIterator dci = tw.getTree(0, DirCacheIterator.class);
                    CanonicalTreeParser tree = tw.GetTree <CanonicalTreeParser>(1);
                    if (tree == null)
                    {
                        // file is not in the commit, remove from index
                        edit.Add(new DirCacheEditor.DeletePath(path));
                    }
                    else
                    {
                        // revert index to commit
                        edit.Add(new _PathEdit_281(tree, path));
                    }
                }
                edit.Commit();
            }
            catch (IOException e)
            {
                throw new RuntimeException(e);
            }
            finally
            {
                if (dc != null)
                {
                    dc.Unlock();
                }
            }
        }
Пример #12
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();
                }
            }
        }
Пример #13
0
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="NGit.Api.Errors.GitAPIException"></exception>
        private void CheckoutIndex(RevCommit commit)
        {
            DirCache dc = repo.LockDirCache();

            try
            {
                DirCacheCheckout checkout = new DirCacheCheckout(repo, dc, commit.Tree);
                checkout.SetFailOnConflict(false);
                try
                {
                    checkout.Checkout();
                }
                catch (NGit.Errors.CheckoutConflictException cce)
                {
                    throw new NGit.Api.Errors.CheckoutConflictException(checkout.GetConflicts(), cce);
                }
            }
            finally
            {
                dc.Unlock();
            }
        }
Пример #14
0
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="NGit.Api.Errors.NoHeadException"></exception>
        /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception>
        private RevCommit CheckoutCurrentHead()
        {
            ObjectId headTree = repo.Resolve(Constants.HEAD + "^{tree}");

            if (headTree == null)
            {
                throw new NoHeadException(JGitText.Get().cannotRebaseWithoutCurrentHead);
            }
            DirCache dc = repo.LockDirCache();

            try
            {
                DirCacheCheckout dco = new DirCacheCheckout(repo, dc, headTree);
                dco.SetFailOnConflict(false);
                bool needsDeleteFiles = dco.Checkout();
                if (needsDeleteFiles)
                {
                    IList <string> fileList = dco.GetToBeDeleted();
                    foreach (string filePath in fileList)
                    {
                        FilePath fileToDelete = new FilePath(repo.WorkTree, filePath);
                        if (fileToDelete.Exists())
                        {
                            FileUtils.Delete(fileToDelete, FileUtils.RECURSIVE | FileUtils.RETRY);
                        }
                    }
                }
            }
            finally
            {
                dc.Unlock();
            }
            RevWalk   rw     = new RevWalk(repo);
            RevCommit commit = rw.ParseCommit(repo.Resolve(Constants.HEAD));

            rw.Release();
            return(commit);
        }
Пример #15
0
        /// <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();
            }
        }
Пример #16
0
        /// <exception cref="System.IO.IOException"></exception>
        private void CheckoutIndex(RevCommit commit)
        {
            DirCache dc = null;

            try
            {
                dc = repo.LockDirCache();
                DirCacheCheckout checkout = new DirCacheCheckout(repo, dc, commit.Tree);
                checkout.SetFailOnConflict(false);
                checkout.Checkout();
            }
            catch (IOException e)
            {
                throw;
            }
            finally
            {
                if (dc != null)
                {
                    dc.Unlock();
                }
            }
        }
Пример #17
0
        /// <exception cref="System.IO.IOException"></exception>
        private void ResetIndex(RevCommit commit)
        {
            DirCache dc = null;

            try
            {
                dc = repo.LockDirCache();
                dc.Clear();
                DirCacheBuilder dcb = dc.Builder();
                dcb.AddTree(new byte[0], 0, repo.NewObjectReader(), commit.Tree);
                dcb.Commit();
            }
            catch (IOException e)
            {
                throw;
            }
            finally
            {
                if (dc != null)
                {
                    dc.Unlock();
                }
            }
        }
Пример #18
0
        /// <summary>
        /// Executes the
        /// <code>commit</code>
        /// command with all the options and parameters
        /// collected by the setter methods of this class. Each instance of this
        /// class should only be used for one invocation of the command (means: one
        /// call to
        /// <see cref="Call()">Call()</see>
        /// )
        /// </summary>
        /// <returns>
        /// a
        /// <see cref="NGit.Revwalk.RevCommit">NGit.Revwalk.RevCommit</see>
        /// object representing the successful commit.
        /// </returns>
        /// <exception cref="NGit.Api.Errors.NoHeadException">when called on a git repo without a HEAD reference
        ///     </exception>
        /// <exception cref="NGit.Api.Errors.NoMessageException">when called without specifying a commit message
        ///     </exception>
        /// <exception cref="NGit.Api.Errors.UnmergedPathsException">when the current index contained unmerged paths (conflicts)
        ///     </exception>
        /// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException">
        /// when HEAD or branch ref is updated concurrently by someone
        /// else
        /// </exception>
        /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">when repository is not in the right state for committing
        ///     </exception>
        /// <exception cref="NGit.Api.Errors.GitAPIException"></exception>
        public override RevCommit Call()
        {
            CheckCallable();
            RepositoryState state = repo.GetRepositoryState();

            if (!state.CanCommit())
            {
                throw new WrongRepositoryStateException(MessageFormat.Format(JGitText.Get().cannotCommitOnARepoWithState
                                                                             , state.Name()));
            }
            ProcessOptions(state);
            try
            {
                if (all && !repo.IsBare && repo.WorkTree != null)
                {
                    Git git = new Git(repo);
                    try
                    {
                        git.Add().AddFilepattern(".").SetUpdate(true).Call();
                    }
                    catch (NoFilepatternException e)
                    {
                        // should really not happen
                        throw new JGitInternalException(e.Message, e);
                    }
                }
                Ref head = repo.GetRef(Constants.HEAD);
                if (head == null)
                {
                    throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported
                                              );
                }
                // determine the current HEAD and the commit it is referring to
                ObjectId headId = repo.Resolve(Constants.HEAD + "^{commit}");
                if (headId == null && amend)
                {
                    throw new WrongRepositoryStateException(JGitText.Get().commitAmendOnInitialNotPossible
                                                            );
                }
                if (headId != null)
                {
                    if (amend)
                    {
                        RevCommit   previousCommit = new RevWalk(repo).ParseCommit(headId);
                        RevCommit[] p = previousCommit.Parents;
                        for (int i = 0; i < p.Length; i++)
                        {
                            parents.Add(0, p[i].Id);
                        }
                        if (author == null)
                        {
                            author = previousCommit.GetAuthorIdent();
                        }
                    }
                    else
                    {
                        parents.Add(0, headId);
                    }
                }
                // lock the index
                DirCache index = repo.LockDirCache();
                try
                {
                    if (!only.IsEmpty())
                    {
                        index = CreateTemporaryIndex(headId, index);
                    }
                    ObjectInserter odi = repo.NewObjectInserter();
                    try
                    {
                        // Write the index as tree to the object database. This may
                        // fail for example when the index contains unmerged paths
                        // (unresolved conflicts)
                        ObjectId indexTreeId = index.WriteTree(odi);
                        if (insertChangeId)
                        {
                            InsertChangeId(indexTreeId);
                        }
                        // Create a Commit object, populate it and write it
                        NGit.CommitBuilder commit = new NGit.CommitBuilder();
                        commit.Committer = committer;
                        commit.Author    = author;
                        commit.Message   = message;
                        commit.SetParentIds(parents);
                        commit.TreeId = indexTreeId;
                        ObjectId commitId = odi.Insert(commit);
                        odi.Flush();
                        RevWalk revWalk = new RevWalk(repo);
                        try
                        {
                            RevCommit revCommit = revWalk.ParseCommit(commitId);
                            RefUpdate ru        = repo.UpdateRef(Constants.HEAD);
                            ru.SetNewObjectId(commitId);
                            if (reflogComment != null)
                            {
                                ru.SetRefLogMessage(reflogComment, false);
                            }
                            else
                            {
                                string prefix = amend ? "commit (amend): " : "commit: ";
                                ru.SetRefLogMessage(prefix + revCommit.GetShortMessage(), false);
                            }
                            if (headId != null)
                            {
                                ru.SetExpectedOldObjectId(headId);
                            }
                            else
                            {
                                ru.SetExpectedOldObjectId(ObjectId.ZeroId);
                            }
                            RefUpdate.Result rc = ru.ForceUpdate();
                            switch (rc)
                            {
                            case RefUpdate.Result.NEW:
                            case RefUpdate.Result.FORCED:
                            case RefUpdate.Result.FAST_FORWARD:
                            {
                                SetCallable(false);
                                if (state == RepositoryState.MERGING_RESOLVED)
                                {
                                    // Commit was successful. Now delete the files
                                    // used for merge commits
                                    repo.WriteMergeCommitMsg(null);
                                    repo.WriteMergeHeads(null);
                                }
                                else
                                {
                                    if (state == RepositoryState.CHERRY_PICKING_RESOLVED)
                                    {
                                        repo.WriteMergeCommitMsg(null);
                                        repo.WriteCherryPickHead(null);
                                    }
                                }
                                return(revCommit);
                            }

                            case RefUpdate.Result.REJECTED:
                            case RefUpdate.Result.LOCK_FAILURE:
                            {
                                throw new ConcurrentRefUpdateException(JGitText.Get().couldNotLockHEAD, ru.GetRef
                                                                           (), rc);
                            }

                            default:
                            {
                                throw new JGitInternalException(MessageFormat.Format(JGitText.Get().updatingRefFailed
                                                                                     , Constants.HEAD, commitId.ToString(), rc));
                            }
                            }
                        }
                        finally
                        {
                            revWalk.Release();
                        }
                    }
                    finally
                    {
                        odi.Release();
                    }
                }
                finally
                {
                    index.Unlock();
                }
            }
            catch (UnmergedPathException e)
            {
                throw new UnmergedPathsException(e);
            }
            catch (IOException e)
            {
                throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfCommitCommand
                                                , e);
            }
        }
Пример #19
0
        /// <summary>Apply the changes in a stashed commit to the working directory and index
        ///     </summary>
        /// <returns>id of stashed commit that was applied</returns>
        /// <exception cref="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException
        ///     </exception>
        /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">NGit.Api.Errors.WrongRepositoryStateException
        ///     </exception>
        public override ObjectId Call()
        {
            CheckCallable();
            if (repo.GetRepositoryState() != RepositoryState.SAFE)
            {
                throw new WrongRepositoryStateException(MessageFormat.Format(JGitText.Get().stashApplyOnUnsafeRepository
                                                                             , repo.GetRepositoryState()));
            }
            ObjectId     headTree = GetHeadTree();
            ObjectId     stashId  = GetStashId();
            ObjectReader reader   = repo.NewObjectReader();

            try
            {
                RevWalk   revWalk     = new RevWalk(reader);
                RevCommit stashCommit = revWalk.ParseCommit(stashId);
                if (stashCommit.ParentCount != 2)
                {
                    throw new JGitInternalException(MessageFormat.Format(JGitText.Get().stashCommitMissingTwoParents
                                                                         , stashId.Name));
                }
                RevTree             stashWorkingTree = stashCommit.Tree;
                RevTree             stashIndexTree   = revWalk.ParseCommit(stashCommit.GetParent(1)).Tree;
                RevTree             stashHeadTree    = revWalk.ParseCommit(stashCommit.GetParent(0)).Tree;
                CanonicalTreeParser stashWorkingIter = new CanonicalTreeParser();
                stashWorkingIter.Reset(reader, stashWorkingTree);
                CanonicalTreeParser stashIndexIter = new CanonicalTreeParser();
                stashIndexIter.Reset(reader, stashIndexTree);
                CanonicalTreeParser stashHeadIter = new CanonicalTreeParser();
                stashHeadIter.Reset(reader, stashHeadTree);
                CanonicalTreeParser headIter = new CanonicalTreeParser();
                headIter.Reset(reader, headTree);
                DirCache       cache  = repo.LockDirCache();
                DirCacheEditor editor = cache.Editor();
                try
                {
                    DirCacheIterator indexIter   = new DirCacheIterator(cache);
                    FileTreeIterator workingIter = new FileTreeIterator(repo);
                    TreeWalk         treeWalk    = new TreeWalk(reader);
                    treeWalk.Recursive = true;
                    treeWalk.Filter    = new StashApplyCommand.StashDiffFilter();
                    treeWalk.AddTree(stashHeadIter);
                    treeWalk.AddTree(stashIndexIter);
                    treeWalk.AddTree(stashWorkingIter);
                    treeWalk.AddTree(headIter);
                    treeWalk.AddTree(indexIter);
                    treeWalk.AddTree(workingIter);
                    ScanForConflicts(treeWalk);
                    // Reset trees and walk
                    treeWalk.Reset();
                    stashWorkingIter.Reset(reader, stashWorkingTree);
                    stashIndexIter.Reset(reader, stashIndexTree);
                    stashHeadIter.Reset(reader, stashHeadTree);
                    treeWalk.AddTree(stashHeadIter);
                    treeWalk.AddTree(stashIndexIter);
                    treeWalk.AddTree(stashWorkingIter);
                    ApplyChanges(treeWalk, cache, editor);
                }
                finally
                {
                    editor.Commit();
                    cache.Unlock();
                }
            }
            catch (JGitInternalException e)
            {
                throw;
            }
            catch (IOException e)
            {
                throw new JGitInternalException(JGitText.Get().stashApplyFailed, e);
            }
            finally
            {
                reader.Release();
            }
            return(stashId);
        }
Пример #20
0
        /// <exception cref="NGit.Api.Errors.RefAlreadyExistsException">
        /// when trying to create (without force) a branch with a name
        /// that already exists
        /// </exception>
        /// <exception cref="NGit.Api.Errors.RefNotFoundException">if the start point or branch can not be found
        ///     </exception>
        /// <exception cref="NGit.Api.Errors.InvalidRefNameException">
        /// if the provided name is <code>null</code> or otherwise
        /// invalid
        /// </exception>
        /// <exception cref="NGit.Api.Errors.CheckoutConflictException">if the checkout results in a conflict
        ///     </exception>
        /// <returns>the newly created branch</returns>
        /// <exception cref="NGit.Api.Errors.GitAPIException"></exception>
        public override Ref Call()
        {
            CheckCallable();
            ProcessOptions();
            try
            {
                if (checkoutAllPaths || !paths.IsEmpty())
                {
                    CheckoutPaths();
                    status = new CheckoutResult(CheckoutResult.Status.OK, paths);
                    SetCallable(false);
                    return(null);
                }
                if (createBranch)
                {
                    Git git = new Git(repo);
                    CreateBranchCommand command = git.BranchCreate();
                    command.SetName(name);
                    command.SetStartPoint(GetStartPoint().Name);
                    if (upstreamMode != null)
                    {
                        command.SetUpstreamMode(upstreamMode);
                    }
                    command.Call();
                }
                Ref      headRef       = repo.GetRef(Constants.HEAD);
                string   shortHeadRef  = GetShortBranchName(headRef);
                string   refLogMessage = "checkout: moving from " + shortHeadRef;
                ObjectId branch        = repo.Resolve(name);
                if (branch == null)
                {
                    throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved
                                                                        , name));
                }
                RevWalk          revWalk    = new RevWalk(repo);
                AnyObjectId      headId     = headRef.GetObjectId();
                RevCommit        headCommit = headId == null ? null : revWalk.ParseCommit(headId);
                RevCommit        newCommit  = revWalk.ParseCommit(branch);
                RevTree          headTree   = headCommit == null ? null : headCommit.Tree;
                DirCacheCheckout dco;
                DirCache         dc = repo.LockDirCache();
                try
                {
                    dco = new DirCacheCheckout(repo, headTree, dc, newCommit.Tree);
                    dco.SetFailOnConflict(true);
                    try
                    {
                        dco.Checkout();
                    }
                    catch (NGit.Errors.CheckoutConflictException e)
                    {
                        status = new CheckoutResult(CheckoutResult.Status.CONFLICTS, dco.GetConflicts());
                        throw new NGit.Api.Errors.CheckoutConflictException(dco.GetConflicts(), e);
                    }
                }
                finally
                {
                    dc.Unlock();
                }
                Ref @ref = repo.GetRef(name);
                if (@ref != null && [email protected]().StartsWith(Constants.R_HEADS))
                {
                    @ref = null;
                }
                string    toName    = Repository.ShortenRefName(name);
                RefUpdate refUpdate = repo.UpdateRef(Constants.HEAD, @ref == null);
                refUpdate.SetForceUpdate(force);
                refUpdate.SetRefLogMessage(refLogMessage + " to " + toName, false);
                RefUpdate.Result updateResult;
                if (@ref != null)
                {
                    updateResult = refUpdate.Link(@ref.GetName());
                }
                else
                {
                    refUpdate.SetNewObjectId(newCommit);
                    updateResult = refUpdate.ForceUpdate();
                }
                SetCallable(false);
                bool ok = false;
                switch (updateResult)
                {
                case RefUpdate.Result.NEW:
                {
                    ok = true;
                    break;
                }

                case RefUpdate.Result.NO_CHANGE:
                case RefUpdate.Result.FAST_FORWARD:
                case RefUpdate.Result.FORCED:
                {
                    ok = true;
                    break;
                }

                default:
                {
                    break;
                    break;
                }
                }
                if (!ok)
                {
                    throw new JGitInternalException(MessageFormat.Format(JGitText.Get().checkoutUnexpectedResult
                                                                         , updateResult.ToString()));
                }
                if (!dco.GetToBeDeleted().IsEmpty())
                {
                    status = new CheckoutResult(CheckoutResult.Status.NONDELETED, dco.GetToBeDeleted(
                                                    ));
                }
                else
                {
                    status = new CheckoutResult(new AList <string>(dco.GetUpdated().Keys), dco.GetRemoved
                                                    ());
                }
                return(@ref);
            }
            catch (IOException ioe)
            {
                throw new JGitInternalException(ioe.Message, ioe);
            }
            finally
            {
                if (status == null)
                {
                    status = CheckoutResult.ERROR_RESULT;
                }
            }
        }
Пример #21
0
        /// <summary>
        /// Stash the contents on the working directory and index in separate commits
        /// and reset to the current HEAD commit.
        /// </summary>
        /// <remarks>
        /// Stash the contents on the working directory and index in separate commits
        /// and reset to the current HEAD commit.
        /// </remarks>
        /// <returns>stashed commit or null if no changes to stash</returns>
        /// <exception cref="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException
        ///     </exception>
        public override RevCommit Call()
        {
            CheckCallable();
            Ref          head   = GetHead();
            ObjectReader reader = repo.NewObjectReader();

            try
            {
                RevCommit      headCommit = ParseCommit(reader, head.GetObjectId());
                DirCache       cache      = repo.LockDirCache();
                ObjectInserter inserter   = repo.NewObjectInserter();
                ObjectId       commitId;
                try
                {
                    TreeWalk treeWalk = new TreeWalk(reader);
                    treeWalk.Recursive = true;
                    treeWalk.AddTree(headCommit.Tree);
                    treeWalk.AddTree(new DirCacheIterator(cache));
                    treeWalk.AddTree(new FileTreeIterator(repo));
                    treeWalk.Filter = AndTreeFilter.Create(new SkipWorkTreeFilter(1), new IndexDiffFilter
                                                               (1, 2));
                    // Return null if no local changes to stash
                    if (!treeWalk.Next())
                    {
                        return(null);
                    }
                    MutableObjectId id = new MutableObjectId();
                    IList <DirCacheEditor.PathEdit> wtEdits = new AList <DirCacheEditor.PathEdit>();
                    IList <string> wtDeletes = new AList <string>();
                    do
                    {
                        AbstractTreeIterator headIter  = treeWalk.GetTree <AbstractTreeIterator>(0);
                        DirCacheIterator     indexIter = treeWalk.GetTree <DirCacheIterator>(1);
                        WorkingTreeIterator  wtIter    = treeWalk.GetTree <WorkingTreeIterator>(2);
                        if (headIter != null && indexIter != null && wtIter != null)
                        {
                            if (!indexIter.GetDirCacheEntry().IsMerged())
                            {
                                throw new UnmergedPathsException(new UnmergedPathException(indexIter.GetDirCacheEntry
                                                                                               ()));
                            }
                            if (wtIter.IdEqual(indexIter) || wtIter.IdEqual(headIter))
                            {
                                continue;
                            }
                            treeWalk.GetObjectId(id, 0);
                            DirCacheEntry entry = new DirCacheEntry(treeWalk.RawPath);
                            entry.SetLength(wtIter.GetEntryLength());
                            entry.LastModified = wtIter.GetEntryLastModified();
                            entry.FileMode     = wtIter.EntryFileMode;
                            long        contentLength = wtIter.GetEntryContentLength();
                            InputStream @in           = wtIter.OpenEntryStream();
                            try
                            {
                                entry.SetObjectId(inserter.Insert(Constants.OBJ_BLOB, contentLength, @in));
                            }
                            finally
                            {
                                @in.Close();
                            }
                            wtEdits.AddItem(new _PathEdit_273(entry, entry));
                        }
                        else
                        {
                            if (indexIter == null)
                            {
                                wtDeletes.AddItem(treeWalk.PathString);
                            }
                            else
                            {
                                if (wtIter == null && headIter != null)
                                {
                                    wtDeletes.AddItem(treeWalk.PathString);
                                }
                            }
                        }
                    }while (treeWalk.Next());
                    string branch = Repository.ShortenRefName(head.GetTarget().GetName());
                    // Commit index changes
                    NGit.CommitBuilder builder = CreateBuilder(headCommit);
                    builder.TreeId  = cache.WriteTree(inserter);
                    builder.Message = MessageFormat.Format(indexMessage, branch, headCommit.Abbreviate
                                                               (7).Name, headCommit.GetShortMessage());
                    ObjectId indexCommit = inserter.Insert(builder);
                    // Commit working tree changes
                    if (!wtEdits.IsEmpty() || !wtDeletes.IsEmpty())
                    {
                        DirCacheEditor editor = cache.Editor();
                        foreach (DirCacheEditor.PathEdit edit in wtEdits)
                        {
                            editor.Add(edit);
                        }
                        foreach (string path in wtDeletes)
                        {
                            editor.Add(new DirCacheEditor.DeletePath(path));
                        }
                        editor.Finish();
                    }
                    builder.AddParentId(indexCommit);
                    builder.Message = MessageFormat.Format(workingDirectoryMessage, branch, headCommit
                                                           .Abbreviate(7).Name, headCommit.GetShortMessage());
                    builder.TreeId = cache.WriteTree(inserter);
                    commitId       = inserter.Insert(builder);
                    inserter.Flush();
                    UpdateStashRef(commitId, builder.Author, builder.Message);
                }
                finally
                {
                    inserter.Release();
                    cache.Unlock();
                }
                // Hard reset to HEAD
                new ResetCommand(repo).SetMode(ResetCommand.ResetType.HARD).Call();
                // Return stashed commit
                return(ParseCommit(reader, commitId));
            }
            catch (IOException e)
            {
                throw new JGitInternalException(JGitText.Get().stashFailed, e);
            }
            finally
            {
                reader.Release();
            }
        }
Пример #22
0
        /// <exception cref="System.IO.IOException"></exception>
        protected internal override bool MergeImpl()
        {
            bool implicitDirCache = false;

            if (dircache == null)
            {
                dircache         = GetRepository().LockDirCache();
                implicitDirCache = true;
            }
            try
            {
                builder = dircache.Builder();
                DirCacheBuildIterator buildIt = new DirCacheBuildIterator(builder);
                tw = new NameConflictTreeWalk(db);
                tw.AddTree(MergeBase());
                tw.AddTree(sourceTrees[0]);
                tw.AddTree(sourceTrees[1]);
                tw.AddTree(buildIt);
                if (workingTreeIterator != null)
                {
                    tw.AddTree(workingTreeIterator);
                }
                while (tw.Next())
                {
                    if (!ProcessEntry(tw.GetTree <CanonicalTreeParser>(T_BASE), tw.GetTree <CanonicalTreeParser
                                                                                            >(T_OURS), tw.GetTree <CanonicalTreeParser>(T_THEIRS), tw.GetTree <DirCacheBuildIterator
                                                                                                                                                               >(T_INDEX), (workingTreeIterator == null) ? null : tw.GetTree <WorkingTreeIterator
                                                                                                                                                                                                                              >(T_FILE)))
                    {
                        CleanUp();
                        return(false);
                    }
                    if (tw.IsSubtree && enterSubtree)
                    {
                        tw.EnterSubtree();
                    }
                }
                if (!inCore)
                {
                    // All content-merges are successfully done. If we can now write the
                    // new index we are on quite safe ground. Even if the checkout of
                    // files coming from "theirs" fails the user can work around such
                    // failures by checking out the index again.
                    if (!builder.Commit())
                    {
                        CleanUp();
                        throw new IndexWriteException();
                    }
                    builder = null;
                    // No problem found. The only thing left to be done is to checkout
                    // all files from "theirs" which have been selected to go into the
                    // new index.
                    Checkout();
                }
                else
                {
                    builder.Finish();
                    builder = null;
                }
                if (GetUnmergedPaths().IsEmpty())
                {
                    resultTree = dircache.WriteTree(oi);
                    return(true);
                }
                else
                {
                    resultTree = null;
                    return(false);
                }
            }
            finally
            {
                if (implicitDirCache)
                {
                    dircache.Unlock();
                }
            }
        }