☰
控制器当Git服务器:TwinCAT 3 AdsGitServer版本回退
2026/10/28 2:08:55 网站建设 项目流程

简介:这份PDF面向使用TwinCAT 3.1.4024及以上版本的自动化工程师与PLC协同开发人员,聚焦控制器内置AdsGitServer的版本管理实践,帮助读者在不依赖外部Git软件的情况下完成程序提交、获取、差异查看与版本回退。资源包共1个PDF文件,约1.77MB,内容从软硬件版本确认、软件安装、控制器路由配置和TwinCAT环境设置讲起,逐步说明启用Multiuser、初始化Git Server以及提交、拉取、查看差异和回退版本等操作,并专门梳理Init创建失败、连续提交两个版本等常见问题。内容还涉及历史版本查看与比较、用旧版本修改当前程序、恢复到指定版本,以及第二台PC从控制器装载不同版本PLC程序等延伸场景,便于团队协作时对照排查。已有373人学习下载,适合需要快速理解TwinCAT集成Git流程、减少外部工具依赖并提升PLC协同开发效率的读者查阅。

1. 控制器当 Git 服务器:AdsGitServer 解决的到底是哪个具体痛点

现场调试最怕什么?改完一版 PLC 程序,登录控制器跑了一周,甲方一句“还是回到上周那版”,你翻遍笔记本只找到一个PLC_最终版_真的最终.zip。TwinCAT 3.1.4024 之后,这个场景有了另一种解法:控制器本身可以充当 Git Server,开发环境里直接做版本管理,不用在笔记本上另装一套 Git 客户端。这个功能就是 AdsGitServer,它把提交、取回、版本差异和回退都放回了 TwinCAT 自己的 Multiuser Explorer 里。适合谁?一个人守着一台控制器、但又确实需要“改坏了能退回去”的 AT 工程师;也适合两台 PC 轮流接手同一个柜子的调试场景。它不是什么企业级代码托管,别指望分支策略和 PR 流程,但把“每周一个可回退的存档点”这件事做扎实,够用。

2. 环境先立住:版本底线、ADS 路由和三个必须打开的开关

AdsGitServer 不是装个插件就能跑的东西,它依赖控制器侧的服务、开发侧的源码管理插件、以及一个专门的比较工具配置,这三者缺一个都会在后面某一步莫名其妙地卡住。我见过最常见的翻车不是操作错,而是版本没对齐——控制器上是 4024.15,笔记本上是 4024.10,路由加得上,Init 也能点,但一比较就报错。所以这一章先把地基打平,再谈提交。

2.1 软硬件版本底线与安装后的服务确认

控制器侧要求 Win7 或 Win10,TwinCAT 3.1.4024.15 或以上;开发 PC 侧同样建议 4024.15 起步。实测下来有两条血泪经验:第一,控制器最好用配套的 IPC/EPC,第三方 PC 上跑 XAR 总会冒出各种玄学问题,路由能通但 Git 服务起不来;第二,XAE 和 XAR 尽量同版本,Build 越高越稳,跨 Build 组合的兼容性没人给你打包票。

安装本身不复杂,笔记本上跑TC31-FULL-Setup.3.1.4024.15.exe,控制器上跑TC31-XAR-Setup.3.1.4024.15.exe,AdsGitServer 会随安装包一起落盘,不需要单独勾选。重启之后第一件事不是打开 XAE,而是去服务列表确认两个服务都在跑,这一步省掉,后面 Init 失败你会怀疑人生。

# 在控制器和开发 PC 上分别执行,确认两个服务处于 Running Get-Service -Name "TwinCAT3*" | Select-Object Name, Status, StartType # 只盯 AdsGitServer,确认它是自动启动而不是手动 Get-Service -Name "TwinCAT3 AdsGitServer" | Format-List Name, Status, StartType, DisplayName

