# 列出所有 stash ➜ git stash list stash@{0}: WIP on main: abc1234 Last commit message stash@{1}: On feature: WIP: working on feature stash@{2}: WIP on main: def5678 Previous commit message
# 当前分支有未提交的更改 ➜ git status On branch feature Changes not staged for commit: modified: src/main.c
# 保存更改 ➜ git stash Saved working directory and index state WIP on feature: abc1234
# 切换到其他分支 ➜ git checkout main
# 处理完其他任务后,切换回来 ➜ git checkout feature
# 恢复更改 ➜ git stash pop
场景2:拉取远程更新
1 2 3 4 5 6 7 8 9 10 11 12 13
# 本地有未提交的更改 ➜ git status Changes not staged for commit: modified: src/main.c
# 保存更改 ➜ git stash
# 拉取远程更新 ➜ git pull origin main
# 恢复更改 ➜ git stash pop
场景3:临时保存实验性更改
1 2 3 4 5 6 7 8 9 10 11 12
# 做一些实验性的更改 ➜ git stash save "experimental: try new approach"
# 继续其他工作...
# 如果实验失败,直接丢弃 ➜ git stash drop stash@{0}
# 如果实验成功,恢复并提交 ➜ git stash pop ➜ git add . ➜ git commit -m "Implement new approach"
场景4:处理多个 Stash
1 2 3 4 5 6 7 8 9 10 11 12 13
# 保存第一个更改 ➜ git stash save "WIP: feature A"
# 继续工作,保存第二个更改 ➜ git stash save "WIP: feature B"
# 查看所有 stash ➜ git stash list stash@{0}: WIP on main: WIP: feature B stash@{1}: WIP on main: WIP: feature A
# 应用特定的 stash ➜ git stash apply stash@{1}
场景5:保存未跟踪的文件
1 2 3 4 5 6 7 8 9 10 11
# 有未跟踪的文件需要保存 ➜ git status Untracked files: newfile.txt
# 保存包括未跟踪的文件 ➜ git stash -u Saved working directory and index state WIP on main: abc1234
# 恢复时,未跟踪的文件也会恢复 ➜ git stash pop
高级用法
交互式选择更改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# 交互式选择要暂存的更改 ➜ git stash -p diff --git a/src/main.c b/src/main.c index 1234567..abcdefg 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,10 @@ #include <stdio.h> + +void new_function() { + // new code +} + int main() { return 0; } Stash this hunk [y,n,q,a,d,/,e,?]? y
交互式选项:
y:暂存这个块
n:不暂存这个块
q:退出
a:暂存这个块和后面的所有块
d:不暂存这个块和后面的所有块
/:搜索匹配的行
e:手动编辑块
?:显示帮助
恢复暂存区状态
1 2 3 4 5
# 保存时保留暂存区 ➜ git stash -k
# 应用时恢复暂存区状态 ➜ git stash apply --index
基于 Stash 创建分支
1 2 3 4 5 6 7
# 如果直接应用 stash 可能产生冲突,可以创建新分支 ➜ git stash branch fix-conflict stash@{1} Switched to a new branch 'fix-conflict' On branch fix-conflict Changes to be committed: modified: src/main.c Dropped stash@{1} (abc1234...)
查看 Stash 的详细信息
1 2 3 4 5 6 7 8
# 查看 stash 的完整信息 ➜ git stash show -p stash@{0}
# 查看 stash 的统计信息 ➜ git stash show --stat stash@{0}
➜ git stash pop Auto-merging src/main.c CONFLICT (content): Merge conflict in src/main.c
解决方法:
解决冲突
添加解决后的文件:git add src/main.c
如果使用 pop,冲突解决后 stash 会自动删除
如果使用 apply,需要手动删除:git stash drop
查看 Stash 的完整内容
1 2 3 4 5
# 查看 stash 中所有文件的完整差异 ➜ git stash show -p stash@{0}
# 查看特定文件的差异 ➜ git diff stash@{0} -- src/main.c
比较 Stash 和当前工作目录
1 2 3 4 5
# 比较 stash 和当前工作目录 ➜ git diff stash@{0}
# 比较 stash 和特定提交 ➜ git diff stash@{0} HEAD
重命名 Stash
Git 不直接支持重命名 stash,但可以通过以下方式:
1 2 3
# 创建一个新的 stash 并删除旧的 ➜ git stash show -p stash@{0} | git stash push -m "New message" ➜ git stash drop stash@{1}
清理旧的 Stash
1 2 3 4 5 6 7 8
# 查看所有 stash ➜ git stash list
# 删除特定的 stash ➜ git stash drop stash@{5}
# 或者清空所有 ➜ git stash clear
在脚本中使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
#!/bin/bash # 检查是否有未提交的更改 if ! git diff-index --quiet HEAD --; then echo"Saving uncommitted changes..." git stash save "Auto-save before script" STASHED=1 fi
# 执行脚本操作...
# 如果有保存的更改,恢复它们 if [ "$STASHED" = "1" ]; then echo"Restoring uncommitted changes..." git stash pop fi
查看 Stash 的创建时间
1 2 3 4
# 使用 reflog 查看 stash 的创建时间 ➜ git reflog show stash abc1234 stash@{0}: WIP on main: def5678 Last commit def5678 stash@{1}: On feature: WIP: working on feature