開発環境の設定

Contents


Eclipse 2025-12 (fc43)

前提条件

  • JDK 17 がインストールされていること

インストール

  1. アーカイブのダウンロード

    https://www.eclipse.org/downloads/packages/ にアクセスして、 「Eclipse IDE for Enterprise Java Developers」から環境に合わせた tar.gz ファイルをダウンロードする。

  2. Eclipseのインストール

    インストール先のディレクトリに移動して以下のコマンドを実行し、ダウンロード したファイルを解凍する。

    $ tar xvfz eclipse-jee-2025-12-R-linux-gtk-x86_64.tar.gz
    参 考

    /opt ディレクトリの下に eclipse を解凍して、ファイルe.jcup.asciidoctoreditor_、ディレクトリの オーナーを「root;root」に変更し、ファイルに読み取り権限を追加、 ディレクトリに実行権限を追加するコマンドは以下のとおり。

    $ sudo tar --owner=0:0 -xvz -f <dir-path>/eclipse-jee-yyyy-MM-R-linux-gtk-x86_64.tar.gz -C /opt
    $ sudo chmod -R a+r /opt/eclipse
    $ sudo chmod a+x `find /opt/eclipse -type d`
  3. JDKのインストール

    Java Defelopment Kit がインストールされていない場合は、以下のコマンドを 実行してインストールする。

    • Java SE 8
      # dnf install java-1.8.0-openjdk-devel
    • Java SE 21
      # dnf install java-21-openjdk-devel

offline installing plugin

Updateサイトからしかインストールできないプラグインをオフラインインストールする ための手順を以下に示す。

  1. dropins ディレクトリの退避

    後で導入したプラグイン(dropinsに存在するプラグイン)に左右されずに動かしたい ならば、eclipseディレクトリの下にある「dropins」ディレクトリの名前を別の ものに変える。

  2. メタデータの取得

    dropins にプラグインを配置する場合は、このステップは実施不要。

    以下のコマンドを実行して、メタデータ(content.jar)を取得する。

    $ eclipse -verbose \
      -application org.eclipse.equinox.p2.metadata.repository.mirrorApplication \
      -source <Update Site URL> \
      -destination <ダウンロード先ディレクトリ>

    コマンドに指定するパラメータは以下の通り。

    • <Update Site URL> - プラグインのUpdate SiteのURLを指定する
    • <ダウンロード先ディレクトリ> - ダウロードしたファイルを保存する ディレクトリを指定する。「<プラグインの名前>_<バージョン>/eclipse」と 指定するのが良い。ディレクトリが存在しない場合は自動的に作成される。

      上記のコマンドを実行すると、<ダウンロード先ディレクトリ>の下に 「content.jar」ファイルがダウンロードされる。

  3. Artifacts(features/plugins)の取得

    メタデータの取得で指定した「-application」の「metadata」となっている部分を 「artifact」に変えて、コマンドを実行する。

    $ eclipse -verbose \
      -application org.eclipse.equinox.p2.artifact.repository.mirrorApplication \
      -source <Update Site URL> \
      -destination <ダウンロード先ディレクトリ>

    このコマンドを実行すると、<ダウンロード先ディレクトリ>に以下のファイル、 ディレクトリがダウンロードされる。

    • artifacts.jar
    • features
    • plugins
  4. dropinsディレクトリの名前を変えた場合は、元に戻す。
  5. プラグインのインストール
    • dropins ディレクトリに配置する場合

      「Artifacts(features/plugins)の取得」でダウンロードしたファイルを、 <ダウンロード先ディレクトリ>ごと dropins ディレクトリに配置する。

    • eclipseからインストールする場合

      EclipseのUpdate SiteのURLに<ダウンローサ機ディレクトリ>のパスを指定 する。

参 考

Eclipse Plugins 2025-12 (fc43)

注 意

以下の記述で「x.x.x」はバージョン番号、「yyyyMMddhhmm」は年月日時分の数値を 表す。

aCute

Eclipse aCute - C# and .NET Core development tools in Eclipse IDE

備 考

eclipse 2023-06 ではプラグインが認識されない状態

  1. サイトアーカイブのダウンロード

    offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://download.eclipse.org/acute/snapshots/ を指定して、プラグインのArtifactsをダウンロードする。

  2. プラグインの配置

    ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。

  3. dotnet パッケージのインストール

    以下のコマンドを実行して、dotnet パッケージをインストールする。

    $ sudo dnf install dotnet

Amateras Modeler

AmaterasERD(ERモデル)、AmaterasUML(UML クラス図、シーケンス図、 アクティビティ図)のエディタのプラグイン

注 意
  • AmaterasERD
    • インストールしてから暫く時間を置かないと、ダイアグラムが保存えきない ときがある。
  1. 依存パッケージについて

    GEF-3.x が必要であるが、Eclipse Java EE Platform にインストール済みのため、 依存パッケージを新たにインストールする必要はない。

  2. サイトアーカイブのダウンロード

    offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://takezoe.github.io/amateras-update-site/ を指定して、プラグインのArtifactsをダウンロードする。

  3. プラグインの配置

    ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。

  4. 不要ファイルの削除

    features、plugins ディレクトリの下に複数のバージョンのjarファイル が存在するので、ファイル名が下記のパターンに一致するものだけを残し、 それ以外のファイルを削除する。なお、${VERSION} は、プラグインのバージョン を表す。

    • *_${VERSION}.*
    • jp.sf.amateras.htmleditor_*

Asciidoctor Editor - AsciiDoc & PlantUML plugin

AsciiDoc、PlantUML の編集やプレビューを行うプラグイン

プラグインのインストール
  1. 最新バージョンの確認

    ソースコードのサイト https://github.com/de-jcup/eclipse-asciidoctor-editor にアクセスして、バージョンを確認する。

  2. サイトアーカイブのダウンロード

    offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://de-jcup.github.io/update-site-eclipse-asciidoctor-editor/update-site/ を指定して、プラグインのArtifactsをダウンロードする。

  3. プラグインの配置

    ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。

asciidocの記述
= 文書の表題
:sectnums:

== 章のタイトル
=== 節のタイトル
本文 +
行末に + (スペースの後ろに + )をつけるとそこで改行される。 +
文章の表題の次の行に「:sectnums:」を書くと、章は番号付きで表示される。

1行空けると段落になる。

コメントは行頭に「//」を書く
// この行はコメントです

=== 箇条書きとチェックリスト
. 番号付き箇条書き +
  箇条書きの後ろに「 +」を書くとそこで改行され、続きはインデント付きで表示
  される。
.. 番号付き箇条書き(レベル2) +
  箇条書きを終えるには、空行に続けてコメント行を書く

// 箇条書きを終えるためのコメント行
* 番号なしの箇条書き +
  番号付き箇条書きと同様、箇条書きの後ろに「 +」を書くとそこで改行される
** 番号なしの箇条書き(レベル2)

// チェックリスト
.チェックリストのタイトル
- [ ] チェックリスト(チェックなし)
- [*] チェックリスト(チェックあり) 
- [x] チェックリスト(チェックあり)

=== 表
.表のタイトル
|===
| ヘッダ1 | ヘッダ2
| 1行目の項目1 | 1行目の項目2
| 2行目の項目1 | 2行目の項目2 +
「 +」の後に改行するとそこで改行して表示する
|===

=== 文字の修飾
. 文字の強調 +
  行頭またはスペースを空けて* で囲むと *その部分が強調表示される。*
  「*」と囲んだ文字の前後にスペースを入れないこと
. {plus}の表示 +
  \{plus} と書くと{plus}を表示する
. マーカー表示 +
  行頭またはスペースを空けて # で囲むと #その部分はマーカー表示される。#
  「#」と囲んだ文字の前後にスペースを入れないこと
. 下線表示 +
  行頭またはスペースを空けて \[.underline]に続けて # で囲んだ文字を書くと、
  [.underline]#その部分が下線表示される。#
  「#」で囲んだ文字の前後にスペースを入れないこと

[asciidoc.adoc]

参考文献
PlantUMLの各種ダイアグラムの記述

PlantUMLは、GUIで作図するのではなく、テキストファイルにダイアグラムの情報を 記述する。ファイルの拡張子は「.pu」とする。以下、各種ダイアグラムの記述方法を 示す。

  • ダイアグラムのイメージの保存
    1. プラグインのエディタ画面の上部にある「Asciidoctor preview in external browser」アイコンをクリックする
    2. WebブラウザーにSVG形式でダイアグラムのイメージが表示されるので、 Webブラウザーのファイルメニューからそのイメージを保存する
  • クラス図の描き方
    @startuml
    title クラス図の描き方
    ' インターフェースの定義
    Interface Map<K,V> {
      + V get(Object key)
      + V put(K key,V value)
    }
    ' クラスの定義
    Class MyClass {
      ' private フィールド
      - Map<String,List> map
      ' private メソッド
      - List getList(String key)
      ' protected メソッド
      # Map getMap(String key)
      ' public メソッド
      + void doSumething(String key)
    }
    Class HashMap<K,V> {
      + V get(Object key)
      + V put(K key,V value)
    }
    Class LinkedHashMap<K,V> {
      + V get(Object key)
      + V put(K key,V value)
    }
    
    ' 実装関係 (横線)
    ' 「.」または「-」1つで横線
    Map <|. HashMap
    ' 継承関係(縦線)
    ' 「.」または「-」2つで縦線
    HashMap <|-- LinkedHashMap
    ' 依存関係(縦線)
    Map <-- MyClass
    
    Class Car
    Class Engine
    Class Accessory
    ' 構成関係(縦線)
    Car *-- Engine
    ' 集約関係(縦線)
    Car o-- Accessory
    ' 注釈(Engineクラスの下)
    note bottom of Engine
      車はエンジンが存在しないと機能しない
    end note
    ' 注釈(Tireクラスの右)
    note right of Accessory
      車はアクセサリーがなくても機能する
    end note
    @enduml

    [class.pu]

  • シーケンス図の描き方
    @startuml
    title シーケンス図の描き方(JDBCによるデータベースアクセスの例)
    ' シーケンス図に配置するオブジェクトを順に指定する
    actor Actor
    participant MyClass
    participant Connection
    participant Statement
    participant ResultSet
    
    ' ActorからMyClassのgetListメソッドを呼び出す
    Actor -> MyClass: getList()
    ' MyClassの活性化開始
    activate MyClass
      MyClass -> Connection: createStatement()
        Connection -> Statement: create
        activate Statement
      MyClass -> Statement: executeQuery()
        ' MyClasからStatementへの呼び出しの右側に注釈をつける
        ' 注釈の終わりは「end note」を指定する。表示位置はりghtまたはleftを指定する
        note right
          SELECT文を指定してStatementクラスのexecuteQueryメソッドを
          呼び出してデータベースを検索する
        end note
        Statement -> ResultSet: create
        activate ResultSet
      ' 繰り返し処理。繰り返しの終わりは「end」を指定する
      Loop while ResultSet exists
        MyClass -> ResultSet: next()
          note left
            次のレコードを取得する
          end note
        MyClass -> ResultSet: getInt("COLUMN1")
          note right
            レコードのカラム名を指定して、レコードのカラムの値を取得する
          end note
        ' 条件分岐。分岐処理の終わりは「end」を指定する
        alt COLUMN1の値 > 0
          ' 再帰呼び出しは呼出元/呼出先を同じオブジェクトにする
          MyClass -> MyClass: doSumething()
          activate MyClass
          deactivate MyClass
        ' 条件分岐(別の条件)
        else COLUMN1の値 = 0
          MyClass -> MyClass: doAnotherThing()
          activate MyClass
          deactivate MyClass
        ' 条件分岐(それ以外の場合)
        else それ以外の場合
          MyClass -> MyClass: break
        end
      end
      MyClass -> Statement: close()
        Statement -> ResultSet: close()
        deactivate ResultSet
      deactivate Statement
    ' MyClassのgetListメソッドの戻り
    Actor <-- MyClass
    ' MyClassの活性化終了
    deactivate MyClass
    @enduml

    [sequence.pu]

参考文献

Babel Language Packs

Eclipseの表示をローカライズするプラグイン

  1. アーカイブのダウンロード

    https://download.eclipse.org/technology/babel/babel_language_packs/latest/index.php#ja にアクセスして、「Language: Japanese」に列挙されているZIPファイル全てを ダウンロードする。

  2. ZIPファイルの解凍

    以下のディレクトリーの下でダウンロードした zip ファイルを解凍する。

    dropins/BabelLanguagePack-ja_x.xx.x.v<年月日時分>
  3. 不要ファイルの削除

    解凍したファイルの eclipse/features、eclipse/plugins ディレクトリの下にある 「*.sdk.*」ファイルを削除する。

Checkstyle

