1
0
wiki/Tech/getting-started/版本控制/Git/入门/基础.md

356 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 基础
description: Git 基础操作
keywords:
- Git
- 基础
tags:
- Git/入门
- 技术/入门
author: 7Wate
date: 2022-09-13
---
本章涵盖了你在使用 Git 完成各种工作时将会用到的各种基本命令。 在学习完本章之后你应该能够配置并初始化一个仓库repository、开始或停止跟踪track文件、暂存stage或提交commit更改。
本章也将向你演示了如何配置 Git 来忽略指定的文件和文件模式、如何迅速而简单地撤销错误操作、如何浏览你的项目的历史版本以及不同提交commits之间的差异、如何向你的远程仓库推送push以及如何从你的远程仓库拉取pull文件。
## 获取 Git 仓库
通常有两种获取 Git 项目仓库的方式:
1. 将尚未进行版本控制的本地目录转换为 Git 仓库。
2. 从其它服务器克隆一个已存在的 Git 仓库。
### 在目录中初始化仓库
```shell
// 当前目录下初始化仓库
git init
```
该命令将创建一个名为 .git 的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件是 Git 仓库的骨干。
### 克隆现有的仓库
如果你想获得一份已经存在了的 Git 仓库的拷贝,比如说,你想为某个开源项目贡献自己的一份力,这时就要用到 git clone 命令。
```shell
// 克隆远程仓库
git clone <url>
```
如果你想在克隆远程仓库的时候,自定义本地仓库的名字,你可以通过额外的参数指定新的目录名:
```shell
// 指定仓库本地命名
git clone <url> <name>
```
克隆现有的仓库,实际上是**多个命令的分解**。首先初始化一个本地仓库,接着添加远程仓库,最后拉取远程仓库数据到本地。
## 记录每次更新到仓库
当我们成功拥有一个仓库后,可以运行 git status 当仓库状态。在未进行开发的情况下,仓库都是干净的。当我们在工作目录对文件进行了变动,此时工作目录下的每一个文件都不外乎这两种状态:
- **已跟踪**:指那些被纳入了版本控制的文件,在上一次快照中有它们的记录,在工作一段时间后, 它们的状态可能是未修改,已修改或已放入暂存区。简而言之,已跟踪的文件就是 Git 已经知道的文件。
- **未跟踪**:工作目录中除已跟踪文件外的其它所有文件都属于未跟踪文件,它们既不存在于上次快照的记录中,也没有被放入暂存区。
运行 git status 就会显示我们对那些文件进行了变动,那些是已跟踪,那些是未跟踪。接着我们可以使用 git add 将文件添加至暂存区。添加至暂存区后可以提交更新或继续工作;如果继续工作,同时对已暂存的文件进行了更改,可以使用 git diff 查看该文件工作区和暂存区之间的差异。
如果提交新修改的文件至暂存区,暂存区的文件会被新提交的覆盖。完成所有的工作开发,并且提交至暂存区后,就运行 git commit 提交更新至 git 目录,记录此次快照。
进行多次开发之后,想要回顾一下提交历史,可以使用 git log 查看提交历史。
### 忽略文件
有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。
在这种情况下,我们可以创建一个名为 .gitignore 的文件,列出要忽略的文件的模式,不同目录下可以拥有不同的 .gitignore 。
#### .gitignore 格式规范:
- 所有空行或者以 # 开头的行都会被 Git 忽略。
- 可以使用标准的 glob 模式匹配它会递归地应用在整个工作区中glob 模式是指 shell 所使用的简化了的正则表达式)。
- 匹配模式可以以(/)开头防止递归。
- 匹配模式可以以(/)结尾指定目录。
- 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(!)取反。
> GitHub 有一个十分详细的针对数十种项目及语言的 .gitignore 文件列表, 你可以在 <https://github.com/github/gitignore> 找到它。
### 检查当前仓库状态
```shell
// 查看当前仓库状态总览
git status
// 查看当前仓库状态简览
git status -s
git status --short
// 当前文件和暂存区之间的具体差异
git diff
// 暂存区和最后一次提交的具体差异
git diff --staged
git diff --cached
```
### 踪新文件或暂存已修改的文件
```shell
// 添加文件到暂存区
git add <file>
// 添加路径到暂存区
git add <path>
```
### 提交更新
```shell
// 提交更新,同时会启动文本编辑器来输入提交说明。
git commit
// 将提交信息与命令放在同一行
git commit -m <msg>
// 跳过暂存,直接提交已跟踪文件。
git commit -a
```
## 查看提交历史
### Git Log 的常用选项
```shell
// 格式化输出一行显示提交历史
git log --oneline
```
| 选项 | 说明 |
| --------------- | ------------------------------------------------------------ |
| -p | 按补丁格式显示每个提交引入的差异。 |
| --stat | 显示每次提交的文件修改统计信息。 |
| --shortstat | 只显示 --stat 中最后的行数修改添加移除统计。 |
| --name-only | 仅在提交信息后显示已修改的文件清单。 |
| --name-status | 显示新增、修改、删除的文件清单。 |
| --abbrev-commit | 仅显示 SHA-1 校验和所有 40 个字符中的前几个字符。 |
| --relative-date | 使用较短的相对时间而不是完整格式显示日期比如“2 weeks ago”。 |
| --graph | 在日志旁以 ASCII 图形显示分支与合并历史。 |
| --pretty | 使用其他格式显示历史提交信息。可用的选项包括 oneline、short、full、fuller 和 format用来定义自己的格式。 |
| --oneline | --pretty=oneline --abbrev-commit 合用的简写。 |
### Git Log --pretty=format 常用的选项
```shell
// format 可以定制记录的显示格式
git log --pretty=format:"%h - %an, %ar : %s"
```
| 选项 | 说明 |
| ---- | --------------------------------------------- |
| %H | 提交的完整哈希值 |
| %h | 提交的简写哈希值 |
| %T | 树的完整哈希值 |
| %t | 树的简写哈希值 |
| %P | 父提交的完整哈希值 |
| %p | 父提交的简写哈希值 |
| %an | 作者名字 |
| %ae | 作者的电子邮件地址 |
| %ad | 作者修订日期(可以用 --date=选项 来定制格式) |
| %ar | 作者修订日期,按多久以前的方式显示 |
| %cn | 提交者的名字 |
| %ce | 提交者的电子邮件地址 |
| %cd | 提交日期 |
| %cr | 提交日期(距今多长时间) |
| %s | 提交说明 |
### Git Log 限制输出的选项
| 选项 | 说明 |
| ----------------- | ------------------------------------------ |
| -n | 仅显示最近的 n 条提交。 |
| --since, --after | 仅显示指定时间之后的提交。 |
| --until, --before | 仅显示指定时间之前的提交。 |
| --author | 仅显示作者匹配指定字符串的提交。 |
| --committer | 仅显示提交者匹配指定字符串的提交。 |
| --grep | 仅显示提交说明中包含指定字符串的提交。 |
| -S | 仅显示添加或删除内容匹配指定字符串的提交。 |
## 撤消操作
有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 --amend 选
项的提交命令来重新提交:
```shell
// 撤销上次提交
git commit --amend
```
此命令会将当前暂存区的文件一并提交,最终只会有一个提交——第二次提交将代替第一次提交的结果。
### 撤销已暂存的文件
```shell
// 取消暂存区文件
git reset HEAD <file>
```
git reset 确实是个危险的命令,如果加上了 --hard 选项则更是如此。 然而在上述场景中,工作目录中的文件尚未修改,因此相对安全一些。
### 撤消对文件的修改
```shell
// 撤销工作区的文件修改
git checkout -- <file>
```
请务必记得 `git checkout -- <file>` 是一个危险的命令。 你对那个文件在本地的任何修改都会消失——Git 会用最近提交的版本覆盖掉它。 除非你确实清楚不想要对那个文件的本地修改了,否则请不要使用这个命令。
## 远程仓库
为了能在任意 Git 项目上协作,你需要知道如何管理自己的远程仓库。远程仓库是指托管在因特网或其他网络中
的你的项目的版本库。
你可以有好几个远程仓库,通常有些仓库对你只读,有些则可以读写。 与他人协作涉及管理远程仓库以及根据需要推送或拉取数据。 管理远程仓库包括了解如何添加远程仓库、移除无效的远程仓库、管理不同的远程分支并定义它们是否被跟踪等等。
### 查看远程仓库
运行 git remote 命令,查看你已经配置的远程仓库服务器。
```shell
// 查看远程仓库
git remote
```
也可以指定选项 -v会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL
```shell
// 显示远程仓库简写及其 URL
git remote -v
```
### 添加远程仓库
你可以运行 `git remote add <shortname> <url>` 添加一个新的远程 Git 仓库,同时指定一个方便使用的简写:
```shell
// 添加一个新的远程 Git 仓库
git remote add <remote-name> <url>
```
### 从远程仓库中抓取与拉取
当你添加远程仓库后,可以从远程仓库拉取数据。
```shell
// 从远程仓库拉取数据,不自动合并。
git fetch <remote-name>
// 从远程仓库抓取数据,并尝试自动合并到当前分支。
git pull
```
### 推送到远程仓库
当你想分享你的项目时,必须将其推送到上游。
```shell
// 推送分支到远程仓库
git push <remote> <branch>
```
### 查看、重命名与移除远程仓库
你可以使用以下命令,对远程仓库进行查看、重命名与移除操作。
```shell
// 查看远程仓库
git remote show <remote>
// 远程仓库的重命名
git remote rename <old> <new>
// 远程仓库的移除
git remote remove <name>
```
## 打标签
Git 可以给仓库历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点( v1.0 、 v2.0 等等)
Git 支持两种标签:**轻量标签lightweight**与**附注标签annotated**。
轻量标签很像一个不会改变的分支——它只是某个特定提交的引用。
而附注标签是存储在 Git 数据库中的一个完整对象, 它们是可以被校验的,其中包含打标签者的名字、电子邮件地址、日期时间, 此外还有一个标签信息,并且可以使用 GNU Privacy Guard GPG签名并验证。 通常会建议创建附注标签,这样你可以拥有以上所有信息。
但是如果你只是想用一个临时的标签, 或者因为某些原因不想要保存这些信息,那么也可以用轻量标签。
### 创建标签
```shell
// 创建轻量标签
git tag <tagname>
// 创建附注标签
git tag -a <tagname>
```
你也可以对过去的提交打标签。,只需要输入提交的 SHA-1 数。
```shell
// 后期打标签
git tag <tagname> <commit-id>
```
### 查看标签
```shell
// 列出已有的标签
git tag
// 显示标签信息
git show <tagname>
```
### 共享标签
默认情况下git push 命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。
```shell
// 推送标签到远程仓库
git push origin <tagname>
// 推送全部标签
git push origin --tags
```
### 删除标签
```shell
// 删除标签
git tag -d <tagname>
// 删除远程仓库标签
git push origin --delete <tagname>
```
## Git 别名
Git 并不会在你输入部分命令时自动推断出你想要的命令。 如果不想每次都输入完整的 Git 命令,可以通过 git
config 文件来轻松地为每一个命令设置一个别名。如下:
```shell
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
```
接下来我们就可以使用 git co 等价代替 git checkout其他同理。