Пример #1
0
        public static Branch SwitchToTargetBranch(this IRepository repository, CherryPickConfig config)
        {
            GetLocalAndRemoteBranch(repository, config.TargetBranch, config.TargetBranchRemote, out var targetBranch, out var targetBranchRemote);

            if (targetBranch == null && targetBranchRemote != null)
            {
                targetBranch = repository.CreateBranch(config.TargetBranch, targetBranchRemote.Tip);
            }

            if (targetBranch is null)
            {
                throw new InvalidOperationException(string.Format("Branch {0} not found", config.TargetBranch));
            }

            // Checkout target branch
            repository.Checkout(targetBranch);

            if (config.SyncTargetBranch && targetBranchRemote != null)
            {
                try
                {
                    // And try pull with fast forward from remote
                    repository.Merge(
                        targetBranchRemote,
                        repository.Config.BuildSignature(DateTimeOffset.Now),
                        new MergeOptions {
                        FastForwardStrategy = FastForwardStrategy.FastForwardOnly
                    });
                }
                catch (NonFastForwardException) { }
            }

            return(targetBranch);
        }
Пример #2
0
    public static Branch CreatePullRequest(this IRepository repository, string from, string to, int prNumber = 2, bool isRemotePr = true)
    {
        repository.Checkout(to);
        repository.MergeNoFF(from);
        repository.CreateBranch("pull/" + prNumber + "/merge").Checkout();
        repository.Checkout(to);
        repository.Reset(ResetMode.Hard, "HEAD~1");
        var pullBranch = repository.Checkout("pull/" + prNumber + "/merge");

        if (isRemotePr)
        {
            // If we delete the branch, it is effectively the same as remote PR
            repository.Branches.Remove(from);
        }

        return(pullBranch);
    }
Пример #3
0
        public Task Checkout(IRepository repository, string branchName)
        {
            Guard.ArgumentNotEmptyString(branchName, nameof(branchName));

            return(Task.Factory.StartNew(() =>
            {
                repository.Checkout(branchName);
            }));
        }
Пример #4
0
        public Task Checkout(IRepository repository, string branchName)
        {
            Guard.ArgumentNotNull(repository, nameof(repository));
            Guard.ArgumentNotEmptyString(branchName, nameof(branchName));

            return(Task.Factory.StartNew(() =>
            {
#pragma warning disable 0618 // TODO: Replace `IRepository.Checkout` with `Commands.Checkout`.
                repository.Checkout(branchName);
#pragma warning restore 0618
            }));
        }
Пример #5
0
    public static Commit CreatePullRequestRef(this IRepository repository, string from, string to, int prNumber = 2, bool normalise = false, bool allowFastFowardMerge = false)
    {
        repository.Checkout(repository.FindBranch(to).Tip);
        if (allowFastFowardMerge)
        {
            repository.Merge(repository.FindBranch(from), Constants.SignatureNow());
        }
        else
        {
            repository.MergeNoFF(from);
        }
        var commit = repository.Head.Tip;

        repository.Refs.Add("refs/pull/" + prNumber + "/merge", commit.Id);
        repository.Checkout(to);
        if (normalise)
        {
            // Turn the ref into a real branch
            repository.Checkout(repository.Branches.Add("pull/" + prNumber + "/merge", commit));
        }

        return(commit);
    }
Пример #6
0
        public void Merge(string sourceBranch, string destinationBranch)
        {
            _repo.Checkout(_repo.Branches[destinationBranch]);

            var oldHeadCommit = _repo.Head.Tip;
            var signature     = GetSignature();
            var result        = _repo.Merge(_repo.Branches[sourceBranch], signature);

            switch (result.Status)
            {
            case MergeStatus.Conflicts:
                //abort the merge by resetting to the state prior to the merge
                _repo.Reset(ResetMode.Hard, oldHeadCommit);
                break;

            case MergeStatus.NonFastForward:
                //https://help.github.com/articles/dealing-with-non-fast-forward-errors/
                Pull();
                Merge(sourceBranch, destinationBranch);     //a little leary about this. Could stack overflow if I'm wrong.
                break;
            }

            Refresh();
        }
