예제 #1
0
        public string GetFullMessage(string hash)
        {
            var walk = new RevWalk(this.git.GetRepository());

            RevCommit commit = walk.ParseCommit(ObjectId.FromString(hash));

            walk.Dispose();

            return commit.GetFullMessage();
        }
예제 #2
0
		public virtual void TestEquals()
		{
			RevCommit a1 = Commit();
			RevCommit b1 = Commit();
			NUnit.Framework.Assert.IsTrue(a1.Equals(a1));
			NUnit.Framework.Assert.IsTrue(a1.Equals((object)a1));
			NUnit.Framework.Assert.IsFalse(a1.Equals(b1));
			NUnit.Framework.Assert.IsTrue(a1.Equals(a1));
			NUnit.Framework.Assert.IsTrue(a1.Equals((object)a1));
			NUnit.Framework.Assert.IsFalse(a1.Equals(string.Empty));
			RevWalk rw2 = new RevWalk(db);
			RevCommit a2 = rw2.ParseCommit(a1);
			RevCommit b2 = rw2.ParseCommit(b1);
			NUnit.Framework.Assert.AreNotSame(a1, a2);
			NUnit.Framework.Assert.AreNotSame(b1, b2);
			NUnit.Framework.Assert.IsTrue(a1.Equals(a2));
			NUnit.Framework.Assert.IsTrue(b1.Equals(b2));
			NUnit.Framework.Assert.AreEqual(a1.GetHashCode(), a2.GetHashCode());
			NUnit.Framework.Assert.AreEqual(b1.GetHashCode(), b2.GetHashCode());
			NUnit.Framework.Assert.IsTrue(AnyObjectId.Equals(a1, a2));
			NUnit.Framework.Assert.IsTrue(AnyObjectId.Equals(b1, b2));
		}
예제 #3
0
		/// <exception cref="System.InvalidOperationException"></exception>
		/// <exception cref="System.IO.IOException"></exception>
		private void CheckoutCommit(RevCommit commit)
		{
			RevWalk walk = new RevWalk(db);
			RevCommit head = walk.ParseCommit(db.Resolve(Constants.HEAD));
			DirCacheCheckout dco = new DirCacheCheckout(db, head.Tree, db.LockDirCache(), commit
				.Tree);
			dco.SetFailOnConflict(true);
			dco.Checkout();
			walk.Release();
			// update the HEAD
			RefUpdate refUpdate = db.UpdateRef(Constants.HEAD, true);
			refUpdate.SetNewObjectId(commit);
			refUpdate.ForceUpdate();
		}
		private RevWalk CreateRevWalker()
		{
			var repository = _git.GetRepository();
			try
			{
				var revWalk = new RevWalk(repository);

				foreach (var reference in repository.GetAllRefs())
				{
					revWalk.MarkStart(revWalk.ParseCommit(reference.Value.GetObjectId()));
				}
				return revWalk;
			}
			finally
			{
				repository.Close();
			}
		}
예제 #5
0
        public override CommitInfo GetLatestCommit()
        {
            using (var repository = GetRepository())
            {
                var repo = (FileRepository)repository;
                var branch = repo.GetBranch();
                if (branch == null) return null;
                var objId = repo.Resolve(branch);
                if (objId == null) return null;
                RevWalk walk = new RevWalk(repo);
                RevCommit commit = walk.ParseCommit(objId);
                if (commit == null) return null;

                return new CommitInfo
                {
                    Message = commit.GetFullMessage(),
                    Date = commit.GetCommitterIdent().GetWhen().ToLocalTime()
                };
            }
        }
예제 #6
0
        public static API_NGit files(this API_NGit nGit,string commitId,  Action<TreeWalk> onTreeWalk)
        {
            try
            {
                var headCommit = nGit.Repository.Resolve(commitId);
                if (commitId.notNull())
                {
                    var revWalk = new RevWalk(nGit.Repository);
                    var commit = revWalk.ParseCommit(headCommit);
                    var treeWalk = new TreeWalk(nGit.Repository);
                    var tree = commit.Tree;
                    treeWalk.AddTree(tree);
                    treeWalk.Recursive = true;

                    while (treeWalk.Next())
                        onTreeWalk(treeWalk);
                }
            }
            catch (Exception ex)
            {
                ex.log("[API_NGit][getRepoFiles]");
            }
            return nGit ;
        }
        public static List<GitData_File> gitData_Files(this API_NGit nGit, int max_FilesToShow, string commitSha1)
        {
            var gitData_Files = new  List<GitData_File>();
            try
            {
                var headCommit = nGit.Repository.Resolve(commitSha1);
                if (commitSha1.notNull())
                {
                    var revWalk = new RevWalk(nGit.Repository);
                    var commit = revWalk.ParseCommit(headCommit);
                    var treeWalk = new TreeWalk(nGit.Repository);
                    var tree = commit.Tree;
                    treeWalk.AddTree(tree);
                    treeWalk.Recursive = true;

                    while (treeWalk.Next() && (max_FilesToShow == -1) || gitData_Files.size() < max_FilesToShow)
                        gitData_Files.add_File(treeWalk);
                        //repoFiles.Add(treeWalk.PathString);
                }
            }
            catch(Exception ex)
            {
                ex.log("[API_NGit][gitData_Files]");
            }
            return gitData_Files;
        }
예제 #8
0
 public virtual void TestStopOnConflictFileCreationAndDeletion()
 {
     // create file1 on master
     WriteTrashFile(FILE1, "Hello World");
     git.Add().AddFilepattern(FILE1).Call();
     // create file2 on master
     FilePath file2 = WriteTrashFile("file2", "Hello World 2");
     git.Add().AddFilepattern("file2").Call();
     // create file3 on master
     FilePath file3 = WriteTrashFile("file3", "Hello World 3");
     git.Add().AddFilepattern("file3").Call();
     RevCommit firstInMaster = git.Commit().SetMessage("Add file 1, 2 and 3").Call();
     // create file4 on master
     FilePath file4 = WriteTrashFile("file4", "Hello World 4");
     git.Add().AddFilepattern("file4").Call();
     DeleteTrashFile("file2");
     git.Add().SetUpdate(true).AddFilepattern("file2").Call();
     // create folder folder6 on topic (conflicts with file folder6 on topic
     // later on)
     WriteTrashFile("folder6/file1", "Hello World folder6");
     git.Add().AddFilepattern("folder6/file1").Call();
     git.Commit().SetMessage("Add file 4 and folder folder6, delete file2 on master").
         Call();
     // create a topic branch based on second commit
     CreateBranch(firstInMaster, "refs/heads/topic");
     CheckoutBranch("refs/heads/topic");
     DeleteTrashFile("file3");
     git.Add().SetUpdate(true).AddFilepattern("file3").Call();
     // create file5 on topic
     FilePath file5 = WriteTrashFile("file5", "Hello World 5");
     git.Add().AddFilepattern("file5").Call();
     git.Commit().SetMessage("Delete file3 and add file5 in topic").Call();
     // create file folder6 on topic (conflicts with folder6 on master)
     WriteTrashFile("folder6", "Hello World 6");
     git.Add().AddFilepattern("folder6").Call();
     // create file7 on topic
     FilePath file7 = WriteTrashFile("file7", "Hello World 7");
     git.Add().AddFilepattern("file7").Call();
     DeleteTrashFile("file5");
     git.Add().SetUpdate(true).AddFilepattern("file5").Call();
     RevCommit conflicting = git.Commit().SetMessage("Delete file5, add file folder6 and file7 in topic"
         ).Call();
     RebaseResult res = git.Rebase().SetUpstream("refs/heads/master").Call();
     NUnit.Framework.Assert.AreEqual(RebaseResult.Status.STOPPED, res.GetStatus());
     NUnit.Framework.Assert.AreEqual(conflicting, res.GetCurrentCommit());
     NUnit.Framework.Assert.AreEqual(RepositoryState.REBASING_INTERACTIVE, db.GetRepositoryState
         ());
     NUnit.Framework.Assert.IsTrue(new FilePath(db.Directory, "rebase-merge").Exists()
         );
     // the first one should be included, so we should have left two picks in
     // the file
     NUnit.Framework.Assert.AreEqual(0, CountPicks());
     NUnit.Framework.Assert.IsFalse(file2.Exists());
     NUnit.Framework.Assert.IsFalse(file3.Exists());
     NUnit.Framework.Assert.IsTrue(file4.Exists());
     NUnit.Framework.Assert.IsFalse(file5.Exists());
     NUnit.Framework.Assert.IsTrue(file7.Exists());
     // abort should reset to topic branch
     res = git.Rebase().SetOperation(RebaseCommand.Operation.ABORT).Call();
     NUnit.Framework.Assert.AreEqual(res.GetStatus(), RebaseResult.Status.ABORTED);
     NUnit.Framework.Assert.AreEqual("refs/heads/topic", db.GetFullBranch());
     RevWalk rw = new RevWalk(db);
     NUnit.Framework.Assert.AreEqual(conflicting, rw.ParseCommit(db.Resolve(Constants.
         HEAD)));
     NUnit.Framework.Assert.AreEqual(RepositoryState.SAFE, db.GetRepositoryState());
     // rebase- dir in .git must be deleted
     NUnit.Framework.Assert.IsFalse(new FilePath(db.Directory, "rebase-merge").Exists(
         ));
     NUnit.Framework.Assert.IsTrue(file2.Exists());
     NUnit.Framework.Assert.IsFalse(file3.Exists());
     NUnit.Framework.Assert.IsFalse(file4.Exists());
     NUnit.Framework.Assert.IsFalse(file5.Exists());
     NUnit.Framework.Assert.IsTrue(file7.Exists());
 }
