mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-05-22 04:34:59 +00:00
feature(Submodule): supports git submodule
This commit is contained in:
parent
789231fdc4
commit
0132fc496b
8 changed files with 359 additions and 13 deletions
72
SourceGit/UI/AddSubmodule.xaml
Normal file
72
SourceGit/UI/AddSubmodule.xaml
Normal file
|
@ -0,0 +1,72 @@
|
|||
<UserControl x:Class="SourceGit.UI.AddSubmodule"
|
||||
x:Name="me"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:helpers="clr-namespace:SourceGit.Helpers"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="192" d:DesignWidth="500" Height="192" Width="500">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="32"/>
|
||||
<RowDefinition Height="16"/>
|
||||
<RowDefinition Height="32"/>
|
||||
<RowDefinition Height="32"/>
|
||||
<RowDefinition Height="32"/>
|
||||
<RowDefinition Height="16"/>
|
||||
<RowDefinition Height="32"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="150"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Grid.Row="0" Grid.ColumnSpan="2" FontWeight="DemiBold" FontSize="18" Content="Add Submodule"/>
|
||||
|
||||
<Label Grid.Row="2" Grid.Column="0" HorizontalAlignment="Right" Content="URL :"/>
|
||||
<TextBox x:Name="txtRepoUrl" Grid.Row="2" Grid.Column="1"
|
||||
Height="24"
|
||||
helpers:TextBoxHelper.Placeholder="Git Repository URL">
|
||||
<TextBox.Text>
|
||||
<Binding Path="RepoURL" ElementName="me" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
|
||||
<Binding.ValidationRules>
|
||||
<helpers:RemoteUriRule/>
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</TextBox.Text>
|
||||
</TextBox>
|
||||
|
||||
<Label Grid.Row="3" Grid.Column="0" HorizontalAlignment="Right" Content="Parent Folder :"/>
|
||||
<TextBox Grid.Row="3" Grid.Column="1"
|
||||
x:Name="txtPath"
|
||||
Height="24"
|
||||
helpers:TextBoxHelper.Placeholder="Relative foler to store this module. Optional.">
|
||||
<TextBox.Text>
|
||||
<Binding Path="LocalPath" ElementName="me" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
|
||||
<Binding.ValidationRules>
|
||||
<helpers:SubmodulePathRequiredRule/>
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</TextBox.Text>
|
||||
</TextBox>
|
||||
|
||||
<CheckBox Grid.Row="4" Grid.Column="1"
|
||||
x:Name="chkRecursive"
|
||||
IsChecked="True"
|
||||
Content="Fetch nested submodules"/>
|
||||
|
||||
<Grid Grid.Row="6" Grid.ColumnSpan="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="80"/>
|
||||
<ColumnDefinition Width="8"/>
|
||||
<ColumnDefinition Width="80"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Grid.Column="1" Click="Sure" Content="SURE" Style="{StaticResource Style.Button.AccentBordered}"/>
|
||||
<Button Grid.Column="3" Click="Cancel" Content="CANCEL" Style="{StaticResource Style.Button.Bordered}"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
71
SourceGit/UI/AddSubmodule.xaml.cs
Normal file
71
SourceGit/UI/AddSubmodule.xaml.cs
Normal file
|
@ -0,0 +1,71 @@
|
|||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace SourceGit.UI {
|
||||
|
||||
/// <summary>
|
||||
/// Dialog to add new submodule.
|
||||
/// </summary>
|
||||
public partial class AddSubmodule : UserControl {
|
||||
private Git.Repository repo = null;
|
||||
|
||||
/// <summary>
|
||||
/// Submodule's repository URL.
|
||||
/// </summary>
|
||||
public string RepoURL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Submodule's relative path.
|
||||
/// </summary>
|
||||
public string LocalPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <param name="opened"></param>
|
||||
public AddSubmodule(Git.Repository opened) {
|
||||
repo = opened;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show this dialog.
|
||||
/// </summary>
|
||||
/// <param name="repo"></param>
|
||||
public static void Show(Git.Repository repo) {
|
||||
PopupManager.Show(new AddSubmodule(repo));
|
||||
}
|
||||
|
||||
#region EVENTS
|
||||
private void SelectFolder(object sender, RoutedEventArgs e) {
|
||||
var dialog = new System.Windows.Forms.FolderBrowserDialog();
|
||||
dialog.Description = "Select Folder To Clone Repository";
|
||||
dialog.SelectedPath = repo.Path;
|
||||
dialog.ShowNewFolderButton = true;
|
||||
|
||||
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
|
||||
txtPath.Text = dialog.SelectedPath;
|
||||
}
|
||||
}
|
||||
|
||||
private async void Sure(object sender, RoutedEventArgs e) {
|
||||
txtRepoUrl.GetBindingExpression(TextBox.TextProperty).UpdateSource();
|
||||
if (Validation.GetHasError(txtRepoUrl)) return;
|
||||
|
||||
txtPath.GetBindingExpression(TextBox.TextProperty).UpdateSource();
|
||||
if (Validation.GetHasError(txtPath)) return;
|
||||
|
||||
var recursive = chkRecursive.IsChecked == true;
|
||||
|
||||
PopupManager.Lock();
|
||||
await Task.Run(() => repo.AddSubmodule(RepoURL, LocalPath, recursive, PopupManager.UpdateStatus));
|
||||
PopupManager.Close(true);
|
||||
}
|
||||
|
||||
private void Cancel(object sender, RoutedEventArgs e) {
|
||||
PopupManager.Close();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -51,9 +51,18 @@
|
|||
<StackPanel Orientation="Horizontal">
|
||||
<Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Manager}"/>
|
||||
<Label Content="Repositories"/>
|
||||
<Path Width="12" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Navigator}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<Button x:Name="btnParent" Click="GotoParent" ToolTip="Open Parent Repository" Padding="0" Margin="6,0,0,0" Visibility="Collapsed">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Git}"/>
|
||||
<Label x:Name="txtParent"/>
|
||||
<Path Width="12" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Navigator}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Path Width="12" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Navigator}"/>
|
||||
|
||||
<Path Margin="6,0,0,0" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Git}"/>
|
||||
<Label x:Name="repoName"/>
|
||||
</StackPanel>
|
||||
|
@ -133,13 +142,16 @@
|
|||
<!-- Left panel -->
|
||||
<Grid Grid.Column="0" x:Name="main" Background="{StaticResource Brush.BG4}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="24"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="24"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="24"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="24"/>
|
||||
<RowDefinition Height="1"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="24"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
|
@ -194,7 +206,7 @@
|
|||
</ListView>
|
||||
|
||||
<!-- LOCAL BRANCHES -->
|
||||
<Grid Grid.Row="2" Margin="4,0,0,0">
|
||||
<Grid Grid.Row="2" Margin="4,0,2,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="16"/>
|
||||
|
@ -275,7 +287,7 @@
|
|||
</TreeView>
|
||||
|
||||
<!-- REMOTES -->
|
||||
<Grid Grid.Row="4" Margin="4,0,0,0">
|
||||
<Grid Grid.Row="4" Margin="4,0,2,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="16"/>
|
||||
|
@ -362,7 +374,7 @@
|
|||
Grid.Row="6"
|
||||
Style="{StaticResource Style.ToggleButton.Expender}"
|
||||
IsChecked="{Binding Source={x:Static source:App.Preference}, Path=UIShowTags, Mode=TwoWay}">
|
||||
<Grid Margin="4,0,0,0">
|
||||
<Grid Margin="4,0,2,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="16"/>
|
||||
|
@ -374,8 +386,9 @@
|
|||
</Button>
|
||||
</Grid>
|
||||
</ToggleButton>
|
||||
<Rectangle Grid.Row="7" Height="1" Fill="{StaticResource Brush.BG3}"/>
|
||||
<DataGrid
|
||||
Grid.Row="7"
|
||||
Grid.Row="8"
|
||||
x:Name="tagList"
|
||||
Visibility="{Binding ElementName=tagListToggle, Path=IsChecked, Converter={StaticResource Bool2Collapsed}}"
|
||||
Background="{StaticResource Brush.BG3}"
|
||||
|
@ -383,12 +396,12 @@
|
|||
Height="200"
|
||||
LostFocus="TagLostFocus"
|
||||
SelectionChanged="TagSelectionChanged"
|
||||
ContextMenuOpening="TagContextMenuOpening"
|
||||
ContextMenuOpening="TagContextMenuOpening"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
SelectionMode="Single"
|
||||
SelectionUnit="FullRow">
|
||||
<DataGrid.Resources>
|
||||
<DataGrid.Resources>
|
||||
<Style x:Key="Style.DataGridText.TagName" TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource Brush.FG}"/>
|
||||
|
@ -421,6 +434,63 @@
|
|||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<!-- SUBMODULES -->
|
||||
<ToggleButton
|
||||
x:Name="submoduleListToggle"
|
||||
Grid.Row="9"
|
||||
Style="{StaticResource Style.ToggleButton.Expender}"
|
||||
IsChecked="False">
|
||||
<Grid Margin="4,0,2,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="16"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Grid.Column="0" x:Name="submoduleCount" Content="SUBMODULES" Style="{StaticResource Style.Label.GroupHeader}"/>
|
||||
<Button Grid.Column="1" Click="OpenAddSubmodule" ToolTip="ADD SUBMODULE">
|
||||
<Path Width="14" Height="14" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Submodule}"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</ToggleButton>
|
||||
<DataGrid
|
||||
Grid.Row="11"
|
||||
x:Name="submoduleList"
|
||||
Visibility="{Binding ElementName=submoduleListToggle, Path=IsChecked, Converter={StaticResource Bool2Collapsed}}"
|
||||
Background="{StaticResource Brush.BG3}"
|
||||
RowHeight="24"
|
||||
Height="200"
|
||||
LostFocus="SubmoduleLostFocus"
|
||||
ContextMenuOpening="SubmoduleContextMenuOpening"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
SelectionMode="Single"
|
||||
SelectionUnit="FullRow">
|
||||
<DataGrid.Resources>
|
||||
<Style x:Key="Style.DataGridText.SubmodulePath" TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource Brush.FG}"/>
|
||||
</Style>
|
||||
</DataGrid.Resources>
|
||||
|
||||
<DataGrid.RowStyle>
|
||||
<Style TargetType="{x:Type DataGridRow}" BasedOn="{StaticResource Style.DataGridRow}">
|
||||
<EventSetter Event="MouseDoubleClick" Handler="SubmoduleMouseDoubleClick"/>
|
||||
</Style>
|
||||
</DataGrid.RowStyle>
|
||||
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Width="26">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Path Width="10" Style="{StaticResource Style.Icon}" Data="{StaticResource Icon.Submodule}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTextColumn Width="*" IsReadOnly="True" Binding="{Binding}" ElementStyle="{StaticResource Style.DataGridText.SubmodulePath}"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</Grid>
|
||||
|
||||
<!-- Splitter -->
|
||||
|
|
|
@ -55,7 +55,8 @@ namespace SourceGit.UI {
|
|||
opened.OnTagChanged = UpdateTags;
|
||||
opened.OnStashChanged = UpdateStashes;
|
||||
opened.OnBranchChanged = () => UpdateBranches(false);
|
||||
opened.OnCommitsChanged = UpdateHistories;
|
||||
opened.OnCommitsChanged = UpdateHistories;
|
||||
opened.OnSubmoduleChanged = UpdateSubmodules;
|
||||
opened.OnNavigateCommit = commit => {
|
||||
Dispatcher.Invoke(() => {
|
||||
workspace.SelectedItem = historiesSwitch;
|
||||
|
@ -70,11 +71,19 @@ namespace SourceGit.UI {
|
|||
histories.Repo = opened;
|
||||
commits.Repo = opened;
|
||||
|
||||
if (repo.Parent != null) {
|
||||
btnParent.Visibility = Visibility.Visible;
|
||||
txtParent.Content = repo.Parent.Name;
|
||||
} else {
|
||||
btnParent.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
UpdateBranches();
|
||||
UpdateHistories();
|
||||
UpdateLocalChanges();
|
||||
UpdateStashes();
|
||||
UpdateTags();
|
||||
UpdateSubmodules();
|
||||
}
|
||||
|
||||
#region DATA_UPDATE
|
||||
|
@ -270,6 +279,16 @@ namespace SourceGit.UI {
|
|||
});
|
||||
}
|
||||
|
||||
private void UpdateSubmodules() {
|
||||
Task.Run(() => {
|
||||
var submodules = repo.Submodules();
|
||||
Dispatcher.Invoke(() => {
|
||||
submoduleCount.Content = $"SUBMODULES ({submodules.Count})";
|
||||
submoduleList.ItemsSource = submodules;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void Cleanup(object sender, RoutedEventArgs e) {
|
||||
localBranchTree.ItemsSource = null;
|
||||
remoteBranchTree.ItemsSource = null;
|
||||
|
@ -290,6 +309,12 @@ namespace SourceGit.UI {
|
|||
repo.Close();
|
||||
}
|
||||
|
||||
private void GotoParent(object sender, RoutedEventArgs e) {
|
||||
if (repo.Parent == null) return;
|
||||
repo.Parent.Open();
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OpenFetch(object sender, RoutedEventArgs e) {
|
||||
Fetch.Show(repo);
|
||||
}
|
||||
|
@ -897,6 +922,58 @@ namespace SourceGit.UI {
|
|||
}
|
||||
#endregion
|
||||
|
||||
#region SUBMODULES
|
||||
private void OpenAddSubmodule(object sender, RoutedEventArgs e) {
|
||||
AddSubmodule.Show(repo);
|
||||
}
|
||||
|
||||
private void SubmoduleLostFocus(object sender, RoutedEventArgs e) {
|
||||
(sender as DataGrid).UnselectAll();
|
||||
}
|
||||
|
||||
private void SubmoduleContextMenuOpening(object sender, ContextMenuEventArgs e) {
|
||||
var path = (sender as DataGrid).SelectedItem as string;
|
||||
if (path == null) return;
|
||||
|
||||
var open = new MenuItem();
|
||||
open.Header = "Open Submodule Repository";
|
||||
open.Click += (o, ev) => {
|
||||
var sub = new Git.Repository();
|
||||
sub.Path = Path.Combine(repo.Path, path);
|
||||
sub.Name = Path.GetFileName(path);
|
||||
sub.Parent = repo;
|
||||
sub.Open();
|
||||
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var copy = new MenuItem();
|
||||
copy.Header = "Copy Relative Path";
|
||||
copy.Click += (o, ev) => {
|
||||
Clipboard.SetText(path);
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var menu = new ContextMenu();
|
||||
menu.Items.Add(open);
|
||||
menu.Items.Add(copy);
|
||||
menu.IsOpen = true;
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void SubmoduleMouseDoubleClick(object sender, MouseButtonEventArgs e) {
|
||||
var path = (sender as DataGridRow).DataContext as string;
|
||||
if (path == null) return;
|
||||
|
||||
var sub = new Git.Repository();
|
||||
sub.Path = Path.Combine(repo.Path, path);
|
||||
sub.Name = Path.GetFileName(path);
|
||||
sub.Parent = repo;
|
||||
sub.Open();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TREES
|
||||
private TreeViewItem FindTreeViewItem(ItemsControl item, BranchNode node) {
|
||||
if (item == null) return null;
|
||||
|
|
|
@ -53,7 +53,6 @@ namespace SourceGit.UI {
|
|||
/// <param name="repo"></param>
|
||||
private void ShowDashboard(Git.Repository repo) {
|
||||
Dispatcher.Invoke(() => {
|
||||
if (body.Content is Dashboard) return;
|
||||
body.Content = new Dashboard(repo);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue