Learning Git Branching学习记录

主要

基础篇

1.git commit

提交一次记录。

2.git branch

创建一个新分支,但是并没有改变HEAD的指向。

git checkout 分支名 将HEAD指向分支名。

git checkout -b 新分支名 创建一个新分支并指向该分支。

3.git merge

merge后面只跟一个参数A,指的是将参数A融合入当前工作指针HEAD指向的分支。

4.git rebase

Rebase 实际上就是取出一系列的提交记录,“复制”它们,然后在另外一个地方逐个的放下去。

Rebase 的优势就是可以创造更线性的提交历史。

git rebase后面跟一个参数时,即git rebase A,会将当前HEAD指向的分支更新到A的下面并移动指针到最新分支的最顶端,其原本的分支依然存在。

git rebase后面跟两个参数时,即git rebase A B,会将B所在的分支更新到A下面,并把HEAD指针指向B并移动到更新分支的最顶端,其原本的分支依然存在。

高级篇

1.分离HEAD

分离 HEAD 就是让其指向了某个具体的提交记录而不是分支名。在命令执行之前的状态如下所示:

HEAD -> main -> C1

HEAD 指向 main, main 指向 C1

在执行了git checkout C1

现在变成了

HEAD -> C1

2.相对引用1(~)

相对引用非常给力,这里我介绍两个简单的用法:

使用 ~<num> 向上移动多个提交记录,如 ~3

3.相对引用2(^)

使用 ^ 向上移动 1 个提交记录。

main^ 相当于“main 的父节点”。

main^^main 的第二个父节点。

强制修改分支位置

你现在是相对引用的专家了,现在用它来做点实际事情。

我使用相对引用最多的就是移动分支。可以直接使用 -f 选项让分支指向另一个提交。例如:

git branch -f main HEAD~3

上面的命令会将 main 分支强制指向 HEAD 的第 3 级父提交。

4.撤销变更

主要有两种方法用来撤销变更 —— 一是 git reset,还有就是 git revert

Git Reset(用于本地仓库)

git reset 通过把分支记录回退几个提交记录来实现撤销改动。你可以将这想象成“改写历史”。git reset 向上移动分支,原来指向的提交记录就跟从来没有提交过一样。例如:git reset HEAD~1

Git Revert(用于远程仓库)

虽然在你的本地分支中使用 git reset 很方便,但是这种“改写历史”的方法对大家一起使用的远程分支是无效的。

为了撤销更改并分享给别人,我们需要使用 git revert

执行git revert HEAD之后

在我们要撤销的提交记录后面多了一个新提交,这是因为新提交记录 C2' 引入了更改 —— 这些更改刚好是用来撤销 C2 这个提交的。也就是说 C2' 的状态与 C1 是相同的。

revert 之后就可以把你的更改推送到远程仓库与别人分享了。

reset和revert指令的对象是head指针,因而想要撤销变更时要先让head指针指向要撤销的位置。

移动提交记录

1.git cherry-pick

将一些提交复制到当前所在的位置(HEAD)下面的话, Cherry-pick 是最直接的方式。

例如执行git cherry-pick C2 C4 后 Git 就将被它们抓过来放到当前分支下。

2.交互式rebase

执行了git rebase -i HEAD~4后,Git找到从HEAD至HEAD上面三个,并打开rebase UI界面

当 rebase UI界面打开时, 能做3件事:

  • 调整提交记录的顺序(通过鼠标拖放来完成)
  • 删除你不想要的提交(通过切换 pick 的状态来完成,关闭就意味着你不想要这个提交记录)
  • 合并提交。 它允许你把多个提交记录合并成一个。

杂项

1.只取一个提交记录

我们只要让 Git 复制解决问题的那一个提交记录就可以了。跟之前我们在“整理提交记录”中学到的一样,我们可以使用

  • git rebase -i
  • git cherry-pick

来达到目的。

2.提交的技巧#1

如果我们已有一个提交记录newImage,然后又基于它创建了 caption 分支,然后又提交了一次。此时你想对newImage进行一些小小的调整。

