This commit is contained in:
notfreshmbp
2020-08-05 07:40:10 +08:00
parent d2ae39170a
commit 5dcc44efac
5 changed files with 3569 additions and 13 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
.idea/
.DS_Store

File diff suppressed because it is too large Load Diff

397
Git教程2-高级主题.md Normal file
View File

@@ -0,0 +1,397 @@
# Git教程2-高级主题
## 标签管理
发布一个版本时我们通常先在版本库中打一个标签tag这样就唯一确定了打标签时刻的版本。将来无论什么时候取某个标签的版本就是把那个打标签的时刻的历史版本取出来。所以标签也是版本库的一个快照。
Git的标签虽然是版本库的快照但其实它就是指向某个commit的指针跟分支很像对不对但是分支可以移动标签不能移动所以创建和删除标签都是瞬间完成的。
Git有commit为什么还要引入tag
“请把上周一的那个版本打包发布commit号是6a5819e...”
“一串乱七八糟的数字不好找!”
如果换一个办法:
“请把上周一的那个版本打包发布版本号是v1.2”
“好的按照tag v1.2查找commit就行
所以tag就是一个让人容易记住的有意义的名字它跟某个commit绑在一起。
### 创建标签
------
在Git中打标签非常简单首先切换到需要打标签的分支上
```
$ git branch
* dev
master
$ git checkout master
Switched to branch 'master'
```
然后,敲命令`git tag <name>`就可以打一个新标签:
```
$ git tag v1.0
```
可以用命令`git tag`查看所有标签:
```
$ git tag
v1.0
```
默认标签是打在最新提交的commit上的。有时候如果忘了打标签比如现在已经是周五了但应该在周一打的标签没有打怎么办
方法是找到历史提交的commit id然后打上就可以了
```
$ git log --pretty=oneline --abbrev-commit
12a631b (HEAD -> master, tag: v1.0, origin/master) merged bug fix 101
4c805e2 fix bug 101
e1e9c68 merge with no-ff
f52c633 add merge
cf810e4 conflict fixed
5dc6824 & simple
14096d0 AND simple
b17d20e branch test
d46f35e remove test.txt
b84166e add test.txt
519219b git tracks changes
e43a48b understand how stage works
1094adb append GPL
e475afc add distributed
eaadf4e wrote a readme file
```
比方说要对`add merge`这次提交打标签它对应的commit id是`f52c633`,敲入命令:
```
$ git tag v0.9 f52c633
```
再用命令`git tag`查看标签:
```
$ git tag
v0.9
v1.0
```
注意,标签不是按时间顺序列出,而是按字母排序的。可以用`git show <tagname>`查看标签信息:
```
$ git show v0.9
commit f52c63349bc3c1593499807e5c8e972b82c8f286 (tag: v0.9)
Author: Michael Liao <askxuefeng@gmail.com>
Date: Fri May 18 21:56:54 2018 +0800
add merge
diff --git a/readme.txt b/readme.txt
...
```
可以看到,`v0.9`确实打在`add merge`这次提交上。
还可以创建带有说明的标签,用`-a`指定标签名,`-m`指定说明文字:
```
$ git tag -a v0.1 -m "version 0.1 released" 1094adb
```
用命令`git show <tagname>`可以看到说明文字:
```
$ git show v0.1
tag v0.1
Tagger: Michael Liao <askxuefeng@gmail.com>
Date: Fri May 18 22:48:43 2018 +0800
version 0.1 released
commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (tag: v0.1)
Author: Michael Liao <askxuefeng@gmail.com>
Date: Fri May 18 21:06:15 2018 +0800
append GPL
diff --git a/readme.txt b/readme.txt
...
```
注意标签总是和某个commit挂钩。如果这个commit既出现在master分支又出现在dev分支那么在这两个分支上都可以看到这个标签。
小结
- 命令`git tag <tagname>`用于新建一个标签,默认为`HEAD`也可以指定一个commit id
- 命令`git tag -a <tagname> -m "blablabla..."`可以指定标签信息;
- 命令`git tag`可以查看所有标签。
### 操作标签
------
如果标签打错了,也可以删除:
```
$ git tag -d v0.1
Deleted tag 'v0.1' (was f15b0dd)
```
因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。
如果要推送某个标签到远程,使用命令`git push origin <tagname>`
```
$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
* [new tag] v1.0 -> v1.0
```
或者,一次性推送全部尚未推送到远程的本地标签:
```
$ git push origin --tags
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
* [new tag] v0.9 -> v0.9
```
如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:
```
$ git tag -d v0.9
Deleted tag 'v0.9' (was f52c633)
```
然后从远程删除。删除命令也是push但是格式如下
```
$ git push origin :refs/tags/v0.9
To github.com:michaelliao/learngit.git
- [deleted] v0.9
```
要看看是否真的从远程库删除了标签可以登陆GitHub查看。
小结
- 命令`git push origin <tagname>`可以推送一个本地标签;
- 命令`git push origin --tags`可以推送全部未推送过的本地标签;
- 命令`git tag -d <tagname>`可以删除一个本地标签;
- 命令`git push origin :refs/tags/<tagname>`可以删除一个远程标签。
## Rebase
在上一个教程中多人在同一个分支上协作时很容易出现冲突。即使没有冲突后push的人不得不先pull在本地合并然后才能push成功。
每次合并再push后分支变成了这样
```
$ git log --graph --pretty=oneline --abbrev-commit
* d1be385 (HEAD -> master, origin/master) init hello
* e5e69f1 Merge branch 'dev'
|\
| * 57c53ab (origin/dev, dev) fix env conflict
| |\
| | * 7a5e5dd add env
| * | 7bd91f1 add new env
| |/
* | 12a631b merged bug fix 101
|\ \
| * | 4c805e2 fix bug 101
|/ /
* | e1e9c68 merge with no-ff
|\ \
| |/
| * f52c633 add merge
|/
* cf810e4 conflict fixed
```
总之看上去很乱有强迫症的童鞋会问为什么Git的提交历史不能是一条干净的直线
其实是可以做到的!
我们还是从实际问题出发,看看怎么把分叉的提交变成直线。
在和远程分支同步后,我们对`hello.py`这个文件做了两次提交。用`git log`命令看看:
```
$ git log --graph --pretty=oneline --abbrev-commit
* 582d922 (HEAD -> master) add author
* 8875536 add comment
* d1be385 (origin/master) init hello
* e5e69f1 Merge branch 'dev'
|\
| * 57c53ab (origin/dev, dev) fix env conflict
| |\
| | * 7a5e5dd add env
| * | 7bd91f1 add new env
...
```
注意到Git用`(HEAD -> master)``(origin/master)`标识出当前分支的HEAD和远程origin的位置分别是`582d922 add author``d1be385 init hello`,本地分支比远程分支快两个提交。
现在我们尝试推送本地分支:
```
$ git push origin master
To github.com:michaelliao/learngit.git
! [rejected] master -> master (fetch first)
error: failed to push some refs to 'git@github.com:michaelliao/learngit.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```
很不幸失败了这说明有人先于我们推送了远程分支。按照经验先pull一下
```
$ git pull
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 3 (delta 1), reused 3 (delta 1), pack-reused 0
Unpacking objects: 100% (3/3), done.
From github.com:michaelliao/learngit
d1be385..f005ed4 master -> origin/master
* [new tag] v1.0 -> v1.0
Auto-merging hello.py
Merge made by the 'recursive' strategy.
hello.py | 1 +
1 file changed, 1 insertion(+)
```
再用`git status`看看状态:
```
$ git status
On branch master
Your branch is ahead of 'origin/master' by 3 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
```
加上刚才合并的提交现在我们本地分支比远程分支超前3个提交。
`git log`看看:
```
$ git log --graph --pretty=oneline --abbrev-commit
* e0ea545 (HEAD -> master) Merge branch 'master' of github.com:michaelliao/learngit
|\
| * f005ed4 (origin/master) set exit=1
* | 582d922 add author
* | 8875536 add comment
|/
* d1be385 init hello
...
```
对强迫症童鞋来说现在事情有点不对头提交历史分叉了。如果现在把本地分支push到远程有没有问题
有!
什么问题?
不好看!
有没有解决方法?
有!
这个时候rebase就派上了用场。我们输入命令`git rebase`试试:
```
$ git rebase
First, rewinding head to replay your work on top of it...
Applying: add comment
Using index info to reconstruct a base tree...
M hello.py
Falling back to patching base and 3-way merge...
Auto-merging hello.py
Applying: add author
Using index info to reconstruct a base tree...
M hello.py
Falling back to patching base and 3-way merge...
Auto-merging hello.py
```
输出了一大堆操作,到底是啥效果?再用`git log`看看:
```
$ git log --graph --pretty=oneline --abbrev-commit
* 7e61ed4 (HEAD -> master) add author
* 3611cfe add comment
* f005ed4 (origin/master) set exit=1
* d1be385 init hello
...
```
原本分叉的提交现在变成一条直线了这种神奇的操作是怎么实现的其实原理非常简单。我们注意观察发现Git把我们本地的提交“挪动”了位置放到了`f005ed4 (origin/master) set exit=1`之后这样整个提交历史就成了一条直线。rebase操作前后最终的提交内容是一致的但是我们本地的commit修改内容已经变化了它们的修改不再基于`d1be385 init hello`,而是基于`f005ed4 (origin/master) set exit=1`,但最后的提交`7e61ed4`内容是一致的。
这就是rebase操作的特点把分叉的提交历史“整理”成一条直线看上去更直观。缺点是本地的分叉提交已经被修改过了。
最后通过push操作把本地分支推送到远程
```
Mac:~/learngit michael$ git push origin master
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 576 bytes | 576.00 KiB/s, done.
Total 6 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 1 local object.
To github.com:michaelliao/learngit.git
f005ed4..7e61ed4 master -> master
```
再用`git log`看看效果:
```
$ git log --graph --pretty=oneline --abbrev-commit
* 7e61ed4 (HEAD -> master, origin/master) add author
* 3611cfe add comment
* f005ed4 set exit=1
* d1be385 init hello
...
```
远程分支的提交历史也是一条直线。
小结
- rebase操作可以把本地未push的分叉提交历史整理成直线
- rebase的目的是使得我们在查看历史提交的变化时更容易因为分叉的提交需要三方对比。
## 查看区别
http://marklodato.github.io/visual-git-guide/index-zh-cn.html#diff
![image-20200722085320388](/Users/zxzx/typora_pics/image-20200722085320388.png)

