我相信做你想做的事的最好方法是在機器特定的分支上進行提交,然後用git rebase移動它們。這與我自己的主目錄大致相同 - 與您的情況基本相同。
# make a new branch starting from branch machine_1
git checkout -b move_to_master
# make whatever commits you need to
git rebase --onto master machine_1 move_to_master
git checkout master
git merge move_to_master # this is a fast-forward
git checkout machine_1
git merge master
如果你不小心犯創建move_to_master之前machine_1,只需創建move_to_master,然後重新回到machine_1它所屬的地方,並按照剩下的步驟。
但是,您的問題值得回答,並且我已經在底部提供了幾個備選方案。
創建承諾不會在當前分支
注意事項:非常非常小心!這是可怕的東西!
它是可能提交到未使用管道命令檢出的分支,只是不是非常需要。你必須讓你的索引到你想要的狀態(這可能是棘手的),然後你可以使用git commit-tree:
git commit-tree -p $PARENT_COMMIT < $COMMIT_MESSAGE_FILE
這將打印到標準輸出新創建的commit對象的SHA1;假設PARENT_COMMIT
是一個分支的頂端,則必須使用git update-ref分支更新到它:
git update-ref -m "commit: [commit subject]" $BRANCH $NEW_SHA1
如果你這個腳本,你可以在一個班輪實現它爲git update-ref -m ... $(git commit tree ...)
。這是最可怕的一步。如果你更新你的其他分支到錯誤的地方,它有點糟糕。儘管如此,您仍然可以找出將其重新設置回git reflog show $BRANCH
的位置。
無論如何,這只是簡單的部分。真正困難的是在沒有真正檢出文件的情況下將索引變成你想要的狀態。公共命令的兩個您可以使用:
- git read-tree - 讀取樹信息進入指數,但不更新所有(GIT結賬工作樹大致相當於混帳讀取樹,git的結帳指數,和git update-ref HEAD)。你可以使用它來使索引包含未簽出分支的內容,而不是HEAD。
- git update-index - 修改索引。您可以使用它從工作樹中添加,刪除或刷新索引中的文件。
- git checkout-index - 將指定路徑從索引複製到工作樹中。在使用讀取樹之後,可以使用它來獲取要更改的單個文件,對其進行修改,然後使用update-index將其恢復。 「修改它」的步驟可能很複雜 - 例如,在完成所有這些之前,您可以使用git diff創建一個補丁,然後在此處應用git apply。
- git apply --cached使用--cached選項,可以將補丁直接應用於索引中的版本,而無需觸摸工作樹。因此,您可以創建一個diff,讀取其他分支的樹,將其應用於索引,commit-tree,然後設置。這可能是最令人敬畏的做法。
之所以這麼辛苦,是因爲所有的git命令讓你能夠訪問它的所有強大的合併功能,這都依賴於工作樹中的文件。當你考慮它時,你想要做的任務是合併 - 你在一個分支上有差異,並且你想在另一個分支上應用它。獲得結果的方法是使用原始分支上的差異,與其他分支共同的祖先以及另一分支的尖端進行三向合併。沒有其他分支簽出,你不能真正做到這一點合併!
像往常一樣,當用管道命令做事情時,你應該非常小心地理解一切是如何工作的,所以你不會毀掉你的倉庫。也就是說,在重構現有存儲庫(由其他人創建的存儲庫...不問)時,我實際上已經使用了這種方法。在這種情況下,我只重新安排提交 - 使用讀取樹而不是一般更新索引 - 因此它比您可能要做的要簡單得多。說了這麼多
替代方法
,還有你可能需要得到完成你想要什麼一對夫婦的其他方法。
克隆您的存儲庫。如果你只跟蹤配置文件,這不會佔用太多額外的空間,而且事情會變得更容易。如果你真的很迷戀,你甚至可以使用git new-workdir(鏈接到git.git HEAD版本)腳本來創建一個工作目錄,而不是重複其餘的repo(它使用.git目錄中的符號鏈接) 。只要記住要小心地將一個workdir提交給在另一箇中簽出的分支 - 另一個將以其工作樹不同步的方式結束。
寫一個提交包裝腳本 - 這是最接近使得單承諾的所有這些選項的另一個分支:
git commit
orig_branch=$(git symbolic-ref HEAD)
orig_branch=${orig_branch#refs/heads/}
git checkout master
git cherry-pick $orig_branch
git checkout $orig_branch
git reset --hard HEAD^
順便說一句,我同意其他問題沒有得到滿意的回答。你可能不應該承諾除HEAD以外的任何地方,但如果你決定真的想要,你可以做到。這個問題值得回答。 – Cascabel 2010-03-20 01:02:14
希望你仍然在看這個 - 我記得'git apply'的'--cached'選項。它使這更容易 - 看看我的答案。 – Cascabel 2010-03-21 01:16:42