You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2132 lines
74 KiB
2132 lines
74 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Security.Permissions;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using GitCommands.Config;
|
|
using PatchApply;
|
|
|
|
namespace GitCommands
|
|
{
|
|
public static class GitCommandHelpers
|
|
{
|
|
private static GitVersion _versionInUse;
|
|
|
|
/// <summary>
|
|
/// This is a faster function to get the names of all submodules then the
|
|
/// GetSubmodules() function. The command @git submodule is very slow.
|
|
/// </summary>
|
|
public static IList<string> GetSubmodulesNames()
|
|
{
|
|
IList<string> submodulesNames = new List<string>();
|
|
ConfigFile configFile = new ConfigFile(Settings.WorkingDir + ".gitmodules");
|
|
foreach (ConfigSection configSection in configFile.GetConfigSections())
|
|
{
|
|
submodulesNames.Add(configSection.SubSection);
|
|
}
|
|
|
|
return submodulesNames;
|
|
}
|
|
|
|
public static string GetGlobalSetting(string setting)
|
|
{
|
|
var configFile = GitCommandHelpers.GetGlobalConfig();
|
|
return configFile.GetValue(setting);
|
|
}
|
|
|
|
public static void SetGlobalSetting(string setting, string value)
|
|
{
|
|
var configFile = GitCommandHelpers.GetGlobalConfig();
|
|
configFile.SetValue(setting, value);
|
|
configFile.Save();
|
|
}
|
|
|
|
public static GitVersion VersionInUse
|
|
{
|
|
get
|
|
{
|
|
if (_versionInUse == null || _versionInUse.IsUnknown)
|
|
{
|
|
var result = RunCmd(Settings.GitCommand, "--version");
|
|
_versionInUse = new GitVersion(result);
|
|
}
|
|
|
|
return _versionInUse;
|
|
}
|
|
}
|
|
|
|
public static string FindGitWorkingDir(string startDir)
|
|
{
|
|
if (string.IsNullOrEmpty(startDir))
|
|
return "";
|
|
|
|
if (!startDir.EndsWith(Settings.PathSeparator.ToString()) && !startDir.EndsWith(Settings.PathSeparatorWrong.ToString()))
|
|
startDir += Settings.PathSeparator;
|
|
|
|
var dir = startDir;
|
|
|
|
while (dir.LastIndexOfAny(new[] { Settings.PathSeparator, Settings.PathSeparatorWrong }) > 0)
|
|
{
|
|
dir = dir.Substring(0, dir.LastIndexOfAny(new[] { Settings.PathSeparator, Settings.PathSeparatorWrong }));
|
|
|
|
if (Settings.ValidWorkingDir(dir))
|
|
return dir + Settings.PathSeparator;
|
|
}
|
|
return startDir;
|
|
}
|
|
|
|
public static Encoding GetLogoutputEncoding()
|
|
{
|
|
string encodingString;
|
|
encodingString = GetLocalConfig().GetValue("i18n.logoutputencoding");
|
|
if (string.IsNullOrEmpty(encodingString))
|
|
encodingString = GetGlobalConfig().GetValue("i18n.logoutputencoding");
|
|
if (string.IsNullOrEmpty(encodingString))
|
|
encodingString = GetLocalConfig().GetValue("i18n.commitEncoding");
|
|
if (string.IsNullOrEmpty(encodingString))
|
|
encodingString = GetGlobalConfig().GetValue("i18n.commitEncoding");
|
|
if (!string.IsNullOrEmpty(encodingString))
|
|
{
|
|
try
|
|
{
|
|
return Encoding.GetEncoding(encodingString);
|
|
}
|
|
catch (ArgumentException ex)
|
|
{
|
|
throw new Exception(ex.Message + Environment.NewLine + "Unsupported encoding set in git config file: " + encodingString + Environment.NewLine + "Please check the setting i18n.commitencoding in your local and/or global config files. Command aborted.", ex);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return Encoding.UTF8;
|
|
}
|
|
}
|
|
|
|
public static string RunCmd(string cmd)
|
|
{
|
|
return RunCmd(cmd, "");
|
|
}
|
|
|
|
public static void SetEnvironmentVariable()
|
|
{
|
|
SetEnvironmentVariable(false);
|
|
}
|
|
|
|
public static void SetEnvironmentVariable(bool reload)
|
|
{
|
|
if (!string.IsNullOrEmpty(Settings.CustomHomeDir))
|
|
{
|
|
Environment.SetEnvironmentVariable(
|
|
"HOME",
|
|
Settings.CustomHomeDir);
|
|
return;
|
|
}
|
|
|
|
if (Settings.UserProfileHomeDir)
|
|
{
|
|
Environment.SetEnvironmentVariable(
|
|
"HOME",
|
|
Environment.GetEnvironmentVariable("USERPROFILE"));
|
|
return;
|
|
}
|
|
|
|
if (reload)
|
|
{
|
|
Environment.SetEnvironmentVariable(
|
|
"HOME",
|
|
Environment.GetEnvironmentVariable("HOME", EnvironmentVariableTarget.User));
|
|
}
|
|
|
|
//Default!
|
|
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("HOME")))
|
|
return;
|
|
|
|
string homePath;
|
|
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("HOMEDRIVE")))
|
|
{
|
|
homePath = Environment.GetEnvironmentVariable("HOMEDRIVE");
|
|
homePath += Environment.GetEnvironmentVariable("HOMEPATH");
|
|
}
|
|
else
|
|
{
|
|
homePath = Environment.GetEnvironmentVariable("USERPROFILE");
|
|
}
|
|
Environment.SetEnvironmentVariable("HOME", homePath);
|
|
}
|
|
|
|
public static void RunRealCmd(string cmd, string arguments)
|
|
{
|
|
try
|
|
{
|
|
CreateAndStartCommand(cmd, arguments, true);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Trace.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
private static string FixPath(string path)
|
|
{
|
|
path = path.Trim();
|
|
|
|
return path.StartsWith("\\\\") ? path : path.Replace('\\', '/');
|
|
}
|
|
|
|
public static void RunRealCmdDetached(string cmd, string arguments)
|
|
{
|
|
try
|
|
{
|
|
CreateAndStartCommand(cmd, arguments, false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Trace.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
private static void CreateAndStartCommand(string cmd, string arguments, bool waitForExit)
|
|
{
|
|
SetEnvironmentVariable();
|
|
|
|
Settings.GitLog.Log(cmd + " " + arguments);
|
|
//process used to execute external commands
|
|
|
|
var info = new ProcessStartInfo()
|
|
{
|
|
UseShellExecute = true,
|
|
ErrorDialog = false,
|
|
RedirectStandardOutput = false,
|
|
RedirectStandardInput = false,
|
|
CreateNoWindow = false,
|
|
FileName = cmd,
|
|
Arguments = arguments,
|
|
WorkingDirectory = Settings.WorkingDir,
|
|
WindowStyle = ProcessWindowStyle.Normal,
|
|
LoadUserProfile = true
|
|
};
|
|
|
|
if (waitForExit)
|
|
{
|
|
using (var process = Process.Start(info))
|
|
{
|
|
process.WaitForExit();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Process.Start(info);
|
|
}
|
|
}
|
|
|
|
public static void StartExternalCommand(string cmd, string arguments)
|
|
{
|
|
try
|
|
{
|
|
SetEnvironmentVariable();
|
|
|
|
var processInfo = new ProcessStartInfo()
|
|
{
|
|
UseShellExecute = false,
|
|
RedirectStandardOutput = false,
|
|
FileName = cmd,
|
|
Arguments = arguments,
|
|
CreateNoWindow = true
|
|
};
|
|
|
|
using (var process = new Process() { StartInfo = processInfo })
|
|
{
|
|
process.Start();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.ToString());
|
|
}
|
|
}
|
|
|
|
internal static ProcessStartInfo CreateProcessStartInfo()
|
|
{
|
|
return new ProcessStartInfo()
|
|
{
|
|
UseShellExecute = false,
|
|
ErrorDialog = false,
|
|
RedirectStandardOutput = true,
|
|
RedirectStandardInput = true,
|
|
RedirectStandardError = true,
|
|
StandardOutputEncoding = Settings.Encoding,
|
|
StandardErrorEncoding = Settings.Encoding
|
|
};
|
|
}
|
|
|
|
internal static bool UseSsh(string arguments)
|
|
{
|
|
var x = !Plink() && GetArgumentsRequiresSsh(arguments);
|
|
return x || arguments.Contains("plink");
|
|
}
|
|
|
|
private static bool GetArgumentsRequiresSsh(string arguments)
|
|
{
|
|
return (arguments.Contains("@") && arguments.Contains("://")) ||
|
|
(arguments.Contains("@") && arguments.Contains(":")) ||
|
|
(arguments.Contains("ssh://")) ||
|
|
(arguments.Contains("http://")) ||
|
|
(arguments.Contains("git://")) ||
|
|
(arguments.Contains("push")) ||
|
|
(arguments.Contains("remote")) ||
|
|
(arguments.Contains("fetch")) ||
|
|
(arguments.Contains("pull"));
|
|
}
|
|
|
|
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
|
|
public static string RunCachableCmd(string cmd, string arguments)
|
|
{
|
|
string output;
|
|
if (GitCommandCache.TryGet(arguments, out output))
|
|
return output;
|
|
|
|
output = RunCmd(cmd, arguments);
|
|
|
|
GitCommandCache.Add(arguments, output);
|
|
|
|
return output;
|
|
}
|
|
|
|
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
|
|
public static string RunCmd(string cmd, string arguments)
|
|
{
|
|
try
|
|
{
|
|
SetEnvironmentVariable();
|
|
|
|
arguments = arguments.Replace("$QUOTE$", "\\\"");
|
|
|
|
string output, error;
|
|
CreateAndStartProcess(arguments, cmd, out output, out error);
|
|
|
|
if (!string.IsNullOrEmpty(error))
|
|
{
|
|
output += Environment.NewLine + error;
|
|
}
|
|
return output;
|
|
}
|
|
catch (Win32Exception)
|
|
{
|
|
return string.Empty;
|
|
}
|
|
}
|
|
|
|
private static void CreateAndStartProcess(string argument, string cmd)
|
|
{
|
|
string stdOutput, stdError;
|
|
CreateAndStartProcess(argument, cmd, out stdOutput, out stdError);
|
|
}
|
|
|
|
private static void CreateAndStartProcess(string arguments, string cmd, out string stdOutput, out string stdError)
|
|
{
|
|
Settings.GitLog.Log(cmd + " " + arguments);
|
|
//process used to execute external commands
|
|
|
|
var startInfo = CreateProcessStartInfo();
|
|
startInfo.CreateNoWindow = true;
|
|
startInfo.FileName = cmd;
|
|
startInfo.Arguments = arguments;
|
|
startInfo.WorkingDirectory = Settings.WorkingDir;
|
|
startInfo.LoadUserProfile = true;
|
|
|
|
using (var process = Process.Start(startInfo))
|
|
{
|
|
stdOutput = process.StandardOutput.ReadToEnd();
|
|
stdError = process.StandardError.ReadToEnd();
|
|
process.WaitForExit();
|
|
}
|
|
}
|
|
|
|
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
|
|
public static void RunCmdAsync(string cmd, string arguments)
|
|
{
|
|
SetEnvironmentVariable();
|
|
|
|
Settings.GitLog.Log(cmd + " " + arguments);
|
|
//process used to execute external commands
|
|
|
|
var info = new ProcessStartInfo()
|
|
{
|
|
UseShellExecute = true,
|
|
ErrorDialog = true,
|
|
RedirectStandardOutput = false,
|
|
RedirectStandardInput = false,
|
|
RedirectStandardError = false,
|
|
|
|
LoadUserProfile = true,
|
|
CreateNoWindow = false,
|
|
FileName = cmd,
|
|
Arguments = arguments,
|
|
WorkingDirectory = Settings.WorkingDir,
|
|
WindowStyle = ProcessWindowStyle.Hidden
|
|
};
|
|
|
|
try
|
|
{
|
|
Process.Start(info);
|
|
}
|
|
catch (Win32Exception ex)
|
|
{
|
|
Trace.WriteLine(ex);
|
|
}
|
|
}
|
|
|
|
public static bool InTheMiddleOfConflictedMerge()
|
|
{
|
|
return !string.IsNullOrEmpty(RunCmd(Settings.GitCommand, "ls-files -z --unmerged"));
|
|
}
|
|
|
|
public static List<GitItem> GetConflictedFiles()
|
|
{
|
|
var unmergedFiles = new List<GitItem>();
|
|
|
|
var fileName = "";
|
|
foreach (var file in GetUnmergedFileListing())
|
|
{
|
|
if (file.IndexOf('\t') <= 0)
|
|
continue;
|
|
if (file.Substring(file.IndexOf('\t') + 1) == fileName)
|
|
continue;
|
|
fileName = file.Substring(file.IndexOf('\t') + 1);
|
|
unmergedFiles.Add(new GitItem { FileName = fileName });
|
|
}
|
|
|
|
return unmergedFiles;
|
|
}
|
|
|
|
private static IEnumerable<string> GetUnmergedFileListing()
|
|
{
|
|
return RunCmd(Settings.GitCommand, "ls-files -z --unmerged").Split(new char[] { '\0', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
|
}
|
|
|
|
public static bool HandleConflictSelectBase(string fileName)
|
|
{
|
|
if (!HandleConflictsSaveSide(fileName, fileName, "1"))
|
|
return false;
|
|
|
|
RunCmd(Settings.GitCommand, "add -- \"" + fileName + "\"");
|
|
return true;
|
|
}
|
|
|
|
public static bool HandleConflictSelectLocal(string fileName)
|
|
{
|
|
if (!HandleConflictsSaveSide(fileName, fileName, "2"))
|
|
return false;
|
|
|
|
RunCmd(Settings.GitCommand, "add -- \"" + fileName + "\"");
|
|
return true;
|
|
}
|
|
|
|
public static bool HandleConflictSelectRemote(string fileName)
|
|
{
|
|
if (!HandleConflictsSaveSide(fileName, fileName, "3"))
|
|
return false;
|
|
|
|
RunCmd(Settings.GitCommand, "add -- \"" + fileName + "\"");
|
|
return true;
|
|
}
|
|
|
|
public static bool HandleConflictsSaveSide(string fileName, string saveAs, string side)
|
|
{
|
|
side = GetSide(side);
|
|
|
|
fileName = FixPath(fileName);
|
|
var unmerged = RunCmd(Settings.GitCommand, "ls-files -z --unmerged \"" + fileName + "\"").Split(new char[] { '\0', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
foreach (var file in unmerged)
|
|
{
|
|
var fileline = file.Split(new[] { ' ', '\t' });
|
|
if (fileline.Length < 3)
|
|
continue;
|
|
if (fileline[2].Trim() != side)
|
|
continue;
|
|
File.WriteAllText(saveAs, RunCmd(Settings.GitCommand, "cat-file blob \"" + fileline[1] + "\""));
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private static string GetSide(string side)
|
|
{
|
|
if (side.Equals("REMOTE", StringComparison.CurrentCultureIgnoreCase))
|
|
side = "3";
|
|
if (side.Equals("LOCAL", StringComparison.CurrentCultureIgnoreCase))
|
|
side = "2";
|
|
if (side.Equals("BASE", StringComparison.CurrentCultureIgnoreCase))
|
|
side = "1";
|
|
return side;
|
|
}
|
|
|
|
public static string[] GetConflictedFiles(string filename)
|
|
{
|
|
filename = FixPath(filename);
|
|
|
|
string[] fileNames =
|
|
{
|
|
filename + ".BASE",
|
|
filename + ".LOCAL",
|
|
filename + ".REMOTE"
|
|
};
|
|
|
|
var unmerged = RunCmd(Settings.GitCommand, "ls-files -z --unmerged \"" + filename + "\"").Split(new char[] { '\0', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
foreach (var file in unmerged)
|
|
{
|
|
var fileline = file.Split(new[] { ' ', '\t' });
|
|
if (fileline.Length < 3)
|
|
continue;
|
|
|
|
int stage;
|
|
Int32.TryParse(fileline[2].Trim(), out stage);
|
|
|
|
var tempFile = RunCmd(Settings.GitCommand, "checkout-index --temp --stage=" + stage + " -- " + filename);
|
|
tempFile = tempFile.Split('\t')[0];
|
|
tempFile = Path.Combine(Settings.WorkingDir, tempFile);
|
|
|
|
var newFileName = Path.Combine(Settings.WorkingDir, fileNames[stage - 1]);
|
|
try
|
|
{
|
|
fileNames[stage - 1] = newFileName;
|
|
var index = 1;
|
|
while (File.Exists(fileNames[stage - 1]) && index < 50)
|
|
{
|
|
fileNames[stage - 1] = newFileName + index;
|
|
index++;
|
|
}
|
|
File.Move(tempFile, fileNames[stage - 1]);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Trace.WriteLine(ex);
|
|
}
|
|
}
|
|
|
|
return fileNames;
|
|
}
|
|
|
|
public static string GetMergeMessage()
|
|
{
|
|
var file = Settings.WorkingDir + ".git" + Settings.PathSeparator + "MERGE_MSG";
|
|
|
|
return
|
|
File.Exists(file)
|
|
? File.ReadAllText(file)
|
|
: "";
|
|
}
|
|
|
|
public static void RunGitK()
|
|
{
|
|
StartExternalCommand("cmd.exe", "/c \"\"" + Settings.GitCommand.Replace("git.cmd", "gitk.cmd")
|
|
.Replace("bin\\git.exe", "cmd\\gitk.cmd")
|
|
.Replace("bin/git.exe", "cmd/gitk.cmd") + "\" --all\"");
|
|
}
|
|
|
|
public static void RunGui()
|
|
{
|
|
StartExternalCommand("cmd.exe", "/c \"\"" + Settings.GitCommand + "\" gui\"");
|
|
}
|
|
|
|
public static void RunBash()
|
|
{
|
|
RunRealCmdDetached("cmd.exe", "/c \"\"" + Settings.GitBinDir + "sh\" --login -i\"");
|
|
}
|
|
|
|
public static string Init(bool bare, bool shared)
|
|
{
|
|
if (bare && shared)
|
|
return RunCmd(Settings.GitCommand, "init --bare --shared=all");
|
|
if (bare)
|
|
return RunCmd(Settings.GitCommand, "init --bare");
|
|
return RunCmd(Settings.GitCommand, "init");
|
|
}
|
|
|
|
public static string CherryPickCmd(string cherry, bool commit)
|
|
{
|
|
if (commit)
|
|
return "cherry-pick \"" + cherry + "\"";
|
|
return "cherry-pick --no-commit \"" + cherry + "\"";
|
|
}
|
|
|
|
|
|
public static string CherryPick(string cherry, bool commit)
|
|
{
|
|
if (commit)
|
|
return RunCmd(Settings.GitCommand, "cherry-pick \"" + cherry + "\"");
|
|
return RunCmd(Settings.GitCommand, "cherry-pick --no-commit \"" + cherry + "\"");
|
|
}
|
|
|
|
public static string ShowSha1(string sha1)
|
|
{
|
|
return RunCachableCmd(Settings.GitCommand, "show --encoding=" + Settings.Encoding + " " + sha1);
|
|
}
|
|
|
|
public static string UserCommitCount()
|
|
{
|
|
return RunCmd(Settings.GitCommand, "shortlog -s -n");
|
|
}
|
|
|
|
public static string DeleteBranch(string branchName, bool force)
|
|
{
|
|
return RunCmd(Settings.GitCommand, DeleteBranchCmd(branchName, force));
|
|
}
|
|
|
|
public static string DeleteBranchCmd(string branchName, bool force)
|
|
{
|
|
if (force)
|
|
return "branch -D \"" + branchName + "\"";
|
|
return "branch -d \"" + branchName + "\"";
|
|
}
|
|
|
|
public static string DeleteTag(string tagName)
|
|
{
|
|
return RunCmd(Settings.GitCommand, DeleteTagCmd(tagName));
|
|
}
|
|
|
|
public static string DeleteTagCmd(string tagName)
|
|
{
|
|
return "tag -d \"" + tagName + "\"";
|
|
}
|
|
|
|
public static string GetCurrentCheckout()
|
|
{
|
|
return RunCmd(Settings.GitCommand, "log -g -1 HEAD --pretty=format:%H");
|
|
}
|
|
|
|
public static int CommitCount()
|
|
{
|
|
int count;
|
|
var arguments = "/c \"\"" + Settings.GitCommand + "\" rev-list --all --abbrev-commit | wc -l\"";
|
|
return
|
|
int.TryParse(RunCmd("cmd.exe", arguments), out count)
|
|
? count
|
|
: 0;
|
|
}
|
|
|
|
public static string GetSubmoduleRemotePath(string name)
|
|
{
|
|
var configFile = new ConfigFile(Settings.WorkingDir + Settings.PathSeparator + ".gitmodules");
|
|
return configFile.GetValue("submodule." + name.Trim() + ".url").Trim();
|
|
}
|
|
|
|
public static string GetSubmoduleLocalPath(string name)
|
|
{
|
|
var configFile = new ConfigFile(Settings.WorkingDir + Settings.PathSeparator + ".gitmodules");
|
|
return configFile.GetValue("submodule." + name.Trim() + ".path").Trim();
|
|
}
|
|
|
|
public static string SubmoduleInitCmd(string name)
|
|
{
|
|
if (string.IsNullOrEmpty(name))
|
|
return "submodule update --init";
|
|
|
|
return "submodule update --init \"" + name.Trim() + "\"";
|
|
}
|
|
|
|
public static string SubmoduleUpdateCmd(string name)
|
|
{
|
|
if (string.IsNullOrEmpty(name))
|
|
return "submodule update";
|
|
|
|
return "submodule update \"" + name.Trim() + "\"";
|
|
}
|
|
|
|
public static string SubmoduleSyncCmd(string name)
|
|
{
|
|
if (string.IsNullOrEmpty(name))
|
|
return "submodule sync";
|
|
|
|
return "submodule sync \"" + name.Trim() + "\"";
|
|
}
|
|
|
|
public static string AddSubmoduleCmd(string remotePath, string localPath, string branch)
|
|
{
|
|
remotePath = FixPath(remotePath);
|
|
localPath = FixPath(localPath);
|
|
|
|
if (!string.IsNullOrEmpty(branch))
|
|
branch = " -b \"" + branch.Trim() + "\"";
|
|
|
|
return "submodule add" + branch + " \"" + remotePath.Trim() + "\" \"" + localPath.Trim() + "\"";
|
|
}
|
|
|
|
internal static GitSubmodule CreateGitSubmodule(string submodule)
|
|
{
|
|
var gitSubmodule =
|
|
new GitSubmodule
|
|
{
|
|
Initialized = submodule[0] != '-',
|
|
UpToDate = submodule[0] != '+',
|
|
CurrentCommitGuid = submodule.Substring(1, 40).Trim()
|
|
};
|
|
|
|
var name = submodule.Substring(42).Trim();
|
|
if (name.Contains("("))
|
|
{
|
|
gitSubmodule.Name = name.Substring(0, name.IndexOf("("));
|
|
gitSubmodule.Branch = name.Substring(name.IndexOf("(")).Trim(new[] { '(', ')', ' ' });
|
|
}
|
|
else
|
|
gitSubmodule.Name = name;
|
|
return gitSubmodule;
|
|
}
|
|
|
|
public static string Stash()
|
|
{
|
|
return RunCmd(Settings.GitCommand, "stash save");
|
|
}
|
|
|
|
public static string StashApply()
|
|
{
|
|
return RunCmd(Settings.GitCommand, "stash apply");
|
|
}
|
|
|
|
public static string StashClear()
|
|
{
|
|
return RunCmd(Settings.GitCommand, "stash clear");
|
|
}
|
|
|
|
public static string RevertCmd(string commit, bool autoCommit)
|
|
{
|
|
if (autoCommit)
|
|
return "revert " + commit;
|
|
return "revert --no-commit " + commit;
|
|
}
|
|
|
|
|
|
public static string ResetSoft(string commit)
|
|
{
|
|
return ResetSoft(commit, "");
|
|
}
|
|
|
|
public static string ResetMixed(string commit)
|
|
{
|
|
return ResetMixed(commit, "");
|
|
}
|
|
|
|
public static string ResetHard(string commit)
|
|
{
|
|
return ResetHard(commit, "");
|
|
}
|
|
|
|
public static string ResetSoft(string commit, string file)
|
|
{
|
|
var args = "reset --soft";
|
|
|
|
if (!string.IsNullOrEmpty(commit))
|
|
args += " \"" + commit + "\"";
|
|
|
|
if (!string.IsNullOrEmpty(file))
|
|
args += " -- \"" + file + "\"";
|
|
|
|
return RunCmd(Settings.GitCommand, args);
|
|
}
|
|
|
|
public static string ResetMixed(string commit, string file)
|
|
{
|
|
var args = "reset --mixed";
|
|
|
|
if (!string.IsNullOrEmpty(commit))
|
|
args += " \"" + commit + "\"";
|
|
|
|
if (!string.IsNullOrEmpty(file))
|
|
args += " -- \"" + file + "\"";
|
|
|
|
return RunCmd(Settings.GitCommand, args);
|
|
}
|
|
|
|
public static string ResetHard(string commit, string file)
|
|
{
|
|
var args = "reset --hard";
|
|
|
|
if (!string.IsNullOrEmpty(commit))
|
|
args += " \"" + commit + "\"";
|
|
|
|
if (!string.IsNullOrEmpty(file))
|
|
args += " -- \"" + file + "\"";
|
|
|
|
return RunCmd(Settings.GitCommand, args);
|
|
}
|
|
|
|
public static string ResetSoftCmd(string commit)
|
|
{
|
|
return "reset --soft \"" + commit + "\"";
|
|
}
|
|
|
|
public static string ResetMixedCmd(string commit)
|
|
{
|
|
return "reset --mixed \"" + commit + "\"";
|
|
}
|
|
|
|
public static string ResetHardCmd(string commit)
|
|
{
|
|
return "reset --hard \"" + commit + "\"";
|
|
}
|
|
|
|
public static string CloneCmd(string fromPath, string toPath, bool central, int? depth)
|
|
{
|
|
var from = FixPath(fromPath);
|
|
var to = FixPath(toPath);
|
|
var options = new List<string> { "-v" };
|
|
if (central)
|
|
options.Add("--bare");
|
|
if (depth.HasValue)
|
|
options.Add("--depth " + depth);
|
|
if (VersionInUse.CloneCanAskForProgress)
|
|
options.Add("--progress");
|
|
options.Add(string.Format("\"{0}\"", from.Trim()));
|
|
options.Add(string.Format("\"{0}\"", to.Trim()));
|
|
|
|
return "clone " + string.Join(" ", options.ToArray());
|
|
}
|
|
|
|
public static string ResetFile(string file)
|
|
{
|
|
file = FixPath(file);
|
|
return RunCmd(Settings.GitCommand, "checkout-index --index --force -- \"" + file + "\"");
|
|
}
|
|
|
|
|
|
public static string FormatPatch(string from, string to, string output, int start)
|
|
{
|
|
output = FixPath(output);
|
|
|
|
var result = RunCmd(Settings.GitCommand,
|
|
"format-patch -M -C -B --start-number " + start + " \"" + from + "\"..\"" + to +
|
|
"\" -o \"" + output + "\"");
|
|
|
|
return result;
|
|
}
|
|
|
|
public static string FormatPatch(string from, string to, string output)
|
|
{
|
|
output = FixPath(output);
|
|
|
|
var result = RunCmd(Settings.GitCommand,
|
|
"format-patch -M -C -B \"" + from + "\"..\"" + to + "\" -o \"" + output + "\"");
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
public static string Tag(string tagName, string revision, bool annotation)
|
|
{
|
|
string result;
|
|
|
|
if (annotation)
|
|
result = RunCmd(Settings.GitCommand,
|
|
"tag \"" + tagName.Trim() + "\" -a -F \"" + Settings.WorkingDirGitDir() +
|
|
"\\TAGMESSAGE\" -- \"" + revision + "\"");
|
|
else
|
|
result = RunCmd(Settings.GitCommand, "tag \"" + tagName.Trim() + "\" \"" + revision + "\"");
|
|
|
|
return result;
|
|
}
|
|
|
|
public static string Branch(string branchName, string revision, bool checkout)
|
|
{
|
|
var result = RunCmd(Settings.GitCommand, BranchCmd(branchName, revision, checkout));
|
|
|
|
return result;
|
|
}
|
|
|
|
public static string BranchCmd(string branchName, string revision, bool checkout)
|
|
{
|
|
if (checkout)
|
|
return "checkout -b \"" + branchName.Trim() + "\" \"" + revision + "\"";
|
|
return "branch \"" + branchName.Trim() + "\" \"" + revision + "\"";
|
|
}
|
|
|
|
public static void UnsetSsh()
|
|
{
|
|
Environment.SetEnvironmentVariable("GIT_SSH", "", EnvironmentVariableTarget.Process);
|
|
}
|
|
|
|
public static void SetSsh(string path)
|
|
{
|
|
Environment.SetEnvironmentVariable("GIT_SSH", path, EnvironmentVariableTarget.Process);
|
|
}
|
|
|
|
public static bool Plink()
|
|
{
|
|
var sshString = GetSsh();
|
|
|
|
return sshString.EndsWith("plink.exe", StringComparison.CurrentCultureIgnoreCase);
|
|
}
|
|
|
|
public static string GetSsh()
|
|
{
|
|
var ssh = Environment.GetEnvironmentVariable("GIT_SSH", EnvironmentVariableTarget.Process);
|
|
|
|
return ssh ?? "";
|
|
}
|
|
|
|
public static string Push(string path)
|
|
{
|
|
return RunCmd(Settings.GitCommand, "push \"" + FixPath(path).Trim() + "\"");
|
|
}
|
|
|
|
public static bool StartPageantForRemote(string remote)
|
|
{
|
|
var sshKeyFile = GetPuttyKeyFileForRemote(remote);
|
|
if (string.IsNullOrEmpty(sshKeyFile))
|
|
return false;
|
|
|
|
StartPageantWithKey(sshKeyFile);
|
|
return true;
|
|
}
|
|
|
|
public static void StartPageantWithKey(string sshKeyFile)
|
|
{
|
|
StartExternalCommand(Settings.Pageant, "\"" + sshKeyFile + "\"");
|
|
}
|
|
|
|
public static string GetPuttyKeyFileForRemote(string remote)
|
|
{
|
|
if (string.IsNullOrEmpty(remote) ||
|
|
string.IsNullOrEmpty(Settings.Pageant) ||
|
|
!Settings.AutoStartPageant ||
|
|
!Plink())
|
|
return "";
|
|
|
|
return GetSetting("remote." + remote + ".puttykeyfile");
|
|
}
|
|
|
|
public static string PushCmd(string path, string branch, bool all)
|
|
{
|
|
return PushCmd(path, null, branch, all, false);
|
|
}
|
|
|
|
public static string PushCmd(string path, string fromBranch, string toBranch, bool all, bool force)
|
|
{
|
|
path = FixPath(path);
|
|
|
|
if (string.IsNullOrEmpty(fromBranch) && !string.IsNullOrEmpty(toBranch))
|
|
fromBranch = "HEAD";
|
|
|
|
toBranch = toBranch.Replace(" ", "");
|
|
|
|
var sforce = "";
|
|
if (force)
|
|
sforce = "-f ";
|
|
|
|
if (all)
|
|
return string.Format("push {0}--all \"{1}\"", sforce, path.Trim());
|
|
|
|
if (!string.IsNullOrEmpty(toBranch) && !string.IsNullOrEmpty(fromBranch))
|
|
return string.Format("push {0}\"{1}\" {2}:{3}", sforce, path.Trim(), fromBranch, toBranch);
|
|
|
|
return string.Format("push {0}\"{1}\" {2}", sforce, path.Trim(), fromBranch);
|
|
}
|
|
|
|
public static string PushTagCmd(string path, string tag, bool all)
|
|
{
|
|
return PushTagCmd(path, tag, all, false);
|
|
}
|
|
|
|
public static string PushTagCmd(string path, string tag, bool all, bool force)
|
|
{
|
|
path = FixPath(path);
|
|
|
|
tag = tag.Replace(" ", "");
|
|
|
|
var sforce = "";
|
|
if (force)
|
|
sforce = "-f ";
|
|
|
|
if (all)
|
|
return "push " + sforce + "\"" + path.Trim() + "\" --tags";
|
|
if (!string.IsNullOrEmpty(tag))
|
|
return "push " + sforce + "\"" + path.Trim() + "\" tag " + tag;
|
|
|
|
return "";
|
|
}
|
|
|
|
public static string Fetch(string remote, string branch)
|
|
{
|
|
remote = FixPath(remote);
|
|
|
|
Directory.SetCurrentDirectory(Settings.WorkingDir);
|
|
|
|
RunRealCmd("cmd.exe", " /k \"\"" + Settings.GitCommand + "\" " + FetchCmd(remote, null, branch) + "\"");
|
|
|
|
return "Done";
|
|
}
|
|
|
|
public static bool PathIsUrl(string path)
|
|
{
|
|
return path.Contains(Settings.PathSeparator.ToString()) || path.Contains(Settings.PathSeparatorWrong.ToString());
|
|
}
|
|
|
|
public static string FetchCmd(string remote, string remoteBranch, string localBranch)
|
|
{
|
|
return "fetch " + GetFetchArgs(remote, remoteBranch, localBranch);
|
|
}
|
|
|
|
public static string Pull(string remote, string remoteBranch, string localBranch, bool rebase)
|
|
{
|
|
remote = FixPath(remote);
|
|
|
|
Directory.SetCurrentDirectory(Settings.WorkingDir);
|
|
|
|
RunRealCmd("cmd.exe", " /k \"\"" + Settings.GitCommand + "\" " + PullCmd(remote, localBranch, remoteBranch, rebase) + "\"");
|
|
|
|
return "Done";
|
|
}
|
|
|
|
public static string PullCmd(string remote, string remoteBranch, string localBranch, bool rebase)
|
|
{
|
|
if (rebase && !string.IsNullOrEmpty(remoteBranch))
|
|
return "pull --rebase " + remote + " refs/heads/" + remoteBranch;
|
|
|
|
if (rebase)
|
|
return "pull --rebase " + remote;
|
|
|
|
return "pull " + GetFetchArgs(remote, remoteBranch, localBranch);
|
|
}
|
|
|
|
private static string GetFetchArgs(string remote, string remoteBranch, string localBranch)
|
|
{
|
|
remote = FixPath(remote);
|
|
|
|
//Remove spaces...
|
|
if (remoteBranch != null)
|
|
remoteBranch = remoteBranch.Replace(" ", "");
|
|
if (localBranch != null)
|
|
localBranch = localBranch.Replace(" ", "");
|
|
|
|
string remoteBranchArguments;
|
|
|
|
if (string.IsNullOrEmpty(remoteBranch))
|
|
remoteBranchArguments = "";
|
|
else
|
|
remoteBranchArguments = "+refs/heads/" + remoteBranch + "";
|
|
|
|
string localBranchArguments;
|
|
var remoteUrl = GetSetting("remote." + remote + ".url");
|
|
|
|
if (PathIsUrl(remote) && !string.IsNullOrEmpty(localBranch) && string.IsNullOrEmpty(remoteUrl))
|
|
localBranchArguments = ":refs/heads/" + localBranch + "";
|
|
else if (string.IsNullOrEmpty(localBranch) || PathIsUrl(remote) || string.IsNullOrEmpty(remoteUrl))
|
|
localBranchArguments = "";
|
|
else
|
|
localBranchArguments = ":" + "refs/remotes/" + remote.Trim() + "/" + localBranch + "";
|
|
|
|
var progressOption = "";
|
|
if (VersionInUse.FetchCanAskForProgress)
|
|
progressOption = "--progress ";
|
|
|
|
return progressOption + "\"" + remote.Trim() + "\" " + remoteBranchArguments + localBranchArguments;
|
|
}
|
|
|
|
public static string ContinueRebase()
|
|
{
|
|
Directory.SetCurrentDirectory(Settings.WorkingDir);
|
|
|
|
var result = RunCmd(Settings.GitCommand, ContinueRebaseCmd());
|
|
|
|
return result;
|
|
}
|
|
|
|
public static string ContinueRebaseCmd()
|
|
{
|
|
return "rebase --continue";
|
|
}
|
|
|
|
public static string SkipRebase()
|
|
{
|
|
Directory.SetCurrentDirectory(Settings.WorkingDir);
|
|
|
|
var result = RunCmd(Settings.GitCommand, SkipRebaseCmd());
|
|
|
|
return result;
|
|
}
|
|
|
|
public static string SkipRebaseCmd()
|
|
{
|
|
return "rebase --skip";
|
|
}
|
|
|
|
public static string GetRebaseDir()
|
|
{
|
|
if (Directory.Exists(Settings.WorkingDir + ".git" + Settings.PathSeparator + "rebase-merge" + Settings.PathSeparator))
|
|
return Settings.WorkingDir + ".git" + Settings.PathSeparator + "rebase-merge" + Settings.PathSeparator;
|
|
if (Directory.Exists(Settings.WorkingDir + ".git" + Settings.PathSeparator + "rebase-apply" + Settings.PathSeparator))
|
|
return Settings.WorkingDir + ".git" + Settings.PathSeparator + "rebase-apply" + Settings.PathSeparator;
|
|
if (Directory.Exists(Settings.WorkingDir + ".git" + Settings.PathSeparator + "rebase" + Settings.PathSeparator))
|
|
return Settings.WorkingDir + ".git" + Settings.PathSeparator + "rebase" + Settings.PathSeparator;
|
|
|
|
return "";
|
|
}
|
|
|
|
public static bool InTheMiddleOfRebase()
|
|
{
|
|
return !File.Exists(GetRebaseDir() + "applying") &&
|
|
Directory.Exists(GetRebaseDir());
|
|
}
|
|
|
|
public static bool InTheMiddleOfPatch()
|
|
{
|
|
return !File.Exists(GetRebaseDir() + "rebasing") &&
|
|
Directory.Exists(GetRebaseDir());
|
|
}
|
|
|
|
|
|
public static string GetNextRebasePatch()
|
|
{
|
|
var file = GetRebaseDir() + "next";
|
|
return File.Exists(file) ? File.ReadAllText(file).Trim() : "";
|
|
}
|
|
|
|
public static List<PatchFile> GetRebasePatchFiles()
|
|
{
|
|
var patchFiles = new List<PatchFile>();
|
|
|
|
var nextFile = GetNextRebasePatch();
|
|
|
|
int next;
|
|
int.TryParse(nextFile, out next);
|
|
|
|
|
|
var files = new string[0];
|
|
if (Directory.Exists(GetRebaseDir()))
|
|
files = Directory.GetFiles(GetRebaseDir());
|
|
|
|
foreach (var fullFileName in files)
|
|
{
|
|
int n;
|
|
var file = fullFileName.Substring(fullFileName.LastIndexOf(Settings.PathSeparator) + 1);
|
|
if (!int.TryParse(file, out n))
|
|
continue;
|
|
|
|
var patchFile =
|
|
new PatchFile
|
|
{
|
|
Name = file,
|
|
FullName = fullFileName,
|
|
IsNext = n == next,
|
|
IsSkipped = n < next
|
|
};
|
|
|
|
if (File.Exists(GetRebaseDir() + file))
|
|
{
|
|
foreach (var line in File.ReadAllLines(GetRebaseDir() + file))
|
|
{
|
|
if (line.StartsWith("From: "))
|
|
if (line.IndexOf('<') > 0 && line.IndexOf('<') < line.Length)
|
|
patchFile.Author = line.Substring(6, line.IndexOf('<') - 6).Trim();
|
|
else
|
|
patchFile.Author = line.Substring(6).Trim();
|
|
|
|
if (line.StartsWith("Date: "))
|
|
if (line.IndexOf('+') > 0 && line.IndexOf('<') < line.Length)
|
|
patchFile.Date = line.Substring(6, line.IndexOf('+') - 6).Trim();
|
|
else
|
|
patchFile.Date = line.Substring(6).Trim();
|
|
|
|
|
|
if (line.StartsWith("Subject: ")) patchFile.Subject = line.Substring(9).Trim();
|
|
|
|
if (!string.IsNullOrEmpty(patchFile.Author) &&
|
|
!string.IsNullOrEmpty(patchFile.Date) &&
|
|
!string.IsNullOrEmpty(patchFile.Subject))
|
|
break;
|
|
}
|
|
}
|
|
|
|
patchFiles.Add(patchFile);
|
|
}
|
|
|
|
return patchFiles;
|
|
}
|
|
|
|
public static string Rebase(string branch)
|
|
{
|
|
Directory.SetCurrentDirectory(Settings.WorkingDir);
|
|
|
|
return RunCmd(Settings.GitCommand, RebaseCmd(branch, false));
|
|
}
|
|
|
|
public static string RebaseCmd(string branch, bool interactive)
|
|
{
|
|
if (interactive)
|
|
return "rebase -i \"" + branch + "\"";
|
|
|
|
return "rebase \"" + branch + "\"";
|
|
}
|
|
|
|
|
|
public static string AbortRebase()
|
|
{
|
|
Directory.SetCurrentDirectory(Settings.WorkingDir);
|
|
|
|
return RunCmd(Settings.GitCommand, AbortRebaseCmd());
|
|
}
|
|
|
|
public static string AbortRebaseCmd()
|
|
{
|
|
return "rebase --abort";
|
|
}
|
|
|
|
public static string Resolved()
|
|
{
|
|
Directory.SetCurrentDirectory(Settings.WorkingDir);
|
|
|
|
return RunCmd(Settings.GitCommand, ResolvedCmd());
|
|
}
|
|
|
|
public static string ResolvedCmd()
|
|
{
|
|
return "am --3way --resolved";
|
|
}
|
|
|
|
public static string Skip()
|
|
{
|
|
Directory.SetCurrentDirectory(Settings.WorkingDir);
|
|
|
|
return RunCmd(Settings.GitCommand, SkipCmd());
|
|
}
|
|
|
|
public static string SkipCmd()
|
|
{
|
|
return "am --3way --skip";
|
|
}
|
|
|
|
public static string Abort()
|
|
{
|
|
Directory.SetCurrentDirectory(Settings.WorkingDir);
|
|
|
|
return RunCmd(Settings.GitCommand, AbortCmd());
|
|
}
|
|
|
|
public static string AbortCmd()
|
|
{
|
|
return "am --3way --abort";
|
|
}
|
|
|
|
public static string Commit(bool amend)
|
|
{
|
|
return RunCmd(Settings.GitCommand, CommitCmd(amend));
|
|
}
|
|
|
|
public static string CommitCmd(bool amend)
|
|
{
|
|
var path = Settings.WorkingDirGitDir() + Settings.PathSeparator + "COMMITMESSAGE\"";
|
|
if (amend)
|
|
return "commit --amend -F \"" + path;
|
|
return "commit -F \"" + path;
|
|
}
|
|
|
|
public static string Patch(string patchFile)
|
|
{
|
|
Directory.SetCurrentDirectory(Settings.WorkingDir);
|
|
|
|
return RunCmd(Settings.GitCommand, PatchCmd(FixPath(patchFile)));
|
|
}
|
|
|
|
public static string PatchCmd(string patchFile)
|
|
{
|
|
return "am --3way --signoff \"" + FixPath(patchFile) + "\"";
|
|
}
|
|
|
|
public static string PatchDirCmd(string patchDir)
|
|
{
|
|
return "am --3way --signoff --directory=\"" + FixPath(patchDir) + "\"";
|
|
}
|
|
|
|
public static string UpdateRemotes()
|
|
{
|
|
return RunCmd(Settings.GitCommand, "remote update");
|
|
}
|
|
|
|
public static string RemoveRemote(string name)
|
|
{
|
|
return RunCmd(Settings.GitCommand, "remote rm \"" + name + "\"");
|
|
}
|
|
|
|
public static string RenameRemote(string name, string newName)
|
|
{
|
|
return RunCmd(Settings.GitCommand, "remote rename \"" + name + "\" \"" + newName + "\"");
|
|
}
|
|
|
|
public static string AddRemote(string name, string path)
|
|
{
|
|
var location = FixPath(path);
|
|
|
|
if (string.IsNullOrEmpty(name))
|
|
return "Please enter a name.";
|
|
|
|
return
|
|
string.IsNullOrEmpty(location)
|
|
? RunCmd(Settings.GitCommand, string.Format("remote add \"{0}\" \"\"", name))
|
|
: RunCmd(Settings.GitCommand, string.Format("remote add \"{0}\" \"{1}\"", name, location));
|
|
}
|
|
|
|
public static string[] GetRemotes()
|
|
{
|
|
return RunCmd(Settings.GitCommand, "remote show").Split('\n');
|
|
}
|
|
|
|
public static string CleanUpCmd(bool dryrun, bool directories, bool nonignored, bool ignored)
|
|
{
|
|
var stringBuilder = new StringBuilder("clean");
|
|
|
|
if (directories)
|
|
stringBuilder.Append(" -d");
|
|
if (!nonignored && !ignored)
|
|
stringBuilder.Append(" -x");
|
|
if (ignored)
|
|
stringBuilder.Append(" -X");
|
|
if (dryrun)
|
|
stringBuilder.Append(" --dry-run");
|
|
if (!dryrun)
|
|
stringBuilder.Append(" -f");
|
|
|
|
return stringBuilder.ToString();
|
|
}
|
|
|
|
public static ConfigFile GetGlobalConfig()
|
|
{
|
|
return new ConfigFile(Environment.GetEnvironmentVariable("HOME") + Settings.PathSeparator + ".gitconfig");
|
|
}
|
|
|
|
public static ConfigFile GetLocalConfig()
|
|
{
|
|
return new ConfigFile(Settings.WorkingDirGitDir() + Settings.PathSeparator + "config");
|
|
}
|
|
|
|
public static string GetSetting(string setting)
|
|
{
|
|
var configFile = GetLocalConfig();
|
|
return configFile.GetValue(setting);
|
|
}
|
|
|
|
public static void UnsetSetting(string setting)
|
|
{
|
|
var configFile = GetLocalConfig();
|
|
configFile.RemoveSetting(setting);
|
|
configFile.Save();
|
|
}
|
|
|
|
public static void SetSetting(string setting, string value)
|
|
{
|
|
var configFile = GetLocalConfig();
|
|
configFile.SetValue(setting, value);
|
|
configFile.Save();
|
|
}
|
|
|
|
public static List<Patch> GetStashedItems(string stashName)
|
|
{
|
|
var patchManager = new PatchManager();
|
|
patchManager.LoadPatch(RunCmd(Settings.GitCommand, "stash show -p " + stashName), false);
|
|
|
|
return patchManager.patches;
|
|
}
|
|
|
|
public static List<GitStash> GetStashes()
|
|
{
|
|
var list = RunCmd(Settings.GitCommand, "stash list").Split('\n');
|
|
|
|
var stashes = new List<GitStash>();
|
|
foreach (var stashString in list)
|
|
{
|
|
if (stashString.IndexOf(':') <= 0)
|
|
continue;
|
|
|
|
var stash =
|
|
new GitStash
|
|
{
|
|
Name = stashString.Substring(0, stashString.IndexOf(':')).Trim()
|
|
};
|
|
|
|
if (stashString.IndexOf(':') + 1 < stashString.Length)
|
|
stash.Message = stashString.Substring(stashString.IndexOf(':') + 1).Trim();
|
|
|
|
stashes.Add(stash);
|
|
}
|
|
|
|
return stashes;
|
|
}
|
|
|
|
public static Patch GetSingleDiff(string from, string to, string filter, string extraDiffArguments)
|
|
{
|
|
filter = FixPath(filter);
|
|
from = FixPath(from);
|
|
to = FixPath(to);
|
|
|
|
var patchManager = new PatchManager();
|
|
var arguments = string.Format("diff{0} \"{1}\" \"{2}\" -- \"{3}\"", extraDiffArguments, to, from, filter);
|
|
patchManager.LoadPatch(RunCachableCmd(Settings.GitCommand, arguments), false);
|
|
|
|
return patchManager.patches.Count > 0 ? patchManager.patches[0] : null;
|
|
}
|
|
|
|
public static List<Patch> GetDiff(string from, string to, string extraDiffArguments)
|
|
{
|
|
var patchManager = new PatchManager();
|
|
var arguments = string.Format("diff{0} \"{1}\" \"{2}\"", extraDiffArguments, from, to);
|
|
patchManager.LoadPatch(RunCachableCmd(Settings.GitCommand, arguments), false);
|
|
|
|
return patchManager.patches;
|
|
}
|
|
|
|
public static List<GitItemStatus> GetDiffFiles(string from, string to)
|
|
{
|
|
var result = RunCachableCmd(Settings.GitCommand, "diff -z --name-status \"" + to + "\" \"" + from + "\"");
|
|
|
|
var files = result.Split(new char[] { '\0', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
var diffFiles = new List<GitItemStatus>();
|
|
for (int n = 0; n + 1 < files.Length; n = n + 2)
|
|
{
|
|
if (string.IsNullOrEmpty(files[n]))
|
|
continue;
|
|
|
|
diffFiles.Add(
|
|
new GitItemStatus
|
|
{
|
|
Name = files[n + 1].Trim(),
|
|
IsNew = files[n] == "A",
|
|
IsChanged = files[n] == "M",
|
|
IsDeleted = files[n] == "D",
|
|
IsTracked = true
|
|
});
|
|
}
|
|
|
|
return diffFiles;
|
|
}
|
|
|
|
public static List<GitItemStatus> GetUntrackedFiles()
|
|
{
|
|
var status = RunCmd(Settings.GitCommand,
|
|
"ls-files -z --others --directory --no-empty-directory --exclude-standard");
|
|
|
|
var statusStrings = status.Split(new char[] { '\0', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
var gitItemStatusList = new List<GitItemStatus>();
|
|
|
|
foreach (var statusString in statusStrings)
|
|
{
|
|
if (string.IsNullOrEmpty(statusString.Trim()))
|
|
continue;
|
|
gitItemStatusList.Add(
|
|
new GitItemStatus
|
|
{
|
|
IsNew = true,
|
|
IsChanged = false,
|
|
IsDeleted = false,
|
|
IsTracked = false,
|
|
Name = statusString.Trim()
|
|
});
|
|
}
|
|
|
|
return gitItemStatusList;
|
|
}
|
|
|
|
public static List<GitItemStatus> GetModifiedFiles()
|
|
{
|
|
var status = RunCmd(Settings.GitCommand, "ls-files -z --modified --exclude-standard");
|
|
|
|
var statusStrings = status.Split(new char[] { '\0', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
var gitItemStatusList = new List<GitItemStatus>();
|
|
|
|
foreach (var statusString in statusStrings)
|
|
{
|
|
if (string.IsNullOrEmpty(statusString.Trim()))
|
|
continue;
|
|
gitItemStatusList.Add(
|
|
new GitItemStatus
|
|
{
|
|
IsNew = false,
|
|
IsChanged = true,
|
|
IsDeleted = false,
|
|
IsTracked = true,
|
|
Name = statusString.Trim()
|
|
});
|
|
}
|
|
|
|
return gitItemStatusList;
|
|
}
|
|
|
|
public static string GetAllChangedFilesCmd(bool excludeIgnoredFiles, bool showUntrackedFiles)
|
|
{
|
|
var stringBuilder = new StringBuilder("ls-files -z --deleted --modified --no-empty-directory -t");
|
|
|
|
if (showUntrackedFiles)
|
|
stringBuilder.Append(" --others");
|
|
if (excludeIgnoredFiles)
|
|
stringBuilder.Append(" --exclude-standard");
|
|
|
|
return stringBuilder.ToString();
|
|
}
|
|
|
|
|
|
public static List<GitItemStatus> GetAllChangedFiles()
|
|
{
|
|
var status = RunCmd(Settings.GitCommand, GetAllChangedFilesCmd(true, true));
|
|
|
|
return GetAllChangedFilesFromString(status);
|
|
}
|
|
|
|
public static List<GitItemStatus> GetTrackedChangedFiles()
|
|
{
|
|
var status = RunCmd(Settings.GitCommand, GetAllChangedFilesCmd(true, false));
|
|
|
|
return GetAllChangedFilesFromString(status);
|
|
}
|
|
|
|
public static List<GitItemStatus> GetAllChangedFilesFromString(string status)
|
|
{
|
|
var statusStrings = status.Split(new char[] { '\0', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
var gitItemStatusList = new List<GitItemStatus>();
|
|
|
|
GitItemStatus itemStatus = null;
|
|
foreach (var statusString in statusStrings)
|
|
{
|
|
if (string.IsNullOrEmpty(statusString.Trim()) || statusString.Length < 2)
|
|
continue;
|
|
|
|
if (!(itemStatus != null && itemStatus.Name == statusString.Substring(1).Trim()))
|
|
{
|
|
itemStatus = new GitItemStatus { Name = statusString.Substring(1).Trim() };
|
|
gitItemStatusList.Add(itemStatus);
|
|
}
|
|
|
|
itemStatus.IsNew = itemStatus.IsNew || statusString[0] == '?';
|
|
itemStatus.IsChanged = itemStatus.IsChanged || statusString[0] == 'C';
|
|
itemStatus.IsDeleted = itemStatus.IsDeleted || statusString[0] == 'R';
|
|
itemStatus.IsTracked = itemStatus.IsTracked || statusString[0] != '?';
|
|
}
|
|
|
|
return gitItemStatusList;
|
|
}
|
|
|
|
public static List<GitItemStatus> GetDeletedFiles()
|
|
{
|
|
var status = RunCmd(Settings.GitCommand, "ls-files -z --deleted --exclude-standard");
|
|
|
|
var statusStrings = status.Split(new char[] { '\0', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
var gitItemStatusList = new List<GitItemStatus>();
|
|
|
|
foreach (var statusString in statusStrings)
|
|
{
|
|
if (string.IsNullOrEmpty(statusString.Trim()))
|
|
continue;
|
|
gitItemStatusList.Add(
|
|
new GitItemStatus
|
|
{
|
|
IsNew = false,
|
|
IsChanged = false,
|
|
IsDeleted = true,
|
|
IsTracked = true,
|
|
Name = statusString.Trim()
|
|
});
|
|
}
|
|
|
|
return gitItemStatusList;
|
|
}
|
|
|
|
public static bool FileIsStaged(string filename)
|
|
{
|
|
var status = RunCmd(Settings.GitCommand, "diff -z --cached --numstat -- \"" + filename + "\"");
|
|
return !string.IsNullOrEmpty(status);
|
|
}
|
|
|
|
public static List<GitItemStatus> GetStagedFiles()
|
|
{
|
|
var status = RunCmd(Settings.GitCommand, "diff -z --cached --name-status");
|
|
|
|
var gitItemStatusList = new List<GitItemStatus>();
|
|
|
|
if (status.Length < 50 && status.Contains("fatal: No HEAD commit to compare"))
|
|
{
|
|
status = RunCmd(Settings.GitCommand, "status --untracked-files=no");
|
|
|
|
var statusStrings = status.Split('\n');
|
|
|
|
foreach (var statusString in statusStrings)
|
|
{
|
|
if (statusString.StartsWith("#\tnew file:"))
|
|
{
|
|
ProcessStatusNewFile(statusString, gitItemStatusList);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var statusStrings = status.Split(new char[] { '\0', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
|
for (int n = 0; n + 1 < statusStrings.Length; n = n + 2)
|
|
{
|
|
if (string.IsNullOrEmpty(statusStrings[n]))
|
|
continue;
|
|
|
|
gitItemStatusList.Add(
|
|
new GitItemStatus
|
|
{
|
|
Name = statusStrings[n + 1].Trim(),
|
|
IsNew = statusStrings[n] == "A",
|
|
IsChanged = statusStrings[n] == "M",
|
|
IsDeleted = statusStrings[n] == "D",
|
|
IsTracked = true
|
|
});
|
|
}
|
|
}
|
|
|
|
return gitItemStatusList;
|
|
}
|
|
|
|
public static List<GitItemStatus> GitStatus()
|
|
{
|
|
return GitStatus(true);
|
|
}
|
|
|
|
public static List<GitItemStatus> GitStatus(bool untracked)
|
|
{
|
|
var status = RunCmd(Settings.GitCommand, untracked ? "status --untracked=all" : "status");
|
|
var statusStrings = status.Split('\n');
|
|
|
|
var gitItemStatusList = new List<GitItemStatus>();
|
|
|
|
foreach (var statusString in statusStrings)
|
|
{
|
|
if (statusString.StartsWith("#\tnew file:"))
|
|
{
|
|
ProcessStatusNewFile(statusString, gitItemStatusList);
|
|
}
|
|
else if (statusString.StartsWith("#\tdeleted:"))
|
|
{
|
|
gitItemStatusList.Add(
|
|
new GitItemStatus
|
|
{
|
|
IsDeleted = true,
|
|
IsTracked = true,
|
|
Name = statusString.Substring(statusString.LastIndexOf(':') + 1).Trim()
|
|
});
|
|
}
|
|
else if (statusString.StartsWith("#\tmodified:"))
|
|
{
|
|
gitItemStatusList.Add(
|
|
new GitItemStatus
|
|
{
|
|
IsChanged = true,
|
|
IsTracked = true,
|
|
Name = statusString.Substring(statusString.LastIndexOf(':') + 1).Trim()
|
|
});
|
|
}
|
|
else if (statusString.StartsWith("#\t"))
|
|
{
|
|
gitItemStatusList.Add(
|
|
new GitItemStatus
|
|
{
|
|
IsNew = true,
|
|
Name = statusString.Substring(2).Trim()
|
|
});
|
|
}
|
|
}
|
|
|
|
return gitItemStatusList;
|
|
}
|
|
|
|
private static void ProcessStatusNewFile(string statusString, ICollection<GitItemStatus> gitItemStatusList)
|
|
{
|
|
gitItemStatusList.Add(
|
|
new GitItemStatus
|
|
{
|
|
IsNew = true,
|
|
IsTracked = true,
|
|
Name = statusString.Substring(statusString.LastIndexOf(':') + 1).Trim()
|
|
});
|
|
}
|
|
|
|
public static string GetCurrentChanges(string name, bool staged, string extraDiffArguments)
|
|
{
|
|
name = FixPath(name);
|
|
var args = "diff" + extraDiffArguments + " -- \"" + name + "\"";
|
|
if (staged)
|
|
args = "diff --cached" + extraDiffArguments + " -- \"" + name + "\"";
|
|
|
|
return RunCmd(Settings.GitCommand, args);
|
|
}
|
|
|
|
public static string StageFiles(IList<GitItemStatus> files)
|
|
{
|
|
var gitCommand = new GitCommandsInstance();
|
|
|
|
var output = "";
|
|
|
|
Process process1 = null;
|
|
foreach (var file in files)
|
|
{
|
|
if (file.IsDeleted)
|
|
continue;
|
|
if (process1 == null)
|
|
process1 = gitCommand.CmdStartProcess(Settings.GitCommand, "update-index --add --stdin");
|
|
|
|
process1.StandardInput.WriteLine("\"" + FixPath(file.Name) + "\"");
|
|
}
|
|
if (process1 != null)
|
|
{
|
|
process1.StandardInput.Close();
|
|
process1.WaitForExit();
|
|
|
|
if (gitCommand.Output != null)
|
|
output = gitCommand.Output.ToString().Trim();
|
|
}
|
|
|
|
Process process2 = null;
|
|
foreach (var file in files)
|
|
{
|
|
if (!file.IsDeleted)
|
|
continue;
|
|
if (process2 == null)
|
|
process2 = gitCommand.CmdStartProcess(Settings.GitCommand, "update-index --remove --stdin");
|
|
process2.StandardInput.WriteLine("\"" + FixPath(file.Name) + "\"");
|
|
}
|
|
if (process2 != null)
|
|
{
|
|
process2.StandardInput.Close();
|
|
process2.WaitForExit();
|
|
|
|
if (gitCommand.Output != null)
|
|
{
|
|
if (!string.IsNullOrEmpty(output))
|
|
{
|
|
output += Environment.NewLine;
|
|
}
|
|
output += gitCommand.Output.ToString().Trim();
|
|
}
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
public static string UnstageFiles(List<GitItemStatus> files)
|
|
{
|
|
var gitCommand = new GitCommandsInstance();
|
|
|
|
var output = "";
|
|
|
|
Process process1 = null;
|
|
foreach (var file in files)
|
|
{
|
|
if (file.IsNew)
|
|
continue;
|
|
if (process1 == null)
|
|
process1 = gitCommand.CmdStartProcess(Settings.GitCommand, "update-index --info-only --index-info");
|
|
|
|
process1.StandardInput.WriteLine("0 0000000000000000000000000000000000000000\t\"" + FixPath(file.Name) +
|
|
"\"");
|
|
}
|
|
if (process1 != null)
|
|
{
|
|
process1.StandardInput.Close();
|
|
process1.WaitForExit();
|
|
}
|
|
|
|
if (gitCommand.Output != null)
|
|
output = gitCommand.Output.ToString();
|
|
|
|
Process process2 = null;
|
|
foreach (var file in files)
|
|
{
|
|
if (!file.IsNew)
|
|
continue;
|
|
if (process2 == null)
|
|
process2 = gitCommand.CmdStartProcess(Settings.GitCommand, "update-index --force-remove --stdin");
|
|
process2.StandardInput.WriteLine("\"" + FixPath(file.Name) + "\"");
|
|
}
|
|
if (process2 != null)
|
|
{
|
|
process2.StandardInput.Close();
|
|
process2.WaitForExit();
|
|
}
|
|
|
|
if (gitCommand.Output != null)
|
|
output += gitCommand.Output.ToString();
|
|
|
|
return output;
|
|
}
|
|
|
|
public static string StageFile(string file)
|
|
{
|
|
return RunCmd(Settings.GitCommand, "update-index --add" + " \"" + FixPath(file) + "\"");
|
|
}
|
|
|
|
public static string StageFileToRemove(string file)
|
|
{
|
|
return RunCmd(Settings.GitCommand, "update-index --remove" + " \"" + FixPath(file) + "\"");
|
|
}
|
|
|
|
|
|
public static string UnstageFile(string file)
|
|
{
|
|
return RunCmd(Settings.GitCommand, "rm" + " --cached \"" + FixPath(file) + "\"");
|
|
}
|
|
|
|
public static string UnstageFileToRemove(string file)
|
|
{
|
|
return RunCmd(Settings.GitCommand, "reset HEAD --" + " \"" + FixPath(file) + "\"");
|
|
}
|
|
|
|
public static string GetSelectedBranch()
|
|
{
|
|
var branches = RunCmd(Settings.GitCommand, "branch");
|
|
var branchStrings = branches.Split('\n');
|
|
foreach (var branch in branchStrings)
|
|
{
|
|
if (branch.IndexOf('*') > -1)
|
|
return branch.Trim('*', ' ');
|
|
}
|
|
return "";
|
|
}
|
|
|
|
public static List<GitHead> GetRemoteHeads(string remote, bool tags, bool branches)
|
|
{
|
|
remote = FixPath(remote);
|
|
|
|
var tree = GetTreeFromRemoteHeands(remote, tags, branches);
|
|
return GetHeads(tree);
|
|
}
|
|
|
|
private static string GetTreeFromRemoteHeands(string remote, bool tags, bool branches)
|
|
{
|
|
if (tags && branches)
|
|
return RunCmd(Settings.GitCommand, "ls-remote --heads --tags \"" + remote + "\"");
|
|
if (tags)
|
|
return RunCmd(Settings.GitCommand, "ls-remote --tags \"" + remote + "\"");
|
|
if (branches)
|
|
return RunCmd(Settings.GitCommand, "ls-remote --heads \"" + remote + "\"");
|
|
return "";
|
|
}
|
|
|
|
public static List<GitHead> GetHeads()
|
|
{
|
|
return GetHeads(true);
|
|
}
|
|
|
|
public static List<GitHead> GetHeads(bool tags)
|
|
{
|
|
return GetHeads(tags, true);
|
|
}
|
|
|
|
public static List<GitHead> GetHeads(bool tags, bool branches)
|
|
{
|
|
var tree = GetTree(tags, branches);
|
|
return GetHeads(tree);
|
|
}
|
|
|
|
private static string GetTree(bool tags, bool branches)
|
|
{
|
|
if (tags && branches)
|
|
return RunCmd(Settings.GitCommand, "show-ref --dereference");
|
|
|
|
if (tags)
|
|
return RunCmd(Settings.GitCommand, "show-ref --tags");
|
|
|
|
if (branches)
|
|
return RunCmd(Settings.GitCommand, "show-ref --dereference --heads");
|
|
return "";
|
|
}
|
|
|
|
private static List<GitHead> GetHeads(string tree)
|
|
{
|
|
var itemsStrings = tree.Split('\n');
|
|
|
|
var heads = new List<GitHead>();
|
|
|
|
var remotes = GetRemotes();
|
|
|
|
foreach (var itemsString in itemsStrings)
|
|
{
|
|
if (itemsString == null || itemsString.Length <= 42) continue;
|
|
|
|
var guid = itemsString.Substring(0, 40);
|
|
var completeName = itemsString.Substring(41).Trim();
|
|
heads.Add(new GitHead(guid, completeName, GetRemoteName(completeName, remotes)));
|
|
}
|
|
|
|
return heads;
|
|
}
|
|
|
|
public static string GetRemoteName(string completeName, IEnumerable<string> remotes)
|
|
{
|
|
string trimmedName = completeName.StartsWith("refs/remotes/") ? completeName.Substring(13) : completeName;
|
|
|
|
foreach (string remote in remotes)
|
|
{
|
|
if (trimmedName.StartsWith(string.Concat(remote, "/")))
|
|
return remote;
|
|
}
|
|
|
|
return string.Empty;
|
|
}
|
|
public static string[] GetFiles(string filePattern)
|
|
{
|
|
return RunCmd(Settings.GitCommand, "ls-files -z -o -m -c \"" + filePattern + "\"")
|
|
.Split(new char[] { '\0', '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
|
}
|
|
|
|
public static List<GitItem> GetFileChanges(string file)
|
|
{
|
|
file = FixPath(file);
|
|
var tree = RunCmd(Settings.GitCommand, "whatchanged --all -- \"" + file + "\"");
|
|
|
|
var itemsStrings = tree.Split('\n');
|
|
|
|
var items = new List<GitItem>();
|
|
|
|
GitItem item = null;
|
|
foreach (var itemsString in itemsStrings)
|
|
{
|
|
if (itemsString.StartsWith("commit "))
|
|
{
|
|
item = new GitItem { CommitGuid = itemsString.Substring(7).Trim() };
|
|
|
|
items.Add(item);
|
|
}
|
|
else if (item == null)
|
|
{
|
|
continue;
|
|
}
|
|
else if (itemsString.StartsWith("Author: "))
|
|
{
|
|
item.Author = itemsString.Substring(7).Trim();
|
|
}
|
|
else if (itemsString.StartsWith("Date: "))
|
|
{
|
|
item.Date = itemsString.Substring(7).Trim();
|
|
}
|
|
else if (!itemsString.StartsWith(":") && !string.IsNullOrEmpty(itemsString))
|
|
{
|
|
item.Name += itemsString.Trim() + Environment.NewLine;
|
|
}
|
|
else
|
|
{
|
|
if (itemsString.Length > 32)
|
|
item.Guid = itemsString.Substring(26, 7);
|
|
}
|
|
}
|
|
|
|
return items;
|
|
}
|
|
|
|
static public string[] GetFullTree(string id)
|
|
{
|
|
string tree = RunCachableCmd(Settings.GitCommand, string.Format("ls-tree -z -r --name-only {0}", id));
|
|
return tree.Split(new char[] { '\0', '\n' });
|
|
}
|
|
public static List<IGitItem> GetTree(string id)
|
|
{
|
|
var tree = RunCachableCmd(Settings.GitCommand, "ls-tree -z \"" + id + "\"");
|
|
|
|
var itemsStrings = tree.Split(new char[] { '\0', '\n' });
|
|
|
|
var items = new List<IGitItem>();
|
|
|
|
foreach (var itemsString in itemsStrings)
|
|
{
|
|
if (itemsString.Length <= 53)
|
|
continue;
|
|
|
|
var item = new GitItem { Mode = itemsString.Substring(0, 6) };
|
|
var guidStart = itemsString.IndexOf(' ', 7);
|
|
item.ItemType = itemsString.Substring(7, guidStart - 7);
|
|
item.Guid = itemsString.Substring(guidStart + 1, 40);
|
|
item.Name = itemsString.Substring(guidStart + 42).Trim();
|
|
item.FileName = item.Name;
|
|
|
|
items.Add(item);
|
|
}
|
|
|
|
return items;
|
|
}
|
|
|
|
public static List<GitBlame> Blame(string filename, string from)
|
|
{
|
|
from = FixPath(from);
|
|
filename = FixPath(filename);
|
|
var itemsStrings =
|
|
RunCmd(
|
|
Settings.GitCommand,
|
|
|
|
string.Format("blame -M -w -l \"{0}\" -- \"{1}\"", from, filename)
|
|
)
|
|
.Split('\n');
|
|
|
|
var items = new List<GitBlame>();
|
|
|
|
GitBlame item;
|
|
var lastCommitGuid = "";
|
|
|
|
var color1 = Color.Azure;
|
|
var color2 = Color.Ivory;
|
|
var currentColor = color1;
|
|
|
|
foreach (var itemsString in itemsStrings)
|
|
{
|
|
if (itemsString.Length <= 50)
|
|
continue;
|
|
|
|
var commitGuid = itemsString.Substring(0, 40).Trim();
|
|
|
|
if (lastCommitGuid != commitGuid)
|
|
currentColor = currentColor == color1 ? color2 : color1;
|
|
|
|
item = new GitBlame { Color = currentColor, CommitGuid = commitGuid };
|
|
items.Add(item);
|
|
|
|
var codeIndex = itemsString.IndexOf(')', 41) + 1;
|
|
if (codeIndex > 41)
|
|
{
|
|
if (lastCommitGuid != commitGuid)
|
|
item.Author = itemsString.Substring(41, codeIndex - 41).Trim();
|
|
|
|
if (!string.IsNullOrEmpty(item.Text))
|
|
item.Text += Environment.NewLine;
|
|
item.Text += itemsString.Substring(codeIndex).Trim(new[] { '\r' });
|
|
}
|
|
|
|
lastCommitGuid = commitGuid;
|
|
}
|
|
|
|
|
|
return items;
|
|
}
|
|
|
|
public static string GetFileRevisionText(string file, string revision)
|
|
{
|
|
return
|
|
RunCachableCmd(
|
|
Settings.GitCommand,
|
|
string.Format("show --encoding=" + Settings.Encoding + " {0}:\"{1}\"", revision, file.Replace('\\', '/')));
|
|
}
|
|
|
|
public static string GetFileText(string id)
|
|
{
|
|
return RunCachableCmd(Settings.GitCommand, "cat-file blob \"" + id + "\"");
|
|
}
|
|
|
|
public static void StreamCopy(Stream input, Stream output)
|
|
{
|
|
int read;
|
|
var buffer = new byte[2048];
|
|
do
|
|
{
|
|
read = input.Read(buffer, 0, buffer.Length);
|
|
output.Write(buffer, 0, read);
|
|
} while (read > 0);
|
|
}
|
|
|
|
|
|
public static Stream GetFileStream(string id)
|
|
{
|
|
try
|
|
{
|
|
var newStream = new MemoryStream();
|
|
|
|
SetEnvironmentVariable();
|
|
|
|
Settings.GitLog.Log(Settings.GitCommand + " " + "cat-file blob \"" + id + "\"");
|
|
//process used to execute external commands
|
|
|
|
var info = new ProcessStartInfo()
|
|
{
|
|
UseShellExecute = false,
|
|
ErrorDialog = false,
|
|
RedirectStandardOutput = true,
|
|
RedirectStandardInput = false,
|
|
RedirectStandardError = false,
|
|
CreateNoWindow = true,
|
|
FileName = "\"" + Settings.GitCommand + "\"",
|
|
Arguments = "cat-file blob \"" + id + "\"",
|
|
WorkingDirectory = Settings.WorkingDir,
|
|
WindowStyle = ProcessWindowStyle.Normal,
|
|
LoadUserProfile = true
|
|
};
|
|
|
|
using (var process = Process.Start(info))
|
|
{
|
|
StreamCopy(process.StandardOutput.BaseStream, newStream);
|
|
newStream.Position = 0;
|
|
|
|
process.WaitForExit();
|
|
return newStream;
|
|
}
|
|
}
|
|
catch (Win32Exception ex)
|
|
{
|
|
Trace.WriteLine(ex);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static string GetPreviousCommitMessage(int numberBack)
|
|
{
|
|
return RunCmd(Settings.GitCommand, "log -n 1 HEAD~" + numberBack + " --pretty=format:%s%n%n%b");
|
|
}
|
|
|
|
public static string MergeBranch(string branch)
|
|
{
|
|
return RunCmd(Settings.GitCommand, MergeBranchCmd(branch, true, null));
|
|
}
|
|
|
|
public static string OpenWithDifftool(string filename)
|
|
{
|
|
var output = "";
|
|
if (VersionInUse.GuiDiffToolExist)
|
|
RunCmdAsync(Settings.GitCommand, "difftool --gui --no-prompt \"" + filename + "\"");
|
|
else
|
|
output = RunCmd(Settings.GitCommand, "difftool --no-prompt \"" + filename + "\"");
|
|
return output;
|
|
}
|
|
|
|
public static string OpenWithDifftool(string filename, string revision1, string revision2)
|
|
{
|
|
var output = "";
|
|
if (VersionInUse.GuiDiffToolExist)
|
|
RunCmdAsync(Settings.GitCommand,
|
|
"difftool --gui --no-prompt " + revision2 + " " + revision1 + " -- \"" + filename + "\"");
|
|
else
|
|
output = RunCmd(Settings.GitCommand,
|
|
"difftool --no-prompt " + revision2 + " " + revision1 + " -- \"" + filename + "\"");
|
|
return output;
|
|
}
|
|
|
|
public static string MergeBranchCmd(string branch, bool allowFastForward, string strategy)
|
|
{
|
|
StringBuilder command = new StringBuilder("merge");
|
|
|
|
if (!allowFastForward)
|
|
command.Append(" --no-ff");
|
|
if (!string.IsNullOrEmpty(strategy))
|
|
{
|
|
command.Append(" --strategy=");
|
|
command.Append(strategy);
|
|
}
|
|
|
|
command.Append(" ");
|
|
command.Append(branch);
|
|
return command.ToString();
|
|
}
|
|
|
|
public static string GetFileExtension(string fileName)
|
|
{
|
|
if (fileName.Contains(".") && fileName.LastIndexOf(".") < fileName.Length)
|
|
return fileName.Substring(fileName.LastIndexOf('.') + 1);
|
|
|
|
return null;
|
|
}
|
|
}
|
|
}
|