Is the program in the PLC the one you approved? Version control for automation code on a GMP site
Monday morning on a liquid filling line. The capping station has been rejecting fewer vials than usual since the weekend, and the process engineer wants to look at the torque check. On the department share she finds four candidates: the integrator’s original, a folder marked final, one marked final2 and a zip from last spring. She takes the newest, goes online with the controller and asks the engineering software to compare.
The comparison is not clean. A debounce timer on the torque check has been lengthened, and the rung that latches a reject has a new contact in it. Two phone calls later the story is clear: on Saturday night a sensor kept tripping, the line kept stopping, and a technician who knows the machine well made an online edit so the batch could finish. A reasonable fix by a competent person. It also never existed on paper, and for three days the line ran logic that nobody had reviewed, tested or approved.
The vendor feature that prompted this article asks the same question: is the code in the controller the code you think it is? Our answer: the tool matters less than the comparison, and a repository is only as good as the rules around it.
The questions an investigator will ask
When a deviation touches automated equipment, the questions about the program come in a predictable order. Which version was approved for this line, and where is it kept? Is it the one running now, and was it running during the batch? What changed since the last release, who changed it, and why? Did a second person look before it reached the controller? And the one people forget: if the CPU died tonight, could you rebuild it from what you hold, with software that still opens the file?
A site that answers all five in an hour has version control, whatever its tooling. A site that needs two days and a call to the integrator does not, even with a server full of repositories.
What the GMP texts already ask
No GMP text says “use version control software”. They ask for something harder: that every change is controlled and that the record shows it.
EU GMP Annex 11, in the 2011 text inspectors apply today, says in §10: “Any changes to a computerised system including system configurations should only be made in a controlled manner in accordance with a defined procedure.” §7.2 asks for regular back-ups whose restore is checked, and §11 puts “upgrade history” into the periodic evaluation. On a filling line, the PLC program is not a detail of the computerised system. It is most of it.
In the US, 21 CFR 211.68(b) requires controls “to assure that changes in master production and control records or other records are instituted only by authorized personnel”, and Part 11, at §11.10(k)(2), asks for “revision and change control procedures to maintain an audit trail that documents time-sequenced development and modification of systems documentation.”
The PIC/S guide PI 011-3 is older but more precise. It defines configuration management as “the process of identifying and defining the configuration items in a system, controlling the release and change of these items throughout the system life cycle, recording and reporting the status of configuration items and change requests, and verifying the completeness and correctness of configuration items.” Read slowly, that is a release process for PLC code. Its category table adds: “Manage any custom (bespoke) programming as Category 5.” The logic written for your machine is exactly that.
Annex 11 is being rewritten. A much longer draft was out for consultation from 7 July to 7 October 2025; at the time of writing, the Commission’s EudraLex Volume 4 page still lists the January 2011 revision as the text in force. Two lines of the draft are worth reading now. §14.2: “Undocumented (unapproved) changes should be effectively identified, e.g. by means of configuration auditing.” And §12.3: “it should not be possible for any user to edit audit trail data.” Keep the second one in mind when we get to Git.
| Text | What it asks | What it means for automation code |
|---|---|---|
| Annex 11 (2011) §10 | Changes controlled, to a defined procedure | Every download to a GMP controller traces back to an approved change |
| Annex 11 (2011) §7.2 | Back-ups, restore checked | The release, and the means to open it, can be restored |
| 21 CFR 211.68(b) | Changes only by authorised personnel | Write access to controllers and to released code is limited and named |
| 21 CFR 11.10(k)(2) | Time-sequenced record of changes | Releases can be shown in order, with reasons |
| PIC/S PI 011-3 | Identify, release, record, verify configuration items | Logic, HMI, drive parameters and firmware are listed and controlled |
| Annex 11 draft (2025) §14.2 | Find undocumented changes | Compare what runs with what was released |
Why the shared folder fails on a plant
The archive folder is what people do when the software offers Save As and the project offers a deadline. It fails for reasons that have little to do with discipline.
- The controller is the master copy whether you like it or not. Most PLCs accept online edits, and on a stopped line at night that is the fastest way back to production. The folder learns about it only if someone uploads and files the result.
- Copies multiply with people. The integrator keeps the SAT version, the maintenance engineer a laptop copy, validation a printout in the OQ report. Each is true for a different date.
- Names carry the history. A suffix such as final2 says that something changed, never what or why.
- The engineering software moves on. A project saved with one release may not open, or may silently convert, in the next. As a backup is a hypothesis explains, a file without the environment that opens it is not a backup.

