Hatena::Groupsubtech

NaN days

ブログを移転しています。最新の記事は motemen.hatenablog.com へどうぞ

2013-02-07

GitHub のリポジトリを管理する小さいツール ghq

| 13:14 | GitHub のリポジトリを管理する小さいツール ghq - NaN days を含むブックマーク はてなブックマーク - GitHub のリポジトリを管理する小さいツール ghq - NaN days

この記事は古いです。お探しなのは ghq: リモートリポジトリのローカルクローンをシンプルに管理する - 詩と創作・思索のひろば の方かもしれません。

GitHub 上の面白そうなコードは手元に clone してから見るのが普通だと思いますがそれをこんな感じに整理してます。

  • ~/extrepo/@author/project に git clone する(~/extrepo/@motemen/ghq とか)
  • ~/extrepo/project からそこに symlink する(~/extrepo/ghq → ~/extrepo/@motemen/ghq

こうすると ~/extrepo/jquery などでアクセスできて楽です。「あの人のあのプロダクト」って思い出し方をしたいときには ~/extrepo/@motemen を辿っていけばよい。

tree するとこんな感じです。

.
|-- @cho45
|   |-- Config-ENV
:
|   |-- jsdeferred
|   `-- starter.pl
|-- @cloudhead
|   |-- http-console
|   `-- less.js
:
|-- Brownie -> @masaki/Brownie
|-- Class-Accessor-Lite -> @kazuho/p5-Class-Accessor-Lite
:
|-- webiblo -> @mizzy/webiblo
`-- ws -> @einaros/ws

ghq

そしてこれを簡単に行うためのオレオレツールが ghq です。以下のようにして使えます。

clone する
% ghq [-clone] https://github.com/motemen/polka

のようにすると ~/extrepo/@motemen/polka に git clone されて先に伸べたようなシンボリックリンクが作られます。

ディレクトリへ移動する
% ghq [-cd] polka

または

% ghq [-cd] @motemen/polka

とするとそのディレクトリへ cd します。

インストール

zsh のスクリプトで書いてます。

% git clone git://github.com/motemen/ghq.git ghq_dir

したのち

fpath=(ghq_dir/zsh $fpath)
autoload -U ghq
autoload -U compinit; compinit

と .zshrc に書くと、ghq というコマンドと補完(-cd したときなど)が有効になります。clone 先のルートディレクトリは git config ghq.root で変更できます(たぶん)。

あとすでに同名のリポジトリが存在しているときは remote に追加するようにしてみたんだけどそれは余計なお世話だったかもしれない……。

2012-11-28

最近変更されたブランチを列挙する

| 19:25 | 最近変更されたブランチを列挙する - NaN days を含むブックマーク はてなブックマーク - 最近変更されたブランチを列挙する - NaN days

週明けになるとアレ?先週なにしてたっけという気分になるので git-recent-branches というスクリプトを書いて、ここ数日間で変更のあったブランチを一覧しています。

git-rev-parse でコマンドラインオプションを解析してみたかったので、シェルスクリプトになってます。

こんな感じに、7 日以内に更新されたブランチとその最新コミットを一覧できる (node のリポジトリを見てみた):

% git recent-branches --no-merged --days=7 --date=iso     
2012-11-27 18:21:05 -0800 remotes/origin/streams2-net-perf-wip - streams2: Set 'readable' flag on Readable streams [isaacs]
2012-11-27 23:52:49 +0900 remotes/origin/v0.8 - doc: Fix missing link target to 'https.request()' [Ryunosuke SATO]
2012-10-25 13:49:32 -0700 remotes/origin/v0.8.15-release - 2012.11.26, Version 0.8.15 (Stable) [isaacs]

ちなみに一番下の日付が 10-25 なのは、その前のコミットが 11 月だったので一覧に出てきたみたいです。

オプションは以下の通り。実装は単に git-log にいろいろフォーマットを与えているだけです。

  • --no-merged を指定すると現在のブランチにマージ済みのものは表示されない
  • --days=n で何日以内のブランチを見るかを指定
  • --date=format は日付のフォーマット

2012-09-17

Git リポジトリの Web サイト (GitHub とか) を簡単に開けるコマンドを作った

| 22:50 | Git リポジトリの Web サイト (GitHub とか) を簡単に開けるコマンドを作った - NaN days を含むブックマーク はてなブックマーク - Git リポジトリの Web サイト (GitHub とか) を簡単に開けるコマンドを作った - NaN days

git-browse-remote というコマンドです。

インストール

今回はじめて RubyGems としてシェアさせていただきましたので

gem install git-browse-remote

でインストールできます。git browse-remote というサブコマンドが使えるようになります。

できること

  • 現在のリポジトリをホストしている Web サイトをブラウザで開きます
  • ブランチやコミットを指定するといい感じに対応するページを開きます

使い方

とりあえずインストールしたらまずは以下を実行してください。

% git browse-remote --init
Writing config for github.com...
Mappings generated:
browse-remote.github.com.top https://{host}/{path}
browse-remote.github.com.ref https://{host}/{path}/tree/{short_ref}
browse-remote.github.com.rev https://{host}/{path}/commit/{commit}

これで GitHub 用の設定が ~/.gitconfig に記録されます。browse-remote.github.com.top みたいな設定項目が増えているはずです。

で、任意のローカルにある (origin が GitHub を向いている) リポジトリに cd して

% git browse-remote

とすると、GitHub のページが開くはずです。引数にコミットやブランチを指定することもできて、たとえば cpanminus をクローンしたディレクトリで

% git browse-remote 1.5000

のようにタグ (またはブランチ) を指定すると https://github.com/miyagawa/cpanminus/tree/1.5000 が、

% git browse-remote 215cb345

のようにコミットを指定すると https://github.com/miyagawa/cpanminus/commit/215cb345d4312c744e7a299a7a33dbc6db33df74 がブラウザで開かれます。無指定の場合は現在 (HEAD) のブランチ/コミットが参照されます。

開かれうるページは 3 種類あり、そのリポジトリのリモートの URL を参照して、ウェブ上のリポジトリビューワの、

  • master ブランチの場合はプロジェクトのトップ (--top)
  • その他のブランチ/タグの場合はそれに対応するブランチ/タグのページ (--ref)
  • それ以外であれば1コミットのページ (--rev)

を開きます。(括弧内はそのページを開くことを強制するコマンドラインオプションです)

さらに以下のように remote が複数ある場合、

% git config --get-regexp '^remote\..*\.url$'
remote.origin.url git://github.com/miyagawa/cpanminus.git
remote.motemen.url git@github.com:motemen/cpanminus.git
% git browse-remote motemen/master # もしくは motemen (motemen というタグやブランチがない場合)

で、motemen がフォークしたプロジェクトのページ (https://github.com/motemen/cpanminus) を開くことができます。

URL のカスタマイズ

git-browse-remote は指定されたブランチ/コミットからどういったページを開くかを決定し、それぞれに用意されたテンプレートを用いて URL を組み立てます。--init 時に表示されている内容ですが、例えば GitHub の場合は ~/.gitconfig に

  • browse-remote.github.com.top (プロジェクトのトップ)
  • browse-remote.github.com.ref (ブランチ/タグ)
  • browse-remote.github.com.rev (コミット)

という風に指定されています。社内リポジトリなど、特定のホストに対して独自のリポジトリビューワを使いたい場合には、git config browse-remote.my.host.top http://… のようにして (または .gitconfig を直接編集して) これをカスタマイズすることができます。テンプレートで使える変数は以下のとおり。{} 内が Ruby のコードとして評価されるかんたんテンプレートです。

  • host ("github.com")
  • path ("motemen/git-browse-remote")
    • ただの文字列ではなく、{path[-2..-1]} のようにスライスすることができます
  • ref ("refs/heads/master")
  • short_ref ("master")
  • commit ("04f7c64ba9d524cf311a673ddce5722b2441e2ea")

ちなみに GitHub Enterprise を使っているなど、配置が完全に GitHub と同じような場合には

% git browse-remote --init github.local=github 
Writing config for github.local...
Mappings generated:
browse-remote.github.local.top https://{host}/{path}
browse-remote.github.local.ref https://{host}/{path}/tree/{short_ref}
browse-remote.github.local.rev https://{host}/{path}/commit/{commit}

とすることで簡単に設定をおこなえます。一応 GitWeb 用に --init host=gitweb というのも作ってますが、GitWeb 常用してないので分からない……。

どうぞご利用ください。

2012-07-17

Git 使ってるときに carton.lock の diff を読みやすくする

| 19:30 | Git 使ってるときに carton.lock の diff を読みやすくする - NaN days を含むブックマーク はてなブックマーク - Git 使ってるときに carton.lock の diff を読みやすくする - NaN days

Carton が生成する carton.lock は開発中わりと頻繁にアップデートされるものの JSON で書かれているので diff が冗長で困る!

そういうときは .gitattributes にこういう風に書いてやる:

% cat .gitattributes 
/carton.lock diff=cartonlock

で、diff=cartonlock なファイルの場合は JSON を "module~version" 形式に展開したもののリストを diff する、という風にしてやると、見やすいです。(--global はお好みで)

% git config --global diff.cartonlock.textconv 'perl -MJSON -0e "\$m = decode_json(<>)->{modules}; print qq(\$_~\$m->{\$_}->{version}\n) for sort keys %\$m"'

git log なんかが以下のようになり便利です。

% git log -p -1 -- carton.lock        
commit ca68ce560d76bbdcde45b6c56c693a4893135e46
Author: motemen <motemen@gmail.com>
Date:   Tue Jul 17 12:53:55 2012 +0900

    +Devel::StackTrace::WithLexicals

diff --git a/carton.lock b/carton.lock
index 9bd1cca..d554455 100644
--- a/carton.lock
+++ b/carton.lock
@@ -54,6 +55,7 @@ Devel::Cover::Report::Clover~0.35
 Devel::KYTProf~0.01
 Devel::StackTrace~1.27
 Devel::StackTrace::AsHTML~0.11
+Devel::StackTrace::WithLexicals~0.10
 Devel::TrackObjects~0.5
 Digest::SHA1~2.13
 Dist::CheckConflicts~0.02

2012-04-19

あるコミット範囲でマージされたブランチを列挙する

| 20:56 | あるコミット範囲でマージされたブランチを列挙する - NaN days を含むブックマーク はてなブックマーク - あるコミット範囲でマージされたブランチを列挙する - NaN days

業務でウェブアプリケーションを運用していくとき Git のブランチは日々の作業を続けるうちに前進してゆくのであとから「このブランチいつマージされたんだっけ?」などと思っても確認しづらかったりする。なので適宜記録しておくのがよいな、と思い、適切な粒度をということで、デプロイのたびに記録するようにしています。

デプロイの際に以下のようなコマンドを実行する:

git rev-list $prev..$curr --topo-order | git name-rev --stdin --name-only --refs='refs/remotes/origin/*' | perl -anal -e 'm<^remotes/origin/((?!HEAD|master)[\w/-]+)$> and print qq(- $1)'

$prev は前回のコミット SHA1、$curr は今回のコミット SHA1 です。

これをデプロイツールの設定に仕込んで起動してやることで

- hogefeature
- fix/fuga

のように今回のデプロイで取り込まれた変更が一覧できます。あとはこの内容を業務で使うグループウェアなり git notes なりに残しておけばあとから見直すときに便利です。

2011-06-28

Git のコミットログで会話できるリレーチャットシステム

| 21:09 | Git のコミットログで会話できるリレーチャットシステム - NaN days を含むブックマーク はてなブックマーク - Git のコミットログで会話できるリレーチャットシステム - NaN days

https://github.com/motemen/git-log-relay-chat

一つの Git リポジトリをフォークした人同士で語らえる、簡単チャットの登場です。

app.psgi があるだけですが、plackup する前に config.pl を以下のような感じで設定する必要があります。

  • 親は (例えば) gist を作ってローカルに clone し、ここへのパスを git_root として指定する
  • チャットの参加者にこの gist を fork してもらって、その Public Clone URL のリストを pull_remote として指定する
  • 他の参加者も同様に、自分のローカルリポジトリと他人のリモートを config.pl に書く

今回は この gist を使い、例えばこんな感じになります。

# config.pl
git_root => 'gist-1050889',
pull_remote => [
    'git://gist.github.com/1050895.git', # hakobe
    'git://gist.github.com/1050896.git', # cho45
    'git://gist.github.com/1050905.git', # shiba-yu36
],

この準備の上で plackup してブラウザで見るとチャット画面になっています。入力欄にメッセージを入れて送信すると発言が git commit; git push され、フォーム空送信するとすべてのリモートリポジトリから git pull されます。git pull の際にログがマージされ、参加者は各々独立しつついい感じにチャットができます。一人で喋り続けていても pull すれば会話に混ざれるのが便利です。

今回もこのように、楽しく語らえました。

f:id:motemen:20110628205636p:image

git log --graph をするとマージ地獄になっているのが分かります。

* 8f0a000a2d913380be30e536066811efbee3855d --graph
*   2b6b7cc7f30658d48adfd7293811004aad436d01 Merge branch 'master' of git://gist.github.com/1050896
|\  
| * 8352e5ac7fb177eb1942c5cdc0df6ea3e04fa368 ぽよぽよ〜
| *   2445980b73ffff9a534e6a60f578089b8e2c6408 Merge branch 'master' of git://gist.github.com/1050895
| |\  
| * \   c32aeea5601984db4576d0764baccc722a5a57d5 Merge branch 'master' of git://gist.github.com/1050889
| |\ \  
| * \ \   29fcc9aa7c4bbc8716e12a2f25838ac8b20432c2 Merge branch 'master' of git://gist.github.com/1050889
| |\ \ \  
* | \ \ \   938151941aff00f07b8631029682a1d5f885e740 Merge branch 'master' of git://gist.github.com/1050895
|\ \ \ \ \  
| |_|_|/ /  
|/| | | /   
| | |_|/    
| |/| |     
| * | | be0304fc464232627191fdb50e26ba100d28c64b こわい..
| * | |   5c0b2c0f1ec60a9d675067607e54ef159e672222 Merge branch 'master' of git://gist.github.com/1050896
| |\ \ \  
| | |/ /  
| * | |   8b0de3c0ae485a25c7144bec2b8dbe3ef4664992 Merge branch 'master' of git://gist.github.com/1050889
| |\ \ \  
| | | |/  
| | |/|   
| * | |   2bd181e44c18c39742480dddf8812b92043bd645 Merge branch 'master' of git://gist.github.com/1050896
| |\ \ \  
* | | | | b36d71a6d198abbe8969e73471d5949cec34f23a ぽよ〜
* | | | |   f65e2e2428409f171e7d5575bf5a74f8c3b52084 Merge branch 'master' of git://gist.github.com/1050896
|\ \ \ \ \  
| |_|_|/ /  
|/| | | /   
| | |_|/    
| |/| |     
| * | | 5006ae8e5eec2f040e729945d84d145347da0997 github つかえなくなったらこわい
| * | | 90a5bfee8201c3f3179d4298d5edde4658776f09 グラフかっこいい
| * | |   fce4490f92e117efa528527bde09e3db129c8bb9 Merge branch 'master' of git://gist.github.com/1050905
| |\ \ \  
* | | | | 0b1d5a3ebfa9319563356f93efd66ef34e7bc143 jj
* | | | |   ecae3a19babb4a3ddd33f612647bd0f20f9ea25e Merge branch 'master' of git://gist.github.com/1050905
|\ \ \ \ \  
| |/ / / /  
|/| / / /   
| |/ / /    
| * | | 806e48d7e3770e360cc1560882546ad775593159 お腹いっぱいです
| * | |   e690bbccd882d5e165533df248a8e60a67c6a851 Merge branch 'master' of git://gist.github.com/1050889
| |\ \ \  
| * \ \ \   2426b253c5668dd1a90aa7ff6bbb8493563fb6d2 Merge branch 'master' of git://gist.github.com/1050896
| |\ \ \ \  
| | | |_|/  
| | |/| |   
| * | | |   5f0e40880989a3ca93a05fc105a42c8526a731e7 Merge branch 'master' of git://gist.github.com/1050896
| |\ \ \ \  
| * \ \ \ \   2b754a1d7977fc26d4a6b1d75fdac7e082c61606 Merge branch 'master' of git://gist.github.com/1050889
| |\ \ \ \ \  
| * \ \ \ \ \   b8f0399c9a79cfa4c42fb574faf106bf79a40a7e Merge branch 'master' of git://gist.github.com/1050889
| |\ \ \ \ \ \  
| * \ \ \ \ \ \   43d2ae4e29702952894ad9b3f07dff9b960e31a7 Merge branch 'master' of git://gist.github.com/1050889
| |\ \ \ \ \ \ \  
* | | | | | | | | 2d8efa748adf561b7942ad197ac4313359029dd9 うける〜
| |_|_|_|_|_|/ /  
|/| | | | | | |   
* | | | | | | | ce21dee9a33da8bcccbe83c46136051b1cc5850e log
... 

今回は id:cho45 さん id:hakobe932 さん d:id:shiba_yu36 さんのおかげで高速に開発が進みました!ありがとうございます!!!

2011-03-30

今日の .vimrc: Git における最後の変更をハイライトする

| 20:29 | 今日の .vimrc: Git における最後の変更をハイライトする - NaN days を含むブックマーク はてなブックマーク - 今日の .vimrc: Git における最後の変更をハイライトする - NaN days

ざっと、ファイルどの辺を変更してたか知りたいときに便利です。

http://gyazo.com/926b0af7210395472b208a1e9746d91d.png

metarw-git (と metarw) が必要です。

https://gist.github.com/894232

2010-11-08

submodule べったりの開発をするときに便利なスクリプト 2 点

| 20:21 | submodule べったりの開発をするときに便利なスクリプト 2 点 - NaN days を含むブックマーク はてなブックマーク - submodule べったりの開発をするときに便利なスクリプト 2 点 - NaN days

submodule なんて使わないほうが幸せなことは多いんですが、どうしても必要になってしまうのは仕方ない。submodule をバリバリ更新しながら開発をする場合に重宝しているスクリプトです。

.git/hooks/prepare-commit-msg

https://gist.github.com/667569

git のフックです。コミットに submodule の変更も含まれている場合、コミットメッセージ編集時に自動で submodule の HEAD のメッセージを入れてくれます。いい例がないのですが


 * Some-Submodule: あれこれ更新

こんな感じに入力されてエディタが起動します。

git-submodule-track

https://gist.github.com/667573

submodule の状態は SHA1 で管理されているので、更新しようとするときどのブランチの最新にすればいいか混乱することがありますが、.gitmodules に

[submodule "modules/Some-Submodule"]
    track = origin/develop

と書いておき git submodule-track とすると、この設定が書いてある submodule のブランチをよしなに最新にします。よしなにというのは例えば上のような設定の場合

  • 既に develop ブランチにいるときには git pull
  • そうでなく、develop ブランチがあるときは git checkout develop && git pull
  • develop ブランチがないときは git fetch && git checkout --track origin/develop

という感じです。最近手を入れてみたので変なところがあるかもしれませんが、自分で使ってるぶんには今のとこ問題ありません。


以上 2 点のオレオレスクリプトでした。