ウェブサイトでワークフローを整理するこの方法にたどり着くまで、私は数か月間Git-svnグリッチと戦い、さまざまなオプションについて考えました。シンプルで、柔軟で使いやすいです。
主な利点:
- リモートコピーからプッシュすることにより、サイトのライブコピーを自動的に更新します
- サーバー上のファイルを編集しても、コミットの履歴は破壊されません。
- シンプル、特別なコミットルールは不要
- ファイルを再展開または移動せずに、既に実行中のサイトに適用できます
復習
システムの主なアイデアは、サーバー上に2つのリポジトリを作成することです。空のベアリポジトリと、サイトの作業用コピーを含む通常のリポジトリです。 このペアは、プッシュとプルの変更を自動化するシンプルなフックのペアで接続されています。
したがって、2つのリポジトリ:
- ハブは裸のリポジトリです。 すべての開発者リポジトリは彼からクローンされています。
- プライムは通常のリポジトリです。 このリポジトリの作業ディレクトリからサイトが起動されます。
2つのリポジトリの操作はシンプルで非常に柔軟です。 sshアクセスのリモートコピーは、 ハブリポジトリにプッシュするだけで、サイトのライブバージョンを簡単に更新できます。 サーバー上のライブバージョンで行われた変更は、コミット時に即座にハブに流れます。 一般に、すべてが非常に簡単に機能します-変更がどこで行われても。
打ち上げ前の小さな準備
当然、まず第一に、サーバーとすべての開発コンピューターにGitをインストールする必要があります。 Gitが共有ホスティングにインストールされていない場合、非常に簡単に修正できます (en)。
サーバーでGitを使用するのがこれが初めての場合は、必ずグローバル設定を指定してください。 プロジェクト履歴でサーバーに加えられた変更を後で見るために、 user.nameに特別な値を指定します。
$ git config --global user.name ", "
行こう!
まず、サイトのライブディレクトリに新しいgitリポジトリを作成し、すべてのサイトファイルを追加してコミットします。 これがPrimeリポジトリと作業コピーになります。 既に他の場所にプロジェクトの履歴がある場合でも、サイトのコンテンツはベースポイントになり、そこに他のすべてのコピーがマージされます。
$ cd ~/www
$ git init
$ git add .
$ git commit -m " "
作業コピーでリポジトリの初期化を行ったため、メンテナンスのためにサイトをオフにしてすべてのファイルを再アップロードする必要はありません。Gitは既存のファイルからリポジトリを作成します。
サイトが既にGitにあるので、サイトの作業ディレクトリの外にベアリポジトリを作成します。
$ cd
$ mkdir site_hub.git
$ cd site_hub.git
$ git --bare init
Initialized empty Git repository in /home/joe/site_hub.git
やった! サイトの作業ディレクトリに戻り、 ハブをリモートリポジトリとして追加してから、マスターブランチのコンテンツをPrimeリポジトリからハブに注ぎます。
$ cd ~/www
$ git remote add hub ~/site_hub.git
$ git remote show hub
* remote hub
URL: /home/joe/site_hub.git
$ git push hub master
フック
最初に述べたように、HubとPrimeは2つの単純なスクリプトを使用して相互に同期します。
Gitを使用する際の基本的なルールの1つは、作業コピーのあるリポジトリにプッシュしないことです。 このルールに従い、「ハブ」リポジトリを作成しました。 何らかの方法で作業コピーに影響を与えないハブからのプッシュを行う代わりに、Primeがハブリポジトリからプルすることを強制するフックを使用します。
更新後-ハブリポジトリ内
変更の新しいバッチがハブに到着するとすぐに、このスクリプトはすぐに実行されます。 Primeリポジトリの作業ディレクトリに移動し、ハブから変更を取得します。 変更をプッシュ(プッシュ)しても、リポジトリの作業ディレクトリの状態は変更されません。そのため、作業ディレクトリでプルを実行する必要があります。
#!/bin/sh
echo
echo "**** Prime [Hub's post-update hook]"
echo
cd $HOME/www || exit
unset GIT_DIR
git pull hub master
exec git update-server-info
コミット後-Primeリポジトリ内
このスクリプトは、Primeリポジトリでコミットするたびに実行され、ハブに変更をプッシュします。 もちろん理想的な世界では、サーバー上で直接何かを支配することは決してありません。 しかし、私たちの不完全な世界では何でも可能ですので、プロジェクトの歴史を破壊せず、起こりうる衝突を避けるために、変更をプッシュするプロセスを自動化しましょう。
#!/bin/sh
echo
echo "**** pushing changes to Hub [Prime's post-commit hook]"
echo
git push hub
したがって、このフックを使用して、Primeリポジトリのmasterブランチで行われたすべての変更をすぐにハブリポジトリに取得します。 他のブランチもクローンできますが、サイトには影響しません。 すべてのリモートコピーはSSHアドレスを介してハブにアクセスするため、シェルに直接アクセスできるユーザーのみがプッシュを実行し、サイトの更新を直接開始できます。
対立
このような2つのリポジトリを同期するシステムを使用してサイトを「敷設」することは非常に困難です。 Primeで行われたすべての変更は自動的にハブに反映され、リポジトリクローンからプッシュしようとすると、すべての競合がすぐに表示されます。
ただし、Primeの状態がハブと異なる場合がいくつかあり、状況を修正するには、いくつかの追加のジェスチャを実行する必要があります。 Primeで何かを修正し、変更をコミットしておらず、この時点でハブのポストアップデートが機能する場合、「エントリ 'foo'が最新ではありません」というメッセージですべてが終了します。 マージできません。 "。 Prime作業ディレクトリへの変更をコミットすると、その状態がクリアされ、 更新後のフックにより未送信の変更がすべてマージされます。
また、Primeの変更をハブにマージできないために競合が発生した場合、Primeの現在の状態をハブの新しいブランチにプッシュすることが最善の解決策であることもわかりました。 Prime作業ディレクトリから実行されるこのコマンドは、Primeリポジトリの現在の状態に基づいてリモートfixmeブランチを作成します。
$ git push hub master:refs/heads/fixme
ハブに変更が加えられるとすぐに、任意のクローンでブランチを取得し、競合を解決してブランチを保持できます。 サーバー上で競合を直接解決しようとすると、競合マーカーが表示されるため、ほぼ確実にサイトで問題が発生します。
すべてを清潔に保つ
.git Primeリポジトリディレクトリはサイトのルートディレクトリにあり、一般に公開されている可能性があります。 だれも鼻をくっつけないように、トップレベルの.htaccessファイルに次の行を追加します。
# deny access to the top-level git repository:
RewriteEngine On
RewriteRule \.git - [F,L]
ご注意 トランスレータ:サーバー上のディレクトリへのアクセスをブロックする他の方法があります。
その他の問題
サーバー上のリポジトリにプッシュしようとすると、次のエラーが表示されます。
git-receive-pack: command not found
fatal: The remote end hung up unexpectedly
この場合、
export PATH=${PATH}:~/bin
をサーバー上の.bashrcファイルに追加するだけです。