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

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


当前回答

根据你对Mike Monkiewicz的回答,我建议使用一个更简单的模型:使用常规的开发分支,但是使用合并的squash选项来在你的主分支中获得一个单一的提交:

git checkout -b bug1    # create the development branch
* hack hack hack *      # do some work
git commit
* hack hack hack *
git commit
* hack hack hack *
git commit
* hack hack hack *
git commit
git checkout master     # go back to the master branch
git merge --squash bug1 # merge the work back
git commit              # commit the merge (don't forget
                        #    to change the default commit message)
git branch -D bug1      # remove the development branch

这个过程的优点是您可以使用正常的git工作流程。

其他回答

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

# 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

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

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

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

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

在git版本2.17.1中测试

更新2022年1月:Git 2.35已经发布,stash现在支持——staging参数。因此,这个答案在Git 2.35+中已经过时了。参见vonc的回答:https://stackoverflow.com/a/70231955/430128。

旧的回答:

在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"

It:

Validates that there are actually staged changes (git diff --cached --exit-code returns a non-zero status if there are). HT: @nandilugio It pushes both the staged and unstaged changes into a temporary stash, leaving the staged changes alone. It then pushes the staged changes into the stash, which is the stash we want to keep. Arguments passed to the alias, such as --message "whatever" will be added to this stash command. It pops the temporary stash to restore the original state and remove the temporary stash, and then Finally "removes" the stashed changes from the working directory via a reverse patch application.

对于相反的问题,只存储非分期的更改(别名存储工作),请参阅以下答案。

另一种方法是用你不想被存储的文件创建一个临时提交,然后存储剩余的文件,轻轻地删除上次提交,保持文件完整:

git add *files that you don't want to be stashed*
git commit -m "temp"
git stash --include-untracked
git reset --soft HEAD~1

这样你只需要触摸你想要触摸的文件。

注意,“——include-untracked”在这里还用于保存新文件(这可能是您真正想要的)。

更新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上测试

限制:

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