-
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 PlumbingとPorcelain
- 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 Plumbingコマンド
2.2 Gitの基本 - リポジトリへの変更の記録
リポジトリへの変更の記録
この時点で、ローカルマシンに *bona fide* のGitリポジトリがあり、そのすべてのファイルのチェックアウトまたは*作業コピー*が目の前にあるはずです。通常、変更を開始し、プロジェクトが記録したい状態に達するたびに、それらの変更のスナップショットをリポジトリにコミットします。
作業ディレクトリ内の各ファイルは、*追跡対象*または*未追跡*の2つの状態のいずれかになる可能性があることに注意してください。追跡対象ファイルとは、最後のスナップショットにあったファイルと、新しくステージングされたファイルのことです。それらは、変更されていない、変更された、またはステージング済みのいずれかになります。要するに、追跡対象ファイルとは、Gitが認識しているファイルのことです。
未追跡ファイルは、それ以外のすべてです。つまり、作業ディレクトリ内の最後のスナップショットになく、ステージング領域にもないファイルです。最初にリポジトリをクローンすると、Gitがそれらをチェックアウトしたばかりで何も編集していないため、すべてのファイルが追跡され、変更されていない状態になります。
ファイルを編集すると、Gitはそれらを変更済みと認識します。最後のコミット以降に変更したためです。作業を進めると、これらの変更されたファイルを選択的にステージングし、ステージングされたすべての変更をコミットします。このサイクルが繰り返されます。

