[GitHub/Atom] リモートブランチを追跡するローカルブランチの設定方法

[Atomエディタ](https://atom.io/)を使っていて、GitHub上で作ったリモートブランチをローカルブランチに紐付ける方法がわからなかったので、gitコマンドの使い方の備忘録です。
きっかけは、画面右下のツールバーに表示されているFetchボタンの動作。

![atom-fetch-icon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469745/acf93413-37a1-1c35-2659-90365ecc89af.png)

GitHubのリポジトリをclone後、GitHubのWeb画面上でブランチ"develop"を作成したとします。cloneしたローカルのプロジェクトをAtomで開いた時、画面右下のツールバーに表示されているFetchをクリックしても、ブランチの一覧は更新されないようです。左側の"main"と表示されているアイコンをクリックしてローカルブランチを作成しても、それをリモートの"develop"と紐づける方法が見当たらずハマりました。結局、ターミナルからgitコマンドを打って解決しました。

リモートブランチとローカルブランチを作成する順序によって、以下の３つのシナリオがあります。

- Case 1. GitHub上でブランチAを作成した。ローカルブランチBを作成した。BをAに紐付けたい
- Case 2. GitHub上でブランチAを作成した。Aに紐づいたローカルブランチAを作りたい
- Case 3. ローカルブランチCを作成した。それに紐づいたリモートブランチCをGitHubに新たに作成したい

それぞれのケースについて、gitコマンドの操作を以下に書きます。動作環境は、macOS Big Sur 11.6.1, git 2.30.1 (Apple Git-130), Atom 1.58.0 （記事執筆時）です。

## Case 1. GitHub上でブランチAを作成した。ローカルブランチBを作成した。BをAに紐付けたい
GitHub上でブランチ"develop-1"を作成したとします。リポジトリをローカルにcloneした直後の状態は、

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

nothing to commit, working tree clean
```

git branchコマンドに-aと-vvオプションを付けて、ローカルとリモートのブランチの一覧を表示します。-vvを付けるとローカルブランチに対する追跡先のリモートブランチが判ります。※出力例の右側に表示されるテキストは「.....」で省略して表記しました。

```shell-session
$ git branch -a -vv
* main                     39f971a [origin/main] .....
  remotes/origin/HEAD      -> origin/main
  remotes/origin/develop-1 39f971a .....
  remotes/origin/main      39f971a .....
```

ここで、Atomエディタでローカルブランチ"local-dev-1"を作成してみます。

```shell-session
$ git status
On branch local-dev-1
nothing to commit, working tree clean
```

```shell-session
$ git branch -a -vv
* local-dev-1              39f971a .....
  main                     39f971a [origin/main] .....
  remotes/origin/HEAD      -> origin/main
  remotes/origin/develop-1 39f971a .....
  remotes/origin/main      39f971a .....
```

まだリモートブランチには紐づいていません。local-dev-1でdevelop-1を追跡させるには、-uオプション(--set-upstream-to)を使います。

```shell-session
$ git branch -u origin/develop-1
Branch 'local-dev-1' set up to track remote branch 'develop-1' from 'origin'.
```

```shell-session
$ git branch -a -vv
* local-dev-1              39f971a [origin/develop-1] .....
  main                     39f971a [origin/main] .....
  remotes/origin/HEAD      -> origin/main
  remotes/origin/develop-1 39f971a .....
  remotes/origin/main      39f971a .....
```

## Case 2. GitHub上でブランチAを作成した。Aに紐づいたローカルブランチAを作りたい
GitHub上でブランチ"develop-x"を作成したとします。

```shell-session
$ git branch -a -vv
* main                     39f971a [origin/main] .....
  remotes/origin/HEAD      -> origin/main
  remotes/origin/develop-x 39f971a .....
  remotes/origin/main      39f971a .....
```

この状態から、"origin/develop-x"を追跡するローカルブランチ"develop-x"を作る方法は２つあります。

### 方法1. fetchしてcheckoutする

```shell-session
$ git fetch origin develop-x
From https://github.com/kazhashimoto/test-branch
 * branch            develop-x  -> FETCH_HEAD
```

```shell-session
$ git checkout develop-x
Branch 'develop-x' set up to track remote branch 'develop-x' from 'origin'.
Switched to a new branch 'develop-x'
```

### 方法2.  --trackオプションを使う

```shell-session
$ git checkout --track origin/develop-x
Branch 'develop-x' set up to track remote branch 'develop-x' from 'origin'.
Switched to a new branch 'develop-x'
```

いずれの方法も結果は、

```shell-session
$ git branch -a -vv
* develop-x                39f971a [origin/develop-x] .....
  main                     39f971a [origin/main] .....
  remotes/origin/HEAD      -> origin/main
  remotes/origin/develop-x 39f971a .....
  remotes/origin/main      39f971a .....
```

## Case 3. ローカルブランチCを作成した。それに紐づいたリモートブランチCをGitHubに新たに作成したい
ローカルにブランチ"my-local-dev"を作ったとします。

```shell-session
$ git status
On branch my-local-dev
nothing to commit, working tree clean
```

```shell-session
$ git branch -a -vv
  main                39f971a [origin/main] .....
* my-local-dev        39f971a .....
  remotes/origin/HEAD -> origin/main
  remotes/origin/main 39f971a .....
```

pushコマンドに-uオプションを付けて実行します。

```shell-session
$ git push -u origin my-local-dev
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
remote: 
remote: Create a pull request for 'my-local-dev' on GitHub by visiting:
remote:      https://github.com/kazhashimoto/test-branch/pull/new/my-local-dev
remote: 
To https://github.com/kazhashimoto/test-branch.git
 * [new branch]      my-local-dev -> my-local-dev
Branch 'my-local-dev' set up to track remote branch 'my-local-dev' from 'origin'.
```

リモートに"my-local-dev"が作られ、ローカルの"my-local-dev"がそれを追跡するようになります。

```shell-session
$ git branch -a -vv
  main                        39f971a [origin/main] .....
* my-local-dev                39f971a [origin/my-local-dev] .....
  remotes/origin/HEAD         -> origin/main
  remotes/origin/main         39f971a .....
  remotes/origin/my-local-dev 39f971a .....
```

## まとめ

**Case 1. GitHub上でブランチAを作成した。ローカルブランチBを作成した。BをAに紐付けたい**

:::note info
（ローカルのbranchBで）
git branch -u origin/branchA
:::

**Case 2. GitHub上でブランチAを作成した。Aに紐づいたローカルブランチAを作りたい**

:::note info
git fetch origin branchA
git checkout branchA
:::

または

:::note info
git checkout --track origin/branchA
:::


**Case 3. ローカルブランチCを作成した。それに紐づいたリモートブランチCをGitHubに新たに作成したい**

:::note info
（ローカルのbranchCで）
git push -u origin branchC
:::

## 参考にした記事
この記事を書くにあたって、以下のサイトを参考にさせていただきました。

[【Git】リモートブランチをチェックアウトしたいときは「git fetch origin <ブランチ名>」と「git checkout <ブランチ名>」を実行すれば良い](https://dev.classmethod.jp/articles/how-to-checkout-remote-branch/)

[How can I tell a local branch to track a remote branch?](https://www.git-tower.com/learn/git/faq/track-remote-upstream-branch)