使用 GIT,如何有选择地合并来自另一个“分叉”上的一个提交的更改?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1405030/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 07:01:21  来源:igfitidea点击:

Using GIT, how can I selectively merge changes from one commit on another 'fork'?

gitmergepull

提问by Tim

Take this scenario:

看这个场景:

  1. I decide to 'fork' a codebase on github.com, and start doing my routine: Edit - Commit - Push; aka hack hack hack.
  2. After I made some changes, I see some changes another person has made on the same project, and I like them!
  3. I decide I want to merge them into mine. Problem is, I only want a 'portion' of one particular commit, out of several commits he has made.
  1. 我决定在 github.com 上“分叉”一个代码库,然后开始做我的日常工作:编辑 - 提交 - 推送;又名黑客黑客黑客。
  2. 在我做了一些改变之后,我看到另一个人在同一个项目上做了一些改变,我喜欢他们!
  3. 我决定将它们合并到我的。问题是,我只想要他所做的几次提交中的一个特定提交的“部分”。

What would be the most efficient method of getting these select amount of changes, merged into my 'fork'?

将这些选定数量的更改合并到我的“分叉”中的最有效方法是什么?

回答by Tim

After trolling the waves of the IRC world, someone gave a great solution:

在IRC世界的浪潮中,有人给出了一个很好的解决方案:

git cherry-pick SHA1 --no-commit
git add --patch

Hopefully that helps anyone else with the same question!

希望这可以帮助其他有同样问题的人!

EDIT: OK, maybe it isn't quite that simple. Here are the full steps:

编辑:好的,也许事情没那么简单。以下是完整步骤:

  1. First you have to be in your repository, do the necessary cd-ing to get to your working directory.

  2. You now need to add the remote branch, and then fetch it. Do this by:

    git remote add someUser git://github.com/someUser/someRepo.git

    git fetch someUser

  3. You can now run commands such as git log someUser/masterto find the commit SHA1 you want to merge in 'partially'.

  4. Once you have the SHA, you can now run:

    git cherry-pick -n SHA1

    where SHA1is the commit SHA, duh!

  5. There quite possibly will be conflicts, depending how old the commit is, and how often that particular area of the project changes. Sorry, but you have to manually resolve these with your trusty editor. So pull out VIM, or whatever else you use, and hack away at the conflicts until you get to the stage where you like the changes.

  6. You now have to reset the index to the HEAD revision, then you can then use the trusty GIT add --patchcommand to pick and choose what changes you want:

    git reset HEAD

    git add --patchor git add -p

  7. Yay! Commit time:

    git commit -m "I merged a select amount of changes"

  8. To clean up the mess (The stuff you said no to in git add --patch) and only keep the selected changes in your working repository, run:

    git reset --hard HEAD

    Apparently git checkout -fis another option as well.

  1. 首先,您必须在您的存储库中,执行必要的cd-ing 以进入您的工作目录。

  2. 您现在需要添加远程分支,然后获取它。这样做:

    git remote add someUser git://github.com/someUser/someRepo.git

    git fetch someUser

  3. 您现在可以运行命令,例如git log someUser/master查找要“部分”合并的提交 SHA1。

  4. 获得 SHA 后,您现在可以运行:

    git cherry-pick -n SHA1

    SHA1提交 SHA在哪里,呃!

  5. 很可能会发生冲突,这取决于提交的时间以及项目特定区域的更改频率。抱歉,您必须使用可信赖的编辑器手动解决这些问题。因此,退出 VIM 或您使用的其他任何东西,并消除冲突,直到达到您喜欢更改的阶段。

  6. 您现在必须将索引重置为 HEAD 修订版,然后您可以使用 trusty GITadd --patch命令来选择您想要的更改:

    git reset HEAD

    git add --patch或者 git add -p

  7. 好极了!提交时间:

    git commit -m "I merged a select amount of changes"

  8. 要清理混乱(您拒绝的内容git add --patch)并仅在您的工作存储库中保留选定的更改,请运行:

    git reset --hard HEAD

    显然git checkout -f也是另一种选择。

回答by Mike Dacre

I really like Tim's solution, however sometimes I like tinkering in vimdiff. My solution to this problem is crude, but it works for me because I like vim.

我真的很喜欢 Tim 的解决方案,但有时我喜欢修改 vimdiff。我对这个问题的解决方案很粗糙,但它对我有用,因为我喜欢 vim。

I have vimdiff set as my difftool, and then to selectively merge I diff the branch:

我将 vimdiff 设置为我的 difftool,然后有选择地合并我 diff 分支:

git difftool <branch> <file>

Then I go to the pane with the current branch's version and edit the original in vim (sometimes this isn't necessary, but sometimes vimdiff opens a version in /tmp) and disable read-only mode:

然后我转到带有当前分支版本的窗格并在 vim 中编辑原始版本(有时这不是必需的,但有时 vimdiff 在 /tmp 中打开一个版本)并禁用只读模式:

:e <file>
:set readonly!

Now I can use vim's patch tools such as doand dpto apply what I want, and make other little edits as I go. When I am done, I save the file, exit out of vim, and then stage and commit the file in git like a regular edit.

现在我可以使用 vim 的补丁工具,例如dodp来应用我想要的,并在我进行时进行其他小的编辑。完成后,我保存文件,退出 vim,然后像常规编辑一样在 git 中暂存和提交文件。

As I said, this isn't particularly sophisticated, but it is very powerful, and still purely in the command line. Just be sure to add a clear commit message, as git won't automatically include a merge message for you.

正如我所说,这不是特别复杂,但它非常强大,并且仍然纯粹在命令行中。请务必添加明确的提交消息,因为 git 不会自动为您包含合并消息。

vimdiff example http://j.mp/1dZVllt

vimdiff 示例 http://j.mp/1dZVllt

回答by hgmnz

I'm not clear on what you want. If you want to bring in only certain commits from the other forks, you can use git cherry-pick SHA. Full explanation on gitready.

我不清楚你想要什么。如果您只想从其他分叉中引入某些提交,您可以使用git cherry-pick SHA. 关于gitready 的完整解释。

回答by Bombe

If you only want a port of a commit, you're probably best off by cherry-picking the commit you want and resetting files you don't want touched.

如果您只想要一个提交的端口,那么最好选择您想要的提交并重置您不想触及的文件。

git cherry-pick SHA1
git checkout HEAD file1 file2 ... fileN

Of course, if you have several modified parts in a file and only want to keep some of them you have no choice but to edit the file manually, cutting out their changes.

当然,如果您在一个文件中有几个修改过的部分并且只想保留其中的一些,您别无选择,只能手动编辑文件,删除它们的更改。