feature: make --recurse-submdoules an option while trying to checkout branch with submodules (#1272)

Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
leo 2025-05-06 11:12:57 +08:00
parent 054bbf7e0c
commit df29edd8f0
No known key found for this signature in database
10 changed files with 80 additions and 11 deletions

View file

@ -11,15 +11,17 @@ namespace SourceGit.Commands
Context = repo; Context = repo;
} }
public bool Branch(string branch) public bool Branch(string branch, bool recurseSubmodules)
{ {
Args = $"checkout --recurse-submodules --progress {branch}"; var options = recurseSubmodules ? "--recurse-submodules" : string.Empty;
Args = $"checkout {options} --progress {branch}";
return Exec(); return Exec();
} }
public bool Branch(string branch, string basedOn) public bool Branch(string branch, string basedOn, bool recurseSubmodules)
{ {
Args = $"checkout --recurse-submodules --progress -b {branch} {basedOn}"; var options = recurseSubmodules ? "--recurse-submodules" : string.Empty;
Args = $"checkout {options} --progress -b {branch} {basedOn}";
return Exec(); return Exec();
} }

View file

@ -110,6 +110,12 @@ namespace SourceGit.Models
set; set;
} = true; } = true;
public bool UpdateSubmodulesOnCheckoutBranch
{
get;
set;
} = true;
public AvaloniaList<Filter> HistoriesFilters public AvaloniaList<Filter> HistoriesFilters
{ {
get; get;

View file

@ -82,6 +82,7 @@
<x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">Local Changes:</x:String> <x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">Local Changes:</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Discard</x:String> <x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Discard</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stash &amp; Reapply</x:String> <x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stash &amp; Reapply</x:String>
<x:String x:Key="Text.Checkout.RecurseSubmodules" xml:space="preserve">Update all submodules</x:String>
<x:String x:Key="Text.Checkout.Target" xml:space="preserve">Branch:</x:String> <x:String x:Key="Text.Checkout.Target" xml:space="preserve">Branch:</x:String>
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry Pick</x:String> <x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry Pick</x:String>
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">Append source to commit message</x:String> <x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">Append source to commit message</x:String>

View file

@ -86,6 +86,7 @@
<x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">未提交更改 </x:String> <x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">未提交更改 </x:String>
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">丢弃更改</x:String> <x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">丢弃更改</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">贮藏并自动恢复</x:String> <x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">贮藏并自动恢复</x:String>
<x:String x:Key="Text.Checkout.RecurseSubmodules" xml:space="preserve">同时更新所有子模块</x:String>
<x:String x:Key="Text.Checkout.Target" xml:space="preserve">目标分支 </x:String> <x:String x:Key="Text.Checkout.Target" xml:space="preserve">目标分支 </x:String>
<x:String x:Key="Text.CherryPick" xml:space="preserve">挑选提交</x:String> <x:String x:Key="Text.CherryPick" xml:space="preserve">挑选提交</x:String>
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">提交信息中追加来源信息</x:String> <x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">提交信息中追加来源信息</x:String>

View file

@ -86,6 +86,7 @@
<x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">未提交變更:</x:String> <x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">未提交變更:</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">捨棄變更</x:String> <x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">捨棄變更</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">擱置變更並自動復原</x:String> <x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">擱置變更並自動復原</x:String>
<x:String x:Key="Text.Checkout.RecurseSubmodules" xml:space="preserve">同時更新所有子模組</x:String>
<x:String x:Key="Text.Checkout.Target" xml:space="preserve">目標分支:</x:String> <x:String x:Key="Text.Checkout.Target" xml:space="preserve">目標分支:</x:String>
<x:String x:Key="Text.CherryPick" xml:space="preserve">揀選提交</x:String> <x:String x:Key="Text.CherryPick" xml:space="preserve">揀選提交</x:String>
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">提交資訊中追加來源資訊</x:String> <x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">提交資訊中追加來源資訊</x:String>

View file

@ -15,11 +15,24 @@ namespace SourceGit.ViewModels
set; set;
} }
public bool IsRecurseSubmoduleVisible
{
get;
private set;
}
public bool RecurseSubmodules
{
get => _repo.Settings.UpdateSubmodulesOnCheckoutBranch;
set => _repo.Settings.UpdateSubmodulesOnCheckoutBranch = value;
}
public Checkout(Repository repo, string branch) public Checkout(Repository repo, string branch)
{ {
_repo = repo; _repo = repo;
Branch = branch; Branch = branch;
DiscardLocalChanges = false; DiscardLocalChanges = false;
IsRecurseSubmoduleVisible = repo.Submodules.Count > 0;
} }
public override Task<bool> Sure() public override Task<bool> Sure()
@ -30,6 +43,7 @@ namespace SourceGit.ViewModels
var log = _repo.CreateLog($"Checkout '{Branch}'"); var log = _repo.CreateLog($"Checkout '{Branch}'");
Use(log); Use(log);
var updateSubmodules = IsRecurseSubmoduleVisible && RecurseSubmodules;
return Task.Run(() => return Task.Run(() =>
{ {
var changes = new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).Result(); var changes = new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).Result();
@ -54,7 +68,7 @@ namespace SourceGit.ViewModels
} }
} }
var rs = new Commands.Checkout(_repo.FullPath).Use(log).Branch(Branch); var rs = new Commands.Checkout(_repo.FullPath).Use(log).Branch(Branch, updateSubmodules);
if (needPopStash) if (needPopStash)
rs = new Commands.Stash(_repo.FullPath).Use(log).Pop("stash@{0}"); rs = new Commands.Stash(_repo.FullPath).Use(log).Pop("stash@{0}");

