Macでrbenvをgit-cloneしたときに、シンボリックリンクがおかしくなっていた件

rbenvをMacBookに入れてみたら、シンボリックリンクが貼られるべきところに貼られておらず、トラブルになりました。手持ちのMacBookProでは何の問題も起きず。OSは同じなのにどうしてでしょう。

自分のMacBookで、

$ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
をしてみました。~/.rbenv/bin に移動して、ls -allしてみると↓、
$ cd ~/.rbenv/bin

$ ls -all
total 16
drwxr-xr-x   4 mk  staff  136  7 18 01:25 .
drwxr-xr-x  11 mk  staff  374  7 18 01:25 ..
-rw-r--r--   1 mk  staff   16  7 18 01:25 rbenv
-rwxr-xr-x   1 mk  staff  724  7 18 01:25 ruby-local-exec

$ cat ./rbenv 
../libexec/rbenv
となっていました。

この状態で、~/.bash_profileに対して、
# rbenv
if [ -d $HOME/.rbenv/bin ]; then
    export RBENV_ROOT=$HOME/.rbenv
    export PATH="$RBENV_ROOT/bin:$PATH"
    eval "$(rbenv init -)"
fi
を追加してみました。

そして、反映させると次のようなエラーになりました。
$ source .bash_profile 
-bash: /opt/local/bin/../completions/rbenv.bash: No such file or directory

いろいろと変更してみましたが、こんな感じのエラーが出ていました↓
$ source .bash_profile 
/Users/mk/.rbenv/bin/rbenv: line 1: ../libexec/rbenv: No such file or directory

$ source .bash_profile 
-bash: /Users/mk/.rbenv/bin/rbenv: Permission denied

もちろん、失敗しているので、rbenvコマンドは動きません。

手持ちのMacBookProでrbenvをgit-cloneしてみたところ、正常に動作したのでおかしいと思い、たくさん調べました。すると、正常に動作する方では、~/.rbenv/bin/rbenvにシンボリックリンクが貼られていたのです。正常な状態↓
[mk@macbook: ~/.rbenv/bin]
$ ls -all
total 16
drwxr-xr-x   4 mk  staff  136  7 18 01:21 .
drwxr-xr-x  15 mk  staff  510  7 18 01:32 ..
lrwxr-xr-x   1 mk  staff   16  7 18 01:21 rbenv -> ../libexec/rbenv
-rwxr-xr-x   1 mk  staff  724  7 18 01:20 ruby-local-exec

失敗しているほうでは、シンボリックリンクは貼られていませんでした。うーん、同じgit-cloneでもおかしなことがあるものです。。。

さっそく修正してみました。おかしい状態のrbenvを削除して、シンボリックリンクを貼っています↓
$ cd ~/.rbenv/bin

$ ls -all
total 16
drwxr-xr-x   4 mk  staff  136  7 18 01:25 .
drwxr-xr-x  11 mk  staff  374  7 18 01:25 ..
-rw-r--r--   1 mk  staff   16  7 18 01:25 rbenv
-rwxr-xr-x   1 mk  staff  724  7 18 01:25 ruby-local-exec

# ↓だめな状態
$ cat ./rbenv 
../libexec/rbenv

# 削除
$ rm ./rbenv

# シンボリックリンクを貼る
$ ln -s ../libexec/rbenv ./rbenv

# 確認
$ ls -all rbenv 
lrwxr-xr-x  1 mk  staff  16  7 18 01:21 rbenv -> ../libexec/rbenv

この状態にしたところ、正常に動くようになりました。

Redmineとgitoliteの連携その2

その1はめちゃくちゃなので非公開にしています…。

連携についての作業を書いておく。毎回忘れて、historyとgrepとlessを多用することになるので。

想定する状況は、新しくレポジトリを作って、Redmineで反映させたいときです。

1. ローカルマシンで、新しくレポジトリを作ってcommit

2. Redmineとgitoliteが入っているリモートマシンにログイン

3. リモートマシンの、/var/lib/redmine/repositories/にて、

git clone --mirror /home/gitolite-user/repositories/hogehoge.git
とする。

4. 次に、su gitolite-userして、/home/gitolite-user/repositories/hogehoge.git/hooks/にて、
vi post-receive
として、
#!/bin/sh
/usr/bin/git push --mirror /var/lib/redmine/repositories/hogehoge.git
と書いて、実行権限を付加。
chmod 700 post-receive

5. RedmineにWebログインして、新しくプロジェクトを作り、レポジトリに、/var/lib/redmine/repositories/hogehoge.git を割り当てる

