GitとGitHub初歩の初歩

# Git
- **クローン**：リモートリポジトリをローカルにコピー
- **プル**：リモートリポジトリの変更をローカルブランチに反映
- **プッシュ**：ローカルブランチに加えた変更をリモートリポジトリのブランチに反映
- **プルリクエスト**：例：開発者Aが変更ファイルをコミットし反映を別の開発者Bにお願いをすること
開発者Bは変更ファイルの中身を確認して問題なければマージする。

**あくまでブランチに関して考え方はmainとorigin/mainは別でmainはローカルのブランチでorigin/mainはリモートのブランチ**

## VSCode

https://qiita.com/daikiozawa/items/48a9fe0e2898c7dd78ae

https://techblog.hubbit.io/2020/10/05/visual-studio-code-show-git-folder/

VScodeで使われる拡張機能としてGit LensやGit Graphが使われる。

## 設定コマンド
ここで設定した内容は今後変更履歴に含まれるようになる。

```
git config --global user.name "ユーザー名"
git config --global user.email "メールアドレス"
git config --global core.editor 'code --wait'  #vscodeで使用
git config --global color.ui auto #ターミナルに色付け
```

## initからcommitまで
プロジェクトのルートディレクトリで下記コマンドを実行

```
git init #gitディレクトリが生成される
git status
git add .  #左記はカレントディレクトリ以下全てをステージングエリア
git commit -m "コメント" #コミット実行
git log #コミットのログ取得、ハッシュが表示される
```

<font color="blue">＊事前にローカルのmasterブランチをmainブランチにした方が良いかも</font>

```
git branch -m <古いブランチ名> <新しいブランチ名>
```

## statusに関して

一度コミットしたファイルは<font color="red">**追跡状態**</font>となる


- ステージングエリアに追加したファイル	<font color="blue">**Changes to be committed:**</font>
- ファイルの内容を変更	   <font color="blue">**Changes not staged for commit:**</font>
- 新規追加したファイル	<font color="blue">**Untracked files:**</font>

README.mdの内容を変更してみる
```
$ git status 
On branch master
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  ←ファイルをステージング
$ git status
On branch master
Changes to be committed:←ここに注目
  (use "git restore --staged <file>..." to unstage)
        modified:   README.md


$ git commit -m "README変更"
$ git status
On branch master
nothing to commit, working tree clean
```


## ステージングの取り消し
下記はREADME.mdを編集後、**編集した内容を取り消すまでの一連の流れ**
```
$ git add README.md 
$ git status                      #この時点ではChanges to be committed:
$ git restore --staged README.md  #ステージングを取り消す
$ git status                      #この時点でChanges not staged for commit:
$ git restore README.md           #ファイルに編集した内容も取り消される
```

## コミットの取り消し:Reset
Resetを使用してのコミットの取り消しは<font color="red">コミットそのものが無くなる動作となる。</font>
Before:           A---B---C---D (master)
After reset C:    A---B---C (master)

注意点は消したいコミットのハッシュでは無く**戻したい時点のハッシュ**を使う
A→B→CとコミットしてCに対して操作したい場合Bのハッシュを使う
```
$ git log ←取り消す為にcommitのハッシュを確認
commit fd72785de04cc4fd4fbadc741c37e22ef2e2baaf 

$ git status
On branch master
nothing to commit, working tree clean

$ git reset --soft fd72785de04cc4fd4fbadc741c37e22ef2e2baaf ←コミットをリセットしたのでステージングエリア時点に戻る

$ git status
On branch master
Changes to be committed:←ステージングエリア時点に戻っているのを確認
  (use "git restore --staged <file>..." to unstage)
        modified:   README.md
```

3つオプションがありそれぞれどの時点まで戻るかを選べる
```
--soft  コミットの操作のみを取り消す
--mixed コミット操作とステージ操作を取り消す
--hard  全ての変更を取り消す
```


```
git log --oneline 簡易表示
```


## コミットの取り消し:Revert
reverは取り消したいコミットのハッシュを利用する
Before:           A---B---C---D (master)
After revert C:   A---B---C---D---E (master)

revertを使用すると、<font color="red">Cの変更点だけが取り消され、D以降の変更はそのまま残ります。そして、取り消された変更を記録するために、新しいコミットEが作成されます。</font>そのため、リポジトリの履歴にはCとEの2つのコミットが含まれることになります。

