Пример #1
0
        /// <exception cref="Sharpen.URISyntaxException"></exception>
        /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception>
        /// <exception cref="NGit.Api.Errors.InvalidRemoteException"></exception>
        /// <exception cref="System.IO.IOException"></exception>
        private FetchResult Fetch(Repository repo, URIish u)
        {
            // create the remote config and save it
            RemoteConfig config = new RemoteConfig(repo.GetConfig(), remote);

            config.AddURI(u);
            string  dst     = bare ? Constants.R_HEADS : Constants.R_REMOTES + config.Name;
            RefSpec refSpec = new RefSpec();

            refSpec = refSpec.SetForceUpdate(true);
            refSpec = refSpec.SetSourceDestination(Constants.R_HEADS + "*", dst + "/*");
            //$NON-NLS-1$ //$NON-NLS-2$
            config.AddFetchRefSpec(refSpec);
            config.Update(repo.GetConfig());
            repo.GetConfig().Save();
            // run the fetch command
            FetchCommand command = new FetchCommand(repo);

            command.SetRemote(remote);
            command.SetProgressMonitor(monitor);
            command.SetTagOpt(TagOpt.FETCH_TAGS);
            command.SetTimeout(timeout);
            if (credentialsProvider != null)
            {
                command.SetCredentialsProvider(credentialsProvider);
            }
            IList <RefSpec> specs = CalculateRefSpecs(dst);

            command.SetRefSpecs(specs);
            return(command.Call());
        }
Пример #2
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"></exception>
        /// <exception cref="NGit.Api.Errors.InvalidConfigurationException"></exception>
        /// <exception cref="NGit.Api.Errors.DetachedHeadException"></exception>
        /// <exception cref="NGit.Api.Errors.InvalidRemoteException"></exception>
        /// <exception cref="NGit.Api.Errors.CanceledException"></exception>
        /// <exception cref="NGit.Api.Errors.RefNotFoundException"></exception>
        public override PullResult Call()
        {
            CheckCallable();
            monitor.BeginTask(JGitText.Get().pullTaskName, 2);
            string branchName;

            try
            {
                string fullBranch = repo.GetFullBranch();
                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("remote", 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);
                fetch.SetTimeout(this.timeout);
                fetch.SetCredentialsProvider(credentialsProvider);
                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);
                }
            }
            PullResult result;

            if (doRebase)
            {
                RebaseCommand rebase = new RebaseCommand(repo);
                try
                {
                    RebaseResult rebaseRes = rebase.SetUpstream(commitToMerge).SetProgressMonitor(monitor
                                                                                                  ).SetOperation(RebaseCommand.Operation.BEGIN).Call();
                    result = new PullResult(fetchRes, remote, rebaseRes);
                }
                catch (NoHeadException e)
                {
                    throw new JGitInternalException(e.Message, e);
                }
                catch (RefNotFoundException e)
                {
                    throw new JGitInternalException(e.Message, e);
                }
                catch (JGitInternalException e)
                {
                    throw new JGitInternalException(e.Message, e);
                }
                catch (GitAPIException e)
                {
                    throw new JGitInternalException(e.Message, e);
                }
            }
            else
            {
                MergeCommand merge = new MergeCommand(repo);
                merge.Include("branch \'" + remoteBranchName + "\' of " + remoteUri, commitToMerge
                              );
                MergeCommandResult mergeRes;
                try
                {
                    mergeRes = merge.Call();
                    monitor.Update(1);
                    result = new PullResult(fetchRes, remote, mergeRes);
                }
                catch (NoHeadException e)
                {
                    throw new JGitInternalException(e.Message, e);
                }
                catch (ConcurrentRefUpdateException e)
                {
                    throw new JGitInternalException(e.Message, e);
                }
                catch (NGit.Api.Errors.CheckoutConflictException e)
                {
                    throw new JGitInternalException(e.Message, e);
                }
                catch (InvalidMergeHeadsException e)
                {
                    throw new JGitInternalException(e.Message, e);
                }
                catch (WrongRepositoryStateException e)
                {
                    throw new JGitInternalException(e.Message, e);
                }
                catch (NoMessageException e)
                {
                    throw new JGitInternalException(e.Message, e);
                }
            }
            monitor.EndTask();
            return(result);
        }