Git在一行内合并 [英] Git merging within a line

查看:92
本文介绍了Git在一行内合并的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



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



问题



有没有办法让git合并两个文件逐字而不是一行一行?

解决方案

这里的解决方案与sehe的解决方案相同,只需稍作更改即可解决您的问题:


  • 这个解决方案考虑通过句子进行合并,而不是像用手一样通过单词进行合并,直到现在,用户会看到每个段落只有一行,但git会将段落分解为句子。这似乎更合乎逻辑,因为添加/删除段落中的句子可能与段落中的其他更改兼容,但当同一句子由两个提交进行编辑时,可能更希望进行手动合并。这也有干净的快照的好处,仍然有点人类可读(和可编译胶乳!)。
  • 过滤器是单行命令,这应该使它更容易移植这对于合作者而言。



在saha的解决方案中,制作一个(或附加到) .gittatributes

  * .tex filter = sentencebreak 

现在执行干净和涂抹过滤器:

  git config filter。 /'&%NL%\\ n / g,除非m /%/ || m / ^ [\\\\\\\\\\\\\\] \\\\
git config filter.sentencebreak.smudgeperl -pe \ s /%NL%\\\
// gm\

I已经创建了一个测试文件,其中包含以下内容,请注意单行的段落。

  \chapter {Tumbleling Tumbleweeds。 Intro} 
西部有一条出路,那就是我想告诉你的家伙,名叫杰夫·莱博斯基的家伙。至少,这是他的爱人父母给他的句柄,但他自己从来没有多少用处。这个Lebowski,他称自己是Dude。现在,伙计,这是一个名字,没有人会自我申请我来自哪里。但那时候,关于这个伙计的事情很多,这对我来说并没有什么意义。很多关于他住的地方,比如明智的。但是,再一次,也许这就是为什么我找到了这个地方转瞬即逝的地方。

这行有两个句子。但它也以评论结束。 %here

在我们将其提交到本地回购后,我们可以看到原始内容。

  $ git show HEAD:test.tex 

\chapter {Tumbleling Tumbleweeds。 Intro}
西部有一条出路,那就是我想告诉你的家伙,名叫杰夫·莱博斯基的家伙。 %NL%
至少,这是他父亲给他的那个句柄,但他自己从来没有多少用处。 %NL%
这个Lebowski,他自称是Dude。 %NL%
现在,伙计,这是一个名字,没有人会自我申请我来自哪里。 %NL%
但是接下来有很多关于Dude的内容对我来说并没有太多意义。 %NL%
关于他住在哪里,很明智。 %NL%
但是,再次,也许这就是为什么我找到了这个地方'innastin'。

这行有两个句子。但它也以评论结束。 %here

所以干净过滤器的规则是每当它发现一串以 ''(这是双引号的乳胶方式),然后是空格,它会添加%NL%和一个换行符。但它会忽略以\(latex命令)开头的行或包含任何地方的注释(以便注释不能成为主要文本的一部分)。



涂抹过滤器可消除%NL%和换行符。



对干净文件进行差异和合并,因此对段落的更改将逐句合并。这是所期望的行为。



好的是,latex文件应该在干净或污迹状态下编译,所以协作者有一些希望不需要做任何事情。最后,你可以将 git config 命令放在作为repo一部分的shell脚本中,这样合作者只需要在repo的根目录下运行它即可配置。

 #!/ bin / bash 

git config filter.sentencebreak.cleanperl -pe \s / [。] *?(\\\\ | | \\!| \\。|'')/ $&%NL%\\\\
/ g除非m /% / || m / ^ [\\\\\\\\\\\\\\] \\\
git config filter.sentencebreak.smudgeperl -pe \s / %NL%\\\
// gm\

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

for((i = 0; i< $ {#fileArray [@]}; i ++));
do
perl -pes /%NL%\\\
// gm< $ {fileArray [$ i]}> temp
mv temp $ {fileArray [$ i]}
完成

最后一点是一个黑客,因为当这个脚本第一次运行时,分支已经签出(干净的形式),它不会自动弄脏。



您可以将此脚本和.gitattributes文件添加到回购站,然后新用户只需克隆,然后在回购站的根目录下运行该脚本。



我认为这个脚本甚至在windows git上运行,如果在git bash中完成的话。



缺点:$ b​​
$ b


  • 这不会巧妙地处理带有注释的行,它只是忽略它们。

  • %NL%有点难看

  • (不知道这个)。

    Preamble

    I'm using git as a version control system for a paper that my lab is writing, in LaTeX. There are several people collaborating.

    I'm running into git being stubborn about how it merges. Let's say two people have made single-word changes to a line, and then attempt to merge them. Though git diff --word-diff seems capable of SHOWING the difference between the branches word-by-word, git merge seems unable to perform the merge word-by-word, and instead requires a manual merge.

    With a LaTeX document this is particularly annoying, as the common habit when writing LaTeX is to write a full paragraph per line and just let your text editor handle word wrapping when displaying for you. We are working around for now by adding a newline for each sentence, so that git can at least merge changes on different sentences within a paragraph. But it will still get confused about multiple changes within a sentence, and this makes the text no longer wrap nicely of course.

    The Question

    Is there a way to git merge two files "word by word" rather than "line by line"?

    解决方案

    Here's a solution in the same vein as sehe's, with a few changes which hopefully will address your comments:

    • This solution considers merging by sentence rather than by word, as you had been doing by hand, only now, the user will see a single line per paragraph, but git will see paragraphs broken into sentences. This seems to be more logical because adding/removing a sentence from a paragraph may be compatible with other changes in the paragraph, but it is probably more desirable to have a manual merge when the same sentence is edited by two commits. This also has the benefit of the "clean" snapshots to still be somewhat human readable (and latex compilable!).
    • The filters are one-line commands, which should make it easier to port this to collaborators.

    As in saha's solution make a (or append to) .gittatributes.

        *.tex filter=sentencebreak
    

    Now to implement the clean and smudge filters:

        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\""
    

    I've created a test file with the following contents, notice the one-line paragraph.

        \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
    

    After we commit it to the local repo, we can see the raw contents.

        $ 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
    

    So the rules of the clean filter are whenever it finds a string of text that ends with . or ? or ! or '' (that's the latex way to do double quotes) then a space, it will add %NL% and a newline character. But it ignores lines that start with \ (latex commands) or contain a comment anywhere (so that comments cannot become part of the main text).

    The smudge filter removes %NL% and the newline.

    Diffing and merging is done on the 'clean' files so changes to paragraphs are merged sentence by sentence. This is the desired behavior.

    The nice thing is that the latex file should compile in either the clean or smudged state, so there is some hope for collaborators to not need to do anything. Finally, you could put the git config commands in a shell script that is part of the repo so a collaborator would just have to run it in the root of the repo to get configured.

        #!/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
    

    That last little bit is a hack because when this script is first run, the branch is already checked out (in the clean form) and it doesn't get smudged automatically.

    You can add this script and the .gitattributes file to the repo, then new users just need to clone, then run the script in the root of the repo.

    I think this script even runs on windows git if done in git bash.

    Drawbacks:

    • This doesn't handle lines with comments smartly, it just ignores them.
    • %NL% is kind of ugly
    • The filters may screw up some equations (not sure about this).

    这篇关于Git在一行内合并的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