Gitの基本③ GitHubを使ってみよう

本記事ではGitの設定方法についてまとめていきます。
環境と前提は下記のようになります。

**環境**
・Windows 11
・git version 2.47.1.windows.1
・VSCode

**前提**
・Gitのインストールが完了していること。
・GitHubの登録が完了していること。
・前回の記事の続きとして進めていきます。

【前回の記事】
[Gitの基本②　Gitの設定方法と開発フロー]( https://qiita.com/y-wanida/items/767869f628b2b3c22815 "Gitの基本②　Gitの設定方法と開発フロー")

------------------------

## リモートリポジトリの作成
まずGitHubでリモートリポジトリを作成してみましょう。

GitHubで自分のアカウントにログインした状態から、タブの「repositories」をクリックし、緑色の「New」ボタンをクリックします。（ユーザーネームを隠すため一部画面のみ表示しています。）
![codespaces_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/4d7aada2-0add-6ef5-7f9d-922ef5210066.gif)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/2d6d87b3-3b8b-2148-8d4d-2be1245bd18e.png)
このような画面に遷移します。

下記画像のように設定して、下部分の「Create repository」ボタンをクリックします。
学習目的なのでprivateリポジトリの作成として良いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/79c217e5-67bd-eecf-ed32-c9a9cfc07ef0.png)


これで新しくリモートリポジトリが作成できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/eacc8bbb-adca-deca-e137-bc749de80ee8.png)

## SSH Keyの設定
SSH Keyはパスワードよりも安全な認証方法です。
キーは秘密鍵と公開鍵のペアで構成されており、秘密鍵はローカル環境に保存され、公開鍵はリモートサーバに配置されます。これによってパスワードを盗まれるリスクが減少します。
（※ローカルに保存される秘密鍵は厳重に管理する必要があります。）

Gitではセキュリティの向上のためにSSHキーを設定することをお勧めします。

VSCodeを開いてコマンドを入力していきます。

まず、下記のようにコマンドを入力し、ダブルクォーテーション内に自分がGitHubで登録したアドレスを設定し、実行します。
```
ssh-keygen -t rsa -b 4096 -C "yourmail@com"
```

下記のように文字列が表示されます。内容としてはKeyのファイル名を入力するように求められています。
ここで何も入力せずに１回Enterを押下すると、デフォルトのファイルが作成されます。
```
->
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\USER/.ssh/id_rsa): 
```

Enterを押下すると下記のようにパスワードが求められます。
先ほど作成した鍵を使用して認証を行うために必要なパスワードです。
パスワードを入力してEnterを押下しましょう。（入力時は何も表示されないようになっています。）

```
Created directory 'C:\\Users\\USER/.ssh'.
Enter passphrase (empty for no passphrase): 
```

もう一度同じパスワードを求められるため、入力してEnterを押下します。
```
Enter same passphrase again: 
```

下記のように公開鍵と秘密鍵が作成された旨が表示されます。
```
Your identification has been saved in C:\Users\USER/.ssh/id_rsa
Your public key has been saved in C:\Users\USER/.ssh/id_rsa.pub
The key fingerprint is:
(----省略----)
```

次に下記のコマンドで作成された鍵のファイルを確認してみましょう。

```
ls ~/.ssh
```
「id_rsa（秘密鍵）」「id_rsa.pub（公開鍵）」というファイルが作成されたことが確認できます

秘密鍵は第三者に知られないように管理しておきましょう。
```
    ディレクトリ: C:\Users\USER\.ssh

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2024/12/11     15:45           3434 id_rsa
-a----        2024/12/11     15:45            743 id_rsa.pub
```

次に公開鍵をGitHubに登録します。
下記のコマンドで公開鍵の中身を表示します。
```
cat ~/.ssh/id_rsa.pub
```

下記のように鍵の内容が表示されます。（部分的に省略しています）
```
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDAP/EZddUgya6ic5JYYQ4hXa75Bhn6FgalgMCFJNDzlyKbaNQbJlBCazej0x5mkeaS3QbxBiFQxDxiCtODgwFbuRuTKZHEuqv1sXu1XyusA1aewZ721/gay7S9498Mx/ErWHkuPgxXTdZ5IvjQqYjtcQeYDtqKq6P5JCOPDp2ngf+XBv4Lxeyx/GSO6qR+orMUsY1r5+e9CcqJbGDpi6TNQ+ywtgn0MJfMQ0eYItNR2Rmu(省略)
```

