bash 检查本地 git repo 是否在远程之前/之后
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17719829/
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
Check if local git repo is ahead/behind remote
提问by Vittorio Romeo
I'm developing a git plug-in, and I need to know when a local repo is changed(can commit changes), ahead(can push to remote) or behind(can pull from remote) using the command line.
我正在开发一个Git插件,我需要知道,当一个本地回购被改变(可提交更改),未来(可推送到远程)或后面使用命令行(可以从远程拉)。
This is what I am doing so far:
这是我目前正在做的事情:
Can commit?
If
git diff-index --name-only --ignore-submodules HEAD --returns something, then yes, there are changes to commit.Can push?
If
git status -sbcontains the word aheadin it's output, then yes, there are commits to push.Can pull?
Nothing implemented yet.
可以答应吗?
如果
git diff-index --name-only --ignore-submodules HEAD --返回某些内容,那么是的,需要提交更改。可以推吗?
如果在它的输出中
git status -sb包含前面的单词,那么是的,有提交要推送。可以拉吗?
尚未实施。
The can commit?part seems to work properly. Can push?only works for the master branch, and this is a huge problem.
在可以提交?部分似乎工作正常。可以推吗?仅适用于 master 分支,这是一个大问题。
How can I safely check if, on every branch, a git repo has changes to commit, commits to push, or needs a git pull?
如何安全地检查 git repo 在每个分支上是否有更改要提交、提交要推送或需要一个git pull?
采纳答案by Vittorio Romeo
In the end, I implemented this in my C++11 git-ws plugin.
最后,我在我的 C++11 git-ws 插件中实现了这个。
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;
Seems to work so far. canPullstill needs to be tested and implemented.
到目前为止似乎工作。canPull仍然需要测试和实施。
Explanation:
解释:
currentBranchgets the console output, which is a string of the current branch namecanCommitgets whether the console outputs something (difference between current changes and HEAD, ignoring submodules)canPushgets the count of changes between origin/currentBranchand the local repo - if> 0, the local repo can be pushed
currentBranch获取控制台输出,这是当前分支名称的字符串canCommit获取控制台是否输出某些内容(当前更改和 HEAD 之间的差异,忽略子模块)canPush获取 origin/currentBranch和本地仓库之间变化的计数- 如果> 0,则可以推送本地仓库
回答by Trebor Rude
You can do this with a combination of git merge-baseand git rev-parse. If git merge-base <branch> <remote branch>returns the same as git rev-parse <remote branch>, then your local branch is ahead. If it returns the same as git rev-parse <branch>, then your local branch is behind. If merge-basereturns a different answer than either rev-parse, then the branches have diverged and you'll need to do a merge.
您可以组合做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,则分支已分叉,您需要进行合并。
It would be best to do a git fetchbefore checking the branches, though, otherwise your determination of whether or not you need to pull will be out of date. You'll also want to verify that each branch you check has a remote tracking branch. You can use git for-each-ref--format='%(upstream:short)' refs/heads/<branch>to do that. That command will return the remote tracking branch of <branch>or the empty string if it doesn't have one. Somewhere on SO there's a different version which will return an error if the branch doesn't haven't a remote tracking branch, which may be more useful for your purpose.
但是,最好git fetch在检查分支之前执行 a ,否则您对是否需要拉取的决定将过时。您还需要验证您检查的每个分支是否都有一个远程跟踪分支。你可以用它git for-each-ref--format='%(upstream:short)' refs/heads/<branch>来做到这一点。如果没有,该命令将返回远程跟踪分支<branch>或空字符串。在 SO 上的某个地方有一个不同的版本,如果分支没有远程跟踪分支,它将返回错误,这可能对您的目的更有用。
回答by Panch93
For future reference. As of Git v2.17.0
备查。从 Git v2.17.0 开始
git status -sb
contains the word behind. So that can be used directly to check for pulls.
包含后面的词。这样就可以直接使用它来检查拉动。
Note: Remember to run git fetchbefore running git status -sb
注意:运行git fetch前记得运行git status -sb
回答by Vittorio Romeo
Thanks to @Trebor I just threw together a simple fish function for the purpose:
感谢@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

