CS-Notes/notes/Git.md
2020-11-17 00:32:18 +08:00

154 lines
7.1 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Git
<!-- GFM-TOC -->
* [Git](#git)
* [集中式与分布式](#集中式与分布式)
* [中心服务器](#中心服务器)
* [工作流](#工作流)
* [分支实现](#分支实现)
* [冲突](#冲突)
* [Fast forward](#fast-forward)
* [储藏Stashing](#储藏stashing)
* [SSH 传输设置](#ssh-传输设置)
* [.gitignore 文件](#gitignore-文件)
* [Git 命令一览](#git-命令一览)
* [参考资料](#参考资料)
<!-- GFM-TOC -->
## 集中式与分布式
Git 属于分布式版本控制系统 SVN 属于集中式
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208200656794.png"/> </div><br>
集中式版本控制只有中心服务器拥有一份代码而分布式版本控制每个人的电脑上就有一份完整的代码
集中式版本控制有安全性问题当中心服务器挂了所有人都没办法工作了
集中式版本控制需要连网才能工作如果网速过慢那么提交一个文件会慢的无法让人忍受而分布式版本控制不需要连网就能工作
分布式版本控制新建分支合并分支操作速度非常快而集中式版本控制新建一个分支相当于复制一份完整代码
## 中心服务器
中心服务器用来交换每个用户的修改没有中心服务器也能工作但是中心服务器能够 24 小时保持开机状态这样就能更方便的交换修改
Github 就是一个中心服务器
## 工作流
新建一个仓库之后当前目录就成为了工作区工作区下有一个隐藏目录 .git它属于 Git 的版本库
Git 的版本库有一个称为 Stage 的暂存区以及最后的 History 版本库History 存储所有分支信息使用一个 HEAD 指针指向当前分支
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208195941661.png"/> </div><br>
- git add files 把文件的修改添加到暂存区
- git commit 把暂存区的修改提交到当前分支提交之后暂存区就被清空了
- git reset -- files 使用当前分支上的修改覆盖暂存区用来撤销最后一次 git add files
- git checkout -- files 使用暂存区的修改覆盖工作目录用来撤销本地修改
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208200014395.png"/> </div><br>
可以跳过暂存区域直接从分支中取出修改或者直接提交修改到分支中
- git commit -a 直接把所有文件的修改添加到暂存区然后执行提交
- git checkout HEAD -- files 取出最后一次修改可以用来进行回滚操作
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208200543923.png"/> </div><br>
## 分支实现
使用指针将每个提交连接成一条时间线HEAD 指针指向当前分支指针
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208203219927.png"/> </div><br>
新建分支是新建一个指针指向时间线的最后一个节点并让 HEAD 指针指向新分支表示新分支成为当前分支
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208203142527.png"/> </div><br>
每次提交只会让当前分支指针向前移动而其它分支指针不会移动
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208203112400.png"/> </div><br>
合并分支也只需要改变指针即可
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208203010540.png"/> </div><br>
## 冲突
当两个分支都对同一个文件的同一行进行了修改在分支合并时就会产生冲突
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208203034705.png"/> </div><br>
Git 会使用 \<\<\<\<\<\<\< ======= \>\>\>\>\>\>\> 标记出不同分支的内容只需要把不同分支中冲突部分修改成一样就能解决冲突
```
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1
```
## Fast forward
"快进式合并"fast-farward merge会直接将 master 分支指向合并的分支这种模式下进行分支合并会丢失分支信息也就不能在分支历史上看出分支信息
可以在合并时加上 --no-ff 参数来禁用 Fast forward 模式并且加上 -m 参数让合并时产生一个新的 commit
```
$ git merge --no-ff -m "merge with no-ff" dev
```
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191208203639712.png"/> </div><br>
## 储藏Stashing
在一个分支上操作之后如果还没有将修改提交到分支上此时进行切换分支那么另一个分支上也能看到新的修改这是因为所有分支都共用一个工作区的缘故
可以使用 git stash 将当前分支的修改储藏起来此时当前工作区的所有修改都会被存到栈中也就是说当前工作区是干净的没有任何未提交的修改此时就可以安全的切换到其它分支上了
```
$ git stash
Saved working directory and index state \ "WIP on master: 049d078 added the index file"
HEAD is now at 049d078 added the index file (To restore them type "git stash apply")
```
该功能可以用于 bug 分支的实现如果当前正在 dev 分支上进行开发但是此时 master 上有个 bug 需要修复但是 dev 分支上的开发还未完成不想立即提交在新建 bug 分支并切换到 bug 分支之前就需要使用 git stash dev 分支的未提交修改储藏起来
## SSH 传输设置
Git 仓库和 Github 中心仓库之间的传输是通过 SSH 加密
如果工作区下没有 .ssh 目录或者该目录下没有 id_rsa id_rsa.pub 这两个文件可以通过以下命令来创建 SSH Key
```
$ ssh-keygen -t rsa -C "youremail@example.com"
```
然后把公钥 id_rsa.pub 的内容复制到 Github "Account settings" SSH Keys
## .gitignore 文件
忽略以下文件
- 操作系统自动生成的文件比如缩略图
- 编译生成的中间文件比如 Java 编译产生的 .class 文件
- 自己的敏感信息比如存放口令的配置文件
不需要全部自己编写可以到 [https://github.com/github/gitignore](https://github.com/github/gitignore) 中进行查询。
## Git 命令一览
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/7a29acce-f243-4914-9f00-f2988c528412.jpg" width=""> </div><br>
比较详细的地址http://www.cheat-sheets.org/saved-copy/git-cheat-sheet.pdf
## 参考资料
- [Git - 简明指南](http://rogerdudler.github.io/git-guide/index.zh.html)
- [图解 Git](http://marklodato.github.io/visual-git-guide/index-zh-cn.html)
- [廖雪峰 : Git 教程](https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000)
- [Learn Git Branching](https://learngitbranching.js.org/)