使用 git 将一系列小的合并从 master 压缩到我的分支中,同时保留对 master 的引用?

2024-06-21

我有一个非常复杂的合并要做。部分问题在于我浪费了太多时间,因此要纳入我的分支的更改量是巨大的。

为了让事情变得更容易,我选择这样做git merge origin/master~20, then git merge origin/master~17, git merge origin/master~15等等,这样我就可以以零碎的方式解决冲突,而不必一次全部解决。

问题是这会导致我想摆脱的日志历史记录的污染。合并所有这些提交同时仍然保持结果提交指向我的分支和主分支的最佳方法是什么?

我通常使用挤压git reset --soft但这不会留下对 master 分支的引用。我也尝试过git rebase -i --preserve-merges但我得到了"Refusing to squash a merge"错误消息。

我应该如何进行?


让我这样描述你的情况:你有合并result你想要——源树——但不是history你希望这会导致这个结果。

As VonC已将其放在其他地方 https://stackoverflow.com/a/5203843/1256452,而你自己也尝试过,git reset --soft通常is答案。您进行软重置,然后进行新的提交。如果你能做一个merge在这一点上提交,它仍然是答案。

有三种简单的方法可以做到这一点,无需git rerere。一种是作弊,其中一种方法是“有记录的作弊”,因此可能是正确的方法。 (我最喜欢的方法是中间一种,因为它又短又甜,但它显然是作弊,所以有一天它可能会停止工作。)

方法 1:笨重,但使用所有常规工具(没有作弊)

请注意,此处的命令序列假设您位于存储库的顶层(特别是git rm and git checkout以下步骤参考.意为“一切”)。我也用$startpoint对于您想要合并之后的提交,以及$other引用另一个分支名称或提交 ID(您想要的那个)git merge).

  1. 保存最终结果的ID(我们想要tree,但是标准工具可以最简单地引用提交,这也可以正常工作):

    $ git tag temp-save-result
    

    (或者使用剪切和粘贴或引用日志来保存它;为了简单起见,我在这里显示了一个标签)。

  2. 重置。这也可能是--hard, 而不是--soft:

    $ git reset --hard $startpoint
    
  3. 运行合并,这将因冲突而失败。忽略冲突和删除整个索引和工作树。到目前为止,我们不希望有冲突的合并或任何临时结果,因为我们有proper其他地方的结果。

    $ git merge $other
    $ git rm -r .
    

    (如果您有一些自定义合并工具留下了粪便,您可能也想将它们从工作树中清除,尽管它们不会影响任何重要的事情:它们只会弄乱您的工作树)。

  4. 提取步骤 1 中保存的工作树,并提交结果:

    $ git checkout temp-save-result -- .
    $ git commit
    

这次提交结束了合并,其tree来自您在步骤 1 中保存的树。您现在可以删除该标签:

$ git tag -d temp-save-result

方法二:作弊

When git commit进行新的提交,如果满足以下条件,则进行合并提交.git/MERGE_HEAD存在。这MERGE_HEAD文件包含第二次提交的 ID,即other or remote or --theirs正在被合并。

因此,我们只需像往常一样进行软重置,然后添加合并 ID,然后提交。 (注意:我最近没有尝试过这个,Git 可能也想要.git/MERGE_MSG。做好需要调整作弊的准备,或者直接转向方法 3。)

$ git reset --soft $startpoint
$ git rev-parse $other > .git/MERGE_HEAD
$ git commit

第一个命令就是我们平常使用的git reset --soft步骤,第二步对 Git 撒谎说我们正在解决冲突的合并(并且索引已全部解决,因此我们必须完成该步骤),并且git commit现在提交合并。

方法 3:使用管道命令(“有记录的作弊”)

生成实际提交对象的命令 -git commit毫无疑问,曾经只是一个在接近尾声时运行的 shell 脚本——是git commit-tree。这个需要:

  • 包含所需树的树对象
  • 一条提交消息(它将从标准输入读取一条消息,但您可能应该使用-m or -F)
  • 新提交的父级 ID

它将新的提交对象写入存储库,并打印出该对象的哈希 ID。

We 已经有那个树!由于它是当前提交,因此它的 ID 是HEAD^{tree} (using gitrevisions syntax https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html)。我们也有两个家长 ID。我们所需要的只是消息:

$ tmp=$(git commit-tree -p $startpoint -p $other -m 'merge msg' HEAD^{tree})

一旦我们有了提交 ID,我们只需要git reset --hard我们当前的分支指向它:

$ git reset --hard $tmp

