跳转至

Git 命令集

git 命令为索引的快速查询;完整语义见 git-scm.com

相关文档协作流程 · Gitignore 与 Hooks · 提交规范 · Git 备忘速查(Notes)

创建项目

git init

在当前目录创建一个新的 Git 仓库(生成 .git 目录)。

一句话:「在这个文件夹里初始化一个本地仓库。」

效果:工作区文件不变;新建本地仓库,尚无提交;远程无变化。

常见场景

  • 本地新项目第一次用 Git 管理
  • 已有代码目录补做 git init 后再首次 commit
# 在当前目录初始化
git init

# 指定目录名初始化(会创建该目录)
git init my-project

git clone

从远程 URL 克隆一份完整仓库到本地(含历史与默认远程 origin)。

一句话:「把远程仓库整包拷到本地,并自动配好 origin。」

效果:本地多一个含 .git 的项目目录;自动关联远程;工作区是远程默认分支的检出。

常见场景

  • 第一次参与已有项目
  • 换机器重新拉代码
# HTTPS
git clone https://github.com/ORG/REPO.git

# SSH
git clone git@github.com:ORG/REPO.git

# 克隆到指定文件夹名
git clone git@github.com:ORG/REPO.git my-folder

基础命令

git status

查看工作区、暂存区与当前分支最新提交之间的差异。

一句话:「先看一眼哪些改了、哪些已 add、哪些还没 commit。」

效果:只读,不改任何文件;终端列出 modified / staged / untracked 等状态。

常见场景

  • commit 前确认要提交的文件
  • 合并冲突后看还有哪些文件未解决
git status

# 简短一行式输出,适合脚本或快速扫一眼
git status -sb

git add

把改动放进暂存区(index),为下一次 git commit 做准备。

一句话:「把要提交的改动选进暂存区。」

效果:工作区文件内容不变;暂存区增加对应版本;远程无变化。

常见场景

  • 只提交部分文件,其它改动继续留着
  • 新文件第一次纳入版本管理
# 添加一个文件
git add file.md

# 添加整个目录下已追踪及新文件
git add sub_folder/

# 添加当前目录所有变更(新建 + 修改 + 删除)
git add .

# 交互式挑选 hunks
git add -p file.md

git diff

比较工作区、暂存区、提交之间的差异。

一句话:「看具体改了哪些行,别急着 commit。」

效果:只读输出 diff;不修改仓库状态。

常见场景

  • commit 前 review 改动
  • 看已 add 但还没 commit 的内容和上次提交差多少
# 工作区 vs 暂存区(还没 add 的改动)
git diff

# 暂存区 vs 最后一次 commit(已经 add、准备 commit 的)
git diff --cached

# 和某个 commit 比
git diff f2a9c2cad88cfe2206dc7e6c271d673365723add

# 和上一个 commit 比
git diff HEAD^

git commit

把暂存区的快照记录到本地仓库,形成新的 commit。

一句话:「把暂存区里的改动正式记一笔账(生成 commit)。」

效果:本地分支指针前进;工作区一般不变;远程要等 push 才有。

