您如何只推送一些本地git commit?


160

假设我有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

Answers:


192

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

$ git push origin master~3:master

如果您使用的是git-svn:

$ git svn dcommit master~3

在git-svn的情况下,您也可以使用HEAD〜3,因为它期望提交。在使用直接git的情况下,您需要使用分支名称,因为refspec中未正确评估HEAD。

您还可以采用以下更长的方法:

$ 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”部分对于您的设置可能是可选的。


14
注意:您不必使用master~3。对所需的“最多”提交的任何引用都同样有效,例如HEAD~3HEAD~~~,特定的SHA或标记该提交的标签。
卡兹(Kaz)2014年

2
好东西。但是警告:这些示例推送到原始主机。如果要复制和粘贴此解决方案,则可能最终会意外地更新master分支。(当然,您应该始终小心并在发出git push... 之前仔细检查您的命令。)
nofinator

看来这会推送提交,但不会远程添加分支。
Nateowami

@Nateowami为此,您需要指定其他内容而不是refspec master的远程端,例如git push origin tocommit:newbramch
Ryan Graham

我懂了。分支名称已在本地存在;我想那不是那样的。遥控器还没有分支名称。
Nateowami '17

16

我要做的是在本地分支机构“ work”上工作。该分支包含我不打算推​​送到上游存储库的所有临时提交(例如解决方法或私有构建选项或其他)。我对那支离开工作,然后当我要提交我切换到主分支,樱桃挑选适当的提交,我希望提交,然后按主。

从上游将更改引入主分支后,我git checkout workgit rebase master。这会将我所有的本地更改重写为历史记录的结尾。

我实际上正在git svn与此工作流程一起使用,所以我的“推送”操作涉及git svn dcommit。我还使用tig了一个不错的文本模式gui存储库查看器,以挑选合适的提交来掌握。


使用git svn dcommit,您可以指定要提交到commit的提交,因此使用git-svn可以获得理想的效果。
瑞安·格雷厄姆

这种方法有一些缺点(此处总结为stackoverflow.com/a/881014/1116674)。一个不错的选择是为您正在使用的每个功能创建分支,以及一个work分支。然后,将特定分支合并到其中,master这样就不会丢失其历史记录。使用时work,您会将所有分支合并到其中。这会增加开销,但在某些情况下可能值得这样做。
Hudon

16

默认情况下,git-push推送所有分支。执行此操作时:

 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

10

简短答案:

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

例子:

git push fc47b2

git push HEAD~2

长答案:

提交通过父/子机制链接在一起。因此,推送提交实际上还会将所有父提交推送到远程不知道的该提交。当您git push当前提交时,将隐式完成此操作:由于该命令等价于,因此也会推送所有先前的提交git push HEAD

因此,该问题可能被重写为“ 如何推送特定的提交”,例如,该特定的提交可能是HEAD〜2。

如果您要推送的提交是非连续的,只需git rebase -i特定推送之前使用a对其重新排序。


5

1)如果需要,请使用“ git rebase”对提交进行重新排序。

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 commitE

选择c3d4961 commitC

选择4791291 commitA

选择aa1cefc commitD

选择一个a2bdfbd commitB

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

或者你也可以使用

git rebase -i HEAD~<commitNumber>

您可以使用

git log

3)现在使用

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

如果只有一个分支位于远程(原始),而一个分支位于本地(主),则只需使用

git push <commit SHA>
git push aa1cefc

这将推送commitB和commitD。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.