LoginSignup
1
1

More than 3 years have passed since last update.

GitとGitHubの応用

Posted at

Gitの仕組み

Gitは差分ではなくスナップショットとして保存している(高速化が目的)。コミットを辿る事で以前の状態に戻せる

ローカルは3つのエリアに分かれている

ワークツリー(ファイルを変更する作業場)
ステージ(コミットする準備)
リポジトリ(スナップショットを記録)

Gitのデータ構造(データの管理の仕方)

・リポジトリに「圧縮ファイル」「ツリーファイル」「コミットファイル」を作成する事でデータ保存をしている。

Gitではこれらのファイルを「Gitオブジェクト」と呼ぶ。Gitオブジェクトは「.git/objects」ディレクトリの下に保存される。

・コミットが直前のコミットを持つことで変更履歴を辿ることができる
・Gitの本質はデータを圧縮して、スナップショットで保存している
・Gitのコマンドは、そのデータに対して色々な操作をしている

blobオブジェクト(圧縮ファイル)
    ステージングする時に作成されるファイル。
    ファイルの中身を圧縮したもの。実際はハッシュIDで表す。
    圧縮ファイルは構造や名前を持たない

treeオブジェクト(ツリーファイル)
    コミットする時に作成されるファイル。
    ファイル名と圧縮ファイルを組み合わせを保存するもの
    厳密にはツリーファイルの中にツリーファイルが追加されている
    ツリーファイルは圧縮ファイルに構造を与えるためのもの

commitオブジェクト(コミットファイル)
    いつ、誰が、何を、何のために変更したかを記録する
    コミットした時点でのtreeが保存されている
    親コミットを保存している(parnet)
    作成者、日付、メールアドレス、コミットメッセージが記録される

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

$ git init    #.gitディレクトリが作成される

.gitディレクトリの中身
・リポジトリ(圧縮ファイル、ツリーファイル、コミットファイル)
・インデックスファイル
・設定ファイル

他の人が既に作成しているプロジェクトから始める場合(GitHub上のプロジェクト)

1.Gitリポジトリのコピーを作成

    $ git clone リポジトリ名(GitHub上のURL)

    リモートからローカルに複製
        ワークツリー →  ファイルを複製
        リポジトリ → .gitを複製

2.変更をステージに追加する

    $ git add ファイル名
    $ git add ディレクトリ名
    $ git add .

    圧縮ファイルA(リポジトリ)
        index.htmlhファイル内容を圧縮したもの

    インデックス(ステージ)
        index.html
        圧縮ファイルA

3.変更を記録する(コミット)

    $ git commit
    $ git commit -m "メッセージ"
    $ git commit -v        #変更差分を表示できる

コミットメッセージの書き方

        1行目 変更内容の要約
        2行目 空行
        3行目 変更した理由

        変更内容の要点と理由を1行で簡潔に書く

4.現在の変更状況を確認する

    $ git status

    変更途中のファイルなどを間違ってあげないように、どのファイルが変更されたのか確認してからコミットやステージに追加する癖をつける

5.何を変更したのか確認する

    $ git diff     #git add前の差分(ワークツリー⇆ステージ)
    $ git diff ファル名 #個別ファイル
        index.html ⇆ インデックス

    $ git diff --staged #git add後の差分(ステージ⇆リポジトリ)
        インデックス ⇆ ツリー1 + コミット1

    コミットやステージに追加する前にどんな変更したかを確認してから追加する癖をつける

6.変更履歴を確認する

    $ git log
    $ git log --oneline #1行で表示する
    $ git log -p ファイル名 #フィアルの変更差分を表示
    $ git log -n コミット数 #表示するコミット数を指定

    履歴は最新の順から表示する

7.ファイルの削除を記録する

    ワークツリーとリポジトリからも削除
    $ git rm ファイル名     #ファイルごと削除
    $ git rm -r ディレクトリ   #ディレクトリごと削除

    リポジトリのみ削除
    $ git rm --cached ファイル名 #ファイルを残したい時

    元の状態に戻したい
    $ git reset HEAD ファイル名
    $ git checkout ファイル名

