gititメモ

このdoc.tir.ne.jpは、gititを使って構築しています。

このページでは、そのgititのノウハウやメモを書いていきます。

このdoc.tir.ne.jpでのgititの構成や設定については、このページではなく、/tir.ne.jp/structure/doc.tir.ne.jpにあります。

使った感想

基本部分

  • 「バックエンドがgit」なのは素晴らしい。裏でgit pushしてバックアップとか本番サイト反映とかできる。git cloneしてローカルで編集してpushとかもできる。

  • あちこちに不具合や不便なところがあり、結構自分で手を入れる必要がある(まだ枯れてないという印象)。
    • よってhaskellできない人は手を出さない方がいいと思う
  • ページ編集時の左側にmarkdown記法の非常に簡潔な記法一覧があり、それが非常に便利。

  • table記法がマルチバイト文字幅を考慮してくれないので使い物にならない。
    • table記法は何種類かあるが、どのtable記法も幅に依存している。
    • htmlタグ記法でtableタグを書けば大丈夫だが…
  • 大した問題ではないが、「ページ/ファイルを移動させる」インターフェースがwebフロントエンドにない。「ファイル/内容をコピーする」「元ページ/ファイルを削除する」と二段階に分けて操作する事はできるがgitのコミットログが別々になってしまう。

  • mediawiki等でよくある「あるページの特定項目だけ部分編集する」機能がない。
    • ブラウザに「textareaをエディタで開いて編集する」アドオンを入れないと、ハードな編集には向かないと思う。
  • バックエンドがgitなので、github連携すると色々と美味しい

プラグイン

  • プラグイン機能を使うとメモリ消費がかなり大きい
    • プラグインなしで30M消費、そこにプラグインを一つでも追加すると150M消費
      • 一つでも追加した後は、何個追加しても大きく変化はしない様子
      • どうも、プラグインを読み込むのにghcそのものの機能を使っている為、これだけ消費してしまうっぽい。どうにかできるなら、なんとかしたいところ
    • プラグインなしでの30M消費も割と大きいように思えるが、これはgititコンパイル時にプラグイン機能を完全にオフにする事で更に軽減できるとの事
      • しかしプラグイン機能は便利なので切りたくない
  • プラグイン機能はあるが、プラグインを追加する事でいじれるのは「本文回り」のみで、「gititにこういう処理(例えばファイル移動など)を追加したい」「本文以外のところを動的制御したい」という用途にはプラグインでは対応できない。
    • プラグインとして設定できるハンドラ種別が「PreCommitTransform(本文ソース保存直前)」「PreParseTransform(本文pandoc化直前)」「PageTransform(本文htmlページ化直前)」の三種しかなく、前述の本文に関わらない操作に対するハンドラ種別がない為。
    • 逆に「本文絡み」であれば、「コミットされた本文を裏で別サーバに送信」「コミットされたら特定コマンド実行」「ページにアクセスされたら本文内の指定された場所に、毎回別々の適切な文字列を生成」等々、大抵の事は柔軟に処理できる。
  • プラグイン種別の切り分けが不完全に思える。
    • プラグインの「PreCommitTransform」種別は「本文ソースの置換フィルタ」と「本文ソース保存時に同時に実行しておきたい操作実行」の両方を兼ねている。この為、プレビュー時にはこのハンドラは呼ばれない(し、呼んだらまずい事になる)ので、結果として「プレビュー時には置換されていなかった部分が保存したら置換されている」という事が起こる。この二つは分離すべきだと思う
  • プラグイン機能の実装方法を考え直した方がいい気がする
    • プラグイン機能は便利かつ必須ではあるけれど、前述の通り、プラグイン機能を使うと使用メモリが150Mに増加してしまう
      • これはプラグイン機能の実装部分が、内部でghcの基本機能を使っている為だと思う。端的に言えば、apacheでmod_gcc的なものを作ってgccの機能を取り込ませたら猛烈にメモリ食ってる、みたいな状況だろう
    • そもそもプラグインの再読み込みはgititプロセスの再起動が必須なので、それなら動的ロードするのではなく、毎回実行バイナリをコンパイルし直す方式でもよかったんじゃ?この方式なら使用メモリが大きく増える事はないと思う

ノウハウ/メモ

