5

I have created a simple PowerShell script to automate the creation of an archive containing all the files that were modified between two git tags.

It seemed to work quite well with the few tests I had done, but today a colleague complained that it wasn't adding a specific file. I started debugging it and I'm seeing a very strange behavior.

As you can see, the command I'm using to list the files modified is git diff, passing the to and from tags that I got from the PowerShell command's argument (as strings).

param(
    # Git tag or commit has from which we want the patch to start
    [String] $FromTag,
    # Path of the patch file
    [String] $PatchFilePath,
    # Git tag or commit hash where to we want the patch to update to (default HEAD, current checkout)
    [String] $ToTag = "HEAD"
)
...
$modifiedFiles = git diff $FromTag..$ToTag --no-commit-id --name-only --diff-filter=ACMRT 
...

Testing it, I saw that the files were indeed missing. I decided to run the command manually, like this:

git diff v041.3.2..v041.3.6 --no-commit-id --name-only --diff-filter=ACMRT

Which returned the files... and got me baffled. I then tried to do the following:

$FromTag = "v041.3.2"
$ToTag = "v041.3.6"
git diff $FromTag..$ToTag --no-commit-id --name-only --diff-filter=ACMRT

Which doesn't return all the files, but a subset of them.

I've then tried to call

git diff "v041.3.2".."v041.3.6" --no-commit-id --name-only --diff-filter=ACMRT

Which gives me the exact same result as with the variables, returning only a subset of all the files that were modified.

I've tried to run that last command in a "DOS" command prompt to check if it was a git issue, but it returns the correct set of files.

There seems to be a difference on how git interprets the input when PowerShell passes it as strings, but I really don't get why and how.

Here's the full script for those interested: https://gist.github.com/Gimly/b865b0ed09f0f9fe13d12f6b0137ecfb

Gimly
  • 5,975
  • 3
  • 40
  • 75
  • 1
    Just for testing, can you declare git as in http://stackoverflow.com/a/9934012/6309? – VonC Sep 08 '16 at 10:56

1 Answers1

8

Run cmd /c echo $FromTag..$ToTag from PowerShell and you'll see a space after the first variable:

v041.3.2 ..v041.3.6

Use doublequotes to pass it as one parameter as-is (the quotes won't be passed to the program):

git diff "$FromTag..$ToTag"
wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • Any clue as to why a space would be added? – Gimly Sep 08 '16 at 12:36
  • The real answer is probably buried in the source code of PS, but it looks like a bug caused by parser's attempt to be smart: evidently, `$a..$b` is seen as two parameters: a variable + a string literal with an embedded variable. – wOxxOm Sep 08 '16 at 12:48
  • Yes, it does make sense. Coupled with the fact that the git-diff parser is very liberal with what it can receive made it quite a weird bug. I could have passed a few hours on that if it were not from your help and clever way to test it. Thanks – Gimly Sep 08 '16 at 12:55