View File

@@ -103,7 +103,7 @@ git的入门是真的难.
[2] 高频使用的 Git 清单
http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
推荐理由:阮一峰出品,必属精品
@@ -116,7 +116,7 @@ http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
网上的教程很多, 但是写的少的却不多. 就我个人而言, 如何形象的感受 Git 在工作中的应用, 我推荐去看廖雪峰的 Git 教程.
因为我在学习 Git 的时候, 刚开始看了一些别的网站的教程, 都是一些支离破碎的命令和比较浅的没有系统讲述 Git 使用的, 而且很多教程是互相抄袭的, 你抄我, 我抄你, 特别是 CSDN 上, 批评一下 CSDN 对于创作者的版权保护不够, 现在乌烟瘴气的, 导出是抄袭的文章.
因为我在学习 Git 的时候, 刚开始看了一些别的网站的教程, 都是一些支离破碎的命令和比较浅的没有系统讲述 Git 使用的, 而且很多教程是互相抄袭的, 你抄我, 我抄你, 特别是 CSDN 上, 批评一下 CSDN 对于创作者的版权保护不够, 现在乌烟瘴气的, 到处是抄袭的文章.
**这个教程内容丰富, 生动形象, 白话为主, 学起来相对 Easy, 我觉得三天或者一周左右可以吃透这个教程**.
@@ -128,9 +128,9 @@ http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
[4] 我用四个命令总结 Git 的所有套路
[4] 四个命令总结 Git 的套路
传送门https://mp.weixin.qq.com/s/VdeQpFCL3GGsfOKrIRW6Hw
传送门https://mp.weixin.qq.com/s/VdeQpFCL3GGsfOKrIRW6Hw
推荐理由labuladong的博客, 简单粗暴,魅力自成体系。
@@ -723,27 +723,62 @@ Small note: If editing the README, please conform to the [standard-readme](https
## 参考文献
[1]git - 简明指南
5@ [4]如果你觉得学习 Git 很枯燥,**那是因为你还没玩过这款游戏** - GitHub Daily的文章 - 知乎
https://zhuanlan.zhihu.com/p/134346782
5@ [6]工作流一目了然看小姐姐用动图展示10大Git命令 - 机器之心的文章 - 知乎
https://zhuanlan.zhihu.com/p/132573100
3@ [2] 高频使用的 Git 清单
http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
3@ [2]给自己点时间再记记这200条Git命令 - 爱前端不爱恋爱的文章 - 知乎
https://zhuanlan.zhihu.com/p/137194960
3@ [24]图解git git diff的用法
http://marklodato.github.io/visual-git-guide/index-zh-cn.html
3@ [1]git - 简明指南
https://rogerdudler.github.io/git-guide/index.zh.html
[2]用动图展示10大Git命令
3@ [2]用动图展示10大Git命令 https://mp.weixin.qq.com/s/PUUL913fig6cFfqy4OKcGA
https://mp.weixin.qq.com/s/PUUL913fig6cFfqy4OKcGA
2@ [4]Git 的 4 个阶段的撤销更改 https://mp.weixin.qq.com/s/S33W_L9-taAC-aEuHvZYPQ
[3]Git使用教程最详细、最傻瓜、最浅显、真正手把手教
2 @[6] -- 的理解
https://mp.weixin.qq.com/s/g0jgzZZ0RG_-dNoBwEs16Q
https://stackoverflow.com/a/22750480/9561380
[4]Git 的 4 个阶段的撤销更改
1@ [5]Git 高级用法 https://mp.weixin.qq.com/s/LTHLKrle5mOczHKsK2k30A
https://mp.weixin.qq.com/s/S33W_L9-taAC-aEuHvZYPQ
1@ [3]Git使用教程最详细、最傻瓜、最浅显、真正手把手教 https://mp.weixin.qq.com/s/g0jgzZZ0RG_-dNoBwEs16Q
[5]Git 高级用法
3@[1] ebooks for git
https://mp.weixin.qq.com/s/LTHLKrle5mOczHKsK2k30A
https://github.com/EbookFoundation/free-programming-books/blob/master/free-programming-books.md#git
2@[5]这才是真正的Git——Git内部原理揭秘 - 腾讯技术工程的文章 - 知乎
https://zhuanlan.zhihu.com/p/96631135
1@[21]我用四个命令,总结了 Git 的所有套路
https://mp.weixin.qq.com/s/VdeQpFCL3GGsfOKrIRW6Hw
1@[11] cherry pick的用法
http://www.ruanyifeng.com/blog/2020/04/git-cherry-pick.html
1@详解 Git 大文件存储Git LFS - 腾讯技术工程的文章 - 知乎 https://zhuanlan.zhihu.com/p/146683392
1@过来人告诉你去工作前最好还是学学Git - Java3y的文章 - 知乎 https://zhuanlan.zhihu.com/p/149169595
1@给女朋友讲解什么是Git - Java3y的文章 - 知乎 https://zhuanlan.zhihu.com/p/147161045

File diff suppressed because it is too large Load Diff