ワークスペースツール

リポジトリのルール(.gitcito.json)

どのプロジェクトにも、コードからは読み取れないルールがあります。release/* には直接プッシュしない。 コミットのスコープは api、web、infra だけ。 動かす前に Node 20、チェックアウト済みのサブモジュール、.env.example から コピーした .env が要る。 そうしたルールは、誰も読み返さない README か、CI の 失敗か、いちばん長くここにいる人の頭の中に住んでいます。

.gitcito.json は、リポジトリがそれらを書き留めて、ツールが実際に扱えるように する場所です。リポジトリのルートに置かれ、他のファイルと同じようにコミットされ、 だからクローンと一緒に運ばれます。プロジェクトを開いた全員が同じルールを受け取り、 新しく入った人は最初のプッシュを弾かれた日ではなく初日に受け取ります。

このファイルは完全に任意です。持たないリポジトリはこれまでどおりに動きます。

手で書く必要はありません。リポジトリチャットにはこのファイルのスキーマが 渡されるので、JIRA-1234 のチケットリンクを追加して や release ブランチを保護して は 確認できるファイル操作として返ってきます。

リポジトリの Config タブ。doctor の行とルールの各セクション

どこで編集するか

ツールバーのツールの隣にある歯車 → Config。このエディタはファイルを作業ツリー に書き込みます。他の場所には保存されないので、チームとルールを共有するには コミットしてください。

まだ無い場合、リポジトリを読む が既にあるものから草案を提案します。.nvmrc または engines.node、.gitmodules、.gitattributes の filter=lfs、隣に .env の無い .env.example、すでにローカルで保護しているブランチ、そして直近 500 件のコミット件名が使ってきたスコープです。保存するまで何も書き込まれません。 ターミナルからは gitcito config init が同じことをします(コマンドライン を参照)。

ファイルに書けること

{
  "version": 1,
  "protect": ["main", "release/*"],
  "links": {
    "tickets": [
      { "match": "\\b[A-Z][A-Z0-9]+-\\d+\\b", "url": "https://tracker.example.com/browse/$0", "label": "Jira" }
    ]
  },
  "commit": {
    "scopes": ["api", "web", "infra"],
    "ticketFromBranch": true,
    "trailers": ["Refs: {ticket}"]
  },
  "requires": {
    "node": ">=20",
    "hooksPath": ".husky",
    "submodules": true,
    "lfs": true,
    "files": [{ "path": ".env", "from": ".env.example", "why": "API のベース URL と開発用トークン" }]
  },
  "checklist": {
    "push": ["ステージングに対して統合テストを流す"]
  }
}
フィールド 何をするか
version 1 である必要があります。新しいスキーマのファイルは推測せず、まるごと無視します。
protect ブランチ名。* は任意の文字列に一致します。ローカルで保護しているブランチに加算されます — 保護ブランチを参照。
links.tickets 正規表現と URL テンプレート。$0 は一致全体、$1…$9 はグループ。コミットの件名と本文の一致がリンクになります。
commit.scopes コンポーザーが自由入力の代わりに提示するスコープ。宣言すると、gitcito commit-check で未知のスコープがスタイル上の助言ではなくエラーになります。
commit.ticketFromBranch ブランチ名からチケットキーを補完します(feature/ABC-123-thing → ABC-123)。ただし空のコンポーザーにだけで、入力中の件名を上書きすることはありません。
commit.trailers コミット本文に追加される行。{ticket} と {branch} が埋められ、埋めるものが無いプレースホルダを含む行は中途半端に書かれるのではなく落とされます。
requires.* 動くクローンに必要なもの。各項目が下の doctor の行になります。
checklist.push セッションごとに一度、最初のプッシュ前に表示される自由記述。

doctor

requires は 「クローンしたのに動かない」 に答える部分です。Gitcito はリポジトリ を開いたときにこれを確認し、何かが合っていなければステータスバーに聴診器のチップを 出します。チップをクリックすると Config タブが doctor の行で開き、再チェック でもう一度実行します。

チェック 通る条件 修復方法
node PATH 上の node が指定を満たす —
submodules チェックアウトされていないサブモジュールが無い git submodule update --init --recursive
lfs git-lfs が入っていて、追跡ファイルがポインタ文字列ではなく実体である git lfs pull
hooksPath core.hooksPath が宣言されたパスと一致する core.hooksPath の設定
files ファイルが存在する from があればそこからコピー

意図的な制限が二つあります。警告は決して「壊れている」という意味ではなく、 doctor が判断できなかったという意味です(解釈できない Node の指定は、対処しようの ない失敗をでっち上げるより通します)。そして警告は CI の gitcito doctor を失敗 させません。また修復は決してファイルが与えたものではありません。上の一覧が全てで、 コンパイル時に閉じています。設定が渡せるのは値だけ — コピー元のパス、 core.hooksPath の値 — であって、コマンドではありません。

ファイルのコピーは決して上書きしません。ファイルが無いことこそ、その行が出ている 理由だからです。

コミット

commit.scopes が宣言されていると、コンポーザーのスコープボタンは自由入力ではなく そのリストを提示します。feat(renderer) と feat(rendererr) の差です。 ticketFromBranch と trailers はメッセージの機械的な部分を埋め、 links.tickets はコミットが表示されるあらゆる場所でキーをリンクに戻します。

同じルールはウィンドウの外でも効きます。gitcito commit-check はこのファイルを 読むので、commit-msg フックと CI はコンポーザーが提案するものとまったく同じ ものを強制します。コマンドラインとコミットを参照。

プッシュ前チェックリスト

checklist.push は、そのセッション最初のプッシュの前に確認ダイアログとして、 1 項目 1 行で表示されます。Gitcito が 代わりに確認することは決してない ので、 ここに置くべきは本当に人の判断が要ること — サポートには誰か伝えた? — です。 これはゲートではなくリマインダーで、読んでプッシュするか、キャンセルするかです。 リポジトリごと・セッションごとに一度だけ表示されます。毎回出るダイアログは、誰も 読まないダイアログだからです。

なぜ危険ではないのか

このファイルはリポジトリと一緒に届きます。つまりリポジトリを書いた誰かから届きます。 コミットメッセージと同じく、信頼できない内容として扱われます。

  • 中身は何も実行されません。 コマンドを保持できるフィールドは無く、doctor の 修復は固定リストです。
  • 制限を足すことしかできません。 protect はローカルの一覧との和集合です。 リポジトリはあなたが選んだ以上に保護できますが、保護をやめさせることはできません。 どのフィールドもガードを切りません。
  • パスはリポジトリの外に出られません。 絶対パス、..、~、ドライブレター、 .git に触れるものは拒否され、文字列が実際のパスになる時点で再度検査されます。
  • リンクは http(s) のみ。 それ以外がシステムの URL オープナーに渡ることは ありません。
  • すべてに上限があります — リストの長さ、文字列の長さ、パターンの長さ。悪意ある リポジトリでも、ダイアログに文字の壁を貼り付けたり、パネルに千個のチップを並べ たりはできません。

不正なフィールドは落とされるだけで致命傷にはなりません。ファイルの残りはそのまま 適用され、落とされたものは Config タブの Gitcito が無視した項目 に理由付きで 並びます。唯一の例外は不正な JSON と未知の version で、その場合は救えるものが ありません。

あえてしないこと

  • コマンドもスクリプトもフックも無し。 それはフックの役目であり、 クローンごとにあなたが決めることです。
  • ブランチ別・人別のルールは無し。 一つのファイル、一組のルール。
  • CI の代わりにはなりません。 チェックリストはテキストで、doctor が見るのは 環境であって、あなたの成果物ではありません。
  • 何も弱められません。 Gitcito のガードはすべてあなたのものです。

関連: リポジトリごとの設定 · コマンドライン · コミット · フックと .gitignore

この翻訳を GitHub で改善