Git 基础操作
1 基本理念
Git是一种用于对项目版本进行控制管理的工具。不同于其他存储差异的版本控制工具,Git基于快照索引。每次保存项目更新,建立项目所有改动文件的快照,然后以快照索引表示一个版本。文件没有变动则指向上一个版本的快照。这里的索引实际上就是哈希值。
因为基于快照,所以Git一般情况下不存在删除的概念。Git存在三种状态:
- 已修改(modified):表示修改了文件,但还没保存到数据库中。
- 已暂存(committed):对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。
- 已提交(staged):表示数据已经安全地保存在本地数据库中。
基于三种状态,可以将Git项目分为三个区域:
- 工作区:从仓库中提取某个版本,供用户编辑修改。
- 暂存区:一个用于保存本次修改文件列表信息的文件。
- 仓库目录:保存项目的元数据和对象数据库,仓库克隆就是克隆仓库目录。
2 运行配置
git存在三级配置,分别是系统级,用户级,仓库级。对应的变量为 --system
、--global
以及--local
,默认是仓库级配置。
使用前需要配置用户信息:
1 | $ git config --global user.name username |
3 基础操作
3.1 获取仓库
3.1.1 本地初始化
在项目的根目录下执行相关命令:
1 | git init #初始化 |
初始化后,会生成.git
文件,存储git的所有有关信息。然后建立对项目文件的追踪,然后将其作为原始版本提交到git仓库中。
3.1.2 克隆仓库
如果想要在一个已存在的仓库上进行操作,可以通过克隆仓库。克隆仓库的命令是 git clone <url> <local path>
。
3.2 文件管理
3.2.1 文件状态
项目中的文件只存在两种状态:已跟踪或未跟踪。通过git status
来查看当前项目的文件状态。使用git status -s
命令或git status --short
命令可以获得紧凑输出。通过"git add <filename>..."
来对文件进行跟踪。
1 | (base)ubuntu:~/Learn/git $git status |
需要注意git add
命令本意并不是添加追踪而是,将修改添加到下次提交中,即添加到暂存区。
1 | (base) ubuntu:$ git status |
通过命令 git rm <filename>
将文件从跟踪状态转换为未跟踪状态。
3.2.2 忽略文件
创建 .gitignore
文件,通过该文件控制哪些文件无需纳入Git管理。文件.gitignore
的格式规范如下:
- 所有空行或者以#开头的行都会被Git忽略。
- 可以使用标准的glob模式匹配,它会递归地应用在整个工作区中。
- 匹配模式可以以(/)开头防止递归。
- 匹配模式可以以(/)结尾指定目录。(build/)
要忽略指定模式以外的文件或目录,可以在模式前加上叹号(!)取反。
glob 模式:
星号(*)匹配零个或多个任意字符;
使用两个星号(**)表示匹配任意中间目录.
[abc] 匹配任何一个列在方括号中的字符 (这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c);
问号(?)只匹配一个任意字符;
如果在方括号中使用短划线分隔两个字符, 表示所有在这两个字符范围内的都可以匹配 (比如 [0-9] 表示匹配所有 0 到 9 的数字)。
3.3 提交
未暂存修改:git diff
提交命令:git commit
,命令 git commit -a
相当于git add
和git commit
的组合。
查看历史:git log
3.4 撤销操作
可以通过git commit --amend
来实现重新提交:
1 | $ git commit -m 'initial commit' |
git checkout --<filename>
可以撤销修改,但是不推荐危险系数很高。
3.5 远程仓库
添加远程仓库:git remote add <remote> <url>
。
从远程仓库抓取:git fetch <remote>
访问远程仓库,从中拉取所有本地还没有的数据。
从远程仓库拉取:git pull <remote>
自动抓取后合并该远程分支到当前分支。
推送:git push <remote> <branch>
将相应的分支推送至远程仓库。
重命名远程仓库: git remote rename <oldremote> <newremote>
移除远程仓库:git remote remove <remote>
3.6 标签
附着标签:git tag -a <tag> -m "<message>"
轻量化标签:git tag <tag>
推荐使用附着标签
4 分支
4.1 存储结构
使用链表存储commit,每个commit指向当前快照,每个快照都是一个树结构指向具体的文件。
而分支则是指向commit链上节点的指针,通过Head指针确定当前分支。
4.2 分支基础操作
分支创建:git branch <branch>
分支切换:git checkout <branch>
添加 -b
实现创建于切换。
分支合并:git merge <branch>
如果存在完整的指针链可以直接移动过去。如果存在支路则需要创建新的commit。
优势存在分支冲突,需要手动的选择保留的代码。
推送: git push <remote> <localbranch>:<remotebranch>
跟踪远程分支 git checkout --track <remote>/<branch>
等价于git checkout -b <branch> <remote>/<branch>
4.3 变基
变基就是将当前分支的操作在目标分支上进行重操作,变基的目的是为了让提交看起来更简洁。如果提交存在于本地仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。
1 | $ git checkout <当前分支> |