mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-23 20:47:25 -08:00
feature<SSH>: supports using ssh private key to access remote git repository
This commit is contained in:
parent
306292147f
commit
75a46ceb74
11 changed files with 200 additions and 18 deletions
|
@ -8,12 +8,20 @@ namespace SourceGit.Commands {
|
||||||
public class Clone : Command {
|
public class Clone : Command {
|
||||||
private Action<string> handler = null;
|
private Action<string> handler = null;
|
||||||
|
|
||||||
public Clone(string path, string url, string localName, string extraArgs, Action<string> outputHandler) {
|
public Clone(string path, string url, string localName, string sshKey, string extraArgs, Action<string> outputHandler) {
|
||||||
Cwd = path;
|
Cwd = path;
|
||||||
TraitErrorAsOutput = true;
|
TraitErrorAsOutput = true;
|
||||||
Args = "-c credential.helper=manager clone --progress --verbose --recurse-submodules ";
|
|
||||||
handler = outputHandler;
|
handler = outputHandler;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(sshKey)) {
|
||||||
|
Environment.SetEnvironmentVariable("GIT_SSH_COMMAND", $"ssh -i '{sshKey}'");
|
||||||
|
Args = "";
|
||||||
|
} else {
|
||||||
|
Args = "-c credential.helper=manager ";
|
||||||
|
}
|
||||||
|
|
||||||
|
Args += "clone --progress --verbose --recurse-submodules ";
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(extraArgs)) Args += $"{extraArgs} ";
|
if (!string.IsNullOrEmpty(extraArgs)) Args += $"{extraArgs} ";
|
||||||
Args += $"{url} ";
|
Args += $"{url} ";
|
||||||
if (!string.IsNullOrEmpty(localName)) Args += localName;
|
if (!string.IsNullOrEmpty(localName)) Args += localName;
|
||||||
|
|
|
@ -13,7 +13,16 @@ namespace SourceGit.Commands {
|
||||||
public Fetch(string repo, string remote, bool prune, Action<string> outputHandler) {
|
public Fetch(string repo, string remote, bool prune, Action<string> outputHandler) {
|
||||||
Cwd = repo;
|
Cwd = repo;
|
||||||
TraitErrorAsOutput = true;
|
TraitErrorAsOutput = true;
|
||||||
Args = "-c credential.helper=manager fetch --progress --verbose ";
|
|
||||||
|
var sshKey = new Config(repo).Get($"remote.{remote}.sshkey");
|
||||||
|
if (!string.IsNullOrEmpty(sshKey)) {
|
||||||
|
Environment.SetEnvironmentVariable("GIT_SSH_COMMAND", $"ssh -i '{sshKey}'");
|
||||||
|
Args = "";
|
||||||
|
} else {
|
||||||
|
Args = "-c credential.helper=manager ";
|
||||||
|
}
|
||||||
|
|
||||||
|
Args += "fetch --progress --verbose ";
|
||||||
if (prune) Args += "--prune ";
|
if (prune) Args += "--prune ";
|
||||||
Args += remote;
|
Args += remote;
|
||||||
handler = outputHandler;
|
handler = outputHandler;
|
||||||
|
|
|
@ -11,10 +11,19 @@ namespace SourceGit.Commands {
|
||||||
|
|
||||||
public Pull(string repo, string remote, string branch, bool useRebase, bool autoStash, Action<string> onProgress) {
|
public Pull(string repo, string remote, string branch, bool useRebase, bool autoStash, Action<string> onProgress) {
|
||||||
Cwd = repo;
|
Cwd = repo;
|
||||||
Args = "-c credential.helper=manager pull --verbose --progress --tags ";
|
|
||||||
TraitErrorAsOutput = true;
|
TraitErrorAsOutput = true;
|
||||||
handler = onProgress;
|
handler = onProgress;
|
||||||
|
|
||||||
|
var sshKey = new Config(repo).Get($"remote.{remote}.sshkey");
|
||||||
|
if (!string.IsNullOrEmpty(sshKey)) {
|
||||||
|
Environment.SetEnvironmentVariable("GIT_SSH_COMMAND", $"ssh -i '{sshKey}'");
|
||||||
|
Args = "";
|
||||||
|
} else {
|
||||||
|
Args = "-c credential.helper=manager ";
|
||||||
|
}
|
||||||
|
|
||||||
|
Args += "pull --verbose --progress --tags ";
|
||||||
|
|
||||||
if (useRebase) Args += "--rebase ";
|
if (useRebase) Args += "--rebase ";
|
||||||
if (autoStash) {
|
if (autoStash) {
|
||||||
if (useRebase) Args += "--autostash ";
|
if (useRebase) Args += "--autostash ";
|
||||||
|
|
|
@ -11,7 +11,16 @@ namespace SourceGit.Commands {
|
||||||
Cwd = repo;
|
Cwd = repo;
|
||||||
TraitErrorAsOutput = true;
|
TraitErrorAsOutput = true;
|
||||||
handler = onProgress;
|
handler = onProgress;
|
||||||
Args = "-c credential.helper=manager push --progress --verbose ";
|
|
||||||
|
var sshKey = new Config(repo).Get($"remote.{remote}.sshkey");
|
||||||
|
if (!string.IsNullOrEmpty(sshKey)) {
|
||||||
|
Environment.SetEnvironmentVariable("GIT_SSH_COMMAND", $"ssh -i '{sshKey}'");
|
||||||
|
Args = "";
|
||||||
|
} else {
|
||||||
|
Args = "-c credential.helper=manager ";
|
||||||
|
}
|
||||||
|
|
||||||
|
Args += "push --progress --verbose ";
|
||||||
|
|
||||||
if (withTags) Args += "--tags ";
|
if (withTags) Args += "--tags ";
|
||||||
if (track) Args += "-u ";
|
if (track) Args += "-u ";
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<sys:String x:Key="Text.ParentFolder">Parent Folder :</sys:String>
|
<sys:String x:Key="Text.ParentFolder">Parent Folder :</sys:String>
|
||||||
<sys:String x:Key="Text.ParentFolder.Placeholder">Relative foler to store this module. Optional.</sys:String>
|
<sys:String x:Key="Text.ParentFolder.Placeholder">Relative foler to store this module. Optional.</sys:String>
|
||||||
|
|
||||||
|
<sys:String x:Key="Text.SSHKey">SSH Private Key</sys:String>
|
||||||
|
<sys:String x:Key="Text.SSHKey.Placeholder">Private SSH key store path</sys:String>
|
||||||
|
|
||||||
<sys:String x:Key="Text.About">ABOUT</sys:String>
|
<sys:String x:Key="Text.About">ABOUT</sys:String>
|
||||||
<sys:String x:Key="Text.About.Title">SourceGit - OPEN SOURCE GIT CLIENT</sys:String>
|
<sys:String x:Key="Text.About.Title">SourceGit - OPEN SOURCE GIT CLIENT</sys:String>
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
<sys:String x:Key="Text.ParentFolder">本地目录 :</sys:String>
|
<sys:String x:Key="Text.ParentFolder">本地目录 :</sys:String>
|
||||||
<sys:String x:Key="Text.ParentFolder.Placeholder">本地存放的父级目录,选填.</sys:String>
|
<sys:String x:Key="Text.ParentFolder.Placeholder">本地存放的父级目录,选填.</sys:String>
|
||||||
|
|
||||||
|
<sys:String x:Key="Text.SSHKey">SSH密钥</sys:String>
|
||||||
|
<sys:String x:Key="Text.SSHKey.Placeholder">SSH密钥文件</sys:String>
|
||||||
|
|
||||||
<sys:String x:Key="Text.About">关于软件</sys:String>
|
<sys:String x:Key="Text.About">关于软件</sys:String>
|
||||||
<sys:String x:Key="Text.About.Title">SourceGit - 开源Git图形客户端</sys:String>
|
<sys:String x:Key="Text.About.Title">SourceGit - 开源Git图形客户端</sys:String>
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="32"/>
|
<RowDefinition Height="32"/>
|
||||||
|
<RowDefinition x:Name="rowSSHKey" Height="0"/>
|
||||||
<RowDefinition Height="32"/>
|
<RowDefinition Height="32"/>
|
||||||
<RowDefinition Height="32"/>
|
<RowDefinition Height="32"/>
|
||||||
<RowDefinition Height="32"/>
|
<RowDefinition Height="32"/>
|
||||||
|
@ -31,7 +32,8 @@
|
||||||
Grid.Row="0" Grid.Column="1"
|
Grid.Row="0" Grid.Column="1"
|
||||||
x:Name="txtUrl"
|
x:Name="txtUrl"
|
||||||
Height="24"
|
Height="24"
|
||||||
Placeholder="{DynamicResource Text.Clone.RemoteURL.Placeholder}">
|
Placeholder="{DynamicResource Text.Clone.RemoteURL.Placeholder}"
|
||||||
|
TextChanged="OnUrlChanged">
|
||||||
<controls:TextEdit.Text>
|
<controls:TextEdit.Text>
|
||||||
<Binding ElementName="me" Path="Uri" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
|
<Binding ElementName="me" Path="Uri" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
|
||||||
<Binding.ValidationRules>
|
<Binding.ValidationRules>
|
||||||
|
@ -43,7 +45,7 @@
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="1" Grid.Column="0"
|
Grid.Row="1" Grid.Column="0"
|
||||||
Text="{DynamicResource Text.Clone.Folder}"
|
Text="{DynamicResource Text.SSHKey}"
|
||||||
Margin="0,0,4,0"
|
Margin="0,0,4,0"
|
||||||
HorizontalAlignment="Right"/>
|
HorizontalAlignment="Right"/>
|
||||||
<Grid Grid.Row="1" Grid.Column="1">
|
<Grid Grid.Row="1" Grid.Column="1">
|
||||||
|
@ -52,6 +54,33 @@
|
||||||
<ColumnDefinition Width="30"/>
|
<ColumnDefinition Width="30"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<controls:TextEdit
|
||||||
|
Grid.Column="0"
|
||||||
|
x:Name="txtSSHKey"
|
||||||
|
Height="24"
|
||||||
|
Placeholder="{DynamicResource Text.SSHKey.Placeholder}"/>
|
||||||
|
|
||||||
|
<controls:IconButton
|
||||||
|
Grid.Column="1"
|
||||||
|
Click="OnSelectSSHKey"
|
||||||
|
Width="24" Height="24"
|
||||||
|
Margin="2,0,0,0" Padding="4"
|
||||||
|
BorderBrush="{DynamicResource Brush.Border1}"
|
||||||
|
BorderThickness="1"
|
||||||
|
Icon="{StaticResource Icon.Folder.Open}"/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="2" Grid.Column="0"
|
||||||
|
Text="{DynamicResource Text.Clone.Folder}"
|
||||||
|
Margin="0,0,4,0"
|
||||||
|
HorizontalAlignment="Right"/>
|
||||||
|
<Grid Grid.Row="2" Grid.Column="1">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="30"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<controls:TextEdit
|
<controls:TextEdit
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
x:Name="txtFolder"
|
x:Name="txtFolder"
|
||||||
|
@ -77,12 +106,12 @@
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="2" Grid.Column="0"
|
Grid.Row="3" Grid.Column="0"
|
||||||
Text="{DynamicResource Text.Clone.LocalName}"
|
Text="{DynamicResource Text.Clone.LocalName}"
|
||||||
Margin="0,0,4,0"
|
Margin="0,0,4,0"
|
||||||
HorizontalAlignment="Right"/>
|
HorizontalAlignment="Right"/>
|
||||||
<controls:TextEdit
|
<controls:TextEdit
|
||||||
Grid.Row="2" Grid.Column="1"
|
Grid.Row="3" Grid.Column="1"
|
||||||
Height="24"
|
Height="24"
|
||||||
x:Name="txtLocal"
|
x:Name="txtLocal"
|
||||||
Placeholder="{DynamicResource Text.Clone.LocalName.Placeholder}">
|
Placeholder="{DynamicResource Text.Clone.LocalName.Placeholder}">
|
||||||
|
@ -96,12 +125,12 @@
|
||||||
</controls:TextEdit>
|
</controls:TextEdit>
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="3" Grid.Column="0"
|
Grid.Row="4" Grid.Column="0"
|
||||||
Text="{DynamicResource Text.Clone.RemoteName}"
|
Text="{DynamicResource Text.Clone.RemoteName}"
|
||||||
Margin="0,0,4,0"
|
Margin="0,0,4,0"
|
||||||
HorizontalAlignment="Right"/>
|
HorizontalAlignment="Right"/>
|
||||||
<controls:TextEdit
|
<controls:TextEdit
|
||||||
Grid.Row="3" Grid.Column="1"
|
Grid.Row="4" Grid.Column="1"
|
||||||
x:Name="txtRemote"
|
x:Name="txtRemote"
|
||||||
Height="24"
|
Height="24"
|
||||||
Placeholder="{DynamicResource Text.Clone.RemoteName.Placeholder}">
|
Placeholder="{DynamicResource Text.Clone.RemoteName.Placeholder}">
|
||||||
|
@ -115,12 +144,12 @@
|
||||||
</controls:TextEdit>
|
</controls:TextEdit>
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="4" Grid.Column="0"
|
Grid.Row="5" Grid.Column="0"
|
||||||
Text="{DynamicResource Text.Clone.AdditionalParam}"
|
Text="{DynamicResource Text.Clone.AdditionalParam}"
|
||||||
Margin="0,0,4,0"
|
Margin="0,0,4,0"
|
||||||
HorizontalAlignment="Right"/>
|
HorizontalAlignment="Right"/>
|
||||||
<controls:TextEdit
|
<controls:TextEdit
|
||||||
Grid.Row="4" Grid.Column="1"
|
Grid.Row="5" Grid.Column="1"
|
||||||
Height="24"
|
Height="24"
|
||||||
Placeholder="{DynamicResource Text.Clone.AdditionalParam.Placeholder}"
|
Placeholder="{DynamicResource Text.Clone.AdditionalParam.Placeholder}"
|
||||||
Text="{Binding ElementName=me, Path=ExtraArgs, Mode=TwoWay}"/>
|
Text="{Binding ElementName=me, Path=ExtraArgs, Mode=TwoWay}"/>
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
|
||||||
namespace SourceGit.Views.Popups {
|
namespace SourceGit.Views.Popups {
|
||||||
|
@ -32,11 +35,13 @@ namespace SourceGit.Views.Popups {
|
||||||
if (Validation.GetHasError(edit)) return null;
|
if (Validation.GetHasError(edit)) return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sshKey = txtSSHKey.Text;
|
||||||
|
|
||||||
return Task.Run(() => {
|
return Task.Run(() => {
|
||||||
var extras = string.IsNullOrEmpty(ExtraArgs) ? "" : ExtraArgs;
|
var extras = string.IsNullOrEmpty(ExtraArgs) ? "" : ExtraArgs;
|
||||||
if (!string.IsNullOrEmpty(RemoteName)) extras += $" --origin {RemoteName}";
|
if (!string.IsNullOrEmpty(RemoteName)) extras += $" --origin {RemoteName}";
|
||||||
|
|
||||||
var succ = new Commands.Clone(Folder, Uri, LocalName, extras, UpdateProgress).Exec();
|
var succ = new Commands.Clone(Folder, Uri, LocalName, sshKey, extras, UpdateProgress).Exec();
|
||||||
if (!succ) return false;
|
if (!succ) return false;
|
||||||
|
|
||||||
var path = Folder;
|
var path = Folder;
|
||||||
|
@ -53,6 +58,13 @@ namespace SourceGit.Views.Popups {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(sshKey)) {
|
||||||
|
var config = new Commands.Config(path);
|
||||||
|
var remote = "origin";
|
||||||
|
if (!string.IsNullOrEmpty(RemoteName)) remote = RemoteName;
|
||||||
|
config.Set($"remote.{remote}.sshkey", sshKey);
|
||||||
|
}
|
||||||
|
|
||||||
var gitDir = new Commands.QueryGitDir(path).Result();
|
var gitDir = new Commands.QueryGitDir(path).Result();
|
||||||
var repo = Models.Preference.Instance.AddRepository(path, gitDir, "");
|
var repo = Models.Preference.Instance.AddRepository(path, gitDir, "");
|
||||||
if (repo != null) Dispatcher.Invoke(() => Models.Watcher.Open(repo));
|
if (repo != null) Dispatcher.Invoke(() => Models.Watcher.Open(repo));
|
||||||
|
@ -60,12 +72,34 @@ namespace SourceGit.Views.Popups {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnFolderSelectorClick(object sender, System.Windows.RoutedEventArgs e) {
|
private void OnFolderSelectorClick(object sender, RoutedEventArgs e) {
|
||||||
var dialog = new Controls.FolderDialog();
|
var dialog = new Controls.FolderDialog();
|
||||||
if (dialog.ShowDialog() == true) {
|
if (dialog.ShowDialog() == true) {
|
||||||
Folder = dialog.SelectedPath;
|
Folder = dialog.SelectedPath;
|
||||||
txtFolder.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
|
txtFolder.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnSelectSSHKey(object sender, RoutedEventArgs e) {
|
||||||
|
var initPath = Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "..", ".ssh"));
|
||||||
|
if (!Directory.Exists(initPath)) Directory.CreateDirectory(initPath);
|
||||||
|
|
||||||
|
var dialog = new OpenFileDialog();
|
||||||
|
dialog.Filter = $"SSH Private Key|*";
|
||||||
|
dialog.Title = App.Text("SSHKey");
|
||||||
|
dialog.InitialDirectory = initPath;
|
||||||
|
dialog.CheckFileExists = true;
|
||||||
|
dialog.Multiselect = false;
|
||||||
|
|
||||||
|
if (dialog.ShowDialog() == true) txtSSHKey.Text = dialog.FileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnUrlChanged(object sender, TextChangedEventArgs e) {
|
||||||
|
if (!string.IsNullOrEmpty(txtUrl.Text)) {
|
||||||
|
rowSSHKey.Height = new GridLength(txtUrl.Text.StartsWith("git@") ? 32 : 0, GridUnitType.Pixel);
|
||||||
|
} else {
|
||||||
|
rowSSHKey.Height = new GridLength(0, GridUnitType.Pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,13 +28,21 @@ namespace SourceGit.Views.Popups {
|
||||||
public override Task<bool> Start() {
|
public override Task<bool> Start() {
|
||||||
var prune = chkPrune.IsChecked == true;
|
var prune = chkPrune.IsChecked == true;
|
||||||
var remote = (remotes.SelectedItem as Models.Remote).Name;
|
var remote = (remotes.SelectedItem as Models.Remote).Name;
|
||||||
if (chkFetchAll.IsChecked == true) remote = "--all";
|
var all = chkFetchAll.IsChecked == true;
|
||||||
|
|
||||||
return Task.Run(() => {
|
return Task.Run(() => {
|
||||||
Models.Watcher.SetEnabled(repo, false);
|
Models.Watcher.SetEnabled(repo, false);
|
||||||
var succ = new Commands.Fetch(repo, remote, prune, UpdateProgress).Exec();
|
|
||||||
|
if (all) {
|
||||||
|
foreach (var r in remotes.ItemsSource) {
|
||||||
|
new Commands.Fetch(repo, (r as Models.Remote).Name, prune, UpdateProgress).Exec();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
new Commands.Fetch(repo, remote, prune, UpdateProgress).Exec();
|
||||||
|
}
|
||||||
|
|
||||||
Models.Watcher.SetEnabled(repo, true);
|
Models.Watcher.SetEnabled(repo, true);
|
||||||
return succ;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="32"/>
|
<RowDefinition Height="32"/>
|
||||||
<RowDefinition Height="32"/>
|
<RowDefinition Height="32"/>
|
||||||
|
<RowDefinition x:Name="rowSSHKey" Height="0"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
|
@ -48,6 +49,7 @@
|
||||||
Grid.Row="1" Grid.Column="1"
|
Grid.Row="1" Grid.Column="1"
|
||||||
x:Name="txtUrl"
|
x:Name="txtUrl"
|
||||||
Height="24"
|
Height="24"
|
||||||
|
TextChanged="OnUrlChanged"
|
||||||
Placeholder="{DynamicResource Text.Remote.URL.Placeholder}">
|
Placeholder="{DynamicResource Text.Remote.URL.Placeholder}">
|
||||||
<controls:TextEdit.Text>
|
<controls:TextEdit.Text>
|
||||||
<Binding ElementName="me" Path="RemoteURL" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
|
<Binding ElementName="me" Path="RemoteURL" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
|
||||||
|
@ -57,5 +59,32 @@
|
||||||
</Binding>
|
</Binding>
|
||||||
</controls:TextEdit.Text>
|
</controls:TextEdit.Text>
|
||||||
</controls:TextEdit>
|
</controls:TextEdit>
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="2" Grid.Column="0"
|
||||||
|
Text="{DynamicResource Text.SSHKey}"
|
||||||
|
Margin="0,0,4,0"
|
||||||
|
HorizontalAlignment="Right"/>
|
||||||
|
<Grid Grid.Row="2" Grid.Column="1">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="30"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<controls:TextEdit
|
||||||
|
Grid.Column="0"
|
||||||
|
x:Name="txtSSHKey"
|
||||||
|
Height="24"
|
||||||
|
Placeholder="{DynamicResource Text.SSHKey.Placeholder}"/>
|
||||||
|
|
||||||
|
<controls:IconButton
|
||||||
|
Grid.Column="1"
|
||||||
|
Click="OnSelectSSHKey"
|
||||||
|
Width="24" Height="24"
|
||||||
|
Margin="2,0,0,0" Padding="4"
|
||||||
|
BorderBrush="{DynamicResource Brush.Border1}"
|
||||||
|
BorderThickness="1"
|
||||||
|
Icon="{StaticResource Icon.Folder.Open}"/>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</controls:PopupWidget>
|
</controls:PopupWidget>
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
|
||||||
namespace SourceGit.Views.Popups {
|
namespace SourceGit.Views.Popups {
|
||||||
|
@ -24,6 +28,11 @@ namespace SourceGit.Views.Popups {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
ruleName.Repo = repo;
|
ruleName.Repo = repo;
|
||||||
|
if (RemoteURL.StartsWith("git@")) {
|
||||||
|
txtSSHKey.Text = new Commands.Config(repo.Path).Get($"remote.{remote.Name}.sshkey");
|
||||||
|
} else {
|
||||||
|
txtSSHKey.Text = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetTitle() {
|
public override string GetTitle() {
|
||||||
|
@ -39,11 +48,17 @@ namespace SourceGit.Views.Popups {
|
||||||
txtUrl.GetBindingExpression(TextBox.TextProperty).UpdateSource();
|
txtUrl.GetBindingExpression(TextBox.TextProperty).UpdateSource();
|
||||||
if (Validation.GetHasError(txtUrl)) return null;
|
if (Validation.GetHasError(txtUrl)) return null;
|
||||||
|
|
||||||
|
var sshKey = txtSSHKey.Text;
|
||||||
|
|
||||||
return Task.Run(() => {
|
return Task.Run(() => {
|
||||||
Models.Watcher.SetEnabled(repo.Path, false);
|
Models.Watcher.SetEnabled(repo.Path, false);
|
||||||
if (remote == null) {
|
if (remote == null) {
|
||||||
var succ = new Commands.Remote(repo.Path).Add(RemoteName, RemoteURL);
|
var succ = new Commands.Remote(repo.Path).Add(RemoteName, RemoteURL);
|
||||||
if (succ) new Commands.Fetch(repo.Path, RemoteName, true, UpdateProgress).Exec();
|
if (succ) new Commands.Fetch(repo.Path, RemoteName, true, UpdateProgress).Exec();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(sshKey)) {
|
||||||
|
new Commands.Config(repo.Path).Set($"remote.{RemoteName}.sshkey", sshKey);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (remote.URL != RemoteURL) {
|
if (remote.URL != RemoteURL) {
|
||||||
var succ = new Commands.Remote(repo.Path).SetURL(remote.Name, RemoteURL);
|
var succ = new Commands.Remote(repo.Path).SetURL(remote.Name, RemoteURL);
|
||||||
|
@ -54,10 +69,36 @@ namespace SourceGit.Views.Popups {
|
||||||
var succ = new Commands.Remote(repo.Path).Rename(remote.Name, RemoteName);
|
var succ = new Commands.Remote(repo.Path).Rename(remote.Name, RemoteName);
|
||||||
if (succ) remote.Name = RemoteName;
|
if (succ) remote.Name = RemoteName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(sshKey)) {
|
||||||
|
new Commands.Config(repo.Path).Set($"remote.{RemoteName}.sshkey", sshKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Models.Watcher.SetEnabled(repo.Path, true);
|
Models.Watcher.SetEnabled(repo.Path, true);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnSelectSSHKey(object sender, RoutedEventArgs e) {
|
||||||
|
var initPath = Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "..", ".ssh"));
|
||||||
|
if (!Directory.Exists(initPath)) Directory.CreateDirectory(initPath);
|
||||||
|
|
||||||
|
var dialog = new OpenFileDialog();
|
||||||
|
dialog.Filter = $"SSH Private Key|*";
|
||||||
|
dialog.Title = App.Text("SSHKey");
|
||||||
|
dialog.InitialDirectory = initPath;
|
||||||
|
dialog.CheckFileExists = true;
|
||||||
|
dialog.Multiselect = false;
|
||||||
|
|
||||||
|
if (dialog.ShowDialog() == true) txtSSHKey.Text = dialog.FileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnUrlChanged(object sender, TextChangedEventArgs e) {
|
||||||
|
if (!string.IsNullOrEmpty(txtUrl.Text)) {
|
||||||
|
rowSSHKey.Height = new GridLength(txtUrl.Text.StartsWith("git@") ? 32 : 0, GridUnitType.Pixel);
|
||||||
|
} else {
|
||||||
|
rowSSHKey.Height = new GridLength(0, GridUnitType.Pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue