bash Shell 脚本 - 尝试在 if/else 语句中验证 git 存储库中是否存在 git 标记
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17790123/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Shell script - trying to validate if a git tag exists in a git repository in an if/else statement
提问by Kim
I am creating a deploy script for a zend application. The scrip is almost done only I want to verify that a tag exists within the repo to force tags on the team. Currently I have the following code:
我正在为 Zend 应用程序创建部署脚本。脚本几乎完成了,只是我想验证存储库中是否存在标签以强制在团队中添加标签。目前我有以下代码:
# Fist update the repo to make sure all the tags are in
cd /git/repo/path
git pull
# Check if the tag exists in the rev-list.
# If it exists output should be zero,
# else an error will be shown which will go to the else statement.
if [ -z "'cd /git/repo/path && git rev-list ..'" ]; then
echo "gogo"
else
echo "No or no correct GIT tag found"
exit
fi
Looking forward to your feedback!
期待您的反馈意见!
Update
更新
When I execute the following in the command line:
当我在命令行中执行以下命令时:
cd /git/repo/path && git rev-list v1.4..
I get NOoutput, which is good. Though when I execute:
我没有输出,这很好。虽然当我执行:
cd /git/repo/path && git rev-list **BLA**..
I get an error, which again is good:
我收到一个错误,这又是好的:
fatal: ambiguous argument 'BLA..': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions
The -z in the statement says, if sting is empty then... In other words, it works fine via command line. Though when I use the same command in a shell script inside a statement it does not seem to work.
语句中的 -z 表示,如果 sting 为空,则......换句话说,它可以通过命令行正常工作。尽管当我在语句中的 shell 脚本中使用相同的命令时,它似乎不起作用。
[ -z "'cd /git/repo/path && git rev-list ..'" ]
This method what inspired by Validate if commit exists
这种方法的灵感来自Validate if commit exists
Update 2
更新 2
I found the problem:
我发现了问题:
See Using if elif fi in shell scripts>
sh is interpreting the && as a shell operator. Change it to -a, that's ['s conjunction operator:
[ "$arg1" = "$arg2" -a "$arg1" != "$arg3" ] Also, you should always quote the variables, because [ gets confused when you leave off arguments.
sh 将 && 解释为 shell 运算符。将其更改为 -a,即 [ 的连接运算符:
[ "$arg1" = "$arg2" -a "$arg1" != "$arg3" ] 另外,你应该总是引用变量,因为 [ 当你离开参数时会感到困惑。
in other words, I changed the &&
to ;
and simplified the condition. Now it works beautiful.
换句话说,我将 更改&&
为;
并简化了条件。现在它工作得很漂亮。
if cd /path/to/repo ; git rev-list .. >/dev/null
then
echo "gogo"
else
echo "WRONG"
exit
fi
采纳答案by John Szakmeister
You could use git rev-parse
instead:
你可以git rev-parse
改用:
if GIT_DIR=/path/to/repo/.git git rev-parse >/dev/null 2>&1
then
echo "Found tag"
else
echo "Tag not found"
fi
git rev-list
invokes graph walking, where git rev-parse
would avoid it. The above has some issues with possibly looking up an object instead of a tag. You can avoid that by using ^{tag}
following the tag name, but this only works for annotated tags and not lightweight tags:
git rev-list
调用图行走,哪里git rev-parse
会避免它。上面有一些可能查找对象而不是标签的问题。您可以通过使用^{tag}
以下标签名称来避免这种情况,但这仅适用于带注释的标签,而不适用于轻量级标签:
if GIT_DIR=/path/to/repo/.git git rev-parse "^{tag}" >/dev/null 2>&1
then
echo "Found tag"
else
echo "Tag not found"
fi
@Lassi also points out that if your tag name begins with a -
, then it might get interpreted as an option instead. You can avoid that issue by looking for refs/tags/$1
instead. So in summary, with the rev-parse
version, you can look for refs/tags/$1
to get both lightweight and annotated tags, and you can append a ^{tag}
to the end to enforce an annotated tag (refs/tags/$1^{tag}
).
@Lassi 还指出,如果您的标签名称以 a 开头-
,则它可能会被解释为一个选项。您可以通过查找来避免该问题refs/tags/$1
。所以总而言之,对于rev-parse
版本,您可以寻找refs/tags/$1
同时获得轻量级和带注释的标签,并且您可以^{tag}
在末尾附加 a以强制使用带注释的标签 ( refs/tags/$1^{tag}
)。
Also, as mentioned before by @forvaidya, you could simply list the tags and grep for the one you want:
此外,正如@forvaidya 之前提到的,您可以简单地列出您想要的标签和 grep:
if GIT_DIR=/path/to/repo/.git git show-ref --tags | egrep -q "refs/tags/$"
then
echo "Found tag"
else
echo "Tag not found"
fi
You can also use git tag --list
instead of git show-ref --tags
:
您还可以使用git tag --list
代替git show-ref --tags
:
if GIT_DIR=/path/to/repo/.git git tag --list | egrep -q "^$"
then
echo "Found tag"
else
echo "Tag not found"
fi
If you know the tag though, I think it's best just to just look it up via rev-parse
. One thing I don't like about the egrep
version is that it's possible you could have characters that could get interpreted as regex sequences and either cause a false positive or false negative. The rev-parse
version is superior in that sense, and in that it doesn't look at the whole list of tags.
如果你知道标签,我认为最好只是通过rev-parse
. 我不喜欢该egrep
版本的一件事是,您可能会将字符解释为正则表达式序列,并导致误报或误报。该rev-parse
版本在这个意义上更胜一筹,因为它不查看整个标签列表。
回答by lxg
Why so complicated? Here's a dead-simple solution (based on cad106uk's approachfurther down the page):
为什么这么复杂?这是一个非常简单的解决方案(基于cad106uk在页面下方的方法):
version=1.2.3
if [ $(git tag -l "$version") ]; then
echo yes
else
echo no
fi
It is not necessary to compare the output of git tag -l
with the version number, because the output will be empty if the version is not found. Therefore it's sufficient to test if there's any output at all.
没有必要将 的输出git tag -l
与版本号进行比较,因为如果找不到版本,输出将是空的。因此,测试是否有任何输出就足够了。
Note: The quotes around $version
are important to avoid false positives. Because if $version
is empty for some reason, git tag -l
would just list alltags, and the condition would always be true.
注意:周围的引号$version
对于避免误报很重要。因为 if 由于$version
某种原因为空,git tag -l
只会列出所有标签,并且条件总是为真。
回答by Lassi
Here's the rev-parseversion developed further:
这是进一步开发的rev-parse版本:
tag=whatever
if git rev-parse -q --verify "refs/tags/$tag" >/dev/null; then
echo "found"
else
echo "not found"
fi
It appears to be robust:
它似乎很健壮:
- Checks only for a tag, not a branch or a commit hash, etc.
- Weird tag name input doesn't cause weird behavior:
- Tag names starting with "-" are not mistaken for command line options
- Tag names containing slashes or dots are not special
- Tag names containing whitespace are not special
- Blank tag name isn't special
- 仅检查tag,而不检查分支或提交哈希等。
- 奇怪的标签名称输入不会导致奇怪的行为:
- 以“-”开头的标签名不会被误认为是命令行选项
- 包含斜线或点的标签名称并不特殊
- 包含空格的标签名称并不特殊
- 空白标签名称并不特殊
回答by cad106uk
The solution I quite like which I think is using a more modern version of git (git version 2.7.4)
我非常喜欢的解决方案是使用更现代的 git 版本(git 版本 2.7.4)
#!/usr/bin/env bash
cd /to/repo/base;
tagName="Whatever";
if [[ `git tag -l $tagName` == $tagName ]]; then
echo "yes";
else
echo "no";
fi
回答by niceilm
Very Simple Version(use git ls-remote)
非常简单的版本(使用 git ls-remote)
TAG_NAME=
git ls-remote --exit-code --tags origin $TAG_NAME || echo 'not found'
回答by l3x
Assuming you're in the project root directory...
假设您在项目根目录中...
# Filename: check-for-tag
# Usage: check-for-tag <TAG_NAME>
# Example: check-for-tag ticket-123-fix-this-bug
TAG_NAME=
git ls-remote --tags 2>/dev/null | grep $TAG_NAME 1>/dev/null
if [ "$?" == 0 ]; then
echo "Git tag $TAG_NAME exists."
else
echo "Git tag $TAG_NAME does not exist."
fi
回答by doctorhino
I use this method to tell if a tag exists for the current revision, to avoid tagging twice.
我使用这种方法来判断当前版本是否存在标签,以避免标记两次。
git_rev_id=$(git -C $REPO_FOLDER rev-parse HEAD)
git_tags=$(git tag)
for git_tag in $git_tags; do
git_temp_tag=$(git cat-file tag $git_tag | grep $git_rev_id);
if [ -z "$git_temp_tag" ]
then
false; #do nothing
else
git_tag_exists=$git_tag
fi
done
if [ -z "$git_tag_exists" ]
then
echo "need to make a tag"
else
echo "Found tag: $git_tag_exits"
fi