Exemple #1
0
 /// <exception cref="NGit.Errors.TransportException"></exception>
 protected internal override void DoFetch(ProgressMonitor monitor, ICollection <Ref
                                                                                > want, ICollection <ObjectId> have)
 {
     MarkLocalRefsComplete(have);
     QueueWants(want);
     while (!monitor.IsCancelled() && !workQueue.IsEmpty())
     {
         ObjectId id = workQueue.RemoveFirst();
         if (!(id is RevObject) || !((RevObject)id).Has(COMPLETE))
         {
             DownloadObject(monitor, id);
         }
         Process(id);
     }
 }
 /// <exception cref="System.IO.IOException"></exception>
 public override void Write(byte[] b, int off, int len)
 {
     while (0 < len)
     {
         int n = Math.Min(len, BYTES_TO_WRITE_BEFORE_CANCEL_CHECK);
         count += n;
         if (checkCancelAt <= count)
         {
             if (writeMonitor.IsCancelled())
             {
                 throw new IOException(JGitText.Get().packingCancelledDuringObjectsWriting);
             }
             checkCancelAt = count + BYTES_TO_WRITE_BEFORE_CANCEL_CHECK;
         }
         @out.Write(b, off, n);
         crc.Update(b, off, n);
         md.Update(b, off, n);
         off += n;
         len -= n;
     }
 }
Exemple #3
0
        /// <exception cref="System.IO.IOException"></exception>
        private void WriteCommands(ICollection <RemoteRefUpdate> refUpdates, ProgressMonitor
                                   monitor)
        {
            string capabilities = EnableCapabilities(monitor);

            foreach (RemoteRefUpdate rru in refUpdates)
            {
                if (!capableDeleteRefs && rru.IsDelete())
                {
                    rru.SetStatus(RemoteRefUpdate.Status.REJECTED_NODELETE);
                    continue;
                }
                StringBuilder sb            = new StringBuilder();
                Ref           advertisedRef = GetRef(rru.GetRemoteName());
                ObjectId      oldId         = (advertisedRef == null ? ObjectId.ZeroId : advertisedRef.GetObjectId
                                                   ());
                sb.Append(oldId.Name);
                sb.Append(' ');
                sb.Append(rru.GetNewObjectId().Name);
                sb.Append(' ');
                sb.Append(rru.GetRemoteName());
                if (!sentCommand)
                {
                    sentCommand = true;
                    sb.Append(capabilities);
                }
                pckOut.WriteString(sb.ToString());
                rru.SetStatus(RemoteRefUpdate.Status.AWAITING_REPORT);
                if (!rru.IsDelete())
                {
                    writePack = true;
                }
            }
            if (monitor.IsCancelled())
            {
                throw new TransportException(uri, JGitText.Get().pushCancelled);
            }
            pckOut.End();
            outNeedsEnd = false;
        }
Exemple #4
0
        /// <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.NoHeadException"></exception>
        /// <exception cref="NGit.Api.Errors.RefNotFoundException"></exception>
        /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception>
        /// <exception cref="NGit.Api.Errors.GitAPIException"></exception>
        public override RebaseResult Call()
        {
            RevCommit newHead            = null;
            bool      lastStepWasForward = false;

            CheckCallable();
            CheckParameters();
            try
            {
                switch (operation)
                {
                case RebaseCommand.Operation.ABORT:
                {
                    try
                    {
                        return(Abort());
                    }
                    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());
                }
                if (this.operation == RebaseCommand.Operation.CONTINUE)
                {
                    newHead = ContinueRebase();
                }
                if (this.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));
                    }
                    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
                        newHead = new Git(repo).CherryPick().Include(commitToPick).Call();
                    }
                    monitor.EndTask();
                    if (newHead == null)
                    {
                        return(Stop(commitToPick));
                    }
                }
                if (newHead != null)
                {
                    // point the previous head (if any) to the new commit
                    string headName = ReadFile(rebaseDir, HEAD_NAME);
                    if (headName.StartsWith(Constants.R_REFS))
                    {
                        RefUpdate rup = repo.UpdateRef(headName);
                        rup.SetNewObjectId(newHead);
                        RefUpdate.Result res_1 = rup.ForceUpdate();
                        switch (res_1)
                        {
                        case RefUpdate.Result.FAST_FORWARD:
                        case RefUpdate.Result.FORCED:
                        case RefUpdate.Result.NO_CHANGE:
                        {
                            break;
                        }

                        default:
                        {
                            throw new JGitInternalException("Updating HEAD failed");
                        }
                        }
                        rup   = repo.UpdateRef(Constants.HEAD);
                        res_1 = rup.Link(headName);
                        switch (res_1)
                        {
                        case RefUpdate.Result.FAST_FORWARD:
                        case RefUpdate.Result.FORCED:
                        case RefUpdate.Result.NO_CHANGE:
                        {
                            break;
                        }

                        default:
                        {
                            throw new JGitInternalException("Updating HEAD failed");
                        }
                        }
                    }
                    FileUtils.Delete(rebaseDir, FileUtils.RECURSIVE);
                    if (lastStepWasForward)
                    {
                        return(new RebaseResult(RebaseResult.Status.FAST_FORWARD));
                    }
                    return(new RebaseResult(RebaseResult.Status.OK));
                }
                return(new RebaseResult(RebaseResult.Status.UP_TO_DATE));
            }
            catch (IOException ioe)
            {
                throw new JGitInternalException(ioe.Message, ioe);
            }
        }
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="NGit.Transport.BasePackFetchConnection.CancelledException"></exception>
        private void Negotiate(ProgressMonitor monitor)
        {
            MutableObjectId ackId                  = new MutableObjectId();
            int             resultsPending         = 0;
            int             havesSent              = 0;
            int             havesSinceLastContinue = 0;
            bool            receivedContinue       = false;
            bool            receivedAck            = false;
            bool            receivedReady          = false;

            if (statelessRPC)
            {
                state.WriteTo(@out, null);
            }
            NegotiateBegin();
            while (!receivedReady)
            {
                RevCommit c = walk.Next();
                if (c == null)
                {
                    goto SEND_HAVES_break;
                }
                pckOut.WriteString("have " + c.Id.Name + "\n");
                havesSent++;
                havesSinceLastContinue++;
                if ((31 & havesSent) != 0)
                {
                    // We group the have lines into blocks of 32, each marked
                    // with a flush (aka end). This one is within a block so
                    // continue with another have line.
                    //
                    continue;
                }
                if (monitor.IsCancelled())
                {
                    throw new BasePackFetchConnection.CancelledException();
                }
                pckOut.End();
                resultsPending++;
                // Each end will cause a result to come back.
                if (havesSent == 32 && !statelessRPC)
                {
                    // On the first block we race ahead and try to send
                    // more of the second block while waiting for the
                    // remote to respond to our first block request.
                    // This keeps us one block ahead of the peer.
                    //
                    continue;
                }
                for (; ;)
                {
                    PacketLineIn.AckNackResult anr = pckIn.ReadACK(ackId);
                    switch (anr)
                    {
                    case PacketLineIn.AckNackResult.NAK:
                    {
                        // More have lines are necessary to compute the
                        // pack on the remote side. Keep doing that.
                        //
                        resultsPending--;
                        goto READ_RESULT_break;
                    }

                    case PacketLineIn.AckNackResult.ACK:
                    {
                        // The remote side is happy and knows exactly what
                        // to send us. There is no further negotiation and
                        // we can break out immediately.
                        //
                        multiAck       = BasePackFetchConnection.MultiAck.OFF;
                        resultsPending = 0;
                        receivedAck    = true;
                        if (statelessRPC)
                        {
                            state.WriteTo(@out, null);
                        }
                        goto SEND_HAVES_break;
                    }

                    case PacketLineIn.AckNackResult.ACK_CONTINUE:
                    case PacketLineIn.AckNackResult.ACK_COMMON:
                    case PacketLineIn.AckNackResult.ACK_READY:
                    {
                        // The server knows this commit (ackId). We don't
                        // need to send any further along its ancestry, but
                        // we need to continue to talk about other parts of
                        // our local history.
                        //
                        MarkCommon(walk.ParseAny(ackId), anr);
                        receivedAck            = true;
                        receivedContinue       = true;
                        havesSinceLastContinue = 0;
                        if (anr == PacketLineIn.AckNackResult.ACK_READY)
                        {
                            receivedReady = true;
                        }
                        break;
                    }
                    }
                    if (monitor.IsCancelled())
                    {
                        throw new BasePackFetchConnection.CancelledException();
                    }
                    READ_RESULT_continue :;
                }
                READ_RESULT_break :;
                if (statelessRPC)
                {
                    state.WriteTo(@out, null);
                }
                if (receivedContinue && havesSinceLastContinue > MAX_HAVES)
                {
                    // Our history must be really different from the remote's.
                    // We just sent a whole slew of have lines, and it did not
                    // recognize any of them. Avoid sending our entire history
                    // to them by giving up early.
                    //
                    goto SEND_HAVES_break;
                }
                SEND_HAVES_continue :;
            }
            SEND_HAVES_break :;
            // Tell the remote side we have run out of things to talk about.
            //
            if (monitor.IsCancelled())
            {
                throw new BasePackFetchConnection.CancelledException();
            }
            if (!receivedReady || !noDone)
            {
                // When statelessRPC is true we should always leave SEND_HAVES
                // loop above while in the middle of a request. This allows us
                // to just write done immediately.
                //
                pckOut.WriteString("done\n");
                pckOut.Flush();
            }
            if (!receivedAck)
            {
                // Apparently if we have never received an ACK earlier
                // there is one more result expected from the done we
                // just sent to the remote.
                //
                multiAck = BasePackFetchConnection.MultiAck.OFF;
                resultsPending++;
            }
            while (resultsPending > 0 || multiAck != BasePackFetchConnection.MultiAck.OFF)
            {
                PacketLineIn.AckNackResult anr = pckIn.ReadACK(ackId);
                resultsPending--;
                switch (anr)
                {
                case PacketLineIn.AckNackResult.NAK:
                {
                    // A NAK is a response to an end we queued earlier
                    // we eat it and look for another ACK/NAK message.
                    //
                    break;
                }

                case PacketLineIn.AckNackResult.ACK:
                {
                    // A solitary ACK at this point means the remote won't
                    // speak anymore, but is going to send us a pack now.
                    //
                    goto READ_RESULT_break2;
                }

                case PacketLineIn.AckNackResult.ACK_CONTINUE:
                case PacketLineIn.AckNackResult.ACK_COMMON:
                case PacketLineIn.AckNackResult.ACK_READY:
                {
                    // We will expect a normal ACK to break out of the loop.
                    //
                    multiAck = BasePackFetchConnection.MultiAck.CONTINUE;
                    break;
                }
                }
                if (monitor.IsCancelled())
                {
                    throw new BasePackFetchConnection.CancelledException();
                }
                READ_RESULT_continue :;
            }
            READ_RESULT_break2 :;
        }
