Programming and IT

How to create a repository from scratch

A repository is your project folder plus a hidden `.git` folder that stores the whole history. One command creates it, but between that command and your first meaningful commit there are a few steps that are hard to redo later — the branch name, the list of ignored files and the link to a server.

Updated
In this article

What git init creates#

$ mkdir invoice-tool && cd invoice-tool
$ git init
Initialized empty Git repository in /home/user/invoice-tool/.git/

A .git folder has appeared — the object database, branch references, settings and the index. Git does not see the rest of the folder yet: files are untracked until you add them.

The command is safe and reversible: deleting .git turns the folder back into an ordinary folder of files. Your working files are not harmed, but the whole history disappears with it, so deleting it only makes sense for an empty, freshly created repository.

There is a second kind — a bare repository, which has no working copy, only the database:

git init --bare /srv/git/invoice-tool.git

You create one on a server so that people can push to it. You do not need one on your own machine.

The default branch name#

Before Git 2.28 the first branch was always called master. Now the name is configurable, and most hosting services default to main. It is easiest to decide once and for all:

$ git config --global init.defaultBranch main
$ git init
Initialized empty Git repository in /home/user/invoice-tool/.git/
$ git branch --show-current
main

If the repository was already created with the old name, rename the branch: git branch -m master main. This works even before the first commit, when the branch has not been "born" yet: it renames the HEAD reference itself.

The first commit#

Three steps: introduce yourself, select files, record them.

$ git config --global user.name "Maria Koval"
$ git config --global user.email "m.koval@example.com"
$ git add .
$ git commit -m "Add project skeleton"
[main (root-commit) 4a1d7c9] Add project skeleton
 3 files changed, 41 insertions(+)
 create mode 100644 README.md
 create mode 100644 app.py
 create mode 100644 requirements.txt

The root-commit note means the commit has no parent: it is the very beginning of history. Git puts your name and email into every commit, and rewriting them in an existing history is hard later, so set them before the first commit.

To check what you got, view the history with git log — after the first commit it shows exactly one line. More on what goes into a commit in git commit.

.gitignore before the first add#

The most common beginner's mistake is committing the virtual environment, the build folder and a file with passwords, and then scrubbing them out of history. It is simpler to write the list of exclusions up front, as a plain text file called .gitignore in the root:

venv/
node_modules/
__pycache__/
dist/
.env
*.local.yml
.DS_Store
.idea/

There are four groups here in a row: environment and build, secrets and local settings, operating-system and editor clutter. Comments in the file go on lines starting with a hash.

The rule is simple: the repository gets what a person wrote; anything produced by a build command or by installing dependencies stays outside.

You can check that a file really is ignored like this:

$ git check-ignore -v .env
.gitignore:5:.env	.env

The output shows which line of which file matched. Empty output means the file is not ignored.

A caveat: .gitignore only affects untracked files. If a file is already in the index, first remove it from there while keeping it on disk: git rm --cached .env. The full syntax is in the article on .gitignore.

Turning an existing folder into a repository#

There are only two differences from an empty project: write .gitignore first, then look at exactly what will go into the first commit.

$ cd ~/projects/old-site
$ git init
$ printf 'node_modules/\ndist/\n' > .gitignore
$ git add .
$ git status -s
A  .gitignore
A  index.html
A  styles/main.css
$ git commit -m "Put the project under version control"

Do not skip the git status -s line: this is exactly where you catch forgotten multi-gigabyte archives and other people's keys. Remove anything extra from the index with git restore --staged <file> and update the exclusion list.

Connecting to a server and the first push#

The repository on your machine is already complete: commits, branches and history all work without any network. A server is needed only for a backup copy and for working together. Create an empty project there (without a README, so the histories do not diverge) and connect it:

$ git remote add origin https://github.com/user/invoice-tool.git
$ git remote -v
origin	https://github.com/user/invoice-tool.git (fetch)
origin	https://github.com/user/invoice-tool.git (push)
$ git push -u origin main

The -u flag links your local main to the server one, after which a plain git push is enough. If the server replies Updates were rejected because the remote contains work that you do not have locally, something is already there — usually an auto-created README. Get it with git pull --rebase origin main and push again. Do not force the push at this point: it would wipe what is on the server. Details in the article on git push.

Common mistakes#

git init was run in the wrong folder. The sign: git status shows hundreds of unrelated files, and a .git folder has appeared in your home directory. The fix is deleting it: rm -rf ~/.git (check the path carefully), then run git init again inside the project.

A nested repository. git init inside a folder that is already under version control creates a second repository; the parent starts seeing that folder as a single object and stops tracking its contents. To check the current root: git rev-parse --show-toplevel.

A secret is already in a commit. Deleting the file in the next commit is not enough — it stays in history. If the commit has not been pushed yet, undoing the commit helps; if it has, the password counts as compromised and must be changed, and the history is cleaned with dedicated tools.

Step-by-step plan

  1. Configure Git onceuser.name, user.email and init.defaultBranch main via git config --global.
  2. Create the repositorygit init in the project folder; check the root with git rev-parse --show-toplevel.
  3. Write .gitignoreDependencies, build output, secrets, editor clutter — before the first git add.
  4. Make the first commitgit add ., review with git status -s, then git commit -m with a meaningful message.
  5. Connect a servergit remote add origin <url> and git push -u origin main.

Start learning this in your own space

The plan goes into your repository: tick off stages, keep notes — the change history shows how far you have come.

Start the plan

Check yourself

1.Which command turns an ordinary folder into a Git repository?

2.The .env file was already committed. What stops Git from tracking it but keeps it on disk?

3.What does the root-commit note in the output of git commit mean?

Sources

Was this helpful?

More articles

Programming and IT git clone git clone takes an entire repository from a server — with all its history, branches and tags — and puts a copy into a new folder on your computer. It is how you start working on any existing project, yours or someone else's. Programming and IT Git branches A Git branch is a movable pointer to a commit, not a copy of your files. That is why creating one costs nothing, and the git branch command is what you use to list, create, rename and delete branches. Programming and IT How to undo a commit The question "how do I undo a commit" actually hides four different ones: fix the last commit, take it back and redo it, erase several, or cancel an old commit in the middle of history. The answer depends above all on one thing — whether anyone besides you has seen that commit. Programming and IT How to learn Python from scratch Python is a good first programming language: code reads almost like text, and the standard library covers most everyday tasks. This plan takes you from installing the interpreter to your own scripts covered by tests in about four months, at roughly an hour a day. Programming and IT How to learn SQL from scratch SQL is the query language of relational databases. Developers, analysts, testers and managers who want to pull numbers themselves all need it. Basic queries take a few weeks to learn; working confidently with complex reports takes two or three months of practice. Below is the order of topics and ways to train on a real database. Programming and IT How to learn Linux from scratch Linux runs most servers, containers and countless devices, so developers, testers, analysts and system administrators all need the command line. The easiest way to learn it is not by reading lists of commands but by working in the terminal every day and solving small practical tasks. Below is a sequence of topics for two to three months.

More solutions