Git Repository Creation and Cloning
Create repositories in the intended directory, understand an empty versus bare repository, and verify the state produced by cloning an existing repository.
Basic
Choose how a repository comes into existence
Git repositories can begin from an existing directory or from an existing repository. `git init` creates an empty repository structure in a directory; `git clone` creates a new working copy from an existing repository. This lesson owns that creation boundary. The previous foundations lesson already introduced the working-tree → index → commit workflow, so this lesson does not re-teach those state transitions.
Create a repository in an existing directory
When you already have a project directory, `git init` can turn that directory into a Git repository. With a directory argument, Git initializes that location; without one, it initializes the current directory. The directory may already contain ordinary files. Initialization creates the repository metadata without turning those files into commits by itself.
mkdir my-project
cd my-project
printf "first file\n" > README.md
git init --initial-branch=main
git status --shortThe important boundary is visible in the result: the directory now has Git repository metadata, while `README.md` is still untracked until a later command stages it. `git init` does not create the first commit.
Quick check
After `git init --initial-branch=main` in a directory containing `README.md`, what has initialization done by itself?
mkdir my-project && cd my-project && printf "first file\n" > README.mdgit init --initial-branch=main && git status --short
Control the initial branch name
An empty repository has an initial branch name even though that branch has no commit yet. `--initial-branch=main` (short form `-b main`) explicitly selects that name at initialization time. This is different from creating a commit: the branch still has no commit until one is made.
mkdir named-repo
git init --initial-branch=main named-repo
cd named-repo
git symbolic-ref --short HEAD
git status --shortQuick check
What does `git symbolic-ref --short HEAD` show immediately after `git init --initial-branch=main` and before the first commit?
git init --initial-branch=main repocd repo && git symbolic-ref --short HEAD
Recognize a bare repository
`git init --bare` creates a repository without a normal working tree. A bare repository is useful as a repository endpoint for sharing, because its top level is the Git repository data rather than a checked-out project directory. Do not confuse it with an ordinary repository whose working tree simply happens to be clean.
git init --bare shared.git
cd shared.git
git rev-parse --is-bare-repositoryQuick check
What is the defining repository-state difference of a repository created with `git init --bare`?
git init --bare shared.gitcd shared.git && git rev-parse --is-bare-repository
Reinitializing an existing repository
Running `git init` in an existing Git repository is not a second, unrelated repository layered on top of the first. Git recognizes the existing repository and reinitializes it. This is useful to understand because initialization is about establishing repository metadata, not about creating a new history every time the command is run.
git init --initial-branch=main existing
cd existing
git init
git symbolic-ref --short HEADQuick check
What should you expect when `git init` is run inside an existing Git repository?
git init --initial-branch=main existingcd existing && git init
Clone an existing repository
`git clone` starts from an existing repository and creates a new directory containing a working tree and repository metadata. After a normal clone, Git creates remote-tracking references for the source branches and configures the source as the remote named `origin` by default. It also checks out an initial local branch corresponding to the source repository's currently active branch.
git clone /path/to/shared.git project-copy
cd project-copy
git remote -v
git branch --show-current
git status --shortThe source path above is only a shape of the command. In practice, use a real repository path or URL. In Foxipa verification, the source is a disposable bare repository so the complete clone operation can be exercised without network access.
Quick check
After a normal clone, what does Git configure by default for the cloned source?
git clone /path/to/shared.git project-copycd project-copy && git remote -v
Verify what the clone actually produced
Do not treat a successful `git clone` exit code as the whole result. Inspect the new repository. A useful verification sequence is to check the current branch, the working-tree status, the `origin` URL, and the relationship between the local HEAD and the remote-tracking branch.
git branch --show-current
git status --short
git config --local --get remote.origin.url
git symbolic-ref refs/remotes/origin/HEAD
git rev-parse HEAD
git rev-parse origin/mainFor a source whose active branch is `main`, the normal clone should leave the new working tree clean, identify `origin` as the source, and place the local HEAD at the same commit as `origin/main` at clone time. These are state assertions, not assumptions based only on the clone message.
Quick check
Why is `git rev-parse HEAD` compared with `git rev-parse origin/main` in the verification example?
git clone /path/to/shared.git project-copy && cd project-copygit rev-parse HEAD && git rev-parse origin/main
Understand destination failures
A normal clone creates its destination directory when needed. Git does not silently overwrite an existing non-empty destination directory. Likewise, a source that does not exist is an error. These failures matter because a script that ignores clone errors can leave a workflow in a state different from the one the author intended.
git clone /path/to/existing-repository new-copy
# `new-copy` must not already be a non-empty directory.
git clone /path/to/missing-repository missing-copyQuick check
What should a normal `git clone` do when its destination already exists and is non-empty?
mkdir existing && printf "do not overwrite\n" > existing/file.txtgit clone /path/to/shared.git existing
Practice what you learned
Use the dedicated Git code-completion exercise for this lesson.
Official-source boundary
This lesson is grounded in the official Git project documentation for `git-init`, `git-clone`, and the official Git user manual. The live documentation baseline is Git 2.56.0. Foxipa executes the lesson's verified behavior with Git 2.47.3; the official `git-init` documentation records no changes from 2.47.1 through 2.47.3, and the official `git-clone` history likewise records no changes from 2.47.1 through 2.47.3 for the documented behavior used here. This version distinction is recorded rather than hidden.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.