Git基础使用

1. Git基础概念与文件结构

1.1 基础概念

  • 分布式版本控制系统(DVCS)

    • 每个开发者拥有完整仓库副本,包括全部历史记录。
    • 支持离线操作,仅在推送/拉取时需要网络。
  • 快照机制

    • Git记录每次文件快照,而不是单纯的差异。
    • 每一次提交都可以回溯和恢复。
  • 数据完整性

    • 所有数据通过SHA-1哈希校验,防止篡改。
    • SHA-1 可以将任意长度的数据(如文件内容、目录结构、提交信息等)转换为一个长度为 40 位的十六进制字符串。这种哈希值几乎不会重复(极低概率),因此可以唯一标识每一个对象(文件快照、提交、分支等)。
  • 分支与合并

    • 分支操作轻量,便于并行开发。
    • 合并与变基让代码历史更清晰。
  • 协作与审查

    • 支持多人协作,代码审查(Pull Request/Merge Request)是业界标准流程。

1.2 文件结构

Git仓库中主要包含以下文件和目录:

1.2.1 工作区(Working Directory)

  • 当前项目文件夹,开发者实际操作和编辑的地方。
  • 文件状态分为:已修改(modified)、已暂存(staged)、已提交(committed)。

1.2.2 暂存区(Stage/Index)

  • 一个临时区域,用于记录你准备提交到仓库的文件和更改
  • 通过 git add 命令将修改从工作区添加到暂存区。暂存区相当于"快照",只有被添加到暂存区的内容才会被下一次提交记录。
  • 位于.git/index

2.3 本地仓库(Local Repository)

  • 本地仓库是你电脑上的 Git 仓库,包含所有提交(commit)的历史记录,当你执行 git commit 命令时,暂存区的内容会被保存到本地仓库,生成一个新的提交。
  • 本地仓库记录了项目的所有版本和变更历史。
  • 本地仓库位于 .git 目录下,包含所有项目元数据和对象。

2.4 远程仓库(Remote Repository)

  • 远程仓库是托管在服务器上的 Git 仓库,比如 GitHub、GitLab、Gitee、GitCode 等。
  • 通过 git pushgit pull 与远程仓库同步数据。

2.5 HEAD

  • HEAD 是 Git 的一个指针,指向当前本地仓库的最新提交(commit)。
  • 它帮助你知道当前处于哪个分支、哪个版本。
  • tips: 保存在 .git/HEAD

