KunSpace
返回博客

Git 常用指令备忘:查历史、切分支、拉代码、cherry-pick 与回退

2026年6月24日
尚无阅读

读完了?别空手走啊 😏

读都读完了,不点个赞说不过去吧

写评论

有想法?直接在这说,不用跑留言板

这篇写什么?

做 Android / 音频这类大仓时,每天都在:查是谁改的、暂存切分支、拉代码冲突、挑提交、回退救场
本文按使用频率整理成一份中文备忘,并补上容易踩坑的点(尤其是 reset --hard、二进制冲突、--ours / --theirs)。

一句话:

查清历史 → 干净地切分支 / 拉代码
  → 提交与推送
  → 跨分支 cherry-pick
  → 回退用 reset,后悔用 reflog

Git 日常指令地图

文中路径、分支名用通用示例;你换成自己的仓库即可。危险命令(--hard、强推)请先确认再执行。


一、查看提交日志

# 最近提交
git log

# 只看最近 5 条
git log -n 5

# 某人的提交
git log --author="liangkun"

# 更紧凑
git log --oneline -n 20

看每个提交改了哪些文件、多少行

git log --stat
git log --stat -n 5

补:直接看某次提交的补丁

git show <commit哈希>
git show <commit哈希> --stat

二、某行代码是谁改的:blame + show

# 看文件每一行最后一次修改的人 / 提交
git blame path/to/file.h

# 只筛和某段内容相关的行
git blame path/to/alsa_manager.h | grep "AML_AUDIO_OUT_DEV_TYPE_SPEAKER1"

# 拿到哈希后,看那次提交完整内容
git show <哈希>

补: 想看某一段行号范围:

git blame -L 120,160 path/to/file.c

三、拉取前后差了什么

git pull 之后,想对比「拉之前 vs 现在」:

git diff HEAD@{1} HEAD
写法 含义
HEAD 当前提交
HEAD@{1} reflog 里「上一个 HEAD 位置」(常是 pull 前)

补: 只看文件名:

git diff --name-status HEAD@{1} HEAD

四、暂存后切分支:stash

手头改到一半,要临时去别的分支:

git stash
git checkout other-branch

# 回来后恢复
git stash pop
# 或只应用不删除栈:git stash apply

常用:

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

补: 含未跟踪新文件时:

git stash -u

五、git pull 时本地有未提交改动

三种常见处理:

5.1 先提交再拉

git add .
git commit -m "描述你的更改"
git pull
# 或:git pull --rebase

5.2 先 stash 再拉(暂不想提交)

git stash
git pull
git stash pop

5.3 丢弃本地改动再拉(不可恢复,慎用)

git reset --hard
git pull
方案 适用
commit 改动有价值,要留在历史上
stash 改动有价值,但还不想成 commit
reset --hard 确定本地垃圾改动可以扔掉

六、创建 / 切换 / 推送自己的分支

# 基于当前 HEAD 建分支并切换
git checkout -b yourbranch
# 新版等价:git switch -c yourbranch

# 基于远程某分支创建
git checkout -b yourbranch origin/basebranch

# 推到远程并建立跟踪
git push -u origin yourbranch

分步写法:

git branch yourbranch
git checkout yourbranch

七、删除分支

# 本地
git branch            # 列表
git branch -d name    # 已合并才删
git branch -D name    # 强制删

# 远程
git branch -r
git push origin -d name

补: 删远程后本地清理过期远程跟踪分支:

git fetch --prune

八、日常改代码 → 合并主干 → 提交推送(典型流程)

git status
git stash                      # 若当前工作区脏
git checkout master            # 或 main
git pull
git checkout yourbranch
git merge master               # 把主干合进自己分支
git stash pop                  # 若之前 stash 了
git status
git add .
git commit -m "注释"
git push

查看某次提交:

git show b747313165

九、提交到远程前的常用清理

# 看改了什么
git diff .
git status .

# 取消暂存(保留工作区修改)
git reset HEAD path/to/file.c

# 丢弃某文件工作区修改(不可恢复)
git checkout -- path/to/file.c
# 新版:git restore path/to/file.c

提交与推送:

git add path/to/file.java
git commit -m "xxx"
git pull --rebase          # 先把别人的提交接到你下面,历史更直
git push origin yourbranch

推错了怎么办?