我们可以通过下面的方法来克服困难:

  • 先用 git rebase -i 将提交重新排序,然后把我们想要修改的提交记录挪到最前
  • 然后用git commit --amend修改它。
  • 接着再用 git rebase -i 来将他们调回原来的顺序。
  • 最后我们把 main 移到修改的最前端(用你自己喜欢的方法)大功告成。

3.提交的技巧#2

cherry-pick 可以将提交树上任何地方的提交记录取过来追加到 HEAD 上(只要不是 HEAD 上游的提交就没问题)。

抓过来改,改完之后在把原来的顺序抓过来拍好。

4.git tag

git tag v1 C1(将C1添加一个标签命名为v1)

5.git describe

由于标签在代码库中起着“锚点”的作用,Git 还为此专门设计了一个命令用来描述离你最近的锚点(也就是标签),它就是 git describe

git describe 能帮你在提交历史中移动了多次以后找到方向。

git describe 的语法是:

git describe <ref>

<ref> 可以是任何能被 Git 识别成提交记录的引用,如果你没有指定的话,Git 会以你目前所检出的位置(HEAD)。

它输出的结果是这样的:

<tag>_<numCommits>_g<hash>

tag 表示的是离 ref 最近的标签, numCommits 是表示这个 reftag 相差有多少个提交记录, hash 表示的是你所给定的 ref 所表示的提交记录哈希值的前几位。

ref 提记录上有某个标签时,则只输出标签名称。

高级话题

1.多次rebase

2.两个父节点

一个合并提交有两个父提交,遇到这样的节点时该选择哪条路径就不是很清晰了。

Git 默认选择合并提交的“第一个”父提交,在操作符 ^ 后跟一个数字可以改变这一默认行为,跟几就是去第几个父提交。

使用 ^~ 可以自由地在提交树中移动,非常给力。更厉害的是,这些操作符还支持链式操作!比如:

git checkout HEAD~^2~2

3.纠缠不清的分支

一关练习。

远程

Push & Pull ——Git 远程仓库!

1.git clone

2.远程分支

3.git fetch

git fetch 做了些什么

git fetch 完成了仅有的但是很重要的两步:

  • 从远程仓库下载本地仓库中缺失的提交记录
  • 更新远程分支指针(如 o/main)

git fetch 实际上将本地仓库中的远程分支更新成了远程仓库相应分支最新的状态。远程分支反映了远程仓库在你最后一次与它通信时的状态。

git fetch 不会做的事

git fetch 并不会改变你本地仓库的状态。它不会更新你的 main 分支,也不会修改你磁盘上的文件。

理解这一点很重要,因为许多开发人员误以为执行了 git fetch 以后,他们本地仓库就与远程仓库同步了。它可能已经将进行这一操作所需的所有数据都下载了下来,但是并没有修改你本地的文件。

所以, 可以将 git fetch 的理解为单纯的下载操作。

4.git pull

git fetch 获取远程的数据, 现在我们学习如何将这些变化更新到我们的工作当中。

由于先抓取更新再合并到本地分支这个流程很常用,因此 Git 提供了一个专门的命令来完成这两个操作。它就是 git pull

git pull 就是 git fetchgit merge 的缩写!

pull同步远程仓库时,需要工作指针指向的是和远程指针相关联的指针;
fetch同步远程仓库时,则不需要。

5.模拟团队合作

6.git push

git push 负责将你的变更上传到指定的远程仓库,并在远程仓库上合并你的新提交记录。

可以将 git push 想象成发布你成果的命令。

注意 —— git push 不带任何参数时的行为与 Git 的一个名为 push.default 的配置有关。它的默认值取决于你正使用的 Git 的版本,但是在教程中我们使用的是 upstream。 这没什么太大的影响,但是在你的项目中进行推送之前,最好检查一下这个配置。

关于 origin 和它的周边 —— Git 远程仓库高级操作

1.推送主分支

git pull --rebase:拉取远程仓库的最新记录o/main并把自己追踪远程分支的指针所在分支例如main更新到o/main下面。

