在 Git 中处理临时更改(不提交)
通常,在分支上工作时,我需要引入一些“临时”更改(例如额外的调试信息,或者让我更好地观察我实际上正在处理的事情的更改)。
关于这些“临时”更改:
- 我希望它们出现在我的分支的工作副本中,因为它们帮助我处理实际的更改,
- 我不希望它们提交给分支< /strong>,因为分支将在某个时候合并到 master 中,并且它们不是生产代码。
目前,我只是将它们保留为未暂存状态,并在暂存每次提交时手动跳过它们。然而,我不能继续使用这个解决方案,因为:
- 我一直都必须记住需要跳过哪些文件,
- 有一天我最终会在一个文件中进行 2 个更改,一个是临时的,一个是要提交的,并且真的会很麻烦。
我该如何处理?
gitignore
显然是不可能的,因为我不想忽略整个文件,而且我仍然对其他提交者的更改感兴趣(我需要时不时地将分支重新设置为 master) 。
Often while working on a branch I need to introduce some "temporary" changes (such as additional debugging info, or a change which lets me better observe the thing i'm actually working on).
About these "temporary" changes:
- I want them in my working copy of my branch, because they help me to work on the actual change,
- I don't want them committed to the branch, because the branch is going to be merged into master some time and they're not production code.
Currently I just keep them as unstaged and I skip them manually when staging every commit. However I can't stay with this solution because:
- All the time I have to remember which files I need to skip,
- Someday I'm going to end up with 2 changes in one file, one being temporary, one to be committed, and it's going to be really troublesome.
How should I deal with it?
gitignore
is obviously out of the question because I don't want to ignore the whole files and I'm still interested in changes from other committers (I need to rebase the branch to master from time to time).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
我通常通过使用以下方法来处理这个问题:
... 逐个进行更改。然后您只需确保按 n 即可进行调试更改。
如果我有更多此类类型的更改,我将创建一个名为
local-changes
的分支,并在其尖端提交一个引入调试代码的提交。创建更多提交后,我将使用:... 对它们重新排序,以便具有本地更改的提交再次位于提示处。然后要更新 master 并返回本地更改分支,您可以执行以下操作:
I typically deal with this by using:
... to stage changes hunk-by-hunk. Then you just have to make sure to press n for your debugging changes.
If I have more involved changes of this type, I'll create a branch called something like
local-changes
with a commit at its tip that introduces the debugging code. After creating a few more commits, I'd then use:... to reorder them so that the commit with the local changes is at the tip again. Then to update master and return to the local changes branch, you can do:
尝试 git update-index --assume-unchanged。这样,当使用 git add 或 git commit -a 时,git 就不会将文件添加到索引中。
编辑:这不允许您处理一个文件同时进行临时和永久更改的情况。
Try
git update-index --assume-unchanged <file>
. This way git will not add the file to the index when usinggit add
orgit commit -a
.EDIT: This doesn't allow you to deal with the case of having one file with both temporary and permanent changes.
这里有一种处理这个问题的方法,一旦设置完毕,只需要您记住一个设置步骤,以及每次推送之前的一个步骤。
设置:
记下该提交的 sha。然后切换到您的工作分支,并且:
现在您的工作分支上已经有了更改。做好你的工作并做出承诺。然后,在推送之前:
您将看到类似这样的内容:
删除包含临时更改的行。然后保存并退出。您的历史记录将被重写以排除临时更改。 (更改仍将存在于 tempChanges 分支中。)完成后,进行您需要的任何测试,然后
git 推送
。当您准备好再次工作时,您可以将临时更改拉回当前工作分支(或新的工作分支):
因此,总之,在此方法中您需要记住的是
创建工作分支后
gitcherry-pick shaOfTempChangesCommit
在完成工作并准备好推送之后
git rebase -i
[在推送之前删除临时更改]Here's a way to deal with this that, once set up, only requires you to remember one step to set it up, and one step before each push.
The setup:
Note the sha for that commit. Then switch to your working branch, and:
Now you have the changes on your working branch. Do your work and make commits. Then, before you push:
You'll see something like this:
Delete the line with your temporary changes. Then save and exit. Your history will be rewritten to exclude the temporary changes. (The changes will still exist in the tempChanges branch.) Once that's done, do any testing you need to and then
git push
.When you're ready to work again, you can pull the temporary changes back onto your current working branch (or a new working branch):
So, in sum, all you have to remember in this method is
after you create a working branch
git cherry-pick shaOfTempChangesCommit
after you're done working and ready to push
git rebase -i
[to remove the temporary changes before you push]您可以使用
将其保存到临时空间中。完成合并后,您可以使用
将临时更改加载回工作目录。
You can use
to save it into a temporary spaces. After doing your merge, you can use
to load back your temporary changes into your working-directory.
我通常将所有调试代码放在自己的提交中,然后在进行合并之前,我
恢复
该提交。我有时会使用大多数其他答案的一些变体,但我喜欢这个答案,因为它简单,而且它保留了我的开发历史。是的,我不希望我的调试代码出现在最终产品中,因此需要恢复
,但如果测试发现问题,我希望能够恢复该调试代码以进行进一步的工作。I usually put all my debug code in its own commit, then before I do the merge, I
revert
that commit. I've used some variation of most of the other answers at times, but I like this one for its simplicity and the fact that it preserves my development history. Yes, I don't want my debug code in the final product, hence therevert
, but if testing finds an issue I want to be able to reinstate that debug code for further work.我找到了解决这个问题的干净方法:(请原谅我的 ascii-art)。它需要一个额外的主题分支。(这有缺陷,正在争议/纠正,请参阅评论)该工作最初看起来像这样:
工作是在“分支”上完成的。
引入一些临时更改:
存储库现在看起来像:
工作现在很高兴在分支上继续,并且临时更改在状态中不可见。
要更改或扩展临时更改:
commit --amend 那里的临时更改- 这是错误的,因为它使“branch-temp”发散将更改从分支合并到主干:
这只是有点棘手。我们希望合并所有更改,除了“branch-temp”引入的更改之外。我的想法是:
(我们现在有一个合并,但有一些不必要的临时更改 - 让我们删除它们)
(这两个步骤应该修改合并提交,以便它不再包含来自branch-temp的更改)
I've found a clean solution to this problem: (pardon my ascii-art). It requires an additional branch for the topic branch.(this has flaws and is being disputed/corrected, see comments)The work looks like this initially:
Work is done on "branch".
To introduce some temporary changes:
The repo now looks like:
Work is now happily continued on branch and the temporary changes are not visible in the status.
To change or extend the temporary changes:
commit --amend the temporary changes there- this is wrong, since it makes "branch-temp" divergeTo merge the changes from branch to master:
This is just a bit more tricky. We want to merge in all changes, except the changes introduced by "branch-temp". My idea is:
(we now have a merge, but with some unnecessary temporary changes - let's remove them)
(these two steps should modify the merge commit, so that it no longer contains the changes from branch-temp)
编写一个简单的 shell 脚本来根据请求修补和撤消调试更改(然后将其设置为 git 别名)怎么样?
例如
What about writing a simple shell script that will patch and undo your debug changes on request (and then make it as a git alias).
E.g.
为了避免在创建功能时弄乱暂存区域,请提交调试更改,并带有明亮闪烁的警告,表明它们不应进入最终合并:
当您准备好合并分支,如果您忘记了它们,您或其他人将在拉取请求的代码审查中发现这些更改。
然后,您将有不同的方法来删除调试提交:
恢复
特定的调试提交。这将在分支中保留他们的历史。cherry-pick
好提交。这将完全删除调试提交。更复杂的东西,例如
rebase -interactive
来就地删除提交。To avoid cluttering up your staging area as you're creating a feature, commit your debug changes with a bright blinking warning that they should not make it into the final merge:
When you're ready to merge the branch, if you've forgotten about them, these changes will be caught by you or someone else in the code review of your pull request.
You'll then have different ways to remove the debug commits:
revert
the specific debug commits. This will retain their history in the branch.cherry-pick
the good commits. This will remove the debug commits entirely.Something more complicated such as
rebase -interactive
to remove the commits in-place.GIT 的存储功能正是您所需要的。至少对于“保留”部分来说是这样。这样在提交时做出好/坏的选择是不可避免的。
GIT's stash functionalities provides exactly what you're asking for. At least for the "keeping" part. Making the good/bad-selection when committing cannot be avoided like this.
我倾向于像这样保留未提交的更改。我总是使用 git add -i 或 git add -p 来暂存更改(除非我确定我想要树中的所有更改)。这样我就可以查看所有我想要提交的更改,并轻松跳过临时更改。它还有助于暂存您需要尽早提交的更改,并保持它们暂存,甚至提交它们,而不是使用 git commit --amend 来添加更多更改。
I tend to keep uncommitted changes like that. I simply always use
git add -i
orgit add -p
to stage changes (unless I am sure I want all changes the tree has). That way I review all the changes I do want committed and easily skip temporary ones. It also helps to stage changes you know you'll want committed early and keep them staged or even commit them and than add more changes withgit commit --amend
.我使用此答案建议的工作流程的修改版本:
设置
首先为调试更改创建分支.
将临时更改提交到该分支。
工作流程
在调试分支中,处理代码并进行将提交到主(或功能)分支的更改。当您满意后,隐藏所有更改。
现在,转到 master 分支并应用存储,然后进行提交。
最后,切换回调试分支并在 master 分支上重新建立基础。
I use a modified version of the workflow suggested by this answer:
Setup
Start by creating a branch for your debug changes.
Commit your temporary changes to that branch.
Workflow
In the debug branch, work on your code and make the changes that will be committed to the master (or feature) branch. When you are satisfied, stash all the changes.
Now, go to master branch and apply the stash, then make your commit.
Finally, switch back to your debug branch and rebase it on the master branch.