```
$ git log
commit 43e1fec28c152d75389d2bedc9023819452c3507 (HEAD -> master) ←取り消しのハッシュ
Author: ユーザー名
Date:   Fri Mar 10 09:26:08 2023 +0900

    revert テスト


$ git revert --no-edit 43e1fec28c152d75389d2bedc9023819452c3507　←取り消しコマンド --no-editでコメント無しで実行できる
[master 5e9e6aa] Revert "revert テスト"
 Date: Fri Mar 10 09:27:09 2023 +0900
 1 file changed, 1 insertion(+), 1 deletion(-)

$ git log
commit 5e9e6aa8e2f86b0f5361fc35bab1ce58551f4cbd (HEAD -> master)
Author: ユーザー名
Date:   Fri Mar 10 09:27:09 2023 +0900

    Revert "revert テスト"

    This reverts commit 43e1fec28c152d75389d2bedc9023819452c3507.
```

## ResetとRevertどっちを使うの
チームでやった事がないのでいまいちイメージが出来ていないが下記とのこと
revertに慣れといた方が良さそう

>たとえば、開発者Aと開発者Bが同じリポジトリをクローンして作業しているとします。この時、開発者Aがリポジトリの履歴から一つ前のコミットBに戻り、resetコマンドを使用して、C以降の変更履歴を削除します。その後、開発者Aはリモートリポジトリにプッシュします。
この時、開発者Bがリポジトリに新しいコミットをプッシュしようとした場合、競合が発生します。なぜなら、開発者Bが持っているリポジトリの履歴と、リモートリポジトリにプッシュされた開発者Aの履歴が異なるため、Gitが自動的に解決できないためです。
つまり、競合が発生するということは、複数の開発者が同じファイルの同じ部分に変更を加えている場合に起こります。それ以降のコミットを削除する場合、他の開発者が既に変更を加えている可能性があるため、競合が発生する可能性があります。




## Branch(ブランチ)
### HEAD
ブランチとコミットはくっついている。
HEADは最新の状態を検知する仕組みがあり違うブランチに変更点があるとHEADも移動する
```
Before:ブランチを作成した時点では同じ内容
master:A--B--C--D(HEAD)
sub:A--B--C--D

After:subブランチにてコミットする。
master:A--B--C--D
sub:A--B--C--D--E(HEAD)
```

### ブランチの作成
下記はそれぞれのブランチにて異なる内容の変更履歴を作成する
結果二つの異なる内容Dの変更履歴が作成される
master:A-B-C-D
sub:A-B-C-D
```
$ git branch sub ←subというブランチを作成
$ git checkout sub  ←ブランチをsubに切り替え
$ git add README.md ←subブランチにて新たにコミットする
$ git commit -m "subブランチテスト"

$ git checkout master ←masterに戻ると変更点が無くなっているのが確認出来る。
$ git add README.md ←masterブランチにて新たにコミット
$ git commit -m "masterブランチテスト"

$ git log --graph --all ←切り替えてコミットしたところから/で表現される。
```

## Merge(マージ)
マージはブランチの統合を操作する。
しかしそれぞのブランチが指すコミットの位置によって、統合する方法が異なります。
マージには二つパターンがある。

### ファストフォワード
**<font color="red">取り込む元のブランチに新しいコミットが無く取り込み先のブランチに新しいコミットがある場合</font>**
下記の場合masterがsubを取り込む事となる。
```
master:A--B--C--D
sub   :A--B--C--D--E
```
下記はsub2ブランチに修正を加えてコミットをしmaster側で取り込みをしている

