2

我在我的 KRL 项目中使用 git 时遇到了一些问题,我想知道是否有一些解决方法可以改进我的工作流程。

KRL 是工业 KUKA 机器人的编程语言。它具有类似 Basic-/Pascal 的语法。一个程序由一个或多个模块组成。一个模块由两个文本文件组成,一个用于源代码 ( .src),另一个用于声明和定义 ( .dat)。

我的第一个问题是,在每个文件中,第一行构建的标题如下所示:

&ACCESS RVO
&REL 175

每个标题行都以 & 开头,对代码没有任何意义。最糟糕的部分是这个标题不断变化。因此,当我将一个文件从机器人控制器复制回我的仓库时,git 指出文件已更改,即使源代码相同。

所以我的第一个问题:有没有办法使用过滤器或钩子来忽略所有以 a 开头的行&

我的第二个问题是 *.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 不应该在这些行中寻找差异。

所以假设我在我的仓库中创建了一个模块并将这个模块复制到机器人。现在我用机器人执行这个模块并且必须覆盖一个位置值。这会更改相应 *.dat 文件中的值。一切正常,几天后我想实现一个计数器。我不能只将新的整数定义放入本地可用的 *.dat 文件中,因为这样我会覆盖机器人上的位置值。所以我必须首先将 *.dat 文件从机器人控制器复制到我的 repo 并在那里定义新变量。但当然 git 向我展示了文件不仅在新行中发生了变化,而且在机器人更改位置等值的行上也发生了变化。这使得审查变得更加困难,因为我有很多不断变化的测量值和计数器值。

所以对于我的第二个问题:有没有办法忽略=*.dat 文件之后的所有内容?这应该与来自标头的工作相同&,因此值应该在 repo 中,但我不关心这些值的任何差异。

4

3 回答 3

2

使用过滤器可以忽略这些行。

假设我们在 /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, ie gitignore for specific lines of code

于 2021-01-02T18:52:07.870 回答
1

欢迎 ascaron37!

对于您的第一个问题,以 '&' 为前缀的标头值是由 KSS 自动生成的,这是一种无法停用或修改的行为。标头对代码执行没有影响,因此可以随时删除;但是,KSS 会在某个时候再次自动生成它们。

我对此的解决方案是在 C# WPF 中创建一个“KRL-Git 清洁器”工具,该工具从 Workvisual 存储库文件夹中的任何文件中清除任何自动生成的行,通常位于“C:\Users”用户名“\Documents\WorkVisual 6.0\存储库”。

我的工作流程是这样的:

  1. 在机器人或 WorkVisual 上编写代码
  2. 运行我的 KRL-Git 清理器以从存储库中删除任何自动生成的行
  3. 做一个 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 专业人士会有更优雅的解决方案。

于 2020-12-23T15:40:52.523 回答
1

标题中 & 后面的值完全不相关,这并不完全正确。至少 &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

在这些情况下,您需要在读取之前分配一些值,否则会出现错误。

或者您在 git 过滤器中添加一些 sed 逗号,例如

`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”。

于 2021-01-04T21:13:22.453 回答