2011-06-22 95 views
167

I git add --interactive。它現在是我日常工作流程的一部分。如何僅使用git分階段創建新文件?

問題似乎是,它不適用於未跟蹤的文件。我想要做的是跟蹤一個新文件,但只添加它的一部分,即這個新文件的某些部分尚未準備好上演。

例如,使用git add -i,我可以選擇修補程序選項,甚至可以編輯個別區塊,以便部署新代碼,從而使調試代碼註釋處於非持續狀態。我喜歡這樣工作,因爲它明確了我目前正在進行的大型補丁的哪些地方仍然需要工作。

不幸的是,我似乎無法對未跟蹤的文件做同樣的事情。要麼是整個文件,要麼沒有。我一直在使用的解決方法是暫存或甚至在空文件時提交一個新文件,然後以通常的方式暫存各個更改。但是這個解決方案感覺像一個骯髒的黑客,當我忘記,或改變主意時,它會產生比應該更多的麻煩。

所以問題是:如何僅階段的一部分新文件,以便這個新文件得到跟蹤,但留下整個或其內容的一部分未分離?

+22

哪個部分是'1'還是'0'? –

+5

@Ignacio:我認爲你不要使用Git登臺區域 – sehe

+7

...今晚艱難的人羣... –

回答

308

哇,所有那update-indexhash-object業務似乎過於複雜。這個怎麼樣,而不是:

git add -N new_file 
git add -i 

git help add

-N, --intent-to-add 
    Record only the fact that the path will be added later. An entry 
    for the path is placed in the index with no content. This is useful 
    for, among other things, showing the unstaged content of such files 
    with git diff and committing them with git commit -a. 
+7

++ 1!應有的信貸。我相信有點太多,我現在知道這些手冊頁......'' – sehe

+0

@sehe:好的呼籲添加手冊頁片斷,謝謝! –

+1

找到了。我應該更進一步滾動手冊頁。也許我應該返回Git Pro徽章。 – dave1010

6
git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile 
git add --interactive newfile 

簡單的演示:

mkdir /tmp/demo 
cd /tmp/demo 
git init . 

echo hello > newfile 
git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile 
  • 提示如果你確定了 '空' 的blob已經存在於你的git對象數據庫,你可以硬編碼的哈希e69de29bb2d1d6434b8b29ae775ad8c2e48c5391代替。我不建議這樣做that_
  • 提示如果您使用的是Windows,你大概可以只使用NUL:,而不是/dev/null。否則,使用類似echo -n '' | git hash-object --stdin -w

現在,該指數將包含newfile爲空的斑點,而斑點空已進入對象數據庫,如果不存在,就:

$ find .git/objects/ -type f 
.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 

$ git status 
# On branch master 
# 
# Initial commit 
# 
# Changes to be committed: 
# (use "git rm --cached <file>..." to unstage) 
# 
# new file: newfile 
# 
# Changed but not updated: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
# modified: newfile 
# 

$ git diff 
diff --git a/newfile b/newfile 
index e69de29..ce01362 100644 
--- a/newfile 
+++ b/newfile 
@@ -0,0 +1 @@ 
+hello 

這應該正是你想要的。我也可以推薦非常智能的索引管理vim fugitive插件(請參閱Better git add -p?

+1

這似乎工作得很好。我已經把它命名爲「stage-empty-file」,因爲它有點複雜。 – dave1010

+1

不錯+1。[6更多] –

+0

@ dave1010:很高興它幫助! _是的,我想添加一個別名,但我不知道你期望如何處理通配符或多個文件名參數。所以我選擇不要_ – sehe

2

編輯:這似乎不工作。我確定它是之前(在git 1.7.1上)。如果它不工作,我建議分期/dev/null作爲sehe以上建議:

git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile 

如果您使用的是Windows(不/dev/null),那麼你可以與路徑設置爲空文件替換它。

原來的答覆

你想

git add -p # (or --patch) 

這增加了未跟蹤文件給我。從手冊頁:

交互式選擇索引和工作樹之間 補丁 的帥哥,並將它們添加到索引。這給 用戶提供了一個機會,在將修改後的 內容添加到索引之前查看 差異。

這有效地運行添加 - 交互,但繞過最初的命令菜單,並直接跳轉到patch子命令 。詳情請參閱 「交互模式」。

+2

然而有趣的是,它不適合我(git 1.7.4); 'git add -p newfile'根本不起作用(nu效果)和'git add --interactive''[a] dd untracked'的效果是'git add newfile' has; **編輯**也使用git 1.7.5.3進行了檢查;沒有骰子 – sehe

+0

Windows的好提示,在我的答案中增加了提示。 Thx – sehe

4

最簡單的方式做到這一點(和一般恕我直言互動分期)是git gui。它與git捆綁在一起,應該可以在git支持的幾乎所有平臺上運行。

只需運行git gui即可打開一個gui,它允許登臺和暫停hunk以及單行跟蹤和未跟蹤的文件。

Git Gui screenshot

+0

這是一個創造性的答案,有時這非常非常有用。 –

+2

請注意,並非所有的git發行版都包含'git gui'。例如,在Debian中,它位於一個名爲「git-gui」的單獨包中。 – cristoper

+0

這個功能多年來一直在尋找(不夠困難),這是一個改變生活的人 – austinmarton