In a world with , chapter 1.4.

THE PATH · SESSION 4 OF 66 · UNIT 1 · ACT I

Guild Sync

GitHub, Remotes, Pull Requests, and Your Dotfiles

65 min read5 diagrams3 side quests7 terminals6,975 words13 code blocks

At a glance

PACE
Session 4 of 66 · suggested week 2. Continue when you are ready.
UNIT
Unit 1 · I Woke Up in a Terminal and All I Had Was a Blinking Cursor
ACT
Act I · Foundation
BEFORE
1.3 Save Points and Respawns
AFTER
1.5 The Scribe's Hand
ARTIFACT
A GitHub account with an SSH key that answers ssh -T git@github.com with your name; quest-log pushed and tracking origin/main; a pull request you opened, reviewed and merged on your own repository; and github.com/YOU/dotfiles, public, with a README, your shell config, your editor settings and a setup script, your first shipped artifact
READ
65 min · 5 diagrams · 13 code blocks

The hook#

So far, everything you have built lives on your laptop. The explorer's journal, the branch quest, the quest log with its two merged timelines; all of it is in one folder on one disk. If that disk dies tonight, Unit 1 dies with it. Last session gave you save points. This session puts the saves somewhere that survives the machine.

Every adventurer starts alone. Then there is a morning when they walk into the guild hall: a long room with a board full of quests, a ledger of members, and other people's maps pinned to the walls. The hero signs the ledger, hangs a copy of their own map beside the others, and from that moment they are not a solo traveller any more. Their work is part of something people can see, borrow from, and build on.

GitHub is the guild hall. It is where developers keep copies of their repositories, read each other's code, propose changes to projects they do not own, and build the public record that will one day be the first thing an employer or a co-founder looks at. Almost every piece of software you use today has a copy of its history on GitHub. By the end of this session so will yours.

The agenda is heavy, and every item is a real thing you will do, not a thing you will read about. You will make an account. You will generate an SSH key pair and understand why it beats a password. You will push the quest log to a remote and watch it appear in a browser. You will clone a repository back down, pull changes, and meet the one message a remote ever sends that frightens people. You will open a pull request, read it the way a reviewer does, merge it, and learn the fork dance for repositories that are not yours. You will pick up two small tools, stash and amend, for messy moments. And then, for the final act, you build and ship your dotfiles repository: shell config, editor settings, a setup script and a proper README, public, on the internet, with your name on it. Not a tutorial. Not a toy. A real thing that works.

The box on this page can rehearse all of it. It has git, it has an SSH toolkit, and it has gh, GitHub's own command-line tool, talking to a small GitHub of its own, so that every click the real walkthrough asks you to make in a browser has a command here that does the same thing. Read the shell transcript, then do it for real, in your own terminal, on the real site.

The idea#

Let us separate two words that beginners glue together. Git is the program on your machine. It made the commits, it holds the branches, it can do everything it did last session with the network cable unplugged. GitHub is a website, run by a company, that hosts Git repositories: it keeps a copy of your .git on its servers and puts a web page in front of it. Other companies run the same kind of service (GitLab, Bitbucket, Codeberg). GitHub is the one almost everybody uses, so it is the one we use, but nothing in Git itself knows or cares that GitHub exists.

The thing that connects them is a remote. A remote is nothing more than a name for a URL, stored in your repository's configuration. When you tell Git "add a remote called origin at this address", you are writing one line into .git/config. From then on, git push origin main means "send my main to the repository at the address I called origin", and git pull means "bring down whatever is there and join it to mine". The name origin is only a convention, the default Git uses when you clone, and you could call it guild if you liked. Everybody calls it origin, so you should too, so that every tutorial and every colleague's instructions work on your machine without translation.

Two boxes: your machine (the working directory ~/git-quest, the full history in ~/git-quest/.git, the main label) and github.com, a remote named origin (adventurer-dev/git-quest, origin/main, the SSH address); between them three arrows: git push going up, git pull coming down, git clone for the first copy; under them the two lines git remote -v prints
Fig 1 · Local and remote. The whole repository is on your machine; GitHub holds a second copy named origin, and three verbs move commits between them.

Look at the two sides of Fig 1 and notice what is not there. There is no arrow that says "save". Commits are made on your side, by you, exactly as they were last session, and they go nowhere until you push. GitHub never sees your working directory or your staging area; it sees commits, and only the ones you send. This is the single most useful fact about the whole model: GitHub is not where you write code and it is not a live mirror of your folder. It is where you put copies of finished saves. People who skip this sentence spend their first month editing files in the GitHub web interface, pulling them down, getting conflicts with their local edits, and concluding that Git hates them. Edit locally, commit locally, push when a save is worth sharing.

A second correction while we are here. Pushing to a public repository lets anyone see your code. It does not let anyone change it. Only the owner and the collaborators the owner adds can push to a repository; everybody else can read, copy, and propose. That proposal mechanism is the pull request, and we will get to it. For now, hold on to this: public means visible, not editable.

Proving who you are without a password#

Before GitHub accepts a push it needs to know the push is from you. The old way was a password, typed on every push, and it was bad for the reasons passwords are always bad: people reused them, people typed them into the wrong window, and anyone who stole one could push as you from anywhere. The professional way, and the way GitHub insists on now for command-line work, is an SSH key pair.

A key pair is two files that are mathematically linked. The private key is a secret that stays on your machine; it lives in ~/.ssh/id_ed25519, its permissions let only you read it, and you never paste it, email it, commit it, or show it to anyone, including people who say they are from GitHub. The public key is its partner, one line of text in ~/.ssh/id_ed25519.pub, and it is safe to show to the whole world. You paste that one line into GitHub's settings once. The metaphor that makes it stick: the public key is a padlock, and you can hand out as many copies of the padlock as you like; the private key is the only key that opens it, and there is exactly one.

Two key cards: the private key ~/.ssh/id_ed25519 in red, never shared, permissions 600; the public key ~/.ssh/id_ed25519.pub in green, one line pasted into GitHub Settings; below, the four-step handshake on every push: you offer the fingerprint, GitHub sends a challenge, the private key signs it, GitHub checks the signature with the public key; the ssh -T output ending in Hi adventurer-dev
Fig 2 · The SSH key pair. The public key is the padlock you hand to GitHub; the private key stays home and answers a challenge on every push.

The handshake in Fig 2 is what happens, silently, every time you push. Your machine connects and offers the fingerprint of your public key. GitHub finds that fingerprint in your account and, instead of asking for a secret, sends back a random challenge. Your private key signs the challenge, the signature goes back, and GitHub checks the signature against the public key it already has. The private key itself never crosses the wire. Nothing is typed. If the signature matches, you are in; ssh -T git@github.com performs exactly this dance and then says hello with your username so you can see it work.

The practical consequences are worth stating plainly. If you lose a laptop, you go to GitHub, delete that laptop's public key from your account, and the laptop is locked out, without changing anything on any other machine. If you get a new laptop, you generate a new pair on it and add the new public key; you do not copy the private key around. And if you ever see your private key in a chat window, a repository, or a screenshot, treat it as burned: delete it from GitHub and make a new pair. The key type we use, ed25519, is the modern default, fast and short; you may see older guides using rsa with much longer keys, and those still work, but there is no reason to start there today.

The README and the language it is written in#

Every repository you push should have a file called README.md at its root. GitHub renders that file on the repository's front page, so it is the first thing anyone sees, including you in six months when you have forgotten what the project was. The .md is Markdown, a way of writing formatted text in plain text: you type a few punctuation marks and GitHub turns them into headings, lists, links and code. Every README on GitHub uses it, as do issue comments, pull request descriptions, most documentation sites, and the page you are reading now. You will write Markdown nearly every day for the rest of this programme, so learn the eight shapes that cover almost everything:

MD
# Heading 1## Heading 2### Heading 3 A paragraph is just a line of text. Leave a blank line between paragraphs. **Bold text** and *italic text* and `inline code`. - A bullet point- Another bullet  - A nested bullet, indented two spaces 1. A numbered list2. Second item [Link text](https://example.com) ![Image alt text](path/to/image.png) > A blockquote, for a note or a quotation. ---

A horizontal rule is three dashes on a line of their own. A code block is three backticks on a line, optionally followed by a language name such as bash or json, then your code, then three backticks to close; GitHub colours the code by language, which is why the name matters. A table is rows of cells separated by | with a second row of --- under the header. That is the whole language, or at least the ninety-five percent of it anyone uses. Markdown is forgiving: if you get something slightly wrong it shows up as the punctuation you typed rather than exploding, and GitHub's Preview tab shows you the result before you commit.

