【问题标题】:Git - push just the last commitGit - 只推送最后一次提交
【发布时间】:2015-01-16 05:46:09
【问题描述】:

我有以下提交 A->B->C->D。如果我推动 D 的 SHA,我知道它也需要 A、B、C。

我的要求是一个 bash 脚本,它将最后一次提交变基并使其成为第一个,因此它不会有任何依赖关系。

所以,A->B->C->D 应该变成 D->A->B->C,这样我就可以在推送中使用 D 的 SHA。

我已经尝试过多次,但我无法在不破坏任何东西的情况下完成它。

您以前是否这样做过,或者您对如何在 bash 脚本中执行此操作以方便重复使用有任何想法?

【问题讨论】:

  • 如果你从 A 的父级创建一个新的分支 NewBranch,然后在其上挑选 D,然后挑选 A、B 和 C?粗略的你可以在最初的cherrypick之后推动。
  • 您是如何陷入想要反复执行此操作的情况的?如果提交 A、B、C 和 D 是真正独立的并且可以像那样移动,则应该将它们全部放在单独的分支上,并在完成后将它们合并。如果它们不是独立的,则无法保证此类操作不会出现需要手动解决的合并冲突。
  • 我正在使用子模块,并且我有一个脚本可以自动标记分支中的子模块并将其推送到特定的远程。问题是,在推送子模块后,我需要从父模块提交它并将其推送到原点。我想重新设置基准,因为用户可能有待推送的提交,并且不想推送所有内容,只推送子模块的“指针”。所以在我的情况下,D 应该独立于 A,B,C
  • 您可以为交互式 rebase 定义一个自定义 EDITOR 以使用它重新排序提交以实现此目的。
  • 是的,但这是用户应该尽可能简单地做的事情,因此在执行 bash 脚本以标记子模块并将其推送到原点之后,我还需要一种自动推送提交的方式父回购

标签: git commit rebase


【解决方案1】:

对此没有完全通用的解决方案,因为比较DC 将取决于C 中的内容,而这又取决于B 中的内容等等。作为一个愚蠢但简单的示例,假设 C-vs-D 包含此更改:

 The quick brown
-sheep
+foxes
 jump over the
 lazy dog.

但是,在A之前的版本中,这样写:

 The quick brown
 sheep
 jumps over the
 lazy dog.

正确的调整无疑是让D使用单数,即现在你想要的改变是用fox(单数)替换sheep

您将如何自动实现 sheep 的复数形式为 sheepfox 的复数形式为 foxes 并且动词编号(jumpsjump)必须与名词匹配的想法?

除此之外,一般来说,rebase 只是一系列精选操作。要在某个新的基础上重现A,然后是B,然后是C,然后是D 序列,您选择提交A(进行新的提交,A'),然后选择樱桃BA' 上创建一个 B',然后将 C 选择到 B' 上,依此类推。要更改顺序,您只需更改樱桃采摘操作的顺序即可。

每个提交都可以用分支或标签名称标记,所以如果你有这个:

... - A - B - C - D   <-- yourbranch

我们希望这样做——让我们首先将... 序列的末尾标记为提交o 并将其命名为start

$ git branch start yourbranch~4

... - o                   <-- start
        \
          A - B - C - D   <-- yourbranch

现在我们将挑选D 到一个新分支tmp,我们从提交o 开始创建:

$ git checkout -b tmp start

... - o                   <-- start, tmp
        \
          A - B - C - D   <-- yourbranch

成功的cherry-pick会创建新的提交D':

$ git cherry-pick yourbranch

         D'               <-- tmp
        /
... - o                   <-- start
        \
          A - B - C - D   <-- yourbranch

现在让我们从AC 中挑选,但添加另一个分支标签tmp2

$ git checkout -b tmp2
$ git cherry-pick yourbranch~4..yourbranch~1   # pick A-C all at once

             A'- B'- C'   <-- tmp2
           /
         D'               <-- tmp
        /
... - o                   <-- start
        \
          A - B - C - D   <-- yourbranch

现在我们可以完全删除分支名称yourbranch,使它看起来好像提交AD 已经消失了(实际上它们并没有,因为git 默认保存30 天) , 完成后,我们可以重命名 tmp 和/或 tmp2

每次挑选樱桃都可能需要手动干预(手动修复单数与复数或其他),因此虽然您可以自动执行其中的一些操作,但您必须准备好应对失败。您必须反复执行此操作也很奇怪(如 cmets 中所述):这表明您的工作流程中有一些奇怪的地方。

【讨论】:

  • 非常感谢您花时间解释这一点,我会尝试这种方式,因为在我的情况下,D 不依赖于 A-B-C
  • 在您的情况下(移动子模块点),您可能可以使用变基脚本的技巧,将樱桃采摘到匿名头部,并在操作结束时移动分支名称。查看交互式 rebase 脚本的代码(它是一个 shell 脚本,在 git-core 目录中——该位置取决于您的系统——名为 git-rebase--interactive)。
猜你喜欢
  • 1970-01-01
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
  • 2017-04-03
  • 2021-08-12
  • 1970-01-01
  • 2021-06-24
  • 2020-01-20
相关资源
最近更新 更多