Пример #1
0
        public virtual void TestStopOnConflictAndSkipWithConflict()
        {
            // create file1 on master
            RevCommit firstInMaster = WriteFileAndCommit(FILE1, "Add file1", "1", "2", "3", "4"
                                                         );

            // change in master
            WriteFileAndCommit(FILE1, "change file1 in master", "1master", "2", "3master", "4"
                               );
            CheckFile(FILE1, "1master", "2", "3master", "4");
            // 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", "4");
            // add a line (non-conflicting)
            WriteFileAndCommit(FILE1, "add a line to file1 in topic", "1", "2", "3", "4", "5topic"
                               );
            // change first line (conflicting)
            WriteFileAndCommit(FILE1, "change file1 in topic\n\nThis is conflicting", "1topic"
                               , "2", "3", "4", "5topic");
            // change third line (conflicting)
            WriteFileAndCommit(FILE1, "change file1 in topic again", "1topic", "2", "3topic",
                               "4", "5topic");
            RebaseResult res = git.Rebase().SetUpstream("refs/heads/master").Call();

            NUnit.Framework.Assert.AreEqual(RebaseResult.Status.STOPPED, res.GetStatus());
            res = git.Rebase().SetOperation(RebaseCommand.Operation.SKIP).Call();
            // TODO is this correct? It is what the command line returns
            CheckFile(FILE1, "1master\n2\n<<<<<<< OURS\n3master\n=======\n3topic\n>>>>>>> THEIRS\n4\n5topic"
                      );
            NUnit.Framework.Assert.AreEqual(RebaseResult.Status.STOPPED, res.GetStatus());
        }
Пример #2
0
        public virtual void TestStopOnConflictAndFailContinueIfFileIsDirty()
        {
            // 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", "2topic", "3",
                               "4topic");
            RebaseResult res = git.Rebase().SetUpstream("refs/heads/master").Call();

            NUnit.Framework.Assert.AreEqual(RebaseResult.Status.STOPPED, res.GetStatus());
            git.Add().AddFilepattern(FILE1).Call();
            FilePath trashFile = WriteTrashFile(FILE1, "Some local change");

            res = git.Rebase().SetOperation(RebaseCommand.Operation.CONTINUE).Call();
            NUnit.Framework.Assert.IsNotNull(res);
            NUnit.Framework.Assert.AreEqual(RebaseResult.Status.STOPPED, res.GetStatus());
            CheckFile(trashFile, "Some local change");
        }
Пример #3
0
        public virtual void TestMergeFirstStopOnLastConflictAndSkip()
        {
            // 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 (conflicting)
            WriteFileAndCommit(FILE1, "add a line to file1 in topic", "1topic", "2", "3", "4topic"
                               );
            // change first line (conflicting again)
            WriteFileAndCommit(FILE1, "change file1 in topic\n\nThis is conflicting", "1topicagain"
                               , "2", "3", "4topic");
            RebaseResult res = git.Rebase().SetUpstream("refs/heads/master").Call();

            NUnit.Framework.Assert.AreEqual(RebaseResult.Status.STOPPED, res.GetStatus());
            WriteFileAndAdd(FILE1, "merged");
            res = git.Rebase().SetOperation(RebaseCommand.Operation.CONTINUE).Call();
            NUnit.Framework.Assert.AreEqual(RebaseResult.Status.STOPPED, res.GetStatus());
            res = git.Rebase().SetOperation(RebaseCommand.Operation.SKIP).Call();
            NUnit.Framework.Assert.IsNotNull(res);
            NUnit.Framework.Assert.AreEqual(RebaseResult.Status.OK, res.GetStatus());
            NUnit.Framework.Assert.AreEqual(RepositoryState.SAFE, db.GetRepositoryState());
            CheckFile(FILE1, "merged");
        }
Пример #4
0
        public virtual void TestFastForwardWithMultipleCommits()
        {
            // create file1 on master
            WriteTrashFile(FILE1, FILE1);
            git.Add().AddFilepattern(FILE1).Call();
            RevCommit first = git.Commit().SetMessage("Add file1").Call();

            NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, FILE1).Exists());
            // create a topic branch
            CreateBranch(first, "refs/heads/topic");
            // create file2 on master
            FilePath file2 = WriteTrashFile("file2", "file2");

            git.Add().AddFilepattern("file2").Call();
            git.Commit().SetMessage("Add file2").Call();
            NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "file2").Exists());
            // write a second commit
            WriteTrashFile("file2", "file2 new content");
            git.Add().AddFilepattern("file2").Call();
            git.Commit().SetMessage("Change content of file2").Call();
            CheckoutBranch("refs/heads/topic");
            NUnit.Framework.Assert.IsFalse(new FilePath(db.WorkTree, "file2").Exists());
            RebaseResult res = git.Rebase().SetUpstream("refs/heads/master").Call();

            NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "file2").Exists());
            CheckFile(file2, "file2 new content");
            NUnit.Framework.Assert.AreEqual(RebaseResult.Status.FAST_FORWARD, res.GetStatus()
                                            );
        }
