Git Commands

1 Bacic

git status

git add .

git commit -m "Some changes"

git push

Below is a precise and practical explanation of each Git command, in the order they are typically executed during development.


1.

git status

Purpose: Shows the state of your working directory and staging area.

Tells you:

  • Which files were modified

  • Which files are staged (ready to commit)

  • Which files are untracked

  • Whether your branch is ahead or behind the remote

This is how you view what is going to change before you commit.


2.

git add .

Purpose: Stages all changes in the current directory for commit.

Meaning:

  • New files

  • Modified files

  • Deleted files

The dot (.) means "add everything in this folder and subfolders".

This command does not save to Git history yet; it just marks changes to include in the next commit.


3.

git commit -m "Some changes"

Purpose: Stores the staged changes in the repository's local history with a message.

  • Creates a snapshot of your code

  • Message should explain what the change is about

  • This is saved only locally on your machine until pushed

Example of better commit messages:

  • "Fix user login validation"

  • "Add search filter to product list"


4.

git push

Purpose: Sends your local commits to the remote repository (GitHub, GitLab, etc.)

  • Your changes become available to others

  • They are stored in remote version control

Git push uploads:

  • Commits

  • Metadata

  • New branches

If this is the first push of a new branch, you may also see: git push -u origin branchname


Full Workflow Summary

Command
Meaning

git status

Inspect what changed

git add .

Stage those changes

git commit -m "msg"

Record changes locally

git push

Upload changes to remote

This sequence is the core Git workflow for submitting updates.


2 How to Pull Changes from a Fork Parent Using Git

You are basically looking at the standard “keep my fork in sync with the original repo” workflow.

Let’s use your two repos:

  • Parent (original): https://github.com/rajasgs/git-test

  • Your fork: https://github.com/rjsgstest/git-test-sgstest

On your local machine, when you cloned your fork, Git set:

  • origingit@github.com:rjsgstest/git-test-sgstest.git (your fork)

  • You then add:

    • upstreamgit@github.com:rajasgs/git-test.git (the original / parent repo)

Now the commands you listed:

Let us walk through them.


1. Add the parent as a new remote

  • origin already points to your fork.

  • This command adds another remote called upstream which points to the parent/original repository.

  • After this, you have at least two remotes:

    • origin → your fork (rjsgstest/git-test-sgstest)

    • upstream → original (rajasgs/git-test)

You do this only once per clone.

You can confirm with:


2. Fetch the latest changes from the parent

  • Downloads all branches, tags, etc. from the upstream remote into your local repo.

  • Does not change your current branch yet.

  • After fetch, Git has:

    • upstream/main (or upstream/master, depending on the parent’s default branch)

    • and possibly other upstream branches.

Think: “sync my local metadata with the parent, but don’t touch my working tree yet.”


3. Merge the parent’s branch into your current branch

  • This assumes:

    • You are currently on, say, master or main in your local repo.

    • The parent’s default branch is master.

This command:

  • Takes commits from upstream/master

  • Merges them into your current branch (e.g., master).

So your local branch now includes whatever new changes happened in the parent repository.

If the parent’s default branch is main instead of master, you would do:


4. Alternatively: git pull upstream main

This is basically a shortcut for:

So:

  • git pull = fetch + merge (by default)

  • git pull upstream main:

    • Fetches from the upstream remote

    • Merges upstream/main into your current local branch.

Note: Your sample sequence has both:

In practice, you would normally do one or the other, not both, and you must use the correct branch name (either master or main, depending on how the parent repo is configured).


5. Push updated fork back to GitHub

  • This pushes your current local branch (now updated with upstream changes) to origin (your fork) on GitHub.

  • Result:

    • Your fork rjsgstest/git-test-sgstest is now in sync with the parent rajasgs/git-test for that branch.

Often you will be on main locally, so you’re effectively doing:

or simply:


Conceptual Summary

  • origin: your fork on GitHub (where you push).

  • upstream: original parent repo (where you pull new changes from).

Usual workflow to sync fork with parent:

  1. Make sure you are on the correct local branch:

  2. Get latest from parent:

  3. Update your fork on GitHub:


3 Git basic commands

Below is a precise explanation of each command and what it shows inside your Git repository.


1.

git remote

Purpose: Lists the names of remote repositories that this project knows about.

Example output:

This means your local repo is linked to two remotes (often:

  • origin → your fork

  • upstream → parent/original)

This command shows only the remote names, not their URLs.


2.

git remote -v

Purpose: Shows the remote repositories and their fetch/push URLs.

Example output:

Use this to verify:

  • Which remote points where

  • Whether fetch and push URLs differ


3.

git branch -r

Purpose: Lists remote branches only.

Example output:

Meaning:

  • They exist on remote servers (origin/upstream)

  • You haven't necessarily checked them out locally

  • These appear after git fetch

Think: branches that exist "somewhere online."


4. Git branch

git branch -l or simply git branch

Purpose: Lists local branches stored inside your machine.

Example output:

These are branches you have created or checked out.


Difference Summary

Command
Shows
Local / Remote

git remote

Remote names

N/A

git remote -v

Remote names + URLs

N/A

git branch -r

Remote branches

Remote

git branch -l (or git branch)

Local branches

Local


Visual Mapping

Local branch →
Points to
Remote branch

main

tracking

origin/main

feature/api

local only

none

hotfix

local until push

origin/hotfix

Remote-tracking branches (origin/main, upstream/main) represent the last known state of those remotes after fetching/pulling.

Ref:

https://stackoverflow.com/questions/10183724/list-of-remotes-for-a-git-repository https://www.git-tower.com/learn/git/commands/git-remote/ https://stackoverflow.com/questions/73297514/fastest-way-to-check-if-a-git-server-is-available


5 force commit the file even though it is .gitignore + git add

Below is a clear explanation of the scenario and the command:


Why the problem occurs

If a file path or file pattern is listed in .gitignore, Git will not track or stage that file when using:

