研究入門者のためのGit/Github入門

はじめに

こんにちは、早稲田大学D2の栗林です。専門はHCIのアクセシビリティという分野です。趣味は筋トレ、ラグビー、インコと遊ぶことです。

さて、皆さんGit/Githubをご存知でしょうか。Git/Githubはバージョン管理ツールです。使うメリットを研究入門者(大学3-4年生)向けに箇条書きで書くと

  • 常にコードの記録が取れる点

    • オンラインにコードのバックアップが取れる(パソコンが壊れても保存した地点までのコードは復元できる)

    • 万が一コードをめちゃくちゃにしても記録した点まで戻れる(例えば1週間前のコードや昨日のコードも復元できる)

  • 共同開発に使える点

    • ブランチ機能を使うことで同時に複数人で開発を並行することができる

ただ実際、Git/Githubってなんだか難しいですし、Git/Githubを学ぶ時間があれば論文を読んだり、コーディングしたくなったりしてしまいますよね。そこで、この記事では研究入門者向けに簡単にGit/Githubの使い方を書きます。なるべく簡単な言葉で、難しいところまでは踏み込みませんのでぜひ最後まで読んでもらえたら嬉しいです。

Git/Github

Githubでリモートリポジトリを作成する:まず、やることはGithubアカウントの作成です。学生は大学のメアドの使用するとGithub Educationプランに加入でき、色々お得です。アカウント作成後は、Your Profile -> Repositoriesよりリポジトリを作成してください。(僕の筋肉自慢の画像が映り込んでいますね。ちなみに得意部位は腕です。)

リポジトリの作成方法

そうすると、以下のように空のリモートレポジトリが作成されます。

空のレポジトリ。最初打つべきコマンドが書いてあるので便利。

ちなみにですがリモートリポジトリはネット上に保存されているリポジトリのことを指して、ローカルリポジトリは手元パソコン上に保存されているリポジトリを指します。リモートリポジトリとローカルリポジトリは必ずしも同期してないため、別々の呼び方をします。

ターミナルからGithubにアクセスする:次にターミナルからGithubにアクセスします。やり方はいくつかありますが、私が普段やっている方法で紹介します。まず、以下のコマンドを打ってください。

$ cd ~/.ssh # $から#までのコマンドを使ってください
$ ssh-keygen -t rsa
Enter file in which to save the key (/Users/masakikuribayashi/.ssh/id_rsa): id_git   #自分にとってわかりやすい名前を設定      
Enter passphrase (empty for no passphrase): #今回はとりあえずEnter Keyを押してください
Enter same passphrase again:          #今回はとりあえずEnter Keyを押してください
Your identification has been saved in id_git
Your public key has been saved in id_git.pub
$ pbcopy < id_git.pub # id_git.pubの中身をコピーするコマンド。この後Ctrl+Vでペーストできるようになる

※環境によってはpbcopyは使えません。pbcopyが使えない場合はcatで表示するなど別手段でコピーしてください。

その後、右上のアイコンをクリックしてSettings->SSH and GPG Keysに行き、New SSH Keyをクリック。タイトルに好きな名前を入れて、その下の欄にid_git.pubの中身をペーストしてください。

sshキーの登録方法

最後に~/.sshの中にconfigというファイルを作成し、以下の内容を記述してください。

$ vim config #以下の内容を記述
Host github github.com
  HostName github.com
  IdentityFile ~/.ssh/id_git
  User git
$ ssh -T github #ちゃんと設定できたか確認。できてたら以下のような文章が出てくる
Hi <user name>! You've successfully authenticated, but GitHub does not provide shell access.

これで登録完了です!

gitの使用を開始する:管理したいディレクトリで以下のコマンドを打ってください。今回はtest_repositoryというディレクトリを作ってその中で作業しましょう。

$ mkdir test_repository
$ cd test_repository
$ git init #test_repositoryディレクトリでgitによる管理を開始
$ git remote add origin git@github.com:<username>/test_repository.git #<username>のtest_repositoryをリモートレポジトリとして登録

管理するファイルを選ぶ :例えばgit initしたディレクトリにmain.pyというファイルがあるとしましょう。main.pyに引き算の関数を書きます。

引き算をする関数をmain.pyに記述

