如何将特定提交推送到远程,而不是之前的提交?

Rob*_*t23 789 git push commit

我已经对不同的文件做了几次提交,但到目前为止,我想将我的远程存储库推送到特定的提交.

那可能吗?

Geo*_*edy 1023

为了推动通过了一个指定的提交,你可以这样写:

git push <remotename> <commit SHA>:<remotebranchname>
Run Code Online (Sandbox Code Playgroud)

提供<remotebranchname>已存在于遥控器上.(如果没有,您可以使用git push <remotename> <commit SHA>:refs/heads/<remotebranchname>它来自动创建它.)

如果要在推送先前提交的情况下推送提交,则应首先使用git rebase -i重新排序提交.

  • `git push <remotename> <commit SHA>:<remotebranchname>`有效.诀窍是将它与`git rebase -i`结合起来,将你想要的提交作为第一次提交,并指定commit-sha (66认同)
  • 请记住,如果远程分支尚不存在,则会失败.可以使用`git push <remotename> <commit SHA>:refs/heads/<new remote branch name>`来创建分支.在此之后,按照答案描述推动. (30认同)
  • 另一个好的建议是确保你复制你想要推送_after_执行该rebase -i的提交的SHA,而不是之前,就像我刚才那样:) (29认同)
  • 例如,使用一些标准名称`git push origin HEAD~1:master`来推送除了最后一次提交之外的所有内容. (28认同)
  • 另请注意,如果您已经将稍后的SHA推送到该远程分支,那么您将需要强制推送这个.使用`-f`标志. (3认同)
  • 有趣的是,对于如此简单的事情,必须使用如此困难的命令。在 Mercurial 中,它只是 `hg push -r &lt;REV&gt;` (2认同)

Sam*_*uel 71

其他答案缺少重新排序的描述.

git push <remotename> <commit SHA>:<remotebranchname>
Run Code Online (Sandbox Code Playgroud)

将推送单个提交,但该提交必须是您的本地,非推送,提交的OLDEST,不要与top,first或tip提交混淆,在我看来这些都是模棱两可的描述.提交需要最早的提交,即距离您最近的提交最远的提交.如果它不是最早的提交,则将推送从最旧的,本地的,未推送的SHA到指定的SHA的所有提交.要重新排序提交使用:

git rebase -i HEAD~xxx
Run Code Online (Sandbox Code Playgroud)

重新排序提交后,您可以安全地将其推送到远程存储库.

总结一下,我用过

git rebase -i HEAD~<number of commits to SHA>
git push origin <post-rebase SHA>:master
Run Code Online (Sandbox Code Playgroud)

将单个提交推送到我的远程主分支.

参考文献:

  1. http://blog.dennisrobinson.name/push-only-one-commit-with-git/
  2. http://blog.dennisrobinson.name/reorder-commits-with-git/

也可以看看:

  1. git:在本地Rebase之后重复提交Pull
  2. git:推送单一提交,重新排序,重复提交

  • 似乎有些起源可能不允许这样.例如,使用GitLab,我看到"您不允许将代码强制推送到此项目的受保护分支." 这有点奇怪,因为我不认为我强迫任何东西,只是正常推动.知道如何在没有"强迫"的情况下做到这一点吗? (2认同)

Wal*_*ndt 25

我建议使用git rebase -i; 将您想要提交的提交移动到您所做的提交的顶部.然后使用git log获取重新提交的提交的SHA,检查它并推送它.rebase将确保您所有其他提交现在都是您推送的提交的子项,因此未来的推送也可以正常工作.

  • 假设您有3个相对独立的提交,其中包含按顺序提交的消息"A","B","C",并且您想要按"B".'git rebase -i'应该让你和编辑列出这三个; 移动B并保存/退出.'git log --pretty = oneline -n​​3'将列出B,A,C,每条消息前都有哈希值,B现在是最后一个.'git checkout -b temp $ hash_of_B; git push'应该在那时推B. 那么你可能想要'git checkout -b master; git branch -d temp'回到你以前的状态,假设你在你当地的主分支上; 替换适用的. (4认同)
  • 你能举一个完整的例子吗?重做`git log`步骤? (3认同)
  • +1 在 rebase-push-rebase 之后你有没有遇到过 [“git 众神的愤怒”](https://help.github.com/articles/interactive-rebase)?(也有可能是偶然发生的,对吧?) (2认同)
  • 如果你仔细阅读我的答案,你会看到推送只发生在*rebase之后*,并且重新提交的提交只会移动到尚未推送的其他提交之上.提交一旦提交,通常应该被认为是一成不变的; 在未来的变革中不要管它.这种技术只能让您在推送它们之前将多个本地更改整理成一个良好的顺序.如果您正确设置了跟踪,那么没有其他参数的'git rebase -i'将默认甚至不显示您推送提交,因此它比其他方法更安全. (2认同)

小智 21

在推送特定提交时,Cherry-pick与所有其他方法相比效果最佳.

这样做的方法是:

创建一个新的分支 -

git branch <new-branch>
Run Code Online (Sandbox Code Playgroud)

使用您的原始分支更新您的新分支 -

git fetch

git rebase
Run Code Online (Sandbox Code Playgroud)

这些操作将确保您完全拥有与原点相同的东西.

樱桃挑选sha id你想做的 -

git cherry-pick <sha id of the commit>
Run Code Online (Sandbox Code Playgroud)

你可以sha id通过跑步来获得

git log
Run Code Online (Sandbox Code Playgroud)

把它推到你的原点 -

git push
Run Code Online (Sandbox Code Playgroud)

运行gitk以查看所有内容都与您想要的一样.

  • 使用`git rebase -i`将是上述解决方案中建议的理想解决方案.只有在您想要复制提交时,才能使用Cherry pick. (2认同)

Jos*_*h K 12

我相信你必须"git revert"回到那个提交然后推送它.或者您可以cherry-pick提交到新分支,并将其推送到远程存储库上的分支.就像是:

git branch onecommit
git checkout onecommit
git cherry-pick 7300a6130d9447e18a931e898b64eefedea19544 # From the other branch
git push origin {branch}
Run Code Online (Sandbox Code Playgroud)

  • git revert在这里是一个坏主意 - 它创建了一个新的提交 (8认同)
  • 恢复和樱桃挑选是坏主意.git rebase -i是你的朋友,请参阅下面的Walter Mundt的回答. (4认同)
  • @Nicolas,为什么樱桃选择一个坏主意? (3认同)
  • @Antoine,通常你希望你的分支与它在原点上跟踪的分支保持同步.如果你挑选,你正在复制/粘贴,你必须在某个时候处理未推送的副本.如果你改变-i,你可以"剪切并粘贴",并使你的分支与遥控器同步到你想要的位置. (3认同)

aps*_*mer 9

完成此操作的最简单方法是使用两个命令。

首先,将本地目录设置为您想要的状态。然后,

git push origin +HEAD^:someBranch

someBranch仅从远程删除最后一次提交,而不是本地。您可以连续执行几次此操作,或者进行更改+HEAD^以反映要从远程批量删除的提交数量。现在你重新站起来,并使用

git push origin someBranch

正常更新遥控器。