Level 2 — Basic Git with a remote
Beginner Git CLI GitLab UI GitHub UI
Objective
Turn the local playground into a shared repository: connect it to a private project of your own on GitLab (or GitHub), push, make a change in the browser, bring it back with fetch and pull, and push a second local commit. By the end, all four areas of the mental model are real, and the everyday loop runs end to end.
Starting state
- The playground repository from Set up a safe playground, with at least the initial commit (
git log --onelineshows it). - An empty private project named
trailguideon GitLab or GitHub, created without a README (the playground page shows how). If you created it with a README, the "Common mistakes" section fixes it. - Git configured with your name and email (lesson 3.3).
- A personal access token ready, or ten minutes to create one in step 3.
The lab shows GitLab; each step notes the GitHub difference.
Instructions
-
Copy the project's HTTPS URL. On GitLab, open the project, click Code (top right) → copy Clone with HTTPS: it looks like
https://gitlab.com/you/trailguide.git. On GitHub, the Code button above the file list → HTTPS tab. -
Tell your repository where the remote is.
Terminal $ cd ~/git-practice/trailguide $ git remote add origin https://gitlab.com/you/trailguide.git $ git remote -vorigin https://gitlab.com/you/trailguide.git (fetch) origin https://gitlab.com/you/trailguide.git (push)originis now a name for that URL. Nothing has been sent yet. -
Push for the first time. The
-ulinks yourmainto the remote'smainso that future pushes and pulls need no arguments.Terminal $ git push -u origin mainTo https://gitlab.com/you/trailguide.git * [new branch] main -> main branch 'main' set up to track 'origin/main'.Git first asks for credentials: your platform username, and as the password a personal access token, not your website password. To create one: GitLab avatar → Edit profile → Access → Personal access tokens → Generate token (older versions: Add new token), scopes
read_repositoryandwrite_repository, an expiry date, then create it and copy it once. GitHub: avatar → Settings → Developer settings → Personal access tokens → Fine-grained tokens → Generate new token, repository access totrailguide, permission Contents: Read and write. Your credential helper stores it, so this happens once. Lesson 8.3 explains tokens in depth.Checkpoint: refresh the project page in the browser. Your files are there.
-
Confirm the link.
Terminal $ git statusOn branch main Your branch is up to date with 'origin/main'. nothing to commit, working tree cleanThe second line is new: your branch now tracks
origin/main. -
Edit a file in the browser. On GitLab: open
docs/faq.md, click Edit → Edit single file, add a question at the end, keep the commit message (Update faq.md), leave the target branch asmain, click Commit changes. On GitHub: open the file, click the pencil, edit, Commit changes…, choose Commit directly to the main branch, confirm. Your project now has a commit that your computer does not. -
See it arrive, without changing your files.
Terminal $ git fetchFrom https://gitlab.com/you/trailguide 216f956..01268bf main -> origin/mainTerminal $ git statusOn branch main Your branch is behind 'origin/main' by 1 commit, and can be fast-forwarded. (use "git pull" to update your local branch) nothing to commit, working tree cleangit fetchupdated your bookmarkorigin/main; your ownmainand your files are unchanged. That is the difference between fetch and pull. -
Pull the change in.
Terminal $ git pullUpdating 216f956..01268bf Fast-forward docs/faq.md | 4 ++++ 1 file changed, 4 insertions(+)Terminal $ git log --oneline -301268bf Update faq.md 216f956 Initial import of trailguide"Fast-forward": your
mainsimply moved up to the remote's commit, because you had nothing new locally. Opendocs/faq.mdin your editor: the browser edit is there. -
Make a local change and push it. No
-uthis time; the link exists.Terminal $ printf '\nLocal line after pull.\n' >> README.md $ git commit -am "docs: add local line" $ git pushTo https://gitlab.com/you/trailguide.git 01268bf..127f39e main -> mainCheckpoint: the project page shows your commit as the latest.
-
(Optional) Clone it somewhere else. This is what a colleague, or you on another computer, would do:
Terminal $ cd ~/git-practice $ git clone https://gitlab.com/you/trailguide.git trailguide-cloneTo https://gitlab.com/you/trailguide.git ! [rejected] main -> main (fetch first) error: failed to push some refs to 'https://gitlab.com/you/trailguide.git' hint: Updates were rejected because the remote contains work that you do not hint: have locally. This is usually caused by another repository pushing to hint: the same ref. If you want to integrate the remote changes, use hint: 'git pull' before pushing again.The clone has every commit and
originalready set. Delete it afterwards:rm -rf ~/git-practice/trailguide-clone.
Expected result
git remote -vshowsoriginwith your URL;git statussays "up to date with 'origin/main'".- The project page on GitLab or GitHub shows the playground files and three commits: the import, the web edit, and your local line.
- You have pushed twice, fetched once, pulled once, and understood each.
Common mistakes
-
! [rejected] main -> main (fetch first)on the first push. The project was created with a README, so the server has a commit you do not have:A plain
git pullthen saysfatal: refusing to merge unrelated histories, because the two histories share no commit. Two fixes: the clean one is to delete the project and recreate it empty; the quick one isgit pull origin main --allow-unrelated-histories(an editor opens for the merge message; save and close), resolve the README conflict if any, thengit push -u origin main. -
Authentication failedorHTTP Basic: Access denied. You typed your website password, or a token without thewrite_repositoryscope, or an expired token. Create a new token and try again; if the helper stored a wrong one, lesson 8.4 shows how to remove it. error: remote origin already exists. A remote was added earlier (perhaps with a typo).git remote set-url origin <correct url>.error: src refspec main does not match any. Either the repository has no commits yet, or your branch is calledmaster.git log --onelineandgit branchtell you which;git branch -m mainrenames.-
Your local changes … would be overwritten by mergeon pull:Output error: Your local changes to the following files would be overwritten by merge: README.md Please commit your changes or stash them before you merge. AbortingYou edited a file that the incoming commit also changes. Commit or stash (lesson 5.7), then pull again.
Show solution
$ cd ~/git-practice/trailguide
$ git remote add origin https://gitlab.com/you/trailguide.git
$ git push -u origin main
$ git status
# … edit docs/faq.md in the browser and commit it there …
$ git fetch
$ git status
$ git pull
$ git log --oneline -3
$ printf '\nLocal line after pull.\n' >> README.md
$ git commit -am "docs: add local line"
$ git push
What happened and why
You added the fourth area. git remote add recorded a name for a URL; git push -u copied your commits there and linked the branches. The browser edit created a commit on the remote that only existed there until git fetch downloaded it into your local repository as origin/main — files untouched — and git pull merged it into your main, which, having no commits of its own, simply fast-forwarded. Your next commit and push closed the loop. From now on, every lesson that says "push" or "pull" refers to this exact movement between your main and origin/main.
Next: Level 3 adds branches, so that work in progress no longer lands on main.