全くの初心者のための GitHub
Git と GitHub は学習したり使いこなしたりするのが難しいツールですが、いくつかの簡単なコマンドと適切なアドバイスがあれば、 MDN への協力を始めるのに十分な程度のことが、さほど苦労せずにできるはずです。この記事の目的は、 Git や GitHub を使いこなすことではなく、基本的なレベルで生産的になり、 MDN に協力するために必要なことを紹介することです。
すでに Git/GitHub の基本に慣れている人は、おそらくここで新しいことを学ぶことはないでしょうが、それでもこの記事をリファレンスとして活用することはできるでしょう。また、長い説明を省いてコマンドだけを掲載している GitHub の早見表もあります。
基本的な概念
以下のものは Git と GitHub を最大限に活用するために知っておかなければならない基本的な概念です。
- Git はバージョン管理システムのツールで、開発ワークフローには欠かせないものです。複数の開発者が同じコードベースで、互いの邪魔にならないように作業したり、コードベースをリモートの場所に安全に保管したり、必要に応じてコードを以前の状態に戻したりといったことができます。
- GitHub は、保存されたコードベースを操作するための便利なツールを Git の上に提供し、コードベースを保存するためのサーバースペースの提供も行うウェブアプリケーションです。この分野の他のアプリケーションである GitLab や Bitbucket などと同様の機能を持っています。
- それぞれのコードベースは、リポジトリー (repository または repo) と呼ばれるコンテナーに格納されます。
- リポジトリーに変更を加える最小限の手順は次の通りです。
- そのリポジトリーの自分用のコピーを作成する (フォーク (fork) といいます)。
- リポジトリーのフォークに別なバージョンのコードを作成し (ブランチ (branch) といいます)、その別なバージョンに変更を加える。
- プルリクエスト (pull request) によって元のリポジトリーのコピーに変更を加えることを提案する。このガイドでは、これらの手順をすべて学ぶことができます。
この記事の前提条件
この記事では以下のことを前提としています。
- コマンドライン/端末の利用に慣れていること。コマンドラインを使うのが初めての方は、コマンドラインの短期集中コース (en-US)をご覧ください。
- 標準的な UNIX スタイルのコマンドラインのコマンドを解釈できるシステムで作業をしている。 macOS/Linux ではこの機能がすぐに使えます。 Windows はこの点ではそれほど単純ではありません (en-US) が、 Gitbash のように Windows でこの機能をエミュレートする便利なアプリケーションがあります。
- Git/GitHub の操作にはコマンドラインを使います。 Git や GitHub 用の GUI ツールはいくつかありますが、このガイドでは利用できません。
初期設定
特定のリポジトリーでの作業を開始する前に、以下の手順を実行してください。
- Git をコンピューターにインストールしてください。 Git ダウンロードページにアクセスして、自分のコンピューター用の最新バージョンをダウンロードし、インストールしてください。 Windows ユーザーの場合は、 Git for Windows パッケージに Gitbash が含まれているのでインストールしてください。
- ついでに、 MDN をローカルで作業するために必要な他の依存関係、すなわち Node.js と yarn もインストールしてください。
- Node.js をインストールするには、上記のリンクをクリックして、自分のコンピューター用の最新バージョンをダウンロードしてインストールしてください。
- Node.js をインストールしたら、
npm install --global yarn
を実行して yarn をインストールしてください。
- すべての Git リポジトリーを保存するための別のディレクトリーを、コンピューターのどこか、コマンドラインで簡単に見つけて移動できるところに作成します。 mdn-git というディレクトリーを home/user ディレクトリーの中に作成するといいでしょう。
- まだない場合は、 GitHub アカウントをサインアップしてください。 MDN のリポジトリーに貢献するのに必要です。
GitHub での SSH 認証の設定
この時点で、 SSH キーを GitHub のアカウントに設定する必要があります。これは基本的に、 GitHub に自分を識別させるためのセキュリティ機構であり、 GitHub のサービスを利用するたびに認証する必要がなくなります。
GitHub は、この設定に関する便利なガイドを用意しています。まずは GitHub に SSH で接続するを参照してください。ここで紹介する手順に従って、 Github で SSH を利用するための設定を行います。
これを行わなくても MDN に貢献することはできますが、 GitHub とやり取りするたびに (例えば、後で触れるようにプルリクエストを送信するたびに) ユーザー名とパスワードを入力しなければならなくなります。
特定のリポジトリーで作業するためのセットアップ
MDN のさまざまなタスクに取り組む際には、いくつかの異なるリポジトリーを更新する必要がありますが (MDN 上のものはどこにあるのか - リポジトリーのガイドを参照)、作業するどのリポジトリーでも、より簡単で一貫した作業を行うために従うべきセットアップ手順がいくつかあります。
フォークとクローン
フォークとクローンという二つの用語は、 Git の世界ではよく遭遇するものです。
- フォークは GitHub 上でリポジトリーの自分用のコピーを作成するという意味です。
- クローンは作業用のリポジトリーのローカルコピーを作成するという意味です (すなわちローカルのハードディスク上に)。
この二つは個別に行うことができますが、実際には他人のプロジェクトに協力する場合、ほとんどは一緒に行うことになるでしょう。まず、作業したいと思っている各リポジトリーのフォークを作成してください。これは、そのリポジトリーのメインバージョンに変更要求を出すために必要となります (プルリクエストの作成方法については後ほど説明します)。セキュリティ上の理由から、メインバージョンのリポジトリーに直接変更を加えることはできません。
今ここで https://github.com/mdn/content をフォークしてみましょう。いつか必ずこのリポジトリーに貢献することになるでしょう。以下の手順に従ってください。
-
content リポジトリーのページの右上にある Fork ボタンを探して押してください。
- リポジトリーをどこにフォークするかを尋ねるモーダルウィンドウが表示されます。個人の GitHub アカウントを選択してください。 "Forking mdn/content. It should only take a few seconds." というようなメッセージが表示されます。 GitHub がフォークを完了すると、ブラウザーは新しいフォークのページにリダイレクトされます。たとえば、私がフォークした https://github.com/mdn/content は https://github.com/chrisdavidmills/content で利用できます。
リポジトリーをフォークしたら、今度はフォークしたものをローカルにクローンしましょう。これは次のように行います。
- github.com の自分のフォークのページ (例えば
https://github.com/<ユーザー名>/content
) へ行ってください。 -
ファイル一覧の上にある緑色の "Code" ボタンを押してください。そうすると、以下のポップアップのようなものが現れます。
- 上で説明したように、 SSH 認証を設定した場合は "SSH" タブをクリックし、ボックス内のテキストフィールドから
git@github.com:<ユーザー名>/content.git
の URL をコピーしてください。 SSH 認証を設定していない場合は、代わりに "HTTPS" タブのテキストフィールドからhttps://github.com/<ユーザー名>/content.git
のような URL をコピーしてください。 - そして自分のコンピューターでコマンドラインを開き、 cd コマンドで先ほど git リポジトリーのローカルのクローンを保存するために設定したディレクトリーに移動します。
cd git
- 次のような形でコマンドを入力し、フォークをクローンしてください。
例えば、私がクローンするときのコマンドは次のようになります。
git clone the-url-you-copied
git clone git@github.com:chrisdavidmills/content.git
これで git ディレクトリーの中に content ディレクトリーができ、そこにリポジトリーの内容が入っているはずです。
リポジトリーのメインバージョンを指すようリモートを設定する
次に進む前の最後の作業として、リモートを設定してメインバージョンのリポジトリーを指すようにしましょう。この例では https://github.com/mdn/content とします。リモートとは基本的に、GitHub 上の特定のリモートリポジトリーの場所を指すものです。後述するように、ローカルのクローンを最新のメインリポジトリーに更新するために最もよく使われます。
リモートの設定は、次のように git remote add
コマンドで行います。
git remote add リモート名 指す先のリポジトリー
- リモート名 は自分で決めた名前で、後にリモートを参照するために使用されます。同じ目的を持つ異なるリポジトリー間では、一貫したリモート名にこだわるのと良いでしょう。同じリモート名であれば、どこでも同じことができ、混乱することも少なくなります。例えば、自分のバージョンをフォークしたリポジトリーのメインバージョンは「upstream (上流) リポジトリー」と呼ばれることが多く、そのためよく "upstream" がリモートの上流の場所を表す名前として使われます。私は通常、上流のリモートを "mozilla" と呼んでいますが、これは Mozilla のメインのリポジトリーを指していることを示すためです。
- 指す先のリポジトリー は、指す先の SSH (または HTTPS) の URL で、先ほどフォークのクローンを作ったときと同じ方法で取得します。
したがって、リモートを追加するには以下のようにします。
- github.com のリポジトリーのメインバージョンのページへ行き (この例では https://github.com/mdn/content とします)、必要に応じて "Code" ポップアップから SSH または HTTPS の URL を取得します。
- コマンドラインから、
cd
で自分の content ディレクトリーに移動します。cd content
- 次のようなコマンドを、 リモート名 と 指す先のリポジトリー を適切に置き換えて実行してください。
したがって、例えば私は SSH の URL を使用してリモートの "mozilla" を呼び出したので、次のようにしました。
git remote add リモート名 指す先のリポジトリー
git remote add mozilla git@github.com:mdn/content.git
これで、リモートの設定が完了しました。端末で git remote -v
というコマンドを実行するとこれを確認できます。このコマンドは、自分のリモートの名前とその場所の一覧を出力します。以下のようなものが表示されるでしょう。
mozilla git@github.com:mdn/content.git (fetch) mozilla git@github.com:mdn/content.git (push) origin git@github.com:chrisdavidmills/content.git (fetch) origin git@github.com:chrisdavidmills/content.git (push)
リポジトリーに変更を加えるための準備
これで、ローカルのフォーククローンで作業できるようになりましたが、新しい変更を行う前に実行しておくべき一連のコマンドがあります。
メインブランチへの切り替え
それぞれのリポジトリーにはいくつかの異なるブランチがあり、これは基本的に同じリポジトリーの中にあるコードベースの異なるバージョンです。つまり、コードベースに変更を加えるたびに、別のブランチで変更を加え、まずそこでテストしてから、コードのメインコピーに変更を反映させるという考え方です。
コンテンツリポジトリーのメインブランチは "main" と呼ばれています (他のリポジトリーでは "master" などと呼ばれているかもしれません。その場合は、以下に示すすべてのコマンドでその名前を読み替える必要があります)。リポジトリーをクローンしたばかりのときは既定ででこのブランチにいることになりますが、すでに作業を終えている場合は別のブランチにいるかもしれません。 何か作業をする前に、次のコマンドを実行してメインブランチに切り替えるようにしましょう。
git switch main
メモ: 他のチュートリアルで、リポジトリーのブランチを変更するのに git checkout
を使っているのを見たことがあるかもしれません。このチュートリアルでは、より新しい git switch
コマンドをお勧めします。これは純粋にブランチを変更するために設計されたもので、失敗する可能性が低いからです。これらのコマンドの関連性や違いに興味がある方は、 Highlights from Git 2.23 > Experimental alternatives for git checkout が良くまとまっています。
自分のメインブランチの更新
次は、メインブランチを更新して、メインリポジトリーのメインブランチと同じ内容になるようにします。 content リポジトリーは数多くの貢献者によって毎日何度も更新されているので、これをやらないとバージョンが古くなってしまい、更新を投稿する際に問題が発生します。ここで、リモートが役に立つのです。
リポジトリーを更新するには次のようにします。
- まず、以下のコマンドで、リモートの更新されたコンテンツを取得してください。
例えば次のようになります。
git fetch リモート名
git fetch mozilla
- 次に、自分のメインブランチの内容を、リモートリポジトリーのメインブランチに置き換えます。いろいろな方法がありますが、私は
rebase
コマンドをよく使います。例えば次のようになります。git rebase リモート名/メインブランチ名
git rebase mozilla/main
- 最後に、次のようにして自分のフォークのリモートバージョンに変更をプッシュしてください。
git push
更新が正しく行われたかどうかは、 github.com で自分のフォークのページを見ればわかります (例えば、私の場合は https://github.com/chrisdavidmills/content です。)。そこには "This branch is even with mdn:main." のような記述があるはずです。もし自分のメインブランチがたくさんのコミットで mdn:main より遅れている (behind) と表示された場合は、もう一度試してみるか、トラブルシューティングを行う必要があります。
作業用のブランチを作成する
フォークでメインブランチを最新の状態にした後は、必ず新しいブランチを作成して変更を加えなければなりません。メインブランチで作業を行い、そこから送信するようなことはしないでください。すぐに面倒なことになってしまいます。すべての作業を別々のブランチで行ったほうが、はるかにすっきりしていて、ミスも起こりにくいのです。
新しいブランチを作成する方法です。
-
github.com で自分のフォークのページ (例えば、私の場合は https://github.com/chrisdavidmills/content) に行くと、ファイル一覧の左上に、おそらく "main" と書かれているブランチボタンが見つかります。
-
これをクリックすると、ブランチの一覧が表示され、 "Find or create a branch..." というテキストフィールドが表示されます。
-
テキストフィールドに既存のブランチ名の一部を入力すると、その文字列によってブランチの一覧が絞り込まれ、既存のブランチを検索しやすくなります。しかし、ここでは新しいブランチを作成したいと思います。まだ存在していないブランチ名を入力すると (test-branch などを試してみてください)、表示が変わり、 "Create branch: test-branch from 'main'" というラベルのついたボタンが表示されます。
-
ブランチ名が決定したら、このボタンをクリックすると表示が更新され、ブランチボタンにそのブランチ名が表示されます。
これで完了です。これで、作業を行うための新しいブランチが作成されました。このブランチは、作成した時点でのメインブランチの状態と同じです。ここから作業を始めるといいでしょう。
豆知識:
- 新しいブランチを作成する前には、前のセクションで説明したように、常にメインブランチを mozilla のメインブランチと同期するように更新するようにしてください。
- 新しいブランチは常に main から作成するようにし、他のブランチから作成しないようにしてください。そのために、ブランチボタンに "main" と表示されており、他のブランチではないことを確認してから作業を始めましょう。そうしないと、新しいブランチが非常に古くなってしまい、コンテンツの問題が発生する可能性があります。
ブランチをローカルに取得して切り替える
前の節では、フォークに新しいブランチを作成する方法を説明しましたが、現在はリモートバージョンのフォークにしか存在していません。このブランチで作業をするには、それを自分のローカルバージョンに取り込む必要があります。
これを行うには、端末に戻って、作業しているリポジトリーのディレクトリー (この例では content
) の中にいることを確認してください。
- リモートで変更した内容をローカルのクローンに取り込むには、
git pull
コマンドを実行してください。 * [new branch] test-branch -> origin/test-branch
のような数行のメッセージが表示されます。- 自分のブランチに切り替える (つまり、 "main" から切り替えてそのブランチで作業する) には、
git switch test-branch
コマンドを実行してください。
成功すると、 git は次のように表示します。
Branch 'test-branch' set up to track remote branch 'test-branch' from 'origin'. Switched to a new branch 'test-branch'
なお、どのブランチにいるのかなど、自分のリポジトリーの状態は git status
コマンドを実行すればいつでも確認できます。このコマンドを実行すると、git は次のように表示します。
On branch test-branch Your branch is up to date with 'origin/test-branch'. nothing to commit, working tree clean
だいたい良いようですね。現在は "test-branch" ブランチにいて、まだ変更は何も行っていません。
変更の追加、コミット、プッシュ
この時点で、作業しているリポジトリーに変更を加える準備が整いました。 MDN のバグを修正したり、何かをするためです。この部分はこのチュートリアルの目的ではないので、ほとんど省略します。 MDN で実際の問題を修正したい場合は、コンテンツの問題一覧から修正するバグを選択するか、より詳しいガイダンスが必要であれば MDN への貢献をお読みください。
例としての性質上、このチュートリアルに沿って進めるのであれば、簡単なことをやってみましょう。
content/README.md
ファイルに入り、 README の一番上の見出しに 1 文字を追加してください。- 次に、コマンドラインに戻って
git status
コマンドを再度入力します。今度は、git が次のように教えてくれるはずです。Your branch is up to date with 'origin/test-branch'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: README.md no changes added to commit (use "git add" and/or "git commit -a")
- つまり、この時点で変更したファイルを教えてくれるのです。次の段階では、そのファイルを「追加」します。つまり、リモートフォークにプッシュするために、コミットしたいファイルの一覧にそのファイルを追加します。このファイルをコミット一覧に追加するには、次のように入力します。
git add README.md
メモ: ### 注
README.md
は、変更したファイルの名前だけではなく、そのファイルへのパスを書きます。サブディレクトリーの中にあった場合は、そのファイルのフルパスを書かなければなりません。 - もう一度
git status
を実行すると、このように表示されます。On branch test-branch Your branch is up to date with 'origin/test-branch'. Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: README.md
- Git は
README.md
がコミット一覧に入ったことを教えてくれました。コミット一覧にあるすべてのファイルをコミット (後にメインブランチに送信しようとする、ひとつの変更セット) に含めるには、次のように入力します (-m
オプションは "message" の略です)。Git は次のように表示します。git commit -m 'my first commit'
[test-branch 44b207ef6] my first commit 1 file changed, 1 insertion(+), 1 deletion(-)
コミットを登録したことを示すためです。 - もう一度
git status
を実行すると、次のような情報が得られます。On branch test-branch Your branch is ahead of 'origin/test-branch' by 1 commit. (use "git push" to publish your local commits) nothing to commit, working tree clean
情報の読み出しは基本的にリセットされています。 — 前回の変更をコミットとしてシステムに送信したので、コミットする変更がないことを伝えています。先ほどとの大きな違いは、 "Your branch is ahead of 'origin/test-branch' by 1 commit." という行です。 — ローカル版の "test-branch" ブランチは、リモート版 "test-branch" よりも 1 コミット分進んでいます。言い換えれば、リモートブランチにはない変更をローカルで行ったということです。
ローカルで行った変更をリモートブランチに送りましょう。そのためには git push
というコマンドを実行します。 — やってみましょう。エラーが出なければ、次のような内容が表示されます。
Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 8 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 292 bytes | 292.00 KiB/s, done. Total 3 (delta 2), reused 0 (delta 0) remote: Resolving deltas: 100% (2/2), completed with 2 local objects. To github.com:chrisdavidmills/content.git 77215e31e..44b207ef6 test-branch -> test-branch
プルリクエストの作成
この時点で、 github.com のリモートフォークのページに戻ってみましょう。すると、 "This branch is 1 commit ahead of mdn:main." というメッセージが表示されるはずです。これは、私たちのフォークのコンテンツには、 mozilla の "main" ブランチにはない内容の変更 (コミット) があることを意味しています。
-
自分の変更をリポジトリーのメインコピーに送るには、プルリクエストを作成する必要があります。この作業は、ブランチに変更がプッシュされたときにファイル一覧の一番上に表示される "Compare & pull request" ボタンを使って簡単に行うことができます。
このボタンを押すと、次のような新しい画面が表示されます。
警告: ここから先の手順は、実際にリポジトリーに変更を加える場合にのみ行ってください。実際にテスト PR をリポジトリーに提出しないでください。
- ここでは、プルリクエストに役立つタイトルと説明を入力し、変更した内容、それがなぜ良いことなのかを正確に書いてください。必要に応じて、修正された関連する問題を書いてください。具体的には、
Fixes issue-url
という行を入れます。 GitHub は、自動的にこれをFixes #1234
のような課題番号へのリンクとして表示し、さらにプルリクエストがマージされると関連する課題を自動的にクローズします。 (訳注:Fixes issue-url
の部分は英語で入力してください。日本語で書くと自動的にクローズする機能が動作しないことがあります。) - プルリクエストを送信する準備ができたら、 "Create pull request" ボタンをクリックしてください。これにより、自分のプルリクエスト (PR) がリポジトリーのプルリクエスト一覧に表示され、レビューチームによるレビューを経て、メインのコードベースにマージされることになります。 レビューチームが変更を加えてほしい場合は、プルリクエストのスレッドのコメントで教えてくれます (その旨の通知メールが届くはずです)。
- すでに提出したプルリクエストにさらに変更を加えたい場合は、同じローカルブランチ上でさらにコミットを行い、先ほど説明したようにプッシュすることで変更を加えることができます。全く新しいプルリクエストを作成する必要はありません。ただ、以前と同じブランチにコミットしていることを確認してください。
トラブルシューティング
上記のチュートリアルは、 GitHub のリポジトリーに貢献するために必要な git と GitHub の基礎知識を基本レベルで提供することを目的としています。お役に立ちましたでしょうか。また、ウェブ業界の標準的なバージョン管理システムであるにもかかわらず、 Git は学ぶのも使うのも非常に難しいツールであるという神話的・伝説的な評判があることについても触れておきましょう。
私たちは、これが完全に公平だとは思いません。 Git には多くのコマンドがあり、その使い方は時に非常に不可解で、マスターするには長い時間がかかります。また、コマンドのいくつかを忘れたり、間違った順序で実行したりすると、なかなか抜け出せない面白い混乱に陥る可能性があるのも事実です。しかし、上記のような良い習慣を身につけていれば、大きく間違えることはないでしょう。また、 Git は 10 年前に比べてはるかに使いやすくなっていることも特筆すべき点です。
この節は今後拡充してゆき、一般的な問題を解決するのに役立つコマンドやシーケンスを紹介します。
コミット一覧に追加されていないファイルに加えた変更を元に戻す
ファイルを変更したものの、まだそれをコミット一覧に追加するための git add ファイルパス
コマンドを実行していない場合は、次のように実行すれば、そのファイルをブランチを最初にチェックアウトしたときの状態に戻すことができます。
git restore ファイルパス
コミット一覧からのファイルの削除
git add ファイルパス
コマンドを実行してファイルをコミット一覧に追加した後で、そのファイルをコミット一覧から削除したい場合は、次のようなコマンドを使います。
git restore --staged ファイルパス
コミットの取り消し
git commit -m 'my commit message'
を使ってコミット一覧をコミットした後、まだプッシュしていないが、何か削除したいものを入れてしまったことに気づいた場合、次のようにしてローカルのコミットを取り消すことができます。
git reset HEAD~1
これで、そのコミットの変更がまだコミット一覧に追加されていない状態に戻ります (問題を解決した後で、再度 git add する必要があります)。これは、このセッションで何かをコミットし始める前の状態に戻ることに注意しましょう。これでは、たとえば 3 つのコミットのうち真ん中のコミットだけを戻したいといった複雑なことをするときには役に立ちません。このレッスンでは、このままにしておきましょう。
リモートフォークにプッシュされたコミットを元に戻す
ここまで来ると、実際には戻ることも巻き戻すこともできません。代わりに、削除したいコミットの効果を逆にするために、別のコミットをプッシュする必要があります。上記で紹介したツールを使って手動で行うこともできますが、これを簡単に行うことができる組み込みのコマンド、 git revert
があります。これを使うと、指定した時点に変更を戻すコミットを自動的に作成することができます。
- 最もシンプルな方法は、以下のコマンドを実行して、リモートブランチをコミット開始前の状態に戻すコミットを作成することです。
git revert HEAD
- すると、コミットメッセージファイルが既定のテキストエディターで開かれるので、それを見て納得できるかどうか確認しましょう。これを閉じると、 git はコミットの作成を完了します。
- あとはプッシュする必要があるだけです。
git push
github.com でリモートフォークのページを再度見ると、元に戻したかったコミットと、それを元に戻したコミットが表示されています。
もっと見たいですか?
他にもこのトラブルシューティングガイドに情報を盛り込むべきだと思われる場合は、課題を作成して提案してください。
関連情報
- MDN 学習 > Git と GitHub
- Dangit, Git — その他の有用なトラブルシューティング技術
- 45 Github Issues Dos and Don'ts
- GitHub CLI tool — リポジトリーの管理に git の CLI コマンドを使うことに慣れてきたら、 GitHub 独自の GitHub CLI ツールのインストールを検討してみてはいかがでしょうか。