The demonstration#

Seven terminals. The first four follow the live walkthrough: key, push, clone and fork, pull request. The fifth is the two small tools. The sixth, in the next section, is everything going wrong on purpose. The seventh, in Your turn, is the dotfiles build. Each box starts from a blank machine, so later scripts begin by rebuilding what the earlier ones made, compressed into one or two lines; those lines are nothing new, just last session's Git and this session's key setup, chained with &&.

Creating the account happens in a browser, not a terminal, so the box cannot show it. Go to github.com, sign up for a free account, and choose your username with care: it becomes part of every URL you will ever share, so pick something you would be happy to see on a résumé. adventurer-dev is the one the box uses. Once you are in, come back to the terminal.

Walkthrough 1: the key. Check whether you already have keys, generate a pair, start the agent that holds the unlocked key for the session, add the key to it, and read your public key. Then, on the real site, go to Settings → SSH and GPG keys → New SSH key, give it a title that names the machine ("My Laptop"), paste the public key, save. In the box, gh auth login and gh ssh-key add do exactly that click from the command line, which is also how you will do it once you are comfortable. Finally ssh -T git@github.com to test. Watch what the test says before the key is on GitHub and after.

SHyou type
ls -la ~/.sshssh-keygen -t ed25519 -C "arthur@newworld.dev"ls -la ~/.ssheval "$(ssh-agent -s)"ssh-add ~/.ssh/id_ed25519cat ~/.ssh/id_ed25519.pubssh -T git@github.com# on your machine: GitHub → Settings → SSH and GPG keys → New SSH key → paste. In the box, the same click:gh auth logingh ssh-key add ~/.ssh/id_ed25519.pub --title "My Laptop"gh ssh-key listssh -T git@github.com
Shell simulatoradventurer@newworld · simulated bashnot run yet

Browser simulation with temporary files, not a real Bash process. Tool versions and app launches are examples. Rerunning or reloading resets this box.

adventurer@newworld:~$

Read it in order. The first ls -la ~/.ssh fails with No such file or directory, or on a machine that has connected to a server before it lists only known_hosts; either is what "I have no keys yet" looks like. ssh-keygen asks where to save (press Enter for the default) and for a passphrase; a passphrase is a password on the private key file itself, so that a stolen disk still cannot use it, and the agent means you type it once per login rather than once per push. The box leaves it empty for the transcript; on your machine, use one. The randomart picture is a visual fingerprint, there so humans can spot a changed key at a glance. After ssh-keygen the directory has two new files, and the permissions tell the story: -rw------- on the private key, readable by you alone; -rw-r--r-- on the public one, readable by anyone. cat the .pub file and that one line, ssh-ed25519 AAAA… your@email, is what you paste into GitHub; the email at the end is only a comment so you can tell keys apart.

The first ssh -T is deliberately before the key is uploaded, and the first time you connect you will also be asked whether to trust github.com; say yes, and its fingerprint is written to ~/.ssh/known_hosts so you are never asked again. Then: Permission denied (publickey). That is the exact message you will see on your machine if you forget to paste the key, so learn its face now. After the key is added, the same command says Hi adventurer-dev! You've successfully authenticated, but GitHub does not provide shell access. The second half is not an error; GitHub is saying it knows who you are and that this door is for Git, not for a login shell. If you see your username, you are in. The guild recognises you.

Walkthrough 2: the first push. Last session's quest-log finally leaves the machine. On the site: the + in the top right, New repository, name it quest-log, keep it Public, and do not tick "Add a README", because you already have one and two READMEs would mean an immediate conflict. GitHub then shows you three commands under push an existing repository from the command line; they are the three in the middle of this box.

