Example #1
0
        private void SetTopProjectSubmoduleInfo(SubmoduleInfoResult result,
                                                string noBranchText,
                                                IGitModule topProject,
                                                bool isCurrentTopProject)
        {
            string path = topProject.WorkingDir;
            string name = Directory.Exists(path) ? Path.GetFileName(Path.GetDirectoryName(path)) : path;

            name += GetBranchNameSuffix(path, noBranchText);
            result.TopProject = new SubmoduleInfo {
                Text = name, Path = path, Bold = isCurrentTopProject
            };
        }
 private void SetTopProjectSubmoduleInfo(SubmoduleInfoResult result, string noBranchText, IGitModule topProject, bool isParentTopProject)
 {
     if (isParentTopProject)
     {
         result.TopProject = result.SuperProject;
     }
     else
     {
         string path = topProject.WorkingDir;
         string name = Path.GetFileName(Path.GetDirectoryName(topProject.WorkingDir)) + GetBranchNameSuffix(path, noBranchText);
         result.TopProject = new SubmoduleInfo {
             Text = name, Path = topProject.WorkingDir
         };
     }
 }
Example #3
0
 private async Task SetTopProjectSubmoduleInfoAsync(bool updateStatus, SubmoduleInfoResult result, GitModule module, CancellationToken cancelToken, string noBranchText, IGitModule topProject, bool isParentTopProject)
 {
     if (isParentTopProject)
     {
         result.TopProject = result.SuperProject;
     }
     else
     {
         string path = topProject.WorkingDir;
         string name = Path.GetFileName(Path.GetDirectoryName(topProject.WorkingDir)) + GetBranchNameSuffix(path, noBranchText);
         result.TopProject = new SubmoduleInfo {
             Text = name, Path = topProject.WorkingDir
         };
         await GetSubmoduleStatusAsync(updateStatus, result.TopProject, cancelToken);
     }
 }
Example #4
0
        private void SetSubmoduleData(GitModule currentModule, SubmoduleInfoResult result, string noBranchText, IGitModule topProject)
        {
            var submodules = topProject.GetSubmodulesLocalPaths().OrderBy(submoduleName => submoduleName).ToArray();

            if (!submodules.Any())
            {
                return;
            }

            var superWorkDir   = currentModule.SuperprojectModule?.WorkingDir;
            var currentWorkDir = currentModule.WorkingDir;
            var localPath      = currentWorkDir.Substring(topProject.WorkingDir.Length);

            if (string.IsNullOrWhiteSpace(localPath))
            {
                localPath = ".";
            }

            localPath = Path.GetDirectoryName(localPath).ToPosixPath();

            foreach (var submodule in submodules)
            {
                string path = topProject.GetSubmoduleFullPath(submodule);
                string name = submodule + GetBranchNameSuffix(path, noBranchText);

                bool bold = false;
                if (submodule == localPath)
                {
                    result.CurrentSubmoduleName = currentModule.GetCurrentSubmoduleLocalPath();
                    bold = true;
                }

                var smi = new SubmoduleInfo {
                    Text = name, Path = path, Bold = bold
                };
                result.AllSubmodules.Add(smi);
                if (path == superWorkDir)
                {
                    result.SuperProject = smi;
                }

                if (path != currentWorkDir && path.StartsWith(currentWorkDir))
                {
                    result.OurSubmodules.Add(smi);
                }
            }
        }
Example #5
0
        private void GetRepositorySubmodulesStructure(SubmoduleInfoResult result, string noBranchText)
        {
            foreach (var submodule in result.Module.GetSubmodulesLocalPaths().OrderBy(submoduleName => submoduleName))
            {
                var    name = submodule;
                string path = result.Module.GetSubmoduleFullPath(submodule);
                if (AppSettings.DashboardShowCurrentBranch && !GitModule.IsBareRepository(path))
                {
                    name = name + " " + GetModuleBranch(path, noBranchText);
                }

                var smi = new SubmoduleInfo {
                    Text = name, Path = path
                };
                result.OurSubmodules.Add(smi);
            }
        }
