https://www.eclipse.org/downloads/packages/ にアクセスして、 「Eclipse IDE for Enterprise Java Developers」から環境に合わせた tar.gz ファイルをダウンロードする。
インストール先のディレクトリに移動して以下のコマンドを実行し、ダウンロード したファイルを解凍する。
$ 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`
Java Defelopment Kit がインストールされていない場合は、以下のコマンドを 実行してインストールする。
# dnf install java-1.8.0-openjdk-devel
# dnf install java-21-openjdk-devel
Updateサイトからしかインストールできないプラグインをオフラインインストールする ための手順を以下に示す。
後で導入したプラグイン(dropinsに存在するプラグイン)に左右されずに動かしたい ならば、eclipseディレクトリの下にある「dropins」ディレクトリの名前を別の ものに変える。
dropins にプラグインを配置する場合は、このステップは実施不要。
以下のコマンドを実行して、メタデータ(content.jar)を取得する。
$ eclipse -verbose \ -application org.eclipse.equinox.p2.metadata.repository.mirrorApplication \ -source <Update Site URL> \ -destination <ダウンロード先ディレクトリ>
コマンドに指定するパラメータは以下の通り。
上記のコマンドを実行すると、<ダウンロード先ディレクトリ>の下に 「content.jar」ファイルがダウンロードされる。
メタデータの取得で指定した「-application」の「metadata」となっている部分を 「artifact」に変えて、コマンドを実行する。
$ eclipse -verbose \ -application org.eclipse.equinox.p2.artifact.repository.mirrorApplication \ -source <Update Site URL> \ -destination <ダウンロード先ディレクトリ>
このコマンドを実行すると、<ダウンロード先ディレクトリ>に以下のファイル、 ディレクトリがダウンロードされる。
「Artifacts(features/plugins)の取得」でダウンロードしたファイルを、 <ダウンロード先ディレクトリ>ごと dropins ディレクトリに配置する。
EclipseのUpdate SiteのURLに<ダウンローサ機ディレクトリ>のパスを指定 する。
以下の記述で「x.x.x」はバージョン番号、「yyyyMMddhhmm」は年月日時分の数値を 表す。
Eclipse aCute - C# and .NET Core development tools in Eclipse IDE
eclipse 2023-06 ではプラグインが認識されない状態
「offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://download.eclipse.org/acute/snapshots/ を指定して、プラグインのArtifactsをダウンロードする。
ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。
以下のコマンドを実行して、dotnet パッケージをインストールする。
$ sudo dnf install dotnet
AmaterasERD(ERモデル)、AmaterasUML(UML クラス図、シーケンス図、 アクティビティ図)のエディタのプラグイン
GEF-3.x が必要であるが、Eclipse Java EE Platform にインストール済みのため、 依存パッケージを新たにインストールする必要はない。
「offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://takezoe.github.io/amateras-update-site/ を指定して、プラグインのArtifactsをダウンロードする。
ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。
features、plugins ディレクトリの下に複数のバージョンのjarファイル が存在するので、ファイル名が下記のパターンに一致するものだけを残し、 それ以外のファイルを削除する。なお、${VERSION} は、プラグインのバージョン を表す。
AsciiDoc、PlantUML の編集やプレビューを行うプラグイン
ソースコードのサイト https://github.com/de-jcup/eclipse-asciidoctor-editor にアクセスして、バージョンを確認する。
「offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://de-jcup.github.io/update-site-eclipse-asciidoctor-editor/update-site/ を指定して、プラグインのArtifactsをダウンロードする。
ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。
= 文書の表題
:sectnums:
== 章のタイトル
=== 節のタイトル
本文 +
行末に + (スペースの後ろに + )をつけるとそこで改行される。 +
文章の表題の次の行に「:sectnums:」を書くと、章は番号付きで表示される。
1行空けると段落になる。
コメントは行頭に「//」を書く
// この行はコメントです
=== 箇条書きとチェックリスト
. 番号付き箇条書き +
箇条書きの後ろに「 +」を書くとそこで改行され、続きはインデント付きで表示
される。
.. 番号付き箇条書き(レベル2) +
箇条書きを終えるには、空行に続けてコメント行を書く
// 箇条書きを終えるためのコメント行
* 番号なしの箇条書き +
番号付き箇条書きと同様、箇条書きの後ろに「 +」を書くとそこで改行される
** 番号なしの箇条書き(レベル2)
// チェックリスト
.チェックリストのタイトル
- [ ] チェックリスト(チェックなし)
- [*] チェックリスト(チェックあり)
- [x] チェックリスト(チェックあり)
=== 表
.表のタイトル
|===
| ヘッダ1 | ヘッダ2
| 1行目の項目1 | 1行目の項目2
| 2行目の項目1 | 2行目の項目2 +
「 +」の後に改行するとそこで改行して表示する
|===
=== 文字の修飾
. 文字の強調 +
行頭またはスペースを空けて* で囲むと *その部分が強調表示される。*
「*」と囲んだ文字の前後にスペースを入れないこと
. {plus}の表示 +
\{plus} と書くと{plus}を表示する
. マーカー表示 +
行頭またはスペースを空けて # で囲むと #その部分はマーカー表示される。#
「#」と囲んだ文字の前後にスペースを入れないこと
. 下線表示 +
行頭またはスペースを空けて \[.underline]に続けて # で囲んだ文字を書くと、
[.underline]#その部分が下線表示される。#
「#」で囲んだ文字の前後にスペースを入れないこと[asciidoc.adoc]
PlantUMLは、GUIで作図するのではなく、テキストファイルにダイアグラムの情報を 記述する。ファイルの拡張子は「.pu」とする。以下、各種ダイアグラムの記述方法を 示す。
@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]
Eclipseの表示をローカライズするプラグイン
https://download.eclipse.org/technology/babel/babel_language_packs/latest/index.php#ja にアクセスして、「Language: Japanese」に列挙されているZIPファイル全てを ダウンロードする。
以下のディレクトリーの下でダウンロードした zip ファイルを解凍する。
dropins/BabelLanguagePack-ja_x.xx.x.v<年月日時分>
解凍したファイルの eclipse/features、eclipse/plugins ディレクトリの下にある 「*.sdk.*」ファイルを削除する。
Javaのソースコードをチェックするプラグイン
以下のコマンドを実行し、表示される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 ...
「offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://checkstyle.org/eclipse-cs-update-site/releases/バージョン を指定して、プラグインのArtifactsをダウンロードする。
ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。
修正が終わったら、「OK」ボタンを押して設定変更画面を閉じ、Checkstyle画面に 戻る。
https://www.eclipse.org/cdt/downloads.php より、cdt-x.x.x.zip を ダウンロードする。
dropins/cdt-x.x.x/eclipse
「offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに http://eclipse-color-theme.github.io/update を指定して、プラグインのArtifactsをダウンロードする。
ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。
GitHub - guari/eclipse-ui-theme: Dark UI Theme for Eclipse 4+ より com.github.eclipseuitheme.moonrise_x.x.x.jar をダウンロードする。
以下のディレクトリーの下にダウンロードした jar ファイルを配置する。
dropins/<Eclipse Color Themeのパッケージ名>/eclipse/plugins
「offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://download.eclipse.org/technology/dltk/updates-nightly/を指定 して、プラグインのArtifactsをダウンロードする。
ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。なお、配置する ファイルは、ファイル名が以下のパターンに一致するものに限る。
features、plugins ディレクトリー配下の「*.sdk_*」、「*.source_*」、 「*.tests_*」ファイルを削除する。
「offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://download.eclipse.org/tools/pdt/updates/ を指定して、プラグインのArtifactsをダウンロードする。
ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。
features、plugins ディレクトリー配下の「*.sdk_*」、「*.source_*」、 「*.gz」ファイルを削除する。
Eclipse DLTKの手順に従って、Eclipse Dynamic Languages Toolkit の site アーカイブをダウンロードする。
php、php-pecl-xdebug パッケージをインストールする。
Windowsの場合は、Xdebug を以下のようにインストールする。
zend_extension = <xdebugのDLLのパス>
php.ini またはそこから読み込まれる設定ファイルに以下の設定をする。
xdebug.remote_enable = true xdebug.remote_connect_back = true xdebug.remote_port = 9000
Xdebug のクライアント(Eclipse)からのリモート・デバッグを可能にして、 PHPの Web アプリケーションのデバッグができるようにする。
サーバーが Xdebug のクライアント(Eclipse)に接続するためのIPアドレス は、HTTPのリクエストから取得するようにして、Xdebugのクライアントの IPアドレスを固定しないようにする。
サーバーが Xdebug のクライアント(Eclipse)に接続ためのポート番号を 設定る。既定値は 9000 なので規定値を使用する場合は設定を省略できる。
Webアプリケーション・サーバーで実行されている PHP のアプリケーションを デバッグできるようにするため、PHP Development Tools Plugin の設定をする。 以下は、Fedora の設定である。他の環境の場合は適切に読み替えること。
PHP の Webアプリケーションが動作している Server の情報を登録する。
Server の一覧表示で表示される名前を設定する。
サーバー名、ポート暗号までの URL を設定する。
例:http://localhost:8080
空白のままで良い
ドロップダウンから「Xdebug」を選択する。
Server が Xdebug のクライアント(Eclipse)に接続するポート番号を 設定する。Xdebug の既定値 9000 以外のポート番号を使用する場合は、 Application Server の Xdebug の設定値と同じポート番号を設定すること。
既定値(空白)のままで良い。
PHP Web Server は、既に起動している Web Application Server (Apache httpd、 PHP Built-in Server など)に接続して、PHP のWebアプリケーションをデバッグ することが可能である。デバッグの構成手順は以下のとおり。
ドロップダウンから接続先のサーバー(「Servers の設定」で作成したもの) を選択する。
「Browse」ボタンを押して、ポップアップしたダイアログから最初にアクセス するURLに対応するコンテンツをPHPプロジェクトのファイルの中から選択 する。
「File:」で設定したPHPプロジェクトのファイルに対応した Web アプリケーション・サーバの URL が自動表示される。この URL とは別の URL を設定する場合は、「Auto Generate」のチェックを外して、 サーバー名、ポート番号より後ろの URI を設定すること。
このチェックが付いていると、PHPのファイルにアクセスするたびに、 1行目で停止する。ブレークポイントの設定位置まで停止させたくない 場合は、このチェックを外すこと。
既定値(空白)のままで良い。
PHPファイルを直接実行してデバッグしたり、PHP Built-in Server を実行したり するための PHP Development Tools Plugin の設定をする。
Eclipseのメニューから「ウィンドウ」⇒「設定」を選択して、「設定」画面を 開き、以下の設定をする。
php実行ファイルのパス(/usr/bin/php)を設定する
/etc/php.ini を設定する
/etc/php.ini を使用する場合はチェックを付ける。Xdebug を使用する 場合はチェックをつけること
ドロップダウンリストから「Xdebug」を選択する
「設定」画面のナビゲーションから「PHP」⇒「Validation」を選択して、 以下の設定をする。
文法チェックのPHPバージョンを指定する。PHP Built-in Server でサーバで 構成するリソースの選択/解除が出来ない場合は、PHPのバージョンを下げて みる。
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 は以下の手順で作成する。
Emonic (Eclipse-Mono-Integration) is a Eclipse-Plugin for C#.
2010-01-07 以降更新がない。EclipseでC#のエディタが使える程度と考えた方が良い。
https://sourceforge.net/projects/emonic/files/latest/download?source=directory をダウンロードする。
以下のディレクトリーの下でダウンロードした zip ファイルを解凍する。
dropins/emonic_0.4.0/eclipse
ソースコードなしのJavaバイトコードからソースコードを表示するプラグイン
Releases · ecd-plugin/ecd · GitHub にアクセスして、 com.github.ecd-plugin.update-3.x.x.zip をダウンロードする。
以下のディレクトリーの下でダウンロードした zip ファイルを解凍する。
dropins/enhanced-class-decompiler-3.x.x.yyyyMMddhhmm/eclipse
ERモデルエディタのプラグイン
このEclipse Pluginは、Linux OSでは動作しない。ER Masterを開こうとすると エラーが発生する。
「offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに http://ermaster.sourceforge.net/update-site/ を指定して、プラグインのArtifactsをダウンロードする。
ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。
features、plugins ディレクトリの下に複数のバージョンのjarファイル が存在するので、ファイル名が下記のパターンに一致するものだけを残し、 それ以外のファイルを削除する。なお、${VERSION} は、プラグインのバージョン を表す。
JGitはgitのJava実装である。JGit LFS は、JGitでGitのLFS(Large File Storage)の 機能を追加するpluginである。
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 は、ファイル名に付けられた年月日時分の数値を表す。
以下のディレクトリーの下で、ダウンロードした zip ファイルを解凍する。
dropins/org.eclipse.jgit.lfs_x.x.x.<年月日時分>-r/eclipse
Markdown のテキスト編集とプレビュー機能を提供する Eclipse プラグイン。
「offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://nodeclipse.github.io/updates/markdown/ を指定して、プラグインのArtifactsをダウンロードする。
ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。
https://github.com/winterstein/Eclipse-Markdown-Editor-Plugin/releases にアクセスして、Assets の zip ファイル名からバージョンを確認する。
Node.js の開発環境を提供する Eclipse プラグイン。 https://nodeclipse.github.io/updates/ の記載内容に従って、Eclipse plugin のインストールと設定を行う。
https://sourceforge.net/projects/nodeclipse/files/latest/downloadより org.nodeclipse.site-1.0.2-201509250223.zip をダウンロードする。
dropins/org.nodeclipse.site-1.0.2-201509250223/eclipse
解凍先ディレクトリの下で、下記のディレクトリー、ファイルを削除する。
以下のコマンドを実行して、Node.js の実行に必要なパッケージをインストール する。
# dnf install nodejs npm
以下のコマンドを実行して、Node.js の開発に必要な Node.js パッケージを インストールする。
# npm install -g nodeclipse express express-generator
Pythonの開発環境を提供するプラグイン
「offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://www.pydev.org/update_sites/13.0.2 を指定して、プラグインのArtifactsをダウンロードする。
ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。
features、plugins ディレクトリー配下の「*.source_*」ファイルを削除する。
Javaの潜在的なバグをチェックするプラグイン。 FindBugsの開発が停止したため、その後継としてSpotBugs が誕生した。
「offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://spotbugs.github.io/eclipse/ を指定して、プラグインのArtifactsをダウンロードする。
ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。
Eclipse Corrosion provides development tools for Rust and Cargo inside the Eclipse IDE.
https://projects.eclipse.org/projects/science.statet/downloadsより 「4.x」のリンクをクリックして「StatET 4.x - Downloads」のページを開き、 「Archive of Update Site」のリンクから Update Site の zip ファイルを ダウンロードする。
dropins/tatet-x.x.x-<年月日時分>-r/eclipse
解凍先のディレクトリーの下で、features、plugins ディレクトリーを除く ファイル、ディレクトリーを削除する。
様々なプログラミング言語に対応したステップカウンタ
Releases · takezoe/stepcounter · GitHub より jp.sf.amateras.stepcounter_3.x.x.年月日時分.jar をダウンロードする。
以下のディレクトリーの下にダウンロードした jar ファイルを配置する。
dropins/jp.sf.amateras.stepcounter_3.x.x/eclipse/plugins
SVNクライアントの機能を提供するプラグイン
「offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://download.eclipse.org/technology/subversive/updates/release/ より確認した最新バージョンの URL を指定して、プラグインのArtifactsを ダウンロードする。
ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。
features、plugins ディレクトリー配下の「*.source_*」ファイルを削除する
SubversiveとSVNサーバーを接続するためのプラグイン
「offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに http://eclipse.svnkit.com/1.10.x を指定して、プラグインのArtifactsをダウンロードする。プラグインの バージョンは、 SVNKit :: Download で確認すること。
ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。
SubversiveとSVNサーバーを接続するためのプラグイン
「offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://arsysop.github.io/svn/release/ を指定して、プラグインのArtifactsをダウンロードする。
ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。 なお、配置するファイルは、ファイル名が以下のパターンに一致するものに 限る。
UMLet は軽量のUML作図ツールである。
https://www.umlet.com/download/ から最新バージョンのディレクトリを 選択して、「umlet-eclipse-p2-x.x.x.zip」をダウンロードする。
dropins/umlet-eclipse-p2-x.x.x
解凍先ディレクトリーの下で、features、plugins ディレクトリーを除くファイル、 ディレクトリーを削除する。
Eclipse-2022-12とUMLet-15.0.0の組み合わせの場合、プロジェクトを選択 → 右クリックメニュー → Update Project の操作でエラーが発生する。
https://visualvm.github.io/download.html より zip形式のVisualVM x.x をダウンロードして、インストール先ディレクトリの下で解凍する。
https://visualvm.github.io/download.html より IDE Integrationsを クリックして、「Eclipse」の「plugin」のリンクよりzip形式のアーカイブ (visualvm_launcher_u3_eclipse.zip) をダウンロードする。
VisualVMインストールディレクトリ/bin/visualvm を設定する
JDK (JREではない)のホームディレクトリを設定する。openjdk-devel パッケージがインストーるされている場合は、初期設定されている
Eclipseの「実行構成の設定」メニューから、Javaアプリケーションの実行構成を 設定する。
「offline installing plugin」の「Artifactsの取得」手順に従って、 Update Site のURLに https://download.eclipse.org/windowbuilder/updates/release/version/ を指定して、プラグインのArtifactsをダウンロードする。 なお、配置するファイルは、ファイル名が以下のパターンに一致するものに限る。
ダウンロードしたファイルの features、plugins ディレクトリを dropins/パッケージ名/eclipse ディレクトリの下に配置する。
Gitは分散型バージョン管理システムであり、以下のものから構成される。
各開発者が変更した内容を最終的にバージョン管理するリポジトリ
開発者が作業するホストごとに存在するリポジトリで、リモート・リポジトリの 複製により作成される。開発者はファイルの変更をローカル・リポジトリで 管理して、作業が終わった段階でその変更内容をリモート・リポジトリに反映 する運用となる。
Gitリポジトリ(リモート/ローカル共に)は、ファイルの変更履歴を blob、tree、 commit の3種類のオブジェクトで管理している。
ファイルのスナップショットを保持する。ファイルが変更される都度ファイルの スナップショットを作成してこれを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を参照のこと。
ローカル・リポジトリで管理されているファイル(blob オブジェクト)を展開して 配置するディレクトリ。ファイルの編集作業はこの作業ディレクトリで行う。
作業ディレクトリの直下に存在するディレクトリで、リポジトリを管理するため のデータ(blob、tree、commitの各オブジェクトとそれ以外のメタデータ)、 及びステージングのデータが配置される。リモート・リポジトリから複製を 行った場合は、その内容が .git ディレクトリに配置される。
ブランチは、あるコミットへのポインタである。ローカル・リポジトリで 「git branch branch-name」コマンドを実行することにより現在参照している ブランチから新しいブランチを作成することができる。
[before commit] [after commit]
HEAD ============> HEAD
↓ ↓
[branch] master ==========> master
↓ ↓
+-----+ +-----+
[commit] |98ca9| <--------- |34ac2|
+-----+ +-----+[コミット前後のブランチの参照先]
リポジトリを新規に作成した時に存在するブランチ。複数の開発者がいる 場合は、master ブランチを直接更新せず、開発者ごとにブランチを作成して そこで変更を管理するのが一般的である。
現在参照しているブランチのポインタ。ブランチを省略してリポジトリへの 操作を行うと、HEADブランチに対する操作となる。
「git fetch」コマンドによりリモート・リポジトリから取得したブランチを 参照するブランチ。
マージは、あるブランチの変更を現在のブランチ(HEAD)に適用することである。 マージには、3方向マージと fast-foward の2つの種類がある。
マージ元のブランチと現在のブランチ(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方向マージ を行っている。
マージ元と現在のブランチ(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 はローカル・リポジトリでのマージの他に、ローカル・リポジトリの ブランチをリモート・リポジトリのブランチにマージ(つまりプッシュ)する場合 でも使用可能なマージ方法である。
開発者がファイルの更新を行う場合の代表的な手順を以下に示す。
以下のコマンドを実行して、gitをインストールする。
# dnf install git
リポジトリを新規に作成(内容は空の状態)する場合は、 「git init [--bare ] [ディレクトリ]」を実行する。
ローカル・リポジトリの取得元、及び変更内容の適用先となるリポジトリ
+----------------+ 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)--> | | +----------------+ +-----------------+
ローカル・リポジトリは開発者が作業をするリポジトリである。 ローカル・リポジトリの運用例を以下に示す。
ローカル・リポジトリを作成するディレクトリに移動して、 「git clolne remote-repo-url」を実行して、リモート・リポジトリの クローンをローカル・リポジトリに作成する。このコマンドを実行すると、 カレント・ディレクトリの下にリモート・リポジトリの名前(.gitを除く)で 作業ディレクトリが作成され、その下の「.git」ディレクトリに ローカル・リポジトリが作成される。
リモート・リポジトリをクローンしたら、以下の手順でユーザーの email アドレス、ユーザー名を設定すること。
作業ディレクトリで「git push」を実行して、ローカル・リポジトリの変更内容を リモート・リポジトリへ反映する。push コマンドを実行すると、 ローカル・リポジトリのブランチ(指定がない場合はHEADブランチ)を リモート・リポジトリのブランチに fast-forward でマージする。
+-----------------+ +-----+ +----------------+
|working directory| --(add)---------> |index| --(commit)--> |local repository|
+-----------------+ --(commit -a)-+-> +-----+ +--> +----------------+
| |
+--------------------+用語の説明
リポジトリのコンテンツが配置されているディレクトリ
作業ディレクトリに配置されたファイルは、「追跡されている」 「追跡されていない」の2通りの状態がある。「追跡されている」ファイルは 直近のコミットのスナップショットに存在するファイルのことである。
ステージされた内容の保管場所。作業ディレクトリのファイルの変更を ローカル・リポジトリにコミットするためには、その前に index に 変更された ファイルを反映する(これをステージするという)必要がある。
local リポジトリに対する操作
コマンド「git add file [file ...]」を実行して、作業ディレクトリの ファイルを index に追加してローカル・リポジトリにコミットできるように する。git add コマンド実行後に作業ディレクトリのファイルが変更され、 その内容もローカル・リポジトリにコミットしたい場合は、再度「git add」 コマンドを実行する必要がある。
コマンド「git rm file」を実行して、作業ディレクトリからファイルを 削除して indexからも削除する。コマンド「git rm -r dir」を実行すると、 作業ディレクトリからディレクトリを削除して index からも削除した ディレクトリ配下のファイルを再帰的に削除する。
git commit コマンドを実行して、ステージされたもの(indexの内容)を local repository に反映する。また、「git commit -a」を実行すると、以下のindex に対する操作(ステージ)を実行した後に local repository にコミットする。
+------------------+ +-----+ +----------------+
|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つ前の状態になる。
「git reset --mixed [commit名]」を実行すると、local repository を commit名 でコミットされた状態に戻した上で、index の内容をクリアするが 作業ディレクトリの状態は変更はしない。これは、モードを指定しない場合の デフォルトの挙動である。
「git reset --hard [commit名]」を実行すると、local repository を commit名でコミットされた状態に戻した上で、indexをクリアし、 作業ディレクトリの内容を commit名でコミットしたバージョンの スナップショットの状態にする。つまり、作業ディレクトリのcommit名で コミットした以降の変更内容が失われることになる。
ステージの取消。index がクリアされるだけで、local repository のコミットの 状態や、作業ディレクトリのファイルの変更は発生しない。
前回のコミット以降の変更を全て破棄。index がクリアされた上、 作業ディレクトリの内容が前回コミットされたときのリポジトリの スナップショットの内容に置き換わる。
コマンド「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 コマンドで ブランチを作成しておくこと。
コマンド「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 ブランチを追跡するローカルブランチを作成して切り 替える。
$ git branch featureA featureB * master
コマンド「git branch」を実行すると、ブランチ名の一覧が表示され、checkout されているブランチの前に「*」が表示される。
$git branch -vv * master 7d89024 [origin/master] pom.xmlその他を修正
コマンド「git branch -vv」を実行すると、ブランチ名の他に最新コミットの ハッシュ値、コミットメッセージ、アップストリーム・ブランチ(リモートの ブランチ名)が表示される。
同一のファイルをマージ元、マージ先(HEADブランチ)の2つのブランチで編集した 場合(特に同一行をそれぞれのブランチで編集してしまった場合)、自動的な ファイルのマージに失敗して、ファイルの競合が発生する場合がある。その場合の 対処手順について説明する。
マージを実行する前に現在のブランチの変更をコミットして、マージが失敗した 時にマージ実行前の状態に戻せるようにする。
コマンド実行後に以下のようなメッセージが表示される。
Auto-merging <ファイルのパス> CONFLICT (content): Merge conflict in <ファイルのパス> Automatic merge failed; fix conflicts and then commit the result.
作業ディレクトリの競合が発生したファイルに、競合が発生した部分について 下記の形式でその内容が記録される。下記の例は topic01 ブランチを現在の ブランチ(HEAD)にマージしようとした場合の例である。
<<<<<<< HEAD 現在のブランチ(HEAD)で編集した内容 ======= マージ元ブランチで編集した内容 >>>>>>> topic01
競合が発生しなかったファイルはステージ済となり、競合が発生したファイルは 修正済の状態となる。コミットは行われない。
競合が発生したファイルを開き、競合が発生した部分の記録を見ながら、変更を 取り込む部分を残し、それ以外の部分(「<<<<」「=======」「>>>>」 で始まる部分と、取り込まない変更)を削除する。
$ git add <file> ...
$ git merge -Xtheirs <マージ元ブランチ名>
バイナリファイルの場合は、ファイル自体がマージ元ブランチのファイルに 置き換えられる。
$ git merge -Xours <マージ先ブランチ名>
バイナリファイルの場合は、ファイル自体が現在のブランチのファイルに 置き換えられる。
マージ結果のコミットが行われていないので、以下のコマンドを実行してマージ 実行前の状態に戻す。
$ git reset --hard HEAD
マージ結果がコミットされているので、以下のコマンドを実行して直前の コミットを取り消してマージ前の状態に戻す。
$ git reset --hard HEAD^
$ git merge -s ours <マージ元ブランチ>
これは現在のブランチ(HEAD)の変更をマージ元ブランチとの共通祖先のコミットまで 遡って取り消して、マージ先ブランチを HEAD ブランチに fast-forward するという ことである。従って以下の手順を実行する。
「マージ先ブランチの変更をマージせずに現在のブランチをマージ結果とする場合」 と同様な手順を実行する。
$ git reset --hard <共通祖先のコミットID>
または、以下の「git revert」コマンドを実行して、マージ元ブランチとの 共通祖先のコミットと同じ内容のコミットを新規に作成してHEADブランチが 参照するようにする。
$ git revert <共通祖先のコミットID>
$ git merge <マージ元ブランチ名>
リモート・リポジトリのマージを開発者任せにすると、マージの間違いなどで ファイルの修正の取り込みが失敗する恐れがある。これは開発規模が大きくなるほど 顕在化しやすい。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
開発者のローカル・リポジトリの現在のブランチ(開発ブランチ)を リモート・リポジトリの開発ブランチにプッシュする。
$ git push -u origin <開発ブランチ名>
以下のコマンドを実行した場合は、リモート・リポジトリの 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 オプションはパッチの出力先ディレクトリを指定するためのオプションで ある。
メンテナのローカル・リポジトリにて、現在のブランチ(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
「git am」コマンドでパッチの適用時に競合(conflict)が発生した場合は、以下の 操作をする。
「git am --skip」を実行して、パッチを適用せずに次のパッチの処理に移る
「git am --abort」を実行して、マージを取りやめる
開発者のローカル・リポジトリの現在のブランチ(開発ブランチ)を リモート・リポジトリの開発ブランチにプッシュする。
$ git push -u origin <開発ブランチ名>
-u オプションの指定によって、以降は origin の現在のブランチは 開発ブランチを参照するようになる。
$ git request-pull origin/master origin <開発ブランチ名> | tee <file-path>
「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(-)出力内容には以下の情報が含まれている。
「git request-pull」コマンドの出力結果より、リポジトリの変更履歴などを 確認して、変更を master ブランチにマージしてよいかを判断する。
メンテナのローカル・リポジトリにて、現在のブランチ(HEAD)が master ブランチを指すようにして、以下のコマンドを実行する。
(a) $ git pull (b) $ git fetch origin <開発ブランチ名> (c) $ git merge origin/<開発ブランチ名> (d) $ git push
「リモート」とは、リモート・リポジトリ の URL の短縮名のことである。
コマンド「git remote [-v]」を実行すると、設定されているリモートを確認する ことができる。-v オプションを付けない場合は、設定されているリモートの一覧 が表示される。-v オプションを指定すると、リモートとリモート・リポジトリの URLが表示される。
「git remote add shotname url」を実行すると、リモート(短縮名)と リモート・リポジトリの URL が追加される。
リモート・リポジトリを clone した場合は、リモート(短縮名)origin に リモート・リポジトリの URL が設定される。
チーム作業において、開発者が 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図の説明
[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)削除 開発者は、C1 コミットから featureA(トピックブランチ)を作成する。
トピックスブランチ作成後に master ブランチでコミットが作成される。
開発者は、ローカル・リポジトリのトピックブランチ(featureA)にファイルの 変更をコミットする。
開発者は、リモート・リポジトリにトピックブランチ(featureA)をプッシュ する。
開発者は、メンテナにトピックブランチの変更を master ブランチに取り込む ように依頼する。
メンテナは、開発者から変更のマージ依頼を受けてトピックブランチ (featrureA)のコミット C3 を master ブランチにマージする。
開発者は、リポジトリ管理者からマージ完了の通知を受け取ったら、 リモート・リポジトリ、ローカルリポジトリの両方からトピックブランチ (featureA)を削除する。
以下のコマンドは、トピックスブランチを作成した後、リモート・リポジトリの master ブランチの変更をマージしている。
(1) $ git checkout -b featureA (2) $ git fetch (3) $ git merge --no-commit --squash origin/master
git merge コマンドのオプションの説明
マージ結果をステージするがコミットはしない
マージ元の変更を1つのコミットにまとめてマージ先の先頭にマージする
(1) $ git add <更新したファイルのパス> [...] (2) $ git commit -m "作業内容のメッセージ"
(1) $ git push origin featureA
使用するコマンドは、Requesting Merge For Remote Repository を 参照のこと
使用するコマンドは、Requesting Merge For Remote Repository を 参照のこと
(1) $ git checkout master (2) $ git push --delete origin featureA (3) $ git branch -D featureA
「git branch」コマンドの -D オプションは、ブランチを強制的に削除する ためのオプションである。-d オプションを指定した場合は、featureA ブランチを分岐元の master ブランチにマージしていないため、削除が失敗 することに注意する。
[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開発者はリモート・リポジトリから長期稼働用ブランチを取得した後、 リモート・リポジトリの master ブランチで発生したコミット C2 をマージ する。
開発者は、ローカル・リポジトリの長期運用ブランチにファイルの変更を コミットする。
開発者は、リモート・リポジトリに長期稼働用ブランチをプッシュする。
開発者は、メンテナに長期化同様ブランチの変更を master ブランチにマージ するように依頼する。
メンテナは開発者から変更のマージ依頼を受けて長期稼働用ブランチのコミット C5 を master ブランチにマージする。
(1) $ git pull (2) $ git checkout -b featureB (3) $ git push origin featureB
(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) $ git add <更新したファイルのパス> [...] (2) $ git commit -m "作業内容のメッセージ"
(1) $ git push
使用するコマンドは、Requesting Merge For Remote Repository を 参照のこと
使用するコマンドは、Requesting Merge For Remote Repository を 参照のこと
git パッケージ以外に git に関連するパッケージを以下に示す。
gitkはグラフィカルな履歴ビュワーで、過去のコミットの履歴をグラフィカルに 表示する。以下のコマンドを実行して、gitkパッケージをインストールする。
# dnf install gitk
git-guiは、indexをステージングされていないもの(git addされていない変更)、 ステージングされているもの(git addされた変更)に分けて表示し、 ステージングの状態を切り替えたり、ステージングされた変更をコミットしたり することができる。以下のコマンドを実行して、git-guiパッケージをインストール する。
# dnf install git-gui
$ git log <オプション> [<コミット>..<コミット>] [-- <ファイルパス> ...]
例:master^^^..master^ (masterブランチの3つ前のコミットから1つ前の コミットを表示する)
「git log」はリモート・リポジトリの履歴を表示する。ローカル・リポジトリに コミットしても「git push」でリモート・リポジトリに変更が反映して いなければ、ローカル・リポジトリの変更は履歴に表示されない。
remote repository にアクセスするコマンド(git push、git fetchなど)を実行 すると、その都度ユーザー名、パスワードの入力が要求される。認証情報を保存する ことによって、ユーザー名、パスワードの入力を抑止することができる。認証情報を 保存するための手順は、以下のとおり。
$ git config credential.helper store
上記のコマンドを実行すると、~/.git-credentials ファイルに保存された認証 情報を git コマンドが参照するようになる。
$ 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 (空行)
httpプロトコルでGitリポジトリにアクセスするための設定手順を説明する。
以下のコマンドを実行して httpd パッケージをインストールする(httpd未導入の場合)
# dnf install httpd
以下のコマンドを実行して、gitwebパッケージをインストールする。
# dnf install gitweb
既に /etc/httpd/conf.d/gitweb.conf ファイルが存在する場合は、インストール された gitweb.conf ファイルの名前が「gitweb.conf.rpmsave」となるので、既に 存在している gitweb.conf ファイルの名前を変更して、gitweb.conf.rpmsave ファイルの名前を 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と被らないようにする。
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
/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 -bc /etc/httpd/conf/htpasswd.git <ユーザー名> <パスワード>
# htpasswd -b /etc/httpd/conf/htpasswd.git <ユーザー名> <パスワード>
# htpasswd -D /etc/httpd/conf/htpasswd.git <ユーザー名>
git-lfs-fcgi は、bcrypt encryption を使用するので、パスワードの作成、 変更する場合は、htpasswd コマンドに -B オプションを指定すること。
以下のコマンドを実行して、httpdを起動する。
# systemctl start httpd
なお、httpdの設定を変更した場合は、コマンド「systemctl restart httpd」を 実行してhttpdを再起動すること。
httpdの実行プログラムに対して、gitの実行プログラムと同様のSELinuxの アクセス権を /var/lib/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を設定することにする。
ioctl read write create getattr setattr lock unlink link rename add_name remove_name reparent search rmdir open
entrypoint ioctl read write create getattr setattr lock map execute execute_no_trans append unlink link rename open
コマンド「git clone GitリポジトリのURL」を実行した後に、SELinux通知 ブラウザーで表示されるメッセージを確認し、「追加情報」の 「ソースコンテキスト」よりプロセスのラベルを確認する。SELinux通知 ブラウザの代わりにコマンドで確認する場合は、SELinuxの通知が発生した時間を 指定して、以下のコマンドを実行する。
$ sudo ausearch -ts MM/DD/YY hh:mm:dd | audit2allow -a
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のプロセスの ラベルは、「{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パッケージのインストールが必要だが、デフォルトでは インストールされていないので追加でインストールすること。
以下のコマンドを実行して、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
Gitの clone、push などリモート・リポジトリに対するコマンドを実行し、 SELinuxの通知が発生したら、「httpdのプロセスのラベルを確認」に戻って、 TEファイルにプロセスのラベルを追加する。
Gitリポジトリを配置するディレクトリ「/var/lib/git」を作成する。
# mkdir -p /var/lib/git
複数のユーザーがGitリポジトリを使用できるように、gitusers グループを作成 する。
# groupadd gitusers
以下のコマンドを実行して、Gitリポジトリの親ディレクトリに gitusers グループ のユーザーがアクセスできるようにする。
# chmod 775 /var/lib/git # chown apache:gitusers /var/lib/git
/var/lib/git ディレクトリの下にリモート・リポジトリを作成して、そこに http で アクセスできるようにする。
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/
hooksディレクトリにあるpost-update.sample スクリプトの名前を変更して、 post-update スクリプトが動作できるようにする。
# cd /var/lib/git/<リポジトリ名>.git/hooks # cp -dpvi post-update.sample post-update # chmod a+x post-update
hooksディレクトリの下にupdateファイルを作成して、update script source に示したスクリプトを記述する。また、以下のコマンドを実行して、update ファイルのオーナー、グループの設定と、実行権限の設定をする。
# chown apache:gitusers <updateファイルのパス> # chmod a+x <updateファイルのパス>
# sudo -u apache git config --file config http.receivepack true
Git本家の解説ドキュメント。httpでリモート・リポジトリをcloneできるように するための簡単な設定手順が紹介されている。
Git リポジトリへのアクセスをhttpで行うための設定の解説。clone / push だけでなくgitwebを使用したブラウジングの話もある。
コマンド「git init <リポジトリ名>」を実行して、先にローカル・リポジトリを 作成した後に、リモート・リポジトリを設定する場合は以下のコマンドを実行する。
$ git remote add origin http://<ユーザー名>:<パスワード>@<ホスト名>/<リポジトリのパス> $ git push --set-upstream origin master
$ 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>
hooksディレクトリに update ファイルを作成し、下記の内容を設定する。この hook script は、adminusersで指定されたユーザー以外のユーザーがbranchesで 指定されたブランチに push しようとしたときにそれを抑止するためのスクリプト である。
#!/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
doneGit LFS (Git Large File Storage) は、大容量のファイルを Git で扱うための拡張 機能である。Git LFS は、大容量のファイルを git に格納するときに、Git リポジトリに直接ファイルを格納せず、「text pointer」にObject IDなどのメタ情報 を格納し、ファイル本体は Git リポジトリとは別の Git LFS サーバに格納する。
Git LFS サーバを構築するために、git-lfs-fcgi パッケージをビルドして インストールする。
プロジェクトの README.md に 「Warning: Not production ready」と記載されて いる。README.md を熟読して制限事項を把握した上で運用すること。
以下のURLからソースファイルをダウンロードする。
ビルドに必要な以下のパッケージをインストールする。
ビルドに必要なパッケージをインストールするコマンドは以下のとおり。
# dnf install bison cmake flex fcgi-devel gcc-c++ json-c-devel \
libsqlite3x-devel make openssl-develCentOS 7の場合は、以下のコマンドを実行する。
# yum install bison cmake3 flex fcgi-devel gcc-c++ json-c-devel \
libsqlite3x-devel make openssl-devel以下の内容を記述する。
# 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 ファイルの処理内容は以下のとおり。
以下のコマンドを実行して、パッケージをビルドする。
$ QA_RPATHS=$(( 0x0002|0x0010 )) rpmbuild -ba ~/rpmbuild/SPECS/git-lfs-fcgi.spec
上記のコマンドを実行すると、以下の場所に RPMファイル(.rpm)、SRPMファイル (.src.rpm)が生成される。
~/rpmbuild/RPMS/x86_64/ ディレクトリーに移動し、以下のコマンドを実行して、 パッケージをインストールする。
$ sudo dnf install ./git-lfs-fcgi-x.x.x-x.fcxx_x86_64.rpm
socketファイルが /var/lib ディレクトリ配下に存在するため、httpd プロセスが /var/lib ディレクトリ配下にある socket ファイルへの書き込みを許可する設定を する必要がある。以下の手順で SELinuxのパッケージを作成してインストールする。
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]
$ checkmodule -m -o my-git-lfs-fcgi.mod my-git-lfs-fcgi.te
$ semodule_package -o my-git-lfs-fcgi.pp -m my-git-lfs-fcgi.mod
# semodule -i my-git-lfs-fcgi.pp
既定値のままで良い
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」の 形式となっている場合は、リポジトリを新規に追加しても設定を追加する必要が ないようになっている。
https://github.com/soundsrc/git-lfs-fcgi には、ProxyPass の転送先 URLにパラメータ「enablereuse=on」を設定するように記載されている。 しかしその場合は、数回 Git LFS のリクエストを実行すると、以後の リクエストはタイムアウトとなってしまう事象が発生するため、パラメータ に「enablereuse=off」を設定するようにした。
HTTP の Authorization ヘッダの設定内容を HTTP_AUTHORIZATION 環境変数に 設定して、FastCGI に認証情報を渡す設定を行っている。なお、httpdの設定 で既に「<Location /git/>」ディレクティブの設定が存在する場合 (例えば、Git Smart HTTP が構成している場合等)は、SetEnvIf ディレクティブの設定をその中で行った方が良い。
Git LFS サーバのベースURL(http://<host-name>)を設定する
既定値のままで良い
※ Gitリポジトリを追加したときに編集する
Gitリポジトリを追加したら、それに対応する Git LFS を以下のように設定する。
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"
}/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 リポジトリの場合の設定例は以下のとおり。
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
Initializing git remote repositoryの手順に従って gitリモート・リポジトリ を作成する。
git-lfs パッケージは Git LFS のクライアントである git lfs コマンドを 提供するパッケージである。
$ git clone http://<hostname>/git/<repository-name>.git
作業ツリー(作業ディレクトリの最上位ディレクトリ)の .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
以下に示す操作は、ローカル・リポジトリの作業ツリー直下のディレクトリで行う こと。
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 からのファイルの取得が行われる。
以下に示す操作は、ローカル・リポジトリの作業ツリー直下おディレクトリで行う こと。
以下のコマンドを実行して、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
Git LFS 格納対象のファイルをロック可能にしたい場合は、対象ファイルの 拡張子を指定して、以下のコマンドを実行する。
$ git lfs track "*.<suffix>" --lockable
*.<suffix> lockable
ロック対象のファイルを編集可能にするためには、以下のコマンドを実行して ファイルをロックする。
$ git lfs lock <file-path>
このコマンドは以下の操作を実行する。
ロックされたファイルはローカル・リポジトリで編集してリモート・サーバに push することができるようになる。
ファイルのロックが不要になったら、以下のコマンドを実行してファイルの ロックを解除する。
$ git lfs unlock <file-path>
何らかの事情で他のユーザーがロックしたファイルを解除する必要がある場合は、 以下のように --force オプションを付けてファイルのロックを解除する。
$ git lfs unlock <file-path> --force
このコマンドは以下の操作を実行する。
$ git lfs locks
コマンド「git checkouit .」を実行(現在のブランチをチェックアウトする) すると、アンロックしたファイルを読み取り専用にすることができる。
https://github.com/ にアクセスして、画面右上の「Sign Up」をクリック して、以下の項目を入力する。
「Create account」ボタンをクリックして、アカウントを作成する。
必要に応じて以下の項目を設定する
git コマンドが「git pull URL」に変わるだけで、手順は clone と同じで ある。
「リポジトリの clone」と同様な手順で URL をクリップボードにコピーする
作成済みのリポジトリに関する Web Page を以下の手順で行うことができる。 なお、リポジトリの visibility が Public でないと サイトが表示されないので 注意すること。
https://<account-name>.github.io/<repo-name>/
なお、リポジトリの visibility が Private の場合は、上記の URL にアクセス すると、「There isn't a GitHub Pages site here.」のエラーが発生する。
以下の手順で GitHub Pages のブランチをローカルリポジトリで編集して、リモート リポジトリに push する。
https://about.gitlab.com/ にアクセスして、画面右上の「Register」を クリックして、以下の項目を入力して、「Register」ボタンをクリックする。
登録画面で入力したメールアドレスに確認メールが届くので、「Confirm your account」のリンクをクリックして表示される画面にパスワードを入力を入力して 「Sign in」をクリックする。
続いて表示される画面の項目を入力する。
以下の項目を入力して、「Continue」をクリックする。
My company or team、Just me のどちらかを選択する
Create a new project、Join a project のどちらかを選択する
以下の項目を入力して、「Continue」をクリックする。
以下の項目を入力して「Create project」をクリックする。 Group name、Project name は空白のままにして、後で設定することも 可能と思われる(未確認)。
「Ok. let(s go」をクリックする。
以上の設定が終わったら、「Register with tow-factor app」ボタンをクリック する。
2要素認証を設定すると、リポジトリへのアクセスにパスワードが使用できなく なるため、パスワードの変わりにアクセス・トークンを使用することになる。 以下の手順に従って、アクセス・トークンを作成する。
keytoolは、jdkに付属する公開鍵、非公開鍵管理ツールである。keytoolは、 jre_home/bin (jre_homeはJava Runtime Environmentのインストール ディレクトリ)に存在する。
秘密鍵、公開鍵、証明書等の保管は、keystoreと呼ばれるファイルで行われる。 以下の手順では、以下に示す3つのPKCS12形式のkeystoreを使用する。
keytoolでは、keystoreの形式の指定を省略すると、JKS(Java Key Store)の形式で keystoreを作成する。keystoreの形式は以下の観点で決めること。
JVM(Java Virtual Machine)が参照するためのkeystoreを作成する場合は、 JKS形式のkeystoreを使用する。
keystore、openssl と相互運用する場合は、この形式のkeystoreを使用する。 Apache httpd で SSL/TLS をサポートする場合は、keystoreから private key を取得するためにopensslコマンドを使用するので、keystoreはPKCS形式にした 方が良い。
自己認証局側で以下のコマンドを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」を指定する。
自己認証局側で以下のコマンドを実行して、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にインポートする。
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 <署名要求ファイル>
自己認証局側で以下のコマンドを実行して、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 でも使用することが可能である。
-ext SAN=DNS:<FQDNホスト名1>,DNS:<FQDNホスト名2>,...
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関連のパッケージが更新された場合に設定が元に戻る恐れがある。
SSLサーバー側で以下のコマンドを実行して、keystoreファイル「server.p12」 (keystoreファイルのパスワードが「storepasswd」)に別名「hostname」を指定 して、サーバー証明書の署名要求の応答ファイル「hostname.pem」をインポート する。
$ keytool -importcert -alias <hostname> -keystore server.p12 \ -storepass <password> -file <hostname>.pem
keystoreファイル、別名は、サーバー証明書の署名要求ファイルを作成したときと 同じものを指定すること。
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 コマンドで行うこと。
Apacht httpdでSSLの設定をする場合、サーバー証明書の他にprivate keyの設定も 必要だが、Java Key Store (JKS)からprivate keyをエクスポートする手段は提供 されていない。JKSに登録されている内容を一旦PKCS12形式のkeystoreにエクスポート し、そこからopensslコマンドによりprivate keyをエクスポートすることができる。
以下のコマンドを実行して、JKS形式のkeystoreから別名で登録されている内容を PKCS12形式のkeystoreにインポートする。
$ keytool -importkeystore -srcalias <インポート元別名> \ -srckeystore <インポート元keystoreファイル> -srcstoretype JKS \ -srcstorepass <インポート元keystoreパスワード> \ -destkeystore <インポート先keystoreファイル> -deststoretype PKCS12 \ -deststorepass <インポート先keystoreパスワード>
以下のコマンドを実行して、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パスワード>
Javaのjarファイルを成果物とするMavenプロジェクトをEclipseで新規に作成する 手順を説明する。
バイナリのjarファイル及びソースコードのjarファイルを生成し、以下のレポートを 出力するための設定例を示す。
<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>pom.xml にビルドに必要な情報、ビルド後に生成するリポートのの設定情報を記載 して、mvnコマンドを実行すると、Javaのjarファイルやwarファイルを作成し、 unit test(通常はjunit)を実行する。また、unit test実行後に、Javadoc、 unit testの実行結果、カバレッジなどのレポートを生成することができる。
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と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を指定すると、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ファイルが存在する。
親子関係のMavenプロジェクトの親プロジェクトで記述し、親子全体適用される buildタグのpluginを設定する。ここに記述されたpluginの設定は、 子プロジェクトで記述する必要なく使用することができる。
当該プロジェクトでjar、warファイル等をビルドするための設定を記述する。 またレポート出力用のプラグインについてMavenの各ゴールごとの挙動もここで 定義する。
各種レポートの出力を指示する。
pom.xmlを開き、以下のプラグインの設定を記述する。
※ jacoco-maven-pluginを動作させる場合、project/build/pluginMangement/plugins に記述すると動かない
これは、テストが失敗してもレポートを出力するための設定である。
jacoco-maven-pluginでカバレッジの情報を出力するために、 「project/build/plugins/plugin(jacoco-maven-plugin)/executions/execution/configuration/propertyName」 で設定したプロパティを参照(${jacocoArgs})すること。
特に設定する項目はない
groupId、artifactId、versionのみを設定する
groupId、artifactId、versionのみを設定する
EclipseのCheckstyleの設定で、設定をエクスポートしたファイルを指定 すると良い。
特に設定する項目はない。
<?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><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>parentプロジェクト配下のmoduleプロジェクト全てをビルド、jarなどの成果物の Maven ローカル・リポジトリへのインストール、サイトの配備を行うには、以下の 手順を実施する。
$ maven clean install site:site site:deploy
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を除外する場合は、手動で削除すること。
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>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 ディレクトリの下に 《ファイルのパス》で指定されたファイルがコピーされる。《ファイルのパス》は、 以下のように指定する。
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 はバージョン管理ツールの一つである。Gitはりビジョンをその時点での スナップショットとして扱うのに対して、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 パッケージをインストールすると、以下の設定が行われる。
/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>
設定したディレクティブの内容は、以下のとおり
URI に /svn を指定して httpd にアクセスした場合は、Subversionのリポジトリに 対する操作とする。
WebDAV を使用して、Apache httpd と Subversion のリポジトリとの通信をする。
Subversionのリポジトリの親ディレクトリーを /var/www/svn に設定する。
リポジトリアクセスは、Basic認証でユーザーの認証をする。
認証の名前を "Subversion repository" に設定する。
ユーザー人称に使用するパスワード・ファイル(ユーザー名とパスワードを格納した ファイル)を指定する。ユーザーの追加、パスワードの変更、ユーザーの削除は、 htpasswdコマンドを使用して行う。
htpasswd -b[c] /etc/httpd/conf/htpasswd.svn ユーザー名 パスワード
※ 初回(パスワード・ファイルが存在しない場合)は、c オプションを指定する
htpasswd -D /etc/httpd/conf/htpasswd.svn ユーザー名
アクセスを許可するグループを定義したグループ・ファイルを指定する。 グループ・ファイルには、以下の形式でグループ名とグループに所属する ユーザー名を設定する。
<group-name>: <user-name> <user-name> ...
リポジトリ別にアクセスを許可するグループ名を指定する。
以下のコマンドを実行して、リポジトリの親ディレクトリーを作成し、オーナーに apache ユーザー、及びグループを指定する。
# mkdir /var/www/svn # chown apache:apache /var/www/svn
以下のコマンドを実行して、リポジトリの親ディレクトリーとその配下のファイル、 ディレクトリに対して、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 オプションを指定すること。
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>