SHyou type
# identity, key and login from the previous terminal, compressed (each box starts fresh)git config --global user.name "Arthur the Adventurer" && git config --global user.email "arthur@newworld.dev" && git config --global init.defaultBranch mainssh-keygen -t ed25519 -C "arthur@newworld.dev" -N "" -f ~/.ssh/id_ed25519 > /dev/null && gh auth login > /dev/null && gh ssh-key add ~/.ssh/id_ed25519.pub --title "My Laptop" > /dev/null# last session's quest-log, rebuilt in two savescd ~ && mkdir quest-log && cd quest-log && git init -qprintf "# Quest Log\nTracking my adventures in the terminal world.\n" > README.md && mkdir quests && echo "Learn Git and GitHub" > quests/main-quest.txt && printf "*.log\ntemp/\n.DS_Store\n" > .gitignoregit add . && git commit -q -m "Initial commit: set up quest log"echo "Build a dotfiles repo" > quests/side-quest-2.txt && git add . && git commit -q -m "Add the dotfiles side quest"git log --onelinegit remote -v# on your machine: github.com → New repository → quest-log, Public, no README. In the box, the same click is one command:gh repo create quest-log --publicgit remote add origin git@github.com:adventurer-dev/quest-log.gitgit remote -vgit branch -M maingit push -u origin maingit statusecho "## Pushed to GitHub!" >> README.mdgit add README.mdgit commit -m "Update README: celebrate first push to GitHub"git pushgit log --onelinegh repo view
Shell simulatoradventurer@newworld · simulated bashnot run yet

Browser simulation with temporary files, not a real Bash process. Tool versions and app launches are examples. Rerunning or reloading resets this box.

adventurer@newworld:~$

The first git remote -v prints nothing: a fresh repository has no remotes. git remote add origin <url> writes one, and the second -v shows it twice, once for fetch and once for push, because Git allows them to differ (they almost never do). git branch -M main renames the current branch to main if it was not already; on your machine, with init.defaultBranch set last session, it is a no-op, but GitHub prints it for people with older defaults, so it does no harm. Then the line that matters: git push -u origin main. Read its output. Git counts objects, compresses them, writes them, and then prints * [new branch] main -> main: your main has created a main on origin. The -u (long form --set-upstream) records that your local main tracks origin/main, which is why the next git status can say Your branch is up to date with 'origin/main' and why, from now on, a bare git push and git pull know where to go without being told.

Refresh the GitHub page on your machine and your files are there, with the README rendered. Then the second loop: edit, add, commit, push. This time push prints <old hash>..<new hash> main -> main, the seven-character hash origin had followed by the one it has now, which is the shape of every ordinary push for the rest of your life. git log --oneline now decorates the top commit with both HEAD -> main and origin/main: your label and the remote's label on the same save, which is the picture of "in sync". gh repo view prints the README as GitHub would render its text. Look at that. Your code is on the internet.

Five chips in a row: git pull, edit, git add, git commit, git push, with a loop arrow back to pull; below, a red card showing the rejected push ( ! [rejected] main -> main (fetch first) ) with a two-lane sketch where origin has commit B and you have commit C from the same A, and a green card showing the fix: git pull merges B and C into M, git push sends M
Fig 3 · The daily loop and its one refusal. Pull before you push; when a teammate pushed first, git refuses, you pull, and the merge commit joins both sides.

Fig 3 is the loop you will run every working day from now until you retire: pull, edit, add, commit, push, and tomorrow pull again. It has one refusal built into it, the rejected push, which the Where-it-breaks box stages on purpose so that the first time it happens for real you recognise it. The next two walkthroughs fill in the verbs the loop needs that you have not met: clone and pull.

Walkthrough 3: clone, pull, and the fork. Clone is how you get a repository that already exists on GitHub onto your machine, whether it is someone else's project or your own from a second computer. It copies everything: all commits, all branches, the whole history, and it sets up origin and the tracking for you, so a cloned repository is ready to push and pull the moment it lands. Pull is how you bring down changes made elsewhere; for now treat it as one verb, and know that it is really two, fetch (download their commits, touch nothing of yours) followed by merge (join them into your branch). We will take fetch apart later in the programme.

The guild in the box has a repository called newworld-guild/quest-board. It exists only inside the box, on the page's pretend GitHub, so rehearse this walkthrough here rather than on your machine (the real github.com has no newworld-guild, and a clone would answer Repository not found). You are a member of the guild but not an owner of that repository, which is the normal situation for every open-source project you will ever meet. Watch what happens when you try to push to it, and then watch the right way.

SHyou type
git config --global user.name "Arthur the Adventurer" && git config --global user.email "arthur@newworld.dev" && git config --global init.defaultBranch mainssh-keygen -t ed25519 -C "arthur@newworld.dev" -N "" -f ~/.ssh/id_ed25519 > /dev/null && gh auth login > /dev/null && gh ssh-key add ~/.ssh/id_ed25519.pub --title "My Laptop" > /dev/nullcd ~/projectsgit clone git@github.com:newworld-guild/quest-board.gitcd quest-boardlsgit log --onelinegit remote -vgit pullecho "adventurer-dev" >> adventurers.txtgit commit -am "Add adventurer-dev to the guild roll"git push# not your guild hall: fork it, then clone your forkcd ~/projects && rm -rf quest-boardgh repo fork newworld-guild/quest-board --clonecd quest-boardgit remote -vgit checkout -b add-adventurerecho "adventurer-dev" >> adventurers.txtgit commit -am "Add adventurer-dev to the guild roll"git push -u origin add-adventurergh pr create --title "Add adventurer-dev to the guild roll" --body "Joining the guild. Completed the welcome quest."gh pr listgh pr merge 1 --merge
Shell simulatoradventurer@newworld · simulated bashnot run yet

Browser simulation with temporary files, not a real Bash process. Tool versions and app launches are examples. Rerunning or reloading resets this box.

adventurer@newworld:~$

The clone prints the same counting and compressing lines a push does, in the other direction, then ls shows the files and git log --oneline shows a history you did not write, with origin/main already decorating the top. git pull says Already up to date, which is the boring, correct answer when nobody has pushed since you cloned. Then the commit and the push, and the push is refused: ERROR: Permission to newworld-guild/quest-board.git denied to adventurer-dev. Read it carefully, because the next line, Could not read from remote repository, is Git's generic wrapper and sends people chasing the wrong problem. The first line is the truth: the key worked, GitHub knows exactly who you are, and you are not allowed to write here.

So you fork. A fork is a copy of someone else's repository made on GitHub, under your account: newworld-guild/quest-board becomes adventurer-dev/quest-board, with a "forked from" line under its name. On the site it is the Fork button at the top right of the repository page; in the box, gh repo fork … --clone presses it and clones the result in one move. Look at git remote -v afterwards: two remotes. origin is your fork, which you can push to, and upstream is the original, which you can only read from; that second remote is how you will later pull in the maintainers' new commits to keep your fork current. Branch, commit, push to origin as before, and then gh pr create opens a pull request from your fork's branch into the original repository; the output says so: adventurer-dev:add-adventurer into main in newworld-guild/quest-board. gh pr list, run inside the fork, shows the open request on the upstream. And gh pr merge fails, on purpose, with a permissions error, because merging into the guild's repository is the guild's decision. You proposed; they dispose. That is not a limitation of the box. It is how every open-source project on Earth accepts contributions, and when you fix a typo in someone's documentation six months from now, this is the dance you will do.

Fork versus clone, once more, because the words are a common stumble: fork copies on GitHub, from their account to yours; clone copies from GitHub down to your machine. To contribute to a project you do not own, you do both, in that order.

Walkthrough 4: the pull request on your own repository. The dance you just did against the guild is the same one you will use on your own work, with one difference: you are also the reviewer, so you get to press Merge. A pull request is a branch asking to join another, with a page around it where the change can be read, discussed, and approved. Even alone, it is worth the ceremony, because the Files changed tab shows you your own diff the way a stranger would see it, and you will catch things there that you never catch in the editor.

Top, your own repository: six numbered stages alternating terminal and GitHub: checkout -b, push -u, Compare & pull request, Files changed and Conversation, Merge pull request, then checkout main and pull; a git log --graph showing the merge commit with two parents. Bottom, someone else's repository: push denied, fork to adventurer-dev/quest-board, clone branch push and open a PR that targets the original, maintainers review and merge
Fig 4 · A pull request, end to end. On your own repo you merge it; on someone else's you fork first and the maintainers decide.

