2013-07-18 52 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