Skip to content

Commit 691686c

Browse files
authored
feature: unlock all locks (Git LFS) (#1890)
* Add "Unlock all my locks" functionality to LFS Locks * Add confirmation dialog for "Unlock all my locks" in LFS Locks * Remove trailing whitespaces across LFS-related files
1 parent 8aafc47 commit 691686c

File tree

6 files changed

+111
-12
lines changed

6 files changed

+111
-12
lines changed

src/Commands/LFS.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,5 +93,23 @@ public async Task<bool> UnlockAsync(string remote, string file, bool force)
9393
Args = builder.ToString();
9494
return await ExecAsync().ConfigureAwait(false);
9595
}
96+
97+
public async Task<bool> UnlockAsync(string remote, List<string> files, bool force)
98+
{
99+
var builder = new StringBuilder();
100+
builder
101+
.Append("lfs unlock --remote=")
102+
.Append(remote)
103+
.Append(force ? " -f " : " ");
104+
105+
foreach (string file in files)
106+
{
107+
builder.Append(file.Quoted());
108+
builder.Append(" ");
109+
}
110+
111+
Args = builder.ToString();
112+
return await ExecAsync().ConfigureAwait(false);
113+
}
96114
}
97115
}

src/Resources/Locales/en_US.axaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,8 @@
441441
<x:String x:Key="Text.GitLFS.Locks.Empty" xml:space="preserve">No Locked Files</x:String>
442442
<x:String x:Key="Text.GitLFS.Locks.Lock" xml:space="preserve">Lock</x:String>
443443
<x:String x:Key="Text.GitLFS.Locks.OnlyMine" xml:space="preserve">Show only my locks</x:String>
444+
<x:String x:Key="Text.GitLFS.Locks.UnlockAll.Confirm" xml:space="preserve">Are you sure you want to unlock all your locked files?</x:String>
445+
<x:String x:Key="Text.GitLFS.Locks.UnlockAllMyLocks" xml:space="preserve">Unlock all of my locks</x:String>
444446
<x:String x:Key="Text.GitLFS.Locks.Title" xml:space="preserve">LFS Locks</x:String>
445447
<x:String x:Key="Text.GitLFS.Locks.Unlock" xml:space="preserve">Unlock</x:String>
446448
<x:String x:Key="Text.GitLFS.Locks.UnlockForce" xml:space="preserve">Force Unlock</x:String>

src/ViewModels/LFSLocks.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Threading.Tasks;
44
using Avalonia.Threading;
55
using CommunityToolkit.Mvvm.ComponentModel;
6+
using SourceGit.Models;
67

78
namespace SourceGit.ViewModels
89
{
@@ -72,6 +73,32 @@ public async Task UnlockAsync(Models.LFSLock lfsLock, bool force)
7273
IsLoading = false;
7374
}
7475

76+
public async Task UnlockAllMyLocksAsync(bool force = false)
77+
{
78+
if (_isLoading)
79+
return;
80+
81+
IsLoading = true;
82+
83+
List<string> myLocks = [];
84+
foreach (LFSLock lfsLock in _cachedLocks)
85+
{
86+
if (lfsLock.Owner.Name.Equals(_userName, StringComparison.Ordinal))
87+
{
88+
myLocks.Add(lfsLock.Path);
89+
}
90+
}
91+
92+
bool succ = await _repo.UnlockLFSFilesAsync(_remote, myLocks, force, false);
93+
if (succ)
94+
{
95+
_cachedLocks.RemoveAll(lfsLock => lfsLock.Owner.Name.Equals(_userName, StringComparison.Ordinal));
96+
UpdateVisibleLocks();
97+
}
98+
99+
IsLoading = false;
100+
}
101+
75102
private void UpdateVisibleLocks()
76103
{
77104
var visible = new List<Models.LFSLock>();

src/ViewModels/Repository.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,20 @@ public async Task<bool> UnlockLFSFileAsync(string remote, string path, bool forc
738738
return succ;
739739
}
740740

741+
public async Task<bool> UnlockLFSFilesAsync(string remote, List<string> paths, bool force, bool notify)
742+
{
743+
CommandLog log = CreateLog("Unlock LFS File");
744+
bool succ = await new Commands.LFS(FullPath)
745+
.Use(log)
746+
.UnlockAsync(remote, paths, force);
747+
748+
if (succ && notify)
749+
App.SendNotification(FullPath, $"Unlocked {paths.Count} files successfully!");
750+
751+
log.Complete();
752+
return succ;
753+
}
754+
741755
public CommandLog CreateLog(string name)
742756
{
743757
var log = new CommandLog(name);

src/Views/LFSLocks.axaml

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,34 @@
3838
</Grid>
3939

4040
<!-- Filter and Unlock All -->
41-
<CheckBox Grid.Row="1"
42-
Margin="8,0,0,0"
43-
Content="{DynamicResource Text.GitLFS.Locks.OnlyMine}"
44-
IsChecked="{Binding ShowOnlyMyLocks, Mode=TwoWay}"
45-
VerticalAlignment="Center">
46-
<CheckBox.IsEnabled>
47-
<MultiBinding Converter="{x:Static BoolConverters.And}">
48-
<Binding Path="HasValidUserName"/>
49-
<Binding Path="!IsLoading"/>
50-
</MultiBinding>
51-
</CheckBox.IsEnabled>
52-
</CheckBox>
41+
<StackPanel Grid.Row="1"
42+
HorizontalAlignment="Left"
43+
Orientation="Horizontal">
44+
45+
<CheckBox Margin="8,0,4,0"
46+
Content="{DynamicResource Text.GitLFS.Locks.OnlyMine}"
47+
IsChecked="{Binding ShowOnlyMyLocks, Mode=TwoWay}"
48+
VerticalAlignment="Center">
49+
<CheckBox.IsEnabled>
50+
<MultiBinding Converter="{x:Static BoolConverters.And}">
51+
<Binding Path="HasValidUserName" />
52+
<Binding Path="!IsLoading" />
53+
</MultiBinding>
54+
</CheckBox.IsEnabled>
55+
</CheckBox>
56+
57+
<Button Margin="4,0,4,0"
58+
Content="{DynamicResource Text.GitLFS.Locks.UnlockAllMyLocks}"
59+
Click="OnUnlockAllMyLocksButtonClicked">
60+
<Button.IsEnabled>
61+
<MultiBinding Converter="{x:Static BoolConverters.And}">
62+
<Binding Path="HasValidUserName" />
63+
<Binding Path="!IsLoading" />
64+
</MultiBinding>
65+
</Button.IsEnabled>
66+
</Button>
67+
68+
</StackPanel>
5369

5470
<!-- Locked Files -->
5571
<Grid Grid.Row="2">

src/Views/LFSLocks.axaml.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,27 @@ private async void OnForceUnlockButtonClicked(object sender, RoutedEventArgs e)
2626

2727
e.Handled = true;
2828
}
29+
30+
private async void OnUnlockAllMyLocksButtonClicked(object sender, RoutedEventArgs e)
31+
{
32+
if (DataContext is ViewModels.LFSLocks vm)
33+
{
34+
Confirm dialog = new()
35+
{
36+
Message =
37+
{
38+
Text = App.Text("GitLFS.Locks.UnlockAll.Confirm")
39+
}
40+
};
41+
42+
bool result = await dialog.ShowDialog<bool>(this);
43+
if (result)
44+
{
45+
await vm.UnlockAllMyLocksAsync(true);
46+
}
47+
}
48+
49+
e.Handled = true;
50+
}
2951
}
3052
}

0 commit comments

Comments
 (0)