예제 #9
0
 public virtual void TestStopOnConflict()
 {
     // create file1 on master
     RevCommit firstInMaster = WriteFileAndCommit(FILE1, "Add file1", "1", "2", "3");
     // change first line in master
     WriteFileAndCommit(FILE1, "change file1 in master", "1master", "2", "3");
     CheckFile(FILE1, "1master", "2", "3");
     // create a topic branch based on second commit
     CreateBranch(firstInMaster, "refs/heads/topic");
     CheckoutBranch("refs/heads/topic");
     // we have the old content again
     CheckFile(FILE1, "1", "2", "3");
     // add a line (non-conflicting)
     WriteFileAndCommit(FILE1, "add a line to file1 in topic", "1", "2", "3", "topic4"
         );
     // change first line (conflicting)
     RevCommit conflicting = WriteFileAndCommit(FILE1, "change file1 in topic", "1topic"
         , "2", "3", "topic4");
     RevCommit lastTopicCommit = WriteFileAndCommit(FILE1, "change file1 in topic again"
         , "1topic", "2", "3", "topic4");
     RebaseResult res = git.Rebase().SetUpstream("refs/heads/master").Call();
     NUnit.Framework.Assert.AreEqual(RebaseResult.Status.STOPPED, res.GetStatus());
     NUnit.Framework.Assert.AreEqual(conflicting, res.GetCurrentCommit());
     CheckFile(FILE1, "<<<<<<< OURS\n1master\n=======\n1topic\n>>>>>>> THEIRS\n2\n3\ntopic4"
         );
     NUnit.Framework.Assert.AreEqual(RepositoryState.REBASING_INTERACTIVE, db.GetRepositoryState
         ());
     NUnit.Framework.Assert.IsTrue(new FilePath(db.Directory, "rebase-merge").Exists()
         );
     // the first one should be included, so we should have left two picks in
     // the file
     NUnit.Framework.Assert.AreEqual(1, CountPicks());
     // rebase should not succeed in this state
     try
     {
         git.Rebase().SetUpstream("refs/heads/master").Call();
         NUnit.Framework.Assert.Fail("Expected exception was not thrown");
     }
     catch (WrongRepositoryStateException)
     {
     }
     // expected
     // abort should reset to topic branch
     res = git.Rebase().SetOperation(RebaseCommand.Operation.ABORT).Call();
     NUnit.Framework.Assert.AreEqual(res.GetStatus(), RebaseResult.Status.ABORTED);
     NUnit.Framework.Assert.AreEqual("refs/heads/topic", db.GetFullBranch());
     CheckFile(FILE1, "1topic", "2", "3", "topic4");
     RevWalk rw = new RevWalk(db);
     NUnit.Framework.Assert.AreEqual(lastTopicCommit, rw.ParseCommit(db.Resolve(Constants
         .HEAD)));
     NUnit.Framework.Assert.AreEqual(RepositoryState.SAFE, db.GetRepositoryState());
     // rebase- dir in .git must be deleted
     NUnit.Framework.Assert.IsFalse(new FilePath(db.Directory, "rebase-merge").Exists(
         ));
 }
예제 #10
0
		public static FileRepository Clone (string targetLocalPath, string url, IProgressMonitor monitor)
		{
			FileRepository repo = Init (targetLocalPath, url, monitor);
			
			// Fetch
			
			string remoteName = "origin";
			string branch = Constants.R_HEADS + "master";
			Transport tn = Transport.Open (repo, remoteName);
			FetchResult r;

			try {
				r = tn.Fetch(new GitMonitor (monitor), null);
			}
			finally {
				tn.Close ();
			}
			
			// Create the master branch
			
			// branch is like 'Constants.R_HEADS + branchName', we need only
			// the 'branchName' part
			String branchName = branch.Substring (Constants.R_HEADS.Length);
			NGit.Api.Git git = new NGit.Api.Git (repo);
			git.BranchCreate ().SetName (branchName).SetUpstreamMode (CreateBranchCommand.SetupUpstreamMode.TRACK).SetStartPoint ("origin/master").Call ();
			
			// Checkout

			DirCache dc = repo.LockDirCache ();
			try {
				RevWalk rw = new RevWalk (repo);
				ObjectId remCommitId = repo.Resolve (remoteName + "/" + branchName);
				RevCommit remCommit = rw.ParseCommit (remCommitId);
				DirCacheCheckout co = new DirCacheCheckout (repo, null, dc, remCommit.Tree);
				co.Checkout ();
			} catch {
				dc.Unlock ();
				throw;
			}
			
			return repo;
		}
예제 #11
0
		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;
			}
		}
예제 #12
0
        // TODO not implemented yet
        // TODO not implemented yet
        /// <summary>
        /// Executes the
        /// <code>Reset</code>
        /// command. Each instance of this class should
        /// only be used for one invocation of the command. Don't call this method
        /// twice on an instance.
        /// </summary>
        /// <returns>the Ref after reset</returns>
        /// <exception cref="System.IO.IOException"></exception>
        public override Ref Call()
        {
            CheckCallable();
            Ref       r;
            RevCommit commit;

            try
            {
                bool merging = false;
                if (repo.GetRepositoryState().Equals(RepositoryState.MERGING) || repo.GetRepositoryState
                        ().Equals(RepositoryState.MERGING_RESOLVED))
                {
                    merging = true;
                }
                // resolve the ref to a commit
                ObjectId commitId;
                try
                {
                    commitId = repo.Resolve(@ref);
                }
                catch (IOException e)
                {
                    throw new JGitInternalException(MessageFormat.Format(JGitText.Get().cannotRead, @ref
                                                                         ), e);
                }
                RevWalk rw = new RevWalk(repo);
                try
                {
                    commit = rw.ParseCommit(commitId);
                }
                catch (IOException e)
                {
                    throw new JGitInternalException(MessageFormat.Format(JGitText.Get().cannotReadCommit
                                                                         , commitId.ToString()), e);
                }
                finally
                {
                    rw.Release();
                }
                // write the ref
                RefUpdate ru = repo.UpdateRef(Constants.HEAD);
                ru.SetNewObjectId(commitId);
                string refName = Repository.ShortenRefName(@ref);
                string message = "reset --" + mode.ToString().ToLower() + " " + refName;
                //$NON-NLS-1$
                //$NON-NLS-1$
                ru.SetRefLogMessage(message, false);
                if (ru.ForceUpdate() == RefUpdate.Result.LOCK_FAILURE)
                {
                    throw new JGitInternalException(MessageFormat.Format(JGitText.Get().cannotLock, ru
                                                                         .GetName()));
                }
                switch (mode)
                {
                case ResetCommand.ResetType.HARD:
                {
                    CheckoutIndex(commit);
                    break;
                }

                case ResetCommand.ResetType.MIXED:
                {
                    ResetIndex(commit);
                    break;
                }

                case ResetCommand.ResetType.SOFT:
                {
                    // do nothing, only the ref was changed
                    break;
                }

                case ResetCommand.ResetType.KEEP:
                case ResetCommand.ResetType.MERGE:
                {
                    // TODO
                    // TODO
                    throw new NotSupportedException();
                }
                }
                if (mode != ResetCommand.ResetType.SOFT && merging)
                {
                    ResetMerge();
                }
                SetCallable(false);
                r = ru.GetRef();
            }
            catch (IOException e)
            {
                throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfResetCommand
                                                , e);
            }
            return(r);
        }
