Git の基礎

産業第1事業部

鈴木真吾

Git とは

バージョン管理システムの 1 つ

特徴として

  • 分散型
  • すぐれたマージと軽量なブランチ
  • コア機能と分離されたスクリプト群

すぐれたマージと軽量なブランチ

Git では差分でなくスナップショットを管理

やっていることは追記型のファイルシステムに近い

  • = ファイルの削除はほとんどない
  • ファイルの追跡をしてない
  • ブランチの作成が高速にすむ
  •  

分散型

<=> 中央集権型 (ex: subversion etc)

  • マスターが存在せず、開発者同士で版の共有が可能
    • マスターが死んでいても開発は続けられる
    • 実際の運用は中央集権的

Git と他のバージョン管理システムとの違い

  • Subversion
    • 中央集権的なバージョン管理システム
    • ファイルの変更が追跡可能
    • ブランチ操作が重い
    • マージが地獄
  • Mercurial
    • 分散バージョン管理システム
    • 版が整数で管理される
    • ファイルの変更が追跡可能

コア機能と分離されたスクリプト群

  • git のツールはコアになる少数のコマンドと、それを組み合わせたスクリプトからできている
  • 拡張が簡単
    • git-* というスクリプトにパスを通すだけでサブコマンドを追加できる

Git を使った開発の流れの例

  1. リポジトリをクローンする
  2. 作業内容に応じてブランチを作る
  3. 作業を行なってコミットする
  4. 作業内容が完成したらブランチをプッシュして共有する
  5. ブランチをマージする
  6. リポジトリ側の変更を手元に取り込む
  7.  2. に戻る

git clone

リポジトリのクローン

  • github など外部にあるリポジトリをコピーすること
    • 外部のリポジトリはリモート
    • 手元マシン内のリポジトリはローカル
$ git clone https://github.com/30-seconds/30-seconds-of-code.git
Cloning into '30-seconds-of-code'...
remote: Enumerating objects: 36, done.
remote: Counting objects: 100% (36/36), done.
remote: Compressing objects: 100% (30/30), done.
remote: Total 29355 (delta 10), reused 27 (delta 6), pack-reused 29319
Receiving objects: 100% (29355/29355), 14.61 MiB | 2.76 MiB/s, done.
Resolving deltas: 100% (18497/18497), done.
$ cd 30-seconds-of-code/
$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean
$ git branch
* master
$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/fix-module-generation
  remotes/origin/glossary-String-clarification-of-instance
  remotes/origin/is-negative-zero
  remotes/origin/master

git branch

ブランチとは、開発の本流から分岐し、本流の開発を邪魔することなく作業を続ける機能のことです

(引用: https://git-scm.com/book/ja/v2/Git-のブランチ機能-ブランチとは)

  • ブランチを作れば、色々修正してもすぐ戻せるということ

 

$ git branch new-branch
$ git branch
* master
  new-branch
$ git  checkout new-branch
Switched to branch 'new-branch'

git add

コミットする修正を選択する

  • git add で指定されたファイル、修正はステージングエリアに入る(ステージング)
  • コミットしたくない場合は git reset HEAD ファイル名でステージングの取り消しができる
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        test.txt

nothing added to commit but untracked files present (use "git add" to track)
$ git add test.txt
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   test.txt

git commit

変更を取り入れてブランチを更新する

  • これで Git に作業内容が保存される
$ git commit -m "Add some files"
[master 07282e2] Add some files
 1 file changed, 1 insertion(+)
 create mode 100644 test.txt

良いコミットをつくろう

過去のコミットは度々見返すことになる

  • レビュー
  • 過去の作業内容の確認

分かりやすい・検索しやすいコミットにする

  • プロジェクト管理システムの issue 番号
  • コミット粒度
    • 流儀は様々
    • プロジェクトで方針があれば揃える

コミット粒度の例

  • 単体テストが通ったらコミット
  • チケット・イシュー単位でコミット
  • 作業量が多かったらとりあえずコミット
  • TODO リストの項目ごとにコミット
  • 草を生やしたいのでとりあえずコミット

git push

ローカルの変更をリモートに反映する

  • デフォルトでは「上流ブランチ」に変更が反映される
    • 大抵の場合はローカルブランチと同名
  • 「上流ブランチ」
    • ローカルのブランチに全ての変更を取り込む前提のリモートブランチ
$ git push origin master
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 484 bytes | 484.00 KiB/s, done.
Total 4 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
To github.com:shingo-s/myrepository.git
   a1e20c0d..9e0ed125  mybranch -> mybranch

git fetch, git merge, git pull

リモート追跡ブランチの変更をローカルに取り込む

$ git merge origin/master
Updating b12fe535..f6f7ec2c
Fast-forward
 README      | 17 +++++++++++++++--
 1 files changed, 17 insertions(+), 2 deletions(-)

リモートの変更を「リモート追跡ブランチ」に取り込む

$ git fetch origin
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (1/1), done.
From github.com:shingo-s/myrepository
   b12fe535..f6f7ec2c  master     -> origin/master

git pull = git fetch + git merge

  • git pull だと merge が走ることがある

git merge

fast foward できない

かつ

fast forward しない

git merge

fast foward できる

fast forward しない

git merge

fast foward できる

かつ

fast forward する

git merge

--no-ff と --ff の違い

  • --ff = fastfoward するとブランチの情報が消えてしまう
    • ブランチ名をプロジェクト管理に使っている場合は注意
  • --no-ff = fastfoward しないと必要ない場合でもマージコミットが作られる 

その他のトピック

  • git のカスタマイズ
  • ブランチ戦略
  • リポジトリの分割

git のカスタマイズ

[user]
    name = Shingo Suzuki
    email = hogehoge@hoge.com
[alias]
    st = status
    ci = commit
    co = checkout
    b = branch
    stt = status -uno
    difff = diff --word-diff
[merge]
    ff = false
[pull]
    rebase = true
[push]
    default = current
[diff "wordx"]
    textconv = docx2txt.sh
[http]
    sslverify = false
    proxy = http://my.proxy.co.jp:8888/

alias など設定しておくと良い

git の設定(社内向け)

machine xxxx.co.jp
login shingo-s
password mypassword

なぜか ssh で繋げられない

どうしてもパスワード打ちたくない場合は .netrc に書く

平文なので当然非推奨

ブランチ戦略

git ではブランチ作成が簡単になったので

  • ブランチが乱立することになりやすい
  • ブランチのさらに孫ブランチなど作ると管理しずらい

 

ブランチの命名規則などを決めておくと良い

 

よく見るブランチ戦略

  • git flow
  • Github flow
  • Gitlab flow

git flow

git flow で使うブランチ

  • master
  • development
  • feature/*
  • hotfix/*

リポジトリの分割

まず安易に分割しない。分割する場合:

  • 疎結合にする
  • API 固まってからにする

方法としては:

  • git submodule を使う
  • プログラミング言語側のツールを使う
    • リポジトリを分け、外部のライブラリとして参照する
      • これぐらい疎結合にしておいたほうがよさそう
    • 最近の依存解決ツールは大抵 github に対応している

参考資料

  • https://git-scm.com/book/ja/v2
    • 公式のドキュメント

Git の基礎

By Shingo Suzuki

Git の基礎

  • 823