2013-07-18 50 views
2

我正在开发一个Git插件,我需要知道,当一个地方回购是改变(可提交更改),提前(可推送到远程)或后面(可以从远程拉)使用命令行。检查本地的git回购领先/落后远程

这是我到目前为止做:

  • 可以提交?

    如果git diff-index --name-only --ignore-submodules HEAD --回报的东西,然后 是的,有变化承诺。

  • 可以推?

    如果git status -sb包含单词在它前面的输出,那么是的,有 是提交推。

  • 可以拉?

    尚未实施。

可以提交?部分似乎正常工作。 可以推?只适用于主分支,这是一个巨大的问题。

如何安全地检查每个分支上的git repo是否有更改提交,承诺推送或需要git pull

+0

对于推动部,你将不得不使用Git 2.5+(Q2 2015)'混帐的for-each-REF --format =“%(push:track)”refs/heads'。看到更多[在我的答案](http://stackoverflow.com/a/30720302/6309)。 – VonC

回答

2

最后,我在我的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获取是否控制台输出的东西的一个字符串(电流的变化和头之间的差异,忽略子模块)
  • canPush获得原产地/ currentBranch和当地回购之间的变化计数 - 如果> 0,本地回购可以推
4

您可以使用git merge-basegit 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

感谢@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