Module 2: Git from Scratch for Automators

6. Push to GitHub: backup and shared work

Description

By the end of this lesson you will be able to take your repository off your machine and put it somewhere safe on the internet, where it can be backed up and shared. You'll understand what a remote is —a copy of your repository hosted somewhere else— and why Git is distributed, you'll create a repository on GitHub, and you'll handle the four commands connecting your machine with that copy: git remote to link them, git push to upload your history, git pull to download what others upload, and git clone so someone else can get a complete copy. And you'll see why GitHub covers —for free— that "sharing workflows between users" thing the Community edition of n8n doesn't provide natively.

This matters for two reinforcing reasons. The first is survival: so far your entire history lives on a single disk, your machine's, and if that disk fails, it's all lost. A remote is your backup. The second is collaboration: a history locked up on your machine is useless to anyone else. Once it's on GitHub, your coworker can clone it, work on her branch, and send her changes back to you. It's the leap from "I version my workflows" to "my team versions its workflows," which is what the market asks for when it talks about delivering "version-controlled JSON" that others can review.

Connection to the module: lessons 2 through 5 were entirely local —everything happened on your machine, with no internet. This one opens the door to the world. Lesson 5's branches take on their full meaning here: in a shared flow, each person works on their own branch and pushes it to GitHub. Lesson 4's diffs are how you review what a coworker pushes before accepting it. And this connects directly to Module 1: there we saw that n8n's Community edition doesn't include source control or the "sharing between users" that the paid editions do; GitHub covers that gap at no cost, and Module 6 revisits that decision with honesty.

What a remote is, and why Git is distributed

Let's start with a property of Git that makes it different from almost everything you know. When you save a document in Google Docs, the document's "truth" lives on Google's servers; your browser just shows a window into that truth. Git doesn't work that way. In Git, every copy of the repository is complete: it has all the history, all the commits, all the branches. The copy on your machine isn't a window into an original living somewhere else; it's an original in itself.

That's called Git being distributed: there's no "central server" that's the sole owner of the truth. There are copies, all complete, that sync with each other when you ask them to. Your machine has a copy. GitHub has another. Your coworker will have a third. All three have the entire history, and every so often they agree with each other.

A remote is, simply, another copy of your repository living somewhere other than yours, and that your Git knows how to connect to. Normally that "somewhere else" is an internet service like GitHub, but conceptually a remote could be a disk on another machine in your office. What makes it "remote" is that it's not your local copy; it's a copy you sync with.

Think of it as two people with identical notebooks writing the same things down. You have your notebook (your local repository) and there's another notebook kept in a safe (the remote on GitHub). Every so often you open the safe and copy into its notebook what you wrote in yours —that's git push, pushing your changes toward the remote. And every so often you copy into your notebook what others wrote in the safe's one —that's git pull, pulling the remote's changes toward you. Both notebooks are complete and valid on their own; the safe just adds security and a meeting point for several people.

This property has a very reassuring practical consequence: you can keep working without internet. Since your copy is complete, you make commits, create branches, read diffs, and get the entire history while disconnected. You only need internet for the two sync moments: push (upload) and pull (download). Everything else is local.

GitHub: what it is and why we use it

A remote needs to live somewhere. GitHub is a website that hosts Git repositories: you give it a copy of your repository and it saves it, backs it up, and serves it to whoever you authorize. It's by far the most popular one, but it isn't the only one —GitLab, Bitbucket, and others exist, doing the same thing. For this guide we use GitHub because it's the market standard and its free plan is more than enough for what we need.

Here it's worth separating two names lesson 1 already distinguished, because this is the moment the distinction becomes tangible. Git is the program on your machine keeping the history; you've used it for the previous four lessons without touching the internet. GitHub is the site where you host a copy of that history. You don't need GitHub to use Git —you've proved it— but you do need something like GitHub to back up and share. Only now, in lesson 6, does GitHub enter the picture, and it enters because you already have something to push.

It's worth connecting this to what we saw in Module 1. There we were honest about a limitation of n8n's Community edition —the free one, the one this guide defaults to: it doesn't include native version control or a built-in feature to share workflows between users; those capabilities live in the paid editions (Enterprise/Cloud). GitHub covers exactly that gap, at no cost. With your workflow in a GitHub repository, you have version control (the kind you learned) and a place where another team member can get the workflow, propose changes, and send them back to you. It isn't exactly the same as n8n's native source control —Module 6 compares the two paths and gives you the criterion for deciding when a paid version is worth it— but for a small team like Cumbre's, the repository-on-GitHub flow solves the problem at zero cost.

