Project workflows

Table of contents


Create a new project

To create a new project, use theproject.createcommand at the root of your codebase.

.> project.create myProject

This will create a new, empty project with the name,myProjectwith amainbranch inside of it as a default. Your console will look something like this:

myProject/main>
🪅
Fun fact: theproject.createcommand optionally accepts zero arguments, in which case the UCM will create a random project name for you!

See also:

Create a project from an existing library with releases

If your existing namespace is a mature library withmain,latest,andreleasesnamespaces, you'll will...

  1. merge themainsubnamespace into into themainbranch of the project
  2. Create a branch called/latestwith thebranchcommand and merge thelatestnamespace into it
  3. Each release is a branch with the special form/releases/releaseVersion.Each of the released version namespaces are merged into their respective branches.

Create a project from an existing namespace

Say you have simple un-versioned namespace that you want to turn into a project. First, create a new project with theproject.createcommand.

.> project.create myProject

Then, merge the namespace into the project with themergecommand.

myProject/main> merge .myExternalNamespace
You cannotforka namespace from outside of a project into a project. You must use themergecommand.

See also:

List all projects in your codebase

To list all projects in your codebase, use theprojectscommand.

.> projects

Renaming a project

To rename a project, use therename.projectcommand from within the project you're trying to rename.

myProject/main> rename.project myNewProject
myNewProject/main>

Renaming a branch

Renaming a branch follows the same pattern

myProject/feature1> rename.branch myNewBranch
myProject/myNewBranch>

Switch between branches or projects

Theswitchcommand is used to change between branches or projects.

Both of these commands will switch to the defaultmainbranch of theotherProject.The absence of a slash preceding the argument toswitchmeans that the UCM will look for aprojectto switch to.

myProject/aBranch> switch otherProject
myProject/aBranch> switch otherProject/main

Switching to a contributor branch of another project contains the contributor's Unison Share handle in the branch name.

myProject/aBranch> switch otherProject/@contributor/contributorsWork

To switch to a branch within thesameproject, omit the project name, leaving slash and the branch name to indicate that the argument is a branch. The slash can help distinguish a branch name from a project name when there is a project with the same name as a branch.

myProject/aBranch> switch /anotherBranch
myProject/aBranch> switch anotherBranch

Create branches

To create a new branch, use thebranchcommand with one or two arguments. You might create branches to work on a new feature in one of your own projects, or to contribute to a project that you've cloned. Branches have a parent-child relationship, so the new branch will be a child of the current branch.

Branch arguments are optionally preceded by a slash to disambiguate them from other codebase entities. This creates a copy of themainbranch inaNewBranchand switches to it.

myProject/main> branch /aNewBranch

You might also see branch arguments prefixed by the contributor's Unison Share handle.

myProject/main> branch /@contributor/aNewBranch

You cannot otherwise have multiple slashes in a branch name.

myProject/main> branch /myNewBranch
@unison/base/main> branch /myNewFeature

It is also possible to create a branch with two arguments. The first is the source, or parent branch, and the second is the new branch being created.

myProject/main> branch /srcBranch /destBranch

List the local branches of a project

To view the branches of a project, use thebranchescommand.

myProject/main> branches

This shows the local branches and theirremote mappings(if any) on Unison Share.

Currently you cannot view the remote cloned instances of your project.

Delete a project or a branch

To delete a project use thedelete.projectcommand. This will delete the project from your local codebase.

myProject/main> delete.project myProject
.>

Deleting a branch can be done with thedelete.branchcommand. This will delete the branch from your local codebase.

myProject/main> delete.branch /myBranch

Deleting a project from Unison Share

You can delete a project fromUnison Shareby heading to your project's settings page.

👉
Deleting a project from Unison Share cannot be reversed.

Pull a project or branch from Unison Share as a library

pullis used to include a project in your local codebase for use as alibrary.If you want to contribute to a project, or merge another contributors' branch into your project, usecloneinstead. For the time being, you'll still usepullfor projects you want to put in yourlibdirectory.

.> pull @unison/base/latest lib.base

Clone a project from Unison Share

Cloning is used to download a project or branch for contributing to it. (To install a project dependency, use thepullcommand.) Unlike with Git workflows, where you clone a project and can download all the project's branches (stale or otherwise,) in Unison you clone specific branches of a project.