Example #6
0
        private void GetRepositorySubmodulesStatus(SubmoduleInfoResult result, IGitModule module, CancellationToken cancelToken, string noBranchText)
        {
            foreach (var submodule in module.GetSubmodulesLocalPaths().OrderBy(submoduleName => submoduleName))
            {
                cancelToken.ThrowIfCancellationRequested();
                var    name = submodule;
                string path = module.GetSubmoduleFullPath(submodule);
                if (AppSettings.DashboardShowCurrentBranch && !GitModule.IsBareRepository(path))
                {
                    name = name + " " + GetModuleBranch(path, noBranchText);
                }

                var smi = new SubmoduleInfo {
                    Text = name, Path = path
                };
                result.OurSubmodules.Add(smi);
                GetSubmoduleStatusAsync(smi, cancelToken).FileAndForget();
            }
        }
Example #7
0
 private void SetTopProjectSubmoduleInfo(SubmoduleInfoResult result,
                                         string noBranchText,
                                         IVsrModule topProject,
                                         bool isParentTopProject,
                                         bool isCurrentTopProject)
 {
     if (isParentTopProject && !isCurrentTopProject)
     {
         result.TopProject = result.SuperProject;
     }
     else
     {
         string path = topProject.WorkingDir;
         string name = Directory.Exists(path) ?
                       Path.GetFileName(Path.GetDirectoryName(path)) + GetBranchNameSuffix(path, noBranchText) :
                       path;
         result.TopProject = new SubmoduleInfo {
             Text = name, Path = path, Bold = isCurrentTopProject
         };
     }
 }
Example #8
0
        /// <summary>
        /// Get the result submodule structure
        /// </summary>
        /// <param name="currentModule">The current module</param>
        /// <param name="noBranchText">text with no branches</param>
        private SubmoduleInfoResult GetSuperProjectRepositorySubmodulesStructure(GitModule currentModule, string noBranchText)
        {
            var result = new SubmoduleInfoResult {
                Module = currentModule
            };

            IGitModule topProject          = currentModule.GetTopModule();
            bool       isCurrentTopProject = currentModule.SuperprojectModule is null;

            SetTopProjectSubmoduleInfo(result, noBranchText, topProject, isCurrentTopProject);

            bool isParentTopProject = currentModule.SuperprojectModule?.WorkingDir == topProject.WorkingDir;

            if (isParentTopProject)
            {
                result.SuperProject = result.TopProject;
            }

            // Set result.CurrentSubmoduleName and populate result.AllSubmodules
            SetSubmoduleData(currentModule, result, noBranchText, topProject);
            return(result);
        }
        private void SetSuperProjectSubmoduleInfo(GitModule superprojectModule, SubmoduleInfoResult result, string noBranchText, IGitModule topProject, bool isParentTopProject)
        {
            string name;

            if (isParentTopProject)
            {
                name = Path.GetFileName(Path.GetDirectoryName(topProject.WorkingDir));
            }
            else
            {
                var localPath = superprojectModule.WorkingDir.Substring(topProject.WorkingDir.Length);
                localPath = PathUtil.GetDirectoryName(localPath.ToPosixPath());
                name      = localPath;
            }

            string path = superprojectModule.WorkingDir;

            name += GetBranchNameSuffix(path, noBranchText);
            result.SuperProject = new SubmoduleInfo {
                Text = name, Path = superprojectModule.WorkingDir
            };
        }
