(Last updated: May 12, 2016)


This note was written for our group as a minimal working example for collaborative writing using LaTeX and Git, and I'll keep updating this note. Below I show a step-by-step instruction to do version control using Git on the command line. The workflow is specifically designed for writing in LaTeX. Everything is tested on Mac with Git ver.2.3.2, so users of earlier versions should be careful. Please leave me a comment if you spot any mistake :)

Here's a list of steps (hyperlinked):
1. One-time-only setting
2. Clone an existing repository to local end
3. Change remote name
4. Push (pull) progress to (from) remote repository
5. Check the change log
6. Compare the difference between versions
7. Using a master BibTeX file as a Git submodule
8. Combining latexdiff and Git

****************************************

1. One-time-only setting.
Every time someone makes a change in the files, Git would record the submitter's name and email. Therefore, it's necessary to identify oneself in a collaboration work. Below shows how to set up a global Git config ("global" in the sense that every Git project you create on your laptop will use the same config):

[code gutter="false" language="bash"]
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
[/code]

This command lets you specify the default editor which will be used in git commit:

[code gutter="false" language="bash"]
$ git config --global core.editor vim
[/code]

For Mac users, one more action is necessary to automatically ignore the annoying .DS_Store file:

[code gutter="false" language="bash"]
$ git config --global core.excludesfile ~/.gitignore
$ echo .DS_Store > ~/.gitignore
[/code]

After above steps, there should be two hidden files placed in the home directory: .gitconfig and .gitignore.

2. Clone an existing repository to local end.
After you collaborators write up something (a draft or a program) and push it to an online repository like GitHub or Overleaf, you'd like to clone it so that you can edit the files on your laptop. Assume you are in a working directory where you'd like to create a folder named temp to store the files, type

[code gutter="false" language="bash"]
$ git clone http://git.example.org/123abc temp
[/code]

Note that the above URL link should be replaced by the one pointing to your own Git project! Now you can cd temp and start working.

3. Change remote name
If you run git status in the temp folder, the output message should look like:

On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean


Apart from the branch concepts (in the beginning we only have one branch called master), the "origin" seems confusing. But it is just a name representing the remote host, and you can change it to anything you want to make it clear (effective locally). For example,

[code gutter="false" language="bash"]
$ git remote rename origin overleaf
[/code]

will replace origin/master by overleaf/master.

4. Push (pull) progress to (from) remote repository
Suppose you edit some files, you may want to ask Git to record this version. When you run git status, you'll see files that you've edited but not yet "staged" (meaning Git does not know which file to look at yet). If so, do git add -u, where the -u argument means including all updated files. Run git status again to check the modified files are staged.

