Gitでバージョン管理する
最終更新 2018/12/11

Gitでバージョン管理する

Git(ギット)は、VCS(バージョン管理システム)のひとつで、 ファイルのバージョン(変更履歴)を管理するシステムで、無料で利用できる。

通常、自分のPC(いわゆるローカル)とサーバ(いわゆるリモート)の両方にインストールして利用する。

一般的に、自分でサーバーにGitをインストールする場合は、 セットでGitLab(ギットラボ)や Gogs(ゴグズ)などの管理システムをインストールして使用する。 あるいは、GitHub(ギットハブ)のような Gitホスティングサービス(最初からGitがインストールされているサーバ)を使えば、サーバにインストールする手間は省ける。

Gitでは、ファイルの変更履歴が「リポジトリ」と呼ばれる場所に保存される。 特に、自分のPC上のものは「ローカルリポジトリ」、サーバ上のものは「リモートリポジトリ」と呼ばれる。

リポジトリの中には「ブランチ」と呼ばれる分岐を作ることができる。 たとえば、本番用と開発用に分岐させて、開発用のファイルを更新していき、 確認が終わって本番に反映してよいとなったタイミングで、 開発用のブランチを本番用のブランチに統合(マージ)することで本番反映するとか。

具体的に体験した内容をまとめていく。

  • webページに関連するデータ(HTMLやCSSや画像など)が保存されているサーバがある
  • Git(および管理システム)がインストールされたサーバがある
  • すでにリモートリポジトリが作成されており、「master」と「develop」のブランチが存在する
  • ローカルにはすでにGitがインストールされている

なお、ここではMac+ターミナルでの作業を記載する。 TortoiseGit(トータスギット)やSourceTree(ソースツリー)のようなGUIを利用する場合は、相当する機能が備わっている(たぶん)。

事前準備

ローカルとリモートでやり取りする際には、リモートリポジトリのURLを指定する。 URLには「SSH」と「HTTPS」の2種類があり、 GitLabやGogs(以下、管理システム)ではダッシュボードからリモートリポジトリのページを開けば記載されている。

なお、SSHでやり取りするには「秘密鍵」と「公開鍵」が必要になるので、ない場合は生成(方法は別ページでまとめる予定)する。

公開鍵は管理システムのダッシュボードから登録しておき、 ローカルでは~/.ssh/configに必要な情報を記載(テキストエディタで編集可能)する。 ファイルが存在しない場合は新規作成する。


Host リモートリポジトリがあるドメイン(例 : github.com)
  HostName リモートリポジトリがあるドメイン(例 : github.com)
  IdentityFile 秘密鍵までのパス(例 : ~/.ssh/鍵ファイル名)
  Port ポート番号の指定が必要な場合ここに番号(例 : 1234)
  User ユーザーネーム(例 : john_doe)

クローン

新たにプロジェクトに参加する場合、リモートリポジトリを複製(クローン)して、 ローカルポジトリを作成する必要がある。

まず、ターミナルを開いて「cd」コマンドで複製を作成したいディレクトリ(たとえばホーム⇒dev⇒git)に移動する。


cd ~/dev/git

念のため「pwd」コマンドで今いる場所を確認する。


pwd
 ⇒ /Users/ユーザー名/dev/gitと表示される
 ⇒ つまり「~/」と「/Users/ユーザー名/」は同義

これで準備できたので、ターミナルから「git clone」コマンドでクローンする。


git clone リモートリポジトリのURL

SSHの場合は、秘密鍵のパスワードを聞かれるのでしかるべく入力する。

HTTPSでやろうとした時に「git-credential-osxkeychainは、キーチェーン内の~」というポップアップが出たので、 Macにログインする時のパスワードを入力して「常に許可」を選択した。

クローンできたら、クローンしたフォルダ(リポジトリの名前、ここでは例としてhoge)の中に移動する。


cd hoge

cd ~/dev/git/hoge

ブランチの一覧を確認する。


git branch

* master

*がついているのが現在いるブランチ。 デフォルトではmasterブランチのみ。 なぜdevelopブランチが無いのかというと、この時点ではまだローカルと紐づいていないから。

オプション「-r」をつけてリモートと紐づいたブランチを出力すると、developブランチが確認できる。


git branch -r

  origin/HEAD -> origin/master
  origin/develop
  origin/master

ローカル対応は基本developブランチでおこなうので、developブランチに移動(チェックアウト)する。


git checkout develop

再度ローカルブランチの一覧を確認すると、developブランチが追加されていてブランチも移動できていた。


* develop
  master

ここから、任意のファイル(たとえばtop.html)を編集するわけだが、 この時developブランチからさらにブランチを切る流れが一般的なので、 「git branch」コマンドで今いるブランチから、たとえばfeature-topという子ブランチを作る。


git branch feature-top

あるいは、「git checkout」コマンドにオプションをつけることで、 作ると同時にチェックアウトすることもできる。


git checkout -b feature-top

確認してみる。


  develop
* feature-top
  master

これで準備完了。top.htmlを修正する。

コミット

編集が完了したら、編集したファイルを「ステージ(またはインデックス)」という領域に登録する(ステージング)。 ステージングには「add」コマンドを使用するが、この時ステージングするファイルがあるところまで「cd」コマンドで移動しておく必要がある。


git add top.html

あるいは、「-u」オプションを使えば「変更したすべて」が対象となるため、移動しなくても良い。


git add -u

ステージングされたファイルに対して「コミット」という作業をおこなうと、 ローカルリポジトリに変更履歴が記録される。


git commit -m "ここに何をしたかコメントを書く"

feature-topでの作業はこれで完了なので、developブランチにマージする。 developブランチにチェックアウトして、「git merge」コマンドでマージする。


git merge feature-top

マージできたらfeature-topはもう不要なので、 「git branch -d」で削除する。


git branch -d feature-top

プッシュ

ローカルの変更が完了したら、「git push」コマンドでその変更をリモートに反映(プッシュ)する。 今回更新したのはdevelopブランチなので、developブランチにプッシュする。


git push origin develop

この時、他の人が並行してdevelopブランチのtop.htmlに別の更新を加えてプッシュしていた場合、 衝突(コンフリクト)が発生してプッシュできないので、 以下の流れで解消する必要がある。

プル

まず、現在のリモートリポジトリの状態をローカルにも反映させる。 すでにローカルリポジトリがある状態なので、クローンではなく「git fetch」コマンドで、 リモートリポジトリにあるすべてのブランチを取得する。


git fetch origin

この時点ではまだリモートと紐づいたブランチ(origin/~)にしか反映されていないので、 ローカルと紐づいたブランチにも反映する。 リモートと紐づいたdevelopブランチを、ローカルと紐づいたdevelopにマージする。 間違ってorigin/masterなど、違うブランチをマージしないように注意。


git merge origin/develop

この時、コンフリクトがある場合はその旨が表示される。


Auto-merging html/top.html
CONFLICT (add/add): Merge conflict in html/top.html

テキストエディタで該当ファイルを開くと、衝突した内容が両方記載されているので、 不要な方を削除するなどして変更を決定する。


<<<<<<< HEAD
対象期間は2018/11/30まで
=======
1週間延長!対象期間は2018/12/7まで
>>>>>>> コミットID

1週間延長!対象期間は2018/12/7まで

あとは、再度プッシュすればOK。

(2018/12/11 追記)
あるいは、以下のようコミットを要求される場合がある。


Merge remote-tracking branch 'origin/develop' into develop

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~

何もせず「:wq」コマンドで終了させればコミットされる。