在Git中,为了方便起见,我想添加一些全局别名。
命令
git config --global alias.unstage 'reset HEAD --'
在文档中找到,工作正常。所以我尝试使用相同的语法,在命令前加!
来运行外部的,更复杂的脚本:
# release-major
latest=$(git describe --abbrev=0 --tags 2>/dev/null); latest=${latest:-v0.0.0}; components=(${latest//./ }); major=${components[0]}; major=${major//v/}; minor=${components[1]}; patch=${components[2]}; major=$((major+1)); minor=0; patch=0; next='v'$major'.'$minor'.'$patch; git tag -a $next -m ""
# release-minor
latest=$(git describe --abbrev=0 --tags 2>/dev/null); latest=${latest:-v0.0.0}; components=(${latest//./ }); major=${components[0]}; major=${major//v/}; minor=${components[1]}; patch=${components[2]}; minor=$((minor+1)); patch=0; next='v'$major'.'$minor'.'$patch; git tag -a $next -m ""
# release-patch
latest=$(git describe --abbrev=0 --tags 2>/dev/null); latest=${latest:-v0.0.0}; components=(${latest//./ }); major=${components[0]}; major=${major//v/}; minor=${components[1]}; patch=${components[2]}; patch=$((patch+1)); next='v'$major'.'$minor'.'$patch; git tag -a $next -m ""
如果我尝试使用语法
添加这三个脚本git config --global alias.my-alias-name '!my-alias-code'
但是,它不起作用。结果始终是解析器错误。
我试过了我能想象的引用,不引用,单引号和双引号的各种变体。我甚至尝试将这些文件直接添加到.gitconfig
文件中。这些都不起作用。
我错过了什么?如何修复这些脚本以便我可以将它们添加为别名?
答案 0 :(得分:4)
您可以对单行脚本进行解除冲突。我们来看看这个例子:
latest=$(git describe --abbrev=0 --tags 2>/dev/null)
latest=${latest:-v0.0.0}
components=(${latest//./ })
这是你的第一个bash-ism:你正在用数字替换空格(然后分解)来制作一个数组。普通shell没有数组;相反,我们使用位置参数,使用$IFS
将其与set
分开。为了保持干净,我们需要在函数中使用它(每个函数都有自己的私有位置),但是如果所有位置参数都已经被捕获到局部变量中,我们可以覆盖它们:
set -- $(echo $latest | sed "s/\./ /g")
(回到你的代码)
major=${components[0]}
major=${major//v/}
minor=${components[1]}
patch=${components[2]}
现在我们在这里使用$ 1,$ 2和$ 3。我们不妨将v
替换移到上面的sed中(POSIX sh可以做这个替换,但我说让我们让它做,因为它更明显和/或更有效率):
set -- $(echo $latest | sed -e s/v// -e "s/\./ /g")
major=$1
minor=$2
patch=$3
返回原始代码:
major=$((major+1))
minor=0
patch=0
next='v'$major'.'$minor'.'$patch
git tag -a $next -m ""
这是所有有效的POSIX sh,所以我们完成了这次转换。
答案 1 :(得分:1)
您在脚本中使用特定于bash的语法(例如$(( ))
用于算术)。但是,默认情况下,!
执行以/bin/sh
开头的git别名。由于/bin/sh
只是一个简单的POSIX shell,因此它的语法中没有任何这些功能。
幸运的是,这很容易解决。只需将#!/bin/bash
添加到脚本的开头即可。 (如果它是一个单独的文件。)
如果您使用这些内联,那么您可能需要直接调用bash。这可能是一个令人头疼的问题,但你的例子看起来并不像是一个大问题。我想这可能会这样做:
# release-major
bash -c "latest=$(git describe --abbrev=0 --tags 2>/dev/null); latest=${latest:-v0.0.0}; components=(${latest//./ }); major=${components[0]}; major=${major//v/}; minor=${components[1]}; patch=${components[2]}; major=$((major+1)); minor=0; patch=0; next='v'$major'.'$minor'.'$patch; git tag -a $next -m ''"
# release-minor
bash -c "latest=$(git describe --abbrev=0 --tags 2>/dev/null); latest=${latest:-v0.0.0}; components=(${latest//./ }); major=${components[0]}; major=${major//v/}; minor=${components[1]}; patch=${components[2]}; minor=$((minor+1)); patch=0; next='v'$major'.'$minor'.'$patch; git tag -a $next -m ''"
# release-patch
bash -c "latest=$(git describe --abbrev=0 --tags 2>/dev/null); latest=${latest:-v0.0.0}; components=(${latest//./ }); major=${components[0]}; major=${major//v/}; minor=${components[1]}; patch=${components[2]}; patch=$((patch+1)); next='v'$major'.'$minor'.'$patch; git tag -a $next -m ''"