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

我做错了吗?我是否误解了git如何以其他方式简化我的过程?


当前回答

Git隐藏推送——自2.35以来已上演#

只保存当前暂存的更改。这类似于基本的git提交,除了状态提交到stash而不是当前分支。

OLD

对于最新的git,您可以使用——patch选项

git stash push --patch   # since 2.14.6

git stash save --patch   # for older git versions

git会询问你文件中的每一个变化是否要添加到stash中。 你只需回答y或n

老乌利希期刊指南 别名DOUBLE STASH:

git config --global alias.stash-staged '!bash -c "git stash --keep-index; git stash push -m "staged" --keep-index; git stash pop stash@{1}"'

现在您可以暂存文件,然后运行git stash- staging。 因此,您的阶段性文件将保存到stash。

如果您不想保留阶段性文件,并希望将它们移动到隐藏。然后你可以添加另一个别名并运行git move- staging:

git config --global alias.move-staged '!bash -c "git stash-staged;git commit -m "temp"; git stash; git reset --hard HEAD^; git stash pop"'

其他回答

我还没有见过这种不需要使用git stash的解决方案:

你甚至不需要使用git隐藏在所有。你可以使用一个专用的分支来解决这个问题(分支很便宜)。

实际上,你可以用几个连续的命令分别隔离非变化和阶段性变化,你可以把它们捆绑在一个git别名中:

创建并切换到一个新的分支,在那里你将分别提交阶段性和非阶段性的更改:参见这里

在任何时候,你都可以从创建的分支中选择-e一个提交,并将其应用到你想要的地方(-e更改其提交消息)。

当你不再需要它时,你可以删除这个“收藏分支”。你可能不得不使用-D选项来强制删除(而不是-D普通选项),因为该分支没有合并,git可能会认为如果你删除它会有丢失数据的风险。如果你没有选择删除前的提交,这是正确的:

git branch -D separated-stashes

您还可以为~/添加别名。Gitconfig,以便自动化此行为:

git config --global alias.bratisla '!git switch -c separated-stashes; git commit -m "staged changes"; git add -u; git commit -m "unstaged changes"; git switch -' # why this name ? : youtu.be/LpE1bJp8-4w

在“藏” 在“藏”



当然,您也可以使用两个连续的存储来实现相同的结果

正如在其他答案中所述,您可以使用git stash (-k|——keep-index)与其他命令组合使用一些方法来仅保存非阶段性或仅阶段性的更改。

我个人认为-k选项非常令人困惑,因为它存储了所有内容,但将阶段性更改保持在阶段性状态(这解释了为什么使用“——keep-index”)。而储存东西通常会把它移动到一个储存入口。使用-k,非暂存的更改通常会被存储,但暂存的更改只是复制到相同的暂存条目。


第0步:你的git状态中有两个东西:一个包含阶段性变化的文件,另一个包含非阶段性变化的文件。

第一步:保存非阶段性+阶段性变化,但将阶段性变化保留在索引中:

git stash -k -m "all changes"

-m "…"部分是可选的,git stash -k实际上是git stash push -k的别名(它不会远程推送任何东西,顺便说一句,不用担心),它接受一个-m选项来标记你的stash条目,以使其清晰(就像一个提交消息或标签,但对于一个stash条目)。它是已弃用的git存储保存的新版本。


步骤1bis(可选):

git stash

隐藏阶段性更改(仍在索引中)。 这一步对于下面的内容不是必需的,但是它表明,如果您愿意,您可以只将阶段性的更改放在存储条目中。 如果你使用这一行,你必须在继续第二步之前git stash (pop|apply) && git add -u。


第二步:

git commit -m "staged changes"

提交只包含从步骤0开始的阶段性更改,它包含与步骤1bis开始的隐藏条目相同的内容。


第三步:

git stash (pop|apply)

恢复第1步的存储。 注意,这个隐藏条目包含了所有内容,但是由于您已经提交了阶段性更改,所以这个隐藏只会添加从第0步开始的非阶段性更改。

注意:这里的“restore”并不是指“git restore”,这是一个不同的命令。


第四步:

git add -u

将弹出的存储的内容添加到索引中


第五步:

git commit -m "unstaged changes"

这里的“未分期”,与步骤2和步骤3注释中的“分期”一样,指的是步骤0。实际上,您正在登台并提交从步骤0开始的“登台更改”。


完成了! 您现在有两个独立的提交,其中包含从第0步开始的(un)阶段性更改。 您可能希望修改/重新设置它们以进行其他更改或重命名/删除/压缩它们。 取决于你对你的stash的堆栈做了什么(弹出或应用),你可能还想要git stash (drop|clear)它。你可以看到你用git stash (list|show)

在这个场景中,我更喜欢为每个问题创建新的分支。我使用了一个前缀temp/,所以我知道我可以稍后删除这些分支。

git checkout -b temp/bug1

准备修复bug1的文件并提交它们。

git checkout -b temp/bug2

然后,您可以根据需要从相应的分支中选择提交,并提交一个拉取请求。

为了达到同样的目的…

只准备您想要处理的文件。 Git提交-m 'temp' Git添加。 git藏 git重置头~1

繁荣。你不想要的文件都被藏起来了。您要的文件都准备好了。

更新2022-04-21 只要使用@VonC的答案,这是对原始问题https://stackoverflow.com/a/70231955/2959469的新惯用方法


只需要为你的git <pathspec>参数添加——$(git diff——staging——name-only)

这是一个简单的一行代码:

git stash -- $(git diff --staged --name-only)

并简单地添加一条消息:

git stash push -m "My work in progress" -- $(git diff --staged --name-only)

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

限制:

请注意,这将隐藏每一个单一的东西,如果你没有文件上演。 同样,如果你有一个文件,只是部分上演(即只有一些更改的行,被上演,而其他一些更改的行没有),那么 整个文件将被存储(包括未登台的行)。

为什么不提交对某个错误的更改,并根据该提交及其前身创建一个补丁呢?

# 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

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

git format-patch HEAD^^

这将创建两个文件:0001-fix-bug-123。补丁和0002-fix-bug-321.patch

或者您可以为每个错误创建单独的分支,这样您就可以单独合并或重新建立错误修复,甚至在它们不起作用时删除它们。