using LibGit2Sharp; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.Core; namespace Tango.Git { public class GitRepositoryManager : IDisposable { private Repository _repo; private String _pat; private String _userEmail; private String _localFolder; public event EventHandler> Progress; public GitRepositoryManager(String localFolder, String userEmail, String personalAccessToken) { _pat = personalAccessToken; _userEmail = userEmail; _localFolder = localFolder; _repo = new Repository(_localFolder); } public void CreatePushTag(String name, String description, String userName) { var tag = _repo.ApplyTag(name, new Signature(userName, _userEmail, DateTime.Now), description); _repo.Network.Push(_repo.Network.Remotes.First(), tag.CanonicalName, new PushOptions() { CredentialsProvider = new LibGit2Sharp.Handlers.CredentialsHandler(CredentialsHandlerMethod), OnPushTransferProgress = new LibGit2Sharp.Handlers.PushTransferProgressHandler(PushTagProgressHandlerMethod) }); } public void Commit(String message) { ExecuteGitProcess($"commit -a -m \"{message}\""); } public void Pull() { ExecuteGitProcess($"pull"); } public void Push() { ExecuteGitProcess($"push"); } public void Sync() { Pull(); Push(); } private bool PushTagProgressHandlerMethod(int current, int total, long bytes) { //TODO: Implement via TangoProgress & event... RaiseProgress("Pushing Tag...", false, 0, total); return true; } public List GetOutgoingCommits() { List commits = new List(); var branch = _repo.Head.TrackedBranch; if (branch.TrackingDetails.AheadBy != null) { foreach (var commit in _repo.Commits.Take(branch.TrackingDetails.AheadBy.Value)) { commits.Add(new GitCommit() { Message = commit.Message }); } } return commits; } public List GetIncomingCommits() { List commits = new List(); var trackingBranch = _repo.Head.TrackedBranch; var log = _repo.Commits.QueryBy(new CommitFilter { IncludeReachableFrom = trackingBranch.Tip.Id, ExcludeReachableFrom = _repo.Head.Tip.Id }); var count = log.Count(); foreach (var commit in log) { commits.Add(new GitCommit() { Message = commit.Message }); } return commits; } public List GetChanges() { List files = new List(); var status = _repo.RetrieveStatus(); foreach (var file in status.Added) { files.Add(new GitFile() { File = file.FilePath, State = GitFileState.Added }); } foreach (var file in status.Modified) { files.Add(new GitFile() { File = file.FilePath, State = GitFileState.Modified }); } return files; } private Credentials CredentialsHandlerMethod(string url, string usernameFromUrl, SupportedCredentialTypes types) { return new UsernamePasswordCredentials { Username = _userEmail, Password = _pat }; } protected virtual void RaiseProgress(String message, bool isIndeterminate = true, double value = 0, double maximum = 100) { Progress?.Invoke(this, new TangoProgressChangedEventArgs(new TangoProgress() { IsIndeterminate = isIndeterminate, Message = message, Value = value, Maximum = maximum })); } private void ExecuteGitProcess(String args) { Core.Components.CmdCommand command = new Core.Components.CmdCommand("git", args); command.WorkingDir = _localFolder; command.Timeout = TimeSpan.FromSeconds(60); var result = command.Run().Result; } public void Dispose() { _repo.Dispose(); } } }