HOWTO · Git
从 Git 仓库中提取特定提交
本文介绍了从远程 Git 仓库中提取特定提交的方法。
本页内容
要将单个提交引入当前分支,请先获取远程历史,再使用 git cherry-pick <commit-id>。如果要检查该提交对应的历史状态,或从那里继续开发,请在该提交处创建分支。只有在需要整合分支历史(其中也可能包含更早的提交)时,才使用 git merge 或 git pull。只有确实要将当前分支移回较早位置时,才使用 git reset。
如何为特定提交选择合适的操作
这些操作的结果各不相同。git cherry-pick 会将所选提交引入的更改作为一个新提交应用到当前分支。在某个提交处创建分支,意味着从该快照开始工作。合并提交时,会纳入当前分支尚未包含、且可从该提交到达的历史记录。拉取会从远程获取内容,并按照已配置的拉取行为进行整合。重置会移动当前分支引用;--hard 还会用目标提交替换工作区和暂存区。请根据需要的是单项更改、历史起点、远程历史,还是将分支回退,来选择操作。
查找提交哈希
运行 git log 可以查看提交 ID、作者和说明。要查看精简列表,请使用 git log --oneline。复制目标提交显示的 ID;只要缩写后没有歧义,Git 也接受缩写 ID,而不必使用完整对象 ID。如果该提交只存在于远程,请先运行 git fetch origin 获取更新,再查看更新后的历史记录。将 origin 替换为你的远程名称,并将 <commit-id> 替换为所选提交的 ID。
使用 git cherry-pick 应用单个提交
先获取远程分支或其对象,然后依次运行 git fetch origin 和 git cherry-pick <commit-id>,应用所选提交。当你只想引入一个提交的更改,而不想合并整个分支时,这是直接的做法。下面的本地示例会先在主题分支上创建一个提交,再将其应用到 main:
repo=$(mktemp -d)
trap 'rm -rf "$repo"' EXIT
git -C "$repo" init -q -b main
git -C "$repo" config user.name "Example User"
git -C "$repo" config user.email "example@example.com"
printf 'base\n' > "$repo/notes.txt"
git -C "$repo" add notes.txt
git -C "$repo" commit -qm "Add notes"
git -C "$repo" switch -q -c topic
printf 'one change\n' >> "$repo/notes.txt"
git -C "$repo" add notes.txt
git -C "$repo" commit -qm "Add one change"
commit_id=$(git -C "$repo" rev-parse HEAD)
git -C "$repo" switch -q main
git -C "$repo" cherry-pick "$commit_id"
printf 'Applied one commit to main.\n'
[main 5ede2b1] Add one change
Date: Mon Oct 26 03:50:14 2026 +0000
1 file changed, 1 insertion(+)
Applied one commit to main.
如果发生冲突,请解决标记出的文件,用 git add 将解决结果暂存,然后运行 git cherry-pick --continue 继续操作。若要停止并恢复到操作开始前的状态,请运行 git cherry-pick --abort。开始其他操作前,请先完成或中止当前操作。
在特定提交处创建分支
如果要检查某个提交或以它为基础开发,同时不移动当前分支,请先获取远程内容,再运行 git checkout -b review-branch <commit-id>。这会在该提交处创建并切换到 review-branch。新分支会包含该提交的历史;除非合并或 cherry-pick 其他分支上的后续提交,否则这些提交不会自动包含在内。
从远程获取并合并提交
运行 git fetch origin 可以更新远程跟踪引用,而不会将其整合到当前分支。然后使用 git merge <commit-id> 合并所选提交,以及当前分支尚未包含、但可从该提交到达的历史记录。这样可能会一并引入祖先提交,因此它与只应用所选提交的更改并不相同。使用 git log --oneline --graph --decorate 查看合并后的历史记录。
使用 git pull 和提交哈希
如果某个提交对象可从远程到达,且服务器允许该请求,远程可能支持按原始提交 ID 获取对象。各远程的支持情况不同,因此 git pull origin <commit-id> 并不是一种通用的单项更改选择方式。请求获准后,pull 会根据你的配置获取并整合内容;这并不表示“只应用此提交”。如果只需要一项更改,请获取后使用 cherry-pick。否则,请获取一个命名分支,再拉取或合并该分支。
将分支重置到特定提交
只有在确实要移动当前分支,并用目标提交替换暂存区和工作区时,才使用 git reset --hard <commit-id>。它可能会丢弃尚未提交的更改。如果之后推送已移动的分支,协作者可能需要处理被改写的共享历史。重置前,请运行 git status,并保存需要保留的工作。若要更安全地撤销更改并保留已发布的历史,请使用 git revert <commit-id> 创建一个新提交,以反转所选更改。
常见问题
如何查找提交 ID? 使用 git log 或 git log --oneline;如果提交只在远程上,请先获取远程内容。
cherry-pick 报告冲突时怎么办? 解决并暂存每个冲突文件,然后运行 git cherry-pick --continue;运行 git cherry-pick --abort 可以取消操作。
可以 cherry-pick 多个提交吗? 可以。按预期顺序将多个 ID 传给 git cherry-pick,也可以先确认提交范围两端分别包含什么,再使用提交范围。
reset 和 revert 一样吗? 不一样。git reset 会移动分支引用,并可能替换本地文件;git revert 会记录一个新提交,用来撤销较早的更改。