GitHubを開き、右上の丸アイコンをクリックすると、メニューが表示されます。
その中の「Setting」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/076d921c-6009-c9b5-7cf4-01f5911436e1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/a1bcb643-1e12-1af8-34a7-b8e697c2a3d7.png)

次に左側の設定メニューにある「SSH and GPG keys」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/e33feba0-ce6a-e2a0-271c-59dac1e79e21.png)

すると、下記のような入力欄が表示されます。
Titleを入力して、Keyの入力欄部分に、先ほどVSCodeのターミナル側で表示した鍵の内容を貼り付け、「Add SSH Key」ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/7de571d7-84d8-8649-eeac-79bbc66f6c4b.png)

これでSSH Keyの登録が行えました。ちなみに複数のSSH Keyの登録が可能かつ、削除も行うことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/ccd99513-fbd3-5e47-7c03-fe47418a0683.png)

ここまで設定ができたら、ローカル環境においてある秘密鍵を使用してGitHubと連携することができます。

動作確認方法は以下です。
VSCodeのターミナルから下記のコマンドを入力しましょう。
```
ssh -T git@github.com
```
下記のように接続許可を求められるため「yes」を入力してEnterを押下します。
```
Are you sure you want to continue connecting (yes/no/[fingerprint])? 
```

次に下記のようにパスフレーズ（パスワード）を求められるため
鍵の設定時に使用したパスワードを入力してEnterを押下します。
```
Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.
Enter passphrase for key 'C:\Users\USER/.ssh/id_rsa': 
```

下記のように結果が表示されていれば認証が成功しています。
```
Hi [GitHubに登録されたユーザーネーム]! You've successfully authenticated, but GitHub does not provide shell access.
```

## リモートリポジトリへのプッシュ
### mainブランチへのプッシュ
ここでようやくローカルリポジトリからGitHubのリモートリポジトリにプッシュしてみます。

GitHubで、作成したリポジトリのページを開き、「<>Code」のボタンを押下します。
すると、表示されたLocalタブ内の「SSH」タブを開き、入力欄に表示されている文字列をコピーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/03153f4e-552b-e5a6-cf76-da01a759970f.png)

VSCodeを開き、githubのリモートリポジトリにプッシュしたいディレクトリがカレントディレクトリであるかどうか確認します。（今回の例ではtestディレクトリとします）
```
C:\Users\USER\Desktop\git_practice\test>
```

下記のコマンドを入力し、最後尾にGitHubからコピーしてきた文字列を入力して実行しましょう。
```
git remote add origin [コピーしてきた文字列
```

これでリモートリポジトリの登録を行うことができました。
次にローカルリポジトリをプッシュする前に、今のブランチがmainであるかどうか確認します。
今のブランチがどこかはgit statusもしくはgit branchで確認することができます。
```
git status

->
On branch main
```

```
git branch

->
  branch_a
  branch_b
* main

```

mainブランチにいることが確認出来たら下記のコマンドを入力し、pushを行います。
```
git push -u origin main
```

**-u**
…ローカルブランチがリモートブランチを追跡するようになります。これにより、次回以降のgit pushやgit pullコマンドでリモート名やブランチ名を省略するようになります。

パスフレーズが求められるため、SSH Keyの設定時に入力したパスワードを入力してEnterを押下します。
```
Enter passphrase for key '/c/Users/USER/.ssh/id_rsa': 
```

今回はおそらくREADmeファイルを先にリモートリポジトリ側で作ってしまっていたがゆえに下記のようなエラーが発生したので、git pull origin mainで一度プルをして対処しました。

