diff --git a/OmegaLeo.HelperLib.ConsoleApp/OmegaLeo.HelperLib.ConsoleApp.csproj b/OmegaLeo.HelperLib.ConsoleApp/OmegaLeo.HelperLib.ConsoleApp.csproj
new file mode 100644
index 0000000..366bf10
--- /dev/null
+++ b/OmegaLeo.HelperLib.ConsoleApp/OmegaLeo.HelperLib.ConsoleApp.csproj
@@ -0,0 +1,15 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
diff --git a/OmegaLeo.HelperLib.ConsoleApp/Program.cs b/OmegaLeo.HelperLib.ConsoleApp/Program.cs
new file mode 100644
index 0000000..56a573f
--- /dev/null
+++ b/OmegaLeo.HelperLib.ConsoleApp/Program.cs
@@ -0,0 +1,44 @@
+// See https://aka.ms/new-console-template for more information
+
+// /media/omegaleo/Development/Library Dev/HelperLib
+
+using GameDevLibrary.Extensions;
+using OmegaLeo.HelperLib.Git;
+using OmegaLeo.HelperLib.Git.Models;
+
+Console.WriteLine("Insert repo path to check changes:");
+var repo = Console.ReadLine();
+
+if (repo.IsNullOrEmpty())
+{
+ repo = "/media/omegaleo/Development/Library Dev/HelperLib";
+}
+
+var git = new GitClient(repo);
+
+var changes = git.GetChanges();
+
+if (changes != null)
+{
+ RecursiveOutput(new List() { changes });
+}
+
+Console.ReadLine();
+
+
+void RecursiveOutput(List folders, int depth = 0)
+{
+ foreach (var folder in folders)
+ {
+ Console.WriteLine($"{new string('\t', depth + 1)}>{folder.FolderName}");
+ if (folder.SubFolders.Any())
+ {
+ RecursiveOutput(folder.SubFolders, depth + 1);
+ }
+
+ foreach (var change in folder.ChangesInFolder)
+ {
+ Console.WriteLine($"{new string('\t', depth + 2)}>{Path.GetFileName(change.Path)} ({change.Status})");
+ }
+ }
+}
\ No newline at end of file
diff --git a/OmegaLeo.HelperLib.Git/GitClient.cs b/OmegaLeo.HelperLib.Git/GitClient.cs
new file mode 100644
index 0000000..79b7f90
--- /dev/null
+++ b/OmegaLeo.HelperLib.Git/GitClient.cs
@@ -0,0 +1,101 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using GameDevLibrary.Extensions;
+using LibGit2Sharp;
+using OmegaLeo.HelperLib.Git.Models;
+
+namespace OmegaLeo.HelperLib.Git
+{
+ public class GitClient
+ {
+ private Repository _repo;
+
+ public GitClient(string path)
+ {
+ if (path.IsNullOrEmpty())
+ {
+ path = AppDomain.CurrentDomain.BaseDirectory;
+ }
+
+ _repo = new Repository(path);
+ }
+
+ public void CheckoutBranch(string branchName)
+ {
+ var branch = _repo.Branches[branchName];
+
+ if (branch == null)
+ {
+ branch = _repo.CreateBranch(branchName);
+ }
+
+ Commands.Checkout(_repo, branch);
+ }
+
+ public bool HasChanges() => _repo.Diff.Compare().Count > 0;
+
+ public ChangeFolder GetChanges()
+ {
+ var folder = new ChangeFolder();
+
+ if (HasChanges())
+ {
+ var changes = _repo.Diff.Compare();
+
+ var allChanges = new List();
+ allChanges.AddRange(changes.Added);
+ allChanges.AddRange(changes.Modified);
+ allChanges.AddRange(changes.Deleted);
+
+ var uniqueFolderPaths = allChanges.Select(x => Path.GetDirectoryName(x.Path)).Distinct();
+
+
+
+ foreach (var path in uniqueFolderPaths)
+ {
+ if (path.IsNullOrEmpty()) continue;
+
+ if (path.Contains(Path.DirectorySeparatorChar))
+ {
+ var paths = path.Split(Path.DirectorySeparatorChar);
+
+ for (var i = 0; i < paths.Length; i++)
+ {
+ var p = paths[i];
+
+ if (folder.FolderName.Equals(p))
+ {
+ if (folder.ChangesInFolder.Any()) continue;
+
+ folder.ChangesInFolder =
+ allChanges.Where(x => Path.GetDirectoryName(x.Path)!.Equals(p, StringComparison.OrdinalIgnoreCase));
+ }
+ else
+ {
+ var pathList = paths[0..(i+1)].ToList();
+ var subFolder = folder.RecursiveGet(pathList);
+ var fullPath = string.Join(Path.DirectorySeparatorChar, pathList);
+
+ if (!subFolder.ChangesInFolder.Any())
+ {
+ subFolder.ChangesInFolder = allChanges.Where(x =>
+ Path.GetDirectoryName(x.Path)!.Equals(fullPath, StringComparison.OrdinalIgnoreCase));
+ }
+ }
+ }
+ }
+ else
+ {
+ folder.FolderName = path;
+ folder.ChangesInFolder =
+ allChanges.Where(x => Path.GetDirectoryName(x.Path)!.Equals(path, StringComparison.OrdinalIgnoreCase));
+ }
+ }
+ }
+
+ return folder;
+ }
+ }
+}
\ No newline at end of file
diff --git a/OmegaLeo.HelperLib.Git/Models/ChangeFolder.cs b/OmegaLeo.HelperLib.Git/Models/ChangeFolder.cs
new file mode 100644
index 0000000..ecb9c71
--- /dev/null
+++ b/OmegaLeo.HelperLib.Git/Models/ChangeFolder.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using LibGit2Sharp;
+
+namespace OmegaLeo.HelperLib.Git.Models
+{
+ public class ChangeFolder
+ {
+ public string FolderName { get; set; }
+ public List SubFolders { get; set; }
+ public IEnumerable ChangesInFolder { get; set; }
+
+ public ChangeFolder()
+ {
+ FolderName = "";
+ SubFolders = new List();
+ ChangesInFolder = new List();
+ }
+
+ public ChangeFolder RecursiveGet(List paths)
+ {
+ if (!paths.Any()) return null;
+
+ var tempPaths = paths;
+ var pathToCheck = tempPaths.FirstOrDefault();
+
+ ChangeFolder folder = new ChangeFolder();
+
+ if (FolderName.Equals(pathToCheck, StringComparison.OrdinalIgnoreCase))
+ {
+ folder = this;
+ }
+ else if (SubFolders.Any(x => x.FolderName.Equals(pathToCheck)))
+ {
+ folder = SubFolders.FirstOrDefault(x => x.FolderName.Equals(pathToCheck))!;
+ }
+ else
+ {
+ folder.FolderName = pathToCheck;
+ SubFolders.Add(folder);
+ }
+
+ tempPaths.RemoveAt(0);
+
+ if (tempPaths.Any())
+ {
+ return folder.RecursiveGet(tempPaths);
+ }
+ else
+ {
+ return folder;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/OmegaLeo.HelperLib.Git/OmegaLeo.HelperLib.Git.csproj b/OmegaLeo.HelperLib.Git/OmegaLeo.HelperLib.Git.csproj
new file mode 100644
index 0000000..c149dcf
--- /dev/null
+++ b/OmegaLeo.HelperLib.Git/OmegaLeo.HelperLib.Git.csproj
@@ -0,0 +1,23 @@
+
+
+
+ netstandard2.1
+ enable
+ GameDevLibrary.Git
+ 0.0.2
+ Omega Leo's Helper Library - LibGit2Sharp Implementation
+ Nuno "Omega Leo" Diogo
+ https://github.com/omegaleo/HelperLib
+ https://github.com/omegaleo/HelperLib
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OmegaLeo.HelperLib.sln b/OmegaLeo.HelperLib.sln
index 9e6e5fc..a1fbcfb 100644
--- a/OmegaLeo.HelperLib.sln
+++ b/OmegaLeo.HelperLib.sln
@@ -2,6 +2,10 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmegaLeo.HelperLib", "OmegaLeo.HelperLib\OmegaLeo.HelperLib.csproj", "{A7256931-5D66-46FA-BA50-22B2FA4CD9E9}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmegaLeo.HelperLib.Git", "OmegaLeo.HelperLib.Git\OmegaLeo.HelperLib.Git.csproj", "{A9579FFB-9A05-4EBF-B298-513C48FB0F91}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmegaLeo.HelperLib.ConsoleApp", "OmegaLeo.HelperLib.ConsoleApp\OmegaLeo.HelperLib.ConsoleApp.csproj", "{3B77B177-FD47-470A-B0EF-01EF8B30CE09}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -12,5 +16,13 @@ Global
{A7256931-5D66-46FA-BA50-22B2FA4CD9E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7256931-5D66-46FA-BA50-22B2FA4CD9E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7256931-5D66-46FA-BA50-22B2FA4CD9E9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A9579FFB-9A05-4EBF-B298-513C48FB0F91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A9579FFB-9A05-4EBF-B298-513C48FB0F91}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A9579FFB-9A05-4EBF-B298-513C48FB0F91}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A9579FFB-9A05-4EBF-B298-513C48FB0F91}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3B77B177-FD47-470A-B0EF-01EF8B30CE09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3B77B177-FD47-470A-B0EF-01EF8B30CE09}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3B77B177-FD47-470A-B0EF-01EF8B30CE09}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3B77B177-FD47-470A-B0EF-01EF8B30CE09}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/OmegaLeo.HelperLib.sln.DotSettings.user b/OmegaLeo.HelperLib.sln.DotSettings.user
new file mode 100644
index 0000000..40fa42b
--- /dev/null
+++ b/OmegaLeo.HelperLib.sln.DotSettings.user
@@ -0,0 +1,2 @@
+
+ ForceIncluded
\ No newline at end of file