こんにちは。テクマトリックスの長久保です。

昨今の開発現場でのデファクトスタンダードになっている「Git」。
【Git入門】はこのGitについて、どういった点でほかのバージョン管理より良いのか、どういった形で利用していくのかなど、Gitについて紹介するシリーズになります。

本シリーズについて

目的

  • Gitがどういったものか理解できる
  • 他のツールと比較してのメリット・デメリットを整理する
  • 実際にGitの簡単な操作ができるようになる

想定するユーザー

このシリーズは以下のユーザーを想定して記載します。

  • Gitに興味はあるけれど、まだ使ったことがない方
  • ソフトウェア開発においてバージョン管理の重要性は理解しているが、どのツールを使うべきか迷っているソフトウェア開発者の方
  • 共有フォルダやSubversionなどのバージョン管理システムを使用しているが、Gitへの移行を検討している方
  • チームでのコラボレーションをより効率的に行いたいと考えている方

構成

本シリーズは全3回で構成されています。

シリーズの第3回目にあたる今回は、GitやGitのホスティングサービスのGitHubを利用すると、具体的にどのように改善されるのかを紹介します。これにより、皆さんがGitを導入するための第一歩を踏み出す手助けとなれば幸いです。
また、参考情報として、SubversionとGitを比較した記事もありますので、併せてご参照ください。

なお、本記事はバージョン管理のGitおよびGitのホスティングサービスであるGitHubの機能も含めて紹介いたします。

共有フォルダやSubversionでの課題

共有フォルダやSubversionでバージョン管理した場合、以下の課題が考えられます。これらの課題をGit(GitHub)を用いることで改善する方法を紹介します。

観点共有フォルダSubversion対応する章
バージョン管理過去の状態を保持する仕組みがなく、誤った変更を行うと、手動での復元が困難です。バージョン管理は可能ですが、柔軟なブランチを作成してのバージョン管理は困難です。
複数人数での開発複数人で同時に作業を行うと、ファイルの競合や上書きが発生しやすく、開発効率が低下します。特定のフォルダは特定の人しか触らないといった運用ルールの徹底が必要になります。Subversionでもブランチ機能を利用した並行開発は可能ですが、Gitと比較するとその操作性や効率性に大きな差があります。Subversionのブランチは「フォルダ」としての概念のため、頻繁なブランチの作成や切り替え、マージといった操作が複雑で、ネットワーク経由での処理が多く、処理速度も遅くなりがちです。
課題管理課題がファイルやメールとして散在し、検索や追跡が困難。担当者や期日も不明確になりがちです。課題管理専用機能がないため、別途ツールを利用したりドキュメント化が必要。連携するための設定も必要になります。
コードの安全性の確保全員が全てのファイルに対する変更権限を持っており、誤った変更が反映されるリスクがあります。コードレビューを行う場合、レビュー対象のコードを共有フォルダから各自がダウンロードし、オフラインでレビューを行う必要があります。レビュー結果はメールや口頭で伝えられるため、レビューの履歴を追跡することは困難な場合が多いです。ブランチの作成やマージは可能ですが、基本的にtrunkに直接コードがコミットされます。そのため、一度もレビューされていないコードがtrunkに混じることになります。
コミット前にコードレビューを行う場合、差分ファイルを手動で抽出し、Subversion以外の方法で共有することになります。レビュー対象の抽出漏れや、レビュー後のマージ漏れが発生するリスクがあります。
また、コードレビューの履歴は、Subversion上で行うことができないため、別に管理する必要があります。共有フォルダ同様レビュー結果とコードの変更箇所との関連性を把握するのが難しいという課題があります。
拡張性運用にあわせた拡張性は特にありません。フックスクリプトなど、運用にあわせた拡張性はありますが少ないです。

Git導入のメリット①:柔軟なバージョン管理による自由な開発

『バージョン管理』の課題と解決方法

開発中に「変更前の状態に戻したい」という状況は頻繁に発生します。共有フォルダでコード管理をした場合、過去の状態を保持する仕組みがなく、誤った変更を行うと、手動での復元が困難です。Subversionの場合、バージョン管理は可能ですが、その仕組み上、柔軟なブランチを作成してのバージョン管理は困難です。

