LoginSignup
13
9

More than 5 years have passed since last update.

Githubを使ったチーム開発の備忘録

Last updated at Posted at 2016-06-04

Githubを使ったチーム開発を3ヶ月ほど行ったので、その知見を備忘録的にメモ。

Gitのデータ領域

Gitには3つのデータ領域があり、以下のような関係になっている。
データ領域を理解することはGitの基本。

ワークツリー

ユーザが編集するファイル / ディレクトリのこと。
作業ディレクトリとも呼ばれる。

ステージングエリア

ワークツリーの変更点を登録する一時領域のこと。
インデックスとも呼ばれる。
git addするとここに登録される。

Gitリポジトリ

.gitディレクトリ内に格納されるデータ。
git commitするとここに登録される。

[ワークツリー] - git add -> [ステージングエリア] - git commit -> [Gitリポジトリ]

基本的なコマンドについて軽くおさらい

add

ワークツリーにあるファイルをステージングエリアへと移動させる。
ステージングエリアとは、コミットするための準備領域のようなもの。
ネクストバッターズサークル的な。

rm

ステージングエリアに置いてあるファイルを削除する。

commit

更新内容をリポジトリに登録する。
新しいコミットが生成され、HEADに格納される。

checkout

変更を加えたワークツリーをステージングエリアの状態に戻す。
またはブランチを切り替えるときにも使う。

reset

変更を加えたステージングエリアをGitリポジトリの状態に戻す。
コミット名を指定することで、特定のコミットにまで戻すことも可能。

push

ローカルで変更を加えたGitリポジトリの状態を、リモートリポジトリに反映させる。

merge

git merge {topic名}
  • 早送り(fast forward)できる場合はそうする。できなければ普通のマージをする。
  • ここで、fast forwardの弊害となる以下の点について認識しておかなければならない。
  1. マージに伴う新しいコミットが生成されない。
  2. 従って、「ブランチをマージした」という事実が歴史(コミットグラフ)に残らない
  3. 結果、「ブランチのマージ」を特定しづらく、取り消しづらい。
  • 上記の理由により、通常mergeを行う場合は--no-ffをつけるのが望ましい。これで、fast-forwardは行われず、上記の問題を避けることができる。
git merge --no-ff {topic名}
  • マージをおこなうと、conflictする場合がある。
  • conflictとは、マージを実行したとき「同じファイルの同じ行に違う変更をしていた」ブランチ同士をマージした場合に起きる。
  • コンフリクトが起こった時は、どちらの変更(ブランチ)を採用するかgitはわからないので利用者の判断が必要になる。
  • コンフリクトが起こった場合、gitはコンフリクトが解決するまで処理を停止する。
  • なのでコンフリクトが発生したら、git statusコマンドでマージ失敗したソースコードを確認し、手作業で修正する必要がある。
  • 修正が完了したら、ソースコードをaddして再度ステージングエリアに登録する必要がある。
  • 最後にコミットを実行してコンフリクトは解決。

rebase

  • クセモノ。注意が必要。
  • rebaseで作られたコミットは元のコミットと内容は同じだが、別のコミット(コピー)になる。
  • 元のコミットとは1つ前のコミットが異なる。コミットのコピーを作って、rebase先のブランチに適用するイメージ。
  • 従って、既にpushされているブランチをrebaseするとpushできなくなる。歴史が変わるから。最新コミットの1つ前のコミットが変わっているため、整合性がとれなくなる。
  • git push -f で強制的にpushすることもできるが、これはタブーであり大変なことになるので絶対にやめたほうがいい。
  • コンフリクトが発生した場合、コミットごとにコンフリクト解消しないといけないため面倒。マージだと、どんなにコンフリクトしていても解消は1回のコミットだけで良い。
  • 基本的にローカルにのみ存在するブランチに対してのみrebaseは行うほうが良い。

stash

  • 作業途中にブランチを切り替えたくなった。でもこのタイミングでコミットするのは中途半端・・。そんなときにはstashを使う。
  • stashを使えば現在の作業状態を一時退避させておくことができる。stash popすることで、再度作業状態を復活させることができる。
  • 結構便利でよく使う。

revert

  • git revert {commit}

{commit} (リビジョン)のコミットを取り消すためのコミットを作る

ちなみにresetとは全く挙動が異なる。

  • git reset --hard {commit}

の場合は、{commit}(リビジョン)時点の状態まで 完全に巻き戻す

fetch

リモートリポジトリから最新情報をローカルリポジトリに持ってくる

pull

  • pull = fetch + merge
  • pull --rebase で fetch + rebaseもできる

プルリクとは?

プルリクとは、変更を加えたコードをMasterブランチにマージする前に 別のエンジニアのコードレビューを通してからマージする仕組みのこと。

これによって、 変更に伴うバグを事前に発見しやすく なったり、
関わっているエンジニアが 他のエンジニアが書いたコードの内容もある程度把握しておける ので、
あとからその場所に手を加えることになった場合にもスムーズに入れるなどのメリットがある。

実際のフローとしては一般的に以下の様になっている。

  1. コードに修正を加えるトピック単位で、ローカルに新規ブランチを切る
  2. コードを修正し、コミットする。
  3. 良きタイミングでリモートにpushし、別のエンジニアに変更内容のレビュー依頼を投げる (これがプルリクエスト)
  4. 依頼されたエンジニアは変更内容をチェックし、問題があればフィードバックを、問題がなければOKサインを返す。 (エンジニア界ではLGTM(Looks Good To Me)という単語がよく使われる)
  5. OKサインがもらえるところまでいけたら、変更を加えたエンジニアがマージ作業を行う。

細かいやりとりのルールはプロジェクトによって違うものの、おおまかな流れはだいたい同じ。
プルリクエストの仕組みは業務だけでなく、オープンソースの世界でも広く利用されている。

ちなみにこのプルリクエストはGit自身の機能ではなく、Github社が最初に提供した機能。
オープンソースでコードに改良を加えていくにあたって、コードの品質を高く保ち続けるためにはなくてはならない仕組み。

その他 チーム開発時に気をつける事項

  • 使い終わったブランチは消しておくと吉。Githubの場合だとweb上のUIからボタンクリックで消すことも可能。
$ git branch -d unused_branch
$ git push origin :unused_branch
  • 常にリモートとローカルの状態は同じにしておくことを心がける!

ちなみにこんな方法もあります。ローカルでごにょごにょやってて収集がつかなくなったときは、大人しくリモートと強制同期させましょう。

gitでリモートのブランチにローカルを強制一致させたい時

  • git push -f は絶対ダメ!

参考サイト

13
9
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
13
9