Exemplo n.º 1
0
        /// <summary>checks if we can fast-forward and returns the new head if it is possible
        ///     </summary>
        /// <param name="newCommit"></param>
        /// <returns>the new head, or null</returns>
        /// <exception cref="NGit.Api.Errors.RefNotFoundException">NGit.Api.Errors.RefNotFoundException
        ///     </exception>
        /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
        public virtual RevCommit TryFastForward(RevCommit newCommit)
        {
            Ref head = repo.GetRef(Constants.HEAD);

            if (head == null || head.GetObjectId() == null)
            {
                throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved
                                                                    , Constants.HEAD));
            }
            ObjectId headId = head.GetObjectId();

            if (headId == null)
            {
                throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved
                                                                    , Constants.HEAD));
            }
            RevCommit headCommit = walk.LookupCommit(headId);

            if (walk.IsMergedInto(newCommit, headCommit))
            {
                return(newCommit);
            }
            string headName;

            if (head.IsSymbolic())
            {
                headName = head.GetTarget().GetName();
            }
            else
            {
                headName = "detached HEAD";
            }
            return(TryFastForward(headName, headCommit, newCommit));
        }
Exemplo n.º 2
0
        /// <exception cref="System.IO.IOException"></exception>
        private RefUpdate.Result UpdateImpl(RevWalk walk, RefUpdate.Store store)
        {
            RevObject newObj;
            RevObject oldObj;

            if (GetRefDatabase().IsNameConflicting(GetName()))
            {
                return(RefUpdate.Result.LOCK_FAILURE);
            }
            try
            {
                if (!TryLock(true))
                {
                    return(RefUpdate.Result.LOCK_FAILURE);
                }
                if (expValue != null)
                {
                    ObjectId o;
                    o = oldValue != null ? oldValue : ObjectId.ZeroId;
                    if (!AnyObjectId.Equals(expValue, o))
                    {
                        return(RefUpdate.Result.LOCK_FAILURE);
                    }
                }
                if (oldValue == null)
                {
                    return(store.Execute(RefUpdate.Result.NEW));
                }
                newObj = SafeParse(walk, newValue);
                oldObj = SafeParse(walk, oldValue);
                if (newObj == oldObj && !detachingSymbolicRef)
                {
                    return(store.Execute(RefUpdate.Result.NO_CHANGE));
                }
                if (newObj is RevCommit && oldObj is RevCommit)
                {
                    if (walk.IsMergedInto((RevCommit)oldObj, (RevCommit)newObj))
                    {
                        return(store.Execute(RefUpdate.Result.FAST_FORWARD));
                    }
                }
                if (IsForceUpdate())
                {
                    return(store.Execute(RefUpdate.Result.FORCED));
                }
                return(RefUpdate.Result.REJECTED);
            }
            finally
            {
                Unlock();
            }
        }
 /// <summary>Update the type of this command by checking for fast-forward.</summary>
 /// <remarks>
 /// Update the type of this command by checking for fast-forward.
 /// <p>
 /// If the command's current type is UPDATE, a merge test will be performed
 /// using the supplied RevWalk to determine if
 /// <see cref="GetOldId()">GetOldId()</see>
 /// is fully
 /// merged into
 /// <see cref="GetNewId()">GetNewId()</see>
 /// . If some commits are not merged the
 /// update type is changed to
 /// <see cref="Type.UPDATE_NONFASTFORWARD">Type.UPDATE_NONFASTFORWARD</see>
 /// .
 /// </remarks>
 /// <param name="walk">
 /// an instance to perform the merge test with. The caller must
 /// allocate and release this object.
 /// </param>
 /// <exception cref="System.IO.IOException">
 /// either oldId or newId is not accessible in the repository
 /// used by the RevWalk. This usually indicates data corruption,
 /// and the command cannot be processed.
 /// </exception>
 public virtual void UpdateType(RevWalk walk)
 {
     if (typeIsCorrect)
     {
         return;
     }
     if (type == ReceiveCommand.Type.UPDATE && !AnyObjectId.Equals(oldId, newId))
     {
         RevObject o = walk.ParseAny(oldId);
         RevObject n = walk.ParseAny(newId);
         if (!(o is RevCommit) || !(n is RevCommit) || !walk.IsMergedInto((RevCommit)o, (RevCommit
                                                                                         )n))
         {
             SetType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
         }
     }
     typeIsCorrect = true;
 }
