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 の基礎

  • 1,462