Git assumes the file is intentionally excluded from version control (commonly for binaries, logs, build artifacts, credentials, etc.).

Example entry in .gitignore:

This will cause rner.jar to be ignored.


Command to force-add an ignored file to Git

or the shorter equivalent:


What this command does

  • Overrides .gitignore rules for this file only

  • Forces Git to stage that file

  • Allows the file to be included in the next commit even though it is normally ignored

This does not delete the rule from .gitignore; it only bypasses it for this one file instance.


When would you use this?

You force-add a file that is normally ignored when:

  • You have a specific binary that must be versioned (example: proprietary JAR dependencies)

  • A config file or generated file is required for deployment or build reproducibility

  • A mistake in .gitignore needs overriding temporarily

Example case: If your application needs that JAR file checked in because it is not available in a Maven/NPM/PyPI repository.


Important Warning

Be cautious with force-adding ignored files. Risks include:

  • Large binary files increasing repository size permanently

  • Accidentally versioning credentials

  • Versioning local machine artifacts instead of real dependencies

If repeated force-add is required, it might mean .gitignore rules need refinement (path-specific ignores instead of global patterns).

Example improvement:

Instead of ignoring all JARs:

You may want to ignore only build output:


Summary

Action
Command
Behavior

Normal add

git add

Ignores files listed in .gitignore

Force add

git add --force FILE

Stages file even if ignored

git add --force (or -f) is the correct instruction when you need to commit a file that .gitignore is blocking.

Ref:

https://stackoverflow.com/questions/8006393/force-add-despite-the-gitignore-file


6 how to install/upgrade git in mac?

Below are the main methods to install or upgrade Git on macOS. The correct method depends on how you prefer to manage software.


If you already use Homebrew, this is the cleanest and most current method.

Install:

Upgrade:

Verify version:

Check where Git is installed:

Homebrew places Git under:


2. Install Git from official installer (GUI Installer)

Download macOS Git installer: Search: “Git for macOS installer” → This is published on git-scm.com, which redirects to the current signed macOS installer.

Run the .pkg, follow setup, close terminal, reopen.

Check:


3. Install Using Xcode Command Line Tools (basic but older version)

If you type git and macOS asks to install developer tools:

This installs Git bundled with Apple dev tools, but this version is usually older.


4. Verify macOS Git Path Priority (Important)

If you have multiple Git installations:

To list all:

If the Homebrew version is installed but not being used, you may need to update your PATH:

For Apple Silicon:

For Intel:

Reload terminal:


Which Method Should You Use?

Method
Version Freshness
Best Use

Homebrew

Very up-to-date

Active development

Git Installer (pkg)

Updated manually

GUI users

Xcode tools

Often outdated

Basic mac Git usage


Confirm Git is Upgraded


7 get all commits

Below is a clear explanation of the command:


What this command does

This command prints all commits in the entire repository history, across all branches, in a single line format.

Meaning:

  • It does not show only the current branch

  • It includes commits reachable from all heads

  • You see the commit hash followed by the commit message on one line

Example output:


Breaking down the command

Part
Meaning

git rev-list

Low-level command to list commit objects

--all

Includes commits from all branches, tags, heads

--pretty=oneline

Show simplified output: one commit per line

Without --pretty=oneline, rev-list prints only the commit hashes in a long block.


Why or when to use this command

This command is helpful for:

  • Auditing the entire history

  • Searching commit messages manually

  • Feeding commit lists to scripts

  • Exporting commit logs

  • Debugging or tracing repository evolution


Alternative Commands for Similar Output

Command
Output

git log --oneline --all

Human-readable version

git log --graph --oneline --all

Visual branch graph

git log --pretty=format:"%h %an %s" --all

Custom formatting

Example graph:


Summary

  • git rev-list --all --pretty=oneline provides a raw, script-friendly list of every commit in the repository.

  • It displays commit hash + subject message, one line each.

  • Useful when performing automation, analysis, history export, or debugging.

Ref:

https://stackoverflow.com/questions/1314950/git-get-all-commits-and-blobs-they-created


8 Git Default Branch

Here’s a clear explanation of what the documentation at that link means — i.e. what it means to “change the default branch” on GitHub, and when/why you’d do that. (GitHub Docs)


What is the “default branch” on GitHub

  • The default branch is the branch that GitHub treats as the main line of development for a repository (the “main” line). (GitHub Docs)

  • It’s the branch that is checked out when someone clones the repo without specifying a branch. (GitHub Docs)

  • It’s also the default base branch for new Pull Requests and many automated workflows (CI, deployment, etc.). (GitHub Docs)

Because of that, choosing the correct default branch influences the repository’s workflow and collaboration model.


When / Why You’d Change the Default Branch

You might want to change the default branch when:

  • You rename your main development branch (e.g. from mastermain). (R-bloggers)

  • You restructure branching strategy: maybe want a different branch (e.g. main, dev, release) as default.

  • You create a new “mainline” branch that should become the canonical base for PRs/merges.

  • After merging or deprecating the old default, you want a clean “central branch” for future development.

Changing default branch ensures new clones and collaborators automatically use the correct branch, and that pull requests target the intended branch by default.


What the Documentation Requires / Preconditions

  • The repository must have at least two branches (so that there’s a branch to switch to). (GitHub Docs)

  • You must have admin access to the repository to change the default branch. (GitHub Docs)

  • If there are organization-level branch-management rules (e.g. protected branches policy), those may limit whether you can change defaults. (GitHub Docs)


How to Change the Default Branch on GitHub

  1. Go to the repository’s main page on GitHub. (GitHub Docs)

  2. Click the Settings tab (or if hidden, open the dropdown menu). (GitHub Docs)

  3. Scroll to the “Default branch” section. Next to the current default branch name, click the “edit” icon. (GitHub Docs)

  4. From the dropdown, select the branch you want as the new default. (GitHub Docs)

  5. Click Update; then read the warning prompt and confirm by clicking “I understand, update the default branch.” (GitHub Docs)

