public async Task CheckAsync(Repository repository)
        {
            Log.Debug("Checking branch tips ...");
            var branches = await gitBranchService.GetBranchesAsync(CancellationToken.None);

            if (branches.IsFaulted)
            {
                return;
            }

            IReadOnlyDictionary <CommitSha, string> commitIds = GetSingleBranchTipCommits(repository, branches.Value);

            foreach (var pair in commitIds)
            {
                BranchName branchName = pair.Value;
                if (branchName.StartsWith(Origin))
                {
                    branchName = branchName.Substring(Origin.Length);
                }

                await gitCommitBranchNameService.SetCommitBranchNameAsync(pair.Key, branchName);
            }

            if (gitSettings.IsRemoteDisabled)
            {
                Log.Info("IsRemoteDisabled = true");
                return;
            }

            await gitCommitBranchNameService.PushNotesAsync(repository.RootCommit.RealCommitSha);
        }
        private async Task <R> MergeAsync(BranchName branchName)
        {
            Log.Debug($"Merge branch {branchName} into current branch ...");

            R <IReadOnlyList <GitBranch> > branches = await gitBranchService.GetBranchesAsync(CancellationToken.None);

            if (branches.IsFaulted)
            {
                return(R.Error("Failed to merge", branches.Exception));
            }

            // Trying to get both local and remote branch
            branches.Value.TryGet(branchName, out GitBranch localbranch);
            branches.Value.TryGet($"origin/{branchName}", out GitBranch remoteBranch);

            GitBranch branch = localbranch ?? remoteBranch;

            if (localbranch != null && remoteBranch != null)
            {
                // Both local and remote tip exists, use the branch with the most resent tip
                R <GitCommit> localTipCommit = await gitCommitService.GetCommitAsync(localbranch.TipSha.Sha, CancellationToken.None);

                R <GitCommit> remoteTipCommit = await gitCommitService.GetCommitAsync(remoteBranch.TipSha.Sha, CancellationToken.None);

                if (localTipCommit.IsFaulted || remoteTipCommit.IsFaulted)
                {
                    return(R.Error("Failed to merge", remoteTipCommit.Exception));
                }

                if (remoteTipCommit.Value.CommitDate > localTipCommit.Value.CommitDate)
                {
                    branch = remoteBranch;
                }
            }

            if (branch == null)
            {
                return(R.Error($"Failed to Merge, not valid branch {branchName}"));
            }


            return(await gitMergeService.MergeAsync(branch.Name, CancellationToken.None));
        }
        private async Task UpdateRepositoryAsync(MRepository repository, GitStatus status, IReadOnlyList <string> repoIds)
        {
            Log.Debug("Updating repository");
            Timing t = new Timing();
            //string gitRepositoryPath = repository.WorkingFolder;

            var branchesResult = await gitBranchService.GetBranchesAsync(CancellationToken.None);

            if (branchesResult.IsFaulted)
            {
                Log.Warn($"Failed to update repo, {branchesResult}");
                return;
            }

            IReadOnlyList <GitBranch> branches = branchesResult.Value;

            repository.Status = status ?? await statusService.GetStatusAsync();

            t.Log("Got status");

            repository.RepositoryIds = repoIds ?? await statusService.GetRepoIdsAsync();

            t.Log("Got repo ids");

            CleanRepositoryOfTempData(repository);
            t.Log("CleanRepositoryOfTempData");

            await commitsService.AddNewCommitsAsync(repository);

            t.Log("Added new commits");

            commitsService.AddBranchCommits(branches, repository);
            t.Log($"Added {repository.Commits.Count} commits referenced by active branches");

            //if (!repository.Commits.Any())
            //{
            //	Log.Debug("No branches, no commits");
            //	return;
            //}

            await tagService.CopyTagsAsync(repository);

            t.Log("CopyTags");

            branchService.AddActiveBranches(branches, repository);
            t.Log("AddActiveBranches");

            await SetSpecifiedCommitBranchNamesAsync(repository);

            t.Log("SetSpecifiedCommitBranchNames");

            commitBranchNameService.SetMasterBranchCommits(repository);
            t.Log("SetMasterBranchCommits");

            branchService.AddInactiveBranches(repository);
            t.Log("AddInactiveBranches");

            commitBranchNameService.SetBranchTipCommitsNames(repository);
            t.Log("SetBranchTipCommitsNames");

            commitBranchNameService.SetNeighborCommitNames(repository);
            t.Log("SetNeighborCommitNames");

            branchService.AddMissingInactiveBranches(repository);
            t.Log("AddMissingInactiveBranches");

            branchService.AddMultiBranches(repository);
            t.Log("AddMultiBranches");

            branchHierarchyService.SetBranchHierarchy(repository);
            t.Log("SetBranchHierarchy");

            SetCurrentBranchAndCommit(repository, branches);
            t.Log("SetCurrentBranchAndCommit");

            repository.SubBranches.Clear();
            t.Log("Clear sub branches");


            t.Log("Done");
        }