上一篇文章,我们学习了 使用 git
如何创建一个仓库。而且还详细的介绍了 git
各个工作目录的作用。
git
: global information tracker
git
其实是内容寻址文件系统。本质是一个 key-value
的数据库。在上一篇文章了解了 git
的四种对象:提交对象,数据对象,树对象和标签对象。还学习了 git
的引用 ( HEAD
, Index
, refs
目录),以及最后学习了 git
的压缩,( git gc
).
今天我们从 简单的 git 使用流程说起。
上一篇中,我们创建了一个仓库.
1 | ➜ gitlearn git init . |
新建完仓库之后,我们一般会对仓库进行配置。
# git config
git
自带了一个 git config
工具来帮助设置控制 Git 外观和行为的配置变量。这些变量存储在三个不同的位置。
A
:/etc/gitconfig
文件:包含系统上每一个用户以及他们仓库的通用配置。 如果执行git config
时,带上 --system 选项,就会读写该配置文件中的配置属性。B
:~/.gitconfig
或~/.config/git/config
文件:只针对当前用户。使用--global
选项会让git
读写此文件,这会对你系统的上的所有仓库生效。C
: 当前使用仓库的git
目录的config
文件 (.git/config
): 只针对当前仓库。 可以使用--local
选项让git
强制读写此文件,默认情况下也会使用它。
读取顺序为: A
-> B
-> C
, C
会覆盖 B
中相同的配置, B
会覆盖 A
中相同的配置。
可以通过 git config --list --show origin 命令查查文件位置以及命令所在的文件。
一般我们新建了仓库,或者 clone
一个远程仓库到本地之后,第一件事就是配置自己的用户名和邮件地址。
刚才说过,三种配置方式的作用范围,这里一般情况下会使用 --global
。 当前登录的用户都会使用一样的配置。
1 | $ git config --global user.name "fangjiaxiaobai" |
这一点非常重要!
我们来查看一下配置的结果。
1 | $ git config --global --list |
# 修改 git 的默认文本编辑器
git
的文本编辑器有什么作用呢?
当我们的文件 在 提交代码,拉取远程代码或者切换分支出现冲突的时候, git
命令行窗口就会有一个处理冲突之后填写 commit
信息的命令行窗口,这里使用的编辑器就是 我们要说的 “文本编辑器了”。
git
中默认的文本编辑器是 nano
编辑器,我们使用进行配置,使用 vim
编辑器。
1 | ➜ gitlearn git:(master) ✗ git config --global core.editor "vim" |
配置完仓库,之后,我们就正式开始使用 git
了。
# 使用 git
进行工作
简单来讲,我们只需三步,两个命令就可以完成文件的版本控制。
- 修改文件 (创建文件,修改文件内容,删除文件)
- 使用
git add .
将文件纳入版本管理 - 使用
git commit -m "xxx"
将文件提交到版本仓库。
在我们的工作目录中 (比如 gitlearn/
), 所有的文件只有两种状态: 已跟踪
和 未跟踪
。
已跟踪的文件是指被纳入版本控制的文件。在上一次快照中有他们的记录,在工作一段时间后,他们的状态可能是未修改,已修改,或者已经放入了 暂存区
$^❶ $。
未跟踪的文件:就是 即不存在上次快照中,也没有被放入暂存区中。
这里我们再次的介绍一下 git
的工作区域:
工作区,暂存区,版本库。
工作区,就是我们修改的文件。包括:新建文件,修改文件内容,删除文件。
暂存区,就是 git
将我们修改的文件记录起来起来。
版本库,就是 git
的记录的版本变更历史。就是 .git
目录下的 objects/
等目录下的所有文件。即我们 进行了 commit
操作之后就会进入了版本库。
# 让 git
跟踪我们的文件
使用 git add
命令,可以让 git
开始跟踪一个文件。
使 git
跟踪文件 README.md
1 | ➜ gitlearn git:(master) echo 'test git跟踪文件' > README.md |
这里我们看到了,未跟踪的该文件: README.md
。我们可以使用 git add
命令,将未跟踪的文件纳入跟踪范围。
1 | ➜ gitlearn git:(master) ✗ git add README.md |
Changes to be committed
: 将要提交的变更。说明下面的文件已经是暂存状态了。使用 git rm --cached <file>...
命令可以取消暂存。此时 README.md
文件已经是 git
跟踪的了。我们再次修改一下 README.md
文件。查看一下工作区中文件的状态.
1 | ➜ gitlearn git:(master) ✗ echo 'test 再次修改已经被跟踪的文件' >> README.md |
又看到了 Changes not staged for commit
: 还没有被暂存的提交去提交。说明第二次的变更还没有被 git
跟踪起来。这就需要我们在运行一次 git add README.md
命令了。
1 | ➜ gitlearn git:(master) ✗ git add README.md |
我们可以看到,第二次更改也被 git
跟踪了起来。
git status
命令的输出十分详细,可以使用 git status -s(--short)
命令,输出非常简洁的结果.
1 | ➜ gitlearn git:(master) ✗ git status -s |
输出结果的格式是这样的:
1 | XX file1 |
左列 XX: 第一个 X 表示,暂存区的状态,第二个 X 表示工作区的状态。
XX 的规则如下:
- 新添加的未跟踪文件前面有??标记
- 新添加到暂存区中的文件前面有 A 标记
- 修改过的文件前面有 M 标记。
# 提交到版本库
现在我们就可以提交文件了。最好在每次提交之前都用 git status
看下,我们需要的文件是否都放入 暂存区了。然后再用 git commit
进行提交。
1 | ➜ gitlearn git:(master) ✗ git status |
可以看到,提交后它会告诉你,当前是在哪个分支( master
)提交的,本次提交的完整 SHA-1
校验和是什么( 463dc4f
),以及在本次提交中,有多少文件修订过,多少行添加和删改过。
以上就是我们最简单的开发流程了。
这时,如果我不想某个文件纳入版本管理,但是这个文件还必须要在工作区中呢?
# 忽略文件
在这种情况下,我们可以创建一个名为: .gitignore
的文件,列出要忽略的文件的模式。
.gitignore
文件的格式规范如下:
- 所有空行或者以 # 开头的行都会被 Git 忽略。
- 可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。
- 匹配模式可以以(/)开头防止递归。
- 匹配模式可以以(/)结尾指定目录。
- 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(!)取反。
所谓的 glob
模式是指 shell
所使用的简化了的正则表达式。 星号 (*)
匹配零个或多个任意字符; [abc]
匹配任何一个列在方括号中的字符 (这个例子要么匹配一个 a
,要么匹配一个 b
,要么匹配一个 c
); 问号 (?)
只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符, 表示所有在这两个字符范围内的都可以匹配(比如 [0-9]
表示匹配所有 0
到 9
的数字)。 使用两个星号( **
)表示匹配任意中间目录,比如 a/**/z
可以匹配 a/z
、 a/b/z
或 a/b/c/z
等。
来看一个 .gitignore
文件的例子:
1 | # 忽略所有的 .a 文件 |
假设:我们还有一个名叫: git.log
的文件。在更早的一个快照中,已经把它纳入了版本库中。现在我们要把它移除掉。应该怎么办呢
1 | ### 准备工作 |
注意:
运行 git rm
命令并不能删除文件!是从 git
中删除,使 git
不在跟踪其变化。
有时候,使用 git rm
命令并不能使文件不被 git
跟踪,因为在缓存中还跟踪了文件。 这使,可以使用 git rm -rf --cached
命令使 git
不跟踪文件。
git rm
命令也可以使用 glob
模式。
# 查看文件的修改内容
git
提供了一个命令 git diff
可以查看文件修改了那些地方.
假设:我们修改了一个文件,我要看一下修改的内容 (此时还没有提交。)
1 | ➜ gitlearn git:(master) echo 'test diff' > README.md |
使用 --staged
选项可以比较 已暂存文件与最后一次提交的文件差异。
请注意, git diff
本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动。 所以有时候你一下子暂存了所有更新过的文件,运行 git diff
后却什么也没有,就是这个原因。
# 移动文件
可以使用 git mv
命令来移动文件。
1 | ➜ gitlearn git:(master) ✗ git mv README.md README.md.md |
这个命令就相当于:
1 | $ mv README.md README.md.md |
本篇文章就到这里啦,下一篇~git 的时光机
# 最后
期望与你一起遇见更好的自己