Exemplo n.º 4
0
		/// <summary>Update the type of this command by checking for fast-forward.</summary>
		/// <remarks>
		/// Update the type of this command by checking for fast-forward.
		/// <p>
		/// If the command's current type is UPDATE, a merge test will be performed
		/// using the supplied RevWalk to determine if
		/// <see cref="GetOldId()">GetOldId()</see>
		/// is fully
		/// merged into
		/// <see cref="GetNewId()">GetNewId()</see>
		/// . If some commits are not merged the
		/// update type is changed to
		/// <see cref="Type.UPDATE_NONFASTFORWARD">Type.UPDATE_NONFASTFORWARD</see>
		/// .
		/// </remarks>
		/// <param name="walk">
		/// an instance to perform the merge test with. The caller must
		/// allocate and release this object.
		/// </param>
		/// <exception cref="System.IO.IOException">
		/// either oldId or newId is not accessible in the repository
		/// used by the RevWalk. This usually indicates data corruption,
		/// and the command cannot be processed.
		/// </exception>
		public virtual void UpdateType(RevWalk walk)
		{
			if (typeIsCorrect)
			{
				return;
			}
			if (type == ReceiveCommand.Type.UPDATE && !AnyObjectId.Equals(oldId, newId))
			{
				RevObject o = walk.ParseAny(oldId);
				RevObject n = walk.ParseAny(newId);
				if (!(o is RevCommit) || !(n is RevCommit) || !walk.IsMergedInto((RevCommit)o, (RevCommit
					)n))
				{
					SetType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
				}
			}
			typeIsCorrect = true;
		}
Exemplo n.º 5
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);
		}
Exemplo n.º 6
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>
        /// <exception cref="NGit.Api.Errors.CannotDeleteCurrentBranchException">NGit.Api.Errors.CannotDeleteCurrentBranchException
        ///     </exception>
        /// <returns>the list with the (full) names of the deleted branches</returns>
        /// <exception cref="NGit.Api.Errors.GitAPIException"></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);
            }
        }
Exemplo n.º 7
0
		/// <exception cref="System.IO.IOException"></exception>
		private RefUpdate.Result UpdateImpl(RevWalk walk, RefUpdate.Store store)
		{
			RevObject newObj;
			RevObject oldObj;
			if (GetRefDatabase().IsNameConflicting(GetName()))
			{
				return RefUpdate.Result.LOCK_FAILURE;
			}
			try
			{
				if (!TryLock(true))
				{
					return RefUpdate.Result.LOCK_FAILURE;
				}
				if (expValue != null)
				{
					ObjectId o;
					o = oldValue != null ? oldValue : ObjectId.ZeroId;
					if (!AnyObjectId.Equals(expValue, o))
					{
						return RefUpdate.Result.LOCK_FAILURE;
					}
				}
				if (oldValue == null)
				{
					return store.Execute(RefUpdate.Result.NEW);
				}
				newObj = SafeParse(walk, newValue);
				oldObj = SafeParse(walk, oldValue);
				if (newObj == oldObj && !detachingSymbolicRef)
				{
					return store.Execute(RefUpdate.Result.NO_CHANGE);
				}
				if (newObj is RevCommit && oldObj is RevCommit)
				{
					if (walk.IsMergedInto((RevCommit)oldObj, (RevCommit)newObj))
					{
						return store.Execute(RefUpdate.Result.FAST_FORWARD);
					}
				}
				if (IsForceUpdate())
				{
					return store.Execute(RefUpdate.Result.FORCED);
				}
				return RefUpdate.Result.REJECTED;
			}
			finally
			{
				Unlock();
			}
		}
