こんにちは。AWS CLIが好きな福島です。
はじめに
突然ですが、私はGitが苦手です。
ただ、最近対応している案件でGitを本格的に使うことがあり、 少しだけ、Gitと仲良くなれた気がするので、 備忘録として、Gitの概要とコマンドを記載いたします。
Gitとは
分散型のバージョン管理システムです。
よく見る例えですが、あるファイルを更新する中で以下のような状態になり、どれが最新のファイルで、どのバックアップがどういう状態なのか、分からなくなることが多々あると思います。
file.txt file - コピー.txt file_20210714.txt file_20210824.txt
この問題を解決してくれるのがGitになります。
◆補足
Gitは分散型のため、集中型と違い、各々がローカルにファイルのバージョン(履歴)を管理するための倉庫(リポジトリ)を持つことが可能です。
そのため、Gitコマンドを実行するのに、ネットワーク接続が必須ではないという特徴があります。
GitHubとは
Gitを使うにあたってGitHubという名前も聞きますが、GitとGitHubは別物です。 そして、GitHubとは、チーム開発をより便利にするGitの仕組みを使ったWebサービスとなります。
Gitの仕組み
登場するエリア(要素)は、以下の通りで、特に重要なのが②になります。
①作業ディレクトリ
②ステージングエリア(インデックス)
③ローカルリポジトリ
※リポジトリとは、ファイルのバージョン(履歴)を管理するエリアになります。
まず、作業ディレクトリはファイルの編集を行うエリアになります。 ファイルの編集が終わるとステージングエリアに移動(add)します。 そして最後にステージエリアからローカルリポジトリに移動(commit)させます。
また、上記の図には、エリアの間にgit xxxと記載しておりますが、 これは、各エリアにファイルを移動させるGitのコマンドになります。
ステージングエリアの必要性
ここで、ステージングエリアって不要では?と思った方はいないでしょうか。
私も当初は不要なのではと思ったのですが、実はこのエリアがとても重要です。
必ずしも編集したファイルを全て移動(commit)させたい訳ではないですし、 テストやデバッグ用に書いたコードを移動(commit)させたい訳ではありません。
そのため、このステージングエリアがあることで、
・ローカルリポジトリに移動(commit)させるファイルを取捨選択
・1ファイルの中で移動(commit)したい箇所だけを選択
することが可能になります。
Gitのコマンド
ここからGitを使う上で基礎となるコマンドの一部をご紹介いたします。 実行例を上から順番に実行いただけるような作りにしています。
- 留意事項
本来、Gitは複数人でコードなどを管理する際に威力を発揮します。
Gitの仕組みに記載した図で表すと以下の通りです。
ということで、Gitを使う場合、リモートリポジトリに対する操作も合わせて覚えた方が良いと思いますが、
今回は、情報量が多くなってしまうので、そこは対象外にしております。
また、ブランチという重要な概念もありますが、そこも対象外です。
config
configの一覧
コマンド)
# git config --list
実行例)
# git config --list core.editor=vi user.name=KazuyaFukushima user.email=fukushima@example.com #
特定の設定項目の値だけ出力も可能です。
コマンド)
# git config 設定項目
実行例)
# git config user.name KazuyaFukushima #
configの設定
コマンド)
# git config --global 設定項目 設定値
実行例)
- ユーザー名の設定
# git config --global user.name "KazuyaFukushima"
- メールアドレスの設定
# git config --global user.email "fukushima@example.com"
- エディタの設定
# git config --global core.editor vi
◆補足
複数人が開発する場合、誰がどういった操作を行ったのか分かるように、
ユーザー名やメールアドレスは設定する方が良いかと思います。
configの取り消し
コマンド)
# git config --global --unset 設定項目
実行例)
# git config --global --unset user.name
init
gitの初期化を行います。
このコマンドを実行すると、カレントディレクトリ配下にあるファイルのバージョン管理が可能になります。
コマンド)
# git init
実行例)
例えば、以下のディレクトリ構成があり、/home/kazuya/work01配下のバージョン管理を行いたい場合、
以下のコマンドを実行します。
ディレクトリ構成)
/home/ ┣ kazuya/ ┃ ┗ work01/ ┃ ┗ sub_work01 ┗ work02/
実行コマンド)
# cd /home/kazuya/work01 # git init Initialized empty Git repository in /home/kazuya/work01/.git/ #
git initを実行すると、出力結果から分かるように「/home/kazuya/work01/.git」が作成されます。 ここにバージョン管理を行うために必要なファイル群が格納されます。 なので、ここは非常に重要なディレクトリになります。
また、sub_work01は、work01のサブディレクトリとなるため、 sub_work01にあるファイルもバージョン管理されます。
ただし、work02は、work01とは別のディレクトリのため、work02配下もバージョン管理したい場合、 work02でgit initを実行する必要があります。
status
gitのステータスを確認できます。
コマンド)
# git status
実行例)
# git status On branch master No commits yet nothing to commit (create/copy files and use "git add" to track) #
add
ステージングエリアへファイルの追加
コマンド)
# git add [ファイル名またはディレクトリ名]
実行例)
# touch test01.txt # git add test01.txt # git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: test01.txt #
git statusでも分かりますが、git addにディレクトリを指定する場合、 以下のコマンドを実行することでaddされるファイルを確認できます。
実行例)
# touch test02.txt test03.txt # git add --dry-run . add 'test02.txt' add 'test03.txt' #
ファイルの一部分をaddすることも可能です。 例えば、作業ディレクトリのtest01.txtには、apple,orange,melonが記載しているが、 ステージングエリアのtest01.txtには、apple,orangeだけにしたいとします。
# echo "apple" > test01.txt # git add test01.txt # echo orange >> test01.txt # echo melon>> test01.txt # cat test01.txt apple orange melon # git add -p diff --git a/test01.txt b/test01.txt index a7f0492..5c222e9 100644 --- a/test01.txt +++ b/test01.txt @@ -1,2 +1,4 @@ apple +orange +melon (1/1) Stage this hunk [y,n,q,a,d,e,?]?e ★編集するため、eを入力しEnterを押します。 ==== viの編集画面 ==== # Manual hunk edit mode -- see bottom for a quick guide. @@ -1,2 +1,4 @@ apple +orange melon ★ここを編集(編集前は、+melonとなっていた。) # --- # To remove '-' lines, make them ' ' lines (context). # To remove '+' lines, delete them. # Lines starting with # will be removed. # # If the patch applies cleanly, the edited hunk will immediately be # marked for staging. # If it does not apply cleanly, you will be given an opportunity to # edit again. If all lines of the hunk are removed, then the edit is # aborted and the hunk is left unchanged. =================
ステージングエリアからファイルを削除
コマンド)
# git rm --cached [ファイル名]
実行例)
# ls test01.txt test02.txt test03.txt # # git add test01.txt # git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: test01.txt Untracked files: (use "git add <file>..." to include in what will be committed) test02.txt test03.txt # git rm --cached test01.txt rm 'test01.txt' # git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) test01.txt test02.txt test03.txt nothing added to commit but untracked files present (use "git add" to track) #
commit
ローカルリポジトリへファイルのコミット
ステージングエリアにあるファイルをローカルリポジトリへコミットします。
コマンド)
# git commit -m "[メッセージ]"
※実行例に記載のメッセージは雑に書いていますが、実際には具体的にどういった変更を加えたのか、具体的に記載することをお勧めいたします。
実行例)
# ls test01.txt test02.txt test03.txt # git add test01.txt #f git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: test01.txt Untracked files: (use "git add <file>..." to include in what will be committed) test02.txt test03.txt # git commit -m "Add test01.txt." [master (root-commit) 8329a39] Add test01.txt. 1 file changed, 3 insertions(+) create mode 100644 test01.txt # git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) test02.txt test03.txt nothing added to commit but untracked files present (use "git add" to track) #
-mオプションを省略すると、エディターが開くため、そこにメッセージを残すことも可能です。
コマンド)
# git commit
実行例)
# git add test02.txt # git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) new file: test02.txt Untracked files: (use "git add <file>..." to include in what will be committed) test03.txt # git commit ==== viの編集画面 ==== Added test02.txt ★ここを追記 # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch master # Changes to be committed: # new file: test02.txt # # Untracked files: # test03.txt # ================= [master f7df1b1] Added test02.txt 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test02.txt #
diff
各エリアに存在するファイルの差分を確認できます。 以下の通り、差分があることを確認します。
作業ディレクトリ⇔ステージングエリア
コマンド)
# git diff
実行例)
色が分かるように画像を張りましたが、
作業ディレクトリのtest01.txtには、appleが記載されており、
ステージングエリアのtest01.txtには、appleが記載されていないことを表しています。
# echo "apple" > test02.txt # git diff diff --git a/test02.txt b/test02.txt index e69de29..4c479de 100644 --- a/test02.txt +++ b/test02.txt @@ -0,0 +1 @@ +apple #
ステージングエリア⇔ローカルリポジトリ
コマンド)
# git diff --staged または # git diff --cached
実行例)
ステージングエリアのtest01.txtには、appleが記載されており、
ローカルリポジトリのtest01.txtには、appleが記載されていないことを表しています。
# git add test02.txt # git diff # git diff --staged diff --git a/test02.txt b/test02.txt index e69de29..4c479de 100644 --- a/test02.txt +++ b/test02.txt @@ -0,0 +1 @@ +apple #
log
コミットのログを確認できます。
コマンド)
# git log
実行例)
# git log commit bf8b2b806fa1d325cbd82f3c07858b1fdee6f05a (HEAD -> master) Author: KazuyaFukushima <fukushima@example.com> Date: Wed Aug 25 13:28:45 2021 +0900 Added test02.txt commit aac465882fe5198390180a6eb196dec69adeec68 Author: KazuyaFukushima <fukushima@example.com> Date: Wed Aug 25 13:28:27 2021 +0900 Add test01.txt. #
- 差分も合わせて、表示することもできます。
# git log --patch commit bf8b2b806fa1d325cbd82f3c07858b1fdee6f05a (HEAD -> master) Author: KazuyaFukushima <fukushima@example.com> Date: Wed Aug 25 13:28:45 2021 +0900 Added test02.txt diff --git a/test02.txt b/test02.txt new file mode 100644 index 0000000..e69de29 commit aac465882fe5198390180a6eb196dec69adeec68 Author: KazuyaFukushima <fukushima@example.com> Date: Wed Aug 25 13:28:27 2021 +0900 Add test01.txt. diff --git a/test01.txt b/test01.txt new file mode 100644 index 0000000..8e32531 --- /dev/null +++ b/test01.txt @@ -0,0 +1,3 @@ +apple +orange +melon #
- 変更がかかったファイルのサマリを表示することもできます。
# git log --stat commit bf8b2b806fa1d325cbd82f3c07858b1fdee6f05a (HEAD -> master) Author: KazuyaFukushima <fukushima@example.com> Date: Wed Aug 25 13:28:45 2021 +0900 Added test02.txt test02.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) commit aac465882fe5198390180a6eb196dec69adeec68 Author: KazuyaFukushima <fukushima@example.com> Date: Wed Aug 25 13:28:27 2021 +0900 Add test01.txt. test01.txt | 3 +++ 1 file changed, 3 insertions(+) #
- 一行で簡潔に表示することもできます。
# git log --oneline bf8b2b8 (HEAD -> master) Added test02.txt aac4658 Add test01.txt. #
rm
作業ディレクトリとステージングエリアからファイルを削除します。
コマンド)
# git rm ファイル名 または # git rm -r ディレクトリ名
実行例)
# ls test01.txt test02.txt test03.txt # git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test02.txt Untracked files: (use "git add <file>..." to include in what will be committed) test03.txt # git rm test01.txt # git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) deleted: test01.txt modified: test02.txt Untracked files: (use "git add <file>..." to include in what will be committed) test03.txt # # ls test02.txt test03.txt #
もし、ステージングエリアとローカルリポジトリに差分があるファイルが対象の場合、 以下の通り、エラーになります。強制的に削除する場合は、-fオプションを付与します。
# ls test02.txt test03.txt # touch test01.txt # git add test01.txt # git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test01.txt modified: test02.txt Untracked files: (use "git add <file>..." to include in what will be committed) test03.txt # git rm test01.txt ★差分があるため、エラーとなる。 error: the following file has changes staged in the index: test01.txt (use --cached to keep the file, or -f to force removal) # git rm -f test01.txt rm 'test01.txt' # git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) deleted: test01.txt modified: test02.txt Untracked files: (use "git add <file>..." to include in what will be committed) test03.txt #
restore
誤って削除した場合、ローカルリポジトリにファイルが存在すれば、resotreで戻すことが可能です。
ローカルリポジトリ⇒ステージングエリア
コマンド)
# git restore --staged ファイル名
実行例)
先ほど削除したtest01.txtを復元します。
# ls test02.txt test03.txt # git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) deleted: test01.txt modified: test02.txt Untracked files: (use "git add <file>..." to include in what will be committed) test03.txt # git restore --staged test01.txt # git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test02.txt 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: test01.txt Untracked files: (use "git add <file>..." to include in what will be committed) test03.txt #
ステージングエリア⇒作業ディレクトリ
コマンド)
# git restore ファイル名
実行例)
# git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test02.txt 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: test01.txt Untracked files: (use "git add <file>..." to include in what will be committed) test03.txt # ls test02.txt test03.txt # git restore test01.txt # ls test01.txt test02.txt test03.txt # git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test02.txt Untracked files: (use "git add <file>..." to include in what will be committed) test03.txt #
mv
作業ディレクトリとステージングエリアのファイルをリネームします。
コマンド)
# git mv 変更前のファイル名 変更後のファイル名
実行例)
# ls test01.txt test02.txt test03.txt # git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test02.txt Untracked files: (use "git add <file>..." to include in what will be committed) test03.txt # git mv test01.txt test01-mv.txt # git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) renamed: test01.txt -> test01-mv.txt modified: test02.txt Untracked files: (use "git add <file>..." to include in what will be committed) test03.txt # ls test01-mv.txt test02.txt test03.txt #
OS上でファイルを変更するだけでいいのでは?と思った方もいるかと思います。 ただそれでは、作業ディレクトリにあるファイルしか更新されず、 ステージングエリアにあるファイルは更新されないため、別途git addを行う必要があります。
この作業を簡潔に行えるのが、git mvコマンドということになります。
mvコマンドを使う場合)
# git mv test01-mv.txt test01.txt ★一旦、元に戻します。 # git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test02.txt Untracked files: (use "git add <file>..." to include in what will be committed) test03.txt # mv test01.txt test01-mv.txt # git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: test02.txt 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: test01.txt Untracked files: (use "git add <file>..." to include in what will be committed) test01-mv.txt test03.txt # git add test01.txt test01-mv.txt # git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) renamed: test01.txt -> test01-mv.txt modified: test02.txt Untracked files: (use "git add <file>..." to include in what will be committed) test03.txt #
終わりに
私自身がgitを理解するために、gitの概要とコマンドをブログにまとめてみました。 もしこのブログがどなたかのお役に立てれば幸いです。
参考
独習Git | リック・ウマリ, 吉川 邦夫 |本 | 通販 | Amazon