gpt4 book ai didi

git - GIT rebase 要求重新提交更改

转载 作者:行者123 更新时间:2023-12-04 15:49:03 25 4
gpt4 key购买 nike

首先,我是git分支的新手。我不知道每个功能分支都应该从master分支出来,而仅使用与下一个功能分支具有这种关系的前提功能分支。

我有三个分支。 masterfeature-1feature-2都推送了一个Bitbucket存储库(启用了问题跟踪)。问题是提交M4M5是关键的提交,所有分支都应在提交合并之前将其重新定基(git rebase的任务)

M1 -- M2 -- M3 -- M4 -- M5   [master]
\ /
A1 --- A2 [feature-1]
\
B1 -- B2 -- B3 [feature-2]


feature-2的开发已完成,现在需要合并到master。这是我为 feature-2M4重新设置基准并将 M5提交给 feature-2所做的任务的优先级。


git push- feature-2的发展
git checkout feature-2
git rebase master
解决冲突
git pull


完成这些步骤后,我在执行 git status之后注意到了。我必须再次推送所有提交( feature-2M4M5和冲突提交)。好吧,我要做的就是执行 git push并启动拉取请求,我完成了,对吗?但这会向问题跟踪器添加另一个git commit注释。

有没有一种方法可以将 feature-2重新设置为 master,而无需再次推送 feature-2M4M5的提交,并且 git log应该包含冲突提交。

更新资料


更改问题详细信息以更好地说明问题

最佳答案

由于您已经推送了两个功能分支,因此根本不应该调整基准。强烈建议不要对已发布的分支机构进行重新定价,因为这会破坏其他开发人员的存储库。这样做的原因是,rebase只是对提交的完全重写。将重新创建您要重新部署的提交,更改内容,并且最重要的是使用不同的哈希值。这导致新提交与旧提交不兼容,因此,拥有旧提交的人最终会与替换新提交的冲突。

正确的解决方案是简单地合并更改。尽管这看起来可能不会看起来那么漂亮,但这是一种无损操作,其中不更改任何现有提交。所发生的一切就是添加了提交,这将在推入或拉出时没有问题。

话虽如此,您可以重新设置基础并仍发布已更改的分支。但是要这样做,您将需要强行推分支,而其他开发人员若要拉这些更改,就需要将其分支重置为新版本。



要将我在下面的一些评论纳入答案:请务必了解,在Git中,分支只是指向提交的指针。整个历史(无分支)是一个很大的无环图,其中提交仅指向其父提交。因此,以问题为例,这就是历史,没有任何分支指针:

A -- B -- C -- D -- E
\ /
F --- G
\
H -- I -- J


每个字母代表一个提交,一个连接到左侧的所有提交都是其父级。因此,例如 F的父级是 A,而 C是与父级 BG的合并提交。

现在,如果我们向该可视化添加分支,则只需添加指向某些提交的指针。其实没什么(分支实际上只是一个包含提交哈希值的文件):

                  master

A -- B -- C -- D -- E
\ /
F --- G ← feature-1
\
H -- I -- J

feature-2


现在,假设我们提交了 feature-2分支。我们将该提交添加到树中...

         \
H -- I -- J -- K

feature-2


…然后将分支指针向前移动一个:

         \
H -- I -- J -- K

feature-2


现在,要了解推送过程中发生的情况,我们需要记住,远程分支也只是分支,因此也就是另一组指针。所以实际上看起来像这样:

         \
H -- I -- J ----------- K
↑ ↑
origin/feature-2 feature-2


我想您可以想象现在推送过程中会发生什么:我们告诉远程存储库更新其分支指针,使其指向 K。但是服务器只有 J,因此我们需要为服务器提供一切以构造 K可以访问的树(因此,其间的所有其他提交以及这些提交的所有实际内容)。但是当然,我们不需要物理地推动 JH甚至 A(尽管从技术上讲,这些都在 feature-2分支上,因为您可以到达它们); Git足够聪明,可以找出实际上缺少哪些对象(您可以在开始推送时看到Git在计算该对象)。

