きり丸の技術日記

技術検証したり、資格等をここに残していきます。

【技術】SVNを改めて調べる + 俺の考えるSVNブランチ戦略

以前、ブランチ戦略について自分が纏めた記事を書きました(当記事の最後にリンクあります)。 ただ、Gitについて書いたはずなのに「SVNブランチ戦略」で検索される方が一定数いらっしゃいます。ここ2年くらいSVNについてはもう触っていませんが、自分の知識を深めるためにSVNを改めて勉強しようと思い、この記事を書きました。

なお、社内でSVN使っているところもあるらしいです。私もまだまだ使う可能性はありますから、学ぶメリットはあるはずです。

この記事のターゲット

  • Gitを既に知っている
  • Git-flowもある程度わかる
  • SVNをこれから知りたい
  • Git-flowをSVNに当てはめるとどうなるか知りたい

非ターゲット

  • SVNの操作を知りたい
  • SVNの詳細を知りたい

SVNとは

Subversion」でSVN。集中管理方式のバージョン管理システムです。バージョン管理システムは、ファイルに対して更新履歴を記録することで、過去のある時点の状態を復元したり変更内容の差分を表示できるようにするシステムです。チームでの開発で最も力を発揮しますが、個人で使用しても数カ月前のことは覚えていなかったりするので、論文や原稿等でも使えます。

なお、正確な捉え方ではないでしょうが、操作履歴を保持する巨大な共有フォルダのイメージで良さそうです。


以下、WikipediaSVNの特徴引用。

  1. ディレクトリの移動や削除をサポートしている。このため、ファイル名やソースツリーの構造がはっきりと決まらないうちからバージョン管理をできる。
  2. バージョン番号(リビジョン番号)はソースツリー全体に対して振られるため、原則としては誰かがソースツリーのどこかのファイルを更新する度に番号が増えてゆく(CVSではファイル毎にリビジョン番号がつけられている)。
  3. 作業ディレクトリ内に、最後にソースリポジトリと同期をとったときのファイルのコピーを持っているため、改編中のファイルの変更部の確認などがソースリポジトリにアクセスする事無く高速に実行できる。また、ファイルの差分送信が効率よく行なわれるため、プアなネットワーク環境で利用したときに快適である。
  4. SSHによるソースリポジトリとの通信を標準でサポートしている。インターネット経由で利用してもセキュリティを容易に保つ事ができる。
  5. WebDAVをバックエンドとして使うことができる。つまり、Apache HTTP ServerなどのWebDAVをサポートするHTTPサーバを経由して、WebDAVプロトコルを用いてSubversionサーバとSubversionクライアントが通信するという形態が使える。

集中管理型と分散管理型

集中管理型は、非常にわかりやすいことがメリットです。開発中のブランチはtrunkディレクトリであることが一般的な慣習です。なので、開発中のブランチ戦略を考えることはありません。常に開発ブランチが明白なので、リファクタリングしてもチームへの影響を最小限にできます。また、一部のソースをロック(チェックアウト)して、他の人に修正させないようにできます。開発中も誰が修正しているかが一目瞭然です。

しかし、デメリットもあります。

集中管理型は分散管理型と違い、リポジトリの存在を1つしか許容しません。それは、リモートとローカルでの差分を許容しないということです。Gitは分散型なのでcloneした段階で、origin/masterとmasterの2つのリポジトリを作成します。SVNはあくまで、リモートリポジトリを参照しているので、1つのリポジトリのままです。

集中管理型では、ローカルで小さくコミットして最後にまとめてプッシュはできません。コミット=プッシュとなります。うっかりコミットすると全員の環境が壊れてしまいます。
また、Gitであれば動かなくなった段階で別ブランチにしてプッシュし、他の人に相談を持ち掛けることもできます。SVNでは環境壊すのを覚悟でプッシュするか、コミット前のローカルの環境を元に相談しに行くしかありません。

あと、別のリポジトリの存在を許容しないという観点から、PullRequestのような別リポジトリ(第三者)からの意見を反映する、ということは思想上難しそうです。OSSが集中管理方式をとることは無いでしょうね。


なお、私はGitでもmasterのみ開発(トランクベース開発)が最高だと信じています。ブランチを切ることは、マージコストを高めてしまいます。リポジトリの存在を1つしか許容しないので、強制的にトランクベース開発を取ることになります。