以下のコマンドを実行してください。具体例1と2どちらでもいいです。

$ git add <管理対象のファイル>
$ git add main.py   #具体例1: main.pyのみ管理
$ git add .         #具体例2: ディレクトリ下のすべてのファイルを管理

変更分を保存する:git addしたファイルのこれまでの変更に名前をつけて保存しましょう。便利なのは具体的に何をしたか書けることです。

$ git commit -m "<何をしたか>"
$ git commit -m "main.pyの追加"                     #具体例1: main.pyを追加する場合
$ git commit -m "main.pyを作成してsubtract関数を記述" #具体例2: subtractという名前の関数を作った場合

リモートリポジトリに反映させる:以下のコマンドを打ってリモートレポジトリに反映させましょう。

$ git push <リモートレポジトリの名前> <ブランチの名前>
$ git push -u origin main #具体例

過去に以下のコマンドでtest_repositoryをoriginという名前で登録するという作業を実は行なっていました。なので<リモートレポジトリの名前>にはoriginが入ります

git remote add origin git@github.com:<username>/test_repository.git

<ブランチの名前>にはmainを入れてますが、ブランチとは作業場所のことですが、現時点では分かりにくいので一旦は気にせずにいきましょう。

ここまでできればひとまずはバックアップとしてのGithub活用ができました。これで間違えてPCをぶっ壊してもGithub上にコードのバックアップがあるので安心です。

main.pyが追加された

同じプロセスを繰り返す:次にmain.pyにadd関数を追加してadd、commit、 pushまでやってみましょう。

gitには現在状況を確認するコマンドがあるので使ってみましょう。
以下のコマンドを叩いて分かることは、今mainというブランチ(作業場所)にいて、origin/main(originというリモートリポジトリのmainブランチ)と同期できていることです。また、特に現在何も変更点がないことも最後に記述されてます。Githubにpushしたばかりなので特に違和感はありません。

$ git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

では、まずはadd関数の追加しましょう。VScode上では新しく追加された部分が緑色にハイライトされます。既存の箇所の変更は青、削除は赤でハイライトされるので常に自分が何をしたかをトラックしてくれるので便利です。

add関数の追加

変更を加えた状態でgit statusと入力すると現在"Changes not staged for commit"(変更されているけれどadd=stageされていない)の欄にmain.pyがmodified(変更が加えられている状態)であることがわかります。

$ git status
On branch main
Your branch is up to date with 'origin/main'.

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:   main.py

no changes added to commit (use "git add" and/or "git commit -a")

では次にaddして再度現在状況を確認してみましょう。main.pyが"Changes to be committed"(commitされるのを待っている変更)の欄に表示されるようになりました。ちなみにaddを取り消したい場合打つべきコマンドの案内も表示されてます。

$ git add main.py
$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   main.py

ではcommitしてから状況確認してどう変化するのか見てみましょう。commitすることによりセーブポイントを作成したので、特に何も表示されてないです。git pushすることにより今手元でcommitした変更をpublish(アップロード)してくださいと書いてあります。

$ git commit -m "add関数の追加"
$ git status
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

ではpushしましょう。

$ git push origin main

リモートリポジトリもアップデートされました。

さっきまで"main.pyを作成してsubtract関数を記述"
と書いてあったところが"add関数の追加"に変更されている

これまでの記録の可視化:先ほどのレポジトリのページからInsights->Networkと移動すると、これまでの変更の記録を見れます。以下の写真がそれです。白いノードが一つの記録(commit)に対応してます。2個目のノードにカーソルを合わせるとその時どんな変更をしたがか表示されます。

ネットワークグラフで一番最後の記録を可視化

一応、ターミナル上でも似たようなことができます。git logと打つとこれまでの変更の履歴が表示されます。

$ git log
commit 5a93c0d7eb8a5a5d78f0f3a90082a9dcfd09f52a (HEAD -> main, origin/main)
Author: chestnutforestlabo <rugbykuribayashi@toki.waseda.jp>
Date:   Sun Dec 15 20:30:30 2024 +0900

    add関数の追加

commit c148ab14575b32953a980eb40df8344e5f2de439
Author: chestnutforestlabo <rugbykuribayashi@toki.waseda.jp>
Date:   Sun Dec 15 19:36:01 2024 +0900

    main.pyを作成してsubtract関数を記述