Example #10
0
        private async Task SetSuperProjectSubmoduleInfoAsync(bool updateStatus, SubmoduleInfoResult result, GitModule module, CancellationToken cancelToken, string noBranchText, IGitModule topProject, bool isParentTopProject)
        {
            string name;

            if (isParentTopProject)
            {
                name = Path.GetFileName(Path.GetDirectoryName(topProject.WorkingDir));
            }
            else
            {
                var localPath = module.SuperprojectModule.WorkingDir.Substring(topProject.WorkingDir.Length);
                localPath = PathUtil.GetDirectoryName(localPath.ToPosixPath());
                name      = localPath;
            }

            string path = module.SuperprojectModule.WorkingDir;

            name += GetBranchNameSuffix(path, noBranchText);
            result.SuperProject = new SubmoduleInfo {
                Text = name, Path = module.SuperprojectModule.WorkingDir
            };
            await GetSubmoduleStatusAsync(updateStatus, result.SuperProject, cancelToken);
        }
        private async Task GetRepositorySubmodulesStatusAsync(SubmoduleInfoResult result, IGitModule module, CancellationToken cancelToken, string noBranchText)
        {
            List <Task> tasks = new List <Task>();

            foreach (var submodule in module.GetSubmodulesLocalPaths().OrderBy(submoduleName => submoduleName))
            {
                cancelToken.ThrowIfCancellationRequested();
                var    name = submodule;
                string path = module.GetSubmoduleFullPath(submodule);
                if (AppSettings.DashboardShowCurrentBranch && !GitModule.IsBareRepository(path))
                {
                    name = name + " " + GetModuleBranch(path, noBranchText);
                }

                var smi = new SubmoduleInfo {
                    Text = name, Path = path
                };
                result.OurSubmodules.Add(smi);
                tasks.Add(GetSubmoduleStatusAsync(smi, cancelToken));
            }

            await Task.WhenAll(tasks);
        }