SVNで使われるクライアントツール

Eclipse等のIDEに含まれていますが、IDE上でうまく操作できず、私は下記リンクのTortoiseSVNを使用してました。読み方は「トータス・エスブイエヌ」です。社会人1年目で読み方が分からなかったので、「カメさんツール」でごり押して表現していました。

qiita.com

俺のブランチ戦略

SIer時代にSVNで開発をしていた時の経験則と、Git開発に慣れた経験則を合わせて考えました。SVNのベストプラクティスはわかりません。

SVNの一般的なリポジトリ構成としては、下記の構成になります。
SVNを構築した段階では下記の構成はなく、まっさらな状態なので自分でディレクトリを作成する必要があります。

  • project/trunk/subdir/...
  • project/branches/branch/subdir/...
  • project/tags/tag/subdir/...

※ 上記のsubdirがGitのbranchの作業ディレクトリと同等と考えていいでしょう。 SVNは全部の作業ディレクトリが同時に存在するので、巨大な共有フォルダという捉え方をしました。

trunk


開発に使用するリポジトリ。開発の中でもメジャーアップデートのために使用していました。一部だけ先行機能追加したい場合は、branchesを使っていました。

  • trunk(開発環境/検証環境)

trunkをGitで表現するなら

master, mainブランチと表現されることもあるけれど、個人的にはdevelopブランチが一番しっくり来ます。もちろん、Gitのブランチ戦略によるのでブランチの捉え方は異なりますが、ブランチが切りづらい=masterブランチと捉えるのは違和感がありました。

branches


trunkからコピーした後、修正OKリポジトリ。本番環境で適応しているソースコード、マイナーアップデート等で使用していました。

なお、SVNはマージのコストが非常に重いです。なので、障害修正も直接branchesにコミットして、その後trunkにマージしていました。同様にマージのコストの関係で、検証環境等はtrunkからデプロイしていました。

  • branches/prd(本番環境)
  • branches/feature(先行リリース機能開発)

等々。

branchesをGitで表現するなら

Gitでいうとリリースブランチ、featureブランチです。hotfixブランチはマージコストが重いのでわざわざ作りません。

tags


trunkからコピーした後、修正NGリポジトリ。リリースタイミングでどんなソースコードだったかを残すときに使用する(スナップショットを残す)

  • tags/1.0(本番バージョン1.0)
  • tags/2.0(本番バージョン2.0)

tagsをGitで表現するなら

Gitと同じ感覚で問題ありません。ただし、Gitのtagはコミットハッシュなので非常に軽いですが、ディレクトリごとコピーなのでやればやるほど重くなります。

SVNのブランチ戦略を図で表現する

f:id:nainaistar:20201012184905p:plain
SVNのブランチ戦略

線が飛び交っていてわかりづらいですが、このような運用を想定しています。
ちなみに、Git-flowだともっとごちゃごちゃします。

時系列の運用とSVN操作

※時系列とは合わない箇所があります。

  1. 本番リリース前の開発を行う
  2. 本番へリリースを行う。trunkからbranches/prdにブランチを切る。
  3. branches/prdからリリース対象に対してタグ(1.0.0)をつける。先行リリース機能として、trunkからbranches/featureブランチを切る。
  4. 本番で障害が発生したので、直接コミットする。branches/prdからリリース対象に対してタグ(1.0.1)をつける
  5. 障害修正を、別ブランチに反映する。branches/prdからtrunk、branches/prdからbranches/featureにマージする。
  6. 先行リリース機能を本番環境に反映する。branches/featureからbranches/prdにマージする。また、先行リリース機能ブランチを使わなくなるので、削除する。
  7. branches/prdからリリース対象に対してタグ(1.1.0)をつける
  8. 先行リリース機能を開発環境に反映する。branches/prdからtrunkにマージする。
  9. 開発環境から本番環境にメジャーアップデートする。trunkからbranches/prdにマージする。
  10. branches/prdからリリース対象に対してタグ(2.0.0)をつける

最終的に残っているブランチ:trunk、branches/prd

タグは基本的には許される限りは残しておくものだと思いますが、タグの生存期間や頻度等は実際の現場での相談になります。

終わりに