Gitの最大の利点の一つは、バージョン管理システムとしての高度な機能により、過去の状態への復元が容易な点です。
Gitでは、変更履歴を「コミット」として記録するため、過去の任意のコミットに迅速に復帰することが可能です。 また、ブランチ単位での履歴管理も容易であり、Subversionと比較した場合でもより柔軟な過去バージョンの復元が可能です。

バージョン管理については第1回:本シリーズの概要、Gitの基本概念と入門にて説明していますので併せてご確認ください。

Subversionでもバージョン管理は可能ですが、Gitの場合はより柔軟なバージョン管理が可能です。例えば、以下のような開発シーンにおいても、Gitの柔軟性は大きなメリットとなります。

実験的コードでの試行錯誤

新しいアルゴリズムやライブラリ、コンソールに標準出力をして確認する俗に言うSysoutデバッグなどを試す際に、ローカルで自由に実験的なコードを書き、検証をする場合もあるでしょう。
このようなことを共有フォルダで行うのは困難です。バージョンを管理できるSubversionであったとしても、途中のコードをリモートリポジトリにコミットするわけにもいかず、途中の確認履歴の管理をすることができません。また、修正中のコードをローカルのどこかに退避しておき、リバートをして手動マージするといった手間が発生することもあります。
Gitの場合、リモートリポジトリと独立してローカルリポジトリを作成し、ローカルリポジトリ内で履歴管理が可能です。検証に用いたSysout行や検証途中に書いた製品として不要なコードはリモートリポジトリに反映させない運用もできます。

赤枠で囲った必要な部分だけリモートリポジトリに更新することも可能です。これをチェリーピックと呼びます。また、そのコミット履歴も分割してコミットすることも、まとめて1つの履歴としてコミットすることも可能です。こちらをスカッシュと呼びます。様々なマージの方法もあり、柔軟なバージョン管理が実現できます。

Git導入のメリット②:ブランチによる並行開発と高速化

『複数人数での開発』の課題と解決方法

共有フォルダで複数人で同時に作業を行うと、ファイルの競合や上書きが発生しやすく、開発効率が低下します。特定のフォルダは特定の人しか触らないといった運用ルールの徹底が必要になります。Subversionの場合、「ブランチ」を作成することで並行開発は可能ですが、Gitと比較するとその操作性や効率性に大きな差があります。Subversionのブランチは「フォルダ」としての概念のため、頻繁なブランチの作成や切り替え、マージといった操作が複雑になります。また、ネットワーク経由での処理が多く、処理速度も遅くなりがちです。

Gitは、ブランチ機能を活用することで、開発の並行化を実現し、開発速度を大幅に向上させます。

大規模な機能を開発する際、他のコードに影響を与えずに複数の出荷バージョンにまたがって進めたい場合があります。また、不具合修正においても、特定のメンバーのみで共有しながら開発したいケースがあります。

一例として、上記のように新機能開発やバグ修正といった作業を、それぞれ独立したブランチで並行して進めることができます。開発完了後、これらの変更をメインブランチに統合することで、開発効率を向上させることが可能です。共有フォルダやSubversionでもこのような運用はできなくもないですが、Gitの方がより簡単で、柔軟に対応することが可能です。

代表的なワークフロー

Gitにはさまざまな運用スタイルが提案されていますが、よく知られるワークフローとして以下のようなものがあります。

  • Git Flow: リリースを明確に区切りたい大規模プロジェクトで便利。developmaster、リリースブランチなどを使い分ける。
  • GitHub Flow: シンプルにmainブランチと機能ブランチのみで回す方法。リリース頻度が高い・小~中規模開発向け。
  • Trunk-Based Development: 「とにかくブランチを短期間でマージし続ける」方法。CI/CDとの相性が良い。

チームの人数や開発スタイル、リリースポリシーなどに合わせて検討すると、Gitの強みを最大限活かした並行開発が実現できます。

Git導入のメリット③:Issuesによる効率的な課題管理と透明性の確保

『課題管理』の課題と解決方法

共有フォルダの場合でも、Subversionの場合でも、不具合管理や機能追加のタスクは別のシステムで管理する必要があります。結果として、ファイルやメールとして散在してしまったり、システムを跨いでの検索や追跡が困難になったり、メンテナンスのし忘れや、担当者や期日も不明確、といった問題が発生しがちです。

