博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
How to migrate svn to gitlab with full history logs
阅读量:6359 次
发布时间:2019-06-23

本文共 6251 字,大约阅读时间需要 20 分钟。

When migrating the source codes from svn to gitlab, we also would like to consider the svn logs migration. Recently we are working on the migration from svn with full history logs, and i would like to share some of the experiences.

Prerequisite

This article only applies to the migrations that, each project in svn will be migrated to gitlab with specified project space, take an example, the projectA in svn will be migrated to

Otherwise, the operations described here may not be served for your purpose.

Typical scenarios

There are three typical scenarios with tools to complete.

Standard svn layout

If you are not quite familiar with the svn standard layout, come to this page for reference

In summary, it should have similar form as:

$repo/paint/trunk
$repo/paint/branches
$repo/paint/tags
$repo/calc/trunk
$repo/calc/branches
$repo/calc/tags

No standard layout but the path never changed

For example, the svn repo has consistent hierarchy

$repo/pkg/paint
$repo/pkg/calc
$repo/branches/paint-skeleton
$repo/branches/paint-hotfix

$repo/tags/paint/v0.1.0

$repo/tags/paint/v0.1.2
$repo/tags/calc/v0.1.1

No standard layout and the path was changed before

For example, before the svn repo has hierarchy as:

$repo/pkg/paint
$repo/pkg/calc suite/calc
$repo/branches/paint-skeleton
$repo/branches/paint-hotfix

Later on, the svn repo changed the organization:

$repo/trunk/paint
$repo/trunk/calc suite/calc
$repo/tags/paint-skeleton
$repo/tags/paint-hotfix

In summary, the original ‘pkg’ was renamed to ‘trunk’; the original ‘branches’ was renamed to ‘tags’; and no ‘branches’ exists any more.

Standard layout Migration

Standard layout migration is relatively simple; here I recommend using subgit.

The subgit is a tool, which is portable and no installation steps. Its official download site is

  1. Choose any clean folder as your operation root directory; we call this dir as $root
  2. In your local svn project directory which you want to migrated, execute command , to get the authors

    svn log | awk '($0 ~ /^r/) {print $3}' | sort |uniq
  3. Switch back to $root, add a new file authormap.txt; this file should contain all mappings between svn(before the equal sign) and gitlab(after the equal sign) authors you listed in step2, example:

    Nicolas wang = xiaoqiang.wang Xiaoqiang.wang@example.com
  4. Execute command in $root

    path/to/subgit-3.2.2/bin/subgit import --non-interactive --default-domain YOUR_DOMAIN --authors-file authormap.txt --trunk trunk --tags tags --branches branches --username SVN_USERNAME --password SVN_PASSWORD --svn-url http://svn.example.com/path/to/repo repo.git

    If any error occurred during the migration and the process was interrupted, execute ‘subgit import repo.git’ to recover

  5. Clone a bare repo and remove the useless svn metadata

    git clone --bare repo.git repo-clone.git
  6. Change to directory repo-clone.git

    cd repo-clone.git
  7. Push local git repo to remote gitlab repository

    git remote add gitlab  http://gitlab.example.com/path/to/repo.gitgit push gitlab --allgit push gitlab --tags

No standard layout migration and the path was changed before

This is the key part of this article. Here we could not use subgit anymore, because this tool will only migrate the logs after renaming pkg->trunk and branches->tags. The logs generated in pkg or branches before, will not be migrated.

What we used here is git svn commands.

  1. Choose any clean folder as your operation root directory; we call this dir as $root
  2. In your local svn project directory which you want to migrated, take the calc project mentioned above as an example, execute command below to get the authors

    svn log | awk '($0 ~ /^r/) {print $3}' | sort –u
  3. Switch back to $root, add a new file authormap.txt; this file should contain all mappings between svn(before the equal sign) and gitlab(after the equal sign) authors you listed in step2, example:

    Nicolas wang = xiaoqiang.wang Xiaoqiang.wang@example.com
  4. Also in $root, execute the command

    git svn clone --no-minimize-url --trunk "trunk/calc suite/calc" --authors-file authormap.txt "http://svn/repo/path/" new.git
  5. Then execute the command

    git svn clone --no-minimize-url --trunk "pkg/calc suite/calc" --authors-file authormap.txt "http://svn/repo/path/" old.git

    The only difference compared to step4, is step5 points to the clone of objects before renaming.

  6. Change to directory old.git, execute command and get the last commit’s SHA in log history, such as 56a0f2578fce65a85436453f37535f416a3c6c07

    git log
  7. Change to directory new.git, execute command and get the first commit’s SHA in log history, such as 63c91bddc647588a3eccf6102df2a4146d447629

    git log
  8. Also in new.git, execute commands

    git remote add oldstuff ../old.gitgit fetch oldstuff
  9. Then execute commands

    git replace [first-commit-sha-from-new.git] [last-commit-sha-from-old.git]
  10. Rewrite the SHA hashes so everything is kosher and you no longer need the replace ref

    git filter-branch
  11. Clean up the no-longer-needed references

    git remote rm oldstuffrm -rf .git/refs/replace
  12. Removing git-svn-id messages

    git filter-branch -f --msg-filter 'sed -e "/git-svn-id:/d"'

    Explanation: When migrating from Subversion, every commit messages has a git-svn-id line appended to it like this one: "git-svn-id: 1eab27b1-3bc6-4acd-4026-59d9a2a3569e". If you are planning on migrating away from your old Subversion repository entirely, there’s no need to keep these.

  13. Removing empty commit messages

    git filter-branch -f --msg-filter 'read msgif [ -n "$msg" ] ; then    echo "$msg"else    echo "
    "fi'

    Explanation: Subversion allows empty commit messages, but Git does not. Any empty commit messages in your newly migrated git repository should be replaced so commands like git rebase will work on these commits.

  14. Push local git repo to remote gitlab repository

    git remote add gitlab http://gitlab.example.com/path/to/repo.gitgit push gitlab --algit push gitlab --tags

    The only drawback of this solution, is that it will overwrite the first commit of new.git using the last commit of old.git, so the first commit of new.git will lose.

No standard layout migration and the path was never changed

Either of the above two scenarios could cover this topic, it depends on the actual situation which tool (subgit or git svn) you should use, and it will not be extended here

References

转载地址:http://ntbma.baihongyu.com/

你可能感兴趣的文章
前端程序员需要具备的几个软实力,你具备了吗
查看>>
RHEL系列网络配置2015083101
查看>>
c# 基本值类型及其默认值
查看>>
服务器端解决JS跨域调用问题
查看>>
MySql中添加用户,新建数据库,用户授权,删除用户,修改密码
查看>>
雨巷-戴望舒
查看>>
OpenCms创建网站过程图解——献给OpenCms的初学者们
查看>>
C++ 异常处理机制的实现
查看>>
Freebsd的ports命令
查看>>
分布式系统---幂等性设计
查看>>
【转】时钟周期,机器周期,指令周期的区别
查看>>
MYSQL 更新时间自己主动同步与创建时间默认值共存问题
查看>>
android 屏幕适配
查看>>
Android Activity的4种启动模式
查看>>
leetcode第一刷_Minimum Depth of Binary Tree
查看>>
pm2-webshell —— 基于浏览器的终端控制台
查看>>
Mysql基准测试
查看>>
Session 撰改演示
查看>>
【转】python3 发邮件实例(包括:文本、html、图片、附件、SSL、群邮件)
查看>>
事务隔离级别(图文详解)
查看>>