仅存储git中的阶段性变化 - 是否可能?

MrD*_*Duk 305 git git-stash

有没有办法可以隐藏我的分阶段变化?我遇到问题的情况是,我在给定时间处理了几个错误,并且有几个未分阶段的更改.我希望能够单独存档这些文件,创建我的.patch文件,并将它们存放起来,直到代码被批准为止.这样,当它被批准时,我可以存储我的整个(当前)会话,弹出该错误并推送代码.

我是以错误的方式来做这件事的吗?我是否误解了git如何以其他方式工作以简化我的流程?

Bar*_*zyk 404

是的,无论是否相信,它都是可能的 :DOUBLE STASH:

  1. 存储您需要存储的所有文件.
  2. git stash --keep-index.此命令将创建一个包含所有更改(暂存和未暂存)的存储,但会在工作目录中保留暂存的更改(仍处于暂存状态).
  3. git stash push -m "good stash"
  4. 现在你"good stash"已经ONLY上演文件.

现在,如果您在存储之前需要非暂存文件,只需应用第一个存储(使用创建的--keep-index存储),现在您可以删除存储到的文件"good stash".

请享用

  • 你怎么能"删除你藏匿的文件"好藏匿""? (13认同)
  • @Aurimas,要存储新文件,你需要使用`-u`开关. (5认同)
  • 你能改善你的答案吗?1-修正一个拼写错误:`这个命令存在`2-解释你的意思`但是会留下那些上演的`.3-解释这个命令在做什么.4-以"现在"开头的最后解释对我来说仍然不清楚.我不相信我可以使用你的解决方案.这只是我. (4认同)
  • 这不知何故遗漏了所有新文件(甚至是暂存的)。 (4认同)
  • 当您重新应用第一个存储并获得所有更改时,您可能只对您的非暂存更改感兴趣,请使用`git stash apply --index`选项.这将试图保持你的(阶段性)状态.现在更容易从工作树中删除不需要的更改. (2认同)
  • 我认为这个答案非常令人困惑,将使用“git stash push --patch”代替 (2认同)
  • 您可以在**步骤 2** 中运行 `git stash --keep-index --include-untracked` 来包含未跟踪的文件。 (2认同)
  • 请停止对这个过时且黑客的答案进行投票。只需使用“git stash push --staged”即可。看看所有其他答案。 (2认同)

Von*_*onC 181

在 Git 2.35(2022 年第 1 季度)中,“ git stashman学会了--staged隐藏已添加到索引中的内容(仅此而已)的选项。

所以这现在得到了官方支持(8年后)。

请参阅提交 a8a6e06(2021 年 10 月 28 日)和提交 41a28eb(2021 年 10 月 18 日),作者:Sergey Organov ( sorganov)
(由Junio C Hamano 合并 -- gitster--提交 44ac8fd中,2021 年 11 月 29 日)

stash:为“推送”和“保存”实施“--staged”选项

签署人:谢尔盖·奥加诺夫

仅存储已上演的更改。

此模式允许轻松隐藏一些与当前正在进行的工作无关的更改,以供以后重用。

与 ' stash push --patch' 不同,--staged支持使用任何工具来选择对 stash-out 的更改,包括但不限于 ' git add --interactive' ( man )

git stash现在包含在其手册页中:

