Exemple #1
0
        private void SetActiveBranchCommits(MRepository repository)
        {
            IEnumerable <MSubBranch> branches = repository.SubBranches.Values
                                                .Where(b =>
                                                       b.TipCommit.BranchId == null &&
                                                       b.IsActive);

            foreach (MSubBranch branch in branches)
            {
                MCommit branchTip = branch.TipCommit;

                MCommit last = TryFindFirstAncestorWithSameName(branchTip, branch.Name);

                if (last == null)
                {
                    // Could not find first ancestor commit with branch name
                    continue;
                }

                foreach (MCommit current in branchTip.CommitAndFirstAncestors())
                {
                    current.SetBranchName(branch.Name);
                    current.SubBranchId = branch.SubBranchId;

                    if (current == last)
                    {
                        break;
                    }
                }
            }
        }
Exemple #2
0
        private static void SetBranchCommitsOfParents(MRepository repository)
        {
            bool found;

            do
            {
                found = false;
                foreach (var commit in repository.Commits.Values)
                {
                    if (commit.BranchId == null && !commit.HasBranchName && commit.HasFirstChild)
                    {
                        MCommit firstChild = commit.FirstChildren.ElementAt(0);
                        if (firstChild.HasBranchName)
                        {
                            if (commit.FirstChildren.All(c => c.BranchName == firstChild.BranchName))
                            {
                                commit.SetBranchName(firstChild.BranchName);
                                commit.SubBranchId = firstChild.SubBranchId;
                                found = true;
                            }
                        }
                    }
                }
            } while (found);
        }
Exemple #3
0
        private static void SetMasterBranchCommits(MRepository repository, MSubBranch subBranch)
        {
            CommitId commitId = subBranch.TipCommitId;

            while (commitId != CommitId.None)
            {
                MCommit commit = repository.Commits[commitId];

                if (commit.BranchName == subBranch.Name && commit.SubBranchId != null)
                {
                    // Do not break if commit is the tip
                    if (!(commit.Id == subBranch.TipCommitId && commit.SubBranchId == subBranch.SubBranchId))
                    {
                        break;
                    }
                }

                if (commit.HasBranchName && commit.BranchName != subBranch.Name)
                {
                    Log.Warn($"commit {commit} already has branch {commit.BranchName} != {subBranch.Name}");
                    break;
                }

                commit.SetBranchName(subBranch.Name);
                commit.SubBranchId = subBranch.SubBranchId;
                commitId           = commit.FirstParentId;
            }
        }
        private static void AddEmptyBranchesVirtualTipCommits(MRepository repository)
        {
            IEnumerable <MBranch> emptyBranches = repository.Branches.Values
                                                  .Where(b => !b.Commits.Any() && !b.IsLocalPart);

            foreach (MBranch branch in emptyBranches)
            {
                string virtualShaText = (Guid.NewGuid() + Guid.NewGuid().ToString()).Replace("-", "")
                                        .Substring(0, 40);
                CommitSha virtualSha = new CommitSha(virtualShaText);
                CommitId  virtualId  = new CommitId(virtualShaText);

                MCommit commit = AddVirtualCommit(repository, virtualId);


                commit.IsVirtual = true;
                commit.BranchId  = branch.Id;
                commit.SetBranchName(branch.Name);
                CopyToVirtualCommit(repository, branch, commit, virtualSha);
                SetChildOfParents(commit);

                //repository.Commits[commit.Id] = commit;

                branch.CommitIds.Add(commit.Id);
                branch.TipCommitId   = commit.Id;
                branch.FirstCommitId = commit.Id;

                branch.TipCommit.BranchTips = $"{branch.Name} branch tip";
            }
        }
