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

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


当前回答

您可以使用——staging来仅保存阶段性更改。

git stash --staged

文档:https://git-scm.com/docs/git-stash文档/ git-stash.txt-push-p——patch-S staged-k——no-keep-index-u include-untracked-a——all-q quiet-m——messageltmessagegt pathspec-from-fileltfilegt——pathspec-file-nul ltpathspecgt82308203

其他回答

要修剪意外的更改,特别是删除多个文件,请执行以下操作:

git add <stuff to keep> && git stash --keep-index && git stash drop

换句话说,把垃圾藏起来,把它们一起扔掉。

在git版本2.17.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

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

铊;博士;总stash-staged

创建别名后:

git config --global alias.stash-staged '!bash -c "git stash -- \$(git diff --staged --name-only)"'

这里git diff返回的是——暂存文件的列表——只有名字 然后我们将这个列表作为pathspec传递给git stash命令。

从男人的赃物:

git stash [--] [<pathspec>...]

<pathspec>...
   The new stash entry records the modified states only for the files
   that match the pathspec. The index entries and working tree
   files are then rolled back to the state in HEAD only for these
   files, too, leaving files that do not match the pathspec intact.

是否绝对有必要同时处理多个bug ?这里的“立刻”指的是“同时对文件进行多个错误的编辑”。因为除非您绝对需要,否则我在您的环境中一次只处理一个错误。这样你就可以使用本地分支和重新建立基础,我发现这比管理复杂的存储/阶段要容易得多。

假设master在提交b,现在处理bug #1。

git checkout -b bug1

现在您在分支bug1上。做一些修改,提交,等待代码审查。这是本地的,所以你不会影响到其他人,而且从git差异中制作补丁应该很容易。

A-B < master
   \
    C < bug1

现在您正在处理bug2。用git checkout master返回master。创建一个新的分支,git checkout -b bug2。进行更改,提交,等待代码审查。

    D < bug2
   /
A-B < master
   \
    C < bug1

让我们假设在您等待审查时,其他人在master上提交了E & F。

    D < bug2
   /
A-B-E-F < master
   \
    C < bug1

当你的代码被批准后,你可以按照以下步骤将其重新设置为master:

git checkout bug1
git rebase master
git checkout master
git merge bug1

这将导致以下结果:

    D < bug2
   /
A-B-E-F-C' < master, bug1

然后你可以推送,删除你的本地bug1分支,然后你就可以走了。在您的工作空间中,一次只处理一个错误,但是通过使用本地分支,您的存储库可以处理多个错误。这样就避免了复杂的舞台舞蹈。

请在评论中回答ctote的问题:

那么,您可以回到为每个bug存储,并且一次只处理一个bug。至少这省去了分期问题。但尝试过之后,我个人觉得很麻烦。在git日志图中,存储有点混乱。更重要的是,如果你把事情搞砸了,你就无法挽回了。如果你有一个脏的工作目录,你弹出一个隐藏,你不能“撤消”这个弹出。搞砸已经存在的提交要困难得多。

那么,这就叫反应i。

当您将一个分支重新基于另一个分支时,您可以交互地进行(-i标志)。当您这样做时,您可以选择对每次提交做什么。Pro Git是一本很棒的书,它也是HTML格式的在线,并且有一个关于重基和压缩的不错的部分:

http://git-scm.com/book/ch6-4.html

为了方便起见,我将逐字逐句地引用他们的例子。假设你有以下提交历史记录,你想要将bug1重置并压缩到master上:

    F < bug2
   /
A-B-G-H < master
   \
    C-D-E < bug1

下面是当你输入git rebase -i master bug1时你会看到的结果

pick f7f3f6d changed my name a bit
pick 310154e updated README formatting and added blame
pick a5f4a0d added cat-file
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

要将一个分支的所有提交压缩为一次提交,请将第一次提交保留为“pick”,并将所有后续的“pick”条目替换为“squash”或简单的“s”。您还将有机会更改提交消息。

pick f7f3f6d changed my name a bit
s 310154e updated README formatting and added blame
s a5f4a0d added cat-file
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit

所以,是的,压扁是有点痛苦,但我仍然建议它比大量使用存储。