What's New
Support for projects in UCM and Unison Share:
In UCM, there's several new project-related commands:
Command | Description |
---|---|
create.project
| Create a new project |
clone
| Download a project branch from Share |
branch
| Create a new branch forked off the current branch |
branch.empty
| Create a new empty branch |
switch
| Switch to a different project/branch |
projects
| List your projects |
branches
| List your branches |
rename.branch
| Rename a branch |
rename.project
| Rename a project |
delete.branch
| Delete a branch |
delete.project
| Delete a project |
See the official docs for more details.
Numerous VSCode / LSP improvements (like docs on hover)

... and many other performance fixes! ⏳
Known Issues
A few commands' outputs aren't fully Projects-aware yet; this means long scary identifiers in certain spots:

In particular, undo
and reset-root
commands aren't project-aware yet. If you use them to undo or revert past a branch or project creation, the project or branch will continue to exist, but with branches reset to the empty branch. Use project.delete
or branch.delete
if you wish to undo a project or branch creation.
If you use undo or reset-root to undo a project or branch deletion, it will resurrect the namespace(s) that were deleted, but won't associate those namespaces with any projects or branches. Use the procedure below to find those namespaces and bring their contents back into a branch.
All changes since last release
- UCM Project Branch APIs by @ChrisPenner in #3829
- Port Codebase.getDeclType to be in Sqlite.Transaction by @ChrisPenner in #3866
- Update nix flake by @tstat in #3869
- Update Backend modules for project-codebase browsing by @ChrisPenner in #3868
- Add documentation for NeoVIM LSP Configuration by @gdbaldw in #3870
- Add LSP diagnostics for several more compiler errors. by @ChrisPenner in #3877
- Ensure we don't hang on 'open' by @ChrisPenner in #3876
- JIT: Implement TLS primops & add TLS tests by @jaredly in #3875
- Adding "allow-from" option so other web clients could call the api by @unorsk in #3882
- Add docs to hover. by @ChrisPenner in #3804
- Docs for completion options by @ChrisPenner in #3880
- Use a list for versions in m1-mac-setup-tips.markdown by @chriskrycho in #3862
- Build PPE using name lookup indices queries by @ChrisPenner in #3682
- Cache constructor enumeration during pattern match coverage checking by @tstat in #3884
- Add names to pattern match coverage checker debug output by @tstat in #3885
- Initial implementation of projects by @mitchellwrosen in #3886
- Misc. projects-related cleanup and bugfixes by @mitchellwrosen in #3889
- Add
projects
command to list projects by @mitchellwrosen in #3890 - project.switch bugfix: the new branch should share all history with its parent by @mitchellwrosen in #3891
- Fix example.com tests in tls-tests and tcp-tests, and disable until scheme generate escapes \r by @jaredly in #3894
- Add
branches
command that lists local branches and their remote mappings by @mitchellwrosen in #3893 - Disallow attempting to create a remote project without a user slug by @mitchellwrosen in #3898
- Delete
pr.create
andpr.load
commands by @mitchellwrosen in #3897 - implement
clone /branch
syntax by @mitchellwrosen in #3899 - Allow streaming diffs in constant memory by @ChrisPenner in #3852
- Add
project.delete-branch
command by @mitchellwrosen in #3896 - Anntoate tls & tcp functions to indicate where bytes, strings and lists are accepted or produced by @jaredly in #3903
- Make merge project aware by @tstat in #3902
- Add
branch
command that creates a branch by @mitchellwrosen in #3904 - Add more in-depth tests of the TLS stack by @jaredly in #3906
- Add md5 hash support to racket crypto by @jaredly in #3908
- Chunked seq integration by @SystemFw in #3905
- Increase busy_timeout by @ChrisPenner in #3907
- Fix md5 tests by @SystemFw in #3911
- Add an onCreate action for sqlite codebases by @ChrisPenner in #3909
- Allow regenerating name lookups by @ChrisPenner in #3910
- Add support for chunked-bytes operations by @SystemFw in #3913
- Implement two-arg variant of
branch
command by @mitchellwrosen in #3916 - add better sql quasi-quoter that allows variable interpolation by @mitchellwrosen in #3912
- Add pattern match coverage checking for ability handlers by @tstat in #3915
- Don't use named parameters in sql2 quasi-quoter by @mitchellwrosen in #3919
- Add
branch.empty
command by @mitchellwrosen in #3918 - Add error cases for release branches by @ChrisPenner in #3914
- Toss comments in sql quasi-quoter by @mitchellwrosen in #3921
- Report original source location in define-unison macro by @SystemFw in #3917
- Use sqlite quasi-quoter more by @mitchellwrosen in #3920
- Remove hacky vim auto-completion by @ceedubs in #3926
- Add a sql quasi-quoter syntax for Haskell values that span multiple SQLite fields by @mitchellwrosen in #3922
- Complete patterns api by @SystemFw in #3923
- Fix parsing of write-repo git(...) by @mitchellwrosen in #3927
- delete
switch
command's ability to make branches by @mitchellwrosen in #3928 - Move to Racket by @SystemFw in #3931
- Relax valid branch names in UCM to allow releases/ and releases/drafts/ by @mitchellwrosen in #3929
- Rename
project.clone
tobranch.clone
; add back differentproject.clone
by @mitchellwrosen in #3933 - Link.Term.toText: handle ability constructors by @ceedubs in #3940
- Add
release.draft
command by @mitchellwrosen in #3934 - Update pull_request_template.md by @aryairani in #3943
- racket: Add base16/32/64 encoding/decoding for chunked-bytes by @lexi-lambda in #3930
- Add zlib.compress and zlib.decompress racket primitives by @jaredly in #3932
- Disable text.term.tests, which uses TermLinks that are not yet supported by the jit by @jaredly in #3946
- release.draft output message tweak by @mitchellwrosen in #3948
- Fix branch.clone/project.clone reflog by @mitchellwrosen in #3950
- Implement encoding and decoding for Bytes, base16/32/64 and 64UrlUnpadded by @jaredly in #3944
- Make
delete.branch foo
delete branch/foo
, notfoo/main
by @mitchellwrosen in #3952 - JIT implementations for
Bytes.{gzip,zlib}.{compress,decompress}
andBytes.{to,from}Base{16,32,64,64UrlUnpadded}
by @jaredly in #3924 - Don't require leading forward slash in
switch /branch
by @mitchellwrosen in #3951 - Update LICENSE by @ceedubs in #3958
- Make
branch.clone
only take a branch by @mitchellwrosen in #3955 - project+branch parsing tweak: trailing forward slash means project by @mitchellwrosen in #3956
- improve project/branch name styling in output messages by @mitchellwrosen in #3960
- implement tab-completion for
switch
by @mitchellwrosen in #3959 - Share Project URLs use /code instead of /branches by @hojberg in #3963
- Create UI url with namespace and definition reference by @hojberg in #3724
ls
pretty print scope bug by @tstat in #3965- Try out a failure by @jaredly in #3949
- Add jit-tests and interpreter-tests to github actions by @jaredly in #3947
- Add helpers for rendering arbitrary top-level docs. by @ChrisPenner in #3969
- style project prompt color consistently by @mitchellwrosen in #3983
- Rename inscrutable function names in Push.hs by @tstat in #3985
- ensureAuthenticated early in share push flow by @tstat in #3984
- When pushing to share, print a link to view it on share by @tstat in #3987
- Remove project uuids from prompt and empty namespace output by @tstat in #3988
- Allow for jit-only and interpreter-only tests in our builtin-tests by @jaredly in #3991
- Add remaining tls primitives to racket by @jaredly in #3993
- Implement some io & clock primops in racket by @jaredly in #3996
- Cleanup clock & io racket functions by @jaredly in #3997
- Add
delete.project
command by @tstat in #3998 - add
clone
command, deleteproject.clone
andbranch.clone
by @mitchellwrosen in #3981 - Interleave more output into pull when a merge is detected. by @ChrisPenner in #4000
- Add Bifunctor and methods to Unison.Prelude by @ChrisPenner in #4003
dependents
anddependencies
are scoped and more useful now by @pchiusano in #3994- Recall most recent branch for
switch
by @tstat in #4002 - Improve project command help docs by @tstat in #4005
- Improve Debug.toText when using run.compiled by @ceedubs in #4012
- Add jit primops for Bytes.{encode,decode}Nat{16,32,64} by @jaredly in #4010
- Attempt to fix mac pre-release builds by @ceedubs in #4015
- Add a bunch of math primitives to racket by @jaredly in #4011
- Fix toNamespaceGlob on empty namespaces by @ChrisPenner in #4020
- Sql query interpolation by @mitchellwrosen in #4018
- Make "No Codebase UI" error message more helpful. by @jaredly in #4021
- building on lts-20.22 (ghc 9.2.7) by @aryairani in #4016
- Update nix flake for GCH 9.2.7 by @ceedubs in #4032
- Dynamic code loading in scheme by @dolio in #4014
- ormolu the world by @mitchellwrosen in #4035
- key haskell cache by resolver by @aryairani in #4038
- pin base version and try keying base.unison cache by file hash by @aryairani in #4028
- (ignore) by @aryairani in #4036
- replace executeFile with executeStatements, which doesn't have to be careful about semicolons by @mitchellwrosen in #4034
- ci(Mergify): configuration update by @aryairani in #4041
- pin
base.unison
atreleases.v2_0_0
by @aryairani in #4040 - Update development.markdown to mention instructions for installing ormolu by @pchiusano in #4044
- Update pull_request_template.md by @aryairani in #4045
- Add
getLine
andseekHandle
primitives to the jit by @jaredly in #4047 - Add configuration for whether to vacuum after migrating by @ChrisPenner in #4033
- Finish the move to a better SQL quasi-quoter and delete the old one by @mitchellwrosen in #4043
- Update development.markdown with better ormolu instructions by @mitchellwrosen in #4048
- add package to flake.nix to fix locales by @stew in #4051
- nix flake: remove commented out code by @ceedubs in #4053
- Fix build with cabal by @jneira in #3722
- fix bug in halting condition of loadRemoteProjectBranchGen by @tstat in #4054
- Fill out array primops, with tests by @dolio in #4055
- add "IN :param" form to sql quasi-quoter by @mitchellwrosen in #4059
- add optional project name argument to
branches
command by @mitchellwrosen in #4061 - Use explicit JSON instances rather than generically derived ones by @ChrisPenner in #4013
- add
project.rename
command by @mitchellwrosen in #4062 - fill out a few more project aliases by @mitchellwrosen in #4057
- improve
switch
autocompletion by @mitchellwrosen in #4063 - Add required queries to clean up unreachable name lookups by @ChrisPenner in #4056
- clone tweak: don't fall back on a name comparison for project by @mitchellwrosen in #4067
- Add
branch.rename
command by @mitchellwrosen in #4064 - don't make contributor branches called "main" by @mitchellwrosen in #4068
- Readonly Sqlite mode by @ChrisPenner in #4058
- Implement some pieces of code/value serialization in Scheme by @dolio in #4075
- Add
reset
command by @tstat in #4074 - Dependency-aware name lookups by @ChrisPenner in #4001
- add Bytes.indexOf and Text.indexOf builtins by @stew in #4065
- reset.output.md by @stew in #4082
- tweak parsing of pull target to be more like merge by @mitchellwrosen in #4080
- make switch autocomplete work better by @mitchellwrosen in #4089
- use breakOn instead of indices which for Text.indexOf by @stew in #4090
- Include latest release in get-project response by @ChrisPenner in #4095
- Launch ucm in last namespace the user had cd'd to by @mitchellwrosen in #4092
- Add unisonLocal.zip to .gitignore by @ceedubs in #4097
- Fix failure to find some docs by @ChrisPenner in #4094
- (issue) transcript of issue with record types and user types by @ceedubs in #4098
- Reset WAL mode after vacuumInto by @ChrisPenner in #4076
- Fuzzy find using SQLite by @ChrisPenner in #4071
- Consider empty strings in Text.indexOf by @runarorama in #4101
- make
unsafe.force-push
work when pushing to project branches, too by @mitchellwrosen in #4103 - add more documentation for project commands by @tstat in #4078
- Generate random project names with no-arg
project.create
by @mitchellwrosen in #4105 - Implement setBuffering and getBuffering in racket by @jaredly in #4111
- Add time zone builtin by @runarorama in #4118
- tweak switch tab-completion so "switch /" and "switch /@" work by @mitchellwrosen in #4121
- Add helpers for hashing v2 branches by @ChrisPenner in #4104
- Pass correct starting path to LSP by @ChrisPenner in #4126
- download latest version of base on project.create by @mitchellwrosen in #4117
- make project commands visible by @mitchellwrosen in #4122
- Add numbered args to namespace dependencies by @ChrisPenner in #4130
- Fallback to transitive dependency search when pretty-printing on Share by @ChrisPenner in #4128
- Add V2 squashing and squash-result cache by @ChrisPenner in #4110
- refactor: add export list to Unison.FileParsers and delete unused type alias by @mitchellwrosen in #4138
- Rework old startup flow by @mitchellwrosen in #4129
- add
help-topics projects
by @mitchellwrosen in #4144
New Contributors
- @gdbaldw made their first contribution in #3870
- @lexi-lambda made their first contribution in #3930
Full Changelog: release/M4i...release/M5a
Appendix: Re-creating a deleted project or branch
Suppose you've accidentally deleted a project or branch. You can still get it back using the following (somewhat kludgy) procedure. A later release of UCM will have something more streamlined for this, but for now:
- Use
reflog
andreset-root
to go back in time before the deletion. This will recreate the namespace(s) in the (hidden)__projects
namespace. The__projects
namespace has a subnamespace per project, and per branch, but they have GUIDs instead of meaningful names. A database table maps these GUIDs to project and branch names. - Use
reflog
again, thendiff.namespace 2 1
to diff the last two entries in the reflog. From the diff, note what namespace(s) were created or deleted. Suppose that was the namespace.__projects.abc_123.branches.efg_456
- Use
project.create
(orbranch.empty
) to recreate an empty project or branch, then domerge .__projects.abc_123.branches.efg_456
to bring that resurrected namespace back into your branch. - You can now optionally
namespace.delete
the namespace you got from step two, since its contents have been merged into the new branch.
Come by the Slack #troubleshooting
channel if you have any difficulties.