Skip to content

Commit 99d2a8a

Browse files
committed
Fix reading of diff tool configuration in .gitconfig (close #32)
1 parent c462ac1 commit 99d2a8a

File tree

1 file changed

+45
-7
lines changed

1 file changed

+45
-7
lines changed

GitDiffMargin/Git/GitCommands.cs

+45-7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Linq;
5+
using System.Runtime.InteropServices;
56
using EnvDTE;
67
using LibGit2Sharp;
78
using Microsoft.VisualStudio.Text;
@@ -15,7 +16,7 @@ public class GitCommands : IGitCommands
1516

1617
public GitCommands(IServiceProvider serviceProvider)
1718
{
18-
_dte = (DTE) serviceProvider.GetService(typeof (_DTE));
19+
_dte = (DTE)serviceProvider.GetService(typeof(_DTE));
1920
}
2021

2122
private const int ContextLines = 0;
@@ -98,26 +99,31 @@ public void StartExternalDiff(ITextDocument textDocument)
9899

99100
using (var repo = new Repository(discoveredPath))
100101
{
101-
var diffGuiTool = repo.Config.Get<string>("diff.guitool");
102+
var diffGuiTool = repo.Config.Get<string>("diff.tool");
102103

103104
if (diffGuiTool == null) return;
104105

105-
var diffCmd = repo.Config.Get<string>("difftool." + diffGuiTool.Value + ".path");
106-
107106
var indexEntry = repo.Index[filename.Replace(repo.Info.WorkingDirectory, "")];
108107
var blob = repo.Lookup<Blob>(indexEntry.Id);
109108

110109
var tempFileName = Path.GetTempFileName();
111110
File.WriteAllText(tempFileName, blob.GetContentText());
112-
111+
112+
var diffCmd = repo.Config.Get<string>("difftool." + diffGuiTool.Value + ".cmd");
113+
var cmd = diffCmd.Value.Replace("$LOCAL", tempFileName).Replace("$REMOTE", filename);
114+
115+
string exe;
116+
var args = CommandLineToArgs(cmd, out exe);
117+
113118
var process = new Process
114119
{
115120
StartInfo =
116121
{
117-
FileName = diffCmd.Value,
118-
Arguments = String.Format("{0} {1}", tempFileName, filename)
122+
FileName = exe,
123+
Arguments = string.Join(" ", args)
119124
}
120125
};
126+
121127
process.Start();
122128
}
123129
}
@@ -141,5 +147,37 @@ public string GetGitRepository(string filePath)
141147
var directoryInfo = Directory.GetParent(fullPath).Parent;
142148
return directoryInfo != null ? directoryInfo.FullName : null;
143149
}
150+
151+
[DllImport("shell32.dll", SetLastError = true)]
152+
static extern IntPtr CommandLineToArgvW(
153+
154+
[MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine, out int pNumArgs);
155+
private static string[] CommandLineToArgs(string commandLine, out string executableName)
156+
{
157+
int argCount;
158+
var result = CommandLineToArgvW(commandLine, out argCount);
159+
if (result == IntPtr.Zero)
160+
{
161+
throw new System.ComponentModel.Win32Exception();
162+
}
163+
164+
try
165+
{
166+
var pStr = Marshal.ReadIntPtr(result, 0 * IntPtr.Size);
167+
executableName = Marshal.PtrToStringUni(pStr);
168+
var args = new string[argCount - 1];
169+
for (var i = 0; i < args.Length; i++)
170+
{
171+
pStr = Marshal.ReadIntPtr(result, (i + 1) * IntPtr.Size);
172+
var arg = Marshal.PtrToStringUni(pStr);
173+
args[i] = arg;
174+
}
175+
return args;
176+
}
177+
finally
178+
{
179+
Marshal.FreeHGlobal(result);
180+
}
181+
}
144182
}
145183
}

0 commit comments

Comments
 (0)