Javaのソースコードをチェックするプラグイン

  1. 最新バージョンの確認

    以下のコマンドを実行し、表示されるURLから最新バージョンを確認する。

    $ eclipse -nosplash -application org.eclipse.equinox.p2.metadata.repository.mirrorApplication \
      -source https://checkstyle.org/eclipse-cs-update-site/ -destination . \
      | grep content.xml.xz | sort

    下記の例では、「/releases/」と「/content.xml.xz」の間にある文字列 「12.0.1.202511131535」がバージョンである。

    [Worker-1: https://checkstyle.org/eclipse-cs-update-site/releases/12.0.1.202511131535/content.xml.xz] DEBUG ...
  2. サイトアーカイブのダウンロード

    offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://checkstyle.org/eclipse-cs-update-site/releases/バージョン を指定して、プラグインのArtifactsをダウンロードする。

  3. プラグインの配置

    ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。

  4. 不要ファイルの削除
    • features、plugins ディレクトリー配下の「org.eclipse.*」「*.doc_*」 「*.source_*」ファイルを削除する。
  5. チェック定義の変更
    1. 「ウィンドウ」「設定」メニューを開き、「CheckStyle」を選択して、 「Checkstyle」画面を開き、「Global Check Configurations」から 「Sun Checks」を選択して、Copyボタンを押す。
    2. Check Configuration Properties 画面が開くので、Typeは「Internal Configuration」のまま、Nameに「Modified Sun Checks」を設定して「OK」 ボタンを押す。
    3. Checkstyle画面に戻るので、上記で作成した「Modified Sun Checks」を 選択して、「Configure」ボタンを押し、以下の変更をする。
      • Javadoc Comments / Style Javadoc ⇒ endOfSentenceFormatの定義で「.」の 後ろに「。」を追加する
      • Javadoc Comments / Package Javadoc ⇒ 「allowLegacy」にチェックを付ける
      • Size Violations / Maximun Line Length ⇒ 「max」を80から120に変更する
      • Class Design / Final Class ⇒ チェックを外す
      • Miscellaneous / Final Parameters ⇒ チェックを外す

      修正が終わったら、「OK」ボタンを押して設定変更画面を閉じ、Checkstyle画面に 戻る。

    4. Checkstyle画面で「Export」ボタンを押して、エクスポート先に <プロジェクトディレクトリ>/config/ModifiedSunChecks.xml を指定して設定を エクスポートする。
    5. Checkstyle画面で「Modified Sun Checks」を選択して「Remove」ボタンを 押して削除した後に、Newボタンを押して、以下の設定をした後に「OK」ボタンを 押す。
      • Type : 「Project Relative Configuration」
      • Name : Modified Sun Checks
      • Location : /<プロジェクト名>/config/ModifiedSunChecks.xml
    6. プロジェクトのプロパティ画面を開き、Checkstyleを選択してCheckstyle 画面にて、ドロップダウンリストから「Modified Sun Checks」を選択する。

Eclipse CDT - Eclipse C/C++ Development Tooling

  1. アーカイブのダウンロード

    https://www.eclipse.org/cdt/downloads.php より、cdt-x.x.x.zip を ダウンロードする。

  2. zip ファイルの解凍
    1. 以下のディレクトリーの下でダウンロードした zip ファイルを解凍する。
      dropins/cdt-x.x.x/eclipse
    2. 不要ファイルの削除
      • 解凍先のディレクトリーの下で features、plugins ディレクトリーを除く ファイル、ディレクトリーを削除する。
      • features、plugins ディレクトリー配下の「*.sdk_*」、「*.source_*」、 「*.gz」 ファイルを削除する。
  3. ToolChainの設定
    1. Eclipseのメニューから「Windows」「設定」を選択して「設定」画面を開き 「C/C++」「Core Build ToolChains」を選択する
    2. 「User Defined Toolchains」の「追加...」ボタンをクリックして 「TNew toolchain」画面を開き、「GCC」を選択して「次へ」ボタンをクリック する
    3. 「GCC Toolchain Setting」画面で「Compiler」に「/usr/bin/gcc」を指定 して、「修了」ボタンをクリックする。
    4. 「設定」で、「適用して閉じる」ボタンをクリックする。

Eclipse Color Theme (with MoonRise UI Theme)

  1. Eclipse Color Theme の site アーカイブダウンロード
    1. サイトアーカイブのダウンロード

      offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに http://eclipse-color-theme.github.io/update を指定して、プラグインのArtifactsをダウンロードする。

    2. プラグインの配置

      ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。

  2. MoonRise UI Theme のアーカイブのダウンロード
    1. プラグインの jar ファイルのダウンロード

      GitHub - guari/eclipse-ui-theme: Dark UI Theme for Eclipse 4+ より com.github.eclipseuitheme.moonrise_x.x.x.jar をダウンロードする。

    2. jarファイルの配置

      以下のディレクトリーの下にダウンロードした jar ファイルを配置する。

      dropins/<Eclipse Color Themeのパッケージ名>/eclipse/plugins

Eclipse DLTK (used by Eclipse PDT)

  1. サイトアーカイブのダウンロード

    offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://download.eclipse.org/technology/dltk/updates-nightly/を指定 して、プラグインのArtifactsをダウンロードする。

  2. プラグインの配置

    ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。なお、配置する ファイルは、ファイル名が以下のパターンに一致するものに限る。

    • org.eclipse.dltk.*
  3. 不要ファイルの削除

    features、plugins ディレクトリー配下の「*.sdk_*」、「*.source_*」、 「*.tests_*」ファイルを削除する。

Eclipse PHP Development Tools

  1. PHP Development Tools の site アーカイブダウンロード
    1. サイトアーカイブのダウンロード

      offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://download.eclipse.org/tools/pdt/updates/ を指定して、プラグインのArtifactsをダウンロードする。

    2. プラグインの配置

      ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。

    3. 不要ファイルの削除

      features、plugins ディレクトリー配下の「*.sdk_*」、「*.source_*」、 「*.gz」ファイルを削除する。

  2. Eclipse Dynamic Languages Toolkit の site アーカイブダウンロード

    Eclipse DLTKの手順に従って、Eclipse Dynamic Languages Toolkit の site アーカイブをダウンロードする。

  3. PHPとXdebug のインストールと設定
    • パッケージのインストール

      php、php-pecl-xdebug パッケージをインストールする。

      補 足

      Windowsの場合は、Xdebug を以下のようにインストールする。

      1. https://xdebug.org/wizard にアクセスし、コマンド「php -i」の 実行結果を貼りつけて、「Analyze my phpinf() output」ボタンを押す
      2. 画面に表示された手順に従ってインストールする
      3. 手順が表示されない場合は、https://xdebug.org/downloadに アクセスしてバイナリモジュール (例:php_xdebug-2.9.6-7.1-vc14-x86_64.dll)を取得する
      4. php.ini またはそこから読み込まれる設定ファイルに以下の行を追加 する
        zend_extension = <xdebugのDLLのパス>
    • Xdebugの設定

      php.ini またはそこから読み込まれる設定ファイルに以下の設定をする。

      xdebug.remote_enable = true
      xdebug.remote_connect_back = true
      xdebug.remote_port = 9000
      • xdebug.remote_enable = true

        Xdebug のクライアント(Eclipse)からのリモート・デバッグを可能にして、 PHPの Web アプリケーションのデバッグができるようにする。

      • xdebug.remote_connect_back = true

        サーバーが Xdebug のクライアント(Eclipse)に接続するためのIPアドレス は、HTTPのリクエストから取得するようにして、Xdebugのクライアントの IPアドレスを固定しないようにする。

      • xdebug.remote_port = 9000

        サーバーが Xdebug のクライアント(Eclipse)に接続ためのポート番号を 設定る。既定値は 9000 なので規定値を使用する場合は設定を省略できる。

  4. リモート・デバッグの設定

    Webアプリケーション・サーバーで実行されている PHP のアプリケーションを デバッグできるようにするため、PHP Development Tools Plugin の設定をする。 以下は、Fedora の設定である。他の環境の場合は適切に読み替えること。

    • Servers の設定

      PHP の Webアプリケーションが動作している Server の情報を登録する。

      1. 「ウィンドウ」⇒「設定」メニューを選択して、「設定」画面を開く
      2. 「設定」画面のフィルタから「PHP」⇒「Servers」を選択する
      3. デフォルトで「http://localhost」のサーバーが「Default PHP Web Server」の名前で作成されている。これ以外のサーバーを使用する場合は、 「New」ボタンを押して、新しい定義を作成する
      4. Serverの設定画面で、以下の設定をする。新規作成の場合は「次へ」 ボタンを押して Debugger の設定画面を表示する。
        • Server Name:

          Server の一覧表示で表示される名前を設定する。

        • Base URL:

          サーバー名、ポート暗号までの URL を設定する。
          例:http://localhost:8080

        • Document Root:

          空白のままで良い

      5. Debuggerの設定画面で、以下の設定をする。新規作成の場合は、「次へ」 ボタンを押して Path Mapping の設定画面を表示する。
        • Debugger:

          ドロップダウンから「Xdebug」を選択する。

        • Port:

          Server が Xdebug のクライアント(Eclipse)に接続するポート番号を 設定する。Xdebug の既定値 9000 以外のポート番号を使用する場合は、 Application Server の Xdebug の設定値と同じポート番号を設定すること。

        • 上記以外の項目

          既定値(空白)のままで良い。

      6. Path Mappingの設定画面は、何も設定しないで「終了」ボタンを押す
    • PHP Web Server のデバッグの構成

      PHP Web Server は、既に起動している Web Application Server (Apache httpd、 PHP Built-in Server など)に接続して、PHP のWebアプリケーションをデバッグ することが可能である。デバッグの構成手順は以下のとおり。

      1. 「実行」⇒「デバッグの構成」メニューを選択して、 「構成の作成、管理、および実行」画面を開く
      2. フィルタから「PHP Web Application」を選択して、「新規の起動構成」 アイコンをクリックする
      3. 「名前:」に適切な名前を入力する
      4. 「Server」タブで以下の項目を設定する
        • PHP Server:

          ドロップダウンから接続先のサーバー(「Servers の設定」で作成したもの) を選択する。

        • File:

          「Browse」ボタンを押して、ポップアップしたダイアログから最初にアクセス するURLに対応するコンテンツをPHPプロジェクトのファイルの中から選択 する。

        • URL:

          「File:」で設定したPHPプロジェクトのファイルに対応した Web アプリケーション・サーバの URL が自動表示される。この URL とは別の URL を設定する場合は、「Auto Generate」のチェックを外して、 サーバー名、ポート番号より後ろの URI を設定すること。

      5. 「Debugger」タブで以下の項目を設定する
        • Break at First Line:

          このチェックが付いていると、PHPのファイルにアクセスするたびに、 1行目で停止する。ブレークポイントの設定位置まで停止させたくない 場合は、このチェックを外すこと。

        • その他の項目

          既定値(空白)のままで良い。

      6. 「適用」ボタンを押した後、「閉じる」ボタンを押して設定画面を 閉じる
  5. ローカル・デバッグの設定

    PHPファイルを直接実行してデバッグしたり、PHP Built-in Server を実行したり するための PHP Development Tools Plugin の設定をする。

    • Installed PHPs の設定

      Eclipseのメニューから「ウィンドウ」⇒「設定」を選択して、「設定」画面を 開き、以下の設定をする。

      1. 「PHP」⇒「Installed PHPs」
        1. 「Add..」ボタンを押す
        2. 「New PHP Executable」画面で以下の設定をする
          • Executable path:

            php実行ファイルのパス(/usr/bin/php)を設定する

          • PHP ini file (optional):

            /etc/php.ini を設定する

          • Use system default php.ini configuration:

            /etc/php.ini を使用する場合はチェックを付ける。Xdebug を使用する 場合はチェックをつけること

          • 「次へ」ボタンを押す
        3. 「Debugger Settings」画面で以下の設定をする
          • Debugger:

            ドロップダウンリストから「Xdebug」を選択する

          • 「終了」ボタンを押す
      2. 「PHP」⇒「Validation」

        「設定」画面のナビゲーションから「PHP」⇒「Validation」を選択して、 以下の設定をする。

        • PHP Version:

          文法チェックのPHPバージョンを指定する。PHP Built-in Server でサーバで 構成するリソースの選択/解除が出来ない場合は、PHPのバージョンを下げて みる。

    • PHP Built-in Server の作成

      PHP Built-in Server は、PHP CLI (Command Line Interface)で動作する 動作確認用のWebサーバーである。Apache httpd は、コンテンツを /var/www/html ディレクトリ以外の場所に配置すると、SELinux の設定をせずに httpd を起動すると、アクセス権限違反のエラーが発生する。PHPのコンテンツの 場所の制約を受けずに PHP のサーバーアプリケーションを動作確認したい場合に PHP Built-in Server を使用することが可能である。

      注 意

      PHP Built-in Serverは、通常モードでの起動の場合は問題なく起動するが、 デバッグモードで動かすことはできない。そのため、以下の手順で構成した PHP Built-in Server はデバッグには使用できない。PHP Built-in Server を デバッグ用途で使用する場合は、以下のようにphp コマンドで起動する必要が ある。

      $ php -S <listen-addr>:<listern-port> -t <document-root-dir> [<file-path>]

      PHP Built-in Server は以下の手順で作成する。

      1. Eclipse のメニューから「ファイル」⇒「新規」⇒「その他」を選択する
      2. 「ウィザードを選択」で、「Server」⇒「Server」を選択して「次へ」 ボタンを押す
      3. 「Define a New Server」の「Select the server type:」で「PHP」⇒ 「PHP Built-in Server」を選択する。その他の項目は規定値のままで、 「次へ」ボタンを押す
      4. 「PHP Built-in Server」の「PHP executable:」でドロップダウンから 「Installed PHPs の設定」で設定した PHP 実行環境を選択して、「次へ」 ボタンを押す
      5. 「Add and Remove」で、PHP Built-in Server のコンテンツに含める PHPプロジェクトを選択して「終了」ボタンを押す
参考文献

Emonic

Emonic (Eclipse-Mono-Integration) is a Eclipse-Plugin for C#.

2010-01-07 以降更新がない。EclipseでC#のエディタが使える程度と考えた方が良い。

  1. アーカイブのダウンロード

    https://sourceforge.net/projects/emonic/files/latest/download?source=directory をダウンロードする。

  2. zip ファイルの解凍

    以下のディレクトリーの下でダウンロードした zip ファイルを解凍する。

    dropins/emonic_0.4.0/eclipse
  3. 関連パッケージのインストール
    • mono-devel
    • nant

Enhanced Class Decompiler

ソースコードなしのJavaバイトコードからソースコードを表示するプラグイン

  1. アーカイブのダウンロード

    Releases · ecd-plugin/ecd · GitHub にアクセスして、 com.github.ecd-plugin.update-3.x.x.zip をダウンロードする。

  2. zip ファイルの解凍

    以下のディレクトリーの下でダウンロードした zip ファイルを解凍する。

    dropins/enhanced-class-decompiler-3.x.x.yyyyMMddhhmm/eclipse
  3. 解凍先ディレクトリーの下で、features、plugins ディレクトリ配下の 「*.source_*」ファイルを削除する

ER Master

ERモデルエディタのプラグイン

注 意

このEclipse Pluginは、Linux OSでは動作しない。ER Masterを開こうとすると エラーが発生する。

  1. サイトアーカイブのダウンロード

    offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに http://ermaster.sourceforge.net/update-site/ を指定して、プラグインのArtifactsをダウンロードする。

  2. プラグインの配置

    ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。

  3. 不要ファイルの削除

    features、plugins ディレクトリの下に複数のバージョンのjarファイル が存在するので、ファイル名が下記のパターンに一致するものだけを残し、 それ以外のファイルを削除する。なお、${VERSION} は、プラグインのバージョン を表す。

    • *_${VERSION}.*
    参 考

JGit LFS

JGitはgitのJava実装である。JGit LFS は、JGitでGitのLFS(Large File Storage)の 機能を追加するpluginである。

  1. EGit p2 リポジトリのダウンロード

    Where to find older releases より目的の Release Version の download p2 repository よりZIP形式のp2 リポジトリのアーカイブをダウンロードする。Release Version は、Eclipseの pluginディレクトリにある org.eclipse.jgit_x.x.x.yyyyMMddHHmm-r.jar」 ファイルの名前で判断すること。なお、「x.x.x」は Release Version、 yyyyMMddHHmm は、ファイル名に付けられた年月日時分の数値を表す。

  2. p2リポジトリのアーカイブファイル解凍

    以下のディレクトリーの下で、ダウンロードした zip ファイルを解凍する。

    dropins/org.eclipse.jgit.lfs_x.x.x.<年月日時分>-r/eclipse
  3. 不要ファイルの削除
    • 解凍先ディレクトリーの下で、features、plugins ディレクトリーを除く ファイル、ディレクトリーを削除する。
    • features、plugins ディレクトリー配下の以下のファイルを削除する。
      • ファイル名が「org.eclipse.jgit.*」以外のファイル
      • ファイル名が「*.source_*」、「*.gz」であるファイル

Markdown Text Editor

Markdown のテキスト編集とプレビュー機能を提供する Eclipse プラグイン。

  1. サイトアーカイブのダウンロード

    offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://nodeclipse.github.io/updates/markdown/ を指定して、プラグインのArtifactsをダウンロードする。

  2. プラグインの配置

    ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。

備 考

Nodeclipse

Node.js の開発環境を提供する Eclipse プラグイン。 https://nodeclipse.github.io/updates/ の記載内容に従って、Eclipse plugin のインストールと設定を行う。

  1. Nodeclipse のインストール
    1. site アーカイブのダウンロード

      https://sourceforge.net/projects/nodeclipse/files/latest/downloadより org.nodeclipse.site-1.0.2-201509250223.zip をダウンロードする。

    2. 以下のディレクトリーの下でダウンロードした zip ファイルを解凍する。
      dropins/org.nodeclipse.site-1.0.2-201509250223/eclipse
    3. 不要ファイルの削除

      解凍先ディレクトリの下で、下記のディレクトリー、ファイルを削除する。

      • features、plugins ディレクトリーを除くファイル、ディレクトリー
      • features、plugins ディレクトリーのファイルで、名前が下記のパターンに あてはまるもの
        • com.github.eclipsecolortheme*
        • com.github.eclipseuitheme.themes.*
        • winterwell.markdown_*
  2. Node.js のインストール
    1. パッケージのインストール

      以下のコマンドを実行して、Node.js の実行に必要なパッケージをインストール する。

      # dnf install nodejs npm
    2. Node.js パッケージのインストール

      以下のコマンドを実行して、Node.js の開発に必要な Node.js パッケージを インストールする。

      # npm install -g nodeclipse express express-generator

PyDev for Eclipse

Pythonの開発環境を提供するプラグイン

  1. サイトアーカイブのダウンロード

    offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://www.pydev.org/update_sites/13.0.2 を指定して、プラグインのArtifactsをダウンロードする。

  2. プラグインの配置

    ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。

  3. 不要ファイルの削除

    features、plugins ディレクトリー配下の「*.source_*」ファイルを削除する。

  4. PyDev for Eclipse の設定
    1. Eclipseを再起動した後、Eclipseのウィンドウ⇒設定メニューを選択して 「設定」ダイアログを開き、PyDev⇒Interpreters⇒Python Interpreterを選択 する。
    2. Python Interpreters画面で「新規」ボタンをクリックして、 「Select Interpreter」ダイアログを表示し、以下の項目を設定してOKボタンを クリックする。
      • Interpreter Name : Python3
      • Interpreter Executable : /usr/bin/python3
    3. 引き続き「Selection needed」ダイアログが表示されるので、OKボタンを クリックする。

SpotBugs

Javaの潜在的なバグをチェックするプラグイン。 FindBugsの開発が停止したため、その後継としてSpotBugs が誕生した。

  1. サイトアーカイブのダウンロード

    offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://spotbugs.github.io/eclipse/ を指定して、プラグインのArtifactsをダウンロードする。

  2. プラグインの配置

    ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。

StatET

Eclipse Corrosion provides development tools for Rust and Cargo inside the Eclipse IDE.

  1. StatET Update Site アーカイブのダウンロード

    https://projects.eclipse.org/projects/science.statet/downloadsより 「4.x」のリンクをクリックして「StatET 4.x - Downloads」のページを開き、 「Archive of Update Site」のリンクから Update Site の zip ファイルを ダウンロードする。

  2. zip ファイルの解凍
    1. 以下のディレクトリーの下でダウンロードした zip ファイルを解凍する。
      dropins/tatet-x.x.x-<年月日時分>-r/eclipse
    2. 不要ファイルの削除

      解凍先のディレクトリーの下で、features、plugins ディレクトリーを除く ファイル、ディレクトリーを削除する。

StepCounter

様々なプログラミング言語に対応したステップカウンタ

  1. アーカイブのダウンロード

    Releases · takezoe/stepcounter · GitHub より jp.sf.amateras.stepcounter_3.x.x.年月日時分.jar をダウンロードする。

  2. jarファイルの配置

    以下のディレクトリーの下にダウンロードした jar ファイルを配置する。

    dropins/jp.sf.amateras.stepcounter_3.x.x/eclipse/plugins

Subversive SVN Team Provider

SVNクライアントの機能を提供するプラグイン

  1. サイトアーカイブのダウンロード

    offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://download.eclipse.org/technology/subversive/updates/release/ より確認した最新バージョンの URL を指定して、プラグインのArtifactsを ダウンロードする。

  2. プラグインの配置

    ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。

  3. 不要ファイルの削除

    features、plugins ディレクトリー配下の「*.source_*」ファイルを削除する

参考文献

Subversive SVNKit

SubversiveとSVNサーバーを接続するためのプラグイン

  1. サイトアーカイブのダウンロード

    offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに http://eclipse.svnkit.com/1.10.x を指定して、プラグインのArtifactsをダウンロードする。プラグインの バージョンは、 SVNKit :: Download で確認すること。

  2. プラグインの配置

    ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。

Subversive SVN Connector

SubversiveとSVNサーバーを接続するためのプラグイン

  1. サイトアーカイブのダウンロード

    offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://arsysop.github.io/svn/release/ を指定して、プラグインのArtifactsをダウンロードする。

  2. プラグインの配置

    ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。 なお、配置するファイルは、ファイル名が以下のパターンに一致するものに 限る。

    • ru.arsysop.svn.connector*
    • org.antlr.runtime*
    • org.tmatesoft.*

UMLet

UMLet は軽量のUML作図ツールである。

  1. アーカイブのダウンロード

    https://www.umlet.com/download/ から最新バージョンのディレクトリを 選択して、「umlet-eclipse-p2-x.x.x.zip」をダウンロードする。

  2. プラグインの配置
    1. 以下のディレクトリーの下でダウンロードした zip ファイルを解凍する。
      dropins/umlet-eclipse-p2-x.x.x
    2. zip ファイルを解凍したディレクトリに移動し、repository ディレクトリ の名前を「eclipse」に変更する。
  3. 不要ファイルの削除

    解凍先ディレクトリーの下で、features、plugins ディレクトリーを除くファイル、 ディレクトリーを削除する。

注 意

Eclipse-2022-12とUMLet-15.0.0の組み合わせの場合、プロジェクトを選択 → 右クリックメニュー → Update Project の操作でエラーが発生する。

VisualVM Eclipse launcher

  1. VisualVMのインストール

    https://visualvm.github.io/download.html より zip形式のVisualVM x.x をダウンロードして、インストール先ディレクトリの下で解凍する。

  2. Eclipse Launcher Pluginのインストール
    1. アーカイブのダウンロード

      https://visualvm.github.io/download.html より IDE Integrationsを クリックして、「Eclipse」の「plugin」のリンクよりzip形式のアーカイブ (visualvm_launcher_u3_eclipse.zip) をダウンロードする。

    2. dropins ディレクトリへの配置
      • Eclipse/dropins ディレクトリの下で visualvm_launcher_u3_eclipse.zip を解凍する
      • 解凍されたディレクトリ(visualvm_launcher_u3_eclipse)に移動する
      • eclipse ディレクトリを作成し、features、plugins ディレクトリをその 下に移動する
      • eclipse ディレクトリ以外のファイル、ディレクトリを削除する
  3. plugin の設定
    1. ] Eclipseを開き、メニューから「ウィンドウ」「設定」を開く
    2. 「設定」ダイアログのツリーから、「実行/デバッグ」「起動中」 「VisualVM Configuration」を選択し、以下の項目を設定する
      • VisualVM Executable

        VisualVMインストールディレクトリ/bin/visualvm を設定する

      • JDK Home

        JDK (JREではない)のホームディレクトリを設定する。openjdk-devel パッケージがインストーるされている場合は、初期設定されている

  4. 利用手順

    Eclipseの「実行構成の設定」メニューから、Javaアプリケーションの実行構成を 設定する。

    1. Eclipseのプロジェクト・エクスプローラーからメインクラスの右 クリックメニューから、実行>実行の構成を選択する
    2. 「構成の作成、管理、および実行」画面が開くので、 「複数のランチャーが使用可能です」の横にある「1つ選択」をクリックして 「優先ランチャーの選択」画面を開く
    3. 「ワークスペース設定を上書き」にチェックして、ランチャーより 「VisualVM ランチャー」を選択して「OK」をクリックする
    4. 「構成の作成、管理、および実行」画面に戻るので、「適用」ボタンを クリックする。

WindowBuilder (fc41)

  1. サイトアーカイブのダウンロード

    offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://download.eclipse.org/windowbuilder/updates/release/version/ を指定して、プラグインのArtifactsをダウンロードする。 なお、配置するファイルは、ファイル名が以下のパターンに一致するものに限る。

    • org.eclipse.wb.*
    • com.evolvedbinary.thirdparty.*
    • com.jgoodies.*
    • com.miglayout.*
    • com.sun.xml.bind.jaxb-osgi_*
    • io.github.toolfactory.*
    • javax.xml_*
    • net.bytebuddy.byte-buddy_*
    • org.apache.commons.logging_*
    • org.burningwave.* org.mvel2_*
  2. プラグインの配置

    ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。

  3. 不要ファイルの削除
    • 解凍先ディレクトリーの下で、features、plugins ディレクトリーを除く ファイル、ディレクトリーを削除する。 * plugins ディレクトリ配下の「*.doc_*」、「*.source_*」ファイルを削除する。

git (fc37)

About Git

リモート・リポジトリとローカル・リポジトリ

Gitは分散型バージョン管理システムであり、以下のものから構成される。

  • リモート・リポジトリ

    各開発者が変更した内容を最終的にバージョン管理するリポジトリ

  • ローカル・リポジトリ

    開発者が作業するホストごとに存在するリポジトリで、リモート・リポジトリの 複製により作成される。開発者はファイルの変更をローカル・リポジトリで 管理して、作業が終わった段階でその変更内容をリモート・リポジトリに反映 する運用となる。

Gitリポジトリの内部構造

Gitリポジトリ(リモート/ローカル共に)は、ファイルの変更履歴を blob、tree、 commit の3種類のオブジェクトで管理している。

  • blob オブジェクト

    ファイルのスナップショットを保持する。ファイルが変更される都度ファイルの スナップショットを作成してこれをGitリポジトリが blob オブジェクトとして 管理する。

  • ツリーオブジェクト

    ファイルがリポジトリに格納された時点の管理対象すべてのファイル(blob オブジェクト)の参照を保持する。

  • コミットオブジェクト

    コミット情報と ツリーオブジェクトへの参照を保持する。コミット情報の 「parent」には変更前のcommit オブジェクトの ID が保持されている。従って parentをたどることによって変更履歴を取得することができる。

以下の図は、コミット 98ca9 の後に、test.rb ファイルを更新してリポジトリに コミットし、コミット 34ac2 が作成されたときのコミット、ツリー、blob の各 オブジェクトの様子を図示したものである。コミット 98ca9 の変更されていない ファイル README については、コミット前後の tree は、同じ blobを参照して いるが、変更されたファイル test.rb については、コミット前後の tree は別々の blob を参照していることが分かる。

コミット、ツリー、blob のこのような構成により、Git は、「コミット単位で ファイルのスナップショットを保持」することを実現している。

[commit]       98ca9                              34ac2
          +--------------+                   +--------------+
          |  commit size |                   |  commit size |
       +--|----tree 62tej|            +------|----tree 184ca|
       |  |  parent      |<-----------|------|--parent 98ca9|
       |  |  author scot |            |      |  author scot |
       |  |commiter scot |            |      |commiter scot |
       |  +--------------+            |      +--------------+
       |                              |          
[tree] |62tej +------------------+    |184ca +------------------+
       +----->|tree size         |    +----->|tree size         |
              |blob 5b1d3 README |---+       |blob 5b1d3 README-|-+
              |blob li7ce test.rb|-+ |       |blob cba0a test.rb|-|-+
              +------------------+ | |       +------------------+ | |
                                   | |                            | |
[blob]                             | | 5b1d3 +---------+          | |
(README)                           | +------>|blob size|<---------+ |
                                   |         |contents |            |
                                   |         +---------+            |
              +---------+ li7ce    |         +---------+ cba0a      |
(test.rb)     |blob size|<---------+         |blob size|<-----------+
              |contents |                    |contents |
              +---------+                    +---------+

[ファイル更新前後のcommitの様子]

参考文献
ローカル・リポジトリに対するコミット
  • ローカル・リポジトリにおけるファイルの変更状態

    ローカル・リポジトリでファイルが変更された場合、Gitはコミット済、 ステージ済、修正済の3つの状態で管理する。

    • コミット済

      ファイルがリポジトリに格納された状態。変更されたファイルがリポジトリに よってblob オブジェクトと保持・管理されている状態。

    • ステージ済

      前回のコミット後にファイルが変更され、次のコミット対象として印を付け られている状態

    • 修正済

      前回のコミット後にファイルが変更されているが、次のコミット対象として 印が付けられていない状態

    変更されたファイルをリポジトリにコミットする手順は以下のとおり。詳細は Local Repository Operationを参照のこと。

    1. 「git add file ...」を実行して変更したファイルをステージ済にする。
    2. 「git commit -m "変更メッセージ"」を実行して、ステージ済のファイル をローカル・リポジトリにコミットする。
  • ローカル・リポジトリのディレクトリ構成
    • 作業ディレクトリ

      ローカル・リポジトリで管理されているファイル(blob オブジェクト)を展開して 配置するディレクトリ。ファイルの編集作業はこの作業ディレクトリで行う。

    • .git ディレクトリ

      作業ディレクトリの直下に存在するディレクトリで、リポジトリを管理するため のデータ(blob、tree、commitの各オブジェクトとそれ以外のメタデータ)、 及びステージングのデータが配置される。リモート・リポジトリから複製を 行った場合は、その内容が .git ディレクトリに配置される。

参考文献
ブランチ
  1. ブランチとは

    ブランチは、あるコミットへのポインタである。ローカル・リポジトリで 「git branch branch-name」コマンドを実行することにより現在参照している ブランチから新しいブランチを作成することができる。

  2. コミット後のブランチのポインタについて
    • ブランチを指定して(指定しない場合は HEAD ブランチ)ローカル・リポジトリ にコミットすると、コミット後はブランチは新しいブランチを参照する。
    • HEADブランチをコミットした場合は、HEADブランチが参照するブランチも一緒に コミット後の新しいブランチを参照する。
          [before commit]    [after commit]
                HEAD ============> HEAD
                 ↓                 ↓
    [branch]   master ==========> master
                 ↓                 ↓
              +-----+            +-----+
    [commit]  |98ca9| <--------- |34ac2|
              +-----+            +-----+

    [コミット前後のブランチの参照先]

  3. 代表的なブランチ
    • master

      リポジトリを新規に作成した時に存在するブランチ。複数の開発者がいる 場合は、master ブランチを直接更新せず、開発者ごとにブランチを作成して そこで変更を管理するのが一般的である。

    • HEAD

      現在参照しているブランチのポインタ。ブランチを省略してリポジトリへの 操作を行うと、HEADブランチに対する操作となる。

    • FETCH_HEAD

      「git fetch」コマンドによりリモート・リポジトリから取得したブランチを 参照するブランチ。