Exemple #5
0
        private MCommit TryFindFirstAncestorWithSameName(MCommit startCommit, BranchName branchName)
        {
            foreach (MCommit commit in startCommit.CommitAndFirstAncestors())
            {
                BranchName commitBranchName = GetBranchName(commit);

                if (commitBranchName != null)
                {
                    if (commitBranchName == branchName)
                    {
                        // Found an ancestor, which has branch name we are searching fore
                        return(commit);
                    }
                    else
                    {
                        // Fond an ancestor with another different name
                        break;
                    }
                }

                if (commit != startCommit &&
                    commit.BranchTipBranches.Count == 1 && commit.BranchTipBranches[0].Name == branchName)
                {
                    // Found a commit with a branch tip of a branch with same name,
                    // this can happen for local/remote pairs. Lets assume the commit is the on that branch
                    return(commit);
                }
            }

            // Could not find an ancestor with the branch name we a searching for
            return(null);
        }
        private static int CompareCommitsDescending(MCommit c1, MCommit c2)
        {
            if (c1 == c2)
            {
                return(0);
            }

            if (c1.CommitDate < c2.CommitDate)
            {
                return(1);
            }
            else if (c1.CommitDate > c2.CommitDate)
            {
                return(-1);
            }
            else
            {
                if (c2.Parents.Any(c => c.Id == c1.Id))
                {
                    return(1);
                }
                else if (c1.Parents.Any(c => c.Id == c2.Id))
                {
                    return(-1);
                }

                return(0);
            }
        }
        private static void SetParentCommitId(MRepository repository)
        {
            foreach (var subBranch in repository.SubBranches.Values)
            {
                MCommit tipCommit = subBranch.TipCommit;
                if (tipCommit.BranchId != null)
                {
                    if (tipCommit.BranchName == subBranch.Name)
                    {
                        subBranch.ParentCommitId = repository.Branches[tipCommit.BranchId].ParentCommitId;
                    }
                    else
                    {
                        // This is a branch with no commits
                        subBranch.ParentCommitId = tipCommit.Id;
                    }
                }
                else
                {
                    IEnumerable <MCommit> commits = subBranch.TipCommit.CommitAndFirstAncestors()
                                                    .TakeWhile(c => c.BranchName == subBranch.Name);

                    bool    foundParent   = false;
                    MCommit currentcommit = null;
                    foreach (MCommit commit in commits)
                    {
                        if (commit.BranchId != null)
                        {
                            subBranch.ParentCommitId = repository.Branches[commit.BranchId].ParentCommitId;
                            foundParent = true;
                            break;
                        }

                        currentcommit = commit;
                    }

                    if (!foundParent)
                    {
                        if (currentcommit != null)
                        {
                            // Sub branch has at least one commit
                            MCommit firstCommit = currentcommit;

                            subBranch.ParentCommitId = firstCommit.FirstParentId;
                        }
                        else
                        {
                            // Sub branch has no commits of its own, setting parent commit to same as branch tip
                            subBranch.ParentCommitId = tipCommit.Id;
                        }
                    }
                }
            }
        }
Exemple #8
0
        public IEnumerable <MCommit> FirstAncestors()
        {
            MCommit current = FirstParent;

            while (current != null)
            {
                yield return(current);

                current = current.FirstParent;
            }
        }
Exemple #9
0
        private MCommit AddNewCommit(CommitId commitId)
        {
            MCommit commit = new MCommit()
            {
                Repository = this,
                Id         = commitId,
            };

            Commits[commitId] = commit;

            return(commit);
        }
Exemple #10
0
        private void AddCommit(MCommit commit, GitCommit gitCommit)
        {
            //string subject = gitCommit.Subject;
            string tickets = "";             // GetTickets(subject);

            commit.Tickets = tickets;

            // Pre-create all parents
            commit.ParentIds.ForEach(pid => commit.Repository.Commit(pid));

            SetChildOfParents(commit);
            commit.IsSet = true;
        }
        private static MCommit AddVirtualCommit(
            MRepository repository,
            CommitId virtualId)
        {
            MCommit commit = new MCommit()
            {
                Repository = repository,
                Id         = virtualId,
            };

            repository.Commits[virtualId] = commit;

            return(commit);
        }
        private async Task SetSpecifiedCommitBranchNamesAsync(MRepository repository)
        {
            MCommit rootCommit = GetRootCommit(repository);

            repository.RootCommitId = rootCommit.RealCommitId;

            IReadOnlyList <CommitBranchName> gitSpecifiedNames = await gitCommitBranchNameService.GetEditedBranchNamesAsync(
                rootCommit.Sha);

            IReadOnlyList <CommitBranchName> commitBranches = await gitCommitBranchNameService.GetCommitBranchNamesAsync(
                rootCommit.Sha);

            commitBranchNameService.SetSpecifiedCommitBranchNames(gitSpecifiedNames, repository);
            commitBranchNameService.SetCommitBranchNames(commitBranches, repository);
        }
        private static MCommit GetRootCommit(MRepository repository)
        {
            MSubBranch mSubBranch = repository.SubBranches
                                    .FirstOrDefault(b => b.Value.IsActive && b.Value.Name == BranchName.Master).Value;

            if (mSubBranch == null)
            {
                Asserter.FailFast($"Repository {repository.WorkingFolder} does not have a master branch");
            }

            IEnumerable <MCommit> firstAncestors = mSubBranch.TipCommit.FirstAncestorsAnSelf();
            MCommit rootCommit = firstAncestors.Last();

            return(rootCommit);
        }
