在历史记录中创建中间提交

时间:2019-05-28 18:07:25

标签: git

我的任务是将集中式VCS解决方案复制到git存储库中。我的计划是使用Jenkins管道来吸收来自CVCS的提交,从git中提取最新的内容,然后将这些更改提交到git并推送。

目标是捕获每次提交时的提交,为此,我正在使用CVCS中的一个Webhook,它将相关信息传递给管道以标识历史中的特定提交。出于这个问题的目的,假设所有开发都是在一条无分支的无尾行中完成的。

我担心的是Webhook调用的异步特性。如果我已经将提交1000同步到git,那么提交1001和1002几乎同时出现,那么Jenkins管道可能在1001之前运行1002。这本身不是一个大问题(我打算在git repo中包含一个文本文件)来跟踪上一次同步的CVCS提交),但是如果我能以比丢弃它更智能的方式处理1001,那将是

有什么方法可以在git历史记录中创建中间提交?像这样:

git checkout HEAD~1
git checkout -b some_temp_branch
git commit -m "This is commit 1001"
git checkout master
git merge some_temp_branch -Xtheirs         # or something?

产生的历史记录来自:

1002
 |
1000

1002
 |
1001
 |
1000

工作目录中没有更改?

2 个答案:

答案 0 :(得分:3)

您是要转换为Git,还是要在Git these tools already exist中创建存储库的镜像。它们的开发水平取决于VCS。例如,git-svn非常完善; Git可以充当Subversion的双向镜像。其他在线可用,请查找<vcs name>2git。例如,如果您使用的是CVS,则将查找cvs2gitgit cvsimport

如果您的VCS尚不存在Git迁移工具,则可以通过将提交转换为适合git fast-import的格式来构建它。与其使用Jenkins,不如使用普通的VCS客户端来检索最新的提交。这样就不会发出订单。


如果打算转换为Git,我建议反转您的过程。哪种方法最好取决于您的情况,但是通常最好将Git用作领导者存储库,而将旧的VCS用作跟随者。 Git非常灵活和强大。它可以适应您使用旧VCS的方式,但是您旧的VCS无法适应Git。使Git成为跟随者会限制您使用与现在相同的版本控制。转换有什么意义?

如果Git是领导者,则Git可以像您习惯的那样以集中模式进行操作。确保在推送之前仅提交master并始终使用git pull --rebase将本地提交提交到master的顶端。同时,您可以探索Git的新功能;例如feature branches。如果有必要保留旧的VCS,请通过将对master分支的提交镜像到旧的VCS中来创建只读镜像。

答案 1 :(得分:0)

值得注意的是,无论您如何执行此操作,获得的内容都不是插入的提交。

如果您重新设置基础(无论如何执行),则会获得一个 new分支,并以 new 提交结束。新分支可以重用旧分支的名称(导致出现明显的问题What exactly do we mean by "branch"?),但是新的提交链将具有与原始提交链不同的新哈希ID。

也就是说,如果您有:

... <-c1000a <-c1001a   <-- master

因为您的系统认为c1001应该在c1000之后出现,现在您已经意识到,不应该在两者之间进行提交,因此您可以创建一个新的c1001b:< / p>

... <-c1000a <-c1001a   <-- master
            \
             c1001b

但现在您必须将 c1001a复制到c1002b

... <-c1000a <-c1001a   <-- master
            \
             c1001b <- c1002b

您现在可以将名称master指向c1002b,完全“忘记” c1001a

... <-c1000a <-c1001a
            \
             c1001b <- c1002b   <-- master

只要Git在某个地方(通常在 reflog条目中)记住其哈希ID,则被遗忘的提交将继续存在(并有效)30天以上,除了{{1} }没有宽限期的存储库服务器)。如果某个 other Git抢占了--bare,则该 other Git会保留它,并可以将其与c1001a合并-或{ {1}}是(后来),因为如果它们都被命名为c1002b,则您可能希望合并master。(您确实不希望合并,但 Git 不知道的。)

如果合并,则只会在最后得到一个合并提交。您将提交添加到新的临时分支中:

master

然后c1001a保留 c1001a <-- master / ... <-c1000a \ c1001b <-- temporary 中的源树:

git checkout master; git merge -s ours temporary

删除临时名称将为您提供最终结果:

c1001a

这不会给其他Git存储库带来任何伤心,因为您没有故意扔掉进行新的改进版本(一个新的Git可能会带回来) )。取而代之的是,您只需添加提交,所有Git都会理解其他Git随时可以做的事情。

merge方法的缺点是这可能不是正确的历史记录。