Skip to content

Instantly share code, notes, and snippets.

@Baste-RainGames
Last active May 10, 2019 12:14
Show Gist options
  • Save Baste-RainGames/2ec5ebba967f679609651b4cab8bd70c to your computer and use it in GitHub Desktop.
Save Baste-RainGames/2ec5ebba967f679609651b4cab8bd70c to your computer and use it in GitHub Desktop.
Git interop from Unity
using System;
using System.Diagnostics;
using System.Linq;
using System.Text;
using UnityEngine;
namespace RainEditor.EditorTools {
public class GitInterop {
/// <summary>
/// Runs a git command and returns the result. Assumes you have git installed and on the PATH.
///
/// When starting git through Process.Start in Unity, two git processes are spawned. The one you wanted, and another one that is just an empty window that
/// doesn't do anything. IDK what that's all about.
///
/// This handles that by finding and closing that other window, taking care to not kill other git processes that might be running at the same time.
/// </summary>
/// <param name="command">Git command to run.</param>
/// <returns>Output. Will be truncated if it's too many lines.</returns>
public static (bool success, string result) RunGitCommand(string command) {
try {
var gitProcessIDsFromBefore = Process.GetProcessesByName("git").Select(p => p.Id);
var runCommandProcess = new Process {
StartInfo = {
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
FileName = "git",
Arguments = command,
// CreateNoWindow = true,
WorkingDirectory = Application.dataPath.Substring(0, Application.dataPath.Length - "Assets/".Length)
},
};
runCommandProcess.Start();
var errorBuilder = new StringBuilder();
while (runCommandProcess.StandardError.Peek() >= 0) {
errorBuilder.AppendLine(runCommandProcess.StandardError.ReadLine());
}
if (errorBuilder.Length > 0) {
return (false, $"git returned an error when running \"git {command}\". The error message is:\n{errorBuilder}");
}
var outputBuilder = new StringBuilder();
while (runCommandProcess.StandardOutput.Peek() >= 0) {
outputBuilder.AppendLine(runCommandProcess.StandardOutput.ReadLine());
}
runCommandProcess.CloseMainWindow();
var currentGitProcesses = Process.GetProcessesByName("git");
foreach (var process in currentGitProcesses) {
if (!gitProcessIDsFromBefore.Any(id => id == process.Id)) {
process.Kill();
}
}
return (true, outputBuilder.ToString());
}
catch (Exception e) {
return (false, $"Got an {e.GetType().Name} when running \"git {command}\", exception message is:\n{e.Message}");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment