Newsletter
Chapter 2 of 5

Git tutorial: create a repo on GitHub or GitLab and clone it

verified on 7 September 2026 · 6 min

Quick answer

Two paths lead to a project tracked by Git and connected to GitHub or GitLab. If the remote repository already exists, git clone is enough. If you start from an existing folder, chain git init, git remote add origin and git push -u origin main. Prefer the SSH address to the HTTPS one: nothing will be asked of you afterwards.

A useful reminder before we start, spelled out in the tutorial introduction: Git runs on your machine, and GitHub and GitLab are nothing more than hosts for Git repositories.

There are two ways to end up with a project tracked by Git and connected to GitHub or GitLab, and the choice depends solely on the order in which things came to exist. Either the remote repository already exists and you fetch it: that is cloning. Or you have a folder on your machine and you publish it: that is init, then push. This chapter covers both.

Creating the remote repository

On GitHub, the New button on the home page, or the address github.com/new. On GitLab, New project then Create blank project.

Three decisions to make at creation time.

The name. It becomes part of the repository URL. Stick to lower case and hyphens, no accents and no spaces.

The visibility. Public means readable by everyone, including the full history and therefore anything you committed there by mistake. Private restricts access to the people you invite. When in doubt, start private: going from private to public later is instant, while the other way round does not erase what has already been copied.

The README file. Tick the box only if you intend to clone the repository. If you already have a folder to publish, leave the repository completely empty, otherwise you will have to reconcile two histories with nothing in common.

Choosing between the SSH and HTTPS addresses

Once the repository is created, the page offers you a URL in two forms. They point at the same repository and differ only in the authentication method.

Service SSH HTTPS
GitHub git@github.com:utilisateur/projet.git https://github.com/utilisateur/projet.git
GitLab git@gitlab.com:utilisateur/projet.git https://gitlab.com/utilisateur/projet.git

Note the difference in shape: the SSH address takes a colon after the host name, not a slash. And above all, the domain changes with the service. Handing out a github.com URL for a project hosted on GitLab is a classic copy-paste mistake.

If you set up an SSH key in the previous chapter, take the SSH address: nothing will ever be asked of you again. The HTTPS address requires a personal access token, which the credential manager can remember for you.

First case: the repository exists, you clone it

This is the situation when you join a project, or when you created the repository with a README.

bash
git clone git@github.com:utilisateur/projet.git

Git creates a projet folder in the current directory, downloads the entire history into it, and registers the remote repository under the name origin. To pick a different folder name, pass it as a second argument:

bash
git clone git@github.com:utilisateur/projet.git mon-dossier

Check what you got:

bash
cd projet
git remote -v
git branch --show-current
Sortie réelle · clone de git/git
origin	https://github.com/git/git.git (fetch)
origin	https://github.com/git/git.git (push)
master

Two remarks about this output. origin appears twice because Git keeps the fetch address separate from the push address, and the two are nearly always identical. And the branch is called master here because that is the default branch name of the cloned repository: cloning takes the name from the server and completely ignores your init.defaultBranch setting, which only applies to the repositories you create yourself.

Second case: the folder exists, you publish it

This is the situation when you started working before you gave Git a thought. Move into the project folder.

bash
cd ~/projets/ma-boutique
git init
Sortie réelle · git init, init.defaultBranch réglé sur main
Initialized empty Git repository in /root/a2/.git/

Git has just created a .git subfolder that holds the whole history. Deleting it would delete version tracking, the rest of your files stays untouched.

Now record a first commit, without which there is nothing to publish:

bash
git add .
git commit -m "Premier commit"

Then declare the remote repository and push:

bash
git remote add origin git@github.com:utilisateur/ma-boutique.git
git branch -M main
git push -u origin main

These three lines deserve an explanation, because they are so often copied without being understood.

git remote add origin ties the short name origin to the repository URL. There is nothing magic about origin, it is a convention, you could call it something else, and nobody does.

git branch -M main renames the current branch to main. The capital -M forces the rename even if a main branch already exists. This line is pointless if you set init.defaultBranch in the previous chapter, but it does no harm.

git push -u origin main sends the branch up and, thanks to -u, remembers the link between your local branch and the one on the server. That link is what lets you write plain git push and git pull from then on. Without it, Git stops you:

Sortie réelle · git push sans dépôt distant configuré
fatal: No configured push destination.
Either specify the URL from the command-line or configure a remote repository using

    git remote add <name> <url>

and then push using the remote name

    git push <name>

To push to multiple remotes at once, configure a remote group using

    git config remotes.<groupname> "<remote1> <remote2>"

and then push using the group name

    git push <groupname>

The ticked README trap

If you created the remote repository with a README while your local folder already had commits, each side has its own first commit, with no common ancestor at all. Git then refuses to bring them together:

Sortie réelle · git pull sur deux historiques sans ancêtre commun
fatal: refusing to merge unrelated histories
If you set pull.rebase in chapter 1

With pull.rebase true, git pull origin main does not merge: it replays your commit on top of the README and succeeds without showing this message. The result is the same history, in a straight line. To observe the refusal described here, add --no-rebase, the --allow-unrelated-histories option below only concerns merging.

The fix is to ask it explicitly, once:

bash
git pull origin main --allow-unrelated-histories
Sortie réelle · avec --allow-unrelated-histories
Merge made by the 'ort' strategy.
 README.md | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

The two histories are joined by a merge commit and the README joins your files. You can then push as normal.

Managing remotes

A few commands worth knowing for what follows.

bash
git remote -v                                    # list the remotes
git remote set-url origin git@github.com:u/p.git # change the URL, for example switch from HTTPS to SSH
git remote rename origin upstream                # rename
git remote remove origin                         # detach

git remote set-url is the one to remember: it is what repairs a repository cloned over HTTPS that you want to switch to SSH, without recloning anything.

A local repository can live without a server

Nothing forces you to publish. A git init followed by commits works perfectly well on a folder that will never leave your machine, and you already get the history and the ability to go back. A remote repository brings three things: a backup somewhere other than your disk, a sharing point with other people, and access to the host’s tools.

Your project is in place. The next chapter moves on to the commands of daily work, and to undoing a mistake.

Common errors

fatal: No configured push destination No remote repository is declared. Add one with git remote add origin, then push the first time with the -u option.
error: remote origin already exists A remote already goes by that name. Fix its address with git remote set-url origin rather than adding a second one.
fatal: refusing to merge unrelated histories The remote repository was created with a README while your folder already had commits. Bring the two together with git pull origin main --allow-unrelated-histories.
SSH URL copied wrong The SSH address takes a colon after the host name, not a slash, and the domain changes with the host: git@gitlab.com:… for GitLab, not github.com.
Newsletter

New tests, tutorials and projects, by e-mail.

Reproducible tests, versioned code, dated results. Never any spam.