Example #12
0
        public void UpdateSubmodulesStatus(bool updateStatus, string workingDirectory, string noBranchText)
        {
            ThreadHelper.JoinableTaskFactory.RunAsync(async() =>
            {
                // Cancel any previous async activities:
                var cancelToken = _submodulesStatusSequence.Next();

                // If not updating the status, allow a 'quick' update
                _previousSubmoduleUpdateTime = updateStatus ? DateTime.Now : DateTime.MinValue;

                OnStatusUpdating();

                await TaskScheduler.Default;

                // Start gathering new submodule information asynchronously.  This makes a significant difference in UI
                // responsiveness if there are numerous submodules (e.g. > 100).
                // First task: Gather list of submodules on a background thread.

                // Don't access Module directly because it's not thread-safe.  Use a thread-local version:
                var threadModule = new GitModule(workingDirectory);
                var result       = new SubmoduleInfoResult
                {
                    Module = threadModule
                };

                // Add all submodules inside the current repository:
                var submodulesTask = GetRepositorySubmodulesStatusAsync(updateStatus, result, threadModule, cancelToken, noBranchText);

                var superTask = GetSuperProjectRepositorySubmodulesStatusAsync(updateStatus, result, threadModule, cancelToken, noBranchText);

                await Task.WhenAll(submodulesTask, superTask);

                OnStatusUpdated(result, cancelToken);

                _previousSubmoduleUpdateTime = updateStatus ? DateTime.Now : DateTime.MinValue;
            }).FileAndForget();
        }
        public void UpdateSubmodulesStatus(string workingDirectory,
                                           string noBranchText,
                                           Action onUpdateBegin,
                                           Func <SubmoduleInfoResult, CancellationToken, Task> onUpdateCompleteAsync)
        {
            // Cancel any previous async activities:
            var cancelToken = _submodulesStatusSequence.Next();

            _previousSubmoduleUpdateTime = DateTime.Now;

            onUpdateBegin();

            // Start gathering new submodule information asynchronously.  This makes a significant difference in UI
            // responsiveness if there are numerous submodules (e.g. > 100).
            ThreadHelper.JoinableTaskFactory.RunAsync(async() =>
            {
                // First task: Gather list of submodules on a background thread.
                // Add a short delay to prio log first
                await Task.Delay(100, cancelToken);

                // Don't access Module directly because it's not thread-safe.  Use a thread-local version:
                var threadModule = new GitModule(workingDirectory);
                var result       = new SubmoduleInfoResult();

                // Add all submodules inside the current repository:
                var submodulesTask = GetRepositorySubmodulesStatusAsync(result, threadModule, cancelToken, noBranchText);

                var superTask = GetSuperProjectRepositorySubmodulesStatusAsync(result, threadModule, cancelToken, noBranchText);

                await Task.WhenAll(submodulesTask, superTask);

                await onUpdateCompleteAsync(result, cancelToken);

                _previousSubmoduleUpdateTime = DateTime.Now;
            }).FileAndForget();
        }
        /// <inheritdoc />
        public async Task UpdateSubmodulesStructureAsync(string workingDirectory, string noBranchText, bool updateStatus)
        {
            _submoduleInfoResult             = null;
            _gitStatusWhileUpdatingStructure = null;
            _submoduleInfos.Clear();

            // Cancel any previous async activities:
            var cancelToken = _submodulesStatusSequence.Next();

            // Do not throttle next status update
            _previousSubmoduleUpdateTime = DateTime.MinValue;

            OnStatusUpdating();

            await TaskScheduler.Default;

            // Start gathering new submodule structure asynchronously.
            var currentModule = new GitModule(workingDirectory);
            var result        = new SubmoduleInfoResult
            {
                Module = currentModule
            };

            // Add all submodules inside the current repository:
            GetRepositorySubmodulesStructure(result, noBranchText);
            GetSuperProjectRepositorySubmodulesStructure(currentModule, result, noBranchText);

            // Structure is updated
            OnStatusUpdated(result, cancelToken);

            // Prepare info for status updates (normally triggered by StatusMonitor)
            foreach (var info in result.OurSubmodules)
            {
                _submoduleInfos[info.Path] = info;
            }

            foreach (var info in result.SuperSubmodules)
            {
                _submoduleInfos[info.Path] = info;
            }

            if (!_submoduleInfos.ContainsKey(result.TopProject.Path))
            {
                _submoduleInfos.Add(result.TopProject.Path, result.TopProject);
            }

            // Start update status for the submodules
            if (updateStatus)
            {
                if (result.SuperProject != null)
                {
                    // For the topmodule, use git-status information to update the status
                    // If a submodule is current, update once from top module to give an overview
                    // The structure _below_ the current module could have been updated from git-status but the current module
                    // must be updated from its super project to set the ahead/behind information
                    await GetSubmoduleDetailedStatusAsync(currentModule.GetTopModule(), cancelToken);

                    // Ignore if possible or at least delay the pending git-status trigger
                    _gitStatusWhileUpdatingStructure = null;
                    _previousSubmoduleUpdateTime     = DateTime.Now;
                }
                else if (_gitStatusWhileUpdatingStructure != null)
                {
                    await UpdateSubmodulesStatusAsync(currentModule, _gitStatusWhileUpdatingStructure, cancelToken);

                    // Ignore if possible or at least delay the pending git-status trigger
                    _gitStatusWhileUpdatingStructure = null;
                    _previousSubmoduleUpdateTime     = DateTime.Now;
                }

                OnStatusUpdated(result, cancelToken);
            }

            _submoduleInfoResult = result;
        }