常见场景

  • 功能做完存一个版本
  • 发现上次 commit 漏文件或写错说明(未 push 时用 --amend
# 提交暂存区全部内容
git commit -m 'add file.'

# 已追踪文件的修改:add + commit 一步(新建文件无效)
git commit -am 'update a tracked file.'

# 改最近一次 commit 的说明(会打开编辑器)
git commit --amend

# 把新改动并进最近一次 commit,说明不变
git commit --amend --no-edit

Note

amend 适合 还没 push 的最后一次提交;已经 push 到共享分支时,优先新开 commit 或按团队规范用 revert。提交说明格式见 提交规范

git restore

恢复工作区文件,或把文件从暂存区撤下(Git 2.23+)。

一句话:「误改文件想还原,或者 add 错了想从暂存区拿出来。」

效果:可丢弃工作区未提交修改,或只取消 staging;不直接改远程。

常见场景

  • 改乱了某个文件,想恢复成上次 commit 的样子
  • git add 加多了,先 unstage 再决定
# 丢弃工作区对 file.md 的未提交修改
git restore file.md

# 只取消暂存,文件改动还在
git restore --staged file.md

# 从指定 commit 恢复某个文件到工作区
git restore --source=HEAD~1 file.md

git reset

把当前分支的 HEAD 移到指定 commit,并可选择是否动暂存区、工作区。

一句话:「撤 commit、清暂存,严重时连工作区一起回到某个版本。」

效果:取决于模式——--soft 只动提交记录;默认 --mixed 清暂存留文件;--hard 连工作区一起回退。远程不变(除非之后再 force push)。

常见场景

  • 最近一次 commit 不想要了,但代码还想留着改
  • 本地实验分支想完全回到干净状态(慎用 --hard

模式速记

  • --soft:只挪 HEAD,暂存和工作区都不动
  • --mixed(默认):挪 HEAD + 清暂存,改动还在工作区
  • --hard:HEAD、暂存、工作区全部对齐目标 commit
# 撤消最近一次 commit,改动回到工作区(未暂存)
git reset HEAD~1

# 撤消最近 N 次 commit,改动保留
git reset HEAD~N

# 连改动一起扔掉(慎用)
git reset --hard HEAD~1

# 只软回退,暂存区仍保持「已 add」状态
git reset --soft HEAD~1

Warning

git reset --hard永久丢掉 未提交改动。对 已经 push 的共享分支,不要用 reset 改历史,改用 git revert

git rm

从 Git 追踪中删除文件,并可选地从磁盘删除。

一句话:「让 Git 知道这文件删了,并顺便从硬盘删掉。」

效果:工作区文件被删(除非 --cached);删除会进入暂存区,等 commit;远程要等 push。

常见场景

  • 重构时移除废弃模块
  • 误用 rm 后还要再 git add,不如直接 git rm
命令 删除工作区 通知 Git 自动暂存 还要 add 吗 风险
rm file ✅ 需要
git rm file
git rm -r folder ⚠️ 高
git rm file.md
git rm -r folder

# 只从 Git 追踪移除,磁盘文件保留
git rm --cached file.md

# commit 后 status 里会看到 deleted:
#   deleted:    start.md

Warning

git rm -r 会递归删目录,执行前确认路径,必要时先备份。

git gc

git garbage collect:清理不可达对象、压缩仓库,提升本地操作性能。

一句话:「给本地 .git 做一次大扫除、压缩。」

效果:只影响本地仓库体积与性能;不改工作区文件;不涉及远程。

常见场景

  • 仓库很大、fetch/clone 变慢
  • 大量临时对象堆积后维护
git gc

# 更积极清理(耗时更长)
git gc --aggressive

git fsck

检查本地仓库对象完整性,排查损坏或孤立对象。

一句话:「仓库是不是坏了、有没有找不着的对象。」

效果:只读诊断;--lost-found 可能往 .git/lost-found 拷贝问题对象。

常见场景

  • clone/fetch 报 object 错误
  • 怀疑磁盘问题导致仓库损坏
git fsck --full
git fsck --lost-found

分支与合并

git branch

列出、创建、重命名、删除本地分支(不切换分支)。

一句话:「看有哪些分支、新建一个分支名、给分支改名。」

效果git branch dev 只创建指针,不切换;删除已合并分支用 -d;远程分支列表用 -r

常见场景

  • 开 feature 分支前先 git branch feature
  • 清理已合并进 main 的本地分支
git branch
git branch --list
git branch -r          # 远程跟踪分支
git branch -a          # 本地 + 远程

# 创建分支(不切换)
git branch dev

# 已合并 / 未合并进当前分支的本地分支
git branch --merged
git branch --no-merged

# 重命名
git branch -m test test_new

# 删除已合并的本地分支
git branch -d test_new

git switch

切换分支或创建并切换(Git 2.23+,专门干「换分支」)。

一句话:「切到另一个分支上去干活。」

效果:工作区切到目标分支的提交;未提交改动若冲突会被拒绝(或需 stash)。

常见场景

  • 从 main 切到 feature 开发
  • 基于远程分支创建本地跟踪分支
git switch main
git switch -c feature              # 创建并切换
git switch -c dev origin/dev       # 跟踪远程 dev

git checkout

切换分支、检出 tag、或(旧写法)恢复文件;老项目里仍极其常见。

一句话:「换分支、看某个 tag,老教程里还用来还原文件。」

效果:切分支时同 switch;detached HEAD 状态下在 tag 上查看历史;-f 可丢弃冲突改动(慎用)。

常见场景

  • 老脚本/文档仍用 checkout
  • 需要检出 tag 做发版对比
git checkout dev
git checkout -b new-branch
git checkout --track origin/dev
git checkout -b dev origin/dev

# 在 tag 上 detached HEAD 查看
git checkout v2.0

git merge

另一个分支 的提交合并进 当前所在分支

一句话:「把 feature 上的改动并进我现在的分支。」

效果:可能产生 merge commit 或 fast-forward;有冲突时要手动解决再 commit;远程要等 push。

常见场景

  • feature 做完合并回 main
  • 想用一条 squash commit 合进 main(--squash
git checkout main
git merge dev

# 即使可以快进,也保留 merge commit
git merge --no-ff feature

# 把 feature 所有改动压成一个 commit
git merge --squash feature
git commit -m "Squashed and merged feature branch"

git rebase

把当前分支的提交「挪到」另一分支最新提交之后,历史更直一条线。

一句话:「在最新 main 上面重新接我的 commit,不想多一个 merge commit。」

效果:重写本地 commit 的基底;已 push 的分支 rebase 后再 push 通常要 force;远程历史可能被改写。

常见场景

  • 本地 feature 跟进 main 最新代码
  • pull --rebase 拉远程时保持线性历史
  • 交互式压缩多个 wip commit
git checkout feature
git rebase main

# 拉远程并变基(等于 fetch + rebase origin/main)
git pull --rebase origin main

# 交互式:压缩、改说明、删 commit(n 为回溯条数)
git rebase -i HEAD~3

Warning

**不要**对已经 push 且多人共用的分支随意 rebase。若必须 push,用 git push --force-with-lease,并和团队打招呼。Fork / PR 流程见 协作流程

git cherry-pick

已有的某个(或几个)commit 原样应用到当前分支。

一句话:「只要那一个 commit 的改动,不要整分支 merge。」

效果:当前分支多出一个新 commit(hash 不同,内容相同);远程要等 push。

常见场景

  • 热修复:把 main 上的 fix commit 摘到 release 分支
  • 误 commit 到错误分支,改 cherry-pick 到正确分支
git cherry-pick abc1234
git cherry-pick -n abc1234    # 只改文件并暂存,不自动 commit

git log

查看提交历史。

一句话:「这分支上都 commit 了啥、谁改的、什么时候。」

效果:只读;输出可配合 --oneline--graph 等格式化。

常见场景

  • 查 bug 是哪次引入的
  • 发版前看 tag 以来的 commit 列表
git log
git log -n 5
git log --oneline --graph -n 20
git log --stat
git log -p -m
git log v0.0.1

git stash

临时把工作区改动「藏起来」,稍后再恢复。

一句话:「手头改了一半要切分支,先 stash 一下。」

效果:工作区变干净(默认);改动存在 stash 栈里;pop/apply 后恢复;远程无。

常见场景

  • 紧急切分支修 bug,当前改动不想 commit
  • 实验性改动暂存,失败就 drop
# 暂存当前修改(含未追踪可选 -u)
git stash
git stash push -m "wip: login form"

git stash list
git stash show -p stash@{0}

# 恢复并删除栈顶
git stash pop
# 恢复但保留 stash
git stash apply stash@{0}

# 从 stash 拉出新分支继续改
git stash branch dev_new stash@{0}

git stash drop stash@{0}

git tag

给某个 commit 打标签,常用于发版标记。

一句话:「给这次提交贴个 v1.0.0 的标签,方便以后 checkout。」

效果:本地多一个指向 commit 的 ref;annotated tag 可带说明;push tag 后远程可见。

常见场景

  • 发布版本打 tag
  • CI 按 tag 触发构建
git tag
git tag -a v0.0.1 -m 'release 0.0.1'
git tag -d v0.0.2

git tag -v v0.0.1
git show v0.0.1
git log v0.0.1

# 推送 tag 到远程
git push origin v0.0.1
git push origin --tags

远程协作

git fetch

从远程下载最新 commit 和分支信息,**不**自动合并到当前分支。

一句话:「先看看远程更新啥了,但不改我当前工作区。」

效果:更新 origin/* 远程跟踪分支;本地当前分支和工作区不变。

常见场景

  • push 前看远程有没有新提交
  • rebase/merge 配合手动整合
git fetch origin
git fetch origin main

git pull

fetch + 合并到当前分支(merge 或 rebase,取决于配置/参数)。

一句话:「拉远程最新代码并并进我当前分支。」

效果:本地分支可能 fast-forward 或产生 merge commit;有冲突需解决;远程只读。

常见场景

  • 每天开始干活前同步 main
  • 团队习惯线性历史时用 --rebase
git pull origin main
git pull --rebase origin main

git push

把本地 commit 上传到远程分支。

一句话:「把我这边的 commit 推到 origin 上。」

效果:远程分支指针前进;首次 push 常用 -u 建立 upstream;force push 会改写远程历史。

常见场景

  • 功能做完推到远程开 PR
  • rebase 后更新远程 feature(需 --force-with-lease
# 首次推送并记住 upstream
git push -u origin main

# 之后直接
git push

# rebase 后更安全地覆盖远程(确认无人新推)
git push --force-with-lease

git remote

管理远程仓库别名(通常是 origin)及其 URL。

一句话:「远程叫啥、地址是啥、怎么增删改。」

效果:改的是本地 .git/config 里的远程配置;不直接改远程服务器。

常见场景

  • fork 后加 upstream
  • 仓库迁移换 URL
git remote
git remote -v
git remote show origin

git remote add origin git@github.com:ORG/REPO.git
git remote rename origin upstream
git remote remove origin

git remote get-url origin
git remote set-url origin git@github.com:ORG/NEW_REPO.git

git remote update origin
git remote prune origin          # 清理已删远程分支的跟踪 ref
git remote prune -n origin       # 试运行

查看与对比

git show

查看某个 commit、tag 或对象的详细信息和 diff。

一句话:「这次 commit 到底改了啥、提交说明是啥。」

效果:只读;可配合 HEAD^HEAD~2 等语法看历史任意点。

常见场景

  • code review 某个 hash
  • 搞懂 merge commit 的两个父提交
git show d4d30167d01d10d7de5e7aca699863dc27735678
git show d4d30
git show v0.0.1

git show HEAD
git show HEAD~0
git show HEAD^              # 第一父提交,线性历史上即 HEAD~1
git show HEAD^1
git show HEAD^^             # HEAD~2
git show HEAD^~1

# merge commit 的第二父提交
git show HEAD^2

git show HEAD@{2}
git show main@{yesterday}

Note

  1. ^:父提交。HEAD^ = HEAD^1,merge 时指第一父链。
  2. ~n:沿第一父链回退 n 步,如 HEAD~2
  3. HEAD^2:merge commit 的第二父提交。
  4. @{n} / @{yesterday}:reflog、按日期查;详见 gitrevisions(7)

配置

git config(全局)

设置对本机所有仓库生效的用户名、邮箱等。

一句话:「这台电脑上所有仓库默认用什么名字 commit。」

效果:写入 ~/.gitconfig;影响之后 commit 的作者信息。

git config --global user.name "your name"
git config --global user.email "your email"

git config --global --list

git config(当前仓库)

仅当前项目覆盖全局配置。

一句话:「这个项目用另一个邮箱 commit(比如公司项目)。」

效果:写入项目 .git/config;优先级高于 global。

git config user.name "name.project.config"
git config user.email "mail@project.config"