git文章

This commit is contained in:
结发受长生
2018-05-06 12:18:58 +08:00
parent 2e536826e2
commit fc3bc198b9
27 changed files with 1097 additions and 4 deletions
+69
View File
@@ -0,0 +1,69 @@
---
title: Git(1) - 初见
date: 2018-4-18 02:35:13
tags:
- git
- 版本控制
categories:
- Git
---
Git是分布式版本控制系统,与SVN类似的集中化版本控制系统相比,集中化版本控制系统虽然能够令多个团队成员一起协作开发,但有时如果中央服务器宕机的话,谁也无法在宕机期间提交更新和协同开发。甚至有时,中央服务器磁盘故障,恰巧又没有做备份或备份没及时,那就可能有丢失数据的风险。
<!-- more -->
但Git是分布式的版本控制系统,客户端不只是提取最新版本的快照,而且将整个代码仓库镜像复制下来。如果任何协同工作用的服务器发生故障了,也可以用任何一个代码仓库来恢复。而且在协作服务器宕机期间,你也可以提交代码到本地仓库,当协作服务器正常工作后,你再将本地仓库同步到远程仓库。
#### Git的优势
+ 能够对文本版本控制和多人协作开发
+ 拥有强大的分支特性 , 所以能够灵活地以不同的工作流协同开发
+ 分布式版本控制系统 , 即使无网络的情况下也能提交代码到本地仓库 , 有网络时再同步到远程仓库
+ 当团队中某个成员完成某个功能时 , 通过pull request操作来通知其他团队成员 , 其他成员可以进行review code后再合并代码
#### Git的特性
+ 版本库当中的文件有3种状态 , 分别是`已提交(committed)` , `已修改(modified)` , `已暂存(staged)`
+ 直接记录快照 , 而非差异比较
+ 多数操作仅添加数据
+ 几乎所有的操作都是在本地执行
+ 时刻保持数据的完整性
### 准备工作
#### config
Git自带一个`git config`工具来帮主设置git的相关配置
```bash
#查看操作系统中所有用户的通用配置
git config --system --list
#查看当前用户的配置
git config --global --list
```
如果是当前仓库中 , 则在.git/config 中的配置是只针对该仓库的 , 每个级别的配置会覆盖上一个级别的配置
```bash
#可以单独查看某一项配置信息
#如果没有指定级别,则表示查看最终生效的配置信息
git config user.name
#或者指定某个级别的某个属性
git config --global user.name
```
##### 设置用户信息
```bash
git config --global user.name "NewName"
#如果不加global则表示只修改当前库当中的配置信息
```
#### .gitignore
每个库中都可以存在一个该文件
用来配置不需要git进行追踪的文件 , 比如日志 , 编译的临时文件等
内容规范如下
+ `#`开头表示注释
+ 可以使用标准的glob模式匹配
+ 匹配模式以`/`开头防止递归
+ 匹配模式以`/`结尾指定目录
+ 要忽略指定模式以外的文件或目录 , 可以在模式前加上`!`表示取反
glob模式是一种简化的正则表达式
+ `*` 匹配零个或多个任意字符
+ `[abc]` 只包含括号内的任意一个字符
+ `[0-9]` 横线表示范围
+ `?` 匹配任意一个字符
+ `**` 匹配任意的目录结构
+144
View File
@@ -0,0 +1,144 @@
---
title: Git(2) - 基础操作
date: 2018-4-18 08:22:13
tags:
- git
- 版本控制
categories:
- Git
---
### 版本库的基础操作
版本库也可以称为`仓库`, 也就是一个目录 , 这个目录里面的所有文件都被Git管理起来 , 每个文件的修改 删除等 , Git都能追踪
<!-- more -->
#### 创建版本库
```bash
#定位到需要创建仓库的目录下执行
git init
```
执行以后就把这个目录变为git可以管理的仓库
该目录下就会多了一个**.git**目录 , 这个目录是git用来追踪管理版本的 , 勿手动修改
#### 添加文件到版本库
```bash
#添加全部暂存区和历史区不存在的或者有更改的.c文件
git add *.c
#添加全部暂存区和历史区不存在或者有更改的文件
git add .
#添加指定文件到版本库
git add test.c
```
使用`git status`可以查看当前版本库的状态
例如
![git status](/images/git/git_status.png)
这个版本库当中有01.txt是已经添加到版本库但是没有提交的新文件 ( 该文件当前的状态就是`staged - 已暂存` )
使用`git rm --cached 01.txt`可以从暂存库当中移除01.txt , 相当于是add的逆操作
02.txt是没有添加到版本库的文件
#### 提交文件
提交操作针对的是暂存区当中的文件 ( 或者说是已暂存状态的文件 )
```bash
#提交暂存区所有的内容到版本库
git commit -a
#提交暂存区中指定的文件到版本库
git commit 01.txt
```
> 提交时可以直接使用-m参数来添加提交的注释
> 例如 `git commit -a -m "我是注释"`
> 如果未添加 , 提交时则会自动调用vi编辑器来编辑提交注释信息
> 也可以修改core.edit来设定喜欢的编辑器
如果提交01.txt完毕以后 , 再次修改了01.txt
![modified](/images/git/git_modified.png)
此时该文件的状态就是`modified - 已修改`
使用`git add`可以将其添加到暂存区
#### 比较差异
`git diff`命令用于比较指定文件的差异
```bash
#查看所有有变动的文件
git diff
#查看指定文件的变动
git diff 01.txt
#查看暂存区中文件的变动
git diff --staged
```
![git diff](/images/git/git_diff.png)
#### 查看提交历史记录
使用`git log`可以按照提交时间列出所有的提交
```bash
#仅显示最近x次的提交 git log -x
git log -2 #查看最近2次的提交
#简略显示每次提交的内容变动
git log --stat
# --pretty对展示内容进行格式化
git log --pretty=oneline #在一行内仅显示每次提交的hash码与注释
#自定义格式化
git log --pretty=format:"%h - %an,%ar : %s"
```
format当中的占位符含义
| 选项 | 说明 |
|----|-----|
|%H|提交对象(commit)的完整哈希字串|
|%h|提交对象的简短哈希字串|
|%T|树对象(tree)的完整哈希字串|
|%t|树对象的简短哈希字串|
|%P|父对象(parent)的完整哈希字串|
|%p|父对象的简短哈希字串|
|%an|作者(author)的名字|
|%ae|作者的电子邮件地址|
|%ad|作者修订日期(可以用 –date= 选项定制格式)|
|%ar|作者修订日期,按多久以前的方式显示|
|%cn|提交者(committer)的名字|
|%ce|提交者的电子邮件地址|
|%cd|提交日期|
|%cr|提交日期,按多久以前的方式显示|
|%s|提交说明|
#### 撤销操作
##### 重新提交
如果执行`git commit`之后发现了漏掉了一个文件 , 再进行一次提交又显得多余
这时候可以使用**amend**进行重新提交
```bash
git commit --amend
```
##### 取消暂存
执行了git add 之后 , 如果要进行撤销
( 与git rm作用类似 )
```bash
git reset HEAD 03.txt
```
但是reset还可以对已提交的内容进行版本的回退
```bash
#回退当上一个版本
git reset --hard HEAD^
```
> 如果要回退当上上个版本就是HEAD^^
也可以使用简便写法`git reset --hard HEAD~100`表示回退到100个版本之前
此时执行了回退 , 我们发现最后一次提交所做的修改已经没有了
如果还想找回来 , 可以执行`git reflog`来查看操作记录 , 找到最后一次提交的版本号
![git reflog](/images/git/git_reflog.png)
执行以后发现是8725f93
于是执行`git reset --hard 8725F93`
即可再次恢复到最新版本
##### 撤销修改
当文件被修改 , 但还没有git add到暂存区 ( 或者从暂存区当中撤销回到工作区也一样 )
```bash
git checkout -- filename
```
> 注意 : 该操作会导致修改彻底丢失 , 无法恢复
+54
View File
@@ -0,0 +1,54 @@
---
title: Git(2) - 基础操作
date: 2018-4-18 09:20:13
tags:
- git
- 版本控制
categories:
- Git
---
### 分支操作
在git当中 , 对于每次提交 , git都把他们串成一条时间线
这条时间线就是一个分支 , 默认只有master这一条主分支
HEAD相当于是一个指针 , 指向的是当前操作的分支
<!-- more -->
```bash
#创建分支dev
git branch dev
#切换到分支dev
git checkout dev
git checkout -b dev #相当于同时执行上面两条命令
#创建并切换到该分支
#查看分支
git branch
#合并分支dev到当前分支
git merge dev
#删除分支dev
git branch -d dev
```
通常在参与一个多人开发的项目时 , 需要创建一个分支进行开发 , 完成后把这个分支合并到主分支
![git merge](/images/git/git_merge.png)
这里代表合并成功
#### 解决冲突
如果不同的分支当中对同一个文件进行了修改 , 那么就会产生冲突 , 导致无法直接合并
![分支冲突](/images/git/分支冲突.png)
这里提示的信息是03.txt文件在合并时产生了冲突
查看03.txt文件可以发现
![冲突代码](/images/git/冲突代码.png)
这时候就需要手动去解决冲突
修改03.txt文件之后
在master分支当中执行 ( 此时因为处于处理分支合并冲突的过程当中 , 所以并不能切换分支 )
```bash
git add 03.txt
git commit -a -m "resolve conflict 03"
```
此时 , 这次的分支合并才算完成
子分支当中的修改内容并没有受到影响
@@ -0,0 +1,56 @@
---
title: Git(4) - 远程仓库
date: 2018-4-19 00:20:13
tags:
- git
- 版本控制
categories:
- Git
---
在多人的协作开发当中 , 我们需要一个公共的远程库 , 每个人都可以从远程库把项目clone到自己的电脑上进行开发 , 之后把自己编写的代码推送到远程库
完全可以自己搭建一台运行的Git服务器 , 或者利用GitHub这种公共的Git托管服务
<!-- more -->
这里用[GitLab](https://gitlab.com/)来进行测试
#### 创建SSH key
由于本地和远程仓库之间的传输是通过SSH加密的 ( 这个取决于Git托管服务本身的架构 , 如果不是的话可以跳过这个步骤 )
```bash
ssh-keygen -t rsa -C "email地址"
```
执行完成后在本地的用户主目录里面找到`.ssh`目录 , 里面有`id_rsa``id_rsa.public`
前一个是密钥 , 后一个是公钥
把公钥的内容添加到自己账号的SSH keys的设置当中
![gitlab ssh](/images/git/gitlab_ssh.png)
Title是自己看的 随便写即可
#### 添加远程库
在GitLab上创建一个名为git_learn的远程库
我的账号对应的SSH链接就是`git@gitlab.com:sookie/git_learn.git`
在本地的git仓库里面执行
```bash
#添加远程库
git remote add origin git@gitlab.com:sookie/git_learn.git
```
origin是本地仓库中给这个远程库起的名字
一个本地仓库可以对应多个远程库
然后就可以把本地库的所有内容推送到远程库上
```bash
#把master分支推送到名为origin的远程库
git push -u origin master
```
第一次推送的时候需要加`-u`参数
之后只需要执行`git push origin master`即可
#### 克隆远程库
如果需要从一个远程库克隆出一个本地库
需要使用
```bash
git clone git@gitlab.com:sookie/git_learn.git
```
如果有多个人协作开发,那么每个人各自从远程克隆一份就可以了。
> 对于远程库的地址 , 还有`https://gitlab.com/sookie/git_learn.git`这样的地址
> 这是由于Git支持多种协议
> 如果服务器只开放了http端口 , 那么就不能使用ssh协议而只能用https
> 原生的git协议速度比较快