How to generate and apply git patches correctly in Powershell (vs bash)?

How to generate and apply git patches correctly in Powershell (vs bash)?

Indeed:

  • PowerShell invariably decodes output from external programs as text (using [Console]::OutputEncoding)

  • It then sends the decoded output line by line through the pipeline, as lines become available.

  • A file-output cmdlet such as Out-File then invariably uses the platform-native newline sequence – CRLF on Windows – to terminate each (stringified) input object when writing to the target file (using its default character encoding (or the one specified via -Encoding), which is technically unrelated to the encoding that was used to decode the external-program output).

In other words: PowerShell pipelines (and redirections) do not support passing raw binary data through, as of PowerShell 7.2 – future raw-data support is being discussed in GitHub issue #1908.

Workarounds:

  • Manually join and terminate the decoded output lines with LF newlines (`n), and write the resulting multi-line string as-is (-NoNewLine) to the target file, as shown in zdans helpful answer.

  • In this simple case it is easiest to delegate to cmd.exe /c, given that cmd.exes pipelines and redirections are raw byte conduits:

cmd /c @
git diff -U3 -r -M HEAD -- .MetadataLegacyTypeModulesxyz.Web.Main.draft.json > c:temp1.diff
@

Note the use of a here-string for readability and ease of any embedded quoting (n/a here).

You could try using join to replace the CRLF with unix EOL:

(git command arguments . . .) -join `n | out-file c:temp1.diff -NoNewline

How to generate and apply git patches correctly in Powershell (vs bash)?

A standard diff (also known as a patch) terminates lines with LF line endings. Thats because thats what POSIX specifies for the output of diff. All lines must contain an LF line ending.

When a CR precedes the LF in a patch, it is considered part of the content to be patched. Therefore, the patch in your situation likely doesnt apply because the old content is being listed as having CRLF line endings, which it does not.

Unfortunately, PowerShell is completely broken in this regard and its pipelines corrupt data passing through them. This is especially true for any sort of binary data. If youre using any sort of tool designed to run on Unix like Git, youll need to avoid using PowerShells pipes.

Leave a Reply

Your email address will not be published.