Metaで開発されているSaplingが公開されましたので、使ってみます。
- インストール
- 初期設定
- リポジトリの作成
- ファイルを追加
- 編集してコミット
- コミットログの表示
- headの表示
- 分岐の作成
- 分岐で次に進む
- ブランチのマージ
- マージを元に戻す
- rebaseにてブランチをマージ
- コミット間の移動
- 操作の取り消しと再実行
- コマンド一覧
今回はWindowsで試してみます。
インストール
インストールは、
https://github.com/facebook/sapling/releases/tag/0.2.20221222-152408-ha6a66d09
からダウンロードしてきたzipを展開してPATHを通すだけです。
頻繁に更新されているようなので、新規にインストールするなら最新のものを利用するのがよさそうです。
初期設定
まずは使用者名の設定をします。
$ sl config --user ui.username "yourname <yourname@mail.address.com>"
今回は、メールアドレスを省略して、
$ sl config --user ui.username "yourname"
としています。
リポジトリの作成
新しいリポジトリを作っていきます。
https://sapling-scm.com/docs/introduction/getting-started
ではGithubからリポジトリを取得するように書かれていますが、ここでは実験的な機能として入っているgitのリポジトリを1から作成する方法を使ってみます。
$ sl init --git
これは実験的な機能であるためか、
sl helpでも今回試しているバージョンではコマンドが出てきません。
何もファイルをコミットしていない状態だと、logもなにも表示されないので、
sl showを実行してみたところ、
$ sl show
changeset: 0000000000000000000000000000000000000000 (@)
user:
date: 木, 01 1 1970 09:00:00 +0900
といった表示がされました。
ファイルを追加
お試し用のファイルを
$ echo aaa > a.txt
のように作成します。
次にSaplingに登録します。
$ sl add a.txt
最後にコミットします。
$ sl commit
Windowsでは、デフォルトではメモ帳が開くので、コミットメッセージを書いて保存し、メモ帳を終了します。
すると、コミットが完了します。
ログを見ると、
$ sl log
changeset: 5bbaee36d524dc4b97c9ee5740cf6440a37ddfb5 (@)
user: yourname <>
date: 木, 05 1 2023 15:31:25 +0900
summary: Initial commit
と表示されます。
単に
slを実行すると、
$ sl
@ 5bbaee36d 2 minutes ago >
Initial commit
となります。コミット時間が相対時間で表示されるので、時刻表示のほうが良い場合は
logのほうがよさそうです。
$ sl head
changeset: 5bbaee36d524dc4b97c9ee5740cf6440a37ddfb5 (@)
user: yourname <>
date: 木, 05 1 2023 15:31:25 +0900
summary: Initial commit
とすると、
logと同じ内容が表示されます。
編集してコミット
次に、
$ echo "bbb" >> a.txt
で、コミットしているファイルを編集してみます。diffをとると、
$ sl diff
diff --git a/a.txt b/a.txt
--- a/a.txt
+++ b/a.txt
@@ -1,1 +1,2 @@
aaa
+"bbb" <0D>
と表示されてbbbが追加されていることがわかります。Windowsなので、改行記号が\r\nになっており、0Dが追加で表示されているようです。
statusを表示してみると、
$ sl status
M a.txt
となり、変更されていると表示されます。
今回は
sl commit -iにて、対話的なコミット画面を表示してみます。
$ sl commit -i
starting interactive selection
実行すると、
Select hunks to record - [x]=selected **=collapsed c: confirm q: abort arrow keys: move/expand/collapse space: deselect ?: help
[x] diff --git a/a.txt b/a.txt
1 hunks, 1 lines changed
[x] @@ -1,1 +1,2 @@
aaa ^M
[x] +"bbb" ^M
と表示されます(色は省略)。Mercurialの
hg com -iや、
git crecordと同じ操作感の画面です。部分コミットを簡単にできます。
今回は1箇所しか変更していないので、そのまま
cを押して、コミットします。
コミットログの表示
単にログを表示します。
$ sl log
changeset: f4adbb569e88ed2127b9b79c0a88d22d396532aa (@)
user: yourname <>
date: 木, 05 1 2023 15:45:49 +0900
summary: Update
changeset: 5bbaee36d524dc4b97c9ee5740cf6440a37ddfb5
user: yourname <>
date: 木, 05 1 2023 15:31:25 +0900
summary: Initial commit
のようになり、履歴がわかります。
--graphにてグラフ表示もできるようです。
$ sl log --graph
@ changeset: f4adbb569e88ed2127b9b79c0a88d22d396532aa (@)
│ user: yourname <>
│ date: 木, 05 1 2023 15:45:49 +0900
│ summary: Update
│
o changeset: 5bbaee36d524dc4b97c9ee5740cf6440a37ddfb5
user: yourname <>
date: 木, 05 1 2023 15:31:25 +0900
summary: Initial commit
単に
slを実行すると、
$ sl
@ f4adbb569 100 seconds ago >
│ Update
│
o 5bbaee36d 16 minutes ago >
Initial commit
と表示されます。
headの表示
headを表示してみます。分岐の先頭の一覧が表示されますが、今の時点では分岐がないので、
$ sl head
changeset: f4adbb569e88ed2127b9b79c0a88d22d396532aa (@)
user: yourname <>
date: 木, 05 1 2023 15:45:49 +0900
summary: Update
のように1つだけ表示されます。
prevコマンドで最初のコミットに戻ってみます。
$ sl prev
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
[5bbaee] Initial commit
$ sl head
changeset: f4adbb569e88ed2127b9b79c0a88d22d396532aa
user: yourname <>
date: 木, 05 1 2023 15:45:49 +0900
summary: Update
headは変わりません。slコマンドでは
$ sl
o f4adbb569 13 minutes ago >
│ Update
│
@ 5bbaee36d 27 minutes ago >
Initial commit
@の場所が変化します。
分岐の作成
最初に
a.txtに文字を追加します。
$ echo "ccc" >> a.txt
を実行し、
$ sl commit
にてコミットします。
$ sl head
changeset: 1cae689a8bab379edcc7e1c63c305f78d37d608a (@)
user: yourname <>
date: 木, 05 1 2023 16:00:24 +0900
summary: Add ccc
changeset: f4adbb569e88ed2127b9b79c0a88d22d396532aa
user: yourname <>
date: 木, 05 1 2023 15:45:49 +0900
summary: Update
となり、headが複数できていることがわかります。この表示はMercurialと同様です。
slを実行すると、
$ sl
@ 1cae689a8 67 seconds ago >
│ Add ccc
│
│ o f4adbb569 15 minutes ago >
├─╯ Update
│
o 5bbaee36d 30 minutes ago >
Initial commit
となります。罫線の幅を半角表示にするときれいに位置がそろうのですが、CSSでうまく書けなかったため、ずれたままで。
また、─╯ は2文字ですが、コマンドプロンプトウィンドウでは、重ねて表示されており、分岐した線のように見えます。
一方、WSL Terminalで当該文字列を表示すると重ならないです。
話はそれますが、 ╯ はUnicodeで
256F、UTF-8で
E2 95 AFです。
分岐で次に進む
まず、今の状態で
sl prevを実行すると、
$ sl
o 1cae689a8 4 minutes ago >
│ Add ccc
│
│ o f4adbb569 18 minutes ago >
├─╯ Update
│
@ 5bbaee36d 33 minutes ago >
Initial commit
となり、最初のコミットに戻ってきます。
この位置では分岐があるのでnextを実行するとどうなるかというと、
$ sl next
commit 5bbaee36d524 has multiple children, namely:
(1) [f4adbb] Update
(2) [1cae68] Add ccc
which commit to move to [1-2/(c)ancel]?
というメッセージが出力され、どちらに進むか選ぶようになっています。
(1)側に進んでみると、
which commit to move to [1-2/(c)ancel]? 1
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
[f4adbb] Update
と表示され、(1)側に移動できます。
$ sl
o 1cae689a8 6 minutes ago >
│ Add ccc
│
│ @ f4adbb569 20 minutes ago >
├─╯ Update
│
o 5bbaee36d 35 minutes ago >
Initial commit
となり、たしかに、f4adbb569 に移動できていることが確認できます。
隣の分岐に移動するには、
$ sl goto 1cae
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
でよさそうです。
$ sl
@ 1cae689a8 9 minutes ago >
│ Add ccc
│
│ o f4adbb569 24 minutes ago >
├─╯ Update
│
o 5bbaee36d 38 minutes ago >
Initial commit
となっており、移動できていることが確認できます。
ブランチのマージ
さきほど作成したブランチをマージします。Saplingではマージよりrebaseを使うように設計されているようですが
(
https://sapling-scm.com/docs/introduction/のCaveatsより)、
mergeコマンドはあるのでそれでマージしてみます。
$ sl merge
を実行すると、kdiff3をインストールしているためか、kdiff3が立ち上がって、コンフリクトを解消するよう指示が出ます。
手動でマージすると、
$ sl merge
merging a.txt
running merge tool kdiff3 for file a.txt
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
と表示され、マージができました。この段階ではコミットされておらず、
$ sl
@ 1cae689a8 25 minutes ago >
│ Add ccc
│
│ @ f4adbb569 39 minutes ago >
├─╯ Update
│
o 5bbaee36d 54 minutes ago >
Initial commit
のように表示されます。@が2箇所に表示されます。
$ sl commit
でコミットすると、
$ sl
@ b84d24eda 15 seconds ago >
├─╯ Merge
│ │
o │ f4adbb569 41 minutes ago >
│ │ Update
│ │
│ o 1cae689a8 26 minutes ago >
├─╯ Add ccc
│
o 5bbaee36d 55 minutes ago >
Initial commit
と表示され、めでたくマージできたことが確認できます。
マージを元に戻す
rebaseが推奨であるようなので、一旦これを元に戻してみます。
インタラクティブにできそうなので、
-i付きで実行してみましたが、
$ sl undo -i
abort: interactive ui is not supported on Windows
となり残念ながら実行できません。
-iなしで試してみると、
$ sl undo
undone to 木 1 05 16:09:49 2023 +0900, before commit
hint[undo-uncommit-unamend]: undoing commits discards their changes.
to restore the changes to the working copy, run 'sl revert -r b84d24eda1a8 --all'
in the future, you can use 'sl uncommit' instead of 'sl undo' to keep changes
hint[hint-ack]: use 'sl hint --ack undo-uncommit-unamend' to silence these hints
$ sl
@ 1cae689a8 30 minutes ago >
│ Add ccc
│
│ o f4adbb569 44 minutes ago >
├─╯ Update
│
o 5bbaee36d 59 minutes ago >
Initial commit
と表示され、マージ処理を元に戻せています。マージしたファイルを取得する方法もメッセージに書かれており、
消えていてもリビジョン(=コミットのハッシュ値)さえわかっていればrevertで戻せるようです。
試して見ると、
$ sl revert -r b84d24eda1a8 --all
reverting a.txt
$ sl diff
diff --git a/a.txt b/a.txt
--- a/a.txt
+++ b/a.txt
@@ -1,2 +1,3 @@
aaa
+"bbb" <0D>
"ccc"
となり、たしかにマージ処理したa.txtが戻ってきます。
さらにundoできるか試してみると、
$ sl undo
abort: uncommitted changes
となります。revertで戻したファイルが未コミットのファイルとなっており、この状態ではundoはできないようです。
rebaseにてブランチをマージ
先程はブランチのコミットを維持したままマージしましたが、今度はrebaseでマージしてみます。
枝を別の場所に継ぎ変えるということです。
今の状態は
$ sl
@ 1cae689a8 38 minutes ago >
│ Add ccc
│
│ o f4adbb569 52 minutes ago >
├─╯ Update
│
o 5bbaee36d 67 minutes ago >
Initial commit
となっています。ここで
$ sl rebase f4ad
abort: you must specify a destination (-d) for the rebase
$ sl rebase -r f4ad
abort: you must specify a destination (-d) for the rebase
$ sl rebase -r 1cae
abort: you must specify a destination (-d) for the rebase
$ sl rebase
abort: you must specify a destination (-d) for the rebase
としてみると、すべてエラーとなります。
ヘルプを見ると
sl rebase [-s REV | -b REV] [-d REV] [OPTION][-i]
と表示されるので、エラーメッセージの通りrebase先を
-dで指定する必要があるようです。
sl rebase -r f4adbb569 -d 1cae689a8
rebasing f4adbb569e88 "Update"
merging a.txt
abort: must use on-disk merge for this rebase (hit merge conflicts in a.txt), but you have working copy changes
(commit, revert, or shelve them)
さきほどローカルの
a.txtをマージ後のものに戻していたので、エラーとなってしまっています。
$ sl revert a.txt
で元に戻します(マージ後のローカルの
a.txtの内容を破棄します)。
再度rebaseしてみます。
$ sl rebase -r f4adbb569 -d 1cae689a8
rebasing f4adbb569e88 "Update"
merging a.txt
hit merge conflicts (in a.txt); switching to on-disk merge
rebasing f4adbb569e88 "Update"
merging a.txt
running merge tool kdiff3 for file a.txt
f4adbb569e88 -> f292f8d2ac45 "Update"
今回もkdiff3が立ち上がるので、手動でマージすると、rebaseが完了します。
$ sl
o f292f8d2a 88 seconds ago >
│ Update
│
@ 1cae689a8 49 minutes ago >
│ Add ccc
│
o 5bbaee36d 78 minutes ago >
Initial commit
となり、一直線になりました。
ヘルプを読むとrebaseしたコミットを適用先にコピーし、さらにrebaseしたブランチを隠すという処理が行われているようです。
$ sl head
changeset: f292f8d2ac45f92a9737cf4d2dd38be2e1a6fb11
user: yourname <>
date: 木, 05 1 2023 16:47:58 +0900
summary: Update
のように、headも1つになりました。コミット履歴が読みやすいので、マージよりもコミット履歴の管理としてはこの方が良いのかもしれません。
一方で、リビジョン番号は変わってしまうので、リビジョン番号を維持しておきたい場合はmergeのほうがよいかもしれません。
rebaseでも元のコミットは隠されているだけで残ってはいますが、コピーができてしまってどれとどれが同じコミットなのかを後から追いにくくなりそうですので、リビジョン番号が重要な場合はmergeでしょうか。
状況に合わせて適切な方法を利用することになりそうです。
コミット間の移動
これまでの説明で既に使用していますが、コミット間の移動は近くのコミットであればnextとprevで移動するのが簡単です。
$ sl next
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
[f292f8] Update
$ sl
@ f292f8d2a 15 minutes ago >
│ Update
│
o 1cae689a8 62 minutes ago >
│ Add ccc
│
o 5bbaee36d Today at 15:31 >
Initial commit
$ echo ddd >> a.txt
$ sl commit
$ sl
@ da3ea5b13 22 seconds ago >
│ Add ddd
│
o f292f8d2a 15 minutes ago >
│ Update
│
o 1cae689a8 63 minutes ago >
│ Add ccc
│
o 5bbaee36d Today at 15:31 >
Initial commit
$ sl prev
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
[f292f8] Update
$ sl
o da3ea5b13 50 seconds ago >
│ Add ddd
│
@ f292f8d2a 16 minutes ago >
│ Update
│
o 1cae689a8 64 minutes ago >
│ Add ccc
│
o 5bbaee36d Today at 15:31 >
Initial commit
操作の取り消しと再実行
なんらかの制限はあるようですが、操作の取り消し(undo)と再実行(redo)も簡単にできます。
先程の操作を元に戻していきます。
$ sl undo
undone to 木 1 05 17:03:41 2023 +0900, before prev
$ sl
@ da3ea5b13 81 seconds ago >
│ Add ddd
│
o f292f8d2a 16 minutes ago >
│ Update
│
o 1cae689a8 64 minutes ago >
│ Add ccc
│
o 5bbaee36d Today at 15:31 >
Initial commit
確かにprevコマンドを実行する前の状態に戻りました。さらに取り消すと、
$ sl undo
undone to 木 1 05 17:02:45 2023 +0900, before commit
$ sl
@ f292f8d2a 17 minutes ago >
│ Update
│
o 1cae689a8 65 minutes ago >
│ Add ccc
│
o 5bbaee36d Today at 15:31 >
Initial commit
dddを追加したコミットが消えました。もう一度実行すると、
$ sl undo
undone to 木 1 05 16:48:26 2023 +0900, before next
$ sl
o f292f8d2a 18 minutes ago >
│ Update
│
@ 1cae689a8 65 minutes ago >
│ Add ccc
│
o 5bbaee36d Today at 15:31 >
Initial commit
となり、参照している場所も戻りました。
今度はredoで一挙にundoをundoしてみます。
$ sl redo 10
undone to 木 1 05 17:05:19 2023 +0900, before undo
$ sl
@ f292f8d2a 19 minutes ago >
│ Update
│
o 1cae689a8 67 minutes ago >
│ Add ccc
│
o 5bbaee36d Today at 15:31 >
Initial commit
再実行はできましたが、残念ながら一括ではundo操作を戻せませんでした。
$ sl redo 2
undone to 木 1 05 17:04:52 2023 +0900, before undo
$ sl
@ da3ea5b13 5 minutes ago >
│ Add ddd
│
o f292f8d2a 21 minutes ago >
│ Update
│
o 1cae689a8 69 minutes ago >
│ Add ccc
│
o 5bbaee36d Today at 15:31 >
Initial commit
残りのundoした回数である2を指定しても1回再実行できるだけで引数の値には効果がないようです。再度redoすると、
$ sl redo
undone to 木 1 05 17:04:19 2023 +0900, before undo
$ sl redo
abort: nothing to redo
$ sl
o da3ea5b13 6 minutes ago >
│ Add ddd
│
@ f292f8d2a 21 minutes ago >
│ Update
│
o 1cae689a8 69 minutes ago >
│ Add ccc
│
o 5bbaee36d Today at 15:31 >
Initial commit
となり、undoする前に戻ってくることはできました。
You can run 'sl redo' multiple times to undo a series of 'sl undo'
commands. Alternatively, you can explicitly specify the number of 'sl
undo' commands to undo by providing a number as a positional argument.
とヘルプには書いてありましたが、できないようです。
コマンド一覧
slコマンドのヘルプ表示では表示されないコマンドを含めたコマンド一覧が
https://sapling-scm.com/docs/category/commands/
に載っています。