Exemple #14
0
        public BranchName GetBranchName(MCommit commit)
        {
            if (commit.BranchName != null)
            {
                return(commit.BranchName);
            }
            else if (commit.SpecifiedBranchName != null)
            {
                return(commit.SpecifiedBranchName);
            }
            else if (commit.FromSubjectBranchName != null)
            {
                return(commit.FromSubjectBranchName);
            }

            return(null);
        }
        private static void CopyToVirtualCommit
            (MRepository repository, MBranch branch, MCommit commit, CommitSha virtualSha)
        {
            GitCommit gitCommit = new GitCommit(
                virtualSha,
                branch.ParentCommit.Subject,
                branch.ParentCommit.Message,
                branch.ParentCommit.Author,
                branch.ParentCommit.AuthorDate,
                branch.ParentCommit.CommitDate + TimeSpan.FromSeconds(1),
                new List <CommitId> {
                branch.ParentCommitId
            });

            repository.GitCommits[commit.Id] = gitCommit;

            // commit.Id = GetId();
        }
Exemple #16
0
        public IEnumerable <MCommit> Ancestors(Func <MCommit, bool> predicate)
        {
            Stack <MCommit> commits = new Stack <MCommit>();

            Parents
            .Where(predicate)
            .ForEach(parent => commits.Push(parent));

            while (commits.Any())
            {
                MCommit commit = commits.Pop();
                yield return(commit);

                commit.Parents
                .Where(predicate)
                .ForEach(parent => commits.Push(parent));
            }
        }
Exemple #17
0
        public void SetBranchTipCommitsNames(MRepository repository)
        {
            IEnumerable <MSubBranch> branches = repository.SubBranches.Values
                                                .Where(b =>
                                                       b.TipCommit.BranchId == null &&
                                                       b.TipCommit.SubBranchId == null);

            foreach (MSubBranch branch in branches)
            {
                MCommit branchTip = branch.TipCommit;

                if (!branchTip.HasFirstChild &&
                    !branches.Any(b => b.Name != branch.Name && b.TipCommitId == branch.TipCommitId))
                {
                    branchTip.SetBranchName(branch.Name);
                    branchTip.SubBranchId = branch.SubBranchId;
                }
            }
        }
Exemple #18
0
        private static void CopyToUncommitedCommit(
            GitBranch currentBranch,
            MRepository repository,
            GitStatus status,
            MCommit commit,
            CommitId parentId)
        {
            int modifiedCount = status.AllChanges;
            int conflictCount = status.Conflicted;

            string subject = $"{modifiedCount} uncommitted changes in working folder";

            if (conflictCount > 0)
            {
                subject =
                    $"{conflictCount} conflicts and {modifiedCount} changes, {ShortSubject(status)}";
                commit.HasConflicts = true;
            }
            else if (status.IsMerging)
            {
                subject          = $"{modifiedCount} changes, {ShortSubject(status)}";
                commit.IsMerging = true;
            }

            GitCommit gitCommit = new GitCommit(
                CommitSha.Uncommitted,
                subject,
                subject,
                "",
                DateTime.Now,
                DateTime.Now,
                new List <CommitId> {
                parentId
            });

            repository.GitCommits[CommitId.Uncommitted] = gitCommit;

            commit.SetBranchName(currentBranch?.Name ?? "master");

            commit.Tickets  = "";
            commit.BranchId = null;
        }
Exemple #19
0
        private BranchName TryFindBranchName(MCommit root)
        {
            BranchName branchName = commitBranchNameService.GetBranchName(root);

            if (branchName == null)
            {
                // Could not find a branch name from the commit, lets try it ancestors
                foreach (MCommit commit in root.FirstAncestors()
                         .TakeWhile(c => c.HasSingleFirstChild))
                {
                    branchName = commitBranchNameService.GetBranchName(commit);
                    if (branchName != null)
                    {
                        return(branchName);
                    }
                }
            }

            return(branchName);
        }
