如果我的本地 Git 存储库发生更改,如何签入 Bash 脚本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5143795/
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
How can I check in a Bash script if my local Git repository has changes?
提问by kmindi
There are some scripts that do not work correctly if they check for changes.
如果检查更改,有些脚本将无法正常工作。
I tried it like this:
我是这样试的:
VN=$(git describe --abbrev=7 HEAD 2>/dev/null)
git update-index -q --refresh
CHANGED=$(git diff-index --name-only HEAD --)
if [ ! -z $CHANGED ];
then VN="$VN-mod"
fi
Is there some kind of boolean check if there has been changes since the last commit, or how can I really test if there are new changes to my local repository?
是否有某种布尔检查自上次提交以来是否有更改,或者我如何真正测试本地存储库是否有新更改?
I'm doing all this for a version creation script (that I found somewhere here).
我正在为版本创建脚本(我在此处找到的某个地方)执行所有这些操作。
回答by ryanmoon
Using git status
:
使用git status
:
cd /git/directory
if [[ `git status --porcelain` ]]; then
# Changes
else
# No changes
fi
回答by Cascabel
What you're doing will almost work: you should quote $CHANGED
in case it's empty, and -z
tests for empty, which means no changes. What you meant was:
你所做的几乎可以工作:你应该引用$CHANGED
以防它为空,并-z
测试为空,这意味着没有变化。你的意思是:
if [ -n "$CHANGED" ]; then
VN="$VN-mod"
fi
A quote from Git's GIT-VERSION-GEN
:
来自 Git 的引用GIT-VERSION-GEN
:
git update-index -q --refresh
test -z "$(git diff-index --name-only HEAD --)" ||
VN="$VN-dirty"
It looks like you were copying that, but you just forgot that detail of quoting.
看起来您正在复制它,但您只是忘记了引用的细节。
Of course, you could also just do this:
当然,你也可以这样做:
if git diff-index --quiet HEAD --; then
# No changes
else
# Changes
fi
Or if you only care about the "something has changed" case:
或者,如果您只关心“某些事情发生了变化”的情况:
if ! git diff-index --quiet HEAD --; then
VN="$VN-mod"
fi
Using --quiet
has the benefit that Git can stop processing as soon as it encounters a single diff, so it may not have to check your entire work tree.
使用--quiet
的好处是 Git 可以在遇到单个差异时立即停止处理,因此它可能不必检查整个工作树。
回答by Arrowmaster
Although Jefromi's answer is good, I'm posting this just for reference.
尽管 Jefromi 的回答很好,但我发布此内容仅供参考。
From the Git source code there is a sh
script which includes the following.
Git 源代码中有一个sh
脚本,其中包含以下内容。
require_clean_work_tree () {
git rev-parse --verify HEAD >/dev/null || exit 1
git update-index -q --ignore-submodules --refresh
err=0
if ! git diff-files --quiet --ignore-submodules
then
echo >&2 "Cannot : You have unstaged changes."
err=1
fi
if ! git diff-index --cached --quiet --ignore-submodules HEAD --
then
if [ $err = 0 ]
then
echo >&2 "Cannot : Your index contains uncommitted changes."
else
echo >&2 "Additionally, your index contains uncommitted changes."
fi
err=1
fi
if [ $err = 1 ]
then
test -n "" && echo >&2 ""
exit 1
fi
}
回答by Leon Waldman
I had a similar problem, but I had to check for added files also. So I did the following:
我有一个类似的问题,但我还必须检查添加的文件。所以我做了以下事情:
cd /local/repo
RUN=0
git diff --no-ext-diff --quiet --exit-code || RUN=1
if [ $RUN = 0 ]; then
RUN=`git ls-files --exclude-standard --others| wc -l`
fi
if [ $RUN = 0 ]; then
exit 0
fi
回答by AndrewD
git status
is your friend
git status
是你的朋友
Change to the Git directory for git status
to work:
切换到 Git 目录以git status
进行工作:
cd c:/path/to/.git
Set a variable to set the work tree so you don't get 'This operation must be run in a work tree' error:
设置一个变量来设置工作树,这样您就不会收到“必须在工作树中运行此操作”错误:
WORKTREE=c:/path/to/worktree
Capture the git status
output in a Bash variable
捕获git status
Bash 变量中的输出
Use --porcelain
which guarantees to be in a standard format and parsable:
使用--porcelain
which 保证采用标准格式并且可解析:
CHANGED=$(git --work-tree=${WORKTREE} status --porcelain)
If -n (not null), we have changes.
如果 -n (非空),我们有变化。
if [ -n "${CHANGED}" ]; then
echo 'changed';
else
echo 'not changed';
fi
回答by robertberrington
This works nicely. It will also list the files affected:
这很好用。它还将列出受影响的文件:
if git diff-index --name-status --exit-code HEAD;
then
echo Git working copy is clean...;
else
echo ;
echo ERROR: Git working copy is dirty!;
echo Commit your changes and try again.;
fi;
回答by Sean
Here is a nice set of Bash script functions that check if there is a diff, prints it to the user and prompts the user if they would like to commit changes before deployment. It is built for a Heroku and Python application, but it needs little change for any other application.
这是一组不错的 Bash 脚本函数,用于检查是否存在差异,将其打印给用户并提示用户是否希望在部署前提交更改。它是为 Heroku 和 Python 应用程序构建的,但对于任何其他应用程序几乎不需要更改。
commit(){
echo "Please enter a commit message..."
read msg
git add . --all
git commit -am $msg
}
check_commit(){
echo ========== CHECKING FOR CHANGES ========
changes=$(git diff)
if [ -n "$changes" ]; then
echo ""
echo "*** CHANGES FOUND ***"
echo "$changes"
echo ""
echo "You have uncomitted changes."
echo "Would you like to commit them (y/n)?"
read n
case $n in
"y") commit;;
"n") echo "Changes will not be included...";;
*) echo "invalid option";;
esac
else
echo "... No changes found"
fi
}
deploy(){
check_commit
echo ========== DEPLOYING TO HEROKU ========
git push heroku master
heroku run python manage.py syncdb
}
You can copy from Gists on: https://gist.github.com/sshadmand/f33afe7c9071bb725105
您可以从 Gists 复制:https://gist.github.com/sshadmand/f33afe7c9071bb725105
回答by Robert A
nano checker_git.sh
paste this
粘贴这个
#!/bin/bash
echo "First arg: "
cd
bob="Already up-to-date."
echo $bob
echo $(git pull) > s.txt
cat s.txt
if [ "$(cat s.txt)" == "$bob" ]
then
echo "up"
else
echo "not up"
fi
rm -rf st.txt
run sh checker_git.sh gitpath
跑 sh checker_git.sh gitpath
回答by Dennis
Based on @storm_m2138 comment to @RyanMoon's answer (link) I am using the following in Powershell
.
基于@storm_m2138 对@RyanMoon 的回答(链接)的评论,我在Powershell
.
function hasChanges($dir="."){ $null -ne (iex "git -C $dir status --porcelain --untracked-files=no") }
gci -Directory | ?{ hasChanges $_ } | %{ Write-Host "$_ has changes" }
gci -Directory | ?{ hasChanges $_ } | %{ iex "git -C $_ add -u"; iex "git -C $_ commit -m"Somemthing" }
回答by Seamus
The OP's question is more than 9 years old now. I don't know what man git-status
said then, but here's what it says now:
OP的问题现在已经超过9年了。我不知道当时man git-status
说了什么,但现在是这样说的:
--porcelain[=<version>]
Give the output in an easy-to-parse format for scripts. This is similar to the
short output, but will remain stable across Git versions and regardless of user
configuration. See below for details.
The version parameter is used to specify the format version. This is optional and
defaults to the original version v1 format.
This suggests that the --porcelain
argument is well-suited to testing the status of a repo for changes.
这表明该--porcelain
论点非常适合测试回购状态的变化。
Wrt the OP's question, "Is there some kind of boolean check if there has been changes since the last commit, or how can I really test if there are new changes to my local repository?"
写 OP 的问题,“是否有某种布尔检查自上次提交以来是否有更改,或者我如何真正测试本地存储库是否有新更改?”
I don't think that bash
has boolean data types per se, but this may be close enough:
我不认为它本身bash
具有布尔数据类型,但这可能足够接近:
[ -z "`git status --porcelain`" ] && echo "NULL-NO DIFFS" || echo "DIFFS EXIST"
This can be re-cast as a if-then-else
form for a script, or executed as-is fm the CLI while in the git repo folder. Otherwise, use the -C
option with a path spec to the repo of interest:
这可以重新转换if-then-else
为脚本的形式,或者在 git repo 文件夹中按 CLI 原样执行。否则,使用-C
带有路径规范的选项到感兴趣的存储库:
git -C ~/path/to/MyGitRepo status --porcelain