Exemplo n.º 8
0
        /// <summary>
        /// Executes the
        /// <code>Merge</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 merge</returns>
        /// <exception cref="NGit.Api.Errors.NoHeadException"></exception>
        /// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException"></exception>
        /// <exception cref="NGit.Api.Errors.CheckoutConflictException"></exception>
        /// <exception cref="NGit.Api.Errors.InvalidMergeHeadsException"></exception>
        /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException"></exception>
        /// <exception cref="NGit.Api.Errors.NoMessageException"></exception>
        public override MergeCommandResult Call()
        {
            CheckCallable();
            if (commits.Count != 1)
            {
                throw new InvalidMergeHeadsException(commits.IsEmpty() ? JGitText.Get().noMergeHeadSpecified
                                         : MessageFormat.Format(JGitText.Get().mergeStrategyDoesNotSupportHeads, mergeStrategy
                                                                .GetName(), Sharpen.Extensions.ValueOf(commits.Count)));
            }
            RevWalk revWalk = null;

            try
            {
                Ref head = repo.GetRef(Constants.HEAD);
                if (head == null)
                {
                    throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported
                                              );
                }
                StringBuilder refLogMessage = new StringBuilder("merge ");
                // Check for FAST_FORWARD, ALREADY_UP_TO_DATE
                revWalk = new RevWalk(repo);
                // we know for now there is only one commit
                Ref @ref = commits[0];
                refLogMessage.Append(@ref.GetName());
                // handle annotated tags
                ObjectId objectId = @ref.GetPeeledObjectId();
                if (objectId == null)
                {
                    objectId = @ref.GetObjectId();
                }
                RevCommit srcCommit = revWalk.LookupCommit(objectId);
                ObjectId  headId    = head.GetObjectId();
                if (headId == null)
                {
                    revWalk.ParseHeaders(srcCommit);
                    DirCacheCheckout dco = new DirCacheCheckout(repo, repo.LockDirCache(), srcCommit.
                                                                Tree);
                    dco.SetFailOnConflict(true);
                    dco.Checkout();
                    RefUpdate refUpdate = repo.UpdateRef(head.GetTarget().GetName());
                    refUpdate.SetNewObjectId(objectId);
                    refUpdate.SetExpectedOldObjectId(null);
                    refUpdate.SetRefLogMessage("initial pull", false);
                    if (refUpdate.Update() != RefUpdate.Result.NEW)
                    {
                        throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported
                                                  );
                    }
                    SetCallable(false);
                    return(new MergeCommandResult(srcCommit, srcCommit, new ObjectId[] { null, srcCommit }, MergeStatus.FAST_FORWARD, mergeStrategy, null, null));
                }
                RevCommit headCommit = revWalk.LookupCommit(headId);
                if (revWalk.IsMergedInto(srcCommit, headCommit))
                {
                    SetCallable(false);
                    return(new MergeCommandResult(headCommit, srcCommit, new ObjectId[] { headCommit,
                                                                                          srcCommit }, MergeStatus.ALREADY_UP_TO_DATE, mergeStrategy, null, null));
                }
                else
                {
                    if (revWalk.IsMergedInto(headCommit, srcCommit))
                    {
                        // FAST_FORWARD detected: skip doing a real merge but only
                        // update HEAD
                        refLogMessage.Append(": " + MergeStatus.FAST_FORWARD);
                        DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache
                                                                        (), srcCommit.Tree);
                        dco.SetFailOnConflict(true);
                        dco.Checkout();
                        UpdateHead(refLogMessage, srcCommit, headId);
                        SetCallable(false);
                        return(new MergeCommandResult(srcCommit, srcCommit, new ObjectId[] { headCommit,
                                                                                             srcCommit }, MergeStatus.FAST_FORWARD, mergeStrategy, null, null));
                    }
                    else
                    {
                        repo.WriteMergeCommitMsg(new MergeMessageFormatter().Format(commits, head));
                        repo.WriteMergeHeads(Arrays.AsList(@ref.GetObjectId()));
                        ThreeWayMerger merger = (ThreeWayMerger)mergeStrategy.NewMerger(repo);
                        bool           noProblems;
                        IDictionary <string, MergeResult <NGit.Diff.Sequence> > lowLevelResults = null;
                        IDictionary <string, ResolveMerger.MergeFailureReason>  failingPaths    = null;
                        if (merger is ResolveMerger)
                        {
                            ResolveMerger resolveMerger = (ResolveMerger)merger;
                            resolveMerger.SetCommitNames(new string[] { "BASE", "HEAD", @ref.GetName() });
                            resolveMerger.SetWorkingTreeIterator(new FileTreeIterator(repo));
                            noProblems      = merger.Merge(headCommit, srcCommit);
                            lowLevelResults = resolveMerger.GetMergeResults();
                            failingPaths    = resolveMerger.GetFailingPaths();
                        }
                        else
                        {
                            noProblems = merger.Merge(headCommit, srcCommit);
                        }
                        if (noProblems)
                        {
                            DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache
                                                                            (), merger.GetResultTreeId());
                            dco.SetFailOnConflict(true);
                            dco.Checkout();
                            RevCommit newHead = new Git(GetRepository()).Commit().Call();
                            return(new MergeCommandResult(newHead.Id, null, new ObjectId[] { headCommit.Id, srcCommit
                                                                                             .Id }, MergeStatus.MERGED, mergeStrategy, null, null));
                        }
                        else
                        {
                            if (failingPaths != null)
                            {
                                repo.WriteMergeCommitMsg(null);
                                repo.WriteMergeHeads(null);
                                return(new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId[] {
                                    headCommit.Id, srcCommit.Id
                                }, MergeStatus.FAILED, mergeStrategy, lowLevelResults
                                                              , null));
                            }
                            else
                            {
                                return(new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId[] {
                                    headCommit.Id, srcCommit.Id
                                }, MergeStatus.CONFLICTING, mergeStrategy, lowLevelResults
                                                              , null));
                            }
                        }
                    }
                }
            }
            catch (IOException e)
            {
                throw new JGitInternalException(MessageFormat.Format(JGitText.Get().exceptionCaughtDuringExecutionOfMergeCommand
                                                                     , e), e);
            }
            finally
            {
                if (revWalk != null)
                {
                    revWalk.Release();
                }
            }
        }
