【Linux】【Git】Git リモートリポジトリの作成【SW】

Git リモートリポジトリを作成する
 
ローカルPC上に、Gitリモートリポジトリを作成する。
用途自体はローカルで作業したファイル等の管理だが、外部公開も可能な形式にしておく。
ローカルリポジトリとは異なり、クライアントの push 作業や、サーバ側の push を受けての pull などが必要になる。
 

 

サーバ設定

サーバPC およびGitリモートリポジトリの構成は次の通りである。
 
PC の設定

項目 内容
IPアドレス 127.0.0.1
DNS なし
Apache あり
SSH OpenSSH を使用する

 
Gitリモートリポジトリ設定

項目 内容
リモートリポジトリの置き場 (ローカルホスト上の) /var/www/git/target
外部公開ディレクトリ (ローカルホスト上の) /var/www/git/target

 

Gitリモートリポジトリ作成手順

 
基本的にはこちらのサイト様の手順を辿ったのみである。
前提条件として、以下が済んでいるものとする

 

1. OpenSSL のインストール

インストールしたら、sshd が動いているかを pgrep や自PCへのログインで確認する。

% sudo apt-get -y install openssh-server
% pgrep -fln sshd
% ssh localhost

 

2. Apache のインストール

Apache のインストール詳細はこちらを参照。
ここでは手順のみを記す。

% sudo apt-get -y install apache2
% sudo apachectl start
% firefox http://localhost/ &

「It works!」というページが出ていれば OK である。
 

3. Gitリモートリポジトリを作成する

/var/www/git/target.git をリモートリポジトリとしている。

% sudo mkdir -p /var/www/git/target.git
% cd /var/www/git/target.git
% sudo git --bare init --shared
Initialized empty shared Git repository in /var/www/git/target.git/

 

4. 外部公開フォルダとして 3 で作成したリポジトリを展開する

詳細はこちらに書いたが、Apache の設定ファイルに対して、上記 Gitリポジトリを登録してやる。
以下のように /etc/apache2/sites-available/000-default.conf の末尾に 「<VirtualHost *:80> DocumentRoot /var/www/html/target </VirtualHost>」を追加する。

% cd /var/www/html
% sudo git clone /var/www/git/target.git 
% ls -l
-rw-r--r-- 1 root root 10918  512 15:29 index.html
drwxr-xr-x 3 root root  4096  512 16:05 target
% sudo cp  /etc/apache2/sites-available/000-default.conf  /etc/apache2/sites-available/000-default.conf.orig
% sudo vim /etc/apache2/sites-available/000-default.conf
中略
<VirtualHost *:80>
        #ServerName ドメイン名.com
        #ServerAlias ドメイン名.com
        DocumentRoot /var/www/html/target
</VirtualHost>
% sudo apachectl restart

5. フックを作成する

クライアントからの push を受けて実施する操作を作る。
具体的には、/var/www/html/target/hooks/post-receive というスクリプトを作成し、適切な実行権限を付与する。(ここではローカルPCのアカウント権限にした)

% sudo mkdir /var/www/html/target/hooks
% sudo vim /var/www/html/target/hooks/post-receive
#!/bin/sh
cd /var/www/html/target/
git --git-dir=.git pull

自身の権限(UID, GID)を付与する

% id
uid=1000(neko) gid=1000(neko) groups=1000(neko),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),121(lpadmin),132(sambashare)

UID は neko、GID は neko なので次のようにする

% sudo chown -R neko:neko /var/www/git/target.git
% sudo chown -R neko:neko /var/www/html/target/

 

6. 効果確認をする

一般ユーザ権限で clone & push が可能か確認をする。
 
まずは clone、add、commit の実施。

% cd /tmp/
% git clone ssh://ユーザ名@localhost:/var/www/git/target.git
Cloning into 'target'...
ユーザ名@localhost's password: 
warning: You appear to have cloned an empty repository.
% cd target
% mkdir unit
% touch unit/.gitkeep
% git add .
% git commit
master (root-commit) 26c99e2] Add: target/unit/ 新規作成
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 unit/.gitkeep

 
次に push の実行。

% git push origin master
ユーザ名@localhost's password: 
Counting objects: 4, done.
Writing objects: 100% (4/4), 273 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To ssh://localhost:/var/www/git/target.git
 * [new branch]      master -> master

 
最後に、リモートリポジトリが push された内容にアップデートされているかを確認する。