Example #15
0
 public SubmoduleStatusEventArgs(SubmoduleInfoResult info, bool structureUpdated, CancellationToken token)
 {
     Info             = info;
     Token            = token;
     StructureUpdated = structureUpdated;
 }
        private async Task GetSuperProjectRepositorySubmodulesStatusAsync(SubmoduleInfoResult result, GitModule module, CancellationToken cancelToken, string noBranchText)
        {
            if (module.SuperprojectModule == null)
            {
                return;
            }

            string    name, path;
            GitModule supersuperproject = FindTopProjectModule(module.SuperprojectModule);

            if (module.SuperprojectModule.WorkingDir != supersuperproject.WorkingDir)
            {
                name = Path.GetFileName(Path.GetDirectoryName(supersuperproject.WorkingDir));
                path = supersuperproject.WorkingDir;
                if (AppSettings.DashboardShowCurrentBranch && !GitModule.IsBareRepository(path))
                {
                    name = name + " " + GetModuleBranch(path, noBranchText);
                }

                result.TopProject = new SubmoduleInfo {
                    Text = name, Path = supersuperproject.WorkingDir
                };
                await GetSubmoduleStatusAsync(result.TopProject, cancelToken);
            }

            if (module.SuperprojectModule.WorkingDir != supersuperproject.WorkingDir)
            {
                var localPath = module.SuperprojectModule.WorkingDir.Substring(supersuperproject.WorkingDir.Length);
                localPath = PathUtil.GetDirectoryName(localPath.ToPosixPath());
                name      = localPath;
            }
            else
            {
                name = Path.GetFileName(Path.GetDirectoryName(supersuperproject.WorkingDir));
            }

            path = module.SuperprojectModule.WorkingDir;
            if (AppSettings.DashboardShowCurrentBranch && !GitModule.IsBareRepository(path))
            {
                name = name + " " + GetModuleBranch(path, noBranchText);
            }

            result.SuperProject = new SubmoduleInfo {
                Text = name, Path = module.SuperprojectModule.WorkingDir
            };
            await GetSubmoduleStatusAsync(result.SuperProject, cancelToken);

            var submodules = supersuperproject.GetSubmodulesLocalPaths().OrderBy(submoduleName => submoduleName).ToArray();

            if (submodules.Any())
            {
                string localPath = module.WorkingDir.Substring(supersuperproject.WorkingDir.Length);
                localPath = PathUtil.GetDirectoryName(localPath.ToPosixPath());

                List <Task> subTasks = new List <Task>();

                foreach (var submodule in submodules)
                {
                    cancelToken.ThrowIfCancellationRequested();
                    name = submodule;
                    path = supersuperproject.GetSubmoduleFullPath(submodule);
                    if (AppSettings.DashboardShowCurrentBranch && !GitModule.IsBareRepository(path))
                    {
                        name = name + " " + GetModuleBranch(path, noBranchText);
                    }

                    bool bold = false;
                    if (submodule == localPath)
                    {
                        result.CurrentSubmoduleName = module.GetCurrentSubmoduleLocalPath();
                        bold = true;
                    }

                    var smi = new SubmoduleInfo {
                        Text = name, Path = path, Bold = bold
                    };
                    result.SuperSubmodules.Add(smi);
                    subTasks.Add(GetSubmoduleStatusAsync(smi, cancelToken));
                }

                await Task.WhenAll(subTasks);
            }
        }
Example #17
0
        /// <summary>
        /// This function always at least sets result.TopProject
        /// </summary>
        /// <param name="result">submodule info</param>
        /// <param name="noBranchText">text with no branches</param>
        private void GetSuperProjectRepositorySubmodulesStructure(GitModule currentModule, SubmoduleInfoResult result, string noBranchText)
        {
            bool isCurrentTopProject = currentModule.SuperprojectModule == null;

            if (isCurrentTopProject)
            {
                SetTopProjectSubmoduleInfo(result, noBranchText, result.Module, false, isCurrentTopProject);

                return;
            }

            IGitModule topProject = currentModule.SuperprojectModule.GetTopModule();

            bool isParentTopProject = currentModule.SuperprojectModule.WorkingDir == topProject.WorkingDir;

            // Set result.SuperProject
            SetSuperProjectSubmoduleInfo(currentModule.SuperprojectModule, result, noBranchText, topProject, isParentTopProject);

            // Set result.TopProject
            SetTopProjectSubmoduleInfo(result, noBranchText, topProject, isParentTopProject, isCurrentTopProject);

            // Set result.CurrentSubmoduleName and populate result.SuperSubmodules
            SetSubmoduleData(currentModule, result, noBranchText, topProject);
        }
