重新发布上游git(GitHub)中的新版本,丢失所有本地更改

时间:2011-09-30 08:00:41

标签: git github git-branch git-rebase

我想拥有以下版本结构:

                  (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中的更改。我该怎么办?

3 个答案:

答案 0 :(得分:3)

git rebase是你的朋友。

如果需要,请标记旧版本并在最新的上游版本上重新绑定您的私有分支。

要仅为E创建拉取请求,您可以:

  1. 为其创建新分支和git cherry-pick E(旧分支将具有旧版本的E)。
  2. git rebase -i分支并重新排序提交以将E放在第一位。您可以标记E并从该标记创建拉取请求。当上游应用它时,变基应该正确应用剩余的提交
  3. 在任何一种情况下,如果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.2rc2Jan 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>”的方式。