セットアップと設定
プロジェクトの取得と作成
基本的なスナップショット
ブランチとマージ
プロジェクトの共有と更新
検査と比較
パッチ適用
デバッグ
メール
外部システム
サーバー管理
- 2.46.2 → 2.49.0 変更なし
-
2.46.1
2024-09-13
- 2.43.1 → 2.46.0 変更なし
-
2.43.0
2023-11-20
- 2.41.1 → 2.42.4 変更なし
-
2.41.0
2023-06-01
- 2.33.1 → 2.40.4 変更なし
-
2.33.0
2021-08-16
- 2.23.1 → 2.32.7 変更なし
-
2.23.0
2019-08-16
- 2.16.6 → 2.22.5 変更なし
-
2.15.4
2019-12-06
- 2.13.7 → 2.14.6 変更なし
-
2.12.5
2017-09-22
- 2.9.5 → 2.11.4 変更なし
-
2.8.6
2017-07-30
- 2.3.10 → 2.7.6 変更なし
-
2.2.3
2015-09-04
- 2.1.4 変更なし
-
2.0.5
2014-12-17
説明
このチュートリアルでは、新しいプロジェクトをGitにインポートし、変更を加え、他の開発者と変更を共有する方法を説明します。
代わりに、例えば最新バージョンをテストするためにGitを使ってプロジェクトをフェッチすることに主に興味がある場合は、Gitユーザーマニュアルの最初の2つの章から始めることをお勧めします。
まず、git log --graph
のようなコマンドのドキュメントは、
$ man git-log
または
$ git help log
後者の方法では、任意のマニュアルビューアを使用できます。詳細については、git-help[1]を参照してください。
いずれかの操作を行う前に、名前と公開メールアドレスをGitに登録しておくことをお勧めします。最も簡単な方法は次のとおりです。
$ git config --global user.name "Your Name Comes Here" $ git config --global user.email you@yourdomain.example.com
新しいプロジェクトのインポート
最初の作業としてproject.tar.gz
というtarballがあると仮定します。これをGitのバージョン管理下に置くには、次のようにします。
$ tar xzf project.tar.gz $ cd project $ git init
Gitは次のように応答します。
Initialized empty Git repository in .git/
これで作業ディレクトリが初期化されました。.git
という新しいディレクトリが作成されていることに気づくでしょう。
次に、git add
を使って現在のディレクトリ内の全てのファイルの内容のスナップショットをGitに取得させます(.
に注意)。
$ git add .
このスナップショットは現在、Gitが「インデックス」と呼ぶ一時的なステージングエリアに保存されています。インデックスの内容をリポジトリに永続的に保存するには、git commit
を使用します。
$ git commit
これによりコミットメッセージの入力を求められます。これでプロジェクトの最初のバージョンがGitに保存されました。
変更を行う
いくつかのファイルを変更し、その更新された内容をインデックスに追加します。
$ git add file1 file2 file3
これでコミットの準備ができました。コミットされる内容を見るには、--cached
オプションを付けてgit diff
を使用します。
$ git diff --cached
(--cached
なしでは、git diff
はあなたが変更したがまだインデックスに追加していない内容を表示します。)また、git status
で状況の簡単な概要を得ることができます。
$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: file1 modified: file2 modified: file3
さらに調整が必要な場合は、今すぐ行い、新しく変更された内容をインデックスに追加します。最後に、変更をコミットします。
$ git commit
これにより、再び変更を記述するメッセージの入力を求められ、プロジェクトの新しいバージョンが記録されます。
あるいは、事前にgit add
を実行する代わりに、次を使用できます。
$ git commit -a
これは、変更された(ただし新規ではない)ファイルを自動的に検出し、それらをインデックスに追加し、コミットするという全ての操作を一度に行います。
コミットメッセージに関する注意: 必須ではありませんが、コミットメッセージは、変更を要約した短い(50文字以内)一行で始め、その後に空白行を挟み、さらに詳細な説明を続けるのが良い習慣です。コミットメッセージの最初の空白行までのテキストはコミットタイトルとして扱われ、そのタイトルはGit全体で使われます。例えば、git-format-patch[1]はコミットをメールに変換する際に、タイトルを件名に、残りのコミットを本文に使用します。
Gitはファイルを追跡せず内容を追跡する
多くのバージョン管理システムには、新しいファイルの変更追跡を開始するようシステムに指示するadd
コマンドが用意されています。Gitのadd
コマンドは、よりシンプルで強力なことを行います。git add
は新規ファイルと変更されたファイルの両方に使用され、どちらの場合も指定されたファイルのスナップショットを取り、その内容をインデックスにステージングし、次のコミットに含める準備をします。
プロジェクト履歴の表示
いつでも、次のコマンドを使って変更履歴を見ることができます。
$ git log
各ステップでの完全な差分も表示したい場合は、次を使用します。
$ git log -p
各ステップの概要は、全体像を把握するのに役立つことがよくあります。
$ git log --stat --summary
ブランチの管理
1つのGitリポジトリは、複数の開発ブランチを管理できます。experimental
という新しいブランチを作成するには、次を使用します。
$ git branch experimental
ここで実行すると、
$ git branch
既存のすべてのブランチのリストが表示されます。
experimental * master
experimental
ブランチはあなたが今作成したもので、master
ブランチは自動的に作成されたデフォルトブランチです。アスタリスクは現在いるブランチを示します。次のように入力します。
$ git switch experimental
experimental
ブランチに切り替えます。次にファイルを編集し、変更をコミットして、master
ブランチに戻ります。
(edit file) $ git commit -a $ git switch master
行った変更がもう表示されないことを確認してください。それはexperimental
ブランチで行われたもので、現在はmaster
ブランチに戻っているからです。
master
ブランチで別の変更を行うことができます。
(edit file) $ git commit -a
この時点で、2つのブランチは分岐しており、それぞれ異なる変更が加えられています。experimental
で行われた変更をmaster
にマージするには、次を実行します。
$ git merge experimental
変更が競合しない場合、完了です。競合がある場合、問題のあるファイルに競合を示すマーカーが残されます。
$ git diff
これが表示されます。競合を解決するためにファイルを編集したら、
$ git commit -a
マージの結果をコミットします。最後に、
$ gitk
結果の履歴を美しいグラフィカルな表示で示します。
この時点で、experimental
ブランチを削除することができます。
$ git branch -d experimental
このコマンドは、experimental
ブランチの変更がすでに現在のブランチにあることを確認します。
もしcrazy-idea
というブランチで開発を進めて後悔した場合、いつでもそのブランチを削除することができます。
$ git branch -D crazy-idea
ブランチは手軽で簡単なので、何かを試す良い方法です。
Gitを共同作業に使う
Aliceが/home/alice/project
にGitリポジトリを持つ新しいプロジェクトを始めたとします。そして、同じマシンにホームディレクトリを持つBobが貢献したいと考えています。
Bobは次から始めます。
bob$ git clone /home/alice/project myrepo
これにより、Aliceのリポジトリのクローンを含む新しいディレクトリmyrepo
が作成されます。このクローンは元のプロジェクトと同等であり、元のプロジェクトの履歴の独自のコピーを持っています。
Bobはその後、いくつかの変更を行い、それらをコミットします。
(edit files) bob$ git commit -a (repeat as necessary)
準備ができたら、彼はAliceに/home/bob/myrepo
のリポジトリから変更をプルするように伝えます。彼女はこれを次のように行います。
alice$ cd /home/alice/project alice$ git pull /home/bob/myrepo master
これはBobのmaster
ブランチからの変更をAliceの現在のブランチにマージします。Aliceがその間に独自の変更を行っていた場合、手動で競合を解決する必要があるかもしれません。
したがって、pull
コマンドは2つの操作を実行します。リモートブランチから変更をフェッチし、それらを現在のブランチにマージします。
一般的に、Aliceはこのpull
を開始する前に、自身のローカルでの変更をコミットしておきたいと考えるでしょう。もしBobの作業が、履歴が分岐してからのAliceの作業と競合する場合、Aliceは自身のワーキングツリーとインデックスを使って競合を解決しますが、既存のローカルでの変更が競合解決プロセスを妨げる可能性があります(Gitはフェッチは実行しますがマージを拒否します。この場合、Aliceは何らかの方法でローカルの変更を取り除き、再度プルを行う必要があります)。
Aliceは、まずマージせずにfetch
コマンドを使ってBobが何をしたか覗き見ることができます。これにより、特別なシンボルFETCH_HEAD
を使ってBobがプルする価値のあるものを持っているかどうかを確認できます。このように行います。
alice$ git fetch /home/bob/myrepo master alice$ git log -p HEAD..FETCH_HEAD
この操作は、Aliceが未コミットのローカルでの変更を持っていても安全です。レンジ表記HEAD..FETCH_HEAD
は、「FETCH_HEAD
から到達可能なもの全てを表示するが、HEAD
から到達可能なものは除く」という意味です。Aliceは自身の現在の状態(HEAD
)につながる全てを既に知っており、このコマンドでまだ見ていないBobの状態(FETCH_HEAD
)の内容を確認します。
Aliceが、彼らの履歴が分岐して以来Bobが何をしたかを視覚化したい場合、以下のコマンドを発行できます。
$ gitk HEAD..FETCH_HEAD
これは、以前git log
で見た2ドットのレンジ表記と同じです。
Aliceは、彼らが分岐して以来、両者が何をしたかを確認したい場合があります。彼女は2ドット形式の代わりに3ドット形式を使用できます。
$ gitk HEAD...FETCH_HEAD
これは「どちらか一方から到達可能なものすべてを表示するが、両方から到達可能なものは除く」という意味です。
これらのレンジ表記は、gitk
とgit log
の両方で使用できることに注意してください。
Bobの作業を検査した後、緊急のものがなければ、AliceはBobからプルせずに作業を続けることを決めるかもしれません。もしBobの履歴にAliceがすぐに必要とするものがある場合、Aliceはまず作業中の変更を一時退避(stash)させ、pull
を実行し、最終的に結果の履歴の上に作業中の変更を元に戻す(unstash)ことを選択するかもしれません。
小規模で密接なグループで作業している場合、同じリポジトリと何度もやり取りすることは珍しくありません。リモートリポジトリのショートハンドを定義することで、これを容易にすることができます。
alice$ git remote add bob /home/bob/myrepo
これにより、Aliceは、自身のブランチとマージせずに、git fetch
コマンドを使ってpull
操作の最初の部分を単独で実行できます。
alice$ git fetch bob
長い形式とは異なり、Aliceがgit remote
で設定されたリモートリポジトリのショートハンドを使ってBobからフェッチすると、フェッチされたものはリモート追跡ブランチ、この場合はbob/master
に保存されます。したがって、この後、
alice$ git log -p master..bob/master
Aliceのmaster
ブランチからBobが分岐して以来行った全ての変更のリストが表示されます。
これらの変更を調べた後、Aliceは変更を自身のmaster
ブランチにマージできます。
alice$ git merge bob/master
このmerge
は、自身のリモート追跡ブランチからプルすることでも行うことができます。このように。
alice$ git pull . remotes/bob/master
git pullは、コマンドラインで他に何が指定されていても、常に現在のブランチにマージされることに注意してください。
後で、BobはAliceの最新の変更を自身のレポに次のように更新できます。
bob$ git pull
Aliceのリポジトリへのパスを指定する必要がないことに注意してください。BobがAliceのリポジトリをクローンしたとき、Gitは彼女のリポジトリの場所をリポジトリ設定に保存しており、その場所はプルに使用されます。
bob$ git config --get remote.origin.url /home/alice/project
(git clone
によって作成された完全な設定は、git config -l
を使って確認でき、git-config[1]のmanページには各オプションの意味が説明されています。)
Gitはまた、Aliceのmaster
ブランチの元のコピーをorigin/master
という名前で保持しています。
bob$ git branch -r origin/master
Bobが後で別のホストから作業することにした場合でも、sshプロトコルを使用してクローンとプルを実行できます。
bob$ git clone alice.org:/home/alice/project myrepo
あるいは、Gitにはネイティブプロトコルがあり、httpも使用できます。詳細については、git-pull[1]を参照してください。
GitはCVSのようなモードでも使用できます。これは、様々なユーザーが変更をプッシュする中央リポジトリを持つものです。詳細はgit-push[1]とgitcvs-migration[7]を参照してください。
履歴の調査
Gitの履歴は相互に関連する一連のコミットとして表現されます。git log
コマンドがそれらのコミットをリスト表示できることはすでに見てきました。各git log
エントリの最初の行がコミットの名前も示していることに注意してください。
$ git log commit c82a22c39cbc32576f64f5c6b3f24b99ea8149c7 Author: Junio C Hamano <junkio@cox.net> Date: Tue May 16 17:18:22 2006 -0700 merge-base: Clarify the comments on post processing.
この名前をgit show
に渡すと、このコミットの詳細を見ることができます。
$ git show c82a22c39cbc32576f64f5c6b3f24b99ea8149c7
しかし、コミットを参照する方法は他にもあります。コミットを一意に識別するのに十分な長さの名前の最初の部分を使用できます。
$ git show c82a22c39c # the first few characters of the name are # usually enough $ git show HEAD # the tip of the current branch $ git show experimental # the tip of the "experimental" branch
各コミットは通常、プロジェクトの以前の状態を指す1つの「親」コミットを持ちます。
$ git show HEAD^ # to see the parent of HEAD $ git show HEAD^^ # to see the grandparent of HEAD $ git show HEAD~4 # to see the great-great grandparent of HEAD
マージコミットは複数の親を持つ場合があることに注意してください。
$ git show HEAD^1 # show the first parent of HEAD (same as HEAD^) $ git show HEAD^2 # show the second parent of HEAD
コミットに独自の命名をすることもできます。実行後、
$ git tag v2.5 1b2e1d63ff
1b2e1d63ff
をv2.5
という名前で参照できます。この名前を他の人と共有する(例えば、リリースバージョンを識別するため)つもりなら、「タグ」オブジェクトを作成し、場合によっては署名するべきです。詳細についてはgit-tag[1]を参照してください。
コミットを知る必要があるGitコマンドは、これらの名前のいずれかを受け取ることができます。例えば、
$ git diff v2.5 HEAD # compare the current HEAD to v2.5 $ git branch stable v2.5 # start a new branch named "stable" based # at v2.5 $ git reset --hard HEAD^ # reset your current branch and working # directory to its state at HEAD^
その最後のコマンドには注意してください。ワーキングディレクトリ内の変更を失うだけでなく、このブランチからそれ以降の全てのコミットも削除されます。もしこのブランチがそれらのコミットを含む唯一のブランチである場合、それらは失われます。また、他の開発者がプルするような公開ブランチではgit reset
を使用しないでください。履歴を整理するために他の開発者に不必要なマージを強制することになります。プッシュした変更を元に戻す必要がある場合は、代わりにgit revert
を使用してください。
git grep
コマンドは、プロジェクトの任意のバージョンで文字列を検索できるため、
$ git grep "hello" v2.5
v2.5
内の"hello"の全ての出現箇所を検索します。
コミット名を省略すると、git grep
は現在のディレクトリで管理しているファイルの中から検索します。したがって、
$ git grep "hello"
Gitによって追跡されているファイルのみを検索する簡単な方法です。
多くのGitコマンドはコミットのセットも受け取り、それらはいくつかの方法で指定できます。git log
のいくつかの例を以下に示します。
$ git log v2.5..v2.6 # commits between v2.5 and v2.6 $ git log v2.5.. # commits since v2.5 $ git log --since="2 weeks ago" # commits from the last 2 weeks $ git log v2.5.. Makefile # commits since v2.5 which modify # Makefile
また、git log
に「レンジ」でコミットを指定することもできます。この場合、最初のコミットが必ずしも2番目のコミットの祖先である必要はありません。例えば、stable
とmaster
のブランチの先端が以前共通のコミットから分岐していた場合、
$ git log stable..master
master
ブランチで行われたがstableブランチでは行われていないコミットをリスト表示します。一方、
$ git log master..stable
stableブランチで行われたがmaster
ブランチでは行われていないコミットのリストを表示します。
git log
コマンドには弱点があります。コミットをリスト形式で表示しなければならないことです。履歴に分岐し、その後再びマージされた開発ラインがある場合、git log
がそれらのコミットを表示する順序は無意味です。
複数の貢献者がいるほとんどのプロジェクト(LinuxカーネルやGit自体など)では頻繁にマージが行われ、gitk
はその履歴をより良く視覚化します。例えば、
$ gitk --since="2 weeks ago" drivers/
drivers
ディレクトリ以下のファイルを変更した、過去2週間分のコミットを閲覧できます。(注:gitkのフォントは、Controlキーを押しながら「-」または「+」を押すことで調整できます。)
最後に、ファイル名を受け取るほとんどのコマンドは、オプションで任意のファイル名の前にコミットを指定することで、ファイルの特定のバージョンを指定することができます。
$ git diff v2.5:Makefile HEAD:Makefile.in
また、git show
を使ってそのようなファイルを見ることもできます。
$ git show v2.5:Makefile
次のステップ
このチュートリアルは、プロジェクトの基本的な分散バージョン管理を行うには十分なはずです。しかし、Gitの深さとパワーを完全に理解するには、Gitが基づいている2つのシンプルな概念を理解する必要があります。
-
オブジェクトデータベースは、ファイル、ディレクトリ、コミットといったプロジェクトの履歴を保存するために使用される、非常に洗練されたシステムです。
-
インデックスファイルは、ディレクトリツリーの状態のキャッシュであり、コミットを作成したり、ワーキングディレクトリをチェックアウトしたり、マージに関わる様々なツリーを保持するために使用されます。
このチュートリアルのパート2では、オブジェクトデータベース、インデックスファイル、およびGitを最大限に活用するために必要なその他のいくつかの事柄について説明します。gittutorial-2[7]でそれを見つけることができます。
もしすぐにそれを続けたくなければ、この時点で興味深いかもしれないその他のいくつかの余談は次のとおりです。
-
git-format-patch[1], git-am[1]: これらは、Gitコミットのシリーズを電子メールパッチに変換し、またその逆を行うもので、電子メールパッチに大きく依存するLinuxカーネルのようなプロジェクトで役立ちます。
-
git-bisect[1]: プロジェクトにリグレッションがある場合、バグを追跡する1つの方法は、履歴を検索して、責任がある正確なコミットを見つけることです。
git bisect
はそのコミットのバイナリ検索を実行するのに役立ちます。多くのマージされたブランチを持つ複雑な非線形履歴の場合でも、ほぼ最適な検索を実行できるほど賢いです。 -
gitworkflows[7]: 推奨されるワークフローの概要を提供します。
-
giteveryday[7]: 約20のコマンドで日常的なGit。
-
gitcvs-migration[7]: CVSユーザー向けのGit。
GIT
git[1] スイートの一部