feature: supports squash multiple commits into selected commit (#408)

This commit is contained in:
leo 2024-08-25 21:39:59 +08:00
parent 4f8ccc4563
commit 184c89ea1d
No known key found for this signature in database
9 changed files with 45 additions and 41 deletions

View file

@ -109,7 +109,7 @@
<x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">Commit rückgängig machen</x:String> <x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">Commit rückgängig machen</x:String>
<x:String x:Key="Text.CommitCM.Reword" xml:space="preserve">Umformulieren</x:String> <x:String x:Key="Text.CommitCM.Reword" xml:space="preserve">Umformulieren</x:String>
<x:String x:Key="Text.CommitCM.SaveAsPatch" xml:space="preserve">Als Patch speichern...</x:String> <x:String x:Key="Text.CommitCM.SaveAsPatch" xml:space="preserve">Als Patch speichern...</x:String>
<x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Squash in den Vorgänger</x:String> <x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Squash Commits</x:String>
<x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">ÄNDERUNGEN</x:String> <x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">ÄNDERUNGEN</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Änderungen durchsuchen...</x:String> <x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Änderungen durchsuchen...</x:String>
<x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">DATEIEN</x:String> <x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">DATEIEN</x:String>

View file

@ -107,6 +107,7 @@
<x:String x:Key="Text.CommitCM.Reword" xml:space="preserve">Reword</x:String> <x:String x:Key="Text.CommitCM.Reword" xml:space="preserve">Reword</x:String>
<x:String x:Key="Text.CommitCM.SaveAsPatch" xml:space="preserve">Save as Patch...</x:String> <x:String x:Key="Text.CommitCM.SaveAsPatch" xml:space="preserve">Save as Patch...</x:String>
<x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Squash Into Parent</x:String> <x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Squash Into Parent</x:String>
<x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">Squash Commits since Here</x:String>
<x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">CHANGES</x:String> <x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">CHANGES</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Search Changes...</x:String> <x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Search Changes...</x:String>
<x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">FILES</x:String> <x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">FILES</x:String>
@ -531,7 +532,7 @@
<x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">Skip This Version</x:String> <x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">Skip This Version</x:String>
<x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">Software Update</x:String> <x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">Software Update</x:String>
<x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">There are currently no updates available.</x:String> <x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">There are currently no updates available.</x:String>
<x:String x:Key="Text.Squash" xml:space="preserve">Squash HEAD Into Parent</x:String> <x:String x:Key="Text.Squash" xml:space="preserve">Squash Commits</x:String>
<x:String x:Key="Text.SSHKey" xml:space="preserve">SSH Private Key:</x:String> <x:String x:Key="Text.SSHKey" xml:space="preserve">SSH Private Key:</x:String>
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Private SSH key store path</x:String> <x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Private SSH key store path</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">START</x:String> <x:String x:Key="Text.Start" xml:space="preserve">START</x:String>

View file

@ -534,7 +534,7 @@
<x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">Passer cette version</x:String> <x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">Passer cette version</x:String>
<x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">Mise à jour du logiciel</x:String> <x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">Mise à jour du logiciel</x:String>
<x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">Il n'y a pas de mise à jour pour le moment.</x:String> <x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">Il n'y a pas de mise à jour pour le moment.</x:String>
<x:String x:Key="Text.Squash" xml:space="preserve">Squash HEAD Into Parent</x:String> <x:String x:Key="Text.Squash" xml:space="preserve">Squash Commits</x:String>
<x:String x:Key="Text.SSHKey" xml:space="preserve">SSH Private Key:</x:String> <x:String x:Key="Text.SSHKey" xml:space="preserve">SSH Private Key:</x:String>
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Private SSH key store path</x:String> <x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Private SSH key store path</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">START</x:String> <x:String x:Key="Text.Start" xml:space="preserve">START</x:String>

View file

@ -527,7 +527,7 @@
<x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">Ignorar esta versão</x:String> <x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">Ignorar esta versão</x:String>
<x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">Atualização de Software</x:String> <x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">Atualização de Software</x:String>
<x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">Não há atualizações disponíveis no momento.</x:String> <x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">Não há atualizações disponíveis no momento.</x:String>
<x:String x:Key="Text.Squash" xml:space="preserve">Unir HEAD ao Parent</x:String> <x:String x:Key="Text.Squash" xml:space="preserve">Squash Commits</x:String>
<x:String x:Key="Text.SSHKey" xml:space="preserve">Chave SSH Privada:</x:String> <x:String x:Key="Text.SSHKey" xml:space="preserve">Chave SSH Privada:</x:String>
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Caminho para a chave SSH privada</x:String> <x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Caminho para a chave SSH privada</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">INICIAR</x:String> <x:String x:Key="Text.Start" xml:space="preserve">INICIAR</x:String>

View file

@ -110,6 +110,7 @@
<x:String x:Key="Text.CommitCM.Reword" xml:space="preserve">编辑提交信息</x:String> <x:String x:Key="Text.CommitCM.Reword" xml:space="preserve">编辑提交信息</x:String>
<x:String x:Key="Text.CommitCM.SaveAsPatch" xml:space="preserve">另存为补丁 ...</x:String> <x:String x:Key="Text.CommitCM.SaveAsPatch" xml:space="preserve">另存为补丁 ...</x:String>
<x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">合并此提交到上一个提交</x:String> <x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">合并此提交到上一个提交</x:String>
<x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">合并之后的提交到此处</x:String>
<x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">变更对比</x:String> <x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">变更对比</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">查找变更...</x:String> <x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">查找变更...</x:String>
<x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">文件列表</x:String> <x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">文件列表</x:String>
@ -533,7 +534,7 @@
<x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">忽略此版本</x:String> <x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">忽略此版本</x:String>
<x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">软件更新</x:String> <x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">软件更新</x:String>
<x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">当前已是最新版本。</x:String> <x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">当前已是最新版本。</x:String>
<x:String x:Key="Text.Squash" xml:space="preserve">合并HEAD到上一个提交</x:String> <x:String x:Key="Text.Squash" xml:space="preserve">压缩为单个提交</x:String>
<x:String x:Key="Text.SSHKey" xml:space="preserve">SSH密钥 </x:String> <x:String x:Key="Text.SSHKey" xml:space="preserve">SSH密钥 </x:String>
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">SSH密钥文件</x:String> <x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">SSH密钥文件</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">开 始</x:String> <x:String x:Key="Text.Start" xml:space="preserve">开 始</x:String>

View file

@ -110,6 +110,7 @@
<x:String x:Key="Text.CommitCM.Reword" xml:space="preserve">編輯提交訊息</x:String> <x:String x:Key="Text.CommitCM.Reword" xml:space="preserve">編輯提交訊息</x:String>
<x:String x:Key="Text.CommitCM.SaveAsPatch" xml:space="preserve">另存為修補檔 (patch)...</x:String> <x:String x:Key="Text.CommitCM.SaveAsPatch" xml:space="preserve">另存為修補檔 (patch)...</x:String>
<x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">合併此提交到上一個提交</x:String> <x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">合併此提交到上一個提交</x:String>
<x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">合併之後的提交到此處</x:String>
<x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">變更對比</x:String> <x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">變更對比</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">搜尋變更...</x:String> <x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">搜尋變更...</x:String>
<x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">檔案列表</x:String> <x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">檔案列表</x:String>
@ -534,7 +535,7 @@
<x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">忽略此版本</x:String> <x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">忽略此版本</x:String>
<x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">軟體更新</x:String> <x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">軟體更新</x:String>
<x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">目前已是最新版本。</x:String> <x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">目前已是最新版本。</x:String>
<x:String x:Key="Text.Squash" xml:space="preserve">合併 HEAD 至前次提交</x:String> <x:String x:Key="Text.Squash" xml:space="preserve">壓縮為單個提交</x:String>
<x:String x:Key="Text.SSHKey" xml:space="preserve">SSH 金鑰:</x:String> <x:String x:Key="Text.SSHKey" xml:space="preserve">SSH 金鑰:</x:String>
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">SSH 金鑰檔案</x:String> <x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">SSH 金鑰檔案</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">開 始</x:String> <x:String x:Key="Text.Start" xml:space="preserve">開 始</x:String>

View file

@ -1,9 +1,11 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.VisualTree; using Avalonia.VisualTree;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.ViewModels namespace SourceGit.ViewModels
@ -240,6 +242,25 @@ namespace SourceGit.ViewModels
e.Handled = true; e.Handled = true;
}; };
menu.Items.Add(reset); menu.Items.Add(reset);
var squash = new MenuItem();
squash.Header = App.Text("CommitCM.SquashCommitsSinceThis");
squash.Icon = App.CreateMenuIcon("Icons.SquashIntoParent");
squash.IsVisible = commit.IsMerged;
squash.Click += (_, e) =>
{
if (_repo.LocalChangesCount > 0)
{
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
return;
}
if (PopupHost.CanCreatePopup())
PopupHost.ShowPopup(new Squash(_repo, commit, commit.SHA));
e.Handled = true;
};
menu.Items.Add(squash);
} }
else else
{ {
@ -276,7 +297,7 @@ namespace SourceGit.ViewModels
{ {
var parent = _commits.Find(x => x.SHA == commit.Parents[0]); var parent = _commits.Find(x => x.SHA == commit.Parents[0]);
if (parent != null && PopupHost.CanCreatePopup()) if (parent != null && PopupHost.CanCreatePopup())
PopupHost.ShowPopup(new Squash(_repo, commit, parent)); PopupHost.ShowPopup(new Squash(_repo, parent, commit.SHA));
} }
e.Handled = true; e.Handled = true;

View file

@ -5,16 +5,9 @@ namespace SourceGit.ViewModels
{ {
public class Squash : Popup public class Squash : Popup
{ {
public Models.Commit Head public Models.Commit Target
{ {
get; get => _target;
private set;
}
public Models.Commit Parent
{
get;
private set;
} }
[Required(ErrorMessage = "Commit message is required!!!")] [Required(ErrorMessage = "Commit message is required!!!")]
@ -24,13 +17,12 @@ namespace SourceGit.ViewModels
set => SetProperty(ref _message, value, true); set => SetProperty(ref _message, value, true);
} }
public Squash(Repository repo, Models.Commit head, Models.Commit parent) public Squash(Repository repo, Models.Commit target, string shaToGetPreferMessage)
{ {
_repo = repo; _repo = repo;
_message = new Commands.QueryCommitFullMessage(_repo.FullPath, head.SHA).Result(); _target = target;
_message = new Commands.QueryCommitFullMessage(_repo.FullPath, shaToGetPreferMessage).Result();
Head = head;
Parent = parent;
View = new Views.Squash() { DataContext = this }; View = new Views.Squash() { DataContext = this };
} }
@ -41,7 +33,7 @@ namespace SourceGit.ViewModels
return Task.Run(() => return Task.Run(() =>
{ {
var succ = new Commands.Reset(_repo.FullPath, Parent.SHA, "--soft").Exec(); var succ = new Commands.Reset(_repo.FullPath, Target.SHA, "--soft").Exec();
if (succ) if (succ)
succ = new Commands.Commit(_repo.FullPath, _message, true).Exec(); succ = new Commands.Commit(_repo.FullPath, _message, true).Exec();
CallUIThread(() => _repo.SetWatcherEnabled(true)); CallUIThread(() => _repo.SetWatcherEnabled(true));
@ -50,6 +42,7 @@ namespace SourceGit.ViewModels
} }
private readonly Repository _repo; private readonly Repository _repo;
private Models.Commit _target;
private string _message; private string _message;
} }
} }

View file

@ -13,30 +13,17 @@
Classes="bold" Classes="bold"
Text="{DynamicResource Text.Squash}"/> Text="{DynamicResource Text.Squash}"/>
<Grid Margin="0,18,0,0" ColumnDefinitions="Auto,Auto,Auto,Auto,*"> <Grid Margin="0,18,0,0" ColumnDefinitions="Auto,Auto,*">
<Border Grid.Column="0" Background="{DynamicResource Brush.Accent}" CornerRadius="4"> <Path Grid.Column="0"
<TextBlock Text="HEAD" Classes="primary" Margin="4,0" Foreground="#FFDDDDDD"/> Margin="2,6,8,0"
</Border>
<Path Grid.Column="1"
Width="14" Height="14"
Margin="12,0,0,0"
Fill="{DynamicResource Brush.FG1}"
Data="{StaticResource Icons.Down}"
VerticalAlignment="Center"
RenderTransformOrigin="50%,50%"
RenderTransform="rotate(270deg)"/>
<Path Grid.Column="2"
Margin="6,6,8,0"
Width="14" Height="14" Width="14" Height="14"
Fill="{DynamicResource Brush.FG1}" Fill="{DynamicResource Brush.FG1}"
Data="{StaticResource Icons.Commit}"/> Data="{StaticResource Icons.Commit}"/>
<TextBlock Grid.Column="3" <TextBlock Grid.Column="1"
Classes="primary" Classes="primary"
Text="{Binding Parent.SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Text="{Binding Target.SHA, Converter={x:Static c:StringConverters.ToShortSHA}}"
Foreground="DarkOrange"/> Foreground="DarkOrange"/>
<TextBlock Grid.Column="4" Margin="8,0,0,0" Text="{Binding Parent.Subject}" TextTrimming="CharacterEllipsis"/> <TextBlock Grid.Column="2" Margin="8,0,0,0" Text="{Binding Target.Subject}" TextTrimming="CharacterEllipsis"/>
</Grid> </Grid>
<v:CommitMessageTextBox Height="120" Margin="0,4,0,0" Text="{Binding Message, Mode=TwoWay}"/> <v:CommitMessageTextBox Height="120" Margin="0,4,0,0" Text="{Binding Message, Mode=TwoWay}"/>