この投稿は 「Git Advent Calendar 2014 - Qiita」 の 2日目の記事です。
2年前の 「Git Advent Calendar 2012 - Qiita」 では、「Gitコマンド総選挙」と題して、本当に使える Git コマンドのベストテン発表というネタを書いたのですが、今振り返ってみても、Git コマンドって、よく使うものから普段あまり使わないものまで様々なコマンドが取り揃えられていて至れり尽くせり感がある一方で、Git 初心者が覚えるにはぶっちゃけ 数が多過ぎて辛い ですよね。
そこで今回は、Git 初心者がプルリクできる ようになるまでに覚えるべきコマンドを絞りに絞って、9つだけ紹介したいと思います(9つでも多いよ!というツッコミは受け付けません!)。
- 【コマンド その1】 git clone
- 【コマンド その2】 git log
- 【コマンド その3】 git branch
- 【コマンド その4】 git checkout -b
- 【コマンド その5】 git diff
- 【コマンド その6】 git status
- 【コマンド その7】 git add
- 【コマンド その8】 git commit -m
- 【コマンド その9】 git push
ハイ、以上!
・・・だと、全然意味が分からないので、以下、プルリクの流れに沿って順番に解説していきます。
前提として、
- チーム用のリモートリポジトリ(下図の「リモートリポジトリ A」)がすでに存在
- GitHub に個人アカウントを登録済み
- ローカルに(Windows なら Cygwin版 Git 等の)Git クライアントをインストール済み
だとします。
リポジトリの最終イメージは以下のようなものになります。
なお、Cygwin版 Git (for Windows) のインストールについては ↓ をどうぞ。
Step 1. チームのリポジトリを Fork しよう!
まず、プロジェクトチームで管理している「リモートリポジトリ A」を、自分のアカウント内のワークスペース(リモートリポジトリ B)にコピー(Fork)してみます。
Fork は、GitHub にログインした状態で、「リモートリポジトリ A」のページ上で操作します。
右上の「Fork」ボタンをクリック。
自分の管理しているワークスペース(リモートリポジトリ B)を選択します。
自分専用の「リモートリポジトリ B」が、GitHub のサーバ内に作成されます。
Step 2. リモートリポジトリを clone しよう!
Step 1. で作成した(GitHubのサーバ内にある)「リモートリポジトリ B」を、ローカル(自分のPC)側のワークスペース(ローカルリポジトリ)にコピー(clone)してみましょう。
ここで、ようやく「コマンド その1」です。
Git コマンドは、ローカル(自分のPC)にインストールした Git クライアントから実行します。
【コマンド その1】 git clone
git clone <repository> リモートリポジトリをローカルにコピーします。
<使い方>
$ cd /c/temp/ $ git clone https://github.com/akiyoko/django-mysite.git
ここで、<repository> は「リモートリポジトリ B」の「clone URL」を指定します。
「clone URL」は、GitHub のページ右側に枠があるので、ここからコピペします。
ローカルに、「ローカルリポジトリ C」が作成されます。
では、正しくコピーされたかどうかチェックしてみましょう。
ローカルの Git クライアントから、「git log」コマンドを実行すると、コミット(変更履歴)の一覧を表示することができます。
【コマンド その2】 git log
git log コミットの一覧(コミットログ)を表示します。
<使い方>
$ cd django-mysite/ $ git log commit c724ba2511d40f580b7baff40bd0b774456b2f06 Author: akiyoko blog <akiyoko-team@users.noreply.github.com> Date: Thu Nov 20 17:12:16 2014 +0000 Run polls syncdb commit 59130a5df51c6a8db50546dab8b152cbf1c0789b Author: akiyoko blog <akiyoko-team@users.noreply.github.com> Date: Thu Nov 20 17:07:24 2014 +0000 Create polls app commit c8c50ff36776303d37a456449f5aa919be3debae Author: akiyoko blog <akiyoko-team@users.noreply.github.com> Date: Thu Nov 20 16:52:12 2014 +0000 Run syncdb commit 729bee74447c4b614138ceca20663a93303d66e6 Author: akiyoko blog <akiyoko-team@users.noreply.github.com> Date: Thu Nov 20 16:48:07 2014 +0000 Change LANGUAGE_CODE & TIME_ZONE commit a91dd71095d9d0ccbff59f73bf2449e0f13a088e Author: akiyoko blog <akiyoko-team@users.noreply.github.com> Date: Fri Nov 21 01:31:17 2014 +0900 Initial commit
コミットの履歴がずらっと表示されましたね。
「リモートリポジトリ B」のコミット履歴は、GitHub画面上の ↓ の部分をクリックすることで確認することができます。
コミット履歴が同じ状態になっているので、最新のリポジトリがコピーされているということが確認できました。
Step 3. トピックブランチを作成しよう!
「ブランチ」は、リポジトリ内でコミットの履歴を複数管理するための仕組みです。
ブランチとは、履歴の流れを分岐して記録していくためのものです。分岐したブランチは他のブランチの影響を受けないため、同じリポジトリ中で複数の変更を同時に進めていくことができます。
特に、機能追加やバグ修正の単位で作成するブランチは「トピックブランチ」と呼ばれます。
トピックブランチとは、何か特定の機能や、それに関する作業を行うための専用のブランチです。
clone した直後の「ローカルリポジトリ C」では、「master」という名前のブランチが 1つしか存在していない状態になっています。ここでは例として、masterブランチから派生させたトピックブランチ「FIX-001」を作成していきます。
まずは、「git branch」で、ローカルリポジトリのブランチ一覧を表示します。
【コマンド その3】 git branch
git branch リポジトリのブランチ一覧を表示します。
オプションなしで実行すると、ローカルリポジトリのブランチ一覧を表示することができます。
<使い方>
$ git branch * master
「master」ブランチが 1つだけ表示されていますね。
次に、バグ修正用のトピックブランチ「FIX-001」を作成します。
【コマンド その4】 git checkout -b
git checkout -b <branch> 「-b」オプションで指定したブランチ名で、新しいブランチを作成します。
<使い方>
$ git checkout -b FIX-001 Switched to a new branch 'FIX-001' $ git branch * FIX-001 master
「git branch」でブランチ一覧を表示すると、新しいブランチ「FIX-001」が作成され、現在のブランチが「FIX-001」に切り替わっていることが分かると思います。
なお、「git checkout」をオプションなしで実行すると、新しいブランチを作成せず、既存のブランチに切り替えることができます。オプションなしの「git checkout」は頻繁に使うことになるので、しっかり覚えておきましょう。
Step 4. コミットしてみよう!
トピックブランチに切り替えた状態で、何か修正を加えてみましょう。
修正が終わったら、ソースコードの差分を確認してみます。差分を確認するには「git diff」を使います。
【コマンド その5】 git diff
git diff ソースコードの差分を表示します。
<使い方>
$ git diff diff --git a/polls/models.py b/polls/models.py index 2a19920..8a48ed7 100644 --- a/polls/models.py +++ b/polls/models.py @@ -2,7 +2,7 @@ from django.db import models class Poll(models.Model): - question = models.CharField(max_length=200) + question = models.CharField(max_length=100) pub_date = models.DateTimeField('date published') def __unicode__(self):
左側に「+」や「-」の付いた形式で表示されるのですが、これがソースコードの差分をピンポイントで表しています。Git 初心者は、diff の表記方法に早く慣れていかないといけないですね。
さてここで、ローカルリポジトリには、「リポジトリ」「ステージ環境」(「インデックス」とも呼ばれます)「作業環境」という 3つのエリアがあるという仕組みを理解しておきましょう。ちょっとややこしいのですが、コミットをするまでに通らなければいけない「3つの部屋」があるというイメージがしっくりくるかもしれません。
何か修正をすると、図の一番下の「作業環境」というエリアに差分が発生します。
「ステージ環境」というのは、コミット候補のソースコードを一時的に保存(プール)しておく部屋と考えればよいかと思います。一旦ステージ環境にプールしてから、後でまとめてコミットをする、といった作業イメージです。
差分の状況を確認するためには、「git status」を使います。
【コマンド その6】 git status
git status 変更されたファイルの一覧を表示します。
<使い方>
$ git status # On branch master # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: polls/models.py # no changes added to commit (use "git add" and/or "git commit -a")
polls/models.py が修正されていて(modified)、ステージ環境に登録されていない(Changes not staged)ということが分かります。
作業環境の差分ファイルをコミットするためには、まず一度ステージ環境に登録する(「ステージング」と呼びます)必要があります。
差分ファイルをステージングするためには、「git add」を使います。
【コマンド その7】 git add
git add <filepattern> 差分をステージングします。
<使い方>
$ git add polls/models.py
これで、ステージ環境に登録されました。
「git status」で差分の状況を確認すると、ステージ環境に差分が登録され(「Changes to be committed」のところに差分ファイルが表示されています)、コミットする準備が整っているということが確認できました。
$ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: polls/models.py #
次に、リポジトリ環境にコミットをしていきます。
【コマンド その8】 git commit -m
git commit -m ステージ環境のファイル差分をリポジトリにコミットします。
なお、コミットする際は、「-m」オプションでコミットコメントを指定する必要があります。
<使い方>
$ git commit -m "Fix max length" [FIX-001 099e954] Fix max length 1 files changed, 1 insertions(+), 1 deletions(-)
$ git log commit 099e954484b5dc0b5590224d67db98a29ca8eba2 Author: akiyoko blog <akiyoko-team@users.noreply.github.com> Date: Sun Nov 30 20:53:36 2014 +0900 Fix max length commit c724ba2511d40f580b7baff40bd0b774456b2f06 Author: akiyoko blog <akiyoko-team@users.noreply.github.com> Date: Thu Nov 20 17:12:16 2014 +0000 Run polls syncdb commit 59130a5df51c6a8db50546dab8b152cbf1c0789b Author: akiyoko blog <akiyoko-team@users.noreply.github.com> Date: Thu Nov 20 17:07:24 2014 +0000 Create polls app commit c8c50ff36776303d37a456449f5aa919be3debae Author: akiyoko blog <akiyoko-team@users.noreply.github.com> Date: Thu Nov 20 16:52:12 2014 +0000 Run syncdb commit 729bee74447c4b614138ceca20663a93303d66e6 Author: akiyoko blog <akiyoko-team@users.noreply.github.com> Date: Thu Nov 20 16:48:07 2014 +0000 Change LANGUAGE_CODE & TIME_ZONE commit a91dd71095d9d0ccbff59f73bf2449e0f13a088e Author: akiyoko blog <akiyoko-team@users.noreply.github.com> Date: Fri Nov 21 01:31:17 2014 +0900 Initial commit
コミット履歴の一番上に追加されました。
これで、リモートリポジトリを更新する準備ができました。
リモートリポジトリをローカルリポジトリ(のリポジトリ環境の内容で)更新するには、「git push」を使います。
【コマンド その9】 git push
git push <repository> <branch> ローカルリポジトリのコミット差分をリモートリポジトリに更新します。
<repository>は、clone元(リモートリポジトリ B)にコミットする場合は「origin」を指定すればよいはずです。<branch>は、ローカルリポジトリのブランチ名を指定します。
<使い方>
$ git push origin FIX-001 Username for 'https://github.com': (username) Password for 'https://akiyoko@github.com': (password) Counting objects: 7, done. Delta compression using up to 4 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (4/4), 393 bytes, done. Total 4 (delta 3), reused 0 (delta 0) To https://github.com/akiyoko/django-mysite.git * [new branch] FIX-001 -> FIX-001
「リモートリポジトリ B」に 新しいブランチ「FIX-001」が作成されました。
さて、ちゃんと push できたかどうか、自分の GitHubアカウントのリモートリポジトリ(リモートリポジトリ B)のページを見てみましょう。
ブランチを「FIX-001」に切り替えます。
同じ commit id のコミットが一番上に来ています。
というわけで、ちゃんと push されていましたね。
これで、覚えるべき 9つのコマンドの紹介は全て終了なのですが、最後にプルリク(プルリクエスト)の方法について説明していきます。
Step 5. プルリク(プルリクエスト)をしてみよう!
最後に、「リモートリポジトリ B」にコミットしたトピックブランチの差分を、「リモートリポジトリ A」に通知(プルリク)してみます。
プルリクは、GitHub の画面上で行います。
GitHub にログインした状態で、「リモートリポジトリ B」のページ上で操作します。
左上の緑のアイコンをクリック。
「Edit」ボタンをクリックして、プルリク元とプルリク先を調整します。
すると、プルリク先のブランチとの変更差分を自動的にまとめてくれるので、これでよければ、「Create pull request」ボタンをクリックします。
プルリクメッセージを入れて、「Create pull request」ボタンをクリック。
プルリク完了です!!
あとはマージを待つだけ。
これで、Fork からプルリクまでの流れの全て説明終了です。
今回説明したのは、あくまで 必要最低限のコマンド 9つ ということなので、これをベースに Git 経験値をガンガン上げていってください。
明日は、sue738 さんの 3日目の記事です。よろしくお願いします。