예제 #13
0
        /// <exception cref="NGit.Api.Errors.NotMergedException">
        /// when trying to delete a branch which has not been merged into
        /// the currently checked out branch without force
        /// </exception>
        /// <returns>the list with the (full) names of the deleted branches</returns>
        /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception>
        /// <exception cref="NGit.Api.Errors.CannotDeleteCurrentBranchException"></exception>
        public override IList <string> Call()
        {
            CheckCallable();
            IList <string> result = new AList <string>();

            if (branchNames.IsEmpty())
            {
                return(result);
            }
            try
            {
                string currentBranch = repo.GetFullBranch();
                if (!force)
                {
                    // check if the branches to be deleted
                    // are all merged into the current branch
                    RevWalk   walk = new RevWalk(repo);
                    RevCommit tip  = walk.ParseCommit(repo.Resolve(Constants.HEAD));
                    foreach (string branchName in branchNames)
                    {
                        if (branchName == null)
                        {
                            continue;
                        }
                        Ref currentRef = repo.GetRef(branchName);
                        if (currentRef == null)
                        {
                            continue;
                        }
                        RevCommit @base = walk.ParseCommit(repo.Resolve(branchName));
                        if (!walk.IsMergedInto(@base, tip))
                        {
                            throw new NotMergedException();
                        }
                    }
                }
                SetCallable(false);
                foreach (string branchName_1 in branchNames)
                {
                    if (branchName_1 == null)
                    {
                        continue;
                    }
                    Ref currentRef = repo.GetRef(branchName_1);
                    if (currentRef == null)
                    {
                        continue;
                    }
                    string fullName = currentRef.GetName();
                    if (fullName.Equals(currentBranch))
                    {
                        throw new CannotDeleteCurrentBranchException(MessageFormat.Format(JGitText.Get().
                                                                                          cannotDeleteCheckedOutBranch, branchName_1));
                    }
                    RefUpdate update = repo.UpdateRef(fullName);
                    update.SetRefLogMessage("branch deleted", false);
                    update.SetForceUpdate(true);
                    RefUpdate.Result deleteResult = update.Delete();
                    bool             ok           = true;
                    switch (deleteResult)
                    {
                    case RefUpdate.Result.IO_FAILURE:
                    case RefUpdate.Result.LOCK_FAILURE:
                    case RefUpdate.Result.REJECTED:
                    {
                        ok = false;
                        break;
                    }

                    default:
                    {
                        break;
                        break;
                    }
                    }
                    if (ok)
                    {
                        result.AddItem(fullName);
                        if (fullName.StartsWith(Constants.R_HEADS))
                        {
                            string shortenedName = Sharpen.Runtime.Substring(fullName, Constants.R_HEADS.Length
                                                                             );
                            // remove upstream configuration if any
                            StoredConfig cfg = repo.GetConfig();
                            cfg.UnsetSection(ConfigConstants.CONFIG_BRANCH_SECTION, shortenedName);
                            cfg.Save();
                        }
                    }
                    else
                    {
                        throw new JGitInternalException(MessageFormat.Format(JGitText.Get().deleteBranchUnexpectedResult
                                                                             , deleteResult.ToString()));
                    }
                }
                return(result);
            }
            catch (IOException ioe)
            {
                throw new JGitInternalException(ioe.Message, ioe);
            }
        }
예제 #14
0
        /// <summary>
        /// Executes the
        /// <code>Cherry-Pick</code>
        /// command with all the options and
        /// parameters collected by the setter methods (e.g.
        /// <see cref="Include(NGit.Ref)">Include(NGit.Ref)</see>
        /// of
        /// this class. Each instance of this class should only be used for one
        /// invocation of the command. Don't call this method twice on an instance.
        /// </summary>
        /// <returns>the result of the cherry-pick</returns>
        /// <exception cref="NGit.Api.Errors.GitAPIException"></exception>
        public override CherryPickResult Call()
        {
            RevCommit   newHead          = null;
            IList <Ref> cherryPickedRefs = new List <Ref>();

            CheckCallable();
            RevWalk revWalk = new RevWalk(repo);

            try
            {
                // get the head commit
                Ref headRef = repo.GetRef(Constants.HEAD);
                if (headRef == null)
                {
                    throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported
                                              );
                }
                RevCommit headCommit = revWalk.ParseCommit(headRef.GetObjectId());
                newHead = headCommit;
                // loop through all refs to be cherry-picked
                foreach (Ref src in commits)
                {
                    // get the commit to be cherry-picked
                    // handle annotated tags
                    ObjectId srcObjectId = src.GetPeeledObjectId();
                    if (srcObjectId == null)
                    {
                        srcObjectId = src.GetObjectId();
                    }
                    RevCommit srcCommit = revWalk.ParseCommit(srcObjectId);
                    // get the parent of the commit to cherry-pick
                    if (srcCommit.ParentCount != 1)
                    {
                        throw new MultipleParentsNotAllowedException(JGitText.Get().canOnlyCherryPickCommitsWithOneParent
                                                                     );
                    }
                    RevCommit srcParent = srcCommit.GetParent(0);
                    revWalk.ParseHeaders(srcParent);
                    ResolveMerger merger = (ResolveMerger)((ThreeWayMerger)MergeStrategy.RESOLVE.NewMerger
                                                               (repo));
                    merger.SetWorkingTreeIterator(new FileTreeIterator(repo));
                    merger.SetBase(srcParent.Tree);
                    if (merger.Merge(headCommit, srcCommit))
                    {
                        if (AnyObjectId.Equals(headCommit.Tree.Id, merger.GetResultTreeId()))
                        {
                            continue;
                        }
                        DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache
                                                                        (), merger.GetResultTreeId());
                        dco.SetFailOnConflict(true);
                        dco.Checkout();
                        newHead = new Git(GetRepository()).Commit().SetMessage(srcCommit.GetFullMessage()
                                                                               ).SetAuthor(srcCommit.GetAuthorIdent()).Call();
                        cherryPickedRefs.AddItem(src);
                    }
                    else
                    {
                        if (merger.Failed())
                        {
                            return(new CherryPickResult(merger.GetFailingPaths()));
                        }
                        // merge conflicts
                        return(CherryPickResult.CONFLICT);
                    }
                }
            }
            catch (IOException e)
            {
                throw new JGitInternalException(MessageFormat.Format(JGitText.Get().exceptionCaughtDuringExecutionOfCherryPickCommand
                                                                     , e), e);
            }
            finally
            {
                revWalk.Release();
            }
            return(new CherryPickResult(newHead, cherryPickedRefs));
        }
        /// <summary>
        /// Executes the
        /// <code>Rebase</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. Don't call
        /// this method twice on an instance.
        /// </summary>
        /// <returns>an object describing the result of this command</returns>
        /// <exception cref="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException
        ///     </exception>
        /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">NGit.Api.Errors.WrongRepositoryStateException
        ///     </exception>
        /// <exception cref="NGit.Api.Errors.NoHeadException">NGit.Api.Errors.NoHeadException
        ///     </exception>
        /// <exception cref="NGit.Api.Errors.RefNotFoundException">NGit.Api.Errors.RefNotFoundException
        ///     </exception>
        public override RebaseResult Call()
        {
            RevCommit newHead            = null;
            bool      lastStepWasForward = false;

            CheckCallable();
            CheckParameters();
            try
            {
                switch (operation)
                {
                case RebaseCommand.Operation.ABORT:
                {
                    try
                    {
                        return(Abort(RebaseResult.ABORTED_RESULT));
                    }
                    catch (IOException ioe)
                    {
                        throw new JGitInternalException(ioe.Message, ioe);
                    }
                    goto case RebaseCommand.Operation.SKIP;
                }

                case RebaseCommand.Operation.SKIP:
                case RebaseCommand.Operation.CONTINUE:
                {
                    // fall through
                    string upstreamCommitName = ReadFile(rebaseDir, ONTO);
                    this.upstreamCommit = walk.ParseCommit(repo.Resolve(upstreamCommitName));
                    break;
                }

                case RebaseCommand.Operation.BEGIN:
                {
                    RebaseResult res = InitFilesAndRewind();
                    if (res != null)
                    {
                        return(res);
                    }
                    break;
                }
                }
                if (monitor.IsCancelled())
                {
                    return(Abort(RebaseResult.ABORTED_RESULT));
                }
                if (operation == RebaseCommand.Operation.CONTINUE)
                {
                    newHead = ContinueRebase();
                    if (newHead == null)
                    {
                        // continueRebase() returns null only if no commit was
                        // neccessary. This means that no changes where left over
                        // after resolving all conflicts. In this case, cgit stops
                        // and displays a nice message to the user, telling him to
                        // either do changes or skip the commit instead of continue.
                        return(RebaseResult.NOTHING_TO_COMMIT_RESULT);
                    }
                }
                if (operation == RebaseCommand.Operation.SKIP)
                {
                    newHead = CheckoutCurrentHead();
                }
                ObjectReader or = repo.NewObjectReader();
                IList <RebaseCommand.Step> steps = LoadSteps();
                foreach (RebaseCommand.Step step in steps)
                {
                    PopSteps(1);
                    ICollection <ObjectId> ids = or.Resolve(step.commit);
                    if (ids.Count != 1)
                    {
                        throw new JGitInternalException("Could not resolve uniquely the abbreviated object ID"
                                                        );
                    }
                    RevCommit commitToPick = walk.ParseCommit(ids.Iterator().Next());
                    if (monitor.IsCancelled())
                    {
                        return(new RebaseResult(commitToPick));
                    }
                    try
                    {
                        monitor.BeginTask(MessageFormat.Format(JGitText.Get().applyingCommit, commitToPick
                                                               .GetShortMessage()), ProgressMonitor.UNKNOWN);
                        // if the first parent of commitToPick is the current HEAD,
                        // we do a fast-forward instead of cherry-pick to avoid
                        // unnecessary object rewriting
                        newHead            = TryFastForward(commitToPick);
                        lastStepWasForward = newHead != null;
                        if (!lastStepWasForward)
                        {
                            // TODO if the content of this commit is already merged
                            // here we should skip this step in order to avoid
                            // confusing pseudo-changed
                            CherryPickResult cherryPickResult = new Git(repo).CherryPick().Include(commitToPick
                                                                                                   ).Call();
                            switch (cherryPickResult.GetStatus())
                            {
                            case CherryPickResult.CherryPickStatus.FAILED:
                            {
                                if (operation == RebaseCommand.Operation.BEGIN)
                                {
                                    return(Abort(new RebaseResult(cherryPickResult.GetFailingPaths())));
                                }
                                else
                                {
                                    return(Stop(commitToPick));
                                }
                                goto case CherryPickResult.CherryPickStatus.CONFLICTING;
                            }

                            case CherryPickResult.CherryPickStatus.CONFLICTING:
                            {
                                return(Stop(commitToPick));
                            }

                            case CherryPickResult.CherryPickStatus.OK:
                            {
                                newHead = cherryPickResult.GetNewHead();
                                break;
                            }
                            }
                        }
                    }
                    finally
                    {
                        monitor.EndTask();
                    }
                }
                if (newHead != null)
                {
                    string headName = ReadFile(rebaseDir, HEAD_NAME);
                    UpdateHead(headName, newHead);
                    FileUtils.Delete(rebaseDir, FileUtils.RECURSIVE);
                    if (lastStepWasForward)
                    {
                        return(RebaseResult.FAST_FORWARD_RESULT);
                    }
                    return(RebaseResult.OK_RESULT);
                }
                return(RebaseResult.FAST_FORWARD_RESULT);
            }
            catch (IOException ioe)
            {
                throw new JGitInternalException(ioe.Message, ioe);
            }
        }
