我正在开发一个git插件,我需要知道本地仓库何时已更改(可以提交更改),提前(可以推送到远程) )或在后面(可以从远程拉出)使用命令行。
这就是我到目前为止所做的事情:
可以提交吗?
如果git diff-index --name-only --ignore-submodules HEAD --
返回某些内容,
然后是的,有提交的更改。
可以推送吗?
如果git status -sb
在其输出中包含提前这个词,那么是的,那里
承诺推动。
能拉吗?
尚未实施。
可以提交吗?部分似乎正常工作。 可以推送吗?仅适用于主分支,这是一个很大的问题。
如何安全地检查每个分支上的git repo是否有提交更改,提交推送或需要git pull
?
答案 0 :(得分:5)
您可以git merge-base
和git rev-parse
的组合执行此操作。如果git merge-base <branch> <remote branch>
返回与git rev-parse <remote branch>
相同的内容,那么您的本地分支就会领先。如果它返回与git rev-parse <branch>
相同,那么您的本地分支就落后了。如果merge-base
返回的答案与rev-parse
不同,则分支已经分歧,您需要进行合并。
最好在检查分支机构之前进行git fetch
,否则您对是否需要拉动的确定将会过时。您还需要验证您检查的每个分支都有远程跟踪分支。您可以使用git for-each-ref --format='%(upstream:short)' refs/heads/<branch>
来执行此操作。该命令将返回<branch>
的远程跟踪分支或空字符串(如果没有)。在SO的某个地方有一个不同的版本,如果分支没有远程跟踪分支,它将返回错误,这可能对您的目的更有用。
答案 1 :(得分:4)
最后,我在我的C ++ 11 git-ws plugin中实现了这一点。
string currentBranch = run("git rev-parse --abbrev-ref HEAD");
bool canCommit = run("git diff-index --name-only --ignore-submodules HEAD --").empty();
bool canPush = stoi(run("git rev-list HEAD...origin/" + currentBranch + " --ignore-submodules --count")[0]) > 0;
到目前为止似乎工作。 canPull
仍然需要进行测试和实施。
<强>解释强>
currentBranch
获取控制台输出,该输出是当前分支名称的字符串canCommit
获取控制台输出的内容(当前更改与HEAD之间的差异,忽略子模块)canPush
获取原点/ currentBranch
与本地仓库之间的更改计数 - 如果> 0
,则可以推送本地仓库答案 2 :(得分:1)
感谢@Trebor我刚刚为此目的汇总了一个简单的鱼功能:
#! /usr/bin/fish
#
# Echos (to stdout) whether your branch is up-to-date, behind, ahead or diverged from another branch.
# Don't forget to fetch before calling.
#
# @param branch
# @param otherbranch
#
# @echo string up-to-date/behind/ahead/diverged
#
# @example
#
# # if master is ahead of origin/master you can find out like this:
# #
# if test ( branch-status master origin/master ) = ahead
#
# echo "We should push"
#
# end
#
function branch-status
set -l a $argv[ 1 ]
set -l b $argv[ 2 ]
set -l base ( git merge-base $a $b )
set -l aref ( git rev-parse $a )
set -l bref ( git rev-parse $b )
if [ $aref = $bref ]; echo up-to-date
else if [ $aref = $base ]; echo behind
else if [ $bref = $base ]; echo ahead
else ; echo diverged
end
end
答案 3 :(得分:1)
供将来参考。截至Git v2.17.0
git status -sb
包含背后的单词。 这样可以直接用来检查拉力。
注意:请务必在运行git fetch
git status -sb
答案 4 :(得分:1)
我制作了@ user1115652答案的bash版本。
function branch_status() {
local a="master" b="origin/master"
local base=$( git merge-base $a $b )
local aref=$( git rev-parse $a )
local bref=$( git rev-parse $b )
if [[ $aref == "$bref" ]]; then
echo up-to-date
elif [[ $aref == "$base" ]]; then
echo behind
elif [[ $bref == "$base" ]]; then
echo ahead
else
echo diverged
fi
}
答案 5 :(得分:1)
来自this answer。
git fetch
。behind_count = $(git rev-list --count HEAD..@{u})
。ahead_count = $(git rev-list --count @{u}..HEAD)
。 (它假定您从哪里获取就是您推送到哪里,请参阅 push.default
配置选项)。behind_count
和 ahead_count
均为 0,则当前分支是最新的。behind_count
为 0 且 ahead_count
大于 0,则当前分支在前面。behind_count
大于 0 且 ahead_count
为 0,则当前分支落后。behind_count
和 ahead_count
都大于 0,则当前分支发散。说明:
git rev-list
列出所有提交范围的提交。 --count
选项输出将列出多少提交,并禁止所有其他输出。HEAD
命名当前分支。@{u}
指当前分支的本地上游(配置了 branch.<name>.remote
和 branch.<name>.merge
)。还有@{push}
,通常与@{u}
指向相同。<rev1>..<rev2>
指定提交范围,包括可从 访问但不包括可从 访问的提交。省略或省略时,默认为 HEAD。