因此,一旦我们将丢失的对象转移到远程存储库中,然后我们告诉远程存储库更新其 feature-1指针,因此它也将指向 K。如果成功,我们还将更新我们的远程分支( origin/feature-2)也指向它(只是为了同步)。

现在,合并的情况实际上是一样的。假设我们将 master合并到 feature-2(在 git merge master上使用 feature-2):

                  master

A -- B -- C -- D -- E -----
\ / \
F --- G ← feature-1 \
\ \
H -- I -- J -- K -- L

feature-2


现在,如果要推送 feature-2,我们再次需要为远程存储库提供它没有的所有对象。由于我们现在正在进行合并提交,因此我们需要检查所有父级:因此,如果服务器没有 K,则需要推送 K;但是,如果它没有 E,我们将不得不按下 E。当然,我们需要再次跟随这些父母,以确保所有对象都存在于遥控器上。完成后,我们只需再次告诉遥控器更新分支指针即可。

因此,总结一下:分支包含可通过在非循环树中导航其提交的父级来以某种方式访问​​的所有提交。但是,即使这意味着分支通常非常“大”(在历史记录的长度上),Git只会将那些对象转移到它没有的远程存储库中。因此,尽管合并可以向分支添加更多的提交,但是如果远程站点已经从另一个分支知道了这些提交,则不必转移这些提交。



最后,关于重定基础的最后几句话:在上面,我们做了 git merge mastermaster分支合并到 feature-2中。如果我们改为使用 git rebase master,则完整的树现在看起来像这样:

                  master               feature-2
↓ ↓
A -- B -- C -- D -- E -- H' -- I' -- J' -- K'
\ /
F --- G ← feature-1
\
H -- I -- J -- K

origin/feature-2


如您所见,有新的提交 H'I'J'K'。这些是重写的提交,因此它们从 E(在重新设置基准时指向 master的地方)而不是 G开始。由于我们已重新设置基础,因此没有合并提交 L。并且如上所述,原始提交仍然存在。只是没有指针可以指向它们而已。因此它们“丢失了”,最终将被垃圾回收。

那么现在推时有什么问题呢?远程分支仍然指向原始的 K,但是我们现在希望它指向 K'。因此,就像以前一样,我们开始为远程存储库提供它需要的所有对象。但是,当我们告诉它设置更新分支指针时,它将拒绝这样做。这样做的原因是,通过将指针设置为 K',它将必须“返回历史记录”,而忽略将 H提交给 K的情况。它不知道我们已经对它们进行了重新设置,并且在重写的和原始的之间也没有链接。因此,为了防止意外的数据丢失,遥控器将拒绝更新分支指针。

现在,您可以强制推动分支。这将告诉远程存储库更新分支指针,即使这样做会丢弃那些原始的提交。因此,您这样做,情况将如下所示:

                                   origin/feature-2
master feature-2
↓ ↓
A -- B -- C -- D -- E -- H' -- I' -- J' -- K'
\ /
F --- G ← feature-1


到目前为止,一切都很好:您决定重新建立分支的基础,并告诉远程存储库不质疑它就接受它。但是现在想像一下,我想拉扯它;而且我的分支仍指向 I。因此,运行pull的功能与反向执行的功能相同:遥控器为我提供了完成历史记录所需的所有对象,然后它告诉我在何处设置分支指针。那时,我的本地Git拒绝这样做,原因与远程存储库之前这样做的原因相同。

通过之前的推动,我们知道我们想要替换原始提交;但是我们没有这样做,所以现在我们需要调查或询问是否应该只替换本地分支机构,还是遥控器上确实存在故障。如果我们自己在本地做一些工作,而现在我们想合并,情况将变得更糟。

这些问题发生在每个曾经获取原始提交的人身上。通常,您想完全避免这种混乱,因此规则是永远不要为已经发布的内容重新设置基础。只要没有其他人能够获得这些原始提交,您就可以进行基准调整,但是一旦情况不再如此,所有参与其中的人都会一团糟。因此,绝对首选合并。

关于git - GIT rebase 要求重新提交更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27856364/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com