Exemple #20
0
        private void AddVirtualUncommitted(GitBranch currentBranch, GitStatus status, MRepository repository)
        {
            MCommit commit = repository.Commit(CommitId.Uncommitted);

            repository.Uncommitted = commit;

            commit.IsVirtual = true;

            CommitId headCommitId = CommitId.NoCommits;

            if (currentBranch != null)
            {
                CommitId headId     = new CommitId(currentBranch.TipSha.Sha);
                MCommit  headCommit = repository.Commit(headId);
                headCommitId = headCommit.Id;
            }

            CopyToUncommitedCommit(currentBranch, repository, status, commit, headCommitId);

            SetChildOfParents(commit);
        }
Exemple #21
0
        private void SetEmptyParentCommits(MRepository repository)
        {
            // All commits, which do have a name, but first parent commit does not have a name
            bool isFound;

            do
            {
                isFound = false;
                IEnumerable <MCommit> commitsWithBranchName = repository.Commits.Values
                                                              .Where(commit =>
                                                                     commit.BranchId == null &&
                                                                     commit.HasBranchName &&
                                                                     commit.HasFirstParent &&
                                                                     !commit.FirstParent.HasBranchName);

                foreach (MCommit commit in commitsWithBranchName)
                {
                    BranchName branchName  = commit.BranchName;
                    string     subBranchId = commit.SubBranchId;

                    MCommit last = TryFindFirstAncestorWithSameName(commit.FirstParent, branchName);

                    if (last != null)
                    {
                        isFound = true;
                        foreach (MCommit current in commit.FirstAncestors())
                        {
                            current.SetBranchName(branchName);
                            current.SubBranchId = subBranchId;

                            if (current == last)
                            {
                                break;
                            }
                        }
                    }
                }
            } while (isFound);
        }
        private static void SetChildOfParents(MCommit commit)
        {
            bool isFirstParent = true;

            foreach (MCommit parent in commit.Parents)
            {
                IList <CommitId> childIds = parent.ChildIds;
                if (!childIds.Contains(commit.Id))
                {
                    childIds.Add(commit.Id);
                }

                if (isFirstParent)
                {
                    isFirstParent = false;
                    IList <CommitId> firstChildIds = parent.FirstChildIds;
                    if (!firstChildIds.Contains(commit.Id))
                    {
                        firstChildIds.Add(commit.Id);
                    }
                }
            }
        }
Exemple #23
0
 public static Commit ToCommit(Repository repository, MCommit commit)
 {
     try
     {
         return(new Commit(
                    repository,
                    commit.Id,
                    commit.RealCommitId,
                    commit.RealCommitSha,
                    commit.Subject,
                    commit.Message,
                    commit.Author,
                    commit.AuthorDate,
                    commit.CommitDate,
                    commit.Tags,
                    commit.Tickets,
                    commit.BranchTips,
                    commit.ParentIds.ToList(),
                    commit.ChildIds.ToList(),
                    commit.BranchId,
                    commit.SpecifiedBranchName,
                    commit.CommitBranchName,
                    commit.IsLocalAhead,
                    commit.IsRemoteAhead,
                    commit.IsCommon,
                    commit.IsUncommitted,
                    commit.IsVirtual,
                    commit.HasConflicts,
                    commit.IsMerging,
                    commit.HasFirstChild));
     }
     catch (Exception e)
     {
         Log.Exception(e, $"Failed to convert {commit.Id}");
         throw;
     }
 }
Exemple #24
0
        private static bool TryGetCommit(
            MRepository repository,
            string id,
            out MCommit commit)
        {
            if (CommitId.TryParse(id, out CommitId commitId))
            {
                return(repository.Commits.TryGetValue(commitId, out commit));
            }
            else
            {
                foreach (var pair in repository.GitCommits.ToList())
                {
                    if (pair.Value.Sha.Sha.StartsWithOic(id))
                    {
                        commitId = new CommitId(pair.Value.Sha);
                        return(repository.Commits.TryGetValue(commitId, out commit));
                    }
                }
            }

            commit = null;
            return(false);
        }