参考文献
マージ

マージは、あるブランチの変更を現在のブランチ(HEAD)に適用することである。 マージには、3方向マージと fast-foward の2つの種類がある。

  • 3方向マージ

    マージ元のブランチと現在のブランチ(HEAD->master)の共通の祖先のコミット から、マージ元のコミットまでの変更内容を現在のブランチに適用して新しい コミットを作成し、マージ先のブランチをそこに設定する。3方向マージは ローカル・リポジトリで行うことが可能である。

                               (before)       (after)
                                 HEAD          HEAD
                                  ↓            ↓
    [branch]                    master ======> master
                                  ↓            ↓
    [commit] C0 <-- C1 <-- C2 <-+ C5 <--------+ C6
                                |             |
                                + C3 <-- C4 <-+
                                         ↑
    [branch]                           issue01

    [issue01をmasterにマージする3方向マージ]

    上記の図の場合は、issue01 ブランチ(C4)を、masterブランチ(C5)にマージすると 両者のブランチの共通の祖先のコミット(C2)から issue01 ブランチで発生したC3、 C4のコミットのそれぞれの変更内容を順にmasterブランチ(C5)に適用して新しい コミット(C6)を作成し、マージ先のmasterブランチをC6に移動して3方向マージ を行っている。

  • fast-forward

    マージ元と現在のブランチ(HEAD->master)の共通の祖先のコミットから、 マージ元ブランチのみにコミットが作成されている場合は、マージ元のブランチを 現在のブランチにマージすると、その結果はマージ先のブランチのポインタが 現在のブランチに移動するだけになる。そのためこのようなマージは fast-forward と呼ばれる。

                        (before)      (after)
                          HEAD          HEAD
                           ↓            ↓
    [branch]             master =====> master
                           ↓            │
    [commit] C0 <-- C1 <-- C2 <-+        │
                                |        ↓
    [branch]                    + C3 <-- C4
                                         ↑
                                       issue01

    [issue01をmasterにマージするfast-forward]

    fast-forward はローカル・リポジトリでのマージの他に、ローカル・リポジトリの ブランチをリモート・リポジトリのブランチにマージ(つまりプッシュ)する場合 でも使用可能なマージ方法である。

参考文献
マージの運用例

開発者がファイルの更新を行う場合の代表的な手順を以下に示す。

  1. 開発者は、リモート・リポジトリを複製する(クローン)か、 リモート・リポジトリをフェッチ&マージすることで、リモート・リポジトリと ローカル・リポジトリの master ブランチの内容を同期する。
  2. 開発者は、ローカル・リポジトリで master ブランチから開発用ブランチを 作成し、ファイルの変更を開発用ブランチにコミットする。
  3. 開発者は、開発用ブランチをリモート・リポジトリにプッシュして、 リモート・リポジトリにファイルの変更を反映し、リポジトリ管理者に開発用 ブランチを master ブランチにマージするよう依頼する(Pull Request)。 具体的な手順は、Requesting Merge For Remote Repository を参照のこと。
  4. リポジトリ管理者は、リモート・リポジトリの開発用ブランチを master ブランチにマージする。なお、リモート・リポジトリは、fast-forwardしか できないため、以下のように開発ブランチを master ブランチにマージする。
    • gitコマンドを使用する場合
      1. クローンまたはフェッチ&マージを行ってリモート・リポジトリと ローカル・リポジトリの master ブランチ、開発用ブランチを同期する
      2. ローカル・リポジトリで開発用ブランチをmasterブランチにマージする
      3. masterブランチをリモート・リポジトリにプッシュする
    • リポジトリ・サービスの機能を使用して、開発ブランチを master ブランチに マージする

Install Git

以下のコマンドを実行して、gitをインストールする。

# dnf install git

Initialize Git Repository

リポジトリを新規に作成(内容は空の状態)する場合は、 「git init [--bare ] [ディレクトリ]」を実行する。

  • ディレクトリを指定しない場合はカレントディレクトリの下にリポジトリが作成 され、ディレクトリを指定するとそのディレクトリが作成された上でその下に リポジトリが作成される。
  • --bare を指定した場合は、bare リポジトリを作成する。bareリポジトリは 作業ディレクトリを持たないリポジトリで、リモート・リポジトリを作成する 場合は、このオプションを指定する必要がある。
  • --bare を指定しなかった場合は、指定されたディレクトリ(指定しない場合は カレントディレクトリ)の下に .git ディレクトリ(リポジトリ)と作業ツリー (作業ディレクトリの最上位ディレクトリ)が配置される。

Git Repository Structure

  • リモート・リポジトリ

    ローカル・リポジトリの取得元、及び変更内容の適用先となるリポジトリ

    • ローカル・リポジトリは、リモート・リポジトリを指定して「git clone」 コマンドを実行することにより作成される
    • ローカル・リポジトリの変更内容は、「git commit」コマンドで変更内容を ローカル・リポジトリにコミットした後、「git push」コマンドの実行により リモート・リポジトリに反映することができる
      +----------------+  clone     push  +-----------------+
      |local repository| <------+-------> |remote repository|
      +----------------+        |         +-----------------+
                                |
      +----------------+  clone |
      |local repository| <------+
      +----------------+
    備 考

    リモート・リポジトリが「non-bare」(作業ディレクトリで編集できる状態)の 場合は、ローカル・リポジトリで「git push」コマンドを実行するとエラーに なる。この場合はリモート・リポジトリで「git config --bool core.bare true」 を実行して、リモート・リポジトリを bare repository(作業ディレクトリを 持たないリポジトリ)にすればローカル・リポジトリからプッシュ可能となるが、 最初から non-bare リポジトリとして作成した場合とディレクトリの構造が 異なってしまうため推奨できない。

  • ローカル・リポジトリ
      +----------------+                         +-----------------+
      |                | <--(clole)------------- |                 |
      |local repository| <--(fetch & merge)----- |remote repository|
      |                | ------------- (push)--> |                 |
      +----------------+                         +-----------------+

    ローカル・リポジトリは開発者が作業をするリポジトリである。 ローカル・リポジトリの運用例を以下に示す。

    1. リモート・リポジトリのURLを指定して「git clone url」を実行して リモート・リポジトリのクローンをローカル・リポジトリに作成する
    2. 開発者は、「git commit」コマンドによりリポジトリの変更内容を ローカル・リポジトリにコミットする
    3. ローカル・リポジトリの変更内容をリモート・リポジトリに反映する。 反映する手順は、以下のようなものがある。
      • 「git push」により、ローカル・リポジトリの変更内容をクローン元の リモート・リポジトリのブランチにそのまま適用する。しかし、以下の理由に より推奨されない。
        • クローン、または フェッチ&マージ でリモート・リポジトリと同期した 後に、他の誰かがリモート・リポジトリにプッシュしていると、プッシュに 失敗する(fast-forwardのマージができないため)。そのため、プッシュ する前にフェッチ&マージを実行してリモート・リポジトリと同期をして からプッシュするという手間が発生する。
        • 開発者が直接リモート・リポジトリを変更するという行為は、不整合 (マージのミスなどにより他のユーザーの変更内容を破壊するなど)が 発生する危険がある。
      • リポジトリの変更を リモート・リポジトリの管理者に依頼する。依頼内容は、 「git request-pull」コマンドにより取得する。

Remote Repository Operation

  1. リモート・リポジトリのクローン

    ローカル・リポジトリを作成するディレクトリに移動して、 「git clolne remote-repo-url」を実行して、リモート・リポジトリの クローンをローカル・リポジトリに作成する。このコマンドを実行すると、 カレント・ディレクトリの下にリモート・リポジトリの名前(.gitを除く)で 作業ディレクトリが作成され、その下の「.git」ディレクトリに ローカル・リポジトリが作成される。

    リモート・リポジトリをクローンしたら、以下の手順でユーザーの email アドレス、ユーザー名を設定すること。

    • 「git config user.email email-address」を実行して email のアドレスを 設定する
    • 「git config user.name user-name」を実行してユーザー名(First Name、 Last Nameなど)を設定する
  2. リモート・ディレクトリへのプッシュ

    作業ディレクトリで「git push」を実行して、ローカル・リポジトリの変更内容を リモート・リポジトリへ反映する。push コマンドを実行すると、 ローカル・リポジトリのブランチ(指定がない場合はHEADブランチ)を リモート・リポジトリのブランチに fast-forward でマージする。

  3. リモート・リポジトリの変更の取り込み
    1. 「git commit -a -m "<コメント>"」などのコマンドを実行して、取り込み 前の作業ディレクトリ、及び index の変更をローカル・リポジトリにコミット する。
    2. 「git fetch」を実行して、リモート・リポジトリの最新バージョンを FETCH_HEAD ブランチに取り込む。
    3. 「git merge FETCH_HEAD」を実行して、リモート・リポジトリの取り込み 結果(FETCH_HEAD)と現在のブランチ(HEAD)をマージする。同一ファイルに 対してリモート・リポジトリとローカル・リポジトリの両方で編集した場合でも 自動的にマージされるが、競合が解決されない場合(例:同じ行に対して リモート・リポジトリとローカル・リポジトリで異なった内容を編集した場合 など)は、ファイルの競合を解決する必要がある。ファイルの競合解決手順に ついては、Advanced Merging - Gitを参照のこと。

Local Repository Operation

  1. git管理対象ファイルの登録と変更の反映(add / commit)
     +-----------------+                   +-----+               +----------------+
     |working directory| --(add)---------> |index| --(commit)--> |local repository| 
     +-----------------+ --(commit -a)-+-> +-----+          +--> +----------------+
                                       |                    |
                                       +--------------------+

    用語の説明

    • 作業ディレクトリ

      リポジトリのコンテンツが配置されているディレクトリ

    • 追跡対象

      作業ディレクトリに配置されたファイルは、「追跡されている」 「追跡されていない」の2通りの状態がある。「追跡されている」ファイルは 直近のコミットのスナップショットに存在するファイルのことである。

    • index

      ステージされた内容の保管場所。作業ディレクトリのファイルの変更を ローカル・リポジトリにコミットするためには、その前に index に 変更された ファイルを反映する(これをステージするという)必要がある。

    local リポジトリに対する操作

    1. index に対する操作
      • ファイルの追跡開始、変更の反映

        コマンド「git add file [file ...]」を実行して、作業ディレクトリの ファイルを index に追加してローカル・リポジトリにコミットできるように する。git add コマンド実行後に作業ディレクトリのファイルが変更され、 その内容もローカル・リポジトリにコミットしたい場合は、再度「git add」 コマンドを実行する必要がある。

      • ファイル名の変更
        • コマンド「git mv src-file dest-file」を実行して、作業ディレクトリ のファイル名を変更して index に反映する
        • コマンド「git mv file ... dest-dir」を実行して、作業ディレクトリ のファイルを別のディレクトリに移動して index に反映する
      • ファイルの削除

        コマンド「git rm file」を実行して、作業ディレクトリからファイルを 削除して indexからも削除する。コマンド「git rm -r dir」を実行すると、 作業ディレクトリからディレクトリを削除して index からも削除した ディレクトリ配下のファイルを再帰的に削除する。

    2. 変更のコミット

      git commit コマンドを実行して、ステージされたもの(indexの内容)を local repository に反映する。また、「git commit -a」を実行すると、以下のindex に対する操作(ステージ)を実行した後に local repository にコミットする。

      • 追跡対象のファイルが変更されている場合は、そのファイルをステージ (indexへの追加)する
      • 追跡対象またはステージされたファイルが作業ディレクトリから削除 されている場合は index からも削除する
  2. 変更の取消(reset)
     +------------------+        +-----+                       +----------------+
     |working directory |        |index| <---(reset --mixed)-- |local repository| 
     +------------------+ <--+   +-----+ <--+-(reset --hard)-- +----------------+
                             |              |
                             +--------------+
    • ローカル・リポジトリのリセット

      「git reset --soft [commit名]」を実行すると、local repository の「HEAD」 を commit名の位置に設定(commit名でコミットした状態)にする。 comit名 を省略すると「HEAD」を指定したことになる(以下同様)。index、 作業ディレクトリの状態は変更されない。例えば、「git reset --soft HEAD^」 を実行すると、local repository が直前の commit の1つ前の状態になる。

    • index のリセット

      「git reset --mixed [commit名]」を実行すると、local repository を commit名 でコミットされた状態に戻した上で、index の内容をクリアするが 作業ディレクトリの状態は変更はしない。これは、モードを指定しない場合の デフォルトの挙動である。

    • index と作業ディレクトリのリセット

      「git reset --hard [commit名]」を実行すると、local repository を commit名でコミットされた状態に戻した上で、indexをクリアし、 作業ディレクトリの内容を commit名でコミットしたバージョンの スナップショットの状態にする。つまり、作業ディレクトリのcommit名で コミットした以降の変更内容が失われることになる。

    commit名を省略した場合の例
    • git reset

      ステージの取消。index がクリアされるだけで、local repository のコミットの 状態や、作業ディレクトリのファイルの変更は発生しない。

    • git reset --hard

      前回のコミット以降の変更を全て破棄。index がクリアされた上、 作業ディレクトリの内容が前回コミットされたときのリポジトリの スナップショットの内容に置き換わる。

  3. ブランチの切り替え

    コマンド「git checkout branch-name」を実行すると、branch-name で指定した ブランチに切り換える(HEADの参照場所が指定されたブランチになる)。index と 作業ディレクトリも切り替わったブランチの内容に置き換わるが、編集中のもの (作業ディレクトリで変更したがコミットされていないもの)がある場合は、 下記のメッセージが表示され、ブランチの切り替えは中止される。

    error: Your local changes to the following files would be overwritten by checkout:
            <ファイルパス>
    Please commit your changes or stash them before you switch branches.
    Aborting
    注 意

    ブランチのポインタがないコミットにブランチを切り替え(例えばコマンド 「git checkout HEAD^^」で2つ前のコミットに切り換える)、この状態で git commit コマンドを実行すると、そこから分岐したコミットが作成される。 しかし、git checkout コマンドで既存のブランチに切り替わった場合、git の garbage collection プロセスでそのコミットが消えてしまうので注意が必要で ある。コミットを残す場合は、checkout する前に、git branch コマンドで ブランチを作成しておくこと。

  4. ブランチの作成
    • 現在のブランチから分岐するブランチの作成

      コマンド「git branch branch-name」を実行すると、HEAD(現在のコミット) から新しいブランチを作成する。ただし、HEADの位置は変わらない)(つまり コミットしても新しいブランチにコミットされない)。

    • 現在のブランチから分岐するブランチの作成と切り替え

      コマンド「git checkout -b branch-name」を実行すると、HEADから分岐する 新しいブランチを作成した後、そのブランチに切り換える(HEADが新しい ブランチを指すようになる)。

    • リモートブランチを追跡するブランチの作成と切り替え

      コマンド「git checkout -b branch-name remote/remote-branch-name」 を実行すると、短縮名 remote に設定されている remote repository の remote-branch-name ブランチを追跡するローカルブランチを作成して切り 替える。

  5. ブランチの確認
    • ブランチの一覧
      $ git branch
        featureA
        featureB
      * master

      コマンド「git branch」を実行すると、ブランチ名の一覧が表示され、checkout されているブランチの前に「*」が表示される。

    • ブランチの詳細表示
      $git branch -vv
      * master 7d89024 [origin/master] pom.xmlその他を修正

      コマンド「git branch -vv」を実行すると、ブランチ名の他に最新コミットの ハッシュ値、コミットメッセージ、アップストリーム・ブランチ(リモートの ブランチ名)が表示される。

Advanced Merging - Git

同一のファイルをマージ元、マージ先(HEADブランチ)の2つのブランチで編集した 場合(特に同一行をそれぞれのブランチで編集してしまった場合)、自動的な ファイルのマージに失敗して、ファイルの競合が発生する場合がある。その場合の 対処手順について説明する。

マージ実行の準備

マージを実行する前に現在のブランチの変更をコミットして、マージが失敗した 時にマージ実行前の状態に戻せるようにする。

ファイルの競合が発生した場合のマージ結果
  • コマンドのメッセージ

    コマンド実行後に以下のようなメッセージが表示される。

    Auto-merging <ファイルのパス>
    CONFLICT (content): Merge conflict in <ファイルのパス>
    Automatic merge failed; fix conflicts and then commit the result.
  • 競合が発生したファイル

    作業ディレクトリの競合が発生したファイルに、競合が発生した部分について 下記の形式でその内容が記録される。下記の例は topic01 ブランチを現在の ブランチ(HEAD)にマージしようとした場合の例である。

    <<<<<<< HEAD
    現在のブランチ(HEAD)で編集した内容
    =======
    マージ元ブランチで編集した内容
    >>>>>>> topic01
  • リポジトリの状態

    競合が発生しなかったファイルはステージ済となり、競合が発生したファイルは 修正済の状態となる。コミットは行われない。

ファイルの競合が発生した場合の対処方法
  • マージ元、マージ先(HEADブランチ)の両方の変更を取り入れる場合
    1. 競合が発生したファイルの編集

      競合が発生したファイルを開き、競合が発生した部分の記録を見ながら、変更を 取り込む部分を残し、それ以外の部分(「<<<<」「=======」「>>>>」 で始まる部分と、取り込まない変更)を削除する。

    2. 以下のコマンドを実行して、競合が解消したファイルをステージ済にする。
      $ git add <file> ...
    3. すべての競合が解消したら、リポジトリにコミットする。
  • 競合発生部分にマージ元の変更を取り込む場合
    1. 「git reset --hard HEAD」を実行して、HEADブランチをマージ実行前の コミットに戻す。
    2. 以下のコマンドを実行して競合部分にマージ元ブランチの変更を適用して マージを行い、その結果をコミットする。
      $ git merge -Xtheirs <マージ元ブランチ名> 

      バイナリファイルの場合は、ファイル自体がマージ元ブランチのファイルに 置き換えられる。

  • 競合発生部分にマージ先の変更を取り込む場合
    1. 「git reset --hard HEAD」を実行して、マージ実行前の 状態に戻す。
    2. 以下のコマンドを実行して競合発生部分に現在のブランチの変更を適用して マージを行い、その結果をコミットする。
      $ git merge -Xours <マージ先ブランチ名> 

      バイナリファイルの場合は、ファイル自体が現在のブランチのファイルに 置き換えられる。

マージ先ブランチの変更をマージせずに現在のブランチをマージ結果とする場合
  1. ローカル・リポジトリをマージ前の状態に戻す
    • ファイルの競合が発生した場合

      マージ結果のコミットが行われていないので、以下のコマンドを実行してマージ 実行前の状態に戻す。

      $ git reset --hard HEAD
    • ファイルの競合が発生しなかった場合

      マージ結果がコミットされているので、以下のコマンドを実行して直前の コミットを取り消してマージ前の状態に戻す。

      $ git reset --hard HEAD^
  2. 以下のコマンドを実行して、現在のブランチの内容ををマージ結果とした コミットを作成する。
    $ git merge -s ours <マージ元ブランチ>
現在のブランチの変更をマージせずにマージ元ブランチをマージ結果とする場合

これは現在のブランチ(HEAD)の変更をマージ元ブランチとの共通祖先のコミットまで 遡って取り消して、マージ先ブランチを HEAD ブランチに fast-forward するという ことである。従って以下の手順を実行する。

  1. ローカル・リポジトリをマージ前の状態に戻す

    「マージ先ブランチの変更をマージせずに現在のブランチをマージ結果とする場合」 と同様な手順を実行する。

  2. 以下の手順を実行する。
    1. 以下の「git reset」コマンドを実行して、現在のブランチ(HEAD)をマージ元 ブランチとの共通祖先のコミットに戻す。
      $ git reset --hard <共通祖先のコミットID>

      または、以下の「git revert」コマンドを実行して、マージ元ブランチとの 共通祖先のコミットと同じ内容のコミットを新規に作成してHEADブランチが 参照するようにする。

      $ git revert <共通祖先のコミットID>
    2. 以下のコマンドを実行して、マージ元ブランチを現在のブランチにマージ する。
      $ git merge <マージ元ブランチ名>
参考文献

Requesting Merge For Remote Repository

リモート・リポジトリのマージを開発者任せにすると、マージの間違いなどで ファイルの修正の取り込みが失敗する恐れがある。これは開発規模が大きくなるほど 顕在化しやすい。gitの公式ドキュメントでは、 5.2 Git での分散作業 - プロジェクトへの貢献 にローカル・リポジトリとリモート・リポジトリの一連の操作について説明されて おり、その中に「Pull request」により開発者がメンテナ(プロジェクトのソース コードの維持管理責任者)にリモート・リポジトリのマージを依頼する流れが説明 されている。

ここでは、開発者がメンテナに自身の変更内容をリモート・リポジトリに反映する ことを依頼する手順として、パッチファイルを送付する場合と request-pull コマンドで依頼する場合について、具体的な手順を説明する。

  • ファイル修正作業の前提

    以下の説明は、リモート・リポジトリの master ブランチをローカル・リポジトリ の master ブランチにフェッチ・マージした後、開発ブランチを作成してそこで ファイルの修正を行っていることを前提としている。

    以下の一連のコマンドは、master ブランチから開発ブランチを発生させて、 リモート・リポジトリの master ブランチをフェッチして開発ブランチにマージ するまでのものである。

    $ git checkout master
    $ git checkout -b <開発ブランチ名>
    $ git fetch origin master
    $ git merge FETCH_HEAD
