diff --git a/src/Commands/QueryRemotes.cs b/src/Commands/QueryRemotes.cs index b5b41b4a..4b6f6a98 100644 --- a/src/Commands/QueryRemotes.cs +++ b/src/Commands/QueryRemotes.cs @@ -30,10 +30,16 @@ namespace SourceGit.Commands var remote = new Models.Remote() { Name = match.Groups[1].Value, - URL = match.Groups[2].Value, + URL = match.Groups[0].Value.Contains("fetch") ? match.Groups[2].Value : "", + PushURL = match.Groups[0].Value.Contains("push") ? match.Groups[2].Value : "", }; + var alreadyFound = _loaded.Find(x => x.Name == remote.Name); + if (alreadyFound != null && !string.IsNullOrEmpty(remote.PushURL)) + { + alreadyFound.PushURL = alreadyFound.URL != remote.PushURL ? remote.PushURL : ""; + } - if (_loaded.Find(x => x.Name == remote.Name) != null) + if (alreadyFound != null) return; _loaded.Add(remote); } diff --git a/src/Commands/Remote.cs b/src/Commands/Remote.cs index 46aa37e3..5428b873 100644 --- a/src/Commands/Remote.cs +++ b/src/Commands/Remote.cs @@ -35,6 +35,24 @@ public bool SetURL(string name, string url) { Args = $"remote set-url {name} {url}"; + var first = Exec(); + Args = $"remote set-url {name} {url} --push"; + return Exec() && first; + } + + public bool SetPushURL(string name, string oldUrl, string newUrl) + { + if (oldUrl == newUrl) + return true; + + if (string.IsNullOrEmpty(newUrl) && !string.IsNullOrEmpty(oldUrl)) + { + Args = $"remote set-url --push --delete {name} {oldUrl}"; + } + else + { + Args = $"remote set-url --push {name} {newUrl}"; + } return Exec(); } } diff --git a/src/Models/Remote.cs b/src/Models/Remote.cs index 2aa69cb5..125d81ce 100644 --- a/src/Models/Remote.cs +++ b/src/Models/Remote.cs @@ -23,6 +23,7 @@ namespace SourceGit.Models public string Name { get; set; } public string URL { get; set; } + public string PushURL { get; set; } public static bool IsSSH(string url) { diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index b4f52b55..d9f963ad 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -477,7 +477,9 @@ Name: Remote name Repository URL: + Push URL: Remote git repository URL + Leave empty if same as URL Copy URL Delete... Edit... diff --git a/src/ViewModels/EditRemote.cs b/src/ViewModels/EditRemote.cs index 0a514324..422ba169 100644 --- a/src/ViewModels/EditRemote.cs +++ b/src/ViewModels/EditRemote.cs @@ -27,6 +27,17 @@ namespace SourceGit.ViewModels } } + [CustomValidation(typeof(EditRemote), nameof(ValidatePushUrl))] + public string PushUrl + { + get => _pushUrl; + set + { + if (SetProperty(ref _pushUrl, value, true)) + UseSSH = Models.Remote.IsSSH(value); + } + } + public bool UseSSH { get => _useSSH; @@ -50,6 +61,7 @@ namespace SourceGit.ViewModels _remote = remote; _name = remote.Name; _url = remote.URL; + _pushUrl = remote.PushURL; _useSSH = Models.Remote.IsSSH(remote.URL); if (_useSSH) @@ -91,6 +103,28 @@ namespace SourceGit.ViewModels return ValidationResult.Success; } + public static ValidationResult ValidatePushUrl(string pushUrl, ValidationContext ctx) + { + if (ctx.ObjectInstance is EditRemote edit) + { + if (string.IsNullOrEmpty(pushUrl)) + { + return ValidationResult.Success; + } + + if (!Models.Remote.IsValidURL(pushUrl)) + return new ValidationResult("Bad remote URL format!!!"); + + foreach (var remote in edit._repo.Remotes) + { + if (remote != edit._remote && pushUrl == remote.PushURL) + return new ValidationResult("A remote with the same url already exists!!!"); + } + } + + return ValidationResult.Success; + } + public static ValidationResult ValidateSSHKey(string sshkey, ValidationContext ctx) { if (ctx.ObjectInstance is EditRemote { _useSSH: true } && !string.IsNullOrEmpty(sshkey)) @@ -123,6 +157,18 @@ namespace SourceGit.ViewModels _remote.URL = _url; } + if (_pushUrl == _url) + { + _pushUrl = ""; + } + + if (_remote.PushURL != _pushUrl) + { + var succ = new Commands.Remote(_repo.FullPath).SetPushURL(_name, _remote.PushURL, _pushUrl); + if (succ) + _remote.PushURL = _pushUrl; + } + SetProgressDescription("Post processing ..."); new Commands.Config(_repo.FullPath).Set($"remote.{_name}.sshkey", _useSSH ? SSHKey : null); @@ -135,6 +181,7 @@ namespace SourceGit.ViewModels private readonly Models.Remote _remote = null; private string _name = null; private string _url = null; + private string _pushUrl = null; private bool _useSSH = false; private string _sshkey = string.Empty; } diff --git a/src/Views/EditRemote.axaml b/src/Views/EditRemote.axaml index 7d64a53a..c762db28 100644 --- a/src/Views/EditRemote.axaml +++ b/src/Views/EditRemote.axaml @@ -35,13 +35,24 @@ CornerRadius="2" Watermark="{DynamicResource Text.Remote.URL.Placeholder}" Text="{Binding Url, Mode=TwoWay}"/> - + + + + -