(当然,您可以使用以下命令将两者合并为一个大命令$(...)代替$tmp在第二个命令中,尽管这假设您git commit-tree命令将起作用:为了个人舒适度,最好执行两个步骤。您可以省略$tmp变量,以及相应的shell$(...)语法,如果您更喜欢的话,可以通过剪切和粘贴哈希 ID 来实现。而且,您可以放入一条俗气的临时提交消息,然后使用git commit --amend一旦你重置它:--amend选项也适用于合并提交。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 git 将一系列小的合并从 master 压缩到我的分支中,同时保留对 master 的引用? 的相关文章

  • 当你的项目有秘钥时,如何推送到 GitHub?

    我正在尝试将一个全新的空 Rail 3 0 4 项目推送到 GitHub 但刚刚意识到 cookie 会话存储有一个密钥 In config initializers secret token rb NewRuby192Rails304Pr
  • Git 将合并恢复到特定父级

    我有一个 git 存储库 但在恢复合并时遇到问题 当前哈希为 0ce2ca0b35f59af267241cf4d40d16a3e13ba6f3 它有两个父母 df1acf5f54426d30f12c6b4558c3dd922297aae3
  • 如果提交格式不正确,是否可以拒绝 Github 上的提交?

    正如中提到的this https stackoverflow com a 6742691 1501285答案 可以在 Github 提交中引用问题 是否可以拒绝它的提交not格式化成这样 Example fix gh 12 foo bar是
  • 如何让 Git diff 忽略版本号更改?

    有没有办法从 Git diff 中消除版本号变化噪音像这个 https github com keith Xcode app strings commit 9502c601cad31ef452c4cd6e8ece3982345fba1d 具
  • 从私有 GitHub 存储库迁移到公共和私有

    我使用 GitHub 上的私人存储库开发了一个客户项目 我们现在要做的就是开放其中的某一部分 并产生该项目的开源版本 我们的想法是 客户的版本将在此基础上构建 对开源版本所做的任何更改也应适用于私有版本 现在的问题是我不能将当前的 GitH
  • 如何将 HEAD 移回之前的位置? (分离头)和撤消提交

    在 Git 中 我试图做一个squash commit通过合并到另一个分支然后重置HEAD通过以下方式前往上一个地点 git reset origin master 但我需要走出这一步 如何将 HEAD 移回之前的位置 我有 SHA 1 片
  • 在大型团队中使用 git VS Mercurial 和 Xcode 进行 iOS 开发有何优缺点?

    我们希望在一个项目上一起工作 签出 签入文件 一些开发人员推荐 git 其他开发人员更喜欢 Mercurial 有没有人对这两者都有经验 并且能告诉我为什么我应该花时间在不与 Xcode 集成的 Mercurial 上 而不是只使用集成的
  • 比较 2 次提交

    我没有找到任何关于获取两个文件之间差异的文档 我使用下面的代码使用坚固的方式提交文件 repo Rugged Repository new reponame email protected cdn cgi l email protectio
  • 尽管存在但未找到 Git https:// 存储库

    我在 github 上有一个私人仓库 它的位置被改变了 我尝试更换遥控器 但无法再按了 ls remote https github com xxxxx xxxxx git 给了我这个 远程 未找到存储库 致命 存储库 https gith
  • PHP 中的文本版本控制,具有差异突出显示

    如果您曾经在 StackOverflow 上编辑过问题 您可能已经注意到它会跟踪问题所应用的确切更改 它以一种形式显示 突出显示文本中已删除的红色部分和自特定编辑以来添加的绿色部分 我的问题是如何自己实现这样一个系统 我正在尝试使用 PHP
  • Visual Studio 代码中的“Git:gpg 未能签署数据”

    全新安装 Linux 后 我尝试设置我的环境 并且不断收到Git gpg failed to sign the data在本地提交更改时出错 我使用的是 Visual Studio Code 专有版本 而不是开源版本 gitconfig u
  • 致命错误:找不到“Fabric/Fabric.h”文件

    我正在使用 xcode 6 3 1 OSX 10 10 3 并且我已经在本地系统上成功配置了 crashlytics 它工作正常 并通过 Fabric 应用程序发布构建 但是当我将相同的代码库转移到 teamcity 时 它向我显示以下错误
  • 如何找出在哪个提交中添加了特定代码?

    我想知道我在哪个提交中添加了下面给出的代码 if getListView getChildCount 0 getActivity findViewById android R id empty setVisibility View VISI
  • github 网络图查看器的替代品? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 当我单击 github 上的 forks 按钮时 我想获得一个摘要 这就是我使用网络图查看器获得的结果 但它并不完全理想 我会做什么ide
  • Git 粒度——解决一行内的差异

    git 基于行的粒度或 diff 粒度是否可以增加到单词 字母分辨率 每行多条语句或使用 git 编写纯文本是值得的 根据评论重新阅读问题时 我想我明白了您最初的意思 所以我将给出一个真正的答案 与伊斯梅尔 巴达维的一行评论 https s
  • 有没有办法显示 Visual Studio 执行的 Git 命令? [复制]

    这个问题在这里已经有答案了 在 Visual Studio Code 中 有一个 显示 Git 输出 菜单项 显示最近运行的 Git 命令 有关其外观的示例 请参阅3 35 在这个视频中 https code visualstudio co
  • AngularJs:显示来自 git 或 Bower 的版本号

    我创建了一个 Angular 应用程序 我想在屏幕上显示应用程序的当前版本号 目前我已将其实现为常量 application constant constants VERSION 1 1 2 但这需要我在每个新版本上更新常量 我使用 Bow
  • 获得干净的 git 沙箱的最有效方法是什么?

    对于我的持续集成构建 我想确保我的 git 沙箱中没有存放任何杂散文件 并且没有任何文件被无意中更改 我知道关于git reset hard HEAD 这解决了部分问题 但我想我想做的是删除所有未跟踪和忽略的文件 我可以用蛮力的方式做到这一
  • 运行 npm install - 如何配置不使用 SSH(端口被防火墙阻止)

    当我跑步时npm install大多数模块配置正确 然而 至少有人想击中ssh 拉取模块的地址 不幸的是 我的公司有一项政策 不允许内部网络之外的 SSH 连接 我收到的具体错误是 Error while executing npm ERR
  • 如何快速查看哪个 Git 分支是最新的?

    例如 如果 git 上有 4 个分支 如下所示 branch1 branch2 current branch branch3 newest commits here master oldest 我的问题是 如何从 git 命令行检查我当前的

随机推荐