private System.Exception CreateException(string message, string uri) { if (process.Execute("git --version", out _, out string stderr) != 0) { return(new RuntimeException(BucketProcessExecutor.FilterSensitive($"Failed to clone {uri}, git was not found, check that it is installed and in your PATH env.{Environment.NewLine}{Environment.NewLine}{stderr}"))); } return(new RuntimeException(BucketProcessExecutor.FilterSensitive(message))); }
/// <summary> /// Updates the given path to the given commit ref. /// </summary> /// <param name="cwd">The given path.</param> /// <param name="reference">Checkout to specified reference(commit ref, tag, branch).</param> /// <param name="branch">The name of the branch to use when checking out.</param> /// <returns>If a string is returned, it is the commit reference that was checked out if the original could not be found.</returns> protected virtual string UpdateToCommit(string cwd, string reference, string branch, DateTime?releaseDate) { Process.Execute("git branch -r", out string branches, cwd); bool IsGitHash(string hash) { return(Regex.IsMatch(hash, "^[a-f0-9]{40}$")); } bool IsBranchesHasRemote(string remote) { return(Regex.IsMatch(branches, $"^\\s+bucket/{Regex.Escape(remote)}\r?$", RegexOptions.Multiline)); } string command; var force = hasDiscardedChanges || hasStashedChanges ? "-f " : string.Empty; branch = Regex.Replace(branch ?? string.Empty, @"(?:^dev-|(?:\.x)?-dev$)", string.Empty, RegexOptions.IgnoreCase); // check whether non-commitish are branches or tags, and fetch branches // with the remote name. Use branch(in the context may be the version) // as the new branch name. if (!IsGitHash(reference) && !string.IsNullOrEmpty(branches) && IsBranchesHasRemote(reference)) { var escapedBranch = ProcessExecutor.Escape(branch); var escapedReference = ProcessExecutor.Escape($"bucket/{reference}"); command = $"git checkout {force}-B {escapedBranch} {escapedReference} -- && git reset --hard {escapedReference} --"; if (Process.Execute(command, cwd) == 0) { return(null); } } // try to checkout branch by name and then reset it so it's on the proper branch name. if (IsGitHash(reference)) { // add 'v' in front of the branch if it was stripped when generating the pretty name. if (!IsBranchesHasRemote(branch) && IsBranchesHasRemote($"v{branch}")) { branch = $"v{branch}"; } var escapedBranch = ProcessExecutor.Escape(branch); command = $"git checkout {escapedBranch} --"; var fallbackCommand = $"git checkout {force}-B {escapedBranch} {ProcessExecutor.Escape($"bucket/{branch}")} --"; if (Process.Execute(command, cwd) == 0 || Process.Execute(fallbackCommand, cwd) == 0) { command = $"git reset --hard {ProcessExecutor.Escape(reference)} --"; if (Process.Execute(command, cwd) == 0) { return(null); } } } // This uses the "--" sequence to separate branch from file parameters. // // Otherwise git tries the branch name as well as file name. // If the non-existent branch is actually the name of a file, the file // is checked out. var escapedGitReference = ProcessExecutor.Escape(reference); command = $"git checkout {force}{escapedGitReference} -- && git reset --hard {escapedGitReference} --"; if (Process.Execute(command, out _, out string stderr, cwd) == 0) { return(null); } // reference was not found (prints "fatal: reference is not a tree: $ref"). if (stderr.Contains(reference)) { IO.WriteError($" <warning>{reference} is gone (history was rewritten?)</warning>"); } stderr = BucketProcessExecutor.FilterSensitive($"Failed to execute \"{command}\" {Environment.NewLine}{Environment.NewLine}{stderr}"); throw new RuntimeException(stderr); }