Пример #7
0
        private static void FeedTheRepository(IRepository repo)
        {
            string fullPath = Touch(repo.Info.WorkingDirectory, "a.txt", "Hello\n");

            repo.Index.Stage(fullPath);
            repo.Commit("Initial commit", Constants.Signature, Constants.Signature);
            repo.ApplyTag("mytag");

            File.AppendAllText(fullPath, "World\n");
            repo.Index.Stage(fullPath);

            Signature shiftedSignature = Constants.Signature.TimeShift(TimeSpan.FromMinutes(1));

            repo.Commit("Update file", shiftedSignature, shiftedSignature);
            repo.CreateBranch("mybranch");

            repo.Checkout("mybranch");

            Assert.False(repo.Index.RetrieveStatus().IsDirty);
        }
Пример #8
0
        private void CherryPickCommits(IRepository repo, ShallowCommit[] commits, string branchName)
        {
            this.logger.Log("Zipping branch " + branchName + "...");
            ShallowCommit previous = null;

            for (int i = 0; i < commits.Length; i++)
            {
                var original = commits[i];
                this.logger.Log((100 * (i + 1) / commits.Length) + "% Zipping commit " + original.Sha, replace: true);

                if (commitMap.ContainsKey(original.Sha))
                {
                    if (repo.Branches[branchName] == null)
                    {
                        previous = commitMap[original.Sha];
                    }
                    else
                    {
                        // FIXME This should ideally be done by rearranging the history
                        this.logger.Log("... cherry-picked");
                        previous = CherryPickCommit(repo, original);
                    }
                    continue;
                }


                if (repo.Branches[branchName] == null)
                {
                    repo.Checkout(repo.CreateBranch(branchName, (previous ?? original).Sha));

                    if (previous == null)
                    {
                        commitMap[original.Sha] = original;
                        continue;
                    }
                }

                previous = CherryPickCommit(repo, original);
                commitMap[original.Sha] = previous;
            }
        }
Пример #9
0
        static void CreateFakeBranchPointingAtThePullRequestTip(IRepository repo)
        {
            var remote     = repo.Network.Remotes.Single();
            var remoteTips = repo.Network.ListReferences(remote);

            var headTipSha = repo.Head.Tip.Sha;

            var refs = remoteTips.Where(r => r.TargetIdentifier == headTipSha).ToList();

            if (refs.Count == 0)
            {
                var message = string.Format("Couldn't find any remote tips from remote '{0}' pointing at the commit '{1}'.", remote.Url, headTipSha);
                throw new Exception(message);
            }

            if (refs.Count > 1)
            {
                var names   = string.Join(", ", refs.Select(r => r.CanonicalName));
                var message = string.Format("Found more than one remote tip from remote '{0}' pointing at the commit '{1}'. Unable to determine which one to use ({2}).", remote.Url, headTipSha, names);
                throw new Exception(message);
            }

            var canonicalName = refs[0].CanonicalName;

            if (!canonicalName.StartsWith("refs/pull/") && !canonicalName.StartsWith("refs/pull-requests/"))
            {
                var message = string.Format("Remote tip '{0}' from remote '{1}' doesn't look like a valid pull request.", canonicalName, remote.Url);
                throw new Exception(message);
            }

            var fakeBranchName = canonicalName
                                 .Replace("refs/pull/", "refs/heads/pull/")
                                 .Replace("refs/pull-requests/", "refs/heads/pull-requests/");

            repo.Refs.Add(fakeBranchName, new ObjectId(headTipSha));

            Console.WriteLine("Checking out {0}", fakeBranchName);
            repo.Checkout(fakeBranchName);
        }
Пример #10
0
        void Commit(IRepository repository, IEnumerable <StatusEntry> entries, string title = "Commit", bool reportProgress = false)
        {
            if (entries.Any() || Amend)
            {
                var dialog = new CommitDialog(title);

                if (Amend)
                {
                    dialog.Message = repository.Commits.FirstOrDefault()?.Message;
                }

                if (mainThread.Invoke(() => dialog.ShowDialog()) == true)
                {
                    if (!string.IsNullOrEmpty(dialog.NewBranchName))
                    {
                        repository.Checkout(repository.CreateBranch(dialog.NewBranchName));
                    }

                    foreach (var entry in entries)
                    {
                        repository.Stage(entry.FilePath);
                    }

                    var signature = repository.Config.BuildSignature(DateTimeOffset.Now);

                    var options = new CommitOptions
                    {
                        AmendPreviousCommit = Amend
                    };

                    eventStream.Push <Status>(0.5f);

                    repository.Commit(dialog.Message, signature, signature, options);
                }
            }
        }
