本勉強会の目的
Gitよくわからん…
↓
Gitスコシワカル
Gitのドキュメントを読む足がかりになれればという位置づけ
今日の内容
- 状態
- ブランチ
- HEAD
- origin
- git コマンドとの付き合い方
- おまけTips(git stash)
Gitの誕生
誕生のきっかけ
Linuxカーネルの開発において新しいVCSが必要になった。
3つのエリアとそれぞれの状態を知ろう
- 作業ディレクトリ(Working Directory)
- ステージングエリア
-
.git
ディレクトリ(Repository)
作業ディレクトリ
- 私達が実際にファイルを追加・修正したりするときのエリア。ファイルはuntracked/trackedのどちらかの状態。
- trackedの場合modified/unmodifiedの状態を取る。
- 別名ワーキングツリーとも
ステージングエリア
-
git add
するとここに配置される。 -
git commit
時にはこのステージングエリアにあるファイルが対象になる。 - 別名インデックスとも。
- このエリアに追加されるとステージ済みの状態(staged/unstaged)
.git
ディレクトリ(Repository)
- プロジェクトのためのメタデータなどが格納されている。
-
git commit
をするとその情報がここに蓄積される。 - このエリアに追加されるとコミット済み
ブランチ
ブランチの前に… git におけるcommitとは?
Gitはデータをミニ・ファイルシステムのスナップショットの集合のように考えます。 Gitで全てのコミット(訳注:commitとは変更を記録・保存するGitの操作。詳細は後の章を参照)をするとき、もしくはプロジェクトの状態を保存するとき、Gitは基本的に、その時の全てのファイルの状態のスナップショットを撮り(訳者注:意訳)、そのスナップショットへの参照を格納するのです。 効率化のため、ファイルに変更が無い場合は、Gitはファイルを再格納せず、既に格納してある、以前の同一のファイルへのリンクを格納します。 Gitは、むしろデータを一連のスナップショットのように考えます。
ブランチとは?
ブランチはある時点のコミットを示すポインタ。
ブランチの種類
- リモートブランチ
- ローカルブランチ
- リモート追跡ブランチ
- ローカル追跡ブランチ
- (通常の)ローカルブランチ
リモートブランチ
リモートリポジトリにあるブランチ
- リモート にあるので普段これを触ったりはしない。
- 私達は
push
/fetch
を通じてしか操作できない。
ローカルブランチ
(通常の)ローカルブランチ
$ git checkout foo master
- 他のローカルブランチ区別するために「通常の」と付けている
- このあと紹介する2つのローカルブランチの特性が無いブランチ
リモート追跡ブランチ
- ローカル に作成される。
- 最初のcloneかfetchの度、リモートブランチの状態を保存してる。
- リモートブランチの状態を知るには、ローカルにあるリモート追跡ブランチを参照することになる。(リモートブランチとのつながりを持っている)
-
remotes/<remote>/<branch>
という名前で作られる。(省略形は<remote>/<branch>
) - このブランチへのコミットは不可
ローカル追跡ブランチ
- ローカルに作成される。
- リモートブランチへのコミットを発行するためのブランチ。
- 通常のローカルブランチとほぼ同じだが唯一の違いは、リモート追跡ブランチとつながっている事。
- このブランチへのコミットは可能
ローカル追跡ブランチの作成方法をみてもリモート追跡ブランチとつながりを持っていることが見て取れる。
$ git checkout -b <local_branch> <remote>/<branch>
- 既に手元にあるローカルブランチを、リモートブランチの取り込み先に設定したい場合
git branch -u <remote>/<branch>
HEAD
?
- HEADは作業しているブランチを指すポインタ
-
git checkout <branch>
で HEADが指すブランチが変わる。
$ git checkout master
$ git checkout testing
$ git commit # 87ab2
$ git checkout master
- 現在のブランチの最新コミットを指す。
- 現在操作しているリビジョンのSHA-1ハッシュ(commit id)が必要な場面でHEADを使える。
- パラメータを指定しない場合のデフォルト値になる
- 相対的な指定もできる。
-
HEAD
のエリアスとして@
が使える
$ git show HEAD # 現在の最新コミット
$ git show HEAD^ # 現在の最新コミットの1つ前
$ git show HEAD~ # 現在の最新コミットの1つ前
$ git show HEAD^1 # 現在の最新コミットの1つ前
$ git show HEAD~1 # 現在の最新コミットの1つ前
$ git show HEAD^^^ # 現在の最新コミットの3つ前
$ git show HEAD~~~ # 現在の最新コミットの3つ前
$ git show HEAD~3 # 現在の最新コミットの3つ前
上記の通り^
(キャレット)または~
(チルダ)で相対指定が可能。
ただし、^数字
(例えばHEAD^2
)と入力した場合は注意が必要となる。HEADがマージコミットで親が2つ持つ場合等はHEAD^数値
は親コミットの指定に使われる。
~
はマージコミットでは常に最初の親を参照する。
$ git show HEAD^2~2 # 2番目の親の2つ前
originとは?
- リモートリポジトリから
git clone
した時にgitがデフォルトでつける名前。読み込み用と書き込み用がある。 - 名前を変更することもできる。
-
git remote -v
で確認できる。 - 複数のリモートリポジトリを登録することもできる。
- 何も特別意味のあるものではない、リモート先の情報を参照するための変数名のようなイメージ
$ git push origin master
# <リモート先> <ブランチ名>
git コマンドとの付き合い方
コマンド+オプションを覚えるのも打鍵するのも大変なので、エリアスを活用しよう。
$ vim ~/.gitconfig
例えば
git add
の取り消し、git reset HEAD
は覚えにくいと感じたら
git unstage <filename>
git commit -m
が長いと感じたら
git save <message>
git branch
で常にたくさんの情報(-a
, -vv
)を観たいとおもったら
git branches
もしくはGitクライアントを利用する。(sourcetree, totoise, tig...)
Tips
Stash 作業をポケットに一時退避
使えるケース:
ある作業中により優先度の高い作業を振られたが、いまの作業はコミットできないし、破棄もしたくないような場合。
git stash
で今の作業を一時退避できる。
- ステージングエリアと作業ディレクトリの現在の状態を保存し
- 作業ディレクトリをリセットする
$ git stash save <任意の名前(省略可)>
# 注意点として untrackedなファイルは対象とならないので先に`git add -A`をしておくのがおすすめ。
この時点で最後のコミットした時点に戻ります。
下記で一時保存した内容を確認できます。
$ git stash list
ここでブランチを切って優先度の高い対応を行う。
コミット後元いたブランチに戻って次のコマンドでsaveした内容を復活。且つリストからも削除
$ git stash pop
参考
- https://git-scm.com/book/ja/v2
- Gitで困っとときに読む本