What a Git repository gives you, and what it does not
Git was written in 2005 for the Linux kernel and has become the default way software teams keep code. Each commit records content, author, time and a message, and every object is named by a hash of its content, so a stored version cannot be altered without its identifier changing. Branches keep work in progress away from the released code. After years of folders, the gain in clarity is large. An inspector reads a repository differently from a developer, though, and four limits matter.
- The author is whoever the computer says it is. Git takes the name and email from the user’s own configuration. Unless the server ties each push to a named, authenticated account and logs it, the author field is a declaration, not an attribution.
- History can be rewritten. The git push documentation says of the force option: “It can cause the remote repository to lose commits; use it with care.” Unreferenced commits are then pruned: by default git gc removes unreachable objects older than two weeks. Hosting platforms can block force pushes and require an approving review before a merge; GitHub’s branch protection rules disable force pushes by default. Someone still has to set the rule on the right branch, and check it.
- The hash is strong, not magic. Git still names objects with SHA-1 by default. A practical SHA-1 collision was shown on 23 February 2017; Git has used a hardened SHA-1 by default since version 2.13, and its transition document still calls SHA-1 weak and plans the move to SHA-256. On a plant, access rules around the server matter far more than the algorithm.
- Git sees that a file changed, not which rung. Ladder and function block diagrams, the graphical languages of IEC 61131-3, usually live in binary or vendor-specific project files. Git shows that the file differs and who committed it. Showing the reviewer what changed in the logic needs the vendor’s compare function, a text export, or a tool built for the purpose.
A governed repository is therefore a good configuration management record. It is not, on its own, an audit trail in the sense of 21 CFR 11.10(e), which asks for “secure, computer-generated, time-stamped audit trails to independently record” operator actions. The change record, the server’s access log and the protection settings together get close. The commit message alone does not.
| Which version is approved? | Newest name, by convention | Tip of the main branch | Tagged release linked to a change record |
|---|---|---|---|
| Who changed it? | File owner, at best | Self-declared name | Named account, push logged |
| Why? | Someone’s memory | Commit message, if written | Change record number required |
| Was it reviewed? | Not visible | Not enforced | Approving review before merge |
| Can history be lost? | Overwrite, delete | Force push, pruning | Force push and deletion blocked, server backed up |
| Does it match the PLC? | Unknown | Unknown | Unknown until you compare |
The real control: compare what runs with what was released
Look at the last row again. None of those columns tells you what the controller is doing. Anyone with the engineering software, a network path and the password, if there is one, can change the program in the CPU. The only evidence that the line runs the released code is a comparison between the two, made by someone other than the last person to change it.
That comparison is what the Annex 11 draft calls configuration auditing, and it costs little. Some sites script a scheduled upload and compare it with the release; others compare by hand during the periodic review. What matters is that it happens on a schedule, after every intervention and before a campaign on an idle line, and that a difference opens a record rather than a quiet re-download.

The online edit from our opening scene still has a place. Plants stop at night and people fix them. An emergency route that allows the edit, demands an upload and a record the same night, and sends the change through review and release afterwards beats a ban that is ignored at 3 a.m. How such a change meets requalification is covered in when does a repair become a requalification.
Qualifying the repository, proportionately
A repository holding GMP code is a computerised system too, and someone will ask how it was qualified. ISPE’s GAMP 5 second edition (July 2022) and Annex 11 both start from risk: test what could harm the record, not every menu. Here that is a short list. Personal, named accounts. A protected release branch with force push and deletion blocked and a review required. Tags that cannot be moved. A server that is backed up and has been restored once. Retention as long as the equipment lives. And a written answer for the night the server is unreachable. A vendor’s change management server or a well-kept folder with a register is judged against the same five questions.
Where to start
- Compare one critical line this week. Take the copy everybody calls the reference and compare it with every controller and HMI on the line.
- List the configuration items per line: PLC and safety PLC logic, HMI projects, drive parameters, robot programs, firmware versions, each with an owner.
- Decide where the release lives and who may write there: one place, named accounts, a second person to release.
- Link every release to a change record, both ways: record number in the commit or register, release tag in the change record.
- Put the comparison into the periodic review and the restart checklist.
- Keep the means to open the code: the engineering software release, its licence and, where possible, a virtual machine image of the engineering station.
Five common mistakes
- Treating the repository as the truth. It holds what was committed; the controller holds what runs.
- Leaving the server on default settings. Without branch protection, named accounts and a review rule, it proves less than its users think.
- Forbidding online edits on paper. The rule breaks on the first night the line stops. Write the emergency route instead.
- Forgetting the integrator’s copy. After the SAT the supplier often holds a newer version than the site. Agree in the contract when the reference is handed over.
- Versioning the logic and not the rest. Drive parameters, HMI screens and safety logic change process behaviour too. The same holds for code an assistant helped to write, as discussed in AI assistants in PLC and HMI code: it goes through the same release.
Version control is not a tool you buy. It is the habit of asking the controller whether it still runs the program you approved, and having a record ready when it does not.
References
- Darren Henry (Copia Automation), Understanding Git-Based Version Control for Industrial Automation, AUTOMATION 2022 Vol 3, June 2022, online 12 July 2022: automation.com (the vendor feature this article starts from).
- European Commission, EudraLex Volume 4, Annex 11: Computerised Systems (2011), §7.2, §10, §11: health.ec.europa.eu.
- European Commission, stakeholders’ consultation on Chapter 4, Annex 11 and new Annex 22 (7 July to 7 October 2025), draft §12.3 and §14.2: health.ec.europa.eu.
- US FDA, 21 CFR 211.68 and 21 CFR 11.10: ecfr.gov, ecfr.gov.
- PIC/S, PI 011-3, Good Practices for Computerised Systems in Regulated “GXP” Environments, 25 September 2007: picscheme.org.
- Git project documentation, hash-function-transition: git-scm.com.
Related articles
All articles- AI assistants in PLC and HMI code: what they help with, what stays human, and how the code stays validatableAn assistant drafts a structured-text block, translates an alarm list or proposes a test list in minutes. On a GMP line that code is still custom…
- A backup is a hypothesis. A restore is evidence.“We have backups” is not an answer. The question is when you last restored one, how long it took, and whether the line ran afterwards.
- When does a repair become a requalification? Change control on qualified equipmentA qualification report describes a machine on the day it was signed. Every repair, spare part and program edit after that day either keeps the…
EUCALEX
Have a project or a technical challenge?
Contact us: we will be pleased to discuss it with you, with no commitment.
Discuss your project with usStay informed
Receive new EUCALEX articles and technical insights by email.