逻辑说明:第一条命令用通配符把所有 TwinCAT 3 相关服务拉出来,重点看TwinCAT 3 System Service和TwinCAT3 AdsGitServer两条;第二条单独确认 AdsGitServer 的启动类型,如果是 Manual,重启后它不会自己起来,Init 会直接超时。参数上-Name支持通配,Format-List比默认表格多显示DisplayName,方便确认没装错版本。

提示:服务列表里如果只有 System Service 没有 AdsGitServer,八成是安装包版本低于 4024,或者装的是 XAE 精简版,回到安装介质核对一遍。

2.2 ADS 路由与环境选项:Git 插件和 Project Compare 配置

路由这一步原文写得很克制——“再次确认控制器的操作系统和 TwinCAT 版本”,但实际现场经常栽在这里。添加路由时 AmsNetId 要和控制器的实际网卡对应,笔记本双网卡(有线接设备、无线连办公网)时容易选错广播地址,结果是 XAE 能登录,但 Multiuser Explorer 里 ADS Route 下拉是空的。

路由通了之后,进 XAE 主菜单Tools → Options → Source Code Control,把源码管理插件选成 Git。这个选项决定的不只是“用哪个后端”,它直接影响版本比较时的行为:选了 Git,比较才会去 Git Server 上取对应版本的源码,并且用集成的 TwinCAT Project Compare Tool 做结构化对比;不选,比较退化成文本 diff,PLC 的 POU 差异你基本看不出来。

Project Compare 还得单独配一次。从编程 PC 的 TC3 图标点Tool,选TwinCAT Project Compare,打开后在主菜单Tool → Configure User Tools,点Export Configuration,选 Git 插件,启用默认的全局 git 配置。这一步不做,History 里右键 Compare 会弹“找不到比较工具”,代码差异窗口是灰的。

# 确认全局 git 配置已经就位(Project Compare 依赖它找 diff 工具) git config --global --list # 关键项:diff 工具路径和 TwinCAT 比较工具的关联 git config --global diff.tool git config --global difftool.prompt false

逻辑说明:Project Compare 的Export Configuration本质是往全局.gitconfig里写 diff/difftool 段,第一条命令把现有配置打出来核对;第二条确认diff.tool有值,空的话比较按钮不会亮。difftool.prompt false是为了批量比较时不弹确认框,单人调试可以不开,多版本对比时开着很烦。

2.3 启用 Multiuser 之前的项目属性检查

新建 TwinCAT 项目、添加 PLC 程序之后,别急着登录控制器。先打开 PLC 项目的属性页,把 Multiuser 启用。这个开关一旦打开,项目目录下会生成 Git 相关文件,后续每次 Login 都会被要求填 Update 信息。

这里有个顺序问题必须强调:在激活配置下载之前就完成 Git Server 初始化。原文专门用一句话点过,但很多人是先把程序跑通、再回头补版本管理,结果 Boot 目录里已经是旧逻辑,Init 出来的第一个版本和实际运行的对不上,后面回退就分不清哪个是“能跑的版本”。

注意:启用 Multiuser 的 PLC 项目文件夹,不要再手动git init。TC3 AdsGitServer 和标准 Git 不能同时追踪同一个文件夹,两边都初始化会直接冲突,历史记录会错乱。

3. Init local and Remote 之后:仓库落点、两次提交与版本比较

初始化按钮点下去的那一瞬间,很多人以为只是“建了个仓库”,其实它同时改了三处东西:控制器上的版本仓库目录、开发 PC 项目目录下的 Git 元数据、以及 XAE 里 ADS Route 和 Multiuser Repository 两个输入框的可编辑状态。搞清这三处的落点,后面排查问题才有方向。

3.1 启用 Multiuser 与 Init 的目录落点

从主菜单视图 → 其它窗口 → Multiuser Explorer打开 Git 控制面板。选好 ADS Route,填一个 Multiuser Repository 名称(比如项目代号),点Init local and Remote,弹出 Update Message 窗体,填Init,确定。

初始化成功后,界面上 ADS Route 和 Multiuser Repository 会变成不可改动。控制器侧会在默认版本仓库根目录下建一个以你填的名称命名的文件夹,根目录是 ProgramData 下的MultiuserRepository(具体厂商目录名按实际安装路径替换)。开发 PC 侧则在 PLC 项目路径下多出 Git 相关的三个文件和一个文件夹。此后每次 Login,只要TwinCAT/3.1/Boot里的内容有变化,控制器仓库里的Objects文件夹就会跟着更新。

# 定位控制器上的版本仓库根目录:ProgramData 下名为 MultiuserRepository 的文件夹 Get-ChildItem "C:\ProgramData" -Directory -Recurse -Depth 1 -Filter "MultiuserRepository" | Select-Object FullName # 假设已定位到 $repoRoot,列出所有已初始化的仓库 $repoRoot = "C:\ProgramData\<厂商目录>\MultiuserRepository" Get-ChildItem $repoRoot -Directory | Select-Object Name, CreationTime # 看某个仓库的 Objects 是否随 Login 更新 Get-ChildItem "$repoRoot\<你的仓库名>\Objects" -Recurse | Sort-Object LastWriteTime -Descending | Select-Object -First 10 FullName, LastWriteTime

逻辑说明:第一条用-Depth 1限制递归深度,避免在 ProgramData 里翻太久;第二条列出所有仓库文件夹,CreationTime能帮你确认是不是新建的;第三条按修改时间倒序取前十条,登录控制器后立刻执行,能看到Objects下的文件时间戳在跳,就说明同步链路是通的。参数上<厂商目录>和<你的仓库名>按实际环境替换,不要照抄。

提示:Status 和 Conflict 界面里的 Local 和 Remote,分别指的就是开发 PC 上那个项目文件夹、和控制器上这个仓库文件夹,理解这一点,后面所有“本地落后/远程更新”的提示都能对上号。

3.2 两次提交:从 V1.0 到 V1.0.1 的变量与代码改动

初始化完成后的每次 Login 都会要求填 Update 信息,这就是版本标题。第一次可以填V1.0 First Code,新建一个 INT 变量 x,写一行x := x + 1;。第二次 Login 前把步长改成 2,Update 信息填V1.0.1 Change Data。两次提交之间只动了一个字面量,这样做的目的是让后面 Compare 的差异足够干净,一眼能看出“逻辑修改”长什么样。

// 版本 V1.0 First Code:新建变量 x,步长 1 PROGRAM MAIN VAR x : INT; END_VAR x := x + 1;
// 版本 V1.0.1 Change Data:只改步长,其余不动 PROGRAM MAIN VAR x : INT; END_VAR x := x + 2;

逻辑说明:这两段不是让你真去跑什么算法,而是故意制造一个最小差异集——变量声明没变,表达式里的常量变了。Compare 工具会把这种改动归类为“逻辑修改”,在差异树里标红,双击进去能看到具体是哪一行。参数说明:Update 信息就是 History 列表里的版本标题,建议统一用V主版本.次版本 简短描述的格式,别写“修改一下”“再改改”,三个月后自己都认不出来。

3.3 历史版本、比较与恢复的单机闭环

History 界面点Show History,所有版本按提交顺序列出来,每一条对应一次 Login 时填的 Update 信息。比较有两种选法:只选一项,是它和当前版本比;选两项,是这两项互比。差异分新增、删除、逻辑修改三类,红色标记,双击红色 POU 能展开到代码行级别。

真正实用的是“拿历史版本的片段修当前版本”。选中某处不同,在比较图上点Accept Single、Accept Block或Accept All,回到 PLC 源码就会发现代码已经被改过来了。整版回退则用右键Get this version,系统会提示File has been changed outside the enviroment. Reload the new file?。

注意:Reload 只是把文件装载回来看看,无论你点不点 Reload,代码都已经改变了。这个提示的措辞容易让人以为是“预览”,实际是“已落盘”。

单机闭环到这里就完整了:改代码 → Login 提交 → History 看差异 → 选择性 Accept 或整版 Get this version。一个人守一台控制器,这套流程足够覆盖 90% 的“改坏了要退回去”场景。