To clone a project from Unison Share, use theclonecommand. The first path segment is the user's Unison Share handle and the second is the name of the project.

.> clone @unison/projectName

Unless otherwise specified, the cloned project will only include themainbranch.

Clone a branch of a project from Unison Share

If you want to clone a branch other thanmain,use the sameclonecommand but include the branch name after the project name.

.> clone @unison/projectName/branch

If you already have the project locally, but wish to clone an additional branch from the remote repository, you can leave off the project name prefix.

@unison/base/main> clone /releases/2.0.0

Branches may also include a path segment for the contributor's Unison Share handle, indicating that the branch is acontributor branch.

.> clone @unison/projectName/@contributor/branch
Cloning is for contributing to a project. If you want to use a project as a dependency, seepulling a project

Push a project or branch to Unison Share

To push a project or branch to Unison Share, use thepushcommand.

Pushing a project to Unison Share automatically establishes a remote mapping between your local project and the project on Unison Share. We can even runpushwith no arguments on a project that we own.

myProject/main> push

Pushing to https://share.unison-lang.org/@myuser/myproj/branches/main...

You can also push a specific branch to Unison Share. The following command will pushsomeOtherBranchto themainbranch of the project.

myProject/main> push @myUser/myProject/main /someOtherBranch

You can stillpusha namespace to yourpublicnamespace in Unison Share, but if you push a project to Unison Share, it will get special UI treatment and functionality, like branch based browsing and versioning.

Merges for projects

Themergecommand is used to combine branch contents or namespace contents. You mightmergea namespace into a branch as a part of moving your code into a project, or you mightmergetwo branches together as part of a pull request. The existing ability tomergetwo namespaces together is still supported as well. Let's look at each of these cases.

Merging a namespace into a branch

From within the project, you can merge a fully qualified namespace into the current branch, by calling merge with one argument, or specify a target branch with the optional second argument tomerge.

myProject/main> merge .feature.from.namespace
myProject/main> merge .feature.from.namespace /featureBranch

Merging two branches together

Merging two branches together looks very similar. To help disambiguate a branch from a namespace, branches can be prefixed with a slash,/.

myProject/main> merge /featureBranch
myProject/main> merge /featureBranch /featureBranch2

If you're reviewing a pull request, the contributor will have created a branch for their work. Their branch will start with their user handle from Unison Share.

myProject/main> merge /@contributor/featureBranch
myProject/main> merge /@contributor/featureBranch /featureBranch2

You can also merge a different project's branch into your project's current branch by supplying the full project name as an argument.

myProject/main> merge @unison/differentProject/featureBranch

Publishing a release of a project

Releases are like immutable snapshots of a given branch. They do not contain the history of the project so other libraries can depend upon them without using additional space in their codebase.

There are two ways to create a release of a project, one is directly from themainbranch using the Unison Share UI, and the other is using therelease.draftcommand.

Creating a release from the Unison Share UI

If you are intending to create a release using only the Unison Share UI and you'd like to associate release notes with the new version, make sure yourReleaseNotesdocument term is up to date with the latest changes to your library. Pushmainup to Unison Share and head to the "releases" tab for the project.

Image of the releases page with a "cut a release" button at the top.

Click the "Cut a release" button to open the release version modal.

You'll have some options for how to version the next release. Increment your release by one major, minor, or patch version.

Image of the release version modal.

Hit publish and Unison Share will create a new release for you! The release process will squash the unneeded codebase history when it creates the release, so users of your library will have a compact version to depend on.

Creating a release draft in the UCM

You can create a release from any branch of a project, but it's common to create a release from themainbranch in the UCM. To start a release, use therelease.draftcommand and enter the version number of the release you want to create.

myProject/main> release.draft 1.0.0

This will create a new branch called/releases/drafts/1.0.0.

You may want toadda Doc term called "ReleaseNotes" to this branch at this point to describe the changes in this version. Upon publication, if Unison Share finds a term called "ReleaseNotes" in a release branch, it will display the notes for others to benefit from.

ReleaseNotes = {{

  * Added function {List.map}
  * Updated function {List.filter}
  ...

}}

After you're done adding the release notes,pushthe branch to Unison Share and head to the project url given in the console.

