レンタルサーバー上にGitサーバを作成してバージョン管理する方法

git bare repository

githubなどを利用せずレンタルサーバー上にgitサーバーを作成しファイルのバージョン管理を行う方法です。

目標とする状態

  • ローカルで作成したプロジェクトをサーバーに反映させることができる。
  • プロジェクトをGitでバージョン管理することができる。
  • Githubを使用せずレンタルサーバー上にGitサーバを自分で作成する。
  • ローカルからリモートにプッシュすると本番リポジトリに自動でデプロイされる。

以下のようなイメージになります。

必要なリポジトリ

  • 開発環境用のリポジトリ…①
  • 更新情報管理用のリポジトリ…②
  • 本番環境のリポジトリ…③

①から②にプッシュすると自動的に③は②から更新情報をプルします。このようにしてローカルの開発環境をサーバーの本番環境に反映させることができるようにします。変更履歴はgitでバージョン管理されます。

前提知識:bareリポジトリとnon-bareリポジトリ

Gitリポジトリにはbareリポジトリとnon-bareリポジトリがあります。non-bareリポジトリは作業ディレクトリすなわち管理対象のファイルの実体を持ちます。一方、bareリポジトリは作業ディレクトリを持ちません。.gitディレクトリにGitのデータ(更新情報など)だけを持ちます。そのため、bareリポジトリではファイルの編集をしてコミットといった作業はできません。

一般的にGitでは複数人で共有するリモートリポジトリをbareリポジトリに設定します。以下で示すように、Gitのドキュメントでは共有するリモートリポジトリは一般的にbareにしておくべきだとされています。

リモートリポジトリは、一般的に ベア(bare)リポジトリ となります。これは、作業ディレクトリをもたない Git リポジトリのことです。 このリポジトリは共同作業の中継地点としてのみ用いられるので、ディスク上にスナップショットをチェックアウトする必要はありません。単に Git のデータがあればそれでよいのです。

https://git-scm.com/book/ja/v2/Git%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB

共有用のリポジトリがnon-bareリポジトリだった場合、意図しない変更が行われてしまうことがあるので、作業ディレクトリをもたないbareリポジトリを作成する必要があるようです。

ノンベアリポジトリにブランチのプッシュを行うと変更が上書きされる可能性があるため、中央リポジトリは必ずベアリポジトリとして作成する必要があります。

https://www.atlassian.com/ja/git/tutorials/setting-up-a-repository/git-init

このことを踏まえて各リポジトリは以下のようにbareまたはnon-bareリポジトリとして設定します。

  • 開発環境用のリポジトリ…① → non-bare
  • 更新情報管理用のリポジトリ…② → bare
  • 本番環境用のリポジトリ…③ → non-bare

ちなみにですが、Githubのリポジトリはbareなのかnon-bareなのか意識したことがなかったので調べたところ、Githubのリポジトリはbareリポジトリと考えた方が正しそうです。リポジトリ内のファイルを表示しているようにみえているので、なんとなく作業ディレクトリがあるような気がしてしまったのですが、本質的にはbareリポジトリであるようです。以下のサイトでこのことが問題になっていました。

https://stackoverflow.com/questions/20854879/whats-the-difference-between-github-repository-and-git-bare-repository

Git環境の構築手順

必要な各リポジトリを作成する

※ ローカル、サーバー間のssh接続は設定済みとします。

サーバーに本番環境用のリポジトリを作成します。

cd ~/web/my_project
git init

サーバーに更新情報管理用のリポジトリを作成します。

# --bare をつけてワークツリーのない更新情報のみのリポジトリをつくる
# bareリポジトリの名前は慣習的に .gitを末尾につける
cd ~/git
git clone --bare ~/web/my_project ~/git/my_project.git

gitの設定ファイルを見るとbare=trueとなっています。

[core]
        repositoryformatversion = 0
        filemode = true
        bare = true

開発環境用のリポジトリの作成します。
ローカルの任意のディレクトリにリポジトリをクローンします。

cd develop/
git clone ssh://[アカウント名]@[sshサーバ名]:[ポート番号][my_projectまでのパス]/my_project.git

リモートリポジトリの設定をします。

①のリモートリポジトリが②になっていることを確認する。

# develop/my_projectで実行
git remote -v

③のリモートリポジトリが②になってないのでリモートリポジトリを設定するコマンドを実行

 # git/web/my_projectで実行
git remote add origin ~/git/my_project.git/

git hooksを使用して自動デプロイ設定

ローカルから更新管理用リポジトリにプッシュすると本番リポジトリがプルするように設定する。この自動デプロイ設定はファイル名”post-receive”にシェルスクリプトを書けばできる。

#!/bin/sh

cd ~/web/my_project/
unset GIT_DIR
git pull origin master

ファイルpost-receiveに実行権限をつける

chmod 755 post-receive

ローカルからプッシュすると本番環境に自動デプロイされるかテスト

ローカルで適当にファイルを作ってリモートにプッシュします。

touch index.html
git add .
git commit -m "test commit"
git push origin master

サーバーでコミットが成功していることを確認します。

cd ~/git/my_project.git
git log
cd ~/web/my_project
git log

ブラウザからサーバの公開ディレクトリにアクセスするとローカルで作成したファイルが表示されていることを確認できます。

ここまででgitでバージョン管理しながらローカルで作成したプロジェクトをサーバーの本番環境に自動で反映させる仕組みができました。以下の記事がGit環境の構築の参考になりました。