Пример #5
0
        public virtual void TestConflictFreeWithSingleFile()
        {
            // create file1 on master
            FilePath theFile = WriteTrashFile(FILE1, "1\n2\n3\n");

            git.Add().AddFilepattern(FILE1).Call();
            RevCommit second = git.Commit().SetMessage("Add file1").Call();

            NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, FILE1).Exists());
            // change first line in master and commit
            WriteTrashFile(FILE1, "1master\n2\n3\n");
            CheckFile(theFile, "1master\n2\n3\n");
            git.Add().AddFilepattern(FILE1).Call();
            RevCommit lastMasterChange = git.Commit().SetMessage("change file1 in master").Call
                                             ();

            // create a topic branch based on second commit
            CreateBranch(second, "refs/heads/topic");
            CheckoutBranch("refs/heads/topic");
            // we have the old content again
            CheckFile(theFile, "1\n2\n3\n");
            NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, FILE1).Exists());
            // change third line in topic branch
            WriteTrashFile(FILE1, "1\n2\n3\ntopic\n");
            git.Add().AddFilepattern(FILE1).Call();
            git.Commit().SetMessage("change file1 in topic").Call();
            RebaseResult res = git.Rebase().SetUpstream("refs/heads/master").Call();

            NUnit.Framework.Assert.AreEqual(RebaseResult.Status.OK, res.GetStatus());
            CheckFile(theFile, "1master\n2\n3\ntopic\n");
            // our old branch should be checked out again
            NUnit.Framework.Assert.AreEqual("refs/heads/topic", db.GetFullBranch());
            NUnit.Framework.Assert.AreEqual(lastMasterChange, new RevWalk(db).ParseCommit(db.
                                                                                          Resolve(Constants.HEAD)).GetParent(0));
        }
Пример #6
0
 internal PullResult(FetchResult fetchResult, string fetchedFrom, RebaseResult rebaseResult
                     )
 {
     this.fetchResult  = fetchResult;
     this.fetchedFrom  = fetchedFrom;
     this.mergeResult  = null;
     this.rebaseResult = rebaseResult;
 }
Пример #7
0
 internal PullResult(FetchResult fetchResult, string fetchedFrom, MergeCommandResult
                     mergeResult)
 {
     this.fetchResult  = fetchResult;
     this.fetchedFrom  = fetchedFrom;
     this.mergeResult  = mergeResult;
     this.rebaseResult = null;
 }
Пример #8
0
		internal PullResult(FetchResult fetchResult, string fetchedFrom, RebaseResult rebaseResult
			)
		{
			this.fetchResult = fetchResult;
			this.fetchedFrom = fetchedFrom;
			this.mergeResult = null;
			this.rebaseResult = rebaseResult;
		}
Пример #9
0
		internal PullResult(FetchResult fetchResult, string fetchedFrom, MergeCommandResult
			 mergeResult)
		{
			this.fetchResult = fetchResult;
			this.fetchedFrom = fetchedFrom;
			this.mergeResult = mergeResult;
			this.rebaseResult = null;
		}
Пример #10
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(
                                               ));
        }
Пример #11
0
        public virtual void TestUpToDate()
        {
            // create file1 on master
            WriteTrashFile(FILE1, FILE1);
            git.Add().AddFilepattern(FILE1).Call();
            RevCommit first = git.Commit().SetMessage("Add file1").Call();

            NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, FILE1).Exists());
            RebaseResult res = git.Rebase().SetUpstream(first).Call();

            NUnit.Framework.Assert.AreEqual(RebaseResult.Status.UP_TO_DATE, res.GetStatus());
        }
Пример #12
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
                                                ());
        }