Exemplo n.º 9
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
Exemplo n.º 10
0
        /// <exception cref="NGit.Errors.TransportException"></exception>
        private IDictionary <string, RemoteRefUpdate> PrepareRemoteUpdates()
        {
            IDictionary <string, RemoteRefUpdate> result = new Dictionary <string, RemoteRefUpdate
                                                                           >();

            foreach (RemoteRefUpdate rru in toPush.Values)
            {
                Ref      advertisedRef = connection.GetRef(rru.GetRemoteName());
                ObjectId advertisedOld = (advertisedRef == null ? ObjectId.ZeroId : advertisedRef
                                          .GetObjectId());
                if (rru.GetNewObjectId().Equals(advertisedOld))
                {
                    if (rru.IsDelete())
                    {
                        // ref does exist neither locally nor remotely
                        rru.SetStatus(RemoteRefUpdate.Status.NON_EXISTING);
                    }
                    else
                    {
                        // same object - nothing to do
                        rru.SetStatus(RemoteRefUpdate.Status.UP_TO_DATE);
                    }
                    continue;
                }
                // caller has explicitly specified expected old object id, while it
                // has been changed in the mean time - reject
                if (rru.IsExpectingOldObjectId() && !rru.GetExpectedOldObjectId().Equals(advertisedOld
                                                                                         ))
                {
                    rru.SetStatus(RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED);
                    continue;
                }
                // create ref (hasn't existed on remote side) and delete ref
                // are always fast-forward commands, feasible at this level
                if (advertisedOld.Equals(ObjectId.ZeroId) || rru.IsDelete())
                {
                    rru.SetFastForward(true);
                    result.Put(rru.GetRemoteName(), rru);
                    continue;
                }
                // check for fast-forward:
                // - both old and new ref must point to commits, AND
                // - both of them must be known for us, exist in repository, AND
                // - old commit must be ancestor of new commit
                bool fastForward = true;
                try
                {
                    RevObject oldRev = walker.ParseAny(advertisedOld);
                    RevObject newRev = walker.ParseAny(rru.GetNewObjectId());
                    if (!(oldRev is RevCommit) || !(newRev is RevCommit) || !walker.IsMergedInto((RevCommit
                                                                                                  )oldRev, (RevCommit)newRev))
                    {
                        fastForward = false;
                    }
                }
                catch (MissingObjectException)
                {
                    fastForward = false;
                }
                catch (Exception x)
                {
                    throw new TransportException(transport.GetURI(), MessageFormat.Format(JGitText.Get
                                                                                              ().readingObjectsFromLocalRepositoryFailed, x.Message), x);
                }
                rru.SetFastForward(fastForward);
                if (!fastForward && !rru.IsForceUpdate())
                {
                    rru.SetStatus(RemoteRefUpdate.Status.REJECTED_NONFASTFORWARD);
                }
                else
                {
                    result.Put(rru.GetRemoteName(), rru);
                }
            }
            return(result);
        }
