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

假设我有5个本地提交。 我只想将其中的两个推到一个集中式回购(使用SVN风格的工作stream程)。 我该怎么做呢?

这不起作用:

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

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

我想我可以做混帐重置,实际上撤消我的提交,其次是混帐隐藏,然后混帐推 – 但我已经有提交的消息写入和文件组织,我不想重做他们。

我的感觉是,一些通过推动或重置的国旗将起作用。

如果有帮助,这是我的gitconfiguration

 [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 push origin master~3:master 

如果你使用的是git-svn:

 $ git svn dcommit master~3 

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

你也可以采取更长的做法:

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

如果你习惯了这种工作stream程,你应该考虑在一个单独的分支上做你的工作。 那么你可以做一些事情:

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

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

我所做的是在当地一个叫“工作”的分店工作。 这个分支包含了所有我不打算推​​送到上游存储库的临时提交(比如变通方法或者私有构build选项或者其他)。 我在那个分支上工作,然后当我想提交时,我切换到主分支,樱桃select我想提交的适当的提交,然后推主。

从上游拉到我的主分支后,我git checkout workgit rebase master 。 这将把我所有的本地更改重写为历史logging的结尾。

我实际上使用这个工作streamgit svn ,所以我的“推”操作涉及到git svn dcommit 。 我也使用tig这是一个很好的文本模式gui存储库查看器,樱桃select适当的提交到主。

默认情况下,git-push推送所有分支。 当你这样做:

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

你移动到一个分离的HEAD(你不在任何分支),然后你把所有的分支,包括本地主(它仍然在那里)到远程主。

手动解决scheme是:

  git push origin HEAD:master 

如果你发现推动所有分支混淆(和危险!)的默认行为,添加到您的〜/ .gitconfig:

  [remote.origin] push = HEAD 

那么只有你所在的分支被推送。 在你的例子(一个分离的头),你会得到这个错误消息,而不是意外推错的提交:

  error: unable to push to unqualified destination: HEAD 

1)如果你想使用“git rebase”重新sorting你的提交。

 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)根据您的select,通过简单的粘贴将您的提交重新sorting。 假设新订单是

选9781434提交

selectc3d4961 commitC

select4791291 commitA

selectaa1cefc 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。

简短的回答:

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重新sorting即可。