Once confirmed: the new default branch becomes the base for future clones, pull requests, and other GitHub interactions. (GitHub Docs)


Consequences & What You Should Consider

  • New clones → by default checkout the new default branch.

  • Existing clones will still have their original checked-out branch. Developers may need to manually switch to the new default and, optionally, set their local branch to track the corresponding remote branch.

  • Open Pull Requests (PRs) — their base may remain the old default (depending on your GitHub settings). You’ll want to review and re-base/target PRs appropriately if needed.

  • CI / automation / tooling / scripts — any pipelines, hooks, or scripts referencing the old default branch name may break; they need updates to refer to the new branch.

  • Collaborator communication — you should inform the team of the branch rename/default-branch change to avoid confusion.

Ref:

https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-branches-in-your-repository/changing-the-default-branch


9 Git Initial Branch

Below is a clear explanation of:


What this command does

This initializes a new Git repository and sets the first branch to be named main instead of the historical default master.

Without this option, Git used to default to master. Newer Git versions may default to main, but this flag guarantees the branch name.


Breakdown

Part
Meaning

git init

Creates a new, empty repository

--initial-branch=main

Specifies the name of the default branch that Git will create first

So instead of:

The repository will start with:


Why this is used

  • Organizations now standardize on using main as the default branch for inclusivity and consistency.

  • It avoids having to rename the branch later.

  • Useful for automation, scripts, templates, and new projects.


Older Workflow vs. New Workflow

Old method (before Git supported this flag):

New and cleaner method:


When you should use this

Use this flag when:

  • Creating new repositories locally

  • Building templates or scaffolding tools

  • Ensuring consistent naming across multiple environments

  • Aligning with GitHub’s default (main)


Confirm Git Version Support

This feature requires Git 2.28 or later.

Check version:

If older than 2.28, the flag will not work; you would use the rename method instead.


Summary

  • git init: create new repo

  • --initial-branch=main: start with branch named main

  • Cleaner, modern way to avoid renaming later


10 How to cherry pick

Below is a structured explanation of how Git cherry-pick works and when to use it.


What is Cherry-Picking in Git?

Cherry-picking allows you to apply a specific commit from one branch onto another branch, without merging the entire branch history.

Example use case:

  • You fixed a bug on feature/login, and you want only that commit applied to main without merging the entire feature branch.


Basic Syntax

Example:

This takes commit a3c9f2b and applies it to your current branch.


Step-by-Step Example

Suppose:

  • The commit you want to copy is on feature/payment

  • You want it on main

  1. Checkout target branch:

  1. Cherry-pick the commit:

  1. Push changes:


Cherry-Pick Multiple Commits

Pick a range (sequential commits)

Or:

Notes:

  • commit1^..commit5 includes commit1

  • commit1..commit5 excludes commit1

Pick multiple non-sequential commits


Handling Conflicts

If conflicts occur:

  1. Resolve conflicts in affected files

  2. Mark resolved:

  1. Continue:

To abort:


Cherry-Pick with Commit Message Editing

Allows editing the commit message after applying.


Cherry-Pick Without Committing (apply only, stage)

This applies changes but leaves them unstaged; good for combining multiple commits into a single commit.


When Should You Use Cherry Picking?

Appropriate
Not Appropriate

Hotfixes into production

Large features

Selective patch adoption

When branch should merge

Copying specific commits

When commit history must remain linear

Backporting to older versions


Summary

Action
Command

Pick specific commit

git cherry-pick <hash>

Pick a range

git cherry-pick A^..B

Pick multiple

git cherry-pick A B C

Abort

git cherry-pick --abort

Continue after conflict

git cherry-pick --continue

Stage but don't commit

git cherry-pick -n <hash>


11 Git Diff

Below is a precise explanation of the command:


What this command means

15dc8^! is a Git revision range specifier that means:

  • “Show the diff of only commit 15dc8

  • “Compare the commit to its immediate parent

  • It’s equivalent to:

Or:


Breaking it down

Symbol
Meaning

15dc8

The commit you want to inspect

^

Refers to the parent of that commit

!

Tells Git to include only this commit and exclude its parent

So 'commit^!' means:

“Include this commit, exclude its parent — display only this commit’s changes.”


What it displays

It shows:

  • Added/deleted lines

  • File changes

  • Patch differences

  • The actual code delta introduced by that commit

This is useful when you want to:

  • Review what exactly changed in one specific commit

  • Inspect a commit before cherry‐pick or revert

  • Analyze a single change without context of surrounding commits


Example usage

If you want to see the changes introduced by commit 15dc8, run:

If you want to see only file names changed:


When this is useful

Situation
Why use this

Reviewing a single commit

Clear isolation

Debugging code history

See exactly what changed

Comparing commit before cherry-picking

Ensure no unrelated changes

Assess patch size

Count additions/deletions


Summary

  • git diff 15dc8^! shows the diff for that commit only

  • It compares commit 15dc8 to its parent.

  • Equivalent to git show <commit>.

Ref:

https://stackoverflow.com/questions/436362/how-to-diff-a-commit-with-its-parent/449128#449128


12 How to find the parent branch?

Below is the correct, realistic explanation: Git does not store the “parent branch” of a branch. Once a branch is created, Git only stores commits, not where the branch was created from. That is why there is no built-in command git parent, and determining “parent branch” is guesswork based on commit history.


Why Git has no concept of a formal parent branch

When you run:

Git only stores:

  • A pointer to a commit hash

  • Where new commits will attach

It does not store: “The feature/login branch was created from main at this time.”

This is intentional; Git is a directed acyclic graph of commits, not a tree of branches.


How we infer a parent branch

There are techniques that inspect history to guess which branch you originally branched from.

Approach 1: Using merge-base

To check where two branches diverged:

This gives the common ancestor commit.

To view the commit:

This doesn’t return the parent branch, but the divergence commit.


Approach 2: Show where the branch began (first commit not in main)

