2011-02-28 174 views
127

目標是獲得可以在shell命令中進行評估的明確狀態。如何檢查當前分支中是否沒有提交?

我試過git status但它總是返回0,即使有項目要提交。

git status 
echo $? #this is always 0 

我有一個想法,但我認爲這是一個壞主意。

if [ git status | grep -i -c "[a-z]"> 2 ]; 
then 
code for change... 
else 
    code for nothing change... 
fi 

還有其他方法嗎?


更新,現在這個解決看到了馬克Longair後

我嘗試這樣做,但是會導致出現問題。

if [ -z $(git status --porcelain) ]; 
then 
    echo "IT IS CLEAN" 
else 
    echo "PLEASE COMMIT YOUR CHANGE FIRST!!!" 
    echo git status 
fi 

它會得到一些錯誤,[:??:二進制運算符預期

現在,我在看的人,嘗試git的差異。

===================代碼爲我的希望,希望更好的回答================== ====

#if [ `git status | grep -i -c "$"` -lt 3 ]; 
# change to below code,although the above code is simple, but I think it is not strict logical 
if [ `git diff --cached --exit-code HEAD^ > /dev/null && (git ls-files --other --exclude-standard --directory | grep -c -v '/$')` ]; 
then 
     echo "PLEASE COMMIT YOUR CHANGE FIRST!!!" 
    exit 1 

else 
    exit 0 
fi 
+0

我已經更新了問題標題。讓我知道這是你的意思。 – 2011-02-28 07:47:38

+2

在更新的部分,似乎你實際上並沒有做[eckes](http://stackoverflow.com/users/520162/eckes)在[他的回答]中提出的建議(http://stackoverflow.com/questions/5139290/how-to-check-if-theres-nothing-to-commit-in-the-current-branch/5139346#5139346) - 正如他所說的,你需要在'$( git status --porcelain)'。另外,如果你想在你的消息中加上驚歎號,你需要使用單引號而不是雙引號 - 也就是說,它應該是'echo'請改變你的改變!''而不是 – 2011-02-28 10:13:25

+2

,因爲Mark說:* *您需要在'$(git status --porcelain)'**周圍加雙引號,就像我告訴過你的! – eckes 2011-02-28 10:28:19

回答

159

測試git status --porcelain的輸出是否爲空的替代方法是單獨測試您關心的每個條件。例如,如果在git status的輸出中存在未跟蹤的文件,則可能不總是在意。

例如,要看看是否有任何地方不分階段的變化,你可以看看的返回代碼:

git diff --exit-code 

要檢查是否有正在上演,但沒有犯下任何的變化,您可以使用返回代碼:

git diff --cached --exit-code 

最後,如果你想了解是否有你的工作樹中的任何未跟蹤文件沒有被忽略,你可以測試以下命令的輸出是否爲空:

git ls-files --other --exclude-standard --directory 

更新:您在下面問您是否可以更改該命令以排除輸出中的目錄。您可以通過添加--no-empty-directory排除空目錄,但排除該輸出的所有目錄,我認爲你必須過濾輸出,如用:

git ls-files --other --exclude-standard --directory | egrep -v '/$' 

-vegrep表示只輸出線,唐與模式不匹配,並且模式匹配任何以/結尾的行。

+0

我傾聽了這些提示並遇到了問題。也就是說,使用git ls-files --other --exclude-standard --directory獲取包含目錄的列表。有沒有排除這些目錄? – 9nix00 2011-02-28 10:26:20

+0

@ 9nix00:我已經更新了我的答案,以解釋如何做到這一點 – 2011-02-28 11:34:45

+0

是的,這是我想要的。我更新我的帖子以獲得新的腳本代碼。我認爲你的建議是更嚴格的邏輯,儘管更多的代碼大聲笑......並希望更好的答案出現。 – 9nix00 2011-03-01 06:42:04

83

git status返回值只是告訴你的git status退出代碼,而不是是否有被提交任何修改。

如果你想git status輸出的多個計算機可讀的版本,嘗試

git status --porcelain 

git status說明,瞭解有關詳情。

使用示例(腳本只是簡單地測試,如果git status --porcelain提供任何輸出,無需要解析):

if [ -n "$(git status --porcelain)" ]; then 
    echo "there are changes"; 
else 
    echo "no changes"; 
fi 

請注意,您必須引用字符串進行測試,即git status --porcelain輸出。有關測試結構的更多提示,請參閱Advanced Bash Scripting Guide(部分字符串比較)。

+0

嗨,你給出了一個很好的建議,我試過了,但是在腳本中,它導致了一些問題,我改進了它,如果我們使用這個if [-z $(git status --porcelain)];它會得到一些錯誤,[:??:二元運算符預計 我找到手冊,並使用這個如果[-z $(git status --short)];這可以工作,謝謝! – 9nix00 2011-02-28 07:52:07

+0

@ 9nix00:參見編輯的文章。 – eckes 2011-02-28 07:55:08

+0

對不起,仍然有問題。當提交是乾淨的。使用瓷器和短兩者都可以。但是當提交不乾淨。它會導致錯誤。 [:??:二元運算符預期。我想也許我們應該嘗試使用base64來編碼它。讓我嘗試!下載base64命令工具....大聲笑 – 9nix00 2011-02-28 07:57:45

0

不漂亮,但工程:

git status | grep -qF 'working directory clean' || echo "DIRTY" 

不知道消息是否依賴於語言環境,所以也許把LANG=C在前面。

5

從git源代碼有一個sh腳本,其中包括以下內容。

require_clean_work_tree() { 
    git rev-parse --verify HEAD >/dev/null || exit 1 
    git update-index -q --ignore-submodules --refresh 
    err=0 

    if ! git diff-files --quiet --ignore-submodules 
    then 
     echo >&2 "Cannot $1: You have unstaged changes." 
     err=1 
    fi 

    if ! git diff-index --cached --quiet --ignore-submodules HEAD -- 
    then 
     if [ $err = 0 ] 
     then 
      echo >&2 "Cannot $1: Your index contains uncommitted changes." 
     else 
      echo >&2 "Additionally, your index contains uncommitted changes." 
     fi 
     err=1 
    fi 

    if [ $err = 1 ] 
    then 
     test -n "$2" && echo >&2 "$2" 
     exit 1 
    fi 
} 

這sniplet顯示瞭如何其可能使用git diff-filesgit diff-index,以找出是否有先前已知的文件進行任何更改。但是,它不允許您查明是否有新的未知文件已添加到工作樹中。

+0

這工作正常,除了新文件。我們可以添加這個。 if! git ls-files --other --exclude-standard --directory | grep -c -v'/ $' then exit 0 else echo「請提交您的新文件,如果您不想添加它,請將其添加到git-ignore文件中。 exit 1 fi – 9nix00 2011-03-01 08:43:50

+0

只要'[如果[-n] $(git ls-files --other --exclude-standard)「]''沒有任何額外的管道或greping應該足以檢測未跟蹤的文件。 – Arrowmaster 2011-03-01 09:10:08

21

如果你像我一樣,你要知道,如果有:

1)改變現有的文件 2)新添加的文件 3)刪除的文件

特別不想知道約4)未追蹤的文件。

