public string GetDefaultPushRemote(ConfigFileRemote remote, string branch)
        {
            if (remote == null)
            {
                throw new ArgumentNullException(nameof(remote));
            }

            var module = GetModule();

            bool IsSettingForBranch(string setting, string branchName)
            {
                var head = new GitRef(module, null, setting);

                return(head.IsHead && head.Name.Equals(branchName, StringComparison.OrdinalIgnoreCase));
            }

            var remoteHead = remote.Push
                             .Select(s => s.Split(':'))
                             .Where(t => t.Length == 2)
                             .Where(t => IsSettingForBranch(t[0], branch))
                             .Select(t => new GitRef(module, null, t[1]))
                             .FirstOrDefault(h => h.IsHead);

            return(remoteHead?.Name);
        }
        /// <summary>
        /// Removes the specified remote from .git/config file.
        /// </summary>
        /// <param name="remote">Remote to remove.</param>
        /// <returns>Output of <see cref="IGitModule.RemoveRemote"/> operation, if the remote is active; otherwise <see cref="string.Empty"/>.</returns>
        public string RemoveRemote(ConfigFileRemote remote)
        {
            if (remote == null)
            {
                throw new ArgumentNullException(nameof(remote));
            }

            var module = GetModule();

            if (!remote.Disabled)
            {
                return(module.RemoveRemote(remote.Name));
            }

            var sectionName = $"{DisabledSectionPrefix}{SectionRemote}.{remote.Name}";

            module.LocalConfigFile.RemoveConfigSection(sectionName, true);
            return(string.Empty);
        }
        /// <summary>
        ///   Saves the remote details by creating a new or updating an existing remote entry in .git/config file.
        /// </summary>
        /// <param name="remote">An existing remote instance or <see langword="null"/> if creating a new entry.</param>
        /// <param name="remoteName">
        ///   <para>The remote name.</para>
        ///   <para>If updating an existing remote and the name changed, it will result in remote name change and prompt for "remote update".</para>
        /// </param>
        /// <param name="remoteUrl">
        ///   <para>The remote URL.</para>
        ///   <para>If updating an existing remote and the URL changed, it will result in remote URL change and prompt for "remote update".</para>
        /// </param>
        /// <param name="remotePushUrl">An optional alternative remote push URL.</param>
        /// <param name="remotePuttySshKey">An optional Putty SSH key.</param>
        /// <returns>Result of the operation.</returns>
        public ConfigFileRemoteSaveResult SaveRemote(ConfigFileRemote remote, string remoteName, string remoteUrl, string remotePushUrl, string remotePuttySshKey)
        {
            if (string.IsNullOrWhiteSpace(remoteName))
            {
                throw new ArgumentNullException(nameof(remoteName));
            }

            remoteName = remoteName.Trim();

            // if create a new remote or updated the url - we may need to perform "update remote"
            bool updateRemoteRequired = false;

            // if operation return anything back, relay that to the user
            var output = string.Empty;

            var  module         = GetModule();
            bool creatingNew    = remote == null;
            bool remoteDisabled = false;

            if (creatingNew)
            {
                output = module.AddRemote(remoteName, remoteUrl);

                // If output was returned, something went wrong
                if (!string.IsNullOrWhiteSpace(output))
                {
                    return(new ConfigFileRemoteSaveResult(output, false));
                }

                updateRemoteRequired = true;
            }
            else
            {
                if (remote.Disabled)
                {
                    // disabled branches can't updated as it poses to many problems, i.e.
                    // - verify that the branch name is valid, and
                    // - it does not duplicate an active branch name etc.
                    return(new ConfigFileRemoteSaveResult(null, false));
                }

                remoteDisabled = remote.Disabled;
                if (!string.Equals(remote.Name, remoteName, StringComparison.Ordinal))
                {
                    // the name of the remote changed - perform rename
                    output = module.RenameRemote(remote.Name, remoteName);
                }

                if (!string.Equals(remote.Url, remoteUrl, StringComparison.Ordinal))
                {
                    // the remote url changed - we may need to update remote
                    updateRemoteRequired = true;
                }
            }

            UpdateSettings(module, remoteName, remoteDisabled, SettingKeyString.RemoteUrl, remoteUrl);
            UpdateSettings(module, remoteName, remoteDisabled, SettingKeyString.RemotePushUrl, remotePushUrl);
            UpdateSettings(module, remoteName, remoteDisabled, SettingKeyString.RemotePuttySshKey, remotePuttySshKey);

            return(new ConfigFileRemoteSaveResult(output, updateRemoteRequired));
        }