GitLabにgitリポジトリを登録し開発できるようにしてみる
こちらの記事(2011-11-02 - ike-daiの日記)を参考にGitLabの導入ができたかと思います。
その後、新規でProject登録して、Userも登録して開発できるようにしたいと思います。
新規PJの登録方法
GitLabにログイン後、「New Project」からプロジェクトを作成します。
Name,Path,Codeに作成するPJの情報を入力します。
Pathの情報のみ、登録後は変更できません。
作成したProjectではここのPathで指定した名前のgitリポジトリを使っていくことになります。
これで新規Projectが作成されました。
このままではまだ何もgitリポジトリは作成されていません。
鍵の設定
環境構築時に作成した秘密鍵を用いて手元の環境から「git@hostname:sample.git」という形式でGitLabのサーバにアクセスするための設定を実施。
Linuxマシンからであれば下記のように設定します。
~/.ssh/configに下記内容を追記
Host hostname HostName 192.168.xx.xx IdentityFile ~/.ssh/id_rsa
gitリポジトリの作成
登録後に下記のような画面が表示されます。
この内容に従ってgitリポジトリを作成していきます。
gitリポジトリは開発環境など手元の環境で作成します。
開発環境など手元の環境で下記を実行
$ mkdir sample $ cd sample $ git init $ touch README $ git add README $ git commit -m 'first commit' $ git remote add origin git@hostname:sample.git $ git push -u origin master
これでGitLabサーバ上にリポジトリが登録されます。
あとは、自分の環境内で変更をcommitし、pushすればGitLabでその変更が反映されていきます。
ユーザの追加
開発ユーザを追加したい場合は、
管理者がGitLabにユーザ登録を実施し、アカウントを発行します。
そのユーザを割り当てたいProjectに登録します。
Projectに登録しないとどのリポジトリにもアクセスすることはできません。
ここまでは管理者が実施します。
その後、アカウント情報をユーザに伝え、以降はユーザ側で作業を実施します。
キーペアの作成
構築時と同様にユーザのキーペアを作成します。
右上の「自分のアカウント名」→「Keys」の順に進み、「Add new」を実施します。
titleに適当な名前を登録し、keyの欄に先ほど作成した公開鍵を貼り付けます。
これだけでこの鍵を用いてgit clone、pushが可能になります。
遭遇した困ったこと
post-updateがうまく動かないため、authorized_keysに追記されない問題の対応
新規で鍵を登録しても/home/git/.ssh/authorized_keysが更新されないということがありました。
鍵登録、削除時にはpost-updateというhookスクリプトが実行されています。
その中身は下記のようになっています。
#!/bin/sh set -e gitosis-run-hook post-update git update-server-info
post-updateのスクリプト内にエラー出力をするように書き込んで、実際の画面から鍵登録。
すると下記のようなエラーが発生
Traceback (most recent call last): File "/usr/bin/gitosis-run-hook", line 9, inload_entry_point('gitosis==0.2', 'console_scripts', 'gitosis-run-hook')() File "/usr/lib/pymodules/python2.7/gitosis/app.py", line 24, in run return app.main() File "/usr/lib/pymodules/python2.7/gitosis/app.py", line 38, in main self.handle_args(parser, cfg, options, args) File "/usr/lib/pymodules/python2.7/gitosis/run_hook.py", line 75, in handle_args post_update(cfg, git_dir) File "/usr/lib/pymodules/python2.7/gitosis/run_hook.py", line 43, in post_update config=cfg, File "/usr/lib/pymodules/python2.7/gitosis/gitdaemon.py", line 79, in set_export_ok assert ext == '.git' AssertionError
/usr/lib/pymodules/python2.7/gitosis/gitdaemon.pyこのファイルの中で、/home/git/repositoriesの中にあるディレクトリをチェックし、
リポジトリ名の一覧を取得してきます。
そのディレクトリ名の中で、「.git」で終わっていないものがあると、assert ext == '.git'の条件に当てはまらずAssertionErrorが発生するようです。
なので、/home/git/repositoriesの中には必ずxxx.gitという形式の名前でgitリポジトリだけを登録して下さい。
そうしないとエラーが発生します。
cloneに失敗する場合の対応
$ git clone git@hostname:sample.git
という形でcloneした場合に下記のようなエラーが発生する場合は、鍵を確認して下さい。
$ git clone git@hostname:sample.git Initialized empty Git repository in /home/git/repositories/sample.git fatal: 'sample.git' does not appear to be a git repository fatal: The remote end hung up unexpectedly
http://d.hatena.ne.jp/thimura/20101008/gitosis#20101008f4
ここに書かれているように、通常のログインに使われる鍵と同様にしていた場合、gitlab経由でログインできないようなので、
id_rsaのようなデフォルトの名前ではなく、gitlab用の鍵の名前にしてssh_configを設定するといいかと思います。
また、git cloneしようとした際に鍵認証ではなく、パスワード認証が聞かれた場合は、ssh_configが読み込まれているかどうか確認して下さい。
.ssh/configの権限についても見なおして下さい。
ownerユーザからの書き込みだけを許可するようにchmod 644にして下さい。
masterブランチがないリポジトリを利用した場合に500エラー
既存のリポジトリを管理下に置きたい場合に発生するかもしれないエラーです。
commitログを見ようとすると500エラーが発生しました。
Started GET "/deltacloud/commits/e1c6809ff390bafaf128101598d46a85b8384bc0b" for Processing by CommitsController#show as HTML Parameters: {"project_id"=>"deltacloud", "id"=>"e1c6809ff390ba52aafafa598d46a85b8384bc0b"} Rendered commits/_diff_head.html.haml (79.3ms) Rendered commits/_text_file.html.haml (0.8ms) Rendered commits/_text_file.html.haml (0.2ms) Rendered commits/_text_file.html.haml (0.2ms) Rendered commits/_text_file.html.haml (0.2ms) Rendered commits/_text_file.html.haml (0.2ms) Rendered commits/_text_file.html.haml (0.2ms) Rendered commits/_diff.html.haml (108.9ms) Rendered notes/_notes_list.html.haml (0.6ms) Rendered notes/_form.html.haml (3.1ms) Rendered notes/_notes.html.haml (4.1ms) Rendered commits/show.html.haml within layouts/application (115.0ms) Rendered layouts/_flash.html.haml (0.1ms) Rendered layouts/_head_panel.html.erb (5.2ms) Rendered projects/_top_menu.html.haml (9.6ms) Completed 500 Internal Server Error in 144ms ActionView::Template::Error (undefined method `id' for nil:NilClass): 28: - if @commit 29: %span= link_to truncate(commit_name(@project,@commit), :length => 15), project_commit_path(@project, :id => @commit.id), :class => current_page?(:controller => "commits", :action => "show", :project_id => @project, :id => @commit.id) ? "current" : nil app/helpers/application_helper.rb:8:in `commit_name' app/views/projects/_top_menu.html.haml:31:in `_app_views_projects__top_menu_html_haml__7153559fafa859057_24443740' app/views/layouts/application.html.haml:23:in `_app_views_layouts_application_html_haml___15805912fafa2185993_43892440' app/controllers/commits_controller.rb:33:in `show' cache: [GET /favicon.ico] miss
↑これはapplication_helper.rbのcommit_nameに送られてくるcommitの中にidが含まれていないことによるエラーです。
application_helper.rbの該当箇所をコメントアウトするとコミットログの内容を確認することができた。
暫定的に対応しました。
また、treeを見ようとしてもエラーになりました。
Started GET "/deltacloud/tree" Processing by ProjectsController#tree as HTML Parameters: {"id"=>"deltacloud"} Rendered public/404.html (0.4ms) Completed 404 Not Found in 22ms (Views: 2.1ms | ActiveRecord: 1.2ms) cache: [GET /favicon.ico] miss
ソースコードの中身を見てみると
projectcontroller.rbのtreeメソッドにおいて、
def tree load_refs # load @branch, @tag & @ref @repo = project.repo if params[:commit_id] @commit = @repo.commits(params[:commit_id]).first else @commit = @repo.commits(@ref || "master").first end
branchやtagの指定が無く、tree表示を試みようとした場合に、デフォルトでmasterを指定してコミット情報を取得するような設定になっていました。
ブランチに「master」がなく、trunkしかない場合にエラーが@commitがnilになり、エラーが発生するようです。
暫定的に下記のように変更
def tree load_refs # load @branch, @tag & @ref @repo = project.repo if params[:commit_id] @commit = @repo.commits(params[:commit_id]).first else if @commit = @repo.commits(@ref || "master").first else @commit = @repo.commits("trunk").first end end