예제 #16
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.Errors.UnmergedPathException">when the current index contained unmerged paths (conflicts)
        ///     </exception>
        /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">when repository is not in the right state for committing
        ///     </exception>
        /// <exception cref="NGit.Api.Errors.JGitInternalException">
        /// a low-level exception of JGit has occurred. The original
        /// exception can be retrieved by calling
        /// <see cref="System.Exception.InnerException()">System.Exception.InnerException()</see>
        /// . Expect only
        /// <code>IOException's</code>
        /// to be wrapped. Subclasses of
        /// <see cref="System.IO.IOException">System.IO.IOException</see>
        /// (e.g.
        /// <see cref="NGit.Errors.UnmergedPathException">NGit.Errors.UnmergedPathException</see>
        /// ) are
        /// typically not wrapped here but thrown as original exception
        /// </exception>
        /// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException"></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)
                {
                    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);
                        }
                    }
                    else
                    {
                        parents.Add(0, headId);
                    }
                }
                // lock the index
                DirCache index = repo.LockDirCache();
                try
                {
                    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);
                        // 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);
                            ru.SetRefLogMessage("commit : " + revCommit.GetShortMessage(), false);
                            ru.SetExpectedOldObjectId(headId);
                            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);
                                }
                                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)
            {
                // since UnmergedPathException is a subclass of IOException
                // which should not be wrapped by a JGitInternalException we
                // have to catch and re-throw it here
                throw;
            }
            catch (IOException e)
            {
                throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfCommitCommand
                                                , e);
            }
        }
예제 #17
0
        } // End Sub ListAllBranches

        // https://stackoverflow.com/questions/15822544/jgit-how-to-get-all-commits-of-a-branch-without-changes-to-the-working-direct
        public static void WalkCommits()
        {
            string     dir  = GetRepoPath();
            Git        git  = Git.Open(dir);
            Repository repo = git.GetRepository();

            RevWalk walk = new RevWalk(repo);


            System.Collections.Generic.IList <Ref> branches = git.BranchList().Call();

            // https://stackoverflow.com/questions/15822544/jgit-how-to-get-all-commits-of-a-branch-without-changes-to-the-working-direct
            foreach (Ref branch in branches)
            {
                string branchName = branch.GetName();
                System.Console.WriteLine("Commits of branch: " + branchName);
                System.Console.WriteLine("-------------------------------------");

                Sharpen.Iterable <RevCommit> commits = git.Log().All().Call();

                foreach (RevCommit commit in commits)
                {
                    bool      foundInThisBranch = false;
                    RevCommit targetCommit      = walk.ParseCommit(repo.Resolve(commit.Name));

                    foreach (System.Collections.Generic.KeyValuePair <string, Ref> e in repo.GetAllRefs())
                    {
                        if (e.Key.StartsWith(Constants.R_HEADS))
                        {
                            if (walk.IsMergedInto(targetCommit, walk.ParseCommit(e.Value.GetObjectId())))
                            {
                                string foundInBranch = e.Value.GetName();

                                if (branchName.Equals(foundInBranch))
                                {
                                    foundInThisBranch = true;
                                    break;
                                } // End if (branchName.Equals(foundInBranch))
                            }     // End if (walk.IsMergedInto(targetCommit, walk.ParseCommit(e.Value.GetObjectId())))
                        }         // End if (e.Key.StartsWith(Constants.R_HEADS))
                    }             // Next e

                    if (foundInThisBranch)
                    {
                        System.Console.WriteLine(commit.Name);
                        System.Console.WriteLine(commit.GetAuthorIdent().GetName());

                        // System.DateTime dt = new System.DateTime(commit.CommitTime);
                        System.DateTime dt = UnixTimeStampToDateTime(commit.CommitTime);

                        System.Console.WriteLine(dt);
                        System.Console.WriteLine(commit.GetFullMessage());
                    } // End if (foundInThisBranch)
                }     // Next commit
            }         // Next branch

            // Handle disposing of NGit's locks
            repo.Close();
            repo.ObjectDatabase.Close();
            repo = null;
            git  = null;
        } // End Sub
예제 #18
0
        public Stash Create(NGit.ProgressMonitor monitor, string message)
        {
            if (monitor != null)
            {
                monitor.Start(1);
                monitor.BeginTask("Stashing changes", 100);
            }

            UserConfig config = _repo.GetConfig().Get(UserConfig.KEY);
            RevWalk    rw     = new RevWalk(_repo);
            ObjectId   headId = _repo.Resolve(Constants.HEAD);
            var        parent = rw.ParseCommit(headId);

            PersonIdent author = new PersonIdent(config.GetAuthorName() ?? "unknown", config.GetAuthorEmail() ?? "unknown@(none).");

            if (string.IsNullOrEmpty(message))
            {
                // Use the commit summary as message
                message = parent.Abbreviate(7).ToString() + " " + parent.GetShortMessage();
                int i = message.IndexOfAny(new char[] { '\r', '\n' });
                if (i != -1)
                {
                    message = message.Substring(0, i);
                }
            }

            // Create the index tree commit
            ObjectInserter inserter = _repo.NewObjectInserter();
            DirCache       dc       = _repo.ReadDirCache();

            if (monitor != null)
            {
                monitor.Update(10);
            }

            var tree_id = dc.WriteTree(inserter);

            inserter.Release();

            if (monitor != null)
            {
                monitor.Update(10);
            }

            string   commitMsg   = "index on " + _repo.GetBranch() + ": " + message;
            ObjectId indexCommit = GitUtil.CreateCommit(_repo, commitMsg + "\n", new ObjectId[] { headId }, tree_id, author, author);

            if (monitor != null)
            {
                monitor.Update(20);
            }

            // Create the working dir commit
            tree_id   = WriteWorkingDirectoryTree(parent.Tree, dc);
            commitMsg = "WIP on " + _repo.GetBranch() + ": " + message;
            var wipCommit = GitUtil.CreateCommit(_repo, commitMsg + "\n", new ObjectId[] { headId, indexCommit }, tree_id, author, author);

            if (monitor != null)
            {
                monitor.Update(20);
            }

            string   prevCommit = null;
            FileInfo sf         = StashRefFile;

            if (sf.Exists)
            {
                prevCommit = File.ReadAllText(sf.FullName).Trim(' ', '\t', '\r', '\n');
            }

            Stash s = new Stash(prevCommit, wipCommit.Name, author, commitMsg);

            FileInfo stashLog = StashLogFile;

            File.AppendAllText(stashLog.FullName, s.FullLine + "\n");
            File.WriteAllText(sf.FullName, s.CommitId + "\n");

            if (monitor != null)
            {
                monitor.Update(5);
            }

            // Wipe all local changes
            GitUtil.HardReset(_repo, Constants.HEAD);

            monitor.EndTask();
            s.StashCollection = this;
            return(s);
        }
예제 #19
0
		public override string GetTextAtRevision (FilePath repositoryPath, Revision revision)
		{
			var repository = GetRepository (repositoryPath);
			ObjectId id = repository.Resolve (revision.ToString ());
			RevWalk rw = new RevWalk (repository);
			RevCommit c = rw.ParseCommit (id);
			if (c == null)
				return string.Empty;
			else
				return GetCommitTextContent (c, repositoryPath);
		}
        public static MergeCommandResult MergeTrees(NGit.ProgressMonitor monitor, NGit.Repository repo, RevCommit srcBase, RevCommit srcCommit, string sourceDisplayName, bool commitResult)
        {
            RevCommit newHead = null;
            RevWalk   revWalk = new RevWalk(repo);

            try
            {
                // get the head commit
                Ref headRef = repo.GetRef(Constants.HEAD);
                if (headRef == null)
                {
                    throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported
                                              );
                }
                RevCommit headCommit = revWalk.ParseCommit(headRef.GetObjectId());

                ResolveMerger merger = (ResolveMerger)((ThreeWayMerger)MergeStrategy.RESOLVE.NewMerger
                                                           (repo));

                merger.SetWorkingTreeIterator(new FileTreeIterator(repo));

                merger.SetBase(srcBase);

                bool noProblems;
                IDictionary <string, MergeResult <NGit.Diff.Sequence> > lowLevelResults = null;
                IDictionary <string, ResolveMerger.MergeFailureReason>  failingPaths    = null;
                IList <string> modifiedFiles = null;

                ResolveMerger resolveMerger = (ResolveMerger)merger;
                resolveMerger.SetCommitNames(new string[] { "BASE", "HEAD", sourceDisplayName });
                noProblems      = merger.Merge(headCommit, srcCommit);
                lowLevelResults = resolveMerger.GetMergeResults();
                modifiedFiles   = resolveMerger.GetModifiedFiles();
                failingPaths    = resolveMerger.GetFailingPaths();

                if (monitor != null)
                {
                    monitor.Update(50);
                }

                if (noProblems)
                {
                    if (modifiedFiles != null && modifiedFiles.Count == 0)
                    {
                        return(new MergeCommandResult(headCommit, null, new ObjectId[] { headCommit.Id, srcCommit
                                                                                         .Id }, MergeStatus.ALREADY_UP_TO_DATE, MergeStrategy.RESOLVE, null, null));
                    }
                    DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache
                                                                    (), merger.GetResultTreeId());
                    dco.SetFailOnConflict(true);
                    dco.Checkout();
                    if (commitResult)
                    {
                        newHead = new NGit.Api.Git(repo).Commit().SetMessage(srcCommit.GetFullMessage()
                                                                             ).SetAuthor(srcCommit.GetAuthorIdent()).Call();
                        return(new MergeCommandResult(newHead.Id, null, new ObjectId[] { headCommit.Id, srcCommit
                                                                                         .Id }, MergeStatus.MERGED, MergeStrategy.RESOLVE, null, null));
                    }
                    else
                    {
                        return(new MergeCommandResult(headCommit, null, new ObjectId[] { headCommit.Id, srcCommit
                                                                                         .Id }, MergeStatus.MERGED, MergeStrategy.RESOLVE, null, null));
                    }
                }
                else
                {
                    if (failingPaths != null)
                    {
                        return(new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId[]
                        {
                            headCommit.Id, srcCommit.Id
                        }, MergeStatus.FAILED, MergeStrategy.RESOLVE, lowLevelResults
                                                      , failingPaths, null));
                    }
                    else
                    {
                        return(new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId[]
                        {
                            headCommit.Id, srcCommit.Id
                        }, MergeStatus.CONFLICTING, MergeStrategy.RESOLVE, lowLevelResults
                                                      , null));
                    }
                }
            }
            finally
            {
                revWalk.Release();
            }
        }
        /// <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);
        }
예제 #22
0
        public static void MergeTest(EngineContext engineContext)
        {
            // TODO: Currently hardcoded
            var db            = new FileRepository(new FilePath(@"C:\DEV\hotei_scene", Constants.DOT_GIT));
            var git           = new Git(db);
            var tree1Ref      = db.GetRef("test");
            var tree2Ref      = db.GetRef(Constants.HEAD);
            var tree1CommitId = tree1Ref.GetObjectId();
            var tree2CommitId = tree2Ref.GetObjectId();

            // Merge tree1 into current tree
            var mergeResult = git.Merge().Include(tree1CommitId).Call();

            if (mergeResult.GetMergeStatus() == MergeStatus.CONFLICTING)
            {
                foreach (var conflict in mergeResult.GetConflicts())
                {
                    if (conflict.Key.EndsWith(".hotei"))
                    {
                        // Search base tree (common ancestor), if any
                        var walk = new RevWalk(db);
                        walk.SetRevFilter(RevFilter.MERGE_BASE);
                        walk.MarkStart(walk.ParseCommit(tree1CommitId));
                        walk.MarkStart(walk.ParseCommit(tree2CommitId));
                        var baseTree = walk.Next();

                        var tw = new NameConflictTreeWalk(db);
                        tw.AddTree(new RevWalk(db).ParseTree(tree1CommitId).ToObjectId());
                        tw.AddTree(new RevWalk(db).ParseTree(tree2CommitId).ToObjectId());
                        if (baseTree != null)
                        {
                            tw.AddTree(new RevWalk(db).ParseTree(baseTree.ToObjectId()).ToObjectId());
                        }
                        tw.Filter = PathFilter.Create(conflict.Key);

                        // Should be only one iteration
                        while (tw.Next())
                        {
                            var tree0 = baseTree != null?tw.GetTree <AbstractTreeIterator>(2) : null;

                            var tree1 = tw.GetTree <AbstractTreeIterator>(0);
                            var tree2 = tw.GetTree <AbstractTreeIterator>(1);

                            // Get contents of every versions for the 3-way merge
                            var data0 = baseTree != null?LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree0.EntryObjectId).GetBytes())) : null;

                            var data1 = LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree1.EntryObjectId).GetBytes()));
                            var data2 = LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree2.EntryObjectId).GetBytes()));

                            // Perform 3-way merge
                            var entities = new List <EntityDefinition>();
                            ThreeWayMergeOrdered.Merge(entities, data0, data1, data2, x => x.Guid, (x, y) => x == y, ResolveEntityConflicts);

                            // Save new merged file
                            var fileStream = new FileStream(new FilePath(db.WorkTree, conflict.Key), FileMode.Create, FileAccess.Write);
                            var stream     = new BinarySerializationWriter(fileStream);
                            stream.Context.Serializer = Serializer;
                            stream.SerializeClass(null, ref entities, ArchiveMode.Serialize);
                            fileStream.Close();

                            // TODO: Check if all conflicts are really resolved
                            // Add resolved file for merge commit
                            git.Add().AddFilepattern(conflict.Key).Call();
                        }
                    }
                }
            }
        }
예제 #23
0
		public static IEnumerable<Change> GetChangedFiles (NGit.Repository repo, string refRev)
		{
			// Get a list of files that are different in the target branch
			RevWalk rw = new RevWalk (repo);
			ObjectId remCommitId = repo.Resolve (refRev);
			if (remCommitId == null)
				return null;
			RevCommit remCommit = rw.ParseCommit (remCommitId);
			
			ObjectId headId = repo.Resolve (Constants.HEAD);
			if (headId == null)
				return null;
			RevCommit headCommit = rw.ParseCommit (headId);
			
			return GitUtil.CompareCommits (repo, headCommit, remCommit);
		}