以上。Redmineで確認してみる。って感じかと。

【Permission denied (publickey,gssapi-keyex,gssapi-with-mic)】WindowsのCygwinでsshでのGit cloneが上手く出来ないとき【fatal: The remote end hung up unexpectedly】

Windows7, Cygwinで↓のように怒られる。yoshiというのは、/home/hoge/.ssh/configで使っているHostである。

$ git clone ssh://yoshi/root/my_repos/sqlite_test.git
Cloning into 'sqlite_test'...
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
fatal: The remote end hung up unexpectedly

どうやら、Cygwinだとconfigで書いたHostが↑のような書き方(ssh://yoshi/root/my_repos/sqlite_test.git)だと参照されないようである。なので全部書いてみた(ssh://root@192.168.0.200/root/my_repos/sqlite_test.git)のがこちら↓。

$ git clone ssh://root@192.168.0.200/root/my_repos/sqlite_test.git
Cloning into 'sqlite_test'...
remote: Counting objects: 13, done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 13 (delta 6), reused 0 (delta 0)
Receiving objects: 100% (13/13), 654.45 KiB, done.
Resolving deltas: 100% (6/6), done.

きちんと行けました。なんか聞くところによると、C:\Users\hoge\.ssh\にconfigを書けば良いとか何とか…(試していないので不明だが)

Gitでmacのhome directoryをバックアップ

———-追記ここから———-
@2012年11月11日

Gitでバックアップ、は悪くはない。ローカルにオブジェクトが存在してるため毎日の差分バックアップがとても高速ではある。だが、↓の方にも書いているように容量を食う。その点が個人的には問題と感じなくはない…。多くの場合、使っている容量の2倍程度にはなる。120GBのSSDで事足りていたが、このように肥大化するわけで足りなくなってきた。ちょっと困る。240GBSSDを購入してくればいいのかもしれないが。
———-追記ここまで———-

前にも書きましたが、その続き。

実際にやってみました。

.gitignore ↓

# いったん全部含めない
/*

# ドットファイルもいったん全部含めない
/.*

# 含めないファイル
.DS_Store
.localized
/Pictures/iChat Icons/

# 含めるファイル・ディレクトリ
!/.git/
!/Desktop/
!/Documents/
!/my_repos/
!/non_git_repos/
!/買い物履歴/
!/Movies/
!/Music/
!/Pictures/
!/.ssh/
↑含めるものを明示的に記述するやり方の方がいろいろと楽な気はします。記述漏れには注意しなければなりませんが。

.gitconfig
[user]
name = hoge tarou
email = hoge@example.jp
[color]
# colorの設定(以下のコマンドは自動で色つける)
status = auto
diff = auto
branch = auto
interactive = auto
grep = auto
[push]
default = tracking       # defaultのpush先はtrackingしているリポジトリ
[core]
symlinks = false
autocrlf = false                 # CRLFを自動変換しない
editor = vim
quotepath = false
↑ symlinks = false, autocrlf = falseにしているのがポイントです。シンボリックリンクは無限ループしたりします(scpでなったことがあります。gitだと賢そうだからならないかも?)ので無視したほうが良いかと、autocrlfは、改行コードをあれこれしてくれるもののようですが、これがonの状態だとwarningがたくさん出てきたので切ったほうが良いと思います。

とまあ、こんな状態で↓、
$ git add -A
# ↑ けっこう時間が掛かりました。ホームディレクトリが57GB、↑のような設定で、core2duoで15分ぐらい。
# ↑ git add . って書くのが普通かと思いますが、
# -AとするとFinderで削除したファイルなども考慮してくれる感じなので
# (git add . だとそういうの考慮しないっぽい)、
# とりあえず -Aとしてます…あまりこの辺よく分かっていません。

$ git commit -m "first commit"
# ↑ これは割とすぐに終わった気がする…。

$ git remote add origin ssh://hoge/root/my_repos/macbook2009late.git
# 共有レポジトリを準備してからこうします↑。
# サーバーにログインして、git init --bare --shared で共有レポジトリ化できます。
# /.ssh/config で Host hogeってのがある場合↑。ないのなら、
# ssh://root@192.168.0.3/my_repos/macbook2009late.git
# みたいな感じでしょうか。

$ git push origin master -u
# pushします。
# こんな感じでした↓
Counting objects: 16833, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (16200/16200), done.
Writing objects: 100% (16833/16833), 14.12 GiB | 5.93 MiB/s, done.
Total 16833 (delta 4036), reused 3 (delta 0)
To ssh://hoge/root/my_repos/macbook2009late.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin by rebasing.

おおよそ2時間程度掛かりました。6MB/s程度しか速度が出なかったので仕方ないのですが…。サーバー側で、送られてきたファイルの暗号化解除あたりに時間が掛かっているみたいです。サーバー側はAtom N2800なのですが、Core 2 Duo以上なら、10MB/sは出るのではないでしょうか。

ちなみに、とても圧縮されたことに驚きました。

また、使用感ですが、新しくファイルを作って、git commit -a -m “commit”しても、あまり時間は掛かりません。2,3秒といったところでしょうか。pushも同様です。かなり高速という印象を抱きました。

毎日バックアップするにはちょうど良いのではないでしょうか。また、共有レポジトリから他のマシンでpullするだけでも冗長性が向上しますのでそうするべきでしょう。

ところでちょっとハマった点として、git add . を何度やっても、なぜかstageされないディレクトリがありました。意味不明過ぎましたが原因としては、そのディレクトリにも.gitがあり、かつ最新の状態をコミットしていないと、上の階層(今回はホームディレクトリ)でgit addがあっても反映されないっぽいです。

言い換えますと、.gitがあるディレクトリを最新状態にしておかないと、さらにその親ではgit addしてもその子ディレクトリは含まれない、ということです。

差分保存が高速、さらに他のマシンでpullするのが容易なので、gitをバックアップ代わりに使うのはなかなか良いのではないでしょうか。

友人には大反対されましたが(gitというブラックボックスを挟んで書き込むべきではない、とのこと。レポジトリが壊れたらどうするのかと)、悪くないと思いました。

gitは訳の分からないものでたいへんなのではないかと敬遠してきましたが、いざ使い始めると手放せなくなってきました。これがない生活が考えられません。取っ付き難いツールではありますが…。ただ、サーバーに共有レポジトリを作ったりするのは、sshなどの知識が必要なので、やはり取っ付き難いと言えるでしょう。

少し気になるのは、.gitの大きさがそれなりにある点でしょうか。たとえば、先の57GBのホームディレクトリ(hogeという名前とする)には、
$ du -s -h .git/
 15G	.git/
というふうに、15GBほどありますので。とは言え仕方ないですね。

gitoliteで他のユーザーをレポジトリにアクセスできるようにするシナリオ

– 複数人でのバージョン管理をしたい
– 何人参加するか分からない
– 人によりアクセス権限を付加したい(=レポジトリにより権限を分けたい。関係ないレポジトリにはアクセス出来ないようにしたい)
– バックアップもしたい
– githubは↑の要望は満たすけれども、お金を払わない限り公開されてしまう。というかそもそもgithubにクリティカルなソースを置きたくない
– お金はない
– クラウドサーバー(インスタンス)はたくさん持っている

という状態なので、サーバーを立ててそこで管理することを考えてみた。素朴に考えてみると、サーバーを私が立てて、管理者となって、コミッターを加えたいときには、コミッターをadduserして、パスワードを設定して、公開鍵を登録して(だいたいこの辺でパーミションとかAllowUsersとかで引っかかる)、sshでログインしてもらって、レポジトリを作ってもらって、となるけれども、複数人開発とかどうすればいいのって感じである。それにそもそも面倒くさそう。

この辺上手く解決するものはないかなと唸っていると、

_人人 人人_
>gitolite <
 ̄Y^Y^Y^Y ̄

があることを知った。参考リンクはこのへん↓。だいたい↑に書いた要望を満たす。

Git管理の神ツール「Gitolite」なら、ここまでできる!
さくらのVPS を改めて使いはじめる 10 – Git、Gitolite、GitHub


導入方法は↑のリンクを参照。私が行なっているgitoliteでのユーザー管理を読んでみて便利さを体感してください。というより自分用の流れの備忘録。

環境:
– Aさん
– 私
– サーバー(example.comというドメインを持ってるとする。そこのサーバーには、「私」はルートを持っているが、Aさんの権限はなく、そもそもアカウントすらないとする)

Aさん(以下A)「レポジトリhogeに参加させてよ」
私「おk」
私「Aさんの公開鍵、メールで添付して私に送って」
A「はいはい。id_rsa.pubはどこに置いたっけかなと…あった。いま送った」
私「受け取りました」
私、おもむろに自分のMacBookのターミナルの新しいタブを開く↓。

$ cd
$ cd my_repos
$ cd gitolite-admin
$ vi conf/gitolite.conf
-----編集内容ここから-----
repo    gitolite-admin
        RW+     =   gitolite-id-rsa

repo    testing
        RW+     =   @all

repo	hoge
		RW+		=	gitolite-id-rsa
		RW		=	a-san

# ↑ repo hogeに RW = a-san を書き加えた。
# gitolite-id-rsaと書いているのは、gitolite管理者の公開鍵の意味。
# repoはプロジェクトを意味していて、repoの横に書かれている文字列はレポジトリ名。
# RW+というのは、RがREAD権限、WがWRITE権限、+はgit reset出来るかどうかという意味。
-----編集内容ここまで-----

$ cd keydir/
$ vi a-san.pub
# ↑ 先ほどメールでもらった村人Aの公開鍵をエディタか何かで開いてコピペしてa-san.pubとした

$ cd ..
# 念のため書いておくが↑の場所は[~/my_repos/gitolite-admin]である。

$ git add .
$ git commit -m "add user a-san and give the right of reading a repo of hoge"
$ git push
# ↑commitしてpushした。

私「よし、これで落とせるようになったはず。まずはsshでの導通確認してみてくれない?シェルは触れないけど」
私「Aさんの端末で、ssh gituser@example.com って打ってみて? Hello とか表示されたらおk」
A「゚(∀) ゚ エッ? ssh a-san@example.com じゃないの?なんでgituser@example.comなの?」
私「違うんです。gituserが、他のユーザーを管理している(キリッ (…たぶんね。」(←間違ってはいないが、単純に/home/gituser/.ssh/authorized_keys にAさんの公開鍵が登録されているだけである)
A「ふーん。まあアクセスできるならどうでもいいや、俺のマシンでターミナル開いて ssh gituser@example.com っと。あ、なんか出てきた↓」
$ ssh gituser@example.com
PTY allocation request failed on channel 0
hello a-san, this is gitolite 2.3.1-1.el6 running on git 1.7.1
the gitolite config gives you the following access:
    @R_ @W_	hoge
Connection to example.com closed.

私「良かった、私のオペレーション間違っていなかった。では次にレポジトリhogeをAさんのマシンに持ってこよう。git clone ssh://gituser@example.com/hoge.git ってしてみて?」
A「へいへい。↓」
$ cd
$ cd my_repos
# ↑gitレポジトリのディレクトリをmy_reposで管理しています。
# 無ければ mkdir my_repos で作ってください。

$ git clone ssh://gituser@example.com/hoge.git
-----出力ここから-----
Initialized empty Git repository in /home/a-san/my_repos/hoge/.git/
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 6 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (6/6), done.
-----出力ここまで-----

# ↑これで、my_repos以下に、hogeというディレクトリが出来る

$ cd hoge

A「出来た。落とせた。これで編集できる」
私「コード書いたらaddしてcommitしてpushしてよ」

まあこんな感じ。新しい人が新しくレポジトリを追加したい時は、vi conf/gitolite.conf にて、repo を新たに書いて、 add, commit, pushすると、以下↓の様な感じでディレクトリが作成される。便利。ローカルでpushするだけで完結する。サーバーにログインしてレポジトリを作ったりしなくてもいい。
$ git remote -v
origin	kawahongogit:gitolite-admin (fetch)
origin	kawahongogit:gitolite-admin (push)

#↑ ~/.ssh/configで、hostnameにkawahongogitを作っているので↑でアクセス出来るようにしている。

$ git push
-----出力内容-----
Counting objects: 7, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 394 bytes, done.
Total 4 (delta 1), reused 0 (delta 0)
remote: creating deleteok...
remote: Initialized empty Git repository in /home/gituser/repositories/deleteok.git/
remote: 
remote: 		***** WARNING *****
remote:         the following users (pubkey files in parens) do not appear in any access rules:
remote: example(example.pub),hogehoge(hogehoge.pub)
To kawahongogit:gitolite-admin
   a4ec7d8..60d6b9c  master -> master
-----出力内容ここまで-----

# ちなみに初めてのコミットのときは git push origin master
# とする必要があるかも。加えて、originがきちんと設定されているかも確認。ダメなら、
# git push ssh://gituser@example.com/deleteok.git master
# などときちんと書く。

とまあ、たいへん便利。大事なことなので二度書くが、先にも書いたようにローカルの手持ちのマシンで編集してcommit&pushするだけで完結するので、一旦gitoliteのサーバーの設定を終えてしまえばそれ以降、サーバーを意識する必要が全くない。

肝心の、gitoliteの設定方法は、このポストで最初の方に引用したリンク先を参照。そのリンク先は私が書くよりずっと分かりやすいので。