gpt4 book ai didi

git - Git:当我从不同计算机到同一远程分支使用 “push”不同的代码时,会发生什么?

转载 作者:行者123 更新时间:2023-12-02 09:35:05 26 4
gpt4 key购买 nike

假设我在两台计算机上工作:说,我在家用计算机上处​​理项目,但是前一天我忘记从工作计算机上推送最新的修改。

推/拉会发生什么?
如果我启动计算机,我是否将以两个分支结束?
如何解决冲突?

最佳答案

在这种情况下,这与您和Bob(或Carol或其他任何人)都在仓库中工作的情况完全相同,而您都是从共享位置克隆的,一个人将更改推回另一个。第一个推动“胜利”的人。

Git并不知道或不在乎你是谁。1它只是看一看就知道推送是否是“快进”操作。如果是这样,则默认情况下将允许推送。2当第一个谁出现时(例如Bob获胜),当Bob进行推送时,他拥有的新提交将直接堆积在接收推送的存储库分支的顶端。那是一个快进,所以被允许。然后,您尝试进行推送,但是您的新提交与该回购中的一些提交一起堆叠:

          D-E   <-- branch (updated by Bob)
/
...-A-B-C
\
F-G <-- what you're trying to push

[注意:这是 Remote 看到的内容,即, Remote 的 branch指向 E。您的 branch指向 G,而您的存储库中没有 DE。通过执行推送,您可以提供远程 FG,然后要求其更改 branch指向的位置。]

您要让 Remote 将 branch设置为指向 G。如果 Remote 执行了此操作,则提交的 DE会丢失,因此它只会告诉您不,除非您强制执行该操作。

即使您也是Bob(在另一台计算机上)也是如此。

解决问题:两种方法

在这种情况下,您需要带出Bob推送的提交:
$ git fetch

在这种情况下,这将带来 DE的提交。一旦有了这些,就需要修改要推送的内容,以将 DE合并到 FG中。

有两种简单的方法可以做到这一点,即使用 git mergegit rebase

合并

此时,您通常可以简单地运行:
$ git merge

(因为会有git知道的上游)。 git merge的作用是尝试合并一个分叉的开发,并进行指向两个链的新“合并提交”:
          D-E
/ \
...-A-B-C M <-- branch
\ /
F-G

[注意:这里和下面,这就是您本地存储库中的内容。]

如果自动合并顺利进行,则应确保结果良好,因为git并不是魔术,它只遵循一堆规则即可进行合并。如果自动合并效果不佳,则必须协助git,因为它的规则无法解决问题。

如果按下此按钮,则要求 Remote 将 branch设置为指向 M。尽管 M并不完全直接堆叠在 E的顶部,但它确实指向 E作为其父级之一,因此 M是一种(略微复杂的)快速转发。 (实际上, M仅需要 E作为某些祖先,而不仅仅是直接祖先,而是其历史上的任何地方。关键是不会丢失任何提交。)

实际合并的优点是它可以显示实际发生的情况:Bob赢得了推跑比赛,然后您调整了内容以进行匹配。缺点是很难通过合并来回溯内容:如果Bob的更改中有错误,或者您的更改中有错误,则很难准确地确定错误的出处;历史“看起来很复杂”,而并发症通常并没有真正的用处。因此,这就是人们使用第二种选择的原因。

重新设定

代替 git merge,您通常可以在此时简单地运行:
$ git rebase

(出于同样的原因,您可以在不使用额外参数的情况下运行 git merge:git通常了解上游,并可以找出要重新设置基础的内容)。这样做是尝试将您的提交(在这种情况下为 FG)“复制”到稍有不同的版本中,这些版本仅堆叠在最新获取的提交(在本例中为 E)的末尾。如果一切顺利,结果将如下所示:
          D-E
/ \
...-A-B-C F'-G' <-- branch
\
F-G [to be abandoned]

您原来的 FG仍然在那里(并且可以在其他重新变基或覆盖 ORIG_HEAD的名称下以 ORIG_HEAD的名称使用;默认情况下,如果您需要恢复它们,它们还会在reflog中保留30天),但基本上已被遗忘如果改组进行顺利。

与合并的情况一样,您需要确保重新设置确实有效:即使git认为一切正常,也遵循简单的规则,就像合并一样。3但通常它确实可以工作,并且原始的 FG可以忽略,因此我们可以像这样重绘提交图,现在调用副本 FG:
...-A-B-C-D-E-F-G   <-- branch

如果现在尝试将其提交到远程,它会发现您只是在最后一次提交的基础上堆叠了两个提交:这是一个快速转发,因此是允许的。

git pull呢?
pull脚本实际上只是在进行 git fetch以及 git mergegit rebase之后的便捷操作。它从字面上调用 git fetch(以稍微复杂的方式,在git的较旧版本中,阻止了一些有用的事情的发生,尽管这里的细节不是很重要)。提取完成后,除非您已告知它使用 git merge,否则它实际上会调用 git rebase。如果您告诉它使用 rebase,则还可以告诉它是否使用 git rebase调用 --preserve-merges。在所有情况下,它都会以稍微复杂的方式调用合并或重新设置基数。但是,是否以及何时使用 --preserve-merges超出了此答案的范围。

在较旧(但不是太旧)版本的git中,如果您使用 git pull进行了变基,那么它也能够从常规 git fetch; git rebase序列无法执行的上游变基中恢复。在较新版本的git中, rebase使用新的 --fork-point内容自行解决,因此 pull脚本不再具有太大的优势。

ugh,TL; DR-因此,何时应使用 git pull

我曾经避免使用它,因为其中有很多错误。我认为他们现在基本上已经固定,所以我主要是避免习惯。随时使用它,只记得它只是 fetch的缩写,然后是 merge-或- rebase的缩写。确定是喜欢合并还是变基,以及 set your "rebase on pull" settings accordingly. As usual with git, it's overly complicated.还是像我一样避免 git pull,这样就不必弄清楚所有 branch.autosetuprebase值的含义。

1推送方法通常很在意,例如使用ssh和key。但是这种认证是在涉及git之前进行的;一旦git运行,就不会在意,因为它不必在意。

即使在创建提交时,git也仅使用您配置的名称和电子邮件。您可以随时将它们设置为任何值,因此从某种意义上讲,它仍然不在乎您是谁。

2关于允许和不允许的确切规则取决于运行您所推送系统的任何人。 “默认默认”规则(即,如果您设置了内容但未进行任何更改,则会得到的结果)是:如果是快进或设置了强制标志,则允许推送到分支。如果标签不存在或设置了强制标志,则允许推送到标签。 (一些较旧的git版本也将分支规则应用于标签,但较新的版本则更为严格。)

3实际上,所有工作都是由通用代码完成的,即git中的“合并引擎”。这几乎用于所有事情:只要git可以在提交图中找到一个共同的祖先,它就可以进行三向合并。

关于git - Git:当我从不同计算机到同一远程分支使用 “push”不同的代码时,会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27268202/

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