Skip to content
MusicStation – Home

Version history

A MusicStation project keeps a version history: named snapshots of the session that you can look at, compare and go back to. The history belongs to one project file - the engine writes it into a directory next to that file (<name>.mshproj.history/), so two projects have two histories and a version of one is never a version of the other. Saving with the preference Snapshot on save engaged, and restoring an older version, add entries to that history on their own; everything else you do here.

The history is shown by the History panel, which Project ▸ Version History and the Panels menu reveal. The shipped Recording and Mix workspaces dock the panel in their right column; every other workspace shows it when you ask for it. This chapter documents the panel and the three dialogs it opens. Nothing here is on the audio path: listing, comparing and snapshotting leave the transport alone, and the one gesture that changes the session - Restore - does exactly what Open… does, with the safety net described below.

The panel

The body of the History panel is the version timeline of the current project. Above the list sits its header: the title Version history, the New snapshot button, the Compare button and - after a command of the project surface failed - the translated sentence the engine's answer stands for, so a rejected gesture is never silent.

The list holds one row per stored version, newest first, in the order the engine reported - the list is never sorted or regrouped by the interface, and two versions that were created in the same second keep their order as well. A row shows:

  • the label of the version: the name you gave it, shown verbatim and never translated, or the translated label of a marker the engine uses for its own entries - Snapshot on save for the snapshot a save wrote and Before the restore for the copy a restore made of the state it replaced;
  • the date and time the version was created, written in the language and time zone of your machine;
  • the note you stored with it, in a second line, while it is not empty;
  • the marker automatic while the engine created the entry itself, and the marker current in the accent colour on the row the state you are looking at corresponds to.

The current marker is exact, not a guess: a row carries it while the session equals the document of that very version - after the save, open, snapshot or restore that wrote it, and never while the project is marked unsaved in the header. Edit a clip and no row is marked any more until you save or take a snapshot; the last row that was marked keeps its place, its name and its note.

Every row carries its own gestures: a press on the row picks it for a comparison, and the three buttons under it open a rename, a delete or a restore of exactly that version. The list itself is read-only data; the interface never invents an entry, never removes one and never re-sorts the list.

Instead of the list the panel shows a sentence when there is nothing to list:

  • There is no connection to the engine. while the interface is not connected to the engine - the version list is engine state like every other value, so it is not cached;
  • No project is open. Save or open a project to keep its version history. while the session has no file yet. Every command of this chapter needs a project: without a path to save into, the engine cannot keep a history;
  • This project has no stored versions yet. while the file exists but has no entries - a perfectly normal state for a project that was never saved with the preference on and never snapshotted.

The engine keeps at most 200 versions per project. When a new one pushes the list past that bound, it prunes older entries on its own, and it prunes its own automatic snapshots first, before the versions you created and named - so a long series of saves does not eat your checkpoints. Pruning needs no gesture and has no control: the list simply never grows past the bound.

Writes are disabled while the interface is not connected, while the session has no project and while an apply - an Open… or a Restore - has not settled: the buttons are shown but do not act, because the engine refuses those commands during a half-applied document. Reading is not affected: the list is refreshed when the panel appears and whenever the connection or the project changes, and a save or an open lists it as well.

New snapshot

New snapshot in the panel header stores the state you are looking at as a named version of the project. It opens the dialog New snapshot with two fields:

  • Name - the label of the version, 1 to 120 characters. It is user data and is shown exactly as you typed it, in every language.
  • Note - what this version is about, 0 to 2000 characters. It appears as the second line of the row and is never translated either.

Create stores the version; the button stays disabled while one of the two values is invalid - in practice until the name field is filled, because the name field itself stops at its bound and only a pasted note can grow too long - and Enter in the name field submits the form as well. The draft is checked while you type: Please enter a name. for an empty field, The name may be at most 120 characters long. and The note may be at most 2000 characters long. while the corresponding text is too long - the field itself stops at its bound, so the note is the one that can reach it by pasting. A draft that cannot be sent changes nothing.