4. 双机协同:第二台 PC 接入、落后提示与冲突处理的顺序

单机流程跑通之后,第二台 PC 接入才是真正考验理解深度的地方。很多人在这里翻车,不是因为操作复杂,而是因为不知道“谁落后于谁”该看哪个界面。Multiuser Explorer 用颜色和文字给了提示,但得先知道 Local 和 Remote 分别指什么,才读得懂。

4.1 从控制器上传源程序与本地仓库同步

第二台笔记本装同版本 TC3.1.4024.15,启动 XAE,加到控制器的路由。接下来要拿到与 PLC 中正在运行的程序名——能直接从第一台 PC 拷贝项目文件最好,拷不了就从控制器上传 TwinCAT 项目。这一步的核心目的不是“读源代码”,而是拿到程序名和项目结构;能不能读到源码不要紧,因为第一台 PC 未必把源码下载下去了。

然后从 Multiuser Explorer 的 ADS Routes 选控制器,从 Multiuser Repository 下拉菜单里选第一台 PC 建好的那个仓库名,点Init Local and Remote。系统会提示 Remote 中已经存在数据仓库,问要不要读取,回 Yes。这个过程会把控制器上的版本仓库同步到第二台笔记本,之后第二台 PC 就能按单机流程继续编程和提交了。

# 第二台 PC 侧确认本地已经出现 Git 元数据(三个文件 + 一个文件夹) Get-ChildItem "<PLC 项目路径>" -Force | Where-Object { $_.Name -match '^\.git|git' } | Select-Object Name, Mode, LastWriteTime

逻辑说明:-Force是为了把隐藏的.git目录也列出来;Where-Object用正则匹配.git开头或名字里带 git 的项,正常情况下能看到.git目录和几个配置文件。如果这里是空的,说明 Init 没真正落盘,回去看 4.1 开头那一步是不是漏了“回 Yes”。

4.2 版本落后、冲突提示与正确的拉取顺序

第二台 PC 上提交两个版本:V2.0 Change Para,把步长从 2 改成 10;V2.0.1 Second Code,新增变量 y,写y := 2 * x;。然后在 History 里能看到四个版本——第一台 PC 的两个加第二台 PC 的两个,线性排列。

// 版本 V2.0 Change Para:步长从 2 改为 10 PROGRAM MAIN VAR x : INT; END_VAR x := x + 10;
// 版本 V2.0.1 Second Code:新增变量 y,依赖 x 计算 PROGRAM MAIN VAR x : INT; y : INT; END_VAR x := x + 10; y := 2 * x;

逻辑说明:V2.0.1里 y 的计算依赖 x 的新步长,这样如果回退时只退一半(比如只退 y 不退 x),编译能过但逻辑是错的——这是故意的,用来验证 Compare 能不能把“删除一行”和“新增一行”分开标。参数说明:第二台 PC 提交前不用做任何“拉取”动作,因为每次 Login 本身就是一次带 Remote 校验的提交,控制器会拒绝落后于 Remote 的 Local 直接覆盖。

回到第一台 PC,打开 History 会发现 Local 和 Remote 不一致:红色两项是 Remote 新增的版本,绿色是当前 PC 保存的最新版本。进 Status 界面,提示LocalsBehindRemote,意思是本地版本比控制器旧。进 Conflict 界面,提示本地丢失了远程若干次修改。这时候点Get Latest,系统会提示程序从外部改动了,并列出与当前代码的区别,可以 Accept 也可以拒绝,也可以关掉不理。

装载最新版本的正确方式是:在 History 里选中V2.0.1,右键Get This Version,提示代码从外部改变时选“是”,当前 PLC 项目就恢复成第二台 PC 编辑的最新代码。再回 History 看,Local 和 Remote 重新对齐。

提示:Get Latest和Get This Version的区别值得记一下——前者是“把远程最新拉下来并尝试合并”,后者是“把指定版本整版覆盖到本地”。落后一两个版本时用前者省事,落后多个版本时用后者更可控,至少你知道自己覆盖到了哪一版。

