リモートリポジトリ

開発者のチームで作業を行う場合は、複数のリポジトリで作業することになります。

リポジトリの公開方法については、 リポジトリを公開 ~ デーモンの開始 を参考にしてください。

ここではアクセス可能なリモートリポジトリがあることを前提として、そのクローンの作成、変更の取得方法等について説明します。

リモートリポジトリのクローンを作成する

$ ls
$ git clone git://localhost/hello.git
Initialized empty Git repository in /home/keisukeo/temp/hello/.git/
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.
$ ls
hello

hello という名前のディレクトリができ、そこにリポジトリが作成されたので中身をみてみましょう。

$ cd hello
$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

ここでは取得されたファイルは次の 1 ファイルだけでした。中身も単純ですね。

$ ls
hello.py
$ cat hello.py
print 'Hello, git!'

リモートリポジトリの変更を取得する - fetch

リモート側で変更をコミットして、そしてその変更を取得します。この動作はフェッチ (fetch) といいます。

フェッチは git fetch コマンドで行います。リモート名を省略した場合は、 origin からフェッチします。

$ git fetch
remote: Counting objects: 5, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From git://localhost/hello
   4a59ec3..8776a3e  master     -> origin/master

これによって、 リモートの master ブランチから、変更が "origin/master" ブランチに取り込まれました。

$ git checkout origin/master
Note: checking out 'origin/master'.

You are in 'detached HEAD' state. You can 
...
HEAD is now at 8776a3e... Changed a message.
keisukeo@keisukeo-toshibal:~/temp/hello$ cat hello.py
print 'Hello, remote repo!'

確かに hello.py の内容が変わりました。

ちなみに、この時点で master のステータスをみると・・・

$ git status
# On branch master
# Your branch is behind 'origin/master' by 1 commit, 
and can be fast-forwarded.
#
nothing to commit (working directory clean)

このように 1 コミット分だけ変更が送れている旨のメッセージが表示されます。 fast-forward 可能ということは、origin/master の変更分のコミットは、 ローカルの master ブランチの最後のコミットの後に行われたということですから、 単純にマージ可能です (というかポインタが切り替わるだけなのですが、そこはまた別の機会に・・・)。

マージしてしまいましょう。

$ git merge origin/master
Updating 4a59ec3..8776a3e
Fast-forward
 hello.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
$ git status
# On branch master
nothing to commit (working directory clean)

確かに 1 コミット分遅れてるというメッセージは消えました。マージ完了です。

pull による fetch と commit

上では fetch コマンドで変更を取得して、 merge で現在の master ブランチにその変更をマージしました。

実はこの一連の流れはもっと簡便に済ますことも可能です。 pull コマンドは変更をフェッチしてそれを続けてマージします。

$ git pull
remote: Counting objects: 5, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From git://localhost/hello
   8776a3e..2383a1e  master     -> origin/master
Updating 8776a3e..2383a1e
Fast-forward
 hello.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

リポジトリのステータスを確認します。

$ git status
# On branch master
nothing to commit (working directory clean)

先ほど表示されたビハインドのメッセージはありません。また、変更が発生したファイルの内容をみると・・・

$ cat hello.py
print 'Hello, Git!'

確かに変更が摘要されています。

リモート・リポジトリに変更を送信する ~ push

リモートリポジトリに変更を送信するコマンドは push です。 ローカルの現在のブランチから、 origin のブランチに送るならばパラメータは不要です。

$ git push

origin に対して master の変更を送信するなら、次のようにします。

$ git push origin master

成功すると次のようになります。

$ git push
Counting objects: 5, done.
Writing objects: 100% (3/3), 273 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To git://iskrdevq/project1.git
   b800919..b90cb6f  master -> master

なお、このときに次のようなエラーが発生する場合があります。

$ git push origin master
localhost[0: ::1]: errno=Connection refused
fatal: The remote end hung up unexpectedly

これは receive-pack が有効でない場合等に発生します。 receive-pack の問題であれば、 git daemon の verbose ログに次のように記録されます。

[...] 'receive-pack': service not enabled for ...

この場合は、 git daemon 起動時のオプションに --enable=receive-pack を追加すれば OK です。

尚、開発リポジトリへの push では、現在のインデックスとワークツリーに不整合が起きることになります。 そのためデフォルトでは許可されていません。もし許可するには次の設定を行います。

$ git config receive.denyCurrentBranch "warn"

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Linux 入門