如何仅推送部分本地 git 提交?

问题描述 投票:0回答:5

假设我有 5 个本地提交。我只想将其中 2 个推送到集中式存储库(使用 SVN 风格的工作流程)。我该怎么做?

这不起作用:

git checkout HEAD~3  #set head to three commits ago
git push #attempt push from that head

最终会推送所有 5 个本地提交。

我想我可以执行 git reset 来实际撤消我的提交,然后执行 git stash ,然后执行 git push ——但是我已经编写了提交消息并组织了文件,我不想重做它们。

我的感觉是,传递给推送或重置的一些标志会起作用。

如果有帮助,这是我的 git 配置

[ramanujan:~/myrepo/.git]$cat config 
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        url = ssh://server/git/myrepo.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master
git version-control
5个回答
242
投票

假设您的提交位于 master 分支上,并且您想将它们推送到远程 master 分支:

$ git push origin master~3:master

如果您使用 git-svn:

$ git svn dcommit master~3

对于 git-svn,您还可以使用 HEAD~3,因为它等待提交。在直接 git 的情况下,您需要使用分支名称,因为 HEAD 在 refspec 中未正确评估。

您还可以采取更长的方法:

$ git checkout -b tocommit HEAD~3
$ git push origin tocommit:master

如果您养成了这种工作流程的习惯,您应该考虑在单独的分支中完成您的工作。然后你可以这样做:

$ git checkout master
$ git merge working~3
$ git push origin master:master

请注意,“origin master:master”部分对于您的设置来说可能是可选的。


47
投票

简短回答:

git push <latest commit SHA1 until you want commits to be pushed>

示例:

git push origin fc47b2:master

git push origin HEAD~2:main

长答案:

提交通过父/子机制作为一条链链接在一起。因此,推送提交实际上也会将所有父提交推送到远程不知道的此提交。当您

git push
当前提交时,这是隐式完成的:所有以前的提交也会被推送,因为此命令相当于
git push HEAD

因此问题可能会被重写为如何推送特定提交,例如,这个特定提交可能是 HEAD~2。

如果您要推送的提交不连续,只需在

特定推送
之前使用git rebase -i重新排序即可。


16
投票

我所做的是在一个名为“工作”的当地分支机构工作。该分支包含我不打算推送到上游存储库的所有临时提交(例如解决方法或私有构建选项或其他内容)。我在该分支上工作,然后当我想要提交时,我切换到主分支,挑选我想要提交的适当提交,然后推送主分支。 将更改从上游拉入我的主分支后,我

git checkout work

git rebase master
。这将重写我所有的本地更改以使其成为历史的末尾。

我实际上在这个工作流程中使用

git svn

,所以我的“推送”操作涉及

git svn dcommit
。我还使用
tig
,这是一个很好的文本模式 GUI 存储库查看器,来挑选适当的提交到 master。


16
投票

git checkout HEAD~3 #set head to three commits ago git push #attempt push from that head

您移动到一个分离的 HEAD(您不在任何分支上),然后将所有分支,包括本地主分支(仍然在原来的位置)推送到远程主分支。

手动解决方案是:

git push origin HEAD:master

如果您发现推送所有分支的默认行为令人困惑(并且危险!),请将其添加到您的 ~/.gitconfig 中:

[remote.origin] push = HEAD

然后只有您所在的分支被推送。在您的示例(分离的头)中,您会收到此错误消息,而不是意外推送错误的提交:

error: unable to push to unqualified destination: HEAD



11
投票

git rebase -i

此命令将在您的编辑器中显示类似的内容(我使用的是 vim )

pick 4791291 commitA pick a2bdfbd commitB pick c3d4961 commitC pick aa1cefc commitD pick 9781434 commitE # Rebase .............. # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out ^G Get Help ^O WriteOut ^R Read File ^Y Prev Page ^K Cut Text ^C Cur Pos ^X Exit ^J Justify ^W Where Is ^V Next Page ^U UnCut Text ^T To Spell

2)通过简单的剪切粘贴根据您的选择重新排序您的提交。假设新订单是

选择9781434提交E

选择c3d4961提交C

选择4791291提交A

选择aa1cefc提交D

选择 a2bdfbd 提交B

在编辑器中进行这些更改,然后按 ctrl+O(writeOut)

或者你也可以使用

git rebase -i HEAD~<commitNumber>

您可以使用
检查新序列

git log

3)现在使用

git push <remoteName> <commit SHA>:<remoteBranchName>

如果远程(origin)只有一个分支,本地(master)只有一个分支,则使用

git push <commit SHA> git push aa1cefc

这将推送 commitB 和 commitD。

© www.soinside.com 2019 - 2024. All rights reserved.