@@ -88,7 +88,6 @@ private Process StartGitProcess(params string[] args)
8888#if DEBUG
8989 Console . WriteLine ( "Running git command: " + string . Join ( " " , args ) ) ;
9090#endif
91- #if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
9291 // run `git ...args` in CheckDirectory working directory with 3 second timeout
9392 var procInfo = new ProcessStartInfo ( "git" )
9493 {
@@ -101,53 +100,64 @@ private Process StartGitProcess(params string[] args)
101100 StandardOutputEncoding = System . Text . Encoding . UTF8 ,
102101 StandardErrorEncoding = System . Text . Encoding . UTF8 ,
103102 } ;
103+ #if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER
104104 foreach ( var a in args )
105105 procInfo . ArgumentList . Add ( a ) ;
106- return Process . Start ( procInfo ) ;
107106#else
108- // Old frameworks don't support ArgumentList, so I rather pull in a dependency than write my own escaping
109- var command = Medallion . Shell . Shell . Default . Run ( "git" , args , options => options . WorkingDirectory ( CheckDirectory ) . Timeout ( TimeSpan . FromSeconds ( 15 ) ) ) ;
110- return command . Process ;
107+ procInfo . Arguments = WindowsEscapeArguments ( args ) ;
111108#endif
109+ return Process . Start ( procInfo ) ;
112110 }
113111
114- private void HandleProcessExit ( Process proc , Task outputReaderTask , params string [ ] args )
112+
113+ #if ! ( NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER )
114+ private static string WindowsEscapeArguments ( params string [ ] args )
115115 {
116- // Literally, a Raspberry PI with a shitty SD card has faster IO than Azure Windows VM
117- var timeout = RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ? 15_000 : 3_000 ;
118- if ( ! proc . WaitForExit ( timeout ) )
119- {
120- proc . Kill ( ) ;
121- throw new Exception ( $ "`git { string . Join ( " " , args ) } ` command timed out") ;
122- }
116+ // based on the logic from http://stackoverflow.com/questions/5510343/escape-command-line-arguments-in-c-sharp.
123117
124- if ( proc . ExitCode != 0 )
125- throw new Exception ( $ "`git { string . Join ( " " , args ) } ` command failed: " + proc . StandardError . ReadToEnd ( ) ) ;
118+ if ( ! RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
119+ throw new InvalidOperationException ( "The nestandard2.0 build is only supported on Windows old .NET Framework" ) ;
126120
127- outputReaderTask . Wait ( ) ;
121+ return string . Join ( " " , args . Select ( a => {
122+ a = Regex . Replace ( a , @"(\\*)" + "\" " , @"$1$1\" + "\" " ) ;
123+ return "\" " + Regex . Replace ( a , @"(\\+)$" , @"$1$1" ) + "\" " ;
124+ } ) ) ;
128125 }
126+ #endif
129127
130- private string [ ] RunGitCommand ( params string [ ] args )
131- {
132- var proc = StartGitProcess ( args ) ;
133128
134- var outputLines = new List < string > ( ) ;
135- var outputReaderTask = Task . Run ( ( ) =>
129+ private void HandleProcessExit ( Process proc , Task outputReaderTask , params string [ ] args )
130+ {
131+ try
136132 {
137- string line ;
138- while ( ( line = proc . StandardOutput . ReadLine ( ) ) != null )
133+ // Literally, a Raspberry PI with a shitty SD card has faster IO than Azure Windows VM
134+ var timeout = RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ? 15_000 : 3_000 ;
135+ if ( ! proc . WaitForExit ( timeout ) )
139136 {
140- if ( line . Length > 0 )
141- outputLines . Add ( line ) ;
137+ proc . Kill ( ) ;
138+ throw new Exception ( $ "`git { string . Join ( " " , args ) } ` command timed out" ) ;
142139 }
143- } ) ;
144140
145- HandleProcessExit ( proc , outputReaderTask , args ) ;
141+ if ( proc . ExitCode != 0 )
142+ throw new Exception ( $ "`git { string . Join ( " " , args ) } ` command failed: " + proc . StandardError . ReadToEnd ( ) ) ;
143+
144+ outputReaderTask . Wait ( ) ;
145+ }
146+ finally
147+ {
148+ proc . Dispose ( ) ;
149+ }
150+ }
151+
152+ private string [ ] RunGitCommand ( params string [ ] args )
153+ {
154+ var output = RunGitBinaryCommand ( args ) ;
146155
147- return outputLines . ToArray ( ) ;
156+ using var reader = new StreamReader ( output ) ;
157+ return ReadAllLines ( reader ) ;
148158 }
149159
150- private byte [ ] RunGitBinaryCommand ( params string [ ] args )
160+ private MemoryStream RunGitBinaryCommand ( params string [ ] args )
151161 {
152162 var proc = StartGitProcess ( args ) ;
153163
@@ -160,14 +170,16 @@ private byte[] RunGitBinaryCommand(params string[] args)
160170
161171 HandleProcessExit ( proc , outputReaderTask , args ) ;
162172
163- return ret . ToArray ( ) ;
173+ ret . Position = 0 ;
174+ return ret ;
164175 }
165176
166177 static string [ ] ReadAllLines ( StreamReader reader )
167178 {
168179 var lines = new List < string > ( ) ;
169180 while ( ! reader . EndOfStream && reader . ReadLine ( ) is { } line )
170- lines . Add ( line ) ;
181+ if ( line . Length > 0 )
182+ lines . Add ( line ) ;
171183 return lines . ToArray ( ) ;
172184 }
173185
@@ -205,7 +217,7 @@ private byte[] GetOldBinaryContent(string file)
205217
206218 var data = RunGitBinaryCommand ( "cat-file" , "blob" , hash ) ;
207219
208- return data ;
220+ return data . ToArray ( ) ;
209221 }
210222 else
211223 {
0 commit comments