-
1. はじめに
- 1.1 バージョン管理について
- 1.2 Gitの簡単な歴史
- 1.3 Gitとは何か?
- 1.4 コマンドライン
- 1.5 Gitのインストール
- 1.6 Gitの初回セットアップ
- 1.7 ヘルプの入手
- 1.8 まとめ
-
2. Gitの基本
- 2.1 Gitリポジトリの取得
- 2.2 リポジトリへの変更の記録
- 2.3 コミット履歴の表示
- 2.4 操作の取り消し
- 2.5 リモートリポジトリの操作
- 2.6 タグ付け
- 2.7 Gitエイリアス
- 2.8 まとめ
-
3. Gitブランチ
- 3.1 ブランチの概要
- 3.2 基本的なブランチとマージ
- 3.3 ブランチ管理
- 3.4 ブランチワークフロー
- 3.5 リモートブランチ
- 3.6 リベース
- 3.7 まとめ
-
4. サーバー上のGit
- 4.1 プロトコル
- 4.2 サーバーにGitを導入する
- 4.3 SSH公開鍵の生成
- 4.4 サーバーのセットアップ
- 4.5 Gitデーモン
- 4.6 スマートHTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 サードパーティホストのオプション
- 4.10 まとめ
-
5. 分散Git
- 5.1 分散ワークフロー
- 5.2 プロジェクトへの貢献
- 5.3 プロジェクトの管理
- 5.4 まとめ
-
6. GitHub
- 6.1 アカウントのセットアップと構成
- 6.2 プロジェクトへの貢献
- 6.3 プロジェクトの管理
- 6.4 組織の管理
- 6.5 GitHubのスクリプト
- 6.6 まとめ
-
7. Gitツール
- 7.1 リビジョンの選択
- 7.2 インタラクティブなステージング
- 7.3 スタッシュとクリーン
- 7.4 作業への署名
- 7.5 検索
- 7.6 履歴の書き換え
- 7.7 リセットの解説
- 7.8 高度なマージ
- 7.9 Rerere
- 7.10 Gitを使用したデバッグ
- 7.11 サブモジュール
- 7.12 バンドル
- 7.13 置換
- 7.14 認証情報の保存
- 7.15 まとめ
-
8. Gitのカスタマイズ
- 8.1 Gitの設定
- 8.2 Git属性
- 8.3 Gitフック
- 8.4 Gitで強制されるポリシーの例
- 8.5 まとめ
-
9. Gitと他のシステム
- 9.1 クライアントとしてのGit
- 9.2 Gitへの移行
- 9.3 まとめ
-
10. Gitの内部
- 10.1 プラミングとポーセリン
- 10.2 Gitオブジェクト
- 10.3 Git参照
- 10.4 パックファイル
- 10.5 Refspec
- 10.6 転送プロトコル
- 10.7 メンテナンスとデータリカバリ
- 10.8 環境変数
- 10.9 まとめ
-
A1. 付録A:他の環境でのGit
- A1.1 グラフィカルインターフェース
- A1.2 Visual StudioでのGit
- A1.3 Visual Studio CodeでのGit
- A1.4 IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMineでのGit
- A1.5 Sublime TextでのGit
- A1.6 BashでのGit
- A1.7 ZshでのGit
- A1.8 PowerShellでのGit
- A1.9 まとめ
-
A2. 付録B:アプリケーションへのGitの埋め込み
- A2.1 コマンドラインGit
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. 付録C:Gitコマンド
- A3.1 セットアップと構成
- A3.2 プロジェクトの取得と作成
- A3.3 基本的なスナップショット
- A3.4 ブランチとマージ
- A3.5 プロジェクトの共有と更新
- A3.6 検査と比較
- A3.7 デバッグ
- A3.8 パッチ
- A3.9 メール
- A3.10 外部システム
- A3.11 管理
- A3.12 プラミングコマンド
4.1 サーバー上のGit - プロトコル
この時点で、Gitを使用する上で日常的に行うほとんどのタスクを実行できるはずです。しかし、Gitで共同作業を行うには、リモートのGitリポジトリが必要です。技術的には、個人のリポジトリにプッシュしたり、個人のリポジトリからプルしたりできますが、そうすると、注意しないと彼らが取り組んでいるものをかなり簡単に混乱させてしまう可能性があるため、推奨されていません。さらに、コンピュータがオフラインの場合でも、共同作業者がリポジトリにアクセスできるようにする必要があります。より信頼性の高い共通のリポジトリを用意することは、多くの場合役立ちます。したがって、誰かと共同作業をするための推奨される方法は、両方がアクセスできる中間リポジトリをセットアップし、そこにプッシュしたり、そこからプルしたりすることです。
Gitサーバーの実行は非常に簡単です。まず、サーバーでサポートするプロトコルを選択します。この章の最初のセクションでは、利用可能なプロトコルと、それぞれの長所と短所について説明します。次のセクションでは、これらのプロトコルを使用した典型的な設定と、サーバーをそれらと共に実行する方法について説明します。最後に、自分のサーバーをセットアップして維持する手間をかけたくない場合に、他人のサーバーでコードをホストすることを気にしない場合の、いくつかのホストオプションについて説明します。
独自のサーバーを実行することに興味がない場合は、章の最後のセクションにスキップして、ホストアカウントを設定するためのいくつかのオプションを確認し、分散ソース管理環境で作業する際のさまざまな詳細について説明する次の章に進むことができます。
通常、リモートリポジトリは、ベアリポジトリです。これは、作業ディレクトリを持たないGitリポジトリです。リポジトリは共同作業のポイントとしてのみ使用されるため、ディスクにスナップショットをチェックアウトする理由はありません。これは単にGitデータです。最も簡単な言葉で言えば、ベアリポジトリは、プロジェクトの.git
ディレクトリの内容であり、それ以外のものではありません。
プロトコル
Gitは、データの転送に4つの異なるプロトコルを使用できます。ローカル、HTTP、Secure Shell(SSH)、およびGitです。ここでは、それらが何であり、どのような基本的な状況で使用したい(または使用したくない)かについて説明します。
ローカルプロトコル
最も基本的なのはローカルプロトコルで、これはリモートリポジトリが同じホスト上の別のディレクトリにある場合に使用されます。これは、チームの全員がNFSマウントなどの共有ファイルシステムにアクセスできる場合や、全員が同じコンピュータにログインするという可能性の低いケースでよく使用されます。後者の場合は、コードリポジトリのインスタンスがすべて同じコンピュータに存在することになり、壊滅的な損失が発生する可能性が高いため、理想的ではありません。
共有のマウントされたファイルシステムがある場合、ローカルのファイルベースのリポジトリに対してクローン、プッシュ、プルができます。このようなリポジトリをクローンしたり、既存のプロジェクトにリモートとして追加するには、リポジトリへのパスをURLとして使用します。たとえば、ローカルリポジトリをクローンするには、次のようなコマンドを実行できます。
$ git clone /srv/git/project.git
または、次のようにすることもできます。
$ git clone file:///srv/git/project.git
Gitは、URLの先頭にfile://
を明示的に指定した場合、少し異なる動作をします。パスのみを指定した場合、Gitは必要なファイルをハードリンクまたは直接コピーしようとします。file://
を指定すると、Gitは通常ネットワーク経由でデータを転送するために使用するプロセスを起動します。これは一般的に効率がはるかに劣ります。file://
プレフィックスを指定する主な理由は、余分な参照やオブジェクトが含まれないリポジトリのクリーンなコピーが必要な場合です。通常、別のVCSからのインポート後や類似の場合に使用します(メンテナンス作業についてはGitの内部構造を参照)。ここでは、ほぼ常に高速になる通常のパスを使用します。
既存のGitプロジェクトにローカルリポジトリを追加するには、次のようなコマンドを実行できます。
$ git remote add local_proj /srv/git/project.git
これで、ネットワーク経由で行うように、新しいリモート名local_proj
を介してそのリモートからプッシュおよびプルできます。
長所
ファイルベースのリポジトリの長所は、シンプルで、既存のファイル権限とネットワークアクセスを使用することです。チーム全体がアクセスできる共有ファイルシステムがすでに存在する場合は、リポジトリの設定は非常に簡単です。共有アクセス権を持つ場所にベアリポジトリのコピーを配置し、他の共有ディレクトリと同じように読み取り/書き込み権限を設定します。この目的でベアリポジトリのコピーをエクスポートする方法については、Gitをサーバーに導入するで説明します。
これは、他の人の作業リポジトリから作業をすばやく取得する場合にも適したオプションです。同僚とあなたが同じプロジェクトに取り組んでいて、同僚があなたに何かをチェックアウトしてもらいたい場合、git pull /home/john/project
のようなコマンドを実行する方が、同僚がリモートサーバーにプッシュしてからあなたがそこからフェッチするよりも簡単なことがよくあります。
短所
この方法の短所は、共有アクセスは、基本的なネットワークアクセスよりも、複数の場所から設定してアクセスするのが一般的に難しいことです。自宅にいるときにラップトップからプッシュしたい場合は、リモートディスクをマウントする必要があります。これは、ネットワークベースのアクセスと比較して、困難で時間がかかる可能性があります。
何らかの共有マウントを使用している場合、これは必ずしも最速のオプションではないことを述べておくことが重要です。ローカルリポジトリは、データへの高速アクセスがある場合にのみ高速です。NFS上のリポジトリは、同じサーバー上のSSH経由のリポジトリよりも遅いことが多く、Gitは各システムのローカルディスクで実行できます。
最後に、このプロトコルは、リポジトリを偶発的な損傷から保護しません。すべてのユーザーは、「リモート」ディレクトリへの完全なシェルアクセス権を持っており、内部のGitファイルを変更または削除してリポジトリを破損することを防ぐものは何もありません。
HTTPプロトコル
Gitは、2つの異なるモードを使用してHTTP経由で通信できます。Git 1.6.6より前は、これを行う方法は1つしかなく、非常にシンプルで、一般的に読み取り専用でした。バージョン1.6.6では、SSH経由と同様の方法で、Gitがデータ転送をインテリジェントにネゴシエートできる新しいスマートなプロトコルが導入されました。ここ数年で、この新しいHTTPプロトコルは、ユーザーにとってよりシンプルで、通信方法についてよりスマートであるため、非常に人気が高まっています。新しいバージョンはスマートHTTPプロトコルと呼ばれ、古い方法はダムHTTPと呼ばれます。まず、新しいスマートHTTPプロトコルについて説明します。
スマートHTTP
スマートHTTPは、SSHまたはGitプロトコルと非常によく似た動作をしますが、標準のHTTPSポートで実行され、さまざまなHTTP認証メカニズムを使用できます。これは、SSHキーを設定する必要はなく、ユーザー名/パスワード認証などのものを使用できるため、SSHよりもユーザーにとって簡単な場合が多いことを意味します。
現在では、git://
プロトコルのように匿名で提供するように設定でき、SSHプロトコルのように認証と暗号化を使用してプッシュすることもできるため、Gitを使用する最も一般的な方法になっているでしょう。これらのさまざまな目的で異なるURLを設定する必要はなく、1つのURLを両方で使用できるようになりました。プッシュしようとして、リポジトリが認証を必要とする場合(通常はそうであるはず)、サーバーはユーザー名とパスワードを要求できます。読み取りアクセスも同様です。
実際、GitHubなどのサービスの場合、オンラインでリポジトリを表示するために使用するURL(たとえば、https://github.com/schacon/simplegit)は、クローン作成に使用できるURLであり、アクセス権がある場合はプッシュもできます。
ダムHTTP
サーバーがGit HTTPスマートサービスで応答しない場合、GitクライアントはよりシンプルなダムHTTPプロトコルにフォールバックしようとします。ダムプロトコルでは、ベアGitリポジトリがWebサーバーから通常のファイルのように提供されることを想定しています。ダムHTTPの美しさは、設定のシンプルさにあります。基本的に、ベアGitリポジトリをHTTPドキュメントルートの下に配置し、特定のpost-update
フックを設定するだけで完了です(Gitフックを参照)。その時点で、リポジトリを配置したWebサーバーにアクセスできる人は誰でも、リポジトリをクローンすることもできます。HTTP経由でリポジトリへの読み取りアクセスを許可するには、次のような操作を行います。
$ cd /var/www/htdocs/
$ git clone --bare /path/to/git_project gitproject.git
$ cd gitproject.git
$ mv hooks/post-update.sample hooks/post-update
$ chmod a+x hooks/post-update
以上です。Gitに付属しているデフォルトのpost-update
フックは、HTTPフェッチとクローンが適切に機能するように適切なコマンド(git update-server-info
)を実行します。このコマンドは、このリポジトリにプッシュしたとき(おそらくSSH経由で)に実行されます。すると、他の人は次のような方法でクローンできます。
$ git clone https://example.com/gitproject.git
この特定のケースでは、Apache設定で一般的な/var/www/htdocs
パスを使用していますが、任意の静的Webサーバーを使用できます。ベアリポジトリをそのパスに配置するだけです。Gitデータは基本的な静的ファイルとして提供されます(正確にどのように提供されるかについての詳細は、Gitの内部構造の章を参照)。
一般的に、読み取り/書き込みスマートHTTPサーバーを実行するか、ファイルをダム方式で読み取り専用としてアクセス可能にするかのいずれかを選択します。2つのサービスを組み合わせて実行することはまれです。
長所
スマートバージョンのHTTPプロトコルの長所に焦点を当てます。
すべてのタイプのアクセスに単一のURLを使用でき、認証が必要な場合にのみサーバーがプロンプトを表示するというシンプルさは、エンドユーザーにとって非常に簡単です。ユーザー名とパスワードで認証できることも、SSHに対する大きな利点です。ユーザーはSSHキーをローカルで生成し、サーバーとやり取りできるようになる前に公開キーをサーバーにアップロードする必要がないためです。あまり洗練されていないユーザーや、SSHがあまり一般的ではないシステムを使用しているユーザーにとっては、これは使いやすさにおいて大きな利点です。また、SSHプロトコルと同様に、非常に高速で効率的なプロトコルです。
HTTPS経由でリポジトリを読み取り専用で提供することもできます。つまり、コンテンツ転送を暗号化できます。または、クライアントに特定の署名付きSSL証明書を使用させることもできます。
もう1つの良い点は、HTTPとHTTPSが非常に一般的に使用されているプロトコルであるため、企業のファイアウォールは多くの場合、それらのポートを介したトラフィックを許可するように設定されていることです。
短所
HTTPS経由のGitは、一部のサーバーではSSHと比較して設定が少し難しい場合があります。それ以外は、他のプロトコルがGitコンテンツの提供に関してスマートHTTPよりも優れている点はほとんどありません。
認証されたプッシュにHTTPを使用している場合、資格情報を提供することは、SSH経由でキーを使用するよりも複雑になる場合があります。ただし、macOSのKeychainアクセスやWindowsのCredential Managerなど、これを非常に簡単にするために使用できるいくつかの資格情報キャッシュツールがあります。システムでの安全なHTTPパスワードキャッシュの設定方法については、資格情報の保存をお読みください。
SSHプロトコル
Gitを自己ホストする場合の一般的なトランスポートプロトコルは、SSH経由です。これは、ほとんどの場所でサーバーへのSSHアクセスがすでに設定されているためです。設定されていない場合でも、簡単に設定できます。SSHは認証されたネットワークプロトコルでもあり、ユビキタスであるため、一般的に設定と使用が簡単です。
SSH経由でGitリポジトリをクローンするには、次のようにssh://
URLを指定できます。
$ git clone ssh://[user@]server/project.git
または、SSHプロトコルのより短いscpのような構文を使用することもできます。
$ git clone [user@]server:project.git
上記の両方の場合、オプションのユーザー名を指定しないと、Gitは現在ログインしているユーザーを想定します。
長所
SSHを使用する利点はたくさんあります。まず、SSHは設定が比較的簡単です。SSHデーモンは一般的であり、多くのネットワーク管理者が経験を持っており、多くのOSディストリビューションはSSHが設定されているか、管理ツールがあります。次に、SSH経由でのアクセスは安全です。すべてのデータ転送は暗号化され、認証されます。最後に、HTTPS、Git、およびローカルプロトコルと同様に、SSHは効率的で、転送前にデータを可能な限りコンパクトにします。
短所
SSHの欠点は、Gitリポジトリへの匿名アクセスをサポートしていないことです。SSHを使用している場合、人々は、読み取り専用の場合でも、自分のマシンへのSSHアクセスを持っている必要があります。これは、リポジトリを調べてみたいだけの人々が参加するオープンソースプロジェクトにはSSHが適していません。社内ネットワーク内でのみ使用している場合は、SSHが対処する必要のある唯一のプロトコルである可能性があります。プロジェクトへの匿名読み取り専用アクセスを許可し、SSHも使用したい場合は、プッシュするためにSSHを設定する必要がありますが、他の人がフェッチするための何かを設定する必要があります。
Gitプロトコル
最後に、Gitプロトコルがあります。これは、Gitにパッケージ化されている特別なデーモンです。専用ポート(9418)でリッスンし、SSHプロトコルと同様のサービスを提供しますが、認証や暗号化は一切ありません。リポジトリをGitプロトコル経由で提供するには、git-daemon-export-ok
ファイルを作成する必要があります。デーモンはそのファイルがないとリポジトリを提供しません。それ以外には、セキュリティはありません。Gitリポジトリは誰でもクローンできるか、できないかのどちらかです。これは、このプロトコル経由でプッシュすることが一般的にないことを意味します。プッシュアクセスを有効にすることはできますが、認証がないため、プロジェクトのURLを見つけたインターネット上の誰もがそのプロジェクトにプッシュできる可能性があります。これはまれであると言えば十分でしょう。
長所
Gitプロトコルは、利用可能なネットワーク転送プロトコルの中で最も高速であることがよくあります。パブリックプロジェクトで多くのトラフィックを処理する場合や、読み取りアクセスにユーザー認証を必要としない非常に大きなプロジェクトを処理する場合は、Gitデーモンを設定してプロジェクトを提供する必要があります。SSHプロトコルと同じデータ転送メカニズムを使用しますが、暗号化と認証のオーバーヘッドはありません。
短所
TLSやその他の暗号化がないため、git://
経由でクローンすると、任意のコード実行の脆弱性につながる可能性があり、そのため、自分が何をしているかを理解している場合を除き、避ける必要があります。
-
git clone git://example.com/project.git
を実行すると、例えばルーターを制御する攻撃者が、クローンしたばかりのリポジトリを改ざんし、悪意のあるコードを挿入する可能性があります。その後、クローンしたばかりのコードをコンパイル/実行すると、悪意のあるコードが実行されます。同じ理由から、git clone http://example.com/project.git
の実行も避けるべきです。 -
git clone https://example.com/project.git
の実行には、同じ問題は発生しません(攻撃者が example.com のTLS証明書を提供できる場合を除く)。git clone git@example.com:project.git
の実行は、誤ったSSHキーのフィンガープリントを受け入れた場合にのみ、この問題が発生します。
また、認証もありません。つまり、誰でもリポジトリをクローンできます(これは多くの場合、まさに望ましいことです)。また、おそらく最も設定が難しいプロトコルでもあります。独自のデーモンを実行する必要があり、xinetd
や systemd
のような設定が必要になりますが、これは必ずしも簡単ではありません。また、ポート9418へのファイアウォールアクセスも必要ですが、これは企業のファイアウォールが常に許可する標準ポートではありません。大規模な企業のファイアウォールの背後では、この不明瞭なポートが一般的にブロックされています。