Search code examples
gitpowershellposh-git

get-childitem with -recurse causes -contains match to behave differently when comparing $GitStatus


Using posh-git in powershell I am able to list all the items in the working tree that have changed, by using the collection variable $GitStatus.Working, I can use this list in a where clause to filter a directory listing like so

dir | where {$GitStatus.Working -contains $_.Name}

this works really well to display all the files in the current directory that are altered but not yet in the index, however when I run this same command with the -recurse directive the file(s) no longer match. I don't understand why. Any ideas?

(Note Posh-GiTDir from Scott Hanselman suffers from the same problem, not surprisingly as he uses basically the same technique, to show the "Git" column)

Edit: This started when I noticed that the Posh-GitDir Git column did not display anything when I did a recursive directory listing. It's useful to be able to quickly see what's changed "from this folder down", I looked at how Posh-GitDir gets its info to try and debug why it wasn't working for a recurse.


Solution

  • That is because you are using $_.Name, but when you do git status, which is what $GitStatus would give you from Posh-Git, it will give the directory and the file name. So when you are considering the current folder only ( dir without -recurse ) it works out find as it will only be the names. But when you consider files within directories, they will be relavtive paths and will not match with $_.name

    And btw, $GitStatus.Working is SUPPOSED to show the files in the repo that are in working directory but not added. Why are you trying to get a list of all files and filtering it with the items from $GitStatus.Working

    If you want FileInfo object from the $GitStatus.Working, try doing:

    $GitStatus.Working | gi
    

    Edited to show the final solution based on this answer:
    So for my purposes, what I did was....

    $working = $GitStatus.Working | gi | %{$_.FullName}
    dir -recurse | where {$working -contains $_.FullName}
    

    (edited the edit, the previous snippet was not correct.)