A git quickstart guide for LaTeX users

2013-09-29

Git is a source control management system that you can use to track changes in any text file. Git, however, is quite complicated and learning it can be quite time consuming. This is a quick introduction to git for someone who will primarily use git to edit LaTeX/text documents (not code) and possibly collaborate with a handful of co-authors.

A few benefits of using Git

Here are a few benefits you get when using git.

Easily see changes made by co-authors

You can display word by word changes made in a form that looks like this:

@@ -3045,12 +3045,15 @@ \section{Proof of Proposition~\ref{ppnCLTFirstHitShort}}
We finally define the function $g$ that appearsappearing in Property (6).
Forfor $x = (q,\xi) \in \CM$, letby setting $g((q,\xi)) = \xi \in \mathbb{Z}^2$.

Or inspect changes line by line:

diff --git a/refs.bib b/refs.bib
index 349c0c3..65b8321 100644
--- a/refs.bib
+++ b/refs.bib
@@ -5556,7 +5585,7 @@
   pages                = {2636--2647}
 }

-@Book{           Rozovski90,
+@Book{           Rozovskii90,
   author       = {Rozovski{\u\i}, B. L.},
   title        = {Stochastic evolution systems},
   series       = {Mathematics and its Applications (Soviet Series)},

Or as a compiled PDF using latexdiff (setup instructions are here):

PDF diff

Easily merge changes made by co-authors

If you and a co-author are working on a file at the same time, git will NEVER allow you to accidentally overwrite each others changes because you “edited the wrong version”. In this case when you push your changes, git will inform you of a conflict. Often, if you and your co-authors edited different files, or even different parts of the same file, git can automatically merge your changes for you. If you and your co-author edited the same part of a file, git will inform you, and leave conflict markers in the file showing the differences. These look something like this:

In 1875, Galton and Watson~\cite{WatsonGalton75} took up an investigation into the phenomenon
of ``the decay of the families of men who occupied conspicuous positions in past times.''
<<<<<<< HEAD:paper.tex
The problem, posed by Galton, was summarized by the Rev. H. W. Watson as follows.
=======
The problem was summarized by the Rev. H. W. Watson as follows.
>>>>>>> fe933fa:paper.tex

Now you can edit the file, and tell git when you have “resolved all conflicts”.

Always have full access to old versions

With git you have full access to older versions at all times. (This, in some sense, is the point of version control). Some of the things you can do are:

  • Restore old versions, or temporarily view them, or compare them.

  • Search for when a phrase was first introduced.

  • Find out who/when a particular line was changed.

Compatible with Dropbox/Box/etc.

You don’t have to abandon your favorite cloud storage (like Dropbox, Box, Google Drive, etc.) to use git. If you use cloud storage to synchronize files on your computer, you can simply run git inside your “cloud folder”. (Look here for instructions on making git and dropbox work well together.) Main caveat: If you run git inside your cloud folder, be sure you only use that folder to synchronize between your own personal computers – don’t ever share this folder with a co-author otherwise there will be trouble.

Core Concepts

Setup

  1. The first thing you should do is install git. If you’re not a command line geek, then you might consider installing a GUI. I’ve heard good things about SourceTree, but there are many other choices.

  2. Introduce yourself to git. If your GUI client doesn’t let you do this directly, open a terminal and type:

    git config --global user.name 'Your Name'
    git config --global user.email you@math.youruniv.edu
    
  3. In order to share changes with others you will (almost surely) need an SSH key. If you don’t have one already, instructions on how do this can be found here. If you are using my git server to share changes, you will need to email me your SSH public key. This is usually a file called id_rsa.pub in your SSH directory (~/.ssh in Linux). Don’t ever share your private key (usually a file called id_rsa without the .pub extension).

Basic operations and terminology.

Cloning a repository.

Every paper is stored in a git repository. The first thing you have to do is to get the repository URL and then clone it. For papers on my git server the repository URL will look something like git@wiki.math.cmu.edu:papers/201401-xxx. Now you can clone the repository by typing following into a terminal.

git clone git@wiki.math.cmu.edu:papers/201401-xxx myfolder

or using your GUI client. (myfolder above is the name of a directory you want to use for this project.)

Pulling changes from the server.

To fetch changes that others might have made when you are away you have to pull them. Most GUI clients can do this directly. On a terminal, change to your project directory first and type

git pull

If you have any local changes, don’t worry. A git pull will never overwrite your changes. If your locally modified files have also been modified by others, then git will abort with an error message and you need to merge the changes (described below) to proceed.

Committing and Pushing your changes to the server.

You can edit the files in the project as you please. When you are done making changes and are ready to share them, you have to commit them and then push them. Committing tells git to save your current changes into your local git repository (not the server). Anything committed into git can be easily resurrected at any time, or compared to the current files or anything else committed into git. Once you have committed your changes, you should push them. This sends your changes to the server for other co-authors to pull.

Committing your changes

Most GUI’s will handle committing. If you prefer the terminal, use

git commit -a

to commit all locally modified files that are currently tracked by git. This will open an editor into which you can type a commit message. TYPE A USEFUL COMMIT MESSAGE. The first line of your commit message should be short, and is called the commit subject. You can optionally provide a more detailed explanation. To do this, leave one blank line after your commit subject and then type a longer message explaining your changes. When you are done, save your changes and close your editor to finish the commit.

Committing is actually a multi-step process: You’re supposed to first stage files by using

git add file.tex ...

and then commit them using git commit. The git commit -a above stages all locally modified files, and commits them. You can do this most of the time. The most common exception is when you create a new file. In this case you have to first add it using git add ... and then commit it. To see what files have been modified, staged, etc. use git status. (More detailed information is in the documentation here)

Pushing your changes

Committing your changes DOES NOT automatically push them. For others to see your changes, you have to push your changes. Most GUIs will handle pushing. On a terminal you can do this by typing

git push

This should work “most of the time”. Sometimes, git will abort with a message saying “Non-fast forward updates were rejected”. This happens when someone else made a change which you did not pull before making your changes. In this case, you have to pull their changes, merge them, and then push your changes.

Merging changes

In the normal workflow of a math paper with a handful of co-authors, you probably won’t have to perform too many merges. The most common situation is when someone else makes change while you are in the middle of yours. (Typically you’ll find out about this either from an email notification, or an error message saying “Non fast forward updates were rejected” when you try to git push.) Most GUIs should have a good way of dealing with merges. If you’re using a terminal instead, here are instructions:

  1. Commit your changes when you are done editing. (But don’t push them yet. If you already tried to push them, and got an error message that’s OK.)

  2. Run git pull (or better still git pull --rebase). One of the following will happen:

    • Your editor is opened with a commit message saying something like:

      Merge branch 'master' of ...
      

      In this case, just save the file and exit your editor. (In this situation if you had run git pull --rebase instead of git pull, you would not have the unfriendly Merge branch ... shenanigans to deal with.)

    • Git exits with an error message saying something about conflicts. This means that some remote change conflicted with some local change you made. Resolve this conflict.

    • Git succeeds.

  3. Push your changes back via git push. No matter what happened with the previous step, DO NOT forget this step.

Resolving conflicts

Conflicts arise when more than one person edited the same part of the same file. You might encounter it after doing a pull (via git pull, git pull --rebase) or a git merge. The status message should tell you what files are conflicted, and what you should do once you have “fixed the conflicts”.

You can fix these conflicts by opening these files in your editor, and searching for the conflict markers <<<<<<<, =======, >>>>>>>. Here’s what it will typically look like:

In 1875, Galton and Watson~\cite{WatsonGalton75} took up an investigation into the phenomenon
of ``the decay of the families of men who occupied conspicuous positions in past times.''
<<<<<<< HEAD:paper.tex
The problem, posed by Galton, was summarized by the Rev. H. W. Watson as follows.
=======
The problem was summarized by the Rev. H. W. Watson as follows.
>>>>>>> fe933fa:paper.tex

The text between <<<<<<< and ======= is what you wrote, and the text between ======= and >>>>>>> is what your co-authors wrote. Edit it to your taste, remove the conflict markers. Your conflict is now fixed. Type git status and follow the instructions. (This will typically involving marking your conflicts as fixed using git add, and the concluding the merge/rebase using git rebase --continue or git commit.) Once you’re done, don’t forget to push your changes back.

Some GUIs might help you with merging, if you don’t like the above. Alternately, you can also use git mergetool to help.

Tips and tricks

Once you’re a more seasoned user of git (on the terminal), here are a few tips that might help you.

Viewing Differences

This page has instructions showing you how to view differences between versions by words, lines or as a complied PDF using latexdiff.

Viewing History

git log shows history and has many options. Here’s a way to get colorful logs that are a bit easier to read. Put the following in ~/.gitconfig:

[alias]
lg = log --format='%w(72,0,8)%C(auto)%h%d %s'
lga = log --date=short --format='%w(72,0,8)%C(auto)%h %C(green)%cd \
        %<(20,trunc)%aN%C(auto)%d%n%w(72,8,8)%s'

Now git lg will show you a brief log, and git lga will show you a brief log with authors. The outputs look like this:

> git lg -5
0caf6bf (HEAD -> master) Avoid md.reset() when processing links
50bbc70 (origin/master, origin/HEAD) Used localhost for smtp.
95826b7 Fluids WG
b47d349 Delete unused files in output
b4a8b5d Added stochastic nucleation paper with Dan

> git lga -5
0caf6bf 2016-12-11  Gautam Iyer          (HEAD -> master)
        Avoid md.reset() when processing links
50bbc70 2016-11-12  Gautam Iyer          (origin/master, origin/HEAD)
        Used localhost for smtp.
95826b7 2016-11-11  Gautam Iyer         
        Fluids WG
b47d349 2016-11-11  Gautam Iyer         
        Delete unused files in output
b4a8b5d 2016-10-25  Gautam Iyer         
        Added stochastic nucleation paper with Dan

Using Git and Dropbox

If you’re using git in a Dropbox folder that you never share with anyone else, then you can “just do it” and nothing should go wrong. If however, you plan to share the folder with co-authors, you should be careful. Here are instructions on how to do this safely.

Sharing files with non-git aware co-authors.

If you use git, but your co-authors don’t you can still get many benefits of git when merging changes. This will also avoid fiascos where your co-author edits an older version of the file, and silently overwrites your changes. The trick to using git in this situation is to find the commit the co-author based his changes on, and create a branch for these changes. git provides a way to do this, but requires some work to set up:

  1. Edit (or create) .gitattributes and add the line

    *.tex text ident
    
  2. Add a line containing $Id$ to your LaTeX files. For instance,

    % DO NOT EDIT -> $Id$ <- DO NOT EDIT
    

    On checkouts (not checkins), git will replace this with the SHA1 sum of the blob identifier.

  3. Install git-ident.

  4. Install the post-commit hook from git-ident:

    cd .git/hooks
    ln -s /path/to/git-ident/post-commit
    

Now edit and commit your changes as you normally would. When you commit your changes, you’ll notice that the $Id$ token has been replaced with $Id: 987547... $. Share this file with your co-author (say over Dropbox, as described here). When they are done making changes and send it to you, run

git-find-commit.pl file.tex

(git-find-commit.pl is supplied with git-ident that was installed earlier.) This will output the commit hash of the file your co-author based his changes on. If this is what HEAD points to, then he made changes based on your latest version, and you can just save his version over yours and you’re good to go. If not, he made changes based on an earlier version (say ffffff). To merge it use

git checkout -b coauthor-v1 ffffff
# Save his file over yours
git commit --author 'Co Author <who@doesnt.use.git>'
git checkout master
git merge coauthor-v1

This way you keep the whole history in your git repository, and are guaranteed that your co-author hasn’t accidentally used an old version and overwritten your changes.

Further reading

Git, of course, is much more powerful than the simple use case described above. Here are links to more information:

📮 Leave a comment (Spammers beware: All comments are moderated)

Sorry. There was an error submitting your comment. Please try again, or contact me if the problem persists.
Sending comment; please wait.
Thanks. Your comment was successfully submitted. It will appear here shortly if it isn't spam.