```winbatch
To github.com:YWanida/remote_test.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'github.com:YWanida/remote_test.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. This is usually caused by another repository pushing to
hint: the same ref. If you want to integrate the remote changes, use
hint: 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

この下記のコマンドはわかりやすくいうとリモートリポジトリの変更をローカルに反映するコマンドです。
```
git pull origin main
```

もう一度プッシュしてみます。
```
git push -u origin main
```

またパスフレーズが求められるため、SSH Keyの設定時に入力したパスワードを入力してEnterを押下します。
```
Enter passphrase for key '/c/Users/USER/.ssh/id_rsa': 
```

```
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (3/3), 856 bytes | 57.00 KiB/s, done.
From github.com:YWanida/remote_test
 * branch            main       -> FETCH_HEAD
 * [new branch]      main       -> origin/main
fatal: refusing to merge unrelated histories
```

fatal出てるやん。無理なんかい。
と、謎に躓いてしまいましたが負けません。

この理由はローカルリポジトリとリモートリポジトリの履歴が関連付けられていないために発生するそうです。
新しいローカルリポジトリを作成し、既存のリモートリポジトリに接続しようとした場合などに起こりえるとのこと。


```
git pull origin main --allow-unrelated-histories
```


**--allow-unrelated-histories**
…git pullコマンドにこのオプションを付けることによって履歴が関連付けられていないブランチを強制的にマージすることができます。


ここでまたパスワードを入力しEnterします。
```
Enter passphrase for key '/c/Users/USER/.ssh/id_rsa':
```

マージ時にエディタが出てきますが、今回は「:q」でコメントを残さずに飛ばします。

下記のように表示されました。
```
From github.com:xxxxx/remote_test
 * branch            main       -> FETCH_HEAD
Merge made by the 'ort' strategy.
 README.md | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
```

気を取り直してpushしてみます。

```
git push -u origin main
```

パスワードを入力してEnterします。
```
Enter passphrase for key '/c/Users/USER/.ssh/id_rsa': 
```

```
Enumerating objects: 18, done.
Counting objects: 100% (18/18), done.
Delta compression using up to 8 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (17/17), 1.53 KiB | 312.00 KiB/s, done.
Total 17 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To github.com:YWanida/remote_test.git
   a8066eb..1a52c60  main -> main
branch 'main' set up to track 'origin/main'.
```
このように表示されているのでできたようです！良かった。

GitHubのリポジトリを確認してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/ba63dbb0-2478-b769-1dc9-567ead281044.png)

test1.jsが追加されているのが確認できました。
ファイル名をクリックすると下記のように内容を確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/807757b5-4ea9-fba9-83a4-f7b84d1b4b40.png)

### mainブランチ以外へのプッシュ
前回の記事で作成しておいた「branch_a」にgit checkout で移動します。
（ない方はmainブランチで「git checkout -b branch_a」で新しくブランチを作成して行って下さい。）

```
 git checkout branch_a
```

このbranch_aをgit pushします。
```
git push -u origin branch_a
```

パスワードを求められるため、入力してEnterを押下します。
```
Enter passphrase for key '/c/Users/USER/.ssh/id_rsa': 
```

```
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
remote: 
remote: Create a pull request for 'branch_a' on GitHub by visiting:
remote:      https://github.com/YWanida/remote_test/pull/new/branch_a
remote:
To github.com:YWanida/remote_test.git
 * [new branch]      branch_a -> branch_a
