git文章
This commit is contained in:
@@ -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]` 横线表示范围
|
||||
+ `?` 匹配任意一个字符
|
||||
+ `**` 匹配任意的目录结构
|
||||
@@ -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`可以查看当前版本库的状态
|
||||
例如
|
||||

|
||||
这个版本库当中有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 - 已修改`
|
||||
使用`git add`可以将其添加到暂存区
|
||||
|
||||
#### 比较差异
|
||||
`git diff`命令用于比较指定文件的差异
|
||||
```bash
|
||||
#查看所有有变动的文件
|
||||
git diff
|
||||
|
||||
#查看指定文件的变动
|
||||
git diff 01.txt
|
||||
|
||||
#查看暂存区中文件的变动
|
||||
git diff --staged
|
||||
```
|
||||

|
||||
|
||||
#### 查看提交历史记录
|
||||
|
||||
使用`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`来查看操作记录 , 找到最后一次提交的版本号
|
||||

|
||||
执行以后发现是8725f93
|
||||
于是执行`git reset --hard 8725F93`
|
||||
即可再次恢复到最新版本
|
||||
|
||||
##### 撤销修改
|
||||
当文件被修改 , 但还没有git add到暂存区 ( 或者从暂存区当中撤销回到工作区也一样 )
|
||||
```bash
|
||||
git checkout -- filename
|
||||
```
|
||||
> 注意 : 该操作会导致修改彻底丢失 , 无法恢复
|
||||
@@ -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
|
||||
```
|
||||
通常在参与一个多人开发的项目时 , 需要创建一个分支进行开发 , 完成后把这个分支合并到主分支
|
||||

|
||||
这里代表合并成功
|
||||
|
||||
#### 解决冲突
|
||||
如果不同的分支当中对同一个文件进行了修改 , 那么就会产生冲突 , 导致无法直接合并
|
||||

|
||||
这里提示的信息是03.txt文件在合并时产生了冲突
|
||||
查看03.txt文件可以发现
|
||||

|
||||
|
||||
这时候就需要手动去解决冲突
|
||||
修改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的设置当中
|
||||

|
||||
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协议速度比较快
|
||||
Reference in New Issue
Block a user