远程git rebase如此邪恶的详细原因
因此,我来自一个集中的VCS背景,并试图用Git(新公司,young code base)确定我们的工作流程。有一个问题我找不到一个简单但详细的答案,那就是远程分支上的rebase到底做了什么。据我所知,它改写了历史,一般只限于当地分支机构 我目前尝试检查的工作流涉及一个远程协作分支,每个开发人员“拥有”一个分支,用于共享代码。(在可预见的未来,每个项目和功能请求有2个开发人员和最多3个功能分支,这似乎是过度的,而且开销大于收益。) 然后我偶然发现并尝试了它,它实现了我想要的——开发人员经常提交并推送到自己的协作分支,当他知道批准发布到staging的内容时,他可以在合并到develope之前远程重新设置基础(挤压,也许重新组织)远程git rebase如此邪恶的详细原因,git,git-rebase,Git,Git Rebase,因此,我来自一个集中的VCS背景,并试图用Git(新公司,young code base)确定我们的工作流程。有一个问题我找不到一个简单但详细的答案,那就是远程分支上的rebase到底做了什么。据我所知,它改写了历史,一般只限于当地分支机构 我目前尝试检查的工作流涉及一个远程协作分支,每个开发人员“拥有”一个分支,用于共享代码。(在可预见的未来,每个项目和功能请求有2个开发人员和最多3个功能分支,这似乎是过度的,而且开销大于收益。) 然后我偶然发现并尝试了它,它实现了我想要的——开发人员经常提交
输入原始问题-如果远程分支是为了协作,那么其他人迟早会拉它。如果“客户开发人员”没有向该协作分支机构承诺这是一个流程/培训问题,那么分支机构所有者会对该远程分支机构进行重新定基吗?对已发布(远程)分支机构进行重新定基(或重写历史)的主要问题是,很难根据这些分支机构重新整合工作。因此,如果这些远程设备只是为了查看而获取的,并且在这些远程设备之上没有提交,甚至没有进行合并,那么通常不会有太多问题。否则,合并和解决冲突可能很快成为主要的麻烦 这并不是真的邪恶,而是实现和期望的问题 我们从错综复杂的事实开始:
- 每个Git散列都代表一些唯一的对象。在这里,我们只需要考虑提交对象。每个散列都是对对象内容应用加密散列函数(对于Git,特别是SHA-1)的结果。对于提交,内容包括源树的ID;作者和提交人的姓名、电子邮件地址和时间/日期戳;提交消息;这里最关键的是,父提交的ID
- 即使只更改内容中的一个位,也会产生一个新的、非常不同的哈希ID。哈希函数的加密属性,用于对每个提交(或其他对象)进行身份验证和验证,这也意味着没有办法让某些不同的对象具有相同的哈希ID。Git也依赖于此在存储库之间传输对象
- 通过将提交复制到新的提交,重基(必然)起作用。即使没有其他更改,而且通常与新副本关联的源代码与原始源代码不同,重基的整个要点是重新设置某个提交链的父级。例如,我们可以从以下内容开始:
其中两个...--o--*--o--o--o <-- develop \ o--o <-- feature
是原始两个提交的副本@
- 分支名称,如
,只是指向(单个)提交的指针。我们通常认为是“一个分支”的东西,比如两个提交--,是通过从每个提交向后工作到其父级而形成的develope
- 分支总是希望增加新的提交。发现
或develope
添加了一些新的提交是完全正常的,因此名称现在指向一个提交,或者指向名称所指向位置的许多提交中的最后一个master
- 每当您让Git将您的存储库与其他Git及其存储库进行同步(无论达到何种程度),您的Git和他们的Git都会交换ID,特别是哈希ID。具体哪个ID取决于传输的方向,以及您要求Git使用的任何分支名称
- 远程跟踪分支实际上是Git存储的与存储库关联的实体。你的远程跟踪分支
实际上是你的Git用来记住“我们上次谈话时,origin/master
的Git说他的origin
是什么。”master
git fetch
是如何工作的。例如,您可以运行git fetch origin
。此时,Git在origin
上调用Git并询问它的分支。他们说的是master=1234567
和branch=89abcde
(尽管散列值的长度都正好是40个字符,而不是这些7个字符)
您的Git可能已经有了这些提交对象。如果是这样,我们就快完成了!如果没有,它会要求他们的Git发送这些提交对象,以及Git需要的任何其他对象来理解它们。附加对象是与这些提交一起使用的任何文件,以及这些提交使用的您尚未拥有的任何父提交,加上父提交的父提交,依此类推,直到我们得到您确实拥有的某些提交对象。这将获得所有新历史记录所需的提交和文件。1
一旦Git安全地存储了所有对象,Git就会用新ID更新远程跟踪分支。他们的Git刚刚告诉您,他们的主控
是1234567
,所以现在您的源/主控
设置为1234567
。它们的分支也是如此:它成为您的源/分支
,您的Git保存89abcde
散列
如果您现在git checkout branch
,您的git将使用origin/branch
创建一个新的本地标签,指向89abcde
。让我们画这个:
...--o--*--o--1 <-- master, origin/master
\
o--8 <-- branch, origin/branch
(我把aaaaaaa…
缩短为A
)
那么,一个有趣的问题是,如果他们从Git中获取重基信息,会发生什么。比如说,假设他们是reba
...--o--*--o--1 <-- master, origin/master
\
o--8 <-- branch, origin/branch
...--o--*--o--1 <-- master, origin/master
\
o--8 <-- origin/branch
\
A <-- branch
...--o--*--o--1 <-- master, origin/master
\ \
\ o--F <-- origin/branch
\
o--8--A <-- branch