mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-05-23 21:24:59 +00:00
enhance: Git LFS support
This commit is contained in:
parent
e731807c91
commit
9a0b10bd9c
24 changed files with 780 additions and 34 deletions
|
@ -18,14 +18,6 @@ namespace SourceGit.ViewModels
|
|||
return Task.Run(() =>
|
||||
{
|
||||
new Commands.GC(_repo.FullPath, SetProgressDescription).Exec();
|
||||
|
||||
var lfs = new Commands.LFS(_repo.FullPath);
|
||||
if (lfs.IsEnabled())
|
||||
{
|
||||
SetProgressDescription("Run LFS prune ...");
|
||||
lfs.Prune(SetProgressDescription);
|
||||
}
|
||||
|
||||
CallUIThread(() => _repo.SetWatcherEnabled(true));
|
||||
return true;
|
||||
});
|
||||
|
|
27
src/ViewModels/LFSFetch.cs
Normal file
27
src/ViewModels/LFSFetch.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace SourceGit.ViewModels
|
||||
{
|
||||
public class LFSFetch : Popup
|
||||
{
|
||||
public LFSFetch(Repository repo)
|
||||
{
|
||||
_repo = repo;
|
||||
View = new Views.LFSFetch() { DataContext = this };
|
||||
}
|
||||
|
||||
public override Task<bool> Sure()
|
||||
{
|
||||
_repo.SetWatcherEnabled(false);
|
||||
ProgressDescription = $"Fetching LFS objects from remote ...";
|
||||
return Task.Run(() =>
|
||||
{
|
||||
new Commands.LFS(_repo.FullPath).Fetch(SetProgressDescription);
|
||||
CallUIThread(() => _repo.SetWatcherEnabled(true));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private readonly Repository _repo = null;
|
||||
}
|
||||
}
|
73
src/ViewModels/LFSLocks.cs
Normal file
73
src/ViewModels/LFSLocks.cs
Normal file
|
@ -0,0 +1,73 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
using Avalonia.Collections;
|
||||
using Avalonia.Threading;
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace SourceGit.ViewModels
|
||||
{
|
||||
public class LFSLocks : ObservableObject
|
||||
{
|
||||
public bool IsLoading
|
||||
{
|
||||
get => _isLoading;
|
||||
private set => SetProperty(ref _isLoading, value);
|
||||
}
|
||||
|
||||
public bool IsEmpty
|
||||
{
|
||||
get => _isEmpty;
|
||||
private set => SetProperty(ref _isEmpty, value);
|
||||
}
|
||||
|
||||
public AvaloniaList<Models.LFSLock> Locks
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public LFSLocks(string repo)
|
||||
{
|
||||
_repo = repo;
|
||||
Locks = new AvaloniaList<Models.LFSLock>();
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
var collect = new Commands.LFS(_repo).Locks();
|
||||
Dispatcher.UIThread.Invoke(() =>
|
||||
{
|
||||
if (collect.Count > 0)
|
||||
Locks.AddRange(collect);
|
||||
|
||||
IsLoading = false;
|
||||
IsEmpty = collect.Count == 0;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void Unlock(Models.LFSLock lfsLock, bool force)
|
||||
{
|
||||
if (_isLoading)
|
||||
return;
|
||||
|
||||
IsLoading = true;
|
||||
Task.Run(() =>
|
||||
{
|
||||
var succ = new Commands.LFS(_repo).Unlock(lfsLock.ID, force);
|
||||
Dispatcher.UIThread.Invoke(() =>
|
||||
{
|
||||
if (succ)
|
||||
Locks.Remove(lfsLock);
|
||||
|
||||
IsLoading = false;
|
||||
IsEmpty = Locks.Count == 0;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private string _repo = string.Empty;
|
||||
private bool _isLoading = true;
|
||||
private bool _isEmpty = false;
|
||||
}
|
||||
}
|
28
src/ViewModels/LFSPrune.cs
Normal file
28
src/ViewModels/LFSPrune.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace SourceGit.ViewModels
|
||||
{
|
||||
public class LFSPrune : Popup
|
||||
{
|
||||
public LFSPrune(Repository repo)
|
||||
{
|
||||
_repo = repo;
|
||||
View = new Views.LFSPrune() { DataContext = this };
|
||||
}
|
||||
|
||||
public override Task<bool> Sure()
|
||||
{
|
||||
_repo.SetWatcherEnabled(false);
|
||||
ProgressDescription = "LFS prune ...";
|
||||
|
||||
return Task.Run(() =>
|
||||
{
|
||||
new Commands.LFS(_repo.FullPath).Prune(SetProgressDescription);
|
||||
CallUIThread(() => _repo.SetWatcherEnabled(true));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private readonly Repository _repo = null;
|
||||
}
|
||||
}
|
27
src/ViewModels/LFSPull.cs
Normal file
27
src/ViewModels/LFSPull.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace SourceGit.ViewModels
|
||||
{
|
||||
public class LFSPull : Popup
|
||||
{
|
||||
public LFSPull(Repository repo)
|
||||
{
|
||||
_repo = repo;
|
||||
View = new Views.LFSPull() { DataContext = this };
|
||||
}
|
||||
|
||||
public override Task<bool> Sure()
|
||||
{
|
||||
_repo.SetWatcherEnabled(false);
|
||||
ProgressDescription = $"Pull LFS objects from remote ...";
|
||||
return Task.Run(() =>
|
||||
{
|
||||
new Commands.LFS(_repo.FullPath).Pull(SetProgressDescription);
|
||||
CallUIThread(() => _repo.SetWatcherEnabled(true));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private readonly Repository _repo = null;
|
||||
}
|
||||
}
|
|
@ -814,7 +814,7 @@ namespace SourceGit.ViewModels
|
|||
{
|
||||
var init = new MenuItem();
|
||||
init.Header = App.Text("GitFlow.Init");
|
||||
init.Icon = App.CreateMenuIcon("Icons.GitFlow.Init");
|
||||
init.Icon = App.CreateMenuIcon("Icons.Init");
|
||||
init.Click += (o, e) =>
|
||||
{
|
||||
if (PopupHost.CanCreatePopup())
|
||||
|
@ -826,6 +826,95 @@ namespace SourceGit.ViewModels
|
|||
return menu;
|
||||
}
|
||||
|
||||
public ContextMenu CreateContextMenuForGitLFS()
|
||||
{
|
||||
var menu = new ContextMenu();
|
||||
menu.Placement = PlacementMode.BottomEdgeAlignedLeft;
|
||||
|
||||
var lfs = new Commands.LFS(_fullpath);
|
||||
if (lfs.IsEnabled())
|
||||
{
|
||||
var fetch = new MenuItem();
|
||||
fetch.Header = App.Text("GitLFS.Fetch");
|
||||
fetch.Icon = App.CreateMenuIcon("Icons.Fetch");
|
||||
fetch.IsEnabled = Remotes.Count > 0;
|
||||
fetch.Click += (o, e) =>
|
||||
{
|
||||
if (PopupHost.CanCreatePopup())
|
||||
{
|
||||
if (Remotes.Count == 1)
|
||||
PopupHost.ShowAndStartPopup(new LFSFetch(this));
|
||||
else
|
||||
PopupHost.ShowPopup(new LFSFetch(this));
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
};
|
||||
menu.Items.Add(fetch);
|
||||
|
||||
var pull = new MenuItem();
|
||||
pull.Header = App.Text("GitLFS.Pull");
|
||||
pull.Icon = App.CreateMenuIcon("Icons.Pull");
|
||||
pull.IsEnabled = Remotes.Count > 0;
|
||||
pull.Click += (o, e) =>
|
||||
{
|
||||
if (PopupHost.CanCreatePopup())
|
||||
{
|
||||
if (Remotes.Count == 1)
|
||||
PopupHost.ShowAndStartPopup(new LFSPull(this));
|
||||
else
|
||||
PopupHost.ShowPopup(new LFSPull(this));
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
};
|
||||
menu.Items.Add(pull);
|
||||
|
||||
var prune = new MenuItem();
|
||||
prune.Header = App.Text("GitLFS.Prune");
|
||||
prune.Icon = App.CreateMenuIcon("Icons.Clean");
|
||||
prune.Click += (o, e) =>
|
||||
{
|
||||
if (PopupHost.CanCreatePopup())
|
||||
PopupHost.ShowAndStartPopup(new LFSPrune(this));
|
||||
|
||||
e.Handled = true;
|
||||
};
|
||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||
menu.Items.Add(prune);
|
||||
|
||||
var locks = new MenuItem();
|
||||
locks.Header = App.Text("GitLFS.Locks");
|
||||
locks.Icon = App.CreateMenuIcon("Icons.Lock");
|
||||
locks.Click += (o, e) =>
|
||||
{
|
||||
var dialog = new Views.LFSLocks() { DataContext = new LFSLocks(_fullpath) };
|
||||
dialog.Show(App.GetTopLevel() as Window);
|
||||
|
||||
e.Handled = true;
|
||||
};
|
||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||
menu.Items.Add(locks);
|
||||
}
|
||||
else
|
||||
{
|
||||
var install = new MenuItem();
|
||||
install.Header = App.Text("GitLFS.Install");
|
||||
install.Icon = App.CreateMenuIcon("Icons.Init");
|
||||
install.Click += (o, e) =>
|
||||
{
|
||||
var succ = new Commands.LFS(_fullpath).Install();
|
||||
if (succ)
|
||||
App.SendNotification(_fullpath, $"LFS enabled successfully!");
|
||||
|
||||
e.Handled = true;
|
||||
};
|
||||
menu.Items.Add(install);
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
public ContextMenu CreateContextMenuForLocalBranch(Models.Branch branch)
|
||||
{
|
||||
var menu = new ContextMenu();
|
||||
|
|
|
@ -527,7 +527,7 @@ namespace SourceGit.ViewModels
|
|||
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
|
||||
var assumeUnchanged = new MenuItem();
|
||||
assumeUnchanged.Header = App.Text("FileCM.AssumeUnchanged");
|
||||
assumeUnchanged.Icon = App.CreateMenuIcon("Icons.File.Ignore");
|
||||
|
@ -556,7 +556,9 @@ namespace SourceGit.ViewModels
|
|||
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||
menu.Items.Add(history);
|
||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||
|
||||
|
||||
var extension = Path.GetExtension(change.Path);
|
||||
var hasExtra = false;
|
||||
if (change.WorkTree == Models.ChangeState.Untracked)
|
||||
{
|
||||
var isRooted = change.Path.IndexOf('/', StringComparison.Ordinal) <= 0;
|
||||
|
@ -583,8 +585,7 @@ namespace SourceGit.ViewModels
|
|||
};
|
||||
addToIgnore.Items.Add(byParentFolder);
|
||||
|
||||
var extension = Path.GetExtension(change.Path);
|
||||
if (!string.IsNullOrEmpty(extension))
|
||||
if (!string.IsNullOrEmpty(extension))
|
||||
{
|
||||
var byExtension = new MenuItem();
|
||||
byExtension.Header = App.Text("WorkingCopy.AddToGitIgnore.Extension", extension);
|
||||
|
@ -594,7 +595,7 @@ namespace SourceGit.ViewModels
|
|||
e.Handled = true;
|
||||
};
|
||||
addToIgnore.Items.Add(byExtension);
|
||||
|
||||
|
||||
var byExtensionInSameFolder = new MenuItem();
|
||||
byExtensionInSameFolder.Header = App.Text("WorkingCopy.AddToGitIgnore.ExtensionInSameFolder", extension);
|
||||
byExtensionInSameFolder.IsVisible = !isRooted;
|
||||
|
@ -607,8 +608,77 @@ namespace SourceGit.ViewModels
|
|||
}
|
||||
|
||||
menu.Items.Add(addToIgnore);
|
||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||
hasExtra = true;
|
||||
}
|
||||
|
||||
var lfsEnabled = new Commands.LFS(_repo.FullPath).IsEnabled();
|
||||
if (lfsEnabled)
|
||||
{
|
||||
var lfs = new MenuItem();
|
||||
lfs.Header = App.Text("GitLFS");
|
||||
lfs.Icon = App.CreateMenuIcon("Icons.LFS");
|
||||
|
||||
var filename = Path.GetFileName(change.Path);
|
||||
var lfsTrackThisFile = new MenuItem();
|
||||
lfsTrackThisFile.Header = App.Text("GitLFS.Track", filename);
|
||||
lfsTrackThisFile.Click += async (_, e) =>
|
||||
{
|
||||
var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Track(filename, true));
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, $"Tracking file named {filename} successfully!");
|
||||
|
||||
e.Handled = true;
|
||||
};
|
||||
lfs.Items.Add(lfsTrackThisFile);
|
||||
|
||||
if (!string.IsNullOrEmpty(extension))
|
||||
{
|
||||
var lfsTrackByExtension = new MenuItem();
|
||||
lfsTrackByExtension.Header = App.Text("GitLFS.TrackByExtension", extension);
|
||||
lfsTrackByExtension.Click += async (_, e) =>
|
||||
{
|
||||
var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Track("*" + extension, false));
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, $"Tracking all *{extension} files successfully!");
|
||||
|
||||
e.Handled = true;
|
||||
};
|
||||
lfs.Items.Add(lfsTrackByExtension);
|
||||
}
|
||||
|
||||
var lfsLock = new MenuItem();
|
||||
lfsLock.Header = App.Text("GitLFS.Locks.Lock");
|
||||
lfsLock.Icon = App.CreateMenuIcon("Icons.Lock");
|
||||
lfsLock.Click += async (_, e) =>
|
||||
{
|
||||
var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Lock(change.Path));
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, $"Lock file \"{change.Path}\" successfully!");
|
||||
|
||||
e.Handled = true;
|
||||
};
|
||||
lfs.Items.Add(new MenuItem() { Header = "-" });
|
||||
lfs.Items.Add(lfsLock);
|
||||
|
||||
var lfsUnlock = new MenuItem();
|
||||
lfsUnlock.Header = App.Text("GitLFS.Locks.Unlock");
|
||||
lfsUnlock.Icon = App.CreateMenuIcon("Icons.Unlock");
|
||||
lfsUnlock.Click += async (_, e) =>
|
||||
{
|
||||
var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Unlock(change.Path, false));
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, $"Unlock file \"{change.Path}\" successfully!");
|
||||
|
||||
e.Handled = true;
|
||||
};
|
||||
lfs.Items.Add(lfsUnlock);
|
||||
|
||||
menu.Items.Add(lfs);
|
||||
hasExtra = true;
|
||||
}
|
||||
|
||||
if (hasExtra)
|
||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||
}
|
||||
|
||||
var copy = new MenuItem();
|
||||
|
@ -702,9 +772,8 @@ namespace SourceGit.ViewModels
|
|||
stash.Click += (_, e) =>
|
||||
{
|
||||
if (PopupHost.CanCreatePopup())
|
||||
{
|
||||
PopupHost.ShowPopup(new StashChanges(_repo, _selectedUnstaged, false));
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
|
@ -797,9 +866,8 @@ namespace SourceGit.ViewModels
|
|||
stash.Click += (_, e) =>
|
||||
{
|
||||
if (PopupHost.CanCreatePopup())
|
||||
{
|
||||
PopupHost.ShowPopup(new StashChanges(_repo, _selectedStaged, false));
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
|
@ -854,6 +922,45 @@ namespace SourceGit.ViewModels
|
|||
menu.Items.Add(stash);
|
||||
menu.Items.Add(patch);
|
||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||
|
||||
var lfsEnabled = new Commands.LFS(_repo.FullPath).IsEnabled();
|
||||
if (lfsEnabled)
|
||||
{
|
||||
var lfs = new MenuItem();
|
||||
lfs.Header = App.Text("GitLFS");
|
||||
lfs.Icon = App.CreateMenuIcon("Icons.LFS");
|
||||
|
||||
var lfsLock = new MenuItem();
|
||||
lfsLock.Header = App.Text("GitLFS.Locks.Lock");
|
||||
lfsLock.Icon = App.CreateMenuIcon("Icons.Lock");
|
||||
lfsLock.Click += async (_, e) =>
|
||||
{
|
||||
var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Lock(change.Path));
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, $"Lock file \"{change.Path}\" successfully!");
|
||||
|
||||
e.Handled = true;
|
||||
};
|
||||
lfs.Items.Add(new MenuItem() { Header = "-" });
|
||||
lfs.Items.Add(lfsLock);
|
||||
|
||||
var lfsUnlock = new MenuItem();
|
||||
lfsUnlock.Header = App.Text("GitLFS.Locks.Unlock");
|
||||
lfsUnlock.Icon = App.CreateMenuIcon("Icons.Unlock");
|
||||
lfsUnlock.Click += async (_, e) =>
|
||||
{
|
||||
var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Unlock(change.Path, false));
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, $"Unlock file \"{change.Path}\" successfully!");
|
||||
|
||||
e.Handled = true;
|
||||
};
|
||||
lfs.Items.Add(lfsUnlock);
|
||||
|
||||
menu.Items.Add(lfs);
|
||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||
}
|
||||
|
||||
menu.Items.Add(copyPath);
|
||||
menu.Items.Add(copyFileName);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue