概述的 fetch-and-rebase 很好。对于第二个问题,我不太确定您在问什么,因此以下内容涵盖了所有基础。
(请注意,git pull 主要只是 git fetch 后跟 git merge,除非您将其配置为例如 rebase。我将在下面仅使用 git merge,假设您'已经完成了一个足够新的fetch。)
假设origin/develop 上的活动持续进行,并且在 origin/develop 上的提交 D1 开始,这就是您将得到的结果:
... - M6 <- master, origin/master
\
D0 - D1 <- develop, origin/develop
\
N0 - N1 <- HEAD=new_feature
现在您执行git fetch 并且“他们”添加了 D2 和 D3。我将省略 master 和 origin/master,假设他们没有移动(如果他们有它也没关系),为本地东西留出更多空间:
D2 - D3 <- origin/develop
/
D0 - D1 <- develop
\
N0 - N1 <- HEAD=new_feature
所以现在(使用HEAD=new_feature,都指向提交N1)你可以这样做:
git rebase origin/develop
而 git 会这样做,提交两个新的提交 N0' 和 N1':
N0' - N1' <- HEAD=new_feature
/
D2 - D3 <- origin/develop
/
D0 - D1 <- develop
\
N0 - N1 [abandoned]
放弃的提交最终会消失(我将在下面将它们排除在外),同时您添加N2,它们添加D4。所以,你 git fetch 和 git rebase origin/develop,给:
N0' - N1' - N2 [abandoned]
/
| N0''-N1''-N2' <- HEAD=new_feature
| /
D2 - D3 - D4 <- origin/develop
/
D0 - D1 <- develop
和以前一样,“废弃”的东西可以被遗忘,这为您提供了从 origin/develop 末尾延伸出来的更改(无论多少次重新调整)的干净整洁的历史记录。
您可以在任何时候,但不必这样做:
git checkout develop && git merge origin/develop && git checkout new_feature
由于您没有在D1 上添加任何提交,这只是快进,因此develop 指向与origin/develop 相同的提交。
假设你还没有操纵本地的develop,但是是时候合并new_feature了,你现在有了这个:
N0''-N1''-N2' <- HEAD=new_feature
/
D2 - D3 - D4 <- origin/develop
/
D0 - D1 <- develop
您可能希望通过上图中的提交N2' 与origin/develop 的端点合并。你现在当然可以这样做了:
git checkout develop # get HEAD onto develop breanch
git merge origin/develop # fast-forward local develop branch
这给了你这个(我会理顺D1和D2之间的纠结):
N0''-N1''-N2' <- new_feature
/
...D1 - D2 - D3 - D4 <- HEAD=develop, origin/develop
但更有趣的问题是,你希望最终的结果是:
N0''-N1''-N2' <- new_feature, HEAD=develop, origin/develop
/
...D1 - D2 - D3 - D4
或者应该是这样的:
N0''-N1''-N2' <- new_feature
/ \
...D1 - D2 - D3 - D4 ------------ M <- HEAD=develop, origin/develop
?如果您想要合并提交M,那么您的最终git merge 命令将需要一个--no-ff 参数,并且您需要首先获取指向提交D4 的本地develop。在这种情况下,您必须进行快进合并以使develop 标签指向D4:
git checkout develop # set HEAD=develop
git merge origin/develop # fast-forward develop to origin/develop
git merge --no-ff new_feature # create merge commit M on local develop
git push origin develop # and push local develop to origin/develop
如果您不想要合并提交,那么当您执行最终的merge 时,develop 指向的位置并不重要,因为它只会快速 -向前。因此,您可以这样做:
git checkout develop # set HEAD=develop
# git merge origin/develop # optional: not needed, but harmless
git merge new_feature # fast-forward local develop to new_feature
git push origin develop # and push local develop to origin/develop
这总是首先弄清楚“我想要最终得到什么提交图”的情况。如果你能画出你想要的图表,那么无论你现在身在何处,都更容易弄清楚如何到达那里。