Git + LaTeX 工作流

303

我正在使用LaTeX撰写一份非常长的文档。我有工作电脑和笔记本电脑,两台电脑都需要用来进行编辑。我需要在两台电脑之间保持所有文件同步,并且还想保留修订历史记录。我选择了git作为我的分布式版本控制系统,并将我的代码托管在服务器上。我还使用Kile+Okular进行编辑。但是,Kile没有集成的git插件。我也不需要与任何人协作。如果我的服务器无法访问,我还考虑在codaset上放置另一个私有仓库。

在这种情况下,推荐的工作流程是什么?如何将分支纳入此工作方案中?有没有办法比较同一文件的两个版本?使用stash(暂存区)怎么样?

4个回答

436

你的LaTeX工作流程的变化:

高效管理Git+LaTeX工作流程的第一步是改变你的LaTeX习惯。

  • 首先,将每个句子单独放在一行上。Git是用于版本控制源代码的,其中每行都是独立的且具有特定的目的。当您在LaTeX中编写文档时,通常会按照段落思考并编写成自由流动的文档。但是,在git中,对段落中的单个单词进行更改会记录为对整个段落的更改。

    一种解决方案是使用git diff --color-words(请参见我回答类似问题如何使用Mercurial来版本控制文本文档?的示例)。但是,我必须强调,将其拆分为单独的行是一个更好的选择(我只是在那个答案中简单提到了它),因为我发现它可避免非常少的合并冲突。

  • 如果需要查看代码差异,请使用Git的原生差异工具。要查看两个任意提交(版本)之间的差异,可以使用各自的sha。有关详细信息,请参阅文档以及显示哪些文件在两个修订版本之间发生了更改

    另一方面,如果需要查看格式化输出的差异,请使用latexdiff,这是一个出色的实用程序(使用perl编写),它可以接受两个LaTeX文件并生成类似pdf的漂亮差异输出,如此 (图像来源):

    您可以使用git-latexdiffgitlatexdiff(如果需要则加上latexpand)组合成单个命令(例如,git latexdiff HEAD^可查看你的工作树和倒数第二个提交之间的差异)。

  • 如果您在LaTeX中编写长文档,我建议将不同章节拆分为自己的文件,然后使用\include{file}命令在主文件中调用它们。这样,您可以更轻松地编辑工作的局部部分,并且对于版本控制也更容易,因为您知道每个章节所做的更改,而无需从一个大文件的日志中找到它们。

高效使用Git:

  • 使用分支! 这可能是我能给出的最好的建议。我发现分支非常有帮助,可以跟踪文本的“不同想法”或“不同状态”。master 分支应该是你的主要工作内容,在其最新的“准备发布”状态下,即如果所有分支中有一个分支你愿意署上自己的名字,那么它应该是 master 分支。

    如果您是研究生,分支也非常有帮助。任何研究生都会证明,导师必须进行许多更正,其中大多数您不同意。然而,您可能需要暂时更改它们,即使在讨论后它们被还原。因此,在这种情况下,您可以创建一个新分支 advisor,按照他们的喜好进行更改,同时保持自己的开发分支。然后,您可以合并两个分支并挑选您所需的部分。

  • 我还建议将每个部分拆分为不同的分支,并仅专注于与您所在分支相对应的部分。在创建新部分或制作初始提交时生成分支(根据您的选择)。当您没有在其分支上时,请勿编辑其他部分(例如第3部分)。如果需要编辑,请提交此分支,然后检出其他分支再进行分支。我发现这非常有帮助,因为它可以将该部分的历史记录保留在其自己的分支中,并且还可以从树状图中一目了然地看出某个部分的年龄。也许您已经向第3部分添加了需要调整到第5部分的材料...当然,在仔细阅读时,这些都可能会被注意到,但我发现一目了然地看到这一点很有帮助,这样我就可以转移注意力,如果我对某个部分感到厌倦。

    以下是我最近一篇论文的分支和合并示例(我在 OS X 上使用 SourceTree 和在 Linux 上使用 Git 命令行)。您可能会注意到,我不是世界上最频繁提交者,也不总是留下有用的评论,但这并不意味着您不必遵循这些好习惯。主要的带走信息是使用分支很有帮助。我的想法、观点和开发过程是非线性的,但是我可以通过分支跟踪它们,并在满意时将它们合并(我还有其他无效的分支,后来被删除)。如果它们具有意义(例如,提交给期刊的初始提交/修订提交等),我还可以“标记”提交。这里,我将其标记为“版本1”,这是目前的草稿。树形结构代表了一周的工作。

  • 另一个有用的事情是将全文更改(例如将 \alpha 更改为 \beta)单独提交。这样,您可以撤消更改,而无需回滚其他内容(使用 git 可以做到这一点,但是,如果可以避免,为什么不呢?)。添加到导言中的内容也是如此。

  • 使用远程存储库并定期将更改推送到上游。使用类似 GitHub 和 Bitbucket 的