Пример #13
0
        public virtual void TestFilesAddedFromTwoBranches()
        {
            // create file1 on master
            WriteTrashFile(FILE1, FILE1);
            git.Add().AddFilepattern(FILE1).Call();
            RevCommit masterCommit = git.Commit().SetMessage("Add file1 to master").Call();

            // create a branch named file2 and add file2
            CreateBranch(masterCommit, "refs/heads/file2");
            CheckoutBranch("refs/heads/file2");
            WriteTrashFile("file2", "file2");
            git.Add().AddFilepattern("file2").Call();
            RevCommit addFile2 = git.Commit().SetMessage("Add file2 to branch file2").Call();

            // create a branch named file3 and add file3
            CreateBranch(masterCommit, "refs/heads/file3");
            CheckoutBranch("refs/heads/file3");
            WriteTrashFile("file3", "file3");
            git.Add().AddFilepattern("file3").Call();
            git.Commit().SetMessage("Add file3 to branch file3").Call();
            NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, FILE1).Exists());
            NUnit.Framework.Assert.IsFalse(new FilePath(db.WorkTree, "file2").Exists());
            NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "file3").Exists());
            RebaseResult res = git.Rebase().SetUpstream("refs/heads/file2").Call();

            NUnit.Framework.Assert.AreEqual(RebaseResult.Status.OK, res.GetStatus());
            NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, FILE1).Exists());
            NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "file2").Exists());
            NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "file3").Exists());
            // our old branch should be checked out again
            NUnit.Framework.Assert.AreEqual("refs/heads/file3", db.GetFullBranch());
            NUnit.Framework.Assert.AreEqual(addFile2, new RevWalk(db).ParseCommit(db.Resolve(
                                                                                      Constants.HEAD)).GetParent(0));
            CheckoutBranch("refs/heads/file2");
            NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, FILE1).Exists());
            NUnit.Framework.Assert.IsTrue(new FilePath(db.WorkTree, "file2").Exists());
            NUnit.Framework.Assert.IsFalse(new FilePath(db.WorkTree, "file3").Exists());
        }
Пример #14
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());
        }
