public Repository(ICredentialManager credentials, string url, string localDestination, string copyDestination, string subFolder, string branch = "master", string tag = "") { _state = new RepoState { CredentialManager = credentials, Url = url, LocalDestination = localDestination, CopyDestination = copyDestination, SubFolder = subFolder, Branch = branch, Tag = tag }; }
public RepoVm(RepoState repoState) { _repoState = repoState; ShortDescription = _repoState.IsUnknown ? "<unknown>" : _repoState.ShortText; if (_repoState.IsSecurityFailure) { StateText = "⛒"; StateColor = "darkslategrey"; TextColor = "yellow"; ShortDescription = _repoState.LongText; return; } if (_repoState.IsFailed) { StateText = "?"; StateColor = "black"; TextColor = "gray"; ShortDescription = _repoState.LongText; return; } if (_repoState.IsUnknown) { StateText = "?"; StateColor = "gray"; TextColor = "white"; return; } // What could be happened ? if (_repoState.IsClean) { if (_repoState.AheadBy > 0) { StateText = $"+{_repoState.AheadBy.ToString()}"; StateColor = "blue"; TextColor = "white"; return; } if (_repoState.BehindBy > 0) { StateText = $"-{_repoState.BehindBy.ToString()}"; StateColor = "yellow"; TextColor = "black"; return; } } if (_repoState.ModifiedCount > 0) { if (_repoState.BehindBy > 0) { // During you work - thi is NOT fine StateText = "❌"; StateColor = "tomato"; TextColor = "yellow"; return; } StateText = $"~{_repoState.ModifiedCount.ToString()}"; StateColor = "orange"; TextColor = "white"; return; } if (_repoState.UntrackedCount > 0) { StateText = $"+{_repoState.UntrackedCount.ToString()}"; StateColor = "slateblue"; TextColor = "white"; return; } // everything fine StateText = "✓"; StateColor = "darkolivegreen"; TextColor = "white"; }
/// <summary> /// Runs in a thread pool. should clone then checkout the appropriate branch/commit. copy subdirectory into specified repo. /// </summary> /// <param name="stateInfo"></param> private void UpdateTask(object stateInfo) { //Do as much as possible outside of unity so we dont get constant rebuilds. Only when everything is ready RepoState state = (RepoState)stateInfo; if (state == null) { _lastOperationSuccess = false; _progressQueue.Enqueue(new Progress(0, "Repository state info is null")); return; } if (state.CredentialManager == null) { _lastOperationSuccess = false; _progressQueue.Enqueue(new Progress(0, "Credentials manager is null")); return; } FetchOptions fetchOptions = new FetchOptions() { /*TagFetchMode = TagFetchMode.All, * OnTransferProgress = new LibGit2Sharp.Handlers.TransferProgressHandler((progress) => * { * _progressQueue.Enqueue(new Progress(((float)progress.ReceivedObjects) / progress.TotalObjects, "Fetching " + progress.ReceivedObjects + "/" + progress.TotalObjects + "(" + progress.ReceivedBytes + " bytes )")); * * return _cancellationPending; * }),*/ CredentialsProvider = (credsUrl, user, supportedCredentials) => { state.CredentialManager.GetCredentials(credsUrl, user, supportedCredentials, out var credentials, out string message); return(credentials); } }; if (LibGit2Sharp.Repository.IsValid(state.LocalDestination)) { _progressQueue.Enqueue(new Progress(0, "Found local repository.")); //Repo exists we are doing a pull using (var repo = new LibGit2Sharp.Repository(state.LocalDestination)) { //_progressQueue.Enqueue(new Progress(0, "Nuking local changes. Checking out " + state.Branch)); //Branch branch = repo.Branches[state.Branch]; //Commands.Checkout(repo, branch, new CheckoutOptions() { CheckoutModifiers = CheckoutModifiers.Force, CheckoutNotifyFlags = CheckoutNotifyFlags.None}); // Credential information to fetch PullOptions options = new PullOptions { FetchOptions = fetchOptions }; // User information to create a merge commit. Should not happen as we force checkout before pulling. var signature = new LibGit2Sharp.Signature( new Identity("RepositoryManager", "*****@*****.**"), DateTimeOffset.Now); try { _progressQueue.Enqueue(new Progress(0, "Pulling from " + state.Url)); Commands.Pull(repo, signature, options); _progressQueue.Enqueue(new Progress(1, "Complete")); _lastOperationSuccess = true; } catch (Exception e) { _progressQueue.Enqueue(new Progress(0, "Pull failed: " + e.Message)); _lastOperationSuccess = false; } /*try * { * var remote = repo.Network.Remotes["origin"]; * var refSpecs = remote.FetchRefSpecs.Select(x => x.Specification); * * _progressQueue.Enqueue(new Progress(0, "Fetching from " + remote.Name)); * * Commands.Fetch(repo, remote.Name, refSpecs, fetchOptions, ""); * * _progressQueue.Enqueue(new Progress(1, "Complete")); * * try * { * Branch branch = repo.Branches["origin/" + state.Branch]; * var signature = new Signature(new Identity("RepositoryManager", "*****@*****.**"), DateTimeOffset.Now); * repo.Merge(branch, signature); * * _lastOperationSuccess = true; * } * catch (Exception e) * { * _progressQueue.Enqueue(new Progress(0, "Merge failed: " + e.Message)); * _lastOperationSuccess = false; * } * } * catch (Exception e) * { * _progressQueue.Enqueue(new Progress(0, "Fetch failed: " + e.Message)); * _lastOperationSuccess = false; * }*/ } } else { _progressQueue.Enqueue(new Progress(0, "Initializing clone")); //Repo does not exist. Clone it. CloneOptions options = new CloneOptions() { CredentialsProvider = (credsUrl, user, supportedCredentials) => { if (!state.CredentialManager.GetCredentials(credsUrl, user, supportedCredentials, out var credentials, out string message)) { throw new Exception("Failed to get credentials: " + message); } return(credentials); }, IsBare = false, // True will result in a bare clone, false a full clone. Checkout = true, // If true, the origin's HEAD will be checked out. This only applies to non-bare repositories. BranchName = state.Branch, // The name of the branch to checkout. When unspecified the remote's default branch will be used instead. RecurseSubmodules = false, // Recursively clone submodules. OnCheckoutProgress = new LibGit2Sharp.Handlers.CheckoutProgressHandler((message, value, total) => { _progressQueue.Enqueue(new Progress(Math.Max(Math.Min(((float)value) / total, 1), 0), message)); }), // Handler for checkout progress information. FetchOptions = fetchOptions }; try { _progressQueue.Enqueue(new Progress(0, "Cloning " + state.Url)); LibGit2Sharp.Repository.Clone(state.Url, state.LocalDestination, options); _progressQueue.Enqueue(new Progress(1, "Complete")); _lastOperationSuccess = true; } catch (Exception e) { _progressQueue.Enqueue(new Progress(0, "Clone failed: " + e.Message)); _lastOperationSuccess = false; } } if (LastOperationSuccess) { _progressQueue.Enqueue(new Progress(1, "Downloading LFS files")); try { InstallAndPullLFS(state.LocalDestination); } catch (Exception e) { _progressQueue.Enqueue(new Progress(0, "LFS Pull failed: " + e.Message)); _lastOperationSuccess = false; } } //Once completed _inProgress = false; _cancellationPending = false; }