fix: can not squash and fixup until first picked/edit/reword commit in interactive rebase exists list (#1362)
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Waiting to run

Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
leo 2025-05-25 13:46:27 +08:00
parent d7c3bb7150
commit ac26d5bb06
No known key found for this signature in database
3 changed files with 63 additions and 26 deletions

View file

@ -35,7 +35,7 @@ namespace SourceGit.ViewModels
public Models.InteractiveRebaseAction Action public Models.InteractiveRebaseAction Action
{ {
get => _action; get => _action;
private set => SetProperty(ref _action, value); set => SetProperty(ref _action, value);
} }
public string Subject public string Subject
@ -68,11 +68,6 @@ namespace SourceGit.ViewModels
CanSquashOrFixup = canSquashOrFixup; CanSquashOrFixup = canSquashOrFixup;
} }
public void SetAction(object param)
{
Action = (Models.InteractiveRebaseAction)param;
}
private Models.InteractiveRebaseAction _action = Models.InteractiveRebaseAction.Pick; private Models.InteractiveRebaseAction _action = Models.InteractiveRebaseAction.Pick;
private string _subject; private string _subject;
private string _fullMessage; private string _fullMessage;
@ -158,10 +153,8 @@ namespace SourceGit.ViewModels
var prev = Items[idx - 1]; var prev = Items[idx - 1];
Items.RemoveAt(idx - 1); Items.RemoveAt(idx - 1);
Items.Insert(idx, prev); Items.Insert(idx, prev);
item.CanSquashOrFixup = true;
prev.CanSquashOrFixup = idx < Items.Count - 1;
SelectedItem = item; SelectedItem = item;
UpdateItems();
} }
} }
@ -173,13 +166,23 @@ namespace SourceGit.ViewModels
var next = Items[idx + 1]; var next = Items[idx + 1];
Items.RemoveAt(idx + 1); Items.RemoveAt(idx + 1);
Items.Insert(idx, next); Items.Insert(idx, next);
item.CanSquashOrFixup = idx < Items.Count - 2;
next.CanSquashOrFixup = true;
SelectedItem = item; SelectedItem = item;
UpdateItems();
} }
} }
public void ChangeAction(InteractiveRebaseItem item, Models.InteractiveRebaseAction action)
{
if (!item.CanSquashOrFixup)
{
if (action == Models.InteractiveRebaseAction.Squash || action == Models.InteractiveRebaseAction.Fixup)
return;
}
item.Action = action;
UpdateItems();
}
public Task<bool> Start() public Task<bool> Start()
{ {
_repo.SetWatcherEnabled(false); _repo.SetWatcherEnabled(false);
@ -210,6 +213,27 @@ namespace SourceGit.ViewModels
}); });
} }
private void UpdateItems()
{
if (Items.Count == 0)
return;
var hasValidParent = false;
for (var i = Items.Count - 1; i >= 0; i--)
{
var item = Items[i];
if (hasValidParent)
{
item.CanSquashOrFixup = true;
}
else
{
item.CanSquashOrFixup = false;
hasValidParent = item.Action != Models.InteractiveRebaseAction.Drop;
}
}
}
private Repository _repo = null; private Repository _repo = null;
private bool _isLoading = false; private bool _isLoading = false;
private InteractiveRebaseItem _selectedItem = null; private InteractiveRebaseItem _selectedItem = null;

View file

