简体   繁体   English

Git调试自定义合并驱动程序

[英]Git debug custom merge driver

I am working on creating a custom merge driver. 我正在创建一个自定义合并驱动程序。 Everything seems to be working under a number of use cases; 一切似乎都在许多用例下进行; however, in one specific one I am getting during a merge: "fatal: custom merge driver users lacks command line." 但是,在合并过程中,我遇到了一个具体问题:“致命:自定义合并驱动程序用户缺少命令行。” which I can only assume means that my custom merge driver is exiting with something other than a 0. 我只能假设这意味着我的自定义合并驱动程序正在退出而不是0。

I am programming the merge driver in node.js and it is installed as a global package on my machine. 我正在node.js中对合并驱动程序进行编程,并将其作为全局软件包安装在我的计算机上。 The .gitconfig and .gitattributes seem to be setup right since the merge driver is being used when I expect it to. .gitconfig和.gitattributes似乎设置正确,因为我期望在使用合并驱动程序时使用它。

When I was doing my own testing (manually specifying 3 files) I was console.log some debug information, but it seems that during runtime with GIT merge these console messages are supressed. 当我进行自己的测试(手动指定3个文件)时,我在console.log中记录了一些调试信息,但是似乎在运行时与GIT合并时,这些控制台消息被禁止了。 Is there anyway that I can see some of this debug information from my custom merge driver as git is actually using it? 无论如何,由于git实际上正在使用它,所以我可以从自定义合并驱动程序中看到一些调试信息?

TL;DR summary TL; DR摘要

You must have, in some Git configuration file(s), at least two lines that read, eg: 在某些Git配置文件中,您必须至少包含两行内容,例如:

[merge "users"]
    any-variable-not-named-driver = any-value

but without a previous or subsequent line (in the same section of the same Git config file) of the form: 没有以下形式的上一行或下一行(在同一Git配置文件的同一部分中):

    driver = some string, preferably with %-escapes

Note that when anyone (including an external program) runs git somecommand , there are up to three such configuration files read. 注意,当任何人(包括外部程序)运行git somecommand ,最多读取三个这样的配置文件。 One is system-wide (usually /etc/gitconfig ), so that all users on any given machine see the same file with the same contents. 一个是系统范围的(通常是/etc/gitconfig ),因此任何给定计算机上的所有用户都可以看到具有相同内容的相同文件。 One file is per-user, found in $HOME/.gitconfig or $XDG_CONFIG_HOME/git/config . 每个用户一个文件,位于$HOME/.gitconfig$XDG_CONFIG_HOME/git/config The last file is per-repository, found in $GIT_DIR/config , where $GIT_DIR defaults to the first .git directory at or above the current working directory. 最后一个文件是每个存储库,位于$GIT_DIR/config ,其中$GIT_DIR默认为当前工作目录或更高目录中的第一个.git目录。

You must also have, in a .gitattributes file, at least one line that reads: 您还必须在.gitattributes文件中至少包含以下一行:

name-or-pattern    merge=users

And you must then invoke a merge that involves a file pathname that matches the name-or-pattern on the left. 然后,您必须调用涉及文件路径名与左侧名称或模式匹配的合并。

Explanation 说明

The message itself comes from ll-merge.c around line 192 : 该消息本身来自192行附近的ll-merge.c

 if (fn->cmdline == NULL) die("custom merge driver %s lacks command line.", fn->name); 

(Incidentally, "ll" here stands for "low level": this is the "low level merge" code, with low level merges being done on a per-file basis.) Due to other error checking, this particular condition— fn->cmdline == NULL —can only occur if there at least one occurrence of merge.users. whatever (顺便说一句,“ ll”在这里代表“低级”:这是“低级合并”代码,其中低级合并是在每个文件的基础上进行的。)由于其他错误检查,这种特殊情况fn->cmdline == NULL —仅在至少出现一次merge.users. whatever发生merge.users. whatever merge.users. whatever in any of the config files Git has read. merge.users. whatever在任何配置文件的Git已经阅读。 (You could get some other errors in various other cases, but those are not the droids you are looking for errors you are seeing.) (在其他各种情况下,您可能会得到一些其他错误,但这些并不是您要查找机器人 ,而是所看到的错误。)