2.6 分支(Branch)

  • 分支允许你在主线之外进行开发,便于多人协作和功能开发。
  • 一些客户端还存在虚拟分支的概念(GitButler

2.7 总结

工作流程

graph LR A[工作区] --> B[暂存区] B --> C[本地仓库] C --> D[远程仓库]

总结描述

区域 作用 典型操作
工作区 编辑和查看代码 编辑、修改文件
暂存区 临时保存待提交的更改 git add
本地仓库 保存所有提交的历史记录 git commit
远程仓库 团队共享和备份代码 git push/pull

2. Git安装/配置

安装

  • win/mac都可以通过在官网下载二进制包安装
  • Mac: brew install git
  • Windows(mac/linux也可以) 直接在官网下载安装:Git二进制文件
  • 以上都可以参照菜鸟教程

配置

  • 用户信息

    bash 复制代码
    # --global 配置全局,不指定会配置为当前工作目录(--local)
    git config --global user.name "runoob"
    git config --global user.email test@runoob.com
  • 仓库配置(没什么卵用)

    bash 复制代码
    git config --local remote.origin.url "https://github.com/your/repo.git"
  • 文本编辑器(没什么用,默认是vi/vim,可以指定为vscode)

    bash 复制代码
    git config --global core.editor "code --wait"
  • 生成SSH秘钥

    bash 复制代码
    # 无特殊要求无脑回车即可
    ssh-keygen -t rsa -b 4096 -C "yourname.email@example.com"
  • 查看配置

    bash 复制代码
    git config --list

3. Git基本命令详解(含场景与代码)

3.1 初始化与克隆

  • 场景:新项目或获取已有项目代码

  • git init:初始化本地仓库

    bash 复制代码
    git init
  • git clone:克隆远程仓库

    bash 复制代码
    git clone https://github.com/user/repo.git

3.2 文件管理

  • git add:跟踪/添加文件到暂存区

    bash 复制代码
    git add <file>
    git add .  # 添加所有改动过的文件(注意不要把不需要管理的添加进去,如一些本地的配置文件)
    git add a.txt b.js c.java d.go # 添加多个文件
    # 使用通配符添加
    git add *.txt    # 添加当前目录下所有txt后缀的文件
    git add '**/*.js' # 添加当前目录以及子目录下所有的 `.js` 文件
    git add test_* # 添加当前目录下所有以 `test_` 开头的文件
    # 添加所有未跟踪文件
    git add --all
    git add -A
    # 添加已修改文件(删除或修改的,不会添加新增的)
    git add -u
    # 交互式添加(只能对已被Git跟踪的文件的"部分修改"进行交互式暂存,而新建的文件(未被跟踪的)并不会被 `git add -p` 识别)
    # 
    git add -p [filename]

    git add -p 交互式选项

    选项 含义
    y 暂存(stage)这块改动,即把这块修改加入到本次提交中
    n 跳过(do not stage)这块改动,即这块修改不会加入到暂存区
    q 退出(quit) ,停止当前操作
    a 暂存所有剩余的块(stage all) ,把后面所有块都暂存
    d 跳过所有剩余的块(do not stage all) ,后面所有块都不暂存
    s 拆分(split)当前块为更小的块,便于更精细地选择哪些改动要暂存
    e 编辑(edit)当前块,可以手动修改要暂存的内容(有点麻烦)
    ? 显示帮助信息,列出所有可用的选项
  • git status:查看当前状态

bash 复制代码
# 当前所在分支
# 工作区和暂存区的文件状态
# 哪些文件被修改但还未暂存
# 哪些文件已被暂存准备提交
# 是否有新建未跟踪(untracked)的文件
# 是否有文件被删除或重命名
git status [filename]
  • git rm:删除文件并从Git中移除
bash 复制代码
# 删除操作完成后需要git commit 提交
git rm [filename]    # 会删除本地文件和暂存区
git rm test.1 test.2 #删除多个文件
git rm  -r testfolder # 递归删除目录下的所有文件
git rm --cached [filename]  # 将文件从暂存区删除,但本地文件不删除,比如.env和一些本地环境文件
# git rm配合.gitignore 
# 如果某个文件**已经被 Git 追踪(已经 add 或 commit)** ,即使你后来把它写进 `.gitignore`,Git 依然会继续追踪它。
#此时,单靠 `.gitignore` 没法让 Git 忽略该文件。你需要用 `git rm --cached <文件/目录>` 将其从版本库中移除(但保留本地文件),这样后续 `.gitignore` 才能生效

3.3 提交与日志

3.3.1 git commit:提交暂存区到本地仓库

3.3.1.1 基础使用
bash 复制代码
# 标准提交 
git add [filename]     
git commit -m '提交说明'  #如果不添加-m 就会打开默认编辑器让输入(vi/vim/上面指定的vscode编辑器)
# 提交所有已暂存的更改 -a会自动把所有已跟踪(tracked)文件的更改添加到暂存区并提交,不会添加新文件(未被add 的新文件不会被提交)
git commit -a -m "直接提交所有修改"
# 修正上一次提交说明
git commit --amend -m "新的提交说明"
3.3.1.2 典型场景
  • 新增文件 :必须先 git add,否则 git commit -a 不会提交新文件。
  • 修改文件 :如果都是已跟踪文件,可直接 git commit -a
3.3.1.3 提交规范:约定式提交
  1. 格式

    xml 复制代码
    <类型>[可选范围]: <描述>
        
    #   类型:必填,标明本次提交的变更类别
    #   范围:可选,说明影响的模块或文件
    #   描述:必填,对本次变更的简要说明
  2. 类型说明

    类型 说明
    feat 新功能(feature)
    fix 修复 bug
    docs 文档变更
    style 代码格式(不影响逻辑)
    refactor 重构(不影响功能的代码变动)
    perf 性能优化
    test 增加或修改测试
    chore 其他杂项(构建、工具等)
    build 构建相关变更
    ci CI/CD 配置变更
  3. 示例

    • 单行提交
    text 复制代码
    feat: 新增用户注册接口
    fix: 修复订单列表分页错误
    docs: 更新API使用说明文档
    style: 格式化代码,统一缩进
    refactor: 优化数据处理流程
    perf: 提升首页加载速度
    test: 增加订单模块单元测试
    chore: 更新依赖包版本
    build: 配置webpack打包
    ci: 优化GitHub Actions流程
    • 带范围提交
    text 复制代码
    feat(user): 新增用户注册接口 
    fix(order): 修复订单列表分页错误 
    docs(api): 更新API使用说明文档
    • 多行提交:第一行为简要说明,后面可以空一行补充详细内容:
    text 复制代码
    fix(order): 修复订单列表分页错误 
    原因:分页参数校验不严导致数据重复。 
    解决方案:增加参数校验逻辑,优化分页处理。

3.3.2 git log:查看提交历史(可视化工具更好用)

基础使用:查看提交历史记录的命令。它可以帮助你追踪项目的变更、查找具体提交、了解每次提交的作者、时间和说明

3.3.2.1: 基础使用
bash 复制代码
git log
# 显示简洁一行(oneline)
git log --oneline --graph
# 指定展示数量
git log -n 5
# 显示提交内容差异
git log -p
# 按作者筛选
git log --author="张三"
# 按文件筛选
git log [filenmae]

3.4 比较与回退(对比变更、撤销操作

用于比较文件差异 的命令,可以帮助你查看代码的修改内容、未提交的变更、不同分支或提交之间的差异。 主要用于代码审查 :查看本地未提交的变更,回溯历史 :对比不同提交或分支的代码差异,协作开发:分析合并冲突前后的具体修改。

3.4.1 git diff:查看未暂存或已暂存的差异

3.4.1.1 基础使用
bash 复制代码
# 显示工作区与暂存区之间的差异(还没有 `git add` 的修改内容)。
git diff
# 查看已暂存但未提交的更改
git diff --cached
# 比较两个提交之间的差异
git diff <commit1> <commit2>
# 比较当前分支与其他分支差异
git diff master develop
# 比较某个文件的差异
git diff [文件名]
3.4.1.2 输出内容说明

- 开头表示被删除的内容 + 开头表示新增的内容

3.4.1.3 常用组合
bash 复制代码
# 强制彩色输出,便于阅读(使用warp终端,不指定也是彩色,和终端有关?)
git diff --color
# 只显示被修改的文件名。
git diff --name-only
# 按单词显示差异,适合文本文件
git diff --word-diff

3.4.2 git checkout:恢复文件或切换分支

用于切换分支、还原文件、回退到指定提交的命令。它是日常开发中非常常用的操作工具

3.4.2.1 基础使用

bash 复制代码
git checkout <branch>
# 新建并切换分支
git checkout -b <branch>
# 回退到某个提交(detached HEAD 游离HEAD-原本指向分支,执行后指向某次提交)
git checkout <commit_id>
# 恢复文件到某个版本
git checkout <commit_id> -- <filenmae>
# 丢弃工作区的修改
git checkout -- <filename>

3.4.2.2 使用场景

  • 临时查看历史版本
bash 复制代码
git checkout <commit_id>
  • 基于历史提交新建分支 比如发现某个历史提交是个稳定版本,想在此基础上开发新功能
bash 复制代码
git checkout <commit_id>
git checkout -b <new_branch_name>
  • 调试、定位历史bug
bash 复制代码
git checkout 3e2f7a1
# 调试代码,再次条件下修改代码 后续切换回主分支回直接丢弃修改
  • 撤销某个文件的部分修改
bash 复制代码
git checkout <commit_id> -- <filename>
  • 局部回退 只回退某个文件,不影响其他文件
bash 复制代码
git checkout <commit_id> -- <filename>
git add <filename>
git commit -m '回退xx文件到历史版本'
  • 对比
命令 影响范围 典型用途 风险/注意事项
git checkout <commit_id> 全部文件 回溯历史、调试、基于历史新建分支 游离HEAD,提交容易丢失
git checkout <commit_id> -- <filename> 单个文件 局部还原、撤销误操作、参考历史内容 只影响指定文件,需 add/commitHEAD,提交容易丢失

3.4.3 git switch

Git 2.23 及以上版本新增的命令,用于切换分支或创建新分支 。它是对 git checkout 的语义化拆分,使操作更直观、更安全。

3.4.3.1 基础使用
bash 复制代码
# 切换到已有分支
git switch <branch> # 等价于 git checkout <branch>
# 新建并切换分支
git switch -c <new_branch> #等价于git checkout -b <new_branch>
# 强制切换(丢弃未提交的更改)
git switch --force <branch> # 如果工作区有未提交的修改,强制切换会丢弃这些更改。
# ### 切换到远程分支(自动创建本地分支)
git switch origin/dev

tip:未提交指的是没有git commit的内容(只要还没到"本地仓库",都属于"未提交内容"。)

plaintext 复制代码
工作区(你编辑的文件)
   │
git add
   │
暂存区(stage/index)
   │
git commit
   │
本地仓库(repository)

3.4.4 git restore

Git 2.23+ 新增的命令,用于还原文件内容 ,替代部分 git checkout 的功能。它让文件恢复操作更直观、更安全

3.4.4.1 基础使用
bash 复制代码
# 丢弃工作区的修改(恢复到暂存区状态)
git restore <filename> # 只影响工作区,未 add 的修改会被丢弃,文件恢复到暂存区的内容
# 丢弃暂存区的修改(恢复到工作区状态)
git restore --staged <文件名> # 只影响暂存区,已 add 的内容会被移出暂存区,恢复到工作区当前状态。
# 恢复文件到某个历史提交
git restore --source <commit_id> <filename> # 把文件恢复到指定历史提交的内容,适合局部回退,相当于 git checkout <commit_id> -- <filename>
3.4.4.2 常见场景
  1. 你编辑了文件但发现有误,不想保留这些修改

    bash 复制代码
    git restore app.js
  2. 不小心 git add 了某个文件,想撤回到未暂存状态

    bash 复制代码
    git restore --staged app.js
  3. 局部回退到历史版本

    bash 复制代码
    git restore --source <commit_id> app.js

3.4.5 git reset

主要用于重置 HEAD 的指向、管理暂存区和工作区的内容 。它可以用来撤销提交、撤销暂存、甚至丢弃本地修改。
根据参数不同,git reset 的影响范围也不同,操作需谨慎

3.4.5.1 基础使用
  1. 撤销暂存
bash 复制代码
git reset <filename>
  • 作用:把文件从暂存区 移回工作区,但不影响文件内容。
  • 场景:你用 git add 把文件加到了暂存区,但还不想提交。
  1. 回退最近的提交,但保留更改(soft)
bash 复制代码
git reset --soft HEAD^
  • 作用:撤销最近一次提交,保留所有修改和暂存区内容
  • 场景:想修改上一次提交说明或补充内容后重新提交。
  1. 回退最近的提交,并取消暂存(mixed,默认)
bash 复制代码
git reset --mixed HEAD^ # 或简写为 git reset HEAD^
  • 作用:撤销最近一次提交,保留所有修改,但移出暂存区
  • 场景:想撤销提交,并重新选择要提交的文件。
  1. 回退并丢弃本地修改(hard)
bash 复制代码
git reset --hard HEAD^
  • 作用:撤销最近一次提交,所有本地修改和暂存内容都会被丢弃,工作区回到上一次提交的状态。
  • 场景:想彻底回退到某个历史状态,放弃所有本地变更。
  1. 回退到任意历史提交
bash 复制代码
git reset --hard <commit_id>
  • 作用:将分支指向某个历史 commit,工作区和暂存区都恢复到该状态。

3.4.6 git revert

*撤销(反向)某次提交 的命令。它通过生成一个新的"反向提交",来抵消指定提交的内容。与 git reset 不同,git revert 不会重写历史,非常适合多人协作和已推送到远程的分支。 *

3.4.6.1 基础使用
  1. 撤销单个提交
bash 复制代码
git revert <commit_id>
  1. 撤销多个提交
bash 复制代码
git revert <commit_id1> <commit_id2> ...
  1. 撤销一段连续的提交
bash 复制代码
git revert <old_commit_id>^..<new_commit_id>
3.4.6.2 典型场景

反向提交: 根据当次的改动,创建一次新的提交,内容是反转当次的操作,让文件恢复成当次提交之前的状态

  • 已推送到远程的分支:撤销错误提交,又不影响他人历史。
  • 多人协作:避免重写历史,安全撤销。
  • 修复 bug:快速回退某次有问题的提交。
3.4.6.3 与git reset 区别
命令 是否重写历史 是否适合协作 撤销方式 备注
git reset 回退到历史状态 会改变提交链(本地历史),不推荐在已推送分支上用
git revert 生成反向提交 生成新的撤销提交,历史不会断裂,适合所有场景

3.4.7 git rebase 不推荐使用?

用于变基(rebase)操作 的命令,主要作用是将当前分支的提交"移动"到另一个基底(通常是目标分支的最新提交之后),从而整理提交历史、保持提交链线性。它是代码协作、合并、压缩提交时非常重要的工具。

3.4.7.1 基础使用
bash 复制代码
# 把当前分支上的所有新提交,移动到 `<目标分支>` 的最新提交之后。
git rebase <目标分支>
# 交互式 rebase(整理、压缩提交)
git reabse -i <基底>
3.4.7.2 使用场景
  1. 本地开开发后,调试过程中有一些问题,需要修改,导致多次commit(实际上是开发同一功能),需要在推送到远程仓库时合并为一次
    • git log --oneline # 查询提交日志,确定需要合并的记录条数
    • git rebase -i HEAD~3 我这里是合并最近三次提交,会打开默认的编辑器,我这里是vscode
    • 修改内容,保存退出
    • 会打开一个新的编辑器,在这里编辑提交信息
    • 修改提交内容,保存退出
    • 命令行显示
    • git log --oneline查看日志

4. Git进阶命令与功能(含场景与代码)

4.1 分支管理

  • 场景:多人协作、并行开发

  • git branch git switch:查看、创建、删除分支

    bash 复制代码
    git branch           # 查看分支
    git branch -a        #查看本地和远程所有分支
    git swicth 
    git branch <name>    # 创建分支
    git branch -b <name> # 创建并切换
    git switch -c <name>
    git branch -d <name> # 删除分支
    git branch -m <新分支名> # 重命名分支
    git branch -v # 显示每个分支最后一次提交的简要信息
  • git checkout -b <name>:创建并切换到新分支

    bash 复制代码
    git checkout -b feature/login
  • git merge <name>:合并分支

    bash 复制代码
    git merge feature/login
  • git rebase <name>:变基操作,整理提交历史

    bash 复制代码
    git rebase main

4.2 远程仓库操作

  • 场景:团队协作、代码共享

  • git remote:管理远程仓库

    bash 复制代码
    git remote -v
    git remote add origin https://github.com/user/repo.git
  • git fetch:获取远程更新但不合并

    bash 复制代码
    git fetch origin
  • git pull:获取并合并远程更新

    bash 复制代码
    git pull origin main
  • git push:推送本地提交到远程仓库

    bash 复制代码
    git push origin main

4.3 标签管理

  • 场景:发布版本、标记重要节点

  • git tag:查看、创建、删除标签

    bash 复制代码
    git tag               # 查看标签
    git tag v1.0          # 创建标签
    git tag -d v1.0       # 删除标签
    git push origin v1.0  # 推送标签到远程

4.4 git stash 临时保存与恢复

用于 临时保存当前工作区和暂存区的修改的命令。它非常适合在开发过程中需要切换分支、拉取代码、但又不想提交或丢弃当前修改时使用。 通过 git stash,你的修改会被"藏起来",工作区恢复到干净状态,等你需要时再恢复。

  • git stash:保存当前工作区变更

    bash 复制代码
    git stash             # 保存
    git stash pop         # 恢复最近一次 stash 的内容,并将其从 stash 列表中删除。
    git stash apply       # 恢复最近一次内容,但不删除该stash
    git stash list        # 查看
    git stash apply stash@{1}  # 恢复指定的stash
    git stash drop stash@{1}   # 删除指定的stash
    git stash clear            # 删除所有stash
    git stash --keep-index #只保存工作区修改,不保存暂存区(git add内容)
    git stash -u # 保存所有已跟踪文件的修改、暂存区内容,以及未跟踪文件。

4.5 reflog与历史恢复

  • 场景:恢复误操作、找回丢失提交

  • git reflog:查看所有操作历史,包括丢失的commit

    bash 复制代码
    git reflog 
    git reset --hard <commit_id> # 找到你需要恢复的 commit id 或 HEAD@{n}

4.6 git filter-branch

Git 提供的历史重写工具,可以批量修改、删除、替换仓库的所有提交

4.6.1. 基础使用

bash 复制代码
git filter-branch [选项] <过滤器> -- [分支范围]

4.6.2 常用过滤器

  1. --index-filter
    • 操作暂存区(速度快,适合删除文件)
  2. --tree-filter
    • 操作整个工作区(慢,适合复杂脚本)
  3. --env-filter
    • 操作环境变量(如作者信息)

4.6.3 实际场景

删除历史大文件

bash 复制代码
# --force:强制执行(覆盖之前 filter-branch 操作)
# --index-filter:只操作暂存区,速度快
# git rm --cached --ignore-unmatch bigfile.zip 从每次提交中删除该文件
# --ignore-unmatch 如果你用 `git rm <文件名>` 删除一个不存在于当前提交的文件,Git 会报错,此参数可以忽略这样的情况,继续执行
# --prune-empty:清理空提交
# --tag-name-filter cat:保留标签名
# --all:遍历所有分支和标签
# 第一步
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch 文件名' --prune-empty --tag-name-filter cat -- --all

# 第二步:清理原始应用和垃圾对象
rm -rf .git/refs/original/   # 删除 filter-branch 操作产生的原始引用
git reflog expire --expire=now --all # 让所有引用日志立即过期
git gc --prune=now --aggressive # 垃圾回收,彻底清除无用对象,缩小仓库体积


# --force:因为历史被重写,必须强制推送,覆盖远端所有分支和标签。
# --all:推送所有分支
# --tags:推送所有标签
# 第三步:推送到远程仓库 
git push origin --force --all
git push origin --force --tags   

# 第四步 通知所有成员重新clone仓库,否则会有冲突和仓库文件残留

# 第五步 检查仓库体积(.git目录应该明显变小)

5. 其他功能与应用场景

5.1 忽略文件

  • 场景:不希望某些文件被跟踪

  • .gitignore:在项目根目录创建.gitignore文件,写入需要忽略的文件/目录名

    bash 复制代码
    node_modules/
    *.log
    .env

5.2 常见协作流程

  • 场景:多人开发、代码审查

    1. 克隆仓库:git clone
    2. 创建分支开发:git checkout -b feature/xxx
    3. 定期拉取更新:git pull
    4. 提交并推送:git addgit commitgit push
    5. 提交Pull Request(PR):在平台(如GitHub)发起代码审查和合并
相关推荐
明月_清风3 小时前
Python 性能微观世界:列表推导式 vs for 循环
后端·python
风象南3 小时前
纯文本模型竟然也能直接“画图”,而且还很好用
前端·人工智能·后端
明月_清风3 小时前
Python 性能翻身仗:从 O(n) 到 O(1) 的工程实践
后端·python
IT_陈寒3 小时前
Vite vs Webpack:5个让你的开发效率翻倍的实战对比
前端·人工智能·后端
JaguarJack3 小时前
FrankenPHP 原生支持 Windows 了
后端·php·服务端
BingoGo4 小时前
FrankenPHP 原生支持 Windows 了
后端·php
Moment16 小时前
Vibe Coding 时代,到底该选什么样的工具来提升效率❓❓❓
前端·后端·github
Victor35616 小时前
MongoDB(27)什么是文本索引?
后端
可夫小子17 小时前
OpenClaw基础-3-telegram机器人配置与加入群聊
后端