4.3 非 TwinCAT 文件的本地 Git 兜底

PLC 代码之外的说明书、操作手册、接线图,AdsGitServer 管不了。原文说得很直白:非代码类文件管理甚至不是 Git 技术要处理的问题,但自动化项目确实有这个需求。折中方案是用 Visual Studio 的“团队资源管理器”做本地 Git 存储——新建、添加、克隆三个入口,够单人存档用。

进存储库配置主页后,更改界面用加减号把改动放进或移出暂存区,再提交到本地 Git Server;同步界面在没配远程的情况下,推送和同步都是摆设。分支、标记这些单人开发基本用不上。

注意:解决方案这个入口尽量别用。新建和打开 TwinCAT 项目都有更顺手的路径,点了“显示文件夹视图”会把当前 TwinCAT 项目关掉,直接跳资源管理器,现场调试时容易手忙脚乱。

查看和恢复非 TwinCAT 文件的历史版本,只能在标准 Git 里做。在目标文件夹右键Git Bash Here,git log --oneline看版本,git reset --hard HEAD^回退到上一版,再打开 Word 文档就能看到内容退回去了。

# 在非 TwinCAT 文件所在目录打开 Git Bash git log --oneline --decorate # 回退到上一个版本(会丢弃工作区改动,先确认没有未提交内容) git status git reset --hard HEAD^

逻辑说明:--oneline把每个版本压成一行,--decorate显示引用名;git status是后悔药,先看清工作区有没有未提交的改动,再决定要不要--hard。参数说明:HEAD^表示上一个版本,HEAD~2是上两个,回退前建议先git log记下目标版本的短哈希,出问题还能git reset --hard <哈希>回来。

5. 避坑与排查:Init 失败、Boot 残留和同名仓库冲突

这一章集中处理四类高频问题,每一条都按“现象 → 原因 → 解决”写,能对上号就直接照做。

5.1 Init 创建失败:从现象到残留清理

现象:点Init local and Remote后界面停在未初始化状态,或者弹窗报错后再点也没反应。

原因:控制器侧或开发 PC 侧存在上一次 Git 设置的残留。常见的是控制器TwinCAT/3.1/Boot里还留着旧项目的文件,或者本地 PLC 项目目录下还躺着上一轮的 Git 元数据,Init 试图在脏环境上建仓库,直接卡死。

解决:三步清理。先清除 Local 和 Remote;再把控制器里的TwinCAT/3.1/Boot文件清空并重启控制器;最后手动删除本地 PLC 项目下的 Git 文件。如果是要在现有控制器上跑一个完全不同的 PLC 项目,最好提前清空 Boot 并重启,控制器上的版本仓库目录本身不用清,将来还能复用。

# 清理本地 PLC 项目下的 Git 元数据(先备份再删) $proj = "<PLC 项目路径>" Get-ChildItem $proj -Force | Where-Object { $_.Name -like ".git*" } | Select-Object FullName # 确认无误后删除 Get-ChildItem $proj -Force | Where-Object { $_.Name -like ".git*" } | Remove-Item -Recurse -Force

逻辑说明:第一条只列不删,确认路径没选错;第二条才执行删除。参数上-Force处理隐藏项,-Recurse处理.git目录内部结构。删之前把项目文件夹整体复制一份,比什么后悔药都管用。

5.2 URL 空白与现有项目接管

现象:选了 ADS Route,Multiuser Repository 的 url 输入框是空白,点 Init 没反应。

原因:新 PLC 项目正常会自动生成 url,但界面刷新偶尔跟不上,尤其是先加路由后开项目、或者中途改过仓库名的场景。

解决:在仓库名输入框里删掉一个字符再重新敲回去,url 会自动刷新。这个操作看起来像玄学,实际是触发一次输入校验。现有 PLC 项目接管则是另一条路:已知控制器上的版本仓库名称,直接从 Multiuser Repository 下拉菜单里选,不用重新输。

