Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
一行内的Git合并_Git_Version Control_Latex - Fatal编程技术网

一行内的Git合并

一行内的Git合并,git,version-control,latex,Git,Version Control,Latex,序言 我正在使用git作为我的实验室正在用LaTeX编写的论文的版本控制系统。有几个人在合作 我遇到git对如何合并很固执。假设两个人对一行进行了单个单词的更改,然后尝试合并它们。尽管git diff--word diff似乎能够逐字显示分支之间的差异,但git merge似乎无法逐字执行合并,而是需要手动合并 对于LaTeX文档,这尤其令人讨厌,因为编写LaTeX时的常见习惯是每行写一整段,并在显示时让文本编辑器处理文字换行。我们现在正在为每个句子添加一个换行符,这样git至少可以在一个段落中

序言

我正在使用git作为我的实验室正在用LaTeX编写的论文的版本控制系统。有几个人在合作

我遇到git对如何合并很固执。假设两个人对一行进行了单个单词的更改,然后尝试合并它们。尽管git diff--word diff似乎能够逐字显示分支之间的差异,但git merge似乎无法逐字执行合并,而是需要手动合并

对于LaTeX文档,这尤其令人讨厌,因为编写LaTeX时的常见习惯是每行写一整段,并在显示时让文本编辑器处理文字换行。我们现在正在为每个句子添加一个换行符,这样git至少可以在一个段落中合并对不同句子的更改。但它仍然会对一个句子中的多个变化感到困惑,这当然会使文本不再很好地包装起来

问题

有没有一种方法可以“逐字”而不是“逐行”将两个文件合并到git中?

我相信(即使使用“耐心”合并策略可以使工作更加困难)。
其工作项将保持不变

但总体思路是将任何细粒度检测和解析机制委托给第三方工具。
如果长行中的某些单词不同,该外部工具(
KDiff3
DiffMerge
,…)将能够拾取该更改并将其呈现给您。

您可以尝试以下方法:

您可以进行某种“规范化”(如果愿意,可以进行规范化),而不是更换合并引擎(硬)。我不说乳胶,但让我举例如下:

假设您有类似
test.raw的输入

curve ball well received {misfit} whatever
proprietary format extinction {benefit}.
您希望它逐字进行区分/合并。添加以下
.gittributes
文件

*.raw     filter=wordbyword
然后

过滤器的最低限度实现是

/home/username/bin/wordbyword.clean 将test.raw的内容更改为

curve ball welled repreived {misfit} whatever
proprietary extinction format {benefit}.
git diff--patch with stat
的输出可能是您想要的:

 test.raw |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/test.raw b/test.raw
index b0b0b88..ed8c393 100644
--- a/test.raw
+++ b/test.raw
@@ -1,14 +1,14 @@
 curve 
 ball 
-well 
-received 
+welled 
+repreived 
 {misfit} 
 whatever

 #@#DELIM#@#
 proprietary 
-format 
 extinction 
+format 
 {benefit}.

 #@#DELIM#@#
您可以看到这将如何神奇地用于合并,从而实现逐字扩散和合并Q.E.D.


(我希望您喜欢我对.gittributes的创造性使用。如果不是,我很喜欢做这个小练习)

这里有一个与sehe相同的解决方案,其中有一些改动,希望能解决您的意见:

  • 这个解决方案考虑按句合并,而不是按词合并,就像你以前用手做的那样,只是现在,用户会看到每个段落只有一行,但是git会看到段落被分解成句子。这似乎更符合逻辑,因为从段落中添加/删除句子可能与段落中的其他更改兼容,但当同一句子由两个提交编辑时,手动合并可能更可取。这还有一个好处,即“干净”的快照在某种程度上仍然是人类可读的(并且是可编译的!)
  • 过滤器是单行命令,这将使将其移植到协作者更加容易
正如在saha的解决方案中一样,创建一个(或附加到)
.gittaributes

    *.tex filter=sentencebreak
现在要实现“清洁”和“污迹”过滤器:

    git config filter.sentencebreak.clean "perl -pe \"s/[.]*?(\\?|\\!|\\.|'') /$&%NL%\\n/g unless m/%/||m/^[\\ *\\\\\\]/\""
    git config filter.sentencebreak.smudge "perl -pe \"s/%NL%\n//gm\""
我已经创建了一个包含以下内容的测试文件,请注意一行段落

    \chapter{Tumbling Tumbleweeds. Intro}
    A way out west there was a fella, fella I want to tell you about, fella by the name of Jeff Lebowski.  At least, that was the handle his lovin' parents gave him, but he never had much use for it himself. This Lebowski, he called himself the Dude. Now, Dude, that's a name no one would self-apply where I come from.  But then, there was a lot about the Dude that didn't make a whole lot of sense to me.  And a lot about where he lived, like- wise.  But then again, maybe that's why I found the place s'durned innarestin'.

    This line has two sentences. But it also ends with a comment. % here