Gitの知識を得てからSVNの知識を学ぶと、それなりに整理できました。「SVN ブランチ戦略」で検索してきて、この記事が目的通りのものかはわかりません…。また、Gitの詳細もSVNの詳細もわかっていないので認識があっているかどうかは分かりませんが、SVNディレクトリをコピーしつつ、履歴を残すブランチやタグを切る処理は重いだろうなぁという感想を持ちました。

動的型付言語と静的型付言語が定期的に人気が変わるように、バージョン管理システムの集中管理方式と分散管理方式の人気が変わるのでしょうか…。一度Gitで分散管理方式に慣れた身としては集中管理方式に強いメリットは感じませんが、技術として出てきたら非常に強いメリットがあるんでしょうね。

もし出てきたら、興味を持って調べてみようと思います。


もしこの記事が役に立ったのであれば、はてぶ、Twitterでの記事の拡散、Twitterのフォローもよろしくお願いします。

私の励みになります。

参考資料

https://ja.wikipedia.org/wiki/Apache_Subversion

https://ja.wikipedia.org/wiki/TortoiseSVN

qiita.com

www.atmarkit.co.jp

backlog.com

類似記事

ブランチ戦略について考える
nainaistar.hatenablog.com

【FTP】FTPサーバをDockerで用意する(stilliard/pure-ftpd)

※ 実は上手くいってない点があるので、正確には未完成です。 また、私がDockerとFTPサーバの初心者なので、おそらく無駄とかあります。


コード上だけであれば、FakeFtpServer等のFTPサーバをモックにしてテストする方法はあります。ただし、モックなしの内部での結合試験を行うときには、FTPサーバが必要になります。

そんな時に、できるだけさっくりとDockerでFTPサーバを建てる方法を探しました。その時に苦労した作業メモです。


当たり前ですが、英語を簡単に読めるなら公式ページ見た方がいいです。

この記事読んでわかること概要

  • DockerでFTPサーバを建てる
  • ユーザ/パスワード/ホームディレクトリを設定する方法

分からないこと

  • Dockerイメージでの永続化方法
    • 開発目的のため調べなかった。実運用は流石に怖い。
  • FWで適切なポート開放が必要な環境でのFTPサーバの建て方
    • localでは問題ないことは確認済

Dockerイメージ

stilliard/pure-ftpd

公式ページ

hub.docker.com

Dockerfileとシェル

Dockerfile

ENVで設定してあげれば、ユーザIDやユーザPASSを指定したうえで起動できるので楽ですね。

もし、この設定をしていない場合は、毎回起動したのちにユーザ名やパスワードをコマンドで実行してあげる必要があります。公式ページにも載っていますが、めんどくさいので起動時に指定してあげた方がいいでしょう。

FROM stilliard/pure-ftpd
ENV FTP_USER_NAME=system # ユーザID
ENV FTP_USER_PASS=pass  # ユーザPASS
ENV FTP_USER_HOME=/home/ftpusers/system # HOMEディレクトリ
CMD /run.sh -c 30 -C 10 -l puredb:/etc/pure-ftpd/pureftpd.pdb -E -j -R -P $PUBLICHOST

シェル


私はdummy-ftpという名前で起動します。上記Dockerfileと同じディレクトリでビルドし、起動します。

21ポートは制御コネクションなので、基本的には必要です。30000-30009はこのDockerイメージのデフォルトのデータコネクションです。

docker stop dummy-ftp
docker rm -f dummy-ftp
docker rmi -f dummy-ftp
docker build -t dummy-ftp -f Dockerfile .
docker run --name dummy-ftp -p 21:21 -p 30000-30009:30000-30009 -d -it dummy-ftp

もし、この辺のデータコネクション(PassiveMode)のポートを変更したい場合は、FTP_PASSIVE_PORT と --exposeで指定してあげれば良さそうです。

※ この箇所を全く試せていません。当時、FTPのモードを理解していなかったので環境構築に時間がかかってしまい、検証環境だけFTPするロジックを潰しました。

docker run -e FTP_PASSIVE_PORTS=10000:10009 --expose=10000-10009 -p 21:21 -p 10000-10009:10000-10009

ソースコード

github.com

終わりに

正直なところ、相手が用意したFTPサーバをすぐに使用できるのであれば、接続すべきだと考えてます。

どの環境にも言えますが、こちらで用意した環境と相手が用意した環境の想定が違う、ということは多々あります。最近も苦しみました。

