2011-01-19 4 views
34

私はGitの履歴がDAGというデータ構造に格納されていることを知っています。私はDFSについて聞いたことがあり、それは多少関連していることを知っています。'git log --graph'または 'hg graphlog'はどのように動作しますか?

私は好奇心が強いです。git log --graphhg graphlogなどのプログラムはどのようにして歴史を描きますか?私はいつも車線やそのすべてを素敵なやり方で描くことはかなり複雑だと思っていました。

誰かがそれを実証する疑似コードを書くことができますか?

注:私はGitまたはhgのコードを見てみましたが、何が起こっているのかについての一般的な考えを追跡するのは非常に難しいです。

+4

Gitの[graph.c](http://git.kernel.org/?p=git​​/git.git;a=blob;f=graph.c)を参考にしてください。 –

+2

SOの質問として「DAGをテキストグラフとして表示する方法」の問題を簡略化して(しかし、よく指定された)バージョンに投稿し、 'code-golf'としてタグ付けします。 Python、Ruby、C、Perlなど、多くの巧妙なソリューションを手に入れることができます。オリジナルのゴルフ以外のコードや「最後のすべてのキャラクターを搾取する」バージョンを投稿するように人々に依頼するかもしれません。 – MatrixFrog

+1

Gitの[history graph API](http://www.kernel.org/pub/software/scm/git/docs/technical/api-history-graph.html)も便利です。 –

答えて

3

一般的なグラフ表示と比べて、この特定の問題はそれほど難しくありません。ノードをコミットした順番に保ちたいので、問題はずっと簡単になります。

また、ディスプレイモデルはグリッドベースで、行はコミットされ、列は過去/未来のエッジです。

私はgitソースを読んでいませんでしたが、おそらく最新のものからコミットのリストを歩いて、開いているエッジのリストを過去のものに保ちます。エッジの後には自然にカラムの分割/マージが行われ、git/hgツリーの種類の表示になります。

エッジをマージするときは、他のエッジとの交差を避けたいので、事前に列を並べ替える必要があります。これは実際には単純ではないかもしれない唯一の部分です。例えば、第1パスのエッジの列順序を構成し、第2パスの描画を行う2パスアルゴリズムを行うことができる。

+4

'git log --graph'の出力には、しばしばエッジが交差していて、時系列ではありません。私はグラフ表示の比較的のケースであっても、あなたが示唆しているよりもそれほど簡単ではないと思います。 – Cascabel

+0

さて、私が言ったことの大半は、コミットの厳密な順序なしでも適用されます。頻繁なエッジの交差は、コミット・グラフに応じて避けることが不可能であり、おそらく理想的な順序を決めるのにあまり費やされません。私はそれが些細なことではないことを示唆したくはありませんでしたが、良い解決策を見つけるのは簡単です。 – Zarat

4

私はGitまたはhgのコードを見てみましたが、何が起こっているのかについての一般的な考え方を理解するのは非常に難しいです。

hgの場合、hg自体のコードまたはグラフログのコードに従ってみましたか?

graphlogのコードがかなり短いためです。あなたはhgext/graphlog.pyで見つけることができます。そして本当に重要な部分はトップ200行です。残りは、拡張機能のブートストラップと選択されたリビジョングラフの検索です。コード生成関数は、最後のパラメータは、asciiedgeの呼び出し(コール自体はgraphlogによってgenerateに提供される機能、generateの最後の行で実行される)

6

まず、一つはA取得の結果であると、asciiありますコミットのリスト(git rev-listのように)、および各コミットの親。 「列予約リスト」はメモリ内に保持される。それぞれについて、

は、コミット:

  • コミットがそれのために予約なしの列を持っていない場合は、無料の列に割り当てます。これがブランチヘッドの開始方法です。
  • 列の予約リストに従ってコミットメッセージを印刷します。
  • 現在のコミットの予約のリストエントリは、現在のコミットの最初の親で更新されます。同じ列に印刷する。
  • 他の親は新しい空き列を取得します。の出力を示す
  • これは、マージした場合は、次の行が期待されているコミットの列に2つ目の親をリンクしようとしますが(これはループと「≡ブリッジ」になり)

例aufs2-utilにgit-forestを追加すると、複数のブランチを持つことになります)。先読みして

Example

、一つはマージポイントダウンし、より美的結果を与えることと2つの列の間の木材を絞るだろうどこまで予想することができます。

関連する問題