パッチファイルを送付してリモート・リポジトリのマージを依頼する
  1. 開発者がメンテナにパッチファイルを送信する
    1. コミットした内容をリモート・リポジトリにプッシュする

      開発者のローカル・リポジトリの現在のブランチ(開発ブランチ)を リモート・リポジトリの開発ブランチにプッシュする。

      $ git push -u origin <開発ブランチ名>
    2. 開発者のローカル・リポジトリで「git-format-path」コマンドを実行して 自身のリポジトリでの変更内容をパッチファイルに出力する。

      以下のコマンドを実行した場合は、リモート・リポジトリの origin/master を現在のブランチ(HEAD->開発ブランチ)にフェッチ&マージした後に、HEAD ブランチで修正した内容をコミット毎にパッチファイルに出力する。

      $ git format-patch -M -o <output-dir> origin/master
      <output-dir>/0001-xxxxx.patch
      <output-dir>/0002-xxxxx.patch
      ...
      • コマンドの説明
        $ git format-patch -M -o <output-dir> origin/master

        -M オプションは、ファイル名の変更を検出するためのオプション、 -o オプションはパッチの出力先ディレクトリを指定するためのオプションで ある。

      • 出力されるパッチファイル
        • パッチファイルは指定されたコミット(上記のコマンドの場合はフェッチ &マージを実行して現在のリポジトリと同期した時点のコミット)から 現在のブランチまでのコミット毎に出力される。
        • パッチのファイル名は「4桁連番-コミット内容.patch」の 形式である。コミット内容は、コミット時に指定したメッセージの 1行目から生成される文字列である。
    3. 出力されたパッチファイルをメンテナにメール等で送信する
  2. メンテナがパッチを適用する

    メンテナのローカル・リポジトリにて、現在のブランチ(HEAD)が master ブランチ を指すようにして、以下のコマンドを実行する。

    (a) $ git pull
    (b) $ git fetch origin <開発ブランチ名>
    (c) $ git am [-3] <patch-dir>/0001-xxxxx.patch <patch-dir>/0002-xxxxx.patch ...
    (d) $ git push
    1. リモート・リポジトリの master ブランチをフェッチ&マージする。
    2. リモート・リポジトリの開発ブランチをフェッチする。
    3. 「git am」コマンドを実行して開発者から送付されたパッチを現在の ブランチ(masterブランチ)に適用する。3方向マージを行う場合は「-3」 オプションを指定する。
    4. パッチを適用した master ブランチをリモート・リポジトリにプッシュする。

    「git am」コマンドでパッチの適用時に競合(conflict)が発生した場合は、以下の 操作をする。

    • 手動でマージする場合
      1. 競合が発生したファイルを編集する
      2. 「git add ファイルのパス」で編集したファイルをステージ済にする
      3. 「git am --resolved」を実行して、次のパッチの処理に移る
    • パッチの適用をスキップする場合

      「git am --skip」を実行して、パッチを適用せずに次のパッチの処理に移る

    • マージを取りやめる場合

      「git am --abort」を実行して、マージを取りやめる

request-pull コマンドを使用してリモート・リポジトリのマージを依頼する
  1. 開発者がプルリクエストを発行する
    1. コミットした内容をリモート・リポジトリにプッシュする

      開発者のローカル・リポジトリの現在のブランチ(開発ブランチ)を リモート・リポジトリの開発ブランチにプッシュする。

      $ git push -u origin <開発ブランチ名>

      -u オプションの指定によって、以降は origin の現在のブランチは 開発ブランチを参照するようになる。

    2. 「git request-pull」コマンドを実行して、コマンドの出力内容を file-pathで指定したファイルに保存する
      $ git request-pull origin/master origin <開発ブランチ名> | tee <file-path>
      • git request-pull コマンド引数の説明
        • origin/master - 開始コミット
        • origin - リモート・リポジトリのURL。短縮形 origin で指定したので、 originの開発ブランチを指すURLとなる。
        • 開発ブランチ名 - 終了コミット
      • git request-pull コマンドの出力について

        「git request-pull」コマンドを実行すると、以下のような内容が標準出力に 出力される。下記の例の「featureA」が開発ブランチ名である。

         The following changes since commit df3adbe04787898f42674860d5aa2300a5f93f45:
        
           <開始コミットメッセージのタイトル> (2020-06-06 21:30:50 +0900)
        
         are available in the Git repository at:
        
           http://user1@fedora-xfce.local/git/example.git featureA
        
         for you to fetch changes up to 1048d81f842eed85a55d90768447906abfd4c49b:
        
           <終了コミットメッセージのタイトル> (2020-06-06 23:19:03 +0900)
        
         ----------------------------------------------------------------
         <ユーザー名> (1):
               <コミットメッセージの本文>
        
          hello.txt  | 2 +-
          hello2.txt | 2 +-
          2 files changed, 2 insertions(+), 2 deletions(-)

        出力内容には以下の情報が含まれている。

        • マージ対象の開始コミットのID
        • マージ対象の終了コミットのID
        • マージ対象ブランチのリモート・リポジトリURL
    3. request-pull コマンドの出力内容を保存したファイルをメンテナに メール等で送付する。
  2. メンテナが開発ブランチの修正をマージする
    1. メール等で届いたプルリクエストの内容を確認する

      「git request-pull」コマンドの出力結果より、リポジトリの変更履歴などを 確認して、変更を master ブランチにマージしてよいかを判断する。

    2. 開発部ランチの変更を master ブランチにマージする

      メンテナのローカル・リポジトリにて、現在のブランチ(HEAD)が master ブランチを指すようにして、以下のコマンドを実行する。

      (a) $ git pull
      (b) $ git fetch origin <開発ブランチ名>
      (c) $ git merge origin/<開発ブランチ名>
      (d) $ git push
      1. originのリモート・リポジトリをプルしてマージ先ブランチ(master)の リモート・リポジトリでのの変更をフェッチ&マージで取り込む
      2. リモート・リポジトリから開発ブランチをフェッチする
      3. マージ元ブランチにリモート・リポジトリの開発ブランチを指定して 現在のブランチ(master)に3方向マージする
      4. 現在のブランチ(master)をリモート・ブランチにプッシュする

Remote Repository Merge Process - Git

「リモート」の管理

「リモート」とは、リモート・リポジトリ の URL の短縮名のことである。

  • リモートの確認

    コマンド「git remote [-v]」を実行すると、設定されているリモートを確認する ことができる。-v オプションを付けない場合は、設定されているリモートの一覧 が表示される。-v オプションを指定すると、リモートとリモート・リポジトリの URLが表示される。

  • リモートの追加

    「git remote add shotname url」を実行すると、リモート(短縮名)と リモート・リポジトリの URL が追加される。

  • リモートの例

    リモート・リポジトリを clone した場合は、リモート(短縮名)origin に リモート・リポジトリの URL が設定される。

ブランチの運用について
  • master ブランチ

    チーム作業において、開発者が master ブランチを直接マージして リモート・リポジトリにプッシュするのは危険である。 Requesting Merge For Remote Repository の手順などにより、メンテナが master ブランチをマージする運用が望まれる。

  • 長期運用ブランチとトピックブランチ

    ブランチの生存期間により、「長期稼働用ブランチ」と「トピックブランチ」の 2種類のブランチの運用をする。

    • 長期稼働用ブランチ

      長期間に渡って存在するブランチ。安定版、開発版のような運用をする。派生 したブランチ(例えば安定版から派生した開発版)が派生元のブランチ (安定板)にマージされた後も派生したブランチは存在し続ける。

    • トピックブランチ

      短期間しか存在せず、派生元のブランチにマージされた後は、そのブランチは 削除される。バグフィックス用のブランチ、機能追加用のブランチのような運用 をする。

    長期稼働用ブランチ(master、develop)とトピックブランチ(topic)の運用 イメージは、以下の図のとおりである。

    [Branch]                               master
                                             |
    [Commit] C0 <- C1 <-+------------------- C6 --
                        |                    |
                        C2 <-+--- C4 <- C5 <-+----- C7 --
                             |    |                 |
                             C3 <-+                 |
                                  |                 |
    [Branch]                    topic => Delete   develop

    図の説明

    1. C1 コミットから develop ブランチ(長期華道用ブランチ)を作成する
    2. C2 コミットから topic ブランチ(トピックブランチ)を作成する
    3. C4 コミットで topic ブランチを develop ブランチにマージした後、 topic ブランチを削除する
    4. C6 コミットで develop ブランチを master ブランチにマージする
トピックブランチの運用で使用するコマンド
  1. トピックブランチの運用作業の流れ
    [Branch]   (a)origin/master  (b)origin/master  (f)origin/master
                       |                 |                 |
    [Commit]   C0 <--- C1 <-+----------- C2 <------------- C4
                            |                              :
                            +----------- C3 <- - - - - - - +
                                         |
    [Branch]                       (c)featureA => (g)削除
                             (d)(e)origin/featureA => (g)削除 
    1. トピックブランチの作成

      開発者は、C1 コミットから featureA(トピックブランチ)を作成する。

    2. masterブランチでのコミット発生

      トピックスブランチ作成後に master ブランチでコミットが作成される。

    3. トピックブランチへのコミット

      開発者は、ローカル・リポジトリのトピックブランチ(featureA)にファイルの 変更をコミットする。

    4. トピックブランチのプッシュ

      開発者は、リモート・リポジトリにトピックブランチ(featureA)をプッシュ する。

    5. メンテナへの master ブランチへのマージ依頼

      開発者は、メンテナにトピックブランチの変更を master ブランチに取り込む ように依頼する。

    6. トピックブランチの master ブランチへのマージ

      メンテナは、開発者から変更のマージ依頼を受けてトピックブランチ (featrureA)のコミット C3 を master ブランチにマージする。

    7. トピックブランチの削除

      開発者は、リポジトリ管理者からマージ完了の通知を受け取ったら、 リモート・リポジトリ、ローカルリポジトリの両方からトピックブランチ (featureA)を削除する。

  2. トピックブランチの運用で使用する git コマンド
    1. トピックブランチの作成

      以下のコマンドは、トピックスブランチを作成した後、リモート・リポジトリの master ブランチの変更をマージしている。

      (1) $ git checkout -b featureA
      (2) $ git fetch
      (3) $ git merge --no-commit --squash origin/master
      1. -b オプションを指定して、master ブランチから トピックブランチ (featureA) を作成し、その現在のブランチ(HEAD)をトピックブランチに 切り換える
      2. 作業中にマージ元のリモートブランチ(origin/master)が変更された 場合は、リモート・リポジトリの master ブランチをフェッチする。 フェッチ元が省略されているが、リモート・リポジトリの既定のブランチは master を指しているものとする。
      3. フェッチしたリモート・リポジトリの変更をマージするがコミットしない

        git merge コマンドのオプションの説明

        • --no-commit

          マージ結果をステージするがコミットはしない

        • --squash

          マージ元の変更を1つのコミットにまとめてマージ先の先頭にマージする

    2. masterブランチでのコミット発生
    3. トピックブランチへのコミット
      (1) $ git add <更新したファイルのパス> [...]
      (2) $ git commit -m "作業内容のメッセージ"
      1. 変更されたファイルをステージ済にする
      2. トピックブランチをコミットする
    4. トピックブランチのプッシュ
      (1) $ git push origin featureA
      1. ローカル・リポジトリのトピックブランチ(featureA)を リモート・リポジトリにプッシュする
    5. メンテナへの master ブランチへのマージ依頼

      使用するコマンドは、Requesting Merge For Remote Repository を 参照のこと

    6. トピックブランチの master ブランチへのマージ

      使用するコマンドは、Requesting Merge For Remote Repository を 参照のこと

    7. トピックブランチの削除
      (1) $ git checkout master
      (2) $ git push --delete origin featureA
      (3) $ git branch -D featureA
      1. 現在のブランチ(HEAD)をトピックブランチから master ブランチに 切り替える
      2. origin のリモート・リポジトリからトピックブランチ(featureA)を削除 する
      3. ローカル・リポジトリのトピックブランチを削除する。

        「git branch」コマンドの -D オプションは、ブランチを強制的に削除する ためのオプションである。-d オプションを指定した場合は、featureA ブランチを分岐元の master ブランチにマージしていないため、削除が失敗 することに注意する。

長期可動用ブランチの運用で使用するコマンド
  1. 長期稼働用ブランチの運用作業の流れ
    [Branch]    (b)origin/master ==> (d)origin/master ===> (h)origin/master
                            |                 |                     |
    [Commit] C0 <-+-------- C2 <-+----------- C4 <----------------- C6
                  |              |                                  :
                  C1 <-----------+--C3 <----------- C5 <- - - - - - +
                  |                 |               |
                  |           (c)featureB ==> (e)featureB
         (a)myfork/featureB ==========> (f)(g)myfork/featureB
    1. リモート・リポジトリに長期稼働用ブランチがプッシュされた
    2. リモート・リポジトリの master ブランチにコミットがプッシュされた
    3. ローカル・リポジトリで master ブランチを長期稼働用ブランチにマージ

      開発者はリモート・リポジトリから長期稼働用ブランチを取得した後、 リモート・リポジトリの master ブランチで発生したコミット C2 をマージ する。

    4. リモート・リポジトリの master ブランチにコミットがプッシュされた
    5. 長期稼働用ブランチへのコミット

      開発者は、ローカル・リポジトリの長期運用ブランチにファイルの変更を コミットする。

    6. 長期稼働用ブランチのプッシュ

      開発者は、リモート・リポジトリに長期稼働用ブランチをプッシュする。

    7. メンテナへの master ブランチへのマージ依頼

      開発者は、メンテナに長期化同様ブランチの変更を master ブランチにマージ するように依頼する。

    8. トピックブランチの master ブランチへのマージ

      メンテナは開発者から変更のマージ依頼を受けて長期稼働用ブランチのコミット C5 を master ブランチにマージする。

  2. 長期稼働用ブランチの運用で使用する git コマンド
    1. リモート・リポジトリに長期稼働用ブランチをプッシュ
      (1) $ git pull
      (2) $ git checkout -b featureB
      (3) $ git push origin featureB
      1. リモート・リポジトリから master ブランチをプルする。upstream が リモート・リポジトリの master ブランチとなっていることが前提。
      2. 現在のブランチ(HEAD->master)から長期稼働用ブランチ featureB を 作成してこれを現在のブランチとする。
      3. 現在のブランチ(HEAD->寵姫稼働用ブランチ)をリモート・リポジトリに プッシュする。upstream が origin/master となっているので、リモートと ブランチを指定してプッシュしている。
    2. リモート・リポジトリの master ブランチにコミットがプッシュされた
    3. ローカル・リポジトリで master ブランチを長期稼働用ブランチにマージ
      (1) $ git pull origin featureB
      (2) $ git checkout featureB
      (3) $ git fetch origin master
      (4) $ git merge --squash origin/master
      (5) $ git branch -u origin/featureB
      1. リモート・リポジトリから長期稼働腰部ランチをプルする。
      2. 長期化可動用ブランチを現在のブランチ(HEAD)にする。
      3. リモート・リポジトリの master ブランチをフェッチする。
      4. リモート・リポジトリの master ブランチのコミット C2 を長期可動用 ブランチにマージする。マージ結果をコミットしたくない場合は、 「--no-commit」オプションを指定する。
      5. ローカル・リポジトリの現在のブランチ(長期稼働用ブランチ)が リモート・リポジトリの featureB ブランチを追跡するようにする。 開発者はリモート・リポジトリへのプッシュは長期稼働用ブランチに対して 行うので、プッシュ、フェッチでリモート・リポジトリのブランチの指定を 省略下端愛に長期稼働用ブランチを追跡するように個の設定を行う。
    4. リモート・リポジトリの master ブランチにコミットがプッシュされた
    5. ローカル・リポジトリの長期稼働用ブランチにコミット
      (1) $ git add <更新したファイルのパス> [...]
      (2) $ git commit -m "作業内容のメッセージ"
      1. 変更されたファイルをステージ済にする
      2. 現在のブランチ(長期稼働用ブランチ)をコミットする
    6. 長期稼働用ブランチのプッシュ
      (1) $ git push
      1. 現在のブランチ(長期稼働用ブランチ)リモート・リポジトリにプッシュ する
    7. メンテナへの master ブランチへのマージ依頼

      使用するコマンドは、Requesting Merge For Remote Repository を 参照のこと

    8. トピックブランチの master ブランチへのマージ

      使用するコマンドは、Requesting Merge For Remote Repository を 参照のこと

参考文献

Git Packages

git パッケージ以外に git に関連するパッケージを以下に示す。

  • gitk

    gitkはグラフィカルな履歴ビュワーで、過去のコミットの履歴をグラフィカルに 表示する。以下のコマンドを実行して、gitkパッケージをインストールする。

    # dnf install gitk
  • git-gui

    git-guiは、indexをステージングされていないもの(git addされていない変更)、 ステージングされているもの(git addされた変更)に分けて表示し、 ステージングの状態を切り替えたり、ステージングされた変更をコミットしたり することができる。以下のコマンドを実行して、git-guiパッケージをインストール する。

    # dnf install git-gui

Other Topics - Git

  • コマンドラインで履歴を表示する
    $ git log <オプション> [<コミット>..<コミット>] [-- <ファイルパス> ...]
    • コミット..コミット」でコミットの範囲を指定する。

      例:master^^^..master^ (masterブランチの3つ前のコミットから1つ前の コミットを表示する)

    • 「-- ファイルパス ...」で指定されたファイルがコミットされた履歴を 表示する
    • 「--graph」オプションを指定すると、ブランチの分岐、統合をわかりやすく 表示する
      注 意

      「git log」はリモート・リポジトリの履歴を表示する。ローカル・リポジトリに コミットしても「git push」でリモート・リポジトリに変更が反映して いなければ、ローカル・リポジトリの変更は履歴に表示されない。

  • 認証情報の保存(ローカル・リポジトリ)

    remote repository にアクセスするコマンド(git push、git fetchなど)を実行 すると、その都度ユーザー名、パスワードの入力が要求される。認証情報を保存する ことによって、ユーザー名、パスワードの入力を抑止することができる。認証情報を 保存するための手順は、以下のとおり。

    1. git の作業ディレクトリの中で以下のコマンドを実行して、ファイルから 認証情報を取得するようにする。
      $ git config credential.helper store

      上記のコマンドを実行すると、~/.git-credentials ファイルに保存された認証 情報を git コマンドが参照するようになる。

    2. 以下のコマンドを実行して、Git リポジトリの URL 毎にユーザー名、 パスワードを設定する。カレントディレクトリは、作業ディレクトリの中で なくても構わない。
      $ git credential-store store
      protocol=<protocol>
      host=<server-name>
      path=<repo-uri>
      username=<user-name>
      password=<password>
      (空行)

      コマンド「git credential-store store」を実行した後に、上記のように リポジトリURLのプロトコル/ホスト名/URI、ユーザー名、パスワードを設定し、 最後に空行を入力(何も入力せずにEnterキーを押す)する。 例えば、リポジトリのURLが「http://my-server/git/example.git」で、 ユーザー名が「foo」、パスワードが「bar」である場合、以下のようにコンソール から入力することになる。

      $ git credential-store store
      protocol=http
      host=my-server
      path=git/example.git
      username=foo
      password=bar
      (空行)
      参考文献

git-http (fc27)

httpプロトコルでGitリポジトリにアクセスするための設定手順を説明する。

Apache httpdのインストール

以下のコマンドを実行して httpd パッケージをインストールする(httpd未導入の場合)

# dnf install httpd

GitWeb - Gitリポジトリの閲覧

  1. gitwebパッケージのインストール

    以下のコマンドを実行して、gitwebパッケージをインストールする。

    # dnf install gitweb
    注 意

    既に /etc/httpd/conf.d/gitweb.conf ファイルが存在する場合は、インストール された gitweb.conf ファイルの名前が「gitweb.conf.rpmsave」となるので、既に 存在している gitweb.conf ファイルの名前を変更して、gitweb.conf.rpmsave ファイルの名前を gitweb.conf に変更すること。

  2. gitweb.conf の編集
    Alias /git /var/www/git
    
    <Directory /var/www/git>
      Options +ExecCGI
      AddHandler cgi-script .cgi
      DirectoryIndex gitweb.cgi
    </Directory>

    上記の設定で、「Alias /git ...」を「Alias /gitweb ...」に変更して、後で インストールする Smart HTTP で使用するURLと被らないようにする。

