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

发布于 2024-10-23 14:38:42 字数 288 浏览 3 评论 0原文

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

I've been using git-svn, and recently, I've been getting errors when trying to commit (I think this is due to a bug in libneon, but this is beyond the scope of this question). The solution has been to re-clone my git repository using git svn clone. However, I have changes on the master branch in my old git repository that I was not able to commit to svn using git svn dcommit. I'd like to replay these changes on the new repository cloned with git svn. I think I could probably export a patch-set using git format-patch, and then replay these changes on the new repository but I'm not entirely sure how to do this, and I wonder if there's an even easier or more elegant way to accomplish this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

过度放纵 2024-10-30 14:38:42

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

git remote add temp file:///path/to/old/repo/on/your/machine

从旧存储库中获取:从

git fetch temp

旧存储库中检查您的主分支:

git checkout temp/master -b wip

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

将更改重新设置为您的内容之上的更改当前存储库:

git rebase master

更新 master 以指向您的新 HEAD:

git checkout master
git merge wip

删除对旧存储库的远程引用和您使用的 wip 分支:

git branch -d wip
git remote rm temp

您实际在做什么:

首先,通过添加远程引用并获取,您将从中提取提交当前存储库中还没有您以前的存储库。 Git 知道如何做到这一点,因为无论在何处或如何进行,相同的提交在任何地方看起来都是相同的。它是一些众所周知的信息的 SHA1 哈希值,包括目录树、提交者、时间戳……

因此,当您基于同一个 SVN 存储库创建新的 Git 存储库时,所有提交都具有相同的 SHA1总和。因此,您提取到当前存储库中的新提交继续指向正确的内容。这非常酷,并且记住这一点很重要。

然后,您切换到 temp 的 master 分支的尖端,并告诉它重新建立到当前的 master 分支。变基可能是不必要的,因为 SVN 的 master 可能没有从旧仓库中的 master 移开,但最好是安全的。

变基通过回溯历史记录来找到两个提交之间最近的共同点,直到它们都指向同一个父提交。然后,它切换到您给它的分支名称(在本例中为 master),并挑选原始分支历史记录中缺少的每个提交。完成后,它会指向您在应用的最后一次提交时开始时所在的分支。

最后master与wip的合并只是为了将master快进到最后。因为是一条直线,所以实际上只是快进。您可以轻松地进行变基或重置 --hard;其中任何一个都会改变主分支以指向正确的位置。合并只是其中最安全的,因为如果发生了奇怪的事情,它会让你知道这不是简单的快进。

From your new repository, add a remote reference to your old repository:

git remote add temp file:///path/to/old/repo/on/your/machine

Fetch from the old repo:

git fetch temp

Check out your master branch from the old repo:

git checkout temp/master -b wip

(wip stands for work-in-progress)

Rebase the changes on top of the stuff in your present repository:

git rebase master

Update master to point at your new HEAD:

git checkout master
git merge wip

Delete the remote reference to your old repo and the wip branch that you used:

git branch -d wip
git remote rm temp

What you are actually doing:

Firstly, by adding the remote reference and fetching, you are pulling the commits from your previous repository which you do not yet have in your current repository. Git knows how to do this because, no matter where or how it was made, the same commit looks the same everywhere. It is the SHA1 hash of a few well-known pieces of information, including the directory tree, the committer, timestamp, ...

So when you created a new Git repository based on the same SVN repository, all the commits had the same SHA1 sums. As a result, the new commits that you fetched into your current repository continued to point at the right stuff. This is very cool, and important to remember.

You then switched to the tip of temp's master branch and told it to rebase onto your current master. The rebase may have been unnecessary, as master from SVN may not have moved away from the master in your old repo, but it was best to be safe.

A rebase finds the nearest point of commonality between two commits by working backwards through their histories until they both point at the same parent commit. It then switches to the branch name you gave it (in this case master) and cherry-picks each of the commits that were missing from its history from your original branch. Once complete, it points the branch you were on when you started at the last commit it applied.

Finally, the merge of master with wip was just to fast-forward master to the end. As it was a straight line, it really was just a fast-forward. You could have just as easily done a rebase or a reset --hard; any of these would have altered the master branch to point at the correct location. Merge was just the safest of these, because if something weird had happened, it would have let you know that it was not a simple fast-forward.

习惯成性 2024-10-30 14:38:42

您可以:

  • 将旧仓库添加为新仓库的远程仓库 (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

即使 SHA1 与您的旧 master 历史记录以及来自第二个 git-svn 克隆的新 master 不同,该解决方案也将起作用。代码>.
这就是为什么我建议使用 rebase --onto:如果出于任何原因,第二个 git-svn 发生变化,两个 master 的历史可能没有任何共同点克隆不会生成完全相同相同的SHA1。

You could:

  • add your old repo as a remote of your new repo (git remote)
  • fetch the old branch
  • rebase the part of the old branch you are interested in on top of your current master.

See How to cherry pick a range of commits and merge into another branch:

# 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

That solution will work even if the SHA1 differs from your old master history and your new master from your second git-svn clone.
That is why I recommend a rebase --onto: the history of both masters might have nothing in common if, for any reason, the second git-svn clone don't generate exactly the same SHA1.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文