gpt4 book ai didi

git - git rebase是否影响远程分支或本地分支

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

我正在名为“角色”的分支上工作。远程主服务器经常更新。因此,在将更改提交到远程分支之后,需要将分支基于最新的master重新建立基础。所以这是我的步骤:

# from local
git add .
git commit 'Add feature'
git push origin role

# rebase
git pull --rebase origin master


重新设置是否只影响本地分支机构或远程分支机构,或两者都影响?如果仅对本地分支进行了重新基准设置,那么在重新设置基准之后,我是否应该再次提交原点?

最佳答案

摘要:是的,但是您的问题是错误的。 :-)
这里有一堆东西可以直接保存。首先,Git术语不是很好-“远程”,“跟踪”,“分支”和“远程跟踪分支”都意味着非常不同的东西!并且您正在使用另一组术语,这使得事情甚至更棘手。因此,在我回答您认为要问的问题之前,让我们定义一下这些术语。 (另请参见gitglossary,尽管并非所有这些都在其中。)

遥控器是短名称,例如origin。它主要用作URL的占位符,因此您不必继续键入一些较长的URL,并且还成为远程跟踪分支名称的一部分(稍后我们将对其进行定义)。

分支是一个模糊的术语:请参见What exactly do we mean by "branch"?在这种特殊情况下,我们将首先使用它来表示分支名称,例如master。在Git中,分支名称只是特定提交的名称,我们称其为分支的尖端,但是本地(普通)分支名称(如master)具有特殊的属性,我们将在稍后介绍。

远程跟踪分支是您的Git分配的名称,并根据您的Git调用其他Git时Git看到的内容在存储库中为您更新。这些是origin/master之类的名称。这些远程跟踪分支名称没有普通(本地)分支名称的特殊属性。

跟踪是一个可怕的动词,Git将其用作简写,以更现代,更冗长的方式表达同一件事。可以将本地分支设置为“跟踪”远程跟踪分支。更为现代的说法是,本地分支将远程跟踪分支设置为其上游。设置上游不会做您无法“手工”做的任何事情,但是会让Git为您自动完成它,这很方便。
通常,我们会将远程跟踪分支origin/master设置为本地分支master的上游。同样,我们将origin/role设置为本地分支role的上游。重要的是,请记住,本地分支和远程跟踪分支都在您自己的Git中。他们实际上都是本地人!远程跟踪分支被称为“远程跟踪”,因为它们是自动更新的。


接下来,请记住,当您使用git fetchgit push(和git pull,但最后请稍等)时,您的Git会调用另一个Git。另一个Git有其自己的独立存储库。您的Git持有另一个Git的方式是通过某个URL,该URL以“远程”名称存储,例如origin:您的Git通过互联网电话调用原始Git并与另一个Git进行对话。您的Git从它们(git fetch)获得东西或将它们交给(git push),并且您的Git和他们的Git都在本地工作,您的Git在您的存储库中工作,而他们的Git在其存储库中工作。
一切都是本地的
这就是为什么至少在Git中,一切都是局部的。实际上并没有任何远程事物,只有本地实体,还有这些特殊的Internet电话呼叫,其中多个Git在本地工作时彼此交换数据。幸运的是,由于fetchpush是主要的两个接触点,因此很容易保持直截了当:所有内容都是本地的,直到您获取或推送。这些就是您的Git和另一个Git传输数据并进行(本地!)更改的地方。
因此,现在我们可以解决您的问题:

重新设置是否只影响本地分支机构或远程分支机构,或两者都影响?

这很容易:如果您不努力,那么只会影响本地事物。

如果仅对本地分支进行了重新基准设置,那么在重新设置基准之后,我是否应该再次提交原点?

这有一个内在的误解。当您进行提交时,您仍然只影响本地事物。要将本地内容发送到其他地方,您需要将其推送(或者,如果您的计算机可以充当服务器,则让您的计算机接听其他人的git fetch电话,但请不要去那里,至少现在还不行!)。
这里有一个很大的麻烦,因为git fetchgit push不对称。
推送和提取不对称
当您运行git fetch时,您的Git会调用他们的Git并从他们那里获取新的东西。您的Git将新内容(提交以及这些提交真正需要的所有内容)保存在存储库中,然后更新了远程跟踪分支名称。这些与您自己的本地分支名称完全不同:您的origin/master与您的master是分开的,而您的origin/role与您的role是分开的。您的origin/*分支名称唯一要做的就是记住您的Git在其Git上看到的内容,因此,只要您的Git在其Git上看到新内容,就可以很安全地进行更改。
但是,当您运行git push时,您的Git会调用其Git,将其发送给他们,然后要求他们更改其masterrole。它们没有ddd/masterddd/role:您让Git要求他们更改自己的,并且只能更改masterrole。如果他们的masterrole中有新内容,而您尚未将它们包含在所推动的内容中,则将要求他们放弃这些新内容,而代之以您的内容。
现在是时候显示本地分支名称的特殊属性,并查看分支名称和提交的工作方式,并查看git rebase的实际工作方式。这也是回顾另一个问题What exactly do we mean by "branch"?的好时机
分支机构通常如何成长,暴力根基为此
Git主要是关于提交的。提交是Git的raison d'être:它们是您所做的任何事情的永恒,不变的快照。尽管可以通过提取旧快照,进行更改(无论可能如何)并将新快照放置在新的位置,将现有的提交复制到新的(不同的)提交中,但是无法更改任何提交。但是,这里的“位置”是什么意思?这是提交图输入图片的地方。
每个提交都有唯一的ID。这是Git在不同时间显示的数字和字母组合的一种大丑陋commit face0ff...类型。 (实际上,每个Git对象都有这些ID之一,但现在我们只关心提交对象。)
每个提交都将保存,并保存您上次提交的所有内容的快照或快照,包括您的姓名,电子邮件地址,日志消息,以及(这是此处的关键项)该先前提交的ID 。
这意味着提交表单(向后)链:

A <- B <- C   <-- master

分支名称(例如 git add)指向技巧提交。小费提交是链中的最新提交。最近指向其父(早期)提交,指向另一个父,依此类推。仅当我们到达没有父项的第一个提交时,此链才结束。
由于新的提交指向较早的提交,因此每当我们进行新的提交时,我们都需要Git来“前​​进”分支名称,以指向我们刚刚进行的新提交。也就是说,如果我们具有上述的 master并创建一个新的 A <- B <- C,则需要Git将 D移至现在指向 master
A <- B <- C <- D   <-- master

这是本地分支名称的特殊属性。当我们在该分支上进行提交时,它们会自动前进到我们刚刚进行的新提交。
这导致了一个关于分支名称的简单规则(但是很快就违反了该规则):它们以保留所有旧提交的方式前进。我们将新的提交添加到分支,新的提交指向旧提交,而我们仅添加到分支。 (请注意,我们现在将分支称为提交的集合,而不是指向一个提交的名称!)
Rebase故意违反了此简单规则。让我们看看建立分支时会发生什么。让我们也停止绘制所有内部箭头,只记得它们都向后指向:当我们从较新的提交向较旧的提交进行向后工作时,我们总是向左移动。
A--B--C--D        <-- master
\
E--F--G <-- role

在这里,我们总共有七个提交,其中三个仅在分支 D上,一个-提交 role-仅在分支 D上,三个- master链在两个分支上。 (这是有关Git的另一件奇特的事情:提交通常在许多分支上。)
当我们使用 A-B-C时,我们希望移动提交,通常要在其他分支的(新)提示之后进行。例如,在这种情况下,我们希望将 git rebase链移动到 E-F-G之后,而不是在 D之后。但是提交不能更改,只能复制。
这就是 C的作用:它复制提交。我们将 git rebase复制到新提交 E-F-G,与 E'-F'-G'非常相似,但是它们位于图中的其他位置:它们位于 E-F-G之后:
A--B--C--D           <-- master
\ \
\ E'-F'-G' <-- role
\
E--F--G [previous role, now abandoned]

rebase命令首先复制提交,然后将分支名称 D剥离旧提示提交 role并将其粘贴到新副本 G上。
这样会丢失旧的 G'链,而放弃它,而转而使用新的闪亮的 E-F-G链。新提交稍有不同(如果没有其他区别, E'-F'-G'E'的不同之处在于 EE'作为其父,而 D具有不同的ID)。
因此,当我们推动时,我们必须用力推动
如果我们将原始 C推送到 E-F-G,则将它们复制为原始 origin的精确副本。这些出现在 E-F-G之后,而不是出现在 C之后。现在我们再次进入 D,因此我们将让我们的Git调用另一个Git并移交 git push origin role,然后要求他们将其 E'-F'-G'设置为指向提交 role
他们会说“不”!
如果他们将 G'设置为指向 role,则将丢失提交 G'。现在,他们的Git找到 E-F-G的唯一方法是查看(他们的)名字 G,如果他们将其 role更改为指向 role,则他们将失去此链接到 G'
当然,这就是我们希望他们做的!但是默认情况下,他们会说“不,如果我这样做,我会丢失一些提交”。 (发生这种默认情况的原因很简单:他们不知道或不在乎我们给了他们 G,他们知道的是,现在,他们将失去 G。)因此,我们必须更改Git的礼貌要求,“请移动 G”,到更强有力的命令:“移动 role!”
理想情况下,我们甚至可以说:“我们认为您的 role命名为 role,如果这样,它应该改为命名为 G;但是让我们知道我们是否对您的 G'错误,好吗? ” Git将此称为 role。并非所有版本的Git都支持该功能,并且如果您确定自己是唯一更改过 --force-with-lease的人,则没有必要。但是需要某种强制,因为您需要像Git一样让他们的Git放弃旧的(复制的)提交。
放在一边: role
git pull命令是为了方便。每当您运行 git pull时,都可以像往常一样从遥控器中拾取一堆新的提交,但是这些新提交全部在它们的远程跟踪分支下结束。一旦有了这些提交,通常就需要对它们进行一些处理。您可以用它们做的两个主要事情是 git fetchgit merge。因此, git rebasegit pull与之后的立即 git fetchgit merge组合在一起。
这样做的主要问题是,在您获取并检查了所有新提交之前,您不一定不确定要使用它们做什么。使用 git rebase使您可以预先决定如何处理它们。想象一下:“我要进入这个黑暗的壁橱,掏出一个瓶子,不管它是什么,我都要喝它。”如果您喝啤酒,那很好。但是如果您拿出一瓶漂白剂怎么办?
无论如何,以上所有内容仍然适用于 git pull,因为它只是 git pull后跟第二个命令。 git fetch通过存储在远程名称下的URL调用另一个Git。第二步,无论是 fetch还是 git merge,然后在本地工作。关于 git rebase的一个特别令人困惑的事情是,由于它早于远程跟踪分支名称的发明,因此它具有一种特殊的语法。这就是为什么即使您从原点获取,然后基于 git pull编写“拉(作为变基)原始原点”而不是“拉(然后变基)原点/原点”的原因。

关于git - git rebase是否影响远程分支或本地分支,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41989300/

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