gititセットアップして起動して最初にやるべき事

  • gititインストール先の data/templates/* を、セットアップ先の templates/ にコピーする
    • テンプレいじる場合は前者ではなく後者をいじるようにする
  • 上記と同様に、gititインストール先の data/static/* の内、自分がいじりそうなディレクトリ/ファイルを、セットアップ先の static/ にコピーする
  • Gitit User's Guide」のページを削除する
    • ページ一覧から辿るか、ローカルで削除してgit commitする
  • gitit.confを編集してgititプロセス再起動

テンプレに任意のStringTemplate変数を追加したい

gititの読み方は「ぎちっと」

  • …でいいのか?

wikiname

  • wikinameはそのままページのURLになってしまうので、これはURL encodeされない文字だけで構成するのがいいようだ。
  • ページのメタ情報のところに「title: ページのタイトル」と入れておけば、このタイトルがwikinameの代わりに正式なタイトルとして使われるので、この機能を多用する。
  • なお、ページのURLは内部リポジトリでのディレクトリ構造にそのまま対応する為、wikinameには「//」や「../」のような、ディレクトリ指定的に問題のありそうな文字列は含めない方がよい。

ページ移動などの複雑な変更

  • 一旦gititサーバを停止させて、コマンドラインから「git mv …」等のようにいじってコミットし、またgititサーバを起動させる。
    • gititサーバを停止させているのは、gitのワークツリーがwebフロントエンドから同時に変更されないようにする為。

書式

  • gititで利用できるmarkdown書式は、通常のものよりも拡張された Pandoc’s markdown との事。
    • なので、エディタの書式設定も、通常のmarkdownではなく、pandoc用のものがベター。

undocumentedな機能

  • /_reloadTemplates にアクセスすると、サーバを再起動しなくてもページテンプレート(*.st)が再読込される。よく変更するならsitenav.stあたりに含めておくと便利

印刷用バージョンにて、テンプレの一部を非表示にするには

  • static/css/print.css を見て、適当に不可視になりそうなクラスを指定すればいい…とか思ってたらなんと、不可視にするクラスは定義されていなかった!
    • 自分で static/css/print.css をいじって、印刷時は不可視にするクラスを用意してしまっても別にいいと思う
  • テンプレに「$if(printable)$$else$(不可視にしたい部分)$endif$」のように書けば普通に不可視になる。
    • ただしこの方法はテンプレ部にしか効果がない。本文の一部を不可視にしたいなら print.css をいじるしかない

見出しへのリンク

  • 各ページ内の見出しは、以下のルールでanchor(#fragment)化される様子。リンクを貼る時に「とりあえずなんか変換が入る」とだけ憶えておけばok
    • アルファベットは全て小文字に
    • spaceは「-」に置換
    • マルチバイト文字はそのまま
    • その他の記号は削除(半角記号のみならず、マルチバイト文字の記号も大半が削除)

Dot.hs プラグインは使うな

このプラグインはコード品質が良くなく、以下の問題が発生する

  • 勝手に static/img/ にファイルを作る。もし名前がかぶった場合は上書きされる。困る
  • graphvizがエラー出した時のハンドリングが悪い
    • 不正なdot記法等によりgraphvizがエラーを出した時であってもページ内容自体は保存されてしまうので、そのページはずっとエラー表示になる
      • この状態になったら、 /_edit/(wikiname) のURLから直に編集ページを開いて直すか、ローカルからpageファイルをいじって直しましょう

readonly運用時の情報

  • gititをreadonlyにするには、「require-authentication: modify」にした上で「authentication-method: mzero」にすればよい
    • 要は「ログインした人のみ編集可」にした上で「誰もログインできない認証モジュールを選択」の状態にしている
  • あとはテンプレートをいじって、適当に編集機能へのリンクとかを消す、が、いじれない部分がある
    • ページ上のタブ部分、ここは個別に変更できないのでまとめて消すしかないようだ
    • export機能も、テンプレートからでは、個別に「この機能だけ提供」とかはできない様子。全部残すか全部消すかの二択

gititで通常のウェブサイト的運用を行う

  • 前述のreadonly化を行う。更新は別のところで行い、git push/pullで反映。
  • ページ編集機能のみならず「全ページ一覧」「カテゴリ一覧」等のwiki的機能も不要ならば、reverse-proxy設定で「/_ ではじまるpathはアクセス不可にする」設定にしてしまう手もある
    • しかし、検索機能である「_search」やフィード購読である「_feed」等、通常のウェブサイトであっても役に立つ機能もあるので、個別に禁止/許可した方がいいかも。

gitリポジトリのカスケード式反映時の注意点

  • gitで普通に「親リポジトリ→子リポジトリ→孫リポジトリ」という構造にすると、孫から子へのpush時に、以下のエラーが出てしまう。

    error: refusing to update checked out branch: refs/heads/master
    • このエラー後の文章の内容はだいたい以下のような内容。
      • デフォルトでは、非bareなリポジトリかつ選択中のブランチへのpushは禁止されている。何故ならそこにpushするとindexとワークツリーに不整合が発生し、「git reset --hard」を実行してワークツリーをHEADに合わせなくてはならなくなるからだ。 ’receive.denyCurrentBranch’を’ignore’か’warn’に設定すればpushできるようになるが、同時に上記コマンドを実行するルールを徹底できないならおすすめしない。 (以下省略)

    • これを回避するには、エラー内で表示されている通り、子リポジトリ側で以下のコマンドを実行すればよい。

      git config --add receive.denyCurrentBranch ignore
    • これで孫から子へpush可能になる。勿論、上記に書いてある通り、pushした後は子で「git reset --hard」を実行するのを忘れないようにする事。

github連携

  • バックエンドがgitなので、github連携すると色々と美味しい
    • github連携するには、事前に用意した有料のプライベートリポジトリ、もしくはpublicなリポジトリへと定期pushするように、プラグインもしくは外部コマンドを用意/設定するだけ。
    • 履歴差分表示等はgithubの方がずっと優れているので、差分リンク等はgithubの方で見る等できる
      • テンプレ上でgithubのurlと $pageUrl$ を上手く組み合わせる事でリンクにできる。リンク先をblobにするかcommitsにするか等、色々と工夫の余地あり
      • 残念ながら、履歴一覧や差分表示そのものをgithubに投げるのは本体に手を入れないとできなさげ
      • 前述の、gitit側リポジトリとgithub側リポジトリの同期状況に注意は必要
  • なお、github連携をする際は、メールアドレスによってのみgithubアカウントが認識されるので、「gititアカウントでのメールアドレス設定」は「githubアカウントのメールアドレス」と同一にしておく事をおすすめします。

不具合対策的な情報

アカウント作成時はメールアドレスを設定しましょう

  • 今のところgititでは、メールアドレスを設定しなかった場合は、パスワードリセット機能が使えないのは勿論の事、あとでメールアドレスを設定しなおす事もwebインターフェースからはできません
    • メールアドレス変更はパスワード強制変更フォームからしかできない為。
    • ローカルから変更する場合は gitit-users ファイルをいじればokだが、このファイルを手で編集した場合は、gititプロセスを再起動しないと変更が反映されないので注意。

キャッシュ回り

  • gitit.confで use-cache: yes にすると、リポジトリ直更新による内容更新がキャッシュに反映されない。
    • 「expireGititCache」コマンドが、gititコマンドと同じ場所にインストールされているので、それを叩くようにすればok
      • しかしこれ、各ページを個別に指定する必要があるのでちょっと面倒。もっと簡単にできないか考えたい
    • The cache is persistent through restarts of gitit. To expire all cached pages, simply remove the cache directory.

      • …との事なので、直にcacheディレクトリを削除していいようだ。

なんかずれた

  • 例えば、リスト項目の中で「¥<!--  --¥>」を書くと、それ以降の文章がリスト項目の子要素にされてしまった
    • ずれた時は、「!」等の他の記号も忘れずエスケープしてみましょう。「¥<¥!--  --¥>」ならずれない。
  • pandocのドキュメントによると、「\」でのエスケープが必要になる可能性のある記号は「\ ` * _ { } [ ] ( ) > # + - . !」との事(記述状況によってはエスケープ無しでも問題ない)。
    • 上記には書かれてないが「&」もエスケープが必要な場面があると思う
      • &」のような、html実体参照の文字列をそのまま書きたい時とか
    • これ以外の記号をエスケープしてしまっても別に問題になる事はないようなので、プレビュー等でなんかずれたり、エディタのpandoc用syntax色付け判定が怪しい時は、とにかくエスケープしてしまっていいようだ。
      • ただし一部の記法の内部(コードブロックVerbatim内)ではそもそもエスケープ不要。よく分からなくなった時はプレビューに頼る。

'」を含むwikinameがwikilink化された時にページが見付からなくなる

  • デフォルトで作られるトップページ内の「Gitit User's Guide」というwikilinkが既にその状態になってる。おそらく仕様。
    • ページの原稿ソース内に含まれている「'」が、htmlへのレンダリング時に「’」という全角記号の実体参照に変換されてしまっているのが原因。この変換結果が半角記号の方である「'」への変換であれば正常に動くと思うが、どうすれば直るのか不明。utf8回りなのは間違いないが…
  • とりあえず「'」を含むページは作らない方がいい、という事だと理解する。
  • とりあえず「Gitit User’s Guide」のページは消してしまい、このページが必要な場合は公式サイトの方にリンクしてしまうのがいいと思う

ページ削除が動いてないっぽい

  • gitit.confのno-deleteに消したいページが設定されてないかを確認
    • エラーメッセージ等は別に出ないので非常に分かりにくい

[http://domain/path/to/url.html]() が内部リンク判定になる

  • これにより困る点は、aタグにtitle="Go to wiki page"属性が付与されてしまうぐらい。しかし紛らわしい。
  • これの判定を行っているのは、 Network/Gitit/ContentTransformer.hs の convertWikiLinks 。正しく直すのは面倒だが、とりあえずここを直せば常にtitle属性を付与しないようにはできる

不具合対策(パッチ有り)

余分にアンエスケープされてしまう

カテゴリページで正しくリンクが表示されないページがある

ページ新規作成の差分表示時に、$revision$が無い扱いになってしまう

導入手順など

あとで!

外部リンク


provided by 技情研ネット.