2009-08-15 43 views
64

是否有可能在git中切換到另一個分支而不檢出所有文件?切換分支後,我需要刪除所有文件,重新生成它們,提交併切換回來。因此檢出文件只是浪費時間(並且大約有14000個文件 - 這是一個長時間的操作)。開關git分支沒有文件簽出

,使一切清晰:

我需要這一切上傳到documentation GitHub上。

我有回購gh-pages分支。當我在本地重建文檔時,我將它複製到repo目錄,提交併推送到github。但我並不開心,因爲我在本地有兩份文件。我決定創建空的分支,並在提交後清空並刪除文件。但切換是一個漫長的操作 - 所以我問了這個問題。

我知道,我可以離開GH-頁面分支和刪除文件,但我不喜歡骯髒的工作樹)

+0

你需要多長時間?你在做什麼平臺?你是否在使用NFS或其他文件共享的網絡上工作? – 2009-08-15 21:56:38

+0

這個練習的目的是什麼?你想有兩個分支,一個有詳細的提交,第二個只記錄重大更改(粗粒度)? – 2009-08-16 08:55:43

+0

也許創建工作副本的臨時(或永久?)克隆會更便宜。 [我的相關答案](http://stackoverflow.com/a/29616287/946850)和[寫作](http://krlmlr.github.io/git-subbranch)顯示了這是如何工作的,甚至作爲一個子目錄主要存儲庫。 – krlmlr 2015-04-13 22:55:34

回答

70

是的,您可以這樣做。

git symbolic-ref HEAD refs/heads/otherbranch 

如果您需要提交這個分支,你要重新索引過,否則你最終會根據最後簽出分支犯下的東西。

git reset 
+0

使用'echo「ebff34ffb665de0694872dceabe0edeaf50ec5a9」> .git/HEAD'後面跟着'git reset'指向一個ref而不是一個分支。 – cadorn 2012-10-18 19:03:21

+1

直接寫入HEAD文件不太可靠。如果你在一個subdir中呢?對於分離的頭部(直接指向SHA1的頭部),試試這個:'git update-ref HEAD refs/heads/otherbranch' – 2013-01-23 20:25:53

+2

如果你想從當前分支簽出一個新的分支,另一種方法是到 #git stash# 2.'git checkout -b other branch' 3.'git stash pop' – Winny 2014-07-15 01:14:35

8

您可以覆蓋具有不同的分支名你的頭文件:

echo「ref:refs/heads/MyOtherBranch」> .git/HEAD

+13

使用symbolic-ref命令可能會更好:'git symbolic-ref HEAD refs/heads/MyOtherBranch' http://www.kernel.org/pub/software/scm/git/docs/git -symbolic-ref.html – 2009-08-15 21:44:39

+0

@GregHewgill,這是我知道將HEAD移動到提交哈希的唯一方式。你可以用'git symbolic-ref'來做到這一點嗎? – tomekwi 2016-02-11 06:47:00

7

我認爲你正在尋找管道命令git read-tree。這將更新索引,但不會更新工作目錄中的任何文件。例如,假設branch是讀取分支名稱:

git read-tree branch

如果你想,然後提交到分支你剛纔讀,你還需要:

git symbolic-ref HEAD refs/heads/branch
+0

不,我只需要切換分支,沒有任何其他變化 - 所以符號引用足夠好 – tig 2009-08-16 23:39:39

0

有這麼多文件,您可能最好只保留兩個回購站,每個分店一個回收站。您可以根據需要來回調整更改。這不會比試圖用git玩壞血腥的技巧更令人驚訝。

+0

你可以使用'git-new-worktree'來代替(在'contrib /') – 2009-08-16 08:49:31

+0

啊是的,對於每一個問題, git有一個新功能... – 2009-08-16 17:24:15

+0

我經常做一些類似的事情,在做任何「可怕的Git東西」作爲新手(如更改分支等)之前複製我的本地目錄。我鼓勵人們走這條路,直到你對自己的git-fu有信心,但在可能的情況下儘量遠離它。保持兩個不同的回購是好的,但增加了一層複雜性,並不會讓你利用git的許多有用的功能(合併,櫻桃採摘等)。 – David 2017-08-04 14:10:36

14

對於擁有兩個工作目錄(兩個工作區域)的存儲庫或甚至兩個存儲庫,這不是一個更好的解決方案嗎?

contrib/節中有git-new-workdir工具可幫助您解決此問題。

+0

+1我對此不知道,謝謝 – MBO 2010-09-14 08:10:23

+0

git-new-workdir與git自己的worktree命令相同嗎?當我想要將分支簽出到不同的文件夾中時(而不必克隆整個回購),我使用worktree。 – Ryuu 2017-04-12 12:53:47

+0

'git-new-worktree'腳本早於'git worktree'子命令;該命令在寫入答案時不可用。例如腳本需要符號鏈接支持;恕我直言,最好使用本機支持。 – 2017-04-12 23:27:04

0

如果您只是試圖改變遠程分支所指向的位置,您可以使用「git push」來完成,而無需觸摸本地副本。

http://kernel.org/pub/software/scm/git/docs/git-push.html

一個<的Refspec的格式>參數是可選的加+,接着是源REF <來源>,後跟一個冒號:,接着目的地REF < DST>。它用於指定< src>對象在遠程存儲庫中的< dst> ref是否要更新。

例如,更新FOO提交c5f7eba做到以下幾點:

git push origin c5f7eba:foo 

不知道,如果這是你所追求與否。

+0

這個問題已經得到了答案:http://stackoverflow.com/questions/1282639/switch-git-branch-without-files-checkout/1282706#1282706 – tig 2010-02-04 16:21:05

24

使用Git的基本命令只:

這個答案是比查爾斯長了一點,但它僅由這我能理解,因此記住基本的Git命令,無需繼續尋找它向上。

標記您的當前位置(如果需要的話第一次提交):

git checkout -b temp 

復位(移動)標記的其他分支,而不改變工作目錄:

git reset <branch where you want to go> 

現在溫度和其他分支點到同一個提交,你的工作目錄是不變的。

git checkout <branch where you want to go> 

,因爲你的腦袋已經指向相同的提交,工作目錄沒有被觸及

git branch -d temp 

注意,這些命令也容易從任何圖形客戶端。

+3

我寧願'git reset --soft <分支你想要的地方去'避免更新索引 – JoelFan 2015-11-23 15:29:50

+6

我同意你的避免git plumbing命令和偏愛瓷器的策略。 – user64141 2016-10-14 17:13:57

0

,您可以利用

 1. git checkout -f <new-branch> 
     2. git cherry-pick -x <previous-branch-commit-id> 

以前的分支提交-ID的是要複製舊的數據提交。

3

爲了讀者的利益:

雖然我認爲Charles Bailey's solution是正確的,切換到的東西,這不是一個地方分支時,這種解決方案需要一個調整。還應該有一些方法如何使用易於理解的常規命令來完成。以下是我想出了:

git checkout --detach 
git reset --soft commitish 
git checkout commitish 

解釋:

  • git checkout --detach相同git checkout HEAD^{}其背後離開當前分支並進入「分離的頭狀態」。所以HEAD的下一個修改不再影響任何分支。分離HEAD不會影響工作樹和索引。
  • git reset --soft commitish然後將HEAD移動到給定的commitish的SHA。如果您還想更新索引,請將--soft離開,但我不建議這樣做。這又一次沒有觸及工作樹,並且(--soft)不是索引。
  • git checkout commitish然後再將HEAD附加到給定的commitish(分支)。 (如果commitish是SHA沒有任何事情發生。)這也不會影響索引或工作樹。

該解決方案接受引用提交的所有內容,因此這對於某些git別名來說是理想的。下面的rev-parse只是一個測試,以確保鏈中沒有任何中斷,這樣錯別字不會意外切換到分離頭部狀態(錯誤恢復會更復雜)。

這導致以下git switch treeish別名:

git config --global alias.switch '!f() { git rev-parse --verify "$*" && git checkout "HEAD^{}" && git reset --soft "$*" && git checkout "$*"; }; f' 

僅供參考,你可以在我的git aliases列表中找到它。

+0

有趣的方法。 +1 – VonC 2017-07-12 14:15:48

+0

非常有用。謝謝! – 2018-03-01 23:11:53