GitHubにプッシュして草を生やすチュートリアル

#1. はじめに  
本記事は、GitHubを使ったことのない人を対象に、今日学んだこと[^1]をプッシュして草を生やせるようにするための記事です。  
[^1]: Today I Learning（TIL）参考：[Githubのリポジトリ「TIL」を使って小さなアウトプットを習慣化する](https://qiita.com/nemui_/items/239335b4ed0c3c797add)
個人開発のバージョン管理をGitでしたい！ 草を生やしてモチベーションを維持したい！ という人のために、今回はTILリポジトリを作成しプッシュするところまで解説します。  
GitHubに学習記録を残すついでに、Gitの動作を学ぶ。Gitの解説記事を読んだ時に頭の中でイメージがつき、理解がしやすくなる。Git学習の足掛かりとして作成しました。
 
■対象読者
動かしながらGitの理解を進めたい！
とりあえず個人でしかGitHub使わないよ！
GitHub登録したけど草生やしたことないよ！という方向け

<details><summary>注意事項(クリックで開く)</summary>
<div>・本記事はチーム開発での運用を考慮していません。
・コマンドも必要最低限です。
・まずは動かしてGitに慣れることを目的としています。
・筆者は最近草を生やし始めたレベルです。（この記事はそのアウトプットです）
・ちなみにQiitaも初投稿です。（指摘・コメント歓迎です）
</div></details>  

#2. 前提  
GitHubアカウント作成済み
#3. 環境
Windows10
Git version 2.31.1

#4. 用語説明
### **・リモートリポジトリ**
GitHub上に存在するリポジトリ（保管庫）  
ローカルリポジトリ上でステージング→コミット→プッシュすることで、リモートリポジトリにローカルリポジトリの内容が更新されます。  
プッシュした段階でリモートリポジトリが更新され、GitHubに草が生えます。


### **・ローカルリポジトリ**
PC上に存在するリポジトリ（保管庫）  


### **・ブランチ**
![Git-use-branch.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/9c4d8229-5ee4-7eef-7627-10613d73d290.jpeg)
ブランチはその名の通り"枝"という意味ですが、イメージ的には"作業場"をイメージすると分かりやすい気がします。  

```
//新規ブランチを作成します。
git branch ブランチ名
```

![Git-use-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/c7ac0c6b-b45f-b680-3901-4c53dce5a4ae.jpeg)
mainブランチは"動作保証の済んだ完成品"を置くブランチとして、もう1つ開発作業用のブランチを作ります。ローカルのmainブランチから切り出した開発作業用のブランチを仮にdevelopと名付けます。  
ローカルのdevelopブランチ上で作業をし、プログラムが完成しました。テストも完了済みで品質は保証されています。これをローカルのmainブランチにマージ（結合）します。  
最後にローカルのmainブランチの内容をリモートのmainブランチにプッシュすることで、ローカルの内容がリモートに更新されます。  
このようにブランチを分けるのは、他人の作業の影響を受けないようにするためです。
また、マージ後に問題が発生しても、コミット履歴を参照すれば追跡調査が容易になります。

GitFlowによるとmainブランチには直接プッシュせず、マージ専用にするべきという考え方があります。GitaFlowの概要については以下の記事が参考になりました。
[Git-flow ～Gitのブランチモデルを知る～](https://tracpath.com/bootcamp/learning_git_git_flow.html)  


### **・クローン**
リモートリポジトリをコピーしてローカルに持ってくること。
![Git-use-clone.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/9fac4a6f-9d6c-2f74-8e24-b141c145061b.jpeg)


```
//カレントディレクトリにリポジトリを作成
git clone

//指定したパスにクローンを作成
git clone 作成先のディレクトリパス

```


### **・ステージング**
コミットを行う前準備。
ステージングエリアに変更内容を追加します。  

```
//カレントディレクトリ配下の更新ファイルを全てステージング
git add .  

//Git管理下の全ての更新ファイルをステージングエリアに追加 
git add -A  

//ステージングするファイルを選択することも可能
git add ファイル名
```


### **・コミット**
ステージングエリア内の変更内容を***記録***します。
イメージ的には、ゲームでいう***セーブ***[^2]に近いです。
[^2]:  上書きセーブではなく別枠セーブ
コミットした時点で変更内容が記録され、いつでもその地点に戻すことが出来ます。
 
```
//変更内容をコミット
git commit -m "コメントメッセージ"
```

コミットの際には、変更内容を表すメッセージを入力してコミットします。  
コミットの粒度は、以下の記事が参考になりました。
[【初心者向け】「コミットの粒度がわからない問題」の模範解答を考えてみた](https://qiita.com/jnchito/items/40e0c7d32fde352607be)  


### **・プッシュ**
![Git-use-push.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/dc80b012-cefe-7ac2-77e2-000e98bd504c.jpeg)
コミットの内容をローカルリポジトリからリモートリポジトリへ送信し、リモートリポジトリに反映させます。  つまりローカルの内容をリモートに更新させる作業です。

```
//リモートリポジトリの指定したブランチにプッシュ
git push origin ブランチ名
```

ここで登場するブランチ名ですが、初期設定のままだと"main"[^3]です。
[^3]: 以前はmasterでしたが、良い表現ではないとのことで修正されました。現在はリモートリポジトリ作成時に初期ブランチ名としてmainが設定されます。過去のGit記事でgit push origin masterと記載されているものが多いのはそういうことです。
originはGitHubのリポジトリURLが設定されています。
言い換えれば下記のコマンドでも実行が可能です。

```
git push https://github.com/GitHubユーザ名/リポジトリ名.git ブランチ名
```

### **・フェッチ/マージ/プル**
![Git-use-fetch-merge-pull.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/d512349c-ba8b-f512-0882-72a4c6597cac.jpeg)
フェッチは、リモートブランチの情報をリモート追跡ブランチに反映させます。

```
//指定したブランチに移動
git checkout ブランチ名

//指定したブランチの情報を取得し、現在のリモート追跡ブランチに反映させる
git fetch origin ブランチ名

//上記画像例の場合：main(リモート)→origin/mainを更新
git checkout main
git fetch origin main

```

マージは、ブランチとブランチを結合します。
2つのブランチの差分を出し、その差分を結合するイメージです。

```
//指定したブランチに移動
git checkout ブランチ名

//指定したブランチを現在のブランチにマージ
git merge マージするブランチ名

//上記画像例の場合：developにorigin/mainをマージ
git checkout develop
git merge origin/main
```

プルは、フェッチとマージを連続して行います。

```
//指定したブランチに移動
git checkout ブランチ名

//指定したブランチを現在のブランチにマージ
git merge マージするブランチ名

//mainブランチとdevelopブランチがある場合、次のコマンドでmainにdevelopをマージ
git checkout main
git merge develop
```

# 5. 事前準備
Gitコマンドを打つ前に事前準備として、リモートリポジトリとローカルリポジトリを作成しましょう。今後Gitで管理するリポジトリ達です。
GitHubアカウントは事前に作成しておいてください。
###GitHubにリモートリポジトリを作成
![Git-use-CreateRemoteRepositly.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/7541c0b1-6a16-905a-07fb-2c50b221ff4a.png)
![Git-use-CreateRemoteRepositly2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/f63548d2-a803-72df-315d-4b8e7f51b37c.jpeg)
![Git-use-CreateRemoteRepositly3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/5a5ef957-3688-d15f-90ec-fdd47d0eb6e5.jpeg)
Repository name：筆者は既にTILが存在するので、TIL-testとして作成しています。
Description：空欄でもOKです。
Public/Private：とりあえずPrivateで作成しています。外部に公開したい方はPublicで。
Initialize this repository wtih：とりあえずREADMEファイルだけ作成するように設定しています。
最後にCreate repositoryを押下します。
![Git-use-CreateRemoteRepositly4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/cb9fb7f9-19cf-7459-9f0b-d2ac4a780347.jpeg)
リモートリポジトリTIL-testが完成しました。

###デスクトップにローカルリポジトリフォルダを作成
必須作業ではありませんが、リモートリポジトリをクローンする先のフォルダを作成します。
名前はなんでもいいです。とりあえずGit-LocalRepositoryという名前のフォルダを作成しました。
![Git-use-CreateRemoteRepositly5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/662a7d56-52af-6c55-114e-f3d005e51894.jpeg)

###コマンドプロンプト表示
![Git-use-CreateRemoteRepositly6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/537fc84e-219d-ba60-d3d0-b50783571895.jpeg)
![Git-use-CreateRemoteRepositly7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/3fd02041-4914-a711-ef96-6435cbb2a4f5.jpeg)
ちなみに筆者はVSCodeとGitを連携して、VSCode上のターミナルからGitコマンドを使用しています。
今回はコマンドプロンプトで行いますが、普通に便利なのでVSCode利用者は連携することをおすすめします。  
参考：[【初心者向け】VSCodeとGithubの連携 for Windows ～連携操作からプッシュまで～](https://breezegroup.co.jp/202102/vscode-github-windows/)  

###リモートリポジトリをローカルにコピーする（クローン)
はじめに、リモートリポジトリのURLを取得しておきましょう。
![Git-use-CreateRemoteRepositly8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/bd7e1769-f727-77d3-f7ae-13547e656cda.jpeg)
次に、先ほどのコマンドプロンプト上で以下のコマンドを入力します。

```
//リモートリポジトリをクローン（複製）する
git clone リモートリポジトリのURL

//結果
C:\Users\kuron\OneDrive\デスクトップ\Git-LocalRepository>git clone https://github.com/MeidyRouge/TIL-test.git
Cloning into 'TIL-test'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.
```
![Git-use-CreateRemoteRepositly9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/55c1da7f-15b7-aea1-8507-d5d487abfcf7.jpeg)
Git-LocalRepositoryフォルダにクローンが生成されました。
隠しファイルの.gitフォルダはGitがこのフォルダを管理するためのフォルダです。
これで準備はOKです。


# 6. 演習：個人開発を想定したGit運用（簡易ver）
簡易的なGitの運用演習です。GitHubに草を生やせるようになるレベルになります。
まずこれができれば、Git学習の足掛かりとしては成功です。

###README.mdファイルを編集してみる
適当にファイルの中身を変更して保存。
![Git-use-CreateRemoteRepositly10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/d47aea9d-092a-b861-3809-5b8bd0fcf307.jpeg)


###変更内容をステージング⇒コミット⇒プッシュする

```
//カレントディレクトリを移動（windowsコマンド）
cd TIL-test

//変更内容をステージング
git add .  

//コミット（コミットメッセージはご自由に）
git commit -m "メッセージ" 

//ローカルの内容をリモートへプッシュ（更新）
git push origin main 
```
![Git-use-CreateRemoteRepositly11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/15b339d6-0fd2-bd1b-5798-6a2292f64b9a.jpeg)

リモートリポジトリが更新されました！ もちろん草も生えます。
これで個人開発において、最低限のGit運用ができるようになりました。  
6.演習の内容を図に起こすと、このようになります。
![Git-use-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/c7ab0460-9310-4822-30f5-e94e759b3355.jpeg)

# 7. 演習：個人開発を想定したGit運用（ブランチ利用）
次はブランチについて、動かして学んでみましょう。  
ブランチという概念を学ぶことで、ブランチの移動・作成・削除、ブランチ同士のマージなどを扱えるようになります。入門者（自分）にとっては、このブランチが結構くせ者でした。  
※Gitコマンド実行前にREADME.mdを好きなように修正しておいてください。
### ブランチの作成&移動

```
//新規ブランチ(develop)作成
git branch develop

//main → developブランチに移動
git checkout develop
```
ここで、現在のブランチを一度確認しておきましょうか。

```
//ブランチの確認
git branch -v

//結果
C:\Users\kuron\OneDrive\デスクトップ\Git-LocalRepository\TIL-test>git branch -v
* develop d55785e add:プッシュテスト
  main    d55785e add:プッシュテスト
```

OK。developブランチになってますね。
###ステージング⇒コミット⇒プッシュ

```
//現在のディレクトリ配下の変更内容を全てステージング
git add .

//コミット
git commit -m "コミットテスト"

//ローカルのdevelop → リモートのdevelopブランチにプッシュ
git push origin develop

//結果
C:\Users\kuron\OneDrive\デスクトップ\Git-LocalRepository\TIL-test>git push origin develop
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 450 bytes | 450.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
remote:
remote: Create a pull request for 'develop' on GitHub by visiting:
remote:      https://github.com/MeidyRouge/TIL-test/pull/new/develop
remote:
To https://github.com/MeidyRouge/TIL-test.git
 * [new branch]      develop -> develop
```
ローカルのdevelopブランチをリモートに向けてプッシュしました。  
 * [new branch]      develop -> develop という一文を見てもらうと分かる通り、リモートリポジトリにdevelopブランチが新たに生成されていることが分かりますね。  
なんやかんや開発し、完成したと思ったらマージします。


###マージ&プッシュ
```
//mainブランチに移動
git checkout main

//develop → mainブランチにマージ
git merge develop

//ローカルのmain → リモートのmainブランチにプッシュ
git push origin main  
     
//使用済みのブランチを削除
git branch -d develop
```
リモートリポジトリmainブランチにプッシュできたか確認してみる。
![Git-use-CreateRemoteRepositly12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/fdfb4983-a6c2-b7f8-e7f7-afcf5781f884.jpeg)
できました！  
新規ブランチを作成し、開発用のブランチの中で開発 → 完成した時にmainブランチにマージすることで、mainブランチには動作の保証されているバージョンのものだけを管理することができます。  

個人開発でブランチは必要なのか？ 当記事を書いている内に興味深いスレが見つかりました。コミットの粒度についても触れており、大変有意義なスレです。補足としてどうぞ。
参考：[Git - 一人Gitでブランチは必要か？｜teratail](https://teratail.com/questions/60285)

7．以上、演習で行った内容を図に起こすと、このようになります
![Git-use-branch-ver.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/4bcb5fc8-4403-4281-eb5e-d745bf046032.jpeg)


#8. 演習：チーム開発を想定したGit運用（一例）
最後に、チーム開発を想定したGit運用の一例[^4]を紹介します。  
[^4]: 筆者はGitのチーム開発はしたことがありません。経験者に「こんな感じ？」と聞きながら作成しました。その認識は明らかに間違っている、という指摘がもしかしたらあるかもしれません。

mainブランチは品質が保証された完成品をマージさせるためのブランチ。
developブランチは、完成したdevelop-〇ブランチをマージさせるためのブランチ。
develop-A,develop-Bは個人のブランチです。A君、B君の開発用ブランチと考えてください。もしくはA機能開発用ブランチ、B機能開発用ブランチと考えても結構です。

![Git-use-team-ver.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533851/362ae629-5ce6-02ff-6fde-b2db460cd54d.jpeg)
このようにB君にはB君専用のブランチを与えることで、A君の更新内容に影響されずに開発を行うことができます。
7.演習と異なるのは、pushの前にpullを挟んでいるところです。

<details><summary>補足：push前にpullする理由ってなに？</summary><div>
developブランチをみんなで使うことを想定しています。  
自分の作業が一段落しました。pushするまでの間に他者がdevelopを更新しているかもしれません。もしdevelopをpullせず、自分のブランチをpushしてしまうと、リモートブランチdevelopがローカルのdevelopに反映されていないので、リジェクト（エラー）が発生します。  
それを防ぐため、push前にpullをしてね！ ということだと思います。
また、開発環境を常に最新の状態を保つという考え方自体が重要という話も伺いました。
</div>

<details><summary>補足：最後に使用済みブランチを削除する理由は？再利用するのは良くないの？</summary><div>
A.新しいブランチはマージする際に競合する可能性が低くなる。最新のmainブランチから切り出したブランチは最新であることが保証されている。   
参考：[マージされたブランチを再利用するのは良い習慣ですか？](https://www.it-swarm-ja.com/ja/git/%E3%83%9E%E3%83%BC%E3%82%B8%E3%81%95%E3%82%8C%E3%81%9F%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%82%92%E5%86%8D%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E3%81%AE%E3%81%AF%E8%89%AF%E3%81%84%E7%BF%92%E6%85%A3%E3%81%A7%E3%81%99%E3%81%8B%EF%BC%9F/l966988231/)  
A君がdevelop-Aブランチからプッシュし、developブランチにマージした後、B君がdevelop-Bブランチの作業内容をdevelopブランチにマージした場合、A君が使いまわしているブランチにはB君の修正が反映されていないため、最新のブランチではない。  
最新にするためにdevelopブランチをdevelop-Aブランチにマージするくらいなら、最初からdevelopからブランチを新しく切り出せばいい。ということだと思います。  
ブランチは作業場(※イメージ)なんだから、その作業が終わったらその作業ブランチは取り壊して新しい場所で作業しなさい！ という意見もありました。
</div>

コマンド自体は7.演習とほとんど変わらないので省略。個人開発の場合、自分以外の開発メンバーがいないので、ここまでする必要はないと思います。  

#9. おわりに
さて、無事に草が生えたでしょうか。この記事がGit学習の足掛かりになれば幸いです。  

もしGitコマンド中にエラーが出て進めない！ これってどういう意味？ なんでステージングする必要があるの？ など疑問が浮かんだ時はチャンスです。人は興味を抱いたことはすんなり覚えられるので、お手持ちのパソコンでググってみましょう！  

以上！