有没有办法让我把阶段性的变化藏起来?我遇到问题的情况是,我在给定的时间内处理了几个bug,并且有几个未分阶段的更改。我希望能够单独运行这些文件,创建我的.patch文件,并将它们保存起来,直到代码被批准。这样,当它被批准时,我可以隐藏我的整个(当前)会话,弹出错误并推送代码。
我做错了吗?我是否误解了git如何以其他方式简化我的过程?
有没有办法让我把阶段性的变化藏起来?我遇到问题的情况是,我在给定的时间内处理了几个bug,并且有几个未分阶段的更改。我希望能够单独运行这些文件,创建我的.patch文件,并将它们保存起来,直到代码被批准。这样,当它被批准时,我可以隐藏我的整个(当前)会话,弹出错误并推送代码。
我做错了吗?我是否误解了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
或者您可以为每个错误创建单独的分支,这样您就可以单独合并或重新建立错误修复,甚至在它们不起作用时删除它们。
其他回答
铊;博士;总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.
为什么不提交对某个错误的更改,并根据该提交及其前身创建一个补丁呢?
# 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 *files that you don't want to be stashed*
git commit -m "temp"
git stash --include-untracked
git reset --soft HEAD~1
这样你只需要触摸你想要触摸的文件。
注意,“——include-untracked”在这里还用于保存新文件(这可能是您真正想要的)。
在Git 2.35 (Q1 2022)中,“Git stash”(man)学会了——staging选项来隐藏添加到索引中的内容(而不是其他内容)。
所以现在这是官方支持的(8年后)。
参见Sergey Organov (sorganov)的commit a8a6e06(2021年10月28日)和commit 41a28eb(2021年10月18日)。 (由Junio C Hamano—gitster—在commit 44ac8fd中合并,2021年11月29日)
Stash:为“推送”和“保存”执行“——staging”选项 署名:Sergey Organov
只保存已上演的更改。 这种模式允许轻松地隐藏一些与当前正在进行的工作无关的更改,以便以后重用。 与'stash push -patch'不同,- staging支持使用任何工具来选择要存储的更改,包括但不限于'git add -interactive'(man)。
Git stash现在包括在它的手册页:
“git藏”[推动[p |——补丁][s |——上演][- k |——[不——]keep-index] [q |——安静)
Git stash现在包括在它的手册页:
保存[- p |——补丁][s |——上演][- k |——[不——]keep-index] [- u |——include-untracked][——|——所有][q |——安静][<消息>]
Git stash现在包括在它的手册页:
- s ——上演了 此选项仅对推送和保存命令有效。 只保存当前暂存的更改。这类似于 基本的git提交,除了状态被提交到stash 当前分支的。 ——patch选项优先于此选项。
Git stash现在包括在它的手册页:
Saving unrelated changes for future use When you are in the middle of massive changes and you find some unrelated issue that you don't want to forget to fix, you can do the change(s), stage them, and use git stash push --staged to stash them out for future use. This is similar to committing the staged changes, only the commit ends-up being in the stash and not on the current branch. ---------------------------------------------------------------- # ... 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 ----------------------------------------------------------------
是否绝对有必要同时处理多个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
所以,是的,压扁是有点痛苦,但我仍然建议它比大量使用存储。