Skip to content

git 操作#

git について#

Git は、プログラムのソースコードなどの変更履歴を記録・追跡するための分散型バージョン管理システムです。

Git はスナップショットを記録します。(差分のあるファイルはデータをまるごと保存) なぜスナップショットで記録するのかというとブランチを切ったり、マージしたりする際に、 差分で記録している場合に、差分を再計算が必要となる。スナップショットだと再計算の必要がなく、 複数人による開発が早くなるため。

commit (変更履歴の記録) 手順#


graph LR
    ワークツリー --> |git add| ステージ
    ステージ --> |git commit| リポジトリ
  • ワークツリー:ファイルを変更する作業場(ディレクトリ)
  • ステージ:コミットする変更を準備する場
  • リポジトリ:スナップショットを記録する場

Git のデータ構造まとめ#

  • リポジトリに「圧縮ファイル」「ツリー」「コミット」ファイルを作成することでデータを保存している
  • コミットが親子ミットを持つことで変更履歴を辿ることができる
  • Gitの本質はデータを圧縮して、スナップショットで記録していること
  • Git のコマンドは、そのデータに対していろいろな操作をしている

リポジトリの作成#

ローカルリポジトリの新規作成#

  • git init

  • git init を実行するとカレントディレクトリに.gitディレクトリが作成されます。

.git/ の中身
$ ls .git/
HEAD  config  description  hooks/  info/  objects/  refs/

commit#

コミットメッセージ#

  • git commit -m "[commit message]" にて一行で記述できる
  • -m オプションを付けない場合は、編集画面に移行する。
  • 変更内容の要点理由を1行で簡潔に
  • 正式に書くとき
    • 1行目:変更内容の要約
    • 2行目:空行
    • 3行目:変更した理由

status / diff#

  • git status:ステージの状態を表示
  • git diff:ワークツリーとステージの間のdiff を表示
  • git diff --staged:ステージとコミットの間の変更差分を表示

変更履歴を確認する#

  • git log
  • git log --online:1行で表示する
  • git log -p [ファイル名]:ファイルの変更差分を表示する
  • git log -n [コミット数]:表示するコミット数を制限する

ファイルの削除#

  • git rm [ファイル名]
  • git rm -r [ディレクトリ名]
  • git rm --cached <ファイル名>:(git の記録を削除)ファイル自体は残したいとき

ファイルの移動(ファイル名の変更)を記録する#

  • git mv [旧ファイル] [新ファイル]

Tip

以下と同じ * mv <旧ファイル> <新ファイル> * git rm <旧ファイル> * git add <新ファイル>

リモートリポジトリ(Github)を新規追加する#

git remote add origin https://github.com/user/repo.git

origin というエイリアスでurlのリモートリポジトリを登録。 エイリアス指定で、2度目以降のremote リポジトリの指定がoriginで済む

Tip

github のリポジトリのことをoriginとつける慣習がある

リモートリポジトリ(Github)へ送信する#

  • 構文:git push [リモート名] [ブランチ名>]
  • 例:git push origin master

alias の作成#

  • git config --global alias.ci commit
  • git config --global alias.st status
  • git config --global alias.br branch
  • git config --global alias.co checkout

Gitの管理から外す#

.gitignore ファイルを作成し、指定する

書き方

  • # から始まる行はコメント

  • 指定したファイルを除外 (例) index.html

  • ルートディレクトリを指定 (例) /root.html

  • ディレクトリ以下を除外 dir/

  • /以外の文字列にマッチ「」 //.css

ワークツリーのファイルを元の状態に戻す#

(ワークツリーでの編集を元に戻す)

  • ファイルへの変更を取り消す git checkout --<ファイル名>
    git checkout --<ディレクトリ名>

  • 全変更を取り消す git checkout --

Tip

ワークツリーの状態をステージの状態へ戻している
-- をつけているのはブランチ名とファイル名が被ったときにわかるようにするため。

ステージした変更を取り消す#

  • 直前にステージした変更を取り消す git reset HEAD <ファイル名>
    git reset HEAD <ディレクトリ名>

  • 全変更を取り消す git reset HEAD

Tip

指定した変更をステージから取り消すだけなので、ワークツリーのファイルには影響を与えない

直前のコミットを取り消す(remote リポジトリにpushする前)#

git commit --amend

  • 使用例
    git add 
    git commit -amend
    

Tip

変更するというより、上書きするイメージ

Warning

リモートリポジトリにPushしたコミットをやり直すのはNG
リモートリポジトリの履歴の状態と他の人がcloneしたリポジトリの履歴に差分が生じ、他の人がPushすることができないため。

リモートの情報を確認する#

git remote  

#対応するURLを表示  
git remote -v  

リモートリポジトリを登録する#

Tip

リモートリポジトリは複数登録することができる