% cd /tmp/
% git clone ssh://ユーザ名@localhost:/var/www/git/target.git target.$$
% cd target.$$
% ls -ltr
合計 4
drwxr-xr-x 2 UID GID 4096  910 19:59 unit
% ls -ltrA unit
合計 0
-rw-r--r-- 1 UID GID 0  910 19:59 .gitkeep

 
無事に target/unit/ と target/unit/.gitkeep が作成されていたので OK。
 

リモートリポジトリ作成および削除スクリプト

リモートリポジトリ作成

  • /var/www/git/ 直下にリポジトリを作るスクリプト。
  • Apache の設定も行わせるために、事前に /etc/apache2/sites-available/000-default.conf 中に目印として $MARK で定義した記述をしておくこと。
    • 下記の場合だと「# don't delete this line # NNR」を書いている
    • 例: /var/www/git/nvim.git を作りたい場合、「make_new_git_repo.sh nvim」とする

make_new_git_repo.sh

#!/bin/sh

echo 
echo "$0 start..."
echo 
sleep 0.5

test ! -n "$1"            && echo "Usage: `basename $0` [new name]"         && exit 2
TARGET="`basename $1`"  ## Target 

#--------------------------------
# ユーザIDとグループIDを指定する
#--------------------------------
U="neko"
G="neko"

#--------------------------------
# リモートリポジトリ
#--------------------------------
VAR_WWW_GIT="/var/www/git"

#--------------------------------
# HTTP公開ディレクトリとアクセス設定ファイル
#--------------------------------
VAR_WWW_HTML="/var/www/html"
ACL="/etc/apache2/sites-available/000-default.conf"
ACLD="/etc/apache2/sites-available/000-default.conf.d"
NOW=`date "+%Y%m%d%H%M%S"` 
ACLBAK="${ACLD}/`basename $ACL`.${NOW}_4_$TARGET"

# アクセス設定ファイルのバックアップディレクトリを作る
test ! -d "$ACLD" && {
    echo "# sudo mkdir $ACLD"
    sudo mkdir $ACLD
}
test ! -d "$ACLD" && echo "Error: could not sudo mkdir \$ACLD<$ACLD>"            && exit 3 


test ! -d "$VAR_WWW_GIT"  && echo "Error: could not found $VAR_WWW_GIT"     && exit 4
test ! -d "$VAR_WWW_HTML" && echo "Error: could not found $VAR_WWW_HTML"    && exit 5

GITREPO="$VAR_WWW_GIT/$TARGET.git"    ## Targe Top directory
H="hooks"          ## Hooks directory
EXE="post-receive" ## execed by hooks

#--------------------------------
# すでにリポジトリが存在していたら終了する
#--------------------------------
test -d "$GITREPO" && echo "Error: GitRepository<$GITREPO> already exists." && exit 6

#--------------------------------
# リモートリポジトリを作る
#--------------------------------
sudo mkdir $GITREPO || {
    echo "Error: could not sudo mkdir GitRepository<$GITREPO>"
    exit 7
}

echo "# cd $GITREPO" 
cd $GITREPO

echo "# sudo git --bare init --shared"
sudo git --bare init --shared 

test ! -d $GITREPO/$H && echo "Error: could not found hookdir<$GITREPO/$H>" && exit 8
sleep 0.2

#--------------------------------
# リモートリポジトリに push された時の Hook 処理を定義する. ($MARK の記述を置換する)
#--------------------------------
echo "# sudo cp -p $ACL  $ACLBAK"
sudo \cp -p $ACL  $ACLBAK 
MARK="# don't delete this line # NNR"
sudo \sed -i "s%$MARK\$%        DocumentRoot $VAR_WWW_HTML/$TARGET\n$MARK%g" $ACL
echo "$ACL was written by <$TARGET>."
# apache restart
echo "# sudo apachectl restart"
sudo apachectl restart
sleep 0.2

echo "# cd `pwd`"
cd $VAR_WWW_HTML

echo "# sudo git clone $GITREPO" ; 
sudo git clone $GITREPO
sleep 0.2
test ! -d $VAR_WWW_HTML/$TARGET && echo "Error: git clone $GITREPO was failed" && exit 9

# リモートリポジトリ作成に失敗した際の不要なファイルやディレクトリの削除
trap "
    echo \"Failure: $GITREPO was could not created.\"
    cd $VAR_WWW_GIT  && rm -rf ./$TARGET.git &&
    cd $VAR_WWW_HTML && rm -rf ./$TARGET;
    \cp -fp ${ACL}.${NOW}_4_$TARGET  $ACL; exit 10 " 1 2 3 15

