先日サブモジュールを扱って色々躓いたので、これを機にgitについて勉強してみました。何番煎じか分からない備忘録です。
※Pro Gitの内容を自分向けに整理したものです。
概要
- gitはsvnのような差分管理ではなく、ファイル単位で管理されている。
- git cloneは最新のコミットのみではなく、過去のコミットを含む全てをクローンする(一部のフックなどを除く)。
- ファイルの状態には、大別して、gitの管理状態を意味するtrackedファイルと管理外のuntrackedファイルがある。
- trackedファイルの状態には,unmodified, staging, modifiedがある。
- stagingのファイルがコミット対象になる。
基本
ファイルを追跡対象にしたりstaging状態にする
例1
git add a.c # そのファイルをstaging状態にする。
git add . # dir(この場合./)を指定するとそのディレクトリを再帰的に追加する。
git add a.c # a.cをstaging状態にする。
vim a.c # 何か編集する。 a.cはmodified状態になる。
# この時点でcommitしても、staging状態がコミットされる。
git add a.c # a.cがstaging状態になる。
git commit -a # 未stagingをstaging状態にして、commitする。通常はこちら
staging状態をmodified状態に戻す
git reset HEAD filename
変更した内容を直近のコミットの内容に戻す
git checkout -- filename
差分を表示する
git diff # 作業ディレクトリの内容とstaging状態の差を表示する。
git diff --staged # staging状態と直近のコミットとの差を表示する。
git diff --check で空白等の余計な文字を(X)で教えてくれる。
コミットする
git commit # -mを指定しない場合、環境変数$EDITORで登録された
# エディタが起動され、コメント入力できる。
git commit --amend # 直近のコミットに対して上書きする。
# 直近のコミットにコメントを上書きしたり、変更を追加できたりする。
ファイルを削除する
git rm file
ファイルを移動する
git mv from to
#上記は、以下のショートカット
mv from to
git rm from
git add to
作業状態を一時的に隠す
git stash # 現在の作業ファイル等をスタックに記録し、直近のコミット状態に戻す。
git stash list # 一覧の表示
git stash apply # 直近のstash状態を復元する.ただしstagin状態は戻らない.
# stackの内容は消えない。
git stash apply --index # sgit stash applyに加えtaging状態も戻す。
git stash drop # 直近のスタックを削除する。
git stash pop # 直近のstash状態を復元して、スタックから削除する.
git stash show -p | git apply -R # 直近のstash applyを戻す。
# git config --global alias.stash-unapply '!git stash show -p | git apply -R'しておくと良い。
git stash branch branch-name # stashで隠した作業ディレクトリから新しいブランチを作成する。
リモート操作
git remote # リモート名の一覧を確認できる。
git remote -v # 名前に対応するURLも表示する。
git remote add remote-name repository-url # リモートリポジトリ追加
git remote show remote-name # リモートの詳細表示
git fetch remote-name # リモートリポジトリの情報を取得するのみで、ローカルリポジトリの内容は変更されない。
git pull # リモートの状態を取得して、ローカルリポジトリにマージする。
git push remote-name repository-url # リモートへローカルリポジトリの内容を更新する。
git remote rm remote-name # リモートの設定を削除する
タグ
git tag # 一覧表示
git tag -l 'v1.*' # 検索
git show tag-text # タグの詳細を表示する
git tag -a tag-text -m "comment" # 注釈付き(現在のスナップショットの複製を作る)
git tag version # 軽量タグ(branchを作る)
リリース用のタグ付け
git tag -s v1.5 -m "comment"
git describe # ビルド番号を自動生成する.
git archive master --prefix=my_project/ # アーカイブファイルを生成する。
ブランチ
- HEADポインタは、参照しているコミットのスナップショットを指す。
ブランチの作成
git branch branchname# 作成するだけ。切り替えない。
ブランチの一覧表示
git branch
git branch -v # 直近のコミットログを確認
git branch --merged # マージされたブランチの一覧を確認する。
git branch --no-merged # 未マージの一覧を確認する。
ブランチを切り替える
- ブランチの変更は、作業中のファイルやstaginファイルがある場合できない。
git checkout branch-name # HEADをbranch-nameを差し替えて、作業ディレクトリをそのブランチのスナップ状態に戻す。
git checkout -b new-branch-name # 新しいブランチを作成して、HEADをそれに切り替える。
ブランチのマージ
- マージ元が直接マージ先に到達できるときは、fast-forwardといい、HEADのの位置を差し替えるだけ.
- 複数のブランチがマージされる場合、自動的に新しいスナップショットを作成して、コミットする。
git merge branch-name # 現在のブランチにbranch-nameのブランチ内容をマージする。
ブランチの削除
git brach -d branch-name
コンフリクトした場合
git status # コンフリクトしたファイルの確認。解決していないファイルは、unmanagedとして表示される。
vim filename # コンフリクトしたファイルを編集する。
#<<<<<<<<< ======== >>>>>>>のコンフリクト部分を編集して、望むの状態にする。
git add filename # コンフリクトの解決済みにする。
git commit
git mergetool # 外部のマージツールでマージ作業を行う
リモートブランチ
- ブランチ名は、remote-name/branch-name。
リモートブランチの情報を取得する
git fetch origin # リモートブランチの情報をローカルに取得する。(取得するだけ)
リモートブランチへ変更を通知する
git push # git push remote-name from-branchname:to-branchnameの省略計
リモートブランチをチェックアウトする
git checkout -b local-branch-name remote-name/branch-name # ローカル名local-branch-nameでリモートのブランチをチェックアウトする。
リモートブランチを削除する
git push remote-name :bracn-name
マージ(rebase/merge)
- 公開リポジトリにpushしたブランチへのrebaseはダメ。
基本形
git checkout branch_b
git rebase master # branch_bの内容がmasterにマージされて、branch_bのスナップショットは、masterのリビジョンに移動する。
# ただしbranchはbranch_bのまま。
git checkout master
git merge branch_b # これでmasterにbranch_bの内容を反映する。
--onto
git rebase --onto master branch_a branch_b # branch_bの変更と、branch_bに関連するbranch_aの変更をmasterに反映して、branch_bのmaster上に移動する。
#ただしbranchはbranch_bのまま
git checkout master
git merge branch_b # これでmasterにbranch_bの内容を反映する。
git log --no-merges remote-name/branch-name ^local-branch # masterからlocal-branchの間に、マージが必要なブランチを表示する
分散作業
プルリクエスト
git request-pull remote-name/branch-name local-branch-name # プルリクエストする
複数のコミットを1つにしてマージ.
例
git checkout -b ver2 origin/master
git merge --no-commit --squash local_branch
git commit
git push origin master
パッチの作成
- diff形式とmbox形式の二つある
git format-patch # mbox形式のパッチが作成できる。
メールの送信
- gitのconfigファイルでメールの設定が行える。
git send-email *.patch
パッチの適用
git apply difffile # git diffからマージする
git apply --check difffile マージできるか確認する。
git am patchfile # format-patch形式のパッチを適用する。
git am -3 patchfile # 3方向マージを行う
git am -i -3 atchfile # 対話的にパッチを行える。
cherry-pick
git cherry-pick commit-ssh # 特定のコミットを現在のブランチにマージする
コミットの範囲指定
git log master..my-branch # my-branchから辿れて、masterからは辿れないブランチのログを表示する。
git log origin/master..HEAD # プッシュしようとしているコミットを表示する。
# 次の3つは同じ意味
git log refA..refB
git log ^refA refB
git log revB --not refA
git log master...experiment # どちらからか辿れるコミットが表示される
git log -left-right masterc..branch_name # どちら向きのコミットかを表示する
歴史の改編
※ あまり使わない事を期待して。
- ログを変えるだけなら git commit --amend
- コミットした内容を消したり、変更するにはgit rebase -i HEAD-3みたいな感じ。
サブモジュール
サブモジュールの追加
- submodule addすると、.gitmodulesファイルという設定ファイルが作られる。
git submodule add other-repository # リポジトリ配下に別のリポジトリを含める
git commit # submoduleがaddしたことをコミットする。
サブモジュールを含むリポジトリをcloneする
git clone repository
git submodule init
git submodule update
サブモジュールの内容をリモートからマージする更新する
- git submodule updateを行うと、サブモジュールに変更がなくても、ローカルの変更を断りなく変更する。
- サブモジュールを親プロジェクトから編集する場合は、git checkout -b tempなど別のブランチを作成した方が変更が失われなくて良い。
- 親プロジェクト内のファイルをサブモジュール化するには、手順が必要。
git merge origin/master #submoduleのHEADポインタは変わるけど、ファイルは更新されていない。
git submodule update # これでマージされる。
(※ 作成中)
便利
自動補完
contrib/completionディレクトリにある.git-completion.bashを~/に
コピーすると、少し幸せになれる。
git config --global alias.co checkout # gitの操作にaliasを作成できる。
git config --global alias.xxx '!git xxx' # !で始めると、外部のコマンドを指定できる。
その他
git clone url dir # dirにリポジトリをcloneする