Example #18
0
        /// <inheritdoc />
        public void UpdateSubmodulesStructure(string workingDirectory, string noBranchText, bool updateStatus)
        {
            _submoduleInfoResult             = null;
            _gitStatusWhileUpdatingStructure = null;
            _submoduleInfos.Clear();
            ThreadHelper.JoinableTaskFactory.RunAsync(async() =>
            {
                // Cancel any previous async activities:
                var cancelToken = _submodulesStatusSequence.Next();

                // Do not throttle next status update
                _previousSubmoduleUpdateTime = DateTime.MinValue;

                OnStatusUpdating();

                await TaskScheduler.Default;

                // Start gathering new submodule structure asynchronously.
                var currentModule = new GitModule(workingDirectory);
                var result        = new SubmoduleInfoResult
                {
                    Module = currentModule
                };

                // Add all submodules inside the current repository:
                GetRepositorySubmodulesStructure(result, noBranchText);
                GetSuperProjectRepositorySubmodulesStructure(currentModule, result, noBranchText);

                // Structure is updated
                OnStatusUpdated(result, cancelToken);

                // Prepare info for status updates (normally triggered by StatusMonitor)
                foreach (var info in result.OurSubmodules)
                {
                    _submoduleInfos[info.Path] = info;
                }

                foreach (var info in result.SuperSubmodules)
                {
                    _submoduleInfos[info.Path] = info;
                }

                if (!_submoduleInfos.ContainsKey(result.TopProject.Path))
                {
                    _submoduleInfos.Add(result.TopProject.Path, result.TopProject);
                }

                // Start update status for the submodules
                if (updateStatus)
                {
                    if (result.SuperProject != null)
                    {
                        // Update from top module (will stop at current)
                        await GetSubmoduleDetailedStatusAsync(currentModule.GetTopModule(), cancelToken);
                    }

                    if (_gitStatusWhileUpdatingStructure != null)
                    {
                        // Current module must be updated separately (not in _submoduleInfos)
                        await UpdateSubmodulesStatusAsync(currentModule, _gitStatusWhileUpdatingStructure, cancelToken);
                    }

                    OnStatusUpdated(result, cancelToken);
                }

                _submoduleInfoResult = result;
            }).FileAndForget();
        }
Example #19
0
        private async Task GetSuperProjectRepositorySubmodulesStatusAsync(bool updateStatus, SubmoduleInfoResult result, GitModule module, CancellationToken cancelToken, string noBranchText)
        {
            // This function always at least sets result.TopProject

            bool isCurrentTopProject = module.SuperprojectModule == null;

            if (isCurrentTopProject)
            {
                string path = module.WorkingDir;
                string name = Path.GetFileName(Path.GetDirectoryName(module.WorkingDir)) + GetBranchNameSuffix(path, noBranchText);
                result.TopProject = new SubmoduleInfo {
                    Text = name, Path = module.WorkingDir, Bold = true
                };
                return;
            }

            IGitModule topProject = module.SuperprojectModule.GetTopModule();

            bool isParentTopProject = module.SuperprojectModule.WorkingDir == topProject.WorkingDir;

            // Set result.SuperProject
            SetSuperProjectSubmoduleInfo(updateStatus, result, module, cancelToken, noBranchText, topProject, isParentTopProject);

            // Set result.TopProject
            await SetTopProjectSubmoduleInfoAsync(updateStatus, result, module, cancelToken, noBranchText, topProject, isParentTopProject);

            // Set result.CurrentSubmoduleName and populate result.SuperSubmodules
            await SetSubmoduleDataAsync(updateStatus, result, module, cancelToken, noBranchText, topProject);
        }
