如何在不使用 git-stash 的情况下保存正在进行的工作?

How do I save work in progress without using git-stash?

我有一个 git 目录有这种情况:

ProgSoul@PROGSOUL-LENOVO:~/esercizio3_2$ git status
Sul branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   A

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   A

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        B

在这种情况下我有:

老师要我暂时停止工作,创建一个BUGFIX文件,提交并恢复之前的状态。

我是通过这些命令实现的:

git stash --include-untracked
touch BUGFIX
git add BUGFIX
git commit -m "Aggiunto file BUGFIX"
git stash pop --index

使用这些命令,我​​保存了我的初始情况,并在提交修复后恢复了它。 我的老师还要求我在不使用 git-stash 的情况下达到这个目标。

我遵循了存储文档中的帮助:

git checkout -b WIP
git commit -a -m "WIP"
git checkout master
touch BUGFIX
git add BUGFIX
git commit -a -m "BUGFIX"
git checkout WIP
git reset --soft HEAD^

使用 git reset --soft 我恢复了索引,但未暂存提交的更改已丢失。

使用 git reset --mixed 我恢复了未暂存提交但索引已丢失的更改。

在不使用 git 存储的情况下提交修复后,如何恢复相同的初始状态?

让我们这样试试:

  • 问:如何在 Git 中保存内容?

  • 答:提交。

  • 问:git stash呢,好像可以省事,怎么办?

  • A:它提交。

  • 问:但是它没有在我的分支上提交任何内容。1

  • A:他们在特殊的 "stash" 事情上,这不是一个分支。但他们仍然提交。


1从技术上讲,这不是问题。 :-)


如果你想在 Git 中保存一些东西,请提交它

这就是 Git 底线,可以说是:提交可以保存东西。否则,您所拥有的只是工作树中的内容,以及索引(暂存区)中的内容。当您 运行 git commit 时,暂存区的东西会永久存在。工作树的东西是永不永久的:你必须将它复制到暂存区然后提交它。

这就是 git stash 所做的。它实际上使 两次 提交,一次用于当前索引,一次用于工作树。2 它只是使它们都在除此之外的其他东西上一个分支,使用名称 stash 来查找它们。

不过,没有什么能阻止您做出自己的承诺。进行两次或多次提交然后必须撤消它们只是有点痛苦,这就是 git stash 存在的原因。


2当你像以前那样使用 --include-untracked 时,它实际上使 三个 提交:一个用于索引,一个第二个用于工作树,第三个用于未跟踪文件。第三次提交非常棘手,无论是制作还是恢复。隐藏脚本使用临时索引而不是尝试在主索引中完成工作。


您可以随时使用另一个克隆

每个 Git 存储库通常独立于所有其他 Git 存储库,但可以与任何相关的 Git 存储库对等。因此,您可以将一个存储库克隆到另一个存储库,从而获得另一个可以工作的工作树。该工作树还带有自己的(单独的)索引/暂存区。

如果您在本地进行克隆,在您的本地文件系统上,Git 通常能够避免大量的存储库文件复制。因此,虽然这看起来很昂贵,但通常还不错。主要问题是你现在有两个存储库要记住提交,你必须获取 and/or 在它们之间推送 and/or 无论你最初从哪个上游克隆。

对于快速的辅助工作,git worktree add(仅限 2.5 和更新版本)

在 Git 2.5 之前有一个 "contributed" 脚本来制作备用工作树。从 2.5 开始,它得到了官方支持,尽管从那时起修复了一些重要的错误(即使现在它也有一些粗糙的边缘)。您现在可以 运行 git worktree add 创建一个新的工作树,它将使用 不同的 分支,但共享底层存储库。

共享一个底层存储库的两个工作树不得使用同一个分支。 (这是因为 Git 存储其对 "current branch" 和 "current commit" 的想法的方式,以及当您创建 时 Git 推进当前分支的方式new commit.) 但是,如果你的目标是修复一些 other 分支而不是你现在正在处理的分支,这正是你所需要的.

Git为此内置了一个鲜为人知的功能。

echo fix fix >> BUGFIX
git add BUGFIX
git commit BUGFIX

... 如果 BUGFIX 已经被跟踪,您甚至不需要 git add,它会为您完成。参见 the git commit description 的第 3 点:

listing files as arguments to the commit command (without --interactive or --patch switch), in which case the commit will ignore changes staged in the index, and instead record the current content of the listed files (which must already be known to Git);

虽然描述中没有说明,但当前内容已添加到索引和提交中。

感谢我收到的每一个答复。我实现了两种可能的解决方案:

git worktree add -b BUGFIX ../bugfix_temp master
pushd ../bugfix_temp
touch BUGFIX
git add BUGFIX
git commit -a -m "emergency BUGFIX"
popd
rm -rf ../bugfix_temp
git worktree prune

touch BUGFIX
git add BUGFIX
git commit --only BUGFIX -m "emergency BUGFIX"

如果您在文件中有大量更改想要保存但尚未提交,那么一个选择是对您的更改进行差异比较并将该差异保存到文件中并将差异存储在其他位置.

git diff changedfile > ~/diff_of_an_idea.diff
git restore changedfile # back to original

然后稍后当你想要包含 diff

git apply ~/diff_of_an_idea.diff
git add & git commit