SHyou type
git config --global user.name "Arthur the Adventurer" && git config --global user.email "arthur@newworld.dev" && git config --global init.defaultBranch mainssh-keygen -t ed25519 -C "arthur@newworld.dev" -N "" -f ~/.ssh/id_ed25519 > /dev/null && gh auth login > /dev/null && gh ssh-key add ~/.ssh/id_ed25519.pub --title "My Laptop" > /dev/nullcd ~ && mkdir git-quest && cd git-quest && git init -q && echo "# Git Quest" > README.md && git add . && git commit -q -m "Initial commit: add README"gh repo create git-quest --public --source=. --remote=origin --pushgit checkout -b add-achievementsecho "# Achievements" > achievements.txtecho "- [x] Set up dev environment" >> achievements.txtecho "- [x] Learn terminal basics" >> achievements.txtecho "- [x] Learn Git" >> achievements.txtecho "- [x] Push to GitHub" >> achievements.txtecho "- [ ] Create first PR" >> achievements.txtgit add achievements.txtgit commit -m "Add achievements tracker"git push -u origin add-achievements# on your machine: the yellow "Compare & pull request" banner, a title, a description, Create pull request. In the box:gh pr create --title "Add achievements tracker" --body "This PR adds an achievements.txt file to track progress through the programme."gh pr listgh pr view 1# on your machine: Files changed, Conversation, then the green Merge pull request → Confirm merge. In the box:gh pr merge 1 --mergegit checkout maingit pulllsgit log --oneline --graphgit branch -d add-achievementsgit push origin --delete add-achievementsgit branch -a
Shell simulatoradventurer@newworld · simulated bashnot run yet

Browser simulation with temporary files, not a real Bash process. Tool versions and app launches are examples. Rerunning or reloading resets this box.

adventurer@newworld:~$

A new repository, created and pushed in one line this time with gh repo create --source=. --push, which is the command-line version of the New repository button plus the three push commands. Then a branch, add-achievements, a file, a commit, and git push -u origin add-achievements: a branch other than main going up, and GitHub replying * [new branch]. On the site, within a minute of that push, the repository page shows a yellow banner, add-achievements had recent pushes, with a Compare & pull request button. Click it. Write a title that says what the change is and a description that says why; both are Markdown, and both are what your reviewer reads first. Create pull request. In the box, gh pr create does the same and prints the request's URL.

Now read it like a reviewer. gh pr view shows what the web page shows at the top: the title, Open, who wants to merge how many commits from which branch into which, and the size of the change, +6 -0. On the site, open Files changed: every line added is green, every line removed is red, and you can click any line to leave a comment on it. Conversation is where those comments and the description live. When it is right, the green Merge pull request button, then Confirm merge; gh pr merge 1 --merge is that pair of clicks. GitHub makes the merge commit on origin, not on your machine, which is why the next three lines matter: git checkout main, git pull, and ls shows achievements.txt has arrived. git log --oneline --graph draws the shape: a merge commit at the top, Merge pull request #1 from adventurer-dev/add-achievements, with the |\ and |/ of last session's three-way merge under it. It is the same merge; the review is the new part.

The last three lines are hygiene. git branch -d deletes your local label; git push origin --delete add-achievements deletes the remote one (the site offers a Delete branch button right after the merge that does the same); git branch -a lists local and remote branches together and shows only main and remotes/origin/main left. Merged branches should disappear. A repository with forty stale branches tells everyone who opens it that nobody is minding the hall.

Two tools for messy moments. Before the dotfiles build, two small commands that will save you constantly. git stash takes every uncommitted change in your working directory and puts it in a pocket dimension, leaving the folder clean so you can switch branches, pull, or deal with an emergency; git stash list shows what is in the pocket; git stash pop brings the most recent one back. git commit --amend replaces your last commit with a corrected one: with -m to fix a typo in the message, or after a git add with --no-edit to include a file you forgot. Both are in the box.

SHyou type
git config --global user.name "Arthur the Adventurer" && git config --global user.email "arthur@newworld.dev" && git config --global init.defaultBranch maincd ~ && mkdir pocket && cd pocket && git init -q && echo "hp: 100" > hero.txt && git add . && git commit -q -m "Create hero"git checkout -q -b potionsecho "potion: 3" >> hero.txtgit status --short# an urgent fix is needed on main, and this half-finished line is not ready to be a commitgit stashgit statusgit checkout mainecho "mp: 50" >> hero.txt && git commit -qam "Give the hero mana"git checkout potionsgit stash listgit stash popcat hero.txtgit commit -am "Carry potoins"git log --onelinegit commit --amend -m "Carry potions"git log --onelineecho "gold: 10" > purse.txtgit add purse.txtgit commit --amend --no-editgit show --stat HEADgit log --oneline --all --graph
Shell simulatoradventurer@newworld · simulated bashnot run yet

Browser simulation with temporary files, not a real Bash process. Tool versions and app launches are examples. Rerunning or reloading resets this box.

