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

13 浏览
0 Comments

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

很久以前,我在我的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只包含:

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

我不确定为什么它说它在test上有问题,当它显然存在。我感到困惑。

0
0 Comments

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

在使用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

之后,如果你想要回收磁盘空间,你需要删除filter branch保存的所有原始引用,过期reflog,并进行垃圾回收。

感谢你的帮助!虽然这里没有显示,但在我们的聊天中提供了所需的答案。可以在这里看到jlconlin所指的聊天记录,尽管应该在这里提供解决方案。

这是正确的答案吗:git filter-branch --index-filter 'git rm --cached --ignore-unmatch -rf dir1 dir2 dirN file1 file2 fileN' --prune-empty -f HEAD?如果不正确,请更新答案或进行评论。

如果你查看评论/聊天记录,你会看到它对OP起作用。尽管如此,filter-branch在最近已被'filter-repo'命令取代,所以如果你现在开始,你可能需要考虑使用它。

我推断你在一段时间前更新了聊天中的答案。太好了。现在是filter-repo了。

0
0 Comments

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

在Git中,您可以使用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

另一种可能对您正在进行的操作有些过度的方法是使用cherry-pick。Cherry-pick允许您根据需要以任何细节级别重写历史记录的任何部分:http://git-scm.com/docs/git-cherry-pick。您可以执行类似于以下操作:git reset --hard <引入子树的提交的哈希值>,然后进行一系列的操作:

git cherry-pick -n <后续提交的哈希值>
git reset
git add -p
git commit

对于您做出的每个后续提交,这将允许您从过去的每个提交中删除子树。您可以参考partly cherry-picking a commit with git获取有关有效cherry-picking的更多信息。完成此版本的删除后,您将希望删除不再属于您分支的旧提交:

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?)

0