使用GIT,我如何有选择地将一个提交的更改合并到另一个'fork'上?

时间:2009-09-10 12:36:03

标签: git merge pull

采取这种情况:

  1. 我决定在github.com上“分叉”代码库,并开始执行我的例程:编辑 - 提交 - 推送;又名hack hack hack。
  2. 在我做了一些更改后,我看到另一个人在同一个项目上做了一些更改,我喜欢它们!
  3. 我决定将它们合并到我的脑中。问题是,我只想要一个特定提交的“部分”,而不是他做过的几次提交。
  4. 获取这些选定数量的更改的最有效方法是什么,合并到我的'fork'中?

4 个答案:

答案 0 :(得分:117)

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

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

希望能帮助其他人解决同样的问题!

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

  1. 首先,您必须进入您的存储库,执行必要的cd来访问您的工作目录。

  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修订版,然后您可以使用可靠的GIT add --patch命令来选择您想要的更改:

    git reset HEAD

    git add --patchgit add -p

  7. 耶!提交时间:

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

  8. 要清理乱七八糟的东西(你在git add --patch中说过的东西)并且只保留工作资料库中的选定更改,请运行:

    git reset --hard HEAD

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

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

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

git difftool <branch> <file>

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

:e <file>
:set readonly!

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

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

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

答案 3 :(得分:1)

如果你只想要一个提交的端口,你可能最好选择你想要的提交并重置你不想触摸的文件。

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

当然,如果你在一个文件中有几个修改过的部分并且只想保留其中的一部分,你别无选择,只能手动编辑文件,切断它们的变化。