sudo mkdir $VAR_WWW_HTML/$TARGET/$H
test ! -d $VAR_WWW_HTML/$TARGET/$H && echo "Error: could not sudo mkdir  $VAR_WWW_HTML/$TARGET/$H" && exit 11
cd $VAR_WWW_HTML/$TARGET/$H    ; echo "# cd $VAR_WWW_HTML/$TARGET/$H"
sudo touch  $EXE               ; echo "# sudo touch  $EXE"
sudo chmod +x $EXE             ; echo "# sudo chmod +x $EXE"
sudo chown -R $U:$G $EXE       ; echo "# sudo chown -R $U:$G $EXE"
echo "# ls -l `realpath $EXE`" ; ls -l `realpath $EXE`       

test ! -f $EXE && echo "Error: could not fould $EXE" && exit 12
sudo echo '#!/bin/sh'                      >> $EXE
sudo echo "cd $VAR_WWW_HTML/$TARGET"       >> $EXE
sudo echo "sudo git --git-dir=.git pull"   >> $EXE
sudo echo                                  >> $EXE
sleep 0.1

# アクセス権の付与 (本来ならば push 専用の GID を設けるべき)
echo "# sudo chown -R $U:$G $GITREPO"
sudo chown -R $U:$G $GITREPO
echo "# sudo chown -R $U:$G $VAR_WWW_HTML/$TARGET"
sudo chown -R $U:$G $VAR_WWW_HTML/$TARGET 

#--------------------------------
# リモートリポジトリの作成が終了した
#--------------------------------
echo 
echo "Success: $GITREPO was created"
echo
sleep 0.1
echo "Let's try => git clone ssh://$U@localhost:$GITREPO"
echo 

 

リモートリポジトリ削除

本ページで言うと、 /var/www/git/nvim の削除を行い、かつ、Apache 設定の削除をするということである。

例: /var/www/git/nvim.git を削除したい場合
以下のように remove_git_repo.sh を作成することで対応する。
なお、Apache に関するディレクトリ・ファイルのアクセス権限を該当ユーザに切り替えておくこと。

% sudo chown -R neko:neko /etc/apache2/sites-available
% sudo chown -R neko:neko /var/www/html

 

% remove_git_repo.sh  nvim 

 
remove_git_repo.sh

#!/bin/sh

#--------------------------------
# リモートリポジトリ
#--------------------------------
VAR_WWW_GIT="/var/www/git"

#--------------------------------
# HTTP公開ディレクトリとアクセス設定ファイル
#--------------------------------
VAR_WWW_HTML="/var/www/html"
ACL="/etc/apache2/sites-available/000-default.conf"

test ! -n "$1"            && echo "Usage: `basename $0` [new name]"         && exit 2
TARGET="`basename $1`"  ## Target 

cd $VAR_WWW_GIT  && rm -rf ./$TARGET.git
cd $VAR_WWW_HTML && rm -rf ./$TARGET;
\sed -i "\\@DocumentRoot $VAR_WWW_HTML/$TARGET@d" $ACL || {
    echo "Error: sed failed." 
    exit 3
}
echo "delete: \"DocumentRoot $VAR_WWW_HTML/$TARGET\" from $ACL"

 

Apache 設定ファイルに目印(マーク)を入れる

 
以下、実例である。
 
/etc/apache2/sites-available/000-default.conf

<VirtualHost *:80>
	# The ServerName directive sets the request scheme, hostname and port that
	# the server uses to identify itself. This is used when creating
	# redirection URLs. In the context of virtual hosts, the ServerName
	# specifies what hostname must appear in the request's Host: header to
	# match this virtual host. For the default virtual host (this file) this
	# value is not decisive as it is used as a last resort host regardless.
	# However, you must set it for any further virtual host explicitly.
	#ServerName www.example.com

	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html

	# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
	# error, crit, alert, emerg.
	# It is also possible to configure the loglevel for particular
	# modules, e.g.
	#LogLevel info ssl:warn

	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

	# For most configuration files from conf-available/, which are
	# enabled or disabled at a global level, it is possible to
	# include a line for only one particular virtual host. For example the
	# following line enables the CGI configuration for this host only
	# after it has been globally disabled with "a2disconf".
	#Include conf-available/serve-cgi-bin.conf
</VirtualHost>

<VirtualHost *:80>
        #ServerName ドメイン名.com
        #ServerAlias ドメイン名.com
        #DocumentRoot /var/www/html/target
        #### ↓ Neko's New Repository
        DocumentRoot /var/www/html/nvim
# don't delete this line # NNR
</VirtualHost>