Example #20
0
 private void OnStatusUpdated(SubmoduleInfoResult info, CancellationToken token)
 {
     token.ThrowIfCancellationRequested();
     StatusUpdated?.Invoke(this, new SubmoduleStatusEventArgs(info, token));
 }
Example #21
0
 public SubmoduleStatusEventArgs(SubmoduleInfoResult info, CancellationToken token)
 {
     Info  = info;
     Token = token;
 }
Example #22
0
        /// <inheritdoc />
        public async Task UpdateSubmodulesStructureAsync(string workingDirectory, string noBranchText, bool updateStatus)
        {
            _submoduleInfoResult = null;
            _submoduleInfos.Clear();

            // Cancel previous structure and status updates
            var cancelToken = _submodulesStructureSequence.Next();

            _submodulesStatusSequence.Next();

            // Do not throttle next status update
            _previousSubmoduleUpdateTime = DateTime.MinValue;

            OnStatusUpdating();

            await TaskScheduler.Default;

            // Start gathering new submodule structure asynchronously.
            var currentModule = new GitModule(workingDirectory);
            var result        = GetSuperProjectRepositorySubmodulesStructure(currentModule, noBranchText);

            // Prepare info for status updates
            _submoduleInfos[result.TopProject.Path] = result.TopProject;
            foreach (var info in result.AllSubmodules)
            {
                _submoduleInfos[info.Path] = info;
            }

            // Structure is updated
            OnStatusUpdated(result, cancelToken);

            if (updateStatus && currentModule.SuperprojectModule is not null)
            {
                // For the top module, use git-status information to update the status
                // If a submodule is current, update once from top module to give an overview
                // (The structure below the current module could have been updated from git-status but the current module
                // must be updated from its super project to set the ahead/behind information)
                // Further git-status updates only the current module and below
                var topModule = currentModule.GetTopModule();
                await GetSubmoduleDetailedStatusAsync(topModule, cancelToken);

                // Set status for top module from submodules
                foreach (var name in topModule.GetSubmodulesLocalPaths(false))
                {
                    var path = topModule.GetSubmoduleFullPath(name);

                    if (_submoduleInfos.ContainsKey(path) && _submoduleInfos[path].Detailed is not null)
                    {
                        SetModuleAsDirtyUpwards(topModule);
                        break;
                    }
                }

                // Ignore if possible or at least delay the pending git-status trigger
                _previousSubmoduleUpdateTime = DateTime.Now;
                _submodulesStatusSequence.Next();
                OnStatusUpdated(result, cancelToken);
            }

            _submoduleInfoResult = result;
        }
        /// <summary>
        /// This function always at least sets result.TopProject
        /// </summary>
        /// <param name="result">submodule info</param>
        /// <param name="noBranchText">text with no branches</param>
        private void GetSuperProjectRepositorySubmodulesStructure(GitModule currentModule, SubmoduleInfoResult result, string noBranchText)
        {
            bool isCurrentTopProject = currentModule.SuperprojectModule == null;

            if (isCurrentTopProject)
            {
                string path = result.Module.WorkingDir;
                string name = Path.GetFileName(Path.GetDirectoryName(result.Module.WorkingDir)) + GetBranchNameSuffix(path, noBranchText);
                result.TopProject = new SubmoduleInfo {
                    Text = name, Path = result.Module.WorkingDir, Bold = true
                };
                return;
            }

            IGitModule topProject = currentModule.SuperprojectModule.GetTopModule();

            bool isParentTopProject = currentModule.SuperprojectModule.WorkingDir == topProject.WorkingDir;

            // Set result.SuperProject
            SetSuperProjectSubmoduleInfo(currentModule.SuperprojectModule, result, noBranchText, topProject, isParentTopProject);

            // Set result.TopProject
            SetTopProjectSubmoduleInfo(result, noBranchText, topProject, isParentTopProject);

            // Set result.CurrentSubmoduleName and populate result.SuperSubmodules
            SetSubmoduleData(currentModule, result, noBranchText, topProject);
        }