Skip to content
pastak edited this page Dec 24, 2014 · 8 revisions

Gitハンズオン

はじめに

  • この資料はhatena/Git-for-Designers (commit: 10ba798c1cb3ad77d936e4e4646ca3eb9e371164) をベースに作成しています。

目次

  1. Gitについて・GitHubについて
  2. 環境構築
  3. 実際に使ってみる
  4. Gitについてのちゃんとした説明
  • 元資料に載ってたのそのまま

はじめてのGit

Git とは

  • バージョン管理システムです (ミスった変更を取り消したり、ブランチを分けて並行して開発ができます)
  • 変更したファイルをサーバに反映するのも Git 経由でおこないます

Before

  • Backup.zip
  • Backup_20140129/
  • Backup_001
  • 新しいフォルダ(3)

Gitの仕組み

  • ファイルの差分を記録
  • 1つ前の状態と1対1 (ブランチがあれば1対多で対応)で木構造になる
    • いつでも親は1つ
    • 絶対にrootまで遡れる

概念図

      ∧_∧            ∧_∧
    ( ´∀`) ―push→   ( ・∀・)
    (    ) ←pull―  .(    )
     | | |        .| | |
    (__)_)        (__)_)

用語集

repository

  • 作業用ワークスペースのようなもの
  • プロジェクトごととかに作る
  • 基本的にはこれを1つの単位として管理する

branch

  • repositoryの木構造を分岐させて切り分ける
  • 1つの状態から複数に分岐させて名前を付けたり
  • 詳しい運用は後述

GitHubとは

Gitをさらに便利にするためのWebサービス。 レポジトリの状態をブラウザで見たり、色々できる。

コラボレーションツールとしてのGit・GitHub

  • issueの管理、アサイン、議論
  • Wikiドキュメントの管理
  • Merge Requestによるコードレビュー
  • スニペット(コード断片)の共有
  • 人の書いてるコードの覗き見

最初に!

Git のバージョンをチェック

% git --version
git version 1.7.2.1.6.g61bf12

バージョン番号が 1.6.5.3 より以前の場合や、そもそもGitが無い時はインストールしましょう。

Gitの環境を整える

Debian / Ubuntu

% apt-get install git

CentOS

% yum install git-core

Mac OS X

% brew install git

Gitの環境を整える(2) Windows

Gitの設定をする

ユーザー名とメールアドレスを設定する

ユーザー名とメールアドレスを設定します。 (これは表示のためのもので、自由な値を設定して構いません。)

git config --global を使用して設定を行うことで、設定値がユーザーのホームディレクトリの ~/.gitconfig ファイルに書き込まれます。 (see: git-config(1) Manual Page)

git config --global user.name "Echizen Taro"
git config --global user.email "gituser@example.com"

便利な設定をしておく

以下をコピペして PowerShellの画面に流してください。Git 生活を快適にします。 一気に流しても大丈夫です。また、既に設定している人が実行しても問題ありません。

  git config --global color.diff   auto
  git config --global color.status auto
  git config --global color.branch auto
  git config --global color.grep   auto

  git config --global core.excludesfile $HOME/.gitignore
  git config --global push.default current

  git config --global alias.st   status
  git config --global alias.co   checkout
  git config --global alias.ci   commit\ -v
  git config --global alias.di   diff
  git config --global alias.br   branch
  git config --global alias.puhs push
  git config --global alias.psuh push
  git config --global alias.pus  push
  git config --global alias.puh  push
  git config --global alias.pl   '!git pull && git submodule update --init'

  echo .DS_Store >> $HOME/.gitignore
  echo Thumbs.db >> $HOME/.gitignore

GitHubにアカウントを設定しよう

ユーザー登録

https://github.com/join

GitHubについて

  • 画面構成
  • Follow
  • プロジェクトを作る
    • clone
    • fork
  • pull request
  • issue
  • wiki

最低限のワークフロー

  1. リポジトリをクローン: git clone
  2. 他人の変更を取得: git pull
  3. ファイルを変更/追加: git add
  4. 変更をコミット: git commit
  5. コミットを送信: git push
  6. 2 へ

以下は適宜

  • 作業の合間合間に: git status
  • ブランチを切り替える: git checkout
  • ブランチを取り込む: git merge

実際にやってみよう

まずはGitHub上のトレーニングツールで

手元の環境でやってみよう

やることメモ

git clone (最初の 1 回だけ)

(必要なら、いつもの作業場所のひとつ上に移動する)

% cd ..

中央のリポジトリをクローンしてきます

% git clone git@repository01:/var/git/projects/Project.git

クローン用のアドレスはGitLabのプロジェクトページからコピペします。

git pull (最新の変更を取得する)

他の人が行った変更を手元にも反映します。

% git pull

手元のファイルがブランチの最新の状態になります。

共用のブランチで作業する場合は作業開始前にgit pullするようにしましょう。

pull = fetch + merge

pull 時のトラブル

error: Your local changes to 'templates/index.html' would be overwritten by merge.  Aborting.
Please, commit your changes or stash them before you can merge.

上のようなメッセージが出た場合は、pull で更新されるファイルが手元で修正されていて、まだコミットされていません。変更をコミットしてからもう一度 git pull しなおして下さい。

Auto-merging templates/index.html
CONFLICT (content): Merge conflict in templates/index.html
Automatic merge failed; fix conflicts and then commit the result.

上のようなメッセージが出た場合は、他の人が行った変更と手元でコミットした内容がコンフリクトしています。量が多すぎる、訳がわからない、修正できるか自信がない場合は、以下のコマンドを実行して中止し、エンジニアに尋ねてください。

% git reset --hard

git checkout (ブランチを切り替える/作成する)

同じリポジトリで複数のブランチを並行して開発できるのが git の便利な点です。常に master ブランチが本番に反映されます。開発は master 以外のブランチで行い、適宜 master にマージして反映、というのが開発の流れです。開発中は複数のブランチを渡り歩くことになるかもしれません。

作業ブランチを切り替えたい

% git checkout branch-name

ブランチ名を指定して git checkout コマンドを呼びます。

新しい機能の開発などで、他の人が push したブランチが手元にまだ出来ていない場合は

% git checkout -t origin/branch-name

とします。

ブランチを作成する

% git checkout -b branch-name

とします。(git branch branch-nameでも可能です。)

ブランチの一覧を見る

% git branch

リモートにあるブランチを全部取得する。

% git fetch

git add (コミットするファイルを追加する)

ファイルの変更をコミットするには、一度 git add してコミット可能な状態にする必要があります。

% git add templates/index.html

ディレクトリ名を指定することで、ディレクトリ以下の全ての変更を Git に通知します。

% git add static/images

変更を小分けにしてaddしたい時とかに便利

% git add -p

横着で神経質な私とあなたに贈るgit add -p - Qiita

git add は通常何の出力も返さないので、次の項でふれる git status で状態を確認してください。

git status (作業状況を確認する)

現在の作業状況を確認するには、git status というコマンドを使います。英語のメッセージですが、読んで下さい。一行一行に意味があります。

% git status

まっさらな状態では、以下のような出力になります。

# On branch master
nothing to commit (working directory clean)

1 行目はいま自分が "master" ブランチにいることを、2 行目はファイルやディレクトリに何の変更も加わっていないことを表しています。

master ブランチで作業中に新しいファイル static/images/hoge.gif をつくったときは、以下のような出力になります。

# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       static/images/hoge.gif

リポジトリに入っておらずバージョン管理されないファイルとして、static/images/hoge.gif がリストされています。3 行目の指示を見れば、これをコミットに含めるには git add すればよいということが分かるようになっています。

すでにリポジトリに含まれているファイルを変更した場合は、以下のような出力になります。

# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   static/images/spacer.gif
#
no changes added to commit (use "git add" and/or "git commit -a")

編集したけれどその変更が Git に伝わっていないファイルとして、static/images/spacer.gif がリストされています。先ほどと同じ 3 行目の指示に加え 4 行目にも指示がありますがまあ試してみてください (変更が元に戻ります)。最後の行は、今のままではコミットするものがないので git add してくださいといっています。(git commit -a を使うのはあまりオススメしません。見なかったことにしてください)

git add static/images/spacer.gif などで変更を Git に通知してやると、git status の結果は以下のようになります。

% git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   static/images/spacer.gif
#

コミットされる予定のファイルがリストされています。

これらの出力は組み合わさって表示されることもあります。

% git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   static/images/spacer.gif
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   static/images/logo_header.gif
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       i18n/a

git commit (コミットする)

git add された変更をまとめてコミットします。git add されていないファイルはコミットに含まれないので、新しい画像を追加したときなどは注意してください。

% git commit

エディタが立ち上がります。適当にコミットメッセージを書いて保存し、エディタを終了させてください。

[master 7196d3f] 文言修正
1 files changed, 1 insertions(+), 0 deletions(-)

こんなメッセージが出たらコミット完了。

%git commit -m"文言修正"

としてコミットメッセージを記述することも出来ます。(日本語を使用する場合は設定などに注意してください。

コミットメッセージについて

git push (変更をサーバに送る)

変更を中央のリポジトリに送信します。 push したつもりがエラーが出て push できていないこともあるので、コマンドの結果に注意してください。

% git push

Counting objects: 24, done.
Compressing objects: 100% (13/13), done.
Writing objects: 100% (13/13), 1.58 KiB, done.
Total 13 (delta 10), reused 0 (delta 0)
To git@repository01:/var/git/projects/Project
   1ede18e..c6fa4c4  HEAD -> master

以下のように出たときは push に失敗しています!他の人が同じブランチに先に push していた場合、この表示になります。一度 pull してから push しなおしてみて下さい。

% git push
To git@repository01:/var/git/projects/Project
! [rejected]        HEAD -> master (non-fast-forward)
error: failed to push some refs to 'git@repository01:/var/git/projects/Project'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the 'Note about
fast-forwards' section of 'git push --help' for details.

git merge(ブランチを取り込む)

bugfixブランチをdevelopブランチに取り込む

1. 取り込み先のブランチに移動

% git checkout develop

2. ブランチを取り込む

% git merge bugfix
  • あとで図解します。
  • コンフリクトした時は解消する(後述)

こんな時は/プラスアルファ

以下はそれほど覚える必要がないものです。

変更履歴がみたい

git log --stat

コンフリクトの解消

git pullgit merge でコンフリクトが発生し、自分の手で解決したい場合。 git status すると、コンフリクトしたファイルが赤く表示されます。

% git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 1 and 3 different commit(s) each, respectively.
#
# Changes to be committed:
#
#       modified:   templates/guide.html
#
# Unmerged paths:
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#       both modified:      templates/index.html
#

この場合 templates/index.html がコンフリクトしているようです。

コンフリクトしたとされるファイルをエディタで開いてください。"<<<<<<<" と ">>>>>>>" に囲まれた部分がコンフリクトしています。

<<<<<<< HEAD
  <div class="container">
=======
  <div>[% IF foobar %]
>>>>>>> 3100b66ffb26bb8b876cb47d68d2b91b4ec17f7f

"=======" を挟んで "HEAD" とある側が自分の変更、反対側が相手の変更です。意図を読むか相談するかして、二つの変更を手動でマージします。分からなくなった場合は、いつでも git reset --hard してエンジニアを呼んでください。

この例だとこれが正しそうです。

  <div class="container">[% IF foobar %]

このようにしてコンフリクトマーカーをすべて消し去ったら、そのファイルを git add し (こうすることでコンフリクトを解消したことをシステムに伝えます)、いつものようにコミット&プッシュします。コンフリクトしているファイルが複数ある場合は、全部に対して手動マージしてからコミットしてください。

% git add templates/index.html
% git commit
% git push

ブランチを間違えてコミットしてしまった

push している場合やよくわからない場合は、エンジニアに頼んでください。 まだ push されておらず自分の手で解決したい場合は、以下のようにしてください。

theme ブランチに行うべき変更を master ブランチにコミットしてしまった場合。その直後なら

(theme ブランチに戻る)

% git checkout theme

(master の最新のコミット=誤った変更を theme ブランチに適用)

% git cherry-pick master

(master の最新のコミットを巻き戻す)

% git revert master

これで完了です。コンフリクトが発生するなどして分からなくなったら、git reset --hard してエンジニアを呼んでください。

あの言葉が入ったファイルを探す

git grep 'word' で、リポジトリ内からその単語を含むファイルと行を表示できます。ふつうに検索すると、アプリのコードも検索されてしまうので最後にディレクトリ名を加えて以下のようにするのがいいです。

% git grep 'TODO' templates

templates/ch.html:[% # TODO : 外部化したい %]
templates/campaign.html:            [% #TODO このテーマを使うボタンが動かない %]

あのときのファイルの内容に戻したい

git checkout $revision -- $file

Gitのコミットを表すハッシュについて

% git log

コミットには1つずつハッシュでidが振られます。

参考:Githubの中の人に聞いた、commit識別番号を人間でも扱いやすくする3つの工夫 - not good but great

Gitのコミットツリーなどについて

Gitの仕組みを少しだけ紹介しておきます。

コミットツリーがブランチなどによってどのように形成されているのかを掴んでおこう。

ブランチを分ける

git checkout -b bugfix

色々する

git merge bugfix

git merge develop

参考資料

参考書籍

最後の2冊はGit内部の構造についての記述が多い。「実用Git」の場合、低レイヤーコマンドの話は読み飛ばしてもさほど問題はなさそうだった。

Clone this wiki locally