Git
Git is a distributed version control system.
Git is free software distributed under the GPL.
国内git仓库:Gitee.
初始设置
1 | git --version |
创建仓库
1 | # 创建一个空白的仓库:如果不给仓库名,则将当前文件夹初始化为git仓库,默认创建分支为master |
三个概念
- 工作区
- 暂存区
- 版本库(.git):Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
文件操作
- 更改
1
2
3
4
5
6
7
8# 将文件加入仓库git(把文件修改添加到暂存区),实现版本跟踪
git add filename
# 将当前文件夹(工作区)内的文件加入仓库git,实现版本跟踪,.gitignore中的文件忽略
git add .
将文件移除仓库.git(取消暂存),不再跟踪
git restore --staged filename
提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 提交更改:把暂存区的所有内容提交到当前分支
git commit -m 'message' filename
# 提交所有更改:需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。Git跟踪并管理的是修改,而非文件。
git commit -m 'message'
# 查看提交日志(结果倒序排列)
git log [--online]
# 查看更改
git diff filename
# 查看工作区和版本库里面最新版本的区别
git diff HEAD -- filename删除
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16# 从工作区和暂存区中删除文件
git rm filename
git commit
# 如果误删了文件,所以可以从版本库中把误删的文件恢复到最新版本。
git checkout
# 其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
# 命令git rm用于删除一个文件。
# 如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。
# 强制删除未提交的文件
git rm -f filename
# 删除整个仓库
rm -rf .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# 放弃工作区的修改,让这个文件回到最近一次git commit或git add时的状态。
git checkout -- filename
# 把暂存区的修改撤销掉(unstage),重新放回工作区
git reset HEAD filename
# 回退到更旧的版本(满屏放不下的时候,就会显示冒号,英文状态下 按 q 可以退出git log 状态)
git log [--pretty=oneline]
git checkout 标识码(commit id至少6位)
git checkout master (回到分支)
# 在版本回退里,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。
# HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,HEAD指向的版本就是当前版本,Git允许我们在版本的历史之间穿梭:
git reset --hard commit_id
git reset --hard HEAD^
HEAD 表示当前版本
HEAD^ 上一个版本
HEAD^^ 上上一个版本
HEAD~100
# 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
# 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。标签
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# 标签也是版本库的一个快照;tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。
# 首先,切换到需要打标签的分支上
git branch
git checkout master
# 敲命令git tag <name>就可以打一个新标签
git tag v1.0
# 查看所有标签
git tag
# 默认标签是打在最新提交的commit上的。有时候,如果忘了打标签,比如,现在已经是周五了,但应该在周一打的标签没有打,怎么办?方法是找到历史提交的commit id,然后打上就可以了:
git tag v0.9 f52c633
# 标签不是按时间顺序列出,而是按字母排序的
# 可以用git show <tagname>查看标签信息
# 还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:
git tag -a v0.1 -m "version 0.1 released" 1094adb
如果标签打错了,也可以删除:git tag -d v0.1
# 因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。
# 如果要推送某个标签到远程,使用命令
git push origin <tagname>
# 一次性推送全部尚未推送到远程的本地标签:
git push origin --tags
# 如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:
git tag -d v0.9
# 然后,远程删除:
git push origin :refs/tags/v0.9
# 版本回退控制点tag:revisions
git tag -a demotag1 -m "message"
git tag -l
git show demotag1
git checkout demotag1gitignore
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61# 在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。
# .gitignore文件本身要放到版本库里,并且可以对.gitignore做版本管理!
# 如果有些文件已经被忽略了,当使用git add时是无法添加的。需要加上-f参数才能强制添加到git中去,这样就能强制添加到缓存中去了。
# 如果我们意外的将想要忽略的文件添加到缓存中去了,我们可以使用rm命令将其从中移除
# 示例
# 表示此为注释,将被Git忽略
*.a 表示忽略所有 .a 结尾的文件
!lib.a 表示但lib.a除外
/TODO 表示仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/ 表示忽略 build/目录下的所有文件,过滤整个build文件夹;
doc/*.txt 表示会忽略doc/notes.txt但不包括 doc/server/arch.txt
bin/: 表示忽略当前路径下的bin文件夹,该文件夹下的所有内容都会被忽略,不忽略 bin 文件
/bin: 表示忽略根目录下的bin文件
/*.c: 表示忽略cat.c,不忽略 build/cat.c
debug/*.obj: 表示忽略debug/io.obj,不忽略 debug/common/io.obj和tools/debug/io.obj
**/foo: 表示忽略/foo,a/foo,a/b/foo等
a/**/b: 表示忽略a/b, a/x/b,a/x/y/b等
!/bin/run.sh 表示不忽略bin目录下的run.sh文件
*.log: 表示忽略所有 .log 文件
config.php: 表示忽略当前路径的 config.php 文件
/mtk/ 表示过滤整个文件夹
*.zip 表示过滤所有.zip文件
/mtk/do.c 表示过滤某个具体文件
被过滤掉的文件就不会出现在git仓库中(gitlab或github)了,当然本地库中还有,只是push的时候不会上传。
需要注意的是,gitignore还可以指定要将哪些文件添加到版本管理中,如下:
!*.zip
!/mtk/one.txt
唯一的区别就是规则开头多了一个感叹号,Git会将满足这类规则的文件添加到版本管理中。为什么要有两种规则呢?
想象一个场景:假如我们只需要管理/mtk/目录中的one.txt文件,这个目录中的其他文件都不需要管理,那么.gitignore规则应写为::
/mtk/*
!/mtk/one.txt
假设我们只有过滤规则,而没有添加规则,那么我们就需要把/mtk/目录下除了one.txt以外的所有文件都写出来!
注意上面的/mtk/*不能写为/mtk/,否则父目录被前面的规则排除掉了,one.txt文件虽然加了!过滤规则,也不会生效!
----------------------------------------------------------------------------------
还有一些规则如下:
fd1/*
说明:忽略目录 fd1 下的全部内容;注意,不管是根目录下的 /fd1/ 目录,还是某个子目录 /child/fd1/ 目录,都会被忽略;
/fd1/*
说明:忽略根目录下的 /fd1/ 目录的全部内容;
/*
!.gitignore
!/fw/
/fw/*
!/fw/bin/
!/fw/sf/
说明:忽略全部内容,但是不忽略 .gitignore 文件、根目录下的 /fw/bin/ 和 /fw/sf/ 目录;注意要先对bin/的父目录使用!规则,使其不被排除。
分支
1 | # 查看分支 |
远程仓库
1 | # 本地Git仓库(master)和GitHub仓库(origin)之间的传输是通过SSH加密的,Git支持多种协议,包括https,但ssh协议速度最快。 |
其他配置
1 | git config --global color.ui true |