git remote add <リモート名> <リモートURL>
(例)
git remote add tutorial https://github.com/user/repo.git

リモートから情報を取得する(フェッチ)#

git fetch <リモート名> (例) git fetch origin
git branch -a にて確認

Warning

リモートリポジトリからローカルリポジトリへ情報を取得してくる 手元のワークツリーへは反映されない。反映するにはgit mergeコマンドを使用する

リモートから情報を取得する(プル)#

git pull <リモート名> <ブランチ名> (例) git pull origin master

Tip

git pull コマンドは git fetch した後に git merge しているのと同じことです

fetch と pull の使い分け#

フェッチを基本的に使うことがおすすめ
master branch にいて何も変更がない場合にプルを使用するなどの運用方法がおすすめ。

Warning

プルは挙動が特殊。カレントディレクトリが取得して来るブランチと異なる場合、意図したブランチと異なるブランチにマージされるため危険。

リモートの詳細情報を表示する#

git remote show <リモート名> (例) git remote show origin

ブランチとマージ#

  • 並行して複数機能を開発するためにあるのがブランチ
  • コミットはスナップショット、それが時系列順に連なる
  • ブランチはコミットファイルを指したポインタ(≒シムリンク)
  • コミットしたらブランチが指すコミットファイルが変わる→並行して開発が可能
  • ブランチはコミットIDを記録したポインタ
  • HEADは現在作業中のブランチへのポインタ

【要約】

  • 分岐することで複数の機能を同時並行で開発するための仕組みがブランチ
  • ブランチとはコミットを刺すポインタ
    (スナップショットによる記録と相まって)
  • Git はブランチの作成や切り替え、マージが他のバージョン管理ツールより高速

ブランチを新規追加する#

  • git branch <ブランチ名>

(例) * git branch feature

Warning

ブランチの切り替えまでは行われない点に注意

Tip

ブランチの一覧を表示

* git branch     * git branch -a

Info

git log --online --decorate

ブランチを切り替える#

git checkout <既存ブランチ名>
(例)
git checkout faature

Tip

ブランチを新規作成して切り替える git checkout -b <新ブランチ名>

変更履歴をマージする#

他のブランチでの変更履歴を取り込む。 featureブランチの内容をmasterブランチに取り込みたいとき、HEADはmasterでgit mergeコマンドを実行する

  • FastFoward : 早送りになるマージ(ex. hotfix)  ブランチが枝分かれしなかったときはブランチのポインタを前に進めるだけ

  • Auto Merge : 基本的なマージ(ex. feature) 枝分かれして開発していた場合、マージコミットという新しいコミットを作る

git merge <ブランチ名>
git merge <リモート名/ブランチ名>
(例)
git merge origin/master

コンフリクト#

同じファイルの同じ行に対し異なる編集を行う(コンフリクト)

コンフリクトの解決方法#

コンフリクトの事故が起きにくいルール#

  • 複数人で同じファイルを変更しない
  • pull やmerge する前に変更中の状態をなくしておく(commitやstashをしておく)
  • pullするときは、pullするブランチに移動してからpull する

ブランチ名を変更#

git branch -m <ブランチ名>
(例)
git branch -m new_branch

自分が変更しているブランチの名前を変更(-m はmoveの略)

ブランチ名を削除#

git branch -d <ブランチ名> (例) git branch -d feature * -d はdelete の略。master にマージされていない変更が残っている場合削除しない仕組み
* 強制削除は git branch -D <ブランチ名> にて行う

ブランチを利用した開発の流れ#

master ブランチをリリース用ブランチに、開発はトピックブランチを作成して進めるのが基本。

リモートブランチ#

リモートブランチとはリモートのブランチの状態へのポインタ

Githubを利用した開発手順#

プルリクエスト#

プルリクエストは自分の変更したコードをリポジトリに取り込んでもらえるよう依頼する機能 (レビューによるコードの質の担保のため)

  1. master ブランチを最新に更新 (ex.) git pull origin maseter
  2. ブランチを作成 (ex.) git chekout -b pull_request
  3. ファイルを変更 (ワークツリーでファイルの編集)
  4. 変更をローカルリポジトリにコミット (ex.) git add → git commit
  5. Github(リモートリポジトリ)にプッシュ (ex.) git push origin pull_request
  6. プルリクエストを送る (github上の Pull request タブから実施)
  7. コードレビュー
  8. プルリクエストをマージ
  9. ブランチを削除

Github Flow の流れ#

Github FlowとはGithub社のワークフローのこと。

  1. master ブランチからブランチ作成
  2. ファイルを変更し、ローカルリポジトリへコミット
  3. 同名のブランチをGitHubへプッシュ
  4. プルリクエストを送る(リモートリポジトリ)
  5. コードレビューし、master ブランチにマージ(リモートリポジトリ)
  6. master ブランチをデプロイ

