【问题标题】:Rebase a single Git commit对单个 Git 提交进行变基
【发布时间】:2013-01-31 21:41:22
【问题描述】:

有没有办法将单个提交从一个分支重新定位到另一个分支?

我有这个分支结构:

-- -- -- -- -- (Master)
            \
              -- -- -- -- -- XX (Feature-branch)

我想要做的就是将Feature-branch 的最后一次提交重新设置为master 并回滚Feature-branch 一次提交。

-- -- -- -- -- XX (Master)
            \
              -- -- -- -- -- (Feature-branch)

我该怎么做?

【问题讨论】:

  • 如果你可以重新设置任意数量的提交,那么你为什么要问关于重新设置单个提交?如果我可以在 SO 中提问,我会问变基(单个提交)和挑选樱桃有什么区别。
  • 因为我不知道樱桃采摘存在,我做了“关于分支的 Faff”、“获取修复不同分支的请求”、“修复它”、“提交到错误的分支”、“哦!”足够问这个问题很有用。

标签: git rebase


【解决方案1】:

你可以挑选 XX 来掌握。

git checkout master
git cherry-pick <commit ID of XX>

并使用 git reset 从功能分支中删除最后一次提交。

git checkout Feature-branch
git reset --hard HEAD^

【讨论】:

  • 一个专门称为“git rebase ...”的问题怎么能得到接受的答案,而不是包含一个完全不同的概念,有时本身被认为是不干净的樱桃挑选?
  • 不确定这是否相关,但我想重新设置的提交有一些文件被移动,cherry-pick 使它们看起来好像从旧位置删除并在新位置创建地点。我想 rebase 会解决这个问题,但现在我已经推到上游,所以我无法测试它。无论如何,如果您有类似的情况,请当心。
  • 注意:要将 Feature-branch 中的更改推送到原点,您需要 git push -f origin Feature-branch,因为您的 Feature-branch 现在被认为是 origin/Feature-branch 后面的 1 次提交。
  • 这个方案和the one by CharlesB有什么实际区别?
  • @Bondax:因为无论如何它们都不是完全不同的概念。它们密切相关,如果你知道变基,但从未听说过“樱桃采摘”这个词,那么很自然地会想出樱桃采摘的想法并将其描述为“变基一次提交”。跨度>
【解决方案2】:
git rebase --onto master branch~1 branch 

这表示“在 master 分支的尖端重新调整 last-before-branch 和分支之间的提交范围(即 XX 提交)”

在此操作之后branch 提示在提交XX 时被移动,所以你想将它设置回来

git checkout branch
git reset --hard branch@{1}^

上面写着“将分支提示重置为之前状态之前的提交”

所以樱桃采摘是一个更简单的解决方案...

【讨论】:

  • 这似乎对我不起作用,我在 XX 之前丢失了提交,并且分支通过一次提交重新设置为 master,但我之前从未使用过 --onto,所以我可能正在做某事错误的。顺便说一句,OP 说 rebase,但似乎他想做一个樱桃挑选。
  • 我的错误,rebase 确实移动了 master 上的分支,它必须重置
  • 这个方案和the one by tewe有什么实际区别?
  • @Lii 我唯一能看到的是它使用 3 个步骤而不是 4 个步骤
  • @Lii 这个更通用。我有一个分支,我想重新设置为 master,我只想重新设置除前 4 次提交之外的所有提交(我们称第 4 次提交为 X)。所以我只需要:git rebase --onto master X branch
【解决方案3】:

实际上做起来很简单。解决方案是进行交互式 rebase 并“删除”您不想包含在 rebase 中的所有提交。

git rebase -i &lt;target_branch&gt; 其中target_branch 是您要变基到的分支

然后你将编辑打开的文件和pick你想要的提交和drop(或简称d)你不想带来的所有提交。

【讨论】:

  • IMO 是一个更好的解决方案,它实际上解决了这个问题。
  • 考虑到它的通用性、直观性和简短性,这应该是公认的解决方案。
  • +1 git rebase -i 是我最喜欢的 Git 命令。它是如此灵活,同时又如此简单明了到底发生了什么。如果您学习了git rebase -i,则无需记住任何其他变基命令。
  • 假设我使用交互式 rebase 删除除了我最新的提交之外的所有提交。结果是否会是我本地分支的最新提交将出现在我重新定位的原始主分支上?如果是这样,如果我为我的分支提交合并请求,git 历史记录会显示“master.....my_branch's_last_commit”吗?
  • 很好的答案,这是一个通用的解决方案,因为它解决了在原始分支中保留任意数量的提交,而不仅仅是一个,就像樱桃选择一样。
【解决方案4】:

@Charles 的回复是正确的。无论如何,我最终使用了很多次,最重要的是在项目上重新设置特定配置

* a8f9182 (HEAD -> production) 生产配置 | * daa18b7 (pre) 预生产配置 |/ | * d365f5f (local) 本地配置 |/ * 27d2835 (dev) 将拯救世界的惊人新功能 * | 56d2467 (master) 钻孔最先进的项目 |/

我为它创建了一个新命令:

$ 猫 ~/bin/git-rebaseshot 提交=$1 DEST=${2:-HEAD} git rebase ${COMMIT}^ ${COMMIT} --onto $DEST

通常您希望自动完成该命令的分支名称,因此将其添加到此函数的源代码中(添加到 .bashrc 或 .profile):

_git_rebaseshot () { __gitcomp_nl "$(__git_refs)" }

git 自动完成会搜索它

你可以像这样使用这个命令:

# rebase config on prepro on actual HEAD
$ git rebaseshot prepro 
# rebase config on local onto dev
$ git rebaseshot local dev
# rebase production config on master
$ git rebaseshot pro master

当你正确地划分特征时,可能性是无穷无尽的。

* a8f9182 (HEAD -> postgres) BBDD 配置 * a8f9182(本地)本地配置 * a8f9182(调试)日志级别配置 * a8f9182(开发)新功能 |

我想这就是quilt人们喜欢做的事情。

不管你提供什么 sha/ref,这个命令都可以工作:

$ git rebaseshot <Feature branch> master
$ git rebaseshot <commit of XX> master

【讨论】:

  • // , 你能链接到任何我们可以看到它在行动的项目吗?
  • 就其性质而言,可用于 rebaseshot 的分支不会在本地 repo 之外提交。只需在 master 之上创建几个分支(日志级别、数据库连接、配置)并在它们之间使用命令。效果一目了然。
  • // ,我遇到了一些问题。我会再试一次。
猜你喜欢
  • 1970-01-01
  • 2015-08-19
  • 1970-01-01
  • 1970-01-01
  • 2020-11-03
  • 1970-01-01
  • 1970-01-01
  • 2010-12-19
  • 2014-08-28
相关资源
最近更新 更多