Windows Server上にGitリモートリポジトリを導入する手順書


# まえがき

以下を前提に記載。

* 社内イントラサーバ上にリモート環境を構築する
* OSはWindows Server
* gitプロンプトによるpush,fetchを行う
* masterをpushしたら同サーバ内で自動デプロイしたい

|フォルダの種類|サンプルパス|
|:------------|:---------|
|ベースフォルダ|`D:\repos`|
|リモートリポジトリ|`D:\repos\sample.git`|
|サーバ上のローカルリポジトリ|`E:\working\directory`|

# サーバ上での環境構築

## Git for Windowsのインストール

https://git-for-windows.github.io/

msysGitと呼ばれていたもの。
最新版（ver1.7.10以上）をダウンロードすること。
以下のものがまとめてインストールされる。

* Gitコマンド本体、およびその周辺コマンド
* Git Bash（Windowsでいうコマンドプロンプト）
* Git GUI（GitのGUIクライアント、あんまり使わない）

### インストーラの指示について

基本的にはNext連打で問題ないが、以下の2点については少し注意。

#### Gitコマンドをどこで受け付けるか

基本はデフォルトの「Git Bashでのみ受け付ける」でよいが、
**batファイルでGitコマンドを打ちたい**など
コマンドプロンプトでGitコマンドを実行したい場合はそれを選択。
赤文字で注意書きが書かれた選択肢は副作用があるのでおすすめしない。

#### 改行コード

*CSVをExcelで開いて見る文化*がある場合、
改行コードは**書き換えない**設定にしたほうが面倒が起きなくてよい。
「そのまま」＝"as-is"がいちばん多く書かれた選択肢を選んでNext。

## Gitのグローバル設定

Git Bashを開いて、以下のコマンドを実行。
サーバ上で`git commit`したときのユーザ設定と、
日本語名を含むフォルダやファイルの文字化け回避の設定。

（2018/2/1追記）
Windowsでgitプロトコルを使用してpushした際にハングアップする不具合に
対処するためのグローバル設定項目を追加。

```
# git config --global user.email "administrator@example.com"
# git config --global user.name "Administrator"
# git config --global core.quotepath false
# git config --global sendpack.sideband false
```

## 共有リポジトリを作成する

### ベースフォルダ、リポジトリフォルダの作成

適当な場所にフォルダを作成する。（仮に`D:\repos`とする。）
このフォルダが**ベースフォルダ**になる。
作ったフォルダの中に、「（リポジトリ名）.git」という名前でフォルダを作成する。
（仮に`D:\repos\sample.git`とする。）
このフォルダが**リポジトリフォルダ**になる。

この作業はエクスプローラで行ってもGit Bashで行ってもよい。
Git Bashで行う場合は以下のコマンドを実行する。

```
# mkdir /d/repos
# mkdir /d/repos/sample.git
```

### リポジトリフォルダの初期化

Git Bashで今つくったリポジトリフォルダに移動して、
共有リポジトリフォルダの初期化コマンドを実行する。

```
# cd /d/repos/sample.git
# git init --bare --shared
```

正常終了して、フォルダの中に何か色々ファイルが作られたことを確認できればOK。

#### git initのオプションについて

`git init`はフォルダをgit管理用に初期化するコマンド。

`--bare`オプションは、*管理用ファイルのみを生成する*ためのもの。
このオプションが付いた状態で生成されたリポジトリを**ベアリポジトリ**という。
これがない場合、フォルダ直下はバージョン管理されたファイルを置く場所
（**ワーキングディレクトリ**）になり、
管理用ファイルは直下の`\.git`という隠しフォルダ内に格納される。
共有リポジトリはベアリポジトリでなければならない。

`--shared`オプションは、*共有リポジトリにするためのパーミッション自動付加*。
このオプションを付け忘れた場合は以下のコマンドで同等になる（らしい）。

```
# git config core.sharedRepository group
# chmod -R g+ws hooks
# chmod -R g+ws info
# chmod -R g+ws objects
# chmod -R g+ws refs
```

### 自動デプロイの設定

生成された`hooks`フォルダ内に以下のファイルを生成する。
このファイルは、「共有リポジトリに更新があった場合、該当するフォルダ（サーバ内ローカルリポジトリ）のファイルを更新する」というスクリプト。
（サーバ内で実際にファイルを置くフォルダのパスは仮に`E:\working\directory`とする。）

```sh:post-receive
#!/bin/sh
cd /e/working/directory
git --git-dir=.git pull origin master
```

また、このファイルに実行権限を追加する。

```
# chmod +x hooks/post-receive
```

## サーバ内ローカルリポジトリの設定

管理したいファイルがある、またはファイルを置く予定のフォルダに移動して、
`git init`コマンドを実行する。
管理ファイルのフォルダ（`/.git`）が追加されるだけなので、
すでにファイルがある場合も勝手に改変されたり削除されたりすることはない。

```
# cd /e/working/directory
# git init
```

### リモートリポジトリと紐付ける

先のフォルダ上で以下のコマンドを実行する。

```
# git remote add origin /d/repos/sample.git
# git remote -v
```

2つめのコマンドの結果で、originという名前で(fetch)と(push)に
リモートリポジトリのパスが表示されていれば成功。

