我想拥有以下版本结构:
(my private changes to 0.1.0) - A - B - C - ...
/
(upstream repo) - 0.1.0 - 0.2.0 - ...
\
(my private changes to 0.2.0) - D - E - F - ...
我不想将我的更改与上游的更改合并,因为上游是快速开发的,并且通常有数以万计的难以解决的冲突,因为上游代码经过重新设计。当0.3.0出来时,我只是创建一个完全的副本,忘记我的私人更改,然后逐个重新应用我的私人修复。但我不希望我的旧变化完全消失 - 我希望他们能够坐在某个地方(在一个单独的分支上?)。
git rebase
不是我想要的。根据{{3}},rebasing将尝试将A-B-C补丁重新应用到0.2.0。以下是上游0.1.0和0.2.0发布日期之间的示例情况:
(upstream) - 0.1.0 - (my master) - A - B - C
现在0.2.0已经出局:
(my master) - A - B - C
/
(upstream) - 0.1.0 - 0.2.0
我不想因为冲突太多而改变我的A - B - C变化。我想将我的A - B - C分支标记为'my-0.1.0'并从0.2.0开始一个'新'主分支:
(my-0.1.0) - A - B - C
/
(upstream) - 0.1.0 - 0.2.0 - (my new master)
我希望我的新主分支成为上游0.2.0的干净副本,而不试图重新应用我的旧A-B-C变更集。所以,如果我在0.2.0之后的世界中需要它,我可以逐个挑选A-B-C的变化。
如何添加my-0.1.0标签?它是标签,标签,分支吗?如何从0.2.0开始空主分支?请注意,有两个不同的回购:我的回购和上游回购。我是否需要将上游分支从上游仓库复制到我的仓库?我如何确保在0.1.0之后拉0.2.0,而不是在C之后?如果我在
后执行拉取请求(上游) - 0.1.0 - (我的主人) - A - B - C
我得到了
(上游) - 0.1.0 - (我的主人) - A - B - C - “0.2.0与ABC合并”
这不是我想要的。
有时我也想将某些变化(例如E)推回上游。是否可以仅为E更改创建拉取请求?在darcs这是可能的。如果用Git / GitHub不可能,那么我需要创建一个单独的分支,手动重新应用E中的更改。我该怎么办?
答案 0 :(得分:3)
git rebase
是你的朋友。
如果需要,请标记旧版本并在最新的上游版本上重新绑定您的私有分支。
要仅为E创建拉取请求,您可以:
git cherry-pick E
(旧分支将具有旧版本的E)。git rebase -i
分支并重新排序提交以将E放在第一位。您可以标记E并从该标记创建拉取请求。当上游应用它时,变基应该正确应用剩余的提交在任何一种情况下,如果rebase没有意识到E在上游最终完成时合并(如果他们修改它就会发生),只需使用交互式rebase删除它的过时版本。
Darcs实际上做了同样的事情,但darcs会自动地进行自动修改而不会发生冲突(并且如果不能就完全拒绝这样做),而在git中你明确地重新定义并且如果有冲突(E结果是依赖于D),它会吐出冲突,让你无论如何都可以处理它。
编辑:啊,你只想把A,B和C放在一边,然后从干净的0.2.0开始。您可以使用任一分支(在master上,do):
git branch -m my-0.1
git checkout -b master 0.2.0
或标签(在主人身上,做):
git tag my-0.1
git reset --keep 0.2.0
分支机构会保留它的reflog,你可以查看并修改它。标签不会有reflog,你将无法检查它(checkout将使你处于“分离的HEAD”状态,除非你给它一个分支来创建)。
答案 1 :(得分:2)
您可能希望查看git rebase --onto
,它可以让您将一组更改应用到与当前不同的基础上
答案 2 :(得分:1)
请注意,since git1.7.2rc2中Jan Hudec提到的his answer选项中的git reset --keep 0.2.0
选项也可以写成:
git checkout -B master 0.2.0
宣布提到:
git checkout -B <current branch> <elsewhere>"
是一种更直观的拼写“
git reset --keep <elsewhere>
”的方式。