2
2
using System . Collections . Generic ;
3
3
using System . IO ;
4
4
using System . Linq ;
5
+ using System . Runtime . InteropServices ;
5
6
using EnvDTE ;
6
7
using LibGit2Sharp ;
7
8
using Microsoft . VisualStudio . Text ;
@@ -15,7 +16,7 @@ public class GitCommands : IGitCommands
15
16
16
17
public GitCommands ( IServiceProvider serviceProvider )
17
18
{
18
- _dte = ( DTE ) serviceProvider . GetService ( typeof ( _DTE ) ) ;
19
+ _dte = ( DTE ) serviceProvider . GetService ( typeof ( _DTE ) ) ;
19
20
}
20
21
21
22
private const int ContextLines = 0 ;
@@ -98,26 +99,31 @@ public void StartExternalDiff(ITextDocument textDocument)
98
99
99
100
using ( var repo = new Repository ( discoveredPath ) )
100
101
{
101
- var diffGuiTool = repo . Config . Get < string > ( "diff.guitool " ) ;
102
+ var diffGuiTool = repo . Config . Get < string > ( "diff.tool " ) ;
102
103
103
104
if ( diffGuiTool == null ) return ;
104
105
105
- var diffCmd = repo . Config . Get < string > ( "difftool." + diffGuiTool . Value + ".path" ) ;
106
-
107
106
var indexEntry = repo . Index [ filename . Replace ( repo . Info . WorkingDirectory , "" ) ] ;
108
107
var blob = repo . Lookup < Blob > ( indexEntry . Id ) ;
109
108
110
109
var tempFileName = Path . GetTempFileName ( ) ;
111
110
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
+
113
118
var process = new Process
114
119
{
115
120
StartInfo =
116
121
{
117
- FileName = diffCmd . Value ,
118
- Arguments = String . Format ( "{0} {1} ", tempFileName , filename )
122
+ FileName = exe ,
123
+ Arguments = string . Join ( " ", args )
119
124
}
120
125
} ;
126
+
121
127
process . Start ( ) ;
122
128
}
123
129
}
@@ -141,5 +147,37 @@ public string GetGitRepository(string filePath)
141
147
var directoryInfo = Directory . GetParent ( fullPath ) . Parent ;
142
148
return directoryInfo != null ? directoryInfo . FullName : null ;
143
149
}
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
+ }
144
182
}
145
183
}
0 commit comments