本記事の目的
本記事の目的は、 「イメージのわきずらいgit」に対して、頭の中でイメージしながら使いこなしていけるようになる方を一人でも多く増やすこと です。
そのために一つ一つのgit コマンドを図と共に理解できるように説明していきます。
gitの3要素
gitは、「誰が」「いつ」「何を」「何のために」変更したのかということを時系列で簡単に把握することができる便利なツールです。
そんなgitには使いこなすために知っておくべき3つの要素があると私は考えています。
- ワークツリー
- ステージ
- ローカルリポジトリ
以下の図を見ていただくと分かりやすいと思いますが、 gitでは主にこの3つの領域を駆使して変更履歴を管理していきます。 これからご説明するコマンドも、この3つの領域を考慮しながら説明させていただくのでしっかりと理解しておきましょう。ただしざっくりとした理解で大丈夫だと思います。
git コマンド(変更を反映させるためのコマンド集)
まずは基本的に用いる「変更した分を反映させるためのコマンド」です。
git add(変更分をワークツリーからステージへ)
git addは、「ワークツリーで変更を加えた分をステージに上げるためのコマンド」です。使用するコマンドと動きのイメージは以下の図の通りです。
git commit(変更分をステージからローカルリポジトリへ)
gitでは、 ローカルリポジトリに変更分を保存することを「コミットする」と言います。
git commitは、「ステージに上げた分をローカルリポジトリに保存するためのコマンド」です。使用するコマンドと動きのイメージは以下の通りです。
# git commitのみの場合エディタが起動し、そこでコミットメッセージを入力することになる
$ git commit
# git commit -m 'メッセージ'の場合、コマンド上でメッセージを入れた上でコミットできる
$ git commit -m 'test.htmlファイル作成'
git status(各領域間での変更状況を確認)
git statusコマンドは、「ワークツリーとステージ間、もしくはステージとローカルリポジトリ間の変更状況を表示する」コマンドです。使用するコマンドと動きのイメージは以下の図の通りです。
git diff(各領域間での変更差分を確認)
git diffコマンドは、git statusコマンドと少し似ていますが、こちらは「差分を詳しく表示するコマンド」です。「git diff」と「git diff --staged」の2種類があります。使用するコマンドと動きのイメージは以下の通りです。
git rm(ファイルやディレクトリを削除する)
git rmコマンドは「ファイルやディレクトリを削除したという記録を反映させるためのコマンド」です。主に以下の2パターンを覚えておきましょう。
# ワークツリーとローカルリポジトリから削除する
git rm ファイル名
git rm -r ディレクトリ名
# ワークツリーには残すがローカルリポジトリからは削除する = 実際のファイルは残すが、変更履歴には載せない
git rm --cached ファイル名
使用するコマンドと動きのイメージは以下の通りです。
git rmコマンドの場合
git rm --cachedコマンドの場合
git rm --cached は、機密情報が入ったファイルなど、ワークツリーには実ファイルを残しておきたいけど安全のためにgitには追跡させたくないからやっぱり消すといった状況で使われることが多い。
git mv(ファイル名を変更する)
git mvコマンドは「ファイル名を変更するときに用いるコマンド」です。使用するコマンドと動きのイメージは以下の通りです。
# git mv home.html home2.htmlは以下と同じこと
$ mv home.html home2.html -- ①ワークツリーでファイル名が変わる
$ git rm home.html -- ②ローカルリポジトリから「home.html」が削除される
$ git add home2.html -- ③リネーム後ファイルがステージへ上げられる
git コマンド(変更を取りやめる/やり直すコマンド集)
次に「変更した分を取りやめたりやり直したりするコマンド」を説明いたします。
git reset HEAD コマンド(ステージに上がっている変更分を取り消す)
git reset HEADコマンドは、「ステージに上げてしまった変更分を取り消すコマンド」です。使用するコマンドと動きのイメージは以下の通りです。
git checkout --<ファイル名> コマンド(ワークツリーでの変更分を取り消す)
git checkout --<ファイル名>コマンドは、「ワークツリーでの変更を取り消すコマンド」です。使用するコマンドと動きのイメージは以下の通りです。
git checkout -- <ファイル名>__ の他に、 git restore <ファイル名> というやり方もある。
git commit --amend コマンド(直前のコミットを取り消してやり直す)
git commit --amend コマンドは、「直前のコミットをやり直すためのコマンド」です。使用するコマンドと動きのイメージは以下の通りです。
↓
git コマンド(リモートリポジトリとのやり取り)
これまではあくまで「ローカル環境」でのgit コマンドについてご説明しました。しかし、gitには「リモートリポジトリ」と
のやり取りをして、他の人が変更したものを自分のところにも取り入れるなどの「共有」操作を行うことができるという大きな特徴を持っています。
そこで、ここからは「リモートリポジトリとのやり取り」に使用するコマンド集をご説明していきます。
git push
git pushコマンドは「ローカルリポジトリに保存したコミットをリモートリポジトリに共有するためのコマンド」です。使用するコマンドと動きのイメージは以下の通りです。
# 基本的にgit push <リモートリポジトリ名> <リモートブランチ名>とする
$ git push origin main
尚、リモートリポジトリ名やリモートブランチ名を指定せずとも省略記法で出来てしまう方法もありますが、ここでの説明は割愛させていただきます。
git fetch ~ git merge
git fetchとは「リモートリポジトリ上の特定のブランチでの変更分をローカルのリモート追跡ブランチに取り込むためのコマンド」です。そして、git mergeは「ローカルのリモート追跡ブランチに取り込んだ内容を実際にローカルリポジトリのブランチに結合させるコマンド」です。
「リモート追跡ブランチ」という意味不明な言葉も出ていますし、これだけでは理解できないと思いますので、以下の図などをご覧ください。
# ①リモートの「main」ブランチで「index.htmlファイル」に「<p>20230109 git fetchの練習</p>」というpタグを追加しとします。
# ②リモートのmainブランチでの変更分を「fetch」
$ git fetch origin main
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 743 bytes | 185.00 KiB/s, done.
From https://github.com/hiddy0329/git-tutorial
* branch main -> FETCH_HEAD
31525b5..153da33 main -> origin/main
# 上のところで、「31525b5..153da33 main -> origin/main 」となっている部分に注目。
# リモートのmainブランチからリモート追跡ブランチである「origin/main」ブランチへ変更分が取り込まれている。
# ③現在のローカル上のブランチを確認する
$ git branch -a
feature
hotfix
* main
remotes/backup/main
remotes/origin/feature
remotes/origin/main
# ④「remotes/origin/main」というのがリモート上のmainブランチの内容を追跡するリモート追跡ブランチなので、このブランチの中身を見てみる。
$ git checkout remotes/origin/main
Note: switching to 'remotes/origin/main'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at 153da33 20230109 git fetchの練習を追記
# ⑤index.htmlファイルの中身を見ると、追記した分が取り込まれていることが分かる
$ ls
hoge.html home3.html main.html tmp.html
home.html index.html test.html tmp.txt
$ cat index.html
<h1>hello world</h1>
<p>my name is Ken</p>
<p>git diffコマンドで差分を表示</p>
<p>git diff --stagedとするとステージとローカルリポとの差分を表示</p>
<p>git commit --amend</p>
<p>git rmコマンドの練習</p>
hellohello
<p>20230109 git fetchの練習</p>
# ⑥mainブランチへ戻る
$ git checkout main
Previous HEAD position was 153da33 20230109 git fetchの練習を追記
Switched to branch 'main'
Your branch and 'origin/main' have diverged,
and have 11 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
# ⑦origin/mainブランチにリモート上の変更が取り込まれていることを確認したので、今度はローカルのmainブランチに取り込みを実行
$ git merge origin/main
Merge made by the 'ort' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)
$ ls
feature.html home.html index.html test.html tmp.txt
hoge.html home3.html main.html tmp.html
# ⑧ローカルのmainブランチに変更分が取り込まれたことを確認
$ cat index.html
<h1>hello world</h1>
<p>my name is Ken</p>
<p>git diffコマンドで差分を表示</p>
<p>git diff --stagedとするとステージとローカルリポとの差分を表示</p>
<p>git commit --amend</p>
<p>git rmコマンドの練習</p>
hellohello
<p>20230109 git fetchの練習</p>
分かりにくくて恐縮ですが、git fetchでは一旦「リモート追跡ブランチ」というところに仮で変更分を取り込むわけですね。その後、実際にローカルのブランチに取り込んで大丈夫であれば取り込むといった流れでしょうか。
git pull
git pullは先ほどの「git fetch ~ git mergeを一度に行なってしまうコマンド」です。イメージは以下の通りです。
git pullでは、一度に「merge」までしてしまうため、「コンフリクト」に気をつける必要があります。この記事では「git fetch」や「git pull」をイメージで理解することのみに留めさせていただきますが、詳しく挙動を知りたいというような方には以下の記事などがとても参考になります。
- git pull(プル)とは何か?使い方を実例で解説|引数が無い場合の処理内容やFETCH_HEADとは何か?–rebaseオプションの使い方
- 【初心者向け】git fetch、git merge、git pullの違いについて
次回の記事
今回は、基本的なgitコマンドでの操作についてイメージを持って理解していただくことを目的にご説明しました。次回の記事では、「ブランチ」などの概念に踏み込んでご説明できたらと思います。