```
$ git branch sub2 
$ git checkout sub2 
$ git add README.md 
$ git commit -m "sub2ブランチに追記"
$ git log --graph --all
* commit fa9e83825396dfd65b77d9062a10f9042c3ca667 (HEAD -> sub2) ←新たにcommitされた為HEADがブランチsub2となる。
| Author: ユーザー名
| Date:   Fri Mar 10 10:58:02 2023 +0900
|
|     sub2ブランチに追記

$ git checkout master ←ブランチを切り替え
$ git merge sub2 ←sub2ブランチを取り込み
$ git log --graph --all
* commit fa9e83825396dfd65b77d9062a10f9042c3ca667 (HEAD -> master, sub2) ←二つのブランチのHEADが左記になっているのがわかる
| Author: ユーザー名
| Date:   Fri Mar 10 10:58:02 2023 +0900
|
|     sub2ブランチに追記
```
### マージコミット
**<font color="red">取り込み元のブランチに新しいコミットが有り、取り込み先のブランチに新しいコミットが無い場合</font>**
イメージとしてはA--Bまでは同じコミット内容、subではC--Dのコミット、masterではEのコミットがある
つまりお互い異なるコミットが有る状態
```
Before:
sub:   A--B--C--D
master:A--B--E

After:←subのC--Dを取り込んだ新たなFを作成する
master:A--B--C--D--E--F
```
HEADは同一の状態
1. masterにてtest.txtを作成
2. subにてtest2.txtを作成
3. masterにて取り込み作業
```
$ git merge --no-edit sub ←masterにて実行する事でtest.txtは消えずtest2.txtが追加される

$ git log --graph --all
* commit 6d3837d23ae1dc8374171665d8ba027f9369570e (HEAD -> sub)
| Author: ユーザー名
| Date:   Fri Mar 10 14:37:18 2023 +0900
|
|     test2.txtを追加
|
| * commit 051aa04ad645e6d6f6ded0415ad837f7692bc7ff (master)
|/  Author: ユーザー名
|   Date:   Fri Mar 10 14:30:02 2023 +0900
|
|       test.txtを追加
````

## コンフリクト(競合)
下記は同一のファイルの同一行に入力してmasterにてsubをmergeする。
コンフリクトが発生している状態、必要な部分を残して再度コミットする

```test.txt:
<<<<<<< HEAD
piyopiyo←masterブランチにて記載
=======
homhom←subブランチにて記載
>>>>>>> sub
```

```test.txt
piyopiyo
homhom
```

```git
$ git add text.txt ←ファイルを修正後ステージングからやり直す
$ git commit -m "修正"

*   commit 859b38e993208e346f5f5c021219fb757965cc28 ←masterブランチ
|\  Merge: 48f32e2 1341303
| | Author: ユーザ名
| | Date:   Fri Mar 10 14:57:27 2023 +0900
| |
| |     修正
| |
| * commit 1341303b0b43b971e1a16726fdf7e2c5333f1bb8 (sub) ←subブランチ
| | Author: ユーザ名
| | Date:   Fri Mar 10 14:50:57 2023 +0900
| |
| |     homhom 
| |
* | commit 48f32e20dab8f9373002e9efc2b1b544776fd33f ←masterブランチ
|/  Author: ユーザ名
|   Date:   Fri Mar 10 14:50:23 2023 +0900
|   
|       piyopiyo 

```

ちなみにmergeを取り消す場合は下記となる
```
git merge --abort
```

## ハンク(一部分をコミット)
ハンクという画面にて必要な部分のみを残しBeforeの状態にする
エディタを閉じる事でハンクの編集は終了する。
<font color="red">**一部分をコミット後ステージングエリアに残った内容に関しては忘れず処理する**</font>


```
$ git add -p ←オプションeで下記が表示される。
```

```:Before
@@ -1,2 +1,4 @@
 piyopiyo
 homhom
+hogehoge
+foobar
\ No newline at end of file
```

```:After
@@ -1,2 +1,4 @@
 piyopiyo
 homhom
+hogehoge
\ No newline at end of file
```

```
$ git status
On branch master
Changes to be committed: ←ステージングエリアに追加したファイル
  (use "git restore --staged <file>..." to unstage)
        modified:   test.txt

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:   test.txt
```

差分に関しては下記で表示される

```
$ git diff ←ワーキングディレクトリとステージングエリアの差分
diff --git a/test.txt b/test.txt
index 5df1994..fcbe0e6 100644
--- a/test.txt
+++ b/test.txt
@@ -1,3 +1,4 @@
 piyopiyo
 homhom
-hogehoge
\ No newline at end of file
+hogehoge
+foobar
\ No newline at end of file


$ git diff --cached ←ステージングエリアとHEAD(コミット)の差分
diff --git a/test.txt b/test.txt
index 596d841..5df1994 100644
--- a/test.txt
+++ b/test.txt
@@ -1,2 +1,3 @@
 piyopiyo
 homhom