### 最初のコミット

すでにファイルが存在する場合は最初の`git commit`をここでする。

#### 無視ファイルの設定

コミットする前に、バージョン管理する必要のないファイルをまとめた
`.gitignore`ファイルを作成し、ディレクトリ直下に置く。

#### コミットする

```
# git add .
# git commit -m "initial commit"
```

##### トラブル：git addに時間がかかる

コミットにバイナリが含まれている可能性がある。
フォルダ名に日本語が含まれていると色々不都合があるので極力英語に。
原因をひとつひとつ探りたい場合は、`git add`の対象を絞りながら行うといいかも。

```
# git add folder1/.
# git add folder2/.
...
```

#### リモートにコミットを反映

```
# git push origin master
```

## 外部接続を行うGit Daemonの起動

Git Bashから以下のコマンドを実行。
Git Daemonが起動してログを逐一垂れ流すようになる。
成功したらそのウィンドウは消さずに放っておく。

```
# git daemon --verbose --export-all --enable=receive-pack --base-path=/d/repos/
```

※gitプロンプトは認証がないため、fetchのみの利用がセキュリティ的には正しい。
本環境は社内イントラ上であり、はじめからアクセス権が社内に限られているので
gitプロンプトによるpushも可能にしている。
sshでの接続が必要な場合は別途Windows Server上にsshの送受信環境を整えればよい。

### ファイヤーウォールのポートを開ける

Windowsファイヤーウォールまたは何らかのセキュリティソフトのファイヤーウォールから、
TCP 9418番ポートの送受信を許可する。このポートはgitプロンプトで使用される。

# クライアント側の環境構築

## Git for Windowsのインストール

サーバでインストールしたのと同じものを同じように。

## SourceTreeのインストール

https://ja.atlassian.com/software/sourcetree/overview

日本語対応で扱いやすいGitのGUIクライアント。
適当にインストールする。

以下はSourceTree上での操作を解説する。

## SourceTreeの設定変更

ツール→オプションからオプションウィンドウを開く。

### 全般タブ

* 「SourceTreeにGitとMercurialのグローバル設定ファイルの変更を許可する」にチェック
* 「デフォルトユーザー情報」の欄を入力
* 「その他」の「デフォルト文字コード」をshift-jisかeuc-jpに

### Gitタブ

* 「Gitバージョン」のところで「システムGitを使用」を選択

## リモートリポジトリをクローンする

「新規/クローンを作成する」をクリックする。
「リポジトリをクローン」タブの「元のパス/URL」欄に
`git://server-name/sample.git`と入力し、
フォーカスを移すと他の欄が自動的に埋まるので、
確認して「クローン」ボタンをクリックする。

終わったら、先のウィンドウの「保存先のパス」に記載されていた場所に
サーバ上のファイル全てが展開されていれば成功。

# 開発作業

作業は、リモートからクローンしてきたフォルダの中で、
ファイルの追加や修正を行う。

## 自分の更新をリモートに反映させる一連の流れ

更新の反映を行う前に、現在自分のいるブランチが
更新をかけたいブランチ（仮に`branch`という名前とする）であることを確認する。
太字で表記されているブランチが自分のいるブランチ。

違っていた場合は、目的のブランチをダブルクリックしてブランチを切り替える（チェックアウト）。

### 自分の編集内容を履歴として残す（コミット）

上部バーの「コミット」ボタンを押す。

「作業ツリーのファイル」欄には、直前の状態から変更されたファイルが
一覧表示されているので、コミットに含めたいものにチェックをいれて
「indexにステージされたファイル」欄に移動させる。
その後、**コミットメッセージを入力して**（必須）
右下の「コミット」ボタンを押すとコミットが実行される。

### リモートの更新を取得する（フェッチ）

上部バーの「フェッチ」ボタンを押す。

現在のブランチ（`branch`）のサーバ側の更新（`origin/branch`という表記になる）が
自分の更新内容と枝分かれしている場合はマージする。
そうでない場合はプッシュする。

### 2つのブランチをひとまとめにする（マージ）

サーバ側の更新（`origin/branch`）を右クリックして「マージ」を選択する。
何もなければ、枝分かれしたブランチがひとつにまとまったコミットが新たに生成される。

「衝突が起きました」と表示された場合は、
それぞれのブランチで同じ行の更新がかかっている。
「作業ツリーのファイル」に黄色三角アイコンが表示されているファイルを開いて修正し、
右クリックして「衝突を解決」を選択、「indexにステージされたファイル」に移動させて
そのまま**コミットする**。

### リモートに自分の更新を反映する（プッシュ）

上部バーの「プッシュ」ボタンを押す。

更新したコミットを含むブランチ（`branch`）にチェックがついていることを確認して「プッシュ」。
リモートに別の更新があった場合はエラーになるので、作業をフェッチからやり直す。

### 注意点

上部バーの「プル」ボタンは、フェッチとマージを勝手にしてくれる機能。
意味がわかって使うぶんには手間が省けるが、
考えなしに使うと意図しない変更がかかる可能性もあるため、
慣れるまではフェッチとマージは別々に行ったほうが無難。

おしまい。