2つのGitリポジトリをマージする

今回も 100% 自分のためのメモです。仕事で２つのGitリポジトリをマージして新しいリポジトリを作る必要がありました。コマンドの意味のいくつかを理解していなかったので、調べてメモしておきます。

# 自分の理解にポイントを置く

普段はこのレベルのは書かなかったですが、結城さんの一連のポストが素晴らしく、見習ってみることにしました。特に「自分の理解にポイントを置く」というのは、私におそらくもっとも足りていないことと思っています。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">（自分の勉強法でいいのか）<br><br>あなたの質問の中で「5分考えて何も思いつかない」というところが気になりました。いつも「5分」でタイムアウトするのはいいことなのかなと思ったからです。また「考えて何も思いつかない」というのは、（続く）<a href="https://t.co/0CSFZX0e8g">https://t.co/0CSFZX0e8g</a> <a href="https://t.co/5APJBrbawm">pic.twitter.com/5APJBrbawm</a></p>&mdash; 結城浩 (@hyuki) <a href="https://twitter.com/hyuki/status/968033552297115648?ref_src=twsrc%5Etfw">2018年2月26日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

こちらも神回答だったのでメモしておきます。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">（勉強法）<br><br>勉強法は、最近よく「結城メルマガ」に出てきてたかも。具体的な「方法」はどうでもよくて（よくないですけど）、勉強を何のためにしてるのかを自問するといいです。ノートを文字で埋めることが目的なのではなくて、自分が理解することが目的ですよね。なので、<a href="https://t.co/0CSFZX0e8g">https://t.co/0CSFZX0e8g</a> <a href="https://t.co/HLyDmPIZJS">pic.twitter.com/HLyDmPIZJS</a></p>&mdash; 結城浩 (@hyuki) <a href="https://twitter.com/hyuki/status/967644379891445760?ref_src=twsrc%5Etfw">2018年2月25日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# リポジトリのマージコマンド

最初に新しく作ったリポジトリをクローンします。

```
git clone git@github.com:Azure-Samples/OpenHack-DevOps.git

```

次に、元のリポジトリを リモートリポジトリの Upstream に指定　　`git remote add REMOTE_NAME URL` ですな。

```
git remote add upstream git@github.com:Azure-Samples/MyDriving.git
```

次に fetch するとそのリポジトリから読み込みます。`fetch` コマンドは、別のリポジトリから読み込むためのコマンドです。`git fetch REMOTE_NAME` ですね。すると、読み込み元のブランチも一緒にローカルのブランチとして作成されます。

```
 git fetch upstream
Enter passphrase for key '/c/Users/tsushi/.ssh/id_rsa':
warning: no common commits
remote: Counting objects: 17127, done.
remote: Total 17127 (delta 0), reused 0 (delta 0), pack-reused 17127
Receiving objects: 100% (17127/17127), 19.79 MiB | 1.14 MiB/s, done.
Resolving deltas: 100% (12667/12667), done.
From github.com:Azure-Samples/MyDriving
 * [new branch]      Fix513         -> upstream/Fix513
 * [new branch]      FixUWPCrash    -> upstream/FixUWPCrash
 * [new branch]      MotzTR         -> upstream/MotzTR
 * [new branch]      NicoleBugFix   -> upstream/NicoleBugFix
 * [new branch]      NicoleBugFixBK -> upstream/NicoleBugFixBK
 * [new branch]      VJTest         -> upstream/VJTest
 * [new branch]      dev            -> upstream/dev
 * [new branch]      evolve         -> upstream/evolve
 * [new branch]      feature/evolve -> upstream/feature/evolve
 * [new branch]      feature/motztr -> upstream/feature/motztr
 * [new branch]      master         -> upstream/master
 * [new branch]      motz           -> upstream/motz
```
ターゲットのブランチを選んで、自分のところの`master` にマージします。 普通に merge をするとこけます。他のリポジトリからマージするので、git 2.9 以降からエラーになるようです。`--allow-unrelated-histories` オプションをつけるとマージが出来ます。

```
git merge --allow-unrelated-histories upstream/master
Auto-merging README.md
CONFLICT (add/add): Merge conflict in README.md
Auto-merging .gitignore
CONFLICT (add/add): Merge conflict in .gitignore
Automatic merge failed; fix conflicts and then commit the result.
```

ちなみに merge のコンフリクト解消には、VSCode がとても便利でした。プラグインでリンクをクリックするだけでどっちを採用するか決められました。

```
git add .
git commit -m "Some reason"
git push -u origin master
```

後はお約束の紺などですが、`git push -u ` のオプションがいる理由です。`-u` は、upstream を指定するオプションです。upstream を指定したので、２つある状態なので、`origin` の方を指定する必要がありそうです。

ちなみに、リモートが二つある場合は、間違えて、upstream の方にpushしてしまったりしないでしょうか？`git push -u` で、デフォルトのリモートが設定されます。`.git/config` を見てどういう設定になったのかを見てみましょう。

```
$ cat .git/config
[core]
        repositoryformatversion = 0
        filemode = false
        bare = false
        logallrefupdates = true
        symlinks = false
        ignorecase = true
[remote "origin"]
        url = git@github.com:Azure-Samples/OpenHack-DevOps.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master
[remote "upstream"]
        url = git@github.com:Azure-Samples/MyDriving.git
        fetch = +refs/heads/*:refs/remotes/upstream/*

```

なるほど、しっかりと、`master` ブランチのリモートが `origin` に設定されていますね。
よし、理解した。

# Resource 

* [Git で複数のリポジトリをまとめたり、逆に切り出したりする](https://qiita.com/uasi/items/77d41698630fef012f82)
* [初めてGitHubリポジトリにpushしたらrejectedエラーになったときの対応メモ](https://qiita.com/takanatsu/items/fc89de9bd11148da1438)
* [リモートリポジトリの登録とデフォルトリモートブランチの設定](https://qiita.com/shyamahira/items/cf8f36e4b2500f82b2bf)