Exemplo n.º 11
0
        /// <exception cref="NGit.Api.Errors.RefNotFoundException"></exception>
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="NGit.Api.Errors.NoHeadException"></exception>
        /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception>
        private RebaseResult InitFilesAndRewind()
        {
            // we need to store everything into files so that we can implement
            // --skip, --continue, and --abort
            Ref head = repo.GetRef(Constants.HEAD);

            if (head == null || head.GetObjectId() == null)
            {
                throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved
                                                                    , Constants.HEAD));
            }
            string headName;

            if (head.IsSymbolic())
            {
                headName = head.GetTarget().GetName();
            }
            else
            {
                headName = "detached HEAD";
            }
            ObjectId headId = head.GetObjectId();

            if (headId == null)
            {
                throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved
                                                                    , Constants.HEAD));
            }
            RevCommit headCommit = walk.LookupCommit(headId);
            RevCommit upstream   = walk.LookupCommit(upstreamCommit.Id);

            if (walk.IsMergedInto(upstream, headCommit))
            {
                return(RebaseResult.UP_TO_DATE_RESULT);
            }
            else
            {
                if (walk.IsMergedInto(headCommit, upstream))
                {
                    // head is already merged into upstream, fast-foward
                    monitor.BeginTask(MessageFormat.Format(JGitText.Get().resettingHead, upstreamCommit
                                                           .GetShortMessage()), ProgressMonitor.UNKNOWN);
                    CheckoutCommit(upstreamCommit);
                    monitor.EndTask();
                    UpdateHead(headName, upstreamCommit);
                    return(RebaseResult.FAST_FORWARD_RESULT);
                }
            }
            monitor.BeginTask(JGitText.Get().obtainingCommitsForCherryPick, ProgressMonitor.UNKNOWN
                              );
            // determine the commits to be applied
            LogCommand           cmd            = new Git(repo).Log().AddRange(upstreamCommit, headCommit);
            Iterable <RevCommit> commitsToUse   = cmd.Call();
            IList <RevCommit>    cherryPickList = new AList <RevCommit>();

            foreach (RevCommit commit in commitsToUse)
            {
                if (commit.ParentCount != 1)
                {
                    throw new JGitInternalException(JGitText.Get().canOnlyCherryPickCommitsWithOneParent
                                                    );
                }
                cherryPickList.AddItem(commit);
            }
            Sharpen.Collections.Reverse(cherryPickList);
            // create the folder for the meta information
            FileUtils.Mkdir(rebaseDir);
            CreateFile(repo.Directory, Constants.ORIG_HEAD, headId.Name);
            CreateFile(rebaseDir, REBASE_HEAD, headId.Name);
            CreateFile(rebaseDir, HEAD_NAME, headName);
            CreateFile(rebaseDir, ONTO, upstreamCommit.Name);
            CreateFile(rebaseDir, INTERACTIVE, string.Empty);
            BufferedWriter fw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream
                                                                              (new FilePath(rebaseDir, GIT_REBASE_TODO)), Constants.CHARACTER_ENCODING));

            fw.Write("# Created by EGit: rebasing " + upstreamCommit.Name + " onto " + headId
                     .Name);
            fw.NewLine();
            try
            {
                StringBuilder sb     = new StringBuilder();
                ObjectReader  reader = walk.GetObjectReader();
                foreach (RevCommit commit_1 in cherryPickList)
                {
                    sb.Length = 0;
                    sb.Append(RebaseCommand.Action.PICK.ToToken());
                    sb.Append(" ");
                    sb.Append(reader.Abbreviate(commit_1).Name);
                    sb.Append(" ");
                    sb.Append(commit_1.GetShortMessage());
                    fw.Write(sb.ToString());
                    fw.NewLine();
                }
            }
            finally
            {
                fw.Close();
            }
            monitor.EndTask();
            // we rewind to the upstream commit
            monitor.BeginTask(MessageFormat.Format(JGitText.Get().rewinding, upstreamCommit.GetShortMessage
                                                       ()), ProgressMonitor.UNKNOWN);
            bool checkoutOk = false;

            try
            {
                checkoutOk = CheckoutCommit(upstreamCommit);
            }
            finally
            {
                if (!checkoutOk)
                {
                    FileUtils.Delete(rebaseDir, FileUtils.RECURSIVE);
                }
            }
            monitor.EndTask();
            return(null);
        }