LaTeX Git Version Control like a Pro

No more FINAL_FINAL.tex chaos – tame your .tex, .bib, and graphics with an offline‐only LaTex Git workflow that follows you from MacBook/Windows to Linux, and back again.

I first went fully offline with LaTeX when my supervisor warned me that cloud-based editors can be vulnerable, and that my unpublished work deserved better protection. So I ditched Overleaf and installed TeXShop on my MacBook. Suddenly I had to learn to troubleshoot compilation errors by hand, no AI smoothing out my mistakes, so my LaTeX chops grew by leaps and bounds. And the payoff was that if it compiled on my Mac, it compiled for my reviewers, too. No one likes wrestling with “missing package” errors before they even read your text.

Once I’d mastered offline editing, another pain point emerged: version madness. Every draft spawned paper_V1.tex, paper_V2.tex, paper_FINALcopy.tex… you get the picture. And after the peer-review feedback for my first paper rolled in, I was spending half my day comparing the different versions, creating fresh folders, deleting .aux files, zipping up only the sources I wanted, and emailing them off. There had to be a better way!

Turns out, there is. You can use Git entirely offline. No GitHub, no public repos. Just you, your MacBook, and even a portable external drive that you can plug into your uni’s Linux workstation.

Here’s the guide I wish I’d had when I first made the switch.

    macOS (Homebrew installed) (I’m pretty sure Windows should work too)

    Linux workstation (any distro, with USB access)

    External drive (formatted HFS+, ext4, or exFAT so both OSs can read/write)

    Basic comfort with the terminal (we’ll keep commands super straightforward!)

    On macOS
    Zsh
    brew install git
    brew install latexdiff
    On Linux
    Zsh
    # Debian/Ubuntu
    sudo apt update
    sudo apt install git latexdiff
    
    # Fedora/CentOS
    sudo dnf install git latexdiff
    
    – Create your project folder
    Zsh
    mkdir -p ~/Writing/my-paper
    cd ~/Writing/my-paper
    
    – Initialize it
    Zsh
    git init
    
    – Add your sources
    Zsh
    git add *.tex *.bib images/
    git commit -m "Initial LaTeX skeleton"
    
    – .gitignore

    The .gitignore file tells Git which files or directories it should leave out of version control – things like .aux, .log, or system files (.DS_Store) that you don’t want cluttering your repo. By listing those patterns in .gitignore, you keep your history and shared snapshots clean of build artifacts and temporary files.

    Create a file named .gitignore. Creating and populating a .gitignore is as simple as making a new text file and listing the patterns you want Git to skip.

    Zsh
    touch .gitignore              # makes an empty .gitignore file
    

    You can use any text editor to edit this file, in the terminal or GUI. For example, with nano:

    Zsh
    nano .gitignore

    Then paste in your ignore rules. Save (Ctrl + O), then exit (Ctrl + X).

    Zsh
    # LaTeX build artifacts
    *.aux
    *.log
    *.toc
    *.out
    *.lof
    *.lot
    *.gz
    *.pdf
    
    # macOS metadata
    .DS_Store
    

    Then, tell Git to track that file and ignore everything you listed:

    Zsh
    git add .gitignore
    git commit -m "Ignore build artifacts"
    

    Because your repo only tracks the files you actually need (and ignores all the build junk), any time you share or archive it – whether via git archive, a simple git clone, or a zip of the folder – you’ll get a clean bundle containing just your .tex, .bib, images, and any other source files. Your collaborators never have to wade through .aux or .log files.

    Edit paper.tex, references.bib, and graphics in TeXShop.

    Decide which files belong in your next checkpoint. Maybe it’s just paper.tex , updated references file, and a graphic.

    Stage changes. You’re telling Git, “Hey, include these exact changes in the next snapshot.” Git collects all the edits you’ve explicitly added into its index (a temporary holding area).

    Zsh
    git add paper.tex references.bib images/fig3.png
    

    Commit your snapshot with a clear message.
    You’re saying, “Okay, Git—take everything in the index right now, bundle it up as a new version, and label it with this message.”

    Zsh
    git commit -m "Clarified methods section; updated Fig. 3"
    

    View history anytime:

    Zsh
    git log --oneline
    
    Quick Shortcuts

    Commit all tracked file edits at once
    If you’ve only modified files Git already knows about (no brand-new files), you can skip the separate add step with:

    Zsh
    git commit -am "Your concise description of what changed"

    The -a flag auto-stages any modified or deleted tracked files before the commit.

    Stage everything – new, changed, or deleted files – in one go.

    Zsh
    git add -A
    git commit -m "Everything up to date"
    

    That’s handy when you want to snapshot “all the things” without naming each file.

      Plain-Text Diff
      Zsh
      git diff        # your working edits vs. last commit
      git diff --staged  # staged changes vs. last commit
      
      LaTeX-Aware PDF Diff
      Zsh
      latexdiff-vc --git paper.tex > diff.tex
      pdflatex diff.tex
      open diff.pdf   # or xdg-open on Linux
      

      Your resulting PDF highlights insertions in blue and deletions in red – ideal for spotting exactly what has changed between versions.

      We’ll keep a bare Git repo on the drive so you can push/pull from both machines.

      Create a bare repo on your USB drive (e.g. /Volumes/Backup/tex-repo.git):

      Zsh
      cd /Volumes/Backup
      mkdir tex-repo.git
      cd tex-repo.git
      git init --bare
      

      Add it as a remote in your MacBook project:

      Bash
      cd ~/Writing/my-paper
      git remote add usb /Volumes/Backup/tex-repo.git
      git push usb main
      

      On Linux, clone from the drive:

      Bash
      git clone /mnt/backup/tex-repo.git ~/Writing/my-paper
      cd ~/Writing/my-paper
      

      Work & commit on Linux, then:

      Bash
      git push origin main
      

      Back on macOS, update with:

      Zsh
      git pull usb main
      

      When you need to send your supervisors the current source bundle, no .aux files, no .log cruft, just run:

      Zsh
      cd ~/Writing/my-paper
      git archive --format=zip --output=paper-for-review.zip HEAD
      

      That ZIP contains only your tracked .tex, .bib, and images/ folders and nothing else.

      – Branch for big rewrites:
      Zsh
      git checkout -b discussion-rewrite
      # …edit…
      git commit -m "Revamped discussion section"
      git checkout main
      git merge discussion-rewrite
      
      Tag milestones:
      Zsh
      git tag -a v1.0 -m "Submitted first draft"
      git push usb --tags
      
      Recover an old file:
      Zsh
      git show HEAD~2:paper.tex > old-intro.tex
      

      Now, you can to track every edit, compare changes, backup your repo, and share polished source bundles with your supervisors, colleagues, or publishers, like a pro! No more “which file was the real FINAL,” and no more manual folder clean-ups before sharing. Now you can focus on the words, and let Git handle the rest. And all of that, offline, in case you are, like me, concerned about safeguarding your intellectual property.

      Keeping all of your graphics in one place, and teaching both Git and LaTeX to find them, makes your workflow smoother.

      Create a dedicated folder

      Markdown
      my-paper/
      ├ paper.tex
      ├ references.bib
      └ images/
          ├ fig1_overview.png
          ├ fig2_results.pdf
          └ diagram.svg
      

      Tell LaTeX where to look.

      In your preamble (before \begin{document}), add:

      LaTeX
      \usepackage{graphicx}
      \graphicspath{{images/}}
      

      Now you can write:

      LaTeX
      \includegraphics[width=0.8\linewidth]{fig2_results.pdf}
      

      without needing images/fig2_results.pdf each time.

      Stage them all at once.

      Whenever you add, update, or delete a graphic, simply:

      Zsh
      git add images/
      git commit -m "Add/update figures"
      

      Git will pick up every new or changed file in images/ in one go.

      Keep names descriptive & version-friendly.

      fig3_experiment1.png instead of image3.png.

      Avoid spaces or special characters.

      If you need a revised version, overwrite the old file (Git still stores the history).

      With this setup, LaTeX compiles seamlessly, Git tracks every figure, and you never have to juggle per-file adds or fight with relative paths again. Your images folder becomes a single source of truth, both for you and for anyone you share your repo with.

      💌 Want More?

      I’d love to hear what tools or setups you’re using! Drop a comment below, shoot me an email, or say hi on YouTube.

      1. Beni Cherniavsky-Paskin Avatar

        Some git/collab tips, based on my wife’s experience:

        – Overleaf is as user-friendly as LaTeX gets for collaborators who don’t want to deal with version control and conflicts.

        – You can mix those naive collaborators with Git power users! There are 2 ways [https://docs.overleaf.com/integrations-and-add-ons/git-integration-and-github-synchronization]:
        1. GitHub sync allows full Git[Hub] experience but has more moving parts. You need to deal with users & permissions on both sites (e.g. make sure the GitHub project is private!)
        2. Direct git clone/pull/push git.overleaf.com! Has limitations but IMHO a better starting point. Main limitation is editing in the browser does NOT create fine-grained git snapshots — even on paid account with fine-grained History shown on web. Those are 2 separate histories. Commits are only created when they “label” a version in web UI, and when you `git pull`, so make sure to pull regularly.

        – Overleaf has pretty advanced “Track changes” and Commenting [https://docs.overleaf.com/collaborating/commenting] functionality. That helps review & keep track which review TODOs have been addressed, kinda like in Google Docs 🗨 🗩. But note those comments never touch the LaTeX source, so are invisible in git / github.

        – If you prefer in-document comments, LaTeX has several packages [https://tex.stackexchange.com/questions/9796/how-to-add-todo-notes], notably todonotes. Better than simply talking in `% TODO` comments 🙂 There are of course ways to suppress comment rendering for submission, while still keeping them in the source. A nice tip is make `\newcommand` macro(s) a for each collaborator to use, for per-person color and/or name.

        – `latexdiff` and `latexdiff-vc` you already mentioned, but worth a 2nd mention ✨ They’re is the main thing people who “already know git” may miss.

      Leave a Reply to Beni Cherniavsky-Paskin Cancel reply

      Your email address will not be published. Required fields are marked *