+hogehoge
\ No newline at end of file
```

## スタッシュ
gitのスタッシュは、ワーキングディレクトリの内容を一時的に退避させる機能で、現在の変更をコミットする前に、作業ディレクトリに残しておく必要があるが、一時的に変更を消去したい場合に便利です。

下記は切り替え先のブランチに存在しないファイルがワーキングディレクトリにある状態で切り替えをしようとするとエラーが表示された際の処理です。

``` 
$ git switch sub 
error: Your local changes to the following files would be overwritten by checkout:
        test2.txt
Please commit your changes or stash them before you switch branches.
Aborting

$ git stash ←ワーキングディレクトリの変更をスタッシュに格納、saveでもok
    or
$ git stash save "コメント" 
Saved working directory and index state WIP on master: 84a9674 test2

$ git switch sub ← スタッシュに退避したおかげでブランチ切り替えが出来る　
Switched to branch 'sub'

$ git stash list
stash@{0}: WIP on master: 84a9674 test2

$ git  switch master  ←再度スタッシュしたブランチに切り替える
Switched to branch 'master'

$ git stash pop　←スタッシュの内容を復元する
On branch master
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:   test2.txt

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (52d152cf0e4706a7b9c74be5b85a03f503b4a2ca)
(venv) 
```

## 特定のファイルをGit管理下から除外する(.gitignore)
ルートディレクトリに.gitignoreファイルを作成し除外項目を記載後コミット
下記はlogというファイルが除外される。
ちなみに指定のディレクトリ配下全てを除外したい場合はフォルダ名を記載すれば良い
```
$ git add .gitignore 
$ git commit ".gitignore作成"
$ git commit -m ".gitignore作成"
```

```.gitignore
log ←ファイル名
setting ←フォルダ名
```

ただし、一度管理下に置いた場合は.gitignoreに記載するのと合わせて
下記コマンドで一旦除外する必要がある。その後は.gitignoreに記載されているので除外された状態となる。

```.gitignore
test2.txt
```

```
$ git rm --cached test2.txt 
$ git commit -m "test2.txtを管理から除外"
```

# GitHub
リポジトリにアクセスする為の秘密鍵と公開鍵を生成する。
<font color="red">**秘密鍵:id_rsa**</font>
<font color="red">**公開鍵:id_rsa.pub**</font>

ちなみに生成する際にパスフレーズという鍵を使用する際にパスワードを設定出来るが下記の通りである。
>パスフレーズを設定することで、他の人があなたの秘密鍵を不正に使用することを防止することができます。パスフレーズを設定することで、秘密鍵を使用する際に常にパスフレーズを入力する必要がありますが、その分セキュリティが高まります。

>ただし、パスフレーズを設定すると、毎回パスフレーズを入力する必要があるため、自動化されたタスクやCI/CDパイプラインのような場合に問題が発生する可能性があります。そのため、自分で使うための秘密鍵であればパスフレーズを設定することをお勧めしますが、CI/CDパイプライン用の鍵など、自動化されたプロセスで使用される秘密鍵にはパスフレーズを設定しない方が良い場合があります。


```
$ mkdir ssh
$ cd ssh
$ ssh-keygen
$ cat id_rsa.pub ←公開鍵が表示される 表示された内容をGitHubに登録する
```

-　Setting
-　SSH and GPG keysのNew SSH key
-　Add SSH key ←Titleは任意、KeytypeはAuth catで表示された内容を貼り付ける

## ローカルにリモートリポジトリのコピーを作成(Clone)
- Codeタブ画面のCodeからSSHを選択、URLをコピー
- git clone {上記URLを貼りつけ} ←リポジトリがcloneされ、コミットの履歴も確認できる
- ```$ git log --graph --all```でコミット一覧が参照可能


origin/main, origin/HEADはリモート追跡ブランチと呼ばれ
**リモートリポジトリの状態をPC上のリポジトリで保持しておくために利用されます。**
```
* commit 5a9ce890fd52a5893c87ce3504b27322c4976297 (HEAD -> main, origin/main, origin/HEAD)
```

## ローカルリポジトリの内容をリモートリポジトリに反映させる(Push)
```
remote:A--B--C(main)
↑をローカルにCloneした場合↓となる
local:A--B--C(origin/main)