Tip

  • master ブランチは常にデプロイできる状態に保つ
  • 新開発はmaster ブランチから新しいブランチを作成してスタート
  • 作成したブランチ上で作業し、コミットする
  • 定期的にpush する
  • master にマージするためにプルリクエストを使う
  • 必ずレビューを受ける
  • master ブランチにマージしたらすぐにデプロイする(テストとデプロイ作業は自動化)

リベース#

変更を統合する際に、履歴をきれいに整えるために使うのがリベース

  • ブランチの基点となるコミットを別のコミットに移動する git rebase <ブランチ名>

一連の流れ(FastFoward) * git checkout feature * git rebase master * git checkout master * git merge feature

Tip

git config --global merge.ff false

Warning

GitHubにプッシュしたコミットをリベースしないこと(絶対NG) リモートリポジトリとローカルリポジトリ間のコミット履歴が矛盾し、push できなくなるため   (git push -f で強制的に可能だが、履歴が壊れるためこちらもNG)

マージとリベースの使い分け#

マージ#

  • コンフリクトの解決が比較的簡単
  • マージコミットがたくさんあると履歴が複雑化する

Tip

作業履歴を残したい場合はマージ

リベース#

  • 履歴をきれいに保つことができる
  • コンフリクトの解決が若干面倒

Tip

作業履歴をきれいにしたい場合はリベース

プッシュしていないローカルの変更にはリベースを使い、プッシュした後はマージを使う。 コンフリクトしそうならマージを使うルールがおすすめ。

プルのマージ型#

  • git pull <リモート名> <ブランチ名>
  • (例) git pull origin master

Tip

マージコミットが残るから、マージしたという記録を残したい場合に使う

プルのリベース型#

  • git pull --rebase <リモート名> <ブランチ名>
  • (例) git pull --rebase origin master

Tip

マージコミットが残らないから、GitHubの内容を取得したいだけの時は--rebaseを使うのがおすすめ

プルをリベース型に設定する(--rebaseを付けなくともgit pull の挙動がリベース型になる)#

git config --global pull.rebase true

Master

git config branch.master.rebase true

複数のコミットをやり直す#

git rebase -i <コミットID> (例) 1. git rebase -i HEAD~3

  1. やり直したいcommit をedit する
    edit xxxx ヘッダー修正
    pick yyyy ファイル追加
    pick zzzz READEME修正

  2. やり直したら以下実行 git commit --amend

  3. 次のコミットへ進む(リベース完了) git rebase --continue

Tip

HEAD~ (1番目の親を指定する。HEADを基点にして数値分の親コミットまで指定する)
HEAD^ (マージした場合の2番目の親を指定する)

rebase -i コマンドの一連の流れ#

  1. git rebase -i コマンドで対話的リベースモードに入る
  2. 修正したいコミットをedit にしてコミットエディタを終了する
  3. edit コミットのところでコミットの適用が止まる
  4. git commit --amend コマンドで修正
  5. git rebase--continue で次のコミットへ行く
  6. pickだとそのままのコミット内容を適用して次へ行く

コミットを並び替える、削除する#

git rebase -i <コミットID> 後に削除、順番を入れ替えればOK

コミットをまとめる#

git rebase -i <コミットID> 後にpickの部分をsquash指定

コミットを分割する#

(例)

git rebase -i HEAD~3

pick xxxx ヘッダー修正
pick yyyy ファイル追加
pick zzzz READMEとindex修正
pick xxxx ヘッダー修正
pick yyyy ファイル追加
edit zzzz READMEとindex修正

$ git reset HEAD^
$ git add README
$ git commit -m 'README修正'
$ git add index.html
$ git commit -m 'index.html修正'
$ git rebase --continue

タグ一覧を表示する#

git tag

パターンを指定してタグを表示
git tag -l "文字列"

タグを作成する#

注釈付きタグ(anotated)
git tag -a [タグ名] -m "メッセージ"


軽量版タグ
git tag [タグ名]

後からタグ付け
git tag [タグ名] [コミット名]

Note

基本的には注釈つきタグで

タグのデータを表示する#

git show [タグ名]

タグをリモートリポジトリに送信する#

git push [リモート名] [タグ名]

タグを一斉に送信する#

git push [リモート名] --tags

作業を一時避難する#

git stash

避難させた作業を確認する#

git stash list

避難させた作業を復元#

# 最新の作業を復元する
git stash apply

# ステージの状況も復元する
git stash apply --index

# 特定の作業を復元する
git stash apply [スタッシュ名もしくは番号]
(例)
git stash apply stash@{1}

一時避難した作業を削除する#

最新の作業を削除する
git stash drop

特定の作業を削除する
git stash drop [スタッシュ名もしくは番号]

全作業を削除する
git stash clear