序言
我正在使用 git 作为我实验室正在用 LaTeX 撰写的论文的版本控制系统。有几个人在协作。
我遇到了 git,它对 merge 的方式很固执。假设两个人对一行进行了单个单词的更改,然后尝试将它们 merge 。尽管 git diff --word-diff 似乎能够逐字显示分支之间的差异,但 git merge 似乎无法逐字执行 merge ,而是需要手动 merge 。
对于 LaTeX 文档,这尤其令人讨厌,因为编写 LaTeX 时的常见习惯是每行写一个完整的段落,并让文本编辑器在为您显示时处理自动换行。我们现在正在通过为每个句子添加一个换行符来解决这个问题,这样 git 至少可以 merge 一个段落中不同句子的更改。但是它仍然会对一个句子中的多个变化感到困惑,这当然会使文本不再很好地换行。
问题
有没有办法“逐字”而不是“逐行” merge 两个文件?
最佳答案
这是一个与 sehe 相同的解决方案,但有一些更改,希望能解决您的意见:
如 saha 的解决方案一样,创建一个(或追加到).gittatributes .
*.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 过滤器的规则是每当它找到以 . 结尾的文本字符串时或 ?或 !或 '' (这是做双引号的胶乳方式)然后是一个空格,它将添加 %NL% 和一个换行符。但它会忽略以\(latex 命令)开头或在任何地方包含注释的行(这样注释就不会成为正文的一部分)。
污迹过滤器移除 %NL% 和换行符。
差异和 merge 是在“干净”的文件上完成的,因此对段落的更改会逐句 merge 。这是期望的行为。
好的是 latex 文件应该在干净或污迹状态下编译,因此合作者有希望不需要做任何事情。最后,你可以把 git config shell 脚本中的命令是 repo 的一部分,因此协作者只需在 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
最后一点是 hack,因为当这个脚本第一次运行时,分支已经被 check out (以干净的形式)并且它不会自动被弄脏。
您可以将此脚本和.gitattributes 文件添加到存储库中,然后新用户只需克隆,然后在存储库的根目录中运行脚本即可。
如果在 git bash 中完成,我认为这个脚本甚至可以在 Windows git 上运行。
缺点:
关于Git 在一行内 merge ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5587626/
两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option
文章目录git常用命令(简介,详细参数往下看)Git提交代码步骤gitpullgitstatusgitaddgitcommitgitpushgit代码冲突合并问题方法一:放弃本地代码方法二:合并代码常用命令以及详细参数gitadd将文件添加到仓库:gitdiff比较文件异同gitlog查看历史记录gitreset代码回滚版本库相关操作远程仓库相关操作分支相关操作创建分支查看分支:gitbranch合并分支:gitmerge删除分支:gitbranch-ddev查看分支合并图:gitlog–graph–pretty=oneline–abbrev-commit撤消某次提交git用户名密码相关配置g
关于如何使用git设置类似Dropbox的服务,您有什么建议吗?您认为git是解决此问题的合适工具吗?我在考虑使用git+rush解决方案,你觉得怎么样? 最佳答案 检查这个开源项目:https://github.com/hbons/SparkleShare来自项目的自述文件:Howdoesitwork?SparkleSharecreatesaspecialfolderonyourcomputer.Youcanaddremotelyhostedfolders(or"projects")tothisfolder.Theseprojec
我正在为锦标赛开发一个Rails应用程序。我在这个查询中使用了三个模型:classPlayertruehas_and_belongs_to_many:tournamentsclassTournament:destroyclassPlayerMatch"Player",:foreign_key=>"player_one"belongs_to:player_two,:class_name=>"Player",:foreign_key=>"player_two"在tournaments_controller的显示操作中,我调用以下查询:Tournament.where(:id=>params
我编写了一个非常简单的“部署”脚本,作为我的裸git存储库中的post-updateHook运行。变量如下livedomain=~/mydomain.comstagingdomain=~/stage.mydomain.comgitrepolocation=~/git.mydomain.com/thisrepo.git(bare)core=~/git.mydomain.com/thisrepo.gitcore==addedremoteintoeachlive&stagegitslive和stage都初始化了gitrepos(非裸),我已经将我的裸仓库作为远程添加到它们中的每一个(名为co
我正在安装gitlabhq,并且在Gemfile中有对某些资源的“git://...”的引用。但是,我在公司防火墙后面,所以我必须使用http://。我可以手动编辑Gemfile,但我想知道是否有另一种方法告诉bundler使用http://作为git存储库? 最佳答案 您可以通过运行gitconfig--globalurl."https://".insteadOfgit://或通过将以下内容添加到~/.gitconfig:[url"https://"]insteadOf=git://
在Ruby(或Rails)中,我们可以做到new_params=params.merge({:order=>'asc'})现在new_params是一个带有添加键:order的散列。但是是否有一行可以返回带有已删除key的散列?线路new_params=params.delete(:order)不会工作,因为delete方法返回值,仅此而已。我们必须分3步完成吗?tmp_params=paramstmp_params.delete(:order)returntmp_params有没有更好的方法?因为我想做一个new_params=(params[:order].blank?||para
Activeadmingem已添加到我的rails项目中,但每次我尝试安装railsgactive_admin:install时,我都会收到类似的错误git://github.com/activeadmin/activeadmin.git(atmaster)isnotyetcheckedout.Runbundleinstallfirst.我肯定在运行“railsgactive_admin:install”之前运行了bundle。运行“bundleshow”后,我看到我已将“*activeadmin(1.0.0.pre3f916d6)”添加到我的项目中,但不断收到此错误消息。我的gem文
我的任务是从数组中选择最高和最低的数字。我想我很清楚我想做什么,但只是努力以正确的格式访问信息以满足通过标准。defhigh_and_low(numbers)array=numbers.split("").map!{|x|x.to_i}array.sort!{|a,b|ba}putsarray[0,-1]end数字可能看起来像"80917234100",要通过,我需要输出"9234"。我正在尝试putsarray.first.last,但一直无法弄明白。 最佳答案 有Array#minmax完全满足您需要的方法:array=[80,
已检查ActiveRecord、DataMapper、Sequel:有些使用全局变量(静态变量)有些需要在使用模型加载源文件之前打开数据库连接。在使用不同数据库的sinatra应用程序中使用哪种ORM更好。 最佳答案 DataMapper专为多数据库使用而设计。你可以通过像DataMapper.setup(:repository_one,"mysql://localhost/my_db_name")这样的方式设置多个存储库。DataMapper随后会跟踪所有已在哈希中设置的存储库,您可以引用该哈希并将其用于范围界定:DataMapp