GitLearnHub
Practice Flow
15px

Repositories & Remotes

How code gets between your machine and the remote: cloning, creating and connecting repositories, and keeping them in sync.

Clone a Repo (HTTPS Link)

Cloning makes a full local copy of a repo — all files, all branches, and the entire commit history. You only do this once per repo.

Step 1 — Copy the HTTPS link: Open the project on GitLab, click the blue Clone button, and copy the URL under Clone with HTTPS. It looks like https://gitlab.company.com/team/some-repo.git.

Step 2 — Clone it:

bash
git clone https://gitlab.company.com/team/some-repo.git
cd some-repo

The first time, Git asks for your username and password — use your username and your Personal Access Token as the password (see Connect to GitLab or GitHub). Your OS credential store saves it so you are not asked again.

Clone into a folder with a different name, or into the current folder:

bash
git clone <url> my-folder   # custom folder name
git clone <url> .            # into current folder (must be empty)

Clone vs fetch: git clone is the one-time setup that downloads the repo and saves the HTTPS link as the origin remote. After that you never need the URL again — to pull in new changes you just run:

bash
git fetch origin     # download new commits (does not touch your files)
git pull             # fetch + merge into your current branch
💡
Check which URL a repo is wired to with git remote -v. To point an existing repo at a new HTTPS link: git remote set-url origin <new-url>.

Before the code will run, install the project's dependencies — Git only fetches source files, not the libraries they need:

bash
npm install        # Node projects
dotnet restore     # .NET projects
pip install -r requirements.txt   # Python projects

Then check out the branch your team is working on (see Branching later in this guide) before you start making changes.

See the side-by-side comparison →

Shallow Clone & Sparse Checkout — Large Repos

Full history and a full checkout aren't always needed — useful when a repo is huge or you're cloning in CI just to build.

Shallow clone — only the latest commit, not the full history:

bash
git clone --depth 1 <url>

Need the full history later after all?

bash
git fetch --unshallow

Sparse checkout — only check out specific folders from a large monorepo, instead of every file:

bash
git clone --filter=blob:none --sparse <url>
cd repo
git sparse-checkout set path/to/folder1 path/to/folder2
💡
Combine both: git clone --depth 1 --filter=blob:none --sparse <url> — minimal history, minimal files, fastest possible clone of a large repo.

Start a New Repo & Connect (git init)

Use this when you have a local folder (a new project, or code that isn't in Git yet) and want to put it on GitLab or GitHub. This is the opposite of cloning — here the code starts on your machine, not on the server.

💡
If the repo already has code on the server, do not use git init — just clone it. Use git init only for a brand-new repo or a local folder that has never been in Git.

Step 1 — Create an empty project on GitLab. Click New project → Create blank project. Leave "Initialize repository with a README" unticked — an empty repo avoids a first-push conflict. Then copy its Clone with HTTPS URL.

Step 2 — In your local folder, run:

bash
cd my-project
git init
git remote add origin https://gitlab.company.com/team/my-project.git
git add .
git commit -m "Initial commit"
git branch -M main
git push -u origin main

git init alone does nothing with the URL — it only creates a local repo. The URL does not become connected until git remote add origin <url>. That is the step people get stuck on. Confirm it worked with:

bash
git remote -v     # should list origin → your HTTPS URL (fetch + push)
⚠️
If the push is rejected with ! [rejected] ... fetch first, the remote was not empty (it had a README or other commits). Pull and merge the unrelated history once, then push:
git pull origin main --allow-unrelated-histories → resolve any conflict → git push -u origin main.

Remote Tracking — origin/main vs main

This confuses almost everyone at first. When you clone a repo, Git creates two kinds of references on your machine:

main (local)
commits A, B, C, D — your local work
git fetch updates
origin/main
snapshot: A, B, C — last fetch, D not here
≠ live server
Remote main
A, B, C, E, F — teammates pushed E, F

This is why git status says things like "Your branch is behind 'origin/main' by 2 commits" — it's comparing against the cached snapshot, not the live server. Run git fetch to refresh the snapshot.

💡
See all local and remote tracking branches: git branch -a. Remote branches are prefixed with remotes/origin/.

Staying in Sync

While you work on your branch, your teammates keep pushing to main. Your branch falls behind. Bring their changes in regularly to avoid a large conflict later.

bash
# Download the latest changes from the remote (does NOT change your files yet)
git fetch origin

# Apply the latest main onto your branch
git rebase origin/main

fetch vs pull:

💡
Get into the habit of running git fetch origin and git rebase origin/main on your feature branch every morning. It keeps your branch close to main and makes the final merge much smoother.

Try it in Practice →