git pull --rebase就是 git fetchgit rebase o/main [追踪o/main的分支名] 的缩写!("[]"可写可不写)

3.远程追踪

默认main远程追踪o/main,我们可以设置远程追踪分支。

设置远程追踪分支的两种方法:

1.git checkout -b totallyNotMain o/main

就可以创建一个名为 totallyNotMain 的分支,它跟踪远程分支 o/main

2.git branch -u o/main foo(注意·:foo应当原本就存在)

这样 foo 就会跟踪 o/main 了。如果当前就在 foo 分支上(HEAD指向foo), 还可以省略 foo:

git branch -u o/main

4.git push的参数

在远程跟踪课程中,你已经学到了 Git 是通过当前检出分支的属性来确定远程仓库以及要 push 的目的地的。这是未指定参数时的行为,我们可以为 push 指定参数,语法是:

git push <remote> <place>(remote是远程仓库名)

把这个命令翻译过来就是:

切到本地仓库中的“main”分支,获取所有的提交,再到远程仓库“origin”中找到“main”分支,将远程仓库中没有的提交记录都添加上去,搞定之后告诉我。

我们通过“place”参数来告诉 Git 提交记录来自于 main, 要推送到远程仓库中的 main。它实际就是要同步的两个仓库的位置。

需要注意的是,因为我们通过指定参数告诉了 Git 所有它需要的信息, 所以它就忽略了我们所检出的分支的属性!

5.git push的参数2

<place>参数详解

当为 git push 指定 place 参数为 main 时,我们同时指定了提交记录的来源和去向。

如果来源和去向分支的名称不同,比如你想把本地的 foo 分支推送到远程仓库中的 bar 分支呢?

要同时为源和目的地指定 <place> 的话,只需要用冒号 : 将二者连起来就可以了:

git push origin <source>:<destination>

这个参数实际的值是个 refspec,“refspec” 是一个自造的词,意思是 Git 能识别的位置(比如分支 foo 或者 HEAD~1

如果要推送到的目的分支不存在会怎么样呢?Git 会在远程仓库中根据你提供的名称帮你创建这个分支。

6.git fetch的参数

<place> 参数

1.如果你像如下命令这样为 git fetch 设置 的话:

git fetch origin foo

Git 会到远程仓库的 foo 分支上,然后获取所有本地不存在的提交,放到本地的 o/foo 上。

2.“如果我们指定 <source>:<destination> 会发生什么呢?”

不能在当前检出的分支上干这个事,但是其它分支是可以的。

这里有一点是需要注意的 —— source 现在指的是远程仓库中的位置,而 <destination> 才是要放置提交的本地仓库的位置。它与 git push 刚好相反,这是可以讲的通的,因为在往相反的方向传送数据。

如果执行命令前目标分支不存在,跟 git push 一样,Git 会在 fetch 前自己创建立本地分支, 就像是 Git 在 push 时,如果远程仓库中不存在目标分支,会自己在建立一样。

3.如果 git fetch 没有参数,它会下载所有的提交记录到各个远程分支。

7.没有 source 的 source

Git 有两种关于 <source> 的用法是比较诡异的,即你可以在 git push 或 git fetch 时不指定任何 source,方法就是仅保留冒号和 destination 部分,source 部分留空。

  • git push origin :side(删除远程仓库中名为side的分支)
  • git fetch origin :bugFix(创建一个名为bugFix的分支到本地仓库)

8.git pull的参数

git pull 到头来就是 fetch 后跟 merge 的缩写。你可以理解为用同样的参数执行 git fetch,然后再 merge 你所抓取到的提交记录。

以下命令在 Git 中是等效的:

git pull origin foo 相当于:

git fetch origin foo; git merge o/foo

还有…

git pull origin bar~1:bugFix 相当于:

git fetch origin bar~1:bugFix; git merge bugFix

看到了? git pull 实际上就是 fetch + merge 的缩写, git pull 唯一关注的是提交最终合并到哪里(也就是为 git fetch 所提供的 destination 参数)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值