ブランチで作業する:
既に何回か出てきましたがgitにはブランチという超重要概念があります。ブランチ(branch)は和訳すると枝です。
ブランチ機能は、同じプロジェクト内で「別々の作業場所」を用意できる仕組みです。たとえば、Aさんは「aブランチ」、Bさんは「bブランチ」を作って、それぞれ独立してコードを変更・追加します。こうすると、他の人の作業に影響を受けずに自分の開発を進められます。そして、作業がひと段落したら、これらのブランチを合流させ、最終的にひとつのコードに統合することができます。

実際に使っていきましょう。チーム開発をしていて、Aさんは割り算を実装し、Bさんは掛け算を実装する場合を考えます。

$ git branch <作成したいブランチ名> #新しいブランチを作成するためのコマンド
$ git switch <移動して作業したいブランチ名> #ブランチを移動するためのコマンド

#Aさんのみ実行
$ git branch add_division     #割り算を実装するためにadd_divisionブランチを作成
$ git switch add_division     #add_divisionブランチに移動
Switched to branch 'add_division'

#Bさんのみ実行
$ git branch add_multiplication #掛け算を実装するためにadd_multiplicationブランチを作成
$ git switch add_multiplication #add_multiplicationブランチに移動
Switched to branch 'add_multiplication'

一旦Aさん視点で進めます。Aさんは以下のような実装をしました。

subtractの上にdivisionを追加

あとは、add、commit、pushするだけ。注意点はpushの最後の引数は実はブランチ名です。さっきまでmainと書いてましたが、add_divisionに変えてください。実はさっきまではmainブランチで作業していました。

$ git add main.py
$ git commit -m "division関数の追加"
$ git push origin add_division #さっきまではgit push origin mainでしたがmainの部分をブランチ名にする!

次にBさんはmultiplyを追加します。以下、Bさん視点です。

multiply関数の追加
$ git add main.py
$ git commit -m "multiply関数の追加"
$ git push origin add_multiplication

ブランチの可視化:いったんInsights->Networkから今どのような状況になっているのかみてみましょう。それぞれ別の場所で作業している様子がわかります。現状としては以下のようになってます。

ブランチが分かれていく様子
  • mainにはaddとsubtractが書いてあるコードがある

  • add_divisionにはadd、subtractとdivisionが書いてあるコードがある

  • add_multiplicationにはadd、subtractとmultiplyが書いてあるコードがある

さて、それぞれの機能開発が終わったのでそれぞれの機能をmainに統合していきましょう。以下、再びAさん視点です。

# merge機能の使い方
$ git merge <統合を受け入れるブランチ> <統合されるブランチ> 

# Aさんが実際に使うコマンド
$ git switch main #mainブランチに移動
$ git merge main add_division --no-ff #mainブランチにAさん自身が行ったadd_divisionブランチのコードを統合

mergeを叩くとテキストエディタが開いてコミットメッセージ書けと言われます。今回はそのまま:wqで保存して閉じてください。コミットメッセージを書かなくてもデフォルトでMerge branch 'add_division'と書いてくれてます。

vimでコミットメッセージを記述している様子

次にAさんがmainブランチに対してBさんが実装した掛け算機能を統合します。

$ git fetch origin #リモートレポジトリの情報を取得
$ git merge main origin/add_multiplication --no-ff #mainブランチにBさんが行ったadd_multiplicationブランチのコードを統合
$ git push origin main #リモートレポジトリに情報を反映させる

fetchコマンドはリモートレポジトリの情報を取得するためのコマンドです。BさんはAさんとは別のPCで作業しているため、AさんのPCにはadd_multiplicationブランチの情報はありません。Bさんはgit push origin add_multiplicationでリモートブランチに情報を反映しています。

なので以下のコマンドを打つことでAさんは手元に無いBさんの開発した情報を取得できます。

$ git fetch <リモートブランチの名前>
$ git fetch origin

mergeの部分にorigin/add_multiplicationという謎のブランチ名が出てきました。origin/add_multiplication は、「origin という名前で登録されたリモートリポジトリの add_multiplication ブランチ」という意味です。git fetch origin を行うと、リモートレポジトリのadd_multiplicationブランチの情報がローカルに取り込まれ、origin/add_multiplication というブランチとして手元で見えるようになります。

