日本語 ▾ トピック ▾ 最新バージョン ▾ gittutorialは最終更新2.46.1

名前

gittutorial - Git入門チュートリアル

概要

git *

説明

このチュートリアルでは、新しいプロジェクトを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

新しいプロジェクトのインポート

初期作業のtarball project.tar.gzがあるとします。これを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ブランチで別の変更を加えることができます。

(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の使用

アリスが/home/alice/projectにGitリポジトリを持つ新しいプロジェクトを開始し、同じマシンにホームディレクトリを持つボブが貢献したいとします。

ボブは次のように始めます。

bob$ git clone /home/alice/project myrepo

これにより、アリスのリポジトリのクローンを含む新しいディレクトリmyrepoが作成されます。このクローンは元のプロジェクトと同等の立場にあり、元のプロジェクトの履歴の独自のコピーを持っています。

ボブはその後、いくつかの変更を加え、それらをコミットします。

(edit files)
bob$ git commit -a
(repeat as necessary)

準備ができたら、ボブはアリスに/home/bob/myrepoのリポジトリから変更をプルするように伝えます。アリスは次のようにします。

alice$ cd /home/alice/project
alice$ git pull /home/bob/myrepo master

これにより、ボブのmasterブランチからの変更がアリスの現在のブランチにマージされます。アリスがその間に独自の変更を行っている場合、手動で競合を修正する必要があるかもしれません。

pullコマンドは、したがって2つの操作を実行します。リモートブランチから変更をフェッチし、それを現在のブランチにマージします。

一般的に、アリスはこのpullを開始する前に、ローカルの変更をコミットしておきたいと考えるでしょう。もしボブの作業が、アリスが履歴が分岐して以来行ったことと競合する場合、アリスはワーキングツリーとインデックスを使って競合を解決することになりますが、既存のローカル変更は競合解決プロセスと干渉します(Gitはフェッチは実行しますが、マージを拒否します。この場合、アリスはローカルの変更を何らかの方法で取り除き、再度プルする必要があります)。

アリスは、まずマージせずに、fetchコマンドを使用してボブが何をしたかを覗き見ることができます。これにより、アリスは、特別なシンボルFETCH_HEADを使用してボブが何をしたかを検査し、プルする価値のあるものがあるかどうかを判断できます。たとえば、次のようになります。

alice$ git fetch /home/bob/myrepo master
alice$ git log -p HEAD..FETCH_HEAD

この操作は、アリスがコミットされていないローカルの変更を持っていても安全です。HEAD..FETCH_HEADという範囲表記は、「FETCH_HEADから到達可能なすべてのものを表示するが、HEADから到達可能なものはすべて除外する」という意味です。アリスは自分の現在の状態(HEAD)につながるすべてのことをすでに知っており、このコマンドでまだ見ていないボブの状態(FETCH_HEAD)にあるものを確認します。

アリスが、分岐してからボブが行ったことを視覚化したい場合、次のコマンドを発行できます。

$ gitk HEAD..FETCH_HEAD

これは、以前にgit logで見たのと同じ2ドット範囲表記を使用します。

アリスは、分岐してから両者が行ったことを見たいと思うかもしれません。2ドット形式の代わりに3ドット形式を使用できます。

$ gitk HEAD...FETCH_HEAD

これは、「どちらか一方から到達可能なすべてのものを表示するが、両方から到達可能なものはすべて除外する」という意味です。

これらの範囲表記は、gitkgit logの両方で使用できることに注意してください。

ボブの作業を調べた後、緊急のことがなければ、アリスはボブからプルせずに作業を続けることを決めるかもしれません。もしボブの履歴にアリスがすぐに必要とするものがある場合、アリスはまず作業中の変更をスタッシュし、pullを実行し、最後に結果の履歴の上に作業中の変更をアンスタッシュすることを選ぶかもしれません。

小規模で密接なグループで作業している場合、同じリポジトリと何度もやり取りすることは珍しくありません。リモートリポジトリのショートハンドを定義することで、それをより簡単にできます。

alice$ git remote add bob /home/bob/myrepo

これにより、アリスは自分のブランチとマージせずに、git fetchコマンドを使ってpull操作の最初の部分のみを実行できます。

alice$ git fetch bob

長い形式とは異なり、アリスがgit remoteで設定されたリモートリポジトリのショートハンドを使用してボブからフェッチすると、フェッチされたものはリモートトラッキングブランチ(この場合はbob/master)に保存されます。したがって、これの後、

alice$ git log -p master..bob/master

は、ボブがアリスのmasterブランチから分岐して以来、ボブが行ったすべての変更のリストを表示します。

これらの変更を調査した後、アリスはそれらの変更を自分のmasterブランチにマージできます。

alice$ git merge bob/master

このmergeは、次のように自分のリモートトラッキングブランチからプルすることでも実行できます。

alice$ git pull . remotes/bob/master

git pullは、コマンドラインで他に何が与えられていても、常に現在のブランチにマージすることに注意してください。

後で、ボブはアリスの最新の変更で自分のリポジトリを更新できます。

bob$ git pull

アリスのリポジトリへのパスを指定する必要がないことに注意してください。ボブがアリスのリポジトリをクローンしたとき、Gitは彼女のリポジトリの場所をリポジトリ設定に保存しており、その場所がプルに使用されます。

bob$ git config --get remote.origin.url
/home/alice/project

git cloneによって作成された完全な設定はgit config -lを使用して表示でき、git-config[1]のmanページは各オプションの意味を説明しています。)

Gitはまた、アリスのmasterブランチの元のコピーをorigin/masterという名前で保持しています。

bob$ git branch -r
  origin/master

ボブが後で別のホストから作業することに決めた場合でも、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

1b2e1d63ffv2.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ブランチで作成されたが安定ブランチにはないコミットをリストし、

$ git log master..stable

は安定ブランチで作成されたがmasterブランチにはないコミットのリストを表示します。

git logコマンドには弱点があります。コミットをリスト形式で提示しなければなりません。履歴が分岐してその後マージされるような開発ラインを持つ場合、git logがそれらのコミットを提示する順序は意味がありません。

複数の貢献者がいるほとんどのプロジェクト(LinuxカーネルやGit自体など)では、頻繁にマージが行われます。gitkは履歴をよりよく視覚化します。たとえば、

$ gitk --since="2 weeks ago" drivers/

これにより、driversディレクトリ下のファイルを変更した過去2週間のコミットを閲覧できます。(注意: Ctrlキーを押しながら「-」または「+」を押すと、gitkのフォントを調整できます。)

最後に、ファイル名を受け入れるほとんどのコマンドは、オプションでファイル名の前にコミットを指定して、ファイルの特定のバージョンを指定できます。

$ git diff v2.5:Makefile HEAD:Makefile.in

git showを使って、そのようなファイルを表示することもできます。

$ git show v2.5:Makefile

次のステップ

このチュートリアルで、プロジェクトの基本的な分散リビジョン管理を実行するには十分なはずです。ただし、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]: 日常的なGitを約20のコマンドで。

  • gitcvs-migration[7]: CVSユーザーのためのGit。

GIT

git[1]スイートの一部

scroll-to-top