myProject/releases/drafts/1.0.0> push

The "releases" tab for the project has a special section for "draft" releases at the top if a branch matching the release draft naming conventions is found. Click publish for the release draft in question to open up a modal for confirming the desired version. Otherwise you can use the "cut a release" button found in the "releases" page to make a release at any time.

Image of the releases page with a draft release at the top.

Unison Share supports semantic versioning for releases, so pick one of the options given in the modal.

Image of the release version modal.

When you're ready, hit "Publish" and Unison Share will add your new version to the list of releases for a project.

How to update a dependency

This doc walks through the process of updating a dependency which has been released as aUnison project.The following workflow uses Unison's standard library,base,as an example.

Suggested workflow summary:

    • (Optionally) create a newbranchfor the update process so that you can easily revert if something goes wrong
      • myProject/main> branch myProject/upgradeBase
    • pullthe latest version of the dependency into your codebase so that it is a sibling of your current library version.
      • myProject/upgradeBase> pull @unison/base/releases/X.Y.Z lib.newBase
    • Apply thepatchfrom the new version of the library to the project
      • patch lib.newBase.patch
    • Check if there aretodoitems in your project as a result of applying the patch
      • myProject/upgradeBase> todo
    • Delete the old version of base from your codebase.
      • myProject/upgradeBase> delete.namespace lib.base
    • Rename the new version of base tobase
      • myProject/upgradeBase> move.namespace lib.newBase lib.base

First,pullthe new version of the library into thelibnamespace of your project. It shouldnotbe pulled into the same namespace as your existing library version. Instead, give the new version a distinct name, likebaseV2ornewBase.We can change the name later. The exact version number of library you want to install can be found by visiting the project's home page onUnison Share.Click the big green button called "Use Project" to get a copy of the command to run.

myProject/upgradeBase> pull @unison/base/releases/X.Y.Z lib.newBase

Then apply the the patch from the new library version to the project. Assuming your UCM console is located at the top of your project, you can use the patch command like so:

myProject/upgradeBase> patch lib.newBase.patch

Patches map old term references to new references in a namespace; they're part of what helps Unison automatically propagate changes when functions get updated. Patch entries are created automatically when the library author runsupdate.

Next you should check if there aretodoitems in your project as a result of applying the patch. At the root of your project, runtodo:

myProject/upgradeBase> todo

Todo items can happen if a function in your project depends on a function in the library whose type signature has changed in the new version. If there aretodoitems after applying the patch, the UCM should supply a suggested order to tackle them in. You'll want to edit the terms into a scratch file, resolve the conflicts and thenupdatethe terms.

Once there are notodoitems it's safe to delete the old library version from thelibnamespace of the project. You may want to rename your new library version tobaseagain so that it's easier to refer to in the future.

myProject/upgradeBase> delete.namespace lib.base
myProject/upgradeBase> rename.namespace lib.newBase lib.base

Finally, merge theupgradeBasebranch intomainand delete your upgrade branch.

myProject/upgradeBase> merge /upgradeBase /main
myProject/upgradeBase> delete.branch /upgradeBase

It's done! Your project is now using the latest version of the dependency!

Reviewing a PR

Full support for pull requests, comments, and code reviews is forthcoming for Unison Share, but you can still accept contributions from other community members using a branches. Once a contributor has created acontributor branchand pushed it to Unison Share, you'll need to clone the branch locally to review and merge it in.

myProject/main> clone /@contributor/featureBranch
myProject/@contributor/featureBranch>

You can use themerge.previewcommand to see what changes will be made to the project if you merge in the contributor's branch.

myProject/@contributor/featureBranch> merge.preview /@contributor/featureBranch /main

If you're happy with the changes, you can merge the contributor's branch into your project'smainbranch.

myProject/@contributor/featureBranch> merge /@contributor/featureBranch /main

Finally, push your changes to Unison Share to make them available to others, orcreate a release!

Deleting a remote branch from Unison Share

Deleting a remote branch from Unison Share can only be done via the Unison Share UI. Head to the project's home page and click on the drop-down menu where the current branch name is displayed. You'll see a short list of all the remote branches for the project. At the bottom of the drop down menu head to "View all branches" and from there you can delete your desired branch. You cannot delete branches that you do not own.