(Git)当当前分支中有很多更改时,将修订提交到另一个分支的最实用方法是什么? [英] (Git) What's the most practical way to commit a fix to a different branch when you have lots of changes in your current branch?

查看:61
本文介绍了(Git)当当前分支中有很多更改时,将修订提交到另一个分支的最实用方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是场景:

  • 您正在开发功能分支
  • 您已经制作了几个新文件,移动了几个文件,并更改了其他几个文件
  • 在处理一些您未编写的代码时,您会注意到并立即修复错误
  • 或者,您会注意到某个函数缺少文档,因此您会为随之而来的下一个开发人员快速添加一些专业提示

然后,您意识到所做的最后几处更改不属于此功能分支.相反,这些更改应提交给其他功能分支,修补程序分支,甚至直接进行开发.

现在,将与功能无关的更改提交到另一个分支的最实用方法是什么?


阐述

处理此问题的直截了​​当"的方法是存储更改,签出正确的分支,在此处提交更改,再次签出功能分支,弹出存储,恢复工作.(可以选择合并到新分支中.)

尽管理论上很简单,但是在许多情况下这是极其不切实际和乏味的.首先,您想移动的更改已被隐藏...那么如何准确地将它们带入新分支?您可能会在新分支中弹出隐藏文件?但是,如果您在功能分支的内部有几个提交,我不希望当前的存储与develop分支兼容.

我希望我可以提交脱离主题的更改,然后使用一个命令将提交的内容移至另一个分支,而无需离开当前分支.

注意:我在SO上还看到了其他与此类似的问题,即如何在不签出的情况下将更改提交到另一个分支".答案几乎总是你做不到".但这不是我要问的,我想知道当您当前深入要素分支时将更改转移到另一个分支的最实用方法.

解决方案

我的首选方法是从您所在分支的现在提交开始.有时这是可选的,具体取决于剩余的步骤,因此请先通读它们.

现在您已经完成了所有操作,下一步取决于是否可以将当前索引和工作树弄乱.如果不是,并且您拥有Git 2.5或更高版本(最好是2.15或更高版本,因为最初在2.15中已修复了一个非常讨厌的错误),请使用 git worktree add 创建一个新工作树可以在您要进行这些修复的分支上/之内进行设置:

 #这假设您位于存储库的顶层git worktree添加../quick-fix开发cd ../快速修复 

此处 ../quick-fix 是您将创建的新工作树,位于分支 develop 上.通过执行 cd ../quick-fix -或在Mac上打开一个新的Terminal窗口,然后进入其中的目录-您现在在主存储库中工作,但在 develop 分支,而不是功能分支.

这时,因为您已经在 feature 分支中提交了,所以您可以访问在feature分支中所做的所有提交,并且可以使用 git cherry-pick git show |git apply 随心所欲(Git的任何工具或系统的任何工具)可以在 develop 分支中使用.如果您没有提交,那么您当然不能选择最后一次提交.

更新完 develop 分支后,可以返回到 feature 分支工作树,运行 rm -rf ../quick-修复来删除另一个工作树,然后运行 git worktree修剪来获取 git工作树以了解另一个工作树现在已经消失了.(一旦完成所有要提交的操作,就可以安全地删除它,但是您必须在某个时候运行 git worktree prune 来提醒Git您没有 develop再次签出.)

如果您不能或不希望使用 git worktree add ,则必须在您的 main 工作树中工作,所以您肯定需要做 git commit .现在,您可以在此处 git checkout开发,照常工作,并照常提交.完成后,再次 git checkout功能以返回到您的功能.

无论哪种方式,您现在都回到一个工作树,该工作树已签出 features .现在假设您已在功能上进行了一次,现在是时候删除在功能上进行的提交了.要删除该提交,请运行:

  git reset HEAD ^ 

(或使用 HEAD〜代替 HEAD ^ ,如果这样更便于您在Shell/CLI中键入和/或更好,例如,如果 ^对您的外壳有特殊含义).这样会删除提交并重置索引,但会保留您所做的临时提交中的工作树.

要点

如有必要,我们进行临时提交.如有必要,

  • 您要从中挑选樱桃,或者
  • 您要重用主工作树及其对应的索引

否则,没有必要.

我们使用 git worktree add 创建一个新的工作树/索引对,使您可以在另一个分支中进行工作,而不必打扰主工作树和Git的主索引./p>

我们在默认(-mixed )模式下使用 git reset 来擦除/删除临时提交(一旦完成).这也会重置索引,因此,如果您将索引用于特殊技巧-稀疏签出,或 git update-index -假定未更改--skip-worktree -在这里至少要小心一点(但是 git reset 确实与这些协调).

This is the scenario:

  • You are working on a feature branch
  • You have made several new files, moved a few files and changed several other files
  • While working on some code you didn't write, you notice and immediately fix a bug
  • Alternatively, you notice a function is missing documentation so you quickly add some pro tips for the next developer that comes along

Then, you realize the last few changes you made doesn't belong in this feature branch. Instead, these changes should be committed to a different feature branch, a hotfix branch or even directly to develop.

Now, what is the most practical way to get your non-feature related changes committed to a different branch?


Elaboration

The "straight forward" way to handle this would be to stash your changes, check out the correct branch, commit your changes there, check out the feature branch again, pop the stash, resume working. (Optionally merge in the new branch.)

While simple in theory, this can be extremely impractical and tedious in many cases. First of all, the changes you want to move got stashed... So how exactly do you get them into the new branch? You could maybe pop the stash in the new branch? But if you are several commits deep into your feature branch, I wouldn't expect the current stash to be compatible with the develop branch.

I wish I could just commit the off-topic changes, then move that commit to a different branch with a single command, without leaving my current branch.

NB: I have seen other similar questions to this on SO, namely "how do I commit changes to a different branch without checking it out". The answers are pretty much always "you can't". But this is not what I'm asking here, I want to know the most practical way to get your changes moved to a different branch, when you're currently neck deep in a feature branch.

解决方案

My preferred method is to start by committing now, on the branch you're on. Sometimes this is optional, depending on the remaining steps, so read through them first.

Now that you've committed everything or not, the next step depends on whether it's OK to mess with the current index and work-tree. If not, and you have Git 2.5 or later—preferably 2.15 or later because of a fairly nasty bug first fixed in 2.15—use git worktree add to create a new work-tree that is set up to work on/in the branch where you want to make these fixes:

# this assumes you're in the top level of your repository
git worktree add ../quick-fix develop
cd ../quick-fix

Here ../quick-fix is the new work-tree you'll create, which is on branch develop. By doing cd ../quick-fix—or opening a new Terminal window on your Mac, perhaps, and going into the directory there—you're now working in your main repository, but on the develop branch, not the feature branch.

At this point, because you already committed in your feature branch, you have access to all of the commits you have made in your feature branch and can use git cherry-pick, or git show | git apply, or whatever you like—any of Git's tools or any of your system's tools—to work in the develop branch. If you didn't commit, you can't cherry-pick that last commit, of course.

When you're done updating your develop branch, you can return to your feature branch work-tree, run rm -rf ../quick-fix to remove the other work-tree, and run git worktree prune to get git worktree to realize that the other work-tree is now gone. (It's safe to remove once you've made all the commits you intend to make, but you do have to run git worktree prune at some point to remind Git that you don't have develop checked out any more.)

If you cannot or do not wish to use git worktree add, you'll have to work in your main work-tree, so you definitely need to have done that git commit. You can now git checkout develop here, work as usual, and commit as usual. Once you're done, git checkout feature again to get back to your feature.

Either way, you are now back to one work-tree, which has feature checked out. It's now time to remove the commit you made on feature, assuming you made one on feature. To remove that one commit, run:

git reset HEAD^

(or use HEAD~ instead of HEAD^ if that's easier for you to type and/or better in your shell / CLI, e.g., if ^ has special meaning to your shell). This removes the commit and resets the index, but keeps the work-tree from the temporary commit you made.

Key points

We make a temporary commit if necessary. It is necessary if:

  • you want to cherry-pick from it, or
  • you want to re-use your main work-tree and its corresponding index

Otherwise, it is not necessary.

We use git worktree add to create a new work-tree/index pair that allows you to do work in another branch, without having to disturb the main work-tree and Git's main index.

We use git reset in its default (--mixed) mode to erase the temporary commit once we are done with it. This also resets the index, so if you are using the index for special tricks—sparse checkout, or git update-index with --assume-unchanged or --skip-worktree—be at least a little bit careful here (but git reset does coördinate with these).

这篇关于(Git)当当前分支中有很多更改时,将修订提交到另一个分支的最实用方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