とはいえ、高速で自分たちの組織の中で環境構築できるような能力を高めておけば、本番環境に近い状況でテストできるので、こういう技術は身に着けていきたいですね。


もしこの記事が役に立ったのであれば、はてぶ、Twitterでの記事の拡散、Twitterのフォローもよろしくお願いします。私の励みになります。

類似記事

nainaistar.hatenablog.com

【資格】Python3エンジニア認定基礎試験の合格記

「Python3エンジニア認定基礎試験」に合格してきましたー!

合格したのでブログにします。

合格日

2020年10月6日(火)

合格した時の点数

f:id:nainaistar:20201007224602p:plain
合格点数

850/1000でした。
合格は70%の700点なので、点数としては余裕でした。

答えが分からなかった問題が2割くらいあったので、落ちるのも覚悟していました。

どんな試験か

文法基礎を問う試験です。

「最近社内でPythonフレームワークを使うシステムが出てきたので、キャッチアップできるように基礎を学びたい」
が、自分のモチベーションだったので、マッチしました。

なので、「最新のPythonを学びたい」という人はマッチしないです。

pipは学べますが、pipenvとかpoetryとかは学べないです。

公式ページ


www.pythonic-exam.com

受験料


受験料金:1万円(税別)学割5千円(税別)

2020年10月13日までなら、勉強のための本もついて受験もできます。

aoten.jp

問題数/出題形式/試験時間


だいたい20分もあれば解けます。
4問中1問をチェックボックスで選択するので、深く考えることもありません。

強いて困ったことと言えば、ホワイトボードもメモもないので、indexを扱う問題が脳内でうまく処理できなかったくらいですかね。

出題範囲


オライリー・ジャパンPythonチュートリアル 第3版」から出ます。

ただ、わざわざ本を読まなくてもPythonチュートリアルが同じものなので、そちらを読んだ方がいいと思います。

docs.Python.org

難易度


普段Python触らないので苦労しましたが、普段から触っている人であれば簡単だと思います。

Javaエンジニアとしての経験があったので、覚えること自体はそこまで難しくありませんでした。

合格に向けた勉強時間と対策

勉強時間:15時間。


主にチュートリアルを写経していました。
写経が一番理解を深める方法だと考えてます。

普通に読んでると読み飛ばしちゃうけど、写経していると手を動かしているから必然的にスピードが落ちますからね。
https://github.com/hirotoKirimaru/Syakyo/tree/master/Python/tutorial

模擬試験


下記模擬試験はだいたい5時間ほど、みっちり使わせていただきました。
最初はチュートリアルを使わずにいきなり模擬試験を行いましたが、やっぱり自殺行為でしたね。
何も分からなかったです。

DIVE INTO EXAM様 exam.diveintocode.jp

PRIME STUDY様 study.prime-strategy.co.jp


あと、なぜかPRIME STUDY様の第1回 Python 3 基礎 模擬試験を受験するの回答後ページで採点されなかったです。
結果が通知されるメールも最初は迷惑メールの方に入っていたので、気づきませんでした。

このサイトでは、メールアドレスの正当性を気にせず使用できてしまいます。
他者に対してメールを送り続けられる点で迷惑メール扱いになってそうですね。

終わりに

基礎を学ぶ機会になったので、受けて良かったと考えてます。
タプルとか、キーワード引数とか、Javaエンジニアとしては触る機会が無いので。

ただ、言語系の試験の宿命ですが、メソッドを暗記するのは嫌いですね。
一々覚えるくらいなら、テストして挙動を確認すれば一発ですから。
特に境界値がtrueかfalseか、メイン言語でさえ覚えてないので多言語なんて猶更。

あと、インタプリタは使う機会が無いと考えているので、インタプリタスクリプトの挙動の違いを覚えるのは嫌でしたね。
サクッと新機能を触りたい時は便利ですが、普段の開発で私はjshell使ったことが無いので、悶々しながら覚えてました。

これが正答率6割くらいなら、正答精度を上げずに済むのですが…。
まぁ、その辺は認定できる最低ラインとしては、7割は仕方ないですね。


合格して、Pythonの基礎は持っていることの証明はできたので、Remote Container等でサクっとスクリプト作る等はやっていきたいです。
何を作るかは決めていませんが、投資に役立つようなツールを作りたいとふんわり考えています。


この記事がお役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。