2014-09-29 79 views
11

許多衛星之前,我在我的git存儲庫中添加了一棵子樹。該子樹包含多個文件夾和文件。我添加了子樹,而不是創建子模塊(按照建議)。現在我意識到我只想要子樹中的其中一個文件,其餘的都不需要。更糟糕的是,當其他clone我的存儲庫中,他們得到的不是預期的 - 與子樹和我創建的其他代碼存在一些衝突。如何刪除以前添加的Git子樹及其歷史記錄

我能得到的文件/文件夾的騎

git rm subtree–folder1 subtree_folder2 subtree_files.* 
然而

,我還是留下了從樹一個漫長的提交歷史。

自從我最初添加子樹並且不能丟失我已生成的提交歷史記錄以來,我已經做了相當多的開發。

總之這是我想什麼:

  1. 刪除所有的子樹的文件/文件夾。
  2. 忘記所有子樹提交的歷史。
  3. 只留下我的代碼和我的歷史。

這可能嗎?

PS。一種可能的複雜情況是,我將我希望從子樹保留的單個頭文件移到我的代碼中的某個文件夾中。我希望這不會妨礙我忘記子樹歷史。

的嘗試

從遠程服務器重新檢出後,我有以下幾點:

$ ls 
.git    CMakeLists.txt Read.cpp   logging.conf 
.gitignore  ENDF6   TestData   src 
.sparse-checkout LICENCE   doc    test 
.travis.yml  README.md  include   tools 

.gitignore只有: 編譯/ 調試/

當我嘗試的命令建議我沒有得到非常滿意的答覆:

$ git filter-branch --index-filter 'git rm --cached -rf test tools src doc LICENCE README.md .travis.yml' HEAD 
Rewrite 2fec85e41e40ae18efd1b130f55b14166a422c7f (1/1701)fatal: pathspec 'test' did not match any files 
index filter failed: git rm --cached -rf test tools src doc LICENCE README.md .travis.yml 

我不確定它爲什麼說它在test出現問題時顯然存在。我很困惑。

+0

您是否嘗試過簡單地使用'git rm '來刪除子樹? – 2014-09-29 20:02:46

+0

@hunch_hunch我這樣做,以及這裏的命令:http://stackoverflow.com/questions/15890047/how-to-remove-history-of-deleted-git-subtree-folder但我仍然有所有的歷史子樹。幫幫我! – jlconlin 2014-09-29 20:31:14

+0

您可以通過rebase或filter-branch重寫您的資料庫歷史記錄嗎? – 2014-10-06 21:39:46

回答

15

您需要使用filter-branch和--prune-empty選項來刪除任何不再引入新變更的提交。

git filter-branch --index-filter 'git rm --cached --ignore-unmatch -rf dir1 dir2 dirN file1 file2 fileN' --prune-empty -f HEAD 

之後,如果要恢復,你將需要刪除所有原始裁判該過濾器分支節省磁盤空間,到期引用日誌,和垃圾回收。

+0

感謝您的幫助!這裏沒有顯示,但在我們的聊天@AndrewC提供了需要的答案。 – jlconlin 2014-10-07 22:09:09

+0

git log仍然顯示歷史記錄。也許我失去了一些東西... – 2016-08-11 03:20:35

+0

@SkylarSaveland查看[chat](http://chat.stackoverflow.com/rooms/62556/discussion-between-jeremy-and-andrew-c)jlconlin指的是,儘管它應該在這裏解決。毫米 – Llopis 2016-09-14 09:26:50

2

您可以使用git filter-branch將操作應用於您在分支中進行的所有提交。這包括在您重寫整個歷史記錄時從每次提交中刪除文件。一個很好的描述和說明可以在這裏找到:http://gitready.com/beginner/2009/03/06/ignoring-doesnt-remove-a-file.html。您可能會發現以下問題也很有用:Completely remove files from Git repo and remote on GitHub(這是我找到鏈接的地方)。您將使用此解決方案運行的實際命令將如git filter-branch --index-filter 'git rm --cached -rf subtree–folder1 subtree_folder2' HEAD

另一種方式,這可能是你所做的事情矯枉過正,櫻桃採摘。挑選櫻桃可以讓你用你喜歡的任何細節重寫你喜歡的任何歷史部分:http://git-scm.com/docs/git-cherry-pick。你會想這樣做git reset --hard <HASH of commit that introduced the subtree>,隨後是每個後續的一系列

git cherry-pick -n <following commit hashes> 
git reset 
git add -p 
git commit 

提交你做了。這將允許您從每次提交中刪除子樹。你可以參考partly cherry-picking a commit with git瞭解更多櫻桃採摘的信息。當您使用此版本刪除的時候,你會想刪除舊的提交是您的分支中不再:

git reflog expire --expire-unreachable=now --all 
git gc --prune=now 

引用的其他問題: How to move a branch backwards in git? Listing and deleting Git commits that are under no branch (dangling?)

相關問題