【Git 教程系列】入门

avatar
前端工程师

基本概念

工作区、暂存区和版本库

在 Git 中,有三个核心概念:工作区,暂存区和版本库:

  • 工作区: 当前正在进行编辑和修改的项目目录,它包含了项目的实际文件和文件夹。
  • 暂存区: 暂存区(stage 或 index)是位于 Git 目录中的一个文件(.git/index),它充当了一个缓冲区,用于暂时存放即将提交的修改。
  • 版本库: 版本库是 Git 的核心部分,它存储了项目的完整历史记录和元数据信息。版本库包括了所有的提交记录(commits)、分支(branches)、标签(tags)等信息。它位于 Git 目录中,通常是一个名为 .git 的隐藏文件夹。

下图展示了工作区、版本库中的暂存区和版本库之间的关系:

image.png

HEAD

HEAD 是一个指向最新提交的指针,它可以是一个分支的引用,也可以是一个具体提交的哈希值。

在 Git 中具有以下几个重要的作用:

  1. 标记当前分支:HEAD 用于标记当前所在的分支。当你切换分支时,HEAD 会随之改变,指向新的分支引用。
  2. 当前提交:HEAD 指向当前所在分支的最新提交。这表示你在这个分支上进行的所有操作,如修改文件、提交等,都是基于该提交进行的。
  3. 建新提交:当你执行 git commit 命令提交更改时,Git 使用 HEAD 指向的提交作为新提交的父提交。这样,新提交就成为了当前分支的最新提交。

在命令行中,可以通过以下方式引用 HEAD

  • HEAD:表示当前引用的完整名称,例如 refs/heads/master
  • HEAD^:表示当前引用的父提交,可以通过增加 ^ 符号来获取更早的提交,如 HEAD^^ 表示当前引用的爷爷提交。
  • HEAD~<num>:表示当前引用的前第 <num> 个提交,如 HEAD~3 表示当前引用的前第三个提交。

常用命令

git config

配置文件位置

  • --system 使用系统级配置文件
  • --global 使用全局配置文件
  • --local 使用仓库级配置文件

操作

  • -l, --list 列出所有配置
  • --unset 删除一个变量
  • --remove-section 删除一个小节
  • --show-origin 显示配置的来源
  • --show-scope 显示配置的作用域

常用示例

设置全局用户名和邮箱

git config --global user.name 'Your Name' 
git config --global user.email 'your@example.com'

设置仓库级别的用户名和邮箱

git config user.name 'Your Name' 
git config user.email 'your@example.com'

查看单个配置

git config user.name

查看所有配置

git config --list

删除单个配置

git config --global --unset user.name

git init

把当前的目录变成可以管理的 git 仓库,生成隐藏 .git 文件夹

  • -b, --initial-branch <名称> 设置默认的分支名称

常用示例

初始化新的 Git 仓库

git init

初始化新的 Git 仓库并设置默认分支

git init -b <branch-name>

初始化新的 Git 仓库并指定目录

git init <dir_name>

git clone

克隆远程 Git 仓库到本地

常用示例

克隆远程仓库到当前目录

git clone <remote-url>

克隆远程仓库到指定目录

git clone <remote-url> <local-directory>

克隆指定分支的远程仓库

git clone --branch <branch-name> <remote-url>

git add

将文件的更改添加到暂存区

  • -i, --interactive 交互式拣选
  • -p, --patch 交互式挑选数据

常用示例

添加单个文件

git add <file_path>

添加多个文件

git add <file_path_1> <file_path_2> ...

添加所有文件

git add .

注意:. 代表当前目录

git rm

从工作区和索引中删除文件

  • --cached 只从索引区删除

示例

# 将文件从暂存区删除
git rm --cached index.ts

git checkout

注意 Git v2.23 之后,建议使用 git switch 替换

切换分支或恢复工作树中的文件

示例

# 切换当前分支为 master
git checkout master

git restore

恢复工作区文件

示例

# 将制定文件 index.ts 恢复到工作区
git restore index.ts

# 将所有文件恢复到工作区
git add .

git mv

移动或重命名文件、目录

  • -f, --force 强制移动/重命令,即使目标存在

常用示例

重命名文件

git mv <old_file_path> <new_file_path>

移动文件到新的目录

git mv <file_path> <new_directory_path>/<file_name>

git log

查看 Git 提交历史

常用示例

查看完整的提交历史

git log

显示简化的提交历史

git log --oneline

查看指定分支的提交历史

git log <branch-name>

查看单个文件的提交历史

git log <file>

限制提交记录的数量

git log -n <number>

git cherry-pick

将已经提交的 commit,复制出新的 commit 应用到当前分支

选项

  • -e, --edit 编辑提交说明
  • -n, --no-commit 不要自动提交
  • --ff 允许快进合并
  • -x 包含原始提交的引用

序列命令

  • --quit 退出操作,会保留已经 cherry-pick 成功的 commit
  • --continue 继续操作
  • --abort 取消操作,回到操作前的样子
  • --skip 跳过当前提交

这些命令只适用于正在进行的 cherry-pick 序列,而不适用于单个提交的 cherry-pick 操作

常用示例

复制单个

git cherry-pick <commit-hash>

复制多个

git cherry-pick <commit-hash1> <commit-hash2> <commit-hash3> ...

复制连续多个

