示例#1
0
        public virtual void TestMultipleHeads()
        {
            Git git = new Git(db);

            WriteTrashFile("file1", "file1");
            git.Add().AddFilepattern("file1").Call();
            RevCommit first = git.Commit().SetMessage("initial commit").Call();

            CreateBranch(first, "refs/heads/branch1");
            WriteTrashFile("file2", "file2");
            git.Add().AddFilepattern("file2").Call();
            RevCommit second = git.Commit().SetMessage("second commit").Call();

            WriteTrashFile("file3", "file3");
            git.Add().AddFilepattern("file3").Call();
            git.Commit().SetMessage("third commit").Call();
            CheckoutBranch("refs/heads/branch1");
            NUnit.Framework.Assert.IsFalse(new FilePath(db.WorkTree, "file2").Exists());
            NUnit.Framework.Assert.IsFalse(new FilePath(db.WorkTree, "file3").Exists());
            MergeCommand merge = git.Merge();

            merge.Include(second.Id);
            merge.Include(db.GetRef(Constants.MASTER));
            try
            {
                merge.Call();
                NUnit.Framework.Assert.Fail("Expected exception not thrown when merging multiple heads"
                                            );
            }
            catch (InvalidMergeHeadsException)
            {
            }
        }
示例#2
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);
     }
 }
示例#3
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;
		}