【问题标题】:Git: How can I put a commit between older commits without changing the files/folders of later commits?Git:如何在不更改以后提交的文件/文件夹的情况下在较旧的提交之间进行提交?
【发布时间】:2014-10-23 10:03:52
【问题描述】:

我有一个包含一系列提交的存储库。假设两个旧的提交是 A,紧随其后的是 C:

A--C

在提交 CI 中没有签入旧文件的新版本,但实际上全新的文件具有相同的名称。

这使得提交 C 的 diff 看起来很混乱 - 实际上这个 diff 没有意义,因为文件完全不同。

我想要的是在 A 和 C 之间添加一个提交(我们称之为 B):

A--B--C

在这个提交 B 中,我想删除我用 C 更改过的文件和文件夹。

我知道通过以下内容我可以在 A 和 C 之间添加一个新的提交:

git rebase --interactive A^

然后对提交 A 进行“编辑”

然后

git rm -rf file folder/
git commit -m "B" # New commit with name B

我现在如何获得与原始提交 C 之后相同的文件和文件夹,这意味着 之前 B 到位?

换句话说:我怎样才能再次获得 C,但没有我在 B 中所做的删除?

【问题讨论】:

  • 怎么样,更新到 A,提交 B,在 B 之上 rebase C?或者只是在 A 之上提交 B,与 C 合并,然后在合并之上提交一个新的变更集以删除不需要的部分?你真的需要改变历史吗?
  • 在 A 之上提交 B 之后,我尝试了 git rebase --onto HEAD A master。这会将 C 重新设置在 B 之上,但是,这(逻辑上)会产生一系列合并冲突。这是我想避免的情况......

标签: git commit rebase


【解决方案1】:

以下是我为解决问题而采取的步骤:

git checkout A
git rm -rf file folder/
# Create a new commit with name B on top of A:
git commit -m "B"
# On top of B create a new commit with what was C:
echo 'new C commit' | git commit-tree C^{tree} -p HEAD 

这将创建一个新的 C 提交并返回其 SHA 哈希。此时,如果您签出 original C 提交,则 new C 提交的签出将包含您将获得的内容。

git checkout new-C-commit # No, this did not happen with git commit-tree
git rebase --onto HEAD C master

这将重新设置分支(在我的情况下它是主分支),从第一个提交开始在新的 C 提交上的原始 C 提交之后。这将毫无问题地适用,因为两个提交都有效地创建了相同的文件和文件夹。

【讨论】:

  • 感谢 knittl 让我走上正轨!向他致敬!
【解决方案2】:

您可以为此使用git-commit-tree:

git checkout A
git rm -rf file folder/
git commit -m 'B'
echo 'new C commit' | git commit-tree C -p HEAD
# create a new branch/update branch with the commit id printed by commit-tree

这将:

  • 结帐 A(分离 HEAD)
  • 删除文件和文件夹,新建提交B
  • 使用与原始提交 C 相同的文件/状态集创建新提交
  • 然后您必须更新旧分支以指向新提交(当前仍然是分离的 HEAD)

另一种方法可能是使用移植物,然后使用过滤器分支使其永久化:

git checkout A
git rm -rf file folder/
git commit -m B
echo `git rev-parse C` `git rev-parse HEAD` >> .git/info/grafts
git filter-branch A^..C

【讨论】:

  • 我已经尝试过你提出的第一种方式。但是,git commit-tree C -p HEAD 不起作用。它给出:fatal: C is not a valid 'tree' object (事实上,我已经用相应提交的 commit-SHA 替换了您命令中的“C”,这个 SHA 也是错误输出中提到)。
  • @Christopher: 试试C^{tree}(将 C 替换为您的提交的哈希/分支名称)
  • 这看起来让我想到了解决方案。我会仔细检查,然后发布我必须做的步骤......
猜你喜欢
  • 2021-02-15
  • 2013-02-06
  • 2022-01-15
  • 2011-07-09
  • 2020-08-11
  • 2010-11-14
  • 1970-01-01
  • 2021-09-23
  • 2021-04-28
相关资源
最近更新 更多