Smart HTTP - HTTPでcloneとpushをする

  1. Apache Moduleの確認

    mod_cgi、mod_alias、mod_env、mod_rewrite が有効であることを確認する。 /etc/httpd/conf.modules.d ディレクトリに移動して、以下のコマンドを実行し、 必要なモジュールがLoadされる設定になっているかを確認する。

    # grep -e mod_cgi -e mod_alias -e mod_env -e mod_rewrite *.conf
  2. git-smart-http.conf ファイルの編集

    /etc/httpd/conf.d ディレクトリの下に「git-smart-http.conf」ファイルを 作成し、以下のように記述する。

    SetEnv GIT_PROJECT_ROOT /var/lib/git
    SetEnv GIT_HTTP_EXPORT_ALL
    ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
    
    RewriteEngine On
    RewriteCond %{QUERY_STRING} service=git-receive-pack [OR]
    RewriteCond %{REQUEST_URI} /git-receive-pack$
    RewriteRule ^/git/ - [E=AUTHREQUIRED]
    
    <Location "/git/">
        AuthType Basic
        AuthName "Git Realm"
        AuthUserFile /etc/httpd/conf/htpasswd.git
        Require valid-user
    </Location>
    • リポジトリ毎にユーザー登録を行う場合

      上記の例では、htpasswd.git に登録されたユーザーは、全てのGit リポジトリに アクセス可能となる。リポジトリ毎にユーザー登録を行う場合は、<Location> ディレクティブをリポジトリのパスごとに分けて設定すること。

    • ユーザーの登録について

      ユーザーを登録・パスワードを変更する場合は、以下のコマンドを実行する。

      • 初回の場合(htpasswd.gitファイルが存在しない場合)
        # htpasswd -bc /etc/httpd/conf/htpasswd.git <ユーザー名> <パスワード>
      • 2回目以降の場合
        # htpasswd -b /etc/httpd/conf/htpasswd.git <ユーザー名> <パスワード>
      • ユーザーを削除する場合
        # htpasswd -D /etc/httpd/conf/htpasswd.git <ユーザー名>
      • git-lfs-fcgi とフィルを共有する場合

        git-lfs-fcgi は、bcrypt encryption を使用するので、パスワードの作成、 変更する場合は、htpasswd コマンドに -B オプションを指定すること。

  3. httpdの起動

    以下のコマンドを実行して、httpdを起動する。

    # systemctl start httpd

    なお、httpdの設定を変更した場合は、コマンド「systemctl restart httpd」を 実行してhttpdを再起動すること。

  4. SELinuxの設定

    httpdの実行プログラムに対して、gitの実行プログラムと同様のSELinuxの アクセス権を /var/lib/git 配下のディレクトリ、ファイルに対して与えるための 設定をする。

    1. Gitのポリシーモジュールの内容確認

      作業ディレクトリに移動して、以下のコマンドを実行する。

      $ sudo semodule -E git
      $ sedismod git.pp

      sedismodのメニューから「1」を選択して、ポリシーモジュールの設定内容を 表示し、関係ありそうなラベル「git_sys_content_t」、「git_rw_content_t」、 「git_script_exec_t」のdir、fileの設定を収集する。dir、fileに対する操作の 設定を重複を除いて抽出した結果は以下の通りである。

        allow git_script_t git_rw_content_t : [dir] { ioctl read write create getattr setattr lock unlink link rename add_name remove_name reparent search rmdir open };
      
        allow git_script_t git_script_exec_t : [file] { entrypoint };
        allow git_script_t git_script_exec_t : [file] { ioctl read getattr lock map execute execute_no_trans open };
        allow git_script_t git_rw_content_t : [file] { ioctl read write create getattr setattr lock append unlink link rename open };

      上記の結果より、httpsのプロセスに対して、ディレクトリ、ファイルに対して 以下の操作を許可するようにSELinuxを設定することにする。

      • dir

        ioctl read write create getattr setattr lock unlink link rename add_name remove_name reparent search rmdir open

      • file

        entrypoint ioctl read write create getattr setattr lock map execute execute_no_trans append unlink link rename open

    2. httpdのプロセスのラベルを確認

      コマンド「git clone GitリポジトリのURL」を実行した後に、SELinux通知 ブラウザーで表示されるメッセージを確認し、「追加情報」の 「ソースコンテキスト」よりプロセスのラベルを確認する。SELinux通知 ブラウザの代わりにコマンドで確認する場合は、SELinuxの通知が発生した時間を 指定して、以下のコマンドを実行する。

      $ sudo ausearch -ts MM/DD/YY hh:mm:dd  | audit2allow -a
    3. Type Enforcedの設定

      httpdのプロセスのラベルと、/var/lib/git ディレクトリに設定されているラベル (git_sys_content_t)を使用して、以下の書式でTEファイル(Type Enforcedの 定義ファイル)を記述する。ファイルの名前は、my-httpd-git.te (<モジュール名>.te)とする。

      module my-httpd-git 1.0;
      require {
              type git_sys_content_t;
              type <httpdのプロセスのラベル1>;
              type <httpdのプロセスのラベル2>;
              class dir {<ディレクトリの操作> ...};
              class file {<ファイルの操作> ...};
      }
      
      #============= <httpdのプロセスのラベル1> ==============
      allow <httpdのプロセスのラベル1> git_sys_content_t : dir {<ディレクトリの操作> ...};
      allow <httpdのプロセスのラベル1> git_sys_content_t : file {<ファイルの操作> ...};
      
      #============= <httpdのプロセスのラベル2> ==============
      ...

      リモート・リポジトリに対するGitのコマンド(clone、push)を行った結果、 最終的にはhttpdのプロセスのコマンドのラベルは、下記の2つであることが 分かった。

      • httpd_t
      • httpd_sys_script_t

        なお、設定を単純にするため、これらのプロセスに対しては、ファイル及び ディレクトリの設定は同じものを適用することにするので、httpdのプロセスの ラベルは、「{httpd_t httpd_sys_script_t}」と記述することにする。従って 最終的なTEファイルは以下のようになる。

        module my-httpd-git 1.0;
        require {
                type git_sys_content_t;
                type httpd_t;
                type httpd_sys_script_t;
                class dir {ioctl read write create getattr setattr lock unlink link rename add_name remove_name reparent search rmdir open};
                class file {entrypoint ioctl read write create getattr setattr lock map execute execute_no_trans append unlink link rename open};
        }
        
        #============= httpd_t httpd_sys_script_t ==============
        allow {httpd_t httpd_sys_script_t} git_sys_content_t:dir {ioctl read write create getattr setattr lock unlink link rename add_name remove_name reparent search rmdir open};
        allow {httpd_t httpd_sys_script_t} git_sys_content_t:file {entrypoint ioctl read write create getattr setattr lock map execute execute_no_trans append unlink link rename open};

        更に下記の補足に基づいて、httpd_tとscript_tの設定を分けた結果は以下の とおり。

        module my-httpd-git 1.0;
        require {
                type git_sys_content_t;
                type httpd_t;
                type httpd_sys_script_t;
                class file { append create entrypoint execute execute_no_trans getattr ioctl link lock map open read rename setattr unlink write };
                class dir { add_name create getattr ioctl link lock open read remove_name rename reparent rmdir search setattr unlink write };
        }
        #============= httpd_t ==============
        allow httpd_t git_sys_content_t:file { append create execute execute_no_trans getattr ioctl link lock map open read rename setattr unlink write };
        allow httpd_t git_sys_content_t:dir { add_name create getattr ioctl link lock open read remove_name rename reparent rmdir search setattr unlink write };
        #============= httpd_sys_script_t ==============
        allow httpd_sys_script_t git_sys_content_t:file { append create entrypoint execute execute_no_trans getattr ioctl link lock map open read rename setattr unlink write };
        allow httpd_sys_script_t git_sys_content_t:dir { add_name create getattr ioctl link lock open read remove_name rename reparent rmdir search setattr unlink write };

        [my-httpd-git.te]

        補 足

        トライ&エラーの回数を少なくするために、http_t と httpd_sys_script_t の プロセスタイプに対して同じ許可の設定を適用したが、より細かく設定する ためには コマンド「sesearch --allow -ds -s httpd_t -rt -t httpd_sys_.*content_t」、 「sesearch --allow -ds -s httpd_sys_script_t -rt -t httpd_sys_.*content_t」 を実行して、httpd_t、httpd_sys_script_tに許可されたapacheの設定を確認の 上、同様な設定に絞り込むことが考えられる。なお、sesearch コマンドを実行 するにはsetools-consoleパッケージのインストールが必要だが、デフォルトでは インストールされていないので追加でインストールすること。

    4. パッケージの作成とインストール

      以下のコマンドを実行して、TEファイル(my-httpd-git.te)をコンパイルして モジュール(my-httpd-git.mod)を作成する。

      $ checkmodule -m -o my-httpd-git.mod my-httpd-git.te

      以下のコマンドを実行して、モジュールからパッケージ(my-httpd-git.pp)を 作成する。

      $ semodule_package -o my-httpd-git.pp -m my-httpd-git.mod

      以下のコマンドを実行して、パッケージをインストールする。

      $ sudo semodule -i my-httpd-git.pp
    5. Gitのコマンドの実行とSELinux通知の確認

      Gitの clone、push などリモート・リポジトリに対するコマンドを実行し、 SELinuxの通知が発生したら、「httpdのプロセスのラベルを確認」に戻って、 TEファイルにプロセスのラベルを追加する。

    参 考

Git remote repository の利用準備

  1. Gitリポジトリの親ディレクトリの作成

    Gitリポジトリを配置するディレクトリ「/var/lib/git」を作成する。

    # mkdir -p /var/lib/git
  2. Gitリポジトリへのアクセスを許可するグループの作成

    複数のユーザーがGitリポジトリを使用できるように、gitusers グループを作成 する。

    # groupadd gitusers
  3. Gitリポジトリの親ディレクトリのアクセス権設定

    以下のコマンドを実行して、Gitリポジトリの親ディレクトリに gitusers グループ のユーザーがアクセスできるようにする。

    # chmod 775 /var/lib/git
    # chown apache:gitusers /var/lib/git

Initializing git remote repository

/var/lib/git ディレクトリの下にリモート・リポジトリを作成して、そこに http で アクセスできるようにする。

  1. bare リポジトリの作成

    OSのグループアカウントでリポジトリにpushできるユーザーを設定できるようにする

    # git init --bare --shared /var/lib/git/<リポジトリ名>.git
    # chown -R apache:gitusers /var/lib/git/<リポジトリ名>.git

    hookスクリプトがSmart HTTPで動作できるようにするため、SELinuxのラベルを つける。

    # chcon -R -h -t httpd_sys_script_exec_t /var/lib/git/<リポジトリ名>.git/hooks/
    永続的なラベル付け

    chcon コマンドでラベルを設定すると、restorecon コマンドなどでラベルの 再作成を行うと設定が消えてしまう。ラベルの再作成をしても設定が残るように する(デフォルトの設定にする)場合は、以下のコマンドを1回だけ実行する。

    # semanage fcontext -a -t httpd_sys_script_exec_t "/var/lib/git/[^/]*/hooks(/.*)?"
    # restorecon -R -v /var/lib/git

    リモート・リポジトリを作成した場合は、以下のコマンドを実行して上記のラベル 設定を適用する。

    # restorecon -R -v /var/lib/git/<リポジトリ名>.git/
    参 考
  2. hookの設定
    • post-update

      hooksディレクトリにあるpost-update.sample スクリプトの名前を変更して、 post-update スクリプトが動作できるようにする。

      # cd /var/lib/git/<リポジトリ名>.git/hooks
      # cp -dpvi post-update.sample post-update
      # chmod a+x post-update
    • update

      hooksディレクトリの下にupdateファイルを作成して、update script source に示したスクリプトを記述する。また、以下のコマンドを実行して、update ファイルのオーナー、グループの設定と、実行権限の設定をする。

      # chown apache:gitusers <updateファイルのパス>
      # chmod a+x <updateファイルのパス>
  3. config ファイルの設定
    • リモートリポジトリのディレクトリ(/var/lib/git/リポジトリ名.git)に移動 して、以下のコマンドを実行する。
      # sudo -u apache git config --file config http.receivepack true
参 考

その他のリモート・リポジトリの設定

  • 後付けでリモート・リポジトリを設定

    コマンド「git init <リポジトリ名>」を実行して、先にローカル・リポジトリを 作成した後に、リモート・リポジトリを設定する場合は以下のコマンドを実行する。

    $ git remote add origin http://<ユーザー名>:<パスワード>@<ホスト名>/<リポジトリのパス>
    $ git push --set-upstream origin master
    備 考
    • 最初のコマンドは、リモート・リポジトリの名前に「origin」を指定して、 リモート・リポジトリのURLを設定する。2番目のコマンドは、masterブランチ のリモート・リポジトリを「origin」に設定する。これらのコマンドを実行する ことでローカル・リポジトリの設定は、コマンド「git clone URL」を実行 した結果と同じになる。
    • ローカル・リポジトリでコミットした後、「remtoe add origin url」などで リモートリポジトリを設定してマージすると、 「fatal: refusing to merge unrelated histories」が発生することがある。 その場合は、以下のように「--allow-unrelated-histories」オプションを 付けてマージする。
      $ git merge --allow-unrelated-histories origin/master
  • 既存のリモート・リポジトリをグループ書き込み対応にする

    「--shared」オプションを付けずに「git init --bare」で作成したリポジトリを 「--shared」オプションを付けて作成した場合と同じ状態にするためには、以下の コマンドを実行する。

    $ chgrp -R <git-group-name> <repository-dir>
    $ chmod -R g+rw <repository-dir>
    $ chmod g+s `find <repository-dir> -type d`
    $ git init --bare --shared <repository-dir>
  • リモート・リポジトリへのpushを制限する

    hooksディレクトリに update ファイルを作成し、下記の内容を設定する。この hook script は、adminusersで指定されたユーザー以外のユーザーがbranchesで 指定されたブランチに push しようとしたときにそれを抑止するためのスクリプト である。

    [update script source]

    #!/bin/sh
    # set allowing users to commit as "<user1> <user2> ..."
    adminusers="gituser"
    # set ristricted branches to commit as "<branch1> <branch2> ..."
    branches="master"
    
    if [ -z ${GIT_COMMITTER_NAME} ]; then
      if [ -n ${USER} ]; then
        GIT_COMMITTER_NAME=${USER}
      else
        GIT_COMMITTER_NAME=${REMOTE_USER}
      fi
    fi
    
    is_admin=false
    for adminuser in ${adminusers}; do
      if [ ${GIT_COMMITTER_NAME} == ${adminuser} ]; then
        is_admin=true
      fi
    done
    for branchname in ${branches}; do
      if [ ${is_admin} != true -a "$1" == refs/heads/${branchname} ]; then
        echo "ERROR: ${GIT_COMMITTER_NAME} are not allowed to update ${branchname}" >&2
        exit 1
      fi
    done

Git LFS (fc33) - Git Large File Storage

Git LFS (Git Large File Storage) は、大容量のファイルを Git で扱うための拡張 機能である。Git LFS は、大容量のファイルを git に格納するときに、Git リポジトリに直接ファイルを格納せず、「text pointer」にObject IDなどのメタ情報 を格納し、ファイル本体は Git リポジトリとは別の Git LFS サーバに格納する。

git-lfs-fcgi パッケージのビルドとインストール

Git LFS サーバを構築するために、git-lfs-fcgi パッケージをビルドして インストールする。

注 意

