Git の基本的な使い方
Git のごく基本的な使い方についての個人的な覚書です。
作成日:2023年8月8日
関連ページ:
- Git の初期設定と更新(Mac)
- Git ブランチ マージ リベース
- Git スタッシュ(stash) 一時的に変更を退避
- Git リセット git reset コマンド
- VS Code で Git を使う(ソース管理機能)
Git は分散型バージョン管理システム(Distributed Version Control System)の一つで、ファイルのバージョン(変更履歴)を管理することができす。
Git を使うとファイルの状態を任意の時点で更新履歴として保存しておくことで、その後編集したファイルを過去の保存した状態に戻したり、編集箇所の差分を表示したりすることができます。
また、Git では様々なファイル形式のデータを扱うことができ、プログラムソースコードだけでなく画像ファイルなども Git でバージョン管理することができます。
Git の仕組みや使い方の詳細(ドキュメント)は以下の Git のサイトに掲載されています。
- トップページ(https://git-scm.com)
- Pro Git book(日本語での詳細)PDF のアイコンをクリックしてダウンロードすることもできます。
- Reference(ドキュメント) ターミナルで help コマンドで表示することもできます。
上記の Reference はコマンドによっては日本語に翻訳されているものもあり右上の言語のプルダウン(初期言語は English)で確認できます(例 init や add など)。
コマンドの Reference は help で表示することもできます。
参考になるサイト
Git のコンセプト
Git は分散型バージョン管理システムで、複数の人が同時に作業していても、それぞれが自分のコンピュータ上でプロジェクトのファイル(ワーキングツリー)と変更履歴を格納する場所(ローカルリポジトリ)を持ち、自分の作業を他の人と独立して行うことができます。
また、Git はリモートリポジトリなしでローカルだけで使用することもできます。ローカルリポジトリだけでも、ファイルの変更履歴を記録し、バージョン管理を行うことができます。
用語 | 説明 |
---|---|
リポジトリ Repository |
プロジェクトのファイルの状態や変更履歴を格納する場所。ローカルリポジトリ(自分のコンピュータ上)とリモートリポジトリ(共有されたサーバ上)があります。 |
ワーキングツリー Working Tree |
直接ファイルを編集する実際のファイルとディレクトリが存在する場所(Git リポジトリの管理下にあるファイルが存在するディレクトリ)。作業ディレクトリ(Working Directory)とも言います。 |
コミット Commit |
コミットには2つの意味があります。変更をリポジトリに記録する操作のことをコミットと呼びますが、その操作により記録された変更内容のことも意味します。つまり、コミットすると、その変更内容(コミット)がリポジトリに追加されます。 |
プル Pull |
リモートリポジトリの変更をローカルリポジトリに取り込む操作。リモートリポジトリの変更を取得する際に使用します。 |
プッシュ Push |
ローカルリポジトリの変更をリモートリポジトリに送信する操作。自分の変更を他の人と共有する際に使用します。 |
基本的な Git のワークフロー
以下が基本的な Git のワークフローです。
-
リポジトリの作成: プロジェクトフォルダを Git リポジトリとして初期化するか、既存のリポジトリをクローンする(リモートリポジトリをローカルに複製する)ことで始めます。
Git リポジトリとして初期化すると .git という名前のリポジトリのフォルダが作成されます。
- ファイルの変更: ファイルを変更・編集します。
- ステージング: 変更したファイルをステージングエリア(インデックス)に追加します。
- コミット: ステージングエリアにある変更をコミットして、変更履歴をリポジトリに記録します。
- 必要に応じて以下を行います。
- ブランチの作成と切り替え: 新しい機能やバグ修正のためにブランチを作成し、作業を行います。
- マージ: ブランチでの作業が終わったら、変更をメインのブランチにマージします。
- プッシュ: ローカルでの変更がリモートリポジトリにアップロードされます。
- プル: リモートリポジトリの変更をローカルに取り込むためにプルを行います。
コミット(Commit)
変更をリポジトリに記録して確定する操作のことをコミットと呼びます。また、コミットは変更内容を保存したデータ(コミットオブジェクト)のことも意味します。
Git ではコミットしたタイミングでのみ履歴の保存が行われます。
コミットすると、その時点でのプロジェクトの状態がスナップショットとしてリポジトリに保存されます。
以下の円(丸)が、ある時点でコミットして保存されたデータ(コミットオブジェクト)です。
コミットの識別子は、SHA-1 というアルゴリズムでコミットオブジェクトを Hash した値(英数字40桁)です。以下では先頭の7文字(例 3f903a4)を表示しています。
各コミットは、前のコミット(親のコミット)が生成した識別子の値の情報を持っていて、これによりコミット同士が繋がっています。
以下の場合、最新のコミット bbeb4bd は、その一つ前のコミット c017211 を参照していて、更にそのコミットは、コミット 5cac768 を参照している・・・というようにしてコミット同士は繋がっています。
コミットオブジェクト
コミットすることによって生成されたデータのことをコミットオブジェクトと言います。
コミットオブジェクトにはツリーオブジェクトの識別子やコミットメッセージ、コミットを作成した日時や作成者の情報、コミットの親の識別子(ハッシュ値)などのメタデータが含まれ、リポジトリ内に永久的に記録されます。これによりプロジェクトの歴史を追跡することができます。
コミットオブジェクトの内容は git cat-file -p で確認することができます。
% git cat-file -p b1acd1b tree 8759e1f7cb2183c13789eeccbe2e0d31ab65263a // ツリーオブジェクトの識別子 parent 65955773eb9f32f979d0a7cfc32051d96766bf6c // 親の識別子 author foo <foo@example.com> 1691721109 +0900 //作成者の情報 committer foo <foo@example.com> 1691721109 +0900 extra text added to foo.txt // コミットメッセージ
Git プロジェクトの 3 つの領域
Git プロジェクトには状態管理の上で以下の3つの主要な場所(領域)があります。
場所 | 説明 |
---|---|
作業ディレクトリ (Working Directory) |
プロジェクトのファイルを編集・作成・削除などの作業を行うディレクトリ。ワーキングツリー(Working Tree)や作業ツリーとも呼びます。 |
ステージングエリア (Staging Area) |
作業ディレクトリから次のコミットに含める変更を追加する場所で、コミットしたい変更をまとめる「仮の領域」と考えることができます。インデックス(index)とも呼びます。 ステージングエリアに追加されたファイルは、次のコミットに含まれます。 |
Git ディレクトリ (Repository) |
Git が管理するプロジェクトのデータベースや履歴を含む特殊なディレクトリ。 Git リポジトリは通常、初期化の際にプロジェクトのルートディレクトリに .git という隠しディレクトリとして配置されます。 |
作業ディレクトリ(ワーキングツリー)には実際に編集するファイルがありますが、これらはリポジトリの特定のバージョンのファイル一式が展開されていると捉えることができます。
基本的には、作業ディレクトリでファイルの変更を行い、変更内容をステージングエリアに追加して、ステージングエリアの内容をコミットすることでリポジトリの履歴に変更が記録されます。
リポジトリとワーキングツリー
Git の管理下にあるプロジェクトは、リポジトリ(本体)とワーキングツリーから構成されます。
リポジトリの本体(.git ディレクトリ)を含むディレクトリ全体(プロジェクトのディレクトリ)をリポジトリと呼ぶこともあります。
リポジトリ(Repository)
リポジトリの本体は、Git が管理するプロジェクトのデータベースや歴史を含む特殊なディレクトリです。
Git リポジトリは通常、初期化の際にプロジェクトのルートディレクトリに ".git" という隠しフォルダとして配置され、以下のような情報が含まれます。
-
- プロジェクトのすべてのファイルのコピー
- リポジトリにはプロジェクト内のすべてのファイルとその変更履歴が保存されます。この履歴によって、過去のコミットの状態に戻ったり、異なるブランチを切り替えたりできます。
-
- コミット履歴
- リポジトリには、過去のコミットの履歴が保存されています。各コミットには、変更されたファイルのスナップショット、コミットメッセージ、コミットした人の情報、コミット日時などが含まれます。
-
- ブランチやタグ
- リポジトリには、異なるブランチ(バージョンの分岐)やタグ(特定のコミットをマークする参照)などの情報が保存されています。
ワーキングツリー(Working Tree)
Git のワーキングツリー(Working Tree)は実際にファイルを編集し、変更を加えるための場所です。作業ディレクトリ(Working Directory)とも呼びます。
リポジトリ内の特定のバージョンをワーキングツリーに展開することで、そのバージョンのファイルが実際に編集可能な状態になります。通常はリポジトリに保存されている直近の状態が展開されています(通常、ワーキングツリーはローカルのファイル システムと同期しています)。
ワーキングツリー内でファイルを編集、追加、削除することができ、これらの変更は Git によって追跡され、新しいコミットとして保存することができます。
言い方を変えると、Git の管理下にあるファイルとディレクトリへの変更はワーキングツリーに即座に反映されます。
ステージングエリア(Staging Area)
ステージングエリアは、Git にファイルの変更を準備させる場所です。
ワーキングツリーから Git リポジトリに変更を反映させる前に、変更を一時的にステージングエリアに追加します。
ステージングエリアにファイルを追加することで、次のコミットに含める変更を明示的に指定できます。
ステージングエリアは一般的に「インデックス(index)」と呼ばれる特別なファイル(データ構造)です。
index ファイルは Git が内部的に使用するバイナリファイルで、Git が変更を追跡するためのデータ構造が含まれています(直接編集することは推奨されません)。
このインデックスは、ステージングエリアに含まれるファイルに関する情報を記述しています。
インデックスは、以下の情報を保持しています。
-
- ファイルのパスと内容のスナップショット
- ステージングエリアにある各ファイルについて、そのパスと内容のスナップショットがインデックスに記録されます。このスナップショットは、ステージングエリアに追加された時点のファイルの状態を示します。
-
- ファイルのハッシュ
- インデックスは、ファイルの内容を識別するために、それぞれのファイルに対してハッシュ値(SHA-1ハッシュ)を計算して保存します。これにより、ファイルの内容が変更されたかどうかを検出することができます。
-
- ファイルの状態情報
- インデックスは、各ファイルの状態情報(トラッキング情報)を持っています。これは、ファイルが新規作成、変更、削除されたかなどの情報を含みます。
Git のワークフローでは、ファイルの変更をステージングエリアに追加することで、インデックスが更新され、変更の情報が記録されます。そして、コミットコマンドを実行すると、インデックスに記録された情報が新しいコミットとしてリポジトリに保存されます。
インデックスが存在することで、Git はコミットに含める変更を明示的に指定することができます。これにより、コミットに含まれる変更を柔軟に管理し、不要な変更を除外するなど、より制御されたバージョン管理が可能となります。
index ファイル
index ファイルはバイナリファイルなので cat コマンドで表示しようとすると文字化けします。
必要であれば、git ls-files コマンドで index の内容を確認できます。
% git ls-files --stage
ファイルの3つの主要な状態
Git で管理するファイルには以下のような3つの主要な状態があります。
状態 | 説明 |
---|---|
Modified 変更済み |
ワーキングツリー内のファイルが変更された状態。ファイルに変更が加えられたが、まだ Gitのバージョン管理(リポジトリ)に含まれていない状態です。ファイルを編集すると、そのファイルは「変更済み」としてマークされます。 |
Staged ステージング済み |
変更済みのファイルがステージングエリア(インデックス)に追加されている状態。Staged 状態にあるファイルは、次のコミットに含まれます。 |
Committed コミット済み |
変更済みのファイルがローカルリポジトリに保存された状態(ステージングされた変更がローカルリポジトリにコミットされ、永続的に保存された状態) |
- ファイルを編集すると、「変更済み」としてマークされます。
- 変更をステージングエリアに追加すると、「ステージング済み」としてマークされます。
- ステージングされた変更をコミットすると、「コミット済み」としてローカルリポジトリに永続的に保存されます。
追跡(Tracked / Untracked)
ワーキングツリー内の各ファイルには大きく分けると、tracked(追跡されているもの)と untracked(追跡されてないもの)の二通りがあります。
ファイル | 説明 |
---|---|
Tracked 追跡済み |
リポジトリの直近のスナップショットに存在したファイル(Git が変更を追跡しているファイル)です。言い換えると、Git によりバージョン管理されているファイルです。 これらのファイルには以下の3つの状態があります。
|
Untracked 未追跡 |
リポジトリの直近のスナップショットには存在せず、ステージングエリアにも存在しないファイル(Git が変更を追跡していないファイル)のことで、上記のいずれの状態にも属しません。 新規に作成したファイルやリポジトリを初期化後まだ Git に登録していないファイル、追跡対象から外されたファイルは Untracked と認識されます。 |
新たにプロジェクトでリポジトリを初期化した直後はどのファイルも Git 管理下にない(リポジトリに登録されていない)ので、全てのファイルは Untracked(未追跡の状態)です。また、新たにプロジェクトに追加したり作成したファイルもリポジトリに登録されていないので Untracked です。
初期化直後のファイルや新規作成したファイルは git add
コマンドを使用してファイルの追跡を開始し、git commit
コマンドでコミットする(リポジトリに記録する)と、Tracked(追跡済み)かつ Unmodified(未変更)となります。
また、プロジェクトをクローンした直後の場合は、リポジトリから取得してまだ何も編集していない状態なので、すべてのファイルは Tracked(追跡済み)かつ Unmodified(未変更)となります。
管理対象のファイルを編集すると、Git はそれを「変更された(Modified)」とみなします。
変更されたファイルをステージに追加すると「ステージされている(Staged)」とみなされます。
それをコミットすると Tracked かつ Unmodified となります。この繰り返しで管理します。
Committed(コミット済み)
変更をコミットした直後の状態は「Committed」(コミット済み)であり、同時にファイルは直近のコミットから変更がないので、「Unmodified」(未変更)であると言えます。 Git ではファイルの状態は次のように進行します。
- Unmodified(未変更): 直近のコミット以降、ファイルに変更が加えられていない状態です。つまり、ファイルがリポジトリに保存されている最新のコミットと同じ内容です。
- Modified(変更済み): ファイルが変更された状態ですが、まだステージングされていないため、変更はコミットされていない状態です。
- Staged(ステージング済み): 変更済みのファイルがステージングエリアに追加された状態です。変更は次のコミットに含まれる予定です。
- Committed(コミット済み): ステージングされたファイルがローカルリポジトリに確定された状態です。変更は永続的に記録されました。
- Unmodified(未変更): 直近のコミット以降、ファイルに変更が加えられていない状態です。つまり、ファイルがリポジトリに保存されている最新のコミットと同じ内容です。
コミットした直後は「Committed」の状態であり、同時に「Unmodified」の状態でもあります。変更がコミットされると、ファイルは「Unmodified」としてマークされ、次回の変更が行われるまでその状態が維持されます。
help(コマンドの詳細)の表示
git help
を実行するとよく使われる git コマンドのリストが表示されます。
% git help usage: git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path] [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare] [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>] [--config-env=<name>=<envvar>] <command> [<args>] These are common Git commands used in various situations: start a working area (see also: git help tutorial) clone Clone a repository into a new directory init Create an empty Git repository or reinitialize an existing one work on the current change (see also: git help everyday) add Add file contents to the index mv Move or rename a file, a directory, or a symlink restore Restore working tree files rm Remove files from the working tree and from the index examine the history and state (see also: git help revisions) bisect Use binary search to find the commit that introduced a bug diff Show changes between commits, commit and working tree, etc grep Print lines matching a pattern log Show commit logs show Show various types of objects status Show the working tree status grow, mark and tweak your common history branch List, create, or delete branches commit Record changes to the repository merge Join two or more development histories together rebase Reapply commits on top of another base tip reset Reset current HEAD to the specified state switch Switch branches tag Create, list, delete or verify a tag object signed with GPG collaborate (see also: git help workflows) fetch Download objects and refs from another repository pull Fetch from and integrate with another repository or a local branch push Update remote refs along with associated objects 'git help -a' and 'git help -g' list available subcommands and some concept guides. See 'git help <command>' or 'git help <concept>' to read about a specific subcommand or concept. See 'git help git' for an overview of the system.
各コマンドのヘルプを参照するには以下の3つの方法があります。<command> はコマンド名です。
% git help <command> //(例)git help config % git <command> --help //(例)git config --help % man git-<command> //(例)man git-config
space キーで一画面分スクロールでき、return キーで一行分スクロールできます。終了するには q キーを押します。※ less コマンドなどのキー操作と同じです。
表示される内容は Git の Reference と同じです。
GIT-CONFIG(1) NAME git-config - Get and set repository or global options SYNOPSIS git config [<file-option>] [--type=<type>] [--fixed-value] [--show-origin] [--show-scope] [-z|--null] <name> [<value> [<value-pattern>]] git config [<file-option>] [--type=<type>] --add <name> <value> git config [<file-option>] [--type=<type>] [--fixed-value] --replace-all <name> <value> [<value-pattern>] git config [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] [--fixed-value] --get <name> [<value-pattern>] git config [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] [--fixed-value] --get-all <name> [<value-pattern>] git config [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] [--fixed-value] [--name-only] --get-regexp <name-rege x> [<value-pattern>] git config [<file-option>] [--type=<type>] [-z|--null] --get-urlmatch <name> <URL> git config [<file-option>] [--fixed-value] --unset <name> [<value-pattern>] git config [<file-option>] [--fixed-value] --unset-all <name> [<value-pattern>] git config [<file-option>] --rename-section <old-name> <new-name> git config [<file-option>] --remove-section <name> git config [<file-option>] [--show-origin] [--show-scope] [-z|--null] [--name-only] -l | --list git config [<file-option>] --get-color <name> [<default>] git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>] git config [<file-option>] -e | --edit DESCRIPTION You can query/set ・・・以下省略・・・ // 終了するには q を押します
以下を実行すると全ての git のサブコマンドのリストが表示されます。
% git --help -a; // コマンドのリストを表示(git help -a でも同じ) See 'git help <command>' to read about a specific subcommand Main Porcelain Commands add Add file contents to the index am Apply a series of patches from a mailbox archive Create an archive of files from a named tree bisect Use binary search to find the commit that introduced a bug branch List, create, or delete branches bundle Move objects and refs by archive checkout Switch branches or restore working tree files cherry-pick Apply the changes introduced by some existing commits citool Graphical alternative to git-commit clean Remove untracked files from the working tree clone Clone a repository into a new directory commit Record changes to the repository describe Give an object a human readable name based on an available ref diff Show changes between commits, commit and working tree, etc fetch Download objects and refs from another repository format-patch Prepare patches for e-mail submission gc Cleanup unnecessary files and optimize the local repository gitk The Git repository browser grep Print lines matching a pattern gui A portable graphical interface to Git init Create an empty Git repository or reinitialize an existing one log Show commit logs ・・・以下省略・・・ // 終了するには q を押します
Git で管理を始める(リポジトリの取得)
Git でバージョン管理を行うには、Git リポジトリを作成または取得する必要があります。
通常、Git リポジトリは次の方法のいずれかで取得します。
- Git で管理されていないプロジェクトのディレクトリを Git リポジトリとして初期化する
- 既存の Git リポジトリをクローンする(リモートリポジトリをローカルに複製する)
プロジェクトでリポジトリの初期化
プロジェクトのサンプルとして my-project というディレクトリを作成し、その中に1つのテキストファイルを作成します。
% mkdir my-project // my-project というディレクトリを作成 % cd my-project // my-project へ移動 % touch file1.txt // 空のテキストファイル(file1.txt)を作成
リポジトリの作成 git init
既存のプロジェクトを Git で管理し始める場合は、そのプロジェクトのディレクトリに移動して git init コマンドを実行してリポジトリを作成します。この操作をリポジトリを初期化するとも言います。
% git init // リポジトリを初期化 Initialized empty Git repository in /.../my-project/.git/
git init コマンドを実行すると .git という名前の新しいサブディレクトリが作られ、リポジトリに必要なすべてのファイルがその中に格納されます。
.git ディレクトリは隠しフォルダになっているので、確認するには見えるようにしておく必要があります。Mac の場合は command + shift + . で表示することができます。
この時点では、まだプロジェクト内のファイルは一切管理対象になっておらず、リポジトリ(.git)の中身はスケルトンの状態でまだ情報はありません。以下は tree コマンドでリポジトリの内容を表示しています。
% tree .git // 初期化直後の .git ディレクトリの内容をツリー表示 .git ├── HEAD ├── config ├── description ├── hooks │ ├─ 中略 │ └── update.sample ├── info │ └── exclude ├── objects │ ├── info │ └── pack └── refs ├── heads └── tags
git init コマンド
Git で管理したいプロジェクトのトップ(一番上の)ディレクトリで git init を実行すると Git の初期化が行われ、git init を実行したディレクトリ直下に .git というディレクトリが作られ、Git の管理情報は全てこのディレクトリに格納されます。
また、git init コマンドにディレクトリを指定して、指定したディレクトリとその中に空のリポジトリを作成することもできます。
% git init git-project // git-project ディレクトリを作成してその中にリポジトリを作成 Initialized empty Git repository in /.../git-project/.git/
状態の確認 git status
git status コマンドを使ってファイルがどの状態(ステータス)にあるのかを確認することができます。
git status コマンドはワーキングツリーのファイルとリポジトリに記録された情報を比較して差分のあるファイルなどを表示します。
この時点で git status コマンドを実行すると、まだ、このプロジェクトのファイルはリポジトリに登録されていないので、Untracked files(未追跡)として file1.txt が赤で表示されます。
% git status // 状態を確認
On branch main // 現在のブランチの名前
No commits yet //まだ、コミットはない
Untracked files:
(use "git add <file>..." to include in what will be committed)
file1.txt // 追跡されてないファイル
nothing added to commit but untracked files present (use "git add" to track)
git status のレスポンスには現在の状態が表示されます。上記のレスポンスからは以下がわかります。
- 現在のブランチ名:main (デフォルトのブランチ)
- まだ、コミットが実行されていないこと
- 追跡されていない(リポジトリに存在しない)ファイルとして file1.txt が存在すること
- file1.txt を追跡する(次回のコミットに含める)には git add コマンドを実行すること
git statu コマンド
git status コマンドを使用すると、どのファイルに変更があるのか、それがどのステージにあるのか、またコミットされていない変更があるかどうかなどを簡単に確認することができます。
git status コマンドは、ワーキングツリー内のファイルとリポジトリ内のファイル(最後にコミットされた状態)を比較して、その間に生じた違いを表示します。
具体的には、以下の情報が表示されます。
- 変更済みファイルの一覧: ワーキングツリー内で変更されたファイルが表示されます。これには新しく追加されたファイル、修正されたファイル、削除されたファイルなどが含まれます。
- ステージングエリアに追加された変更: git add コマンドを使用してステージングエリアに追加された変更が表示されます。これは、次のコミットに含まれる変更を指します。
- コミットされていない変更: まだコミットされていない変更が表示されます。これらの変更はまだ履歴に記録されていないため、コミットする必要があります。
- 現在のブランチ: 現在のブランチ名が表示されます。どのブランチで作業しているかがわかります。
- リモートブランチとの差分: リモートリポジトリとの差分が表示されます。リモートリポジトリに存在する変更と、ローカルリポジトリでの変更との違いが示されます。
ステージングエリアに追加 git add
git add コマンドはインデックスを更新し、指定したファイルを次回のコミットの対象に含めます。
Git ではこの操作をステージングと呼び、ファイルをステージングエリアに追加するなどと言います。
以下を実行して file1.txt をステージングエリアに追加し、ファイルの追跡を開始します。
% git add file1.txt // file1.txt をステージングエリアに追加
git status コマンドを実行してステータスを確認してみると以下のように Changes to be committed に new file として file1.txt が緑色で表示されます。
Changes to be committed には ステージングエリアに追加された次回のコミットに含まれるファイルが表示され、新たに追加されたファイルなのでファイル名の前に new file と表示されています。
% git status
On branch main
No commits yet
Changes to be committed: // ステージングエリアに追加されたファイルが表示される
(use "git rm --cached <file>..." to unstage)
new file: file1.txt
git add コマンド
ワーキングツリーに変更を加えた後は commit コマンドを実行する前に、 git add コマンドを使用し、新しいファイルまたは変更されたファイルをインデックス(ステージングエリア)に追加します。
git add コマンドには対象のファイルのパスを指定しますが、ワーキングツリー全体を追加したい場合には、以下のように .
を指定することができます。
% git add .
また、シェルのワイルドカードを使ってファイルを指定することもできます。
以下は変更があったテキストファイルを全てステージングエリアに追加する(ステージする)例です。
% git add *.txt
コミット git commit
git commit コマンドで、変更(この場合は新しいファイルの追加)をリポジトリにコミットします。
git commit コマンドはオプション無しで実行すると、デフォルトのテキストエディタが起動しますが -m オプションを使えば、コミットメッセージを直接インラインでコマンドに指定することができます。
以下の例では、-m オプションを付けてコミットメッセージをインラインで記述しています。
% git commit -m "first commit" [main (root-commit) 37fda94] first commit 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 file1.txt
git status コマンドを実行してステータスを確認すると、nothing to commit, working tree clean と表示されます。
これは「追跡されているファイルの中に変更されているものがなく、追跡されていないファイルも存在しない」、つまりワーキングツリーとリポジトリの直近のスナップショットが同じであることを意味します。
これでプロジェクト file1.txt のスナップショットがリポジトリに登録され、Git のバージョン管理対象になります。
% git status On branch main nothing to commit, working tree clean
git commit コマンド
コミットとはインデックスに登録されている状態(スナップショット)を、コミットとしてリポジトリに保存する操作です。
また、Git ではコミットをする際にコミットメッセージをつけることが必須です。
git commit コマンドはオプション無しで単に git commit と実行すると、デフォルトエディタが開いてコミットメッセージを求められますが、-m オプションに続けてコミットメッセージを指定して、エディタを開くことなくコマンドラインからコミットすることができます。
git log でコミットの履歴を確認
git log コマンドを使用すると、コミットの履歴を確認することができます。
% git log commit 37fda9418964d932e34d4ab85b51e4abe59ca46a (HEAD -> main) Author: foo <foo@example.com> Date: Mon Jul 31 16:04:47 2023 +0900 first commit
以下の情報が表示されます。
- コミットの SHA-1 チェックサム(コミットを識別するための文字列)
- コミットしたユーザーの情報
- 日付
- コミットメッセージ
既存の Git リポジトリをクローン
Git リポジトリを取得するには、前述の既存プロジェクトでリポジトリを初期化する方法以外に git clone コマンドを使って既存の Git リポジトリをクローンする方法があります。
リモートリポジトリ(共有リポジトリ)を利用して開発を進める場合などでは、クローンしてワーキングツリーをローカルに作成することができます。
git clone コマンドを使ったクローンはサーバ(指定した既存の Git プロジェクト)が保持しているデータをほぼすべてローカルにコピーします。
リモートリポジトリを取得して、ワーキングツリーを作成するには git clone にリモートリポジトリの URL を指定します。
以下を実行すると、コマンドを実行したディレクトリの中に simplegit-progit ディレクトリが作成されクローンしたリポジトリとデータが格納されます。
https://github.com/schacon/simplegit-progit は Pro Git book 用のサンプルのプロジェクトです。
% git clone https://github.com/schacon/simplegit-progit Cloning into 'simplegit-progit'... remote: Enumerating objects: 13, done. remote: Total 13 (delta 0), reused 0 (delta 0), pack-reused 13 Receiving objects: 100% (13/13), done. Resolving deltas: 100% (3/3), done.
上記は simplegit-progit というディレクトリを作成してその中で .git ディレクトリを初期化し、リポジトリのすべてのデータを抽出し、そして最新バージョンの作業コピーをチェックアウトします。
別の名前のディレクトリにクローンするには、コマンドラインオプションでディレクトリ名を指定します。
以下は上記と同じ処理をしますが、ディレクトリ名は my-git-project となります。
% git clone https://github.com/schacon/simplegit-progit my-git-project
git status コマンドでステータスを確認すると以下のように "nothing to commit, working tree clean" と表示され、既存プロジェクトをクローンした直後ではワーキングツリーのファイルとリポジトリの直近のスナップショットは同じ状態になっていることがわかります。
また、現在のブランチは master で origin リモートリポジトリの master ブランチと同期していることもわかります(origin という名前は、通常リモートリポジトリに付けられるデフォルトの名前です)。
% git status On branch master Your branch is up to date with 'origin/master'. nothing to commit, working tree clean
git log コマンドを実行すると、クローンしたプロジェクトのコミットの履歴を確認することができます。
% git log commit ca82a6dff817ec66f44342007202690a93763949 (HEAD -> master, origin/master, origin/HEAD) Author: Scott Chacon <schacon@gmail.com> Date: Mon Mar 17 21:52:11 2008 -0700 changed the verison number commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 Author: Scott Chacon <schacon@gmail.com> Date: Sat Mar 15 16:40:33 2008 -0700 removed unnecessary test code commit a11bef06a3f659402fe7563abf99ad00de2209e6 Author: Scott Chacon <schacon@gmail.com> Date: Sat Mar 15 10:31:28 2008 -0700 first commit
Git の管理を止める
Git で管理しているプロジェクトの管理を止めるには以下の手順を実行します。
※ リポジトリの履歴や変更履歴は削除され、元に戻すことが難しくなります。
- バックアップ:念のため、プロジェクトディレクトリのバックアップを取ります。
- リポジトリの削除:プロジェクトディレクトリ内の .git ディレクトリを削除します。
リポジトリの削除は、隠しフォルダを表示して、.git ディレクトリを右クリックから削除すればゴミ箱に移動するので戻すことは可能ですが、以下を実行すると戻すことはできません。
//プロジェクトのルートディレクトリで以下のコマンドを実行します rm -rf .git // .git ディレクトリを削除
サンプルプロジェクトの削除
練習用に作成した Git のプロジェクトなどが不要になった場合は、単にフォルダごとゴミ箱に入れいれば削除できます。
変更をリポジトリへ保存
バージョン管理を利用する場合、ファイルを変更したら切りが良いところなど特定のタイミングでファイルの状態をリポジトリに保存します。
以下はファイルの変更からファイルの状態の保存までの基本的なワークフローです。
-
ワーキングツリー上のファイルを変更、またはファイルを新たに追加
-
git add コマンドで変更済みのファイルをステージングエリア(インデックス)に追加
-
git commit コマンドでステージングエリアに追加された内容をリポジトリに保存(コミット)
サンプルとして my-project2 という名前のディレクトリを作成し、リポジトリを初期化します。
% mkdir my-project2 // my-project2 というディレクトリを作成 % cd my-project2 // my-project2 へ移動 % git init // リポジトリを初期化 Initialized empty Git repository in /.../my-project2/.git/
ls コマンドに -a を指定して隠しファイルも表示するようにして実行すると .git ディレクトリ(リポジトリ)が作成されていることが確認できます。
% ls -a // 隠しファイルも含めて一覧表示 . .. .git
これでこのディレクトリ my-project2 内のファイルの変更を Git に追跡してもらう準備ができました。
この時点で git status コマンドを使用してステータスを確認すると、現在ファイルは1つもないので、以下のように nothing to commit(コミットするものは何もない)と表示されます。
% git status // ステータスを確認 On branch main No commits yet nothing to commit (create/copy files and use "git add" to track)
ファイルの追加
新しいファイル hello.txt を作成してディレクトリ my-project2 に追加します。
% echo Hello Git! > hello.txt
git status コマンドでステータスを確認すると、Untracked files(未追跡のファイル)として追加した hello.txt が表示されています。
これは、まだ Git がこのファイルを追跡していないため(リポジトリにスナップショットがないため)このように表示されます。
% git status
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
hello.txt // 追跡されてないファイル
nothing added to commit but untracked files present (use "git add" to track)
ファイルをステージングエリアに追加 git add
git add コマンドを使って新規作成したファイルをステージングエリアに追加します。
git add コマンドには、ファイルあるいはディレクトリのパスを指定します。ディレクトリを指定した場合は、そのディレクトリ以下にあるすべてのファイルを再帰的に追加します。
% git add hello.txt
git status コマンドでステータスを確認すると、Changes to be committed に new file として hello.txt が緑色で表示されます。Changes to be committed にはステージングエリアの内容が表示されます。
% git status
On branch main
No commits yet
Changes to be committed: // 次回のコミットに含まれるファイル(ステージングエリアの内容)
(use "git rm --cached <file>..." to unstage)
new file: hello.txt
変更をコミット git commit
ステージングエリアに追加された変更(この場合は、新規ファイルの追加)は、コミットを実行することでリポジトリの履歴に記録されます。コミットによって、ステージングエリアの内容がリポジトリ内の新しいスナップショット(バージョン)として保存されます。
git commit コマンドでコミットを実行します。
% git commit
git commit コマンドをオプション無しで実行すると、デフォルトエディタが起動し、以下のような画面が表示されます。コミットメッセージを作成後ファイルを保存してエディタを終了するとコミットが実行されます。
#で始まる行はコミットメッセージには含まれません。例えば、以下のままメッセージを作成せずにエディタを終了するとコミットは中止されます。
# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch main # # Initial commit # # Changes to be committed: # new file: hello.txt # ~ ~
メッセージを作成(編集)するには、i キーを押してインサートモードに切り替えて、コミットメッセージを編集します。以下は Initial commit の前の # を外してその部分をコミットメッセージとしています。
関連ページ:vim の使い方
# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch main # Initial commit # # Changes to be committed: # new file: hello.txt # ~ ~ -- INSERT -- // インサートモード
または、先頭にメッセージを記述しても同じです(#で始まる行はコミットメッセージには含まれません)。
Initial commit # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch main # # Initial commit # # Changes to be committed: # new file: hello.txt # ~ ~ -- INSERT -- // インサートモード
編集が終了したら esc キーを押し、:wq と入力し、return キーを押して保存すると、コミットが実行されます。
% git commit [main (root-commit) 3f903a4] Initial commit // コミットメッセージ 1 file changed, 1 insertion(+) create mode 100644 hello.txt
Git のエディタを VS code に変更する
デフォルトで起動するテキストエディタを VS Code にするには以下を実行します。
% git config --global core.editor "code --wait"
VS Code でコミットメッセージを編集する場合、編集後保存してそのタブを閉じるとコミットされます(タブを閉じるまで待機します)。
関連:
git commit コマンド -m オプション
-m オプションを使えば、テキストエディタを起動せずに、コミットメッセージを直接インラインでコマンドに指定することができます。以下でも上記と同じ結果になります。
% git commit -m "Initial commit"
コミット後、ステータスを確認すると以下のように表示されます。
% git status On branch main nothing to commit, working tree clean
上記のメッセージは以下のことを意味します。
- On branch main :現在、mainブランチにいる
- nothing to commit :現在のワーキングツリーには変更をコミットする必要がない
- working tree clean :ワーキングツリーが「クリーン」である(変更されたファイルがない)
git log コマンドでコミットの履歴を確認すると、例えば以下のように表示されます。
% git log commit 3f903a46cdb83d13bbb1d843029f11ee5f67e589 (HEAD -> main) Author: foo <foo@example.com> Date: Tue Aug 1 15:33:49 2023 +0900 Initial commit
git log の出力にはコミット履歴が表示され、それぞれのコミットのハッシュ値(SHA-1 チェックサム)や日付、コミットメッセージなどの情報が含まれています
上記のファイルの追加のコミットは、先述の既存プロジェクトでのリポジトリの初期化でのファイルの登録と同様、Untracked の状態のファイルをまずステージし、コミットしてリポジトリに登録しています。
ファイルの変更
先述のサンプルの続きです。現在の状態を確認します。
コミット後、何も変更していないので nothing to commit, working tree clean と表示されます。
% git status On branch main nothing to commit, working tree clean
先に作成したテキストファイル hello.txt にテキストを追加し、ファイルを変更します。
% echo additional text >> hello.txt //テキストを追加 % cat hello.txt //テキストファイルの内容を表示 Hello Git! additional text // 追加されたテキスト
git status でステータスを確認すると以下のように表示されます。
Changes not staged for commit(ステージングエリアに追加されていない変更)に変更済み(modified)のファイルとして hello.txt が表示されています。これは hello.txt に変更が加えられたが、まだコミット対象にはなっていないことを意味しています。
レスポンスを読むと変更をコミットするための手順などが記載されています。
use "git add <file>..." to update what will be committed は「コミットを更新するには、git add コマンドを使用する」とあり、また、use "git restore <file>..." to discard changes in... は「ワーキングツリーでの変更を取り消すには、git restore コマンドを使用する」というような意味になります。
% git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: hello.txt // 変更が検知されたファイル
no changes added to commit (use "git add" and/or "git commit -a")
ファイルの変更をコミットするには、まず git add コマンドを使って変更されたファイルをステージングエリアに追加します。
ファイルをステージングエリアに追加
git add コマンドを使って変更されたファイル hello.txt をステージングエリアに追加します。そしてステータスを確認すると以下のように hello.txt がステージングされ、変更がコミットできる状態になっています。
% git add hello.txt //ファイルをステージングエリアに追加
% git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: hello.txt
変更をコミット git commit
コミットする準備が整ったので、変更をコミットします。
以下は -m オプションを使ってコミットメッセージを直接インラインで指定してコミットしています。
% git commit -m "text added" [main 5cac768] text added 1 file changed, 1 insertion(+)
git status を実行すると、コミット直後なので以下のように表示されます。これで変更はリポジトリに保存されました。
% git status On branch main nothing to commit, working tree clean
git log を実行すると、これまでにコミットを2回行っているので、以下のように2回のコミットのログが表示されます。
% git log commit 5cac768fa17a08989926ee972240b044277b7224 (HEAD -> main) Author: foo <foo@example.com> Date: Thu Aug 1 15:43:04 2023 +0900 text added //コミットメッセージ commit 3f903a46cdb83d13bbb1d843029f11ee5f67e589 Author: foo <foo@example.com> Date: Tue Aug 1 15:33:49 2023 +0900 Initial commit //コミットメッセージ
ステージ後の変更
ファイルにテキストを追加して変更し、ステータスを確認します。
% echo additional text2 >> hello.txt // ファイルを変更
% cat hello.txt // ファイルを表示
Hello Git!
additional text
additional text2 // 追加したテキスト
% git add hello.txt // ファイルをステージングエリアに追加
% git status // ステータスを確認
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: hello.txt
コミットする前に、ステージングエリアに追加されているファイルを再度変更してみます。
% echo some more text >> hello.txt % cat hello.txt Hello Git! additional text additional text2 some more text // ステージ後に追加したテキスト
ここでステータスを確認すると、Changes to be committed と Changes not staged for commit の両方に hello.txt が表示されています。
Git は「git add コマンドを実行した時点の状態のファイル」をステージします。 ここでコミットをすると、実際にコミットされるのは git add を実行した時点の hello.txt であり、リポジトリのスナップショットとワーキングツリーにある内容とは違うものになります。
% git status On branch main Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: hello.txt Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: hello.txt
git add した後にファイルを変更した場合に、最新版のファイルをステージしなおすにはもう一度 git add を実行します。 ステータスを確認すると、Changes not staged for commit はなくなり、ステージ済みのファイルとしてのみ hello.txt が表示されます。
% git add hello.txt // もう一度 git add を実行
% git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: hello.txt
必要に応じてコミットします。
% git commit -m "3rd commit" [main c017211] 3rd commit 1 file changed, 2 insertions(+) //1つのファイルが変更され、2行が追加された
変更の差分を表示 git diff
git diff コマンドを使用すると、変更の差分を表示して確認することができます。
hello.txt を新しい文字列で上書きして変更します。
% echo Hello Again! > hello.txt // ファイルを上書き my-project2 % cat hello.txt Hello Again!
まだステージングエリアに追加していないので、ステータスを確認すると以下のように表示されます。
% git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: hello.txt
no changes added to commit (use "git add" and/or "git commit -a")
ワーキングツリーとインデックスの差分を表示
git diff コマンドを引数無しで実行すると、ワーキングツリーの内容とステージングエリア(インデックス)の内容を比較します。以下では上書きにより削除された4行と追加された行が確認できます。
% git diff //ワーキングツリーとインデックスの差分を表示 diff --git a/hello.txt b/hello.txt index d6eb0c5..48abe86 100644 --- a/hello.txt +++ b/hello.txt @@ -1,4 +1 @@ -Hello Git! -additional text -additional text2 -some more text +Hello Again!
hello.txt をステージングエリア(インデックス)に追加します。
% git add hello.txt
% git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: hello.txt
再度、git diff コマンドを引数無しで実行すると、hello.txt はすでにステージされているので、ワーキングツリーの内容とステージングエリア(インデックス)の内容は同じなので何も表示されません。
% git diff //何も表示されない
インデックスとリポジトリの差分を表示
git diff に --cached または --staged オプションを指定するとインデックスとリポジトリの内容を比較して差分を表示します。
% git diff --cached //インデックスとリポジトリの差分を表示 diff --git a/hello.txt b/hello.txt index d6eb0c5..48abe86 100644 --- a/hello.txt +++ b/hello.txt @@ -1,4 +1 @@ -Hello Git! -additional text -additional text2 -some more text +Hello Again!
必要に応じてコミットします。
% git commit -m "overwrite" [main bbeb4bd] overwrite 1 file changed, 1 insertion(+), 4 deletions(-) // 1つのファイルが変更され、1行が追加され、4行が削除された
git log コマンドで履歴を確認して、特定のファイルのある時点との差分を表示することもできます。
関連項目:VS Code で差分を表示
ステージングエリアの省略
通常、コミットはファイルをステージングエリアに追加してから実行する必要があります。そのため以下のようにステージせずにコミットをしようとしてもできません。
% echo Goodbye! >> hello.txt // ファイルを変更 % git commit -m "goodbye added" // ステージせずにコミットしようとしてもできない On branch main Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: hello.txt no changes added to commit (use "git add" and/or "git commit -a")
上記のレスポンスにも表示されていますが、git add または git commit -a を実行する必要があります。
git commit -a ステージの省略
git commit コマンドに -a オプションを指定すると、追跡対象となっているファイルを自動的にステージしてからコミットすることができ、ステージングエリアへの追加(git add)を省略することができます。
% git commit -a -m "goodbye added" // -a オプションを指定してステージングエリアをスキップ [main 9bc0d5f] goodbye added 1 file changed, 1 insertion(+)
-a と -m はまとめて -am のように指定することができます。
% git commit -am "goodbye added" // -a -m をまとめて指定
※ -a フラグは便利ですが、意図しない変更をコミットに含んでしまうことにもなるので注意が必要です。
Git の管理から除外する
プロジェクトディレクトリには含めておきたいけれど、Git リポジトリに含めたくないファイルやディレクトリがある場合、プロジェクトディレクトリに .gitignore ファイルを配置することで、Git がファイルの変更を追跡しないようにすることができます。
但し、すでにインデックスに追加されているファイルは後から除外設定をしても除外設定は反映されません(インデックスに追加されているファイルを除外)。
.gitignore ファイルの書き方は以下の通りです。
- 行ごとに1つのパターンを指定します。
- パターンは、ファイル名、ディレクトリ名、ワイルドカードを含めることができます。
- #で始まる行はコメント行として無視されます。
- パターンの指定方法には次のようなものがあります:
- ファイル名の完全一致: file.txt(file.txt というファイルを除外)
- ワイルドカードの使用: *.log(.log拡張子を持つすべてのファイルを除外)
- ディレクトリを無視: /my_directory/(my_directoryディレクトリ全体を除外)
- ディレクトリ以下のすべての内容を除外: /my_directory/*
- 特定のパターンを対象外にする: !important_file.txt(important_file.txt を除外しない)
表現 | 意味 |
---|---|
* |
0個以上の任意の文字にマッチ |
? |
任意の1文字にマッチ |
[abc] |
a、b、cのいずれかの文字にマッチ |
[0-9] |
0から9の数字のいずれかにマッチ |
** |
ゼロ個以上のサブディレクトリに再帰的にマッチ |
*.{txt,md} |
.txtまたは.md拡張子のファイルにマッチ |
! |
除外を示し、パターンにマッチするものを除外 |
※ .gitignore ファイル自体も Git リポジトリに含める必要があるため、作成した後にコミットしてリポジトリに追加する必要があります。
例えば password.txt というファイルがプロジェクトディレクトリにあり、これを Git で管理していない場合、git status を実行すると、追跡されていないファイルとして毎回表示されます。
% git status
On branch main
Untracked files:
(use "git add <file>..." to include in what will be committed)
password.txt
nothing added to commit but untracked files present (use "git add" to track)
.gitignore というファイルを作成して、プロジェクトのルートディレクトリに配置し、除外するファイルとして password.txt を記述します。
% echo password.txt > .gitignore // .gitignore を作成して password.txt を記述 % cat .gitignore // .gitignore の内容を表示 password.txt
git status を実行すると .gitignore が追跡されていないファイルとして表示されます。
% git status
On branch main
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
nothing added to commit but untracked files present (use "git add" to track)
.gitignore もコミットする必要があるので、ステージ後、コミットします。
% git add .gitignore // .gitignore をステージングエリアに追加 % git commit -m "adds .gitignore" // .gitignore をコミット
これで .gitignore が有効になり、指定した password.txt が管理から除外されます。
% git status On branch main nothing to commit, working tree clean
.gitignore を更新した場合もステージングエリアに追加後、コミットする必要があります。
.gitignore ファイルの場所
.gitignore ファイルはプロジェクトのルートディレクトリに置くことが一般的です。
ルートディレクトリに置くことですべてのサブディレクトリに対して影響を与えることができ、また、管理しやすくなります(必要に応じて異なるディレクトリに配置することもできます)。
インデックスに追加されているファイルを除外
すでに一度 git add でステージしたファイル(インデックスに追加されているファイル)は後から除外設定をしても除外設定は反映されません。
すでにインデックスに追加されているファイルを除外するには、git rm --cached
コマンドでインデックスから削除してから .gitignore に追加します。
※ --cached を指定しない場合はファイル自体も削除されるので注意が必要です。
以下はすでにインデックスに追加されている sample.txt を git rm --cached コマンドでインデックスから削除してから .gitignore に追加する例です。
インデックスから削除したらコミットします。
% git rm --cached sample.txt rm 'sample.txt' % git commit -m "sample.txt removed from index" [main e5ce14f] sample.txt removed from index 1 file changed, 1 deletion(-) delete mode 100644 sample.txt
sample.txt をインデックスから削除したら、.gitignore に追加します。
.gitignore を更新したら、変更をステージしてコミットする必要があります
% echo sample.txt >> .gitignore // .gitignore に追加(更新) % git commit -am "add sample.txt to .gitignore" // -a オプションでステージングを省略 [main 712f243] add sample.txt to .gitignore 1 file changed, 1 insertion(+)
全てのプロジェクトで Git の管理から除外
ユーザーレベルで(全てのプロジェクトで)Git の管理からファイルやディレクトリを除外するには ~/.config/git/ignore
というファイルを作成して除外するファイルやディレクトリを指定します。
ファイルの削除
ファイルを Git から削除するには、削除したファイルをステージングエリアに追加してコミットします。
以下は削除の動作確認です。削除するサンプルのファイル foo.txt を作成し Git に登録します。
% echo this is foo > foo.txt // foo.txt を作成 % git add foo.txt // foo.txt をステージエリアに追加 % git commit -m "foo.txt added" // foo.txt をコミット [main 726c5e3] foo.txt added 1 file changed, 1 insertion(+) create mode 100644 foo.txt % git status // ステータスはクリーン On branch main nothing to commit, working tree clean
foo.txt をワーキングツリーから削除します。
ステータスを確認すると foo.txt はワーキングツリーから削除されていますが、Git には削除が反映されていないため、foo.txt の削除がステージされていないと表示されます。
% rm foo.txt // foo.txt を削除
% git status // ステータスを確認
On branch main
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: foo.txt
no changes added to commit (use "git add" and/or "git commit -a")
foo.txt をステージエリアに追加します。
% git add foo.txt // foo.txt をステージエリアに追加 % git status On branch main Changes to be committed: (use "git restore --staged <file>..." to unstage) deleted: foo.txt
コミットを実行すると削除したファイル foo.txt は管理対象外となり、追跡されていないファイルとして残り続けることはありません。
% git commit -m "foo.txt removed" //コミットを実行 [main f6d6e9e] foo.txt removed 1 file changed, 1 deletion(-) delete mode 100644 foo.txt % git status On branch main nothing to commit, working tree clean
git rm コマンドで削除
git rm コマンドを使うと、ワーキングツリーからファイルを削除し、その状態をステージングエリアに追加してくれます。
サンプルのファイル bar.txt を作成し Git に登録します。
% touch bar.txt % git add bar.txt % git commit -m "bar.txt added" [main 7990699] bar.txt added 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 bar.txt % git status On branch main nothing to commit, working tree clean
git rm コマンドを使って bar.txt を削除すると、ワーキングツリーから bar.txt が削除され、ステージングエリアに追加されます。
その後、任意のタイミングでコミットすれば bar.txt は管理対象外となります。
% git rm bar.txt // git rm コマンドで bar.txt を削除
rm 'bar.txt' // rm コマンドで削除される
% git status // ステータスを確認すると、bar.txt がステージされている
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: bar.txt
% git commit -m "bar.txt removed" // コミットを実行
[main 4ec7b2f] bar.txt removed
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 bar.txt
% git status
On branch main
nothing to commit, working tree clean
ファイル自体はプロジェクトに残すが追跡対象外とする --cached オプション
ハードディスク上にはファイルを残しておきたいけれど、もう Git では追跡させたくないというような場合は --cached オプションを使用して git rm コマンドを実行します。
以下は baz.txt というファイルをプロジェクトには残し、追跡の対象外(Untracked files)とする例です。
サンプルのファイル baz.txt を作成し Git に登録します。
% touch baz.txt // baz.txt を作成 % git add baz.txt // baz.txt をステージ % git commit -m "baz.txt added" // コミット [main fa2bf0f] baz.txt added 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 baz.txt % git status // ステータスを確認 On branch main nothing to commit, working tree clean
--cached オプションを指定して baz.txt を削除します。
削除後ステータスを確認すると、削除の変更がステージされ、Changes to be committed: と Untracked files: の両方に baz.txt がリストされています。
% git rm --cached baz.txt // --cached オプションを指定して削除 rm 'baz.txt' // 削除と表示されるがプロジェクトには残る % git status // ステータスを確認 On branch main Changes to be committed: (use "git restore --staged <file>..." to unstage) deleted: baz.txt Untracked files: (use "git add <file>..." to include in what will be committed) baz.txt
コミットを実行して、ステータスを確認すると baz.txt は追跡の対象外(Untracked files)となっています(baz.txt は物理的には削除されていません)。
% git commit -m "bax.txt removed from stage" // コミットを実行
[main 84e9692] bax.txt removed from stage
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 baz.txt
% git status // ステータスを確認
On branch main
Untracked files:
(use "git add <file>..." to include in what will be committed)
baz.txt
nothing added to commit but untracked files present (use "git add" to track)
但し、このままでは、毎回ステータスを確認すると baz.txt は Untracked として表示されてしまいます。
追跡対象外とした baz.txt を .gitignore に追加して、管理から除外すればステータスを確認しても Untracked として表示されなくなります。
そのためには .gitignore に baz.txt を追加し、.gitignore をステージしてコミットします。
% echo baz.txt >> .gitignore // .gitignore に baz.txt を追加
% cat .gitignore // .gitignore の内容を確認
password.txt
baz.txt
% git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: .gitignore
no changes added to commit (use "git add" and/or "git commit -a")
% git add .gitignore //.gitignore をステージエリアに追加
% git commit -m ".gitignore updated with baz.txt" //.gitignore をコミット
[main 871916f] .gitignore updated with baz.txt
1 file changed, 1 insertion(+)
% git status // ステータスを確認(baz.txt は管理対象外となったので表示されない)
On branch main
nothing to commit, working tree clean
ファイルの移動(名前の変更)
Git にはファイルを移動(または名前を変更)するための git mv コマンドがあります。
実際には git mv コマンドを使った方がはるかに簡単ですが、以下は git mv コマンドを使わずにファイルを移動する場合の例です。
まず、移動するサンプルのファイル file.txt と移動先のディレクトリ foo を作成します。
% touch file.txt // file.txt を作成 % git add file.txt // file.txt をステージ % git commit -m "file.txt added" // file.txt をコミット [main d745d03] file.txt added 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 file.txt % echo text for file.txt >> file.txt // file.txt を変更 % git add file.txt // file.txt をステージ % git commit -m "add text to file.txt" // file.txt をコミット [main aa8d937] add text to file.txt 1 file changed, 1 insertion(+) % mkdir foo // ディレクトリ foo を作成 % git status // ステータスを確認 On branch main nothing to commit, working tree clean
file.txt をディレクトリ foo に移動して、ステータスを確認すると以下のように表示されます。
- 移動前のファイルの状態:削除されたが、ステージされていないファイルとして表示される
- 移動後のファイルの状態:ディレクトリ foo に追跡されていないファイルとして表示される
% mv file.txt foo // シェルの mv コマンドで file.txt を移動 % git status On branch main Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) deleted: file.txt Untracked files: (use "git add <file>..." to include in what will be committed) foo/ no changes added to commit (use "git add" and/or "git commit -a")
git rm コマンドで元の場所から削除された file.txt をステージングエリアに追加します。
% git rm file.txt rm 'file.txt' % git status On branch main Changes to be committed: (use "git restore --staged <file>..." to unstage) deleted: file.txt Untracked files: (use "git add <file>..." to include in what will be committed) foo/
ディレクトリ foo に移動した file.txt をステージングエリアに追加します。
これにより、file.txt は foo/file.txt に変更(renamed)されたと認識されるので、コミットします。
% git add foo/file.txt
% git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: file.txt -> foo/file.txt
% git commit -m "file.txt move to foo"
[main 0833233] file.txt move to foo
1 file changed, 0 insertions(+), 0 deletions(-)
rename file.txt => foo/file.txt (100%)
% git status
On branch main
nothing to commit, working tree clean
上記の場合、シェルの mv コマンドで file.txt を移動し、git rm コマンドで file.txt をステージングエリアに追加し、更に git add コマンドで移動した foo/file.txt をステージングエリアに追加して、コミットを実行しましたが、 git mv コマンドを使えばもっと簡単です。
以下は上記と同じことを git mv コマンドで実行する例です。
% git mv file.txt foo // git mv コマンドを使って移動 % git status // ファイルは移動され、ステージもされている On branch main Changes to be committed: (use "git restore --staged <file>..." to unstage) renamed: file.txt -> foo/file.txt % git commit -m "move file.txt to foo" // コミット [main 8c2967f] move file.txt to foo 1 file changed, 0 insertions(+), 0 deletions(-) rename file.txt => foo/file.txt (100%) % git status On branch main nothing to commit, working tree clean
コミット履歴(変更履歴) git log
コミットの履歴(変更履歴)は git log コマンドで確認することができます。
引数を何も指定しなければ、git log はそのリポジトリでのコミットを新しい順に表示します。
% git log commit 8c2967fef3616cd79aa5bb55fbeabc427546eb48 (HEAD -> main) Author: foo <foo@example.com> Date: Fri Aug 4 14:02:47 2023 +0900 move file.txt to foo commit edf49a8931cd9975853b38a571e9c7484e1fd41b Author: foo <foo@example.com> Date: Fri Aug 4 13:56:02 2023 +0900 move back file.txt ・・・中略・・・ commit c017211c81c71b4d57b95a3d8c28e348d7957631 Author: foo <foo@example.com> Date: Thu Aug 3 15:17:57 2023 +0900 3rd commit commit 5cac768fa17a08989926ee972240b044277b7224 Author: foo <foo@example.com> Date: Thu Aug 3 12:43:04 2023 +0900 text added commit 3f903a46cdb83d13bbb1d843029f11ee5f67e589 Author: foo <foo@example.com> Date: Tue Aug 1 15:33:49 2023 +0900 Initial commit
履歴が多い場合(一画面に表示しきれない場合)は space キーで一画面分スクロールでき、return キーで一行分スクロールすることができます(less コマンドなどのキー操作と同じ)。
終了するには q キーを押します。
git log コマンドは以下の情報を表示します。
項目 | 説明 |
---|---|
commit | コミットの SHA-1 チェックサム(コミットを識別するための文字列) |
HEAD -> main | HEAD は現在チェックアウトされているブランチを示します(現在チェックアウトされているブランチは main という意味)。 |
Author | コミットを行った作者の名前とメールアドレス |
Date | コミットされた日付とタイムスタンプ |
コミットメッセージ | コミットメッセージ |
git log コマンドには数多くのオプションがあります。以下はそのごく一部です。
コミットの変更点(diff)を表示 -p
git log コマンドに -p オプションを指定して実行すると、各コミットで反映された変更点(diff)を表示します。
% git log -p commit bbeb4bd32946b90a5fab7f1db8f0c029fb632916 (HEAD -> main) Author: foo <foo@example.com> Date: Thu Aug 3 16:02:52 2023 +0900 overwrite diff --git a/hello.txt b/hello.txt // 差分(変更点) index d6eb0c5..48abe86 100644 --- a/hello.txt +++ b/hello.txt @@ -1,4 +1 @@ -Hello Git! // 行の削除 -additional text // 行の削除 -additional text2 // 行の削除 -some more text // 行の削除 +Hello Again! // 行の追加 commit c017211c81c71b4d57b95a3d8c28e348d7957631 Author: foo <foo@example.com> Date: Thu Aug 3 15:17:57 2023 +0900 3rd commit diff --git a/hello.txt b/hello.txt // 差分(変更点) index 525c197..d6eb0c5 100644 --- a/hello.txt +++ b/hello.txt @@ -1,2 +1,4 @@ Hello Git! additional text +additional text2 // 行の追加 +some more text // 行の追加 ・・・以下省略・・・
1行で表示 --oneline
--oneline オプションを指定すると各履歴を1行で表示することができます。
-oneline オプションは --pretty=oneline --abbrev-commit のショートハンドオプションで、--abbrev-commit は SHA-1 チェックサムの全体 (40文字) ではなく最初の数文字のみを表示するオプションです。
% git log --oneline 8c2967f (HEAD -> main) move file.txt to foo edf49a8 move back file.txt 0833233 file.txt move to foo aa8d937 add text to file.txt d745d03 file.txt added e5aee37 file.txt removed 47ac2ad file.txt added 871916f .gitignore updated with baz.txt 84e9692 bax.txt removed from stage 00a7b39 baz.txt added 4ec7b2f bar.txt removed 7990699 bar.txt added f6d6e9e foo.txt removed 726c5e3 foo.txt added 0012513 .itignore updated 5b171d5 adds .gitignore 9bc0d5f goodbye added bbeb4bd overwrite c017211 3rd commit 5cac768 text added 3f903a4 Initial commit
ハッシュ値の省略形
コミットのハッシュ値を使用する場合、40桁全てではなく、冒頭の数文字で指定することができます。
上記のように git log --oneline でログを一覧表示すると、ハッシュ値の冒頭部分(デフォルトは先頭7バイト分)を表示しますが、ここに表示されている値だけでコミットを指定することが可能です。
--pretty カスタム形式
--pretty はログの書式をあらかじめ用意されているいくつかのオプション(oneline, short, medium, full など)から指定することができます。
% git log --pretty=oneline 8c2967fef3616cd79aa5bb55fbeabc427546eb48 (HEAD -> main) move file.txt to foo edf49a8931cd9975853b38a571e9c7484e1fd41b move back file.txt 0833233eaed2da42000f054b383563fad435764e file.txt move to foo aa8d937d7a9dc052fbc7a2570885cfa301cafd41 add text to file.txt d745d03782842cfba63221e18482e747fe1967fc file.txt added e5aee37b0772d18a35b5189266b55fd9c7ac4947 file.txt removed 47ac2ad11b9f904177293aadeaf8cc7e9f27546e file.txt added 871916f233dd6cb0038ac72ad1a81ad755b73794 .gitignore updated with baz.txt ・・・
--pretty=format: でフォーマット文字を指定して独自の書式を指定することもできます。
% git log --pretty=format:"%h - %an, %ar : %s" 8c2967f - foo, 3 hours ago : move file.txt to foo edf49a8 - foo, 3 hours ago : move back file.txt 0833233 - foo, 5 hours ago : file.txt move to foo aa8d937 - foo, 5 hours ago : add text to file.txt d745d03 - foo, 5 hours ago : file.txt added e5aee37 - foo, 5 hours ago : file.txt removed 47ac2ad - foo, 5 hours ago : file.txt added 871916f - foo, 6 hours ago : .gitignore updated with baz.txt ・・・
フォーマット文字 | 説明 |
---|---|
%H | コミットのハッシュ |
%h | コミットのハッシュ (短縮版) |
%an | Author の名前 |
%ad | Author の日付 (--date= オプションに従った形式) |
%ar | Author の相対日付 |
%s | コミットメッセージ |
ログ出力を制限
コミットの一部だけを表示するようなログ出力を制限するオプションもあります。
例えば、直近の3つのログだけを出力するには -3 と指定します。
% git log --oneline -3 8c2967f (HEAD -> main) move file.txt to foo edf49a8 move back file.txt 0833233 file.txt move to foo
オプション | 説明 |
---|---|
-(n) | 直近の n 件のコミットのみを表示 |
- -since, - -after | 指定した日付/時刻以降のCommitDateのコミットのみに制限 |
- -until, - -before | 指定した日付/時刻以前のCommitDateのコミットのみに制限する |
--author | 作成者のエントリが指定された文字列と一致するコミットのみを表示 |
--grep | 指定した文字列がコミットメッセージに含まれているコミットのみを表示 |
-S | 指定した文字列をコードに追加・削除したコミットのみを表示 |
以下はコミットメッセージに foo が含まれているコミットのコミットハッシュ (短縮版)とコミットメッセージを表示する例です。
% git log --pretty="%h - %s" --grep=foo 8c2967f - move file.txt to foo 0833233 - file.txt move to foo f6d6e9e - foo.txt removed 726c5e3 - foo.txt added
特定のファイルのある時点との差分を表示
git log と git diff を使って特定のファイルのある時点との差分を表示することができます。
特定のファイルのある時点との差分は、そのファイルのコミット間の差分になるので、git log に特定のファイルのパスを指定して、そのファイルの変更履歴を確認します。
git log path/to/your/file
以下は hello.txt の履歴を --oneline を指定して1行で表示して確認する例です。
% git log --oneline hello.txt 9bc0d5f goodbye added bbeb4bd overwrite c017211 3rd commit 5cac768 text added 3f903a4 Initial commit
コミット間の差分を確認するためには、git diff コマンドを使用して以下のように、コミットのハッシュ値を2つ指定して差分を表示します。
git diff commit_hash1 commit_hash2 path/to/your/file
以下は hello.txt のコミットのハッシュ値が 5cac768 と c017211 の時点での差分を表示する例です。
% git diff 5cac768 c017211 hello.txt diff --git a/hello.txt b/hello.txt index 525c197..d6eb0c5 100644 --- a/hello.txt +++ b/hello.txt @@ -1,2 +1,4 @@ Hello Git! additional text +additional text2 +some more text
作業のやり直し
Git では作業のやり直しのためのコマンドが用意されています。
但し、コマンドによっては作業内容を失ってしまう可能性があるので注意が必要です。
直前のコミットを修正
git commit --amend を使うと、直近のコミットを修正または変更することができます。主な目的は、直前のコミットに追加の変更を統合することや、コミットメッセージを編集することです。
git commit --amend を使用すると、直前のコミットが変更され、コミットヒストリーが変更されます。
git commit --amend は便利なツールですがコミット履歴が複雑になる可能性があるため、必要な場合にのみ使用するようにします。
コミットメッセージを修正
例えば、以下のように file1.txt を編集し、ステージしてコミットした後に、コミットメッセージを間違えたことに気がついた場合、
% echo Hello! >> file1.txt % git add file1.txt % git commit -m "test added" [main 04ea458] test added 1 file changed, 1 insertion(+) % git log --oneline file1.txt 04ea458 (HEAD -> main) test added //コミットメッセージを間違えた a1d4863 initial commit
git commit --amend
を実行して、直前のコミットのコミットメッセージを修正することができます。そのまま実行するとエディタが開きますが、-m を指定してコミットメッセージを上書きすることもできます。
git commit --amend を実行後、git log でコミット履歴を確認すると、コミットメッセージが修正されているのが確認できます。
※ 但し、ハッシュ値が 04ea458 から 7ac06cc に変わっています。そのため、git push した後では git commit --amend を実行してはいけません。
% git commit --amend -m "text added" [main 7ac06cc] text added Date: Sat Aug 5 15:01:25 2023 +0900 1 file changed, 1 insertion(+) % git log --oneline file1.txt 7ac06cc (HEAD -> main) text added //コミットメッセージが修正された(ハッシュ値が変わる) a1d4863 initial commit
直前のコミットに新たな変更を追加
例えば、コミットした後に、あるファイルをステージするのを忘れていたのに気づいたと場合、忘れてしまったファイルをステージ後、git commit --amend を実行してコミットをやり直すことができます。
以下は file2.txt をステージするのを忘れてコミットした後に、file2.txt をステージして git commit --amend を実行してひとつのコミットにまとまています。
この場合も、ハッシュ値が e0c30a7 から b50b841 に変わっています。
% git commit -m "udate file1" // file2.txt をステージするのを忘れてコミット [main e0c30a7] udate file1 1 file changed, 1 insertion(+) % git log --oneline e0c30a7 (HEAD -> main) udate file1 7ac06cc text added a1d4863 initial commit % git add file2.txt // file2.txt をステージ % git commit --amend -m "update file1 and added file2" // git commit --amend [main b50b841] update file1 and added file2 Date: Sat Aug 5 15:19:49 2023 +0900 2 files changed, 2 insertions(+) create mode 100644 file2.txt % git log --oneline b50b841 (HEAD -> main) update file1 and added file2 7ac06cc text added a1d4863 initial commit
ステージングの取り消し
ステージングした状態を取り消す(解除する)には git restore --staged ファイル名
を実行します。
以下は file2.txt を変更後ステージして、ステータスを確認しています。
git status のレスポンスを読むと、ステージングを解除するには git restore --staged <file> を実行すると、その方法が表示されています(6行目)。
% git add file2.txt //ファイルを変更後ステージングする
% git status //ステータスを確認
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: file2.txt
git restore --staged file2.txt を実行して git status で確認するとステージングが解除されているのがわかります。
% git restore --staged file2.txt //ステージングの取り消し
% git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file2.txt
no changes added to commit (use "git add" and/or "git commit -a")
ファイルへの変更の取り消し
ファイルに加えた変更を取り消す(最後にコミットした状態に戻す)には git restore ファイル名
を実行します。
例えば、以下の file2.txt は最後にコミットした状態からワーキングツリーで変更が加えられています。
git diff で差分を表示すると「some additional text」が追加されています。
% git diff file2.txt diff --git a/file2.txt b/file2.txt index 009cf80..ceed7ef 100644 --- a/file2.txt +++ b/file2.txt @@ -1 +1,2 @@ this is file2 +some additional text % cat file2.txt // ワーキングツリーのファイルの内容を表示 this is file2 some additional text
git status を実行して確認すると、まだステージされていない状態です。
git status のレスポンスには、ワーキングツリーでの変更を取り消すには git restore <file> を実行すると表示されています。
% git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file2.txt
no changes added to commit (use "git add" and/or "git commit -a")
git restore file2.txt を実行してファイルへの変更を取り消します。
% git restore file2.txt % git diff file2.txt // 差分なし % cat file2.txt this is file2 // 変更は削除されている
注意
git restore <file>
を実行すると、そのファイルに加えたローカルの変更はすべて失われます(Git はそのファイルを、最後にステージングまたはコミットされたバージョンに置き換えます)。
コマンド リンク
Git コマンドのドキュメントは https://git-scm.com/docs に掲載されていますが、Bitbucket のドキュメントもわかりやすいので、よく使われると思われるコマンドのリンクをリストしました。
- git init
- git config
- .gitignore
- git add(変更の保存)
- git commit
- git status
- git diff
- git log
- git stash
- git clone
- git checkout (過去のコミットの表示/コミットや変更を元に戻す)
- git checkout (ブランチに対するチェックアウト操作)
- git revert
- git reset
- git reflog
- git rm
- ブランチを使用する
- 履歴の書き換え(git commit --amend、git rebase)
- リセット、チェックアウト、元に戻す
追記:以下のコマンドや用語の一覧ページが用意されています。