tag:blogger.com,1999:blog-21195452204277176402024-03-05T15:10:38.604+09:00誰得UNIX誰かが得するUnix関連技術の情報kthttp://www.blogger.com/profile/11677147387926441458noreply@blogger.comBlogger47125tag:blogger.com,1999:blog-2119545220427717640.post-17476958429104804762016-09-28T21:41:00.000+09:002016-09-28T21:43:14.359+09:00C/C++中規模プロジェクト用のMakefileを自動生成する「C/C++中規模プロジェクトのための超シンプルなMakefile」という記事が話題になっていた。
僕はC/C++のプロジェクトを作る場合、いつも Autotools (Autoconf, Automake, etc. の総称) を使ってる。
Autotools は少ない労力で似たような目的に使えて非常に便利なんだ("out-of-sourceビルド" や、ヘッダ依存関係の自動生成、再帰 make 等々に対応、make install などの便利ターゲットも準備されている)。 ./configure && make && make install というコマンドは有名で、みんな一度は実行したことがあると思うけど、この3つのコマンドによるビルドが可能な configure スクリプトとMakefile.in は普通、 Autotools によってkthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-9496191077317658382015-07-26T12:36:00.000+09:002015-07-26T12:37:55.184+09:00Gitを使う上で便利なzshの設定僕がzshrcに設定している Git 用の設定を紹介する。
プロンプトにブランチ名を表示
run-help をカスタマイズ
あんまりヘビーなカスタマイズはしてなくて,必要最低限,って感じだ。
まずは「プロンプトにブランチ名を表示」から。
設定は以下の通り。
autoload -Uz vcs_info
zstyle ':vcs_info:*' formats '(%b)'
zstyle ':vcs_info:*' actionformats '(%b|%a)'
function precmd () { vcs_info }
RPROMPT='[%(5C.%4C.%~)${vcs_info_msg_0_}]'
1行目はプロンプトにVCS関連情報を表示するためのモジュールのロード。
2, 3行目は表示内容のフォーマット指定。指定可能なフォーマットはいくつもあるけど,僕はkthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-68182421727294453832015-06-17T22:24:00.000+09:002015-06-17T22:25:36.929+09:00SICP3章後半に書いてあるストリーム(遅延リスト)についてSICP3章ってそんなに「オブジェクトはオワコン! 関数プログラミング的なストリームこそ最強!」な内容だったかなぁ、と思って3章の最後を読みなおしてみたが、こんな内容だった:
オブジェクト(状態をオブジェクトのローカル変数とし、状態の変更をローカル変数への再代入とするような)モデルは直感的で強力だけど「実行順序」や「同期」といった面倒な問題をプログラミングにもたらす。
関数プログラミング的モデル化であるストリームは状態を「時間」をパラメータとしたリストとしてモデル化することで「実行順序」の問題を解消する。 銀行口座のモデルも口座へのトランザクションの列を入力ストリームとして残高の列を出力ストリームにすれば対話システムとして「状態」を持っているかのように振る舞える。
しかしストリームであっても複数の対話者が口座を共有している状況を考えると、入力ストリームをマージさせなければならなくkthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-33345733770889692112015-03-29T17:33:00.000+09:002015-03-29T17:33:35.874+09:00Gitの最初の姿この4月で、Gitが誕生してからちょうど10年になるようだ。
10年前、つまり一番最初のGitはどのようなプログラムだったんだろう?
当然だけど Git プロジェクトのリポジトリには10年前の最初の姿が e83c516 というコミットとして記録されている。
% git log --max-parents=0
commit e83c5163316f89bfbde7d9ab23ca2e25604af290
Author: Linus Torvalds <torvalds ppc970.osdl.org>
Date: Thu Apr 7 15:13:13 2005 -0700
Initial revision of "git", the information manager from hell
# --max-parents=0 は親のないコミット、つまりルートkthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-89191769290036305772015-02-15T07:29:00.000+09:002015-02-16T03:59:44.441+09:00rebase して FF マージすることによる一直線の履歴は本当にわかりやすいのかGit でトピックブランチを統合ブランチにマージする直前、最新の統合ブランチの先端にrebaseしたうえで FF (Fast-forward)マージすることで、見かけ上の履歴は一直線になる。 このような一直線の履歴が「わかりやすい」と解説されていることが多いんだけど、これは本当だろうか?
実は、このような見かけだけ「一直線」の履歴はむしろトピックの範囲が不明確になるのでわかりにくいんだ。
rebase && FF マージする理由としてよく挙げられるのが「マージコミットがあると log で見た時に履歴が入り乱れてわかりにくい」というものなんだけど、 これは明確な誤りだ。
マージコミットを含んだ統合ブランチにおいてファーストペアレントが常に統合ブランチ側になるようにマージしていれば[※]、
[※] これは「統合ブランチ側をcheckoutして git merge kthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-65304591258504935292015-02-07T23:20:00.000+09:002015-02-08T11:13:33.431+09:003imp 読書メモ(2)今回はチャプター4の最初の第1節について書く。
3imp 未読の人には何が何やらわからない内容だと思う。 読んだことがある人は間違い探しでもしながら読んでもらえればと思う。
チャプター4 はスタックベースモデルの章だ。
ヒープベースモデルでは変数ルックアップと関数呼び出しのコストが大きい。一方でスタックベース言語の代表みたいなCなんかは、 コールフレームや環境にヒープを必要としないのでそのへんが速いようだ。でも(定義場所からリターンした後も使えるような本物の)ファーストクラス関数、 TCO, 継続などをスタックベースで実装するのは簡単ではない。(Cなどでそういった機能が限定的なのもそれが理由だろう)
そこでチャプター4ではまずこの辺のサポートをしないSchemeライクな言語をスタックベースで実装し、最終的にこれらの機能のサポートを目指す。
つまり 4.1節で考えるのは、 kthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-75558099930924685122015-01-30T03:09:00.000+09:002015-02-01T09:52:28.067+09:00Gitでpush -fせずにmasterの間違いを修正する方法そんなものはない (タイトルは釣りだ。ゴメン)。
でもよく聞く「ミスに気づいて、思わず master に push -f しちゃった」という話は、実はある運用方法で簡単に防ぐことができるんだ。 その運用方法とは・・・
「使い捨て統合ブランチを作って、最初はそちらにmergeすること」
これだけ。
どのようなやり方なのか、具体的に見ていこう。
1. まず使い捨て統合ブランチを作る。
使い捨て統合ブランチの名前は何でもいいけど、pu (proposed update) がよく使われる。ここではとりあえず pu という名前を使うことにする。チェックアウトしたら push --set-upstream / -u で push しておこう。
% git checkout -b pu master
% git push -u origin pu
2. 新しいトピックがあれば、まず kthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-16416118390187483322015-01-22T05:27:00.000+09:002015-01-22T05:28:05.478+09:00『アンダースタンディング・コンピュテーション』とベネディクト・カンバーバッチ昨年の話なんだけど、会社の読書会で『アンダースタンディング・コンピュテーション』を読んだ。
普通の技術書(とくに他のオライリー本)と比べると、この本を読むことによってどういうスキルが身につくのか、若干イメージしにくいと思うんだけど、それはこの本がプログラミングの基礎的な内容を扱ってるからだと思う。
個人的に得られた知見とかは以下の通り
プログラミングの「意味論」という言葉が何を示しているのか、なんとなくわかった(一言で言えばevalの仕様。例えばコンパイルや型システム(や静的解析)はプログラムの動的な意味論(その言語のプログラマが、自分が書いたプログラムがどう動くと思っているかを想像するときに想定する動作仕様)ではなく、同じ字面のプログラムに対して翻訳や型の整合性のチェックといったそれぞれの異なる役割を実現する意味論でevalしている。)
ラムダ計算とかYコンビネータkthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-82940921442856556252015-01-20T23:56:00.000+09:002015-01-20T23:56:27.481+09:003imp 読書メモ(1)「Three Implementation Models for Scheme」(R. Kent Dybvig, 1987)という、Schemeの実装モデル3パターンについて論じた論文がある。
Scheme 方面では有名らしく、 ファイル名由来だと思うんだけど、通称 3imp と呼ばれて親しまれているみたい。(@nfunato さん、情報ありがとうございます)
これはその読書メモだ。3章まで読んでいる。続きはまた後日。
概要
(当時)Scheme実装モデルには3パターンあるらしい。当時主流のヒープベース、論文著者がChez Schemeとして実装した性能がいいスタックベース、FFPマシン用ストリングベース。
FFPとは何なのか謎。「マルチプロセッサ、ストリングリダクション」と書いてあるが、よくわからず。マシンは(当時)まだないようだが、FFP言語を直接実行するFFPマシンが実現さkthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-35578369350460413552015-01-16T23:45:00.001+09:002015-01-16T23:45:17.353+09:00仕事で英語を使わないITエンジニアが効率よく英語を習得するにはタイトルは釣りです。ごめんなさい。
普段英語をまったく必要としない職場にいるのですが、そのメンバー
の中では比較的TOEIC点数が高めのため、
「プライベートで英語使うことあんの?」(ないです)とか
「海外経験あんの?」(ないです)とか
聞かれることが増えてきたので、これまで勉強してきた中で「コレ
は効いたな」あるいは「気軽にできて続けやすい」という、まぁ自分
の中での勉強法のランキングを主観ですが整理してみたので調子に
乗って紹介します。
その前にまず私のスペックです。
・学生のときは英語は苦手科目でした。勉強した記憶もなし。
・入社(10年くらい前)時点のTOEICが500点くらい
・2014年時点のTOEIC(IP)スコアは 845 (L:480, R:365)
・海外留学等経験なし、普段の仕事で英語を使う機会なし
・英語を必要とするのは(主に趣味で)技術系のkthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-7669754818897084712015-01-15T22:28:00.000+09:002015-01-16T18:48:18.037+09:00Yコンビネータを導出してみる以前 Yコンビネータが call-with-myself だという記事を書いたけど、
そこでは Y コンビネータがどこから来たのか、ということについては書かなかった。
今回はYコンビネータがどこから来たのかについて書くつもりだ。
あらかじめ大筋を話してしまうと、Yコンビネータの導出は
1. 自分自身の名前を使っても良いので、簡単な再帰関数を定義する。
2. その定義から自分自身の名前をどうにかして外に追い出す
って感じで進めるので頭の片隅に置いておいてほしい。
じゃあまず n の階乗を計算する関数 fact を考えるところからはじめよう。
fact は再帰で簡単に定義すると下記のとおりだ。
(define (fact n)
(if (zero? n)
1
(* n (fact (- n 1)))))
実行すると正しい回答が返る
(fact 5) ; =kthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com1tag:blogger.com,1999:blog-2119545220427717640.post-55112028063670003772014-12-23T15:50:00.000+09:002014-12-23T17:11:10.857+09:00オレオレLisp処理系を実装してみた(感想)SICP4章が「Lisp実装しようぜ」なのですが、本ではSchemeでLispを実装するというメタサーキュラーなevalを作ってて、実装言語と被実装言語の境目をちゃんと理解できるか不安だったのでC++で実装してみる、ということをやってみました。
やってみたら意外と簡単で、足りないところは多々ありますが3日でLispとしてとりあえず動くようになりました。
(実装メモ1日目、2日目、3日目)
以下は今回の実装を体験してわかったこととか感想とかです。
静的型システムの言語で動的型システムの言語を書くのはちょっと面倒
GCがない言語でGCをサポートする言語を書くのは相当面倒そう。
C++のdynamic_castは注意が必要
Effective C++ は偉大である
偉大な本が示してくれる落とし穴も、実際には自分がはまってから気づくことになって悲しい
print は再帰的に書くと楽
kthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-10668615084611058592014-12-23T15:15:00.001+09:002015-01-18T22:05:54.029+09:00オレオレLisp処理系を実装してみた(3日目=最終日)Lisp処理系の実装メモ3日目です。(1日目, 2日目)実装メモとしてはこれが最終日になりますが、感想などのまとめを次の記事としてのせるつもりです。例によってコードは一番下に載せてます。
== 3日目 ==
car, cdr 等が正しく動かない件、lambda が動かない件は両方とも
1日置いたら解決した。
car, cdr, ... のほうの原因は内部でS式を扱ってる関数をユーザに見せる関数prm*()に
ラップするときのミス。
引数が一つのリストにまとめられてくるので、(まさしくapplyされる状態なので)
それを受け取る側の実装は
lptr prmcar(const lptr& args) { return car(car(args)); }
lptr prmcdr(const lptr& args) { return cdr(car(args)); }
kthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-14666654194419342802014-12-22T20:05:00.000+09:002014-12-23T15:29:30.373+09:00オレオレLisp処理系を実装してみた(2日目)Lisp処理系の実装メモ2日目です。(1日目、3日目)
例によって最後にその日の最後の時点くらいのコードを載せますが、
結構がっつり書き換えたりしてるんで、あんまりメモ内の記述と整合性がないかもしれません。あくまで参考ということで。
== 2日目 ==
evalにむけて少し関数を書いてたけど eval より reader のほうが先か、ということでreaderを実装する。
最初カッコの対応つけるのに、カッコのネストレベルを
渡すようなインターフェースにしてたんだけど、
printer同様'('を読んだらread_list()に飛んでそいつは
reader()を呼ぶ、という感じで再帰的な感じで書くと、スッキリできた。
再帰的に作ってやればread_list()が同一レベルのカッコの対応に責任を持つことが
できるので、 そもそもネストのレベルなんて見なくてもread_list(kthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-82963119659021198952014-12-21T23:45:00.000+09:002014-12-23T15:28:36.258+09:00オレオレLisp処理系を実装してみた(1日目)この週末でLisp処理系をスクラッチから作ってみたので、そのときのメモをアップしていきいます。
この記事はその初日のメモです。(2日目、3日目)
あんまり推敲もしてないので読みにくいかもしれません。
その日のコードは最後に Gist を貼っておきます。
== 1日目 ==
SICPを読んでて4章に入ったところで無性にLispをつくりたくなったので作ることにした。
Lispを実装したことないとLisperを名乗れないらしいとどこかで見た気がするので、
完成したら(REPLができたら)俺もLisperを名乗れるかもしれない。
実装言語はSICPだとSchemeだけど、C++にすることにした。理由は:
* 静的型付けでどうやって実装するのか考えてみたかった
* C++で書けばもしかして少しは速いんじゃないか、という下心
まず大雑把な設計を考える。
LISP-2にするとちょっと大変kthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-8271279773286249232014-11-26T23:59:00.000+09:002014-12-21T23:46:15.975+09:00Schemer のための「すぐ理解できるYコンビネータ」ラムダ計算の説明などによく登場するYコンビネータ(不動点コンビネータ)ですが、
「ラムダだけで再帰関数を定義できる」というのはわかってもYコンビネータを使った関数の定義は複雑ですし、
そもそもYコンビネータ自体の定義からしてどうなってるのかよくわからないので、少し難解です。
しかし、Schemer (Schemeプログラマ) 向けには簡単に理解できる説明があります。
Scheme でよく使う call-with というイディオムがありますが、これを使うことで
「Yコンビネータとは call-with-myself である」と言えるのです。
具体例で説明します。
階乗を計算する関数 fact を考えます。*1
fact は再帰で素直に定義すると以下のようになります。
(define (fact n)
(if (zero? n)
1
(* n (fact kthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com1tag:blogger.com,1999:blog-2119545220427717640.post-34667909472600333532014-11-18T23:29:00.000+09:002014-12-21T23:46:53.264+09:00自分が書いているプログラムが正しく動くと信じてプログラムを書く感覚次のような記事が話題になっていたんだけど、少し感じるところがあったのでメモっとく。ただの自分の感覚なので、結論とかは特にない。
『難しいプログラムでは自分がいままで書いたコードが正しく動くと信じて残りのコードを書く必要がある -- Medium』
多分この元記事の方は複雑なプログラムのことについて言っていて、俺の考えてるような単純な例ではなかろうと思うんだけど、自分の場合は結構単純なプログラムであっても再帰が関わってくるとそう感じる場合がある。単純にループにできそうにないやつ(本質的に再帰的なやつ)とか。
例えば Scheme でリストの長さを返す関数 length は次のように定義できる。
(define (length lst)
(if (null? lst)
0
(+ 1 (length (cdr lst)))))
これも実際には再帰呼出しのkthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com1tag:blogger.com,1999:blog-2119545220427717640.post-31017957725348328642014-11-03T00:47:00.002+09:002015-01-18T11:36:59.225+09:00『プログラミングGauche』を読んだフムフムヌクヌクアプアア本としても知られる『プログラミングGauche』を最近読みました(今3周目を読んでます)。
読後の感想ですが、ひとことで言えば『Scheme すごい、Gauche 楽しい』って感じです。
プログラミング自体の初心者には向きませんが、ほかの言語を知っていれば難易度の勾配もゆるやかで、無理なく読み進められる良い本だと思います。
とくに面白かったのは7章(手続き)、18章(マクロ)、 19章(継続)あたりです。
関数プログラミングに触れたことがない人は、7章まで読むとその面白さを体験できると思います。Common Lispを触ったことがある自分でも、Lisp-1での関数プログラミングの気持ちよさは特筆すべきものがありました。あとLispのパワーを顕著に体感できるのが18,19章です。こういうのを知ってしまうと Scheme ならアレができるのに、とか思ってしまいそうkthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-24749566095278754502014-06-28T19:01:00.001+09:002014-06-28T19:01:49.230+09:00gitworkflows(7)を図解したスライドをアップしました前回に引き続き、こちらも会社の読書会でGit関連本の番外編として実施したgitworkflows(7)の解説資料(の加筆修正版)です。
マニュアルからすると講義用にかなりつまみ食い的な内容になってます。
副読本的な位置づけでマニュアルを読むのも良いかなと思います。
Gitの布教などにお使いください。
図解gitworkflows(7) from ktateish
講義した感触だと、やはり少しややこしいワークフローだと感じるようです。
確かにGitの動きにある程度慣れてないと理解しづらいですし、スライドでは最終的な機能リリース直後だけ見るとシンプルなコミットグラフなんですが、途中のnextが混じった図は結構カオスです。
ただ、「ステージング環境は便利そう」という感想もありました。
Q and Aに出てきていますが、プロジェクトの状態や開発スピードによっては kthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-39041666185486156212014-06-24T08:29:00.000+09:002014-06-25T23:14:26.626+09:00コンセプトから理解するGitコマンドGitのコマンドってわかりにくい、というかとっつきにくいものや、役割が複数あって覚えにくいものとか多い気がします。
でもGitが内部でデータ(コミットやツリー、ブロブ等いわゆるGitオブジェクト)をどのように扱っているかを理解すると、コマンドの役割や挙動の理解も進むのでは、と思ってスライドを作りました。
コンセプトから理解するGitコマンド from ktateish
会社の有志が余暇に集まってやっている勉強会向けにつくったもので、400ページを超えてしまったのですが、パラパラマンガ風の図がページ数を増やしているだけで、内容的には基礎的なものです。
でも、これだけ覚えとけばGitの動きに戸惑わなくなるんじゃないかなー、というあたりを抑えたつもりです。
本来の勉強会のテーマは「GitHub実践入門」で、途中の基本のコマンドの章あたりで、補足としてインデックスのkthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com1tag:blogger.com,1999:blog-2119545220427717640.post-13868416212492709132014-04-27T19:27:00.000+09:002014-04-27T19:27:23.023+09:00Git 2.0 rc1先日(2014/04/26) Git 2.0 の rc1 (Release Candidate 1) がテスト用に公開されました。
来るリリースに向けた変更点で大きいのは、やはり 1.9 までとの非互換性です。具体的には
ブランチ指定なしで git push した場合のデフォルトの挙動が 'simple' になった
サブディレクトリで git add -u または git add -A したとき(pathを明示的に指定しない場合)、ツリー全体が対象になった
git add <path> したとき(<path>を明示的に指定したとき)の挙動が git add -A <path> と同じになった
あたりです。(実は小さな非互換な変更が別にひとつあります。詳細はリリースノート草稿をどうぞ)
1番目はすでにいろいろなところで記事になっていて有名ですね。kthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-89751195197474640282014-03-15T12:53:00.001+09:002014-06-29T23:55:08.621+09:00「Git 2.0 がリリースされた」というデマ「Git 2.0がリリースされた」という話がtwitterで広まっていましたが、2014/03/14現在、実際にはリリースされていません。
(2014/04/27追記: 2.0-rc1がリリースされましたので、もうすぐ本当に2.0がリリースされます→日本時間で5/29に当初予定より約2weekおくれでリリースされました)
「Git 2.0のリリースノート」「Git 2.0がもうすぐリリースされる」はまだしも、「Git 2.0がリリースされた」は完全に誤りです。
twitterで検索したところ、的確な内容をつぶやいているのは数人の方だけのようでした。正しい内容を最も端的に指摘されていたのは @uu59 さんの
次バージョンのためにrelnote用意するのはgitの伝統なので2.0リリースはまだ数ヶ月は先だと思います https://t.co/axdjeIRZlF https://kthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-13032030949491246632014-02-28T22:10:00.000+09:002014-02-28T22:40:50.826+09:00Gitで特定の関数の変遷だけを確認する(git log -L)最近知ったのですが、 git log では特定の関数の歴史だけを見ることができます(たぶんGit 1.8.4 以降)。
やり方は
git log -L :<regex>:<file>
これだけです。git showのように、コミットメッセージとともに、<file>中で最初に<regex>にマッチする関数に関してのみdiffを表示してくれます。diffは関数の途中で省略されず、全体を1ハンクに収めるかたちで、見やすく表示されます。
-L オプションは複数回指定可能です。
関数名は現在のHEADの<file>の内容の中でマッチするものを指定する必要があります。HEADの内容でマッチさえすれば、歴史をたどっていく途中で関数名が変わっても、コンテキストから推測して最後まで(初めてその関数を追加したコミットまで)追跡してくれるようですkthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-29160771806821978862014-02-14T07:22:00.001+09:002014-03-15T11:51:54.887+09:00Gitで今作ったコミットを以前のコミットに半自動的に融合させる(rebase autosquash)よく「トピックブランチにおけるコミットは、トピックに関連した内容のみ、論理的単位で小さく作れ」といわれますが、実際にコードを書いているときは最初から完璧だと思える一連のコミットをつくり上げるのは非常に困難です。
たとえば、「あー、この変更はさっきのコミットに含めておくべきだったな」とか。
Gitの場合あとから rebase -i で表示されるTODOリストの順番を並べ替えたうえ、squashやfixupを指定すれば、前のコミットに融合できますが、コミットの時点でfixup先のコミットがわかっている場合、autosquashを使うと、その作業を半自動化できます。
たとえば
% git log --oneline master..
4ce35ee 新機能: ほげほげを追加
40a7ef4 ほげほげ機能追加のための準備
のように2つのコミットがあった場合、マージ前にレビューしたkthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0tag:blogger.com,1999:blog-2119545220427717640.post-18275976714830490042014-02-08T14:22:00.002+09:002014-02-09T00:24:19.706+09:00コンフリクトしたマージの解消作業を再利用する(git-rerere)前回や前々回の記事では、nextのようなブランチを再構成する利点を解説しましたが、「再構成の利点はわかったけど、コンフリクトしたマージはrebaseしたらどっかいっちゃうのでできるだけやりたくない」という人も多いかと思います。
実はgitにはコンフリクトしたマージの解消方法を記録して、同じコンフリクトに対しては同じ解消方法を自動的に適用する機能があります。
それが git-rerere(1) です。rerereは REuse REcorded REsolutionの略みたいです。この機能はデフォルトでは無効になっているので、明示的に有効にしてやる必要があります。詳しい方法などは git-rerere(1) やrerereを解説したブログなどを参照すると良いと思います。
参考:
- git-rerere(1)
- unpushの日記: kthttp://www.blogger.com/profile/01572571295417893191noreply@blogger.com0