adventurer@newworld:~$

Follow the stash first. On potions with a half-written line, git stash reports Saved working directory and index state WIP on potions, and git status immediately says nothing to commit, working tree clean: the change is gone from the folder and safe in the pocket. Switch to main, make the urgent fix, commit, switch back. git stash list shows stash@{0} still waiting; git stash pop restores it and drops it from the list, and cat hero.txt shows the potion line back where you left it, with no sign of main's mana line, because potions branched before that commit existed. Then the amend. The first commit's message has a typo. git commit --amend -m "Carry potions" replaces it: look at the two git log --oneline outputs and notice the hash at the top is different. That is not the same commit with a new message; it is a new commit, and the old one is unreferenced. Add a forgotten file and --amend --no-edit, and the hash changes again while the message stays, and git show --stat HEAD lists both files in the one save.

Where it breaks#

Your turn#

The quest#

By the start of Session 1.5, have on GitHub:

  • ssh -T git@github.com greeting you by name.
  • quest-log, pushed, with git status on your machine saying Your branch is up to date with 'origin/main'.
  • At least one pull request you opened, read under Files changed, and merged on a repository of your own, visible under the Pull requests tab with its Closed filter.
  • github.com/YOU/dotfiles, public, with a README that renders cleanly and has at least three sections, both .zshrc and .bashrc with at least twelve aliases, vscode/settings.json and vscode/extensions.txt, and the seven-line setup.sh, executable, run once on your machine.

The independent lab is the stretch, not the gate: the extra aliases, the git/.gitconfig and the branch-per-change habit can land over the next few days, and every one of them is a pull request waiting to happen. Paste the dotfiles URL into your journal and into your résumé draft; it is the first line of your portfolio.

Side quests#

Three pages in the library look further down roads you walked today. They are written for later units, so read the opening and the first picture, not the code.

Side quests from this session

  • A04:2025 Cryptographic FailuresYour SSH key pair is public-key cryptography doing exactly what it is for: a signature anyone can check and only you can make. This page is the catalogue of ways that goes wrong in real systems: weak algorithms, secrets committed to repositories, keys that never rotate. Read the opening and the first example; the rule about never pushing a private key is item one on its list.
    Security
  • A07:2025 Authentication Failures`Permission denied (publickey)` and `Hi adventurer-dev!` are the two outcomes of an authentication check, and GitHub chose keys over passwords for the reasons this page catalogues: credential stuffing, reuse, and secrets that cross the wire. Read the opening and the lockout example, and notice that a key never has to be typed anywhere.
    Security
  • Grit: The Long ReturnYou just watched a demonstration: a key, a remote, a push. This page is what to do next. Copy that loop until it works, then use it on a repository that is yours. The skill is coming back tomorrow, not the first green square.
    Mindset

Before next session#

Run the loop. Every time you sit down to work: git pull; every time you stand up: git push. Make the dotfiles changes on branches and merge them. By the time Unit 2 starts, a bare git push with nothing to send should feel slightly disappointing, and your GitHub profile page should show a row of green squares on its contribution graph. That graph is public, it is what the industry glances at first, and from today every commit you push paints it.

Spend fifteen minutes on your profile. Add a photo and a one-line bio. Then look at three other people's dotfiles repositories from the awesome-dotfiles list and notice what their READMEs do that yours does not yet; notice, too, that their setup scripts have lines you cannot read yet, an if here, a case there, a loop, a function or two. Spend another fifteen on the GitHub Docs page about pull requests, which is the reference you will come back to when a PR does something you did not expect.

Here is what exists when the next session opens. ~/dotfiles is a repository on GitHub with both rc files and a plain prompt, your editor settings, the extension list, a README, and the seven-line setup.sh, which has already created ~/projects on your machine. Session 1.5, The Scribe's Hand, starts from exactly that folder. It teaches the shell as a language, one sentence shape at a time, with a prediction written down before every run, and it ends with the full setup script in this same repository, proven on a fresh clone, and the current branch in your prompt. Nothing is left running between sessions; there is no server yet to stop. The guild hall is open, and your map is on the wall.

You have a project on the internet. A real project, with a README and a setup script and configuration you wrote and understand. You are not a future developer. You are a developer, with a public repository and a key that opens the guild hall door. Right now. Today.

See also