本機テスト環境:macOS 11
14 | 不要なブランチを削除するには?#
git branch -d <BRANCH_NAME>
-d
:--delete
- 条件付きでローカルブランチを削除
- ❗️条件:そのブランチが上流ブランチ(ローカルブランチに対応するリモートブランチ、設定可能)または HEAD(現在のブランチ)にマージされている場合にのみ、削除が成功する
git branch -D <BRANCH_NAME>
-D
:--delete --force
- ローカルブランチを強制的に削除
- ブランチを削除するリスクがないと確信している場合に使用できる
PS:
- 現在のブランチは削除できません。削除する必要がある場合は、まず
git checkout <BRANCH_NAME>
でブランチを切り替えてください。 - リモートブランチを削除するには:
git push <REMOTE> --delete <BRANCH_NAME>
git fetch -p / --prune
でブランチリストを同期すると、リモートで削除されたブランチは表示されなくなります。
15 | 最新のコミットメッセージを変更するには?#
git commit --amend
と入力すると、テキストエディタが開き、新しいコミットメッセージを変更できます。赤枠のように:
:wq
と入力して保存して終了すると、ターミナルに変更結果が表示されます:
再度コミット情報を確認します:
変更成功!
PS:git commit --amend
- 本質的には前回のコミットを置き換えるもので、メッセージの変更に限定されません。
- 一般的には、リモートにプッシュする前のコミット操作の修正に使用されます。
16 | 古いコミットのメッセージを変更するには?#
git rebase -i
を使用して、過去のいくつかのコミット情報を変更できます。 -i
はインタラクティブモードを使用します。
—— 具体的な手順 ——
まず git log
を使用して現在のバージョン履歴を確認します:
順番で 3 番目のコミットのメッセージを変更したい場合、その親コミットに基づいて操作する必要があります。
git rebase -i d8796c00719323800976e6c7fcfe6b02627ec6b2
コマンドを使用し、末尾に親コミットのハッシュ値を追加します(最初のコミットを変更する場合は git rebase -i --root
を使用できます)。編集画面が開きます:
コミットの順序が逆転しました;Commands 部分には多くの使い方が見えます。
reword / r
コマンドを使用して、特定のコミットを保持しつつ、そのメッセージを変更します:
:wq
で保存して終了すると、新しい編集画面が再び開きます:
コミットのメッセージを変更し、再度 :wq
で保存して終了します。
変更成功、❗️ここで分離した HEAD ポインタが使用されていることがわかります。変更後、master ブランチの指向も更新され、コミットのハッシュ値が変更される可能性が高いことを示しています。
確認のため、再度 git log
でバージョン履歴を確認します:
順番で 3 番目のコミットのメッセージが変更され、最初の 3 つのコミットのハッシュ値がすべて変更されていることがわかります。3 番目のコミットのメッセージは変更されていませんが、他の情報も実際には変更されていないことが確認できます。
⚠️:
- 一般的には自分のブランチに基づいて使用し、統合ブランチ(チーム)にまだコミットしていない場合に限ります。そうでない場合は慎重に使用してください。統合ブランチに影響を与える可能性があります。
rebase
はリベースに一般的に使用され、merge
との共通点と相違点に注目できます。参考:- Git ブランチ - リベース—— 公式
- GIT の rebase と merge の正しい使い方—— 知乎
17 | 連続する複数のコミットを 1 つに整理するには?#
同様に git rebase -i
を使用します。
—— 具体的な手順 ——
まず git log
を使用して現在のバージョン履歴を確認します:
今、赤枠内の 3 つのコミットをマージして、ブランチ内のコミット数を減らしたいと思います。
git rebase -i --root
コマンドを使用し、末尾に親コミットのハッシュ値を追加します(最初のコミットを変更するため、--root
を使用します)。編集画面が開きます:
マージする 3 つのコミットは上記の赤枠内にあり、順序は git log
に表示される順序とは逆です。
Commands の中の squash / s
コマンドを使用すると、特定のコミットを前のコミットに統合できます。以下のように変更します:
:wq
で保存して終了すると、新しい編集画面が再び開きます:
2 行目を追加して、3 つのコミットを統合するメッセージとして保持し、下の各コミットのメッセージを保持し、再度 :wq
で保存して終了します。
統合成功、❗️ここで分離した HEAD ポインタが使用されていることがわかります。変更後、master ブランチの指向も更新されました。
git log
でも統合の結果を確認できます。2 つのコミットのハッシュ値が変更されていることがわかります。コミットのメッセージまたは親コミットの指向が変更されたためです。
PS:
- 統合後、一部のコミットが不要になるため、git はクリーンアップを行います。
gitk --all
を使用して、現在のブランチの状況を観察します:
- 2 つの木が現れ、2 つのブランチ間に関連がなくなったことがわかります。
- これは master ブランチの根コミットが変更されたためです。
18 | 間隔のあるいくつかのコミットを 1 つに整理するには?#
コマンド: git rebase -i
git log
コマンドを使用してバージョン履歴を確認します:
赤枠で示された間隔のあるいくつかのコミットをマージしたい場合、同様に git rebase -i 76e5c9ca
コマンドを使用し、後ろに親コミットのハッシュ値を追加します。編集画面が開きます:
マージするコミットの位置を調整し、s
コマンドを使用して以下のように変更します:
:wq
で保存して終了すると、マージの競合が発生することを示すメッセージが表示されます。
上の青枠で次に行う操作が提示されます。ここでは最初の方法を試みます:競合を解決します。
PS:git status
を使用して現在の推奨操作を確認することもできます:
次に、readme ファイルを確認し、その中の競合を解決します。赤枠の位置のコードを削除するだけです:
その後、git add readme
を実行して、先ほどの変更を追加します。
次に、前の指示に従って git rebase --continue
コマンドを実行し、編集ボックスが開き、メッセージ情報を入力し、:wq
で保存して終了します(競合を解決する必要がある場合もあり、上記の手順を繰り返すことができます)。
最後に git log
でバージョン履歴を確認します:
間隔のあるコミットとマージするコミットに関連がある場合、期待通りに動作しない可能性があるため、それらが 1 つのコミットに統合されることがあります。したがって、これらのコミットの内容を非常に明確に理解しておく必要があります。
PS:個人的にはあまり実用的ではなく、競合が発生しやすいと思います。
19 | ステージングエリアと HEAD に含まれるファイルの差異を比較するには?#
コマンド: git diff --cached
この図を忘れないでください:
- HEAD は現在のブランチを指し、ブランチはコミットを指します。
デモ:
readme.md ファイルを変更した後、git add readme.md
を入力して変更をステージングエリアに追加します;
次に git diff --cached
を入力して、ステージングエリアと HEAD の差異を比較します:
2 行のテキストが追加されたことが確認でき、期待通りであればコミットできます。
20 | 作業ディレクトリとステージングエリアに含まれるファイルの差異を比較するには?#
コマンド: git diff
コマンドの後にファイル名を追加することで、特定のファイルの作業ディレクトリとステージングエリアの差異を比較できます。例えば git diff readme.md
とし、もちろん複数のファイル名を追加することもできます。
21 | ステージングエリアを HEAD と同じ状態に戻すには?#
シナリオ:ステージングエリアの内容を不要にしたい場合、ステージングエリア👉HEAD。
コマンド: git reset HEAD
、HEAD
の後に何も加えないと、すべてのファイルが HEAD と一致するように戻ります。
git status
を使用して、reset
前後の変化を観察できます。以下の図を参照してください:
reset
の後、変更操作は再び作業ディレクトリに戻り、git add
コマンドを使用して再度ステージングエリアに追加できます。
PS:
git diff --cached
を使用して、ステージングエリアと HEAD の内容の一致を確認できます。
git reset HEAD
と git restore --staged .
の効果は同じで、後者は git 2.23 以降に追加されました。
22 | 作業ディレクトリのファイルをステージングエリアと同じ状態に戻すには?#
シナリオ:作業ディレクトリで変更を行ったが、不要になったため、ステージングエリアと同じ状態に戻したい。
コマンド: git checkout <FILENAME>
この図を再度思い出してください:
プロセスのデモ:
まず git add
を使用して、変更された readme.md ファイルを作業ディレクトリからステージングエリアに追加します:
操作前後の git diff --cached
の結果を観察し、ステージングエリアと HEAD の差異の変化を確認します。git add
が成功したことがわかります。
次に、再度変更された readme.md ファイルを確認し、git diff
を使用して作業ディレクトリとステージングエリアの差異を観察します:
赤枠部分が今回の変更です。
git status
を使用して作業ディレクトリとステージングエリアの状況を確認します:
図の上半分はステージングエリアのコミット待ちの内容で、下半分は作業ディレクトリのステージングエリアに追加待ちの内容です。
両方の部分で readme.md の変更があり、それぞれが先ほどの 2 回の変更に対応しています。
❗️この時、作業ディレクトリの readme.md ファイルの内容をステージングエリアの状態に戻したい場合は、git checkout readme.md
を使用すればよいです。
作業ディレクトリの readme.md ファイルがステージング待ちの状態でなくなったことが確認できます。
PS:
git checkout
の使用には注意が必要で、ファイルが戻らなくなる可能性があります。- Git 2.23 以降は、
git switch
とgit restore
を使用してgit checkout
の機能を置き換えます:git switch
はブランチの切り替え機能を置き換え、git restore
は作業ディレクトリのファイルを復元する機能を置き換えます。 git checkout <FILENAME>
とgit restore <FILENAME>
の効果は同じで、後者は git 2.23 以降に追加されました。
23 | ステージングエリアの一部ファイルの変更を取り消すには?#
コマンド: git reset HEAD [FILENAME]
、第 21 節と似ており、コマンドの後に具体的なファイル名を追加することもでき、複数のファイルを指定することもできます。
以下の例では、ステージングエリアの変更が 1 つずつ作業ディレクトリに戻される様子を示しています:
作業ディレクトリの変更を再度ステージングエリアに追加したい場合は、git add
コマンドを使用できます。
24 | 最近のいくつかのコミットを消去するには?#
コマンド: git reset --hard <HASH_OF_COMMIT>
、HEAD のコミット指向を変更し、ステージングエリアと作業ディレクトリの内容をそのコミットに戻します。
以下の例を見てください:
git reset --hard
前後の 2 つのポイントを観察します:
1)git log
を使用すると、HEAD の指向が 2 つのコミット分後退したことがわかります;
2)git diff
を使用すると、作業ディレクトリとステージングエリアの差異が存在から無に変わったことがわかります。
25 | 異なるコミットの特定のファイルの差異を確認するには?#
コマンド: git diff <HASH_OF_COMMIT> <HASH_OF_COMMIT> [-- FILENAME]
最後に特定のファイルを追加します。追加しない場合は、すべてのファイルの差異が表示されます;
<HASH_OF_COMMIT>
は直接ブランチ名に置き換えることができ、ブランチ名は本質的にコミットを指します。
PS:--
を加えることで、Git はあなたの意図をより明確にします。
26 | 正しいファイル削除の方法#
コマンド: git rm <FILENAME>
効果は以下の通りです:
本質的にはファイルを削除し、この削除操作を作業ディレクトリとステージングエリアに同期させることに相当します。これは以下のように等しいです:
まず git reset --hard HEAD
を使用して作業ディレクトリとステージングエリアを HEAD の状態に戻します;
次に git status
を使用して、rm
ファイルと git rm
ファイル後の作業ディレクトリとステージングエリアの状態をそれぞれ観察します:
1)前者は作業ディレクトリを変更しましたが、ステージングされていません;
2)後者はステージングエリアを同期させました。この時、今回の変更をコミットできます。
27 | 開発中に緊急タスクが発生した場合の対処法#
緊急タスクが発生し、現在の作業が未完成の場合、どうすればよいでしょうか?
git stash
:現在の作業ディレクトリとステージングエリアの内容を追加のスタックに移動します。これは追跡されているファイルにのみ有効です。
緊急タスクが完了したら、先ほどの未完成の作業を復元するために、まず stash した内容を確認します。
git stash list
:stash の記録リストを表示します。
次に、最近の stash 内容を作業ディレクトリに復元します。
git stash apply
:スタックのトップの保存記録を復元し、記録リストにはその記録が保持されます。
git stash pop
:スタックのトップの保存記録を復元し、記録リストからその記録を削除します。
- PS:特定の記録を指定して復元することもできます。
プロセスのデモ:
緊急タスクが発生したため、まずステージングエリアの未完成の内容を stash します。
この時、stash 記録リストに記録 {0} が追加され、現在の作業ディレクトリとステージングエリアはすでにクリーンです。
忙しい作業が終わったら、最近の stash の記録を復元します。
apply
は stash 記録を消去しないことがわかります。また、復元された内容は作業ディレクトリに配置され、以前に stash したのはステージングエリアの内容です。
次に、別の方法で復元します。pop
を使用し、--index
パラメータを追加します。
pop
はその stash 記録を消去し、復元された内容は stash 時と同じステージングエリアに配置されます。--index
は実際にはステージングエリアも復元されることを意味します。
PS:
WIP は Work in progress の略で、作業中を示します。引き伸ばされた意味として「現在作業中のコードはまだ実行できず、未完成である」ということを示します。
28 | Git 管理が不要なファイルを指定するには?#
方法:.gitignore
ファイルにファイルタイプまたはファイル名を宣言するだけです(必ず .gitignore
である必要があります)。
doc / と doc の違いのデモ:
1)doc/:フォルダを無視しますが、同名のファイルは無視しません。
doc フォルダを作成し、その中に readhim ファイルを追加します。
.gitignore
ファイルに doc/
を追加すると、Git は doc フォルダの追跡を無視します。
しかし、doc フォルダを docファイルに変更すると、Git は doc ファイルの追跡を無視しません。
2)doc:フォルダと同名のファイルの両方を無視します。
無視ルール doc に対しては、フォルダでも同名のファイルでも、Git はその追跡を無視します。
⚠️:
- よく使われるワイルドカード
*
は同類のファイルを無視します。 - ファイルがすでに追跡されている場合、
.gitignore
ファイルは効果がありません。- コミット後に、すでにコミットされたファイルを無視したい場合は、無視したいファイルを
.gitignore
ファイルに追加し、git rm --cached FILENAME
の方法で追跡を無視します。
- コミット後に、すでにコミットされたファイルを無視したい場合は、無視したいファイルを
- GitHub で新しいリポジトリを作成する際に、適切な.gitignore ファイルを追加するオプションがあります:(とても親切❤️)
PS:異なる言語やプロジェクトに対する一般的な .gitignore
ファイルは、github/gitignoreリポジトリを参考にできます。
29 | Git リポジトリをローカルにバックアップするには?#
関連コマンド: git clone
、 git remote
、 git push
一般的な転送プロトコル:ローカルプロトコル、http/https プロトコル、ssh プロトコル。後者の 2 つが作業中に最も一般的です。
転送プロトコルは 2 つのカテゴリに分けられます:ダミープロトコルとインテリジェントプロトコル。ここではローカルプロトコルを例にします:
1)/Path/to/.git;2)file:///Path/to/.git
前者はダミープロトコルで、後者はインテリジェントプロトコルです。
では、Git バックアップ時に両者にどのような違いがあるのでしょうか?
インテリジェントプロトコルはダミープロトコルに比べて、1)転送進捗が可視化され、2)転送速度が速くなります。
インテリジェントプロトコルとダミープロトコルの効果の比較:
pwd
を使用して、以前のデモで使用したリポジトリのアドレスを取得しました: /Users/double/Desktop/test
現在、2 つのプロトコルを使用して、リポジトリを別の場所にバックアップします:test_remote ディレクトリに。
ダミープロトコル
⚠️: --bare
は裸リポジトリを作成することを示し、作業ディレクトリを持たないリポジトリで、サーバーとして便利です。バックアップは.git フォルダであるため、アドレスには /.git
を追加する必要があります。最後の ya.git
はリポジトリ名を示します。
インテリジェントプロトコル
test.remote ディレクトリに戻り、インテリジェントプロトコルを使用し、file://
プレフィックスを追加します。
比較すると、視覚的な違いが見られます:ダミープロトコルには進捗バーがなく、インテリジェントプロトコルには進捗バーがあります。
上記はリモートからローカルにリポジトリをクローンするプロセスを示しましたが、ローカルリポジトリをリモートにプッシュするにはどうすればよいでしょうか?
元のリポジトリに戻り(ここで元のリポジトリの役割はリモートからローカルに変わります)、new
という名前のブランチを新たに作成します。
この時、リモートの intel.git リポジトリにはまだ 3 つのブランチしかありません:
ローカルにリモートサーバーを追加します:
git remote add intel file:///Users/double/Desktop/test_remote/intel.git
PS: intel
はサーバーのエイリアスで、後ろはサーバーのアドレスで、インテリジェントプロトコルを使用します。
git remote -v
を使用して、詳細なサーバー情報を確認できます。
次にプッシュを行います: git push REMOTE_NAME
コマンド
⚠️:直接プッシュするとエラーが発生します。最初に上流を設定する必要があります。
リモートの intel.git リポジトリのブランチ状況を再度確認します:
ブランチ new
がプッシュされたことが確認できます~
ここまで学んだことの中で、あなたが以前知らなかったことは何ですか?ぜひ交流しましょう~