【问题标题】:git overwrite branch but keep historygit覆盖分支但保留历史
【发布时间】:2020-05-20 13:33:16
【问题描述】:

我想用另一个(即 master)覆盖开发分支中的所有内容,但我不想错过 dev 分支上较旧的提交。

这就是我想要的:

我尝试了merge with ours strategydoing an hard reset,但开发分支不断丢失旧的提交。

我想要获得的是蓝色和红色之间差异为零的提交,以及在将蓝色与第一个黑色进行差异时丢弃的代码。


只是为了分享迄今为止尝试过的解决方案的概述。 通过这样做:

git checkout master
git merge -s ours dev
git checkout dev
git merge master

我得到了这个(开发者从主人那里得到了所有的历史)

这样做

git checkout dev
git reset --hard master

我得到了这个(如果我推动开发,我将失去所有的黑色提交):

如果我这样做:

git checkout dev
git merge $(git commit-tree -p dev -m "Align master > dev" master^{tree})

我得到了这个(几乎完美,但我很难回忆起我做到这一点的确切时刻):

【问题讨论】:

  • 只是好奇为什么以这种方式将过去的历史放在开发分支上?为什么不变基?
  • 他想保留旧的历史。 rebase 会丢弃它。
  • Rebase 在这个过程中产生了很多冲突(并且有很多提交,我有很多冲突。这根本不切实际)。我认为不会因为 dev 分支中所有内容的完全蒙眼覆盖而产生任何冲突。
  • 如果您使用我们的策略 (merge -s ours),则不会丢失任何历史记录和提交。但是,所有更改都将“丢失”(即被覆盖)。但这正是您要问的。另见:How do I 'overwrite', rather than 'merge', a branch on another branch in Git?
  • @knittl 我尝试了 -s ours 和 -X theirs 策略(分别在目标和源分支上签出),但之后我仍然在开发和掌握之间存在差异(即,我有一些从未部署的开发数据,我想重置,但由于合并是一个非破坏性过程,这些东西继续存在于开发中)。

标签: git


【解决方案1】:

可以这样:

git checkout -f develop # go to develop branch
git merge --no-commit master
git checkout master -- . # this checkouts code from master and doesn't switch branch
# you are still in merge process on branch develop
git commit

请注意,跟踪 -- . 会改变 git checkout 的行为。

【讨论】:

  • 非常适合保留旧提交,但运行 git diff dev..master 会给我非空结果。
  • 您是否在存储库的根目录中运行了此命令?这个. 表示当前目录。如果您在子目录中,则并非master 中的所有内容都将被结帐。
  • 是的,我确认我正在从基本文件夹运行 bash。尽管如此,差异还是给了我在“蓝色”提交中似乎根本没有改变的文件的结果。
  • 这很有趣,删除文件有问题。
  • 对不起,我不小心删除了之前关于文件删除的评论。我在说什么,第三条指令留下了文件删除,没有从 master 报告到开发。执行git rm $(git diff --name-only master -- .) 似乎可以解决问题。
【解决方案2】:

如果我正确理解您的需求,您想在dev 上进行新的提交,并且该提交使dev 的内容与master 完全相同。如果是这样,

git checkout dev
git merge $(git commit-tree -p dev -m "foo" master^{tree})

git commit-treemaster head 的树中创建一个提交,以便新的提交与master 具有相同的内容。该命令返回提交的哈希值,可以传递给git merge

-p dev 指定 dev head 作为新提交的父级。

-m "foo" 使用foo 作为新提交的消息。你可以直接使用foo,一个随机字符串,因为最后你可以使用git commit --amend来指定一个正式的消息。

master^{tree} 表示master 头部的树对象的哈希值。

在这种情况下git mergegit reset --hard 具有相同的效果。

【讨论】:

  • 嘿,这似乎行得通!谢谢!唯一的事情是,我得到的是一个新的开发提交,它等于 master(所以 diff 是预期的空)但是分支之间没有明确的链接(正如我在我的 gui 中看到的那样)。
猜你喜欢
  • 2015-04-17
  • 2019-07-28
  • 2014-06-29
  • 1970-01-01
  • 2015-07-24
  • 1970-01-01
  • 2011-04-22
  • 2021-09-03
  • 2017-12-08
相关资源
最近更新 更多