问题描述
我在 KRL 项目中使用 git 时遇到一些问题,想知道是否有一些解决方法可以改进我的工作流程。
KRL 是工业 KUKA 机器人的编程语言。它具有类似 Basic-/Pascal 的语法。一个程序由一个或多个模块组成。一个模块由两个文本文件组成,一个用于源代码 (.src),另一个用于声明和定义 (.dat)。
&ACCESS RVO
&REL 175
每个标题行都以 & 开头,对代码完全没有意义。最糟糕的是这个标题不断变化。因此,当我将文件从机器人控制器复制回我的 repo 时,git 指出即使源代码相同,该文件也已更改。
所以我的第一个问题是:有没有办法使用过滤器或钩子来忽略所有以 &
开头的行?
我的第二个问题是 *.dat 文件不仅用于声明和定义,如类 C 语言中的头文件,而且还用于存储值。这看起来像这样:
DECL E6POS XP1={X 319.710815,Y -488.601227,Z 1364.72363,A -73.5368805,B 88.6439896,C 10.5155058,S 6,T 26,E1 0.0,E2 0.0,E3 0.0,E4 0.0,E5 0.0,E6 0.0}
INT counter=123
REAL offset=0.123
我依赖于这些值,因为它们存储需要保持持久性的头寸和计数器,但我不在我的回购中关心它们。不完全是,它们必须在文件和我的仓库中,但 git 不应该在这些行中查找差异。
所以假设我在我的 repo 中创建了一个模块并将这个模块复制到机器人。现在我用机器人执行这个模块并且必须覆盖一个位置值。这会更改相应 *.dat 文件中的值。一切正常,几天后我想实现一个计数器。我不能只是将新的整数定义放入本地可用的 *.dat 文件中,因为这样我会覆盖机器人上的位置值。所以我必须首先将机器人控制器中的 *.dat 文件复制到我的存储库中并在那里定义新变量。但是当然 git 向我展示了文件不仅在新行中发生了变化,而且在机器人更改了位置等值的行中也发生了变化。这让评论变得更加困难,因为我有很多不断变化的测量值和计数器值。
对于我的第二个问题:有没有办法忽略 =
之后的所有内容,但只能忽略 *.dat 文件?这应该与标头中的 &
相同,因此值应该在存储库中,但我不关心这些值的任何差异。
解决方法
使用过滤器可以忽略这些行。
假设我们在 /scripts/krl_filter.sh 上有一个过滤器:
sed -e '/\&ACCESS/d' -e '/\&REL/d' -e '/\&PARAM/d' -e '/\&COMMENT/d'
我们将过滤器设置为/.git/config
[filter "krl"]
clean = $PWD/scripts/krl_filter.sh
smudge = cat
required = true
我们将其应用于 KRL 文件 .gitattributes
*.src filter=krl
*.dat filter=krl
*.sub filter=krl
也许您会在提交标题行之前看到更改但一旦进行更改或以其他方式应用过滤器
*对于 .dat 文件,您可以使用这样的过滤器:
sed -e 's/=[^=]*$/=/'
有关在 git 中忽略行的更多信息,请查看: How to tell git to ignore individual lines,i.e. gitignore for specific lines of code
,欢迎 ascaron37!
对于你的第一个问题, 以“&”为前缀的标头值由 KSS 自动生成,这种行为无法停用或修改。头文件对代码执行没有影响,因此可以随时删除;但是,KSS 会在某个时候再次自动生成它们。
我的解决方案是在 C# WPF 中创建一个“KRL-Git 清洁器”工具,该工具可以从 Workvisual 存储库文件夹中的任何文件中清除任何自动生成的行,通常位于“C:\Users”username”\Documents\ WorkVisual 6.0\Repositories”。
我的工作流程是这样的:
- 在机器人或 WorkVisual 上编写代码
- 运行我的 KRL-Git 清理器以从存储库中删除任何自动生成的行
- 提交 git 提交
由于公司政策,我无法共享该项目,但我可以提供一个片段,其中包含我如何清理线条的示例:
using System;
using System.IO;
using System.Windows;
using System.Windows.Input;
/// <summary>
/// Delete deletable lines withing directory and children
/// </summary>
/// <param name="parentDirectory"></param>
/// <returns></returns>
private int DeleteAllChildren(DirectoryInfo parentDirectory)
{
int deletables = 0;
foreach (var childDirectory in parentDirectory.GetDirectories())
{
deletables += DeleteAllChildren(childDirectory);
}
foreach (var childFile in parentDirectory.GetFiles())
{
if (childFile.Extension == ".src" || childFile.Extension == ".dat" || childFile.Extension == ".sub")
{
var tempFile = Path.GetTempFileName();
using (StreamWriter sw = new StreamWriter(tempFile))
{
using (StreamReader sr = new StreamReader(childFile.FullName))
{
var inLine = "";
while (!sr.EndOfStream && !inLine.Contains("DEF"))
{
inLine = sr.ReadLine();
if (!inLine.Contains("&REL") && !inLine.Contains("&ACCESS"))
{
sw.WriteLine(inLine);
}
else
{
deletables += 1;
}
}
while (!sr.EndOfStream)
{
sw.WriteLine(sr.ReadLine());
}
sr.Close();
}
sw.Close();
}
File.Delete(childFile.FullName);
File.Move(tempFile,childFile.FullName);
}
}
return deletables;
}
如果您正在寻找更简单的方法,我很抱歉,但 KUKA 似乎不太关心行业标准版本控制。
至于你的第二个问题,我的策略是在我上面的代码片段中使用该功能,因为我已经在使用它来摆脱自动生成的行。不过我敢打赌,一些 Git 专业人士会有更优雅的解决方案。
,Header 中 & 后面的值完全不相关,这是不完全正确的。 至少 &ACCESS 参数后面的“V”标志是有用的,请声明这些模块和这些模块功能的调用在 SmartPad/SmartHmi 上是否可见。其他值(除了 COMMENT,这是不言自明的)不经常使用,并由 KRC 正确添加。
因此,我在 ~/.git/config 中添加了一个过滤器,该过滤器仅删除 &ACCESS 行中的数字以及其他一些标头参数。
[filter "krl"]
clean = "sed -e 's/\(^&ACCESS [A-Z]*\).*$/\1/' -e '/\^&REL/d' -e '/\^&PARAM/d'"
smudge = "sed -e 's/\(^&ACCESS [A-Z]*\).*$/\1/' -e '/\^&REL/d' -e '/\^&PARAM/d'"
您还必须将这些过滤器应用于 .gitattributes 中的文件
*.src filter=krl
*.dat filter=krl
*.sub filter=krl
.dat 文件中的数据是一个更大的问题。但是,如果您不需要持久性(您可能不需要,否则您可能希望将其添加到版本控制中),您可以在 .dat 文件中声明变量而无需赋值。喜欢:
DECL INT foo
DECL E6POS bar
在这些情况下,您需要在读取之前分配一些值,否则会出错。
或者你添加一些sed的commad送至git过滤像
`sed -e 's/\(^ *DECL *[A-Z]* *[A-Za-z][A-Za-z0-9]* *=\).*\(;\\ignoreVersion\[\(.*\)\]\)/\1 \3 \2/'
通过这些,您可以在作业后面添加评论,例如
DECL INT foo = 1234 ;ignoreVersion[12]
在这种情况下,每次提交时 foo 的值都会被替换为“12”。