예제 #24
0
		public static FileRepository Clone (string targetLocalPath, string url, IProgressMonitor monitor)
		{
			// Initialize
			
			InitCommand ci = new InitCommand ();
			ci.SetDirectory (targetLocalPath);
			var git = ci.Call ();
			FileRepository repo = (FileRepository) git.GetRepository ();
			
			string branch = Constants.R_HEADS + "master";
			string remoteName = "origin";
			
			RefUpdate head = repo.UpdateRef (Constants.HEAD);
			head.DisableRefLog ();
			head.Link (branch);
			
			RemoteConfig remoteConfig = new RemoteConfig (repo.GetConfig (), remoteName);
			remoteConfig.AddURI (new URIish (url));
			
			string dst = Constants.R_REMOTES + remoteConfig.Name;
			RefSpec wcrs = new RefSpec();
			wcrs = wcrs.SetForceUpdate (true);
			wcrs = wcrs.SetSourceDestination (Constants.R_HEADS	+ "*", dst + "/*");
			
			remoteConfig.AddFetchRefSpec (wcrs);
	
			// we're setting up for a clone with a checkout
			repo.GetConfig().SetBoolean ("core", null, "bare", false);
	
			remoteConfig.Update (repo.GetConfig());
	
			repo.GetConfig().Save();
			
			// Fetch
			
			Transport tn = Transport.Open (repo, remoteName);
			FetchResult r;

			try {
				r = tn.Fetch(new GitMonitor (monitor), null);
			}
			finally {
				tn.Close ();
			}
			
			// Create the master branch
			
			// branch is like 'Constants.R_HEADS + branchName', we need only
			// the 'branchName' part
			String branchName = branch.Substring (Constants.R_HEADS.Length);
			git.BranchCreate ().SetName (branchName).SetUpstreamMode (CreateBranchCommand.SetupUpstreamMode.TRACK).SetStartPoint ("origin/master").Call ();
			
			// Checkout

			DirCache dc = repo.LockDirCache ();
			try {
				RevWalk rw = new RevWalk (repo);
				ObjectId remCommitId = repo.Resolve (remoteName + "/" + branchName);
				RevCommit remCommit = rw.ParseCommit (remCommitId);
				DirCacheCheckout co = new DirCacheCheckout (repo, null, dc, remCommit.Tree);
				co.Checkout ();
			} catch {
				dc.Unlock ();
				throw;
			}
			
			return repo;
		}
예제 #25
0
		public static MergeCommandResult MergeTrees (NGit.Repository repo, RevCommit srcBase, RevCommit srcCommit, string sourceDisplayName, bool commitResult)
		{
			RevCommit newHead = null;
			RevWalk revWalk = new RevWalk(repo);
			try
			{
				// get the head commit
				Ref headRef = repo.GetRef(Constants.HEAD);
				if (headRef == null)
				{
					throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported
						);
				}
				RevCommit headCommit = revWalk.ParseCommit(headRef.GetObjectId());
				
				ResolveMerger merger = (ResolveMerger)((ThreeWayMerger)MergeStrategy.RESOLVE.NewMerger
					(repo));
				
				// CherryPick command sets the working tree, but this should not be necessary, and when setting it
				// untracked files are deleted during the merge
				// merger.SetWorkingTreeIterator(new FileTreeIterator(repo));
				
				merger.SetBase(srcBase);
				
				bool noProblems;
				IDictionary<string, MergeResult<NGit.Diff.Sequence>> lowLevelResults = null;
				IDictionary<string, ResolveMerger.MergeFailureReason> failingPaths = null;
				IList<string> modifiedFiles = null;
				
				ResolveMerger resolveMerger = (ResolveMerger)merger;
				resolveMerger.SetCommitNames(new string[] { "BASE", "HEAD", sourceDisplayName });
				noProblems = merger.Merge(headCommit, srcCommit);
				lowLevelResults = resolveMerger.GetMergeResults();
				modifiedFiles = resolveMerger.GetModifiedFiles();
				failingPaths = resolveMerger.GetFailingPaths();
				
				if (noProblems)
				{
					if (modifiedFiles != null && modifiedFiles.Count == 0) {
						return new MergeCommandResult(headCommit, null, new ObjectId[] { headCommit.Id, srcCommit
							.Id }, MergeStatus.ALREADY_UP_TO_DATE, MergeStrategy.RESOLVE, null, null);
					}
					DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache
						(), merger.GetResultTreeId());
					dco.SetFailOnConflict(true);
					dco.Checkout();
					if (commitResult) {
						newHead = new NGit.Api.Git(repo).Commit().SetMessage(srcCommit.GetFullMessage()
							).SetAuthor(srcCommit.GetAuthorIdent()).Call();
						return new MergeCommandResult(newHead.Id, null, new ObjectId[] { headCommit.Id, srcCommit
							.Id }, MergeStatus.MERGED, MergeStrategy.RESOLVE, null, null);
					} else {
						return new MergeCommandResult(headCommit, null, new ObjectId[] { headCommit.Id, srcCommit
							.Id }, MergeStatus.MERGED, MergeStrategy.RESOLVE, null, null);
					}
				}
				else
				{
					if (failingPaths != null)
					{
						return new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId[] { 
							headCommit.Id, srcCommit.Id }, MergeStatus.FAILED, MergeStrategy.RESOLVE, lowLevelResults
							, null);
					}
					else
					{
						return new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId[] { 
							headCommit.Id, srcCommit.Id }, MergeStatus.CONFLICTING, MergeStrategy.RESOLVE, lowLevelResults
							, null);
					}
				}
			}
			finally
			{
				revWalk.Release();
			}
		}
예제 #26
0
		public static RevCommit[] Blame (NGit.Repository repo, RevCommit c, string file)
		{
			TreeWalk tw = TreeWalk.ForPath (repo, ToGitPath (repo, file), c.Tree);
			if (tw == null)
				return new RevCommit [0];
			ObjectId id = tw.GetObjectId (0);
			byte[] data = repo.ObjectDatabase.Open (id).GetBytes ();
			
			int lineCount = NGit.Util.RawParseUtils.LineMap (data, 0, data.Length).Size ();
			RevCommit[] lines = new RevCommit [lineCount];
			var curText = new RawText (data);
			RevCommit prevAncestor = c;
			
			ObjectId prevObjectId = null;
			RevCommit prevCommit = null;
			int emptyLines = lineCount;
			RevWalk rw = new RevWalk (repo);
			
			foreach (ObjectId ancestorId in c.Parents) {
				RevCommit ancestor = rw.ParseCommit (ancestorId);
				tw = TreeWalk.ForPath (repo, ToGitPath (repo, file), ancestor.Tree);
				if (prevCommit != null && (tw == null || tw.GetObjectId (0) != prevObjectId)) {
					if (prevObjectId == null)
						break;
					byte[] prevData = repo.ObjectDatabase.Open (prevObjectId).GetBytes ();
					var prevText = new RawText (prevData);
					var differ = MyersDiff<RawText>.INSTANCE;
					foreach (Edit e in differ.Diff (RawTextComparator.DEFAULT, prevText, curText)) {
						for (int n = e.GetBeginB (); n < e.GetEndB (); n++) {
							if (lines [n] == null) {
								lines [n] = prevCommit;
								emptyLines--;
							}
						}
					}
					if (tw == null || emptyLines <= 0)
						break;
				}
				prevCommit = ancestor;
				prevObjectId = tw != null ? tw.GetObjectId (0) : null;
			}
			for (int n=0; n<lines.Length; n++)
				if (lines [n] == null)
					lines [n] = prevAncestor;
			return lines;
		}
예제 #27
0
		protected override string OnGetTextAtRevision (FilePath repositoryPath, Revision revision)
		{
			var repository = GetRepository (repositoryPath);
			ObjectId id = repository.Resolve (revision.ToString ());
			RevWalk rw = new RevWalk (repository);
			RevCommit c = rw.ParseCommit (id);
			return c == null ? string.Empty : GetCommitTextContent (c, repositoryPath);
		}
예제 #28
0
		public static MergeCommandResult CherryPick (NGit.Repository repo, RevCommit srcCommit)
		{
			RevCommit newHead = null;
			RevWalk revWalk = new RevWalk(repo);
			try
			{
				// get the head commit
				Ref headRef = repo.GetRef(Constants.HEAD);
				if (headRef == null)
				{
					throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported
						);
				}
				RevCommit headCommit = revWalk.ParseCommit(headRef.GetObjectId());
				
				// get the parent of the commit to cherry-pick
				if (srcCommit.ParentCount != 1)
				{
					throw new MultipleParentsNotAllowedException(JGitText.Get().canOnlyCherryPickCommitsWithOneParent
						);
				}
				RevCommit srcParent = srcCommit.GetParent(0);
				revWalk.ParseHeaders(srcParent);
				
				return MergeTrees (repo, srcParent, srcCommit, srcCommit.Name, true);
			}
			catch (IOException e)
			{
				throw new Exception ("Commit failed", e);
			}
			finally
			{
				revWalk.Release();
			}
		}