Пример #11
0
 public void Checkout(string branch)
 {
     Repository.Checkout(branch);
 }
Пример #12
0
 /// <summary>
 /// Checkout the specified <see cref="LibGit2Sharp.Commit"/>.
 /// <para>
 ///   Will detach the HEAD and make it point to this commit sha.
 /// </para>
 /// </summary>
 /// <param name="repository">The <see cref="Repository"/> being worked with.</param>
 /// <param name="commit">The <see cref="LibGit2Sharp.Commit"/> to check out.</param>
 /// <returns>The <see cref="Branch"/> that was checked out.</returns>
 public static Branch Checkout(this IRepository repository, Commit commit)
 {
     return(repository.Checkout(commit, CheckoutModifiers.None, null, null));
 }
Пример #13
0
 /// <summary>
 /// Checkout the commit pointed at by the tip of the specified <see cref="Branch"/>.
 /// <para>
 ///   If this commit is the current tip of the branch as it exists in the repository, the HEAD
 ///   will point to this branch. Otherwise, the HEAD will be detached, pointing at the commit sha.
 /// </para>
 /// </summary>
 /// <param name="repository">The <see cref="Repository"/> being worked with.</param>
 /// <param name="branch">The <see cref="Branch"/> to check out.</param>
 /// <returns>The <see cref="Branch"/> that was checked out.</returns>
 public static Branch Checkout(this IRepository repository, Branch branch)
 {
     return(repository.Checkout(branch, CheckoutModifiers.None, null, null));
 }
Пример #14
0
 /// <summary>
 /// Checkout the specified <see cref="Branch"/>, reference or SHA.
 /// </summary>
 /// <param name="repository">The <see cref="Repository"/> being worked with.</param>
 /// <param name="commitOrBranchSpec">A revparse spec for the commit or branch to checkout.</param>
 /// <returns>The <see cref="Branch"/> that was checked out.</returns>
 public static Branch Checkout(this IRepository repository, string commitOrBranchSpec)
 {
     return(repository.Checkout(commitOrBranchSpec, CheckoutModifiers.None, null, null));
 }
Пример #15
0
        /// <summary>
        /// Internal implementation of Checkout that expects the ID of the checkout target
        /// to already be in the form of a canonical branch name or a commit ID.
        /// </summary>
        /// <param name="repository">The repository to act on</param>
        /// <param name="tree">The <see cref="Tree"/> to checkout.</param>
        /// <param name="checkoutOptions"><see cref="CheckoutOptions"/> controlling checkout behavior.</param>
        /// <param name="refLogHeadSpec">The spec which will be written as target in the reflog.</param>
        public static void Checkout(IRepository repository, Tree tree, CheckoutOptions checkoutOptions, string refLogHeadSpec)
        {
            repository.Checkout(tree, null, checkoutOptions);

            repository.Refs.MoveHeadTarget(refLogHeadSpec);
        }
Пример #16
0
 public void Checkout(Tree tree, IEnumerable <string> paths, CheckoutOptions opts) =>
 repository.Checkout(tree, paths, opts);
 /// <summary>
 /// Checkout the tip commit of the specified <see cref="Branch"/> object. If this commit is the
 /// current tip of the branch, will checkout the named branch. Otherwise, will checkout the tip commit
 /// as a detached HEAD.
 /// </summary>
 /// <param name="repository">The <see cref="IRepository"/> being worked with.</param>
 /// <param name="branch">The <see cref="Branch"/> to check out.</param>
 /// <param name="options"><see cref="CheckoutOptions"/> controlling checkout behavior.</param>
 /// <returns>The <see cref="Branch"/> that was checked out.</returns>
 public static Branch Checkout(this IRepository repository, Branch branch, CheckoutOptions options)
 {
     return(repository.Checkout(branch, options, null));
 }
        /// <summary>
        /// Checkout the specified <see cref="LibGit2Sharp.Commit"/>.
        /// <para>
        ///   Will detach the HEAD and make it point to this commit sha.
        /// </para>
        /// </summary>
        /// <param name="repository">The <see cref="Repository"/> being worked with.</param>
        /// <param name="commit">The <see cref="LibGit2Sharp.Commit"/> to check out.</param>
        /// <param name="signature">The identity used for updating the reflog</param>
        /// <returns>The <see cref="Branch"/> that was checked out.</returns>
        public static Branch Checkout(this IRepository repository, Commit commit, Signature signature = null)
        {
            CheckoutOptions options = new CheckoutOptions();

            return(repository.Checkout(commit, options, signature));
        }
Пример #19
0
        /// <summary>
        /// Internal implementation of Checkout that expects the ID of the checkout target
        /// to already be in the form of a canonical branch name or a commit ID.
        /// </summary>
        /// <param name="repository">The repository to act on</param>
        /// <param name="tree">The <see cref="Tree"/> to checkout.</param>
        /// <param name="checkoutOptions"><see cref="CheckoutOptions"/> controlling checkout behavior.</param>
        /// <param name="refLogHeadSpec">The spec which will be written as target in the reflog.</param>
        public static void Checkout(IRepository repository, Tree tree, CheckoutOptions checkoutOptions, string refLogHeadSpec)
        {
            repository.Checkout(tree, null, checkoutOptions);

            repository.Refs.MoveHeadTarget(refLogHeadSpec);
        }
        /// <summary>
        /// Checkout the specified <see cref="LibGit2Sharp.Commit"/>.
        /// <para>
        ///   Will detach the HEAD and make it point to this commit sha.
        /// </para>
        /// </summary>
        /// <param name="repository">The <see cref="Repository"/> being worked with.</param>
        /// <param name="commit">The <see cref="LibGit2Sharp.Commit"/> to check out.</param>
        /// <returns>The <see cref="Branch"/> that was checked out.</returns>
        public static Branch Checkout(this IRepository repository, Commit commit)
        {
            CheckoutOptions options = new CheckoutOptions();

            return(repository.Checkout(commit, options));
        }
        /// <summary>
        /// Checkout the commit pointed at by the tip of the specified <see cref="Branch"/>.
        /// <para>
        ///   If this commit is the current tip of the branch as it exists in the repository, the HEAD
        ///   will point to this branch. Otherwise, the HEAD will be detached, pointing at the commit sha.
        /// </para>
        /// </summary>
        /// <param name="repository">The <see cref="Repository"/> being worked with.</param>
        /// <param name="branch">The <see cref="Branch"/> to check out.</param>
        /// <returns>The <see cref="Branch"/> that was checked out.</returns>
        public static Branch Checkout(this IRepository repository, Branch branch)
        {
            CheckoutOptions options = new CheckoutOptions();

            return(repository.Checkout(branch, options));
        }
        /// <summary>
        /// Checkout the specified <see cref="Branch"/>, reference or SHA.
        /// </summary>
        /// <param name="repository">The <see cref="Repository"/> being worked with.</param>
        /// <param name="commitOrBranchSpec">A revparse spec for the commit or branch to checkout.</param>
        /// <returns>The <see cref="Branch"/> that was checked out.</returns>
        public static Branch Checkout(this IRepository repository, string commitOrBranchSpec)
        {
            CheckoutOptions options = new CheckoutOptions();

            return(repository.Checkout(commitOrBranchSpec, options));
        }
Пример #23
0
        public Task ExecuteAsync(object?parameter = null, CancellationToken cancellation = default)
        {
            var dialog = new SwitchDialog(branches: repository.Branches.Select(x => x.FriendlyName).OrderBy(x => x).ToArray());

            if (mainThread.Invoke(() => dialog.ShowDialog()) == true && !string.IsNullOrEmpty(dialog.Branch))
            {
                var branch = repository.Branches.FirstOrDefault(x => x.FriendlyName == dialog.Branch);

                var targetBranch          = branch;
                var targetBranchName      = dialog.Branch;
                var overwriteTargetBranch = false;

                // Check if the selected branch is remote
                if (branch?.IsRemote == true)
                {
                    // Get the branch name from the remote
                    targetBranchName = branch.GetName();

                    // Allow the user to create a branch for the remote
                    var createBranchDialog = new InputBox("Create Branch", "Branch")
                    {
                        Text = targetBranchName
                    };
                    if (mainThread.Invoke(() => createBranchDialog.ShowDialog()) == true)
                    {
                        // Check if the new branch already exists
                        targetBranchName = createBranchDialog.Text;
                        targetBranch     = repository.Branches.FirstOrDefault(x =>
                                                                              !x.IsRemote && x.FriendlyName == createBranchDialog.Text);

                        if (targetBranch != null)
                        {
                            // The branch already exist => ask the user to overwrite it
                            var forceDialog = new MessageBox(
                                "Warning",
                                DialogBoxButton.Ok | DialogBoxButton.Cancel,
                                "A branch with this name already exists. Do you want to overwrite it?");

                            overwriteTargetBranch = mainThread.Invoke(() => forceDialog.ShowDialog() == true);
                            if (!overwriteTargetBranch)
                            {
                                return(CancelCheckout());
                            }
                        }
                    }
                    else
                    {
                        return(CancelCheckout());
                    }
                }

                // 1. Check the remote branch if remote was selected
                if (branch?.IsRemote == true)
                {
                    repository.Checkout(branch);
                }

                // 2. Remove the existing branch if the user decided to overwrite it
                if (overwriteTargetBranch && targetBranch != null)
                {
                    eventStream.Push(Status.Create(0.2f, "Removing branch {0}", targetBranch.FriendlyName));
                    repository.Branches.Remove(targetBranch);
                }

                // 3. Create the branch if it does not exist
                if (targetBranch == null)
                {
                    eventStream.Push(Status.Create(0.4f, "Creating branch {0}", targetBranchName));
                    targetBranch = repository.CreateBranch(targetBranchName);
                }

                // 4. Checkout the branch
                eventStream.Push(Status.Create(0.6f, "Swithing to branch {0}", targetBranchName));
                repository.Checkout(targetBranch);

                // 5. Update submodules
                if (dialog.UpdateSubmodules)
                {
                    eventStream.Push(Status.Create(0.8f, "Updating submodules..."));
                    repository.UpdateSubmodules(eventStream: eventStream);
                }

                eventStream.Push(new BranchChanged(targetBranchName));
                eventStream.Push(Status.Succeeded());
            }

            return(Task.CompletedTask);
        }
 /// <summary>
 /// Checkout the specified <see cref="LibGit2Sharp.Commit"/>.
 /// <para>
 ///   Will detach the HEAD and make it point to this commit sha.
 /// </para>
 /// </summary>
 /// <param name="repository">The <see cref="IRepository"/> being worked with.</param>
 /// <param name="commit">The <see cref="LibGit2Sharp.Commit"/> to check out.</param>
 /// <param name="options"><see cref="CheckoutOptions"/> controlling checkout behavior.</param>
 /// <returns>The <see cref="Branch"/> that was checked out.</returns>
 public static Branch Checkout(this IRepository repository, Commit commit, CheckoutOptions options)
 {
     return(repository.Checkout(commit, options, null));
 }
 /// <summary>
 /// Checkout the specified <see cref="Branch"/>, reference or SHA.
 /// <para>
 ///   If the committishOrBranchSpec parameter resolves to a branch name, then the checked out HEAD will
 ///   will point to the branch. Otherwise, the HEAD will be detached, pointing at the commit sha.
 /// </para>
 /// </summary>
 /// <param name="repository">The <see cref="IRepository"/> being worked with.</param>
 /// <param name="committishOrBranchSpec">A revparse spec for the commit or branch to checkout.</param>
 /// <param name="options"><see cref="CheckoutOptions"/> controlling checkout behavior.</param>
 /// <returns>The <see cref="Branch"/> that was checked out.</returns>
 public static Branch Checkout(this IRepository repository, string committishOrBranchSpec, CheckoutOptions options)
 {
     return(repository.Checkout(committishOrBranchSpec, options, null));
 }
 static void CheckoutCommit(IRepository repo, string targetCommit)
 {
     Log.Info(string.Format("Checking out {0}", targetCommit));
     repo.Checkout(targetCommit);
 }
Пример #27
0
        private static void FeedTheRepository(IRepository repo)
        {
            string fullPath = Touch(repo.Info.WorkingDirectory, "a.txt", "Hello\n");
            repo.Stage(fullPath);
            repo.Commit("Initial commit", Constants.Signature, Constants.Signature);
            repo.ApplyTag("mytag");

            File.AppendAllText(fullPath, "World\n");
            repo.Stage(fullPath);

            Signature shiftedSignature = Constants.Signature.TimeShift(TimeSpan.FromMinutes(1));
            repo.Commit("Update file", shiftedSignature, shiftedSignature);
            repo.CreateBranch("mybranch");

            repo.Checkout("mybranch");

            Assert.False(repo.RetrieveStatus().IsDirty);
        }