プロジェクトの README.md に 「Warning: Not production ready」と記載されて いる。README.md を熟読して制限事項を把握した上で運用すること。

  1. ソースファイルのダウンロード
  2. ビルドに必要なパッケージのインストール

    ビルドに必要な以下のパッケージをインストールする。

    • bison
    • cmake
    • flex
    • fcgi-devel
    • gcc-c++
    • json-c-devel
    • libsqlite3x-devel
    • make
    • openssl-devel
    注 意
    • CentOS 7 の場合は、cmake の代わりに cmake3 パッケージをインストールする こと

    ビルドに必要なパッケージをインストールするコマンドは以下のとおり。

    # dnf install bison cmake flex fcgi-devel gcc-c++ json-c-devel \
          libsqlite3x-devel make openssl-devel

    CentOS 7の場合は、以下のコマンドを実行する。

    # yum install bison cmake3 flex fcgi-devel gcc-c++ json-c-devel \
          libsqlite3x-devel make openssl-devel
  3. gti-lfs-fcgi のビルド
    1. specファイル

      以下の内容を記述する。

      # Basic information
      Name:           git-lfs-fcgi
      Version:        1.0.0
      Release:        2%{?dist}
      Summary:        Git LFS FastCGI Server
      License:        ISC License
      #Group:          
      URL:            https://github.com/soundsrc/git-lfs-fcgi
      
      # Required Information when building package
      Source0:        https://codeload.github.com/%{name}-%{version}.tar.gz
      BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root
      
      # Define tags for package names and building.
      %define sqlite_libs sqlite-libs
      %define cmake cmake
      %if 0%{?el7}
        # CentOS 7 / RHEL 7
        %define sqlite_libs sqlite
        %define cmake cmake3
      %endif
      %define debug_package %{nil}
      
      # Dependency information
      Requires:       httpd
      Requires:       fcgi
      Requires:       json-c
      Requires:       openssl-libs
      Requires:       %{sqlite_libs}
      BuildRequires:  %{cmake}
      BuildRequires:  bison
      BuildRequires:  flex
      BuildRequires:  fcgi-devel
      BuildRequires:  gcc-c++
      BuildRequires:  json-c-devel
      BuildRequires:  libsqlite3x-devel
      BuildRequires:  make
      BuildRequires:  openssl-devel
      
      # Detail information
      %description
      Warning: Not production ready
      This server is designed to be used when Git repositories are already hosted
      over HTTP using an existing webserver and you want to add LFS support.
      It is a FastCGI binary that should interface with most webservers after a bit
      of configuration.
      
      %prep
      %setup
      
      %build
      mkdir builddir
      cd builddir
      CXX=g++ %{cmake} ..
      %{cmake} --build .
      mkdir -p etc/httpd/conf.d/
      echo -e '<Location "/git/*/info/lfs/">\n    ProxyPassReverse "unix:/var/lib/git-lfs-fcgi/run/git-lfs-fcgi.sock|fcgi://localhost/"\n</Location>\n\nProxyPassMatch "^/git/[^/]*/info/lfs/" "unix:/var/lib/git-lfs-fcgi/run/git-lfs-fcgi.sock|fcgi://localhost/" enablereuse=off\n\n# If <Location "/git/"> directive is exists, set SetEnvIf directive there.\nSetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1' > etc/httpd/conf.d/git-lfs-fcgi.conf
      sed -e 's/\(^After=.*$\)/\1\nRequires=httpd.service/g' -i ../conf/git-lfs-fcgi.service
      sed -e 's/^# repo "[^*]*"$/repo "Example Repository"/g' \
          -e 's/^# {/{/g' \
          -e 's/^# }/}/g' \
          -e 's/^#\([ \t]*uri \).*$/\1"\/git\/example.git\/info\/lfs"/g' \
          -e 's/^#\([ \t]*root \).*$/\1"\/var\/lib\/git-lfs-fcgi\/repository\/example.git"/g' \
          -e 's/^#\([ \t]*enable_authentication \).*$/\1yes/g' \
          -e 's/^#\([ \t]*auth_realm \).*$/\1"Git Realm"/g' \
          -e 's/^#\([ \t]*auth_file \).*$/\1"\/etc\/httpd\/conf\/htpasswd.git"/g' \
          -i ../conf/example-repo.conf
      
      %install
      %__install -d -m 0755 %{buildroot}%{_sbindir}
      %__install -d -m 0755 %{buildroot}%{_sysconfdir}/git-lfs-fcgi/conf.d
      %__install -d -m 0755 %{buildroot}%{_sysconfdir}/httpd/conf.d
      %__install -d -m 0755 %{buildroot}/usr/lib/systemd/system
      %__install -d -m 0755 %{buildroot}%{_mandir}/man5
      %__install -d -m 0755 %{buildroot}%{_mandir}/man8
      %__install -D -m 0755 -t %{buildroot}%{_sbindir} builddir/git-lfs-fcgi
      %__install -D -m 0644 -t %{buildroot}%{_sysconfdir}/git-lfs-fcgi conf/git-lfs-fcgi.conf
      %__install -D -m 0644 -t %{buildroot}%{_sysconfdir}/git-lfs-fcgi/conf.d conf/example-repo.conf
      %__install -D -m 0644 -t %{buildroot}%{_sysconfdir}/httpd/conf.d builddir/etc/httpd/conf.d/git-lfs-fcgi.conf
      %__install -D -m 0644 -t %{buildroot}/usr/lib/systemd/system conf/git-lfs-fcgi.service
      %__install -d -m 0755 %{buildroot}%{_sharedstatedir}/git-lfs-fcgi
      %__install -d -m 0755 %{buildroot}%{_sharedstatedir}/git-lfs-fcgi/run
      gzip man/git-lfs-fcgi.conf.5
      gzip man/git-lfs-fcgi.8
      %__install -D -m 0644 -t %{buildroot}%{_mandir}/man5 man/git-lfs-fcgi.conf.5.gz
      %__install -D -m 0644 -t %{buildroot}%{_mandir}/man8 man/git-lfs-fcgi.8.gz
      
      %clean
      rm -rf %{buildroot}
      
      %post
      # set hostname to  configuratio
      sed -e "s/\"http:\/\/example\.com\"/\"http:\/\/`hostname`\"/g" -i %{_sysconfdir}/git-lfs-fcgi/git-lfs-fcgi.conf
      # install chroot required binaries.
      mkdir %{_sharedstatedir}/git-lfs-fcgi/bin
      cp -dp /bin/bash %{_sharedstatedir}/git-lfs-fcgi/bin
      mkdir %{_sharedstatedir}/git-lfs-fcgi/lib64
      cp -dp /lib64/ld-*.so*      %{_sharedstatedir}/git-lfs-fcgi/lib64
      cp -dp /lib64/libc-*.so     %{_sharedstatedir}/git-lfs-fcgi/lib64
      cp -dp /lib64/libc.so.*     %{_sharedstatedir}/git-lfs-fcgi/lib64
      cp -dp /lib64/libdl-*.so    %{_sharedstatedir}/git-lfs-fcgi/lib64
      cp -dp /lib64/libdl.so.*    %{_sharedstatedir}/git-lfs-fcgi/lib64
      cp -dp /lib64/libtinfo.so.* %{_sharedstatedir}/git-lfs-fcgi/lib64
      # add git-lfs user and group
      useradd git-lfs -r -d %{_sysconfdir}/git-lfs-fcgi -s /sbin/nologin
      # create git-lfs repository for example
      mkdir -p /var/lib/git-lfs-fcgi/repository/example.git
      # set git-lfs owner to git-lfs directories
      chown -R git-lfs:git-lfs /var/lib/git-lfs-fcgi
      
      %postun
      userdel -r git-lfs
      rm -rf %{_sharedstatedir}/git-lfs-fcgi/bin/
      rm -rf %{_sharedstatedir}/git-lfs-fcgi/lib64/
      
      %files
      %defattr(-,root,root)
      %license LICENSE
      %{_sbindir}/git-lfs-fcgi
      %{_sysconfdir}/git-lfs-fcgi/git-lfs-fcgi.conf
      %{_sysconfdir}/git-lfs-fcgi/conf.d/example-repo.conf
      %{_sysconfdir}/httpd/conf.d/git-lfs-fcgi.conf
      /usr/lib/systemd/system/git-lfs-fcgi.service
      %{_mandir}/man5/git-lfs-fcgi.conf.5.gz
      %{_mandir}/man8/git-lfs-fcgi.8.gz
      %defattr(775,root,root)
      %dir /var/lib/git-lfs-fcgi
      %dir /var/lib/git-lfs-fcgi/run
      
      %changelog

      [~/rpmbuild/SPECS/git-lfs-fcgi.spec]

      spec ファイルの処理内容は以下のとおり。

      • ソースを展開したディレクトリに移動し、「builddir」ディレクトリを作成 して、そこへ移動して cmake コマンドを実行してソースコードをコンパイル する
      • /etc/httpd/conf.d/git-lfs-fcgi.conf に git-lfs-fcgi への リバース・プロキシへの設定を保存する
      • UnitファイルのUnitセクションに「Requires=httpd.service」を追加する
      • パッケージのインストール時に実行する処理を以下のように設定する
        • /etc/git-lfs-fcgi ディレクトリに配置する git-lfs-fcgi.conf ファイル の 「"http://example.com"」を「"http://host-name"」に置換する
        • /var/lib/git-lfs-fcgi に chroot するために必要な bash とその 依存ライブラリを /var/lib/git-lfs-fcgi ディレクトリ配下に配置する
        • git-lfs ユーザー/グループを作成する
        • /var/lib/git-lfs-fcgi ディレクトリ及びその配下のファイル・ディレクトリ のオーナーとグループを git-lfs:git-lfs に設定する
    2. パッケージのビルド

      以下のコマンドを実行して、パッケージをビルドする。

      $ QA_RPATHS=$(( 0x0002|0x0010 )) rpmbuild -ba ~/rpmbuild/SPECS/git-lfs-fcgi.spec

      上記のコマンドを実行すると、以下の場所に RPMファイル(.rpm)、SRPMファイル (.src.rpm)が生成される。

      • ~/rpmbuild/RPMS/x86_64/git-lfs-fcgi-x.x.x-x.fcxx_x86_64.rpm
      • ~/rpmbuild/SRPMS/git-lfs-fcgi-x.x.x-x.fcxx.src.rpm
  4. パッケージのインストール

    ~/rpmbuild/RPMS/x86_64/ ディレクトリーに移動し、以下のコマンドを実行して、 パッケージをインストールする。

    $ sudo dnf install ./git-lfs-fcgi-x.x.x-x.fcxx_x86_64.rpm
  5. SELinuxの設定

    socketファイルが /var/lib ディレクトリ配下に存在するため、httpd プロセスが /var/lib ディレクトリ配下にある socket ファイルへの書き込みを許可する設定を する必要がある。以下の手順で SELinuxのパッケージを作成してインストールする。

    1. TEファイルの作成
      module my-git-lfs-fcgi 1.0.0;
      require {
        type httpd_t;
        type var_lib_t;
        type unconfined_service_t;
        class sock_file write;
        class unix_stream_socket connectto;
      }
      #============= httpd_t ==============
      allow httpd_t var_lib_t:sock_file write;
      allow httpd_t unconfined_service_t:unix_stream_socket connectto;

      [my-git-lfs-fcgi.te]

    2. TEファイルのコンパイル(モジュールの作成)
      $ checkmodule -m -o my-git-lfs-fcgi.mod my-git-lfs-fcgi.te
    3. パッケージの作成
      $ semodule_package -o my-git-lfs-fcgi.pp -m my-git-lfs-fcgi.mod
    4. パッケージのインストール
      # semodule -i my-git-lfs-fcgi.pp
  6. git-lfs-fcgi の設定
    • /etc/httpd/conf.d/git-lfs-fcgi.conf

      既定値のままで良い

      git-lfs-fcgi.conf は、<repository-uri>/info/lfs/ 宛のGit LFSの リクエストを socket経由で Fast CGI に転送するための Reverse Proxyの設定を している。

      <Location "/git/*/info/lfs/">
          ProxyPassReverse "unix:/var/lib/git-lfs-fcgi/run/git-lfs-fcgi.sock|fcgi://localhost/"
      </Location>
      ProxyPassMatch "^/git/[^/]*/info/lfs/" "unix:/var/lib/git-lfs-fcgi/run/git-lfs-fcgi.sock|fcgi://localhost/" enablereuse=off
      
      # If <Location "/git/"> directive is exists, set SetEnvIf directive there.
      SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

      この設定は、リモート・リポジトリのURIが、「/git/repository-name.git」の 形式となっている場合は、リポジトリを新規に追加しても設定を追加する必要が ないようになっている。

      補 足
      • enablereuse パラメータについて

        https://github.com/soundsrc/git-lfs-fcgi には、ProxyPass の転送先 URLにパラメータ「enablereuse=on」を設定するように記載されている。 しかしその場合は、数回 Git LFS のリクエストを実行すると、以後の リクエストはタイムアウトとなってしまう事象が発生するため、パラメータ に「enablereuse=off」を設定するようにした。

      • SetEnvIf ディレクティブについて

        HTTP の Authorization ヘッダの設定内容を HTTP_AUTHORIZATION 環境変数に 設定して、FastCGI に認証情報を渡す設定を行っている。なお、httpdの設定 で既に「<Location /git/>」ディレクティブの設定が存在する場合 (例えば、Git Smart HTTP が構成している場合等)は、SetEnvIf ディレクティブの設定をその中で行った方が良い。

    • /etc/git-lfs-fcgi/git-lfs-fcgi.conf の編集
      • base_url ディレクティブ

        Git LFS サーバのベースURL(http://<host-name>)を設定する

      • その他のディレクティブ

        既定値のままで良い

    • /etc/git-lfs-fcgi/conf.d/<repository-name>-repo.conf ファイルの編集

      ※ Gitリポジトリを追加したときに編集する

  7. Setting up Git LFS

    Gitリポジトリを追加したら、それに対応する Git LFS を以下のように設定する。

    1. /etc/git-lfs-fcgi/conf.d/<repository-name>-repo.conf ファイルの編集

      uri に Git LFSのリクエストURI、rootにそのリクエストに対応するストレージの 場所を設定する。

      repo "<<repository-name>> Repository"
      {
          uri "/git/<<repository-name>>.git/info/lfs"
          root "/var/lib/git-lfs-fcgi/repository/<<repository-name>>.git"
          enable_authentication yes
          auth_realm "Git Realm"
          auth_file "/etc/httpd/conf/htpasswd.git"
      }
      補 足
      • uri、root の設定内容は、「uri にマッチするリクエストが来たら、root の ディレクトリ配下のコンテンツを参照する」というものである
      • Git LFS のファイルロック機能で、ロックしたユーザーを識別するために、 「enable_authentication yes」を設定してユーザー認証を有効にする
      • auth_realm ディレクティブは、Git リポジトリと同じ Auth Realm を設定 すること
      • auth_file ディレクティブは、Gitリポジトリのパスワード・ファイルと同じ パスを指定する
      • パスワードの変更は、-Bオプションを付けて htpasswd コマンドを実行する
      • パスワード・ファイル(htpasswd.git)を変更した場合は、git-lfs-fcgi サービスを再起動して変更を反映する
    2. ファイル配置先ディレクトリの作成

      /etc/git-lfs-fcgi/conf.d/<repository-name>-repo.conf で設定した ストレージのディレクトリを作成して、ディレクトリのオーナーとグループを git-lfs:git-lfs に設定する。

      # mkdir /var/lib/git-lfs-fcgi/repository/<<repository-name>>.git
      # chown git-lfs:git-lfs /var/lib/git-lfs-fcgi/repository/<<repository-name>>.git

    Git リポジトリ名が example の Git リポジトリの場合の設定例は以下のとおり。

    • /etc/git-lfs-fcgi/conf.d/example-repo.conf ファイル
      repo "Example Repository"
      {
              uri "/git/example.git/info/lfs"
              root "/var/lib/git-lfs-fcgi/repository/example.git"
              enable_authentication yes
              auth_realm "Git Realm"
              auth_file "/etc/httpd/conf/htpasswd.git"
      }
    • ファイル配置先ディレクトリの作成
      # mkdir /var/lib/git-lfs-fcgi/repository/example.git
      # chown git-lfs:git-lfs /var/lib/git-lfs-fcgi/repository/example.git
参 考

Git LFSの利用手順

  1. リモート・リポジトリの作成

    Initializing git remote repositoryの手順に従って gitリモート・リポジトリ を作成する。

  2. git-lfs パッケージのインストール

    git-lfs パッケージは Git LFS のクライアントである git lfs コマンドを 提供するパッケージである。

    • ローカル・リポジトリ側のシステムに git-lfs パッケージをインストールする
    • コマンド「git lfs install」を実行する。コマンドを実行する場所はどこでも 良いが、ログイン・ユーザーのホームディレクトリで実行するのが無難
  3. リモート・リポジトリをクローンしてローカル・リポジトリを作成する。
    $ git clone http://<hostname>/git/<repository-name>.git
  4. Git LFS の格納対象ファイルの拡張子を登録する

    作業ツリー(作業ディレクトリの最上位ディレクトリ)の .gitattribute ファイルに Git LFS の格納対象ファイルの拡張子が設定されていない場合は、 作業ツリー配下で以下の手順を実行して拡張子を 登録する。

    $ git lfs track "*.<suffix>"

    拡張子が「jpg」のファイルを Git LFS の格納対象とする場合の例は以下のとおり。

    $ git lfs track "*.jpg"
    備 考

    コマンド「git lfs track ".suffix"」を実行すると、設定結果は作業ツリー 配下の .gitattributes ファイルに以下のように設定される。

    *.<suffix> filter=lfs diff=lfs merge=lfs -text

    .gitattributes ファイルがステージされていない場合は、以下のコマンドを 実行して .gitattribute をステージして、リモートサーバに設定を反映される ようにする。

    $ git add .gitattributes
  5. Git LFS のURLを設定する

    以下に示す操作は、ローカル・リポジトリの作業ツリー直下のディレクトリで行う こと。

    git-lfs のデフォルトの設定では、Git LFS のURLは、GitリポジトリURLの後に 「/info/lfs」を追加したものとなっている。Git LFSのURLがこれとは異なる 場合は、ローカル・リポジトリの作業ツリー直下のディレクトリでコマンド 「git config -f .lfsconfig lfs.url git-lfs-url」を実行して、Git LFSの URLを設定する。このコマンドの実行結果は、<working-dir>/.lfsconfig ファイルに以下の形式で設定される。

    [lfs]
        url = "<git-lfs-url>"

    .lfsconfig ファイルがステージされていない場合は、コマンド 「git add .lfsconfig」を実行してこのファイルを Git リポジトリに反映させる こと。

    例えば、git-lfs-fcgi パッケージを使用している場合に以下のコマンド

    $ git config -f .lfsconfig lfs.url http://<user-name>@<server-name>/git/example.git/info/lfs

    を実行すれば、example.git リポジトリに http でアクセスした場合でも ssh でアクセスした場合でも、Git LFS を使用することができるようになる。

    以上を設定すれば、git コマンドの push、pull、feth コマンドの実行により Git LFS へのファイルの登録、Git LFS からのファイルの取得が行われる。

  6. ファイルのロック

    以下に示す操作は、ローカル・リポジトリの作業ツリー直下おディレクトリで行う こと。

    1. ファイル・ロックの有効化

      以下のコマンドを実行して、Git LFSのファイル・ロックを有効にする。

      $ git config lfs.<git-lfs-url>.locksverify true

      例えば GitリポジトリのURLが「http://user1@foo-server/git/example.git」で Git LFS サーバがデフォルトの構成である場合は、以下のコマンドを実行すれば 良い。

      $ git config lfs.http://user1@foo-server/git/example.git/info/lfs.locksverify true
    2. ロック対象のファイルの登録

      Git LFS 格納対象のファイルをロック可能にしたい場合は、対象ファイルの 拡張子を指定して、以下のコマンドを実行する。

      $ git lfs track "*.<suffix>" --lockable
      • 設定結果は作業ツリー(作業ディレクトリの最上位ディレクトリ)配下の .gitattributes ファイルに設定される
      • .gitattributes がステージされていない場合は、コマンド 「git add .gitattributes」を実行してステージして、Git リポジトリに登録 すること
      • ロック対象のファイルは、リモート・リポジトリからクローンされるときに 読み取り専用となる
      • Git LFSのロック機能を使用するが、ファイルは Git LFS で管理したくない 場合は、.gitattributes ファイルに以下の行を手動で追加する
        *.<suffix> lockable
    3. ファイルのロック

      ロック対象のファイルを編集可能にするためには、以下のコマンドを実行して ファイルをロックする。

      $ git lfs lock <file-path>

      このコマンドは以下の操作を実行する。

      • ロック対象の情報として、ユーザーとファイルのパスをリモート・サーバに 登録する
      • ロック対象のファイルのモードを読み取り専用から書き込可能にする

      ロックされたファイルはローカル・リポジトリで編集してリモート・サーバに push することができるようになる。

    4. ファイルのロック解除

      ファイルのロックが不要になったら、以下のコマンドを実行してファイルの ロックを解除する。

      $ git lfs unlock <file-path>

      何らかの事情で他のユーザーがロックしたファイルを解除する必要がある場合は、 以下のように --force オプションを付けてファイルのロックを解除する。

      $ git lfs unlock <file-path> --force

      このコマンドは以下の操作を実行する。

      • ロック対象の情報として、ユーザーとファイルのパスをリモート・サーバに 登録した情報を削除する
      • ロック対象のファイルのモードを書き込可能から読み取り専用にする
    5. その他
      • ロックされているファイルを確認する
        $ git lfs locks
      • アンロックしたファイルを読み取り専用にする

        コマンド「git checkouit .」を実行(現在のブランチをチェックアウトする) すると、アンロックしたファイルを読み取り専用にすることができる。

参考文献


GitHub (fc36)

アカウントの作成

  1. アカウントの作成

    https://github.com/ にアクセスして、画面右上の「Sign Up」をクリック して、以下の項目を入力する。

    • Enter your email
    • Create a password - 15文字以上のパスワードか、英小文字と数字を含む パスワードを入力する
    • Enter a username - ここで設定したユーザー名が、GitHub の URL の一部になる
    • Would you like to receive product updates and announcements via email? - 「y」または「n」を入力する
    • Verify your account - 質問に該当する画像を選択する

    「Create account」ボタンをクリックして、アカウントを作成する。

  2. 2要素認証の設定
    1. https://github.com/ にアクセスして、画面右上の「Sign In」を クリックして、ユーザー名、パスワードを入力してログインする
    2. 画面右上のアカウントのアイコンをクリックして、「Settings」を 選択する
    3. 画面左側のメニューから「Password and authentication」を選択する
    4. 「Two-factor authentication」で「Enable tow-factor authentication」 をクリックする
    5. Set up using an app / Set up using SMS の何れかを選択して「Continue」 をクリックする。以下は、「Set up using SMS」を選択した場合の手順を説明 する。
    6. 「Authentication verification」の以下の項目を設定する
      • Country code - 国/地域を選択する
      • Phone number - SMS送信先の携帯端末の電話番号を入力して 「Semd authentication code」をクリックする
      • SMS に送信された6桁のコードを入力する。「Save your recovery codes」 にリカバリコードが表示されるので「Download」ボタンをクリックして、 リカバリコードを保存して、「I have saved recovery codes」をクリック する。
      • 「Done」ボタンをクリックして、設定を完了する
  3. 個人アクセストークンの使用
    1. 画面右上のアカウントのアイコンをクリックして、「Settings」を 選択する
    2. 画面左側メニューから「Developper settings」(メニューの下の方にある) を選択して、「Developer settings」画面を開く
    3. 画面左側のメニューから「Personal access tokens」を選択して、 「Generate new token」ボタンをクリックする
    4. 「New personal access token」画面で以下の項目を設定する
      • Note - トークンを識別するための名前を入力する
      • Ecpiration - 有効期間(既定値は30日間)を入力する
      • Select scopes - トークンを使用してアクセスする機能を選択する。 リポジトリのアクセスの認証をする場合は、「repo」にチェックをつける
      • 「Create token」ボタンをクリックしてトークンを作成する
      • 画面が切り替わってトークンが表示されるので、トークンをコピーして 保管する
    参考資料

リポジトリの作成

  1. https://github.com/ にアクセスして、画面右上の「Sign In」をクリック してログインする。2要素認証を有効にした場合は、ユーザー名、パスワードを 入力するとSMSにコードが送信されるので、そのコードを入力してログインを完了 する。
  2. 画面右上のアカウントのアイコンをクリックして、「Your repositories」を 選択し、「Repositories」タブ画面を表示する
  3. 画面上部の「New」ボタンをクリックして、「Create a new repository」画面を 開き、以下の項目を設定する。
    • Owner / Repository name
      • Owner - ドロップダウンから選択する
      • Repository name - リポジトリ名を入力する。ここで入力した名前が、 GitHub の URL の一部になる。
    • Description - 省略可。リポジトリの説明を入力する。
    • Public / Private - リポジトリを公開する/しないの選択をする。Private を 選択した場合は、リポジトリのオーナーと招待したユーザーのみアクセス可能と なる。
    • Initialize this repository with:

      必要に応じて以下の項目を設定する

      • Add a README file - チェックを付けると「README,md」が作成されるので、 後で編集する
      • Add .gitignore - ドロップダウンからリポジトリ登録を除外するファイル名の パターンのテンプレートを選択する。規定値の「None」を選択した場合は、 .gitignore ファイルは作成されない
      • Choose a license - ドロップダウンからライセンスファイルのテンプレートを 選択する。規定値の「None」を選択した場合は、LICENSE ファイルは作成 されない。
  4. 「Create repository」ボタンをクリックして、リポジトリ(master ブランチ) を作成する。

リポジトリの clone と pull / push

  • リポジトリの clone
    1. GitHubのリポジトリのサイト (https://github.com/account-name/repo-name)にアクセスする
    2. 画面上部の「Code」をクリックして、「Clone」のポップアップ画面を 開き、プロトコルを選択して、コピーボタンをクリックして URL をクリップ ボードにコピーする
    3. ローカルリポジトリを作成するディレクトリに移動して、 「git clone URL」コマンド(URLはクリップボードにコピーされたURL)を 実行する
      • リポジトリの visibility を Public にした場合は、認証なしでローカル リポジトリがクローンされる
      • リポジトリの visibility を Private にした場合は、アカウント名と パスフレーズ(個人アクセストークン)による認証が必要となる
  • リポジトリの pull

    git コマンドが「git pull URL」に変わるだけで、手順は clone と同じで ある。

  • リポジトリの push
    1. URLの取得

      「リポジトリの clone」と同様な手順で URL をクリップボードにコピーする

    2. git push コマンドの実行
      • ローカルリポジトリのディレクトリに移動して、「git push URL」コマンド (URLはクリップボードにコピーされたURL)を実行する
      • アカウント名とパスフレーズ(個人アクセストークン)による認証をする

GitHub Pages サイト

GitHub Pages サイトの作成

作成済みのリポジトリに関する Web Page を以下の手順で行うことができる。 なお、リポジトリの visibility が Public でないと サイトが表示されないので 注意すること。

  1. GitHubにログインして、リポジトリを選択する。
  2. 画面上部の「Settings」をクリックし、画面左側に表示されたメニューから 「Pages」を選択して、「GitHub Pages」画面を表示する。
  3. 「GitHub Pages」画面で以下の項目を設定する。
    • Source - None
    • Theme Chooser - 「Choose a theme」ボタンをクリックして、テーマを選択する 画面を開き、テーマのプレビュー画像を選択して「Select theme」ボタンを クリックしてテーマを選択する。
  4. gh-pages ブランチの index.md ファイルのコード画面が表示されるので、 「Commit changes」の設定値は既定値のままで、「Commit changes」ボタンを クリックして設定を完了する
  5. GitHub Pages サイトへのアクセスは、以下の URL を指定して行う。
    https://<account-name>.github.io/<repo-name>/

    なお、リポジトリの visibility が Private の場合は、上記の URL にアクセス すると、「There isn't a GitHub Pages site here.」のエラーが発生する。

参考資料
GitHub Pages のコンテンツ管理

以下の手順で GitHub Pages のブランチをローカルリポジトリで編集して、リモート リポジトリに push する。

  1. ローカルリポジトリで GitHub Pages のブランチ(既定値では gh-pages)を チェックアウトする。git コマンドを実行する場合は、ローカルリポジトリの ディレクトリに移動して、「git checkout gh-pages」コマンド(既定値の ブランチの場合)を実行する。
  2. ローカルリポジトリのコンテンツを編集して、ローカルリポジトリに コミットする。
  3. リモートリポジトリにプッシュする。git コマンドを実行する場合は、 ローカルリポジトリのディレクトリに移動して、「git push」コマンドを 実行し、ユーザー名とパスフレーズ(個人アクセストークン)を入力して 認証する。

GitLab (fc36)

アカウントの作成

  1. アカウント登録画面の入力

    https://about.gitlab.com/ にアクセスして、画面右上の「Register」を クリックして、以下の項目を入力して、「Register」ボタンをクリックする。

    • First name
    • Last name
    • Username
    • Email
    • Password - 最低8文字のパスワードを入力する
  2. メールアドレスによる確認

    登録画面で入力したメールアドレスに確認メールが届くので、「Confirm your account」のリンクをクリックして表示される画面にパスワードを入力を入力して 「Sign in」をクリックする。

  3. 登録の続き

    続いて表示される画面の項目を入力する。

    1. Welcome to GitLab, Refavor!

      以下の項目を入力して、「Continue」をクリックする。

      • Role - ドロップダウンから選択する
      • I'm signing up for GitLab because: ドロップダウンから選択する
      • Who will be using GitLab?

        My company or team、Just me のどちらかを選択する

      • What would you like to do?

        Create a new project、Join a project のどちらかを選択する

    2. About your company

      以下の項目を入力して、「Continue」をクリックする。

      • Company Name
      • Number of employees - ドロップダウンから選択する
      • Country - ドロップダウンから選択する
      • Telephone number (optional)
      • Website (optional)
      • GitLab Ultimate trial (optional) - 30日間無料トライアルをするかしないか を選択する
    3. Create or import your first project
      • Create タブを選択の場合

        以下の項目を入力して「Create project」をクリックする。 Group name、Project name は空白のままにして、後で設定することも 可能と思われる(未確認)。

        • Group name
        • Project name
        • Include a Getting Started README - 必要に応じてチェックを付け外しする
          備 考

          Your project will be created at: https://gitlab.com/group/project

      • Import タブを選択の場合
        • Group name
        • インポート元の Git リポジトリのサービスを選択する
    4. Get started with GitLab

      「Ok. let(s go」をクリックする。

  4. 2要素認証の設定
    1. https://gitlab.com から登録したアカウントでログインする。
    2. 画面右上のユーザー設定アイコンをクリックして、表示された画面の 左側のアイコンから「Account」を選択して「Account」画面を開く。
    3. 「Two-factor authentication」の「Enable two-factor authentication」 をクリックして「Two-Factor authentication」画面を開く。
    4. 「Register Two-Factor Authenticator」に表示されている QR コードを モバイル認証アプリ(Authy など)で読み取ってアカウントを登録した後に、 以下の項目を設定する。
      • Pin code - モバイル認証アプリに登録したアカウント用に表示されている 6桁の Pin code を入力する。
      • Current password - アカウントのパスワードを入力する。

        以上の設定が終わったら、「Register with tow-factor app」ボタンをクリック する。

    5. 「Two-factor Authentication Recovery codes」画面で「Download codes」 をクリックして、リカバリーコードをダウンロードして保存した後、「Proceed」 をクリックして設定を完了する。
  5. アクセス・トークンの設定

    2要素認証を設定すると、リポジトリへのアクセスにパスワードが使用できなく なるため、パスワードの変わりにアクセス・トークンを使用することになる。 以下の手順に従って、アクセス・トークンを作成する。

    1. 画面右上のユーザー設定アイコンをクリックして、表示された画面の 左側のアイコンから「Access Tokens」を選択して「Access Tokens」画面を 開く。
    2. 「Personal Access Tokens」で以下の項目を設定して、「Create persolan access token」をクリックする。
      • Token name - 複数のトークンを設定できるので、識別しやすい名前を設定する
      • Expiration date - 有効期限(年月日)を設定する。有効期限を定めない 場合は、入力欄の「×」をクリックする
      • Select scopes - 認証の対象となる機能にチェックを付ける。リモート リポジトリの push / pull を行う場合は、「read repository」、 「write repository」にチェックを付けること
    3. 「Personal Access Tokens」の一番上に「Your new personal access token」項目が表示され、そこにアクセス・トークンが表示されるので、 トークンをコピーして保存する。

keytool (fc27) - jdk 1.8 keytool

keytoolは、jdkに付属する公開鍵、非公開鍵管理ツールである。keytoolは、 jre_home/bin (jre_homeはJava Runtime Environmentのインストール ディレクトリ)に存在する。

サーバ証明書を自己認証局で署名する手順

  1. keystore(Java Key Store)の準備

    秘密鍵、公開鍵、証明書等の保管は、keystoreと呼ばれるファイルで行われる。 以下の手順では、以下に示す3つのPKCS12形式のkeystoreを使用する。

    • self-ca.p12 - 自己認証局のkeystore
    • server.p12 - SSLサーバーのkeystore
    • client.p12 - SSLサーバーに接続する端末のkeystore
    備 考

    keytoolでは、keystoreの形式の指定を省略すると、JKS(Java Key Store)の形式で keystoreを作成する。keystoreの形式は以下の観点で決めること。

    • JKS (Java Key Store)

      JVM(Java Virtual Machine)が参照するためのkeystoreを作成する場合は、 JKS形式のkeystoreを使用する。

    • PKCS12

      keystore、openssl と相互運用する場合は、この形式のkeystoreを使用する。 Apache httpd で SSL/TLS をサポートする場合は、keystoreから private key を取得するためにopensslコマンドを使用するので、keystoreはPKCS形式にした 方が良い。

  2. 自己認証局の証明書を作成する (自己認証局)

    自己認証局側で以下のコマンドをroot権限で実行して、秘密鍵と公開鍵をラップした 自己認証局の証明書を作成する。

    $ keytool -genkeypair -alias self-ca -storetype PKCS12 -keystore self-ca.p12 \
      -storepass <password> [-keypass <key-password>] -keyalg RSA -keysize 2048 \
      -ext bc:c -validity 3650 \
      -dname "CN=<認証局名>[, OU=<部署名>], O=<組織名>, L=<市町村>, S=<都道府県>, C=<国コード>"

    このコマンドを実行すると、keystoreファイル「self-ca.p12」(keystoreファイル のパスワードが「storepasswd」、秘密鍵保護用のパスワードが「keypasswd」)に 秘密鍵と公開鍵が作成され、公開鍵は有効期間10年の証明書(内容は-dnameで 指定されたもの)でラップされる。またこの証明書にアクセスする際は、名前 「self-ca」を指定する。

  3. 自己認証局の証明書をエクスポートする (自己認証局)

    自己認証局側で以下のコマンドを実行して、keystoreファイル「self-ca.p12」 (keystoreファイルのパスワードが「storepasswd」)に別名「self-ca」で格納 された自己認証局の証明書をエクスポートして証明書ファイル「self-ca.pem」 を作成する。

    $ keytool -exportcert -alias self-ca -keystore self-ca.p12 \
      -storepass <password> -rfc -file self-ca.pem

    ここでエクスポートされた自己認証局の証明書は、後でSSLサーバー、及びSSL サーバーにアクセスする端末のkeystoreにインポートする。

  4. サーバー証明書の署名要求ファイルを作成する (SSLサーバー)

    SSLサーバー側で以下のコマンドをroot権限で実行して、秘密鍵と公開鍵を作成 する。

    $ keytool -genkeypair -alias <hostname> -storetype PKCS12 -keystore server.p12 \
      -storepass <password> [-keypass <key-password>] -keyalg RSA -keysize 2048 \
      -ext bc:c \
      -dname "CN=<hostname>[, OU=<部署名>], O=<組織名>, L=<市町村>, S=<都道府県>, C=<国コード>"

    このコマンドを実行すると、keystoreファイル「server.p12」(keystoreファイルの パスワードが「storepasswd」、秘密鍵保護用のパスワードが「keypasswd」)に 秘密鍵と公開鍵が作成され、公開鍵は証明書(内容は-dnameで指定されたもので 有効期間は既定値である90日間)でラップされる。またこの証明書にアクセスする 際は、-aliasで指定したhostnameを指定する。-dnameの"CN="で指定する hostnameは、URLに使用するサーバ名のFQDNを指定すること。

    次に以下のコマンドを実行して、keystoreファイル「server.p12」(パスワードは 「storepasswd」)に別名「hostname」で格納されたSSLサーバーに対する署名付き サーバー証明書の要求ファイル「hostname.csr」を作成する。

    $ keytool -certreq -alias <hostname> -keystore server.p12 \
      -storepass <password> -file <hostname>.csr
    備 考

    署名要求ファイルのエンコードは PrintableString を求められる場合がある。 作成した署名要求ファイルのエンコードは、以下の openssl コマンドで確認する ことができる。

    $ openssl asn1parse -in <署名要求ファイル>
  5. サーバー証明書の署名要求ファイルへ署名する (自己認証局)

    自己認証局側で以下のコマンドを実行して、keystoreファイル「self-ca.p12」 (keystoreファイルのパスワードは[storepasswd」)に別名「self-ca」で格納された 自己認証局の証明書を使用して署名付きサーバー証明書の署名要求ファイル 「hostname.csr」に対して有効期間が1年の署名を行い、その結果(署名要求応答) をファイル「hostname.pem」に出力する。

    $ keytool -gencert -alias self-ca -keystore self-ca.p12 \
      -storepass <password> -rfc -validity 365 -ext ku:c=dig,keyE \
      -ext san=dns:<hostname> \
      -infile <hostname>.csr -outfile <hostname>.pem
    備 考

    SAN (Subject Alternative Name)について

    オプション「-ext san=」を指定して、Subject Alternative Name を指定する。 このオプションは、-gencert でも使用することが可能である。

    • 最近は、ホスト名をCN (Common Name) で設定することは推奨されず、 SAN (Subject Alternative Name) で設定することが推奨されている。
    • 以下のように、複数のホスト名を認証することができる。
      -ext SAN=DNS:<FQDNホスト名1>,DNS:<FQDNホスト名2>,...
    • FQDNホスト名に、先頭に「*.」を付けて、任意の第一レベルのサブドメインを 認証することが可能。
    • 「IP:IPアドレス」の形式でIPアドレスを認証することも可能。ホスト名を IPアドレスとしたい場合は、この設定をしないとSSL接続エラーが発生する 場合がある。
    備 考
    • 出力されたファイル(署名要求応答ファイル)は-rfcオプションによりBase64で エンコードされている。
  6. 自己認証局の証明書をインポートする (SSLサーバー)

    SSLサーバー側でサーバー証明書(の署名要求応答ファイル)をインポートする前に、 以下のコマンドをroot権限で実行して、keystoreファイル「server.p12」 (keystoreファイルのパスワードが「keystorepasswd」)に別名「self-ca」を 指定して自己認証局の証明書「self-ca.pem」を信頼できる証明書としてインポート する。

    $ keytool -importcert -alias self-ca -keystore server.p12 \
      -storepass <password> -file self-ca.pem

    このコマンドを実行すると、「この証明書を信頼しますか。」のメッセージが 表示され、「y」を入力すると、「self-ca.pem」が信頼できる証明書として インポートされる。

    注 意

    Fedora、RedhatなどのLinux OSの場合は、認証局の証明書のインポートは、 update-ca-trust コマンドで行うこと。keytoolコマンドで証明書のインポートを 行うと、java関連のパッケージが更新された場合に設定が元に戻る恐れがある。

  7. サーバー証明書の署名要求応答ファイルをインポートする (SSLサーバー)

    SSLサーバー側で以下のコマンドを実行して、keystoreファイル「server.p12」 (keystoreファイルのパスワードが「storepasswd」)に別名「hostname」を指定 して、サーバー証明書の署名要求の応答ファイル「hostname.pem」をインポート する。

    $ keytool -importcert -alias <hostname> -keystore server.p12 \
      -storepass <password> -file <hostname>.pem

    keystoreファイル、別名は、サーバー証明書の署名要求ファイルを作成したときと 同じものを指定すること。

  8. 自己認証局の証明書をインポートする (SSLサーバーにアクセスする端末)

    SSLサーバーにアクセスする端末側で以下のコマンドを実行して、keystoreファイル 「client.p12」(keystoreファイルのパスワードが「keystorepasswd」)に別名 「self-ca」を指定して、自己認証局の証明書「self-ca.pem」をインポートする。 keystoreファイルが存在していない場合は、オプション 「-storetype PKCS12」を 付けること。

    $ keytool -importcert -alias self-ca [-storetype PKCS12] -keystore client.p12 \
      -storepass <password> -file self-ca.pem

    このコマンドを実行すると、「この証明書を信頼しますか。」のメッセージが表示 されるので、「y」を入力して、「self-ca.pem」をインポートする。

    注 意

    SSLサーバーの場合と同じく、Fedora、RedhatなどのLinux OSの場合は、認証局の 証明書のインポートは、update-ca-trust コマンドで行うこと。

出 典

Java Platform, Standard Editionツール・リファレンス keytool

Java Key Storeからのprivate keyエクスポート手順

Apacht httpdでSSLの設定をする場合、サーバー証明書の他にprivate keyの設定も 必要だが、Java Key Store (JKS)からprivate keyをエクスポートする手段は提供 されていない。JKSに登録されている内容を一旦PKCS12形式のkeystoreにエクスポート し、そこからopensslコマンドによりprivate keyをエクスポートすることができる。

  1. JKSからPKCS12形式のkeystoreへのインポート

    以下のコマンドを実行して、JKS形式のkeystoreから別名で登録されている内容を PKCS12形式のkeystoreにインポートする。

    $ keytool -importkeystore -srcalias <インポート元別名> \
      -srckeystore <インポート元keystoreファイル> -srcstoretype JKS \
      -srcstorepass <インポート元keystoreパスワード> \
      -destkeystore <インポート先keystoreファイル> -deststoretype PKCS12 \
      -deststorepass <インポート先keystoreパスワード>
  2. private keyのエクスポート

    以下のコマンドを実行して、PKCS12形式のkeystoreからprivate keyをファイルに エクスポートする。

    $ openssl pkcs12 -in <PKCS12 keystoreファイル> -nocerts -out <keyファイル> \
      -passin pass:<keystoreパスワード> -passout pass:<keystoreパスワード>

    なお、上記のコマンドで取得したkeyファイルにアクセスするとパスワードを求め られるので、例えばApache httpd に使用するとサービス起動時にパスワード入力を 求めれることになる。パスワードなし(暗号化なし)のkeyファイルを取得する 場合は、以下のコマンドを実行する。

    $ openssl pkcs12 -in <PKCS12 keystoreファイル> -nodes -nocerts \
      -out <keyファイル> -passin pass:<keystoreパスワード>
    注 意
    • 複数のkeypairが存在している場合は、それら全てが出力されるので、必要な private key に限定する場合は、keyファイルをテキストエディタで開き、 「frendlyName」でalias名を確認して不要なものを削除すること。
    • 出力されたkeyファイルは暗号化されていないので、ファイルのアクセス権を 制限するなどして厳重に保管すること。

Maven (fc27)

Javaのjarファイルを成果物とするMavenプロジェクトをEclipseで新規に作成する 手順を説明する。

pom.xml example

バイナリのjarファイル及びソースコードのjarファイルを生成し、以下のレポートを 出力するための設定例を示す。

  • Javadoc
  • Checkdtyle
  • FindBugs
  • JUnitの試験結果
  • JUnitのカバレッジ
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId><<GROUP_ID>></groupId>
  <artifactId><<ARTIFACT_ID>></artifactId>
  <version><<VERSION>></version>
  <name><<PROJECT_NAME>></name>
  <description><<PROJECT_DESCRIPTION>></description>
  <organization>
    <name>ycookjp my project</name>
  </organization>
  <licenses>
    <license>
      <name>Eclipse Public License 1.0</name>
      <url>http://www.eclipse.org/legal/epl-v10.html</url>
      <distribution>repo</distribution>
    </license>
  </licenses>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <proxy.host></proxy.host>
    <proxy.port></proxy.port>
    <slf4j.ver>1.7.25</slf4j.ver>
    <logback.ver>1.2.3</logback.ver>
    <junit.version>4.12</junit.version>
    <maven-compiler.ver>3.7.0</maven-compiler.ver>
    <maven-jar.ver>3.0.2</maven-jar.ver>
    <maven-source.ver>3.0.1</maven-source.ver>
    <maven-surefire.ver>3.0.0-M2</maven-surefire.ver>
    <jacoco-maven.ver>0.8.0</jacoco-maven.ver>
    <maven-site.ver>3.7.1</maven-site.ver>
    <maven-project-info-reports.ver>3.0.0</maven-project-info-reports.ver>
    <maven-javadoc.ver>3.0.0</maven-javadoc.ver>
    <maven-checkstyle.ver>3.0.0</maven-checkstyle.ver>
    <findbugs-maven.ver>3.0.5</findbugs-maven.ver>
    <maven-surefire-report.ver>2.20.1</maven-surefire-report.ver>
    <maven-jxr.ver>2.1</maven-jxr.ver>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${slf4j.ver}</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>${logback.ver}</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <!-- Compiles Java sources. -->
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven-compiler.ver}</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
      <!-- Build a JAR from the current project. -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>${maven-jar.ver}</version>
        <configuration>
          <outputDirectory>${project.reporting.outputDirectory}</outputDirectory>
        </configuration>
      </plugin>
      <!-- Build a source-JAR from the current project. -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        <version>${maven-source.ver}</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>jar</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <outputDirectory>${project.reporting.outputDirectory}</outputDirectory>
          <attach>false</attach>
        </configuration>
      </plugin>
      <!-- Run the JUnit unit tests in an isolated classloader. -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${maven-surefire.ver}</version>
        <configuration>
          <testFailureIgnore>true</testFailureIgnore>
          <forkMode>once</forkMode>
          <forkCount>1</forkCount>
          <argLine>${jacocoArgs} -Xmx1024m </argLine>
          <reuseForks>false</reuseForks>
        </configuration>
      </plugin>
      <!-- Basic report creation.  -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-site-plugin</artifactId>
        <version>${maven-site.ver}</version>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-project-info-reports-plugin</artifactId>
        <version>${maven-project-info-reports.ver}</version>
      </plugin>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>${jacoco-maven.ver}</version>
        <executions>
         <execution>
           <id>prepare-agent</id>
           <goals>
              <goal>prepare-agent</goal>
           </goals>
           <configuration>
              <propertyName>jacocoArgs</propertyName>
           </configuration>
         </execution>
       </executions>
      </plugin>
    </plugins>
  </build>
  <reporting>
    <plugins>
      <!-- Generate Javadoc for the project. -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-javadoc-plugin</artifactId>
        <version>${maven-javadoc.ver}</version>
        <configuration>
          <links>
            <link>https://docs.oracle.com/javase/jp/8/docs/api/</link>
          </links>
          <failOnError>false</failOnError>
          <additionalJOptions>
            <additionalJOption>-J-Dhttps.proxyHost=${proxy.host}</additionalJOption>
            <additionalJOption>-J-Dhttps.proxyPort=${proxy.port}</additionalJOption>
          </additionalJOptions>
        </configuration>
      </plugin>
      <!-- Generate a Checkstyle report. -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-checkstyle-plugin</artifactId>
        <version>${maven-checkstyle.ver}</version>
        <configuration>
          <configLocation>config/ModifiedSunChecks.xml</configLocation>
        </configuration>
        <reportSets>
          <reportSet>
            <reports>
              <report>checkstyle</report>
            </reports>
          </reportSet>
        </reportSets>
      </plugin>
      <!-- Generates a FindBugs report -->
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>findbugs-maven-plugin</artifactId>
        <version>${findbugs-maven.ver}</version>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-report-plugin</artifactId>
        <version>${maven-surefire-report.ver}</version>
      </plugin>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>${jacoco-maven.ver}</version>
        <reportSets>
          <reportSet>
            <reports>
              <!-- select non-aggregate reports -->
              <report>report</report>
            </reports>
          </reportSet>
        </reportSets>
      </plugin>
<!-- 
 - OPTIONAL
 -->
      <!-- Generate a source cross reference. -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jxr-plugin</artifactId>
        <version>${maven-jxr.ver}</version>
        <configuration>
          <inputEncoding>UTF-8</inputEncoding>
          <outputEncoding>UTF-8</outputEncoding>
        </configuration>
      </plugin>
    </plugins>
  </reporting>
</project>

はじめに

  • 用語について
    • Maven

      pom.xml にビルドに必要な情報、ビルド後に生成するリポートのの設定情報を記載 して、mvnコマンドを実行すると、Javaのjarファイルやwarファイルを作成し、 unit test(通常はjunit)を実行する。また、unit test実行後に、Javadoc、 unit testの実行結果、カバレッジなどのレポートを生成することができる。

    • Group Id

      jarファイルは、Group Id、Artifact Id、Versionにより一意に識別される。 Group Idは、Jarの親階層を示し、Mavenリポジトリにjarファイルを配置する ディレクトリを示すことになる。例えば、Group Idが「org.apache.commons」 の場合、jarファイルはMavenリポジトリの http://repo.maven.apache.org/maven2/org/apache/commons/ の下に配置される。

    • Artifact Id

      Artifact IdとVersionはjarのファイル名を決定する。jarファイルの名前は、 <Artifact Id>-<Version>.jar となる。またArtifact IdはMavneリポジトリの 配置場所も定義し、jarファイルはGroup Idのディレクトリの下にあるArtifact Idの名前のディレクトリの下に配置される。。例えば、Artifact Idが 「commons-csv」の場合、jarファイルはMavenリポジトリの http://repo.maven.apache.org/maven2/org/apache/commons/commons-csv の下に配置される。

    • Version

      Versionを指定すると、jarファイルが一意に決まる。Mavenリポジトリには、 最終的に <Group Idで決まるディレクトリ>/<Artifact Id>/<Version> ディレクトリの下に <Artifact Id>-<Version>.jar という名前で格納されて いる。例えばVersionが「1.5」の場合、Group Idが「org.apache.commons」、 Artifact Idが「commons-csv」のjarファイルは、Mavenリポジトリの http://repo.maven.apache.org/maven2/org/apache/commons/commons-csv/1.5/ にjarファイルが存在する。

  • pluginタグの記述場所
    • project/build/pluginManagement/plugins

      親子関係のMavenプロジェクトの親プロジェクトで記述し、親子全体適用される buildタグのpluginを設定する。ここに記述されたpluginの設定は、 子プロジェクトで記述する必要なく使用することができる。

    • project/build/plugins

      当該プロジェクトでjar、warファイル等をビルドするための設定を記述する。 またレポート出力用のプラグインについてMavenの各ゴールごとの挙動もここで 定義する。

    • project/reporting/plugins

      各種レポートの出力を指示する。

pom.xml の作成

  1. EclipseのJavaプロジェクトを作成する
    1. Eclipseのメニューから「ファイル」「新規」「Javaプロジェクト」を選択 して、「プロジェクト名」を入力し、「次へ」ボタンを押す。
    2. 「Java設定」画面で以下の構成のソースフォルダを作成して「終了」 ボタンを押す。
      • src/main/java
      • src/main/resources
      • src/test/java
      • src/test/resources
  2. Mavenプロジェクトに変換する
    1. 上記で作成したプロジェクトを右クリックし、「構成」「Convert to Maven Project」を選択する。
    2. 「Maven POM」画面で以下の項目を設定して「終了」ボタンを押す。
      • Group Id
      • Artifact Id
      • Version
      • Packaging - 「jar」を選択する。
      • Name
      • Description
  3. 依存関係(このプロジェクトが使用するjar)を設定する
    1. pom.xmlを右クリックして、「アプリケーションから開く」 「Maven POM Editor」を選択する。
    2. 「Dependencies」タブを選択し、「Dependencies」の「Add」ボタンを押して 「Select Dependency」画面を開き、以下の項目を設定する。
      • Group Id
      • Artifact Id
      • Version
      • Scope
        • compile - コンパイル及び実行時に必要なjar
        • test - テスト時に必要なjar。例えばjunit.jarの場合
        • runtime - コンパイルには必要ないが実行時に必要なjar

Maven Pluginの設定

pom.xmlを開き、以下のプラグインの設定を記述する。

  • maven-compiler-plugin
    • project/build/plugins/plugin
      • configuration/source : Javaのバージョンを設定
      • configuration/target : Javaのバージョンを設定
  • maven-jar-plugin
    • project/build/plugins/plugin
      • configuration/outputDirectory : jarファイルの出力先ディレクトリを設定
  • maven-source-plugin
    • project/build/plugins/plugin
      • executions/execution/phase : package
      • executions/execution/gloals/goal : jar
      • configuration/outputDirectory : jarファイルの出力先ディレクトリを設定
      • configuration/attach : false
  • maven-surefire-plugin

    ※ jacoco-maven-pluginを動作させる場合、project/build/pluginMangement/plugins に記述すると動かない

    • project/build/plugins/plugin
      • configuration/testFailureIgnore : false
        ※重要

        これは、テストが失敗してもレポートを出力するための設定である。

      • configuration/forkMode : once
      • configuration/forkCount : 「1」を設定
      • configuration/argLine : JUnitを実行するときのオプションを設定する。 例「${jacocoArgs} -Xmx1024m」
        ※重要

        jacoco-maven-pluginでカバレッジの情報を出力するために、 「project/build/plugins/plugin(jacoco-maven-plugin)/executions/execution/configuration/propertyName」 で設定したプロパティを参照(${jacocoArgs})すること。

      • configuration/reuseForks : false
    • project/reporting/plugins/plugin

      特に設定する項目はない

  • jacoco-maven-plugin
    • project/build/plugins/plugin
      • executions/execution/id : goalと同じ名前を設定
      • executions/execution/goals/goal : prepare-agent
      • configuration/propertyName : maven-surefire-pluginの設定で参照する プロパティの名前を設定する。例「jacocoArgs」
    • project/reporting/plugins/plugin
      • reportSets/reportSet/reports/report : report
  • maven-site-plugin
    • project/build/plugins/plugin

      groupId、artifactId、versionのみを設定する

  • maven-project-info-reports-plugin
    • project/build/plugins/plugin

      groupId、artifactId、versionのみを設定する

  • maven-javadoc-plugin
    • project/reporting/plugins/plugin
      • configuration/links/link : 外部のJavadocのURLを設定する。 例:「https://docs.oracle.com/javase/jp/8/docs/api/」
      • configuration/failOnError : false (Javadocの生成でエラーが発生しても レポートの出力を継続する)
      • configuration/additionalJOptions/additionalJOption : -J-Dhttps.proxyHost=PROXYサーバーのホスト名
      • configuration/additionalJOptions/additionalJOption : -J-Dhttps.proxyPort=PROXYサーバーのポート番号
  • maven-checkstyle-plugin
    • project/reporting/plugins/plugin
      • configuration/configLocation : checkstyleの定義ファイル(XML)のパスを 指定する。例:「${project.basedir}/config/ModifiedSunChecks.xm」
        備 考

        EclipseのCheckstyleの設定で、設定をエクスポートしたファイルを指定 すると良い。

      • reportSets/reportSet/reports/report : checkstyle
  • findbugs-maven-plugin
    • project/reporting/plugins/plugin

      特に設定する項目はない。

  • maven-jxr-plugin
    • project/reporting/plugins/plugin
      • configuration/inputEncoding : ソースファイルのエンコーディング。 $project.build.sourceEncodingを引き継ぐはずだが、明示的に指定しないと 「ISO-8859-1」になってしまう。
      • configuration/outputEncoding : 生成されるドキュメントの エンコーディング。$project.reporting.outputEncodingを引き継ぐはず だが、明示的に指定しないと「ISO-8859-1」になってしまう。

multi module

  1. multi moduleの概要
    • 複数のプロジェクトから構成されるプロジェクトを multi module と呼ぶ。
    • 複数のプロジェクトを呼び出す親のプロジェクトを「parent」、呼び出される側の プロジェクトを「module」と呼ぶ。
    • parent プロジェクトのPackagingには「pom」を指定する
    • module プロジェクトのPackagingには、「pom」以外を指定する
    • module プロジェクトの中で依存関係を持つことができる。例えば、共通機能を パッケージしたAプロジェクトとそれを利用するBプロジェクトの間には、Bの pomの中で、Aのdependencyを設定する
  2. parentプロジェクトのpom.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId><<GROUP_ID>></groupId>
      <artifactId><<PARENT_ARTIFACT_ID>></artifactId>
      <name><<PARENT_PROJECT_NAME>></name>
      <version><<PARENT_VERSION>></version>
      <packaging>pom</packaging>
      <description><<PARENT_PROJECT_DESCRIPTION>></description>
      <modules>
        <module><<MODULE_ARTIFADT_ID>></module>
      </modules>
      <organization>
        <name><<ORGANIZATION_NAME>></name>
      </organization>
      <licenses>
        <license>
          <name>Eclipse Public License 1.0</name>
          <url>http://www.eclipse.org/legal/epl-v10.html</url>
          <distribution>repo</distribution>
        </license>
      </licenses>
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <proxy.host></proxy.host>
        <proxy.port></proxy.port>
        <slf4j.ver>1.7.36</slf4j.ver>
        <logback.ver>1.2.3</logback.ver>
        <junit.version>4.13.2</junit.version>
        <maven-compiler.ver>3.10.1</maven-compiler.ver>
        <maven-jar.ver>3.3.0</maven-jar.ver>
        <maven-source.ver>3.2.1</maven-source.ver>
        <maven-surefire.ver> 3.0.0-M7</maven-surefire.ver>
        <jacoco-maven.ver>0.8.8</jacoco-maven.ver>
        <maven-site.ver>3.12.1</maven-site.ver>
        <maven-project-info-reports.ver>3.4.1</maven-project-info-reports.ver>
        <maven-javadoc.ver>3.4.1</maven-javadoc.ver>
        <maven-checkstyle.ver>3.2.0</maven-checkstyle.ver>
        <spotbugs-maven.ver>4.7.2.0</spotbugs-maven.ver>
        <maven-surefire-report.ver>3.0.0-M7</maven-surefire-report.ver>
        <maven-jxr.ver>3.3.0</maven-jxr.ver>
        <maven-assembly.var>3.4.2</maven-assembly.var>
        <maven-antrun.ver>3.1.0</maven-antrun.ver>
      </properties>
      <dependencies>
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
          <version>${slf4j.ver}</version>
        </dependency>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>${junit.version}</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>ch.qos.logback</groupId>
          <artifactId>logback-classic</artifactId>
          <version>${logback.ver}</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
      <build>
        <pluginManagement>
          <plugins>
            <!-- Compiles Java sources. -->
            <plugin>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>${maven-compiler.ver}</version>
              <configuration>
                <source>1.8</source>
                <target>1.8</target>
              </configuration>
            </plugin>
            <!-- Build a JAR from the current project. -->
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-jar-plugin</artifactId>
              <version>${maven-jar.ver}</version>
              <configuration>
                <outputDirectory>${project.reporting.outputDirectory}</outputDirectory>
              </configuration>
            </plugin>
            <!-- Build a source-JAR from the current project. -->
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-source-plugin</artifactId>
              <version>${maven-source.ver}</version>
              <executions>
                <execution>
                  <phase>package</phase>
                  <goals>
                    <goal>jar</goal>
                  </goals>
                </execution>
              </executions>
              <configuration>
                <outputDirectory>${project.reporting.outputDirectory}</outputDirectory>
                <attach>false</attach>
              </configuration>
            </plugin>
            <!-- Run the JUnit unit tests in an isolated classloader. -->
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-surefire-plugin</artifactId>
              <version>${maven-surefire.ver}</version>
              <configuration>
                <testFailureIgnore>true</testFailureIgnore>
                <forkMode>once</forkMode>
                <forkCount>1</forkCount>
                <argLine>${jacocoArgs} -Xmx1024m </argLine>
                <reuseForks>false</reuseForks>
              </configuration>
            </plugin>
            <plugin>
              <groupId>org.jacoco</groupId>
              <artifactId>jacoco-maven-plugin</artifactId>
              <version>${jacoco-maven.ver}</version>
              <executions>
                <execution>
                  <id>prepare-agent</id>
                  <goals>
                    <goal>prepare-agent</goal>
                  </goals>
                  <configuration>
                    <propertyName>jacocoArgs</propertyName>
                  </configuration>
                </execution>
              </executions>
            </plugin>
            <!-- Basic report creation.  -->
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-site-plugin</artifactId>
              <version>${maven-site.ver}</version>
            </plugin>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-project-info-reports-plugin</artifactId>
              <version>${maven-project-info-reports.ver}</version>
            </plugin>
          </plugins>
        </pluginManagement>
        <plugins>
          <!--
           * source、surefire、JaCoCoはbuild時に実行する
           -->
          <!-- Build a source-JAR from the current project. -->
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
          </plugin>
          <!-- Run the JUnit unit tests in an isolated classloader. -->
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
          </plugin>
          <!-- Basic report creation.  -->
          <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
          </plugin>
        </plugins>
      </build>
      <reporting>
        <plugins>
          <!-- Generate Javadoc for the project. -->
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>${maven-javadoc.ver}</version>
            <configuration>
              <links>
                <link>https://docs.oracle.com/javase/jp/8/docs/api/</link>
              </links>
              <failOnError>false</failOnError>
              <additionalJOptions>
                <additionalJOption>-J-Dhttps.proxyHost=${proxy.host}</additionalJOption>
                <additionalJOption>-J-Dhttps.proxyPort=${proxy.port}</additionalJOption>
              </additionalJOptions>
            </configuration>
          </plugin>
          <!-- Generate a Checkstyle report. -->
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-checkstyle-plugin</artifactId>
            <version>${maven-checkstyle.ver}</version>
            <configuration>
              <configLocation>config/ModifiedSunChecks.xml</configLocation>
            </configuration>
            <reportSets>
              <reportSet>
                <reports>
                  <report>checkstyle</report>
                </reports>
              </reportSet>
            </reportSets>
          </plugin>
          <!-- Generates a SpotBugs report -->
          <plugin>
            <groupId>com.github.spotbugs</groupId>
            <artifactId>spotbugs-maven-plugin</artifactId>
            <version>${spotbugs-maven.ver}</version>
          </plugin>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-report-plugin</artifactId>
            <version>${maven-surefire-report.ver}</version>
          </plugin>
          <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>${jacoco-maven.ver}</version>
            <reportSets>
              <reportSet>
                <reports>
                  <!-- select non-aggregate reports -->
                  <report>report</report>
                </reports>
              </reportSet>
            </reportSets>
          </plugin>
    <!-- 
     - OPTIONAL
     -->
          <!-- Generate a source cross reference. -->
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jxr-plugin</artifactId>
            <version>${maven-jxr.ver}</version>
            <configuration>
              <inputEncoding>UTF-8</inputEncoding>
              <outputEncoding>UTF-8</outputEncoding>
            </configuration>
          </plugin>
        </plugins>
      </reporting>
      <distributionManagement>
        <site>
          <id>javasolutions</id>
          <url>file://${java.io.tmpdir}/maven/site/PARENT_PROJECT_NAME</url>
        </site>
      </distributionManagement>
    </project>
  3. module プロジェクトのpom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <artifactId><<MODULE_ARTIFACT_ID>></artifactId>
      <name><<MODULE_PROJECT_NAME>></name>
      <description><<MODULE_PROJECT_DESCRIPTION>></description>
      <parent>
        <groupId><<PARENT_GROUP_ID>></groupId>
        <artifactId><<PARENT_ARTIFACT_ID>></artifactId>
        <version><<PARENT_VERSION>></version>
        <relativePath>../pom.xml</relativePath>
      </parent>
    </project>
  4. mavenコマンドの実行

    parentプロジェクト配下のmoduleプロジェクト全てをビルド、jarなどの成果物の Maven ローカル・リポジトリへのインストール、サイトの配備を行うには、以下の 手順を実施する。

    1. parentプロジェクトのpom.xmlに「distributionManagement」タグを記述 する。
    2. parent プロジェクトのディレクトリに移動し、以下のコマンドを実行する。
      $ maven clean install site:site site:deploy

packaging a la carte

  1. 依存するjarファイルをダウンロードする

    pom.xml の maven-dependency-plugin を以下のように設定する。依存する jar ファイルは、$basedir/target/dist/lib ディレクトリの下にダウンロード される。

    <project>
      ...
      <build>
        ...
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.0.2</version>
            <executions>
              <execution>
                <id>copy-dependencies</id>
                <phase>package</phase>
                <goals>
                  <goal>copy-dependencies</goal>
                </goals>
                <configuration>
                  <outputDirectory>${project.build.directory}/dist/lib</outputDirectory>
                  <overWriteReleases>false</overWriteReleases>
                  <overWriteSnapshots>false</overWriteSnapshots>
                  <overWriteIfNewer>true</overWriteIfNewer>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
      ...
    </project>
    注 意

    testスコープで依存するjarファイルもダウンロードされてしまうので、test だけで使用するjarを除外する場合は、手動で削除すること。

  2. jar-widh-dependenciesを作成する

    pom.xml の maven-assembly-plugins を以下のように設定すると、compile スコープで依存する jar ファイルの内容(クラスファイル)を取り込んだ jar ファイルを $basedir/target/dist/lib ディレクトリの下に作成する。

    <project>
      ...
      <build>
        ...
        <plugins>
          <plugin>
            <!-- NOTE: We don't need a groupId specification because the group is
                 org.apache.maven.plugins ...which is assumed by default.
             -->
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.1.0</version>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
              <outputDirectory>${project.build.directory}/dist/lib</outputDirectory>
            </configuration>
            <executions>
              <execution>
                <id>make-assembly</id> <!-- this is used for inheritance merges -->
                <phase>package</phase> <!-- bind to the packaging phase -->
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </project>
  3. リソースファイルを外出しにする

    maven-jar-pluginで外出しにするファイルを除外し、maven-resources-pluginで 外出しにするファイルのコピー先を指定するために、pom.xml に以下のような設定を する。

    <project>
      ...
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.0.2</version>
            <configuration>
              <excludes>
                <exclude>《ファイルのパス》</exclude>
              </excludes>
            </configuration>
          </plugin>
          <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <version>3.0.2</version>
            <executions>
              <execution>
                <id>copy-resources</id>
                <!-- here the phase you need -->
                <phase>validate</phase>
                <goals>
                  <goal>copy-resources</goal>
                </goals>
                <configuration>
                  <outputDirectory>${project.build.directory}/dist/classes</outputDirectory>
                  <resources>
                    <resource>
                      <directory>src/main/resources</directory>
                      <includes>
                        <include>《ファイルのパス》</include>
                      </includes>
                    </resource>
                  </resources>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
        ...
      </build>
      ...
    </project>

    上記の設定では、jar ファイルから《ファイルのパス》で指定されたファイルが 除外され、 $basedir/target/dist/classes ディレクトリの下に 《ファイルのパス》で指定されたファイルがコピーされる。《ファイルのパス》は、 以下のように指定する。

    • ファイル名 : <ディレクトリ>で指定したディレクトリの下にあるファイル
    • **/*.txt : <ディレクトリ>で指定されたディレクトリの配下にある(階層が 深くても良い)拡張子が「.txt」のファイル
  4. アーカイブを作成する

    Eclipseの設定ファイルとmavenのtargetディレクトリを除くmaven プロジェクトの ファイル一式をZIPファイルに圧縮して、siteディレクトリの下に配置するための 設定例を以下に示す。

    <project>
      ...
      <build>
        <plugins>
          <!-- project source assembly -->
          <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.1.1</version>
            <configuration>
              <filters>
                <filter>src/assembly/filter.properties</filter>
              </filters>
              <descriptors>
                <descriptor>src/assembly/distribution.xml</descriptor>
              </descriptors>
            </configuration>
            <executions>
              <execution>
                <id>distribution</id>
                <phase>site</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.7</version>
            <executions>
              <execution>
                <!-- move zip file to target/site directory-->
                <id>move-zipfile</id>
                <phase>site</phase>
                <configuration>
                  <target>
                    <!-- move scripts archive to site directory -->
                    <move file="target/${artifactId}-${version}-distribution.zip" todir="target/site" />
                  </target>
                </configuration>
                <goals>
                  <goal>run</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
        ...
      </build>
      ...
    </project>

    pom.xml

    # lines beginning with the # sign are comments
    
    #variable1=value1
    #variable2=value2

    src/assembly/filter.properties

    <assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
      <id>sources</id>
      <formats>
        <format>zip</format>
      </formats>
      <fileSets>
        <fileSet>
          <directory>${basedir}</directory>
          <excludes>
            <exclude>**/.*</exclude>
            <exclude>**/.*/**</exclude>
            <exclude>**/target/**</exclude>
          </excludes>
          <lineEnding>unix</lineEnding>
          <fileMode>0755</fileMode>
        </fileSet>
      </fileSets>
    </assembly>

    src/assembly/distribution.xml


Subversion (fc33)

Subversion はバージョン管理ツールの一つである。Gitはりビジョンをその時点での スナップショットとして扱うのに対して、Subversionは、りビジョンをファイル単位の 差分の集まりとして扱うのが特徴である。

Subversion のインストール

以下のコマンドを実行して、httpd、mod_dav_svn、subversion の2つのパッケージを インストールする。

# dnf install httpd mod_dav_svn subversion

http(s)でリポジトリの操作を行うためには、httpd、mod_dav_svn パッケージで 十分だが、リポジトリの作成や管理をするために svnadmin コマンドを使用するので subversion パッケージもインストールすること。

備 考

mod_dav_svn パッケージをインストールすると、以下の設定が行われる。

  1. /usr/lib64/httpd/modules/ ディレクトリーに以下の Apache module を インストールする
    • mod_authz_svn.so
    • mod_dav_svn.so
    • mod_dontdothat.so
  2. subversion-libs パッケージをインストールして、subversion の ライブラリをインストールする
  3. /etc/httpd/conf.modules.d/10-subversion.conf に 以下の Apache module をロードための設定をする
    • modules/mod_dav.so
    • modules/mod_dav_svn.so

Apache httpd の設定

/etc/httpd/conf.d/svn.conf ファイルに以下の設定をする。

<Location /svn>
  DAV svn
  SVNParentPath /var/www/svn
  AuthType Basic
  AuthName "Subversion repository"
  AuthUserFile /etc/httpd/conf/htpasswd.svn
  AuthGroupFile /etc/httpd/conf/htgroup.svn
</Location>

<Location /svn/<<repo-name>>
  Require group <<repo-group>>
</Location>

設定したディレクティブの内容は、以下のとおり

  • <Location /svn> ... <Location>

    URI に /svn を指定して httpd にアクセスした場合は、Subversionのリポジトリに 対する操作とする。

  • DAV svn

    WebDAV を使用して、Apache httpd と Subversion のリポジトリとの通信をする。

  • SVNParentPath /var/www/svn

    Subversionのリポジトリの親ディレクトリーを /var/www/svn に設定する。

  • AuthType Basic

    リポジトリアクセスは、Basic認証でユーザーの認証をする。

  • AuthName "Subversion repository"

    認証の名前を "Subversion repository" に設定する。

  • AuthUserFile /etc/httpd/conf/htpasswd.svn

    ユーザー人称に使用するパスワード・ファイル(ユーザー名とパスワードを格納した ファイル)を指定する。ユーザーの追加、パスワードの変更、ユーザーの削除は、 htpasswdコマンドを使用して行う。

    • ユーザーの追加、パスワードの変更

      htpasswd -b[c] /etc/httpd/conf/htpasswd.svn ユーザー名 パスワード

      ※ 初回(パスワード・ファイルが存在しない場合)は、c オプションを指定する

    • ユーザーの削除

      htpasswd -D /etc/httpd/conf/htpasswd.svn ユーザー名

  • AuthGroupFile /etc/httpd/conf/htgroup.svn

    アクセスを許可するグループを定義したグループ・ファイルを指定する。 グループ・ファイルには、以下の形式でグループ名とグループに所属する ユーザー名を設定する。

    <group-name>: <user-name> <user-name> ...
  • <Location /svn/repo-name> .. </Location>

    リポジトリ別にアクセスを許可するグループ名を指定する。

リポジトリの作成

  1. リポジトリの親ディレクトリーの作成

    以下のコマンドを実行して、リポジトリの親ディレクトリーを作成し、オーナーに apache ユーザー、及びグループを指定する。

    # mkdir /var/www/svn
    # chown apache:apache /var/www/svn
  2. SELinuxnのラベル設定

    以下のコマンドを実行して、リポジトリの親ディレクトリーとその配下のファイル、 ディレクトリに対して、SELinuxの「httpd_sys_content_t」ラベルを設定する。

    # semanage fcontext -a -t httpd_sys_content_t "/var/www/svn(/.*)?"
    # semanage fcontext -a -t httpd_sys_script_exec_t "/var/www/svn/[^/]+/hooks(/.*)?"
    # semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/svn/[^/]+/db/txn-current-lock"
    # restorecon -R -v /var/www/svn/
    # setsebool -P httpd_unified 1
    注 意

    「semanage fcontext」コマンドを実行した結果、「ファイルコンテキストは すでに定義されています」とのメッセージが表示されたら、-a オプションの 代わりに -m オプションを指定すること。

  3. リポジトリの作成

    svnadmin コマンドで /var/www/svn ディレクトリーの下にリポジトリを作成した 後に、リポジトリのファイル、ディレクトリーのオーナーを apache ユーザー、 グループに設定する。

    # cd /var/www/svn
    # svnadmin create <repo-name>
    # chown -R apache:apache <repo-name>

    次に以下のコマンドを実行して、リポジトリのファイル、ディレクトリーに リポジトリの親ディレクトリーに設定した SELinux のラベルを設定する。

    # restorecon -R -v <repo-name>

参考文献