Public and private: a decision that matters

When creating a repository on GitHub you choose whether it's public (anyone on the internet can see it) or private (only you and whoever you invite). For a company's workflows, the default answer is clear: private.

The reason is twofold. First, a workflow is company business logic —how Cumbre classifies and routes its orders isn't something you want to publish. Second, and more delicate: even though in lesson 3 we said credentials must never enter the repository (and Module 3 formalizes it with credential separation), a workflow's JSON can contain traces you don't want exposed —internal URLs, system names, data structures. A private repository gives you a safety margin. The simple rule: work-related workflow repositories go private unless you have a deliberate reason to make them public. A practice repository of yours can be public without a problem; cumbre-automations with real logic, private.

Authentication: the part that changes over time

Before pushing anything, an honest warning. For GitHub to let you push changes to your repository, it has to be sure it's you. That step —authentication— is the part of this lesson that has changed the most over the years and the most likely to be different by the time you read this, so I handle it carefully and point you to the official source for the exact details.

The important thing to know: GitHub no longer accepts your regular password for Git operations from the terminal. It stopped in 2021, for security. Today there are two main paths, and either one works:

  • Personal access token (PAT) over HTTPS. A PAT is like a special password, long and revocable, that you generate in your GitHub account settings and use instead of your password when Git asks for it. It's the simplest path to get started.
  • SSH key. A pair of cryptographic keys —a public one you give GitHub and a private one that stays on your machine— that authenticate without typing anything each time. More convenient long term, but with more initial setup steps.

In practice, on many modern systems, the first time you do git push a wizard shows up —the Git Credential Manager— that opens your browser for you to sign into GitHub and saves the authorization for you, without you having to generate a PAT by hand. If that happens, follow the wizard and you're done. If not, you're going to need to generate a PAT or set up an SSH key following GitHub's official guide, which is always up to date and explains each step with screenshots.

I'm not going to reproduce the exact clicks here because they'd age badly: GitHub's button names and screens change several times a year. What doesn't change is the concept —you have to prove to GitHub that you're you, with a PAT or with SSH— and where to look for it, which is in the resources at the end. I'll date this piece of information, like anything volatile: as of July 2026, PAT over HTTPS and SSH keys are the two current paths, and the browser wizard is the most common thing when getting started.

Connecting and pushing: remote, push, clone, pull

With the concept clear, let's go through the complete flow. It's four commands.

Worked example: push cumbre-automations to GitHub

Step 1 — Create the empty repository on GitHub. Go to GitHub (create an account if you don't have one; the free plan is enough), and create a new repository. On the creation screen:

  • Name it cumbre-automations, same as your local folder. They don't have to match, but it helps avoid confusion.
  • Choose Private, for the reasons above.
  • Do not check the options for "initialize with a README," ".gitignore," or "license." This is key: your local repository already has commits, and you want to push those. If GitHub creates the repo with its own files, the two histories clash and complicate the first push. Create it completely empty.

When it's done, GitHub shows you a page with instructions and, above all, the repository's URL, something like https://github.com/ana-cumbre/cumbre-automations.git. That URL is your remote's address. Copy it.

Step 2 — Connect your local repository with the remote. Back in your terminal, standing in cumbre-automations, tell Git where the remote lives:

# git remote add <nickname> <url>: registers a remote with a nickname.
git remote add origin https://github.com/ana-cumbre/cumbre-automations.git

What to expect. The silence of success: nothing. Let's break down the command, because it has a piece that confuses people:

  • git remote add means "register a new remote."
  • origin is the nickname you're giving this remote. By universal convention, the main remote is called origin —it's not a magic word, it's just custom, like calling your main address "home." You could name it something else, but everyone uses origin and it's worth following the custom.
  • The URL is the address you copied from GitHub.

Confirm it got registered:

git remote -v
origin	https://github.com/ana-cumbre/cumbre-automations.git (fetch)
origin	https://github.com/ana-cumbre/cumbre-automations.git (push)

It shows up twice —one for fetch (download) and another for push (upload)— because Git technically lets you download from one place and push to another; in practice they're the same URL. What matters is that origin now points to your GitHub repository.

Step 3 — Push your history to the remote. The moment of sending it:

# -u links your local main branch with the remote's, for future pushes.
git push -u origin main

This is where the authentication step might show up —the browser wizard, or a request for your PAT. Resolve it based on what your system shows you.

What to expect once authenticated:

Enumerating objects: 12, done.
Counting objects: 100% (12/12), done.
Compressing objects: 100% (10/10), done.
Writing objects: 100% (12/12), 4.21 KiB | 4.21 MiB/s, done.
Total 12 (delta 3), reused 0
To https://github.com/ana-cumbre/cumbre-automations.git
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.

It's more verbose than other commands, but the lines that matter are at the bottom. * [new branch] main -> main: your local main branch got created on the remote. And branch 'main' set up to track 'origin/main': your local main is now linked with the remote's main —that's what the -u did— which means from now on you can do git push and git pull bare, without repeating origin main every time. The -u is only needed the first time per branch.

You did it: your entire history is safe on GitHub. If you open your repository's URL in the browser, you're going to see your order-triage.json and, in the commits tab, the whole history you built —Add order-triage workflow, Widen CRM lookup timeout, Add wholesale category— each with your name and its date. That's the backup and the meeting point we were looking for.

Step 4 — The everyday flow: push and pull. From here on, your cycle has one more step. You work locally as always —edit, add, commit— and when you want to back up or share your work, you push it:

git push

(No origin main, because the -u already linked the branch.) What to expect: a summary similar to the first push, but shorter, ending in something like a91c3f8..b2c4d6e main -> main, which tells you what range of commits went up.

And when you want to bring in what others have pushed to the remote:

git pull

What to expect, if there's nothing new: Already up to date. If there are changes from someone else, Git downloads them and merges them with your work, showing you a summary like the diffs you already know how to read. pull is, at bottom, "download what's new from the remote and merge it with mine" —that's why, when there are conflicting changes, it can ask you to resolve a merge conflict, exactly as you saw in lesson 5.

How your coworker gets the workflow: git clone

The other side of collaboration. When someone new on the team needs the repository —or when you need it on another machine— it isn't created from scratch: it gets cloned. Cloning is downloading a complete copy of the repository from the remote, with all its history and all its branches.

Your coworker, on her machine, runs:

# git clone <url>: downloads a complete copy of the repository.
git clone https://github.com/ana-cumbre/cumbre-automations.git

What to expect:

Cloning into 'cumbre-automations'...
remote: Enumerating objects: 12, done.
remote: Total 12 (delta 3), reused 12
Receiving objects: 100% (12/12), 4.21 KiB | 4.21 MiB/s, done.
Resolving deltas: 100% (3/3), done.

Git creates a cumbre-automations folder with order-triage.json inside and the entire history in its .git. Notice what didn't need to happen: she didn't run git init, or git remote add —cloning configures the origin remote automatically, pointing at the URL she cloned from. From that moment, she has a complete, independent copy: she can create branches, make commits, and when she wants to share, git push (if you gave her write access to the repository) or propose the changes to you. It's the distributed copy we were talking about: complete, valid on its own, syncable with yours through the shared remote.

The shared flow, in one image

Putting it all together, this is what two people's work on order-triage looks like through GitHub:

  1. You create the repository and make the first git push. The remote now has the history.
  2. Your coworker does git clone. Now both of you have complete copies.
  3. Each of you works on your own branch (lesson 5): you on add-priority-routing, her on fix-crm-timeout. Each of you does git push of your branch to the remote.
  4. Before merging, you review each other's changes with lesson 4's diffs —GitHub also shows them visually on its site.
  5. The good branches get merged into main, and main gets a git push. The other person does git pull to bring that updated main into their copy.

That back and forth —push to give, pull to receive, each person on their own branch— is the heartbeat of shared work. There's no central boss who "has the good file"; there's a shared remote everyone syncs with, and main on that remote is the version of the truth the team agrees on. For Cumbre, that's exactly the "sharing workflows between users" the Community edition didn't provide, solved with free tools.

GitHub isn't just a backup: it's also a viewer

It's worth knowing GitHub doesn't keep your history in silence; it shows it to you. Everything you learned to read in the terminal, GitHub presents visually on its website, and for a lot of reviews it's more convenient.

On your repository's page you can browse the commit history with one click, and opening any commit, GitHub shows you its diff —the same one you'd see with git diff, with removed lines in red and added ones in green, but colored and better formatted. It's a pleasant way to review what changed without leaving the browser. Lesson 4's four "read through the noise" rules apply here just the same: on a non-normalized n8n JSON, GitHub is also going to show you the versionId and position noise mixed in with the real change.

There's a feature worth mentioning even though we're not going to develop it: Pull Requests. A Pull Request is GitHub's way of proposing merging one branch into another —for example, your add-priority-routing branch into mainstopping to review before merging. It shows the complete diff of everything the branch brings, lets a coworker comment on it line by line and approve it, and only then does it merge. It's the standard mechanism teams use to review changes before they enter main, and it's exactly where your diff-reading skill turns into money: reviewing someone else's Pull Request is reading their diff and deciding whether the change goes in.

We're not going to set up the Pull Request flow here —team review work gets developed further in Module 6, including reviewing AI-generated changes. For now hold on to the fact that it exists, that it rests on lesson 5's branches and lesson 4's diffs, and that it's why pushing your work to GitHub isn't just backing it up: it's enabling someone else to review it before accepting it.

An expectation warning, so it doesn't frustrate you when you see it: on a non-normalized n8n JSON, GitHub's diff view —same as your terminal's— is going to mix the real change with versionId and position noise, and on a minified single-line file it'll be just as useless as in the terminal. GitHub doesn't do magic on the file's format; it just presents it more nicely. The real fix is still the same one we announced in lesson 4: normalizing the JSON, which is Module 3. With clean diffs, GitHub's view and Pull Requests become a genuinely convenient review tool.

Common mistakes

Initializing the GitHub repository with files and clashing on the first push (practical). What happens: when creating the repo on GitHub you check "Add a README" (or a .gitignore, or a license), and when you try git push from your local repository —which already has commits— Git rejects the push with a message about mismatched histories ("rejected," "failed to push some refs," "fetch first"). Why it happens: GitHub created its own commit (the README's) that your local history doesn't know about, so the two lines diverged from the start and Git doesn't want to overwrite one with the other. How to spot it: if your first push fails mentioning "rejected" or "fetch first" and you hadn't pushed anything before, this is it. How to fix it: the cleanest thing is to create the GitHub repository empty, with no box checked, when you already have local history to push. If you already created it with files, the way out is doing git pull origin main first to bring in and merge the README commit, and only then git push.

Trying to authenticate with your GitHub password (practical). What happens: you do git push, Git asks for username and password, you type your regular GitHub password, and it fails with an authentication error. Why it happens: GitHub stopped accepting the account password for Git operations in 2021; now you have to use a PAT or SSH. How to spot it: if the push fails right after typing your password, with a message about authentication or "support for password authentication was removed," this is it. How to fix it: use the browser wizard if it shows up, or generate a personal access token (PAT) in GitHub's settings and use it instead of the password when Git asks for it, or set up an SSH key. GitHub's official guide (in the resources) has the up-to-date step-by-step.

Pushing a repository with secrets, or leaving it public (practical and serious). What happens: a repository containing a credentials file gets pushed to GitHub, or the repo gets created as public when it had business logic or sensitive traces. Why it happens: the rush to "push everything" runs over the review, and the public option is sometimes preselected. How to spot it: before your first push, check with git status and git log which files are versioned; if you see .env, credentials.json, or similar, there's a problem. How to fix it: prevent it —lesson 3's .gitignore must exclude secrets before the first commit, and the work repository defaults to private. If you already pushed a secret, switching visibility to private isn't enough: the secret stayed in the history and it has to be rotated (invalidated and a new one generated) and cleaned from the history, a serious topic Module 3 addresses. The rule: think about secrets and visibility before pushing, not after.

Push rejected because the remote has changes you don't (practical). What happens: you do git push and Git rejects it saying something like "Updates were rejected because the remote contains work that you do not have locally" and suggests git pull. Why it happens: someone else (or you from another machine) pushed commits to the remote that your local copy doesn't have, so pushing yours on top would erase theirs —Git doesn't allow it. How to spot it: the rejection message mentions "fetch first" or "remote contains work." How to fix it: do git pull first to bring in and merge the remote's changes with yours —resolving a conflict if one shows up, like in lesson 5— and then git push. It's the normal rhythm of shared work: download before you upload. Adopting the habit of git pull before starting work each day prevents most of these rejections.

Exercises

Exercise 1 — Push your repository from start to finish. Create a GitHub account if you don't have one, create an empty and private repository called cumbre-automations, connect it to your local repository with git remote add origin <url>, verify with git remote -v, and push your history with git push -u origin main. Confirm by opening the URL in the browser that you see your order-triage.json and the list of commits.

See solution

The command sequence:

git remote add origin https://github.com/YOUR-USERNAME/cumbre-automations.git
git remote -v
git push -u origin main

(Replacing the URL with yours, and resolving authentication when it shows up.)

The real verification isn't that the commands don't error, it's opening the repository's page on GitHub and seeing your history there. You should recognize every commit you made in the previous lessons, with its note and your name. Seeing your own history reflected on the web is the moment "I backed up my work" stops being an abstract idea.

Why it works: this exercise puts together the three steps —creating the empty remote, linking it, pushing— which are the only tricky part of all of collaboration. Once your history is on GitHub, the rest (push, pull) is routine. The detail most people forget is creating the repo empty; if you did it right, your first push had no problems with clashing histories.

Exercise 2 — Simulate a coworker with a clone. In a different folder on your machine (for example, a practice folder), clone your own repository with git clone <url>. Go into the cloned folder, run git log --oneline, and confirm it has the whole history. Then run git remote -v in the clone and notice which remote got configured without you adding it.

See solution

After git clone <url> and going into the cloned folder, git log --oneline shows exactly the same history as your original repository: the same commits, with the same IDs. It's a complete copy, not a summary.

And git remote -v in the clone shows that origin is already configured pointing at the URL you cloned from, without you running git remote add. That's what I wanted you to see: cloning does the connection to the remote for you. Your coworker, cloning, gets a repository ready to push and pull with nothing to configure.

Why it works: cloning your own repo into another folder is the safest way to understand what someone collaborating with you receives: the entire history, plus the connection to the remote already done. It's also, incidentally, a real technique: if you want your repository on a second machine, you don't copy it by hand —you clone it.

Exercise 3 — Reason through the two-person flow. You and a coworker work on order-triage through GitHub. Order these steps in the correct sequence and say, for each push/pull, what travels and in which direction: (a) she does git pull, (b) you do git push of your merged branch to main, (c) she does git clone, (d) you merge your branch into local main, (e) you do the repository's first git push, (f) she creates her branch and works.

See solution

A correct sequence: (e) → (c) → (f) → (d) → (b) → (a).

  • (e) You do the first git push: your local history goes up to the remote. GitHub now has the repository.
  • (c) She does git clone: the complete history comes down from the remote to her machine. She now has her copy.
  • (f) She creates her branch and works: all local on her machine, nothing traveling yet.
  • (d) You merge your branch into local main: also local on your machine.
  • (b) You do git push of main: your updated main goes up to the remote.
  • (a) She does git pull: your new main comes down from the remote into her copy, and merges with hers.

Why it works: the pattern that emerges is "push goes up, pull comes down, and the remote is the middleman." Nothing travels directly from your machine to hers; everything goes through the shared remote. Understanding there's no direct connection between the two machines —only between each one and GitHub— is what makes shared work stop feeling magic and become predictable.

Summary and next step

In this lesson you took your repository off your machine and put it somewhere safe on GitHub. You understood what a remote is —another complete copy of your repository, one you sync with— and why Git is distributed: every copy has the entire history, so you work without internet and only connect to push (upload) and pull (download). You saw that GitHub hosts that copy and covers, for free, the "sharing workflows between users" that n8n's Community edition doesn't provide, and why work repositories go private. You honestly faced authentication —that GitHub no longer accepts your password and you have to use a PAT or SSH, a volatile detail worth confirming at the official source. And you walked through the complete flow: git remote add origin to link, git push -u origin main for the first push, git push and git pull for everyday work, and git clone so a coworker gets their copy. You closed with the image of two people's work: each on their own branch, everything going through the shared remote.

Before moving on to lesson 7 you should be able to: create an empty repository on GitHub and push your local history; explain the difference between push, pull, and clone; and understand why a push can be rejected and what to do then.

You now have your workflow versioned, branched, and backed up in the cloud. All that's left is to close the loop with the reason all of this is worth it on the day something goes wrong: being able to go back. In lesson 7 you're going to learn to recover a version that worked. You're going to see the difference between git revert —undoing a change while leaving a record, the safe and auditable path— and git reset —moving the history backward, powerful and dangerous— when to use each and why, and how to recover a single file's previous version with git checkout <commit> -- file. It's the lesson that turns all the history you built into a real safety net: the difference between Cumbre's "bad Tuesday" solved in ten minutes and one solved at midnight through guesswork.

Resources