在我们将其提交给本地回购协议后,我们可以看到原始内容

    $ git show HEAD:test.tex

    \chapter{Tumbling Tumbleweeds. Intro}
    A way out west there was a fella, fella I want to tell you about, fella by the name of Jeff Lebowski. %NL%
     At least, that was the handle his lovin' parents gave him, but he never had much use for it himself. %NL%
    This Lebowski, he called himself the Dude. %NL%
    Now, Dude, that's a name no one would self-apply where I come from. %NL%
     But then, there was a lot about the Dude that didn't make a whole lot of sense to me. %NL%
     And a lot about where he lived, like- wise. %NL%
     But then again, maybe that's why I found the place s'durned innarestin'.

    This line has two sentences. But it also ends with a comment. % here
因此,clean筛选器的规则是每当它找到以
结尾的文本字符串时,
'
(这是双引号的latex方法)然后是一个空格,它将添加%NL%和一个换行符。但它会忽略以\(latex命令)开头或在任何地方包含注释的行(因此注释不能成为主文本的一部分)

污迹过滤器将删除%NL%和换行符

区分和合并是在“干净”文件上完成的,因此对段落的更改是逐句合并的。这是理想的行为

很好的一点是,latex文件应该在干净或污迹状态下编译,因此协作者不需要做任何事情。最后,您可以将
git config
命令放在作为repo一部分的shell脚本中,以便协作者只需在repo的根目录中运行它即可进行配置

    #!/bin/bash

    git config filter.sentencebreak.clean "perl -pe \"s/[.]*?(\\?|\\!|\\.|'') /$&%NL%\\n/g unless m/%/||m/^[\\ *\\\\\\]/\""
    git config filter.sentencebreak.smudge "perl -pe \"s/%NL%\n//gm\""

    fileArray=($(find . -iname "*.tex"))

    for (( i=0; i<${#fileArray[@]}; i++ ));
    do
        perl -pe "s/%NL%\n//gm" < ${fileArray[$i]} > temp
        mv temp ${fileArray[$i]}
    done
#/bin/bash
git config filter.sentencebreak.clean“perl-pe\”s/[.]*?(\\?\\!\\\\\.\\.\'''/$和%NL%\\n/g,除非是m/%/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
git config filter.sentencebreak.smudge“perl-pe\”s/%NL%\n//gm”
fileArray=($(find.-iname“*.tex”))
对于((i=0;i温度
mv temp${fileArray[$i]}
完成
最后一点是一个黑客行为,因为当这个脚本第一次运行时,分支已经被签出(以干净的形式),它不会自动被弄脏

您可以将此脚本和.gittributes文件添加到repo,然后新用户只需克隆,然后在repo的根目录中运行脚本

我认为如果在GitBash中完成,这个脚本甚至可以在WindowsGit上运行

缺点:

  • 这并不能巧妙地处理带有注释的行,它只是忽略它们
  • %NL%有点难看
  • 过滤器可能会弄乱一些方程式(对此不确定)

如果我理解正确,git mergetool(您可以选择一个用户友好的word感知工具)可以用来解决git检测到的合并冲突,但是如果不将这些更改视为冲突,git无法在一行中以静默方式合并单独的更改?@akeshet:是的,这就是为什么git被引用为“愚蠢的内容管理者”:你要求的那种智能是你提供的,要么通过合并工具,要么通过某种脚本,就像sehe在回答中所说明的那样。还有合并drivers@felixfbeck
    git config filter.sentencebreak.clean "perl -pe \"s/[.]*?(\\?|\\!|\\.|'') /$&%NL%\\n/g unless m/%/||m/^[\\ *\\\\\\]/\""
    git config filter.sentencebreak.smudge "perl -pe \"s/%NL%\n//gm\""
    \chapter{Tumbling Tumbleweeds. Intro}
    A way out west there was a fella, fella I want to tell you about, fella by the name of Jeff Lebowski.  At least, that was the handle his lovin' parents gave him, but he never had much use for it himself. This Lebowski, he called himself the Dude. Now, Dude, that's a name no one would self-apply where I come from.  But then, there was a lot about the Dude that didn't make a whole lot of sense to me.  And a lot about where he lived, like- wise.  But then again, maybe that's why I found the place s'durned innarestin'.

    This line has two sentences. But it also ends with a comment. % here
    $ git show HEAD:test.tex

    \chapter{Tumbling Tumbleweeds. Intro}
    A way out west there was a fella, fella I want to tell you about, fella by the name of Jeff Lebowski. %NL%
     At least, that was the handle his lovin' parents gave him, but he never had much use for it himself. %NL%
    This Lebowski, he called himself the Dude. %NL%
    Now, Dude, that's a name no one would self-apply where I come from. %NL%
     But then, there was a lot about the Dude that didn't make a whole lot of sense to me. %NL%
     And a lot about where he lived, like- wise. %NL%
     But then again, maybe that's why I found the place s'durned innarestin'.

    This line has two sentences. But it also ends with a comment. % here
    #!/bin/bash

    git config filter.sentencebreak.clean "perl -pe \"s/[.]*?(\\?|\\!|\\.|'') /$&%NL%\\n/g unless m/%/||m/^[\\ *\\\\\\]/\""
    git config filter.sentencebreak.smudge "perl -pe \"s/%NL%\n//gm\""

    fileArray=($(find . -iname "*.tex"))

    for (( i=0; i<${#fileArray[@]}; i++ ));
    do
        perl -pe "s/%NL%\n//gm" < ${fileArray[$i]} > temp
        mv temp ${fileArray[$i]}
    done