Introduction
Git is a distributed version control system used to track changes in source code and collaborate with other developers. Although Git provides many commands, beginners do not need to learn all of them at once.
A better way to learn Git is to understand the commands through a real development workflow.
In this article, we will create a small project, initialize a Git repository, track and commit changes, create a feature branch, merge the changes, connect the repository to a remote repository, and push the project.
Along the way, we will use commonly required Git commands such as git init, git status, git add, git commit, git branch, git switch, git merge, git remote, git fetch, git pull, and git push.
What We Will Build
Suppose we are working on a simple application called ShoppingApp.
Our workflow will look like this:
Create Project
↓
git init
↓
Create / Modify Files
↓
git status
↓
git add
↓
git commit
↓
Create Feature Branch
↓
Make Changes
↓
git commit
↓
Merge Feature
↓
git push
This workflow represents a simplified version of what developers commonly do when working with Git.
Step 1: Create a Project
Create a directory for the project:
mkdir ShoppingApp
cd ShoppingApp
Create a simple file:
README.md
Add some content to the file:
# ShoppingApp
A simple application for managing products.
At this point, the directory is just a normal folder. Git is not tracking it yet.
Step 2: Initialize the Git Repository
Run:
git init
Output may look similar to:
Initialized empty Git repository in .../ShoppingApp/.git/
The git init command creates a new Git repository in the current directory.
Git creates a hidden .git directory containing repository metadata such as:
Commit information
Branch information
Configuration
Object database
References
You normally should not manually modify the contents of the .git directory.
The project now has Git version control enabled.
Step 3: Check the Repository Status
Run:
git status
You may see:
Untracked files:
README.md
This means Git knows that the file exists, but the file has not yet been added to the staging area.
The basic Git workflow has three important states:
Working Directory
↓
Staging Area
↓
Repository
Step 4: Stage the File with git add
To stage the README file:
git add README.md
You can check the status again:
git status
The output should now indicate that README.md is staged for commit.
To stage all changes in the current directory, you can use:
git add .
The staging area allows you to choose exactly which changes should become part of the next commit.
Step 5: Create Your First Commit
Create a commit:
git commit -m "Add project README"
The commit records the staged changes in Git's repository history.
A commit is essentially a snapshot of the project at a particular point in time.
You can think of the workflow as:
Edit Files
↓
git add
↓
Staging Area
↓
git commit
↓
Repository History
Step 6: Configure Your Git Identity
Git records information about who created each commit.
You can configure your name and email globally:
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
You can verify the configuration:
git config --global --list
If you want a configuration to apply only to the current repository, omit --global:
git config user.name "Your Name"
git config user.email "[email protected]"
Repository-specific configuration overrides the corresponding global configuration.
Step 7: View Commit History
After creating a commit, use:
git log
You may see output similar to:
commit 7a91c2d...
Author: Your Name <[email protected]>
Date: ...
Add project README
For a shorter view:
git log --oneline
Example:
7a91c2d Add project README
The commit hash uniquely identifies the commit.
Step 8: Create a Feature Branch
Suppose the team now wants to add product functionality.
Instead of making the changes directly on the main branch, create a feature branch.
Modern Git provides:
git switch -c add-products
This creates the add-products branch and switches to it.
You can verify the current branch with:
git branch
Example:
* add-products
main
The * indicates the current branch.
What Is a Branch?
A branch provides an independent line of development.
Conceptually:
add-products
/
main ----------●
Developers can work on a feature without immediately changing the main branch.
Step 9: Add a Product Feature
Create a file called:
Product.cs
For example:
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
}
Check the changes:
git status
Git will report Product.cs as an untracked file.
Stage it:
git add Product.cs
Create a commit:
git commit -m "Add Product model"
The feature branch now contains the new commit.
Step 10: Compare Changes with git diff
Before committing changes, you may want to inspect what changed.
Modify Product.cs:
public int StockQuantity { get; set; }
Then run:
git diff
Git displays the differences between the working directory and the staged version.
For example:
public decimal Price { get; set; }
+public int StockQuantity { get; set; }
This is useful for reviewing changes before staging them.
After staging the file:
git add Product.cs
you can inspect the staged changes with:
git diff --staged
This distinction is important:
git diff
↓
Working Directory vs Staging Area
git diff --staged
↓
Staging Area vs Last Commit
Step 11: Rename or Move Files with git mv
Suppose we rename:
Product.cs
to:
ProductModel.cs
Instead of manually moving the file and then staging the changes separately, you can use:
git mv Product.cs ProductModel.cs
Git stages the rename.
Commit it:
git commit -m "Rename product model"
Step 12: Remove a File with git rm
If a file is no longer required:
git rm ProductModel.cs
This removes the file and stages the deletion.
Commit the change:
git commit -m "Remove obsolete product model"
Step 13: Merge the Feature Branch
After completing and testing the feature, switch back to the main branch:
git switch main
Then merge the feature:
git merge add-products
Git attempts to integrate the commits from add-products into main.
The history can now look like:
main
|
● Add project README
|
● Add Product model
|
● Rename product model
For more complex projects, Git may encounter a merge conflict.
Step 14: Understand Merge Conflicts
A conflict can occur when two branches modify the same part of a file differently.
For example:
<<<<<<< HEAD
decimal Price;
=======
decimal ProductPrice;
>>>>>>> add-products
Git cannot determine which version should be retained automatically.
The developer must manually resolve the file, remove the conflict markers, and then stage the resolved file:
git add Product.cs
Finally:
git commit
The exact sequence can vary depending on the merge state and Git version.
Step 15: Connect the Repository to a Remote
Local Git repositories can be connected to remote repositories hosted on services such as GitHub or GitLab.
First, create a remote repository.
Then add the remote URL:
git remote add origin <repository-url>
You can verify it with:
git remote -v
Example output:
origin <repository-url> (fetch)
origin <repository-url> (push)
The name origin is a conventional name for the primary remote, but it is not mandatory.
Step 16: Push Changes to the Remote Repository
To upload the local main branch:
git push -u origin main
The -u option establishes an upstream relationship between the local branch and the remote branch.
After that, future pushes can often be performed with:
git push
The workflow is now:
Local Repository
|
git push
↓
Remote Repository
Step 17: Get Changes from the Remote Repository
When other developers push changes, your local repository may not contain those commits.
There are two commonly used commands for retrieving remote changes.
git fetch
Run:
git fetch
This downloads information about new commits and branches from the remote repository without automatically integrating those changes into your current branch.
You can then inspect the changes before deciding how to integrate them.
git pull
Run:
git pull
git pull generally performs a fetch followed by an integration step. Depending on the repository configuration and Git options, that integration may be a merge or rebase.
A simplified view is:
git fetch
↓
Download Remote Updates
git pull
↓
Fetch + Integrate Updates
Understanding this distinction is important when working in a team.
Step 18: Temporarily Save Work with git stash
Sometimes you are working on a feature and need to switch branches, but your current changes are not ready for a commit.
You can temporarily save them:
git stash
Git stores the working changes and returns the working directory to a clean state.
Later, restore the changes:
git stash pop
This is useful when you need to temporarily switch context without creating an incomplete commit.
Step 19: Inspect a Specific Commit with git show
To inspect a particular commit:
git show <commit-hash>
For example:
git show 7a91c2d
The command can display information such as:
Commit metadata
Commit message
Files changed
Line-by-line differences
This is useful when investigating what a particular commit introduced.
Step 20: Understand git reset
git reset can move the current branch reference to another commit and, depending on the mode, change the staging area and working directory.
For example:
git reset --soft HEAD~1
moves the branch back by one commit while keeping the changes staged.
A mixed reset:
git reset HEAD~1
typically moves the branch back and leaves the changes in the working directory but unstaged.
A hard reset:
git reset --hard HEAD~1
also changes the working directory to match the target commit.
Be careful with --hard because uncommitted changes can be lost.
Step 21: Create a Release Tag
Tags can mark important points in repository history, such as application releases.
Create a tag:
git tag v1.0.0
List tags:
git tag
Push a tag to the remote:
git push origin v1.0.0
Tags are commonly used to identify release versions.
Step 22: Find Who Changed a Line with git blame
When investigating a particular line of code, git blame can show the commit associated with that line.
For example:
git blame Product.cs
The output includes information such as:
Commit
Author
Timestamp
Line content
This can be useful during debugging or code archaeology when you need to understand when and why a particular change was introduced.
Essential Git Commands
The commands used in this workflow can be grouped by purpose.
Command | Purpose |
|---|---|
| Create a local repository |
| Configure Git settings |
| View repository status |
| Stage changes |
| Record staged changes |
| View commit history |
| Compare changes |
| Manage branches |
| Switch branches |
| Combine branch changes |
| Manage remote repositories |
| Download remote updates |
| Fetch and integrate remote changes |
| Upload local commits |
| Temporarily save changes |
| Move branch/staging state |
| Mark repository versions |
| Inspect a commit |
| Identify line-level commit information |
| Move or rename files |
| Remove files |
A Typical Daily Git Workflow
A developer may use a workflow similar to this:
git switch main
git pull
git switch -c feature/product-search
# Make code changes
git status
git diff
git add .
git commit -m "Add product search"
git switch main
git pull
git merge feature/product-search
git push
In a team environment, the actual workflow may instead use pull requests or merge requests rather than directly merging feature branches into main.
Git Workflow to Remember
For beginners, the most important sequence is:
1. Create or modify files
↓
2. git status
↓
3. git diff
↓
4. git add
↓
5. git commit
↓
6. git push
For collaborative development:
Create Feature Branch
↓
Make Changes
↓
Commit
↓
Push Branch
↓
Pull Request
↓
Code Review
↓
Merge
This workflow is more important to understand than memorizing dozens of Git commands individually.
Common Git Mistakes
Committing Without Checking the Changes
Before committing, use:
git status
git diff
This helps verify what will actually be included.
Working Directly on main
For team projects, feature branches generally provide a safer development workflow.
Using git reset --hard Carelessly
Always understand which changes will be discarded before using a destructive reset.
Confusing git fetch and git pull
git fetch retrieves remote information without automatically integrating it into the current branch.
git pull retrieves and then integrates remote changes according to the configured pull behavior.
Ignoring Merge Conflicts
A merge conflict is not a Git error that should simply be bypassed. The conflicting code needs to be reviewed and resolved correctly.
Committing Sensitive Information
Never commit passwords, API keys, connection strings containing secrets, private certificates, or other sensitive information.
Use mechanisms such as environment variables, secret stores, and appropriate .gitignore rules.
Conclusion
Git becomes much easier to learn when its commands are understood as part of a development workflow rather than as an isolated list of commands.
The fundamental workflow is:
Working Directory
↓
git add
↓
Staging Area
↓
git commit
↓
Local Repository
↓
git push
↓
Remote Repository
From there, branches allow developers to work on features independently, git merge integrates completed work, git fetch and git pull bring remote changes into the local repository, and commands such as git log, git diff, git show, and git blame help developers inspect repository history.
Once this basic workflow becomes familiar, advanced Git operations become much easier to understand.
For the final C# Corner submission, screenshots from the author's own Git/GitHub workflow can be added for the major steps—repository initialization, staging, commit history, branch creation, merge, and push. This directly addresses the editor's request for step-by-step snapshots and gives readers visual confirmation of each operation.
Join the conversation! Your thoughts help the community grow.