Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
3
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@usuiat

いろいろ残念なSVN職場で自分だけGitを使おうとして苦労した話

職場がいまだにSVNでツライのでgit-svnで自分だけGitを使おうとしたら、SVNリポジトリがいろいろ残念で苦労したという話です。
同じ環境の人は少ないとは思いますが、誰かの参考になれば。

環境

  • Windows 10
  • Gitの操作は基本的にBash for Git

SVNリポジトリの現状

  • リポジトリ構成が変則的
  • Shift-JISとUTF-8が混在

変則的なリポジトリへの対応

SVNリポジトリは、以下のような構成になっていました。trunkの下にbranchがあるのはいまだに納得いかない・・・

SVN_REPO/
    trunk/
        doc/
        src/       ← 実質的なトランク
        src_foo/   ← ブランチ
        src_bar/   ← ブランチ
        src_v001/  ← タグ
        src_v002/  ← タグ
        (以下、src_vXXXがいっぱい)
        tool/
    branches/
        hoge/      ← ブランチ
            doc/
            src/
            tool/
    tags/          ← 空っぽ

やりたいこと

  • trunk/src/をtrunkとしてgit-svnに取り込む
  • branches/hoge/src/trunk/src_*/をbranchesとして取り込む

手順

どうやらgit svn cloneのオプションだけで上記を実現するのは無理そうだったので、init後にconfigをいじってfetchすることで実現しました。

まずはinitします。

  • GitからSVNのリポジトリを見たときに区別がつくように、--prefixオプションを指定します。
  • srcディレクトリの下だけを対称とするので、-T trunk/srcと指定します。
  • ブランチは複雑なので後でconfigを編集するのですが、ここではconfigの雛形を作るために適当に-bオプションを指定します。
$ git svn init --prefix=svn/ -T trunk/src -b trunk/ http://SVN_REPO_URL

次に.git/configを編集します。

[svn-remote]branches =で始まる行を編集します。これはブランチの履歴情報などが保存されるパスを示していて、:の左側はリモート側のパスを、右側はローカル側のパスを意味するそうです。
今回はブランチが2箇所に別れているので2行に分けて指定します。*でワイルドカードが使えるので、1行目でtrunkの下のsrc_で始まるすべてのブランチをまとめて指定します。(今回の構成ではタグも一緒に取り込まれてしまいますが、気にしないことにします。)2行目でbranchesの下の任意のディレクトリの下のsrcディレクトリを指定します。
また、ローカルに作成されるブランチが、リモートリポジトリのどのブランチだったかの区別がつくように、片方をbranches_in_trunk、もう片方をstd_branchesとしました。

branches = trunk/src_*:refs/remotes/branches_in_trunk/*
branches = branches/*/src:refs/remotes/std_branches/*

最後にfetchします。

$ git svn fetch

これでトランクとブランチそれぞれのsrc以下を取り込むことができました。

$ git branch -r
svn/branches/hoge
svn/branches_in_trunk/src_foo
svn/branches_in_trunk/src_bar
svn/branches_in_trunk/src_v001
svn/branches_in_trunk/src_v002
svn/trunk

文字エンコード混在への対応

現状はSJISとUTF-8のファイルが混在していました。フォルダによって違うとかならまだしも、同じフォルダ内でもバラバラ。同名の.cと.hでも揃ってなかったりと、ひどい状況。
このままだとdiffが見づらくて仕方ありません。
SJISのファイルをGitで扱う方法をググるとiconvがよく使われているようですが、iconvは元のエンコードを指定する必要があるため、今回のケースでは使えません。
そこでnkfを使うことにしました。

手順

ローカルリポジトリのルートディレクトリに、.gitattributesという名前でファイルを作成して、下記を記述します。
これによって、指定した拡張子に対してdiffコマンドを使うときには"sjis"フィルターを適用するようになります。

*.c diff=sjis
*.h diff=sjis
*.cpp diff=sjis
*.hpp diff=sjis

次に、.git/configファイルにsjisフィルタを記述します。

[diff "sjis"]
    textconv = nkf -w8

これで、SJISとUTF-8が混在していても文字化け無くdiffを見れるようになりました。

ただ、git add -pなどのパッチ系コマンドは相変わらず文字化けするんですよね。解決策はまだ見つかっていません。ご存じの方、教えてください。
まあ、それよりエンコード統一しろよって話ですけどね。。。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
3
Help us understand the problem. What are the problem?