Exemple #25
0
        public void AddBranchCommits(IReadOnlyList <GitBranch> branches, MRepository repository)
        {
            GitStatus status = repository.Status;

            Timing t = new Timing();
            IEnumerable <CommitSha> rootCommits = branches.Select(b => b.TipSha);

            if (branches.TryGetCurrent(out GitBranch current) && current.IsDetached)
            {
                rootCommits = rootCommits.Concat(new[] { current.TipSha });
            }

            if (!rootCommits.Any())
            {
                AddVirtualEmptyCommit(repository);
                rootCommits = new[] { CommitSha.NoCommits };
            }

            rootCommits = rootCommits.ToList();
            t.Log("Root commit ids");


            Dictionary <CommitSha, object> added = new Dictionary <CommitSha, object>();

            Dictionary <CommitId, BranchName> branchNameByCommitId        = new Dictionary <CommitId, BranchName>();
            Dictionary <CommitId, BranchName> subjectBranchNameByCommitId = new Dictionary <CommitId, BranchName>();

            Stack <CommitSha> commitShas = new Stack <CommitSha>();

            rootCommits.ForEach(sha => commitShas.Push(sha));
            rootCommits.ForEach(sha => added[sha] = null);
            t.Log("Pushed roots on stack");

            while (commitShas.Any())
            {
                CommitSha commitSha = commitShas.Pop();
                CommitId  commitId  = new CommitId(commitSha.Sha);

                GitCommit gitCommit;
                IEnumerable <CommitSha> parentIds = null;
                if (!repository.GitCommits.TryGetValue(commitId, out gitCommit))
                {
                    Log.Warn($"Unknown commit {commitSha}");
                    continue;
                }

                if (IsMergeCommit(gitCommit))
                {
                    TrySetBranchNameFromSubject(commitId, gitCommit, branchNameByCommitId, subjectBranchNameByCommitId);
                }

                MCommit commit = repository.Commit(commitId);
                if (!commit.IsSet)
                {
                    if (commit.Id == CommitId.NoCommits)
                    {
                        commit.IsVirtual = true;
                        commit.SetBranchName("master");
                    }

                    AddCommit(commit, gitCommit);

                    if (parentIds == null)
                    {
                        parentIds = gitCommit.ParentIds.Select(id => repository.GitCommits[id].Sha);
                    }

                    AddParents(parentIds, commitShas, added);
                }

                BranchName branchName;
                if (branchNameByCommitId.TryGetValue(commitId, out branchName))
                {
                    // Branch name set by a child commit (pull merge commit)
                    commit.SetBranchName(branchName);
                }

                BranchName subjectBranchName;
                if (subjectBranchNameByCommitId.TryGetValue(commitId, out subjectBranchName))
                {
                    // Subject branch name set by a child commit (merge commit)
                    gitCommit.SetBranchNameFromSubject(subjectBranchName);
                }
            }

            if (!status.OK)
            {
                // Adding a virtual "uncommitted" commit since current working folder status has changes
                AddVirtualUncommitted(current, status, repository);
            }
        }
        private void SetLocalAndRemoteAhead(MRepository repository)
        {
            IEnumerable <MBranch> unsynkedBranches = repository.Branches.Values
                                                     .Where(b =>
                                                            b.IsActive &&
                                                            b.IsLocal &&
                                                            b.IsRemote &&
                                                            b.LocalTipCommitId != b.RemoteTipCommitId)
                                                     .ToList();

            foreach (MBranch branch in unsynkedBranches)
            {
                MCommit localTipCommit  = repository.Commits[branch.LocalTipCommitId];
                MCommit remoteTipCommit = repository.Commits[branch.RemoteTipCommitId];

                if (localTipCommit.Id == CommitId.Uncommitted)
                {
                    localTipCommit = localTipCommit.FirstParent;
                }

                branch.Commits.ForEach(commit =>
                {
                    commit.IsLocalAhead  = false;
                    commit.IsRemoteAhead = false;
                    commit.IsLocal       = false;
                    commit.IsRemote      = false;
                    commit.IsCommon      = false;
                });

                localTipCommit
                .CommitAndAncestors(c => c.BranchId == branch.Id && c.IsLocal != true)
                .ForEach(c => c.IsLocal = true);

                remoteTipCommit
                .CommitAndAncestors(c => c.BranchId == branch.Id && c.IsRemote != true)
                .ForEach(c => c.IsRemote = true);

                branch.Commits.ForEach(commit =>
                {
                    commit.IsCommon = commit.IsLocal && commit.IsRemote;
                });

                MCommit commonCommit = localTipCommit
                                       .CommitAndAncestors(c => c.BranchId == branch.Id)
                                       .FirstOrDefault(c => c.IsCommon);

                if (commonCommit == null)
                {
                    if (branch.HasParentBranch)
                    {
                        commonCommit = branch.ParentCommit;
                    }
                    else
                    {
                        commonCommit = branch.FirstCommit;
                    }
                }

                if (commonCommit.Sha != localTipCommit.Sha ||
                    (repository.Commits[branch.LocalTipCommitId].IsUncommitted &&
                     !repository.Commits[branch.FirstCommitId].IsUncommitted))
                {
                    MakeLocalBranch(repository, branch, localTipCommit.Id, commonCommit.Id);
                }

                if (branch.IsLocal)
                {
                    HashSet <CommitId> marked  = new HashSet <CommitId>();
                    int             localCount = 0;
                    Stack <MCommit> commits    = new Stack <MCommit>();
                    commits.Push(localTipCommit);

                    while (commits.Any())
                    {
                        MCommit commit = commits.Pop();
                        if (!marked.Contains(commit.Id) && !commit.IsCommon && commit.Branch == branch)
                        {
                            commit.IsLocalAhead = true;
                            localCount++;
                            marked.Add(commit.Id);
                            commit.Parents
                            .Where(p => p.Branch == branch)
                            .ForEach(p => commits.Push(p));
                        }
                    }

                    branch.LocalAheadCount = localCount;
                }

                if (branch.IsRemote)
                {
                    HashSet <CommitId> marked   = new HashSet <CommitId>();
                    int             remoteCount = 0;
                    Stack <MCommit> commits     = new Stack <MCommit>();
                    commits.Push(remoteTipCommit);

                    while (commits.Any())
                    {
                        MCommit commit = commits.Pop();

                        if (!marked.Contains(commit.Id) && !commit.IsCommon && commit.Branch == branch)
                        {
                            commit.IsRemoteAhead = true;
                            remoteCount++;
                            marked.Add(commit.Id);

                            commit.Parents
                            .Where(p => p.Branch == branch)
                            .ForEach(p => commits.Push(p));
                        }
                    }

                    branch.RemoteAheadCount = remoteCount;
                }
            }
        }
        private static void MakeLocalBranch(
            MRepository repository,
            MBranch branch,
            CommitId localTip,
            CommitId commonTip)
        {
            string  name     = $"{branch.Name}";
            string  branchId = name + "(local)-" + commonTip;
            MBranch localBranch;

            if (!repository.Branches.TryGetValue(branchId, out localBranch))
            {
                localBranch = new MBranch
                {
                    IsLocalPart    = true,
                    Repository     = branch.Repository,
                    Name           = name,
                    IsMultiBranch  = false,
                    IsActive       = true,
                    IsLocal        = true,
                    ParentCommitId = commonTip,
                };

                localBranch.Id = branchId;
                repository.Branches[localBranch.Id] = localBranch;
            }

            localBranch.TipCommitId      = localTip;
            localBranch.LocalTipCommitId = localTip;
            localBranch.IsCurrent        = branch.IsCurrent;
            localBranch.IsActive         = branch.IsActive;

            Stack <MCommit> commits = new Stack <MCommit>();

            commits.Push(repository.Commits[localTip]);

            while (commits.Any())
            {
                MCommit commit = commits.Pop();
                if (!commit.IsCommon && commit.Branch == branch)
                {
                    commit.IsLocalAhead = true;
                    localBranch.CommitIds.Add(commit.Id);
                    branch.CommitIds.Remove(commit.Id);
                    commit.BranchId = localBranch.Id;
                    commit.Parents
                    .Where(p => p.Branch == branch)
                    .ForEach(p => commits.Push(p));
                }
            }

            localBranch.LocalAheadCount  = localBranch.Commits.Count();
            localBranch.RemoteAheadCount = 0;

            if (repository.Commits.TryGetValue(CommitId.Uncommitted, out MCommit uncommitted) &&
                branch.TipCommitId == CommitId.Uncommitted)
            {
                localBranch.TipCommitId      = uncommitted.Id;
                localBranch.LocalTipCommitId = uncommitted.Id;
                localBranch.CommitIds.Insert(0, uncommitted.Id);
                branch.CommitIds.Remove(uncommitted.Id);
                branch.TipCommitId   = uncommitted.FirstParentId;
                uncommitted.BranchId = localBranch.Id;
            }

            localBranch.FirstCommitId = localBranch.Commits.Last().Id;

            branch.IsMainPart        = true;
            branch.LocalSubBranchId  = localBranch.Id;
            localBranch.MainBranchId = branch.Id;
            if (branch.IsCurrent)
            {
                branch.IsCurrent = false;
            }

            branch.IsLocal = false;

            branch.TipCommitId = branch.RemoteTipCommitId;
            if (!branch.CommitIds.Any())
            {
                branch.FirstCommitId = branch.TipCommitId;
            }
        }