Yakstは、海外の役立つブログ記事などを人力で翻訳して公開するプロジェクトです。
6年以上前投稿 修正あり

git rebaseを使うときのルール

Linusが語るgit rebaseのルールについて、Linuxモジュール開発メーリングリストから。

原文
Re: [git pull] drm-next (English)
翻訳依頼者
D98ee74ffe0fafbdc83b23907dda3665
翻訳者
D98ee74ffe0fafbdc83b23907dda3665 doublemarket
原著者への翻訳報告
未報告


Re: [git pull] drm-next Linus Torvalds Sun, 29 Mar 2009 14:48:18 -0700

(訳注 : Daveのrebaseのやり方が好みでないというLinusに対して)

> 2009年5月29日(日曜日) Dave Airlieの発言
> 
> 今から自分がしようとしているのは、直線じゃないツリーを送ろうとしているだけだ。
> パッチを自分の次のツリーにマージする時はいつでも、そこにそれがあるからだ。
> 自分は、Ericのツリーを自分のツリーに直接プルして、その結果を送ろうとしている。
> きれいなマージ履歴について注意しているとは思っているけど、前に言ったように、
> カーネルツリーに関してのドキュメントが何もない状態では、君がどうしたいのか
> 本当のところは今の今まで分からないよ。

自分が求めているのは、きれいな履歴だ。でも、それは「(a) きれいな」「(b) 履歴」ってことだ。

自分自身の プライベートな ツリー(個人の成果物)は rebase できるし、すべきだろう。それは きれいにする ということだ。でも、他人のコードについてはやってはならない。それは「履歴を消す」ってことだからだ。

すると、(b) 履歴の部分については結構簡単だ。1つの大きなルールと、1つの小さな説明で終わる。

  • 他人の履歴は 絶対 消してはならない。他人がコミットしたものは rebase してはならない。基本的に、君の署名がない場合、そこからは立ち入り禁止区域だ。 君のものじゃないから、 rebase してはならない。

    これは、他人の 履歴 についてであって、他人の コード のことでないことに 注意してほしい。誰かがメールでパッチを送ってきて、君が git am -s で それを適用したのなら、それはパッチを送ってきた人のコードだが、 君の 履歴だ。

    君が書いたコードじゃなくても、コミット自体が君がやったものなら、それに対する git rebase はガンガンやっていいというわけだ。

  • このルールに対するちょっとした説明: 君の履歴を一度どこかに公開して、 誰かがそれを使うことになったら、その履歴は明らかに君の プライベートな ものではない。

    つまりこの説明で言いたいのは、「君のコミット」であるかどうかだけでなく、 それが君のプライベートなツリー内でおさまっていて、どこにもプッシュされておらず、 公表されていないものでなければならない、ということだ。

これってすごい分かりやすいだろ。そうでもない?

最初のルールは明白で簡単だったけど、(a) きれいな、の部分はちょっと分かりにくい。

  • 自分の履歴は読んでわかるようにしておく

    単に頭から順番に間違わずやっていけばそうなるという人もいるだろうが、それは レアケースだ。それ以外の我々は、何か問題に取り組むときに git rebase とかを 使うことになる。

    だから、 git rebase 自体は悪くない。でもそれは 君の完全に プライベートな git ツリーでだけ正しい法則だ。

  • くだらないものを見せるな

    これはつまり、まだ git rebase するような段階にある場合、そういうコードを プッシュしてはならないということだ。。準備ができていないなら、パッチを送るか、 一般には存在を知らせていないプライベートな git ツリー(単なる一連のパッチの 代わりとして)を使うべきだ。

度を超えた git rebase はきれいなツリーを保つことにならないことにも注目 するべきだろう。あまりたくさんの rebase をすると、古い rebase 前のテストが あやふやになってしまうからだ。従って、なんとしてでも rebase しなければ ならないのか、いくらかは 判断の必要がある。

注意 上のルールの組み合わせ(「自分の履歴をきれいに」と「他人の履歴を いじるな」)は、間接的な効果がある。これは少し難しくなり始めるところだ。 他人のやったことを rebase してはならないのだから、それはすなわち、 いい感じの形になっていないブランチにプルしてはならないということだ。 それは、一度マージしてしまうと、それまでの自分のコミットはもう rebase してはいけなくなってしまうからだ。

気付いたかな? git pull するということは、最終的には同期点になるという ことだ。でも、プルする時の以下の2つのルールに従うなら、それは全くもって 簡単なことだ。

  • アップストリームのコードを好き勝手な時点でマージしてはならない

    自分の好きな時に私のツリーからプル してはならない (初めの頃の git ユーザの 一番大きな問題がこれだ。多くの開発者達が、私のその日ごとのツリーから適当に 選んで、各々の開発用ツリーにプルしたものだ)。こうすると、君らのツリーを 単なるでたらめな開発の寄せ集めにしてしまう。そういうことは するもんじゃない!

    そして、実際には、君らは私のツリーを 一切 プルしない方がいい。 私のツリーにあるものは、 君らの 開発とは別物であるべきだからだ。 そうせざるを得ない時(特別厄介な依存性の問題を解決する場合)も あるだろう。とはいえそういうことは非常にまれで特別なことだし、 そういう時はじっくり考えるべきだ。

    だから、メジャーリリースと同期したい時は、以下のように

    git pull linus-repo v2.6.29
    

    というように、 好き勝手な時点ではない ところに同期してくれ。 これなら筋が通ってる。「v2.6.29を開発ブランチにマージ」なら、 マージのメッセージとして意味をなすだろ? 問題にはならない。

    もし誰かのログに「linusブランチとマージ」というのをたくさん発見したら、 そいつからはプルしない。それは、そいつのツリーはそこにあるべきでない でたらめなゴミ屑があるのが明白だからだ。テスタビリティも失って、 その時から全てのそいつのテストは、私のでたらめなコードの一部になる だろう。

  • ダウンストリームの コードも同じく好き勝手な時点にマージしてはならない

    ここで言う「任意の点」は2つの意味がある。ダウンストリームが重要な 意味を持っている(ダウンストリームの開発者は何をなぜマージするのかは 伝えておくべき)だけでなく、君自身のツリーが重要とされているなら、 好き勝手にマージするべきではない。

    単純に言うと、「自分のトピックブランチに、関係のないダウンストリームの コードをマージするな」

    少し複雑に言うと、「ダウンストリームをマージする時は常に 理由 が 必要」。なぜかって、「このブランチはリリースブランチであって、思いつきで 開発しているブランチでは ない 。そして、そのすぐ使える機能は次の リリースの一部になるからマージしたいんだ」

分かった? 全てのルールはほんとにシンプルだ。「自分の履歴をきれいに」と 「他人 の履歴をいじるな」の間には分かりにくい相互作用がいくらか あるけれど、プルする時のルールにのっとれば、問題は起きない。

もちろん、このルールがちゃんと運用されるようにするには、他の人にも きれいな履歴を持ってるところ から プルさせるようにしなきゃならない。

そしたら君ならどうする? 彼らがやらないなら文句を言えばいい。 どうやるべきか、何が悪いのか教えてやればいい。私の文句を、プルしようと している奴らに伝えてやればいい。ここでの話を引用するのは大歓迎だし、 「ちゃんとやれよ、だってLinusが最終的な結果に期待してるのはそういうこと なんだから」って説明してやってくれ。

Linus

次の記事
MongoDBとMySQLでのスキーマデザインの違い
前の記事
InnoDBのB+木リーフノードの整合性チェック

Feed small 記事フィード

新着記事Twitterアカウント

新着翻訳リクエストTwitterアカウント