文章目录
今年寒假在看《Git权威指南》,看到 2.5. Git检出 但接下来没继续看了,之后有空会继续看下去,这本书介绍了比较深入的
git
底层的细节,有助于很多概念的理解。等我全部看完之后会继续整理成博文。
这篇文章主要是来总结一下通过 https://learngitbranching.js.org/ 这个网址学习到的一些命令。
初始化新仓库
git init
从现有仓库克隆
git clone [url]
Git 支持许多数据传输协议,像 git:// 协议 , http(s)?/ 或者 user@server:/path.git 表示的 SSH 传输协议。
这个命令发生了什么?
你可能注意到的第一个事就是在我们的本地仓库多了一个名为
<remote name>/<branch name>
的分支, 这种类型的分支就叫远程分支。由于远程分支的特性导致其拥有一些特殊属性。远程分支反映了远程仓库(在你上次和它通信时)的状态。这会有助于你理解本地的工作与公共工作的差别 —— 这是你与别人分享工作成果前至关重要的一步.
远程分支有一个特别的属性,在你检出时自动进入分离 HEAD 状态。Git 这么做是出于不能直接在这些分支上进行操作的原因, 你必须在别的地方完成你的工作, (更新了远程分支之后)再用远程分享你的工作成果。
最后一句话的理解:可看下图,C1 commit
之后,master
会下移,但O/master
还是原来的节点。
创建分支
git branch bugFix
切换分支
git checkout bugFix
创建并切换分支
- 等同于前两个命令
- 提交后就能得到下图part1重的结果
git checkout -b bugFix
合并分支
此时我们通过git checkout master
将分支切换到master
节点,在提交后执行一下命令
git merge bugFix
就能得到上图中part2的结果
rebase
假如我们不执行合并分支的命令,在我们提交master
节点后将分支切换到bugFix
,再执行如下命令
git rebase master
就能得到以下的结果,可以看到原来和master
同一层级的bugFix
,被移动到了master
的下一层级。
HEAD
- 总是指向当前分支上最近一次提交记录
- 通过
cat .git/HEAD
或git symbolic-ref HEAD
查看head的指向。 - 绝对引用:通过哈希值
- 相对引用
- 使用 ^ 向上移动 1 个提交记录
- 使用 ~ 向上移动多个提交记录,如 ~3
强制修改分支位置
将 master 分支强制指向 HEAD 的第 3 级父提交
git branch -f master HEAD~3
撤销变更
- 用 Git Reset 把分支记录回退几个提交记录来实现撤销改动
- 实际上在 reset 之后,原来的 head 记录是存在的,但是处于未加入暂存区状态
- 这种“改写历史”的方法对远程分支无效
git reset HEAD~1
- 或者用 Git Revert,这种方法可以把更改推送到远程分支
整理提交记录
git cherry-pick C2 C4
该命令的效果如下图所示,左图可以转换为右图
除了cherry-pick
外,还可以使用git rebase -i
这个命令。通过这个命令,Git 会打开一个 UI 界面并列出将要被复制到目标分支的备选提交记录,它还会显示每个提交记录的哈希值和提交说明,提交说明有助于你理解这个提交进行了哪些更改。
当 rebase UI界面打开时, 你能做3件事:
• 调整提交记录的顺序(通过鼠标拖放来完成)
• 删除你不想要的提交(通过切换 pick 的状态来完成,关闭就意味着你不想要这个提交记录)
• 合并提交,允许你把多个提交记录合并成一个。
提交的技巧
情景:开发过程中出现了 bug,所以我们添加了很多调试语句,最后我们找到了 bug 并解决了它。那我们该如何优雅的去掉这些调试语句呢?
- 先用
git rebase -i
将提交重新排序,然后把我们想要修改的提交记录挪到最前 - 然后用
commit --amend
来进行一些小修改 - 接着再用
git rebase -i
来将他们调回原来的顺序
新建标签
git tag v1 C1
将标签命名为 v1,并且让它指向提交记录 C1
如果不指定提交记录,Git 会用 HEAD 所指向的位置。
Git Describe
git describe <ref>
可以是任何能被 Git 识别成提交记录的引用
如果不指定提交记录,Git 会用 HEAD 所指向的位置。
输出结果:
<tag>_<numCommits>_g<hash>
tag
表示的是离 ref
最近的标签, numCommits
是表示这个 ref
与 tag
相差有多少个提交记录, hash
表示的是你所给定的 ref 所表示的提交记录哈希值的前几位。
当 ref
提交记录上有某个标签时,则只输出标签名称
Git Fetch
只需要下面这个命令,就可以
- 从远程仓库下载本地仓库中缺失的提交记录
- 更新远程分支指针(如 o/master)
git fetch origin foo
git fetch origin :bar #会在本地创建一个新分支
但我们需要⚠️注意
git fetch
并不会改变你本地仓库的状态。- 它不会更新你的 master 分支,也不会修改你磁盘上的文件。
Git Pull
git fetch
仅仅是下载了远程的数据,我们可以像本地合并分支那样合并远程分支,但是 Git 提供了一个专门的命令来完成这两个操作即git pull
git pull origin foo #相当于:git fetch origin foo; git merge o/foo
Git Push
git push <remote> <place>
git push origin <source>:<destination>
git push origin foo^:master
git push origin master:newBranch #推送到的目的分支不存在会自动创建新的
git push origin :foo #成功删除了远程仓库中的 foo 分支
切到本地仓库中的“master”分支,获取所有的提交,再到远程仓库“origin”中找到“master”分支,将远程仓库中没有的提交记录都添加上去,搞定之后告诉我
但是我们可能面临着这样一个问题:
我们修改的代码是远程仓库的旧版本,这时候使用该命令是无法提交的。那该如何解决这个问题呢?
git fetch; git rebase o/master; git push
# 或者
git fetch; git merge o/master; git push
远程仓库的提交
git fakeTeamwork
还可以指定提交的分支或是数量
git fakeTeamwork foo 3
跟踪远程分支
git checkout -b foo o/master; git pull
git checkout -b foo o/master; git commit; git push
git branch -u o/master foo
这样 foo
就会跟踪 o/master
了
参考资料