But to put staged file into Git's record, we need to "commit" them. Run git commit, and an text editor you specified earlier will be opened to let you type information related to this change. Save it and it's done. Now this version is recorded in your local machine. (If the message you'd like to type is just one line, you can do this in command line by git commit -m "This message will be logged".) Note that the two steps (add and commit) can be combined by git commit -a --- But use this carefully!

To sync the record between the local end and the remote repository, do

[code gutter="false" language="bash"]
$ git push overleaf master
[/code]

will upload the local master branch to "overleaf" (the name specified for the remote host). On the contrary, do

[code gutter="false" language="bash"]
$ git pull overleaf master
[/code]

will download the remote master branch on overleaf to local end. Caution: if you and your collaborators are working on the same branch (say you're writing a small-scale tex file on the master branch), it is highly recommended (see here and here) to use git pull --rebase overleaf master instead!

Two side notes: (i) pull is the combination of fetch and merge; (ii) pull and checkout are different. You use the latter to recover to earlier status when you mess up locally.

5. Check the change log
From the programmer point of view, the change log is extremely important as an essential ingredient of version control. To see the log, type git log. You will see a list of commit history in the following format:

commit 2277e9415a77ad89b142154a3a1b04be5730924b
Author: John Doe <johndoe@example.com>
Date: Tue May 10 19:35:35 2016 -0400


Each of these is called a revision with a 40-character identifier. But in practice, the first 6 characters are enough to identify a revision (in this case it's 2277e9).

6. Compare the difference between versions
See the instruction in the "Exploring History" section here. The key idea is to use the 6-character identifiers to do comparisons between revisions.

7. Using a master BibTeX file as a Git submodule
This step closely follows the blog by Andrius Velykis, and the main reason of doing this is to keep one and only one bib file up-to-date without forgetting where it is stored.

Suppose your collaborator or you maintains a bib file on a repository, named RefBib for instance, and you'd like to use it in your tex file. Three scenarios: (i) you just initiated a Git project for writing in LaTeX: in this case, simply run

[code gutter="false" language="bash"]
$ git submodule add git://example.org/user/RefBib
[/code]

to add that bib file as a submodule to your Git project, where the URL points to the repository of RefBib;

(ii) your local repository is out-of-date (without any submodule), and the remote repository is up-to-date (with a submodule recently added): in this case, first pull the latest revision as usual,

[code gutter="false" language="bash"]
$ git pull overleaf master
[/code]

and you may be prompted to input some message regarding this merge (pull involves a merge, remember?). The problem is after pulling the subdirectory of the module (see the discussion below) is empty, and a few more actions are required to make it work:

[code gutter="false" language="bash"]
$ git submodule update --init
$ cd RefBib
$ git checkout master
[/code]

Note that in the second step we need to go to the subdirectory for a reason explained below;

(iii) you have not created the Git project yet and would like to clone from an existing one: this case is like starting from Step 2 above. The only difference is that here the submodule RefBib is assumed existing in the project. Run

[code gutter="false" language="bash"]
$ git clone --recursive http://git.example.org/123abc temp
[/code]

and Git will first pull down the main project, then pull down the submodule (thanks to the --recursive argument), and merge them automatically.

Anyway, after doing so, run ls -al and you'll see inside temp there is a folder named RefBib, which stores the bib file, and a hidden file .gitmodules; both of them should be kept track by Git. Now you can include the bib file as you normally do in your tex file.

Git submodules are sometimes confusing, and there are some subtleties I'd really like to skip here, but basically the key idea is that you should regard temp and RefBib as two different Git projects, each has its own Git version history.

Therefore, if you modify the bib file in RefBib, you should remember to go to the RefBib directory, commit the change, and push it to the remote repository of RefBib so that the status can be synced between your local copy and the remote one. On the other hand, in the main branch temp Git simply notes in .gitmodules that there's a submodule RefBib (pointing to a specific revision!) but does not store the content of it. An alternative of getting around these steps is to run

[code gutter="false" language="bash"]
$ git push --recurse-submodules=on-demand
[/code]

so that both the main project and the submodule will be pushed to their corresponding repositories.

Similarly, if you'd like to update your local submodule to the latest version on remote, you can either go to the subdirectory and pull as usual (because it's a separate project), or stay in the parent directory and run

[code gutter="false" language="bash"]
$ git submodule update --remote
[/code]

Either way would work. For further details of submodule, see here.

8. Combining latexdiff and Git
LaTeX users probably know a convenient Perl script called latexdiff which marks up differences between two tex files. For version control systems such as Git, it has a counterpart called latexdiff-vc, which should already be installed along with latexdiff. The syntax is equally simple. Suppose you'd like to compare the current version of example.tex with that of a particular revision (assuming its 6-character identifier is 2277e9), run

[code gutter="false" language="bash"]
$ latexdiff-vc --git -r 2277e9 example.tex
[/code]

and latexdiff-vc will create a compared tex file for you, just like what latexdiff does. The argument --git tells latexdiff-vc that the version control system is Git, and -r 2277e9 specifies which revision to look at. For more sophisticated uses, see the latexdiff manual.

****************************************

I think these is the basics on Git. I've skipped things like branches (how to create one, to switch between them, to merge them, etc) and handling conflicts, but you can easily find instructions online. Here's a short list I found useful:
The Pro Git ebook
Duke-OSG Workshop material
How to synchronize an Overleaf LaTeX paper with a GitHub repository
Git and Overleaf