GitHubの場合、Issues(イシュー)を活用することで、課題管理を一元化し、開発プロセスの透明性を大幅に向上させることができます。

バグ報告や新機能の要望など、日々生じるタスクをリポジトリ内のIssuesで管理すれば、担当者、期日、優先度などが可視化され、コミットや後述のプルリクエストと結びつけて追跡できます。

当然GitHubはほかの課題管理ツールと連携することもできますが、外部の課題管理ツールを導入するより簡単にバージョン管理と連携することができます。選択肢の一つとして有効な手段かと思います

実際に運用されているIssuesを見ると、より運用イメージが付きやすいかもしれません。例えばミニブログサービスのMastodonのリポジトリのIssuesはこちらになります。

https://github.com/mastodon/mastodon/issues

Git導入のメリット④:プルリクエストとProtected Branchによる安全な開発

『コードの安全性の確保』の課題と解決方法

コードの安全性を高めるための施策としてコードレビューがあります。
共有フォルダの場合、全員が全てのファイルに対する変更権限を持っており、誤った変更が反映されるリスクがあります。コードレビューを行う場合、レビュー対象のコードを共有フォルダから各自がダウンロードし、オフラインでレビューを行う必要があります。レビュー漏れということも考えられますし、レビュー結果はメールや口頭で伝えられるため、レビューの履歴を追跡することは困難な場合が多いです。
Subversionの場合、ブランチの作成やマージは可能ですが、基本的にtrunkに直接コードがコミットされます。そのため、一度もレビューされていないコードがtrunkに混じることになります。コミット前にコードレビューを行う場合、共有フォルダと同じような問題が発生します。また、コードレビューの履歴は、共有フォルダ同様レビュー結果とコードの変更箇所との関連性を把握するのが難しいという課題があります。

GitHubやGitLabなどのホスティングサービスを利用すると、プルリクエスト(GitHubではプルリクエスト、GitLabではマージリクエストと呼ばれます)機能によってレビューを実施してからマージするフローを自然に取り入れられます。プルリクエストは、単なるコードのマージ機能ではなく、レビューの履歴を追跡する場としても活用できます。

プルリクエスト

プルリクエストは、ソフトウェア開発においてコードの変更をレビューしてもらうための手段の一つです。例えばmainブランチにマージする際にプルリクエストを必須にする運用にすれば、コードレビュー前のコードがmainブランチに混入することはありません。

どのコードが修正されたのかを一覧で表示することもできますし、具体的に何が変更されたのかをブラウザ上で即座に確認することも可能です。また、コードレビューの指摘点や確認などもプルリクエスト上で管理することができ、後から確認することも可能です。


また、後述のGitHub Actionsという自動化の仕組みと連携すると、より利便性を高めることも可能です。

Protected Branch(保護ブランチ)の活用

GitHubにはProtected Branch機能があり、本番用ブランチやリリース用ブランチへの直接コミットを禁止したり、一定のレビュー数やCI成功を必須とする設定が可能です。これにより、バグ混入のリスクを大幅に低減し、チームとしてコード品質を保ちやすくなります。

Git導入のメリット⑤:開発プロセスに合わせた拡張性

『拡張性』の課題と解決方法

共有フォルダの場合、開発プロセスや運用にあわせた拡張性は特にありません。また、Subversionにおいても、フックスクリプトなど運用にあわせた拡張性はありますが、GitHubと比較すると非常に少ないです。

GitHubは開発プロセスに応じて、カスタマイズしてより良い開発環境を構築することが可能です。ここでは代表的な以下の2つを紹介します。

  • GitHub Marketplace: さまざまな開発ツールや連携サービスを利用可能にし、開発効率を向上させる
  • GitHub Actions: CI/CDパイプラインを自動化し、テスト、デプロイなどを自動化する

これらの機能を利用することで、開発者はより創造的な作業に集中できるようになり、開発チーム全体の生産性向上に繋がります。

GitHub Marketplace

GitHub Marketplaceは、GitHubユーザーが開発プロセスを効率化するためのツールやサービスを簡単に見つけて利用できるプラットフォームです。ここでは、開発者向けのさまざまなツールが提供されており、GitHubとシームレスに統合できるのが特徴です。CI/CDツールであるGitHub ActionsもGitHub Marketplaceに含まれますが、次の章として分割して記載します。
例えば先に挙げたマージリクエスト時に自動でセキュリティ脆弱性のチェックをし、レビュアーはそのチェックの結果を合わせて確認するといったことも可能です。
そのうちの一つである「Secure Code Warrior for GitHub」について、次のブログの「GitHubとの連携」で紹介しておりますので、併せてご確認いただけるとイメージがつかみやすいかと思います。