Пример #15
0
		/// <summary>
		/// Executes the
		/// <code>Pull</code>
		/// command with all the options and parameters
		/// collected by the setter methods (e.g.
		/// <see cref="SetProgressMonitor(NGit.ProgressMonitor)">SetProgressMonitor(NGit.ProgressMonitor)
		/// 	</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 pull</returns>
		/// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">NGit.Api.Errors.WrongRepositoryStateException
		/// 	</exception>
		/// <exception cref="NGit.Api.Errors.InvalidConfigurationException">NGit.Api.Errors.InvalidConfigurationException
		/// 	</exception>
		/// <exception cref="NGit.Api.Errors.DetachedHeadException">NGit.Api.Errors.DetachedHeadException
		/// 	</exception>
		/// <exception cref="NGit.Api.Errors.InvalidRemoteException">NGit.Api.Errors.InvalidRemoteException
		/// 	</exception>
		/// <exception cref="NGit.Api.Errors.CanceledException">NGit.Api.Errors.CanceledException
		/// 	</exception>
		/// <exception cref="NGit.Api.Errors.RefNotFoundException">NGit.Api.Errors.RefNotFoundException
		/// 	</exception>
		/// <exception cref="NGit.Api.Errors.NoHeadException">NGit.Api.Errors.NoHeadException
		/// 	</exception>
		/// <exception cref="NGit.Api.Errors.TransportException">NGit.Api.Errors.TransportException
		/// 	</exception>
		/// <exception cref="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException
		/// 	</exception>
		public override PullResult Call()
		{
			CheckCallable();
			monitor.BeginTask(JGitText.Get().pullTaskName, 2);
			string branchName;
			try
			{
				string fullBranch = repo.GetFullBranch();
				if (fullBranch == null)
				{
					throw new NoHeadException(JGitText.Get().pullOnRepoWithoutHEADCurrentlyNotSupported
						);
				}
				if (!fullBranch.StartsWith(Constants.R_HEADS))
				{
					// we can not pull if HEAD is detached and branch is not
					// specified explicitly
					throw new DetachedHeadException();
				}
				branchName = Sharpen.Runtime.Substring(fullBranch, Constants.R_HEADS.Length);
			}
			catch (IOException e)
			{
				throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfPullCommand
					, e);
			}
			if (!repo.GetRepositoryState().Equals(RepositoryState.SAFE))
			{
				throw new WrongRepositoryStateException(MessageFormat.Format(JGitText.Get().cannotPullOnARepoWithState
					, repo.GetRepositoryState().Name()));
			}
			// get the configured remote for the currently checked out branch
			// stored in configuration key branch.<branch name>.remote
			Config repoConfig = repo.GetConfig();
			string remote = repoConfig.GetString(ConfigConstants.CONFIG_BRANCH_SECTION, branchName
				, ConfigConstants.CONFIG_KEY_REMOTE);
			if (remote == null)
			{
				// fall back to default remote
				remote = Constants.DEFAULT_REMOTE_NAME;
			}
			// get the name of the branch in the remote repository
			// stored in configuration key branch.<branch name>.merge
			string remoteBranchName = repoConfig.GetString(ConfigConstants.CONFIG_BRANCH_SECTION
				, branchName, ConfigConstants.CONFIG_KEY_MERGE);
			// check if the branch is configured for pull-rebase
			bool doRebase = repoConfig.GetBoolean(ConfigConstants.CONFIG_BRANCH_SECTION, branchName
				, ConfigConstants.CONFIG_KEY_REBASE, false);
			if (remoteBranchName == null)
			{
				string missingKey = ConfigConstants.CONFIG_BRANCH_SECTION + DOT + branchName + DOT
					 + ConfigConstants.CONFIG_KEY_MERGE;
				throw new InvalidConfigurationException(MessageFormat.Format(JGitText.Get().missingConfigurationForKey
					, missingKey));
			}
			bool isRemote = !remote.Equals(".");
			string remoteUri;
			FetchResult fetchRes;
			if (isRemote)
			{
				remoteUri = repoConfig.GetString(ConfigConstants.CONFIG_REMOTE_SECTION, remote, ConfigConstants
					.CONFIG_KEY_URL);
				if (remoteUri == null)
				{
					string missingKey = ConfigConstants.CONFIG_REMOTE_SECTION + DOT + remote + DOT + 
						ConfigConstants.CONFIG_KEY_URL;
					throw new InvalidConfigurationException(MessageFormat.Format(JGitText.Get().missingConfigurationForKey
						, missingKey));
				}
				if (monitor.IsCancelled())
				{
					throw new CanceledException(MessageFormat.Format(JGitText.Get().operationCanceled
						, JGitText.Get().pullTaskName));
				}
				FetchCommand fetch = new FetchCommand(repo);
				fetch.SetRemote(remote);
				fetch.SetProgressMonitor(monitor);
				Configure(fetch);
				fetchRes = fetch.Call();
			}
			else
			{
				// we can skip the fetch altogether
				remoteUri = "local repository";
				fetchRes = null;
			}
			monitor.Update(1);
			if (monitor.IsCancelled())
			{
				throw new CanceledException(MessageFormat.Format(JGitText.Get().operationCanceled
					, JGitText.Get().pullTaskName));
			}
			// we check the updates to see which of the updated branches
			// corresponds
			// to the remote branch name
			AnyObjectId commitToMerge;
			if (isRemote)
			{
				Ref r = null;
				if (fetchRes != null)
				{
					r = fetchRes.GetAdvertisedRef(remoteBranchName);
					if (r == null)
					{
						r = fetchRes.GetAdvertisedRef(Constants.R_HEADS + remoteBranchName);
					}
				}
				if (r == null)
				{
					throw new JGitInternalException(MessageFormat.Format(JGitText.Get().couldNotGetAdvertisedRef
						, remoteBranchName));
				}
				else
				{
					commitToMerge = r.GetObjectId();
				}
			}
			else
			{
				try
				{
					commitToMerge = repo.Resolve(remoteBranchName);
					if (commitToMerge == null)
					{
						throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved
							, remoteBranchName));
					}
				}
				catch (IOException e)
				{
					throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfPullCommand
						, e);
				}
			}
			string upstreamName = "branch \'" + Repository.ShortenRefName(remoteBranchName) +
				 "\' of " + remoteUri;
			PullResult result;
			if (doRebase)
			{
				RebaseCommand rebase = new RebaseCommand(repo);
				RebaseResult rebaseRes = rebase.SetUpstream(commitToMerge).SetUpstreamName(upstreamName
					).SetProgressMonitor(monitor).SetOperation(RebaseCommand.Operation.BEGIN).Call();
				result = new PullResult(fetchRes, remote, rebaseRes);
			}
			else
			{
				MergeCommand merge = new MergeCommand(repo);
				merge.Include(upstreamName, commitToMerge);
				MergeCommandResult mergeRes = merge.Call();
				monitor.Update(1);
				result = new PullResult(fetchRes, remote, mergeRes);
			}
			monitor.EndTask();
			return result;
		}
Пример #16
0
		private RebaseResult(RebaseResult.Status status)
		{
			this.mySatus = status;
			currentCommit = null;
		}