如何检查远程存储库是否已更改,是否需要进行拉取?
现在我使用这个简单的脚本:
git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1
但它相当重。
有没有更好的办法?理想的解决方案是检查所有远程分支,并返回已更改分支的名称以及每个分支中新提交的数量。
如何检查远程存储库是否已更改,是否需要进行拉取?
现在我使用这个简单的脚本:
git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1
但它相当重。
有没有更好的办法?理想的解决方案是检查所有远程分支,并返回已更改分支的名称以及每个分支中新提交的数量。
当前回答
我基于@jberger的评论来解决这个问题。
if git checkout master &&
git fetch origin master &&
[ `git rev-list HEAD...origin/master --count` != 0 ] &&
git merge origin/master
then
echo 'Updated!'
else
echo 'Not updated.'
fi
其他回答
命令
git ls-remote origin -h refs/heads/master
将列出远程上的当前头—您可以将其与以前的值进行比较,或者查看您的本地回购中是否有SHA。
下面是一个Bash一行代码,比较了当前分支的HEAD提交哈希和它的远程上游分支,不需要大量的git获取或git拉取——需要干运行操作:
[ $(git rev-parse HEAD) = $(git ls-remote $(git rev-parse --abbrev-ref @{u} | \
sed 's/\// /g') | cut -f1) ] && echo up to date || echo not up to date
以下是这条有点密集的线是如何被分解的:
Commands are grouped and nested using $(x) Bash command-substitution syntax. git rev-parse --abbrev-ref @{u} returns an abbreviated upstream ref (e.g. origin/master), which is then converted into space-separated fields by the piped sed command, e.g. origin master. This string is fed into git ls-remote which returns the head commit of the remote branch. This command will communicate with the remote repository. The piped cut command extracts just the first field (the commit hash), removing the tab-separated reference string. git rev-parse HEAD returns the local commit hash. The Bash syntax [ a = b ] && x || y completes the one-liner: this is a Bash string-comparison = within a test construct [ test ], followed by and-list and or-list constructs && true || false.
我建议你去看看脚本https://github.com/badele/gitcheck。我编写了这个脚本,用于一次性检查所有Git存储库,它显示了谁没有提交,谁没有推/拉。
下面是一个示例结果:
git ls-remote | cut -f1 | git cat-file --batch-check >&-
将列出所有在任何远程引用,不在你的回购。要捕捉你已经拥有的东西的远程引用更改(例如,重置到以前的提交)需要更多一点:
git pack-refs --all
mine=`mktemp`
sed '/^#/d;/^^/{G;s/.\(.*\)\n.* \(.*\)/\1 \2^{}/;};h' .git/packed-refs | sort -k2 >$mine
for r in `git remote`; do
echo Checking $r ...
git ls-remote $r | sort -k2 | diff -b - $mine | grep ^\<
done
使用简单的regexp:
str=$(git status)
if [[ $str =~ .*Your\ branch\ is\ behind.*by.*commits,\ and\ can\ be\ fast-forwarded ]]; then
echo `date "+%Y-%m-%d %H:%M:%S"` "Needs pull"
else
echo "Code is up to date"
fi