情况 做法
已 push git revert <哈希> 生成「反向提交」再 push(安全,适合共享分支)
还没 push git reset --soft <旧哈希> 回退提交但保留改动,再重新 commit
git revert 9b747313165986b660
git reset --soft 15757914116eddbc4b012f9bcee288be9d906671

共享分支尽量避免 reset --hard + push --force


十、跨仓库 / 跨分支 cherry-pick

把分支 A 上的几笔提交,接到分支 B:

cd /path/to/target-repo
git checkout target-branch

# 若源在另一个本地仓库,可先加 remote
git remote add other /path/to/source-repo
git fetch other source-branch

# 按时间顺序逐个挑
git cherry-pick <hash1>
git cherry-pick <hash2>
git cherry-pick <hash3>

# 有冲突:改文件 → add → 继续
git cherry-pick --continue
# 放弃这次 pick:git cherry-pick --abort

git push origin target-branch

二进制冲突(如 .apk

Git 无法自动合并二进制,需要二选一:

git status   # 看到 both modified

# 用「被 pick 进来的那一方」(cherry-pick 语境下常叫 theirs)
git checkout --theirs path/to/app.apk
git add path/to/app.apk

# 或保留当前分支版本
git checkout --ours path/to/app.apk
git add path/to/app.apk

git cherry-pick --continue

补: ours / theirsmergecherry-pick/rebase 里含义容易反着记。拿不准就:

git show :2:path/to/file   # 一方
git show :3:path/to/file   # 另一方

或直接用明确来源覆盖后再 git add


十一、回退到指定提交 / 再救回来

硬回退(丢弃之后所有本地提交与工作区)

git reset --hard 4bf967474d45061ea959745661a9c90579356d9d

回退后又想回到「以前最新」

git fetch
git log --oneline --graph --all
git reset --hard 854a9e6          # 选你想恢复到的哈希
# 若远程分支还在:git reset --hard origin/yourbranch

补: 不确定哈希时先看:

git reflog

十二、导出 patch

# 某个已有 commit → patch 文件
git format-patch -1 d163256d0ba9f3c2fd6264d53bebd6be280fafed -o ./patches

# 当前未提交 diff → 一个文件
git diff > ./patches/my_change.patch

应用:

git apply ./patches/my_change.patch
# 或:git am 0001-xxx.patch

十三、交互式 rebase:删提交 / 压成一个

删掉中间某几笔

先找到「要保留的起点」的父提交,再:

git rebase -i 75d2b17ba3158826d4c07fb60418c3f46e50b657

编辑器里把不要的行改成 drop(或删掉该行),保存退出。

rebase 搞砸了:回到 rebase 前

git reflog
# 找到 rebase 开始前的 HEAD@{n}
git reset --hard HEAD@{4}

或正在 rebase 中途:

git rebase --abort

多个 commit 压成一个(squash)

注意:列表里第一行必须是 pick,后面才能 squash / s

pick   245ce7b  fix build error +2
squash de41801  fix build error +1
squash 1ba3f71  fix build error
squash 16f3bc1  add permission

冲突时:

git status
# 编辑冲突文件,去掉 <<<<<<< ======= >>>>>>>
git add <file>
git rebase --continue

合并完成后改说明:

git commit --amend

不满意整体:

git rebase --abort

十四、一张「先想清楚再敲」对照表

目的 优先命令 危险度
查谁改的行 blame + show
临时切走 stash
拉代码有本地改动 commit / stash /(慎)hard 中~高
只要某几笔 cherry-pick 中(冲突)
改历史形状 rebase -i 中(已 push 更危险)
本地整段扔掉 reset --hard
救回误操作 reflogreset --hard
已 push 的错提交 revert 低(推荐)

十五、再补几条高频命令

# 当前分支跟踪谁、是否领先/落后
git status -sb

# 只下载不合并
git fetch origin

# 看两个分支差哪些提交
git log --oneline branchA..branchB

# 暂存区与上次提交的差
git diff --cached

# 改最后一次提交说明(尚未 push 或确认可改)
git commit --amend -m "新说明"

小结

日常记住五件事就够应付大半场景:

  1. log / blame / show / diff
  2. stash 再切分支、再 pull
  3. addcommitpull --rebasepush
  4. cherry-pick,二进制冲突用手选 ours/theirs
  5. reflog + reset;已共享历史优先 revert

把这份当速查表即可;真正危险的是 --hard 和强推,敲之前先 statusreflog 看一眼。


相关阅读

评论

还没有评论,来做第一个吧

有想法?直接在这说,不用跑留言板