Cancel, Escape and a click on the dimmed area around the dialog close it without storing anything. A stored snapshot appears at the top of the list at once. It carries the current marker while the project is not marked unsaved in the header: the state it holds is the state you are looking at, but taking a snapshot does not write the project file, so a session with unsaved changes keeps the marker off until you save. Its name may repeat the name of another version - two rows may carry the same label, and the date, the note and the markers tell them apart - and it is a named version, not an automatic one, so nothing may prune it before your automatic snapshots.

Taking a snapshot is the safe way to mark a point you may want to come back to. The engine does not record one on its own: the automatic Snapshot on save entry appears only while the preference Snapshot on save is engaged and you save. It stands for a save that really happened: a save the engine refuses writes nothing and records no snapshot either (see Save), so a failed save leaves the list as it was.

Rename

Rename under the row of a version opens the dialog Rename version with both fields filled in with what the version carries. Correct the Name and the Note - the same bounds and the same hints as New snapshot - and press Rename or Enter in the name field to write them. The row, the diff of a later comparison and the question of a Delete or Restore then name the version the new way.

Renaming an automatic version is allowed and replaces its translated marker with your text: the row is still marked automatic, but its label is the name you typed from then on. Replacing the marker does not change what the version contains - a renamed save-time snapshot is still the document that save wrote. Cancel, Escape and a click outside the dialog leave the version as it was.

A failed rename is reported in the panel header and changes nothing; a version that was deleted in the meantime is answered as no longer existing, which that same line says.

Delete

Delete under the row of a version removes that version. It asks first: the dialog Delete version names the row - Delete “{name}”? This cannot be undone. - and offers Delete and Cancel. Only Delete removes the version, together with the document the engine stored for it. Cancel, Escape and a click outside the dialog drop the question.

Deleting cannot be undone, and deleting is not the same as going back: the session you are looking at is not touched at all. The only visible consequence beyond the row is the current marker - a version that carried it is gone, so no row is marked any more until the session matches another stored document again. The engine prunes its own entries when the list grows past its bound, so deleting is for the entries you want out of the way now.

Restore

Restore under the row of a version makes the document of that version the session again, and it is non-destructive: the state you are looking at is not lost. It asks first - the dialog Restore version says Restore “{name}”? The current state is kept as a new version, so nothing is lost. - and offers Restore and Cancel.

Restore carries out two steps, and the engine does both:

  1. it records the state before the restore as a new automatic version, labelled Before the restore and derived from the version you picked, so the way back is already in the list;
  2. it applies the stored document by exactly the rule Open… applies to a file - the same rule in both chapters, never two: the engine first asks for the size of every distinct source file the document references, and for nothing else (no sample is read, no file is hashed). Then every slot the grid holds is replaced by the slots of the document: a slot the document does not list is cleared - a clip that is sounding stops, without a fade. A slot whose file is unchanged - the same path and the same size the engine last read it at - keeps the clip it has, and its file is not read again. A slot whose file changed size is cleared and decoded again with the bounds of a clip load. A slot whose file is gone cannot be read at all: it is cleared, reported as a failed load, and the loader is never asked for it - the rest of the project is applied, the answer is still an acknowledgement, and the project counts as unsaved afterwards, because the session then differs from the document it was given.

Because only the size is ever asked for, a source file that was replaced by another file of exactly the same size counts as unchanged - that is the price of not reading every source on every apply.

The gesture is answered once the apply settled - on a project whose files changed that may take a moment - and the answer names the version step 1 created. Until then the session keeps the state you see; while the apply runs, the write commands of the project are refused (the panel shows their buttons as disabled), and comparing two versions still works. Afterwards the restored rows carry the current marker: the state is the one the version holds, and Before the restore is the copy of what you left.

Cancel, Escape and a click outside the dialog change nothing at all - not even a version.

Compare

Compare shows what changed between two versions. Both halves of the gesture live in the panel:

  • Picking - a press on the row of a version picks it (the row is a latched button: press it again to drop it). The panel keeps the last two picks, so picking a third row replaces the older of the two; every pick is announced with the label of the version, its date, whether it is automatic or current, and its note.
  • Comparing - the Compare button in the panel header is enabled exactly while two rows are picked and the interface is connected to the engine; it opens the comparison. The older pick is the before side, so every row of the result reads as the change the newer version brought. Two versions of the same second keep the engine's order, and that order decides which of them counts as the newer one.

