GitLearnHub
Practice Flow
15px

Daily Git Workflow

The commands you run dozens of times a day, and the habits that keep your history clean.

The Core Workflow

Every day with Git follows the same loop:

🔁
Pull latest  →  Make changes  →  Stage  →  Commit  →  Push

Pull — get the latest changes from the remote before you start:

bash
git pull

Check what has changed — after editing files:

bash
# See which files changed
git status

# See exactly what lines changed
git diff

# See what's staged and about to be committed
git diff --staged

Stage — choose which changes to include in your next save point:

bash
# Stage one specific file
git add src/app.js

# Stage all changed files at once
git add .

Commit — save a snapshot with a message describing what you did:

bash
git commit -m "Add login endpoint to AuthController"
💡
Write commit messages in plain English. Say what you did and why if it is not obvious. Good: "Fix null error when user email is missing". Bad: "fix stuff".

Forgot a file, or want to tweak the message? As long as you haven't pushed yet, --amend folds changes into the last commit instead of creating a "fix typo" commit:

bash
git add forgotten-file.md
git commit --amend --no-edit        # keep the same message
git commit --amend -m "New message" # or change the message too
⚠️
Only amend a commit that has not been pushed yet. Amending after pushing rewrites history — if you must, it needs git push --force-with-lease, and only ever on your own branch.

Push — send your commits to the remote so the team can see them:

bash
git push
⚠️
The first push on a brand-new branch fails with fatal: The current branch has no upstream branch. Git does not yet know where to send it. Run the command it suggests once — git push -u origin your-branch-name — to create the branch on the remote and link it. After that, plain git push works for the rest of the branch's life.

See the history — view past commits:

bash
# Full history
git log

# Compact one line per commit
git log --oneline

Try it in Practice →

Common mistake here →

Staging Selectively — git add -p

Instead of staging a whole file, you can choose individual chunks of changes with git add -p. This is useful when you made several unrelated edits to one file and want to split them into separate, focused commits.

bash
git add -p

Git shows each changed section and asks what to do. The main keys:

💡
Even when you only have one thing to commit, git add -p forces you to review every line before it's staged — a good habit for catching debug logs or accidental changes before they land in the repo.

Try it in Practice →

Reading History — git log

The default git log is verbose. These flags make it useful:

bash
# Compact view with branch graph
git log --oneline --graph --all

# Filter by author
git log --author="Alice"

# Filter by date
git log --since="1 week ago"

# Search commit messages
git log --grep="login"

# Find when a specific piece of code was added or removed
git log -S "getUserById"

# Show what files changed in each commit
git log --stat

# Inspect one specific commit in full
git show a1b2c3d
💡
git log -S "someFunction" (called the "pickaxe") finds every commit that added or removed that exact string — extremely useful for tracking down when something was introduced or deleted.

git blame — Who Changed What

git blame shows who last changed each line of a file and in which commit. Essential when you find a bug and need context, or when you want to know who to ask about a piece of code.

bash
# See author and commit for each line
git blame src/auth/login.js

# Blame a specific range of lines only
git blame -L 20,40 src/auth/login.js
💡
VS Code users: Install the GitLens extension (free) — it shows inline blame on every line as you type. Hover any line to see the full commit message and author without running any command.

Commit Message Conventions

Conventional Commits is a lightweight standard that makes your history searchable and the purpose of every commit immediately clear.

Format: <type>: <short description>

Type When to use Example
featNew featurefeat: add user profile page
fixBug fixfix: null error when email is missing
refactorCode change, no behaviour changerefactor: extract validation to helper
choreBuild, config, dependencieschore: update NuGet packages
docsDocumentation onlydocs: update API auth steps
testAdding or fixing teststest: add coverage for login edge cases
💡
Breaking changes: add ! after the type — feat!: rename GetUser to FindUser. Even just using fix: and feat: consistently makes git log --grep="fix:" useful for filtering.

Stash — Save Work Without Committing

Sometimes you are in the middle of something and need to switch to another task urgently — but your changes are not ready to commit. Stash saves your in-progress work temporarily.

bash
# Save your current changes away
git stash

# (Do your urgent task, switch branches, etc.)

# Bring your saved changes back
git stash pop

# See all saved stashes
git stash list

# Delete a stash you no longer need
git stash drop

Try it in Practice →

Stack Tips: .NET & Angular

The same ideas apply to any stack — here's how they look for .NET and Angular.

A few things to know when using Git with .NET solutions.

Always use a .gitignore for .NET. Without it, Git will try to track thousands of generated files in bin/ and obj/. Add this to a file named .gitignore at the root of your repo:

bash
bin/
obj/
.vs/
*.user
*.suo
.idea/
appsettings.Development.json
appsettings.Local.json
⚠️
Never commit appsettings.Development.json or any file containing connection strings, passwords, or API keys. Add these files to .gitignore and share them with teammates through a password manager or secure channel.

Conflicts in .csproj files are common when two people add a NuGet package at the same time. They are XML files — resolve the conflict markers as normal, keep both <PackageReference> entries, then run dotnet build to confirm the file is valid.

After pulling changes that include new NuGet packages, run:

bash
dotnet restore