8.ファイルの移動/変更を記録する

    $ git mv 旧ファイル名 新ファイル名

9.GitHubにプッシュする(コミットをリモートリポジトリに上げる)

    リモートリポジトリを新規登録
    $ git remote add origin GitHub上のリポジトリ(URL)

    リモtーリポジトリへ送信
    $ git push リモート名 ブランチ名
    $ git push origin master
    $ git push -u origin master  #-u:次回以降git pushのみで送信できるオプション

10.コマンドにエイリアスをつける(コマンドを簡略化する)

    $ git config --global alias.ci commit #ciコマンドに変換
    $ git config --global alias.st status  #stコマンドに変換
    $ git config --global alias.br branch  #brコマンドに変換
    $ git config --global alias.co checkout #coコマンドに変換

    git configは設定を変更するコマンド
    --globalをつけるとP C全体の設定になる
        ~/.gitconfig
        ~/.config/git/config
    --gloabalをつけないと特定のプロジェクトでしか使えない
        今の自分のプロジェクト/.git/config

11.バージョン管理したくないファイルを無視するやり方

    バージョン管理したくないファイル
        パスワードなどの機密情報
        チームの開発で必要のないファイル(自動生成されるファイルやキャッシュなど)

    .gitignoreファイルを作成、記述で指定する
        #から始まる行はコメントとみなされ無視される
        指定したファイルを除外(index.html)
        ルートディレクトリを指定(/root.html)
        ディレクトリ以下を除外(dir/)
        /以外の文字列にマッチ(/*/*.css)

        .gitignoreファイル自体はコミットしても問題ない

12.変更を元に戻す

    ワークツリーのファイルを元の状態に戻す(ワークツリー←ステージ)
    $ git checkout -- ファイル名
    $ git checkout -- ディレクトリ名
    4 git checkout -- .         #全変更を取り消す

        . ファイル全てを指定
        -- ブランチ名とファイル名が被った時に、どちらを指しているかGitがわからなくなるのを避けるために明示する

        ステージの内容をワークツリーと同じにする作業が行われている


    ステージに追加した変更を元に戻す(ステージ←リポジトリ)
    $ git reset HEAD ファイル名
    $ git reset HEAD ディレクトリ名
    $ git reset HEAD .

        ステージの変更を取り消すのみで、ワークツリーには影響を与えない
        内部ではリポジトリから最新のコミット情報を引っ張りステージを上書きする

        HEAD 今いるブランチの最新のコミットを明示する
        reset リセット、上書きすると明示する


    直前のコミットをやり直す
    $ git commit --amend

    注意! リモートリポジトリにpushしたコミットはやり直したらダメ!
    このコマンドの有効範囲はcommitする前のデータであることが条件!

    例)
        リポジトリ(コミットした)
        やり直したい
        ワークツリーで修正
        ステージに追加($ git add)
        直前のコミットを修正($ git commit --amend)

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

    $ git remote  #リモート名を表示
    $ git remote -v #対応するURLを表示

    設定しているリモートリポジトリの情報を表示する

14.リモートリポジトリの新規追加

    $ git remote add リモート名 リモートURL

    リモート名は省略して追加できる

15.リモートから情報を取得する

    $ git fetch リモート名

    リモートリポジトリ → ローカルリポジトリ(remotes/リモート名/ブランチ名)
    ワークツリーには反映されない($ git merge で反映できる)

    備考)
        $ git branch -a
        取得した情報(ブランチ)を確認できる

        $ git checkout remotes/リモート名/ブランチ名
        ブランチ名を指定してワークツリーを切り替える

        $ git merge リモート名/ブランチ名
        統合したいブランチ名に移動してからブランチ名を取得して実行

    git fetchがおすすめ

16.リモートから情報を取得する(pull)

    $ git pull リモート名 ブランチ名
    $ git pull

     リモートリポジトリ → ローカルリポジトリ → ワークツリー

    pullの注意点!
        pullは、現在いるブランチに対してマージまでを一括まで行うコマンド。謝って別のブランチを上書きする危険性がる。

17.リモートの情報を詳しく確認する

    $ git remote show リモート名

    表示される情報
        ・fetchとpushのURL
        ・リモートブランチ
        ・git pullの挙動
        ・git pushの挙動

18.リモートを変更・削除する

    変更
    $ git remote nename 旧リモート名 新リモート名

    削除
    $ git remote rm リモート名

19.ブランチとマージ

ブランチ

並行しながら複数機能を開発するためのもの

ブランチの仕組み
        Gitのデータの持ち方:リポジト → 圧縮ファイルA、ツリー1、コミット1

            コミット → スナップショットを記録している
            スナップショットを時系列順に記録している
            コミットごとに直前の親コミットを記録している

        ブランチとはコミットを指したポインタ
            HEAD = 自分が今作業しているブランチのこと

            ブランチの中身
                最新のコミットIDが格納

            HEADの中身
                ブランチ名を格納

ブランチを新規作成

        $ git branch ブランチ名

ブランチの一覧を表示する

        $ git branch
        $ git branch -a #全てのブランチを表示

ブランチを切り替える

        $ git checkout 既存のブランチ名
        $ git checkout -b 新ブランチ名 #-b: ブランチを新規作成して切り替える

変更履歴をマージする

        $ git merge ブランチ名
        $ git merge リモート名/ブランチ名

マージには3種類ある

            Fast Forward: 早送りになるマージ
            Auto Merge: 基本的なマージ
            コンフリクト:
                同じファイルの同じ行に対して異なる編集を行なった時
                どちらを優先していいかわからない時にコンフリクトが発生する

                例)
                    <<<<<<<<HEAD
                    HEADの変更部分が表示
                    =============
                    別のブランチの変更部分が表示
                    >>>>>>>>>他ブランチ名

コンフリクト関連の事故が起きにくい運用ルール

複数人で同じファイルを変更しない
pullやmergeする前に変更中の状態をなくしておく(commitやstashをする)
pullする時はpullするブランチに移動してからpullする
コンフリクトしても慌てない

    ブランチ名を変更したい
        $ git branch -m ブランチ名

    ブランチを削除したい
        $ git branch -d ブランチ名 #マージされていない変更が残っている場合は削除されない
        $ git branch -D ブランチ名 #強制削除する

    ブランチを利用した開発の流れ
        masterブランチ → リリース用ブランチ
        開発 → トピックブランチを作成して進める

    リモートブランチとは
        リモートのブランチ

GitHubを利用した開発手順

プルリクエスト
    自分の変更したコードをリポジトリに取り込んでもらえるように依頼する機能

プルリクエストの流れ
    ワークツリー → ローカルリポジトリ
        1 masterブランチを最新に更新 ($ git pull リモート名 ブランチ名)
        2 ブランチを作成($ git checkout -b 新ブランチ名)
        3 ファイルを変更($ git add ファイル名)
        4 変更をコミット($ git commit)

    ローカル → リモートリポジトリ(GitHub)
        5 GitHubへプッシュ($ git push リモート名 ブランチ名)
        6 プルリクエストを送る (GitHub上でリクエストを指定)
        7 コードレビューをお願い(GitHub上でコードレビューを指定)
        8 プルリクエストをマージ
        9 ブランチの削除

GitHub Flowの流れ

    GitHub社のワークフロー

    master -> branch -> プルリクエスト ->master…

    1 masterブランチからブランチを作成
    2 ファイルを変更しコミット
    3 同名のブランチをGitHubへプッシュ

    4 プルリクエストを送る
    5 コードレビューしmasterブランチにマージ
    6 masterブランチをデプロイ

GitHub Flowを実践する上でのポイント( 開発フローをシンプルに保ちたい)

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

リベースで変更履歴を修正する

リベースとは

変更を統合する際に、履歴(分岐)を綺麗に整えるために使うもの。

    $ git rebase ブランチ名

        ブランチの起点となるコミットを別のコミットに移動する

マージとの違い

        リベース: 分岐したコミットを残さずにポインタごと移動する
        マージ: 分岐したコミットを残したまま新コミットを生成

リベースの注意点

GitHubにプッシュしたコミットをリベースするのはNG!
強制的に上書きしてしまう$git push -fはもちろん絶対NG!

マージかリベースかの考え方

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

        結論:作業の履歴を残したい時はマージ

    リベース
        メリット:履歴をきれいに保つことができる
        デメリット:コンフリクトの解決が若干面倒(各コミットに解消が必要)

        結論:履歴をきれいにしたい場合はリベース

    結論
        プッシュしていないローカルの変更 →  リベース
        プッシュしているローカルの変更 → マージ
        コンフリクトしそう(チーム開発やプルリクエストで判断) → マージ

プルの設定をリベースに変更する

    プルのマージ型
        $ git pull リモート名 ブランチ名

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

    プルのリベース型
        $ git pull --rebase リモート名 ブランチ名

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

リベースで変更履歴を修正する

コミットをきれいに整えてからPushしたい時は履歴を書き換える
※GitHubni Pushしていないコミットに限られる

    直前のコミットをやり直す
        $ git commit --amend
        リモートリポジトリにPushしたコミットはやり直したらダメ!

    複数のコミットをやり直す
        ①-I によって対話的リベースモードになる
            $ git rebase -i コミットID
            $ git rebase -i HEAD~3

                HEAD = 最新のコミット
                HEAD~1 = HEAD^2 = HEADの親コミット

                #表示(HEAD~3までを指定部分)
                    pick gh21f6d ヘッダー修正
                    pick 193054e ファイル追加
                    pick 84gha0d README修正

                        コミットエディッターで表示される
                        履歴は古い順に表示される

        ②やり直したいcommitをeditする
            edit gh21f6d ヘッダー修正

        ③やり直しを実行
        $ git commit --amend

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


    コミットを並び替える、削除する
        $ git rebase -i HEAD~3

            #表示
                pick gh21f6d ヘッダー修正
                pick 193054e ファイル追加
                pick 84gha0d README修正


        コミットエディッタ
            ①84gha0dのコミット(行)を消す
            ②193054eを先に適用する(手動)

    コミットをまとめる
        $ git rebase -I HEAD~3

        コミットエディッタ
            squash 193054e ファイル追加
            squash 84gha0d README修正

    コミットを分割
        $ git rebase -I HEAD~3

            #表示
                pick gh21f6d ヘッダー修正
                pick 193054e ファイル追加
                edit 84gha0d 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 "201705" #パターンを指定してタグを表示

    コミットを参照し易くするためのもの。わかりやすい名前をつけるのがタグ。
    リリースポイントに使う。

タグを作成する

    注釈付き版(annotated)
    $ git tag -a タグ名 -m "メッセージ"

        -aオプション:注釈付き
        名前、コメント、署名をつけられる

    軽量版(lightweight)
    $ git tag タグ名
    $ git tag タグ名 コミット名 #後からタグをつける

        名前のみつけられる

タグのデータ表示する

    $ git show タグ名

    タグのデータと関連づけられたコミットを表示する

    #表示
        タグ付けした人の情報
        タグ付けした日時
        注釈メッセージ
        コミット

タグをリモートリポジトリに送信するやり方

    $ git push リモート名 タグ名
    $ git push リモート名 --tags #タグを一斉送信する

    --tagsオプション:ローカルにあってリモートに存在しないタグを送信する

作業を一時避難する

    作業が途中でコミットしたくないけど、別のブランチで作業しないといけない時に使う。

    $ git stash
    $ git stash save

    stashという場所に一時保管する。

一時避難した作業を確認する

    $ git stash list

非難した作業を復元する

    $ git stash apply    #最新の作業を復元する
    $ git stash apply --index #ステージの状況も復元する

    $git stash apply スタッシュ名 #特定の作業を復元する
        スタッシュ名はgit stash listで確認できる

一時避難した行を削除する

    $ git stash drop #最新の作業を削除する
    $ git stash drop スタッシュ名 #特定の作業を削除する
    $ git stash clear #全作業を削除する

参考元
もう怖くないGit!チーム開発で必要なGitを完全マスター/山浦清透

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1