まえがき
今年は色々あって、時間も取れずアドベントカレンダーにいまいち乗り切れないまま11月となってしまった。
とはいえ、せっかくの機会なので、前年の様に手を動かすことにこだわらず、気軽に今年気になったツールの体験記や情報まとめでも記して行こうと思う。
Pijul とは
分散型バージョン管理システム (distributed version control system) 。 Git や Mercurial の仲間。
プロジェクト自体は約 3年前にスタートしていて、今年の 11月に 0.11 がリリースされた。まだまだ若い VSC。
特徴
その最大の特徴としては、カテゴリー理論 (パッチ理論) をベースとしたデータモデルを採用している事 らしい。
カテゴリー理論 (パッチ理論)
カテゴリー理論 (パッチ理論) について深掘りする心の余裕が無かったので、とにかく情報だけ集めた。
https://jneem.github.io/merging/
https://jneem.github.io/pijul/
https://arxiv.org/pdf/1311.3903.pdf
https://pijul.org/faq/
https://pijul.org/model/
http://darcs.net/Using/Model
https://news.ycombinator.com/item?id=13643025
https://news.ycombinator.com/item?id=18235798
何となく分かったことは、
- Git はスナップショットの履歴で、Pijul は変更差分 (パッチ) の集合
- Git の Diff は、スナップショット同士の比較
- Pijul の Diff は、お互いのパッチサブセットの差分の比較
- 各パッチ間の依存関係を自動判別・保存しておき、チェリーピッキングの際に自動解決される
- Pijul のチェリーピッキングは、Git のブランチ同士のマージに近い?
- Hunk レベルでの依存関係はこれで良いが、関数呼び出しなどの依存関係は結局のところ破綻する?
- それらは一つのパッチに一緒に含めるべき、というルールを守れば起こらないのか
気軽にやろうと決意した前書きとは大きくかけ離れた難しさだ。。。
深掘りは来年やろう。
Darcs との関係性
Pijul を語る上で欠かせないのが、この Darcs という VCS。
そもそも、Pijul は Darcs のパフォーマンス問題を解決するために実装されたコードがそのまま別ツールとしてリリースされたものらしい。
その為、Pijul はパッチ理論がベースにあるという点をはじめ多くの特徴を引き継いている。
Darcs について調べると、
- チェリーピッキングが簡単で正しく適用される
- データモデルが直感的なので、操作も直感的
など他にない利点があったとの評価が多かったが、以下のような指摘もあった。
- パフォーマンス問題。プロジェクトが大きくなると重い
- Svn や Git とは違うコマンド体型
- Git や Mercurial のようなブランチ機能を持たない
特にパフォーマンス問題が大きかったようで、対策をとっている間に Git や Mercurial などの VCS や Github を中心としたエコシステムが発達してしまったので、広く人気を得ることができなかった ( Haskeller には人気のようだ )。
Git との関係性
Pujul ドキュメント内でも Git は強く意識され、その対比で自身の特徴を説明するシーンが多い。
馴染んだコマンド体型
Pijul では、Git のコマンド体型に寄せてきていて、Git 経験者でも導入しやすいように心がけているように見える。
それでいて、非直感的なコマンドは変わってたり。
git branch -d
→ pijul delete-branch
とか個人的に Pijul の方が分かりやすい。
Git like なブランチ機能
元々、Darcs では『ブランチ=別リポジトリ (=別フォルダ )』のような考え方があったようだが、Pijul では一つのリポジトリ内でも状態を切り替えられる Git Likeなブランチ機能が導入されている。
Git のブランチは歴史の枝分かれといったイメージだが、Pijul のブランチは全パッチから抜き出したサブセットというイメージだ。
インストール
とりあえず、使ってみないことには分からないのでインストールする。
- Windows 10 pro October 2018 Update
Cargo で導入する方法もあるが、おすすめはしない。自分は引っかかりまくって時間をロスした。
おとなしく、PreBuild されたバイナリをインストールする。一緒に vcruntime140.dll
も必要なので、そっちも落として pijul-0.11.0.exe
と一緒に配置する。
pijul.org/downloads
起動するも上手く動かないが、どうやら libssl-1_1-x64.dll
と libcrypto-1_1-x64.dll
が必要なようだ。
自分は scoop を使って openssl
を導入していたので、その中の lib
から拝借した。ちなみに、バージョンによっては含まれていないケースもあるらしい。1.1.0h
には含まれていなかった。
これで、
$ pijul -V
pijul 0.10.1
上手くいった。 0.11.0
を入れたのに 0.10.1
なのはご愛嬌。
実践
ということで、実践しながら操作感を確かめていく。
最近お気に入りの nim プロジェクトを構築しながら Pijul でバージョン管理していく。
1. 初期化
まずは、プロジェクトを作成し、Pijul で管理するための初期化を行う。
pijul init
$ nimble init.
$ tree
# ├── sample_1202.nimble
# └── src
# └── sample_1202.nim
$ pijul init
$ tree
# .
# ├── .pijul
# │ ├── hooks
# │ ├── id
# │ ├── local
# │ │ └── ignore
# │ ├── patches
# │ ├── pristine
# │ │ ├── db
# │ │ └── db.lock
# │ └── version
# ├── sample_1202.nimble
# └── src
# └── sample_1202.nim
Git の .git
フォルダに対応するのが、 .pijul
フォルダかな。
2. 変更の追跡・記録・破棄
pijul status
現在のリポジトリの状態を把握するには、pijul status
が使える。
$ pijul status
# On branch master
#
# Untracked files:
# (use "pijul add <file>..." to track them)
#
# src
# sample_1202.nimble
# src\sample_1202.nim
pijul add
ファイルの変更を追跡するためには、pijul add
をする必要がある。
$ pijul add src\sample_1202.nim sample_1202.nimble
$ pijul status
# On branch master
#
# Changes not yet recorded:
# (use "pijul record ..." to record a new patch)
#
# new file: sample_1202.nimble
# new file: src
# new file: src\sample_1202.nim
追跡が始まったが、まだ記録はされていない状態。
pijul record
Git であれば、 commit
コマンドを使うところだが、Pijul では pijul record
で変更を記録する。
$ pijul record
# added file sample_1202.nimble
#
# Shall I record this change? (1/5) [ynkadi?] y
#
# In file "sample_1202.nimble"
#
# + # Package
# +
# + version = "0.1.0"
# + author = "username"
# + description = "A new awesome nimble package"
# + license = "MIT"
# + srcDir = "src"
# + bin = @["sample_1202"]
# +
# +
# + # Dependencies
# +
# + requires "nim >= 0.19.0"
#
# Shall I record this change? (2/5) [ynkad?] y
#
# added file src
#
# Shall I record this change? (3/5) [ynkadi?] y
#
# added file src\sample_1202.nim
#
# Shall I record this change? (4/5) [ynkadi?] y
#
# In file "src\\sample_1202.nim"
#
# + # This is just an example to get you started. A typical binary package
# + # uses this file as the main entry point of the application.
# +
# + when isMainModule:
# + echo("Hello, World!")
#
# Shall I record this change? (5/5) [ynkad?] y
#
# first commit
# What is the name of this patch? Recorded patch 8AoNvRnRvhnTyMCZmdQbpdwqBr6Ax4WNsHYL7f55iHkGw7bttoUuoiDetQmmK7iWq53tecQwRTn1wFqMy7BpL7Pi
$ pijul status
# On branch master
# Nothing to record, working tree clean
変更は一つづつ [ynkadi]
を聞かれ、このパッチに含めるかどうかを判断する必要がある。
y: record this change
n: don't record this change
k: go back to the previous change
a: record all remaining changes
d: skip all remaining changes
一つ注意する点として、すべての Yes or No を判断した後、キャレットが左端で点滅しているので『処理待ちかな?』と思っていたら、どうやらコミットメッセージを待っているようなのだ。これは気が付かない。
pijul record -m "first commit"
とメッセージをオプションで渡すこともできる。こっちのほうがびっくりしないのでオススメ。
また、すべての追跡対象の変更をパッチ化する場合には、pijul record -a
で一発。
pijul log
パッチの履歴を見る場合は pijul log
。
$ pijul log
# Hash: 8AoNvRnRvhnTyMCZmdQbpdwqBr6Ax4WNsHYL7f55iHkGw7bttoUuoiDetQmmK7iWq53tecQwRTn1wFqMy7BpL7Pi
# Internal id: JA4E96crMn8
# Authors:
#
# Timestamp: 2018-11-23 03:19:14.245532200 UTC
#
# first commit
pijul ls
追跡中のファイル一覧を確認する場合は pijul ls
。
$ pijul ls
# sample_1202.nimble
# src
# src\sample_1202.nim
pijul patch
パッチの内容を確認する場合は pijul patch <<Patch Hash>>
。
$ pijul patch 8AoNvRnRvhnTyMCZmdQbpdwqBr6Ax4WNsHYL7f55iHkGw7bttoUuoiDetQmmK7iWq53tecQwRTn1wFqMy7BpL7Pi
# In "["sample_1202.nimble"]":
# From line 1:
# + # Package
# +
# + version = "0.1.0"
# + author = "username"
# + description = "A new awesome nimble package"
# + license = "MIT"
# + srcDir = "src"
# + bin = @["sample_1202"]
# +
# +
# + # Dependencies
# +
# + requires "nim >= 0.19.0"
# In "["src", "sample_1202.nim"]":
# From line 1:
# + # This is just an example to get you started. A typical binary package
# + # uses this file as the main entry point of the application.
# +
# + when isMainModule:
# + echo("Hello, World!")
pijul diff
まだパッチ化されていないローカル変更の差分を確認する場合は pijul diff
で可能。
まずは、src\sample_1202.nim
ファイルを以下のように変更して
when isMainModule:
+ echo("Good Morning, World!")
echo("Hello, World!")
+ echo("Good Night, World!")
差分を確認すると、
$ pijul diff
# In file "src\\sample_1202.nim"
#
# + echo("Good Morning, World!")
#
# + echo("Good Night, World!")
もう一度、pijul record
上記変更をした上で、もう一度パッチを作成する。
ポイントとしては、Pijul は Git でいうインデックスが無いので、追跡対象ファイルの差分はすべて record の対象となる。
$ pijul status
# On branch master
#
# Changes not yet recorded:
# (use "pijul record ..." to record a new patch)
#
# modified: src\sample_1202.nim
$ pijul record
# In file "src\\sample_1202.nim"
#
# + echo("Good Morning, World!")
#
# Shall I record this change? (1/2) [ynkad?] y
#
# + echo("Good Night, World!")
#
# Shall I record this change? (2/2) [ynkad?] y
#
# second commit
# What is the name of this patch? Recorded patch 6mLyhM75oVJpzDBTkhBxPC3zjSztDCXE2PuSDsQHQiuHb2vXNLNDipbVBRTpeYfMgK9B1puQMgLfqgvD57SeH7xK
ここで一つ気がつくことは、パッチは Hunk 単位で選択可能 ということ。
これは、git add -p
と同様の機能が標準であるということ。賢く Hunk 化してくれるなら便利。
pijul unrecord
一度記録したパッチを無かったことにする場合、pijul unrecord <<Patch Hash>>
を使う。
$ pijul log
# Hash: 6mLyhM75oVJpzDBTkhBxPC3zjSztDCXE2PuSDsQHQiuHb2vXNLNDipbVBRTpeYfMgK9B1puQMgLfqgvD57SeH7xK
# Internal id: 6Qbvwo8Xm7Z
# Authors:
#
# Timestamp: 2018-11-23 03:43:08.077835100 UTC
#
# second commit
#
#
# Hash: 8AoNvRnRvhnTyMCZmdQbpdwqBr6Ax4WNsHYL7f55iHkGw7bttoUuoiDetQmmK7iWq53tecQwRTn1wFqMy7BpL7Pi
# Internal id: JA4E96crMn8
# Authors:
#
# Timestamp: 2018-11-23 03:19:14.245532200 UTC
#
# first commit
#
$ pijul unrecord 6mLyhM75oVJpzDBTkhBxPC3zjSztDCXE2PuSDsQHQiuHb2vXNLNDipbVBRTpeYfMgK9B1puQMgLfqgvD57SeH7xK
$ pijul log
# Hash: 8AoNvRnRvhnTyMCZmdQbpdwqBr6Ax4WNsHYL7f55iHkGw7bttoUuoiDetQmmK7iWq53tecQwRTn1wFqMy7BpL7Pi
# Internal id: JA4E96crMn8
# Authors:
#
# Timestamp: 2018-11-23 03:19:14.245532200 UTC
#
# first commit
#
$ pijul diff
# In file "src\\sample_1202.nim"
#
# + echo("Good Morning, World!")
#
# + echo("Good Night, World!")
確かにパッチが記録されたという事実は削除されたが、ファイルの変更はそのままだった。
Git のようにインデックスが無いため完全に同等ではないが、 git reset --mixed/--soft
相当の機能と思われる。
pijul revert
記録されていない変更を無かったことにする場合は、pujul revert
を使う。
$ pijul diff
# In file "src\\sample_1202.nim"
#
# + echo("Good Morning, World!")
#
# + echo("Good Night, World!")
$ pijul revert
# In file "src\\sample_1202.nim"
#
# + echo("Good Morning, World!")
#
# Shall I revert this change? (1/2) [ynkad?] y
#
# + echo("Good Night, World!")
#
# Shall I revert this change? (2/2) [ynkad?] y
$ pijul diff
#
git reset --hard HEAD
みたいな感じだろうか。
pijul remove
追跡をやめたいファイルがある場合は、pujul remove <<ファイル>>
を使う。
$ nimble build
# Verifying dependencies for sample_1202@0.1.0
# Building sample_1202/sample_1202.exe using c backend
$ pijul status
# On branch master
#
# Untracked files:
# (use "pijul add <file>..." to track them)
#
# sample_1202.exe
$ pijul add sample_1202.exe
$ pijul status
# On branch master
#
# Changes not yet recorded:
# (use "pijul record ..." to record a new patch)
#
# new file: sample_1202.exe
$ pijul remove sample_1202.exe
$ pijul status
# On branch master
#
# Untracked files:
# (use "pijul add <file>..." to track them)
#
# sample_1202.exe
ちなみに、いつも Untrackd files に出てくるのが邪魔だったら、明示的に無視することもできる。
.ignore
か .pijulignore
ファイルを置いて、その中に無視したいファイルを追加する。
$ pijul status
# On branch master
#
# Untracked files:
# (use "pijul add <file>..." to track them)
#
# sample_1202.exe
$ echo "sample_1202.exe" > .pijulignore
$ pijul status
# On branch master
#
# Untracked files:
# (use "pijul add <file>..." to track them)
#
# .pijulignore
.gitignore
の様にワイルドカードの指定も可能。
2. ブランチ操作
pijul fork
ブランチを作成するには、pijul fork
を使う。
$ pijul status
# On branch master
# Nothing to record, working tree clean
master
ブランチをフォーク元として、新しく newbranch
を作成する。
$ pijul log
# Hash: 6XBqejgpKyKETHqYuoEGdMmqJkJ6Lj1ZNrhaez9cbKJrCeyRdhbKPjPJX9nLFaKA7jUC24NjZZQgGqU61JEEXLvV
# Internal id: 4NAHqDtPyoj
# Authors:
#
# Timestamp: 2018-11-23 04:14:36.624109200 UTC
#
# add ignore file
#
# Hash: 8AoNvRnRvhnTyMCZmdQbpdwqBr6Ax4WNsHYL7f55iHkGw7bttoUuoiDetQmmK7iWq53tecQwRTn1wFqMy7BpL7Pi
# Internal id: JA4E96crMn8
# Authors:
#
# Timestamp: 2018-11-23 03:19:14.245532200 UTC
#
# first commit
#
$ pijul fork newbranch
$ pijul status
# On branch newbranch
# Nothing to record, working tree clean
試しに、newbranch
の src\sample_1202.nim
を修正してみる。
$ pijul diff
# In file "src\\sample_1202.nim"
#
# - echo("Hello, World!")
# + echo("Hello, Mars!")
$ pijul record
# In file "src\\sample_1202.nim"
#
# - echo("Hello, World!")
# + echo("Hello, Mars!")
#
# Shall I record this change? (1/1) [ynkad?] y
#
# go to mars
# What is the name of this patch? Recorded patch 7RbjQKRMXL7MaC8naU29bGV1obYudvntGSVfEuDmpf9JAChhcbwb944hFQtdVcaujtcc4KCa1z3A8fPHNLpzNaZC
$ pijul log
# Hash: 7RbjQKRMXL7MaC8naU29bGV1obYudvntGSVfEuDmpf9JAChhcbwb944hFQtdVcaujtcc4KCa1z3A8fPHNLpzNaZC
# Internal id: Bve1Gm9QMuB
# Authors:
#
# Timestamp: 2018-11-23 04:21:05.123480300 UTC
#
# go to mars
#
#
# Hash: 6XBqejgpKyKETHqYuoEGdMmqJkJ6Lj1ZNrhaez9cbKJrCeyRdhbKPjPJX9nLFaKA7jUC24NjZZQgGqU61JEEXLvV
# Internal id: 4NAHqDtPyoj
# Authors:
#
# Timestamp: 2018-11-23 04:14:36.624109200 UTC
#
# add ignore file
#
# Hash: 8AoNvRnRvhnTyMCZmdQbpdwqBr6Ax4WNsHYL7f55iHkGw7bttoUuoiDetQmmK7iWq53tecQwRTn1wFqMy7BpL7Pi
# Internal id: JA4E96crMn8
# Authors:
#
# Timestamp: 2018-11-23 03:19:14.245532200 UTC
#
# first commit
これで、newbranch
には 7RbjQKRMXL7MaC8naU29bGV1obYudvntGSVfEuDmpf9JAChhcbwb944hFQtdVcaujtcc4KCa1z3A8fPHNLpzNaZC
が追加されたが、
$ pijul log --branch master
# Hash: 6XBqejgpKyKETHqYuoEGdMmqJkJ6Lj1ZNrhaez9cbKJrCeyRdhbKPjPJX9nLFaKA7jUC24NjZZQgGqU61JEEXLvV
# Internal id: 4NAHqDtPyoj
# Authors:
#
# Timestamp: 2018-11-23 04:14:36.624109200 UTC
#
# add ignore file
#
# Hash: 8AoNvRnRvhnTyMCZmdQbpdwqBr6Ax4WNsHYL7f55iHkGw7bttoUuoiDetQmmK7iWq53tecQwRTn1wFqMy7BpL7Pi
# Internal id: JA4E96crMn8
# Authors:
#
# Timestamp: 2018-11-23 03:19:14.245532200 UTC
#
# first commit
master
ブランチには、7RbjQKRMXL7MaC8naU29bGV1obYudvntGSVfEuDmpf9JAChhcbwb944hFQtdVcaujtcc4KCa1z3A8fPHNLpzNaZC
が存在していない事が分かる。
pijul branches
[公式ドキュメントに記載なし]
ブランチ一覧を表示するには、pijul branches
を使う。
$ pijul branches
# master
# * newbranch
pijul checkout
ブランチを変更するには、pijul checkout
を使う。
$ pijul branches
# master
# * newbranch
$ pijul checkout master
# Current branch: "master"
$ pijul branches
# * master
# newbranch
pijul apply
Pijul の醍醐味である、チェリーピッキングを行うには pijul apply
を使う。
$ pijul log --branch master
# Hash: 6XBqejgpKyKETHqYuoEGdMmqJkJ6Lj1ZNrhaez9cbKJrCeyRdhbKPjPJX9nLFaKA7jUC24NjZZQgGqU61JEEXLvV
# Internal id: 4NAHqDtPyoj
# Authors:
#
# Timestamp: 2018-11-23 04:14:36.624109200 UTC
#
# add ignore file
#
# Hash: 8AoNvRnRvhnTyMCZmdQbpdwqBr6Ax4WNsHYL7f55iHkGw7bttoUuoiDetQmmK7iWq53tecQwRTn1wFqMy7BpL7Pi
# Internal id: JA4E96crMn8
# Authors:
#
# Timestamp: 2018-11-23 03:19:14.245532200 UTC
#
# first commit
#
$ pijul log --branch newbranch
# Hash: 7RbjQKRMXL7MaC8naU29bGV1obYudvntGSVfEuDmpf9JAChhcbwb944hFQtdVcaujtcc4KCa1z3A8fPHNLpzNaZC
# Internal id: Bve1Gm9QMuB
# Authors:
#
# Timestamp: 2018-11-23 04:21:05.123480300 UTC
#
# go to mars
#
#
# Hash: 6XBqejgpKyKETHqYuoEGdMmqJkJ6Lj1ZNrhaez9cbKJrCeyRdhbKPjPJX9nLFaKA7jUC24NjZZQgGqU61JEEXLvV
# Internal id: 4NAHqDtPyoj
# Authors:
#
# Timestamp: 2018-11-23 04:14:36.624109200 UTC
#
# add ignore file
#
# Hash: 8AoNvRnRvhnTyMCZmdQbpdwqBr6Ax4WNsHYL7f55iHkGw7bttoUuoiDetQmmK7iWq53tecQwRTn1wFqMy7BpL7Pi
# Internal id: JA4E96crMn8
# Authors:
#
# Timestamp: 2018-11-23 03:19:14.245532200 UTC
#
# first commit
#
この、newbranch
の 7RbjQKRMXL7MaC8naU29bGV1obYudvntGSVfEuDmpf9JAChhcbwb944hFQtdVcaujtcc4KCa1z3A8fPHNLpzNaZC
を master
にチェリーピッキングする。
$ pijul branches
# * master
# newbranch
$ pijul apply 7RbjQKRMXL7MaC8naU29bGV1obYudvntGSVfEuDmpf9JAChhcbwb944hFQtdVcaujtcc4KCa1z3A8fPHNLpzNaZC
$ pijul log
# Hash: 7RbjQKRMXL7MaC8naU29bGV1obYudvntGSVfEuDmpf9JAChhcbwb944hFQtdVcaujtcc4KCa1z3A8fPHNLpzNaZC
# Internal id: Bve1Gm9QMuB
# Authors:
#
# Timestamp: 2018-11-23 04:21:05.123480300 UTC
#
# go to mars
#
#
# Hash: 6XBqejgpKyKETHqYuoEGdMmqJkJ6Lj1ZNrhaez9cbKJrCeyRdhbKPjPJX9nLFaKA7jUC24NjZZQgGqU61JEEXLvV
# Internal id: 4NAHqDtPyoj
# Authors:
#
# Timestamp: 2018-11-23 04:14:36.624109200 UTC
#
# add ignore file
#
# Hash: 8AoNvRnRvhnTyMCZmdQbpdwqBr6Ax4WNsHYL7f55iHkGw7bttoUuoiDetQmmK7iWq53tecQwRTn1wFqMy7BpL7Pi
# Internal id: JA4E96crMn8
# Authors:
#
# Timestamp: 2018-11-23 03:19:14.245532200 UTC
#
# first commit
#
チェリーピッキングされたパッチのハッシュは変更されておらず、またマージコミットのようなものも作成されていない。
とても自然だ。
( Fast-Forward なので、驚くのもアレなんだけど。もっと良い例にすれば良かった )
pijul delete-branch
ブランチを削除するには pijul delete-branch
を使う。
$ pijul delete-branch newbranch
$ pijul branches
# * master
3. チーム開発
Git に Github があるように、Pijul には Nest (2018/11/27 現在停止中) がある。
Nest を使ってリモートリポジトリを利用したチーム開発をやってみる。
pijul key
Pijul では、2つの用途で SSH キーを利用する。
- パッチへの署名
- リモートリポジトリへのアクセス
● パッチへの署名
パッチへ署名するためのキーは、以下コマンドで作成できる。デフォルトで Ed25519 の鍵ペアが作られる。
# グローバルキー
$ pijul key gen --signing
# ローカルキー
$ pijul key gen --signing --local
グローバルキーは C:\Users\<<usename>>\.pijulconfig
に sig_ed25519
と sig_ed25519.pub
が作成される。
ローカルキーは <<Project Root>>\.pijul
に sig_ed25519
と sig_ed25519.pub
が作成される。
ローカルキーが優先される。
どちらかの鍵が作られると、以降はすべてのパッチに署名がつく。
それを Pijul CLI から確認する方法は分からなかったが、 <<Project Root>>\.pijul\patches
以下に <<Patch Hash>>.sig
という JSON ファイルが作成されている。
{
"hash":"<<パッチハッシュ>>",
"signatures":{
"<<公開鍵ハッシュ>>":"<<署名>>"
}
}
● リモートリポジトリへの登録
# グローバルキー
$ pijul key gen --ssh
# ローカルキー
$ pijul key gen --ssh --local
グローバルキーは C:\Users\<<usename>>\.pijulconfig
の中に、ローカルキーは <<Project Root>>\.pijul
の中に id_ed25519
と id_ed25519.pub
が作成される。
また、作成した鍵をリモートリポジトリに登録するためのコマンドも用意されている (サーバ落ちてるので使ったことはない)
# グローバルキー
$ pijul key upload <url>
# ローカルキー
$ pijul key upload --local <url>
pijul clone
リポジトリを複製するためのコマンド。
$ pijul clone https://nest.pijul.com/pijul_org/pijul
また、このコマンドは必ずしもリモートを対象とする必要はなく、あくまで url or path で表現されたリポジトリをコピーするためのコマンドであるため、ローカルディレクトリでも実は問題ない。
$ pijul clone src_project copied_project
pijul push
, pijul pull
https://pijul.org/manual/reference/push.html
https://pijul.org/manual/reference/pull.html
リモートリポジトリからパッチを取得 / パッチを送信する為のコマンド。
現在、nest が使えないので、ローカルディレクトリで仮想的にやってみる。
$ cd ..
$ pijul clone sample_1202 other_sample_1202
# Pulling patches: 100% (3/3), done.
# Applying patches: 100% (3/3), done.
$ pijul clone sample_1202 remote_sample_1202
# Pulling patches: 100% (3/3), done.
# Applying patches: 100% (3/3), done.
remote_sample_1202 | リモートリポジトリ |
sample_1202 | ローカルリポジトリ 1 |
other_sample_1202 | ローカルリポジトリ 2 |
sample_1202
で変更して、push してみる。
$ cd sample_1202
$ pijul log --hash-only # 長いので Hash だけ
# 6eFvL0vf4228RZ4zIMl3QYNkvtkEPmdR8nMm4hKlvTpqgILTodkJh2ukXlUuMHtJEBswp00QD8VTSlgwnpPW2zPhzx9LY8Z3cDjL
# 7RbjQKRMXL7MaC8naU29bGV1obYudvntGSVfEuDmpf9JAChhcbwb944hFQtdVcaujtcc4KCa1z3A8fPHNLpzNaZC:0
# 6XBqejgpKyKETHqYuoEGdMmqJkJ6Lj1ZNrhaez9cbKJrCeyRdhbKPjPJX9nLFaKA7jUC24NjZZQgGqU61JEEXLvV:1
# 8AoNvRnRvhnTyMCZmdQbpdwqBr6Ax4WNsHYL7f55iHkGw7bttoUuoiDetQmmK7iWq53tecQwRTn1wFqMy7BpL7Pi:2
$ pijul diff
# In file "src\\sample_1202.nim"
#
# - echo("Hello, Mars!")
# + echo("Hello, Jupiter!")
$ pijul record
# In file "src\\sample_1202.nim"
#
# - echo("Hello, Mars!")
# + echo("Hello, Jupiter!")
#
# Shall I record this change? (1/1) [ynkad?] y
#
# go to jupiter
# What is the name of this patch? Recorded patch 6PQoiSFhwaVz6H78rpH4ewhrm9AgxsSKCbnqU9taS8nN6S4X8So8TPH2zvkhuCMJY79LDcL6dpWC196csGMMqDZj
$ pijul log --hash-only
# 6eFvL0vf4228RZ4zIMl3QYNkvtkEPmdR8nMm4hKlvTpqgILTodkJh2ukXlUuMHtJEBswp00QD8VTSlgwnpPW2zPhzx9LY8Z3cDjL
# 6PQoiSFhwaVz6H78rpH4ewhrm9AgxsSKCbnqU9taS8nN6S4X8So8TPH2zvkhuCMJY79LDcL6dpWC196csGMMqDZj:0 # ← 増えてる
# 7RbjQKRMXL7MaC8naU29bGV1obYudvntGSVfEuDmpf9JAChhcbwb944hFQtdVcaujtcc4KCa1z3A8fPHNLpzNaZC:1
# 6XBqejgpKyKETHqYuoEGdMmqJkJ6Lj1ZNrhaez9cbKJrCeyRdhbKPjPJX9nLFaKA7jUC24NjZZQgGqU61JEEXLvV:2
# 8AoNvRnRvhnTyMCZmdQbpdwqBr6Ax4WNsHYL7f55iHkGw7bttoUuoiDetQmmK7iWq53tecQwRTn1wFqMy7BpL7Pi:3
$ pijul push ..\remote_sample_1202
# Hash: 6PQoiSFhwaVz6H78rpH4ewhrm9AgxsSKCbnqU9taS8nN6S4X8So8TPH2zvkhuCMJY79LDcL6dpWC196csGMMqDZj
# Internal id: 3F6x1mrWp6A
# Authors:
#
# Timestamp: 2018-11-23 05:16:17.734130100 UTC
#
# go to jupiter
#
#
# Shall I push this patch? [ynkad?] y
remote_sample_1202
を確認してみると、
$ cd ..\remote_sample_1202
$ pijul log --hash-only
# gxrv4obMWGn54OFKHVx6542FWbKzz88yRvyxsAP24w5agr7JRBauQF79PHK2DlBa75noy5IG0IKh0eHkJWumbzEZStFWKx6tdFgd
# 6PQoiSFhwaVz6H78rpH4ewhrm9AgxsSKCbnqU9taS8nN6S4X8So8TPH2zvkhuCMJY79LDcL6dpWC196csGMMqDZj:0 # ← 増えてる
# 6XBqejgpKyKETHqYuoEGdMmqJkJ6Lj1ZNrhaez9cbKJrCeyRdhbKPjPJX9nLFaKA7jUC24NjZZQgGqU61JEEXLvV:1
# 7RbjQKRMXL7MaC8naU29bGV1obYudvntGSVfEuDmpf9JAChhcbwb944hFQtdVcaujtcc4KCa1z3A8fPHNLpzNaZC:2
# 8AoNvRnRvhnTyMCZmdQbpdwqBr6Ax4WNsHYL7f55iHkGw7bttoUuoiDetQmmK7iWq53tecQwRTn1wFqMy7BpL7Pi:3
other_sample_1202
で pull してみる。
$ cd ..\other_sample_1202
$ pijul log --hash-only
# jYdKkshCFAs1KFN27Te9oW3VzUQaCtF4l25VTAUuUmOi5lLpNthrS8ibdfKx3npjHylZOmCEhbyKwSv1fhAhKQSNQcBQKMhbMWPY
# 6XBqejgpKyKETHqYuoEGdMmqJkJ6Lj1ZNrhaez9cbKJrCeyRdhbKPjPJX9nLFaKA7jUC24NjZZQgGqU61JEEXLvV:0
# 7RbjQKRMXL7MaC8naU29bGV1obYudvntGSVfEuDmpf9JAChhcbwb944hFQtdVcaujtcc4KCa1z3A8fPHNLpzNaZC:1
# 8AoNvRnRvhnTyMCZmdQbpdwqBr6Ax4WNsHYL7f55iHkGw7bttoUuoiDetQmmK7iWq53tecQwRTn1wFqMy7BpL7Pi:2
$ pijul pull ..\remote_sample_1202
# Pulling patches: 100% (1/1), done.
# Hash: 6PQoiSFhwaVz6H78rpH4ewhrm9AgxsSKCbnqU9taS8nN6S4X8So8TPH2zvkhuCMJY79LDcL6dpWC196csGMMqDZj
# Authors:
#
# Timestamp: 2018-11-23 05:16:17.734130100 UTC
#
# go to jupiter
#
#
# Shall I pull this patch? [ynkad?] y
# Applying patches: 100% (1/1), done.
$ pijul log --hash-only
# jYdKkshCFAs1KFN27Te9oW3VzUQaCtF4l25VTAUuUmOi5lLpNthrS8ibdfKx3npjHylZOmCEhbyKwSv1fhAhKQSNQcBQKMhbMWPY
# 6PQoiSFhwaVz6H78rpH4ewhrm9AgxsSKCbnqU9taS8nN6S4X8So8TPH2zvkhuCMJY79LDcL6dpWC196csGMMqDZj:0
# 6XBqejgpKyKETHqYuoEGdMmqJkJ6Lj1ZNrhaez9cbKJrCeyRdhbKPjPJX9nLFaKA7jUC24NjZZQgGqU61JEEXLvV:1
# 7RbjQKRMXL7MaC8naU29bGV1obYudvntGSVfEuDmpf9JAChhcbwb944hFQtdVcaujtcc4KCa1z3A8fPHNLpzNaZC:2
# 8AoNvRnRvhnTyMCZmdQbpdwqBr6Ax4WNsHYL7f55iHkGw7bttoUuoiDetQmmK7iWq53tecQwRTn1wFqMy7BpL7Pi:3
$ cat src\sample_1202.nim
# # This is just an example to get you started. A typical binary package
# # uses this file as the main entry point of the application.
#
# when isMainModule:
# echo("Hello, Jupiter!")
共有できている。
Git と違い、追跡ブランチが無いため git fetch
して git merge
みたいな操作はできない。そもそも、マージが起こらないということであれば、その必要もないのか。
感覚としては、リモートリポジトリも一つのブランチで、pull はリモートリポジトリの未取得パッチを apply しているような。
と、こんな感じで大体の動きが確認できた。
あとは気になるのが、衝突したときの挙動 だ。
衝突と解決
とても気になるのが、衝突をどう解決するのか。
Pijul のドキュメントを見ていると、様々な場面で
- Pijul はパッチの集合
- パッチは基本前後を入れ替えても問題ない
- 過去に適用したパッチを非適用しても問題ない
みたいな説明を見た。
けど、衝突と解決を行ったら、それらは崩れてしまいそうに思う。
多分、答えは以下等を読むと分かりそうだが、そこそこ難しい。
https://jneem.github.io/merging/
https://jneem.github.io/pijul/
https://arxiv.org/pdf/1311.3903.pdf
今はそっとしておく。
もっとこうして欲しい
そっけない態度
レスポンスが結構簡素で、 pijul add
しても pijul apply
しても「しました!」みたいな反応をくれない。
HEAD
がない
Git の HEAD
みたいなのがあると、pijul unrecord HEAD
みたいにできるんだけど。
時系列的な意味合いを含む HEAD (先頭) は Pijul 的には正しくないのかもしれないが。
あとがき
※ この記事は個人の見解であり、所属する組織を代表するものではありません。