예제 #29
0
 public virtual void TestStopOnConflictCommitAndContinue()
 {
     // create file1 on master
     RevCommit firstInMaster = WriteFileAndCommit(FILE1, "Add file1", "1", "2", "3");
     // change in master
     WriteFileAndCommit(FILE1, "change file1 in master", "1master", "2", "3");
     CheckFile(FILE1, "1master", "2", "3");
     // create a topic branch based on the first commit
     CreateBranch(firstInMaster, "refs/heads/topic");
     CheckoutBranch("refs/heads/topic");
     // we have the old content again
     CheckFile(FILE1, "1", "2", "3");
     // add a line (non-conflicting)
     WriteFileAndCommit(FILE1, "add a line to file1 in topic", "1", "2", "3", "4topic"
         );
     // change first line (conflicting)
     WriteFileAndCommit(FILE1, "change file1 in topic\n\nThis is conflicting", "1topic"
         , "2", "3", "4topic");
     // change second line (not conflicting)
     WriteFileAndCommit(FILE1, "change file1 in topic again", "1topic", "2", "3topic",
         "4topic");
     RebaseResult res = git.Rebase().SetUpstream("refs/heads/master").Call();
     NUnit.Framework.Assert.AreEqual(RebaseResult.Status.STOPPED, res.GetStatus());
     // continue should throw a meaningful exception
     try
     {
         res = git.Rebase().SetOperation(RebaseCommand.Operation.CONTINUE).Call();
         NUnit.Framework.Assert.Fail("Expected Exception not thrown");
     }
     catch (UnmergedPathsException)
     {
     }
     // expected
     // merge the file; the second topic commit should go through
     WriteFileAndCommit(FILE1, "A different commit message", "1topic", "2", "3", "4topic"
         );
     res = git.Rebase().SetOperation(RebaseCommand.Operation.CONTINUE).Call();
     NUnit.Framework.Assert.IsNotNull(res);
     NUnit.Framework.Assert.AreEqual(RebaseResult.Status.OK, res.GetStatus());
     NUnit.Framework.Assert.AreEqual(RepositoryState.SAFE, db.GetRepositoryState());
     ObjectId headId = db.Resolve(Constants.HEAD);
     RevWalk rw = new RevWalk(db);
     RevCommit rc = rw.ParseCommit(headId);
     RevCommit parent = rw.ParseCommit(rc.GetParent(0));
     NUnit.Framework.Assert.AreEqual("A different commit message", parent.GetFullMessage
         ());
 }
예제 #30
0
		public void SwitchToBranch (IProgressMonitor monitor, string branch)
		{
			monitor.BeginTask (GettextCatalog.GetString ("Switching to branch {0}", branch), GitService.StashUnstashWhenSwitchingBranches ? 4 : 2);
			
			// Get a list of files that are different in the target branch
			IEnumerable<DiffEntry> statusList = GitUtil.GetChangedFiles (RootRepository, branch);
			
			StashCollection stashes = null;
			Stash stash = null;
			
			if (GitService.StashUnstashWhenSwitchingBranches) {
				stashes = GitUtil.GetStashes (RootRepository);
				
				// Remove the stash for this branch, if exists
				string currentBranch = GetCurrentBranch ();
				stash = GetStashForBranch (stashes, currentBranch);
				if (stash != null)
					stashes.Remove (stash);
				
				// Create a new stash for the branch. This allows switching branches
				// without losing local changes
				using (var gm = new GitMonitor (monitor))
					stash = stashes.Create (gm, GetStashName (currentBranch));
			
				monitor.Step (1);
			}
			
			// Switch to the target branch
			DirCache dc = RootRepository.LockDirCache ();
			try {
				RevWalk rw = new RevWalk (RootRepository);
				ObjectId branchHeadId = RootRepository.Resolve (branch);
				if (branchHeadId == null)
					throw new InvalidOperationException ("Branch head commit not found");
				
				RevCommit branchCommit = rw.ParseCommit (branchHeadId);
				DirCacheCheckout checkout = new DirCacheCheckout (RootRepository, null, dc, branchCommit.Tree);
				checkout.Checkout ();
				
				RefUpdate u = RootRepository.UpdateRef(Constants.HEAD);
				u.Link ("refs/heads/" + branch);
				monitor.Step (1);
			} catch {
				dc.Unlock ();
				if (GitService.StashUnstashWhenSwitchingBranches) {
					// If something goes wrong, restore the work tree status
					using (var gm = new GitMonitor (monitor))
						stash.Apply (gm);
					stashes.Remove (stash);
				}
				throw;
			}
			
			// Restore the branch stash
			
			if (GitService.StashUnstashWhenSwitchingBranches) {
				stash = GetStashForBranch (stashes, branch);
				if (stash != null) {
					using (var gm = new GitMonitor (monitor))
						stash.Apply (gm);
					stashes.Remove (stash);
				}
				monitor.Step (1);
			}
			
			// Notify file changes
			
			NotifyFileChanges (monitor, statusList);
			
			if (BranchSelectionChanged != null)
				BranchSelectionChanged (this, EventArgs.Empty);
			
			monitor.EndTask ();
		}
예제 #31
0
 /// <exception cref="NGit.Errors.MissingObjectException"></exception>
 /// <exception cref="NGit.Errors.IncorrectObjectTypeException"></exception>
 /// <exception cref="System.IO.IOException"></exception>
 private RevCommit ParseCommit(AnyObjectId id)
 {
     RevWalk rw = new RevWalk(db);
     try
     {
         return rw.ParseCommit(id);
     }
     finally
     {
         rw.Release();
     }
 }
예제 #32
0
		public DiffInfo[] GetPushDiff (string remote, string branch)
		{
			ObjectId cid1 = RootRepository.Resolve (remote + "/" + branch);
			ObjectId cid2 = RootRepository.Resolve (RootRepository.GetBranch ());
			RevWalk rw = new RevWalk (RootRepository);
			RevCommit c1 = rw.ParseCommit (cid1);
			RevCommit c2 = rw.ParseCommit (cid2);
			
			List<DiffInfo> diffs = new List<DiffInfo> ();
			foreach (var change in GitUtil.CompareCommits (RootRepository, c1, c2)) {
				string diff;
				switch (change.GetChangeType ()) {
				case DiffEntry.ChangeType.DELETE:
					diff = GenerateDiff (EmptyContent, GetCommitContent (c2, change.GetOldPath ()));
					break;
				case DiffEntry.ChangeType.ADD:
					diff = GenerateDiff (GetCommitContent (c1, change.GetNewPath ()), EmptyContent);
					break;
				default:
					diff = GenerateDiff (GetCommitContent (c1, change.GetNewPath ()), GetCommitContent (c2, change.GetNewPath ()));
					break;
				}
				DiffInfo di = new DiffInfo (RootPath, RootRepository.FromGitPath (change.GetNewPath ()), diff);
				diffs.Add (di);
			}
			return diffs.ToArray ();
		}
예제 #33
0
		public bool IsBranchMerged (string branchName)
		{
			// check if a branch is merged into HEAD
			RevWalk walk = new RevWalk(RootRepository);
			RevCommit tip = walk.ParseCommit(RootRepository.Resolve(Constants.HEAD));
			Ref currentRef = RootRepository.GetRef(branchName);
			if (currentRef == null)
				return true;
			RevCommit @base = walk.ParseCommit(RootRepository.Resolve(branchName));
			return walk.IsMergedInto(@base, tip);
		}
