Gitのリモートリポジトリをローカル環境に作成，後からpush先をSSH先(Github, Devops等)に変更

# 経緯
- 個人開発の場合はcommitだけで正直事足りるが，いつもと同様のルールでバージョン管理したい
- どうしても生まれる裏作業内容や秘匿性の高いソースコードを個人でバージョン管理したい
- アジャイル開発に必須だと思うGitの勉強(時間がない時修正箇所にconflictができて迷惑をかけた経験)

# Gitでリモートリポジトリをローカル環境に作成
基本は以下(リモートを先に立てて，git clone)を参考したが，
今回は既にローカルが存在することを前提としたい．
`remote add`する形でリモートリポジトリを作成する．

https://qiita.com/masatomix/items/19f4604c939567929ee8

以下のローカルリポジトリが既に存在するとする．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421973/bdf966f6-1f6a-dd4c-8d31-d2b3a130955f.png)

空のリモートリポジトリを任意のディレクトリに作成．
```bash
mkdir gitserver
cd gitserver
git init --bare --shared ./hoge.git  # gitファイル名はオプション
```

```bash
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint:   git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint:   git branch -m <name>
Initialized empty shared Git repository in /.../gitserver/hoge.git/
```

ローカルリポジトリをリモートリポジトリへ反映する．

```bash
git remote add origin /.../gitserver/hoge.git
git config -l
```

```bash
user.name=...
user.email=...
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
remote.origin.url=/.../gitserver/hoge.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
```

### push
以下の状態でpushを試すと当然developブランチが無いので警告が出るのでOKする．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421973/c28d37a8-0b84-187e-a3f9-6edf1ff0136e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421973/da44eb38-f284-7c93-923e-151981565a8d.png)

### clone
VSCode上でbranchをdevelopに切り替えると，無事cloneできていることがわかった．
しかし，当然developブランチしか紐付かないので，以下のように一直線になった．

```bash
mkdir local2 && cd $_
git clone /.../gitserver/hoge.git/
```

```bash
Cloning into '2024_VSCode_Git_Github_test'...
done.
warning: remote HEAD refers to nonexistent ref, unable to checkout.
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421973/6639569e-fc67-7137-eae4-a33bf8bd232a.png)

~~やはり最初から計画的にリモートリポジトリを作って`git clone`する方が自然かも．~~
以下で解決．

```bash
git push --all
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To /.../gitserver/hoge.git
 * [new branch]      main -> main
 * [new branch]      master -> master
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421973/8ce3f887-9247-eebc-48e6-9b00037aae24.png)


追記：後々調べたら以上までの点で同じようなことを試した方がいらっしゃった．

https://maru-note.net/entry/2022/06/11/235528

https://qiita.com/tom_eng_ltd/items/9784ce55eb643657e3ef


# 後からpush先をSSH先(Github, Devops等)に変更
ローカルリポジトリのpush先`remote.origin.url`を，上のローカルPC内リモートリポジトリからSSH先(Github, Devops等)に変更したい．

```bash
git remote set-url origin (Githubで作ったリモートリポジトリURL)
git push --all
```
mainだけ後からGithub上につくったせいで順番が逆になったが，master, developはOK
```bash
Enumerating objects: 17, done.
Counting objects: 100% (17/17), done.
Delta compression using up to 16 threads
Compressing objects: 100% (9/9), done.
Writing objects: 100% (17/17), 1.18 KiB | 604.00 KiB/s, done.
Total 17 (delta 3), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (3/3), done.
To https://github.com/.../test.git
 * [new branch]      develop -> develop
 * [new branch]      master -> master
 ! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'https://github.com/.../test.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. Check out this branch and integrate the remote changes
hint: (e.g. 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421973/77c5edc7-0575-7725-af72-3892f3c67a36.png)


# 所感
リモート作ってからローカル作る方が自然かもしれないが，
今後はローカルである程度commitできたら，ローカルPCにGit用サーバー立てて，
リモートリポジトリでバージョン管理するようにしても良いと思う．

上記の逆はどうするのか？：
開発にOSSを使う目的で，OSS自体の機能追加はしたくない
（例えば，このOSSアルゴリズムを使ったROSの開発をするときに，
　挙動を確認するために評価スクリプトを作った時）
➡そのコードをForkせずcloneしたとき，
ただその開発成果を公知したい場合，元のOSSもフリーだから，
全く別のリポジトリに挙げても問題ないと思うのだが，
その場合も`git remote set-url origin`すればよいのだろうか？
もちろん開発途中はPrivate repositoryになると思うが，本当のcontributor情報は残したい
あと，.gitが入れ子になったときの挙動等，まだまだわからないことがいっぱい．
とりあえずこういう場合はOSS側の.gitを消すのが良いのか．

ここら辺？↓

https://qiita.com/S42100254h/items/fcbead402f711c091f8b

https://yuito-blog.com/repository-change/