Remember that there are three such files (system, global, and local). 请记住,有三个这样的文件(系统文件,全局文件和本地文件)。 They are read in that order: system first, then global, then local. 它们的读取顺序是:首先是系统,然后是全局,然后是本地。 Any or all three of these files can contain lines that partially or completely define a custom merge driver; 这些文件中的任何一个或全部三个都可以包含部分或完全定义自定义合并驱动程序的行; the settings from all three files get applied, in whatever order they occur, with later settings generally overriding earlier settings. 这三个文件中的设置将以它们出现的顺序应用,以后的设置通常会覆盖以前的设置。

This is how and why local settings generally override global settings. 就是本地设置通常会覆盖全局设置的方式和原因 There are a few cases where settings accumulate, rather than overriding. 在某些情况下,设置会累积而不是覆盖。 For custom merge drivers, the overall effect is a weird hybrid: the drivers —the name part from merge. name . whatever 对于自定义合并驱动程序,总体效果是一个怪异的混合: 驱动程序 -来自merge. name . whatevername部分merge. name . whatever merge. name . whatever merge. name . whatever —accumulate, but the individual settings —the whatever part for any one given merge. name . whatever merge. name . whatever累加,但个别设置 - whatever给定merge. name . whateverwhatever部分merge. name . whatever merge. name . whatever merge. name . whatever —get overridden, if they occur more than once! merge. name . whatever如果它们多次出现,就被覆盖!

Next, see read_merge_config() , lines 232-296 of the same file : these mean that whenever merge.users. whatever 接下来,请参见read_merge_config() ,同一文件的第232-296行 :这些意味着每当merge.users. whatever merge.users. whatever is read, a data structure of type struct ll_merge_driver is created if necessary, or—if it exists—the existing one with name users is re-used. merge.users. whatever读取merge.users. whatever内容,都将在必要时创建struct ll_merge_driver类型的数据结构,或者(如果存在的话)将重复使用名称为users的现有数据结构。 The variable fn points to this structure; 变量fn指向此结构; fn->name is users and fn->fn is ll_ext_merge() (the latter is the C code function that invokes an external merge driver, and is where the quoted two lines above are found). fn->nameusersfn->fnll_ext_merge() (后者是调用外部合并驱动程序的C代码函数,在上面找到了引用的两行)。

Some of the remaining lines in read_merge_config() check whether the whatever is the literal string name or driver . read_merge_config()剩余的一些行用于检查文字字符串namedriverwhatever For the latter case ( driver ), the code fills in the fn->cmdline field with the specified value. 对于后一种情况( driver ),代码将使用指定的值填充fn->cmdline字段。

To get ll_ext_merge() itself called at all with users as the name of the user-defined merge driver, these three conditions must be satisfied: 为了使ll_ext_merge()本身完全被users作为用户定义的合并驱动程序的名称来调用,必须满足以下三个条件:

  • You have run (directly or indirectly) git merge or a command that invokes a merge (such as git cherry-pick or git revert or git rebase or git apply -3 , for instance); 您已经(直接或间接)运行了git merge或一个调用git merge的命令(例如git cherry-pickgit revertgit rebasegit apply -3 );

  • Based on all three inputs (the merge base and the two tip commits), some file F requires a full three-way "low level" merge because it has three different hash IDs in the three inputs; 基于所有三个输入(合并基础和两个小提示提交),某些文件F需要完整的三向“低级”合并,因为它在三个输入中具有三个不同的哈希ID。 and

  • The .gitattributes for file F includes the line merge=users . 文件F.gitattributes包括merge=users

At this time (and at no other time), Git actually calls ll_ext_merge , passing it the data structure created and filled in (whether partially or completely) while reading the three Git configuration files (system, global, and local). 在这个时候(并且没有其他时间),Git实际上调用ll_ext_merge ,将读取的三个Git配置文件(系统文件,全局文件和本地文件)传递给创建和填充的数据结构(无论是部分还是全部)。

Since you now get the error message that you got, we know: 由于您现在收到了收到的错误消息,因此我们知道:

  • There existed, in the three configuration files, at least one occurrence of merge.users. whatever 在这三个配置文件中,至少存在一次merge.users. whatever merge.users. whatever , but merge.users. whatever
  • None of the whatever s was driver . 在没有whatever S为driver

This is how I reached the conclusion at the top of this answer. 这就是我在此答案顶部得出结论的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM