示例#1
0
    public void BranchTo(string branchName, string @as = null)
    {
        if (!participants.ContainsKey(branchName))
        {
            diagramBuilder.Append("create ");
            Participant(branchName, @as);
        }

        var branch = Repository.Head.Name;

        diagramBuilder.AppendLineFormat("{0} -> {1}: branch from {2}", GetParticipant(branch), GetParticipant(branchName), branch);
        Repository.CreateBranch(branchName).Checkout();
    }
示例#2
0
        public Branch Create(string branchName)
        {
            var newBranch = _repository.CreateBranch(branchName);

            return(new Branch
            {
                CannonicalName = newBranch.CanonicalName,
                IsRemote = newBranch.IsRemote,
                Name = newBranch.FriendlyName,
                IsHead = newBranch.IsCurrentRepositoryHead,
                Tip = newBranch.Tip.Sha,
                IsTracking = newBranch.IsTracking,
                TrackingDetails = new TrackingDetails(newBranch.TrackedBranch?.CanonicalName, newBranch.TrackingDetails)
            });
        }
示例#3
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);
        }
示例#4
0
 public void Create(string branchName)
 {
     if (string.IsNullOrEmpty(branchName))
     {
         throw new ArgumentNullException(nameof(branchName));
     }
     _repository.CreateBranch(branchName);
 }
示例#5
0
        public Task CreateBranch(IRepository repository, string branchName)
        {
            Guard.ArgumentNotNull(repository, nameof(repository));
            Guard.ArgumentNotEmptyString(branchName, nameof(branchName));

            return(Task.Factory.StartNew(() =>
            {
                repository.CreateBranch(branchName);
            }));
        }
示例#6
0
        /// <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 repository to act on</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(IRepository repository, string committishOrBranchSpec, CheckoutOptions options)
        {
            Ensure.ArgumentNotNull(repository, "repository");
            Ensure.ArgumentNotNullOrEmptyString(committishOrBranchSpec, "committishOrBranchSpec");
            Ensure.ArgumentNotNull(options, "options");

            Reference reference = null;
            GitObject obj       = null;
            Branch    branch    = null;

            try
            {
                repository.RevParse(committishOrBranchSpec, out reference, out obj);
            }
            catch (NotFoundException)
            {
                // If committishOrBranchSpec is not a local branch but matches a tracking branch
                // in exactly one remote, use it. This is the "git checkout" command's default behavior.
                // https://git-scm.com/docs/git-checkout#Documentation/git-checkout.txt-emgitcheckoutemltbranchgt
                var remoteBranches = repository.Network.Remotes
                                     .SelectMany(r => repository.Branches.Where(b =>
                                                                                b.IsRemote &&
                                                                                b.CanonicalName == $"refs/remotes/{r.Name}/{committishOrBranchSpec}"))
                                     .ToList();

                if (remoteBranches.Count == 1)
                {
                    branch = repository.CreateBranch(committishOrBranchSpec, remoteBranches[0].Tip);
                    repository.Branches.Update(branch, b => b.TrackedBranch = remoteBranches[0].CanonicalName);

                    return(Checkout(repository, branch, options));
                }

                if (remoteBranches.Count > 1)
                {
                    throw new AmbiguousSpecificationException($"'{committishOrBranchSpec}' matched multiple ({remoteBranches.Count}) remote tracking branches");
                }

                throw;
            }

            if (reference != null && reference.IsLocalBranch)
            {
                branch = repository.Branches[reference.CanonicalName];
                return(Checkout(repository, branch, options));
            }

            Commit commit = obj.Peel <Commit>(true);

            Checkout(repository, commit.Tree, options, committishOrBranchSpec);

            return(repository.Head);
        }
 private static void CopyRemoteBranchesToHeads(IRepository repository)
 {
     foreach (var branch in repository.Branches)
     {
         if (branch.IsRemote)
         {
             var localName = branch.FriendlyName.Replace($"{branch.RemoteName}/", "");
             if (repository.Branches[localName] == null)
             {
                 repository.CreateBranch(localName, branch.FriendlyName);
             }
         }
     }
 }
示例#8
0
        /// <summary>
        /// Helper method to populate a simple repository with
        /// a single file and two branches.
        /// </summary>
        /// <param name="repo">Repository to populate</param>
        private void PopulateBasicRepository(IRepository repo)
        {
            // Generate a .gitignore file.
            string gitIgnoreFilePath = Touch(repo.Info.WorkingDirectory, ".gitignore", "bin");

            repo.Stage(gitIgnoreFilePath);

            string fullPathFileA = Touch(repo.Info.WorkingDirectory, originalFilePath, originalFileContent);

            repo.Stage(fullPathFileA);

            repo.Commit("Initial commit", Constants.Signature, Constants.Signature);

            repo.CreateBranch(otherBranchName);
        }
示例#9
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);
    }
示例#10
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);
        }
示例#11
0
        /// <summary>
        /// Checkout local branch failed so try and checkout from remote
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="sourceBranch"></param>
        /// <returns></returns>
        private static Branch GetBranchFromRemote(IRepository repository, string sourceBranch)
        {
            var branch = repository.Branches[_origin + "/" + sourceBranch];

            if (branch == null)
            {
                return(null);
            }

            if (!branch.IsRemote)
            {
                return(branch);
            }

            var localBranch = repository.CreateBranch(sourceBranch, branch.Tip);

            repository.Branches.Update(localBranch, b => b.UpstreamBranch = _refsHead + sourceBranch, b => b.Remote = _origin);

            return(Commands.Checkout(repository, sourceBranch));
        }
示例#12
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;
            }
        }
示例#13
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);
                }
            }
        }
示例#14
0
 public void Create(string branchName)
 {
     _repository.CreateBranch(branchName);
 }
示例#15
0
        /// <summary>
        /// Helper method to populate a simple repository with
        /// a single file and two branches.
        /// </summary>
        /// <param name="repo">Repository to populate</param>
        private void PopulateBasicRepository(IRepository repo)
        {
            // Generate a .gitignore file.
            string gitIgnoreFilePath = Touch(repo.Info.WorkingDirectory, ".gitignore", "bin");
            repo.Stage(gitIgnoreFilePath);

            string fullPathFileA = Touch(repo.Info.WorkingDirectory, originalFilePath, originalFileContent);
            repo.Stage(fullPathFileA);

            repo.Commit("Initial commit", Constants.Signature, Constants.Signature);

            repo.CreateBranch(otherBranchName);
        }
示例#16
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);
        }
示例#17
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);
        }