【问题标题】:How do I save work in progress without using git-stash?如何在不使用 git-stash 的情况下保存正在进行的工作?
【发布时间】:2017-05-04 17:30:27
【问题描述】:

我有这个情况的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

在这种情况下,我有:

  • 索引中有一个名为 A 的文件,其中包含一个字符串“AA”
  • 我修改了文件 A,其中包含“AAA”,但我没有在舞台上添加此更改。所以在工作目录中,我有一个 A,里面有一个字符串“AAA”
  • 未跟踪的空文件 B

我的老师要我暂时暂停我的工作,创建一个 BUGFIX 文件,提交它并恢复我以前的情况。

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

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

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

我遵循了 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 stash 提交修复后,如何恢复相同的初始情况?

【问题讨论】:

  • 我看不到这个问题的价值。你为什么要刻意尝试解决一个已经存在的好而简单的解决方案?这仅与您的班级相关,因此您最好只问您的老师如何解决这个“问题”。
  • 我无法向老师询问解决方案,所以我需要一个解决方法。也许对你没用,但对我有用。
  • 您是否允许提交您的更改并在另一个分支上创建错误修复?
  • 是的,我可以。我对如何实现结果没有任何限制。
  • 将原始存储库克隆到新目录。进行错误修复/提交/推送。回到原来的目录。下拉更改。继续。

标签: git git-branch git-commit git-stash git-reset


【解决方案1】:

如果您想要保存但尚未提交的文件中有大量更改,那么一种选择是获取更改的差异并将该差异保存到文件中并将差异存储在其他位置。

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

之后的某个时候,当你想要包含差异时

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

【讨论】:

    【解决方案2】:

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

    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"
    

    【讨论】:

      【解决方案3】:

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

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

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

      列出文件作为提交命令的参数(没有 --interactive 或 --patch 开关),在这种情况下,提交将忽略索引中暂存的更改,而是记录列出文件的当前内容(必须已经Git 知道);

      虽然描述没有说出来,但当前内容和提交一样被添加到索引中。

      【讨论】:

      • 这样做的一个问题是,如果没有--only 或命令行文件参数,您还将提交当前暂存的文件,因此很容易出错。 (对于命令行参数,还包括暂存文件,请使用--include。)不过,对于只提交一个文件来说,这是一件很方便的事情。 [旁注:如果有命令行文件参数,--only 是默认值,而--only 没有这样的参数是没有意义的,那么为什么--only 存在呢? :-)]
      • 但是对于错误提交的撤销既便宜又容易,git reset @^; git read-tree @{1}
      • 嗯。哦,我最近还没有检查过——自从我前一阵子试验以来,Git 发生了变化——但是 git commit --only foo 最终将提交的工作树 fooHEAD 提取到索引中,即使有修改版本foo 上演,因此破坏了精心上演的版本。所以这里还有另一种危险,我忘记了,但现在记起来了。
      • 好吧,它的行为与 stash 方法的结果完全相同,因为 stash pop 合并了。
      • 是的,除非您使用git stash pop --indexgit stash apply --index(或git stash branch,它使用pop --index)。当然,这些都不是 new 文件的问题。
      【解决方案4】:

      让我们这样试试吧:

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

      • 答:提交。

      • Q:那git stash呢,好像能救东西,它是怎么做到的?

      • 答:它提交。

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

      • A:他们在特殊的“stash”东西上,它不是一个分支。但它们仍然是提交。


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


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

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

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

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


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


      你总是可以使用另一个克隆

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

      如果您在本地进行克隆,在本地文件系统上,Git 通常能够避免大量的存储库文件复制。因此,虽然这可能看起来很昂贵,但通常并没有那么糟糕。主要问题是您现在有两个要记住提交的存储库,并且您必须在它们和/或您最初克隆的任何上游之间获取和/或推送。

      为了快速完成工作,git worktree add(仅限 2.5 和更高版本)

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

      共享一个底层存储库的两个工作树不能使用同一个分支。 (这是因为 Git 存储“当前分支”和“当前提交”概念的方式,以及当您进行 new 提交时 Git 推进当前分支的方式。)如果你的目标是,但是,要修复一些 other 分支而不是您现在正在处理的分支,这正是您所需要的。

      【讨论】:

      • 谢谢,这是一个有用的答案。我发布了完整的解决方案。 +1
      猜你喜欢
      • 1970-01-01
      • 2011-09-13
      • 2013-07-21
      • 2020-05-17
      • 1970-01-01
      • 1970-01-01
      • 2021-01-18
      • 2011-04-08
      • 1970-01-01
      相关资源
      最近更新 更多