///// <summary> ///// Clones a repository ///// </summary> ///// <param name="gitUrl"></param> ///// <param name="localPath"></param> ///// <param name="useGitCredentialManager"></param> ///// <param name="username"></param> ///// <param name="password"></param> ///// <returns></returns> //public bool CloneRepository(string gitUrl, // string localPath, // bool useGitCredentialManager = false, // string username = null, // string password = null, // string branch = "master" // ) //{ // try // { // var options = new CloneOptions // { // Checkout = true, // BranchName = branch // }; // if (CloneProgress != null) // options.OnProgress = new LibGit2Sharp.Handlers.ProgressHandler(CloneProgress); // if (useGitCredentialManager) // { // var creds = GetGitCredentials(gitUrl); // if (creds?.Username != null) // { // options.CredentialsProvider = (_url, _user, _cred) => new UsernamePasswordCredentials() // { // Username = creds.Username, // Password = creds.Password // }; // } // else // { // // oAuth flow then set credentials // } // } // else if (!string.IsNullOrEmpty(username)) // { // options.CredentialsProvider = (_url, _user, _cred) => new UsernamePasswordCredentials() // { // Username = username, // Password = password // }; // } // Repository.Clone(gitUrl, localPath, options); // } // catch (Exception ex) // { // SetError(ex); // return false; // } // return true; //} /// <summary> /// Clones a repository using the Command Line Tooling. /// Provides built-in authentication UI. /// </summary> /// <param name="gitUrl"></param> /// <param name="localPath"></param> /// <param name="depth">Depth of the Git revision history (shallow copy)</param> /// <returns></returns> public GitCommandResult CloneRepositoryCommandLine(string gitUrl, string localPath, Action <object, DataReceivedEventArgs> progress = null, int depth = 0) { try { string cloneDepth = null; if (depth > 0) { cloneDepth = $" --depth={depth}"; } return(ExecuteGitCommand($"clone {gitUrl} \"{localPath}\"{cloneDepth}", timeoutMs: 100000, windowStyle: ProcessWindowStyle.Hidden, progress: progress)); } catch (Exception ex) { var result = new GitCommandResult { HasError = true, Message = "Error cloning repository: " + ex.Message }; return(result); } }
/// <summary> /// Executes a Git Command on the command line. /// /// Recommend that you only use this for Remote commands that /// require authentication so that the Windows Credentials Store /// can handle providing sticky Auth to Github, VSTS and BitBucket. /// </summary> /// <param name="arguments"></param> /// <param name="timeoutMs"></param> /// <param name="windowStyle"></param> /// <param name="progress"></param> /// <returns></returns> public GitCommandResult ExecuteGitCommand(string arguments, string path = null, int timeoutMs = 10000, ProcessWindowStyle windowStyle = ProcessWindowStyle.Hidden, Action <object, DataReceivedEventArgs> progress = null) { Process process; var result = new GitCommandResult(); if (string.IsNullOrEmpty(arguments)) { return(null); } arguments = arguments.Trim(); string oldPath = null; if (!string.IsNullOrEmpty(path)) { oldPath = Directory.GetCurrentDirectory(); Directory.SetCurrentDirectory(path); } try { using (process = new Process()) { process.StartInfo.FileName = "git.exe"; process.StartInfo.Arguments = arguments; process.StartInfo.WindowStyle = windowStyle; if (windowStyle == ProcessWindowStyle.Hidden) { process.StartInfo.CreateNoWindow = true; } process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; DataReceivedEventHandler evh = (s, e) => { progress(s, e); result.Output += e.Data; }; bool hookupProgressEvents = progress != null && timeoutMs > 0; if (hookupProgressEvents) { process.OutputDataReceived += evh; process.ErrorDataReceived += evh; } process.Start(); if (hookupProgressEvents) { process.BeginOutputReadLine(); process.BeginErrorReadLine(); } if (timeoutMs < 0) { timeoutMs = 99999999; // indefinitely } if (timeoutMs > 0) { bool waited = process.WaitForExit(timeoutMs); if (hookupProgressEvents) { process.OutputDataReceived -= evh; process.ErrorDataReceived -= evh; } else { result.Output = process.StandardError.ReadToEnd(); } result.ExitCode = process.ExitCode; if (result.ExitCode != 0) { result.HasError = true; } if (!waited) { result.HasError = true; if (result.ExitCode == 0) { result.Message = "Process timed out."; } } else if (result.HasError) { result.Message = result.Output; } if (oldPath != null) { Directory.SetCurrentDirectory(oldPath); } return(result); } result.ExitCode = process.ExitCode; } } catch (Exception ex) { result.ExitCode = -1; result.Message = ex.Message; } if (oldPath != null) { Directory.SetCurrentDirectory(oldPath); } return(result); }