DEV Community

Manu
Manu

Posted on

My 'First' GitHub Project

From a Local Folder to GitHub, Using Git and SSH

Before this week, my GitHub profile was mostly a place where projects sat as plain uploaded folders. I had never taken a project through the actual Git workflow from scratch, starting a local repository, track changes properly, and push it up over SSH instead of typing a username and password every time. This article walks through how I did that for the first time, using one of my own data science projects (an EPL results analysis notebook I had been building locally) as the real example.

The point of this article isn't to define Git and GitHub in the abstract. It's to show, step by step, what actually happened on my machine when I turned a folder sitting on my laptop into a proper, version-controlled GitHub repository.

The starting point: a folder, not a repository.

I had a project folder on my machine with a Jupyter notebook, a CSV of match data, and a few helper scripts. Nothing in that folder was being tracked by git yet it was just files sitting on disk. This distinction matters: a folder only becomes a Git repository once you deliberately initialize it. Until then, there is no history, no staging area, and nothing to push anywhere.
To turn the folder into a repository, I ran:

cd epl-results-analysis
git init
Enter fullscreen mode Exit fullscreen mode

This creates a hidden .git folder inside the project. That hidden folder is where Git stores every commit, every branch, and the entire history of the project. Nothing in my actual project files changed git simply started watching the folder.

Deciding what Git should ignore.

Before making my first commit, I created a .gitignore file. This step matters more than it looks. A data science folder tends to fill up with things that should never end up in version control: virtual environment folders, __pycache__directories, .ipynb_checkpoints, and large raw data exports that change constantly. If these get committed early, they clutter the history and make the repository heavier than it needs to be.

.venv/
__pycache__/
.ipynb_checkpoints/
*.pyc
.env
Enter fullscreen mode Exit fullscreen mode

Git ignores anything listed here, so when I check the status of the project, only files that actually matter for the project show up as changes.

Understanding the staging area

This was the part that finally clicked for me during this project. Git does not commit your whole folder every time it commits whatever you have deliberately placed in the staging area. Running git status showed my notebook and script files listed as untracked. To move them into the staging area, I used:

git status
git add notebook.ipynb epl_helpers.py README.md
git status
Enter fullscreen mode Exit fullscreen mode

Running git status again after git add showed the same files, but now listed as "changes to be committed" instead of "untracked." The staging area is essentially a preview of the next commit. This is useful in practice: if I only wanted to commit the README and not the half-finished notebook, I could stage just that one file rather than everything at once.

Making the first commit.

Once the files I wanted were staged, I committed them with a message describing what the commit actually contains:
git commit -m "Add initial EPL results notebook and data loading script"
A commit is a snapshot, not just a save. git records exactly which files changed, what the content looked like, who made the change, and when. Because I staged deliberately rather than committing everything blindly, this first commit told a clear story: "here is the starting version of the analysis," rather than a vague dump of every file on my laptop.

Setting up SSH instead of HTTPS

GitHub lets you connect over HTTPS or SSH. HTTPS works, but it usually means typing a username and a personal access token every time you push. SSH avoids that by using a key pair: a private key that stays on my machine, and a public key that I register with GitHub. Once that's set up, GitHub can verify it's really my machine pushing the code, with no password prompt.
To generate a new key pair, I ran:

ssh-keygen -t ed25519 -C "imm********@gmail.com"
Enter fullscreen mode Exit fullscreen mode

This created two files: a private key (id_ed25519) that never leaves my machine, and a public key (id_ed25519.pub) that is safe to share. I copied the contents of the public key file and added it under GitHub's SSH keys settings. I then confirmed the connection worked before pushing anything:

ssh -T git@github.com
Enter fullscreen mode Exit fullscreen mode

A successful response confirms GitHub recognizes the key and identifies me by username, without ever asking for a password. The private key is the one piece of this whole workflow that must never be shared, committed, or pasted anywhere. It's the equivalent of a house key, while the public key is just the lock GitHub uses to check it.

Connecting the local repository to GitHub.

With SSH working, I created an empty repository on GitHub through the website deliberately empty, with no README or .gitignore auto-generated, since my local project already had its own history started. GitHub then gave me an SSH remote URL, which I attached to my local repository:

git remote add origin git@github.com:<my-username>/epl-results-analysis.git
git remote -v
Enter fullscreen mode Exit fullscreen mode

The remote is just a label Git uses to know where "GitHub" is for this project. Running git remote -v afterward let me confirm the URL was set correctly and was using the SSH form (starting with git@github.com) rather than the HTTPS form.

Pushing the project.

The final step was pushing my local commit history up to GitHub:

git push -u origin main
Enter fullscreen mode Exit fullscreen mode

The -u flag links my local main branch to origin/main, so future pushes and pulls can just be git push and git pull without repeating the branch name each time. After this ran, refreshing the GitHub page showed the notebook, helper script, and README sitting in the repository, with the commit message I had written earlier attached to the file history.

A small mistake that taught me something

On my first attempt, I forgot to add the .gitignore file before staging everything, and a .venv folder briefly got added to the staging area. I caught it before committing by checking git status carefully and unstaged it with git restore --staged .venv/ before adding the .gitignore and trying again. This reinforced why checking git status before every commit is worth the extra few seconds. It's the one command that shows exactly what's about to be recorded in the project's history.

What this project actually taught me

Going through this once, deliberately, made several ideas concrete that had previously just been definitions I could recite:
• The working directory, staging area, and commit history are three distinct stages, not one blurry "saving" step.
• Staging lets you commit selectively and intentionally, instead of everything you happen to have open.
SSH keys remove repeated authentication friction and are safer than typing credentials into a terminal repeatedly as long as the private key stays private.
• A .gitignore written before the first commit saves cleanup work later.
git status is the single most useful command in the whole workflow, because it tells you exactly what state your repository is in before you commit or push anything.

Where this goes next.

With the EPL results project now properly version-controlled and published, later changes follow the same pattern: edit files, check status, stage deliberately, commit with a clear message, and push. The next improvement I want to make to this workflow is writing a proper README before pushing, rather than after, so that anyone finding the repository understands what the project does before they open a single file. That's a small habit, but this project made it obvious why it matters.

Disclaimer.

This is not for educational purposes only. _
_This repository is private.

Top comments (0)