The Git guide

Git makes more sense
when you see the model.

Git is not really a collection of commands. It is a way of recording snapshots of a project and connecting those snapshots together. Once that picture clicks, the terminology becomes much less mysterious.

01 · Repository

What is a Git repository?

A repository is a project together with the history Git keeps for it. The hidden .git directory contains Git's internal information: commits, references, configuration and the data needed to reconstruct previous versions.

Underneath, that .git directory is really a small database of objects — blobs (file contents), trees (directory listings) and commits (snapshots) — plus a set of references that point at particular commits. Everything else Git does is built on top of that simple structure.

Think of it as: Your project + its complete Git history.
In Git Lizard

Opening a repository in Git Lizard means pointing it at a folder that contains a .git directory — either a fresh git clone or one you already have on disk. Once it's open, it stays in your Recent Repositories list, and every panel (graph, status, branches, Notes) is scoped to whichever repository is currently selected.

02 · Commit

A commit is a snapshot.

A commit records a version of your project at a particular point in time. It also contains metadata such as the author, message and links to the commit's parent snapshot.

Every commit is identified by a hash, computed from its contents — the snapshot, the parent(s), the author and the message. Change any of those and the commit gets a different hash, which is why editing history rewrites hashes downstream of the change. Most commits have exactly one parent; a merge commit has two, since it's the point where two lines of history join back together.

That means a history is a chain — or, with branches and merges, a graph — of snapshots.

$ git log --oneline
8f31a2d Add conflict editor
4bc19ef Improve status view
91a73c1 Initial Git Lizard prototype
In Git Lizard

Every dot in the commit graph is one of these snapshots. Click a dot and Git Lizard shows the full diff, author, timestamp and message without you leaving the graph view — and merge commits are drawn with two incoming lines so you can see exactly which branches they joined.

03 · Branch

A branch is a movable name for a line of history.

A branch does not copy your project. It is essentially a name pointing at a commit. Creating a branch gives you a separate line of development while the existing history remains intact.

Because a branch is just a pointer, creating one is instant — Git isn't duplicating any files. As you commit while a branch is checked out, that branch's pointer automatically moves forward to the new commit. This is also why branches are so cheap in Git compared to some other version control systems: it's normal to create a new branch for every small piece of work and delete it once it's merged.

Example: main → stable history  ·  feature/login → your new work
In Git Lizard

The branch switcher lists every local and remote branch. Picking one checks it out and re-centers the graph on that branch's line of history, so you can see at a glance how far it's diverged from main. Creating a new branch from the current commit is a single action — no need to remember the underlying git branch / git checkout pair.

05 · Staging

The staging area is your next snapshot.

When you edit a file, the working tree changes. When you stage it, you tell Git which version of that file should go into the next commit.

This middle step — often called the "index" — is what lets a commit be smaller or more focused than everything you've changed. You can stage only some of the files you've edited, and Git will even let you stage part of a file: individual hunks, or individual lines, so one commit doesn't have to bundle unrelated changes together.

Working treeYour current files
Staging areaWhat the next commit will contain
CommitThe saved snapshot
In Git Lizard

The Status view mirrors this model directly: unstaged changes on one side, staged changes on the other. Each modified file expands into a diff with hunk-level checkboxes, so you can stage exactly the lines that belong in a given commit and leave the rest for later — without touching the command line.

06 · Remote

A remote is another copy of the repository's history.

A remote such as a GitHub repository gives your local repository somewhere to exchange commits with. The remote is not your project itself — your local repository is still a complete Git repository.

That distinction explains why you can commit without an internet connection.

Git keeps track of a remote's branches using remote-tracking branches — names like origin/main, which represent where main was on the remote the last time Git checked. They only update when you fetch or pull; they don't move on their own, which is exactly what lets you compare your local branch against the remote before doing anything.

In Git Lizard

Remote branches show up in the graph alongside your local ones, labelled with the remote's name, so you can see at a glance whether your local branch is ahead of, behind, or diverged from origin. Adding a remote — GitHub, GitLab, or a private server — is a one-time step in the repository settings.

06b · Fetch vs pull

Fetch downloads. Pull downloads and merges.

git fetch updates your remote-tracking branches (origin/main) with whatever is new on the remote, but it never touches your own branches or working tree. It's a safe way to see what's changed before deciding what to do about it.

git pull is effectively a fetch followed by a merge (or, depending on configuration, a rebase) of the remote-tracking branch into your current branch. It's more convenient, but it changes your working history immediately, which is why some people prefer to fetch first and merge deliberately.

In Git Lizard

The toolbar keeps Fetch and Pull as separate buttons for exactly this reason. Fetch quietly updates the graph with incoming commits on origin/main so you can inspect them first; Pull fetches and merges them into your current branch in one step, and Git Lizard will flag it up front if that merge is likely to conflict.

07 · Merge

Merging joins two lines of history.

Suppose main and feature/login have both moved forward. A merge combines the histories so the changes from the feature can become part of the target branch.

If the target branch hasn't moved since the feature branch split off, Git can just move the target's pointer forward to the feature's latest commit — a fast-forward merge, with no new commit needed. If both branches have moved independently, Git instead looks at the two branch tips and their common ancestor, works out what changed on each side since that ancestor, and combines both sets of changes into a new merge commit with two parents.

If both branches changed the same part of a file in incompatible ways, Git cannot safely choose for you. That is a merge conflict — covered in detail next.

In Git Lizard

Merging a branch is a single action from the graph or the branch switcher. Git Lizard shows you up front whether the merge will fast-forward cleanly or need a real merge commit, and after a merge, the graph makes the join point visually obvious — two lines converging into one commit.

07b · Conflicts

A conflict means Git needs you to decide.

When a merge can't be resolved automatically, Git stops partway through and marks the affected files directly, using conflict markers:

<<<<<<< HEAD (ours)
maxAttempts = 5
=======
maxAttempts = config.retryLimit
>>>>>>> feature/ledger-v2 (theirs)
Everything between the markers is both versions, side by side — Git is asking you to pick, combine, or rewrite.

Everything above the ======= line is "ours" — the version on the branch you're merging into. Everything below, up to the closing marker, is "theirs" — the version coming in from the branch being merged. Resolving the conflict means editing the file down to what it should actually say, removing the markers, then staging and committing the result.

In Git Lizard

Rather than handing you raw conflict markers, Git Lizard's conflict editor shows the "ours" and "theirs" changes side by side with the surrounding code for context, and can propose a resolution based on what both changes appear to be trying to do — like combining a hardcoded default with an incoming config-driven value instead of picking one and discarding the other. You can accept the suggestion as-is, edit it, or resolve the conflict manually — the suggestion is always a starting point you can inspect, never something applied silently.

08 · Push

Push sends your commits to a remote.

Push uploads the commits on your current branch to the matching branch on a remote, so anyone with access can see and pull them. Git will refuse a push if the remote branch has commits you don't have locally — you need to pull (or fetch and merge) first, so you never accidentally overwrite someone else's work.

It's possible to override that check with a force push, which replaces the remote branch's history with your own. It's occasionally necessary — after rewriting local history, for instance — but it can discard other people's commits on that branch, so it's worth treating as a deliberate, rare action rather than a routine one.

Simple mental model: Commit locally → push your commits → pull other people's commits.
In Git Lizard

The push button shows how many commits you're ahead of the remote before you click it, and a rejected push (because the remote has moved on) surfaces as a clear prompt to pull first rather than a cryptic error. Force pushing is a separate, explicitly labelled action — not something a normal push can do by accident.

09 · Git Lizard Notes

Not core Git, but part of the workflow.

Git itself has no concept of project notes — this one is specific to Git Lizard rather than something git the command-line tool does. Git Lizard Notes stores plain Markdown files in a .gitlizard folder inside your repository, so plans, decisions and TODOs travel with the project instead of living in a separate app.

Because that folder is just regular files on disk, it's tracked like anything else: it shows up in the status view when you edit a note, and it can be staged, committed and pushed the same way as code — which means your notes have their own history too, and teammates who pull the repository get them automatically.

In Git Lizard

The Notes panel sits alongside the graph and status views, so you can jot down why a conflict was resolved a certain way, or what a branch is for, without leaving the repository or switching to a separate wiki.

The big picture

Put the pieces together.

You edit files in your working tree. You stage the changes you want. You commit a snapshot. Branches give those snapshots different lines of development. HEAD tells you where you are. Remotes let repositories exchange history. Merges bring lines back together.

working tree
→
staging
→
commit
→
branch history

That is the core of Git. The commands are interfaces to this model — and here's roughly what that looks like end to end inside Git Lizard.

  1. Open the repository.Pick it from Recent Repositories, or clone a fresh one from a remote URL.
  2. Check the status.See what's changed in the working tree since your last commit, file by file.
  3. Stage what belongs together.Check off whole files, or individual hunks, to build a focused next commit.
  4. Commit.Write a message and save the snapshot — it appears immediately in the graph.
  5. Branch for new work.Create a branch before starting something separate from what's on main.
  6. Fetch, then pull.Check what's new on the remote, then merge it into your branch when you're ready.
  7. Merge, resolving conflicts with AI assistance if needed.Review any suggested resolution, edit it, or resolve manually — then commit the merge.
  8. Push.Send your finished commits to the remote so the team — and your notes — stay in sync.