GIT:如何从初始提交中删除文件夹及其内容?

时间:2018-01-06 16:06:22

标签: git git-commit

如何从初始提交中删除文件夹及其内容?

我有一个初始提交有几个目录。然后很多基于它的提交。

示例:

Commit A, having the following directories & files:
A/aaa.txt
B/bbb.txt
C/ccc.txt

A - B - C - D - E - F

我想删除目录B& C从初始提交A. 然后      - 使用B / bbb.txt创建B1分支。      - 使用C / ccc.txt创建C1分支。

所以最后这棵树看起来像这样:

A(modified) - B1 - C1 - B - C - D - E - F

如何获得此结果?

谢谢!

EDIT1:我想仅从初始提交中删除目录。 因此,我认为它与其他问题不同,而不是重复。

3 个答案:

答案 0 :(得分:3)

您无法修改任何现有提交。这是一个基本的Git保证:任何内容一旦保存,将以永远的方式保存,保存时生成的哈希ID。

可以只是停止使用任何现有的提交,当然你总是可以进行新的提交。因此,您需要创建一个新提交,其几乎与提交A相同,但不完全完全相同:< / p>

  • 提取现有提交A;
  • 删除不需要的文件;
  • 并且最后,在大多数情况下创建一个新的根提交A'A的副本,除了这些文件现已消失的事实。

你现在有:

A--B--C--D--E--F   <-- old-master

A'   <-- new-master

当然,那不是完全你需要什么,因为你仍然需要其他提交。所以现在你必须将B复制到B'B与新B'之间的 - 或至少 - 差异是B'的父级是A',而不是A。现有B已将现有A作为其父级,并且无法更改任何现有提交

所以现在你解压缩B(如果这是你的目标的一部分,可能会再次删除那些相同的文件),然后创建其父级为B'的新提交A'

A--B--C--D--E--F   <-- old-master

A'-B'   <-- new-master

显然,你还没有完成。您现在必须将C复制到C',方法与将B复制到B'的方式相同,然后重复其余的提交。最终你结束了这个:

A--B--C--D--E--F   <-- old-master

A'-B'-C'-D'-E'-F'  <-- new-master

现在你可以使用新的提交链作为master并且你完成了(好吧,除了创建新的分支(必须单独完成) - 你把它们画成{{1附加到新分支中的最后一次提交,但我怀疑你并不是那么意思。)

有一个Git命令正是这样做的:Bgit filter-branch命令获取您在命令行上命名的分支,查找从这些名称可以访问的每个提交(因此git filter-branch然后F然后E然后...然后D),按顺序排列(A首先等),然后开始复制:

  • 提取原始提交;
  • 按照the documentation;
  • 中列出的顺序应用每个过滤器
  • 进行新的提交,其父级是在过滤过程中先前创建的父级(或者对于原始根,进行新的根提交)。

复制完所有指定的提交后,A会调整分支名称以指向最终复制的提交。

通常,要执行整个存储库,您可以使用git filter-branch复制所有提交并调整所有分支名称以及--all调整所有标签名称。您可以使用--tag-name-filter cat,因为它是最简单的:它允许您对普通文件使用普通文件系统操作,以操纵每个提交的内容。但到目前为止,它也是最慢的过滤器;因此,您可能需要进行试验,直到您可以使用最快的过滤器(--tree-filter进行文件删除。

(您仍然需要单独构建新分支,因为--index-filter仅更改任何现有分支名称,并构建旧到新提交哈希的映射它不同于BFG,它在某些方面设计得更好 - 在完成后删除这张地图,但出于特定目的,您不再需要它,您可以找到新的根提交。最好的方法是尝试克隆存储库,可能是git filter-branch克隆。)

答案 1 :(得分:1)

尝试使用interactive mode重新定位:

NSStackView

然后在第一次提交时使用编辑命令。

答案 2 :(得分:-1)

您无法从旧提交中删除目录。 如果您在最初之后提交了几个提交,我认为最好的办法是:

  • 为每个目录创建一个新分支
  • 处理其分支中的目录
  • 合并主分支上的更新

如果您在初始版本之后立即进行了提交,则可以执行git reset --soft转到初始提交并保留更改。