# Git Stash 与 gwip

## 1、如何在不提交修改的前提下，执行 pull 或分支切换的操作？

我见过最圡方法是，将修改的文件 copy 到 git 仓库之外的目录临时存放，pull 或分支切换操作完成之后，再 copy 回来。

**拷贝覆盖文件的做法，一是效率不高，二是可能会遗漏潜在的冲突。**

事实上，如果你的 git 版本大于 2.10，那么只需以下一行命令就能自动完成 git stash -> git pull -> git stash pop 的操作。

```
git pull --rebase --autostash # gupa
```

## 2、git stash

在当前任务未完成前，我们可能需要执行本地与远程分支的同步或本地不同分支的 merge 操作。这时候如果将未完成修改的文件直接 commit，会导致 log 中记录许多无效的 commit 和 merge 记录。

git stash 可以将当前工作状态（WIP，work in progress）临时存放在 stash 列表中，待 pull / merge 操作完成后，再从 stash 中重新应用这些修改。

以下是 git stash 常用命令：

```
# 查看 stash 列表中已暂存了多少 WIP
git stash list              # gstl
​
# 添加当前 WIP
# -u 参数表明新增的文件也一起 stash
git stash -u save 'message' # gsta -u

# 恢复上一次的 WIP 状态，并从列表中移除
git stash pop               # gstp

# 恢复指定编号的 WIP，同时从列表中移除
git stash pop stash@{num}   # gstp 0
​
# 恢复指定编号的 WIP，但不从列表中移除
git stash apply stash@{num} # gstaa 0
```

**注：如果 git stash 的文件刚好被其他提交修改过了，那么在 pop 时会自动将修改过的文件标记为 conflict 状态。需要注意的是，pop 出来的文件，是 --theirs 而非 --ours。**

## 3、gwip 与 gunwip

Stash 的记录只保存在本地，如果需要在不同电脑间（例如公司和家里）同步临时性的修改，则无法通过 git stash 完成。

Git 社区中有一条约定是，在 commit 中通过 **wip** 关键词表示，这是一次 **work in progress** 的临时提交。借助 zsh git alias，我们可以通过一组 `gwip` 和 `gunwip` 命令来实现同步。

其实现原理是，gwip 提交了特定的 commit message（即，`--wip-- [skip ci]`），gunwip 判断如果上一次提交为 gwip 提交，则自动进行 reset，以下是 alias 的细节。

```
alias gunwip='git log -n 1 | grep -q -c "\-\-wip\-\-" && git reset HEAD~1'
alias gwip='git add -A; git rm $(git ls-files --deleted) 2> /dev/null; git commit --no-verify -m "--wip-- [skip ci]"'
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gb.yekai.net/concepts/stash-vs-gwip.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
