本機テスト環境:macOS 11
01 | コース概要#
VSC:バージョン管理システム
- 中央集権型 —— クライアントは常にサーバーに接続している必要がある
- SVM
- 分散型 —— サーバーとクライアントの両方に完全なリポジトリがある
- Git、Linus が開発
- Git ベースのオープンソースコミュニティ —— 背景:DevOps 時代、開発と運用
- GitHub—— 世界最大
- GitLab—— 企業でよく使われる;無料、継続的インテグレーション - CI を提供;例:阿里云、点评
02 | Git のインストール#
- 始めに - Git のインストール—— 公式サイト:Linux、macOS、Windows、ソースコード
03 | Git を使用する前に必要な最小限の設定#
## nameとemailの設定を追加
git config [--local | --global | --system] user.name 'あなたの名前'
git config [--local | --global | --system] user.email 'あなたのメール'
## 既存の設定を確認
git config --list [--local | --global | --system]
## 違い
## --local:このリポジトリ
## --global: 現在のユーザーのすべてのリポジトリ
## --system: このシステムのすべてのユーザー
- 効果:人員情報を記録し、CR(コードレビュー)時にメール通知を行うことができる
04 | 最初のリポジトリを作成し、ローカルユーザー情報を設定#
- リポジトリを作成する 2 つの方法、どちらも.git フォルダを生成する
## 既存のプロジェクトフォルダ内にgitリポジトリを作成
git init
## [プロジェクト名]という名前の新しいgitリポジトリを作成
git init [プロジェクト名]
- ローカルユーザー情報を個別に設定する必要がある場合は、--local 設定を使用すればよい。この設定は最優先される、前のセクションを参照
- 簡単な commit を行う❗️
## このgitプロジェクトにファイルを追加、略
## commitするファイルを追加
git add [ファイル名]
### PS:現在のパス下のすべてのファイルを追加—— git add .
## メッセージを添えてcommit操作を行う
git commit -m'何らかのメッセージ'
### gitの状態を確認する、例:どのファイルがcommit待ちで、どのファイルが追跡されていないか
git status
### gitの記録を確認する、例:commitの記録
git log
05 | いくつかの commit を通じて作業ディレクトリとステージングエリアを理解する#
- ステージングエリア❗️——Git の本質の一つ
- 使用シーン:2 つのプランを開発する、最初のプランが完成したらまずステージングし、次に 2 つ目のプランを作成する。もし 2 つ目のプランが最初のプランより良くない場合は、最初のプランに戻ることができる
- PS:
- 作業ディレクトリの特定のファイルをステージングエリアに置き換えたい場合は、
git checkout -- file
- 作業ディレクトリの変更されたすべてのファイルを復元してステージングエリアと同じにする場合は、
git checkout *
- 作業ディレクトリの特定のファイルをステージングエリアに置き換えたい場合は、
git add -u
とgit add .
- 前者:すでに追跡されているファイルのみを操作し、ファイルの変更と削除をステージングエリアに追加する
- 後者:新しいファイルの作成も操作し、ファイルの作成、変更、削除をステージングエリアに追加する
- PS:
git add all/-A
はリポジトリ全体に対して行われ、現在のパスだけではない
- 具体的な操作は前のセクションと似ている —— 簡単な commit を 1 回行う
06 | ファイル名を変更する簡便な方法#
- ステップを細分化
## 名前を変更
mv readme readme.md
## 新しいファイルreadme.mdを追加
git add readme.md
## 追跡されている古いファイルreadmeを削除
git rm readme
## 提交
git commit -m"rename"
git reset --hard
を使用して最新の commit に戻り、ステージングエリアを空にする- 簡略化されたステップを再表示
## 一つのコマンドで上記の3つを実行
git mv readme readme.md
## 提交
git commit -m"rename"
- 実践展示
git status を通じてステージングエリアの状態をリアルタイムで観察する。
PS:最初の方法でも git status は renamed を検出できる
07 | git log を通じてバージョンの進化の歴史を確認する#
## 簡潔な単行の履歴を確認
git log --oneline
## 最近の4つの履歴を確認
git log -n4
git log -4
## すべてのブランチの履歴を確認
git log --all
## 指定したブランチ(名はBRANCH_NAME)の履歴を確認
git log BRANCH_NAME
## グラフィカルなバージョン履歴を確認
git log --graph
## 組み合わせて使用:すべてのブランチの最近4つのグラフィカルな単行履歴を確認
git log --all -n4 --graph --oneline
## ウェブ版のgit logヘルプドキュメントにジャンプ
git help --web log
git log --all -n4 --graph --oneline
の効果図
追加コマンド
git branch
でローカルにどのようなブランチがあるかを確認し、-a
を使用するとローカルとリモートのブランチを同時に確認できるgit checkout -b
<new_branch> []- 新しいブランチ名 new_branch(commit hash 値を start point とする commit を基に)を作成
- 簡便のため、start point は hash 値の一部を選択でき、commit を一意に識別できればよい
git commit -am'msg'
- 作業ディレクトリとステージングエリアのファイルを直接バージョン管理に追加し、add を使用したのと同じ
- ⚠️:すでに追跡されているファイルのみを commit でき、新しいファイルは先に
git add .
でステージングエリアに追加する必要がある
PS
- ~ /.zshrc で、エイリアスを設定してよりフレンドリーな log 表示方法を設定し、設定後は
lg ...
を使用するだけ
alias lg="git log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
- 一般的に、単一文字のオプションは
-
に対応し、非単一文字のオプションは--
08 | gitk:グラフィカルインターフェースツールを通じてバージョン履歴を確認#
- Mac でのインストール:
brew install git-gui
- 使用:
gitk
- インターフェースの簡単な表示
- View-New View を選択し、All refs を選択すると、すべてのブランチ、タグ情報が表示される
- 特定の commit を右クリックすると、多くの操作が可能で、Create tag などがある
PS
- なぜ一つの commit には著者 Author とコミッター Committer が両方存在するのか
- 著作権を尊重するため
- 例えば
git cherry-pick
コマンド:指定した commit を他のブランチに適用する - 具体的な使用法はgit cherry-pick チュートリアルを参照 —— 阮一峰
- もう一つの Git グラフィカルインターフェースツールを推薦:Sourcetree、実際にはツール間の違いは少なく、個人の習慣による
09 | .git ディレクトリの秘密#
Git は優れたストレージ能力を持ち、ネットワークがなくてもローカルでバージョン管理ができる
- 🌟4 つの重要なファイル:HEAD、config、refs、objects、以下で一つずつ分析
- ❗️3 つの重要なオブジェクト:commit、tree、blob、PS:tag
- 関係図は上記の通り、参考:GIT オブジェクトモデル——Git Community Book 日本語版
- blob:全称 Binary Large Object、すなわちバイナリ大オブジェクト、ファイルオブジェクトと理解できる
- 次のセクションでも詳しく説明するが、まずは 4 つの重要なファイルを見てみよう~
- HEAD:現在作業中のブランチを指す
HEAD 内のブランチを手動で変更すると、 git checkout
と同じ効果がある
- config:ローカルリポジトリ(local)の設定情報
主にユーザー情報に注目
config ファイルを手動で変更すると、 git config --local
と同じ効果がある
- refs:heads と tags フォルダを含む
- heads 内の各ブランチには commit の hash 値が保存されている
- tags 内の各マイルストーンにも commit の hash 値が保存されている
- または tag の hash 値が保存されている可能性があり、それは commit を指す
git cat-file
:リポジトリオブジェクトの情報を表示-t
:タイプ-p
:内容(cat コマンドを直接使用すると文字化けする可能性があるため、これらのオブジェクトは解析が必要)- 後者には一意の hash 値またはファイル名を指定すればよい
PS:注意深いあなたは、1 つの commit に tree の hash 値が保存されていることに気づくでしょう。それは最初の関係図とつながっています。tree の内容を確認してみましょう。
- objects:すべてのオブジェクトを保存、tree /blob/commit を含む
- 1)ほとんどのフォルダ📁は hash 値の最初の 2 文字で命名され、その中に 38 文字のファイルが保存されている
- この 40 文字の hash 値が一意にオブジェクトを指し示す
- 2)tree オブジェクトには blob オブジェクトの情報が保存されており、blob オブジェクトの内容は特定のファイルの内容である(例:css.x)
- tree オブジェクトは別の tree オブジェクトの情報も保存できる
- ファイルの内容が同じであれば、Git の観点からはそれは唯一の blob である
- 3)blob オブジェクトの内容はその指し示すファイルの内容と一致する
- 一致することは必ずしも保証されない、バージョンに依存する
- PS:pack フォルダと info フォルダもある
- 前者はパッケージ化された緩やかなフォルダを保存するために使用され、後者は前者と連携している
10 | commit、tree、blob の 3 つのオブジェクト間の関係#
前のセクションで彼ら 3 人について言及したので、このセクションでは commit を具体的に見て、理解を深める
- これは彼ら 3 者の関係図であり、矢印の向きを注目してください。参考:GIT オブジェクトモデル——Git Community Book 日本語版
- 解析
- 1 つの commit の内容は 1 つの tree によって管理され、1 つだけ存在する
- 現在の commit 内のすべてのフォルダとファイルのスナップショットを保存する
- 1 つの tree には複数の子 tree と複数の blob が含まれることができる
- 1 つの blob にはファイルオブジェクトの具体的な情報が保存される
- ファイルの内容が同じであれば唯一であり、ファイル名とは完全に無関係である
- 1 つの commit の内容は 1 つの tree によって管理され、1 つだけ存在する
- 例
commit👉tree👉blob + tree
PS: lg
は第 7 節で設定した git log
のフレンドリー表示版コマンドです
11 | 小練習:tree の数を数える#
新しく作成した Git リポジトリには、1 つの commit しかなく、/doc/readme のみを含む
内含されている tree の数と blob の数はそれぞれいくつですか?
これから実験を始めます🧪
## まず新しいGitリポジトリを作成
git init watch_git_object
## リポジトリに入って、docフォルダを作成し、readmeを追加
cd watch_git_object
mkdir doc
echo "hello, world" > doc/readme
## この時点で.git/objectsにファイルタイプのファイルがあるかどうかを確認:空
find .git/objects -type f
## docをステージングエリアに追加
git add doc/
## 再度確認:Gitがblobオブジェクトを生成し、readmeの内容を記録している
find .git/objects -type f
- ステージングエリアに追加すると、blob オブジェクトが生成される
- ❗️この時点では commit、tree オブジェクトはまだ存在しない。次に commit を行う
## commitを行う
git commit -m'Add readme'
## .git/objects内のファイルを確認:すでに4つある
find .git/objects -type f
## それらのタイプと内容を一つずつ確認する、以下の図のように
git cat-file -t ***
git cat-file -p ***
- 新たに生成されたのは:1 つの commit、2 つの tree
- 彼らの関係は:
- commit👉tree(commit は 1 つの tree に対応)👉tree(doc フォルダ)👉blob(readme ファイル)
12 | HEAD が分離した状態での注意事項#
detached HEAD
- 発生:HEAD を特定の commit に切り替えたとき(特定のブランチの最新の commit でも)
git checkout <HASH_OF_COMMIT>
、特定のブランチではなく
この時点で detached HEAD の状態が発生し、いくつかの試験的操作を行い、commit を行うことができる
1)これらの commit を保持したくない場合:ブランチに直接切り替え、他の追加操作を行わない
2)これらの commit を保持したい場合:新しいブランチを作成し、それに関連付ける必要がある
- 次に readme にいくつかの変更を加え、commit を行い、特定のブランチに切り替えると
Git は友好的に提示します:先ほどの commit を保持したい場合は、commit の hash 値を使って新しいブランチを作成できます
gitk を使ってこの時点でのブランチの状況を確認すると、先ほどの commit の影は見えません
上記の友好的な提示に従い、 git branch fix_readme 34976f8
を実行します
前に行った commit はすでに fix_readme ブランチに関連付けられています
- 小結
- 使用シーン:いくつかの試験的な試みを行う
- ⚠️:行った commit を保持したい場合は、特定のブランチに関連付ける必要がある
13 | HEAD とブランチをさらに理解する#
- 2 つの問題を持って学ぶ:
- 新しいブランチを作成するとき、HEAD はどう変化するのか?(HEAD は何を指すのか)
- HEAD に関連する使用のコツは何か?(commit を指し示す、特別なマーク
^
、~
)
以下で一つずつ探討します:
- 1
HEAD は特定のブランチを指すことも、特定の commit を指すこともできる
git checkout -b <NEW_BRANCH_NAME> <BASE_BRANCH_NAME/HASH_OF_COMMIT>
コマンドを使用して、特定のブランチまたは commit に基づいて新しいブランチを作成し、新しいブランチに切り替える
HEAD は分離した状態から、fix_new ブランチを指すように変わります
HEAD ファイルの情報を再確認します
実際には、HEADは特定のブランチを指し、そのブランチは特定のcommitを指します
- 2
HEAD が最終的に commit を指すので、それを使って commit の hash 値を指し示すこともできます~
例えば、 git diff <A> <B>
で 2 つの commit を比較する際
上記の 3 つのコマンドは同等です、すなわち:
git diff 34976f8 a60a3d5
、 git diff HEAD HEAD~
、 git diff HEAD 'HEAD^'
⚠️:
HEAD の ^
と ~
マークは HEAD の祖先 commit を取得するために使用でき、彼らの違いは下の図を参照してください:
このブランチ図の方向は git log --graph
で生成される図の方向とは逆で、A が最小のものであり、マージブランチの状況も考慮されています
参考:HEAD^ と HEAD~ の違いは何ですか?——StackOverflow
PS:zsh では、 ^
には特別な意味があるため、引用符で囲む必要があります
ここまで学んだことで、Git に対する認識が更新されましたか~次のパートを楽しみにしていますか?!