Exemple #6
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;
		}
Exemple #7
0
        /// <exception cref="NGit.Errors.TransportException"></exception>
        private bool DownloadPackedObject(ProgressMonitor monitor, AnyObjectId id)
        {
            // Search for the object in a remote pack whose index we have,
            // but whose pack we do not yet have.
            //
            Iterator <WalkFetchConnection.RemotePack> packItr = unfetchedPacks.Iterator();

            while (packItr.HasNext() && !monitor.IsCancelled())
            {
                WalkFetchConnection.RemotePack pack = packItr.Next();
                try
                {
                    pack.OpenIndex(monitor);
                }
                catch (IOException err)
                {
                    // If the index won't open its either not found or
                    // its a format we don't recognize. In either case
                    // we may still be able to obtain the object from
                    // another source, so don't consider it a failure.
                    //
                    RecordError(id, err);
                    packItr.Remove();
                    continue;
                }
                if (monitor.IsCancelled())
                {
                    // If we were cancelled while the index was opening
                    // the open may have aborted. We can't search an
                    // unopen index.
                    //
                    return(false);
                }
                if (!pack.index.HasObject(id))
                {
                    // Not in this pack? Try another.
                    //
                    continue;
                }
                // It should be in the associated pack. Download that
                // and attach it to the local repository so we can use
                // all of the contained objects.
                //
                try
                {
                    pack.DownloadPack(monitor);
                }
                catch (IOException err)
                {
                    // If the pack failed to download, index correctly,
                    // or open in the local repository we may still be
                    // able to obtain this object from another pack or
                    // an alternate.
                    //
                    RecordError(id, err);
                    continue;
                }
                finally
                {
                    // If the pack was good its in the local repository
                    // and Repository.hasObject(id) will succeed in the
                    // future, so we do not need this data anymore. If
                    // it failed the index and pack are unusable and we
                    // shouldn't consult them again.
                    //
                    try
                    {
                        if (pack.tmpIdx != null)
                        {
                            FileUtils.Delete(pack.tmpIdx);
                        }
                    }
                    catch (IOException e)
                    {
                        throw new TransportException(e.Message, e);
                    }
                    packItr.Remove();
                }
                if (!AlreadyHave(id))
                {
                    // What the hell? This pack claimed to have
                    // the object, but after indexing we didn't
                    // actually find it in the pack.
                    //
                    RecordError(id, new FileNotFoundException(MessageFormat.Format(JGitText.Get().objectNotFoundIn
                                                                                   , id.Name, pack.packName)));
                    continue;
                }
                // Complete any other objects that we can.
                //
                Iterator <ObjectId> pending = SwapFetchQueue();
                while (pending.HasNext())
                {
                    ObjectId p = pending.Next();
                    if (pack.index.HasObject(p))
                    {
                        pending.Remove();
                        Process(p);
                    }
                    else
                    {
                        workQueue.AddItem(p);
                    }
                }
                return(true);
            }
            return(false);
        }
Exemple #8
0
 /// <exception cref="System.IO.IOException"></exception>
 internal virtual void OpenIndex(ProgressMonitor pm)
 {
     if (this.index != null)
     {
         return;
     }
     if (this.tmpIdx == null)
     {
         this.tmpIdx = FilePath.CreateTempFile("jgit-walk-", ".idx");
     }
     else
     {
         if (this.tmpIdx.IsFile())
         {
             try
             {
                 this.index = PackIndex.Open(this.tmpIdx);
                 return;
             }
             catch (FileNotFoundException)
             {
             }
         }
     }
     // Fall through and get the file.
     WalkRemoteObjectDatabase.FileStream s;
     s = this.connection.Open("pack/" + this.idxName);
     pm.BeginTask("Get " + Sharpen.Runtime.Substring(this.idxName, 0, 12) + "..idx", s
                  .length < 0 ? ProgressMonitor.UNKNOWN : (int)(s.length / 1024));
     try
     {
         FileOutputStream fos = new FileOutputStream(this.tmpIdx);
         try
         {
             byte[] buf = new byte[2048];
             int    cnt;
             while (!pm.IsCancelled() && (cnt = [email protected](buf)) >= 0)
             {
                 fos.Write(buf, 0, cnt);
                 pm.Update(cnt / 1024);
             }
         }
         finally
         {
             fos.Close();
         }
     }
     catch (IOException err)
     {
         FileUtils.Delete(this.tmpIdx);
         throw;
     }
     finally
     {
         [email protected]();
     }
     pm.EndTask();
     if (pm.IsCancelled())
     {
         FileUtils.Delete(this.tmpIdx);
         return;
     }
     try
     {
         this.index = PackIndex.Open(this.tmpIdx);
     }
     catch (IOException e)
     {
         FileUtils.Delete(this.tmpIdx);
         throw;
     }
 }
Exemple #9
0
        /// <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.NoHeadException"></exception>
        /// <exception cref="NGit.Api.Errors.RefNotFoundException"></exception>
        /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception>
        /// <exception cref="NGit.Api.Errors.GitAPIException"></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 (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);
            }
        }