Question Details

No question body available.

Tags

bash git shell git-alias

Answers (3)

Accepted Answer Available
Accepted Answer
October 29, 2025 Score: 5 Rep: 20,541 Quality: High Completeness: 50%

Aliases with ! are run through /bin/sh – not through your user's default shell. On some distributions, /bin/sh is Dash, which does not support array-range expansions like ${@:start:end}.

This is easiest to solve by making your mega-alias into a proper shell script (all commands named git- automatically become git subcommands), and using #! to specify the script interpreter:

~/bin/git-mv-into-dir
#!/usr/bin/env bash

quote the path to prevent issues with spaces in paths

cd "${GIT_PREFIX:-.}"

use an array variable to preserve individual args

allArgsButLast=( "${@:1:$#-1}" ) lastArg=${@:(-1)}

git mv -v "${allArgsButLast[@]}" "$lastArg/" && git commit -uno "$@" -m "Moved ${allArgsButLast[
]} into $lastArg/"
October 29, 2025 Score: 4 Rep: 4,608 Quality: Medium Completeness: 60%

What would git(1) do? Or, What does git(1) do?

! tells it to run your alias in a shell. What shell? It can’t use a specific one like Ksh or Zsh. It just says “shell”. So let’s try /bin/sh:

#!/bin/sh

mvIntoDIR() { cd ${GITPREFIX:-.}; allArgsButLast="${@:1:$#-1}"; lastArg="${@: -1}"; git mv -v $allArgsButLast $lastArg/; git commit -uno $allArgsButLast $lastArg -m "Moved $allArgsButLast into $lastArg/"; \ };

mvIntoDIR

We get the same error but a useful line number:

5: Bad substitution

Namely:

allArgsButLast="${@:1:$#-1}";

Okay. But this is a Bash construct. So let’s change it to that:

#!/usr/bin/env bash

mvIntoDIR() { cd ${GITPREFIX:-.}; allArgsButLast="${@:1:$#-1}"; lastArg="${@: -1}"; git mv -v $allArgsButLast $lastArg/; git commit -uno $allArgsButLast $lastArg -m "Moved $allArgsButLast into $lastArg/"; \ };

mvIntoDIR

We get a different error:

line 5: $#-1: substring expression < 0

Okay. So git(1) must be running a shell which does not even know what ${@:1:$#-1} means. But Bash at least recognizes that you are trying to use a construct that it knows, even if it is being misused in some way.

Now the script is still faulty. But at least it can be fixed since it is running in the shell intended for it.

I would either ditch the alias in favor of a Bash script or make a Bash script and make a wrapper alias to run it.

October 31, 2025 Score: 3 Rep: 20,465 Quality: Medium Completeness: 50%

A POSIX-shell implementation that will therefore not require the use of Bash:

#!/bin/sh

: "${2:?Needs at least a destination}" git mv -v -- "$@" || exit # On fail exit with the git error code if any

Composes the commit message with all sources and destination

m=Moved # Message start while [ $# -gt 1 ] # Iterates all arguments except the last one do m="$m $1" # Append argument to the message string shift done m="$m into $1" # Suffixes message with the last argument

Performs the commit with given message

git commit -uno -m "$m" || exit # On fail exit with the git error code if any