ではlocalにファイル編集が加えられcommitした場合はどのようになるのかというとlocalのブランチのコミットが生成される。
remote:A--B--C(main)
local: A--B--C(origin/main)--D(main)

プッシュをすると両者のリポジトリは下記のようになる。
remote:A--B--C--D(main)
local: A--B--C--D(origin/main)(main)
```

一連の流れですがとりあえずローカルのファイルを編集してコミットします。
```
git add .
git commit -m "変更"
$ git remote -v ←originの部分がpushする際の名前となる、おそらくブランチ名に対してだと思われる
$ origin  git@github.com:ユーザー名/TestRemoteRepository.git (fetch)
$ origin  git@github.com:ユーザー名/TestRemoteRepository.git (push) ←先頭のoriginがブランチ
$ git push -u {リモートブランチ名} {ローカルブランチ名} ←例：git push -u origin main 
ブラウザにて反映されているか確認する
``` 

git push -uのオプションに関しては下記メリットがあります。
>1.簡潔なコマンドの実行が可能
-uフラグを使用することで、次回以降のプッシュコマンドにおいて、リモートブランチ名を省略することができます。つまり、git pushコマンドを実行するだけで、自動的に対応するリモートブランチにプッシュされます。これにより、簡潔なコマンド実行が可能になります。

>2.追跡状態の確認や情報の取得が容易になる
-uフラグを使用することで、現在のブランチがどのリモートブランチを追跡しているか、また、どのような設定がされているかを確認することが容易になります。例えば、git branch -vvコマンドを使用することで、現在のブランチが追跡しているリモートブランチ名や、リモートリポジトリのURLなどの情報を取得することができます。これにより、開発者はより正確かつ迅速な情報収集が可能になります。

今度はローカルの別ブランチをプッシュしてみる。
ブラウザ上でsubブランチが作成されているのが確認出来る。

```
git branch sub
git switch sub
git push -u origin sub
```

## ローカルにリモートリポジトリの変更を反映させる(fetch)
```
remote:A--B--C--D(main)
↑フェッチ前の状態で、リモートに編集点がある。
local:A--B--C(origin/main)(main)

remote:A--B--C--D(main)
↑フェッチ後の状態
local:A--B--C(main)--D(origin/main)
```


一連の流れとしてブラウザ上でファイル編集後コミットしローカルでフェッチ
<font color="red">フェッチしただけではリモートリポジトリのブランチを取得したのみでローカルに反映されない</font>
```
$ git fetch
$ git log --graph --all
* commit c5587aa4528aab02168856b37a5d6491ebca0d2c (origin/main, origin/HEAD) ←ローカルのmeinブランチが含まれていない
$ git checkout origin/main ←リモートリポジトリのブランチは変更されている事を確認出来る。
$ git switch main ←mainに戻りリモートリポジトリのブランチ内容を取り込む
$ git merge origin/main

$ git log --graph --all
* commit c5587aa4528aab02168856b37a5d6491ebca0d2c (HEAD -> main, origin/sub2, origin/main, origin/HEAD, sub2) ←取り込み完了
```

### リモートで新しいブランチを作成してローカルに取り込むケース
前提としてブラウザ上でsub2というブランチを作成している
```
$ git fetch
$ git branch ←この時点ではブランチは取り込まれていない
$ git checkout -b sub2 origin/sub2 ← sub2を取り込む
$ git branch 
```

<font color="red">**fetchはあくまでリモートリポジトリの状態を取得するのみで反映は別、リモートリポジトリの状態を確認する時等に有効**<font>


## ローカルにリモートリポジトリの変更を反映させる(Pull)
<font color="red">**pullはリモートリポジトリの状態を取得、ローカルに反映までを行う**<font>

```
remote:A--B--C--D(main)
↑プル前の状態で、リモートに変更がある。
local:A--B--C(origin/main)(main)

