2016-05-04 77 views
0

我創建了一個新的功能分支並在那裏添加了一個文件。創建該分支後的每個提交都只針對該文件。
現在我想將這些提交移動到僅用於這個新文件的新存儲庫。
我該如何做到這一點?我試圖將舊的存儲庫作爲遠程分支添加到新的存儲庫並挑選所有提交,但我也從功能分支之前和其他文件中獲取舊的提交消息,並丟失了原始提交日期。git:複製/移動提交範圍到獨立的存儲庫

所以這正是我需要的:從一個回購

  • 複製/移動範圍提交到另一個
  • 只能從創建文件從今天開始該文件的提交(沒有其他參與之間的文件,但創建舊的特性分支
  • )之前保持原始作者和提交日期

什麼我也試過:

# git rebase --onto develop oldRepo/feature/issue#14 c7bc952 

其中c7bc952是當前的HEAD。

我得到了什麼:

First, rewinding head to replay your work on top of it... 

# git status 
HEAD detached from 4ae31a1 
nothing to commit, working directory clean 
+0

看起來像這裏的東西:http://stackoverflow.com/questions/7375528/how-to-extract-one-file-with-commit-history-from-a-git-repo-with-index-filter – kan

+0

嗯......看起來像unix外殼,但我在Windows上。 –

+0

「git bash」shell通常在Windows中可用dist – kan

回答

2

大手術這樣最好通過直接建造新的歷史做了。我喜歡做這樣的工作,在臨時克隆:

git clone -s . $TMPDIR/wip   # scratch clone 
cd !$ 

現在重寫所有歷史的,只包括提交影響該文件,並從這些提交只有文件:

git filter-branch --index-filter ' 
         git read-tree --empty 
         git reset $GIT_COMMIT -- that/file 
       ' \ 
     -- --all -- that/file 

如果您只需要一個分支,使用例如master而不是上面的--all

現在您可以將重寫的分支推送到您想要的任何地方。請記住,此回購協議中的「起源」是您從中克隆的回購協議。


作爲一個快速回顧:

  • 工作倉庫進來四個部分:對象分貝,裁判,指數,worktree。通常,HEAD ref標識產生當前索引和工作樹的提交; git commit將它用作新提交的第一個父代,git checkout將其切換到新分支,依此類推。

  • 該索引只是一個列表:路徑名,內容ID,關於機上操作的元數據。例如,Git狀態會檢查HEAD引用來查看路徑中提交的內容,查看您最後添加或檢出的內容的索引,以及查找任何未分離的又名未加入的又名未追蹤的未索引內容的工作樹。

  • 該refs只是拇指進入對象分貝。

所以,git read-tree就是加載從對象分貝指數(如果你問它的worktree)。這是你用git做的很多基本操作。


所以過濾分支(東東第一--後)調用您提供的一切過濾器REV-從中找到ARGS產生。在這裏,我提供--all -- that/file,因此rev-list提供了涉及that/file的所有提交。當您提供索引過濾器時,filter-branch從提交中加載索引,設置GIT_COMMIT,運行過濾器,並使用生成的索引狀態重寫提交。

這裏,git read-tree --empty; git reset $GIT_COMMIT -- that/file清空索引,然後僅從當前提交加載that/file條目。泡沫,沖洗,重複。

+0

它工作正常。我有一個粗略的想法,它是如何工作的,但有沒有解釋可用的工作原理?我試圖閱讀過濾器分支和讀取樹的文檔,但目前這對我來說太高了。但我想學習! –

0

我回答我的問題,因爲這是第一個解決方案,我發現,也許是對他人有所幫助:

git rebase hash_of_parent_of_first-commit hash_of_last_commit --onto develop --committer-date-is-author-date 

這種變基從我目前的特性分支的所有提交到我的空開發分支之前。

相關問題