本番運用しているサーバーにgit/GitHubを導入するときのベストプラクティスとマサカリ

# 本番運用しているphp/Laravelサーバーにgitを入れたいんだけどこれであってるのかな。

こんにちは！ @ykhirao です！本番サーバーにFTPでぽちぽちアップロードしている現状ですが、 `ssh production` `git pull origin master` とかで本番コードを反映させたいなと夢みたいなことを考えています。適当に考えたベストプラクティス（たたき台ともいう）を投稿するのでマサカリください！！！！！

## 手順の大まかなながれ

だいたいこんな状況を仮定すると

- ローカルブランチにgitを導入して、GitHubにpushする
- GitHubのレポジトリがあるし、masterブランチで最新になっている
- 本番コードはだいたいmasterブランチと同じ、一部デプロイ忘れとかある

こんなものかなと思う。それに対してやることは

- サーバー上で `ssh key-gen` して公開鍵・秘密鍵を作成する
- GitHubでデプロイキーを登録する（GitHubにデプロイユーザーとか作らなくていいよ！）
- .gitignoreが適切に設定されているか確認する
- 特に.envファイルとか、storageフォルダとか、DB以外に本番とローカル環境で違うものがないかよく確認する

とかでしょうか。

## 実際の動作で確認する

GitHubにレポジトリ作るのを省略するためにlocalにremote addする。
GitHubとして読み解いてほしい。

```bash
yk@yk local % git remote add origin /Users/yk/server/project.git
yk@yk local % cd ..                 
yk@yk server % ls
local	prod
yk@yk server % git clone --bare local project.git 
Cloning into bare repository 'project.git'...
done.
yk@yk server % cd local 
yk@yk local % git push origin master                            
Everything up-to-date
```

prodフォルダにcloneしてくる！！で `.git` フォルダを削除して、git管理下に置かれてない状況に戻す。

```bash
yk@yk server % cd prod
yk@yk prod % ls
yk@yk prod % git clone /Users/yk/server/project.git .
Cloning into '.'...
done.
yk@yk prod % ll
total 8
drwxr-xr-x   5 yk  staff  160  7 11 01:54 .
drwxr-xr-x   5 yk  staff  160  7 11 01:51 ..
drwxr-xr-x  12 yk  staff  384  7 11 01:54 .git
-rw-r--r--   1 yk  staff   16  7 11 01:54 .gitignore
-rw-r--r--   1 yk  staff    0  7 11 01:54 README.md

yk@yk prod % rm -fr .git

# 本番ではstorageフォルダに画像がたくさん溜まっていることを仮定
yk@yk prod % mkdir storage
yk@yk prod % touch storage/image-prod.jpg
yk@yk prod % touch storage/image-prod2.jpg
yk@yk prod % touch storage/image-prod3.jpg

# .envファイル を本番用に書き換え
yk@yk prod % vim .env
yk@yk prod % cat .env 
APP=prod
```

いろいろlocalで作業した！

```bash
yk@yk server % cd local 

yk@yk local % echo "# README.md を追記" >> README.md 

yk@yk local % git diff
diff --git a/README.md b/README.md
index e69de29..7039b84 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1 @@
+# README.md を追記

yk@yk local % git commit -am "Update"
[master 1b9e11d] Update
 1 file changed, 1 insertion(+)

yk@yk local % git push origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 298 bytes | 298.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /Users/yk/server/project.git
   cf9a63e..1b9e11d  master -> master
```

さてこの状況で本番にgitを導入しようと思います。

- 少しlocalのほうが進んでいる
- .envファイルが書き換わるとまずい
- storage配下に画像たくさんあるけど.gitignoreしているから大丈夫なんだっけ？

とかそんな感じの疑問を抱えつつ、見てみます。

サーバーで `ssh-keygen` をして 公開鍵を GitHubのこのあたりhttps://github.com/XXXXX/XXXXX/settings/keys に登録すると、privateレポジトリでも、いい感じにpullとかできるようになります。デプロイユーザーとかをGitHubに登録しなくても大丈夫です。


本番のプロジェクトにはgit initされていない状態を確認する。

```bash
yk@yk prod % git log
fatal: not a git repository (or any of the parent directories): .git
```

```bash
yk@yk prod % git init 
Initialized empty Git repository in /Users/yk/server/prod/.git/
yk@yk prod % git log
fatal: your current branch 'master' does not have any commits yet
```

masterブランチもないし、操作できない状態なので、remoteでGitHubとかを指定して、pullしてきましょう。

```bash
yk@yk prod % git remote add origin /Users/yk/server/project.git 
yk@yk prod % git pull origin master
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 7 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (7/7), 516 bytes | 103.00 KiB/s, done.
From /Users/yk/server/project
 * branch            master     -> FETCH_HEAD
 * [new branch]      master     -> origin/master
error: The following untracked working tree files would be overwritten by merge:
	.gitignore
	README.md
Please move or remove them before you merge.
Aborting
```


いい感じ。


```bash
yk@yk prod % git log
fatal: your current branch 'master' does not have any commits yet
yk@yk prod % git status                   
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	.gitignore
	README.md

nothing added to commit but untracked files present (use "git add" to track)
```

まだlogも見れないのでブランチを切り替えて一旦コミットする

```bash
yk@yk prod % git checkout -b master-backup
Switched to a new branch 'master-backup'
yk@yk prod % git add .
yk@yk prod % git commit -m "マスターのバックアップ"
[master-backup (root-commit) a6fd38c] マスターのバックアップ
 2 files changed, 3 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 README.md

yk@yk prod % git branch
* master-backup
```

大丈夫そう。masterにチェックアウトしてみる


```bash
yk@yk prod % git checkout master
Branch 'master' set up to track remote branch 'master' from 'origin'.
Switched to a new branch 'master'

yk@yk prod % git log
commit 1b9e11d15bda2ecdec75a8d205bdbdec185a9388 (HEAD -> master, origin/master)
Author: Yuki <yuki@example.com>
Date:   Sat Jul 11 02:01:05 2020 +0900

    Update

commit cf9a63ebb4676faa949aa29a9fdf56244ed313d0
Author: Yuki <yuki@example.com>
Date:   Sat Jul 11 01:48:36 2020 +0900

    init
```

`Update` という変更はまだ `prod` フォルダには適応させてなかったのに、きちんとpullされていることがわかりますね！
これで最新ブランチの適応はOKかと思います。

```bash
yk@yk prod % cat .env 
APP=prod
yk@yk prod % ls storage 
image-prod.jpg	image-prod2.jpg	image-prod3.jpg
```

`.env` ファイルとか `storage/` とか `.gitignore` に記述しているものは書き換わってないことがわかります。
もちろんlocalファイルは `AA=local` ときちんとなったままです。

```bash
yk@yk prod % cat ../local/.env 
APP=local
```

## まとめ

こんな感じでサーバー上で `git init` して `remote add` `checkout -b` `git add .` `git commit` `git checkout master` って流れでいい感じにgit適応できる気がしたのです。

あまりこのあたりちゃんとまとめられてなかったので、サーバー運用得意な方いたら編集リクエスト、
コメント欄記入、自分なりのやつを投稿、何でも構いませんので後世に残せるいいドキュメントになればと思ってます。



。