添加原始哈希以在git rebase上提交(使用新根)
我有一个过去用SVN管理的代码库,但现在用git管理。当代码迁移到git时,历史记录丢失了 我已经设法做到了,现在正试图添加原始哈希以在git rebase上提交(使用新根),git,version-control,rebase,git-rebase,git-filter-branch,Git,Version Control,Rebase,Git Rebase,Git Filter Branch,我有一个过去用SVN管理的代码库,但现在用git管理。当代码迁移到git时,历史记录丢失了 我已经设法做到了,现在正试图git重新设置最近提交的内容的基础 我有两个分支,gitcommits,其中包含自迁移到git以来的提交,以及svncommits,其中包含较旧的历史记录。每个分支包含3000多个提交 我发现以下命令在旧历史的基础上构建新的历史(尽管有一些手动合并冲突处理): 有几个提交引用了提交散列,我知道在重新基址完成后,这些散列会发生变化。为了使这些信息不会永远丢失,我想将每个提交的原始
git重新设置最近提交的内容的基础
我有两个分支,gitcommits
,其中包含自迁移到git以来的提交,以及svncommits
,其中包含较旧的历史记录。每个分支包含3000多个提交
我发现以下命令在旧历史的基础上构建新的历史(尽管有一些手动合并冲突处理):
有几个提交引用了提交散列,我知道在重新基址完成后,这些散列会发生变化。为了使这些信息不会永远丢失,我想将每个提交的原始提交哈希添加到新重定基础的提交消息中
这意味着像这样的原始提交:
commit aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Author: Boaty McBoatface <boaty@example.com>
AuthorDate: Wed Jul 27 00:00:00 1938 +0000
Commit: Boaty McBoatface <boaty@example.com>
CommitDate: Wed Jul 27 00:00:00 1938 +0000
Reticulate splines
The splines had been derezzed, and needed to be reticulated.
commit aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
作者:Boaty McBoatface
作者日期:星期三7月27日00:00:00 1938+0000
提交:Boaty McBoatface
委托日期:星期三7月27日00:00:00 1938+0000
网状样条
样条线已经去毛刺,需要进行网格化处理。
会变成
commit bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
Author: Boaty McBoatface <boaty@example.com>
AuthorDate: Wed Jul 27 00:00:00 1938 +0000
Commit: Meshy <meshy@example.com>
CommitDate: Wed Nov 16 10:23:31 2016 +0000
Reticulate splines
The splines had been derezzed, and needed to be reticulated.
Original hash: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
提交bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
作者:Boaty McBoatface
作者日期:星期三7月27日00:00:00 1938+0000
提交:Meshy
委托日期:2016年11月16日星期三10:23:31+0000
网状样条
样条线已经去毛刺,需要进行网格化处理。
原始哈希:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
这可能吗?也许使用git过滤器分支
?时,答案可能取决于要重新设置基础的提交数量。
如果要重定基址的分支包含的提交数量相当少,且您可以手动编辑,则以下提示可能会起作用:
一般来说,交互式的基础应该对您有所帮助,我希望您不一定要进行分支过滤
r, reword = use commit, but edit the commit message
使用交互式重基,尝试通过在提交消息中插入原始哈希来重写每个提交
对于更大数量的提交,在3000个左右的情况下,让我们尝试使用筛选器分支:
git filter-branch --msg-filter 'cat && echo "Original hash $GIT_COMMIT"' HEAD~3000..HEAD
它将为您所在分支的过去3000次提交中的每一次提交生成新的提交,其中包含重写的提交消息。新提交消息的格式与此类似(请注意底部的提交哈希):
之后,您可以安全地进行重设基础。应该保留旧的提交哈希
溴
Maciej首先,请注意:确保您确实想要这样做,因为可以使用git replace
(下面简要提及)以保留ID的方式将历史记录缝合在一起。当然,它也有自己的缺点;搜索使用过它的人的报告
是的,您可以使用git filter branch
执行此操作
不过,您可能希望将“在新转换上重新设置新提交的基础”步骤与“…相结合,然后编辑所有新提交以同时包含其旧ID”步骤,因为重新设置基础通过复制提交来工作,而过滤分支通过。。。复制提交::-)
所有执行此类操作的Git命令都必须复制,因为每个提交的哈希ID都是提交内容的函数。如果新提交与原始提交在任何方面都不同,它将获得一个新的、不同的ID
git-rebase
和git-filter-branch
之间的区别在于复制了哪些提交以及如何执行复制
如果不使用--保留合并
,则可通过选择非合并提交列表,将每个此类提交转换为一个变更集(通过减法,或多或少:child减去parent=从父到子的增量),然后将此增量添加到--到
点或到目前为止添加的提交
使用--preserve merges
时,rebase仍会选择非合并提交的列表。然后,在有合并提交的地方,rebase重新执行合并(这就是为什么必须重新解决合并冲突)。它必须重新合并,因为新的基可能导致不同的合并,而且合并不能转换为单个变更集(“子-父”提供一个增量,但至少有两个父,因此至少有两个增量,在一般情况下,我们不能同时保留这两个增量)
过滤器分支使用完全不同的方法。无论是否为合并,都会选择要筛选的提交。(实际的选择是通过运行git rev list
,这是相当于git log
的“管道”来完成的)这个完整的提交ID列表被放置到一个堆中:一个存储在普通文件中的排序拓扑顺序堆,以便父提交总是在其子提交之前进行处理
然后,对于列表中的每个ID:
- 将原来的提交一个la
git checkout
,提取到一个没有底层git repo的临时树中
- 应用树过滤器以修改树。(此修改在保存临时树的临时目录中运行。当许多人尝试访问像
。/../fixed version
这样的文件时,这一部分会使他们在执行第一个树筛选时出错。相对路径失败,因为临时树根本不在存储库中。)
- 重建一组新的Git树和代表新树的blob对象,即新的提交快照
- 将提交消息筛选器应用于消息
- 将提交环境筛选器应用于其余的提交元数据(author和committer内容)
- 使用新消息和新树进行新提交。或者,如果您提供了提交筛选器,则使用它进行提交或不进行提交;此时,还可以使用父过滤器修改新提交的父项
- 拉斯维加斯
git filter-branch --msg-filter 'cat && echo "Original hash $GIT_COMMIT"' HEAD~3000..HEAD
commit 08ac9b84d820ec7b70fa53075adc06f0a8185ab4
Author:
Date: Mon Nov 14 13:14:30 2016 +0100
Adds javadoc
Auto inserted text: ....
Change-Id: ...dbf9497387a3c271ae0349822cb4b8...
Original hash 9d01f3e5b39b15c9dbe923916b6c25019b5b9796
$ git rev-parse svn-commits
9999999999999...
$ git rev-list --max-parents=0 git-commits
11111111111111...
--parent-filter 'if [ $GIT_COMMIT = 11111... ]; then
echo -p 999999...; else cat; fi'
Original hash: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
--msg-filter 'cat; echo; echo "Original hash: $GIT_COMMIT"'
--msg-filter 'cat; echo; echo "new commit $(map $GIT_COMMIT) \
filtered to reparent original commit $GIT_COMMIT"'