branch 'branch_a' set up to track 'origin/branch_a'
```
上記のように表示されていたらOKです。GitHubを確認してみます。

まずリポジトリを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/12b5f71c-6016-8af6-dee7-0dd36cb0fab2.png)

左上あたりに「main」と書かれたボタンがあるのでクリックします。
（ここではmainとなっていますが、リポジトリによって名前が変わりますのであしからず。）
すると先ほどプッシュした「branch_a」が選択肢として出てくるのでクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/f21bdd21-1471-ffaf-d529-84a78237a52e.png)]

このようにbranch_aに切り替わって表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/649617d7-bd3f-b396-496b-a74269080b96.png)

ファイル名をクリックするとbranch_aのtest1.jsの内容が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/c87af156-e027-d5f5-91d3-30e036c2c67c.png)

## リモートリポジトリのクローン作成
リモートリポジトリの内容をローカル環境にとってくるためにgit cloneというコマンドを用います。

VSCodeのターミナルを開きます。
git cloneしたいgit_practiceディレクトリにいることを確認します。
```
PS C:\Users\USER\Desktop\git_practice> 
```
git hubを開いて、「Code」ボタンを押下し、SSHタブの中の文字列をコピーしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/ec20122a-91a1-b20b-f1cf-6e2a4fc89904.png)

再びターミナルを開いて、下記のコマンドを入力して実行します。
```
git clone git@github.com:YWanida/remote_test.git remote_test_2
```
コマンドの意味は、「git@github.com:YWanida/remote_test.git」のクローンを「remote_test_2」としてとってくるという意味合いになります。
コマンドを実行すると下記のような結果が表示されます。

```
Cloning into 'remote_test_2'...
Enter passphrase for key '/c/Users/USER/.ssh/id_rsa': 
remote: Enumerating objects: 20, done.
remote: Counting objects: 100% (20/20), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 20 (delta 0), reused 17 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (20/20), done.
```

VSCodeを確認していただくとわかるように、githubに作っておいたリモートリポジトリ「remote_test」の内容がごっそりコピーされて「remote_test_2」として配置されていることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/1a4fc433-e94a-3178-7cb9-fd3d661bb2be.png)

実務の例でいうと、例えばプロジェクトの追加機能を作成したい、かつ機能を追加する前の環境でも保守のために検証を行わなければならないといったときに、追加機能用のブランチをクローンで作成すれば、本番環境と同じソースを残したまま、開発を続行することができます。

## リモートリポジトリからのプル
git pullは、過去にgit pushされた内容をローカル環境に反映します。

VSCodeのターミナルを開きます。先ほど作成したremote_test_2を他の開発者のリポジトリと見立てて操作していきます。

他の開発者がremote_test_2を使用して修正を行い、修正内容をgit pushするまでの動きを再現します。

まずremote_test_2にディレクトリ移動し、ブランチを作成します。
```
PS C:\Users\USER\Desktop\git_practice> cd .\remote_test_2 
```

```
git checkout -b other_1
```

VSCodeにて「others_file.js」を作成し、内容を保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906686/eec4f0fb-7409-181f-3280-e2cd662fe6e0.png)

git addとgit commitを行います。

```
git add .
```

```
git commit -m 'ほかの開発者の修正'
```

次に、mainブランチへ移動し、他の開発者のブランチ（other_1）をマージします

```
git checkout main
```

```
 git merge other_1
```

エディタが表示され、コメントの入力を求められますが、今回はそのまま「esc」キー押下後に「:wq」を押下し、デフォルトのまま保存します。

次にmainブランチをリモートブランチへpushします。

```
git push origin main
```


ここまで完了したら、branch_aに移動します。このブランチにはまだ「others_file.js」が存在しないはずです。

```
git checkout branch_a
```

他の開発者が修正した内容がmainにマージされているので、branch_aにもその修正内容を反映させます。
```
git pull origin main


ー＞Enter passphrase for key '/c/Users/USER/.ssh/id_rsa': 
From github.com:YWanida/remote_test
 * branch            main       -> FETCH_HEAD
Updating 1a52c60..d9cc146
Fast-forward
 others_file.js | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 others_file.js
```

「others_file.js」が追加されたことが確認できました。
このように他の開発者の修正をpullで引っ張ってくることができます。

## ブランチの削除方法
ブランチの削除を行うためにまず、ブランチの内容を確認してみましょう。
ここでは「branch_a」を削除します。
```
git branch --remote
->
  origin/HEAD -> origin/main
  origin/branch_a
  origin/main
```
削除のコマンドは以下のようになります。（リモートリポジトリを編集するなどの処理に大体パスワードが求められるので都度入力してEnterを押下してください。）

```
git push --delete origin branch_a
```
下記のような結果が表示されたら、ブランチが無事削除されています。
```
->
To github.com:xxxxx/remote_test.git
 - [deleted]         branch_a
```

念のため先ほどと同様リモートブランチの一覧を表示して、本当に削除されたかどうか確認してみましょう。

```
git branch --remote
->
  origin/HEAD -> origin/main
  origin/main
```

開発工程の中で、古すぎるブランチや間違えて作成してしまったブランチ等を削除するのに使用されます。
削除する場合は本当に削除しても良いブランチなのか、また、自分の今いるブランチがどこなのかという確認が必ず必要ですので注意して作業を行ってください。