如何在不破坏树的情况下重新设置推送的分支?
How to rebase pushed branches without ruining tree?
我是唯一一个在存储库中工作的开发人员,所以破坏人们的流程没有问题。但是,当我在本地重新设置基准然后尝试将其推送到 Bitbucket 时,它返回告诉我需要提取最新的更改。我这样做了,rebase 完全毁了我干净的树。
有没有一种方法可以将变基推送到服务器,而无需额外 "Merge branch" 提交作为其中的一部分?
谢谢!
Rebase 基本上是一个 "copy some commits, then discard the old commits in favor of the new and supposedly improved commits" 操作。
例如,考虑这种情况:
...--A--B--E--F <-- master
\
C--D--G <-- feature (HEAD)
您已经完成了您的功能 feature
,但无论出于何种原因,您必须在工作时在 master
上创建两个提交。所以现在feature
可以重写了。
没有提交可以 永远 改变,所以实际上不可能 replace C
用新的和改进的变体,但我们可以创建一个新的和改进的 C'
来替换 C
,使用临时分支或 Git 的 "detached HEAD" 模式:
C' <-- HEAD
/
...--A--B--E--F <-- master
\
C--D--G <-- feature
提交 C'
对提交 F
的作用与提交 C
对提交 B
的作用相同。旧的(现在很糟糕)C
的父级是 B
,而改进后的新的 C'
的父级是 F
。所以现在我们需要将 D
复制到新的和改进的 D'
,然后对 G
:
再次执行相同的操作
C'--D'--G' <-- HEAD
/
...--A--B--E--F <-- master
\
C--D--G <-- feature
我们现在准备好了 git rebase
的最后一招。它从提交 G
中剥离名称 feature
并使 feature
指向 G'
而不是:
C'--D'--G' <-- feature (HEAD)
/
...--A--B--E--F <-- master
\
C--D--G [abandoned]
由于我们甚至无法看到 被遗弃的提交,因此在您笔记本电脑的本地存储库中,历史似乎一直都是这样:您编写了提交 C'
基于 F
,依此类推。哈希 ID 看起来是随机的;除了你,没有人会知道这一切。
仅...您对 Bitbucket 进行了 git push
次提交 C-D-G
,或至少其中一些。 他们 有你的旧的和糟糕的提交,由 他们的 分支名称 feature
指出。你把你闪亮的新名字发给他们——git push origin feature
——最后,你的Git礼貌地请他们把他们的feature
名字移到指向提交 G'
而不是 G
.
这当然会导致 他们 放弃提交 G
以支持新的和改进的 G'
。这就是您希望他们做的。但他们会说:不,如果我那样做,我将失去我宝贵的承诺 G
!
你所要做的就是告诉他们——或者让你的 Git 告诉他们——是的,我知道你可能会丢失一些提交,但无论如何都要这样做!也就是说,您 Git 向他们发送了一个强有力的命令,而不是礼貌的请求。
您这样做的方法是将 --force
或 --force-with-lease
添加到您的 git push
命令中。这变成了礼貌的请求,请,如果可以,请将您的 feature
设置为命令:设置您的功能!
--force
和--force-with-lease
的区别在于后者先增加了安全检查。而不是仅仅说 Set your name feature
to point to commit G'
!,你的 Git 会说:I think,根据我的信息,您的 feature
指向提交 G
。如果是这样,请将其设置为指向 G'
。如果没有,让我知道我搞砸了。
安全检查显然通常很好,但也没有必要如果你是唯一一个在 Bitbucket 上将新提交放入存储库的人。
我是唯一一个在存储库中工作的开发人员,所以破坏人们的流程没有问题。但是,当我在本地重新设置基准然后尝试将其推送到 Bitbucket 时,它返回告诉我需要提取最新的更改。我这样做了,rebase 完全毁了我干净的树。
有没有一种方法可以将变基推送到服务器,而无需额外 "Merge branch" 提交作为其中的一部分?
谢谢!
Rebase 基本上是一个 "copy some commits, then discard the old commits in favor of the new and supposedly improved commits" 操作。
例如,考虑这种情况:
...--A--B--E--F <-- master
\
C--D--G <-- feature (HEAD)
您已经完成了您的功能 feature
,但无论出于何种原因,您必须在工作时在 master
上创建两个提交。所以现在feature
可以重写了。
没有提交可以 永远 改变,所以实际上不可能 replace C
用新的和改进的变体,但我们可以创建一个新的和改进的 C'
来替换 C
,使用临时分支或 Git 的 "detached HEAD" 模式:
C' <-- HEAD
/
...--A--B--E--F <-- master
\
C--D--G <-- feature
提交 C'
对提交 F
的作用与提交 C
对提交 B
的作用相同。旧的(现在很糟糕)C
的父级是 B
,而改进后的新的 C'
的父级是 F
。所以现在我们需要将 D
复制到新的和改进的 D'
,然后对 G
:
C'--D'--G' <-- HEAD
/
...--A--B--E--F <-- master
\
C--D--G <-- feature
我们现在准备好了 git rebase
的最后一招。它从提交 G
中剥离名称 feature
并使 feature
指向 G'
而不是:
C'--D'--G' <-- feature (HEAD)
/
...--A--B--E--F <-- master
\
C--D--G [abandoned]
由于我们甚至无法看到 被遗弃的提交,因此在您笔记本电脑的本地存储库中,历史似乎一直都是这样:您编写了提交 C'
基于 F
,依此类推。哈希 ID 看起来是随机的;除了你,没有人会知道这一切。
仅...您对 Bitbucket 进行了 git push
次提交 C-D-G
,或至少其中一些。 他们 有你的旧的和糟糕的提交,由 他们的 分支名称 feature
指出。你把你闪亮的新名字发给他们——git push origin feature
——最后,你的Git礼貌地请他们把他们的feature
名字移到指向提交 G'
而不是 G
.
这当然会导致 他们 放弃提交 G
以支持新的和改进的 G'
。这就是您希望他们做的。但他们会说:不,如果我那样做,我将失去我宝贵的承诺 G
!
你所要做的就是告诉他们——或者让你的 Git 告诉他们——是的,我知道你可能会丢失一些提交,但无论如何都要这样做!也就是说,您 Git 向他们发送了一个强有力的命令,而不是礼貌的请求。
您这样做的方法是将 --force
或 --force-with-lease
添加到您的 git push
命令中。这变成了礼貌的请求,请,如果可以,请将您的 feature
设置为命令:设置您的功能!
--force
和--force-with-lease
的区别在于后者先增加了安全检查。而不是仅仅说 Set your name feature
to point to commit G'
!,你的 Git 会说:I think,根据我的信息,您的 feature
指向提交 G
。如果是这样,请将其设置为指向 G'
。如果没有,让我知道我搞砸了。
安全检查显然通常很好,但也没有必要如果你是唯一一个在 Bitbucket 上将新提交放入存储库的人。