Gitとは、一言でいうとソースコードなどの分散型バージョン管理システムです。 もともとはLinuxカーネルのソースコード管理をするためにLinuxカーネルの開発者でもあるリーナス・トーバルズ氏によって開発され、それ以降ほかの多くのプロジェクトで採用されています。
Gitは分散型のバージョン管理システムと最初に説明したように、作業に常時ネットワークアクセスが必要ない点が他のバージョン管理システムと異なるところです。普段はローカルリポジトリー上で開発して、定期的にリモートリポジトリーと同期して開発を進めていく...そんな使い方をします。すでに開発中のソフトウェアに対して開発する場合は、もとのリポジトリーをクローンして開発を行ってソースコード元にコントリビュートするためにプルリクエストを投げたり、コミット権があるリポジトリーであればソースコードをマージします。 ソースコードはすべて履歴管理されるため、複数人でのソースコード開発がしやすくなります。
一人でGitを使ってソースコード管理する場合は必須ではありませんが、Gitで複数人でソースコード管理するには何らかのGitサーバーが必要です。もっとも一人で開発していたとしても現在は何らかのGitサーバーを介してソースコード管理していると思います。
最も多くの人に知られているGitサーバーはGitHubかもしれません。GitHubはアカウントさえ作れば無料でも結構便利に使えるので、聞いたことがあるとか触ったことがあるという人は多いと思います。同じように無料から使えるSaaSのGitサーバーだと、GitLab SaaS版(gitlab.com)やBitBucketなどもあります。
Gitを勉強するだけであればGitのSaaSサービスのいずれかを使えばある程度できるのですが、一方でちょっと高度なことを試したいとか、インターネット上には置きたくないようなソースコードを管理したいときとか、なにか起きても誰にも迷惑がかからないようにオンプレミスの環境でGitサーバーを動かしてみたいということもあるかもしれません。これまで筆者はそういうときはオンプレミス版のGitLabを使っていました。
GitLabはソースコード管理以外にも、さまざまな機能を有しています。バージョンアップデートも比較的に頻繁にあります。きちんと管理できれば問題ありませんが、私のように雑にメンテナンスをしていると結構頻繁に環境が壊れたりします(バックアップを取っていればリカバリーできるのですが、...まあそういうことです)。
そこで、GitLab以外のオンプレミスで動くGitサーバーとして代表的なものをいくつか調べてみました。 この中でGiteaは過去に触ったことがありますし、そのフォークであるForgejoも触ったことがあります。 というわけで、今回はまださわったことがないGitbucketを試すことにしました。
ソフトウェア | コメント |
---|---|
GitLab | CI/CDも使えていいけど重量級。メンテが難しい(失敗すると壊れる) |
Gitea | 簡単セットアップ。過去のいざこざの件で将来性が不安 |
Forgejo | Giteaのフォーク。使い勝手は一緒 |
Gitbucket | Java製。簡単そう |
Gitbucketの導入
GitBucketはGitHubで開発されており、そこからダウンロードできます。
サイトによると現時点では実行にJava 8が必要とのことです。 https://github.com/gitbucket/gitbucket
次のように実行するだけで、かんたんに実行できます。この後はLinuxディストリビューションの設定によっては、ファイアウォールの設定で8080ポートを開放する必要があります。クラウドのインスタンスで動かす場合は特別な方法でポート開放が必要だと思います。
sudo dnf install java-1.8.0-openjdk mkdir .gitdir cd .gitdir curl -L "https://github.com/gitbucket/gitbucket/releases/download/4.38.4/gitbucket.war" -o gitbucket-4.38.4.war java -jar gitbucket-4.38.4.war &
GitBucketをVirtualBoxのような仮想マシンで動かす場合は、Javaで動かすので最低4GB以上のメモリーを割り当ててください。vCPUは1もしくは2、ストレージは40GBくらいだといいと思います。
準備ができたら、ブラウザーで初期ユーザーでログインしてみましょう。
- Go to: http://[hostname or IPアドレス]:8080/
- log in with ID: root / Pass: root.
rootユーザーでログインしたら、普段使うアカウントを作成しておきましょう。作成した環境を常用する場合は、rootユーザーのパスワードも変更しておいたほうが良いでしょう。普段使うアカウントはユーザー権限と管理権限のあるユーザーを作成できますが、今回の作業では管理権限のあるユーザーとして作っておいてください。
Gitbucketにリポジトリーを作ってみる
いずれかのアカウントでログインしたら画面の右上の+ボタンをクリックすると、リポジトリーを作成できます。リポジトリー名や公開リポジトリーにするか、プライベートにするかなどを洗濯してリポジトリーを作成します。ここら辺はGitHubなどと一緒です。
この後、ソースコードをプッシュしたりリポジトリーソースをプルしたり...などもGitHubなどと使い勝手は同じです。 唯一違うところは、デフォルト設定のままではGitbucketのリポジトリー側に変更を加えるときに、ユーザー名とパスワードの入力が必要な点でしょうか。
GitbucketのバックエンドDBについて
GitbucketはデフォルトではH2 Databaseを利用しています。 次のようにMySQL 5.7以降やPostgreSQLを、バックエンドDBに設定できるようです。大規模で使うなら要検討かもしれません。 https://github.com/gitbucket/gitbucket/wiki/External-database-configuration
今回はデフォルト設定のままにします。
Let's Try
今回、おためしするために次のようなリポジトリーを用意しました。 https://github.com/ytooyama/first
これを自分のGitHubアカウントでフォークしておいてください (以降、 https://github.com/ytooyama/first.git となっている箇所は、自分のアカウントのクローンしたリポジトリーURLに置き換えて実行してください)。
フォークしたリポジトリーを手元の開発環境にクローンします。
git clone https://github.com/ytooyama/first.git
ソースコードを開発環境でクローンしたら、Python3がインストールされた環境で実行してみてください。 次のように表示されるはずです。
コードは単純に今年の西暦から生まれた年を引いて、今年何歳になるかを表示しているだけのコードです。
% python3 test.py 今年は 2023 年 Aさんは 42 歳
ではソースコードに新しい人を追加してみましょう。追加するのは自分でもこの例のようでも構いません。
from datetime import datetime #今年の年を取得 current_year = datetime.now().year #人を定義 a = current_year - 1981 dora = current_year - 2012 #結果表示 print('今年は', current_year, '年') print('Aさんは', a, '歳') print('ドラえもんは', dora, '歳')
実行してみましょう。
% python3 test3.py 今年は 2023 年 Aさんは 42 歳 ドラえもんは 11 歳
ドラえもんの生まれた年は2012年?
ドラえもんの誕生日はかつては2012年9月3日でした。 一方現在は2023年。私も知らなかったのですが、ドラえもんの誕生日は2012年9月3日からは2112年9月3日に変更されています(100年後に変更)。 100年後の日本や世界がどうなっているかはもはや知る由もないですが、今回のネタでは2012年としています。
GitHubにソースコードをコミット
自分のGitHubリポジトリーに変更をコミットしましょう。 Gitの基本操作についてはここでは詳しく説明しませんが、diffで変更前と変更後の差分を確認して、git addでステージングし、コミットにどういった変更をソースに行ったかメッセージを加えた後、ソースコードをプッシュします。
git diff git add . git commit --signoff -m "add dora" git push -u origin main
--signoffオプションはコミットログメッセージの最後に、コミッターによるサインオフラインを追加するオプションです。サインオフの意味は、通常はコミッターが同じライセンスの下でこのワークを提出する権利を持っており、オリジナル証明書に同意することを証明します (Linux カーネルおよび Git プロジェクトで使用されるものについては、http://developercertificate.org を参照してください。) そのプロジェクトでサインオフがどのように使用されるかを理解するには、貢献しているプロジェクトのドキュメント等を参照してください。
ここまで実行すると、リポジトリーに新しい変更が加わったと思います。
GitBucketにGitHubリポジトリーのミラーを作ってみよう
まずGitBucketにログインして、firstという名前の空のリポジトリーを作っておいてください。
空のリポジトリーが作成されると、次のように表示されますが、そのままにしてください。
ミラークローンの作成
リポジトリのミラークローンを作成します。ミラー元として指定するリポジトリーは、自分のアカウントでフォークしたリポジトリーを指定してください。
git clone --mirror https://github.com/ytooyama/first.git cd first.git
コピー先を追加
コピー先に指定するリポジトリーURLは、GitBucketにログインして自分のGitBucketアカウントで作った「first」という、空のリポジトリーです。 現時点では指定したリポジトリーには何もソースコードは含まれていないはずです。
git remote set-url --push origin http://172.16.214.196:8080/git/ytooyama/first.git
設定を確認するには次のように実行します。Fetchにはコピー元のソースURLが、Pushにはコピー先のソースURLが設定されています。
git remote show origin * remote origin Fetch URL: https://github.com/ytooyama/first.git Push URL: http://172.16.214.196:8080/git/ytooyama/first.git HEAD branch: main Remote branch: main tracked Local refs will be mirrored by 'git push'
ミラーしたクローンにはすべてのリモートブランチとタグが含まれますが、フェッチするたびにすべてのローカルの情報が上書きされるため、常に元のリポジトリと同じになります。 プッシュする URL を設定することで、ミラーへのプッシュが簡単になります。
ミラーを更新するには、更新をフェッチしてプッシュします。 これを実行すると、ソース元であるGitHub上のリポジトリーと同期されて、GitBucketのリポジトリーとGitHubのリポジトリーの内容が一緒になります。
git fetch -p origin git push --mirror
git push --mirror
を実行すると、コピー元とコピー先のGitリポジトリーが同期されます。
git push --mirror Enumerating objects: 7, done. Counting objects: 100% (7/7), done. Delta compression using up to 8 threads Compressing objects: 100% (5/5), done. Writing objects: 100% (7/7), 1.07 KiB | 1.07 MiB/s, done. Total 7 (delta 0), reused 7 (delta 0), pack-reused 0 remote: Updating references: 100% (1/1) To http://172.16.214.196:8080/git/ytooyama/first.git * [new branch] main -> main
GitBucketのリポジトリーをみると、GitHubと同期されていることがわかります。 GitHub側のソースを書き換えたあと次のように実行すると、同様に同期されるはずです。
cd first.git git fetch -p origin git push --mirror
これで、万が一GitHubがサービスダウンしていても他のGitサーバー上で開発は継続できる環境ができました。今回はオンプレミスで構築したGitBucketを使っていますが、他のオンプレミス上のGitサーバーでも、他のSaaSのGitサーバーでも同様に対応できます。