假设我有 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
假设您的提交位于 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”部分对于您的设置来说可能是可选的。
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
重新排序即可。
我所做的是在一个名为“工作”的当地分支机构工作。该分支包含我不打算推送到上游存储库的所有临时提交(例如解决方法或私有构建选项或其他内容)。我在该分支上工作,然后当我想要提交时,我切换到主分支,挑选我想要提交的适当提交,然后推送主分支。 将更改从上游拉入我的主分支后,我
git checkout work
和
git rebase master
。这将重写我所有的本地更改以使其成为历史的末尾。我实际上在这个工作流程中使用
git svn
,所以我的“推送”操作涉及
git svn dcommit
。我还使用 tig
,这是一个很好的文本模式 GUI 存储库查看器,来挑选适当的提交到 master。
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
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。