SNV環境データをGit Submodule機能を使ってプロジェクト管理してみた

今ではGitで開発することが当たり前になってきましたが、クライアントワークではまだまだSVNを使うこともあります。
自分はSVNのデータを落とすときは git svn を使っています。
落としてきたデータを元にローカルではGit。リモート環境はSVNという形で開発をしています。

SVNはコーディングデータを受け取るだけになるので、なにかを編集しリモートへコミットすることはありません。
CMSで使用するテーマや設定ファイルはSVN環境へはコミットせずに別リポジトリ(Git)を立てて管理しています。
2つの環境は完全に独立してしまうため、SVNをupdateしたあとに手動でGit環境へファイルをコピーするという手順では芸がないと思いGit Submodule機能を使って簡易で紐づけし更新があったら rebase してGit環境にpullできるようにしてみました。

リポジトリ構成

構成としては3つのリポジトリがある想定になります。
主にコーディングデータのみを取得するためのクライアントSVN環境リポジトリ。
自分の開発リポジトリにGit Submodule機能で紐づけするためのSVNデータ格納先のGitリポジトリ
主にメインで開発を進めるGitリポジトリ。

  • クライアントのSVN環境リポジトリ
  • SVNデータ格納先のGitリポジトリ
  • 自分の開発データ格納先のGit環境リポジトリ

はじめは自分のGitリポジトリに子ディレクトリを作成しSVN環境のリポジトリを git svn で落としてこようと思ったのですが出来ず、調べてみるとstack ovarflowに参考の記事があったので上記の構成にしてみました。

Git Submoduleについて

Git Submoduleはブランチ単位で管理するリポジトリと違いCommitID単位で管理するようです。
Git submoduleの押さえておきたい理解ポイントのまとめ の記事でまとめられていました。

構成作成の手順

ここから本題のGit Submodule機能を使って紐づけする環境構築の手順になります。

クライアントSVN環境チェックアウト・Git側のリポジトリを登録する

まずはクライアントSVN環境からデータを取得します。
チェックアウト完了したら、Git側で用意したリポジトリを追加します。
記載しているチェックアウト先URLやGitのリポジトリはご自身の環境に合わせて読み替えてください。

  
// チェックアウト先に移動しgit svnでcloneする ※projece-name-svnは任意のディレクトリ名
cd ~/チェックアウトしたいディレクトリ/
git svn clone --prefix svn/ http://www.XXXXXX.jp/svn projece-name-svn
// cloneしたディレクトリに移動しリポジトリを追加する
cd projece-name-svn/
git remote add origin git@gitlab.XXXXXX.jp:projece-name-svn.git
// Git側で用意したリポジトリにpushします
git add .
git commit -m 'SVNデータ Gitリポジトリに追加'
git push origin mastar
  

クライアントSVN環境と紐付ける

すでに上記のリポジトリの登録済みでcloneのみ場合は、以下の手順で紐づけを行います。

  
// cloneしたいディレクトリに移動して、cloneする
cd ~/cloneしたいディレクトリ/
git clone git@gitlab.XXXXXX.jp:projece-name-svn.git
cd projece-name-svn/
// git configを直接編集
vi .git/config
以下の内容をconfigに追記
[svn-remote "svn"]
    url = http://www.XXXXXX.jp/svn
    fetch = :refs/remotes/svn/git-svn
  

Git Submoduleを使い開発リポジトリに紐づけする

クライアント環境とは独立している開発専用リポジトリに、クライアントSVN環境に紐づけしたGitリポジトリを追加します。
svn-project はSVN環境とわかるように明記したディレクトリにしています。
リモートリポジトリの名前 git@gitlab.XXXXXX.jp:projece-name.gitsvn を外したプロジェクト名にしていますので、ご自身の環境に合わせたリポジトリ名に読み替えてください。

  
// 初期化・ファイル追加・コミット
git init .
// ファイルがあれば不要
echo test > README.md
git add .
git commit -m 'first commit'
// SubmoduleでクライアントSVN環境に紐づけしたGitリポジトリ追加・コミット・push
git submodule add git@gitlab.XXXXXX.jp:projece-name-svn.git -- svn-project
git commit -m 'Add submodule'
// リモート先の開発リポジトリを登録
git remote add origin git@gitlab.XXXXXX.jp:projece-name.git
// リモートリポジトリにpush
git push origin master
  

Submoduleを含んでクローンする

すでに開発環境に .gitmodules が設定されている状態の場合は、以下のコマンドでSubmoduleのデータを含めてクローンできます。
通常のクローンでは取得は出来ません。

  
git clone --recursive git@gitlab.XXXXXX.jp:projece-name.git
  

すでにクローン済みの場合

すでにクローン済みでSubmoduleが入ってなかった場合は、以下のコマンドで取得できます。

  
git submodule update --init --recursive
// or
git clone git@gitlab.XXXXXX.jp:projece-name.git
git submodule init
git submodule update
  

SVN更新データを開発リポジトリに反映する方法

SVN側で更新したデータを開発リポジトリのSubmoduleに反映させる方法になります。
SVNのリポジトリと開発のリポジトリで行き来する必要がありますが、手動でコピーするよりは正確なデータが取得できると思います。
以下の流れを繰り返すような形で開発リポジトリに反映するようにしています。

  
// SVNのリポジトリに移動しクライアントSVNデータを更新する
cd ~/cloneしたいディレクトリ/projece-name-svn/
git svn rebase
// 更新したデータをprojece-name-svn.gitにpushする
git add .
git commit -m 'UPDATE SVN'
git push origin master
// 開発側のリポジトリに移動しSubmoduleを更新する
cd ~/cloneしたいディレクトリ/projece-name/
git submodule foreach git pull origin mastar
git add .
git commit -m 'UPDATE Submodule'
git push origin mastar
  

その他のコマンド

その他 git svngit submodule のコマンドになります。

クライアントSVN環境更新する方法

  
git svn rebase
  

クライアントSVN環境へコミットする方法

git svn はgitと違いpushではなくdcommitでコミットします。

  
git add .
git commit -m 'update'
git svn dcommit
  

Submoduleを編集する

Submodule側で編集することは、ほとんどありませんが念の為メモしておきます。
Submoduleを直接編集する場合は、作業用ブランチを切って作業しマージします。
そのまま編集してしまうとdetached HEAD状態になるようです。

  
cd ~/cloneしたいディレクトリ/projece-name/svn-project/
git checkout -b feature/develop
echo 'fileを追加' > newfile.md
git add .
git commit -m 'add submodule update'
git checkout master
git merge feature/develop
git push origin master
// feature/develop削除
git branch -d feature/develop
// 開発リポジトリ更新
cd ../
git add .
git commit -m 'add submodule update'
git push origin master
  

Submoduleを削除する方法

  
git submodule deinit svn-project
git rm -rf svn-project
rm -rf .git/modules/svn-project
  

Submoduleの状態確認

  
git submodule status
// or
git submodule
  

参考記事

まとめ

SVNリポジトリとGitリポジトリだけでOKでは?と思うのですが、SVNリポジトリには不要なファイル(開発ツール)などを含めたくない場合などは、Submodulesを使ってみていかがでしょうか。
更新のやり方などは手数が多くなり少し面倒ではありますが、独立した形で管理することができたのでクライアントワークのみではありますが使ってみていこうと思いました。

Author

札幌でフロントエンドエンジニアとして働いています。好きな音楽はSIAM SHADE!
SIAM SHADEの六人目のメンバーとして日々ロックを愛し続けている。
HTML,CSS,JavaScriptをベースにCMS構築が得意です。
HAMWORKS社員 https://ham.works