2012-07-03 18 views
9

我使用git checkout --<dir_name(or)file_name>來放棄特定目錄或文件中的所有更改。每當我這樣做時,GIT都會從存儲庫中檢出目錄(或)文件。- git checkout中的幹運行選項

有沒有一種方法,我可以告訴GIT?「不會覆蓋的變化,只是告訴我會發生什麼。

類似git clean -n(或)git clean --dry-run

UPDATE: 我執行之前,git checkout --src/,我想看看有哪些會被覆蓋的文件。我知道我們可以使用git status src/。但是,git checkout -n --src/不是很好嗎?對用戶沒有太多的命令更改。

+0

也許我很困惑,但你不只是要求你的工作樹和索引之間的差異?那些用'git diff'顯示。 –

+0

@TilmanVogel:如您所知,'git clean'命令將刪除未跟蹤的文件。但'git clean -n'不會刪除文件,它只是告訴文件將被刪除。我只是想知道,在git checkout命令中是否有這樣的選項。謝謝。 –

+0

好的,那麼看看'git help checkout'很容易回答爲「否」。我認爲原因是'git status'和'git diff'一起給出了所有相應的信息。我也喜歡'git citool'。當然,這個故事在使用'git checkout'時不同於索引。 –

回答

3

您可以運行

$ git checkout --patch -- <files> 

,它會要求每個差你是否要「退房」這種差別。如果你對每個提示都說不,那麼它就會保持不變。

+0

不錯。這幾乎是我想要的。謝謝。 –

+0

但我仍然覺得,如果'git checkout'具有'-n'選項,就像'git clean'一樣,這可能會很棒。給我們一個文件名列表,而不是內容。不管怎麼說,還是要謝謝你。 –

1

不知道,但作爲一個工作,你可不git stash -u然後git apply然後git checkout

如果你不滿意,你總是可以回到藏匿處。

5

Git checkout命令沒有dry-run(或類似)選項。但是,您可以使用Git的ls-files命令來查看其工作目錄中的文件從HEAD不同:

git ls-files -dm -- src/ 

這將列出已被刪除或修改的所有文件,將通常由checkout被覆蓋的文件。

另一種選擇是使用的Git diff命令:

git diff --name-only HEAD -- src/ 

此列出了從頭部不同,將在checkout替換所有文件。

如果是這種東西,會經常做,你可能希望創建一個alias

git config --global alias.lco "diff --name-only HEAD" 

然後你可以使用:

git lco -- src/ 
+0

謝謝丹。這非常有用。我做了upvote :-) –

0

如果你想避免交互(一拉「對每個提示說不」),使用git diff。如果您想要問題的確切答案,請使用git diff -R。如果您只需要文件名稱,請使用git diff --name-only

如果沒有-R標誌,git diff會以補丁格式報告您的工作樹和索引之間的所有差異,即您在發出git show <commit>時看到的格式。 -R反轉輸出,告訴你將會發生什麼變化被刪除,就好像刪除本身就是一個補丁。考慮一個例子:

git init /tmp/test && cd /tmp/test 
echo "old line">file 
git add . 
git commit -m "Initial commit" 
echo "new line">file 

現在發行git diff沒有任何標誌。你應該:

$ git diff 
diff --git a/file b/file 
index 0906fba..86ba82a 100644 
--- a/file 
+++ b/file 
@@ -1 +1 @@ 
-old line 
+new line 

坦率地說,我發現,輸出很容易解析我從來沒有使用-R標誌。如果您經常發出git diff命令(並且我發現它是我使用的最常用命令之一),則反向輸出可能不是必需的。儘管如此,對於這個答案的目的,嘗試:

$ git diff -R 
git diff -R 
diff --git b/file a/file 
index 86ba82a..0906fba 100644 
--- b/file 
+++ a/file 
@@ -1 +1 @@ 
-new line 
+old line 

這正是輸出描述你所追求的:「不覆蓋的變化,只是告訴我會發生什麼。」

默認情況下,該命令將使用索引來區分整個工作目錄。它會顯示每個修改文件中的差異。假設你只想看一個文件的效果。這很容易。只需使用你已經在使用相同的雙橫線命名:

git diff -- <file> 

