コミット:現在のブランチの先端にノードを追加
git add . && git commit -m "…"各コミットは自分の親コミットを記憶します。ブランチはコミットを指す可動ポインタにすぎず、コミットすると main と HEAD が一緒に進みます。
149 件の Git コマンドを状況別に分類し、解説・例・危険度を掲載。検索・ワンクリックコピー・お気に入りに対応し、操作図と練習用シミュレーター端末も付属
このツールの翻訳は未完了です。一部は原文または代替言語で表示されます。
git init git init -b main # 指定初始分支名
git clone https://github.com/git/git.git git clone git@github.com:user/repo.git my-dir
git clone --depth 1 --branch v2.0 https://github.com/user/repo.git
git clone -b develop https://github.com/user/repo.git
git config --global user.name "Zhang San" git config --global user.email "zs@example.com"
git config user.email "me@company.com"
git config --list --show-origin git config --get user.name
git config --global core.autocrlf input
git config --global alias.lg "log --oneline --graph --all" git lg
Windows 通常已带 manager;macOS 用 osxkeychain 更安全。
git help rebase git reset -h # 简短用法
git status git status -s # 短格式:M 修改 A 新增 D 删除 ?? 未跟踪
git add src/app.js git add src/ # 整个目录 git add "*.md" # 通配
git add -A git add -u # 只暂存已跟踪文件的修改与删除,不含新文件
git add -p src/app.js # y 暂存这块 n 跳过 s 拆得更小 q 退出
git commit -m "fix: 修正登录超时判断"
git commit -am "docs: update readme"
容易把不想提交的改动一起带进去,提交前先 git status。
git add forgotten.js git commit --amend --no-edit # 补文件但不改说明 git commit --amend -m "新说明"
产生新的提交 id;已经推送过的提交不要 amend,否则需要强推。
git diff git diff src/app.js # 只看一个文件
git diff --staged
git diff main feature git diff HEAD~3 HEAD -- src/ git diff main...feature # feature 相对分叉点的改动
git diff --stat HEAD~1
git diff --word-diff=color README.md
git log git log -5 # 最近 5 条 git log --oneline # 一行一条
git log --oneline --graph --all --decorate
git show HEAD git show a1b2c3d --stat git show HEAD:src/app.js # 看某版本的文件内容
git rm old.txt git rm -r legacy/
git rm --cached .env echo ".env" >> .gitignore
git mv utils.js helpers.js
git branch git branch -a # 含远程分支 git branch -vv # 带最新提交与跟踪关系
git branch feature/login git branch hotfix a1b2c3d # 从指定提交创建
git switch main git switch - # 回到上一个分支
git switch -c feature/search git switch -c hotfix origin/main # 基于远程分支
git checkout -b release/1.2
git branch -m master main git push -u origin main && git push origin --delete master
git branch -d feature/login
git branch -D experiment
分支上的独有提交会成为孤儿,短期内可用 reflog 找回。
git branch --merged main git branch --no-merged # 反过来
git branch -u origin/feature/login
git branch -a --contains a1b2c3d
git checkout v1.0 git switch -c fix-from-v1 # 想保留改动就在此建分支
此状态下的提交不属于任何分支,切走后容易丢。
git branch --sort=-committerdate | head
git fetch -p git remote prune origin
git switch main git merge feature/login
git merge --no-ff feature/login
git merge --squash feature/login git commit -m "feat: login"
git merge --abort
git add src/app.js git commit # 默认说明 Merge branch ...
git checkout --theirs package-lock.json git add package-lock.json
rebase 时 ours / theirs 含义反过来:ours 是被变基到的分支。
git switch feature git rebase main
所有被搬的提交 id 都会变;已推送并有人基于它工作的分支不要 rebase。
git rebase -i HEAD~3 # pick 保留 reword 改说明 squash 并入上一条 fixup 并入且丢说明 drop 删除
git add . git rebase --continue
git rebase --abort
git rebase --onto main server client
适合「分支开错了地方」的情形。
git commit --fixup a1b2c3d git rebase -i --autosquash a1b2c3d~1
git cherry-pick a1b2c3d git cherry-pick a1b2c3d..e5f6g7h # 一段范围(不含 a1b2c3d)
git cherry-pick -n a1b2c3d
git config --global merge.tool vscode git config --global mergetool.vscode.cmd "code --wait $MERGED" git mergetool
git restore src/app.js git restore . # 整个目录
未暂存的改动会直接丢失,无法用 Git 找回。
git restore --staged src/app.js git reset HEAD src/app.js # 旧写法
git restore --source HEAD~2 config.yml git restore --source v1.0 -- src/
git reset --soft HEAD~1 git commit -m "更合适的说明"
git reset HEAD~1
git reset --hard HEAD~1 # 扔掉最后一次提交 git reset --hard origin/main # 与远程完全一致
工作区改动不可恢复;已提交的可用 git reflog 找回。
git reset package-lock.json
git revert HEAD git revert a1b2c3d --no-edit
git revert --no-commit HEAD~3..HEAD git commit -m "revert last 3 commits"
git revert -m 1 f00ba12
撤销合并后再想合入同一分支需先 revert 这个 revert。
git reflog
git reset --hard HEAD@{2} # 回到 2 步之前的状态
git branch rescue a1b2c3d # 给孤儿提交建分支git clean -n # 预览会删什么 git clean -fd # 执行 git clean -fdx # 连 .gitignore 里忽略的也删(如 node_modules)
git checkout -- src/app.js
git fsck --lost-found git show <dangling-commit-id>
git fsck --unreachable | grep commit | cut -d" " -f3 | xargs git log --merges --no-walk
git remote -v
git remote add origin git@github.com:user/repo.git
git remote set-url origin git@github.com:user/repo.git
git remote rename origin upstream
git remote remove upstream
git fetch git fetch origin main git fetch --all --prune
git pull git pull origin main
git pull --rebase origin main
git push git push origin main
git push -u origin feature/login
git push origin --delete feature/old git push origin --delete v0.1 # 也可删远程标签
git push --force-with-lease origin feature/login
优先用它而不是 --force。
git push -f origin feature/login
会抹掉别人推上去的提交;共享分支禁止。
git push --all origin
git ls-remote --heads origin git ls-remote --tags https://github.com/git/git.git
git remote add upstream https://github.com/original/repo.git git fetch upstream git switch main && git merge upstream/main
git pull --ff-only
git stash git stash push -m "登录页半成品"
git stash -u git stash -a # 连忽略文件也收
git stash list
git stash pop
git stash pop stash@{2}git stash apply stash@{1}git stash show -p stash@{0}git stash drop stash@{0}
git stash clear # 全部删除git stash branch fix-from-stash stash@{0}git stash push -m "只收起样式" -- src/styles/
git tag git tag -l "v1.*" # 按模式过滤
git tag -a v1.2.0 -m "Release 1.2.0"
git tag build-2026-09-09
git tag -a v1.1.1 a1b2c3d -m "补打"
git show v1.2.0
git tag -d v1.2.0
git push origin --delete v1.2.0
git describe --tags --always
git submodule add https://github.com/user/lib.git vendor/lib
git submodule update --init --recursive
git clone --recurse-submodules https://github.com/user/repo.git
git submodule update --remote vendor/lib git add vendor/lib && git commit -m "bump lib"
git submodule status
git submodule deinit -f vendor/lib git rm -f vendor/lib rm -rf .git/modules/vendor/lib
git worktree add ../repo-hotfix hotfix/1.2.1 git worktree add -b review ../repo-review origin/pr-42
git worktree list
git worktree remove ../repo-hotfix git worktree prune # 清理已手工删除目录的登记
git clone --filter=blob:none --sparse <url> cd repo && git sparse-checkout set apps/web packages/ui
git log -p -- src/app.js git log --follow -- src/app.js # 跨重命名跟踪
git log --grep="登录" -i --oneline
git log -S"validateToken" --oneline git log -G"regex" --oneline # 正则版
git log main..feature --oneline git log origin/main..HEAD # 还没推送的提交
git log --pretty=format:"%h %ad %an %s" --date=short -10
git log --since="2026-09-01" --until="2026-09-09" --oneline
git shortlog -sn --all --no-merges
git blame -L 40,60 src/app.js git blame -w -C src/app.js # 忽略空白、跟踪移动
git bisect start git bisect bad # 当前是坏的 git bisect good v1.1.0 # 这个版本是好的 # 反复测试并执行 git bisect good/bad git bisect reset
git bisect run npm test
git grep -n "TODO" -- "*.ts" git grep "foo" v1.0 # 在某个版本里搜
git show HEAD~5:src/config.js > old-config.js
git diff --name-only HEAD~3 HEAD git diff --name-status main # 带 M/A/D 状态
git count-objects -vH
git gc --aggressive --prune=now
prune 会真正删除不可达对象,reflog 里的后悔药会一起消失。
git rev-parse --short HEAD git rev-parse --abbrev-ref HEAD git rev-parse --show-toplevel # 仓库根目录
git archive -o release.zip v1.2.0 git archive HEAD src/ | tar -x -C /tmp/out
# .gitignore node_modules/ dist/ *.log .env* !.env.example
git check-ignore -v dist/app.js
git rm -r --cached . git add . git commit -m "chore: apply .gitignore"
echo ".DS_Store" >> ~/.gitignore_global git config --global core.excludesFile ~/.gitignore_global
git update-index --skip-worktree config/local.php git update-index --no-skip-worktree config/local.php # 取消
* text=auto *.sh text eol=lf *.png binary *.psd filter=lfs diff=lfs merge=lfs -text
git lfs install git lfs track "*.psd" git add .gitattributes
いくつかのコマンドを「これをやりたい」というレシピにまとめたものです。展開するとまとめてコピーできます。
提交早了 / 说明写错 / 想拆成两个提交(且尚未推送)
git reset --soft HEAD~1提交撤掉,改动仍在暂存区git status确认文件都在「要提交的变更」里git commit -m "新的说明"别人可能已经拉取了,不能改写历史
git revert <commit>生成反向提交git push本地实验搞乱了,想彻底回到某个提交
git log --oneline找到目标提交 idgit stash -u(可选)先收起还想保留的改动git reset --hard <commit>忘了开分支就提交了 N 次
git branch feature/x在当前位置建分支(把这些提交「存」起来)git reset --hard origin/mainmain 回到远程状态git switch feature/x开 PR 之前整理历史(分支未被他人使用)
git rebase -i HEAD~4把后面几行的 pick 改成 squash 或 fixupgit push --force-with-lease分支已推送过才需要main 已经有新提交,功能分支要在其之上继续
git fetch origingit switch feature/xgit rebase origin/main或 git merge origin/main(保留合并提交)统一默认分支名
git branch -m master maingit push -u origin maingit push origin --delete master先在托管平台把默认分支切到 maingit branch -D 之后发现还有用
git reflog找到该分支最后一次提交的 id(如 "commit: xxx")git branch <name> <commit-id>.env 或几百 MB 的文件进了历史
git rm --cached .env && echo ".env" >> .gitignore若只在最近一次提交:接着 git commit --amendgit filter-repo --path .env --invert-paths已在历史深处:用 git-filter-repo 重写全部历史(需单独安装)git push --force-with-lease --all所有协作者都要重新克隆;泄露的密钥无论如何都要作废重发main 上修好的 bug 也要进 release/1.2
git switch release/1.2git cherry-pick <commit>git pushgit merge / pull 报 CONFLICT
git status看哪些文件「双方修改」code <file>在编辑器里处理 <<<<<<< ======= >>>>>>> 标记,保留正确内容git add <file>每修好一个就 add 一个git commitrebase 时则是 git rebase --continue先在本地写了代码,后来才在 GitHub 建了仓库
git init -b main && git add -A && git commit -m "init"git remote add origin git@github.com:user/repo.gitgit push -u origin main丸はコミット、矢印は親コミットを指します。緑のラベルはブランチ、紫は HEAD があるブランチを示します。灰色の丸はどのブランチからも参照されていないコミット(reflog で復元可能)、塗りつぶしの丸は今回の操作で新しく作られたコミットです。
git add . && git commit -m "…"各コミットは自分の親コミットを記憶します。ブランチはコミットを指す可動ポインタにすぎず、コミットすると main と HEAD が一緒に進みます。
git switch -c feature新しいブランチと main は同じコミットを指すため、作成は一瞬です。その後 feature でコミットすると、進むのは feature だけです。
git switch main && git merge feature新しいコミットは作られず、履歴は一直線のままです。ここにブランチが存在した記録を残したい場合は --no-ff を使います。
git merge featureGit は共通の祖先 b2 を見つけ、b2 に対する両側の変更をまとめて、親コミットを2つ持つ m6 を生成します。同じ箇所の変更が異なる場合にのみ競合します。
git switch feature && git rebase main履歴は一直線になりますが、c3 と d4 は新しいコミット c3′ と d4′ に置き換わります(id が変わります)。すでに push したブランチを rebase するのは避けてください。でないと、他の人の履歴と衝突します。
git reset --hard HEAD~1--soft はポインタだけを移動します。--mixed はさらにステージングエリアを空にします。--hard は作業ツリーも元に戻します。孤立したコミット c3 は reflog から復元できます(デフォルトで 30 日以上保持)。
git revert HEADc3 は履歴に残り、新しいコミット r4 の内容は c3 の変更を逆にしたものです。すでに push したコミットを取り消す場合は reset ではなく revert を使います。
git cherry-pick x7x7 が親コミットに対して行った変更を main 上に再生し、内容は同じで id が異なる x7′ を作ります。特定の修正だけをリリースブランチに持っていくのに適しています。
メモリ上だけで動く Git シミュレーターです(本物の Git ではなく、ネットワークにも接続しません):init / add / commit / branch / switch / merge / rebase / reset / revert / stash / tag / remote / push / pull などのよく使うサブコマンドに対応し、右側のコミットグラフはリアルタイムで更新されます。全10レベルは「最初のコミット」から「マージコンフリクトの解決」まで。Linux コマンドの練習はLinux コマンド早見表。