View file

@ -28,7 +28,14 @@ namespace SourceGit.ViewModels
public bool CheckoutAfterCreated public bool CheckoutAfterCreated
{ {
get => _repo.Settings.CheckoutBranchOnCreateBranch; get => _repo.Settings.CheckoutBranchOnCreateBranch;
set => _repo.Settings.CheckoutBranchOnCreateBranch = value; set
{
if (_repo.Settings.CheckoutBranchOnCreateBranch != value)
{
_repo.Settings.CheckoutBranchOnCreateBranch = value;
OnPropertyChanged();
}
}
} }
public bool IsBareRepository public bool IsBareRepository
@ -36,6 +43,18 @@ namespace SourceGit.ViewModels
get => _repo.IsBare; get => _repo.IsBare;
} }
public bool IsRecurseSubmoduleVisible
{
get;
private set;
}
public bool RecurseSubmodules
{
get => _repo.Settings.UpdateSubmodulesOnCheckoutBranch;
set => _repo.Settings.UpdateSubmodulesOnCheckoutBranch = value;
}
public CreateBranch(Repository repo, Models.Branch branch) public CreateBranch(Repository repo, Models.Branch branch)
{ {
_repo = repo; _repo = repo;
@ -48,6 +67,7 @@ namespace SourceGit.ViewModels
BasedOn = branch; BasedOn = branch;
DiscardLocalChanges = false; DiscardLocalChanges = false;
IsRecurseSubmoduleVisible = repo.Submodules.Count > 0;
} }
public CreateBranch(Repository repo, Models.Commit commit) public CreateBranch(Repository repo, Models.Commit commit)
@ -57,6 +77,7 @@ namespace SourceGit.ViewModels
BasedOn = commit; BasedOn = commit;
DiscardLocalChanges = false; DiscardLocalChanges = false;
IsRecurseSubmoduleVisible = repo.Submodules.Count > 0;
} }
public CreateBranch(Repository repo, Models.Tag tag) public CreateBranch(Repository repo, Models.Tag tag)
@ -66,6 +87,7 @@ namespace SourceGit.ViewModels
BasedOn = tag; BasedOn = tag;
DiscardLocalChanges = false; DiscardLocalChanges = false;
IsRecurseSubmoduleVisible = repo.Submodules.Count > 0;
} }
public static ValidationResult ValidateBranchName(string name, ValidationContext ctx) public static ValidationResult ValidateBranchName(string name, ValidationContext ctx)
@ -92,6 +114,7 @@ namespace SourceGit.ViewModels
var log = _repo.CreateLog($"Create Branch '{fixedName}'"); var log = _repo.CreateLog($"Create Branch '{fixedName}'");
Use(log); Use(log);
var updateSubmodules = IsRecurseSubmoduleVisible && RecurseSubmodules;
return Task.Run(() => return Task.Run(() =>
{ {
bool succ; bool succ;
@ -119,7 +142,7 @@ namespace SourceGit.ViewModels
} }
} }
succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(fixedName, _baseOnRevision); succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(fixedName, _baseOnRevision, updateSubmodules);
if (needPopStash) if (needPopStash)
new Commands.Stash(_repo.FullPath).Use(log).Pop("stash@{0}"); new Commands.Stash(_repo.FullPath).Use(log).Pop("stash@{0}");
} }