This often reveals the first commit exclusive to the branch.


Approach 3: Script to guess “parent branch”

Git community often uses this StackOverflow-shared script:

This prints the likely ancestor branch name.

But remember — this is a guess, not guaranteed.


Approach 4: Using reflog (only local, only if never cleaned)

You may find:

This is the closest to the truth, but works only if reflog is intact and only on the developer’s machine where the branch was created.


Important Concept — Branch Parent Is Contextual

Example:

Developer A creates branch → pushes to repo Developer B clones later Developer B cannot know the origin branch from Git alone.

Unless:

  • There is a naming convention (e.g., feature/abc-from-main)

  • There are pull request policies

  • Tools like Jira store branch metadata

Teams solve this by:

Workflow Pattern
Parent Tracking

GitHub PR workflow

PR target determines parent

GitFlow

Dumb knowledge: features always branch from develop

Trunk-based development

Only main exists

Ticket naming conventions

e.g. feature/123-from-main


Summary

| Can Git tell you the parent branch? | No | | Can Git infer one? | Sometimes | | Is the inference guaranteed? | No | | Best reliable source | PR history or your branching policy |


13 When did I create a branch

Below is a clear technical explanation of how to determine when a Git branch was created using reflog, plus what the commands in your example represent.


Core Concept: Git Does not Store Branch Creation Time

Git does not record the timestamp of branch creation as metadata.

However, Git reflog maintains a history of HEAD and reference movements, so we infer the creation moment by examining when a branch first pointed to a commit.


The Command

  • Shows movements of HEAD (checkouts, merges, commits).

  • Displays dates in your local time.

  • Useful to see when you switched branches, created branches, checked out from where, etc.


To Check Reflog of a Specific Branch

This shows all reference updates for the branch dev — including the moment it first appeared as a reflog entry (i.e., creation).

Example:

This means the branch dev was created or checked-out at that moment.

Similarly:

Shows history for that branch’s reference.


Interpreting Your Sample Output

Example log snippet:

This means:

  • On Aug 10, 2022 at 15:08, the user checked out into dev

  • If that commit didn’t previously exist under that branch name, this reflects the branch creation moment.

Another entry:

This suggests that branch Docker-etl-dev existed before 13:02:48.


Important: Reflog Can Expire

Reflog holds a limited history (default 90 days, but can be configured), and may not help for branches created long ago.


From StackOverflow – The Key Takeaways

Link 1: How to determine when a git branch was created?

  • The accepted consensus: No direct metadata.

  • Reflog is the best practical method but not guaranteed if garbage collected.

Link 2: How to go back to the previous master branch

  • Demonstrates using reflog to determine movement between branches, letting you return to a previous state.

Example:


Alternative — Infer Branch Creation Without Reflog

If reflog expired but you know branch parent:

This finds the first commit that exists only in this branch, which is often close to its creation.

Example:

This won’t give an exact time if branch creation preceded first commit, but it provides earliest unique commit timestamp.


Summary

Method
Accuracy
When Useful

git reflog --date=local <branch>

Most accurate

Branch created recently

git log --reverse

Approximate

Reflog expired

Metadata in Git itself

Not available

Not supported

Ref:

https://stackoverflow.com/questions/2255416/how-to-determine-when-a-git-branch-was-created https://stackoverflow.com/questions/42811432/how-to-go-back-to-the-previous-master-branch


14 Create a branch from another branch

Below is a clear explanation of the Git command and the concept of creating a new branch from another branch.


Command:

What it does:

Action
Meaning

git checkout

Switch to a branch

-b

Create a new branch

myfeature

Name of the new branch

dev

Use dev as the starting point

So this command:

  1. Creates a new branch named myfeature.

  2. The branch is created from the current state of dev.

  3. It automatically switches HEAD to the new branch.


Equivalent Using Newer Git Command (git switch)

Modern Git prefers:

  • -c = create

  • Same result, more intuitive.


Why specify the second branch (dev)?

If you do:

It creates myfeature from your current branch (whatever you are on).

But if you want to branch from a different base, you must specify it:

Means: "Start hotfix based on release branch."


When to Create a Branch from Another Branch

Common development workflows:

Scenario
Create from

Start a new feature

main or dev

Bug fix for production

main or master

Fix for older release

release/v2.3

Experimental code

Any branch

Example:

This ensures the new feature has all updates from dev, not only main.


Quick Validation

After creation:

To see which branch you are on and verify:

To confirm commit base:


Summary

Command
Outcome

git checkout -b mybranch

Create from current branch

git checkout -b mybranch dev

Create from dev

git switch -c mybranch dev

Modern equivalent


15 How to rename a branch name?

Below is a precise explanation of how to rename a Git branch in both local and remote workflows.


Rename a Local Branch (Not yet pushed or no remote concern)

If you are currently on the branch you want to rename:

If you want to rename another branch while current branch differs:

Example:


Rename Local Branch and Update Remote

If the branch has been pushed already, renaming involves these steps:

Step 1: Rename locally

Step 2: Delete the old name on remote

Step 3: Push the branch with the new name

If you want the new branch to track the remote:


Verify changes

Shows tracking info and renamed branch reference.


Notes and Warnings

Situation
Impact

Other developers are on the old name

They must fetch new name

Open Pull Requests

Need to be updated

CI pipelines referencing old name

Must be changed

Git reflog still contains old entries

Expected; history is recorded

Developers using the old branch name must run:


Summary Table

Task
Command

Rename current branch locally

git branch -m new-name

Rename another branch locally

git branch -m old new

Push renamed branch

git push origin new-name

Delete old remote branch

git push origin --delete old-name

Set upstream

git push --set-upstream origin new-name

Ref:

https://stackoverflow.com/questions/6591213/how-do-i-rename-a-local-git-branch


16 Git Diff and apply

Below is a precise explanation of the command:


What This Command Does

This:

  1. Generates a patch (set of code changes) representing the difference between two branches:

  2. Pipes that patch output as input (|) to:

    Where - means “read patch from STDIN”.

  3. git apply applies the patch to your current working directory.

Result: The changes that exist in new-feature2 but not in new-feature are applied to your current branch without merging, without committing, and without changing history.


Practical Interpretation

Command
Meaning

git diff A..B

Show changes between A and B

git apply

Apply those changes as modifications

This workflow is effectively: “Take the diff between these two branches and apply that set of edits here.”


When You Would Use This

Use cases:

Scenario
Reason

Copy specific changes without merging

Avoids merging unwanted commits

Backporting code

Patch only selected updates

Apply changes temporarily for testing

Reversible

Move part of a feature into another branch

Manual patching

This is similar to cherry-pick, but:

  • cherry-pick applies the commit(s) with history

  • diff | apply applies the changes without carrying commit metadata


Important Notes

Behavior
Explanation

No commit created

Changes appear as uncommitted in working directory

Can conflict

Same as any patch

Reversible

Using git apply -R (reverse apply)

To reverse:


Example Flow

Suppose you are currently on branch test-branch:

Now test-branch contains edits from new-feature2 that differ from new-feature.

Check what changed:

Commit if desired:


Difference: Cherry-Pick vs Diff|Apply

| Feature | cherry-pick | diff | apply | |--------|-------------|------| | Keeps commit message | Yes | No | | Keeps author name | Yes | No | | Applies uncommitted patch | No | Yes | | Can combine multiple commits before applying | Harder | Easy | | Transfers history | Yes | No |

Summary: diff|apply = patch transfer without history.


Short Summary

  • git diff A..B shows changes

  • | git apply - applies those changes as a patch

  • Useful when you want only the code changes, not the commit history


17 Git for each Ref

Below is a step-by-step technical explanation of the full command:

This script lists all local branches and prints which remote branch each one is tracking.


Break Down the Command

Part 1 — List all local branches

  • refs/heads/* = namespace where local branches are stored.

  • --format='%(refname:short)' prints only the short branch name (e.g., dev instead of refs/heads/dev).

This outputs something like:

Output is piped into while.


Part 2 — Loop through each branch

Reads each branch name into variable b.


Part 3 — Check if this branch has a configured remote tracking branch

  • Looks up: branch.<branchname>.remote

  • Example: branch.dev.remote = origin

  • If it exists, assigns the remote name to variable r.

If a branch is not tracking anything, this IF fails and nothing prints for that branch.


Part 4 — Retrieve the merge reference configured for that branch

  • Looks up: branch.<branchname>.merge

  • Example: branch.dev.merge = refs/heads/main

  • This is the remote branch name that local branch pulls from.


Part 5 — Print result in readable form

Breakdown of ${m##*/} (Bash substring expression):

  • Removes everything before the last /

  • Converts refs/heads/mainmain

Example Output:

Meaning:

  • Local branch dev tracks remote branch origin/main.


What This Script Essentially Does

Local Branch

Remote Name

Remote Branch

It produces a mapping like:

This answers questions like:

  • Which remote branch does my local branch track?

  • Is dev pulling from main or from dev?

  • Which remote branch will git pull apply to?

  • Which branch would --set-upstream refer to?


Why People Use This Command

It is especially useful when:

  • Working in large repos with many feature branches

  • Auditing tracking branches

  • Diagnosing unexpected pulls or merges

  • Verifying CI/CD dependencies

  • Cleaning unused or incorrectly configured branches


Summary

This one-liner:

  • Lists all local branches

  • Finds their configured remote tracking branch

  • Prints it in local -> remote/branch format

A simpler conceptual description:

Show every local branch and the remote branch it tracks

Ref:

https://blog.liplex.de/git-show-parent-branch/


18 Git Rebase

Below is a structured and comprehensive explanation of Git Rebase, its purpose, workflow, and risks.


What is Git Rebase?

Git rebase is a way to replay or relocate commits on top of another base commit or branch.

Meaning:

  • It takes commits from one branch

  • Reapplies them on a different branch

  • Produces a linear commit history

Example conceptually:

Notice D and E were reapplied as new commits (D' and E').


Command: Basic Syntax

To rebase your branch onto another branch:

This means:

Take the commits from feature and apply them after the latest commit on main.


Why Use Rebase?

Advantage: Clean, Linear History

No merge commits cluttering the graph.

Compare:

Merge produces:

Rebase produces:

Useful for:

  • Cleaner project history

  • Easier debugging (bisect, blame)

  • Easier code review


When to Use Rebase

Scenario
Rebase?

Before opening PR

Yes

Updating feature branch with main

Yes

After review changes

Yes

Local, private history

Yes

Public shared branch

No


Important Rule: Never Rebase Public History

If others already pulled your branch, rebasing rewrites commit hashes and causes conflicts for others.

Do not:

Safe rule:

Rebase your local work; merge shared history.


Interactive Rebase

Allows:

  • Squashing commits

  • Editing messages

  • Reordering commits

  • Dropping commits

Practical example:

Change to:

Results in one cleaned commit.


Abort, Continue, Skip

When conflicts occur:

Resolve manually, then:

Skip current commit:

Abort completely:


Rebase vs Merge

Rebase
Merge

Rewrites history

Preserves history

No merge commits

Append merge commit

Cleaner, linear

Accurate timeline

Good before PR

Good for shared branches

Dangerous after push

Safe after push

Industry workflow best practice:

  1. Feature branch: rebase often with main

  2. Shared branches: merge


Summary

Concept
Meaning

Rebase

Move/replay commits

Purpose

Linear readable history

Use

Update feature branches

Avoid

Rebasing public history

Think of rebase as rewriting the story, while merge records the story as it happened.

Ref:

https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase


19 git bi-sect

Below is a clear and complete explanation of Git Bisect, what it solves, how it works, and why it is one of Git’s most powerful debugging tools.


What Is git bisect?

git bisect is a binary search tool in Git that helps you find the exact commit that introduced a bug, regression, or broken behavior.

Instead of checking every commit manually, bisect cuts the search space in half repeatedly, making it very efficient even in large repositories.

Example:

  • If you have 1,000 commits, manual checking means worst-case 1,000 tests.

  • Bisect reduces that to around 10–12 decisions (log2(1000) ≈ 10).


When to Use Git Bisect

Use bisect whenever:

Problem
Example

Bug suddenly started happening

Login button stopped working

Feature disappeared

API stopped returning results

CI test fails but unclear when

Performance dropped

Someone introduced regression

Memory leak appears

You know:

  • A good commit (without the bug)

  • A bad commit (where bug exists)

  • And you want Git to find the commit in between that broke things.


Basic Workflow: Finding a Bad Commit

  1. Start bisect mode:

  1. Mark the commit where the issue exists:

  1. Mark an older commit where the issue was working:

Git now automatically checks out a commit halfway between good and bad.

  1. Test the code manually:

  • If problem is present:

  • If problem is NOT present:

Git continues narrowing until:

  1. When finished:

This returns you to your original branch.


Automating Bisect With a Script

If you can write a test that returns:

  • exit code 0 → good

  • exit code 1 → bad

Then:

Examples of automated bisect tests:

  • Run unit tests that detect regression

  • Check performance thresholds

  • Test build failures

  • Validate API response structure

Automation makes bisect extremely powerful.


Visual Concept

Before:

Each step eliminates half the search space.


Benefits of Git Bisect

Benefit
Result

Fast

Find bug in large repo quickly

Reliable

Unbiased commit discovery

Automatable

Script-friendly

Works without logs

Does not require branch notes

Proven debugging tool

Used in Linux kernel


Real-World Example

If a CI build broke after merge:

  • Mark current HEAD as bad

  • Mark yesterday’s passing commit as good

  • Let bisect find the culprit commit across multiple merges and branches.


Summary Table

Command
Meaning

git bisect start

Begin binary search

git bisect good <commit>

Mark known working

git bisect bad <commit>

Mark known broken

git bisect run test.sh

Automated testing

git bisect reset

End and return

Ref:

https://git-scm.com/docs/git-bisect


20 Git rebase vs git merge

Below is a thorough and practical comparison of Git Rebase vs Git Merge, including behavior, workflow, history impact, and when to use each.


Core Concept

Git Merge

  • Combines two branches by creating a merge commit.

  • Maintains complete history as it happened.

  • Non-destructive — does not rewrite past commits.

Example:

After merge:

Where M is the merge commit.


Git Rebase

  • Moves (replays) commits of one branch onto another branch.

  • Rewrites history by creating new commit hashes.

  • Produces clean, linear history.

Example rebasing feature onto main:

After rebase:

Commits D and E are rewritten to D' and E' (new IDs).


How They Feel in Practice

Action
Merge
Rebase

Bring main branch updates into feature

git merge main

git rebase main

Resulting history

Shows branching

Linear

Commit hashes change

No

Yes

Creates merge commit

Yes

No

Easy to track timeline

Yes

Harder

Easy to read (clean)

Less

More


Key Differences

Category
Git Merge
Git Rebase

History

Preserves real history

Rewrites

Safety

Very safe

Risky when branch shared

Pull Requests

Shows merge arrows

Cleaner review

Sharing Work

Safe to share

Dangerous after push

Local fix-ups

No

Great for squashing


Golden Rule of Rebasing

Do not rebase public or already-pushed branches that others pull from.

Rebase only your private/local feature branches.

If you rewrite history others depend on, git pull becomes painful, requiring force pushes.


When to Use Merge vs Rebase

Situation
Merge
Rebase

Large team shared branches

Yes

No

Preserve historical timeline

Yes

No

Clean readable PR

No

Yes

Before submitting PR

No

Yes

After PR is merged

Yes

No

Simplified heuristic:

  • Use rebase on your local feature work before you push.

  • Use merge to integrate shared branches or finish PRs.


Real Examples

Updating your feature branch with changes from main

Option A: Merge

Creates merge commit.

Option B: Rebase

Replays your commits so the branch appears created after the last commit on main.


Summary

Rebase
Merge

Rewrite history

Keep history

Clean

Accurate

Compact commit list

Shows real branching

Harder for teams

Easier and safer

Rebase = rewrite story Merge = record the story

Ref:

https://stackoverflow.com/questions/804115/when-do-you-use-git-rebase-instead-of-git-merge


21 Head Detached

Here is a clear explanation of that message:


What this means

You are in detached HEAD state.

Specifically:

Your HEAD (your current working position) is not pointing to an active branch, but instead pointing to a commit that used to be part of the branch:

This happens when:

  • You check out a specific commit hash

  • You check out a tag

  • You check out remote branch without creating a local branch

  • You run git checkout <commit> instead of branch name

  • You finish a rebase or got interrupted

Your prompt shows:

Meaning:

You are currently in the history somewhere along that branch’s commit chain, but not on the branch itself.


Why is it called "detached"?

Normally:

Detached:

Your new commits will not belong to a branch. They will be “dangling” commits unless you create a branch.


Is this bad?

Not necessarily, unless you continue working and expect your work to be saved on that branch.

What you lose:

  • If you commit now, and switch branches, your commits may be hard to find.

  • Git keeps them temporarily (in reflog), but they are not attached to a branch.


How to return to your branch


What if you made commits in detached HEAD and want to save them?

Create a branch from here:

Or older syntax:

Now your commits have a branch pointer associated.


Why you might have seen this

Common causes:

Action
Result

git checkout <commit-hash>

Detached HEAD

git checkout tags/v1.2

Detached HEAD

Viewing old code

Detached HEAD

Running bisect

Detached HEAD

Rebasing before finalizing

Detached HEAD


Summary

Detached HEAD
Meaning

You are not on a branch

Correct

You are at a commit

Correct

New commits will not belong to branch

Correct

Can recover

Yes

Ref:

https://loekvandenouweland.com/content/head-detached-from-origin-master.html


22 When should I git pull rebase

Good question to ask explicitly, because git pull --rebase is powerful but easy to misuse.

Let’s keep it focused on “when should I use it” rather than theory.


What git pull --rebase actually does

Normal pull:

= git fetch + merge remote changes into your local branch.

Rebase pull:

= git fetch + rebase your local commits on top of the updated remote branch.

So if:

  • origin/main: A – B – C

  • local main: A – B – C – D – E (your local commits)

Remote adds F:

  • origin/main: A – B – C – F

Then:

rewrites your history to:

  • local main: A – B – C – F – D' – E'

D' and E' are the same changes as D/E, but rewritten on top of F (new hashes). History becomes linear, no merge commit.


When you should use git pull --rebase

1. You want a clean, linear history on your feature branch

Typical scenario:

  • You have a feature branch tracking origin/feature-x

  • Others are pushing to the same branch, or main is moving

  • You don’t want lots of noisy “Merge branch 'main' into feature-x” commits

Use:

Good for:

  • Personal branches

  • Feature branches before opening a PR

  • Repositories where the team prefers rebase over merge for day-to-day development


2. You have local commits and the remote moved ahead

If:

Then:

is ideal. It:

  • Brings in the 3 remote commits

  • Re-applies your 2 local commits on top of them

  • Avoids a merge commit

Result: git log --oneline is much easier to read.


3. Before pushing a feature branch / opening a PR

Common workflow:

Why:

  • Your PR looks like a straight line off main

  • Reviewers see a clean sequence of commits

  • CI pipelines have less branching complexity


4. In repositories that have a “no merge commits” policy on dev branches

Some teams enforce:

  • Only fast-forward merges

  • Or they squash at PR time

Those teams typically recommend setting:

So every git pull is effectively git pull --rebase by default.


When you should NOT use git pull --rebase

1. On branches where history is already shared and used by many people

If you and others are all pushing directly to the same branch (e.g., develop, main, or a shared release branch), and people regularly pull from it:

  • Rebasing rewrites commits

  • That forces everyone else to reconcile history (painful)

Safer there:

or have a process where only PRs go into those branches (and you don’t rebase them after merge).


2. When you want to preserve merge commits as part of history

Sometimes merges themselves are meaningful (e.g., merging feature A into release branch, with a particular context).

Rebasing would:

  • Linearize history

  • Potentially hide where integration actually happened

Use standard merge/pull in these cases.


3. After you’ve already pushed and others have based work on your local commits

If you:

  • Commit locally

  • Push

  • Someone else pulls and builds on top

  • Then you rebase and --force push

You’ve made their history inconsistent. They’ll hit conflicts and confusion.

So: rebase before sharing, not after.


Typical Rules of Thumb

You should use git pull --rebase when:

  1. You’re working on a personal/feature branch, and:

    • You want it up-to-date with main or dev, and

    • You want to avoid merge commits.

  2. You haven’t yet made the branch a long-lived shared base for others.

  3. Your team’s workflow is “rebase to keep history clean”.

You should prefer plain git pull (merge) when:

  1. You are on a shared, canonical branch (e.g., main, develop, release/x.y), and many people pull from it.

  2. The repo’s policy is “we preserve all real merge points in history”.

  3. You’re not comfortable rewriting history that others might already depend on.


Short mental model

  • git pull → “Bring remote work in and create a merge if needed.”

  • git pull --rebase → “Bring remote work in, then re-play my commits as if I wrote them on top of that.”

Ref:

https://stackoverflow.com/questions/2472254/when-should-i-use-git-pull-rebase


23 fetch and merge

Below is a direct, accurate explanation of merge vs pull, and specifically why:

is essentially the same as:


What git pull actually does

Git pull is a shorthand composed of two operations:

Without special options, git pull:

  1. Downloads changes from the remote (fetch)

  2. Merges those changes into your current local branch (merge)


Your Example

Running:

Means:

  • Fetch master from origin,

  • Merge origin/master into your current branch.

Equivalent:

Where:

Command
What it does

git fetch origin

Download latest references from remote

git merge origin/master

Merge remote branch into your local branch

Both result in:

  • Updating your tracking branch (origin/master)

  • Bringing the remote changes into your current branch


Key Difference: Explicit vs Implicit

Method
Visibility

git pull

Does merge automatically

git fetch + merge

Lets you inspect changes before merging

Example:

After fetch, you can inspect:

Then decide to merge or not.


Optional Variation — Rebase Pull

If your config is set to:

Then this:

= git fetch + git rebase instead of merge.

Meaning:

  • The second half is rebase, not merge.

  • History becomes linear.


When to Prefer Each Approach

Action
Best Choice

Quick sync

git pull

Review changes first

git fetch + inspect manually

Clean history before PR

git pull --rebase

Large shared teams

Prefer merge pulls


Visual Summary

Command
Step 1
Step 2

git pull

Fetch

Merge

git fetch + git merge

Fetch

Merge (explicitly)

git pull --rebase

Fetch

Rebase


Final Summary

Yes:

is functionally the same as:

Except git pull hides the intermediate step and merges automatically.

Ref:

https://stackoverflow.com/questions/21756614/difference-between-git-merge-origin-master-and-git-pull


24 abc

Below is the clear explanation of how to merge another branch’s changes into your current branch in Git.


Goal

You have:

  • Your current branch: my-branch

  • Another branch with updates: other-branch

You want to bring all changes from other-branch into my-branch.


Steps to Merge Another Branch into Yours

1. Checkout your branch

Verify:

(Your branch shows with an *)


2. Merge the other branch

What this does:

Applies all commits from other-branch on top of your branch.

If merge completes automatically, Git will fast-forward or create a merge commit.


3. Resolve conflicts if any

If Git shows conflict messages:

  • Open the files and resolve conflicts manually

  • Then:

(if Git didn’t auto-create a commit, you write one)


4. Push your updated branch to remote (optional)


Example: Merge main into your feature branch

This brings all updates from main into feature-login.


If You Prefer Rebase Instead of Merge

Some teams use:

Or:

Rebase = rewrite your work on top of the latest main.

Merge vs Rebase Summary:

Merge
Rebase

Keeps history intact

Rewrites

Adds merge commit

No merge commit

Best for shared branches

Best for local feature

Easy to undo

Clean commit history


Verification Commands

See merge results:

See file differences before merge:


Final Summary

To merge another branch into yours:

If you want clean history and haven’t pushed yet, use:

Ref:

https://help.github.com/en/articles/merging-an-upstream-repository-into-your-fork


25 Show which files have been changed from another branch

Below is exactly what those commands do and how to use them to show which files changed between your current branch and another branch.


Command:

Meaning

  • git diff → show differences

  • --name-status → show only file names plus status letter

  • another_branch → branch to compare against your current branch

This displays a list of changed files and whether each file was:

Code
Meaning

A

Added

M

Modified

D

Deleted

R

Renamed

C

Copied

Example output:

This means:

  • One file modified

  • One file new

  • One deleted


Example with your branch

This shows how your current branch differs from the branch:


Shortened form you wrote:

This works only if:

  • The branch name starts with "p"

  • Git auto-expands it as an abbreviation (unique prefix)

Example:

  • If you have prod, patch, prefix, only one match → auto expand

  • If multiple exist → Git shows error asking for clarity


Compare two branches explicitly (not your current one)

If you want to compare two branches:

Example:


Optional: Show only file names (no status)


Optional: Count changes

Output:


Summary

Goal
Command

See changed files

git diff --name-status branch

Only names

git diff --name-only branch

Summary count

git diff --stat branch

Compare two branches

git diff branch1..branch2

Ref:

https://stackoverflow.com/questions/822811/showing-which-files-have-changed-between-two-revisions


26 Delete a branch

Below is a clear explanation of how to delete branches in Git, both locally and remotely, and the difference between the delete flags (-d vs -D).


Delete a Local Branch

Safe delete (refuses if branch is not merged)

This will delete the branch only if Git determines that its commits are already merged into main, master, or the current branch.

If the branch still contains unmerged commits, Git will warn:

This prevents accidental loss.


Force delete (dangerous but allowed)

This is a force delete.

Use when:

  • You intentionally want to delete even though changes are unmerged.

  • The branch is abandoned, incomplete, or experimental.

Internal translation:


Delete a Remote Branch

Older (still works)

Both remove the branch reference from the remote repository.

Example:

This removes the branch from GitHub/GitLab/Bitbucket, not your local clone.


Summary Table

Task
Command

Delete local branch (safe)

git branch -d branch_name

Force delete local branch

git branch -D branch_name

Delete remote branch

git push origin --delete branch_name


What People Typically Do After Merging a PR

Once your PR is merged to main:

This cleans both local and remote environments.

Ref:

https://stackoverflow.com/questions/2003505/how-do-i-delete-a-git-branch-locally-and-remotely


27 Git stash

Below is a clear explanation of Git Stash, git stash list, and git stash show.


What Git Stash Does

git stash saves your uncommitted changes (modified or staged) and clears your working directory, letting you switch branches or work on something else without committing.

Example:

  • You are in the middle of work

  • You need to switch branches urgently (bug fix, code review, etc.)

  • You do not want to commit yet

You run:

Git:

  • Saves your changes in a temporary stack

  • Restores the branch to a clean state


git stash list

Displays all stashes saved in your repository.

Example output:

Meaning:

  • stash@{0} is the most recent

  • Each stash stores:

    • The branch name you were on

    • The commit you were working against

    • Optional message


git stash show

Shows which files have changed in the most recent stash (stash@{0}).

Output example:

To see the full diff:

or

This prints the actual code differences.


Command
Purpose

git stash

Save changes

git stash save "msg"

Save stash with a message

git stash list

List all stashes

git stash show -p

Show diff of stash

git stash apply

Reapply changes but keep stash

git stash pop

Reapply changes and remove stash

git stash drop stash@{n}

Delete a stash

git stash clear

Remove all stashes


Example Workflow


Quick Summary

Command
Result

git stash list

Shows stored stashes

git stash show

Shows what is inside the stash

git stash show -p

Show patch details

Ref:

https://git-scm.com/docs/git-stash https://www.koskila.net/how-to-list-your-git-stashes/


28 Show git username

To show the Git username configured on your system, use:


Show Global Git Username (most common)

Shows the username used for all repositories unless overridden.


Show Username for Current Repository Only

This shows a username configured specifically for the current project (if set).


Show All Git Configuration With Username Included

or

Look for:


If you want to check which config file holds the username

Output example:


Summary:

Task
Command

Global username

git config --global user.name

Repo-specific username

git config user.name

List all config values

git config --list

Show file and value

git config --show-origin user.name

Ref:

https://alvinalexander.com/git/git-show-change-username-email-address


29 View file in another branch

To view a file from another branch without switching branches, Git provides multiple useful commands.


1. View a file directly from another branch

Example:

This prints the content of the file as it exists in the dev branch.


2. Compare your current file with the version in another branch

Example:

Shows line-by-line changes between your version and main’s version.


3. Temporarily open file using cat

Or redirect to a temp file:


4. Use git checkout for a single file (without switching branch)

If you want to temporarily bring the file into your working directory:

Example:

Warning:

  • This overwrites your working copy of that file (unless saved/stashed first).


5. In modern Git, use git restore for single-file restore

Example:

This is cleaner and safer.


Quick Summary

Task
Command

View file content from another branch

git show branch:file

Compare with other branch

git diff branch -- file

Restore file from another branch

git restore --source=branch file

Checkout only the file

git checkout branch -- file

Ref:

https://stackoverflow.com/questions/7856416/view-a-file-in-a-different-git-branch-without-changing-branches


30

Last updated