1
0

fix: 无法正确唤起Merge的问题

This commit is contained in:
Ca2didi 2025-05-21 01:36:38 +08:00
parent 3afafd4e91
commit ef1395945f
6 changed files with 94 additions and 98 deletions

View File

@ -8,7 +8,7 @@ public enum RepositoryResetMethod
Keep, Keep,
/// <summary> /// <summary>
/// Tracked files will being reset, changes will being reset. /// Tracked files will being reset, changes will being merged.
/// </summary> /// </summary>
Soft, Soft,
@ -16,14 +16,4 @@ public enum RepositoryResetMethod
/// All files will being reset, changes will being reset, changes list will being cleaned. /// All files will being reset, changes will being reset, changes list will being cleaned.
/// </summary> /// </summary>
Hard, Hard,
/// <summary>
/// Tracked files will being reset, changes will being merged.
/// </summary>
Merge,
/// <summary>
/// All files will being reset, changes will being merged.
/// </summary>
HardMerge
} }

View File

@ -837,9 +837,9 @@ public class RepositoryService : BaseService<RepositoryService>
try try
{ {
var mergeChanges = method is RepositoryResetMethod.Merge or RepositoryResetMethod.HardMerge; var mergeChanges = method is RepositoryResetMethod.Soft;
var resetChanges = method is RepositoryResetMethod.Soft or RepositoryResetMethod.Hard; var resetChanges = method is RepositoryResetMethod.Soft or RepositoryResetMethod.Hard;
var hardMode = method is RepositoryResetMethod.Hard or RepositoryResetMethod.HardMerge; var hardMode = method is RepositoryResetMethod.Hard;
List<WorkspaceFile> unmerged = new(); List<WorkspaceFile> unmerged = new();
// Apply files excepts local changed. // Apply files excepts local changed.
@ -892,7 +892,6 @@ public class RepositoryService : BaseService<RepositoryService>
} }
catch (Exception exception) { Console.WriteLine(exception); } catch (Exception exception) { Console.WriteLine(exception); }
UIHelper.NotifyError(e); UIHelper.NotifyError(e);
Console.WriteLine(e); Console.WriteLine(e);
await DeleteFromDiskAsync(repo); await DeleteFromDiskAsync(repo);
@ -938,47 +937,45 @@ public class RepositoryService : BaseService<RepositoryService>
} }
} }
public async ValueTask MergeFilesAsync(RepositoryModel repo, RepositoryFileTreeAccessor repoAccessor, IEnumerable<WorkspaceFile> unmerged) public async ValueTask<bool> MergeFilesAsync(RepositoryModel repo, RepositoryFileTreeAccessor repoAccessor, IEnumerable<WorkspaceFile> unmerged)
{ {
var root = PathUtility.GetWorkspaceManagerPath(Api.C.Username.Value, repo.OwnerName, repo.Name); var root = PathUtility.GetWorkspaceManagerPath(Api.C.Username.Value, repo.OwnerName, repo.Name);
var srcTem = Path.Combine(root, "MergeInTemp"); var tempFolder = Path.Combine(root, "MergeInTemp");
var wsRoot = PathUtility.GetWorkspacePath(Api.C.Username.Value, repo.OwnerName, repo.Name);
var left = Path.Combine(tempFolder, "left");
var right = Path.Combine(tempFolder, "right");
using (Disposable.Create(srcTem, r => Directory.Delete(r, true))) using (Disposable.Create(tempFolder, r => Directory.Delete(r, true)))
{ {
Directory.CreateDirectory(root); Directory.CreateDirectory(root);
// Prepare server files foreach (var p in unmerged)
var wsRoot = PathUtility.GetWorkspacePath(Api.C.Username.Value, repo.OwnerName, repo.Name);
var vm = new MergeDialogViewModel(repo, unmerged, srcTem, wsRoot);
foreach (var f in vm.MergeFiles)
{ {
var pf = WorkPath.ToPlatformPath(f.WorkPath, vm.SrcFolder); try
Directory.CreateDirectory(Path.GetDirectoryName(pf)!); {
await using var fs = File.Create(pf); // Prepare for left and right file
repoAccessor.TryWriteDataIntoDisk(f.WorkPath, fs, out _); var wfs = WorkPath.ToPlatformPath(wsRoot, p.WorkPath);
} File.Copy(wfs, left, true);
await using var rightFs = File.Create(right);
repoAccessor.TryWriteDataIntoDisk(p.WorkPath, rightFs, out _);
// Raise merge window // Raise dialog window
var opt = UIHelper.DefaultOverlayDialogOptionsYesNo(); var opt = UIHelper.DefaultOverlayDialogOptionsYesNo();
opt.Buttons = DialogButton.OK; opt.Buttons = DialogButton.None;
opt.Title = "Merge files"; opt.Title = "Merge files";
opt.FullScreen = true; opt.IsCloseButtonVisible = true;
opt.IsCloseButtonVisible = false;
var vm = new MergeDialogViewModel(p.WorkPath, wfs, p.WorkPath, left, right);
await OverlayDialog.ShowModal<MergeDialogView, MergeDialogViewModel>(vm, AppDefaultValues.HostId, opt); await OverlayDialog.ShowModal<MergeDialogView, MergeDialogViewModel>(vm, AppDefaultValues.HostId, opt);
}
// Rollback files catch (Exception e)
foreach (var f in vm.MergeFiles)
{ {
var copyFrom = WorkPath.ToPlatformPath(f.WorkPath, vm.TmpFolder); Console.Error.WriteLine(e);
if (!File.Exists(copyFrom)) continue; // If file existed, override it. }
}
}
var copyTo = WorkPath.ToPlatformPath(f.WorkPath, vm.DstFolder); return true;
Directory.CreateDirectory(Path.GetDirectoryName(copyTo)!);
File.Copy(copyFrom, copyTo, true);
}
}
} }
public async ValueTask<bool> UpdateCommitsHistoryFromServerAsync(RepositoryModel repo) public async ValueTask<bool> UpdateCommitsHistoryFromServerAsync(RepositoryModel repo)

View File

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Flawless.Abstraction; using Flawless.Abstraction;
@ -11,34 +12,42 @@ namespace Flawless.Client.ViewModels.ModalBox;
public partial class MergeDialogViewModel : ViewModelBase public partial class MergeDialogViewModel : ViewModelBase
{ {
public ObservableCollection<WorkspaceFile> MergeFiles { get; } [Reactive] private string _ws;
public RepositoryModel Repository { get; } [Reactive] private string _final;
public string SrcFolder { get; } [Reactive] private string _leftFile; // Local file
public string DstFolder { get; } [Reactive] private string _rightFile; // Remote file
public string TmpFolder { get; } public MergeDialogViewModel(string ws, string final, string fileWorkPath, string leftFile, string rightFile)
public MergeDialogViewModel(RepositoryModel repository, IEnumerable<WorkspaceFile> files,
string srcFolder, string dstFolder)
{ {
Repository = repository; _ws = ws;
MergeFiles = new ObservableCollection<WorkspaceFile>(files); _final = final;
SrcFolder = srcFolder; _leftFile = leftFile;
DstFolder = dstFolder; _rightFile = rightFile;
TmpFolder = Directory.CreateTempSubdirectory("Flawless_Merge").Name;
} }
[ReactiveCommand] [ReactiveCommand]
private async Task RaiseMergeToolsAsync(string fileWorkPath) private async Task RaiseMergeToolsAsync(string fileWorkPath)
{ {
var srcFile = WorkPath.ToPlatformPath(fileWorkPath, SrcFolder); var result = Process.Start($"meld \"{LeftFile}\" \"{RightFile}\"");
var dstFile = Path.Combine(fileWorkPath, DstFolder); }
var tmpFile = Path.Combine(fileWorkPath, TmpFolder);
[ReactiveCommand]
private Task UseLeftFileAsync()
{
return UseFileAsync(LeftFile);
}
[ReactiveCommand]
private Task UseRightFileAsync()
{
return UseFileAsync(RightFile);
}
private async Task UseFileAsync(string path)
{
File.Copy(path, _final, true);
} }
} }

View File

@ -235,15 +235,19 @@ public partial class SettingViewModel : RoutableViewModelBase
Users.Clear(); Users.Clear();
foreach (var user in users) foreach (var user in users)
{ {
Users.Add(new UserModel var m = new UserModel
{ {
Username = user.Username, Username = user.Username,
Email = user.Email, Email = user.Email,
IsActive = user.IsActive, IsActive = user.IsActive,
IsAdmin = user.IsAdmin ?? false, IsAdmin = user.IsAdmin ?? false,
CanEdit = user.Username != Api.C.Username.Value! CanEdit = user.Username != Api.C.Username.Value!
}); };
if (m.CanEdit) Users.Insert(0, m);
else Users.Add(m);
} }
} }
catch (ApiException ex) catch (ApiException ex)
{ {

View File

@ -6,19 +6,15 @@
xmlns:u="https://irihi.tech/ursa" xmlns:u="https://irihi.tech/ursa"
x:DataType="vm:MergeDialogViewModel" x:DataType="vm:MergeDialogViewModel"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
MinWidth="400" MinWidth="600"
x:Class="Flawless.Client.Views.ModalBox.MergeDialogView"> x:Class="Flawless.Client.Views.ModalBox.MergeDialogView">
<ListBox HorizontalAlignment="Stretch" ItemsSource="{Binding MergeFiles}"> <StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" Spacing="12">
<ListBox.ItemTemplate> <Label Content="{Binding Ws, StringFormat='Conflict on file:\n {0}'}"/>
<DataTemplate> <Label Content="{Binding Ws, StringFormat='Left is local and right is remote'}"/>
<ListBoxItem> <StackPanel Orientation="Horizontal" Spacing="4" HorizontalAlignment="Center">
<Grid ColumnDefinitions="Auto, *, Auto"> <Button Content="Use Left" Command="{Binding UseLeftFileCommand}"/>
<Label Grid.Column="0" Content="{Binding WorkPath}"/> <Button Content="Merge" Command="{Binding RaiseMergeToolsCommand}"/>
<u:IconButton Command="{Binding $parent[ItemsControl].((vm:MergeDialogViewModel)DataContext).RaiseMergeToolsCommand}" <Button Content="Use Right" Command="{Binding UseRightFileCommand}"/>
CommandParameter="{Binding WorkPath}"/> </StackPanel>
</Grid> </StackPanel>
</ListBoxItem>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</UserControl> </UserControl>

View File

@ -36,22 +36,22 @@
</u:Form> </u:Form>
</ScrollViewer> </ScrollViewer>
</TabItem> </TabItem>
<TabItem Header="Preference"> <!-- <TabItem Header="Preference"> -->
<ScrollViewer Width="600" HorizontalAlignment="Left" Margin="6"> <!-- <ScrollViewer Width="600" HorizontalAlignment="Left" Margin="6"> -->
<u:Form HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <!-- <u:Form HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> -->
<!-- <u:FormItem Label="Default Storage Location"> --> <!-- ~1~ <u:FormItem Label="Default Storage Location"> @1@ -->
<!-- <u:PathPicker/> --> <!-- ~1~ <u:PathPicker/> @1@ -->
<!-- </u:FormItem> --> <!-- ~1~ </u:FormItem> @1@ -->
<u:FormGroup Header="Extern Tools"> <!-- <u:FormGroup Header="Extern Tools"> -->
<u:PathPicker u:FormItem.Label="Diff Tool"/> <!-- <u:PathPicker u:FormItem.Label="Diff Tool"/> -->
</u:FormGroup> <!-- </u:FormGroup> -->
<StackPanel Orientation="Horizontal" Spacing="4"> <!-- <StackPanel Orientation="Horizontal" Spacing="4"> -->
<u:IconButton Content="Save" Command="{Binding SaveClientPreferenceCommand}"/> <!-- <u:IconButton Content="Save" Command="{Binding SaveClientPreferenceCommand}"/> -->
<u:IconButton Classes="Danger" Content="Reset" Command="{Binding ResetClientPreferenceCommand}"/> <!-- <u:IconButton Classes="Danger" Content="Reset" Command="{Binding ResetClientPreferenceCommand}"/> -->
</StackPanel> <!-- </StackPanel> -->
</u:Form> <!-- </u:Form> -->
</ScrollViewer> <!-- </ScrollViewer> -->
</TabItem> <!-- </TabItem> -->
<TabItem IsVisible="{Binding LoginUser.IsAdmin}" Header="Server"> <TabItem IsVisible="{Binding LoginUser.IsAdmin}" Header="Server">
<ScrollViewer Width="600" HorizontalAlignment="Left" Margin="6"> <ScrollViewer Width="600" HorizontalAlignment="Left" Margin="6">
<u:Form HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <u:Form HorizontalAlignment="Stretch" VerticalAlignment="Stretch">