這應做到:

git status --untracked-files=no --porcelain 

這裏是我的bash代碼退出腳本,如果回購是乾淨的。它使用未跟蹤文件選項的短版:

[[ -z $(git status -uno --porcelain) ]] && echo "this branch is clean, no need to push..." && kill -SIGINT $$; 
+2

+1爲'-untracked-files = no';我認爲你的測試可以簡化爲'[[-z $(git status --untracked-files = no --porcelain)]]]。 'git status'不應該寫入stderr,除非出現一些基本錯誤 - 然後你希望看到那個輸出。 (如果在這種情況下需要更強大的行爲,請將'|| echo no'追加到命令替換中,以便乾淨度測試仍然失敗)。字符串比較/'-z'運算符可以處理多行字符串 - 不需要'tail'。 – mklement0 2014-10-20 04:55:53

+1

感謝@ mklement0,甚至更短一點:'[[-z $(git status -u no --porcelain)]]' – moodboom 2014-10-21 01:03:46

+1

更正:我的較短版本實際上只檢查名爲「no」的文件狀態! Bzzt。應該是: '[[-z $(git status -uno --porcelain)]]' – moodboom 2015-03-05 22:22:49

6

這是可能的git status --porcelain用一個簡單的grep組合進行測試。

if git status --porcelain | grep .; then 
    echo Repo is dirty 
else 
    echo Repo is clean 
fi 

我用這個作爲一個簡單的,有時一行代碼:

# pull from origin if our repo is clean 
git status --porcelain | grep . || git pull origin master 

添加-qs到您的grep命令,使其沉默。

+0

+1優雅;輕微的警告:如果'git status'失敗(例如,損壞的回購),您的測試將錯誤地報告_clean_工作區。一種選擇是使用'git status --porcelain 2>&1',但是如果您使用'-q'使用grep,則會'吃'錯誤消息。 (處理這將失去優雅:'(git status --porcelain || echo err)| grep -q .') – mklement0 2014-10-20 05:16:51

+0

或者,可以寫:'test -z「$(git status --porcelain)」| | git pull origin master' – VasyaNovikov 2018-01-17 14:09:39

2

我會做一個測試這個:

git diff --quiet --cached 

或這是明確的:

git diff --quiet --exit-code --cached 

其中:

--exit碼

用類似於diff(1)的代碼退出程序。也就是說,如果存在差異,則1退出,0表示沒有差異。

--quiet

禁用程序的所有輸出。意味着--exit碼

1

我在腳本中使用這個有:

  • 0時,一切都乾淨
  • 1時,有一個差異或未經跟蹤文件

    [ -z「$(git status --porcelain)」]

相關問題