Changeset Files Are Read-Only: Editing, Renaming, and Deleting Changesets

Sepasoft MES Module Suite

Editing, Renaming, and Deleting Changesets

Warning Changeset Files Are Read-Only once its changeset has been committed in MES.

Treat a changeset file as read-only once its changeset has been committed in MES. Do not edit, rename, move, or delete it, in the changeset folder or in your Git repository.

This page is for system integrators and engineers who keep MES changesets in Git or another version control system. It explains why the files must stay as the gateway wrote them, what goes wrong if they change, and how to recover.

If you need to change or undo something, make a new changeset in MES. Never change an old file.

Why changeset files must not change

The gateway relies on three things about each file, and each mistake breaks one of them.

  1. The file name and folders are the changeset's identity. Each file is named after its changeset ID and stored two folder levels deep, built from the start of that ID. For example, changeset 123e4567-e89b-12d3-a456-426614174000 is stored at 12/3e/4567e89b12d3a456426614174000.json. The gateway finds a changeset only by that path, and checks that the ID inside the file matches it.

  2. The content is sealed when the changeset is committed. Committing stores a fingerprint of the changeset's object changes inside the file. Every time the gateway reads the file, it recalculates the fingerprint and rejects the file if they differ.

  3. Changesets form a chain. Each committed changeset records the changeset it was applied on top of. Gateways use that chain to apply changesets in the right order. A missing link stops everything after it.

A gateway updates its own copy of a file after applying it, to record when and by whom it was applied. That is expected. It is the only change to a committed file that should ever happen, and only the gateway should make it.

What happens if a file is changed

Every mistake below is worst on a new gateway that builds its MES configuration from the repository at startup. One bad file stops the gateway from starting.

What was done to the file

What the gateway does

Effect on a running gateway

Effect on a new gateway starting from the repository

Edited a value in the object changes

Fails the content check and rejects the file

That changeset and every one after it cannot be applied

Startup stops

Edited the description, note, or applied details

May not be detected

Can apply changesets in the wrong order, or mislead reviewers

Can fail or apply in the wrong order

Renamed or moved to a name that is not a changeset ID

Ignores the file. The changeset counts as missing

Same as deleting it

Same as deleting it

Renamed or moved to another changeset ID's path

Reports an ID mismatch and rejects the file. The original counts as missing

Same as deleting it

Startup stops

Deleted a changeset this gateway already applied

Reports a missing applied changeset. Its record is kept

Errors every time changesets are checked

Startup stops

Deleted a changeset this gateway has not applied yet

Drops it without an error

Every later changeset that depends on it is blocked

Startup stops

Git merges never cause these problems on their own. Each changeset is its own file, so two people's changesets never touch the same file.

Symptoms and log messages

If changesets stop applying, or a gateway will not finish starting after you pulled from Git, search the gateway logs for these messages. Each one names the changeset ID to look at.

Log message contains

Likely cause

Changesets bootstrap failed; aborting startup

A new gateway hit one of the errors below while building from the repository. The gateway also shows a restart-required notice

Integrity check failed. Expected SHA-256 … computed …

The file's object changes were edited

UUID mismatch for file … vs JSON …

The file was renamed or moved to another changeset's path, or copied over another file

Applied closed changeset missing from disk

A changeset this gateway already applied was deleted, renamed, or moved

Missing dependency …

A changeset earlier in the chain is missing or was rejected

Invalid JSON for …

The file was damaged, for example by a bad merge, a partial copy, or a manual edit

To find the file for a changeset ID, remove the dashes. The first two characters are the first folder, the next two are the second folder, and the rest is the file name.

How to recover

To fix any of these problems, put the original file back at its original path. Do not try to repair the file by hand.

  1. Pause configuration changes on the affected gateways until the chain is whole again.

  2. Find the changeset ID in the log message and work out its file path (see above).

  3. Get the original file back.

    • From Git: find the commit that added it with git log --diff-filter=A -- <path>, then restore it with git restore --source=<commit> -- <path>. If it was renamed or moved, move it back to its original path.

    • From another gateway: any gateway that applied the changeset has its own copy in its changeset folder. Copy that file to the same path. Its applied details belong to that gateway, which is fine.

  4. Commit and push the restored file, so nobody else pulls the broken version.

  5. Pull on every affected gateway, then retry.

    • Running gateway: apply the pulled changesets again.

    • New gateway that stopped during startup: restart it. Startup checks every file before applying any, so the MES database is still empty and the next start runs the full build again.

If no copy of the original file exists in Git or on any gateway, contact Sepasoft Support before making more changes. Include the log messages and the changeset ID.

How to undo or fix a change correctly

To undo or correct a committed changeset, make a new changeset in MES that reverses or fixes it, then commits it and adds its new file to Git. The history keeps both: what was changed, and how it was put right.


You want to…

Do this

Not this

Undo a change

Make a new changeset that sets the values back

Delete or edit the old file

Fix a wrong value

Make a new changeset with the correct value

Edit the value in the file

Reword a description

Use the Git commit message or pull request to explain it

Edit the description in the file

Drop work that was never committed

Cancel the open changeset in MES

Delete its file

Tidy up the folder

Leave the layout as the gateway wrote it

Rename, regroup, or move files

Safe things to do in Git: add new changeset files, commit, push, pull, merge, and branch. You can also discard a gateway's own applied-details changes to files it pulled. Unsafe: anything that changes, renames, or removes a file that is already on the main branch.

Committing a changeset also applies it on the gateway where it was made. So a changeset becomes part of that gateway's history as soon as it is committed, even if its Git branch is never merged. Do not discard a branch that holds committed changesets. Merge it and reverse the changes with a new changeset instead.

Preventing mistakes

The most reliable protection is to have Git refuse any commit that changes or removes an existing changeset file.

  • Add a pre-commit hook to the repository. The example below assumes the changeset files live in a changesets/ folder at the root of the repository. It rejects open (uncommitted) changesets and any change to, or deletion of, an existing changeset file. Save it as .githooks/pre-commit, then run git config core.hooksPath .githooks in each clone.

  • Protect the main branch in your Git server. Require a pull request, and have reviewers reject any pull request that shows changeset files as modified, renamed, or deleted. Only new files are expected.

  • Keep line endings as written. On Windows, add changesets/** -text to .gitattributes. That stops Git from showing every file as changed.

  • Do not open changeset files in an editor that formats on save.

  • Give every gateway its own clone. Never point two gateways at one shared folder.

  • Do not make files read-only. The gateway must be able to record applied details in its own copy.

Code
#!/bin/sh
# Reject open changesets and any change to an existing changeset file.
fail=0

for f in $(git diff --cached --name-only --diff-filter=A -- 'changesets/*.json'); do
	if git show ":$f" | grep -q '"state": *"OPEN"'; then
		echo "pre-commit: $f is an open changeset. Commit it in MES first."
		fail=1
	fi
done

for f in $(git diff --cached --name-only --diff-filter=MDR -- 'changesets/*.json'); do
	echo "pre-commit: $f is an existing changeset and must not be changed, renamed, or deleted."
	echo "            To discard the change: git restore --staged --worktree \"$f\""
	fail=1
done

exit $fail


Sepasoft MES Module Suite