所以我来自一个集中的VCS背景,并试图确定我们在Git(新公司,年轻代码库)的工作流程.我无法找到一个简单而详细的答案的一个问题是远程分支上的rebase究竟是做什么的.据我所知,它重写了历史,一般应仅限于本地分支机构.
我目前正在尝试审核的工作流涉及一个远程协作分支,每个开发人员"拥有"一个用于共享代码的目的.(在可预见的未来,有2个开发人员和最多3个开发人员,每个项目和功能请求的功能分支似乎过多,而且开销比获得的收益更多.)
然后我遇到了这个答案并尝试了它并且它完成了我想要的东西 - 一个开发人员承诺并经常推送到他自己的合作分支,当他知道什么被批准发布到分期他可以远程变换(压扁和可能在合并开发之前重组.
输入原始问题 - 如果远程分支是出于协作目的,其他人迟早会被拉出来.如果流程/培训问题是没有"访客开发者"对该协作分支的提交,那么分支所有者实际上会对该远程分支进行重新绑定?
tor*_*rek 10
这不是真正的邪恶,这是实施和期望的问题.
我们从一堆事实开始:
每个Git哈希都代表一些独特的对象.出于我们的目的,我们只需要考虑提交对象.每个哈希都是将加密哈希函数(对于Git,特别是它的SHA-1)应用于对象内容的结果.对于提交,内容包括源树的ID; 作者和提交者的姓名和电子邮件地址以及时间/日期戳; 提交消息; 最重要的是,这里是父提交的ID .
即使只改变内容中的一个位,也会产生一个新的,非常不同的哈希ID.散列函数的加密属性,用于验证和验证每个提交(或其他对象),也意味着没有办法让某些不同的对象具有相同的散列ID.Git也会依赖于在存储库之间传输对象.
Rebase通过将提交复制到新提交来工作(必要).即使没有别的变化,通常,与新副本相关的源代码从原来的源代码,整个的不同点的底垫是重新父一些犯链.例如,我们可以从:
...--o--*--o--o--o <-- develop
\
o--o <-- feature
Run Code Online (Sandbox Code Playgroud)
其中branch 在commit时feature与branch 分开,但现在我们想从tip提交中继下来,所以我们对它进行rebase.结果是:develop*featuredevelop
...--o--*--o--o--o <-- develop
\ \
\ @--@ <-- feature
\
o--o abandoned [used to be feature, now left-overs]
Run Code Online (Sandbox Code Playgroud)
其中两个@是原始两个提交的副本.
分支名称,develop只是指向(单个)提交的指针.我们倾向于认为是"分支"的东西,就像两个提交一样@--@,是通过从每个提交向后工作到其父代来形成的.
分支机构总是希望增加新的提交.找到develop或者master添加了一些新的提交是完全正常的,所以现在名称指向提交 - 或许多提交的最后一个 - 指向名称用于指向的位置.
每当你让你的 Git与你的其他Git及其他存储库同步(无论何种程度)你的存储库时,你的Git和他们的Git就会交换ID特定的哈希ID.究竟哪些ID取决于传输方向,以及您要求Git使用的任何分支名称.
一个远程跟踪分支实际上是一个实体您的Git存储,关联您的存储库.您的远程跟踪分支origin/master,实际上,你的Git的地方,记住"什么的蠢货origin说他 master是,我们谈到了最后一次."
所以,现在我们采取这七个项目,并看看它是如何git fetch工作的.git fetch origin例如,你可能会跑.此时,你的Git调用Git origin并询问它的分支.他们说喜欢master = 1234567和branch = 89abcde(虽然哈希值都是40个字符长,而不是这些7个字符).
您的Git可能已经有这些提交对象.如果是这样,我们差不多完成了!如果没有,它会要求他们的Git发送这些提交对象,以及Git需要的任何其他对象来理解它们.其他对象是与这些提交一起使用的任何文件,以及那些提交使用您尚未拥有的任何父提交,以及父母的父母等等,直到我们找到一些提交对象为止你也有.这将为您提供所有新历史记录所需的所有提交和文件.1
一旦你的Git安全地存储了所有对象,你的Git就会用新的ID更新你的远程跟踪分支.他们的Git刚告诉你他们master是1234567,所以现在你origin/master的设定1234567.对他们来说也是如此branch:它成为你的origin/branch,你的Git保存了89abcde哈希.
如果你现在git checkout branch,你的Git origin/branch用来制作一个新的本地标签,指向89abcde.我们来画这个:
...--o--*--o--1 <-- master, origin/master
\
o--8 <-- branch, origin/branch
Run Code Online (Sandbox Code Playgroud)
(我已缩短1234567到1这里,89abcde只是8为了让它们更合适.)
为了让事情变得非常有趣,让我们自己做一个新的提交branch.让我们说它被编号aaaaaaa...:
...--o--*--o--1 <-- master, origin/master
\
o--8 <-- origin/branch
\
A <-- branch
Run Code Online (Sandbox Code Playgroud)
(我缩短aaaaaaa...到了A).
那么有趣的问题是,如果他们 - 你从中获取某些内容的Git,会发生什么.例如,假设他们重新branch加入master.这会复制一些提交.现在你跑了git fetch,你的Git看到他们说branch = fedcba9.你的Git检查你是否有这个对象; 如果没有,你得到它(和它的文件)及其父(和那个提交的文件)等等,直到我们达到一些共同点 - 事实上,这将是提交1234567.
现在你有了这个:
...--o--*--o--1 <-- master, origin/master
\ \
\ o--F <-- origin/branch
\
o--8--A <-- branch
Run Code Online (Sandbox Code Playgroud)
在这里,我写F了提交fedcba9,origin/branch现在指向的那个.
如果你遇到这个后来没有意识到上游家伙重订基期的branch(你的origin/branch),你可以看看这个,认为你必须有书面的所有三个在提交o--8--A链,因为他们是你的branch,而不是上origin/branch了.但他们没有的原因origin/branch是上游放弃了他们,转而支持新版本.事实上,这些新副本实际上是副本,并且您也应该放弃这些提交,这有点难以辨别.
1如果分支以"正常","预期"的方式增长,那么你的Git和他们的Git很容易弄清楚你的Git需要从哪些提交:你origin/master告诉你你master最后一次看到了什么,现在他们的master分数进一步提高了更长的链条.你需要提交正是那些对他们 master的举报后而来的 origin/master.
如果分支机构以不太典型的方式进行改组,那就更难了.在最常见的情况下,他们只需要通过哈希ID 枚举所有对象,直到你的Git告诉他们已经达到了你已经拥有的对象.浅克隆使具体细节变得更加复杂.
这不是不可能的,因为Git 2.0版左右,现在有内置的工具可以让Git为你找到它.(具体而言,git merge-base --fork-point由其调用git rebase --fork-point,使用您的reflog origin/branch来确定o--8链接曾经origin/branch在某一点开启.这仅适用于保留这些reflog条目的时间段,但默认为至少30天给你一个月的时间来赶上.这是你的时间线上的30天:从你跑的30天开始git fetch,无论多久以前上游做了什么改变.)
这到底是什么归结为是,如果你和你的上游同意,事先,该分支(ES)的一些特定的一组得到重建基础,你可以安排采取一切所需的资料库每次他们这样做的时候.随着更典型的发展过程中,虽然你不会指望他们变基,如果他们不-如果他们从来没有"放弃"发布的承诺,你已经赚得了,然后没有什么你需要恢复的.