用 Git 管理 Word 文档版本的方法,包括提交、对比、回退和协作。

Word 文档的版本控制,可以简单理解为对于多次修改产生的多种版本的 Word 文档进行控制与管理。我在论文的撰写过程中遇到需要反复修改文稿的问题,因此想要实现对 Word 文档的版本控制。我的需求大致可以概括为以下3点:

  • 版本间文字比对
  • 回退到指定版本
  • 版本信息备注

Git 是一种普遍使用的代码的版本控制方案,那直接使用 Git 管理 Word 文件不就可以了?我只需要在每次修改版本完成以后提交即可,也可以实现文字比对的功能。在每次提交时简要备注,也可以较为方便地标记版本信息。使用 Git 需要额外准备的,也仅仅是在电脑上安装 Git ,掌握几句 Git 命令语句即可。

Git 安装和学习的官方教程为 Git - Book (git-scm.com),也可以观看入门视频【GeekHour】一小时Git教程 ,最简单的 Git 使用仅需学会使用以下几条命令行即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 第一次使用 Git 时,需要配置用户名、邮箱
git config --global user.name "Your Name" # 配置用户名
git config --global user.email "mail@example.com" # 配置邮箱
git config --global credential.helper store # 存储配置

# Git基本命令3条
git init # 初始化 Git 仓库
git add <file> # 添加一个文件到暂存区; git add . 添加所有文件到暂存区
git commit -m "message" # 提交所有暂存区的文件到本地仓库

# Git常用命令3条
git log # 查看 Git 提交记录
git diff <commit-id> <commit-id> # 不同提交版本文件比对
git checkout <file> <commit-id> # 恢复一个文件到之前的版本

# Git tips
HEAD : 指向当前版本的指针,可替代版本id
HEAD^ : 指向上一版本的指针,可替代版本id
不添加和提交某后缀文件:创建 .gitignore 文件,写入 *.docx 表示不同步 .docx 文件

需要注意的是, Git 在提交 Word 时,对于文字变动显示并不那么友好,一个简易的折中办法是,可以在文档的每一句话结束后换行,这样即可在 Git 页面更清楚地比对是哪一句文字内容发生了变化,便于比对时定位修改句。

其实到这里,问题已经解决了,但如果 Word 版本数过多,每个 Word 文档体积又较大, Git 仓库的体积就会变得很大,从而造成较大的管理负担,因此需要一个更加优化的办法。

对于现有的 Git 管理 Word 文档的办法有2种优化方案:

第一种是利用 Pandoc 将 .docx 文件转换为其他便于 Git 管理的格式,如 Markdown 的 .md 文件。可以参照 Git配合Pandoc实现Word需求文档的迭代 来安装一个 Pandoc 就可以了,但这个办法的缺点也比较明显,就是仅仅优化了文本变动需求,而忽略了 Word 本身的其他功能如格式等的版本控制,对于论文需要插入参考文献的情景这个缺点尤其突出。

那为什么不直接使用 Markdown 进行论文的写作?这是一个听起来不错的解决方案,将工作流转到 Markdown 文件中也是有 Zotero 配套的优雅方案的。但是,由于我每次修改论文,都需要找老师或师兄师姐帮忙修改和提出建议,而对方往往会改好一份 Word 发回来,如果我在 .md 文档中做文本编辑,需要用 Pandoc 频繁地进行转换,并且这样做也不会解决格式控制的问题,而若为此转用 LaTex 来进行写作和排版,协作的时候还是要使用 Word ,也并不便捷。此外,我所修读的专业领域经常有杂志要求投稿格式为 Word ,使用 LaTex 反而显得繁琐,因此,我使用 Word 进行文稿写作则是绕不开的一个问题。

第二种办法是利用了 .docx.xml 文件的转换特性,可以参照视频 如何用 git 版本控制 word 文件 。这一方案可以保留 .docx 文件的原本信息,但其缺点就是对于文本变动的查看更加不友好。视频教程中的步骤可以文字概括如下:

  1. 将需要版本控制的文件 .docx 复制,后缀转为 .zip
  2. 使用压缩文件解压文件,得到一个主要由 .xml 文件组成的文件夹,存储了所有文件信息
  3. 每次 Word 文档内容准备提交时,仅提交其对应的解压文件夹
  4. 删除 .zip 后缀文件
1
2
3
4
5
6
7
# 也可以用 Git bash 命令行完成操作,需提前给变量 filename 赋值
cp ${filepath}/${filename}.docx ${filepath}/${filename}.zip # 复制.zip
mkdir ${filepath}/${filename} # 创建指定文件夹
unzip -o ${filepath}/${filename}.zip -d ${filepath}/${filename}/ # 解压至指定文件夹
rm ${filepath}/${filename}.zip # 删除.zip
# 在 1 行内完成以上内容使用 && 连接即可
cp ${filepath}/${filename}.docx ${filepath}/${filename}.zip && mkdir ${filepath}/${filename} && unzip -o ${filepath}/${filename}.zip -d ${filepath}/${filename}/ && rm ${filepath}/${filename}.zip

对于需要使用 Word 调整文档格式的情况,第一种方法的硬伤过于明显,因此我的选择便仅只有第二种办法了。原本在此处我没有发挥的空间,但该方法的原视频中并未具体说明如何将解压后的文件夹转回 .docx 的格式,这给新手的我造成过一点小麻烦,因此我在这里补充一下如何将解压后的文件夹中的内容转回 Word :

  1. .docx 后缀转为 .zip
  2. 使用压缩文件查看软件查看压缩文件
  3. 将需要还原的版本文件夹中的全部内容复制替换掉压缩文件中的内容
  4. 关闭压缩文件查看窗口,将 .zip 后缀改回 .docx
1
2
3
4
5
6
7
8
# 也可以用 Git bash 命令行完成操作,需提前给变量 filepath, filename, filenmae_n 赋值
cp ${filepath}/${filename}.docx ${filepath}/${filename}.zip # 复制.zip
cd ${filepath}/${filename} # 进入文件夹
zip -r ${filepath}/${filename}.zip ./* -x "${filepath}/${filename}.zip" # 替换内容
cp ${filepath}/${filename}.zip ${filepath}/${filename_t}.docx # 复制.docx
rm ${filepath}/${filename}.zip # 删除.zip
# 在 1 行内完成以上内容使用 && 连接即可
cp ${filepath}/${filename}.docx ${filepath}/${filename}.zip && cd ${filepath}/${filename} && zip -r ${filepath}/${filename}.zip ./* -x "${filepath}/${filename}.zip" && cp ${filepath}/${filename}.zip ${filepath}/${filename_n}.docx && rm ${filepath}/${filename}.zip

之后再打开这个 Word 文件,就会发现所有的文件内容都与需要还原的 Word 版本相同了。

Word文档版本控制命令速查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Git基本命令3条
git init # 初始化 Git 仓库
git add <file> # 添加一个文件到暂存区; git add . 添加所有文件到暂存区
git commit -m "message" # 提交所有暂存区的文件到本地仓库

# Git常用命令3条
git log # 查看 Git 提交记录
git diff <commit-id> <commit-id> # 不同提交版本文件比对
git checkout <file> <commit-id> # 恢复一个文件到之前的版本

# Git tips
HEAD : 指向当前版本的指针,可替代版本id
HEAD^ : 指向上一版本的指针,可替代版本id
不添加和提交某后缀文件:创建 .gitignore 文件,写入 *.docx 表示不同步 .docx 文件

【先命令行操作,后提交 Git ,即当前版本 Word 的解压文件夹】 .docx -> .zip -> 解压文件夹 -> 删除 .zip 命令行操作结果:当前版本 Word 、当前版本 Word 的解压文件夹(用于上传)

1
2
3
4
filepath=FILEPATH
filename=FILENAME

cp ${filepath}/${filename}.docx ${filepath}/${filename}.zip && mkdir ${filepath}/${filename} && unzip -o ${filepath}/${filename}.zip -d ${filepath}/${filename}/ && rm ${filepath}/${filename}.zip

【先指定 Git 的回滚版本,即目标版本 Word 的解压文件夹,后命令行操作】 .docx -> .zip -> 复制目标版本的解压文件夹到 .zip -> new.docx -> 删除 .zip 命令行操作结果:当前版本 Word 、目标版本 Word 的解压文件夹(用于下载)、目标版本 Word

1
2
3
4
5
filepath=FILEPATH
filename=FILENAME
filename_n=FILENAME_N

cp ${filepath}/${filename}.docx ${filepath}/${filename}.zip && cd ${filepath}/${filename} && zip -r ${filepath}/${filename}.zip ./* -x "${filepath}/${filename}.zip" && cp ${filepath}/${filename}.zip ${filepath}/${filename_n}.docx && rm ${filepath}/${filename}.zip