给定多个未推送的git
提交,是否可以git-svn dcommit
只进行其中一个提交?
例如,我有提交 foo、bar 和 baz,但现在我只想让 bar 出现在 svn 存储库中。这可能吗?
(以下假设您的工作在master
.)
首先,重新排序你的最后三个提交,以便它bar
是第一个。
git rebase -i HEAD~3
编辑器会弹出如下内容:
pick 498e4f4 foo
pick 71547ae bar
pick abf09c6 baz
# Rebase 4d3fe72..abf09c6 onto 4d3fe72
#
# ...
在弹出的编辑器中重新排序它们,以便bar
首先出现。
pick 71547ae bar
pick 498e4f4 foo
pick abf09c6 baz
# Rebase 4d3fe72..abf09c6 onto 4d3fe72
#
# ...
Git 将旋转几秒钟并弹出确认信息:
Successfully rebased and updated refs/heads/master.
现在您可以暂时回滚到bar
提交(HEAD~2
意味着从 两次提交HEAD
)并 dcommit 它:
git checkout HEAD~2
git svn dcommit
如果你像我一样偏执,你可以git svn dcommit -n
先确保你只做你想做的事。
现在跳回master
:
git checkout master
最后一点是 rebase 以便master
与 svn 同步:
git svn rebase
为什么需要这样做对我来说有点模糊,但我猜想 dcommitting 处于分离的 HEAD 状态与它有关。
git svn dcommit 不能选择性地提交吧。如果您在 master 分支上直接提交了 foo、bar 和 baz,那么您必须执行以下操作才能在 svn 中仅获取 bar。
假设 bar 的提交 sha 类似于 13abc ...
git log master 会显示你所有的 3 次提交 foo、bar 和 baz。
你需要从master创建一个分支
git 分支 wip
wip 分支现在有 foo、bar 和 baz
在 foo、bar 或 baz 之前将 master 的头部重置为提交。您可以使用git reset来做到这一点(阅读手册,硬、软和混合选项之间的差异会影响工作树中未提交的更改)
git reset --hard(在 foo、bar、baz 之前的 COMMIT-ID)
(或者)
git reset --hard HEAD~3(返回 3 个修订版)
现在你的主分支没有 foo、bar 或 baz。用 git log 验证。
现在你可以只挑选你想从 wip 分支提交到 svn 的提交到 master 中。所以得到吧
git cherry-pick wip 13abc(酒吧提交的sha)
主人只能单独获得酒吧提交。
建议未来使用
所以对于 git-svn,最好不要直接在跟踪远程 svn 的 master 分支上提交。在本地分支上做你的工作,并在 dcommiting 之前有选择地合并到 master。
我有一种严厉的答案。您可以创建一个没有 foo、bar 和 baz的新分支,然后将cherry-pick
bar 转到新分支,然后git-svn dcommit
是该分支,完成后将其删除。不过,这似乎不是很优雅。
所以假设 foo、bar 和 baz 在分支 x 中,而 master 没有它们。
git branch y master
git checkout y
git cherry-pick <sha1 of bar>
git svn dcommit
git checkout x
git svn rebase
git branch -d y
如果 master 确实有这些提交,您可以按照 Sizzler 的建议重置头部。
我有时只想提交我的分支的一些提交。例如
A-----B-----C------D
^ ^
| |
svn/trunk trunk
如果我想提交B
但C
不想D
创建一个新分支,请执行 a svn dcommit
,切换回trunk
并删除该分支。
当我在分支时trunk
,我做
git checkout -b temp `C`
git svn info // just to check that branch temp is properly connected to svn
git svn dcommit
git checkout trunk
git branch -D temp
编辑
就像 Stefan 评论的那样:
加上一个额外的“git svn rebase”,它对我来说效果很好。
这是必要的,因为提交到 svn 的提交将被重写。git-svn
将 添加git-svn-id
到提交消息中,因此即使提交的内容相同,提交哈希也会更改。但由于内容相同,rebase 不会引起冲突。
PS:我也经常省略新的分支,只是结帐分离。例如
git checkout --detach C
git svn dcommit
git checkout trunk
git svn rebase