Git的使用

Git的介绍和使用

Git的介绍

版本控制系统: 版本控制是一种记录一个或若干文件内容变化, 以便将来查阅特定版本修订情况的系统.

Git的特点

直接记录快照, 而非差异比较

Git中, 每当你提交更新或保存项目状态时, 它基本上就会对当时的全部文件创建一个快照并保存这个快照的索引. 为了效率, 如果文件没有修改, Git不再重新存储该文件, 而是只保留一个连接指向之前存储的文件. Git对待数据更像是一个快照流.

近乎所有操作都是本地执行

Git中的绝大多数操作都只需要访问本地文件和资源, 一般不需要来自网络上其他计算机得信息. 因为你在本地磁盘上就有项目的完整历史. 例如, 要浏览项目的历史, Git不需要外连到服务器去获取历史, 然后在显示出来, 它只需要直接从本地数据库中读取.

Git保证完整性

Git中所有的数据都在存储前计算校验和, 然后以校验和来引用. 这意味着不可能在Git不知情时更改任何文件内容或目录内容.

Git一般只添加数据

你执行的Git操作, 几乎只往Git数据库中添加数据. 同别的VCS一样, 未提交更新时有可能丢失或弄乱修改的内容. 但是一旦你提交快照到Git中, 就难以再丢失数据.

Git的配置

Git的配置可以保存在三个地方.

  • /etc/gitconfig文件: 包含系统上每一个用户以及他们仓库的通用配置. 如果在执行git config时带上--system选项, 那么它就会读写该文件中的配置变量.
  • ~/.gitconfig~/.config/git/config文件: 只针对当前用户. 你可以传递--global选项让Git读写此文件, 这会对你系统上该用户的所有仓库有效.
  • 当前使用仓库的Git目录中的config文件(.git/config): 针对该仓库. 你可以传递--local选项让Git强制读写该文件, 虽然默认情况下用的就是它. (这个只有你进入某个Git仓库中才能让该选项生效).

每一个级别会覆盖上一级别的配置, 所以.git/config的配置会覆盖/etc/gitconfig中的配置变量.

1
2
3
4
5
6
7
8
# 查看所在目录的所有配置以及它们所在的文件
git config --list --show-origin

# 设置git配置
git config [--system|--global|--local] <key> <value>

# 查询git配置
git config [--show-origin] <key>

获得Git文档

1
2
3
4
5
6
7
# 获得详细的文档
git help <verb>
git <verb> --help
man git-<verb>

#获得简略的文档
git <verb> -h

Git的使用

获得Git仓库

通常有两种获取Git项目仓库的方式:

  1. 将尚未进行版本控制的本地目录装换为Git仓库
  2. 从其塔服务器克隆一个已存在的Git仓库

在已存在目录中初始化仓库

1
git init [仓库名]

不写仓库名,将会在当前目录下创建.git的子目录, 从而管理当前目录. 但我们现在仅仅做了一个初始化操作, 并没有跟踪任何文件.

克隆现有的仓库

1
git clone 仓库地址 [仓库名]

如果不写仓库名, 会以远程仓库命名. 这个命令, 会创建一个目录, 并在其中生成.git子目录. 当执行git clone命令的时候, 默认配置下远程仓库中的每一个文件的每一个版本都将被拉取下来. Git支持https://协议, git://协议和SSH传输协议, 例如user@server:path/to/repo.git.

记录每次更新到仓库

工作目录中的每一个文件都不外乎这两种状态: 已跟踪未跟踪. 已跟踪的文件是指那些被纳入了版本控制的文件.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 检查当前文件状态
git status

# 跟踪新文件或暂存已修改的文件
git add 文件或目录

# 恢复文件
git restore [--staged] [-s tree] 文件或目录

# 如果指定--staged从head或tree恢复index
# 如果指定-s, 将从tree恢复工作区
# 如果不指定--staged和-s, 将从index恢复工作区

# 状态简介
git status -s

# 查看已暂存和未暂存的修改
git diff [--staged]

# 不加--staged, 比较的是工作区和暂存区的区别
# 加--staged, 比较的时候暂存区和最后一次提交的区别

# 提交更新
git commit [--amend] [-m 提交信息] [-a]

# -a: Git会自动把所有已跟踪过的文件暂存起来一并提交
--amend: 取代上一次提交

