mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-23 20:47:25 -08:00
enhance: Git LFS support
This commit is contained in:
parent
e731807c91
commit
9a0b10bd9c
24 changed files with 780 additions and 34 deletions
|
@ -8,9 +8,9 @@ namespace SourceGit.Commands
|
|||
{
|
||||
var file = Path.Combine(repo, ".gitignore");
|
||||
if (!File.Exists(file))
|
||||
File.WriteAllLines(file, [ pattern ]);
|
||||
File.WriteAllLines(file, [pattern]);
|
||||
else
|
||||
File.AppendAllLines(file, [ pattern ]);
|
||||
File.AppendAllLines(file, [pattern]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SourceGit.Commands
|
||||
{
|
||||
public class LFS
|
||||
public partial class LFS
|
||||
{
|
||||
class PruneCmd : Command
|
||||
[GeneratedRegex(@"^(.+)\s+(\w+)\s+\w+:(\d+)$")]
|
||||
private static partial Regex REG_LOCK();
|
||||
|
||||
class SubCmd : Command
|
||||
{
|
||||
public PruneCmd(string repo, Action<string> onProgress)
|
||||
public SubCmd(string repo, string args, Action<string> onProgress)
|
||||
{
|
||||
WorkingDirectory = repo;
|
||||
Context = repo;
|
||||
Args = "lfs prune";
|
||||
Args = args;
|
||||
TraitErrorAsOutput = true;
|
||||
_outputHandler = onProgress;
|
||||
}
|
||||
|
@ -39,9 +44,73 @@ namespace SourceGit.Commands
|
|||
return content.Contains("git lfs pre-push");
|
||||
}
|
||||
|
||||
public bool Install()
|
||||
{
|
||||
return new SubCmd(_repo, $"lfs install", null).Exec();
|
||||
}
|
||||
|
||||
public bool Track(string pattern, bool isFilenameMode = false)
|
||||
{
|
||||
var opt = isFilenameMode ? "--filename" : "";
|
||||
return new SubCmd(_repo, $"lfs track {opt} \"{pattern}\"", null).Exec();
|
||||
}
|
||||
|
||||
public void Fetch(Action<string> outputHandler)
|
||||
{
|
||||
new SubCmd(_repo, $"lfs fetch", outputHandler).Exec();
|
||||
}
|
||||
|
||||
public void Pull(Action<string> outputHandler)
|
||||
{
|
||||
new SubCmd(_repo, $"lfs pull", outputHandler).Exec();
|
||||
}
|
||||
|
||||
public void Prune(Action<string> outputHandler)
|
||||
{
|
||||
new PruneCmd(_repo, outputHandler).Exec();
|
||||
new SubCmd(_repo, "lfs prune", outputHandler).Exec();
|
||||
}
|
||||
|
||||
public List<Models.LFSLock> Locks()
|
||||
{
|
||||
var locks = new List<Models.LFSLock>();
|
||||
var cmd = new SubCmd(_repo, "lfs locks", null);
|
||||
var rs = cmd.ReadToEnd();
|
||||
if (rs.IsSuccess)
|
||||
{
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var match = REG_LOCK().Match(line);
|
||||
if (match.Success)
|
||||
{
|
||||
locks.Add(new Models.LFSLock()
|
||||
{
|
||||
File = match.Groups[1].Value,
|
||||
User = match.Groups[2].Value,
|
||||
ID = long.Parse(match.Groups[3].Value),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return locks;
|
||||
}
|
||||
|
||||
public bool Lock(string file)
|
||||
{
|
||||
return new SubCmd(_repo, $"lfs lock \"{file}\"", null).Exec();
|
||||
}
|
||||
|
||||
public bool Unlock(string file, bool force)
|
||||
{
|
||||
var opt = force ? "-f" : "";
|
||||
return new SubCmd(_repo, $"lfs unlock {opt} \"{file}\"", null).Exec();
|
||||
}
|
||||
|
||||
public bool Unlock(long id, bool force)
|
||||
{
|
||||
var opt = force ? "-f" : "";
|
||||
return new SubCmd(_repo, $"lfs unlock {opt} --id={id}", null).Exec();
|
||||
}
|
||||
|
||||
private readonly string _repo;
|
||||
|
|
9
src/Models/LFSLock.cs
Normal file
9
src/Models/LFSLock.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace SourceGit.Models
|
||||
{
|
||||
public class LFSLock
|
||||
{
|
||||
public string File { get; set; } = string.Empty;
|
||||
public string User { get; set; } = string.Empty;
|
||||
public long ID { get; set; } = 0;
|
||||
}
|
||||
}
|
|
@ -61,7 +61,6 @@
|
|||
<StreamGeometry x:Key="Icons.Tag.Add">M683 537h-144v-142h-142V283H239a44 44 0 00-41 41v171a56 56 0 0014 34l321 321a41 41 0 0058 0l174-174a41 41 0 000-58zm-341-109a41 41 0 110-58a41 41 0 010 58zM649 284V142h-69v142h-142v68h142v142h69v-142h142v-68h-142z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Submodule">M557.7 545.3 789.9 402.7c24-15 31.3-46.5 16.4-70.5c-14.8-23.8-46-31.2-70-16.7L506.5 456.6 277.1 315.4c-24.1-14.8-55.6-7.3-70.5 16.8c-14.8 24.1-7.3 55.6 16.8 70.5l231.8 142.6V819.1c0 28.3 22.9 51.2 51.2 51.2c28.3 0 51.2-22.9 51.2-51.2V545.3h.1zM506.5 0l443.4 256v511.9L506.5 1023.9 63.1 767.9v-511.9L506.5 0z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Submodule.Add">M770 320a41 41 0 00-56-14l-252 153L207 306a41 41 0 10-43 70l255 153 2 296a41 41 0 0082 0l-2-295 255-155a41 41 0 0014-56zM481 935a42 42 0 01-42 0L105 741a42 42 0 01-21-36v-386a42 42 0 0121-36L439 89a42 42 0 0142 0l335 193a42 42 0 0121 36v87h84v-87a126 126 0 00-63-109L523 17a126 126 0 00-126 0L63 210a126 126 0 00-63 109v386a126 126 0 0063 109l335 193a126 126 0 00126 0l94-54-42-72zM1029 700h-126v-125a42 42 0 00-84 0v126h-126a42 42 0 000 84h126v126a42 42 0 1084 0v-126h126a42 42 0 000-84z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.LFS">M170 470l0 84 86 0 0-84-86 0zM86 598l0-172 852 0 0 172-852 0zM256 298l0-84-86 0 0 84 86 0zM86 170l852 0 0 172-852 0 0-172zM170 726l0 84 86 0 0-84-86 0zM86 854l0-172 852 0 0 172-852 0z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Waiting">M812 864h-29V654c0-21-11-40-28-52l-133-88 134-89c18-12 28-31 28-52V164h28c18 0 32-14 32-32s-14-32-32-32H212c-18 0-32 14-32 32s14 32 32 32h30v210c0 21 11 40 28 52l133 88-134 89c-18 12-28 31-28 52V864H212c-18 0-32 14-32 32s14 32 32 32h600c18 0 32-14 32-32s-14-32-32-32zM441 566c18-12 28-31 28-52s-11-40-28-52L306 373V164h414v209l-136 90c-18 12-28 31-28 52 0 21 11 40 28 52l135 89V695c-9-7-20-13-32-19-30-15-93-41-176-41-63 0-125 14-175 38-12 6-22 12-31 18v-36l136-90z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Loading">M512 0C233 0 7 223 0 500C6 258 190 64 416 64c230 0 416 200 416 448c0 53 43 96 96 96s96-43 96-96c0-283-229-512-512-512zm0 1023c279 0 505-223 512-500c-6 242-190 436-416 436c-230 0-416-200-416-448c0-53-43-96-96-96s-96 43-96 96c0 283 229 512 512 512z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Detail">M888.8 0H135.2c-32.3 0-58.9 26.1-58.9 58.9v906.2c0 32.3 26.1 58.9 58.9 58.9h753.2c32.3 0 58.9-26.1 58.9-58.9v-906.2c.5-32.8-26.1-58.9-58.4-58.9zm-164.9 176.6c30.7 0 55.8 25.1 55.8 55.8s-25.1 55.8-55.8 55.8s-55.8-25.1-55.8-55.8s24.6-55.8 55.8-55.8zm-212 0c30.7 0 55.8 25.1 55.8 55.8S542.7 288.3 512 288.3s-55.8-25.1-55.8-55.8S481.3 176.6 512 176.6zm-212 0c30.7 0 55.8 25.1 55.8 55.8s-25.1 55.8-55.8 55.8s-55.8-25.1-55.8-55.8s25.1-55.8 55.8-55.8zm208.9 606.2H285.2c-24.6 0-44-20-44-44c0-24.6 20-44 44-44h223.7c24.6 0 44 20 44 44c0 24.1-19.5 44-44 44zm229.9-212H285.2c-24.6 0-44-20-44-44c0-24.6 20-44 44-44h453.1c24.6 0 44 20 44 44c.5 24.1-19.5 44-43.5 44z</StreamGeometry>
|
||||
|
@ -90,7 +89,7 @@
|
|||
<StreamGeometry x:Key="Icons.Target">M765 118 629 239l-16 137-186 160 54 59 183-168 144 4 136-129 47-43-175-12L827 67zM489 404c-66 0-124 55-124 125s54 121 124 121c66 0 120-55 120-121H489l23-121c-8-4-16-4-23-4zM695 525c0 114-93 207-206 207s-206-94-206-207 93-207 206-207c16 0 27 0 43 4l43-207c-27-4-54-8-85-8-229 0-416 188-416 419s187 419 416 419c225 0 408-180 416-403v-12l-210-4z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Incoming">M973 358a51 51 0 0151 51v563a51 51 0 01-51 51H51a51 51 0 01-51-51V410a51 51 0 0151-51h256a51 51 0 110 102H102v461h819V461h-205a51 51 0 110-102h256zM51 102a51 51 0 110-102h256c141 0 256 115 256 256v388l66-66a51 51 0 1172 72l-154 154a51 51 0 01-72 0l-154-154a51 51 0 1172-72L461 644V256c0-85-69-154-154-154H51z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Local">M976 0h-928A48 48 0 000 48v652a48 48 0 0048 48h416V928H200a48 48 0 000 96h624a48 48 0 000-96H560v-180h416a48 48 0 0048-48V48A48 48 0 00976 0zM928 652H96V96h832v556z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.GitFlow.Init">M412 66C326 132 271 233 271 347c0 17 1 34 4 50-41-48-98-79-162-83a444 444 0 00-46 196c0 207 142 382 337 439h2c19 0 34 15 34 33 0 11-6 21-14 26l1 14C183 973 0 763 0 511 0 272 166 70 393 7A35 35 0 01414 0c19 0 34 15 34 33a33 33 0 01-36 33zm200 893c86-66 141-168 141-282 0-17-1-34-4-50 41 48 98 79 162 83a444 444 0 0046-196c0-207-142-382-337-439h-2a33 33 0 01-34-33c0-11 6-21 14-26L596 0C841 51 1024 261 1024 513c0 239-166 441-393 504A35 35 0 01610 1024a33 33 0 01-34-33 33 33 0 0136-33zM512 704a192 192 0 110-384 192 192 0 010 384z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Init">M412 66C326 132 271 233 271 347c0 17 1 34 4 50-41-48-98-79-162-83a444 444 0 00-46 196c0 207 142 382 337 439h2c19 0 34 15 34 33 0 11-6 21-14 26l1 14C183 973 0 763 0 511 0 272 166 70 393 7A35 35 0 01414 0c19 0 34 15 34 33a33 33 0 01-36 33zm200 893c86-66 141-168 141-282 0-17-1-34-4-50 41 48 98 79 162 83a444 444 0 0046-196c0-207-142-382-337-439h-2a33 33 0 01-34-33c0-11 6-21 14-26L596 0C841 51 1024 261 1024 513c0 239-166 441-393 504A35 35 0 01610 1024a33 33 0 01-34-33 33 33 0 0136-33zM512 704a192 192 0 110-384 192 192 0 010 384z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.GitFlow.Feature">M939 94v710L512 998 85 805V94h-64A21 21 0 010 73v-0C0 61 10 51 21 51h981c12 0 21 10 21 21v0c0 12-10 21-21 21h-64zm-536 588L512 624l109 58c6 3 13 4 20 3a32 32 0 0026-37l-21-122 88-87c5-5 8-11 9-18a32 32 0 00-27-37l-122-18-54-111a32 32 0 00-57 0l-54 111-122 18c-7 1-13 4-18 9a33 33 0 001 46l88 87-21 122c-1 7-0 14 3 20a32 32 0 0043 14z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.GitFlow.Hotfix">M236 542a32 32 0 109 63l86-12a180 180 0 0022 78l-71 47a32 32 0 1035 53l75-50a176 176 0 00166 40L326 529zM512 16C238 16 16 238 16 512s222 496 496 496 496-222 496-496S786 16 512 16zm0 896c-221 0-400-179-400-400a398 398 0 0186-247l561 561A398 398 0 01512 912zm314-154L690 622a179 179 0 004-29l85 12a32 32 0 109-63l-94-13v-49l94-13a32 32 0 10-9-63l-87 12a180 180 0 00-20-62l71-47A32 32 0 10708 252l-75 50a181 181 0 00-252 10l-115-115A398 398 0 01512 112c221 0 400 179 400 400a398 398 0 01-86 247z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.GitFlow.Release">M884 159l-18-18a43 43 0 00-38-12l-235 43a166 166 0 00-101 60L400 349a128 128 0 00-148 47l-120 171a21 21 0 005 29l17 12a128 128 0 00178-32l27-38 124 124-38 27a128 128 0 00-32 178l12 17a21 21 0 0029 5l171-120a128 128 0 0047-148l117-92A166 166 0 00853 431l43-235a43 43 0 00-12-38zm-177 249a64 64 0 110-90 64 64 0 010 90zm-373 312a21 21 0 010 30l-139 139a21 21 0 01-30 0l-30-30a21 21 0 010-30l139-139a21 21 0 0130 0z</StreamGeometry>
|
||||
|
@ -100,4 +99,7 @@
|
|||
<StreamGeometry x:Key="Icons.WordWrap">M248 221a77 77 0 00-30-21c-18-7-40-10-68-5a224 224 0 00-45 13c-5 2-10 5-15 8l-3 2v68l11-9c10-8 21-14 34-19 13-5 26-7 39-7 12 0 21 3 28 10 6 6 9 16 9 29l-62 9c-14 2-26 6-36 11a80 80 0 00-25 20c-7 8-12 17-15 27-6 21-6 44 1 65a70 70 0 0041 43c10 4 21 6 34 6a80 80 0 0063-28v22h64V298c0-16-2-31-6-44a91 91 0 00-18-33zm-41 121v15c0 8-1 15-4 22a48 48 0 01-24 29 44 44 0 01-33 2 29 29 0 01-10-6 25 25 0 01-6-9 30 30 0 01-2-12c0-5 1-9 2-14a21 21 0 015-9 28 28 0 0110-7 83 83 0 0120-5l42-6zm323-68a144 144 0 00-16-42 87 87 0 00-28-29 75 75 0 00-41-11 73 73 0 00-44 14c-6 5-12 11-17 17V64H326v398h59v-18c8 10 18 17 30 21 6 2 13 3 21 3 16 0 31-4 43-11 12-7 23-18 31-31a147 147 0 0019-46 248 248 0 006-57c0-17-2-33-5-49zm-55 49c0 15-1 28-4 39-2 11-6 20-10 27a41 41 0 01-15 15 37 37 0 01-36 1 44 44 0 01-13-12 59 59 0 01-9-18A76 76 0 01384 352v-33c0-10 1-20 4-29 2-8 6-15 10-22a43 43 0 0115-13 37 37 0 0119-5 35 35 0 0132 18c4 6 7 14 9 23 2 9 3 20 3 31zM154 634a58 58 0 0120-15c14-6 35-7 49-1 7 3 13 6 20 12l21 17V572l-6-4a124 124 0 00-58-14c-20 0-38 4-54 11-16 7-30 17-41 30-12 13-20 29-26 46-6 17-9 36-9 57 0 18 3 36 8 52 6 16 14 30 24 42 10 12 23 21 38 28 15 7 32 10 50 10 15 0 28-2 39-5 11-3 21-8 30-14l5-4v-57l-13 6a26 26 0 01-5 2c-3 1-6 2-8 3-2 1-15 6-15 6-4 2-9 3-14 4a63 63 0 01-38-4 53 53 0 01-20-14 70 70 0 01-13-24 111 111 0 01-5-34c0-13 2-26 5-36 3-10 8-19 14-26zM896 384h-256V320h288c21 1 32 12 32 32v384c0 18-12 32-32 32H504l132 133-45 45-185-185c-16-21-16-25 0-45l185-185L637 576l-128 128H896V384z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Detached">M128 183C128 154 154 128 183 128h521c30 0 55 26 55 55v38c0 17-17 34-34 34s-34-17-34-34v-26H196v495h26c17 0 34 17 34 34s-17 34-34 34h-38c-30 0-55-26-55-55V183zM380 896h-34c-26 0-47-21-47-47v-90h68V828h64V896H380c4 0 0 0 0 0zM759 828V896h90c26 0 47-21 47-47v-90h-68V828h-68zM828 435H896V346c0-26-21-47-47-47h-90v68H828v68zM435 299v68H367V439H299V346C299 320 320 299 346 299h90zM367 649H299v-107h68v107zM546 367V299h107v68h-107zM828 546H896v107h-68v-107zM649 828V896h-107v-68h107zM730 508v188c0 17-17 34-34 34h-188c-17 0-34-17-34-34s17-34 34-34h102l-124-124c-13-13-13-34 0-47 13-13 34-13 47 0l124 124V512c0-17 17-34 34-34 21-4 38 9 38 30z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.GitIgnore">M590 74 859 342V876c0 38-31 68-68 68H233c-38 0-68-31-68-68V142c0-38 31-68 68-68h357zm-12 28H233a40 40 0 00-40 38L193 142v734a40 40 0 0038 40L233 916h558a40 40 0 0040-38L831 876V354L578 102zM855 371h-215c-46 0-83-36-84-82l0-2V74h28v213c0 30 24 54 54 55l2 0h215v28zM57 489m28 0 853 0q28 0 28 28l0 284q0 28-28 28l-853 0q-28 0-28-28l0-284q0-28 28-28ZM157 717c15 0 29-6 37-13v-51h-41v22h17v18c-2 2-6 3-10 3-21 0-30-13-30-34 0-21 12-34 28-34 9 0 15 4 20 9l14-17C184 610 172 603 156 603c-29 0-54 21-54 57 0 37 24 56 54 56zM245 711v-108h-34v108h34zm69 0v-86H341V603H262v22h28V711h24zM393 711v-108h-34v108h34zm66 6c15 0 29-6 37-13v-51h-41v22h17v18c-2 2-6 3-10 3-21 0-30-13-30-34 0-21 12-34 28-34 9 0 15 4 20 9l14-17C485 610 474 603 458 603c-29 0-54 21-54 57 0 37 24 56 54 56zm88-6v-36c0-13-2-28-3-40h1l10 24 25 52H603v-108h-23v36c0 13 2 28 3 40h-1l-10-24L548 603H523v108h23zM677 717c30 0 51-22 51-57 0-36-21-56-51-56-30 0-51 20-51 56 0 36 21 57 51 57zm3-23c-16 0-26-12-26-32 0-19 10-31 26-31 16 0 26 11 26 31S696 694 680 694zm93 17v-38h13l21 38H836l-25-43c12-5 19-15 19-31 0-26-20-34-44-34H745v108h27zm16-51H774v-34h15c16 0 25 4 25 16s-9 18-25 18zM922 711v-22h-43v-23h35v-22h-35V625h41V603H853v108h68z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.LFS">M40 9 15 23 15 31 9 28 9 20 34 5 24 0 0 14 0 34 25 48 25 28 49 14zM26 29 26 48 49 34 49 15z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Lock">M832 464h-68V240a128 128 0 00-128-128h-248a128 128 0 00-128 128v224H192c-18 0-32 14-32 32v384c0 18 14 32 32 32h640c18 0 32-14 32-32v-384c0-18-14-32-32-32zm-292 237v53a8 8 0 01-8 8h-40a8 8 0 01-8-8v-53a48 48 0 1156 0zm152-237H332V240a56 56 0 0156-56h248a56 56 0 0156 56v224z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Unlock">M832 464H332V240c0-31 25-56 56-56h248c31 0 56 25 56 56v68c0 4 4 8 8 8h56c4 0 8-4 8-8v-68c0-71-57-128-128-128H388c-71 0-128 57-128 128v224h-68c-18 0-32 14-32 32v384c0 18 14 32 32 32h640c18 0 32-14 32-32V496c0-18-14-32-32-32zM540 701v53c0 4-4 8-8 8h-40c-4 0-8-4-8-8v-53c-12-9-20-23-20-39 0-27 22-48 48-48s48 22 48 48c0 16-8 30-20 39z</StreamGeometry>
|
||||
</ResourceDictionary>
|
||||
|
|
|
@ -228,6 +228,24 @@
|
|||
<x:String x:Key="Text.GitFlow.StartRelease" xml:space="preserve">Start Release ...</x:String>
|
||||
<x:String x:Key="Text.GitFlow.StartReleaseTitle" xml:space="preserve">FLOW - Start Release</x:String>
|
||||
<x:String x:Key="Text.GitFlow.TagPrefix" xml:space="preserve">Version Tag Prefix :</x:String>
|
||||
<x:String x:Key="Text.GitLFS" xml:space="preserve">Git LFS</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Fetch" xml:space="preserve">Fetch ...</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Fetch.Title" xml:space="preserve">Fetch LFS Objects</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Fetch.Tips" xml:space="preserve">Run `git lfs fetch` to download Git LFS objects. This does not update the working copy.</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Install" xml:space="preserve">Install Git LFS hooks</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks" xml:space="preserve">Show Locks</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks.Empty" xml:space="preserve">No Locked Files</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks.Lock" xml:space="preserve">Lock</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks.Title" xml:space="preserve">LFS Locks</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks.Unlock" xml:space="preserve">Unlock</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks.UnlockForce" xml:space="preserve">Force Unlock</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Prune" xml:space="preserve">Prune</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Prune.Tips" xml:space="preserve">Run `git lfs prune` to delete old LFS files from local storage</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Pull" xml:space="preserve">Pull ...</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Pull.Title" xml:space="preserve">Pull LFS Objects</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Pull.Tips" xml:space="preserve">Run `git lfs pull` to download all Git LFS files for current ref & checkout</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Track" xml:space="preserve">Track files named '{0}'</x:String>
|
||||
<x:String x:Key="Text.GitLFS.TrackByExtension" xml:space="preserve">Track all *{0} files</x:String>
|
||||
<x:String x:Key="Text.Histories" xml:space="preserve">Histories</x:String>
|
||||
<x:String x:Key="Text.Histories.DisplayMode" xml:space="preserve">Switch Horizontal/Vertical Layout</x:String>
|
||||
<x:String x:Key="Text.Histories.GraphMode" xml:space="preserve">Switch Curve/Polyline Graph Mode</x:String>
|
||||
|
@ -373,7 +391,7 @@
|
|||
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">Branch :</x:String>
|
||||
<x:String x:Key="Text.Repository.Abort" xml:space="preserve">ABORT</x:String>
|
||||
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">Cleanup(GC & Prune)</x:String>
|
||||
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Run `gc` command and do `lfs prune` if LFS is installed.</x:String>
|
||||
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Run `git gc` command for this repository.</x:String>
|
||||
<x:String x:Key="Text.Repository.Configure" xml:space="preserve">Configure this repository</x:String>
|
||||
<x:String x:Key="Text.Repository.Continue" xml:space="preserve">CONTINUE</x:String>
|
||||
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">Open In File Browser</x:String>
|
||||
|
@ -477,7 +495,7 @@
|
|||
<x:String x:Key="Text.Welcome.Search" xml:space="preserve">Search Repositories ...</x:String>
|
||||
<x:String x:Key="Text.Welcome.Sort" xml:space="preserve">Sort</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy" xml:space="preserve">Changes</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Add To .gitignore ...</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignore all *{0} files</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignore *{0} files in the same folder</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">Ignore files in the same folder</x:String>
|
||||
|
|
|
@ -231,6 +231,24 @@
|
|||
<x:String x:Key="Text.GitFlow.StartRelease" xml:space="preserve">开始版本分支...</x:String>
|
||||
<x:String x:Key="Text.GitFlow.StartReleaseTitle" xml:space="preserve">开始版本分支</x:String>
|
||||
<x:String x:Key="Text.GitFlow.TagPrefix" xml:space="preserve">版本标签前缀 :</x:String>
|
||||
<x:String x:Key="Text.GitLFS" xml:space="preserve">Git LFS</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Fetch" xml:space="preserve">拉取LFS对象 (fetch) ...</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Fetch.Title" xml:space="preserve">拉取LFS对象</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Fetch.Tips" xml:space="preserve">执行`git lfs prune`命令,下载远程LFS对象,但不会更新工作副本。</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Install" xml:space="preserve">启用Git LFS支持</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks" xml:space="preserve">显示LFS对象锁</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks.Empty" xml:space="preserve">没有锁定的LFS文件</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks.Lock" xml:space="preserve">锁定</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks.Title" xml:space="preserve">LFS对象锁状态</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks.Unlock" xml:space="preserve">解锁</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks.UnlockForce" xml:space="preserve">强制解锁</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Prune" xml:space="preserve">精简本地LFS对象存储</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Prune.Tips" xml:space="preserve">运行`git lfs prune`命令,从本地存储中精简当前版本不需要的LFS对象</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Pull" xml:space="preserve">拉回LFS对象 (pull) ...</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Pull.Title" xml:space="preserve">拉回LFS对象</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Pull.Tips" xml:space="preserve">运行`git lfs pull`命令,下载远程LFS对象并更新工作副本。</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Track" xml:space="preserve">跟踪名为'{0}'的文件</x:String>
|
||||
<x:String x:Key="Text.GitLFS.TrackByExtension" xml:space="preserve">跟踪所有 *{0} 文件</x:String>
|
||||
<x:String x:Key="Text.Histories" xml:space="preserve">历史记录</x:String>
|
||||
<x:String x:Key="Text.Histories.DisplayMode" xml:space="preserve">切换横向/纵向显示</x:String>
|
||||
<x:String x:Key="Text.Histories.GraphMode" xml:space="preserve">切换曲线/折线显示</x:String>
|
||||
|
@ -376,7 +394,7 @@
|
|||
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">分支 :</x:String>
|
||||
<x:String x:Key="Text.Repository.Abort" xml:space="preserve">终止合并</x:String>
|
||||
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">清理本仓库(GC)</x:String>
|
||||
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">本操作将执行`gc`,对于启用LFS的仓库也会执行`lfs prune`。</x:String>
|
||||
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">本操作将执行`git gc`命令。</x:String>
|
||||
<x:String x:Key="Text.Repository.Configure" xml:space="preserve">配置本仓库</x:String>
|
||||
<x:String x:Key="Text.Repository.Continue" xml:space="preserve">下一步</x:String>
|
||||
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">在文件浏览器中打开</x:String>
|
||||
|
@ -480,7 +498,7 @@
|
|||
<x:String x:Key="Text.Welcome.Search" xml:space="preserve">快速查找仓库...</x:String>
|
||||
<x:String x:Key="Text.Welcome.Sort" xml:space="preserve">排序</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy" xml:space="preserve">本地更改</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">添加至 .gitignore 忽略列表 ...</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">添加至 .gitignore 忽略列表</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">忽略所有 *{0} 文件</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">忽略同目录下所有 *{0} 文件</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">忽略同目录下所有文件</x:String>
|
||||
|
|
|
@ -231,6 +231,24 @@
|
|||
<x:String x:Key="Text.GitFlow.StartRelease" xml:space="preserve">開始版本分支...</x:String>
|
||||
<x:String x:Key="Text.GitFlow.StartReleaseTitle" xml:space="preserve">開始版本分支</x:String>
|
||||
<x:String x:Key="Text.GitFlow.TagPrefix" xml:space="preserve">版本標籤字首 :</x:String>
|
||||
<x:String x:Key="Text.GitLFS" xml:space="preserve">Git LFS</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Fetch" xml:space="preserve">拉取LFS物件 (fetch) ...</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Fetch.Title" xml:space="preserve">拉取LFS物件</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Fetch.Tips" xml:space="preserve">執行`git lfs fetch`命令,下載遠端LFS物件,但不會更新工作副本。</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Install" xml:space="preserve">啟用Git LFS支援</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks" xml:space="preserve">顯示LFS物件鎖</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks.Empty" xml:space="preserve">沒有鎖定的LFS物件</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks.Lock" xml:space="preserve">鎖定</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks.Title" xml:space="preserve">LFS物件鎖</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks.Unlock" xml:space="preserve">解鎖</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Locks.UnlockForce" xml:space="preserve">強制解鎖</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Prune" xml:space="preserve">精簡本地LFS物件存儲</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Prune.Tips" xml:space="preserve">執行`git lfs prune`命令,從本地存儲中精簡當前版本不需要的LFS物件</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Pull" xml:space="preserve">拉回LFS物件 (pull) ...</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Pull.Title" xml:space="preserve">拉回LFS物件</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Pull.Tips" xml:space="preserve">執行`git lfs pull`命令,下載遠端LFS物件并更新工作副本。</x:String>
|
||||
<x:String x:Key="Text.GitLFS.Track" xml:space="preserve">跟蹤名為'{0}'的檔案</x:String>
|
||||
<x:String x:Key="Text.GitLFS.TrackByExtension" xml:space="preserve">跟蹤所有 *{0} 檔案</x:String>
|
||||
<x:String x:Key="Text.Histories" xml:space="preserve">歷史記錄</x:String>
|
||||
<x:String x:Key="Text.Histories.DisplayMode" xml:space="preserve">切換橫向/縱向顯示</x:String>
|
||||
<x:String x:Key="Text.Histories.GraphMode" xml:space="preserve">切換曲線/折線顯示</x:String>
|
||||
|
@ -376,7 +394,7 @@
|
|||
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">分支 :</x:String>
|
||||
<x:String x:Key="Text.Repository.Abort" xml:space="preserve">終止合併</x:String>
|
||||
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">清理本倉庫(GC)</x:String>
|
||||
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">本操作將執行`gc`,對於啟用LFS的倉庫也會執行`lfs prune`。</x:String>
|
||||
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">本操作將執行`git gc`命令。</x:String>
|
||||
<x:String x:Key="Text.Repository.Configure" xml:space="preserve">配置本倉庫</x:String>
|
||||
<x:String x:Key="Text.Repository.Continue" xml:space="preserve">下一步</x:String>
|
||||
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">在檔案瀏覽器中開啟</x:String>
|
||||
|
@ -480,7 +498,7 @@
|
|||
<x:String x:Key="Text.Welcome.Search" xml:space="preserve">快速查詢倉庫...</x:String>
|
||||
<x:String x:Key="Text.Welcome.Sort" xml:space="preserve">排序</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy" xml:space="preserve">本地更改</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">添加至 .gitignore 忽略清單 ...</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">添加至 .gitignore 忽略清單</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">忽略所有 *{0} 檔案</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">忽略同路徑下所有 *{0} 檔案</x:String>
|
||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">忽略同路徑下所有檔案</x:String>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
18
src/Views/LFSFetch.axaml
Normal file
18
src/Views/LFSFetch.axaml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:m="using:SourceGit.Models"
|
||||
xmlns:vm="using:SourceGit.ViewModels"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="SourceGit.Views.LFSFetch">
|
||||
<StackPanel Orientation="Vertical" Margin="8,0">
|
||||
<TextBlock FontSize="18"
|
||||
Classes="bold"
|
||||
Text="{DynamicResource Text.GitLFS.Fetch.Title}"/>
|
||||
<TextBlock Text="{DynamicResource Text.GitLFS.Fetch.Tips}"
|
||||
Margin="8,16,8,0"
|
||||
HorizontalAlignment="Center"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</UserControl>
|
12
src/Views/LFSFetch.axaml.cs
Normal file
12
src/Views/LFSFetch.axaml.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using Avalonia.Controls;
|
||||
|
||||
namespace SourceGit.Views
|
||||
{
|
||||
public partial class LFSFetch : UserControl
|
||||
{
|
||||
public LFSFetch()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
126
src/Views/LFSLocks.axaml
Normal file
126
src/Views/LFSLocks.axaml
Normal file
|
@ -0,0 +1,126 @@
|
|||
<v:ChromelessWindow xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:SourceGit.ViewModels"
|
||||
xmlns:c="using:SourceGit.Converters"
|
||||
xmlns:v="using:SourceGit.Views"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="SourceGit.Views.LFSLocks"
|
||||
x:DataType="vm:LFSLocks"
|
||||
Icon="/App.ico"
|
||||
Title="{DynamicResource Text.GitLFS.Locks.Title}"
|
||||
Width="600" Height="400"
|
||||
CanResize="False"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<!-- TitleBar -->
|
||||
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30">
|
||||
<Border Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Background="{DynamicResource Brush.TitleBar}"
|
||||
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
|
||||
PointerPressed="BeginMoveWindow"/>
|
||||
|
||||
<Path Grid.Column="0"
|
||||
Width="14" Height="14"
|
||||
Margin="10,0,0,0"
|
||||
Data="{StaticResource Icons.Lock}"
|
||||
IsVisible="{OnPlatform True, macOS=False}"/>
|
||||
|
||||
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
|
||||
<Button Classes="caption_button_macos" Click="CloseWindow">
|
||||
<Grid>
|
||||
<Ellipse Fill="{DynamicResource Brush.MacOS.Close}"/>
|
||||
<Path Height="6" Width="6" Stretch="Fill" Fill="#404040" Stroke="#404040" StrokeThickness="1" Data="{StaticResource Icons.Window.Close}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Classes="bold"
|
||||
Text="{DynamicResource Text.GitLFS.Locks.Title}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsHitTestVisible="False"/>
|
||||
|
||||
<Button Grid.Column="2"
|
||||
Classes="caption_button"
|
||||
Click="CloseWindow"
|
||||
IsVisible="{OnPlatform True, macOS=False}">
|
||||
<Path Data="{StaticResource Icons.Window.Close}"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<!-- Locked Files -->
|
||||
<Grid Grid.Row="1">
|
||||
<DataGrid Margin="8"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
ItemsSource="{Binding Locks}"
|
||||
SelectionMode="Single"
|
||||
CanUserReorderColumns="False"
|
||||
CanUserResizeColumns="False"
|
||||
CanUserSortColumns="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="None"
|
||||
Focusable="False"
|
||||
RowHeight="26"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{DynamicResource Brush.Border2}"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Width="*">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="14" Height="14" Margin="8,0,4,0" Data="{StaticResource Icons.File}"/>
|
||||
<TextBlock Text="{Binding File}" Margin="4,0"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn>
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding User}" Margin="8,0"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn>
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Button Classes="icon_button" Click="OnUnlockButtonClicked" ToolTip.Tip="{DynamicResource Text.GitLFS.Locks.Unlock}">
|
||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Unlock}"/>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn>
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Button Classes="icon_button" Click="OnForceUnlockButtonClicked" ToolTip.Tip="{DynamicResource Text.GitLFS.Locks.UnlockForce}">
|
||||
<Path Width="14" Height="14" Fill="Red" Data="{StaticResource Icons.Unlock}"/>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<!-- Empty -->
|
||||
<StackPanel Orientation="Vertical"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsVisible="{Binding IsEmpty}">
|
||||
<Path Width="48" Height="48" Data="{StaticResource Icons.Empty}" Fill="{DynamicResource Brush.FG2}"/>
|
||||
<TextBlock Margin="0,16,0,0" Text="{DynamicResource Text.GitLFS.Locks.Empty}" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Loading -->
|
||||
<v:LoadingIcon Width="48" Height="48"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
IsVisible="{Binding IsLoading}"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</v:ChromelessWindow>
|
40
src/Views/LFSLocks.axaml.cs
Normal file
40
src/Views/LFSLocks.axaml.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
||||
namespace SourceGit.Views
|
||||
{
|
||||
public partial class LFSLocks : ChromelessWindow
|
||||
{
|
||||
public LFSLocks()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void BeginMoveWindow(object sender, PointerPressedEventArgs e)
|
||||
{
|
||||
BeginMoveDrag(e);
|
||||
}
|
||||
|
||||
private void CloseWindow(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void OnUnlockButtonClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.LFSLocks vm && sender is Button button)
|
||||
vm.Unlock(button.DataContext as Models.LFSLock, false);
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OnForceUnlockButtonClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.LFSLocks vm && sender is Button button)
|
||||
vm.Unlock(button.DataContext as Models.LFSLock, true);
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
16
src/Views/LFSPrune.axaml
Normal file
16
src/Views/LFSPrune.axaml
Normal file
|
@ -0,0 +1,16 @@
|
|||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="SourceGit.Views.LFSPrune">
|
||||
<StackPanel Orientation="Vertical" Margin="8,0">
|
||||
<TextBlock FontSize="18"
|
||||
Classes="bold"
|
||||
Text="{DynamicResource Text.GitLFS.Prune}"/>
|
||||
<TextBlock Text="{DynamicResource Text.GitLFS.Prune.Tips}"
|
||||
Margin="8,16,8,0"
|
||||
HorizontalAlignment="Center"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</UserControl>
|
12
src/Views/LFSPrune.axaml.cs
Normal file
12
src/Views/LFSPrune.axaml.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using Avalonia.Controls;
|
||||
|
||||
namespace SourceGit.Views
|
||||
{
|
||||
public partial class LFSPrune : UserControl
|
||||
{
|
||||
public LFSPrune()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
18
src/Views/LFSPull.axaml
Normal file
18
src/Views/LFSPull.axaml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:m="using:SourceGit.Models"
|
||||
xmlns:vm="using:SourceGit.ViewModels"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="SourceGit.Views.LFSPull">
|
||||
<StackPanel Orientation="Vertical" Margin="8,0">
|
||||
<TextBlock FontSize="18"
|
||||
Classes="bold"
|
||||
Text="{DynamicResource Text.GitLFS.Pull.Title}"/>
|
||||
<TextBlock Text="{DynamicResource Text.GitLFS.Pull.Tips}"
|
||||
Margin="8,16,8,0"
|
||||
HorizontalAlignment="Center"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</UserControl>
|
12
src/Views/LFSPull.axaml.cs
Normal file
12
src/Views/LFSPull.axaml.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using Avalonia.Controls;
|
||||
|
||||
namespace SourceGit.Views
|
||||
{
|
||||
public partial class LFSPull : UserControl
|
||||
{
|
||||
public LFSPull()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -72,6 +72,10 @@
|
|||
<Button Classes="icon_button" Width="32" Margin="8,0,0,0" Click="OpenGitFlowMenu" ToolTip.Tip="{DynamicResource Text.GitFlow}">
|
||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Flow}"/>
|
||||
</Button>
|
||||
|
||||
<Button Classes="icon_button" Width="32" Margin="8,0,0,0" Click="OpenGitLFSMenu" ToolTip.Tip="{DynamicResource Text.GitLFS}">
|
||||
<Path Width="14" Height="14" Data="{StaticResource Icons.LFS}"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,0,4,0">
|
||||
|
|
|
@ -37,6 +37,17 @@ namespace SourceGit.Views
|
|||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void OpenGitLFSMenu(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.Repository repo)
|
||||
{
|
||||
var menu = repo.CreateContextMenuForGitLFS();
|
||||
(sender as Control)?.OpenContextMenu(menu);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private async void OpenStatistics(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is ViewModels.Repository repo)
|
||||
|
|
Loading…
Reference in a new issue