你怎么只推动你的一些本地git提交?

时间:2009-03-02 22:48:25

标签: git version-control

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

[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

5 个答案:

答案 0 :(得分:169)

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

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

答案 1 :(得分:16)

我所做的是在名为“work”的本地分支上工作。此分支包含我不打算推​​送到上游存储库的所有临时提交(如变通办法或私有构建选项或其他)。我在那个分支上工作,然后当我想提交时,我切换到主分支,挑选我要提交的相应提交,然后推送主。

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

我实际上在此工作流程中使用了git svn,因此我的“推送”操作涉及git svn dcommit。我还使用tig这是一个很好的文本模式gui存储库查看器,来挑选适当的提交来掌握。

答案 2 :(得分:13)

默认情况下,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

答案 3 :(得分:6)

简答:

DATE DIRECTION FROM TO TYPE STATUS RECORDING DURATION 14:52:54 UTC 2016-11-29 Outgoing Dial (512) xxx-xxxx +91xxxxxxxxxx Phone No Answer — — 14:52:53 UTC 2016-11-29 Incoming Anonymous — Client Completed — 37 secs

示例:

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

git push fc47b2

答案很长:

将提交链接在一起作为具有父/子机制的链。因此,推送提交实际上也会将所有父提交推送到此远程未知的提交。当git push HEAD~2当前提交时,这是隐式完成的:所有先前的提交也被推送,因为此命令等同于git push

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

如果您要推送的提交不是连续的,只需在特定推送之前使用git push HEAD重新排序。

答案 4 :(得分:4)

1)使用&#34; git rebase&#34;如果你愿意,可以重新安排你的提交。

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(writeOut)

或者您也可以使用

git rebase -i HEAD~<commitNumber>

您可以使用

检查新序列
git log

3)现在使用

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

如果只有一个分支在远程(原点),一个在本地(主),只需使用

git push <commit SHA>
git push aa1cefc

这将推送commitB和commitD。