简体   繁体   English

使用Git,我如何只合并属于不同分支中较大提交的一部分的文件删除

[英]Using Git, how can I merge only file deletions which are part of a bigger commit in a different branch

I spent a few hours and exhausted my google-foo skills with nothing to show for, so here is a question to more experiences git users coming from a git newbie... 我花了几个小时并用尽了我的google-foo技能,没什么可展示的,所以这是一个更多来自git新手的git用户体验的问题...

Scenario: 场景:

I have two branches - B1 and B2 我有两个分支-B1和B2

B2 branched from B1 and has had the following commits - C5, C6, C7 B2从B1分支出来,并具有以下提交-C5,C6,C7

Commit C5 has the following changes: 提交C5具有以下更改:

  • Many files changed 许多文件已更改
  • Many files deleted 许多文件已删除

Now, if possible, I'd like to merge only a part of C5 to B1, namely, the "many files deleted" change. 现在,如果可能的话,我只想将C5的一部分合并到B1,即“删除许多文件”的更改。

Should I just delete these same files in B1 directly and commit, or is there a better way? 我应该直接删除B1中的相同文件并提交,还是有更好的方法?

The intention is to eventually merge B1 and B2 back together, so I'm not sure if there will be issues if the same files are deleted in both branches in separate commits. 目的是最终将B1和B2重新合并在一起,所以我不确定如果在单独的提交中在两个分支中删除相同的文件是否会出现问题。

I appreciate any input on this. 我对此表示感谢。

Summary 摘要

It is not possible to merge only a part of a commit. 不可能仅合并提交的一部分。

You can, however, reset (soft or mixed) to the commit before C5 , commit the changes and the removals in two separate commits and apply your other commits on top of that. 但是,您可以将C5之前的提交reset (软或混合),在两个单独的提交中提交更改和删除,并在此之上应用其他提交。 This will, however, change your branches history, so you should not do that if you pushed the branch to a remote and/or anyone else is working on top of your commits. 但是,这将更改分支的历史记录,因此,如果将分支推送到远程和/或其他任何人都在提交之上工作,则不应这样做。

Details 细节

The first advisable step, as always when you want to mess with your branches' history, is to create a backup branch in case everything goes south. 通常,当您想弄乱分支机构的历史时,建议的第一步是创建备份分支,以防万一。 git branch backup_branch shoud do this. git branch backup_branch应该做到这一点。 If you mess everything up, you can just git checkout backup_branch and be on your old stage. 如果您搞砸了所有内容,则可以git checkout backup_branch并保持原有状态。

Then, you can do a git reset --hard HEAD~2 . 然后,您可以执行git reset --hard HEAD~2 This sets all your files back to the state right after you commited C5 . 提交C5后,这会将所有文件立即恢复为状态。 We lost the changes of commits C6 and C7 now, but can cherry-pick them later on top of our new commits. 我们失去了提交的变化C6C7了,但可以cherry-pick后他们对我们的新提交的顶部。

The magic step now is a git reset HEAD~1 . 现在的魔术步骤是git reset HEAD~1 This performs a mixed reset, resetting your branch to the commit before C5 , but keeping all the changes you did in C5 as unstaged changes in your working directory. 这将执行混合重置,将您的分支重置为C5之前的提交,但将您在C5中所做的所有更改保留为工作目录中的未暂存更改。 Now, you can just stage all deletions, do a commit, and then stage all changes and do another commit. 现在,您可以暂存所有删除,进行提交,然后暂存所有更改并进行另一个提交。 Voilà, two seperate commits, one with deletions and one with changes. Voilà,两个单独的提交,一个带有删除,一个带有更改。

To obtain the other commits C6 and C7 , you can just git checkout backup_branch , git log -n2 to show you info about those two commits, along with their SHA ids. 要获取其他提交C6C7 ,您可以git checkout backup_branchgit log -n2向您显示有关这两个提交及其SHA ID的信息。 Back on your original branch, you can just git cherry-pick either one commit after another or both at the same time. 回到您的原始分支,您可以git cherry-pick一次又一次提交,或者同时进行两次。

Your data will be in the old state, but your C5 commit was replaced by two separate commits. 您的数据将处于旧状态,但是您的C5提交已被两个单独的提交替换。 Cherry pick one of them to your B1 branch, and that's it. Cherry选择其中一个到B1分支,就是这样。

Say C5 changes foo.c and deletes bar.c. 说C5更改foo.c并删除bar.c。

git checkout B1
git cherry-pick C5 -n
git reset HEAD -- foo.c
git commit

This is the simplest scenario. 这是最简单的情况。 But in your case a lot more files are changed, so you need to reset the changed files all. 但是,如果您更改了许多文件,则需要全部重置更改的文件。 This may not be more convenient than deleting the bar.c files directly from B1. 这可能比直接从B1删除bar.c文件更方便。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM