為什么用Latex寫論文需要設(shè)計(jì)“工作流程”
Latex是理工類論文的事實(shí)標(biāo)準(zhǔn)鼠哥,但是對于“寫作-合作者審閱-討論并修訂-寫作新內(nèi)容”這樣迭代式的寫作流程來說,它缺少清晰的修訂模式露久。尤其當(dāng)作者和合作者并行修改論文時(shí)更米,這個(gè)缺陷會(huì)經(jīng)常導(dǎo)致內(nèi)容沖突、遺失等問題毫痕,全靠肉眼一行行地修訂非常費(fèi)時(shí)間征峦。
第二個(gè)問題是論文是會(huì)被拒的。在快則個(gè)把月消请,慢則長達(dá)一年的評閱時(shí)間之后栏笆,再度撿起論文草稿,很難記起當(dāng)時(shí)的寫作思路和版本迭代思路臊泰。
采用Git管理論文工作流程可以保存所有歷史版本竖伯、簡化內(nèi)容合并過程。
整體思路
- 在code hosting網(wǎng)站上建立你的論文倉庫(如:my-papers文件夾)因宇,每一篇內(nèi)容獨(dú)立的論文用一個(gè)單獨(dú)的文件夾保存七婴。網(wǎng)站選擇的原則是隨時(shí)可訪問和支持私有庫。
- 每一篇的論文寫作察滑,均只從遠(yuǎn)程倉庫
pull
當(dāng)前論文的目錄打厘,不影響其他論文。 - 用至少三個(gè)分支進(jìn)行寫作贺辰。和程序開發(fā)相似户盯,
master
分支的代碼總是submission-ready的。每個(gè)合作者的修改單獨(dú)用一個(gè)分支保存饲化,比如co-author
分支莽鸭。收到新的修改后,放到co-author
分支下吃靠,然后merge
到當(dāng)前寫作分支硫眨,比如my-writing
分支。
具體流程
利用Git的sparse-checkout功能建立論文倉庫
在代碼托管網(wǎng)站上建論文倉庫沒什么可說的巢块,這里只說一下如何每次只pull
當(dāng)前論文的目錄礁阁。
ref: http://blog.algony.net/2015/05/git-sparse-checkout/
$ git init <project>
$ cd <project>
$ git remote add origin <your_remote_paper_repo>
$ git config core.sparsecheckout true # 打開sparse-checkout模式
$ echo "<current_paper_dir>" >> .git/info/sparse-checkout # 設(shè)置需要pull的論文目錄
$ git pull origin master
$ <edit_your_paper> # 修修補(bǔ)補(bǔ)你的寶貝論文
$ git pull origin master # 如果遠(yuǎn)程倉庫有新的修改,則pull下來合并族奢,可選
$ git push --set-upstream-to origin master # 第一次push需要設(shè)置本地分支和
# 遠(yuǎn)程分支的跟蹤關(guān)系姥闭,之后直接
# "git push origin"就可以
注意事項(xiàng):
-
git pull
操作相當(dāng)于git fetch
+git merge
操作組合。因此如果你不止想pull
遠(yuǎn)程倉庫里的master
分支越走,而是所有分支棚品,上述命令中的第一個(gè)pull
操作可以用git fetch origin
代替,后者默認(rèn)下載origin
服務(wù)器上所有分支,所取回的更新铜跑。這些分支在本地主機(jī)上要用"遠(yuǎn)程主機(jī)名/分支名"的形式讀取门怪,如remotes/origin/master
。 -
git fetch
之后本地是沒有分支的疼进,本地工作目錄也為空。需要在遠(yuǎn)程分支基礎(chǔ)上秧廉,使用$ git checkout -b <new_local_branch> origin/<remote_branch>
創(chuàng)建一個(gè)本地分支<new_local_branch>
伞广。
- 或者執(zhí)行
$ git checkout merge origin/<remote_branch>
將origin/<remote_branch>
合并到本地master
分支。如果當(dāng)前沒有分支疼电,git merge
會(huì)在本地創(chuàng)建master
分支嚼锄。
- 或先在本地
checkout
一個(gè)分支,然后執(zhí)行git branch --set-upstream-to=origin/<branch>
指定當(dāng)前本地分支跟蹤遠(yuǎn)程分支
Git寫Latex的流程
ref: https://stackoverflow.com/questions/6188780/git-latex-workflow
- 最好每一章一個(gè)單獨(dú)的tex文件蔽豺,因?yàn)檎撐牟恢懈耐兜臅r(shí)候可能需要換模板区丑。這時(shí)候?qū)⒚恳徽轮苯?code>\input到模板文件里就可以。
- 每句話一段修陡。Git的
diff
默認(rèn)以行為單位沧侥,而Latex只有在每段話前面有空行時(shí)才認(rèn)為是新的段落,所以每句話一段不影響Latex排版魄鸦,又可以方便Git做diff
宴杀。你甚至可以git diff --color-words
打開逐字比對的效果。 - 為每個(gè)
\section
開一個(gè)分支拾因。合作論文最常見的情況就是一個(gè)人寫一章旺罢,合作者寫/改另一章。為每一章開一個(gè)單獨(dú)的分支绢记,方便跟蹤進(jìn)度和合并扁达。 - 全局性的修改,如將整個(gè)論文中的“Section”改成“Chapter”蠢熄,做成單獨(dú)的
commit
跪解。導(dǎo)言區(qū)的修改也是如此。這樣無論是diff
或者patch
都很清楚做了什么修改签孔,不會(huì)和內(nèi)容修改相混淆惠遏。
和不使用Git的合作者合作
ref: http://www.math.cmu.edu/~gautam/sj/blog/20130929-git-quickstart.html
你沒有辦法讓你的合作者為了改你的論文在學(xué)會(huì)了Latex之后還專門去學(xué)Git,尤其是那些德高望重的合作者骏啰,比如你的導(dǎo)師节吮。而他們的意見和修改,一般來說是非聽不可的判耕。這時(shí)我們面臨的主要問題有兩個(gè):
- 記住交給合作者的論文版本
- 合作者返回時(shí)透绩,快速定位修改位置,并和你的當(dāng)前版本合并。
- 而你的當(dāng)前版本帚豪,可能已經(jīng)不是當(dāng)初交給合作者的版本了碳竟,甚至
push
到遠(yuǎn)程服務(wù)器了。(這不算第三個(gè)問題狸臣。)
有時(shí)候你會(huì)覺得合作者的意見并不那么靠譜莹桅,但是溝通還得繼續(xù),他仍然是你的導(dǎo)師烛亦,你必須得讓他知道你欣然接受了他的意見诈泼。這時(shí)候可以新開一個(gè)分支,用于接受合作者的意見并和他繼續(xù)往來溝通煤禽,而論文的實(shí)際發(fā)布版本則在另一個(gè)分支上铐达。
總之,我們需要一個(gè)叫做git-ident的Perl腳本幫我們自動(dòng)化這些事情檬果。步驟如下:
- 在你打算
commit
一個(gè)版本瓮孙,并將這個(gè)版本發(fā)給合作者之前,在當(dāng)前論文的根目錄下創(chuàng)建/修改.gitattributes
文件选脊,內(nèi)容為:*.tex ident *.bib ident
- 然后在你要發(fā)給合作者的主文件里杭抠,如
main.tex
,加上一句包含$Id$
的注釋恳啥,如:% DO NOT EDIT -> $Id$ <- DO NOT EDIT
- 安裝git-ident祈争,并在你的論文根目錄下添加它的post-commit hook:
$ cd .git/hooks $ ln -s /path/to/git-ident/post-commit
-
commit
或者checkout
你的論文,這時(shí)候Git會(huì)自動(dòng)將$Id$
替換為當(dāng)前版本的SHA1值(并不是你commit的版本號)角寸。
這時(shí)候你就可以把你最新的commit
的版本發(fā)給合作者了菩混,靜靜地等待他的修改,或者自己繼續(xù)寫下一章節(jié)扁藕。等他返回給你的時(shí)候沮峡,執(zhí)行
$ /path/to/git-ident/git-find-commit.pl <your_shared_tex_file>.tex
腳本會(huì)輸出你當(dāng)時(shí)交給合作者的commit版本號,比如b2234fa5
之類亿柑。根據(jù)這個(gè)版本號邢疙,你可以創(chuàng)建/轉(zhuǎn)到你的co-author分支,保存他的修改望薄,并merge
到你的當(dāng)前版本:
$ git checkout -b co-author b2234fa5
$ <save_his_file> # Save his file over yours
$ git commit --author 'Co Author <who@doesnt.use.git>'
$ git checkout my-writing
$ git merge co-author
當(dāng)你完成你對合作者這次修改的內(nèi)容的編輯之后疟游,可以重復(fù)這個(gè)流程,開始下一輪的“寫作-合作者審閱-討論并修訂”了痕支。
注意:git-ident
需要Perl環(huán)境颁虐,并安裝IPC::Run
和IPC::System::Simple
模塊。方式為:
- 執(zhí)行
sudo cpan
進(jìn)入cpan環(huán)境 - 執(zhí)行
install MODULE_NAME
安裝模塊
查看修訂
第一種辦法是用git diff
卧须,實(shí)現(xiàn)在tex源代碼上顯示差異另绩。缺陷就是Git以行為單位做diff
儒陨,而且tex源碼上看diff
非常不清晰。
第二種辦法是使用\usepackage{changes}
笋籽,這需要需要合作者在修訂的時(shí)候自己加標(biāo)注蹦漠,實(shí)在難為人。
第三種辦法就是用latexdiff
工具车海,一般TeX版本都自帶笛园,方法為:
$ latexdiff <old_tex_file>.tex <new_tex_file>.tex > <diff_file>.tex
當(dāng)我們采用每章一個(gè)tex文件的方式組織論文時(shí),latexdiff
需要加上--flatten
參數(shù)以展開main.tex
中的各種\input
侍芝,但效果并不好研铆。可以試試git-latexdiff工具
另外竭贩,latexdiff
得到的<diff_file>.tex
經(jīng)常容易出錯(cuò)蚜印,尤其在新老文件的\section
莺禁、\subsection
等名字不一致的時(shí)候留量。自己手動(dòng)把兩個(gè)文檔改成一樣的就行了。