remote:A--B--C--D(main)
local:A--B--C--D(origin/main)(main)
```
```
$ git pull ←デフォルトはorigin/mainを取得する
```

>Gitの"pull"コマンドは、指定されたリポジトリから変更を取得し、自動的にマージするコマンドです。デフォルトでは、"pull"はリモートリポジトリの"origin"とローカルブランチの"main"をマージするために使用されますが、これはあくまでもデフォルトの動作であり、他のブランチに対しても使用することができます。
以下は、"pull"コマンドでリモートリポジトリの"origin"とブランチ"develop"から変更を取得し、ローカルブランチ"main"にマージする例です。

```
git pull origin develop:main
```

## そもそもoriginってなんでしょう
>GitHub上のリポジトリには、リモートリポジトリとして"origin"というデフォルトの名前が付けられています。"origin"は、リポジトリがクローンされた元のリモートリポジトリのことを指します。つまり、"origin"は、Gitリポジトリにおけるリモートリポジトリのデフォルトの名前であり、GitHubの場合は、リポジトリがユーザーのアカウントからクローンされた場合には、そのアカウントが"origin"になります。

>例えば、あなたが自分のGitHubアカウントで新しいリポジトリを作成し、ローカル環境にクローンする場合、"origin"という名前がリポジトリに自動的に割り当てられます。そのため、Gitコマンドでリモートリポジトリを指定する際には、通常は"origin"を使用します。

>例えば、リポジトリに変更をプッシュする場合、以下のように"push"コマンドでリモートリポジトリ"origin"に変更をプッシュすることができます。

```
git push origin main
```

>"origin"という名前は、デフォルトのリモートリポジトリ名であり、別の名前を指定することもできます。ただし、"origin"という名前が慣例的に使用されているため、ほとんどの場合、この名前が使用されます。

## プッシュの失敗ケース
両方のリポジトリに対して同一のファイルを編集しコミット、その後ローカルからpushをするとエラーが表示されます。
```
Before
remote: A--B--C(main)
local: A--B--C(origin/main)(main)

Afte:両者ともに同一ファイルの新しいコミットが有る状態でローカルからプッシュ
remote: A--B--C--D(main)
local A--B--C(origin/main)--D(main) ←Dはリモートリポジトリの内容では無くローカルで新たに作成したコミット
```

つまり、一度プルで取得してコンフリクトを発生させ、ファイルを修正後再度pushする。

```
$ git push
To github.com:suzutoh/TestRemoteRepository.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'github.com:suzutoh/TestRemoteRepository.git'

$ git config --glocal pull.rebase false ←pullの挙動をマージとする
$ git pull ←ファイルにコンフリクトが表示されるので修正する
$ git add .
$ git commit -m "修正"
$ git push
```

### 上記では一度コンフリクトを解消してからpushをしたがPC上の変更を強制的に上書きも可能 <font color="red"> ただし非推奨</font>
```
git add .
git commmit -m "変更"
git push -f ←オプションのfを入れる事で強制的にローカルの変更がリモートリポジトリに反映
```

## プルの失敗ケース
プルをした際にローカルに変更があると失敗する場合がある。
```
Before
remote: A--B(main)
local:  A--B(origin/main)--C(main) ←ローカルにCコミットがあるがプッシュはしていない

