如何删除以前添加的git子树及其历史记录

jlc*_*lin 15 git git-subtree

许多月前我在我的git存储库中添加了一个子树.该子树包含多个文件夹和文件.我添加了子树而不是创建子模块(如推荐的那样).现在我意识到我只想要子树中的一个文件,而不是其他文件.更糟糕的是,当其他人成为clone我的存储库时,他们得到的并不是预期的 - 与子树和我创建的其他代码存在一些冲突.

我可以随身携带文件/文件夹

git rm subtree–folder1 subtree_folder2 subtree_files.*
Run Code Online (Sandbox Code Playgroud)

但是,我仍然从子树中留下了冗长的提交历史.

自从我最初添加子树以来,我已经完成了相当多的开发,并且不会丢失我生成的提交历史记录.

总之,这就是我想要的:

  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
Run Code Online (Sandbox Code Playgroud)

哪里.gitignore只有:build/debug /

当我按照建议尝试命令时,我没有得到非常满意的回复:

$ 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
Run Code Online (Sandbox Code Playgroud)

我不确定为什么它test显然存在问题.我很困惑.

And*_*w C 19

您需要使用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
Run Code Online (Sandbox Code Playgroud)

之后,如果要恢复磁盘空间,则需要删除过滤分支保存的所有原始引用,使reflog过期,以及垃圾回收.


Mad*_*ist 5

您可以使用git filter-branch操作应用于您在分支中所做的所有提交。这包括在重写整个历史记录时从每次提交中删除文件。这里提供了很好的描述和说明:http://gitready.com/beginner/2009/03/06/ignoring-doesnt-remove-a-file.html。您可能会发现以下问题也很有用:从 Git 存储库和 GitHub 上远程完全删除文件(这是我找到链接的地方)。您将使用此解决方案运行的实际命令类似于git filter-branch --index-filter \'git rm --cached -rf subtree\xe2\x80\x93folder1 subtree_folder2\' HEAD

\n\n

另一种方法是精挑细选,这对于你正在做的事情来说可能有点过分了。精挑细选允许您以您喜欢的任何细节程度重写您的历史记录的任何部分:http://git-scm.com/docs/git-cherry-pick。你会想要做类似的事情git reset --hard <HASH of commit that introduced the subtree>,然后是一系列

\n\n
git cherry-pick -n <following commit hashes>\ngit reset\ngit add -p\ngit commit\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于您所做的每个后续提交。这将允许您从过去所做的每个提交中删除子树。您可以参考使用 git 部分挑选提交,以获取有关有效挑选的更多信息。完成此版本的删除后,您将需要删除不再属于分支的旧提交:

\n\n
git reflog expire --expire-unreachable=now --all\ngit gc --prune=now\n
Run Code Online (Sandbox Code Playgroud)\n\n

其他参考问题:\n如何在 git 中向后移动分支?\n列出并删除不在分支下的 Git 提交(悬空?)

\n