顺序坑:初始化要在激活配置下载之前做。先下载后补 Git,Boot 里已经是新逻辑,Init 出来的基线版本和实际运行对不上,后面回退分不清哪个能跑。

5.3 同名文件夹与 Boot 目录残留

现象:换项目后 Init 总失败,或者 History 里冒出上一个项目的版本记录。

原因:控制器上同名仓库文件夹还在,Boot 目录里是旧项目残留;更隐蔽的一种是 PLC 项目文件夹既启用了 Multiuser,又被手动git init过,两套 Git 元数据打架。

解决:不同项目用不同的 Multiuser Repository 名称,别图省事全叫Project;换项目前清空 Boot 并重启;PLC 项目文件夹只走 AdsGitServer 一套,标准 Git 只用于非 TwinCAT 文件,两者物理隔离。

注意:TC3 AdsGitServer 和标准 Git 不能同时追踪同一个文件夹,这条是硬约束,不是建议。

5.4 授权缺位与多人协同的边界

现象:多人同时改一个 PLC 程序,History 里版本记录乱七八糟,谁改的、为什么改说不清,最后还不如人工合并。

原因:Multiuser 文档里没写怎么授权用户访问 Git Server,测试阶段普遍用完全无加密状态;多人分工、代码编辑边界、上传下载时机没提前约定。

解决:AdsGitServer 走的是 ADS 通道,ADS 支持的安全方式都能用——CA、PSK、最简单的用户名/密码,实际项目尤其是多人协同时应该启用,别裸奔。协同规范上,提前约定谁负责哪个 POU、提交信息统一格式、每天开工先Get Latest再动手。单人开发时 History 是清晰线性结构,多人不约定就是一团乱麻。

6. 进阶验证:用 History 与 Compare 走一遍可回退的交付检查

交付前我习惯做一次“可回退性验证”,不是走形式,而是确认三件事:当前版本在 History 里有明确落点、上一版能整版取回、非代码文档也有独立存档。这三件事任何一件没做到,现场出问题时就会多花半小时找文件。

6.1 交付前的版本核对清单

检查项操作位置通过标准
当前版本已提交Multiuser Explorer → History最新一条与当前代码一致,Update 信息可读
上一版可整版取回History 选中上一版 → Get This Version提示外部改动后选“是”,代码回到上一版
关键 POU 差异可读History 选两版 → Compare红色标记能定位到具体代码行
非代码文档有独立记录Git Bash →git log --oneline文档目录有独立提交历史
服务状态正常Get-Service TwinCAT3*System Service 与 AdsGitServer 均为 Running

表格里的第三项最容易被跳过。很多人只验证“能回退”,不验证“差异看得懂”,结果真出问题时回退了却不知道改了什么。Compare 的红色标记要能双击进到 POU,看到具体哪一行新增、哪一行删除、哪一行逻辑被改,这才算过关。

6.2 非代码文件用 git log 做最后一道检查

PLC 代码之外的文档,交付前单独跑一遍日志检查,确认没有未提交的改动留在工作区。

# 进入非 TwinCAT 文件目录 cd /d/项目文档 # 看提交历史,确认版本信息带日期和简述 git log --pretty=format:"%h %ad %s" --date=short # 看工作区是否干净,有未提交改动就先提交再交付 git status --short

逻辑说明:--pretty=format自定义输出,%h短哈希、%ad作者日期、%s提交信息,一行一个版本,比默认格式紧凑;git status --short输出为空才代表工作区干净,有M或??就先处理掉。参数上--date=short把日期压成YYYY-MM-DD,交付记录里看起来更整齐。

这套检查我吃过亏。有一次现场回退,PLC 代码退回去了,但配套的操作说明文档还停在新版,客户按旧文档操作直接报错,查了半天才发现是文档没跟着回退。从那以后我每次交付前都强制走一遍“代码回退 + 文档日志 + 服务状态”三件套,哪怕项目再小也不省这一步。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询