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