Learn Git Branching
链接:https://learngitbranching.js.org
目录
一 主要
(五)高级话题
1. 多次rebase
2. 两个parent节点
3. 纠缠不清的分支
二、远程
(一)Push & Pull - Git 远程仓库
1. git clone
2. 远程分支
3. git fetch
4. 模拟团队合作
5. git push
6. 偏离的历史提交
7. locked main
(二)original及周边-Git远程仓库高级操作
1. 推送主分支
2. 合并远程仓库
3. 远程跟踪分支
4. Git push
5. Git fetch
6. Git push,fetch 中的source
7. Git pull
一 主要
(五)高级话题
1. 多次rebase


2. 两个parent节点

![]()
3. 纠缠不清的分支


![]()
![]()
二、远程
(一)Push & Pull - Git 远程仓库
1. git clone
git clone 命令在真实的环境下的作用是在本地创建一个远程仓库的拷贝(比如从 github.com)


2. 远程分支
远程分支
既然你已经看过 git clone 命令了,咱们深入地看一下发生了什么。
你可能注意到的第一个事就是在我们的本地仓库多了一个名为 o/main 的分支, 这种类型的分支就叫远程分支。由于远程分支的特性导致其拥有一些特殊属性。
远程分支反映了远程仓库(在你上次和它通信时)的状态。这会有助于你理解本地的工作与公共工作的差别 —— 这是你与别人分享工作成果前至关重要的一步.
远程分支有一个特别的属性,在你切换到远程分支时,自动进入分离 HEAD 状态。Git 这么做是出于不能直接在这些分支上进行操作的原因, 你必须在别的地方完成你的工作, (更新了远程分支之后)再用远程分享你的工作成果。


checkout切换到远程分支o/main时直接提交 不会真正影响远程仓库的分支,只会造成head分离
3. git fetch
git fetch 完成了仅有的但是很重要的两步:
- 从远程仓库下载本地仓库中缺失的提交记录
- 更新远程分支指针(如
o/main)
git fetch 实际上将本地仓库中的远程分支更新成了远程仓库相应分支最新的状态
git fetch 并不会改变你本地仓库的状态。它不会更新你的 main 分支,也不会修改你磁盘上的文件。
-
远程仓库:是一个完整的仓库,用于存储代码、提交和其他 Git 元数据,通常托管在 GitHub 或 GitLab 等平台上。
-
远程分支:是远程仓库中分支的引用,是远程分支的本地副本,只能在本地通过拉取(fetch)获取最新内容,不能直接修改,修改后需要推送到远程分支

git fetch4. git pull
-
使用fetch 还需要使用merge将本地与远程分支保持一致,pull是二者的合并

git pull
4. 模拟团队合作


commit 后产生c4提交记录,但还没有c2,c3的记录,此时pull之后会把c2,c3记录同步过来然后再去与c4合并,生成最终c5的提交记录
5. git push


6. 偏离的历史提交


7. locked main
远程服务器拒绝直接推送(push)提交到main, 因为策略配置要求 pull requests 来提交更新.
你应该按照流程,新建一个分支, 推送(push)这个分支并申请pull request,但是你忘记并直接提交给了main.现在你卡住并且无法推送你的更新.
新建一个分支feature, 推送到远程服务器. 然后reset你的main分支和远程服务器保持一致, 否则下次你pull并且他人的提交和你冲突的时候就会有问题.


(二)original及周边-Git远程仓库高级操作
1. 推送主分支




2. 合并远程仓库




3. 远程跟踪分支
在前几节课程中有件事儿挺神奇的,Git 好像知道 main 与 o/main 是相关的。当然这些分支的名字是相似的,可能会让你觉得是依此将远程分支 main 和本地的 main 分支进行了关联。这种关联在以下两种情况下可以清楚地得到展示:
- pull 操作时, 提交记录会被先下载到 o/main 上,之后再合并到本地的 main 分支。隐含的合并目标由这个关联确定的。
- push 操作时, 我们把工作从
main推到远程仓库中的main分支(同时会更新远程分支o/main) 。这个推送的目的地也是由这种关联确定的!
远程跟踪
直接了当地讲,main 和 o/main 的关联关系就是由分支的“remote tracking”属性决定的。main 被设定为跟踪 o/main —— 这意味着为 main 分支指定了推送的目的地以及拉取后合并的目标。
你可能想知道 main 分支上这个属性是怎么被设定的,你并没有用任何命令指定过这个属性呀!好吧, 当你克隆仓库的时候, Git 就自动帮你把这个属性设置好了。
当你克隆时, Git 会为远程仓库中的每个分支在本地仓库中创建一个远程分支(比如 o/main)。然后再创建一个跟踪远程仓库中活动分支的本地分支,默认情况下这个本地分支会被命名为 main。
克隆完成后,你会得到一个本地分支(如果没有这个本地分支的话,你的目录就是“空白”的),但是可以查看远程仓库中所有的分支(如果你好奇心很强的话)。这样做对于本地仓库和远程仓库来说,都是最佳选择。
这也解释了为什么会在克隆的时候会看到下面的输出:
local branch "main" set to track remote branch "o/main"
我能自己指定这个属性吗?
当然可以啦!你可以让任意分支跟踪 o/main, 然后该分支会像 main 分支一样得到隐含的 push 目的地以及 merge 的目标。 这意味着你可以在分支 totallyNotMain 上执行 git push,将工作推送到远程仓库的 main 分支上。
有两种方法设置这个属性,第一种就是通过远程分支切换到一个新的分支,执行:
git checkout -b totallyNotMain o/main
就可以创建一个名为 totallyNotMain 的分支,它跟踪远程分支 o/main。

4. Git push
很好! 既然你知道了远程跟踪分支,我们可以开始揭开 git push、fetch 和 pull 的神秘面纱了。我们会逐个介绍这几个命令,它们在理念上是非常相似的。
首先来看 git push。在远程跟踪课程中,你已经学到了 Git 是通过当前所在分支的属性来确定远程仓库以及要 push 的目的地的。这是未指定参数时的行为,我们可以为 push 指定参数,语法是:
git push <remote> <place>

git push origin main
git push origin foo


5. Git fetch
<place> 参数
如果你像如下命令这样为 git fetch 设置 的话:
git fetch origin foo
Git 会到远程仓库的 foo 分支上,然后获取所有本地不存在的提交,放到本地的 o/foo 上。
它不会更新你的本地的非远程分支, 只是下载提交记录(这样, 你就可以对远程分支进行检查或者合并了)。
如果 git fetch 没有参数,它会下载所有的提交记录到各个远程分支……



git fetch origin C3:foo
git fetch origin C6:main
git checkout foo
git merge main
6. Git push,fetch 中的source
古怪的 <source>
Git 有两种关于 <source> 的用法是比较诡异的,即你可以在 git push 或 git fetch 时不指定任何 source,方法就是仅保留冒号和 destination 部分,source 部分留空。
git push origin :sidegit fetch origin :bugFix
我们分别来看一下这两条命令的作用……



git push origin :foo
git fetch origin :bar
7. Git pull




git pull origin C3:foo
git pull origin C2:side
