2014-09-29 81 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?)

相关问题