예제 #34
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>
        /// <returns>the newly created branch</returns>
        /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception>
        public override Ref Call()
        {
            CheckCallable();
            ProcessOptions();
            try
            {
                if (!paths.IsEmpty())
                {
                    CheckoutPaths();
                    status = CheckoutResult.OK_RESULT;
                    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   refLogMessage = "checkout: moving from " + headRef.GetTarget().GetName();
                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        = new DirCacheCheckout(repo, headTree, repo.LockDirCache(),
                                                                   newCommit.Tree);
                dco.SetFailOnConflict(true);
                try
                {
                    dco.Checkout();
                }
                catch (NGit.Errors.CheckoutConflictException e)
                {
                    status = new CheckoutResult(CheckoutResult.Status.CONFLICTS, dco.GetConflicts());
                    throw;
                }
                Ref @ref = repo.GetRef(name);
                if (@ref != null && [email protected]().StartsWith(Constants.R_HEADS))
                {
                    @ref = null;
                }
                RefUpdate refUpdate = repo.UpdateRef(Constants.HEAD, @ref == null);
                refUpdate.SetForceUpdate(force);
                refUpdate.SetRefLogMessage(refLogMessage + " to " + newCommit.GetName(), 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 = CheckoutResult.OK_RESULT;
                }
                return(@ref);
            }
            catch (IOException ioe)
            {
                throw new JGitInternalException(ioe.Message, ioe);
            }
            finally
            {
                if (status == null)
                {
                    status = CheckoutResult.ERROR_RESULT;
                }
            }
        }
예제 #35
0
		public ChangeSet GetPushChangeSet (string remote, string branch)
		{
			ChangeSet cset = CreateChangeSet (RootPath);
			ObjectId cid1 = RootRepository.Resolve (remote + "/" + branch);
			ObjectId cid2 = RootRepository.Resolve (RootRepository.GetBranch ());
			RevWalk rw = new RevWalk (RootRepository);
			RevCommit c1 = rw.ParseCommit (cid1);
			RevCommit c2 = rw.ParseCommit (cid2);
			
			foreach (var change in GitUtil.CompareCommits (RootRepository, c2, c1)) {
				VersionStatus status;
				switch (change.GetChangeType ()) {
				case DiffEntry.ChangeType.ADD:
					status = VersionStatus.ScheduledAdd;
					break;
				case DiffEntry.ChangeType.DELETE:
					status = VersionStatus.ScheduledDelete;
					break;
				default:
					status = VersionStatus.Modified;
					break;
				}
				VersionInfo vi = new VersionInfo (RootRepository.FromGitPath (change.GetNewPath ()), "", false, status | VersionStatus.Versioned, null, VersionStatus.Versioned, null);
				cset.AddFile (vi);
			}
			return cset;
		}
예제 #36
0
        private RevCommit ParseCommit(Repository repo, ObjectId id)
        {
            RevWalk rw = new RevWalk(repo);
            var head = rw.ParseCommit(id);
            rw.MarkStart(head);
            RevCommit commit = null;
            try
            {
                commit = rw.Next();
                while( commit != null )
                {
                    if (commit.Id.Name == id.Name)
                    {
                        return commit;
                    }
                    commit = rw.Next();
                }

            }
            finally
            {
                rw.Release();
            }
            return commit;
        }
예제 #37
0
		RevCommit GetHeadCommit (NGit.Repository repository)
		{
			RevWalk rw = new RevWalk (repository);
			ObjectId headId = repository.Resolve (Constants.HEAD);
			if (headId == null)
				return null;
			return rw.ParseCommit (headId);
		}
예제 #38
0
 /// <exception cref="System.InvalidOperationException"></exception>
 /// <exception cref="System.IO.IOException"></exception>
 private void CheckoutBranch(string branchName)
 {
     RevWalk walk = new RevWalk(db);
     RevCommit head = walk.ParseCommit(db.Resolve(Constants.HEAD));
     RevCommit branch = walk.ParseCommit(db.Resolve(branchName));
     DirCacheCheckout dco = new DirCacheCheckout(db, head.Tree, db.LockDirCache(), branch
         .Tree);
     dco.SetFailOnConflict(true);
     NUnit.Framework.Assert.IsTrue(dco.Checkout());
     walk.Release();
     // update the HEAD
     RefUpdate refUpdate = db.UpdateRef(Constants.HEAD);
     NUnit.Framework.Assert.AreEqual(RefUpdate.Result.FORCED, refUpdate.Link(branchName
         ));
 }
예제 #39
0
		/// <exception cref="System.InvalidOperationException"></exception>
		/// <exception cref="System.IO.IOException"></exception>
		protected internal virtual void CheckoutBranch(string branchName)
		{
			RevWalk walk = new RevWalk(db);
			RevCommit head = walk.ParseCommit(db.Resolve(Constants.HEAD));
			RevCommit branch = walk.ParseCommit(db.Resolve(branchName));
			DirCacheCheckout dco = new DirCacheCheckout(db, head.Tree.Id, db.LockDirCache(), 
				branch.Tree.Id);
			dco.SetFailOnConflict(true);
			dco.Checkout();
			walk.Release();
			// update the HEAD
			RefUpdate refUpdate = db.UpdateRef(Constants.HEAD);
			refUpdate.Link(branchName);
		}
예제 #40
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;
							}
						}
					}
				}
			}
		}
예제 #41
0
		protected override Revision GetHeadRevision ()
		{
			GitRepository repo2 = (GitRepository)repo;
			RevWalk rw = new RevWalk (repo2.RootRepository);
			ObjectId headId = repo2.RootRepository.Resolve (Constants.HEAD);
			if (headId == null)
				return null;

			RevCommit commit = rw.ParseCommit (headId);
			GitRevision rev = new GitRevision (repo, repo2.RootRepository, commit.Id.Name);
			rev.Commit = commit;
			return rev;
		}
예제 #42
0
 /// <summary>Execute the SubmoduleUpdateCommand command.</summary>
 /// <remarks>Execute the SubmoduleUpdateCommand command.</remarks>
 /// <returns>a collection of updated submodule paths</returns>
 /// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException">NGit.Api.Errors.ConcurrentRefUpdateException
 ///     </exception>
 /// <exception cref="NGit.Api.Errors.CheckoutConflictException">NGit.Api.Errors.CheckoutConflictException
 ///     </exception>
 /// <exception cref="NGit.Api.Errors.InvalidMergeHeadsException">NGit.Api.Errors.InvalidMergeHeadsException
 ///     </exception>
 /// <exception cref="NGit.Api.Errors.InvalidConfigurationException">NGit.Api.Errors.InvalidConfigurationException
 ///     </exception>
 /// <exception cref="NGit.Api.Errors.NoHeadException">NGit.Api.Errors.NoHeadException
 ///     </exception>
 /// <exception cref="NGit.Api.Errors.NoMessageException">NGit.Api.Errors.NoMessageException
 ///     </exception>
 /// <exception cref="NGit.Api.Errors.RefNotFoundException">NGit.Api.Errors.RefNotFoundException
 ///     </exception>
 /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">NGit.Api.Errors.WrongRepositoryStateException
 ///     </exception>
 /// <exception cref="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException
 ///     </exception>
 public override ICollection <string> Call()
 {
     CheckCallable();
     try
     {
         SubmoduleWalk generator = SubmoduleWalk.ForIndex(repo);
         if (!paths.IsEmpty())
         {
             generator.SetFilter(PathFilterGroup.CreateFromStrings(paths));
         }
         IList <string> updated = new AList <string>();
         while (generator.Next())
         {
             // Skip submodules not registered in .gitmodules file
             if (generator.GetModulesPath() == null)
             {
                 continue;
             }
             // Skip submodules not registered in parent repository's config
             string url = generator.GetConfigUrl();
             if (url == null)
             {
                 continue;
             }
             Repository submoduleRepo = generator.GetRepository();
             // Clone repository is not present
             if (submoduleRepo == null)
             {
                 CloneCommand clone = Git.CloneRepository();
                 Configure(clone);
                 clone.SetURI(url);
                 clone.SetDirectory(generator.GetDirectory());
                 if (monitor != null)
                 {
                     clone.SetProgressMonitor(monitor);
                 }
                 submoduleRepo = clone.Call().GetRepository();
             }
             try
             {
                 RevWalk   walk   = new RevWalk(submoduleRepo);
                 RevCommit commit = walk.ParseCommit(generator.GetObjectId());
                 string    update = generator.GetConfigUpdate();
                 if (ConfigConstants.CONFIG_KEY_MERGE.Equals(update))
                 {
                     MergeCommand merge = new MergeCommand(submoduleRepo);
                     merge.Include(commit);
                     merge.Call();
                 }
                 else
                 {
                     if (ConfigConstants.CONFIG_KEY_REBASE.Equals(update))
                     {
                         RebaseCommand rebase = new RebaseCommand(submoduleRepo);
                         rebase.SetUpstream(commit);
                         rebase.Call();
                     }
                     else
                     {
                         // Checkout commit referenced in parent repository's
                         // index as a detached HEAD
                         DirCacheCheckout co = new DirCacheCheckout(submoduleRepo, submoduleRepo.LockDirCache
                                                                        (), commit.Tree);
                         co.SetFailOnConflict(true);
                         co.Checkout();
                         RefUpdate refUpdate = submoduleRepo.UpdateRef(Constants.HEAD, true);
                         refUpdate.SetNewObjectId(commit);
                         refUpdate.ForceUpdate();
                     }
                 }
             }
             finally
             {
                 submoduleRepo.Close();
             }
             updated.AddItem(generator.GetPath());
         }
         return(updated);
     }
     catch (IOException e)
     {
         throw new JGitInternalException(e.Message, e);
     }
     catch (ConfigInvalidException e)
     {
         throw new InvalidConfigurationException(e.Message, e);
     }
 }