最近流行の生成AIとの連携をするサービスもあります。
無償から有償まで、様々な種類のアプリケーションがありますので、ご確認ください。

GitHub Actions

GitHub Actionsは、GitHubが提供する自動化ツールで、リポジトリ内で行われる様々なイベントに基づいて自動化ワークフローを作成することができます。簡単に言うと、コードのビルド、テスト、デプロイなどのプロセスを自動化するための機能です。

GitHub Actionsを使うと、以下のような作業を自動化できます

  • CI/CDプロセス: コードがプッシュされたり、プルリクエストが作成された際に、自動でビルドやテストを行い、結果を通知します。
  • デプロイメント: コードが特定のブランチにマージされたときに、自動でサーバーにデプロイすることができます。
  • コード品質チェック: コードスタイルのチェックや静的解析を自動で行い、問題があれば通知します

例えば、次のことを行うGitHub Actionsを作成します。

  • Mavenでビルド
  • SpotBugsを用いてテストを実行
  • 成果物をアーティファクトとしてダウンロード可能な状態にする
  • 単体テストの結果を登録

GitHub Actionsはymlファイルで実行したい内容を記述します。

name: Java CI with Maven and SpotBugs

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'
          cache: maven

      - name: Build, Test and Package
        run: mvn -B clean package

      - name: Publish Test Results
        uses: dorny/test-reporter@v1
        if: always()
        with:
          name: JUnit Tests
          path: target/surefire-reports/*.xml
          reporter: java-junit
          fail-on-error: true

      - name: Run SpotBugs
        run: mvn -B spotbugs:spotbugs

      - name: Upload SpotBugs Results
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: spotbugs-report
          path: target/spotbugsXml.xml

      - name: Upload Build Artifacts
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: build-artifacts
          path: target/*.jar

mainブランチにpush、またはmainブランチにプルリクエストが行われると、自動的にビルドが行われ、成果物やテスト結果をGitHub上から参照、ダウンロードすることができるようになります。

pushやプルリクエストをトリガーとして、自動的にActionsが実行されます。

実行が完了すると成果物としてダウンロードが可能になります。

テストの実行結果のサマリーもGitHub上から参照することが可能です。

注意

GitHub Marketplaceのツールは無料でも使えるものもありますが、有料のものも多くあります。GitHub Actionsについても契約プランやプライベートリポジトリではActionsの利用回数に制限がある場合があります。利用前に公式ドキュメントを参照するとよいかと思います。

開発の流れ(一例:typo修正)

最後に、不具合報告のIssueが作成されてから、修正、プルリクエスト、そしてIssueのクローズまでの一連の流れを、簡単なtypo修正でご紹介します。

1.不具合報告(Issue起票)

評価チームが「Hello World」が「Halloworld」とtypoを発見したので、Issueを作成します。

2.担当者のアサイン

ここで直接担当者をアサインすることもできますし、例えば先述のGitHub Actionsを用いて、Issueの起票をトリガーとしたアサイン依頼の通知をslackに投げる、といったことも可能です。

name: Issue作成時にSlack通知

on:
  issues:
    types: [opened]

jobs:
  notify-slack:
    runs-on: ubuntu-latest
    steps:
      - name: Slackに通知
        if: github.event.issue.labels[0].name == 'bug' # 'bug'ラベルが付いたIssueのみ
        uses: Slack通知用アクション
        with:
          channel: '#general'  # 通知先チャンネル
          message: |  # 通知メッセージ
            新しいバグレポート: ${{ github.event.issue.title }}
            Issue URL: ${{ github.event.issue.html_url }}

3.開発者による修正

修正には、このIssueに対応する不具合修正用のissue-2という名前のブランチを作成し、そこで作業を行うことにします。(2はIssue番号)
修正が完了したら、コミットメッセージにclose #2と関連付けるIssue番号を記入しpushします。

4.プルリクエスト作成

開発者は、修正したコードをGitHubにプッシュし、プルリクエストを作成します。プルリクエストの本文には、修正内容(typoを修正したこと)とIssue番号を記述します。
プルリクエストをトリガーとして先述のGitHub Actionsが実行されます。開発者は意識せずに、今回のプルリクエストのコードを対象としたビルドや自動テスト、自動デプロイが実行されます。

5.レビューとマージ

レビュワーはGitHub Actionsの実行結果が正常に完了しているかといったことや、どういったコードがコミットされたかの確認をUI上で行うことが可能です。修正内容に問題がある場合、プルリクエスト上でコメントのやり取りや、直接コードの編集を行うことも可能です。

レビュアーが確認し問題が無ければプルリクエストを承認し、マージします。

マージ完了後、運用に拠っては不具合修正用のブランチ(issue-2)を削除してもよいでしょう。
また、コミットコメントや、プルリクエストのメッセージにclose #Issue番号とつければ、プルリクエストが承認されたタイミングで、関連付くIssuesが自動的にcloseされます。

Issues側からも、どういった修正が行われたかなど、不具合修正に関わる情報を参照することができます。

あくまで一例ですが、このようにGitHubの機能を利用すると、すべて履歴が管理された状態で、スムーズに集中して開発を行うことが可能になるかと思います。

まとめ

ここまで、Gitを導入するメリットとして以下のポイントを挙げてきました。

柔軟なバージョン管理による自由な開発
過去のコミットへの容易な復帰やローカルでの試行錯誤が可能なため、開発の自由度が大幅に向上します。

ブランチによる並行開発と高速化
ブランチを用いた開発により、複数人・複数機能を同時並行で安全かつ効率的に進められます。

Issuesによる効率的な課題管理と透明性の確保
バグ報告や機能要望をリポジトリ内で一元管理でき、担当者のアサインや進捗可視化をスムーズに行うことが可能です。外部の課題管理ツールを導入するよりも簡単かつ密接にバージョン管理と連携できます。

プルリクエストとProtected Branchによる安全な開発
プルリクエスト(マージリクエスト)機能を活用し、コードレビューや承認フローを確立することで、リリースブランチや本番ブランチの品質を守れます。

開発プロセスに合わせた拡張性
GitHub MarketplaceやGitHub Actionsなどを組み合わせることで、CI/CDやコード品質チェック、外部ツールとの連携を自動化し、チーム全体の生産性を一段と高められます。

さらに、実際の開発フローとして、Issues に起票された不具合を修正し、プルリクエストでレビューを行い、マージすることで自動的に Issue をクローズするといった一連の流れをスムーズに実現できる点も大きな魅力です。たとえ単純なtypo修正であっても、Issueによるチケット駆動・プルリクエストによるレビュー・GitHub Actionsによる自動テストのサイクルを回すことで、品質向上と作業漏れの防止を同時に実現できます。

本記事で紹介した各機能は、特別なツールを追加導入しなくても、Gitとそのホスティングサービス(GitHubやGitLabなど)のみで基本的に完結するものばかりです。バージョン管理システムとしてだけでなく、チームの開発効率化と品質向上のプラットフォームとして、Gitを導入・活用してみてはいかがでしょうか。
本記事が皆様の検討材料の一つとなれば幸いです。

宣伝

Gitの導入支援

Gitはとても強力なバージョン管理ツールですが、Gitの高度な機能を手探りで使うと、コミット履歴が複雑化したり、場合によっては履歴が消失したりする可能性があります。これらの問題を避けるためには、適切な運用方法と開発メンバーへの教育が必要となります。

テクマトリックスでは環境構築からトレーニングまでGitの導入支援が可能です。
お客様のご要望や開発プロセスをヒアリングしたうえで、Gitを用いたソフトウェア構成管理(バージョン管理)の環境構築・移行を行います。また、運用のコンサルティング、トレーニングなども実施しています。
特に、Gitの適切な運用方法や、問題が発生した際の対処法などについての教育は、開発の効率化と安全性向上に大いに寄与します。どのような運用が最適か迷ったり、Gitの使い方についての疑問がある場合は、お気軽にご相談ください。

詳細につきましては、次のボタンより参照ください。

By nagakubo

主にCI環境構築をメインで担当しています。 Certified CloudBees Jenkins Engineer (CCJE)