# 移除文件
git rm [-f]

# 这个和自己手动用rm移除的区别是, 这个命令会自己将移除的文件提交到暂存区, 如果自己用rm, 需要自己手动添加到暂存区
-f: 如果文件在工作区或暂存区被修改过, 必须要使用-f, 这是为了防止未提交的修改被删除
--cached: 仅从index移除, 而不从工作区移除, 可以用来取消跟踪文件

# 移动文件(重命名文件)
git mv file_from file_to

# 这条命令相当于, 所以使用mv命令时, 记得补上后面两条
mv file_from file_to
git rm file_from
git add file_to

# 查看提交历史
git log [--oneline --graph] [--since|--until="yyyy-MM-dd"] [--author] [--grep=""[--grep=""]...] [--all-match] [-S function_name] [--no-merges] [--] [dir]

--: 是用来隔开参数和目录的, 没有别的作用

忽略文件

使用.gitignore来忽略某些文件. 这个文件是放在仓库的根目录下的, 还可以给子目录添加.gitignore, 子目录下的.gitignore只会对子目录有效. 要养成一个开始就为新仓库设置好.gitignore文件的习惯, 以免将来误提交无用的文件.

远程仓库的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 列出远程仓库
git remote [-v]

-v: 列出url

# 添加远程仓库
git remote add <short> <url>

# 从远程仓库抓取与拉取, 这个命令会访问远程仓库, 从中拉取所有你还没有的数据. 执行完成之后, 你将会拥有那个远程仓库中所有分支的引用, 可以随时查看, 还会更新远程跟踪分支的位置
git fetch <remote>

# 推送到远程仓库
git push <remote> <branch>
git push <remote> <localbranch>:<remotebranch>


# 查看远程仓库信息, 可以查看远程仓库当前处于那个分支, 下一次抓取将会存储的分支, 远程已经删除的分支, 这个是实时的, 不需要fetch
git remote show <remote>

# 删除存储在本地, 但远端已经删除的分支
git remote prune <remote>

# 远程仓库从命名
git remote rename <oldname> <newname>

# 移除远程仓库
git remote remove <remote>

打标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 列出标签
git tag [-l "blob表达式"] [-n]

# 创建轻量标签
git tag <tagname> [hash]

# 创建附注标签
git tag -a <tagname> -m "注释" [hash]

# 查看标签详情
git show <tagname>

# 删除标签
git tag -d <tagname>

# 推送标签到远端
git push origin <tagname>

# 删除远端标签
git push origin --delete <tagname>
git push <remote> :[refs/tags/]<tagname>

Git分支

Git的分支, 其实本质上仅仅是指向提交对象的可变指针.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 创建分支
git branch <branchname>

# 切换分支, 在切换分支前, 需要保证工作目录和暂存区的干净, 如果tree不存在, 有且只有一个同名的本地远程分支, 将会自动创建分支, 并跟踪本地远程跟踪分支
git checkout <tree>

# 创建并切换分支, 如果有本地远程分支, 会自动跟踪
git checkout -b <newbranchname> [本地远程分支]

# 合并分支
git merge <需要被合并的分支>

# 查看分支
git branch [-l <pattern>] [-v] [--merged|--no-merged [commit]

-v: 查看提交信息, 以及与本地远程分支的关系(领先或落后)
--merged: 过滤出已经合并到当前分支的分支
--no-merged: 过滤出尚未合并到当前分支的分支

# 切换跟踪分支
git branch -u <本地远程分支>

# 查看跟踪分支, 这里的数据来自与从每个服务器最后一次抓取的数据. 这个命令并没有连接服务器, 它只会根据本地缓存的数据. 如果需要统计最新的领先与落后数字, 需要在运行此命令之前抓取所有的远程仓库. git fetch --all; git branch -vv
git branch -vv

git变基

变基是将一系列提交按照原有次序依次应用到另一分支上, 而合并是把最终结果合并在一起.

1
2
3
4
# 不写tree, 默认是当前head执行的分支
git rebase 基底 [tree]
# 这个会选中在tree2的, 但没在tree1中的提交
git rebase --onto 基底 tree1 tree2

变基的风险

如果提交存在于你的仓库之外, 而别人可能基于这些提交进行开发, 那么不要执行变基.

-------------本文结束感谢您的阅读-------------