我有一个问题,关于git如何从遥控器中提取更改,以及有多少历史记录。
我正在考虑为我的项目遵循gitFlow工作流程。我们是80位开发人员,我们将把我们的更改从功能分支集成到开发分支 - 通过拉取请求首先执行代码审查。
我们需要(本地)修改我们的功能分支(顶部)开发,以便我们集成所有最新的开发更改。因此,我们将经常拉动发展。在这里,我不想取其他队友的功能分支 - 也不想了解他们的提交历史。
现在,如果我拉动开发,如果可以从开发中获得(通过合并提交),此操作是否会带来在其他功能分支下发生的提交历史记录?
提前致谢: - )
编辑:我可能不够清楚:
我们在本地使用rebase,因此对开发分支的pull请求是可合并的。我们不使用合并,因为它可能在执行代码审查时“污染”功能分支。如果接受pulll请求,我们将合并非快进提交。
我知道我可以“git fetch origin origin”。这是我的问题:将git pull origin开发为“获取”蓝色提交还是绿色提交?见图git-pull-
答案 0 :(得分:1)
我开始完整答案,但方式太长了。
回答几个细节,你的担忧是真实的,但有点误导(不是你的错,因为Git文档很糟糕)。关键问题不在于git fetch
提取, 1 它与你合并的提交的提交图中的内容是什么git merge
}};当您选择运行git rebase
时,会复制哪些提交,这些提交再次依赖于提交图,以及您提供给git rebase
的参数。
关键概念是可达性。像origin/master
这样的名称(git fetch
更新)使提交可以访问,但是提交(git fetch
引入)也使得其他提交可以访问。可达提交使整个提交链#34;之前#34;提交可达。合并提交,列出多个父提交ID,使两个(或更多)提交链可达。
1 当然,git fetch
没有提取的内容,可能无法访问(在您的回购副本中) ,因为它不存在(在您的回购副本中)。我怀疑你的目标是什么,但总的来说难以实现,而且无论如何都是不必要的。
请记住:(1)每个提交都由其SHA-1哈希ID标识,(2)每个提交包含其父提交的哈希ID,(3)分支名称只是名称一个提交ID。分支名称经常填充新的ID,增加分支(添加常规或合并提交),或指向由rebase复制的提交。
然后,请记住git rebase
通过复制提交工作。副本具有新的不同ID:
A--B--C [original mybranch, before rebase]
/
...--o--o
\
o--o <-- origin/theirbranch
\
A'-B'-C' <-- mybranch [after rebase]
只要没有其他人拥有名称(分支或标记名称)或指向任何原始提交的提交A
,{{1} },或B
。如果他们确实有这样的名称,那些现有名称可能 - 或者可能不 - 继续指回原件,而不是新副本。只要你现在不使用它们,即使这样也很好。如果更新名称以指向新提交,只要没有仍然可访问的提交指向旧提交,旧的提交就变得无关紧要。如果现有提交指向&#34;过时&#34;但是,这些提交将继续永久地指向它们,因为提交是永久性的。 2
2 没有Git对象可以改变。这是Git的基本保证。但是,完全无法访问的所有 Git对象(包括提交)最终都会被删除。 Git有一个&#34;垃圾收集器&#34;,C
,这样做。它有点复杂,因为有许多宽限期技巧可以保持对象:默认情况下一切都有14天,而引用 - 包括分支,标记和远程跟踪分支名称 - 可能有reflog条目,否则 - 无法访问的提交再次可达。默认情况下,reflog条目本身会持续30天或90天,具体取决于另一个可达性计算,将引用中的当前哈希值与reflog条目中的哈希值进行比较。每当Git认为这可能是一个好主意时,通常会自动调用垃圾收集器。
git gc
例如,假设您的fetch
引入了您的存储库git fetch
,它指向某些提交:
origin/BobsBranch
你可以随时改变你的工作。与此同时,Bob可以重新定义BobsBranch(尽管他可能需要强制将结果推送到服务器)。让我们说他完全抛弃了这三个提交,支持一个新的 B1-B2-B3 <-- origin/BobsBranch
/
...--o--o <-- origin/develop
\
C1-C2-C3 <-- my_independent_work
提交。您运行B4
并选择一个新的,不同的git fetch
;您的存储库现在具有:
origin/BobsBranch
仅在 B4 <-- origin/BobsBranch
/
| B1-B2-B3 [a reflog entry for origin/BobsBranch]
|/
...--o--o <-- origin/develop
\
C1-C2-C3 <-- my_independent_work
或git log --all
次观看中仅显示reflog-only提交,只要您从未使用过任何gitk --all
次提交,它们就不会造成伤害你以任何方式(好吧,他们做占用你的存储库中的一些空间)。
为了避免将它们带到,即使它们是无害的,您可以运行B*
并附带说明以避免将它们带过来。当您运行git fetch
便捷命令时,git pull
会运行git pull
,其中包含仅带来一个 git fetch
分支机构可访问提交的说明,因此,通常可以避免让它们过来 - 当然,除非它们可以根据一个分支提示从Git 需要的东西中找到它们。
origin/whatever
A&#34;坏&#34;当您在提交中合并&#34;到达&#34;稍后由rebase复制的提交。例如,假设你有这个:
merge
现在您决定是时候将...--o--o--A--B <-- origin/feature_X
\
C--D <-- feature_Y
的提交(origin/feature_X
和A
)合并到您的B
中,以便进行合并提交:
feature_Y
如果其他人(上游)决定改变并强制推送他们的...--o--o--A--B <-- origin/feature_X
\ \
C--D--o <-- feature_Y
,以便您的feature_X
指向新副本,那么您最终会得到这样的结果:
origin/feature_X
即使没有 name 附加到rebase复制的提交,如果您通过其名称选择了其他内容,也会发生这种情况。例如,如果其他人推了 o--A'-B' <-- origin/feature_X
/
...--o--o--A--B
\ \
C--D--o <-- feature_Y
并承诺它已经完成:
feature_F
然后你合并它,你得到这个:
A----B
/ \
...--o--o--E--F <-- origin/feature_F
\
C--D <-- feature_Y
现在假设他们或第三个人,然后将他们的分支重新绑定到 A----B
/ \
...--o--o--E--F <-- origin/feature_F
\ \
C--D--o <-- feature_Y
,而没有意识到/记住提交B
本身 指向F
。也就是说,他们从此开始(请注意他们没有B
):
feature_Y
然后决定将 A----B <-- myhacks
/ \
...--o--o--E--F <-- feature_F, origin/feature_F
重新定义到提交myhacks
会更好,所以他们运行:
E
产生:
$ git checkout myhacks
$ git rebase 123e4567 # <id-of-E>
最后,当您获取(可能是通过 A----B
/ \
...--o--o--E--F <-- feature_F, origin/feature_F
\
A'-B' <-- myhacks
)并获取其最终版本git pull
时 - 无论其当时是否有名称,只要它已提交{{1} }和myhacks
- 您将通过提交A'
拥有(并保留)原始B'
提交,并添加A--B
链,即使您可能永远不会拥有见过他们的分支 - 名称 F
。
&#34;坏&#34;我们在上面看到的情况发生在A'-B'
通过名称(在您从中央服务器上提取的存储库中)中提交myhacks
时git fetch
F
。 (你和你的Git重命名了这个feature_F
。)问题不是origin/feature_F
(或feature_F
)本身,而是origin/feature_F
:一个名字既不是你,也不是中央服务器,见过!确实拥有该名称的人 - 或者甚至在事实之后将其用于复制的人提交myhacks
和A
,而不考虑谁拥有原件。然后他推了副本,可能是另一个名称。
名称在B
和fetch
时间很重要,因为push
和git fetch
通过 refspecs 转移提交(大多数只是参考名称对,加上一些辅助的东西)。然而,在这一点之前和之后,这些名称主要是分心:它们的提交集合,以及它们的可访问性状态,这些都很重要。
答案 1 :(得分:0)
git pull的起源会发展为“获取”蓝色提交还是绿色提交?
Git 2.19(2018年第三季度)增加了两个改进,在获取提交时(在客户端,一个在服务器端)(提醒,获取由git pull
调用)。
这会影响“ 可达性”的完成方式,但不会解决torek提到的问题。
第一:
“ git fetch
”学会了一个新选项“ --negotiation-tip
”来限制它告诉另一端为“ have”的提交集,以减少浪费的带宽和周期,这在接收存储库中有很多引用,这些引用与从中获取远程数据库的历史记录无关。
请参见commit 3390e42的Jonathan Tan (jhowtan
)(2018年7月2日)。
(由Junio C Hamano -- gitster
--在commit 30bf8d9中合并,2018年8月2日)
fetch-pack
:支持协商提示白名单在协商过程中,fetch-pack最终报告为“有”行,所有引用都可以访问所有提交。允许用户通过提供提示白名单来限制以这种方式发送的提交;仅会发送小费本身及其祖先。
glob和单个对象均受支持。
仅支持连接或连接的协议支持此功能 无状态连接(例如HTTP v2协议)。
当存储库具有多个相对独立的分支时(例如,当存储库与多个存储库(例如,与
linux-next
和torvalds/linux
进行交互)时,这将加速协商,并且用户知道哪个本地存储库。分支可能与它们正在获取的上游分支具有相同的提交。
第二,Git将一次获取更多提交:
Git添加了一个服务器端旋钮,以指数/斐波那契跨步跳过提交,从而尝试以较小的迭代次数覆盖更广泛的历史记录,可能接受较大的packfile传输,而不是回退一次提交。
请参见commit 42cc748的Jonathan Tan (jhowtan
)(2018年7月16日)。
(由Junio C Hamano -- gitster
--在commit 7c85ee6中合并,2018年8月2日)
谈判者/跳过:在获取过程中跳过提交
引入一种在获取过程中使用的新协商算法,该算法会跳过提交,以更快地找到共同祖先。
随着提交步距尖端越来越远,跳跃的增长与斐波那契数列相似。跳过可能会导致不必要的提交包含在packfile中,但是协商步骤通常会更快地结束。此算法的使用在配置flag
fetch.negotiationAlgorithm
之后受到保护。