'git stash' [push [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--quiet]

git stash现在包含在其手册页中:

save [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>]

git stash现在包含在其手册页中:

-S

--staged

push该选项仅对和命令有效save

仅存储当前正在进行的更改。这与基本类似git commit,只是状态被提交到存储而不是当前分支。

--patch选项优先于该选项。

git stash现在包含在其手册页中:

Saving unrelated changes for future use

当您正在进行大规模更改并且发现一些您不想忘记修复的不相关问题时,您可以进行更改,暂存它们,并将git stash push --staged它们存放起来以供将来使用。
这类似于提交分阶段的更改,只是提交最终位于存储中而不是当前分支上。

----------------------------------------------------------------
# ... hack hack hack ...
$ git add --patch foo           # add unrelated changes to the index
$ git stash push --staged       # save these changes to the stash
# ... hack hack hack, finish curent changes ...
$ git commit -m 'Massive'       # commit fully tested changes
$ git switch fixup-branch       # switch to another branch
$ git stash pop                 # to finish work on the saved changes
----------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

  • 如果暂存和未暂存的块接触文件的相同行,则“git stash --staged”会失败。 (7认同)
  • 很高兴您不需要使用“-u”,任何上演的内容(无论是否被跟踪)都将被隐藏。 (2认同)

Som*_* S. 127

TL;DR只需-- $(git diff --staged --name-only)为您的 git<pathspec>参数添加

这是一个简单的单行:

git stash -- $(git diff --staged --name-only)
Run Code Online (Sandbox Code Playgroud)

并简单地添加一条消息:

git stash push -m "My work in progress" -- $(git diff --staged --name-only)
Run Code Online (Sandbox Code Playgroud)

v2.17.1v2.21.0.windows.1上测试

限制:

  • 请注意,如果您没有暂存文件,这将隐藏所有内容。
  • 此外,如果您有一个仅部分暂存的文件(即只有一些已更改的行已暂存,而其他一些已更改的行未暂存),则整个文件将被隐藏(包括未暂存的行)。

  • 我认为这是针对所描述情况的最佳选择:易于理解并且不涉及黑魔法! (22认同)
  • 请注意(至少在我的机器 2.27.0.windows.1 上)只有当您位于存储库的顶级目录中时,此操作才有效。 (4认同)
  • @IgorNadj 当然!这是:https://github.com/panchalkalpesh/git-aliases/commit/e6cf92d056600f7202f18cd223f5dc966620ec4c (2认同)
  • @marco6,使用 `--relative` 标志来解决这个问题 (2认同)
  • 如果暂存已删除的文件,这似乎不起作用。 (2认同)

Eug*_*kov 97

使用最新的git,您可以使用--patch选项

git stash push --patch
Run Code Online (Sandbox Code Playgroud)

并且git会要求您将文件中的每个更改添加或不添加到存储中.你只需回答yn

  • 技术上没有回答这个问题 - 但这是一种非常好的技术,可以实现选择性的存储. (12认同)
  • 同意,这没关系,但是这里的问题是我已经完成了所有我要进行的更改工作(表面上是最初要提交,但现在想隐藏),而不是仅仅考虑再做一遍。 (4认同)
  • 不适用于新创建的文件(仅适用于修改后的文件) (3认同)
  • @DerekLiang:根本不会跟踪新创建的文件。您可能应该检查 `git-stash` 的 `-u|--include-untracked` 选项 (2认同)
  • 从[docs](https://git-scm.com/docs/git-stash):“ **保存**:不建议使用此选项,而推荐使用_git stash push_。它与'stash push'不同之处在于它不能采用pathspec,并且任何非选项参数都构成消息。” (2认同)

小智 47

我创建了一个脚本,只保存当前暂存的内容,并保留其他所有内容.当我开始做太多无关的更改时,这很棒.简单地发布与所需提交无关的内容并将其存储起来.

(感谢Bartłomiej的起点)

#!/bin/bash

#Stash everything temporarily.  Keep staged files, discard everything else after stashing.
git stash --keep-index

#Stash everything that remains (only the staged files should remain)  This is the stash we want to keep, so give it a name.
git stash save "$1"

#Apply the original stash to get us back to where we started.
git stash apply stash@{1}

#Create a temporary patch to reverse the originally staged changes and apply it
git stash show -p | git apply -R

#Delete the temporary stash
git stash drop stash@{1}
Run Code Online (Sandbox Code Playgroud)

  • 我想补充一点,您可以通过http://thediscoblog.com/blog/2014/03/29/custom-git-commands-in-3-steps/将脚本转换为git命令 (7认同)
  • 这很棒!我已对其进行了调整,以提示用户是否在命令行中未输入存储说明:https://gist.github.com/brookinc/e2589a8c5ca33f804e4868f6bfc18282 (3认同)

Ram*_*man 11

在 Git 中仅存储索引(分阶段更改)比应有的更困难。我发现@Joe 的答案效果很好,并将它的一个小变化变成了这个别名:

stash-index = "!f() { \
  ! git diff --cached --exit-code --quiet && \
  git stash push --quiet --keep-index -m \"temp for stash-index\" && \
  git stash push \"$@\" && \
  git stash pop --quiet stash@{1} && \
  git stash show -p | git apply -R; }; f"
Run Code Online (Sandbox Code Playgroud)

它:

  1. 验证是否存在实际分阶段更改(git diff --cached --exit-code如果有则返回非零状态)。HT:@nandilugio

  2. 这必将推动双方的演出和未分级变成一个临时藏匿处,留下独自上演的变化。

  3. 然后它将分阶段的更改推送到 stash 中,这是我们想要保留的 stash。传递给别名的参数,例如--message "whatever"将添加到此 stash 命令中。

  4. 它弹出临时存储以恢复原始状态并删除临时存储,然后

  5. 最后通过反向补丁应用程序从工作目录中“删除”隐藏的更改。

对于仅存储未暂存更改(别名stash-working)的相反问题,请参阅此答案


Sha*_*mps 8

在这种情况下,我更愿意为每个问题创建新的分支。我使用前缀temp /,所以我知道以后可以删除这些分支。

git checkout -b temp/bug1
Run Code Online (Sandbox Code Playgroud)

暂存修复bug1的文件并提交。

git checkout -b temp/bug2
Run Code Online (Sandbox Code Playgroud)

然后,您可以根据需要从各个分支中挑选提交,并提交拉取请求。

  • 虽然花哨的声音听起来很不错,但实际上,这似乎是我不太可能采用的方法。 (2认同)

kni*_*ttl 6

为什么不为某个bug提交更改并从该提交及其前身创建补丁?

# hackhackhack, fix two unrelated bugs
git add -p                   # add hunks of first bug
git commit -m 'fix bug #123' # create commit #1
git add -p                   # add hunks of second bug
git commit -m 'fix bug #321' # create commit #2
Run Code Online (Sandbox Code Playgroud)

然后,要创建适当的补丁,请使用git format-patch:

git format-patch HEAD^^
Run Code Online (Sandbox Code Playgroud)

这将创建两个文件:0001-fix-bug-123.patch0002-fix-bug-321.patch

或者,您可以为每个错误创建单独的分支,因此您可以单独合并或重新定义错误修复,如果它们无法解决,甚至可以删除它们.


Mic*_*ael 5

为了完成同一件事...

  1. 仅暂存您要处理的文件。
  2. git commit -m 'temp'
  3. git add .
  4. git stash
  5. git reset HEAD~1

繁荣。不需要的文件被保存起来。所需的文件已准备就绪。

  • 这很容易是最好的答案,也是最容易记住的 (7认同)
  • 投票是因为有用,但这并不能回答问题——最终在存储中的是步骤 #1 中未暂存的更改,而问题是询问是否仅存储已暂存的更改。您正在回答与此问题相反的问题:/sf/ask/535555821/。我构建了一个基本上可以实现此目的的别名,并在此处进行了一些增强:/sf/answers/4261255771/。 (3认同)