全てを統合した結果、無事全て四則演算が定義されたPythonコードが出来上がりました。

全てのブランチを統合し終えたコード

統合後の状態の可視化:今の状態でInsights->Networkを再度確認すると各々のブランチが統合された様子がわかります。まず最初に割り算が、その次に掛け算が統合されてます。

統合されていく様子

同じ場所を編集してしまったらどうなる?:先ほどはAさん、Bさんがうまいこと違う場所にコードを書いたおかげで統合した時に変なことが起きることがありませんでした。では、もし同じ場所にコードを書いてしまった場合、コードは統合できるのでしょうか?できません。この同じ場所を編集してしまい、統合できない状態をコンフリクトと言います

わざとコンフリクトを起こしてみましょう。例えばAさんが関数をsubtractの下側に書いてしまったとしましょう。Bさんも新しい関数をsubtractの下に書いたので変なことが起こるはずです。

コミュニケーションミスで二人とも同じ行に開発してしまった例

この状況で最初にAさんの変更をmergeしてからBさんの変更をmergeすると以下のようになります。7行目multiplyが入ってきたいのですが、それをdivideが邪魔してます。

conflictが起きてしまっている例

コンフリクトを解消するためには<<<<<<< HEAD、=======、>>>>>>>を消した上でうまく手動で直す必要があります。この場合は単にmultiplyをdivideの下に置けば解消できます。

conflictを解消した後

コミュニケーションによってコンフリクトは防げる:コンフリクトは時たまおきますが、コミュニケーションによって防ぐことができます。私がやっているやり方では複数人で同じファイルをそもそも編集することはないです。個々人がアサインされた場所を編集します。

発展 - プルリクエスト(Pull Request)を使った開発プロセス:今回はmergeを使った開発プロセスについて説明しました。しかし上記のような開発プロセスではBさんがバグの含んだコードをmainブランチに統合してしまうかもしれません。mainに統合する前に他の人に一旦自分のコードをチェックしてもらってからmergeできると良いかもしれません。そこで活躍するのがプルリクエストを使った開発プロセスです。プルリクエストとは開発者が行なった変更を別の開発者に通知して、チェックしてもらう機能です。チェックしてもらって問題がなければmergeします。より詳しい説明は以下の記事を参考にしてみてください。

発展 - README.mdを書こう:GithubではREADME.mdというファイルを作成することでそのレポジトリの使い方などを記載することができます。現状のレポジトリはREADME.mdがないので説明が何もない状態です。

README.mdがない状態

そこでREADME.mdを作成してその中に簡単にこのレポジトリの用途を書いてみましょう。

$ vim README.md #以下を記述。(記述方式はマークダウン形式)

# Repository for Learning Git/GitHub

Thank you for reading!

## TODO
- [ ] Learn more about Git/GitHub
- [ ] Do more research
- [ ] Go to the gym

$ git add README.md
$ git commit -m "README.mdを追加"
$ git push origin main

すると以下のようにGithubで表示されます。共同開発者にこのレポジトリの使い方を伝えたり、自分のメモ代わりとして使うことができます。

README.mdを作成した様子

発展 - issueを使ってみよう:issueは開発者がバグや開発方針について議論するためのツールです。レポジトリのIssues->New IssueからIssueを作成可能です。以下の画像のようにタイトルと内容を指定するとissueが作成され議論ができる様になります。

issueを作成して議論している様子。
公のレポジトリではさまざまなバグの解決方法がissue
にちゃっかり乗っていることはよくあります。

また、以下のように人によってはissueを使って研究サーベイをしている人もいます。

最後に - わからなくなったらLLMに頼ろう:一見すると、gitは難しいように見えるかと思います。私も最初はとっても怖かった覚えがあります。何のコマンド打てばいいかわからなくなったらLLMに聞いてしまいましょう。

終わりに

とても長かったですが、ここまでできればいいかなと思います!実際に手を動かしてみて体験してください!Git/Githubには他にもいろいろ機能があるので、より詳しく学びたい方は以下の書籍やリンクがおすすめです。


いいなと思ったら応援しよう!