← Blog

Task 2.3 - Implimenting Git

TLDR

  • Switched the Zola MainSite from ad-hoc scp syncs to a Git/GitHub workflow.
  • Initialised a Git repo on the Pi, renamed the default branch to MainSite, and created a tagged v1.0.0 snapshot.
  • Connected the Pi repo to GitHub, pushed the MainSite branch and tags so GitHub is now the source of truth.
  • Enabled Git credential storage on both the Pi and Mac so pulls/pushes don’t keep asking for the PAT.
  • Cloned the repo to the Mac and tested the full Stage → Commit → Tag → Push loop, then pulled successfully on the Pi.

Task Requirements

I wanted the Zola MainSite to be versioned in Git, with GitHub holding the canonical repo so I’m not manually shuffling files over scp. Git should handle version tracking, tags, and history, while GitHub acts as the shared remote between the Pi and my Mac. I also wanted a solid mental model of Git’s core features (version tracking, staging, commits, branches, merges, diffs, history, reverting, resetting, tagging, ignoring via .gitignore, stashing, and local remotes over SSH) so the commands weren’t just magic incantations. Authentication needed to be lightweight: use a PAT, but cache it so I’m not typing it on every git pull or git push from either machine.

Goal

The goal was to make the Zola site live in a proper Git/GitHub workflow where GitHub is the single source of truth, and both the Pi and Mac simply clone, pull, and push. That removes scp from the picture, gives me proper history and tags for rollbacks, and standardises on a simple Stage → Commit → Tag → Push loop across all machines.

Implementation Steps

  1. I started by writing down a Git mental model: Git is a local tool first, with version tracking, staging, committing, branching, merging, diffing, history, reverting, resetting, tagging, ignoring via .gitignore, stashing, and even local remotes over SSH. That gave me a framework for what I was actually doing.

  2. On the Pi, I checked Git was installed:

    git -v
    

    It printed a version, so I knew I could go straight into initialising the repo.

  3. I moved into the Zola project directory on the Pi and initialised a new Git repo so MainSite would be under version control:

    cd MainSite
    git init
    

    This created MainSite/.git/, the folder where Git does its work.

  4. I configured my global Git identity so commits from the Pi would have consistent author metadata, redacting the real details here:

    git config --global user.name "[REDACTED USER]"
    git config --global user.email "[REDACTED EMAIL]"
    

    I also renamed the default branch from master to MainSite so the main branch name actually matches the project.

  5. With the repo initialised, I staged all the current project files so the initial snapshot would capture the entire MainSite state:

    cd MainSite
    git add .
    

    In my head: Stage is choosing what goes into the next snapshot.

  6. I created the first commit to lock in the current site as v1.0.0, using the version number directly in the commit message:

    git commit -m "v1.0.0"
    

    A commit is effectively a snapshot of the repo at that point.

  7. Because I care about rollbacks via versions, I tagged that initial commit so I can find it easily later. Tags always attach to the most recent commit, not to anything currently staged:

    git tag v1.0.0
    

    My mental pipeline is explicit: Stage → Commit → Tag, with rollbacks always done via tags, so their implementation matters.

  8. With a working local repo on the Pi, I created/used a GitHub repo for the site and wired the Pi’s local repo to that remote using origin:

    git remote add origin PATHHERE
    

    This is the step that replaces scp with Git.

  9. Before pushing, I set up a GitHub Personal Access Token (PAT) so I could authenticate over HTTPS. Once that existed, I pushed the MainSite branch from the Pi up to GitHub and set the upstream tracking:

    git push -u origin MainSite
    

    At that point, the site lived on GitHub instead of just on the Pi.

  10. I then pushed tags so v1.0.0 existed on GitHub as well as locally:

    git push --tags
    

    Now both the commit and its tag are visible on the remote.

  11. I documented my “emergency restore” mental model on the Pi: within the MainSite folder, if I want to force local files back to whatever the main branch currently is, I’d run:

    git reset --hard main
    

    And if I want to move to a specific tagged version, I’d do:

    git checkout tagname
    

    Commits create new versions, the old ones stay saved, and tags give me named points to jump to.

  12. I sanity-checked the GitHub connection by running a git pull on the Pi and seeing it respond with “up to date”, confirming the remote and branch tracking were wired correctly.

  13. To avoid constantly re-entering the PAT on the Pi, I read the Git credential storage documentation:

    • Git book: Git-Tools-Credential-Storage
    • Helper examples: git-credential-store docs
  14. Based on that, I configured the credential store helper so Git would cache my credentials locally:

    git config credential.helper store
    

    This uses a simple file-based store that remembers what I type once.

  15. After enabling the helper, I ran a Git command that required authentication (e.g. git pull), entered my username and PAT, and let the helper save them. When the token expires in ~90 days, the plan is simple: type the new PAT once and let the helper overwrite the stored value.

  16. I immediately tested the setup: first git pull prompted for credentials, I entered them; a second git pull didn’t ask for anything and just worked. That’s exactly the behaviour I wanted.

  17. With GitHub as the source of truth, I wrote down the pattern for getting the repo onto any machine (including the Pi or Mac) from scratch:

    git clone REPOURL
    

    That gives me a fresh working copy whenever I need one.

  18. I captured the core update workflow as a simple pipeline that I actually use now: Stage → Commit → Tag → Push:

    git add .
    git commit -m "description here"
    git tag v1.0.0
    git push --follow-tags
    

    Using --follow-tags is effectively git push plus git push --tags in one go.

  19. On the Mac, I implemented the same setup rather than just planning it: I created a folder for the clone (e.g. git-clone-mainsite), ran git clone against the HTTP URL, configured git config credential.helper store, edited files as needed, and then followed the same Stage → Commit → Tag → Push loop. That confirmed the full “edit on Mac, pull on Pi” cycle works end to end without scp.

Notes & Decisions

I anchored everything around the idea that Git is a local-first tool: it tracks every change, lets me selectively stage, and gives me commit history and tags so I can diff, revert, and reset without trashing the working tree. I like tags as the main rollback mechanism, so I’m deliberately treating rollbacks as “go to tag X” rather than messing with raw commit hashes. My mental model of GitHub is that every commit creates a new version, the old ones are automatically kept, and tags hang off specific commits while the branch pointer just moves forward. Historic commits are effectively read-only; I don’t edit them, I move the branch pointer or create new commits. I chose HTTPS + PAT for simplicity, then layered credential.helper store on both Pi and Mac so I’m not constantly typing the PAT, accepting that I’ll just refresh it every 90 days or so. Renaming the default branch to MainSite keeps the naming aligned with how I think about the project, and having the same Git workflow on both machines makes the whole thing feel consistent instead of hacky.

Next Ideas / Follow-ups

None captured yet.