サーバーなしローカル環境でGitによるお手軽バージョン管理

# 目的

- 今どき開発するのだからバージョン管理は最低限やりたい
- だけど、顧客環境での開発で制限が多く、Githubすら使えない
- 少人数プロジェクトのためGitに詳しい人間もあまりいない

っていうこと、けっこうあるんじゃないかと思います
そういうプロジェクトのために、Gitによるお手軽環境構築手順を作ってみました

# 最終的に実現したいディレクトリ構成
同じサーバーに、複数人で同時にアクセスするような状況を想定しています
- project1 ：開発環境
- project.gitディレクトリ：管理用リポジトリ置き場
- kimuraディレクトリ：kimuraさんの開発環境
- tanakaディレクトリ：tanakaさんの開発環境

```
$ tree
.
├── kimura
│   └── project1
│       ├── aaa.txt
│       └── bbb.txt
├── tanaka
│   └── project1
│       ├── aaa.txt
│       └── bbb.txt
├── project.git
│   ├── HEAD
│   ├── branches
│   ├── config
│   ├── description
│   ├── hooks
（以下省略）

18 directories, 26 files
```

# 環境構築

### 1.管理用リポジトリ(project.git)を作る

```
$ mkdir project.git
$ cd project.git
$ git init --bare
Initialized empty Git repository in /hogehoge/project.git/
```

### 2.開発者用ディレクトリを作る(kimuraさん)
gitのコミットにはユーザー名とメールアドレスが必須なので、設定します
ローカル環境前提なので、`git config --local` とします
```
$ git clone ./project.git kimura
Cloning into 'kimura'...
warning: You appear to have cloned an empty repository.
done.
$ cd kimura
$ git config --local user.name "kimura"
$ git config --local user.email "kimura@mail.com"
```

### 3.開発者用ディレクトリに成果物をコピーする
kimuraディレクトリ配下に開発ソースをまるっとコピーする
こんな構成になったとする
```
$ tree kimura/
kimura/
└── project1
    ├── aaa.txt
    └── bbb.txt

1 directory, 2 files
```

### 4.ローカルのマスターブランチにcommitする
gitのcommitにはコメントが必須です
```
$ cd kimura
$ git add .
$ git commit -m "My First Commit"
[master (root-commit) d9b6109] My First Commit
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 project1/aaa.txt
 create mode 100644 project1/bbb.txt
```

### 5.リモートのマスターブランチにpushする
pushすることによって、project.gitディレクトリに変更が反映されます
```
$ git push
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 2 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 259 bytes | 25.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To /hogehoge/./project.git
 * [new branch]      master -> master
```

### 6.開発者用ディレクトリを作る(tanakaさん)
2と同じ手順です
ただし今はproject1ディレクトリがpushされた後なので、tanakaさんディレクトリ配下にもproject1ディレクトリが見えることになります

```
$ git clone ./project.git/ tanaka
Cloning into 'tanaka'...
done.
$ cd tanaka/
$ git config --local user.name "tanaka"
$ git config --local user.email "tanaka@mail.com"
$ tree
.
└── project1
    ├── aaa.txt
    └── bbb.txt

1 directory, 2 files
```

これで開発環境構築は完了です
ユーザーを増やしたいときは6の手順を人数分増やせばOKです

# 開発
git flowを使ってもいいのですが、gitに慣れていない少人数前提なので、`master`ブランチと`develop`ブランチだけを用意する形式にしてみます
- masterブランチ：本番運用されているソース
- developブランチ：開発中のソース


### 1.developブランチをpush
`master` ブランチは環境構築ですでに出来上がっているので、 `develop`ブランチを作ってproject.gitにpushします

```
$ cd kimura
$ git checkout -b develop master
Switched to a new branch 'develop'
$ git push --set-upstream origin develop
Total 0 (delta 0), reused 0 (delta 0)
To /hogehoge/./project.git
 * [new branch]      develop -> develop
Branch 'develop' set up to track remote branch 'develop' from 'origin'.
```

### 2.他の開発者(tanaka)もdevelopブランチをcheckout
```
$ cd tanaka
$ git checkout develop
Branch 'develop' set up to track remote branch 'develop' from 'origin'.
Switched to a new branch 'develop'
```

基本的にはこの、developブランチがチェックアウトされた状態で開発します

- ローカルでファイルを保存しておきたい場合：git add して git commitまで

```kimuraさんがbbb.txtファイルを修正したとする
$ cd kimura
$ git add .
$ git commit -m "Modify bbb.txt"
[develop bc83a40] Modify bbb.txt
 1 file changed, 1 insertion(+)
```

- ローカルの修正をproject.gitに反映させたい場合：git addして git commit後、pushする
```tanakaさんがaaa.txtファイルを修正したとする
$ cd tanaka
$ git add .
$ git commit -m "Modify aaa.txt"
git add .
[develop 7b350d2] Modify aaa.txt
 1 file changed, 1 insertion(+)
$ git push origin develop
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 2 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 325 bytes | 325.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To /hogehoge/project.git/
   d9b6109..7b350d2  develop -> develop
```

- 前回のcommitから修正を一つもしていない場合は、git pushだけでOK
```kimuraさんがcommitしたbbb.txtをpush
$ git push origin develop
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 2 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 325 bytes | 325.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To /hogehoge/project.git/
   d9b6109..7b350d2  develop -> develop
```
なお、pushの際に誰かがすでにproject.gitに反映している場合は、こんなエラーになります
```
$ git push origin develop
To /hogehoge/./project.git
 ! [rejected]        develop -> develop (fetch first)
error: failed to push some refs to '/hogehoge/./project.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first 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.
```
この場合は次の手順（マージ）を先にしましょう

- project.gitの内容をローカルに反映（マージ）させたい場合
事前にローカルの内容を保存(commit)しておくほうが良いでしょう
fast fowardでない場合（誰かと同時編集している場合）はpullのタイミングでマージcommitされます

```project.gitの反映をローカルに反映
$ git pull origin develop
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 4 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (4/4), 305 bytes | 305.00 KiB/s, done.
From /hogehoge/./project
 * branch            develop    -> FETCH_HEAD
   d9b6109..7b350d2  develop    -> origin/develop
Merge made by the 'recursive' strategy.
 project1/aaa.txt | 1 +
 1 file changed, 1 insertion(+)
```
これはcommitされている状態なので、マージした内容をproject.gitに反映したい場合はpushしてください

# 本番適用
developで実装完了したものをmasterにマージします
基本的にmasterブランチは一人で触るもののため、fast forwardされるはずで、commitはされないはずです
masterブランチで間違って開発しないように、最後にdevelopブランチにcheckoutし直しておきます
```
$ cd kimura
$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
$ git pull origin master
$ git merge develop
Updating d9b6109..42259f3
Fast-forward
 project1/aaa.txt | 1 +
 project1/bbb.txt | 1 +
 2 files changed, 2 insertions(+)
$ git push origin master
Total 0 (delta 0), reused 0 (delta 0)
To /hogehoge/./project.git
   d9b6109..42259f3  master -> master
$ git checkout develop
Switched to branch 'develop'
Your branch is up to date with 'origin/develop'.
```

# おわりに
基本的な使い方しか書いていないため、こういう時どうする？というのは随時検索してみてください
バージョン管理のないプロジェクトが撲滅されますように

## 参考

https://qiita.com/devzooiiooz/items/56a02342d9d65d79f6c3