你會發現git diff是在Git中最有用的,可擴展的命令之一,你可以用它做各種有益的東西。您可以使用它來比較兩個提交,兩個分支或兩個文件。我最近的「最喜歡的瘋狂Git操作」是管道git diffgit apply。前者產生可理解的補丁。後者適用於他們。當他們結合時重寫歷史的能力幾乎是無限的 - 本地當然,永遠不會重寫共享歷史。考慮另一個例子,在這一點上脫離主題,但嚴重娛樂(如果你是這樣的事情)。從我們的測試庫中,上面:

git add . 
git commit -m "Second commit" 
echo "even newer line">file 
git add . 
git commit -m "Third commit" 

你知道嗎?我不喜歡那第二個承諾。它的實現是錯誤的。它正在破壞測試。我不想分享它。不過,我確實想保留「第二次提交」提交消息,因爲這很難輸入。我可以用git rebase -i HEAD~2來重定義它,但是這涉及到打開編輯器,刪除提交,編輯另一個和(唉)複製/粘貼。什麼是開發者?這個怎麼樣:

git checkout ":/Initial" ;# get back to the first commit 
git diff HEAD ":/Third" | git apply ;# apply the diff between the first and third commit 
git add . ;# add the result 
git commit -C ":/Second" ;# with second commit's message 
git checkout -B master HEAD ;# and replace old 'master' 

結果和git rebase一樣。我只是設法避免交互式會話,我不必使用編輯器。這是否過分矯枉過正?可能吧,但它確實很有趣。此外,構建更復雜的用例很容易,特別是當您結合使用git diff,git applygit add -p時。

1

對於任何命令,您都希望使用幹運行選項,而不管假設「您不需要用於結帳的幹運行,因爲您可以通過其他方式獲取差異列表」。

您不想通過幹運行選項來獲取差異列表,您需要進行幹運行以驗證「按下輸入時會發生什麼情況?」。在你真正做到之前。它們是有區別的。您正在測試程序的實際/確切行爲,如果您所做的只是閱讀手冊,可能會有些不明確之處。

我有一個奇怪的項目,其中回購基於'/'。所以,有一個'/.git'目錄和'/.gitignore'和'/.gitmodules'文件。 /.gitignore和/。gitmodules文件在回購中被跟蹤,這是一個問題,因爲即使開發人員用戶有權編輯文件,他們仍然沒有權限刪除並重新創建文件,因爲不可以和可以',對'/'本身有寫權限。如果git編輯的文件就地沒有問題,但git刪除並替換,因爲用戶得到一個錯誤,git無法取消鏈接文件。在發展變化給我們回購的配置,以及一些方向爲開發的過程中遵循在未來可以解決這一問題,一路上我想知道會這個命令做到:

git checkout master -- /.git*

等可能的變化像

git checkout master -- '/.git*'

等,改變殼通配符和/或查看的git本身可能會將最終的文件規範值。如果我從shell中轉義'*',git會擴展一個'*',還是將它視爲文字?如果擴展它,它會包含'/.git/'目錄嗎?如果它擴展它,是否有一些我可以使用的正則表達式語法意味着'任何單一非空字符'就像一個'。'。在正則表達式或'?'在外殼上? etc等

我不想知道哪些文件是不同的,我想測試一下git的確切行爲,找到一個不尋常的命令或命令集的最佳/最簡單的版本。

爲此,您真的想要一個幹運行選項。我已經知道哪些文件是不同的。在這種情況下,MANY文件會有所不同,我不想要其中的任何文件。我只想要/.gitignore和/.gitmodules,而沒有別的。

在這種情況下,我知道我可以通過在命令行中明確指定它們來做到這一點。

git checkout master -- /.gitignore /.gitmodules

但我想看看是否有更短的通配語法,將自動獲得他們兩個,但理想情況下,不包括/.git目錄。理想的情況下,我想弄清楚我可以擺脫的最簡單的形式。我知道我可以使用shell來做一些特殊的擴展,但是如果像'/ git *'這樣的東西可以工作,我寧願使用'/ git {i,m} *'

這個特殊的任務很小,有幾個簡單的答案。請不要告訴我在沒有「git checkout --dry-run」的情況下解決這個問題的方法,或者告訴我做一個回購有多愚蠢,我也知道。我已經知道幾種方法來完成我的直接工作。那不是重點。它可能很容易涉及更多的文件或更復雜的匹配模式,以至於明確列出文件並不方便,或者它可能是一些完全不同類型的問題。

關鍵是,一般來說,適用於任何地方的任何命令,包括git checkout,總有一個用於測試程序本身行爲的幹運行選項。閱讀手冊或--help不能回答以空運回答的問題。