ファイルの状態の確認
どのファイルがどの状態にあるかを判断するために使用する主なツールは、git status
コマンドです。クローン直後にこのコマンドを実行すると、次のような結果が表示されます。
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
これは、作業ディレクトリがクリーンであることを意味します。つまり、追跡対象のファイルは変更されていません。また、Gitは未追跡のファイルを認識していません。もしあれば、ここにリストされます。最後に、コマンドはどのブランチにいるかを伝え、サーバー上の同じブランチから分岐していないことを通知します。今のところ、そのブランチは常にデフォルトであるmaster
です。ここでは心配する必要はありません。Gitブランチでは、ブランチと参照について詳しく説明します。
注意
|
GitHubは、2020年半ばにデフォルトのブランチ名を ただし、Git自体はまだ |
プロジェクトに新しいファイル、単純なREADME
ファイルを追加するとしましょう。ファイルが以前に存在せず、git status
を実行すると、次のように未追跡のファイルが表示されます。
$ echo 'My Project' > README
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
README
nothing added to commit but untracked files present (use "git add" to track)
新しいREADME
ファイルが未追跡であることがわかります。ステータス出力の「Untracked files」ヘッダーの下にあるためです。未追跡とは、基本的に、Gitが以前のスナップショット(コミット)になかったファイルを見ており、まだステージングされていないことを意味します。Gitは、明示的にそうするように指示するまで、コミットスナップショットにファイルを含めることは開始しません。これは、生成されたバイナリファイルや、含めるつもりでなかったその他のファイルを誤って含め始めないようにするためです。README
を含め始めるので、ファイルを追跡しましょう。
新しいファイルの追跡
新しいファイルの追跡を開始するには、git add
コマンドを使用します。README
ファイルの追跡を開始するには、次を実行できます。
$ git add README
ステータスコマンドを再度実行すると、README
ファイルが追跡され、コミットされるようにステージングされていることがわかります。
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: README
「コミット対象の変更」という見出しの下にあるので、それがステージングされた状態であることがわかります。この時点でコミットすると、git add
を実行した時点でのファイルのバージョンが、その後の履歴スナップショットに含まれます。以前にgit init
を実行したときに、git add <files>
も実行したことを覚えているかもしれません。これは、ディレクトリ内のファイルの追跡を開始するためでした。git add
コマンドは、ファイルまたはディレクトリのパス名を受け取り、ディレクトリの場合は、そのディレクトリ内のすべてのファイルが再帰的に追加されます。
変更されたファイルのステージング
すでに追跡されているファイルを変更してみましょう。すでに追跡されているCONTRIBUTING.md
というファイルを変更し、再度git status
コマンドを実行すると、次のようになります。
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: CONTRIBUTING.md
CONTRIBUTING.md
ファイルは、「コミット用にステージされていない変更」というセクションの下に表示されます。これは、追跡されているファイルが作業ディレクトリ内で変更されたが、まだステージングされていないことを意味します。ステージングするには、git add
コマンドを実行します。git add
は多目的コマンドであり、新しいファイルの追跡を開始したり、ファイルをステージングしたり、マージ競合したファイルを解決済みとしてマークしたりするなど、さまざまな用途で使用します。「プロジェクトにこのファイルを追加する」というよりも、「この内容を次のコミットに正確に追加する」と考えると役に立つでしょう。ここでgit add
を実行してCONTRIBUTING.md
ファイルをステージングし、再度git status
を実行してみましょう。
$ git add CONTRIBUTING.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
modified: CONTRIBUTING.md
両方のファイルがステージングされ、次のコミットに含まれる予定です。この時点で、コミットする前にCONTRIBUTING.md
に少し変更を加えたいと思い出したとします。再度ファイルを開き、変更を加えてコミットする準備が整いました。しかし、もう一度git status
を実行してみましょう。
$ vim CONTRIBUTING.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
modified: CONTRIBUTING.md
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: CONTRIBUTING.md
一体どういうことでしょう? 今度はCONTRIBUTING.md
がステージング済みとステージングされていないの両方としてリストされています。これはどのようにして可能なのでしょうか? 実は、Gitはgit add
コマンドを実行した時点のファイルの状態を正確にステージングします。今コミットすると、git add
コマンドを最後に実行した時点のCONTRIBUTING.md
のバージョンがコミットに含まれ、git commit
を実行した時点の作業ディレクトリ内のファイルのバージョンではありません。git add
を実行した後でファイルを変更した場合は、最新バージョンのファイルをステージングするためにもう一度git add
を実行する必要があります。
$ git add CONTRIBUTING.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
modified: CONTRIBUTING.md
短いステータス
git status
の出力は非常に包括的ですが、かなり冗長でもあります。Gitには、変更をよりコンパクトに表示できる短いステータスフラグもあります。git status -s
またはgit status --short
を実行すると、コマンドの出力が大幅に簡略化されます。
$ git status -s
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt
追跡されていない新しいファイルには??
が、ステージング領域に追加された新しいファイルにはA
が、変更されたファイルにはM
などが付いています。出力には2つの列があります。左側の列はステージング領域のステータスを示し、右側の列は作業ツリーのステータスを示します。たとえば、この出力では、README
ファイルは作業ディレクトリ内で変更されていますが、まだステージングされていません。一方、lib/simplegit.rb
ファイルは変更されてステージングされています。Rakefile
は変更、ステージングされた後、再度変更されたため、ステージング済みとステージングされていない両方の変更があります。
ファイルの無視
多くの場合、Gitに自動的に追加させたり、追跡されていないものとして表示させたりしたくないファイルのクラスがあります。これらは一般的に、ログファイルやビルドシステムによって生成されたファイルなど、自動的に生成されるファイルです。そのような場合は、.gitignore
という名前で、それらに一致するパターンのリストを記述したファイルを作成できます。以下は.gitignore
ファイルの例です。
$ cat .gitignore
*.[oa]
*~
最初の行は、Gitに「.o」または「.a」で終わるファイル(コードのビルド結果であるオブジェクトファイルとアーカイブファイル)を無視するように指示します。2番目の行は、多くのテキストエディタ(Emacsなど)で一時ファイルをマークするために使用されるチルダ(~
)で終わるすべてのファイルを無視するようにGitに指示します。ログ、tmp、pidディレクトリ、自動生成されたドキュメントなども含めることができます。新しいリポジトリで作業を開始する前に、.gitignore
ファイルを設定することは、Gitリポジトリに本当に含めたくないファイルを誤ってコミットしないようにするために一般的に良い考えです。
.gitignore
ファイルに記述できるパターンのルールは次のとおりです。
-
空白行または
#
で始まる行は無視されます。 -
標準のglobパターンが機能し、作業ツリー全体に再帰的に適用されます。
-
パターンをスラッシュ(
/
)で開始して、再帰を回避できます。 -
パターンをスラッシュ(
/
)で終了して、ディレクトリを指定できます。 -
パターンを感嘆符(
!
)で開始して、パターンを否定できます。
globパターンは、シェルが使用する単純化された正規表現のようなものです。アスタリスク(*
)は、ゼロ個以上の文字に一致します。[abc]
は、角かっこ内の任意の文字(この場合はa、b、またはc)に一致します。疑問符(?
)は、1つの文字に一致します。ハイフンで区切られた文字を角かっこで囲むと([0-9]
)、それらの間の任意の文字に一致します(この場合は0から9)。また、2つのアスタリスクを使用してネストされたディレクトリを照合することもできます。a/**/z
は、a/z
、a/b/z
、a/b/c/z
などに一致します。
以下は、.gitignore
ファイルの別の例です。
# ignore all .a files
*.a
# but do track lib.a, even though you're ignoring .a files above
!lib.a
# only ignore the TODO file in the current directory, not subdir/TODO
/TODO
# ignore all files in any directory named build
build/
# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt
# ignore all .pdf files in the doc/ directory and any of its subdirectories
doc/**/*.pdf
ヒント
|
GitHubは、プロジェクトの開始点として使用できる、数十のプロジェクトと言語に対応した適切な |
注意
|
単純なケースでは、リポジトリのルートディレクトリに1つの 複数の |
ステージング済みおよびステージングされていない変更の表示
git status
コマンドが曖昧すぎると感じる場合、つまり、どのファイルが変更されたかだけでなく、変更内容を正確に知りたい場合は、git diff
コマンドを使用できます。git diff
については後で詳しく説明しますが、おそらく次の2つの質問に答えるためによく使用するでしょう。「変更したがまだステージングしていないものは何か」と「コミットしようとしているステージング済みは何なのか」です。git status
はファイル名を一覧表示することでこれらの質問に大まかに答えますが、git diff
は追加および削除された正確な行、つまりパッチを示します。
README
ファイルを編集してステージングし、CONTRIBUTING.md
ファイルをステージングせずに編集したとします。git status
コマンドを実行すると、次のようになります。
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: CONTRIBUTING.md
変更したがまだステージングしていないものを確認するには、引数を指定せずにgit diff
と入力します。
$ git diff
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8ebb991..643e24f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -65,7 +65,8 @@ branch directly, things can get messy.
Please include a nice description of your changes when you submit your PR;
if we have to read the whole diff to figure out why you're contributing
in the first place, you're less likely to get feedback and have your change
-merged in.
+merged in. Also, split your changes into comprehensive chunks if your patch is
+longer than a dozen lines.
If you are starting to work on a particular area, feel free to submit a PR
that highlights your work in progress (and note in the PR title that it's
このコマンドは、作業ディレクトリの内容とステージング領域の内容を比較します。結果は、まだステージングしていない変更を示します。
次のコミットに含まれるステージング済みを確認する場合は、git diff --staged
を使用できます。このコマンドは、ステージングされた変更を最後のコミットと比較します。
$ git diff --staged
diff --git a/README b/README
new file mode 100644
index 0000000..03902a1
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+My Project
git diff
自体は、最後のコミット以降のすべての変更を示すわけではなく、まだステージングされていない変更のみを示すことに注意することが重要です。すべての変更をステージングした場合、git diff
は何も出力しません。
別の例として、CONTRIBUTING.md
ファイルをステージングしてから編集した場合、git diff
を使用して、ファイル内でステージングされている変更とステージングされていない変更を確認できます。環境が次のようになっている場合
$ git add CONTRIBUTING.md
$ echo '# test line' >> CONTRIBUTING.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: CONTRIBUTING.md
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: CONTRIBUTING.md
ここで、git diff
を使用して、まだステージングされていないものを確認できます。
$ git diff
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 643e24f..87f08c8 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -119,3 +119,4 @@ at the
## Starter Projects
See our [projects list](https://github.com/libgit2/libgit2/blob/development/PROJECTS.md).
+# test line
また、git diff --cached
を使用して、これまでにステージングしたものを確認できます(--staged
と--cached
は同義です)。
$ git diff --cached
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8ebb991..643e24f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -65,7 +65,8 @@ branch directly, things can get messy.
Please include a nice description of your changes when you submit your PR;
if we have to read the whole diff to figure out why you're contributing
in the first place, you're less likely to get feedback and have your change
-merged in.
+merged in. Also, split your changes into comprehensive chunks if your patch is
+longer than a dozen lines.
If you are starting to work on a particular area, feel free to submit a PR
that highlights your work in progress (and note in the PR title that it's
注意
|
外部ツールでのGit Diff
本書の残りの部分では、さまざまな方法で |
変更のコミット
ステージング領域が目的どおりに設定されたら、変更をコミットできます。まだステージングされていないもの、つまり編集後にgit add
を実行していない作成または変更したファイルは、このコミットに含まれないことに注意してください。これらは、ディスク上の変更されたファイルとして残ります。この場合、最後にgit status
を実行したときに、すべてがステージングされていることを確認したので、変更をコミットする準備が整ったとします。コミットする最も簡単な方法は、git commit
と入力することです。
$ git 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 master
# Your branch is up-to-date with 'origin/master'.
#
# Changes to be committed:
# new file: README
# modified: CONTRIBUTING.md
#
~
~
~
".git/COMMIT_EDITMSG" 9L, 283C
デフォルトのコミットメッセージには、git status
コマンドの最新の出力がコメントアウトされて含まれており、上に空行が1つあることがわかります。これらのコメントを削除してコミットメッセージを入力することも、コミットしている内容を思い出すためにそのままにしておくこともできます。
注意
|
変更した内容をより明確に確認するために、 |
エディターを終了すると、Git はコミットメッセージ(コメントと差分は削除されます)でコミットを作成します。
あるいは、commit
コマンドで -m
フラグの後にコミットメッセージをインラインで記述することもできます。例えば、このようになります。
$ git commit -m "Story 182: fix benchmarks for speed"
[master 463dc4f] Story 182: fix benchmarks for speed
2 files changed, 2 insertions(+)
create mode 100644 README
これで最初のコミットが作成されました!コミットによって、どのブランチ(master
)にコミットしたか、コミットの SHA-1 チェックサム(463dc4f
)、変更されたファイル数、コミットで追加および削除された行数に関する情報が出力されていることがわかります。
コミットはステージングエリアに設定したスナップショットを記録することを覚えておいてください。ステージングしなかったものはすべて変更されたまま残っています。履歴に追加するには、別のコミットを実行できます。コミットを実行するたびに、後で元に戻したり比較したりできるプロジェクトのスナップショットを記録しています。
ステージングエリアをスキップする
ステージングエリアは、コミットを思い通りに作成するのに非常に役立つ場合がありますが、ワークフローに必要なよりも少し複雑な場合があります。ステージングエリアをスキップしたい場合、Git は簡単なショートカットを提供します。git commit
コマンドに -a
オプションを追加すると、Git はコミットを実行する前に、すでに追跡されているすべてのファイルを自動的にステージングするため、git add
の部分をスキップできます。
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: CONTRIBUTING.md
no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -a -m 'Add new benchmarks'
[master 83e38c7] Add new benchmarks
1 file changed, 5 insertions(+), 0 deletions(-)
この場合、コミットする前に CONTRIBUTING.md
ファイルで git add
を実行する必要がないことに注目してください。これは、-a
フラグが変更されたすべてのファイルを含むためです。これは便利ですが、注意が必要です。このフラグを使用すると、不要な変更が含まれる場合があります。
ファイルを削除する
Git からファイルを削除するには、追跡対象のファイルから削除し(より正確には、ステージングエリアから削除し)、コミットする必要があります。git rm
コマンドはこれを行い、ワーキングディレクトリからもファイルを削除するため、次回は未追跡ファイルとして表示されません。
単にワーキングディレクトリからファイルを削除すると、git status
出力の「コミット用にステージされていない変更」エリア(つまり、ステージされていない)に表示されます。
$ rm PROJECTS.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: PROJECTS.md
no changes added to commit (use "git add" and/or "git commit -a")
次に、git rm
を実行すると、ファイルの削除がステージングされます。
$ git rm PROJECTS.md
rm 'PROJECTS.md'
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: PROJECTS.md
次回コミットすると、ファイルは削除され、追跡されなくなります。ファイルを変更した場合、またはすでにステージングエリアに追加している場合は、-f
オプションを使用して削除を強制する必要があります。これは、スナップショットにまだ記録されておらず、Git から復元できないデータの誤った削除を防ぐための安全機能です。
もう一つ便利なことは、ファイルをワーキングツリーに保持したまま、ステージングエリアから削除することです。言い換えれば、ファイルをハードドライブに保持したまま、Git で追跡しないようにしたい場合があります。これは、.gitignore
ファイルに何かを追加するのを忘れて、大きなログファイルやコンパイルされた .a
ファイルのようなものを誤ってステージングした場合に特に役立ちます。これを行うには、--cached
オプションを使用します。
$ git rm --cached README
git rm
コマンドには、ファイル、ディレクトリ、およびファイルグロブパターンを渡すことができます。つまり、次のようなことができます。
$ git rm log/\*.log
*
の前のバックスラッシュ(\
)に注意してください。これは、Git がシェルによるファイル名展開に加えて、独自のファイル名展開を行うため必要です。このコマンドは、log/
ディレクトリにある .log
拡張子を持つすべてのファイルを削除します。または、次のようなこともできます。
$ git rm \*~
このコマンドは、名前が ~
で終わるすべてのファイルを削除します。
ファイルを移動する
他の多くの VCS とは異なり、Git はファイルの移動を明示的に追跡しません。Git でファイルの名前を変更した場合、ファイルの名前を変更したことを示すメタデータは Git に保存されません。ただし、Git は後でそれを把握することに非常に優れています。ファイルの移動の検出については、後で詳しく説明します。
したがって、Git に mv
コマンドがあるのは少し紛らわしいです。Git でファイルの名前を変更する場合は、次のようなものを実行できます。
$ git mv file_from file_to
これは問題なく機能します。実際、これのようなものを実行してステータスを確認すると、Git はそれを名前が変更されたファイルと見なしていることがわかります。
$ git mv README.md README
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: README.md -> README
ただし、これは次のようなものを実行するのと同等です。
$ mv README.md README
$ git rm README.md
$ git add README
Git はそれが暗黙的な名前の変更であると判断するため、そのようにファイルを名前変更するか、mv
コマンドを使用するかは関係ありません。唯一の本当の違いは、git mv
が 3 つのコマンドではなく 1 つのコマンドであることです。これは便利な機能です。さらに重要なことは、ファイルの名前を変更するために好きなツールを使用でき、コミットする前に後で add
/rm
を処理できることです。