@ -107,7 +107,7 @@
<Button Grid.Column="1" Opacity="1" Margin="4,0,0,0" Padding="8,2" Background="Transparent"> <Button Grid.Column="1" Opacity="1" Margin="4,0,0,0" Padding="8,2" Background="Transparent">
<Button.Flyout> <Button.Flyout>
<MenuFlyout Placement="BottomEdgeAlignedLeft" VerticalOffset="-4"> <MenuFlyout Placement="BottomEdgeAlignedLeft" VerticalOffset="-4">
<MenuItem InputGesture="P" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Pick}"> <MenuItem InputGesture="P" Click="OnChangeRebaseAction" Tag="{x:Static m:InteractiveRebaseAction.Pick}">
<MenuItem.Icon> <MenuItem.Icon>
<Ellipse Width="14" Height="14" Fill="Green"/> <Ellipse Width="14" Height="14" Fill="Green"/>
</MenuItem.Icon> </MenuItem.Icon>
@ -119,7 +119,7 @@
</MenuItem.Header> </MenuItem.Header>
</MenuItem> </MenuItem>
<MenuItem InputGesture="E" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Edit}"> <MenuItem InputGesture="E" Click="OnChangeRebaseAction" Tag="{x:Static m:InteractiveRebaseAction.Edit}">
<MenuItem.Icon> <MenuItem.Icon>
<Ellipse Width="14" Height="14" Fill="Orange"/> <Ellipse Width="14" Height="14" Fill="Orange"/>
</MenuItem.Icon> </MenuItem.Icon>
@ -131,7 +131,7 @@
</MenuItem.Header> </MenuItem.Header>
</MenuItem> </MenuItem>
<MenuItem InputGesture="R" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Reword}"> <MenuItem InputGesture="R" Click="OnChangeRebaseAction" Tag="{x:Static m:InteractiveRebaseAction.Reword}">
<MenuItem.Icon> <MenuItem.Icon>
<Ellipse Width="14" Height="14" Fill="Orange"/> <Ellipse Width="14" Height="14" Fill="Orange"/>
</MenuItem.Icon> </MenuItem.Icon>
@ -143,7 +143,7 @@
</MenuItem.Header> </MenuItem.Header>
</MenuItem> </MenuItem>
<MenuItem InputGesture="S" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Squash}" IsVisible="{Binding CanSquashOrFixup}"> <MenuItem InputGesture="S" Click="OnChangeRebaseAction" Tag="{x:Static m:InteractiveRebaseAction.Squash}" IsVisible="{Binding CanSquashOrFixup}">
<MenuItem.Icon> <MenuItem.Icon>
<Ellipse Width="14" Height="14" Fill="LightGray"/> <Ellipse Width="14" Height="14" Fill="LightGray"/>
</MenuItem.Icon> </MenuItem.Icon>
@ -155,7 +155,7 @@
</MenuItem.Header> </MenuItem.Header>
</MenuItem> </MenuItem>
<MenuItem InputGesture="F" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Fixup}" IsVisible="{Binding CanSquashOrFixup}"> <MenuItem InputGesture="F" Click="OnChangeRebaseAction" Tag="{x:Static m:InteractiveRebaseAction.Fixup}" IsVisible="{Binding CanSquashOrFixup}">
<MenuItem.Icon> <MenuItem.Icon>
<Ellipse Width="14" Height="14" Fill="LightGray"/> <Ellipse Width="14" Height="14" Fill="LightGray"/>
</MenuItem.Icon> </MenuItem.Icon>
@ -167,7 +167,7 @@
</MenuItem.Header> </MenuItem.Header>
</MenuItem> </MenuItem>
<MenuItem InputGesture="D" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Drop}"> <MenuItem InputGesture="D" Click="OnChangeRebaseAction" Tag="{x:Static m:InteractiveRebaseAction.Drop}">
<MenuItem.Icon> <MenuItem.Icon>
<Ellipse Width="14" Height="14" Fill="Red"/> <Ellipse Width="14" Height="14" Fill="Red"/>
</MenuItem.Icon> </MenuItem.Icon>
@ -280,7 +280,7 @@
Minimum="0" Minimum="0"
Maximum="100" Maximum="100"
IsVisible="False"/> IsVisible="False"/>
<Button Grid.Column="1" Classes="flat primary" MinWidth="80" Content="{DynamicResource Text.Start}" Click="StartJobs"/> <Button Grid.Column="1" Classes="flat primary" MinWidth="80" Content="{DynamicResource Text.Start}" Click="OnStartJobs"/>
<Button Grid.Column="2" Classes="flat" Margin="8,0,0,0" MinWidth="80" Content="{DynamicResource Text.Cancel}" Click="CloseWindow"/> <Button Grid.Column="2" Classes="flat" Margin="8,0,0,0" MinWidth="80" Content="{DynamicResource Text.Cancel}" Click="CloseWindow"/>
</Grid> </Grid>
</Grid> </Grid>

View file

@ -29,32 +29,32 @@ namespace SourceGit.Views
if (e.Key == Key.P) if (e.Key == Key.P)
{ {
item.SetAction(Models.InteractiveRebaseAction.Pick); vm.ChangeAction(item, Models.InteractiveRebaseAction.Pick);
e.Handled = true; e.Handled = true;
} }
else if (e.Key == Key.E) else if (e.Key == Key.E)
{ {
item.SetAction(Models.InteractiveRebaseAction.Edit); vm.ChangeAction(item, Models.InteractiveRebaseAction.Edit);
e.Handled = true; e.Handled = true;
} }
else if (e.Key == Key.R) else if (e.Key == Key.R)
{ {
item.SetAction(Models.InteractiveRebaseAction.Reword); vm.ChangeAction(item, Models.InteractiveRebaseAction.Reword);
e.Handled = true; e.Handled = true;
} }
else if (e.Key == Key.S) else if (e.Key == Key.S)
{ {
item.SetAction(Models.InteractiveRebaseAction.Squash); vm.ChangeAction(item, Models.InteractiveRebaseAction.Squash);
e.Handled = true; e.Handled = true;
} }
else if (e.Key == Key.F) else if (e.Key == Key.F)
{ {
item.SetAction(Models.InteractiveRebaseAction.Fixup); vm.ChangeAction(item, Models.InteractiveRebaseAction.Fixup);
e.Handled = true; e.Handled = true;
} }
else if (e.Key == Key.D) else if (e.Key == Key.D)
{ {
item.SetAction(Models.InteractiveRebaseAction.Drop); vm.ChangeAction(item, Models.InteractiveRebaseAction.Drop);
e.Handled = true; e.Handled = true;
} }
else if (e.KeyModifiers == KeyModifiers.Alt && e.Key == Key.Up) else if (e.KeyModifiers == KeyModifiers.Alt && e.Key == Key.Up)
@ -153,8 +153,21 @@ namespace SourceGit.Views
e.Handled = true; e.Handled = true;
} }
} }
private void OnChangeRebaseAction(object sender, RoutedEventArgs e)
{
if (DataContext is ViewModels.InteractiveRebase vm &&
sender is Control
{
DataContext: ViewModels.InteractiveRebaseItem item,
Tag: Models.InteractiveRebaseAction action
})
vm.ChangeAction(item, action);
private async void StartJobs(object _1, RoutedEventArgs _2) e.Handled = true;
}
private async void OnStartJobs(object _1, RoutedEventArgs _2)
{ {
var vm = DataContext as ViewModels.InteractiveRebase; var vm = DataContext as ViewModels.InteractiveRebase;
if (vm == null) if (vm == null)