TechEarl

Set Up Git for a New or Existing Local Project

Initialize a new or existing local project, ignore sensitive files before staging, review the first commit, connect an empty remote and push.

Ishan Karunaratne⏱️ 6 min readUpdated
Share thisCopied
How to set up Git for a new project: git init, a starter .gitignore, the first commit, and pushing to a new remote
bash
cd my-project
git init -b main
# Create and review .gitignore before staging files.
git add -A
git diff --cached --stat
git diff --cached
git commit -m "Initial commit"

This starts version control for a new directory or an existing local codebase. The important pause is before the commit: inspect what is staged so secrets, dependency folders and build output do not become part of the first snapshot.

If the code already lives in a repository on GitHub or another host, clone that repository instead. Initializing a new repository does not retrieve someone else's history.

Choose your starting state

For a new folder:

bash
mkdir my-project
cd my-project

For an existing unversioned project:

bash
cd my-existing-project
pwd

Inspect the directory and any enclosing repository before initializing. Running git status here can reveal that the folder is already inside a parent repository. A “not a git repository” result is expected for a genuinely unversioned project. Avoid creating an accidental nested repository.

A first commit of existing code records its state now. It cannot recover development history from before version control existed.

Initialize and choose the branch name

bash
git init -b main

The -b option is available in Git 2.28 and later. It makes the branch name explicit regardless of the installation's default. To set a preference for future repositories:

bash
git config --global init.defaultBranch main

Current Git documentation still describes master as the fallback unless configured otherwise; hosting-service defaults do not determine your local git init default. On an older Git version, initialize first and rename the branch after the first commit:

bash
git branch -m main
Terminal illustrating repository initialization and a first commit.
Initialization creates repository metadata; the first commit records the staged files.

git init normally creates .git, which holds local repository metadata. Deleting it can destroy local history and configuration. If you initialize the wrong directory, establish whether a repository existed beforehand and back up anything important before removing metadata; do not use a blanket rm -rf .git as a routine undo command.

Write .gitignore before staging

A Node project might start with:

gitignore
# Dependencies and build output
node_modules/
dist/
build/
.next/

# Local environment files, with an intentionally sanitized example allowed
.env
.env.*
!.env.example

# Local logs and operating-system files
*.log
.DS_Store
Thumbs.db

Review the patterns for the project. A Python application may also ignore __pycache__/ and its virtual environment; a PHP application often ignores vendor/. Team editor settings may be worth tracking, so do not hide every editor directory automatically. A public .env.example must contain placeholders, never a copied live secret.

Ignore rules do not discover credentials for you. Private keys, database exports, service-account files and other sensitive files may have unrelated names. Inspect the files and the staged diff, and use secret scanning where available.

For pattern precedence and exceptions, see the .gitignore guide.

Stage and inspect the exact first snapshot

bash
git add -A
git status --short
git diff --cached --stat
git diff --cached

git add updates the index; it does not make a commit. The diff is your chance to catch accidental inclusions. For more deliberate selection, stage named files rather than the entire directory.

Before the first commit, remove accidentally staged files from the index while keeping them on disk:

bash
git rm --cached -- .env
git rm -r --cached -- node_modules

Fix the ignore rules and inspect the index again. If a file has changed since staging and Git refuses to remove it, inspect both versions rather than adding -f reflexively. After a repository already has commits, git restore --staged -- path/to/file is another way to unstage a change.

Already committed a credential? Revoke or rotate it first, then follow the sensitive-history cleanup process. Removing it in a later commit leaves older copies in history, and rewriting your repository cannot retract copies already cloned or downloaded.

Set identity and make the first commit

Check the identity this repository will use:

bash
git config user.name
git config user.email

Set repository-local values if needed:

bash
git config --local user.name "Your Name"
git config --local user.email "you@example.com"
git commit -m "Initial commit"

Choose the email you intend to expose in commit metadata, such as a hosting provider's noreply address. Use --global only when that identity is correct for all your repositories. If Git reports “Please tell me who you are,” see the identity setup fix.

Create an empty remote and connect it

Create a repository on your host without adding a README, license or starter ignore file. That gives the local history an empty destination.

GitHub quick setup screen for connecting a local repository to an empty remote.
Copy the URL of the empty remote repository you created.

Choose one authentication method. With SSH:

bash
git remote add origin git@github.com:your-username/my-project.git

Or with HTTPS:

bash
git remote add origin https://github.com/your-username/my-project.git

Run only one of those remote add commands, then inspect the result:

bash
git remote -v

SSH uses a key registered with the host. GitHub HTTPS Git access uses a supported credential flow, such as a personal access token through a credential manager or GitHub CLI sign-in, rather than your account password. Do not embed a token in the remote URL or paste it into shell history. See SSH versus HTTPS remotes.

If the remote is already populated, inspect its history first. Starting by cloning it and copying your local files into that checkout is often easier than reconciling two unrelated initial commits. Do not force-push merely to make the first-push error disappear.

Push and set the upstream

bash
git push -u origin main

For the usual Git configuration, -u records origin/main as the upstream so future git push and git pull have a default branch to use. Confirm the files and commit on the host after the push.

A push error is information about a specific mismatch:

ErrorFirst check
remote origin already existsInspect git remote -v; change the URL if it is wrong
src refspec main does not match anyConfirm a commit exists and the local branch is named main
The current branch has no upstream branchSet the intended upstream
failed to push some refsFetch and inspect the remote's history before deciding how to integrate
refusing to merge unrelated historiesThe two repositories have different roots; review the reconciliation options
Permission denied (publickey)Check SSH key registration and authentication

Protect the shared branch

Configure branch protection or a repository ruleset on the host, where your plan and repository visibility support it. Useful policies include required pull requests, required CI checks and blocking force pushes or deletion.

Inspect the rules' bypass settings: administrators and designated actors may retain exceptions. A rule only protects what its scope and enforcement settings cover. See protecting main on GitHub for the detailed setup.

FAQ

Yes. Initialize in the project root, write ignore rules, stage and inspect the files, then make the first commit. That records today's snapshot and starts history from this point.

No. It stages their current content in the index. Review git diff --cached before git commit, and unstage anything that should not be included.

Usually clone the existing repository instead. A fresh init does not bring its history down and may create a separate history you then have to reconcile.

See also

Sources

Authoritative references this article was fact-checked against.

TagsSet Up Git for a ProjectGitVersion ControlGitHubDevOps

Found this useful? Pass it on.

Copied

Ishan Karunaratne

Systems and Network Architect · Chief Technology Officer

Systems and network architect and Chief Technology Officer with more than two decades designing, building, and running production software, cloud and network architecture, Linux systems, and the bare metal underneath them, and lately working AI into the stack. A US Army veteran who served in Operation Iraqi Freedom. What I write here is drawn from the full arc of that work, across architecture, engineering, and operations, not any single job.

Keep reading

Related posts