独自ルール:多人数開発のためのグループプロジェクトについて

【[自分とこの環境下におけるGit & GitLabレクチャー](https://qiita.com/NeK/items/dee76f411cf2488b6873)】

グループプロジェクトに関わる人達に向けて．大きく分けると以下の利用が考えられる．

* プロジェクト立ち上げ側
* プロジェクト利用側
    * 単に使いたい
    * 自分のプロジェクトの一部として使いたい
    * 使いながら追加・修正し，もとのプロジェクトに貢献もしたい
        * プロジェクト開発にも関わる

# プロジェクトの立ち上げ側
流れとしては以下のようになる．

1. 個人プロジェクトとして作成．
- 共有したいプロジェクトが出てきたらグループプロジェクトに変更

後輩などに自分のプロジェクトを使用してもらいたくなった場合，個人プロジェクトからcloneすると面倒になる．
そのような要求が出始めたらグループプロジェクトにしましょう，という話である．

### グループプロジェクトへの変更方法
~~フォークを使用する．~~(自分のプロジェクトだとできない)
プロジェクトの転送を使用する．

#### GitLabでの作業
1. 左ペインの[設定]-[一般]から[高度な設定]を展開
1. プロジェクトを転送

#### 立ち上げ者のローカルでの作業
git pushやpullのアドレスが合わるのでURLを更新する．
やり方としては

* git cloneをし直す
* git remoteでoriginのアドレスを更新する

のどちらか．git remoteを使用する場合は以下の通り．

```
$ git remote set-url origin [グループプロジェクトの新URL]
```

ここでグループプロジェクトのURLはGitLabの『クローンする』で出てくるgit@から始まるもの．

# プロジェクト利用側
以下の例のもとに説明する．

* ワークスペースやプロジェクトを置きたいディレクトリ
    * 名前を[ws]
* プロジェクト
    * 名前を[proj]や[my_proj]
* プロジェクト内部の一部のディレクトリ・ファイルなど
    * 名前を[dirfile]など
* プロジェクトのURL
    * 名前を[group_url]

## 単に使いたい
とりあえず難しく考えずに使いたかったり，プロジェクト自体が完結しているのでそのまま使える場合を想定する．

### 手順

```bash
$ cd [ws]
$ git clone [group_url]
```

### 手順:ちょっと凝った手順
clone時に全部DLするのではなく，必要なもののみをDLする方法．
参考:[Gitの一部のディレクトリだけ取得する方法](https://qiita.com/ponsuke0531/items/1e0ab0d6845ec93a0dc0)

```bash
$ cd [ws]
$ git init
$ git config core.sparsecheckout true
$ echo [dirfile] >> .git/info/sparse-checkout # sparse-checkoutの中に記述されてるもののみをDL．複数の場合は複数行記述．
$ git remote add origin [group_url]
$ git pull origin main
```

## 自分のプロジェクトの一部として使いたい
外部のプロジェクトを自分のプロジェクトの一部として使いたい．そのプロジェクトの管理は外部に任せて，自分ではいじらない．
git cloneで持ってきちゃうとオリジナルと持ってきたもので2重になり管理が大変．そんなことはしたくない場合に使用．
基本的にROS2システムの場合，様々なパッケージ(プロジェクト)を寄せ集めて一つのやりたいこと(ワークスペース)をしているので，この使い方になりそう．
参考:

* [依存リポジトリ管理でのsubmodule/subtree/subrepoの使い分け](https://qiita.com/horimislime/items/577b6de47f2e897b4e2a)

### 手順
基本的に自分のプロジェクト[my_proj]があり，その中に外部のプロジェクト[group_url]([proj])を取り込む．
前提として自分のプロジェクトが既に存在し設定していること．

#### 設定
設定しただけでは外部のプロジェクトの中身は空っぽです．

```bash
$ cd [my_proj]
$ git submodule add [group_url]
```

#### 使用
外部プロジェクトのDL．

```bash
$ git submodule init
$ git submodule update
```

外部プロジェクトのアップデート．
(外部プロジェクトが下位互換のないアップデートすることもあるので注意．タグやコミットIDで指定できるのでなんともならないことにはならないけど．)

```bash
$ cd [submoduleとしてaddしたプロジェクトのディレクトリ]
$ git fetch
$ git merge origin/main
```

<details><summary>外部プロジェクトのアップデート:間違いの修正</summary>2020/08/08(タコの日)までコマンドを間違えて`git submodule fetch, git submodule merge origin/main`としていたので修正</details>


### 手順:ちょっと凝った手順
clone時に全部DLするのではなく，必要なもののみをDLする方法．
参考:[Git 特定のフォルダのみcloneする submodule編](https://qiita.com/icoxfog417/items/89e55947e9e8f2c16077)
むしろsubmoduleにこそ必要なもののみDLすることが重要．

```bash
$ cd [ws]
$ git submodule add [group_url]
$ git commit -m "Added module"
$ git cd [group_urlのディレクトリ]
$ git config core.sparsecheckout true
$ echo [dirfile] >> ../.git/modules/[group_urlのプロジェクト名]/info/sparse-checkout # sparse-checkoutの中に記述されてるもののみをDL．複数の場合は複数行記述．
$ git read-tree -mu HEAD
```

lsなどで都度確認すると，git read-treeで必要なディレクトリ以外確かに見えなくなっている．

## 使いながら追加・修正し，もとのプロジェクトに貢献もしたい
外部のプロジェクトを使いながら，中身を追加・修正しもとのプロジェクトに貢献したい偉い人用．
基本的にROS2システムの場合，様々なパッケージ(プロジェクト)を寄せ集めて一つのやりたいこと(ワークスペース)をしているので，この使い方になりそう．

### 手順:自分の好みのままにいじってみたい場合
GitLab上にて，グループプロジェクトを自分の個人プロジェクトとしてForkしていじる．
その中で他人にも使えそうなものは，グループプロジェクトにマージリクエストして還元する．

### 手順:自分のプロジェクトの一部として使用していく場合
基本的に自分のプロジェクト[my_proj]があり，その中に外部のプロジェクト[group_url]([proj])を取り込む．
前提として自分のプロジェクトが既に存在し設定していること．
またremote addでつける名前はなんでもいいが，ここでは[out_name]とし，取り込むディレクトリを[out_dir]で説明．
参考:

* [依存リポジトリ管理でのsubmodule/subtree/subrepoの使い分け](https://qiita.com/horimislime/items/577b6de47f2e897b4e2a)
* [Git Subtree 事始め](https://qiita.com/mikakane/items/487ca8b3acddfa5fdb41)
* [git subtreeの練習](https://hail2u.net/blog/software/git-subtree-training.html)

#### 設定

```bash
$ cd [my_proj]
$ git remote add [out_name] [group_url]
$ git subtree add --prefix [out_dir] [out_name] main --squash
```

### 更新

```bash
$ git pull -s subtree --squash [out_name] main
```


# その他:他の人のプロジェクトを見るためには
グループプロジェクトを選択した状態で左ペインにある「メンバー」をクリックすると参加しているメンバー一覧を見ることができる．そこからメンバーをクリックすると各メンバーのページに飛び，そのメンバーが持っているプロジェクトを見ることができる．
なお，universal_toolsのグループプロジェクトには全員を登録している(つもり)なので，他のプロジェクトに参加している人にアクセスしたい場合はこちらのグループプロジェクトを参照のこと．