Comparing only reads the two stored documents, so it works while an apply is in flight and it changes nothing: neither the session nor the version list. What it reads is exactly what a project file holds and nothing else - the clips with their source files, the tempo, the launch quantisation and the track colours; mixer values and plugin state are no part of a project yet, so they are never compared (see The comparison). A comparison that the engine refuses - a row that was deleted in the meantime, for instance - shows its translated reason in the panel header, and the picked rows stay picked. The picks are interface state and are not stored anywhere; a row that is no longer in the list drops out of the pair instead of being compared as a stale version.

The comparison

The Compare versions dialog shows the change from the older version to the newer one. The line at the top names the two sides as {from} → {to}, and under it every difference sits in one table grouped by what it touches - Clips, Tempo, Quantisation and Track colours. Each table has four columns: Slot (the grid address a row belongs to, empty for the two document-wide kinds), Property, Before and After.

Only what really differs is listed: a property that is equal in both versions never appears, and a slot that holds a clip in one version and none in the other gets the single Clip row instead of three rows about that clip. The names of the properties this build knows are Clip, Source file, File size and Loop for clips, Tempo for the tempo, Quantisation for the launch quantisation and Track colour for a track's colour. The two sides are shown as the interface reads values everywhere else - numbers in the language of the interface, Yes/No for the loop flag, not set for a value that does not exist on that side, and a source file as its base name, because the full path only means something on the machine the engine runs on. A kind or a property this build does not know keeps its technical name instead of disappearing.

What a comparison covers is exactly what a project file holds: the clips with their source files (the path and the file size), the tempo, the launch quantisation and the track colours - the four tables above and nothing else. Mixer values and plugin state are not part of a project document yet, so they never appear in a comparison, however far they differ; they arrive with their own project format version. Two sessions that differ only in a mixer or plugin value therefore compare as equal.

Two versions that hold the same document have no differences, and the dialog says so: The two versions have no differences. It is the answer for a comparison of two saves that changed nothing - changing only device sample rate or a value the format deliberately ignores leaves no difference, and that is by design. Close, Escape and a click on the dimmed area put the comparison away; the answer is not stored, it belongs to the two versions you picked.

A comparison never touches the session: no clip is loaded or stopped, no tempo is set and nothing is sent to the engine beyond the one read command.

Close

Close is the control that puts a dialog of this chapter away, and it is the same one in all of them: the Close button of the comparison, the Cancel button of the two confirmations and of the snapshot and rename form. Escape and a click on the dimmed area around the dialog do the same in every one of them.

Closing a dialog is not an undo. Everything you confirmed in it - a stored snapshot, a rename, a deletion, a restore - reached the engine when you confirmed it; only a question that was still waiting for an answer (a Delete or Restore confirmation, a draft in the snapshot form) is dropped.

Workflow: keep a checkpoint before a risky change

  1. Reveal the History panel - with Project ▸ Version History or with an entry of the Panels menu.
  2. Press New snapshot, type a name such as Before the mix and a note you will still understand in a week, and press Create.
  3. Work on: the row stays in the list and is marked as current as long as the session matches it and the project is not marked unsaved - the first edit moves the session away from it, and the marker goes out.
  4. If you want to go back, press Restore under that row and confirm - the state you are leaving stays in the list as Before the restore.
  5. Make it a habit while the preference Snapshot on save is engaged: every save that goes through adds its own Snapshot on save entry, so your named checkpoints stand out in the list. A save the engine refuses adds none (see Save).

Workflow: find out what changed between two saves

  1. Save the project (see Save) - with the preference on, each save leaves one entry in the version history.
  2. Press the row of the older of the two versions and then the row of the newer one; both rows are marked, and the older pick is the before side.
  3. Press Compare. The comparison lists every changed clip, the tempo, the quantisation and the track colours.
  4. Press Close to return to the list. The picks stay, so you can compare the same pair with another version by picking a third row.

Remote

The iPad remote has no version history: it neither lists, snapshots, compares nor restores versions, and it has no project surface of its own (see iPad remote). The history belongs to the project file on the engine machine, and a restore carried out on the desktop is simply the session the remote sees afterwards - its grid follows the session state like after any other apply.