View file

@ -1154,7 +1154,7 @@ namespace SourceGit.ViewModels
if (branch.IsLocal) if (branch.IsLocal)
{ {
if (_localChangesCount > 0) if (_localChangesCount > 0 || _submodules.Count > 0)
ShowPopup(new Checkout(this, branch.Name)); ShowPopup(new Checkout(this, branch.Name));
else else
ShowAndStartPopup(new Checkout(this, branch.Name)); ShowAndStartPopup(new Checkout(this, branch.Name));

View file

@ -17,6 +17,7 @@
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="32"/> <RowDefinition Height="32"/>
<RowDefinition Height="Auto" MinHeight="32"/> <RowDefinition Height="Auto" MinHeight="32"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
@ -35,11 +36,18 @@
<WrapPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center"> <WrapPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
<RadioButton GroupName="LocalChanges" <RadioButton GroupName="LocalChanges"
Margin="0,0,8,0" Margin="0,0,8,0"
Content="{DynamicResource Text.CreateBranch.LocalChanges.StashAndReply}" Content="{DynamicResource Text.Checkout.LocalChanges.StashAndReply}"
IsChecked="{Binding !DiscardLocalChanges, Mode=TwoWay}"/> IsChecked="{Binding !DiscardLocalChanges, Mode=TwoWay}"/>
<RadioButton GroupName="LocalChanges" <RadioButton GroupName="LocalChanges"
Content="{DynamicResource Text.CreateBranch.LocalChanges.Discard}"/> Content="{DynamicResource Text.Checkout.LocalChanges.Discard}"/>
</WrapPanel> </WrapPanel>
<CheckBox Grid.Row="2" Grid.Column="1"
Height="32"
Content="{DynamicResource Text.Checkout.RecurseSubmodules}"
IsChecked="{Binding RecurseSubmodules, Mode=TwoWay}"
IsVisible="{Binding IsRecurseSubmoduleVisible}"
ToolTip.Tip="--recurse-submodules"/>
</Grid> </Grid>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View file

@ -14,7 +14,7 @@
<TextBlock FontSize="18" <TextBlock FontSize="18"
Classes="bold" Classes="bold"
Text="{DynamicResource Text.CreateBranch.Title}"/> Text="{DynamicResource Text.CreateBranch.Title}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32,Auto,Auto,Auto" ColumnDefinitions="140,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32,Auto,Auto,Auto,Auto" ColumnDefinitions="140,*">
<TextBlock Grid.Row="0" Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
@ -83,6 +83,19 @@
Content="{DynamicResource Text.CreateBranch.Checkout}" Content="{DynamicResource Text.CreateBranch.Checkout}"
IsChecked="{Binding CheckoutAfterCreated, Mode=TwoWay}" IsChecked="{Binding CheckoutAfterCreated, Mode=TwoWay}"
IsVisible="{Binding !IsBareRepository}"/> IsVisible="{Binding !IsBareRepository}"/>
<CheckBox Grid.Row="5" Grid.Column="1"
Content="{DynamicResource Text.Checkout.RecurseSubmodules}"
IsChecked="{Binding RecurseSubmodules, Mode=TwoWay}"
ToolTip.Tip="--recurse-submodules">
<CheckBox.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="IsBareRepository" Converter="{x:Static BoolConverters.Not}"/>
<Binding Path="CheckoutAfterCreated"/>
<Binding Path="IsRecurseSubmoduleVisible"/>
</MultiBinding>
</CheckBox.IsVisible>
</CheckBox>
</Grid> </Grid>
</StackPanel> </StackPanel>
</UserControl> </UserControl>