git cherry-pick <start-commit>..<end-commit>
git cherry-pick <start-commit>^..<end-commit>

加了 ^ 符号表示包含 <start-commit> 提交

复制分支最新的提交

git cherry-pick <branch-name>

git status

示当前仓库中所有已修改的文件的状态

  • -v, --verbose 冗长输出
  • -s, --short 以简洁的格式显示状态,状态代码的含义如下
    • ??:未跟踪的文件。
    • A:新增的文件。
    • M:已修改的文件。
    • D:已删除的文件。
    • R:文件名已修改。
    • C:文件的拷贝/修改已冲突。

示例

# 显示状态
git status

# 以简洁的格式显示状态
git status -s

git branch

列出、创建或删除分支

  • d, --delete 删除完全合并的分支
  • -D 删除分支(即使没有合并)
  • -m, --move 移动/重命名一个分支,以及它的引用日志
  • -u, --set-upstream-to 设置当前分支的远程分支
  • --unset-upstream 取消远程分支的设置

常用示例

创建新分支

git branch <branch_name>

切换分支

git switch <branch_name>

列出分支

git branch

合并分支

git merge <branch_name>

删除分支

git branch -d <branch_name>

重命名

git branch -m <old_branch_name> <new_branch_name>

建立本地分支和远程分支的关联

git branch --set-upstream <branch_name> origin/<branch_name>

git stash

临时保存当前工作进度

常用示例

保存当前的工作进度,并添加一个可选的描述信息

git stash save "message"
  

查看所有保存的存储项列表

git stash list

恢复最新的存储项到工作目录,但不删除存储项

git stash apply

恢复最新的存储项到工作目录,并删除存储项

git stash pop

删除最近的存储项

git stash drop

删除指定的存储项

git stash drop <stash>

删除 stash 的所有记录

git stash clear

git commit

将更改保存到 Git 仓库

  • -m, --message <说明> 提交说明
  • -a, --all 提交所有改动的文件
  • --amend 修改先前的提交

常用示例

基本提交

git commit -m "Commit message"

将所有更改提交

git commit -a -m "Commit message"

编写详细的提交信息

git commit

提交并修改上一次提交的信息

git commit --amend

git merge

将一个分支的更改合并到当前分支

常用示例

合并指定分支到当前分支:

git merge <branch-name>

合并远程分支到当前分支:

git merge origin/<branch-name>

合并并创建合并提交

git merge --no-ff <branch-name>

git rebase

在另一个分支上重新应用提交

  • r, --rebase-merges[=<模式>] 交互式编辑和修改提交历史

常用示例

将当前分支的更改应用到目标分支上:

git rebase <branch-name>

将远程分支的更改应用到当前分支上:

git rebase origin/<branch-name>

将当前分支的多个提交合并为单个提交:

git rebase -i HEAD~3

git reset

重置当前 HEAD 到指定状态

  • --hard  重置 HEAD、索引和工作区

常用示例

撤销提交并保留更改:

git reset HEAD~1

撤销提交并丢弃更改:

git reset --hard HEAD~1

取消暂存的更改:

git reset HEAD

移动分支指针位置:

git reset <commit-hash>

git switch

注意 Git v2.23 之后,建议使用此命令替换 git checkout

切换分支或还原工作树文件

  • -c, --create <分支> 创建并切换一个新分支
  • -C, --force-create <分支> 创建/重置并切换一个分支
  • --discard-changes 丢弃本地修改

常用示例

切换到现有分支:

git switch <branch-name>

切换到上一个分支

git switch -

创建新分支并切换到该分支

git switch -c <new-branch-name>

丢弃本地修改并切换到其他分支

git switch -f <branch-name>

切换到特定的提交(分离 HEAD)

git switch <commit-hash>

git tag

创建、操作标签

  • -l, --list 列出标签列表
  • -n[<n>] 每个标签信息打印 n 行
  • -d, --delete 删除标签

标签创建选项

  • -a, --annotate 附注标签,需要一个说明
  • -m, --message <说明> 标签说明

常用示例

创建轻量级标签

git tag <tag_name>

创建带注释的标签

git tag -a <tag_name> -m "Tag message"

查看标签

git tag

查看特定标签的详细信息

git show <tag_name>

给指定提交创建标签

git tag <tag_name> <commit_sha>

删除本地标签

git tag -d <tag_name>

删除远程标签

# 请先删除本地标签
git push origin :refs/tags/<tag_name>

推送标签到远程仓库

git push origin <tag_name>

推送所有标签到远程仓库

git push origin --tags

git fetch

从另外一个仓库下载对象和引用

git pull

从远程仓库拉取最新代码并合并到当前分支

  • -r, --rebase[=(false|true|merges|interactive)] 使用变基操作取代合并操作以合入修改
  • --all 从所有的远程抓取
  • -f, --force 强制覆盖本地分支
  • -t, --tags 抓取所有的标签和关联对象

常用示例

拉取并合并远程分支

git pull <remote> <branch>

拉取并与当前分支合并

git pull

拉取并重新应用变基

git pull --rebase

拉取所有分支

git pull --all

git push

将本地代码推送到远程仓库

  • -all 推送所有分支
  • -f, --force 强制更新

常用示例

推送到默认远程分支

git push

推送到指定的远程分支

git push <remote> <branch-name>

强制推送

git push --force

推送所有分支

git push --all

参考资源