Afte:両者ともに同一ファイルの新しいコミットが有る状態でローカルからプル
remote: A--B--C(main) ←リモートリポジトリに新たにCコミットがある
local   A--B(origin/main)--C(main) 
```

下記はローカルに変更が残った状態で、pullをしエラーが表示された際の対応
ローカルの変更をstashに一時保存後、再度pullをしてスタッシュを復元してコンフリクトを発生させる。

```
$ git pull
$ git stash ←ワーキングディレクトリの変更をスタッシュに格納、saveでもok
$ git pull
$ git stash pop ←スタッシュの内容を復元する、コンフリクトが発生するのでファイルを編集する。
$ git add .
$ git commit -m "修正" ←この時点でリモートリポジトリの内容も取得し修正も出来ているのでリモートリポジトリに反映させたい場合はpushする
$ git push
$ git log --graph --all
* commit 664304bb94eb9e7c01285a5582553c2802c9379e (HEAD -> main, origin/main, origin/HEAD)
```

## 既にローカルに環境がありリモートリポジトリにプッシュしたい場合
リモートリポジトリを作成した際に表示されるコードを入れれば問題ない
特に下記によってローカルのブランチとリモートリポジトリのブランチが関連付けられます。
```
git remote add origin git@github.com:[ユーザー名]/プロジェクト名
```

<font color="blue">＊事前にローカルのmasterブランチをmainブランチにした方が良いかも</font>
```
git push -u origin main
```


# 実務フロー
## リポジトリの作成
今回はGithub Pageを使ってページを公開する為、Publicでリポジトリを作成する
settingのpagesにて下記設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326357/0c97626f-9023-0d15-86a1-152126ef4212.png)

今回は2点目標として開発者を分ける
- リポジトリの管理者であり仕事の割り当てとWebページの更新(管理者)
- Webページに写真を表示する(開発者A)
- Webページに別のページにジャンプ出来るリンクを作成(開発者B)

## 開発の流れ
- リリース用(main)と開発用(develop)を分ける
- 目標をissueに分けて見える化する
- それぞれの課題を開発者に割り当てる
- 開発者がissueを解決する開発を実施
- issueが解決されたら、開発用ブランチ(develop)に統合する
- 開発用ブランチ()の動作確認をし、リリース用ブランチ(main)に統合

### 管理者の実施内容

```
下記はブランチの作成と切り替えを同時にする
$ git checkout -b develop
```

<font color="red">**チームがdevelopブランチを使用できるようpushする、特定のブランチをプッシュする場合は下記**</font>
```
$ git push origin {ブランチ名}
```

<font color="blue">**developブランチをデフォルトブランチとして設定します。
そうすることでgit pushでdevelopに対してpushされるようになります
また、他のユーザーがcloneした際のブランチがmainからdevelopとなります。**</font>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326357/9d92698a-e1b9-dc47-559b-213c50610d54.png)

### Issueの作成
タブのIssueからNew issueにて作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326357/32d7ff23-9d88-b6d4-bd97-837a3c4e9822.png)

### 開発者A(ホームページに写真を貼りつけ)
リモートリポジトリからCloneする。
```
$ git clone git@github.com:ユーザー名/SamplePages.git
```

[ホームページに写真を貼り付ける]ためのブランチを作成
```
git checkout -b feature/picture ←ブランチ名に実施内容を含ませる
```

画像を貼り付ける、今回はプロジェクトのカレントディレクトリに画像を置いてmdを編集

```
![猫の画像](./neko.jpg)
```

git pushをしていく
```
$ git add.
$ git commit -m "ホームページに画像を貼り付ける"
$ git push origin feature/picture
```

マージするブランチを選択する、今回はfeature/picture
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326357/e4bd504d-7685-2308-b6a8-9a558e917dd3.png)
base:{マージしてもらうブランチ先}
テキストボックスには修正内容を示すコメントを記載
close #まで記載するとissueのリンクが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326357/a442ba44-855b-a790-cec5-8ede77fcb4c7.png)

- リポジトリをクローン
- developブランチに移行
- コードを作成
- 変更をプッシュ
- プルリクエスト作成

### 開発者B(別のページにジャンプ出来るリンクを作成)
リモートリポジトリからCloneする。
```
$ git clone git@github.com:ユーザー名/SamplePages.git
```

[リンクを貼り付ける]ためのブランチを作成
```
$ git checkout -b feature/addlink
```

リンクを作成し、コミットする
```
git add .
git commit -m "リンクを作成"
git push origin feature/addlink
```

A開発者と同様プルリクエストを作成する。

### 管理者
現在プルリクエストが2件なので2と表示される。
問題が無ければconfirm mergeを実施する
もう使わないbranchであれば削除する、これを繰り返す。
コンフリクトが起きてる場合編集を実施後、confirm mergeをする。
Issueを確認し、残っていればclose issueと実施する
その後developブランチとmainブランチをmergeする為のpullリクエストをする
そして再度pull requestに行きマージする。
スパーリロードはShift + 更新ボタン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326357/09d28a7e-c6a1-5fa4-dd45-587bffefdcc0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326357/ec74541b-2d9f-c172-cf1f-279fab58eef8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326357/b894221f-86bd-69b6-ee67-62a87ff5a14d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326357/407eb7f2-fa24-a379-de90-00b74e66678c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326357/2b69781b-228b-a690-5ce3-d9cc023a85c7.png)

# まとめ
- 管理者は開発者の為にdevelopブランチを作成
- 開発者にタスク振り分けのissueを作成
- 開発者はdevelopブランチからさらに機能追加項目として新たにfeatureブランチを作成
- featureブランチに新機能を入れてpush
- pushされた内容をpull requestから確認
- 問題が無ければmergeする
- 必要の無いブランチは削除


つまりブランチの数はローカルとリモートで異なる。