커밋: 현재 브랜치 끝에 노드 추가
git add . && git commit -m "…"각 커밋은 자신의 부모 커밋을 기억합니다. 브랜치는 커밋을 가리키는 이동 가능한 포인터일 뿐이며, 커밋하면 main과 HEAD가 함께 이동합니다.
Git 명령 149개를 상황별로 분류, 각 항목에 설명·예시·위험도를 제공. 검색, 원클릭 복사, 즐겨찾기 지원, 동작 다이어그램과 연습용 시뮬 터미널 포함
이 도구는 아직 완전히 번역되지 않아 일부 내용이 원문 또는 대체 언어로 표시됩니다.
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 기준 양쪽의 변경 사항을 합치고, 부모 커밋이 두 개인 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 명령어 모음.