1

I'm trying to setup a git alias to list all files that are marked 'assume-unchanged' with this command:

git ls-files -v | sls -pattern ^h -casesensitive

When i use this command directly in powershell it works as expected but as an alias i get the error :

PS C:\git\sim> git unchanged
git ls-files -v | sls -pattern ^h -casesensitive: sls: command not found

In my .gitconfig file i have

# ALIASES   
[alias]
  unchanged = !git ls-files -v | sls -pattern ^h -casesensitive

I have tried different variations... with '!' exclamation and without,
wrapped in double/single quotes and without.

If i remove the end part it works as expected e.g.

[alias]
  unchanged = !git ls-files -v

So i assume something is wrong with the syntax in the second half of the command?

Any help would be appreciated...

1 Answers1

1

When you define a Git alias with ! in order to have it execute a shell command (rather than the default behavior of passing arguments to git), Git uses:

  • on Unix-like platforms: the default shell, /bin/sh
  • on Windows: the Bash version that comes bundled with Git

Therefore, in order to define a Git alias that executes a PowerShell command, you must invoke PowerShell's CLI explicitly and pass the command to it via the -c parameter:

Here's a full example; note that it assumes PowerShell Core; for Windows PowerShell, replace pwsh with powershell:

# Run from PowerShell

# Define the alias.
# Note the unexpected need to escape " as \" - see below.
git config --global alias.unchanged '! pwsh -noprofile -c \"git ls-files -v | sls -pattern ^h -casesensitive\"'

# Invoke it.
git unchanged

As an aside: Note the awkward need to \-escape the embedded " chars., even though they're inside a single-quoted string '...' - this unfortunate requirement - which seemingly won't be removed for the sake of backward compatibility - is discussed in this GitHub issue.


As for what you tried:

Defining your alias as:

[alias] unchanged = !git ls-files -v | sls -pattern ^h -casesensitive

means that sh / bash is executing the command, as explained above.

While the command is syntactically valid there, it fails because sls is looked for as an external program (given that it is neither a sh / bash builtin, nor a user-defined function, nor a sh / bash alias), which doesn't exist ("command not found").

Only PowerShell knows that sls is an alias for the Select-String cmdlet (and even using the latter's actual name wouldn't allow it to be called from outside of PowerShell, given that it is implemented via a PowerShell-specific DLL).

By contrast, git ls-files -v by itself works in sh / bash as well, because it is a call to git, an external program (a platform-native executable that any shell can call).

mklement0
  • 382,024
  • 64
  • 607
  • 775