8
@Diego: 起初需要一点时间适应,因为你的大脑想要连续阅读。然而,这实际上更容易,因为我(以及大多数人)查看整洁的LaTeX输出来检查句子是否有意义并进行校对。使用这些间断没有影响输出,并且使差异比较更加容易。此外,你可以将LaTeX输出链接到源文件,因此如果你发现错误或打字错误,只需单击它,它就会带你直接到相应的源代码位置。 - user616736
1
我使用类似的方法,但是你如何处理数字或其他二进制文件?Git能够处理它们吗?还是有其他方法可以将应该包含在存储库中但不需要版本跟踪的文件包含进去? - liborw
10
除了其中一个我觉得用处不大的建议——即每个章节都要新建一个分支,其他都是非常实用的小贴士。因为你可以通过按文件查看更改状态,所以为什么要增加一个额外的分离层来增加工作流程的复杂性呢?使用git [log|show|add] some_file.tex 就能够完成所有操作,没有必要在这里添加不必要的分支切换步骤。如果需要的话,你仍然可以针对每个单独的文件进行提交。 - rubenvb
2
如果你将每个部分拆分到不同的文件中,那么是的。我通常(以及许多学术圈子的人)只使用单个tex文件来撰写文章。对于书籍/论文,每个章节都有大量的材料,因此单独的文件是有意义的。当然,这些只是建议...每个人都应该根据自己的工作流程选择和拒绝提示 :) - user616736
2
@yoda 哦,我明白了。是的,那就有道理了。我总是强制在期刊上使用多个tex文件;-)。 - rubenvb
显示剩余10条评论

14

我也有一个类似的工作流程。尽管一次只有一个分支被工作,但我发现为不同的工作状态设立独立的分支是有好处的。例如,想象一下把你的论文草稿发送给你的导师后,你又有了一个疯狂的想法!你想开始改变一些核心概念,重新审视一些主要章节等等。于是你就分支出来并开始工作。你的主分支始终处于“可以发布”的状态(或者说尽可能接近那个状态)。因此,尽管其他分支充满了疯狂的和激进的改变,如果其他出版商想要查看你的内容,或者你想提交给会议的论文,主分支始终是可发布的,随时准备好去展示给你的导师或者其他人。如果你的博士导师想在早上第一时间看到这篇文章,你可以stash/stage/commit当前的改变,使用标签或者检索日志,但是为什么不保持独立的分支呢?!

假设你的主分支已经到达了“可以发布”的状态。你现在想将其提交到多个同行评审期刊,每个期刊都对相同内容有不同的格式要求,你期望他们会提出一些不同的修改意见来编辑论文以适应他们的读者等等。你可以很容易地为每个期刊创建一个分支,进行期刊特定的修改,提交,在收到反馈后在每个独立的分支上进行更改。

我还使用Dropbox和git创建了你描述的系统。你可以在Dropbox文件夹中创建一个最简版本的仓库。然后你可以从任何一台电脑上推送/拉取到你的Dropbox中,以使所有端点保持更新。这个系统通常只适用于合作者数量较少的情况,因为如果人们同时尝试推送到Dropbox存储库,可能会导致损坏。

你也可以在Dropbox文件夹内只保留一个仓库,从那里完成所有工作。但是我要强烈反对这种方法,因为有人提到Dropbox在同步不断变化的文件(例如git内部文件)方面存在一些问题。


7
请注意,将同一篇论文同时提交给多个期刊或会议进行同行评审通常被认为是不道德的行为! - Supernormal

9

我尝试将此作为Bash函数实现,将其包含在我的~/.bashrc中使其随时可用。

function git-latexdiff {    
    if [[ $# != 2 ]];    
    then      
        printf "\tusage: git-latexdiff <file> <back-revision>  \n";    
    elif [[ $2 -lt 0 ]];     
    then     
        printf "\t<Back-revision> must be positive\n";   
    else      
        dire=$(dirname $PWD/$1);      
        based=$(git rev-parse --show-toplevel);      
        git show HEAD~$2:$(echo $dire| sed 's!'$(echo $based)'/!!')/$1 > $1_diff.tmp;      
        latexdiff $1 $1_diff.tmp > $1_diff.tex;      
        pdflatex $1_diff.tex;     
        okular $1_diff.pdf;      
        rm $1_diff*;   
    fi; 
}

请注意,此功能需要安装latexdiff(并在路径上找到它)。 同样重要的是,它需要找到pdflatexokular
第一个是我处理LaTeX的首选方式,因此您也可以将其更改为latex。 第二个是我的PDF阅读器,我想您会想在gnome下使用evince或其他解决方案。
这是一个快速版本,仅针对单个文档制作,因为使用git,跟踪多文件LaTeX文档将浪费大量时间和精力。您也可以让git完成此任务,但如果您愿意,也可以继续使用\include

请注意,LaTeX 引用无法适应生成的可视化效果。同时,生成的文件将在函数结束时被删除。正如我所说,这只是一个快速版本。 - Rafareino
1
在这个使用latexdiff与git的答案中,使用latexdiff作为gif助手的提议更加完整。 - juandesant
“gif helper”是什么意思,@juandesant? - Rafareino
1
抱歉,@Rafareino,我的意思是“Git助手”:Git助手是一种可以被Git调用进行某些操作的工具。在这种情况下,您可以通过正确配置,仅使用git diff就可以使用latexdiff命令行工具。 - juandesant

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接