在新的git存储库上重放提交的最简单方法

jbe*_*rd4 18 git git-svn

我一直在使用git-svn,最近,我在尝试提交时遇到了错误(我认为这是由于libneon中的一个错误,但这超出了这个问题的范围).解决方案是使用重新克隆我的git存储库git svn clone.但是,我在我的旧git存储库中的master分支上有更改,我无法使用svn git svn dcommit.我想在使用git svn克隆的新存储库中重放这些更改.我想我可以使用导出补丁集git format-patch,然后在新的存储库上重放这些更改,但我不完全确定如何做到这一点,我想知道是否有更简单或更优雅的方法来实现这一点.

Jon*_*han 46

从新存储库中,添加对旧存储库的远程引用:

git remote add temp file:///path/to/old/repo/on/your/machine
Run Code Online (Sandbox Code Playgroud)

从旧回购获取:

git fetch temp
Run Code Online (Sandbox Code Playgroud)

从旧回购中查看您的主分支:

git checkout temp/master -b wip
Run Code Online (Sandbox Code Playgroud)

(wip代表正在进行中的工作)

将更改重新基于当前存储库中的内容:

git rebase master
Run Code Online (Sandbox Code Playgroud)

更新master以指向新的HEAD:

git checkout master
git merge wip
Run Code Online (Sandbox Code Playgroud)

删除旧回购的远程引用和您使用的wip分支:

git branch -d wip
git remote rm temp
Run Code Online (Sandbox Code Playgroud)

你在做什么:

首先,通过添加远程引用和获取,您将从先前存储库中提取当前存储库中尚未提交的提交.Git知道如何做到这一点,因为无论在何处或如何制作,相同的提交在任何地方看起来都是一样的.它是一些众所周知的信息的SHA1哈希,包括目录树,提交者,时间戳,......

因此,当您基于相同的SVN存储库创建新的Git存储库时,所有提交都具有相同的SHA1总和.结果,您提取到当前存储库的新提交继续指向正确的东西.这非常酷,记住很重要.

然后你切换到temp的主分支的尖端,并告诉它重新绑定到你当前的主人.可能没有必要使用rebase,因为SVN的主人可能没有离开旧回购中的主人,但最好是安全的.

通过在历史记录中向后工作直到它们都指向同一父提交,rebase在两个提交之间找到最接近的共同点.然后它切换到你给它的分支名称(在这种情况下master),并从原始分支中挑选其历史记录中缺少的每个提交.完成后,它指向您在应用的最后一次提交时开始的分支.

最后,master和wip的合并只是为了快速掌握到最后.因为它是一条直线,它真的只是一个快速前进.你可以轻松地做一个rebase或重置 - 硬; 其中任何一个都会改变主分支以指向正确的位置.合并只是其中最安全的,因为如果发生了一些奇怪的事情,它会让你知道这不是一个简单的快进.


Von*_*onC 9

你可以:

  • 将您的旧仓库添加为新仓库的远程(git remote)
  • 获取旧分支
  • 在当前的基础上重新设置您感兴趣的旧分支部分master.

请参见如何选择一系列提交并合并到另一个分支:

# go to your current but incomplete new master branch
git checkout master

# mark your current master HEAD as branch 'tmp'
git checkout -b tmp

# reset your master to the old one
git branch -f master oldrepo/master

# replay the right commits on top of 'tmp' (which was your master HEAD)
git rebase --onto tmp first_SHA-1_of_old_master_to_replay~1 master

# remove tmp branch, 
# your master HEAD is now on top of tmp, with the right commits replayed
git branch -d tmp
Run Code Online (Sandbox Code Playgroud)

即使SHA1与您的旧master历史不同,您的新主人与您的第二人不同,该解决方案仍然有效git-svn clone.
这就是为什么我推荐一个rebase --onto:master如果由于某种原因,第二个s git-svn clone不会产生完全相同的SHA1 ,那么两个s 的历史可能没有任何共同之处.