Git 吉特:当我;推;从不同计算机到同一远程分支的不同代码?

Git 吉特:当我;推;从不同计算机到同一远程分支的不同代码?,git,push,pull,Git,Push,Pull,比如说我用两台电脑工作:比如说,我用家用电脑做一个项目,但前一天我忘了用我的工作电脑推送最新的修改 在推/拉的情况下会发生什么? 如果我打开电脑,我会有两个分支吗? 如何解决冲突?在这种情况下,如果您和Bob(或Carol或其他任何人,不是您)都在repos中工作,则完全相同。您都是从共享位置克隆的,并且其中一个将更改推到另一个之前。第一个推动“胜利”的人 Git不知道也不关心你是谁。1它只是查看推送时,推送是否是“快进”操作。如果是这样的话,推送在默认情况下是允许的。2当谁是第一个(比如说Bo

比如说我用两台电脑工作:比如说,我用家用电脑做一个项目,但前一天我忘了用我的工作电脑推送最新的修改

在推/拉的情况下会发生什么? 如果我打开电脑,我会有两个分支吗?
如何解决冲突?

在这种情况下,如果您和Bob(或Carol或其他任何人,不是您)都在repos中工作,则完全相同。您都是从共享位置克隆的,并且其中一个将更改推到另一个之前。第一个推动“胜利”的人

Git不知道也不关心你是谁。1它只是查看推送时,推送是否是“快进”操作。如果是这样的话,推送在默认情况下是允许的。2当谁是第一个(比如说Bob在推送时获胜)时,他所做的新提交将直接堆叠在接收推送的存储库分支的顶端。这是一个快进,所以这是允许的。然后您尝试推送,但您的新提交被堆叠在该回购中的一些提交旁边:

          D-E   <-- branch (updated by Bob)
         /
...-A-B-C
         \
          F-G   <-- what you're trying to push
在这种特殊情况下,这将带来提交
D
E
。一旦你有了这些,你就需要修改你想要推动的内容,以某种方式将
D
E
合并到你的
F
G

有两种简单的方法可以做到这一点,使用
gitmerge
gitrebase

合并 此时,您通常可以简单地运行:

$ git merge
$ git rebase
(因为git知道会有一个上游)。
git merge
所做的是尝试组合一个分叉开发,并创建一个新的“merge commit”,它指向两个链:

(与运行
git merge
时无需额外参数的原因相同:git通常知道上游的情况,并且可以确定要重新设置的基础)。这样做的目的是尝试将您的提交(在本例中为
F
G
)复制到稍微不同的版本中,这些版本仅堆叠在最新获取的提交(在本例中为
E
)的末尾。如果一切顺利,结果如下所示:

          D-E
         /   \
...-A-B-C     F'-G'   <-- branch
         \
          F-G   [to be abandoned]
如果您现在尝试将其推到远程,它会看到您只是在上一次提交的基础上叠加了两次提交:这是一个快进,因此是允许的

git pull怎么样?
pull
脚本实际上只是执行
git fetch
然后执行
git merge
git rebase
的一件方便的事情。它从字面上调用了
git fetch
(以一种稍微复杂的方式,在较旧的git版本中,它阻止了一些有用的事情发生,尽管这里的细节不是很重要)。当提取完成时,它会直接调用
git merge
,除非您告诉它使用
git-rebase
。如果您已经告诉它使用
rebase
,您还可以告诉它是否使用
调用
git rebase
——保留合并。在所有情况下,它都会以一种稍微复杂的方式调用合并或重基。但是,是否以及何时使用
--保留合并
超出了本答案的范围

在较旧(但不是太旧)的git版本中,如果您有
git pull
执行重新基址,它还能够从上游重新基址恢复,其中常规的
git获取;git rebase
序列无法执行。在较新版本的git中,
rebase
使用新的
--fork point
工具来自行解决这个问题,因此
pull
脚本不再有什么大的优势

呃,TL;那么,我应该在什么时候使用git pull? 我过去常常避开它,因为它里面有一堆bug。我想它们现在大部分都是固定的,所以我主要是因为习惯而避免使用。请随意使用它,只需记住它只是
获取
然后
合并
-或-
重新基址
的简写。决定您是喜欢合并还是重基,还是像我一样避免使用
git pull
,这样您就不必弄清楚所有
branch.autosetuprebase
值的含义


1推送的方法通常很重要,例如使用ssh和密钥。但这种身份验证发生在git参与之前;一旦git运行,它就不在乎了,因为它不必在意

即使在创建提交时,git也只使用您配置的名称和电子邮件。您可以在任何时候将这些设置为任何值,因此在特定意义上,它仍然不关心您是谁

2什么是允许的,什么是不允许的,具体规则取决于运行您推送的系统的人。“默认”规则,也就是说,如果您设置了内容,并且没有更改任何内容,那么您得到的是,如果分支是快进的,或者如果设置了force标志,则允许推送到分支。如果标签不存在或设置了强制标志,则允许推送到标签。(一些较旧版本的git也将分支规则应用于标记,但较新版本更严格。)


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

如果发生冲突,git将创建一个冲突分支。您将看到错误在哪里,以及不同版本有哪些不同之处。一旦您通过删除字符和错误的版本解决了问题,您就必须进行git添加和git签出—继续。不要在签出之前提交git(否则您几乎已经签出了)。哇!解释得很好!还要感谢git-up的
git-up
扩展,该扩展更新了所有远程分支,并重新调整了您当前的工作。完全取代了我的工作流中的拉取和重基。
$ git rebase
          D-E
         /   \
...-A-B-C     F'-G'   <-- branch
         \
          F-G   [to be abandoned]
...-A-B-C-D-E-F-G   <-- branch