Thursday, September 10, 2026

India Plans Points System to Strip Repeat Traffic Offenders of Licences and Vehicle RCs

See All Articles


5 Key Takeaways

  • India plans a graded points system that would deduct points from driving licences and vehicle registration certificates for traffic offences, with suspension or cancellation after a defined limit.
  • The policy aims to reduce road accidents and fatalities in India, where about 500,000 accidents and 180,000 deaths occur yearly, mostly among people aged 18 to 36.
  • Under the proposed system, clean-record drivers may receive insurance or company incentives, while habitual offenders face escalating penalties and possible loss of driving privileges.
  • The Road Transport and Highways Ministry plans 1,600 driving training centres nationwide, with 24 operational, 112 in the pipeline, and about one million drivers already trained.
  • Other announced measures include Bharat NCAP 2.0 from October 2027 and emission-control retrofit devices for older BS IV and BS III/IV diesel vehicles, though formal points-system rules remain unpublished.



See All Posts on GitHub    « Previously

Git Checkout vs. Git Switch: Comparing and Contrasting Two Branch Commands

Git provides several commands for working with branches, but two commands that often cause confusion are git checkout and git switch. Both can be used to move from one branch to another, but they are not equivalent in purpose or design. Understanding the difference helps you write clearer Git commands and avoid accidentally performing the wrong operation.

1. Why Are There Two Commands?

Historically, git checkout was the main command used to change branches. However, it eventually became a multi-purpose command that could do several unrelated things, including switching branches and restoring files.

This created a common source of confusion. For example, the same command could mean "move to another branch" in one situation and "restore this file" in another.

To make these operations easier to understand, Git introduced git switch and git restore. The idea was to separate the responsibilities that had previously been handled by git checkout.

The key idea: git switch is specifically designed for changing branches, while git checkout is a broader, older command that can change branches as well as check out files and specific commits.

2. Using Git Checkout to Switch Branches

Before git switch existed, developers commonly used git checkout to move from one branch to another.

git checkout feature-login

This tells Git to move the current working directory from the current branch to feature-login.

For example, suppose you are currently on main:

git branch

* main
  feature-login
  bugfix

Running:

git checkout feature-login

changes the current branch to feature-login.

3. Using Git Switch to Change Branches

The same operation can be expressed more explicitly with git switch:

git switch feature-login

The meaning is immediately clear: switch the current branch to feature-login.

This is one of the main reasons git switch was introduced. Its purpose is narrower and therefore easier to understand.

4. Comparing the Basic Syntax

Operation Git Checkout Git Switch
Switch to an existing branch git checkout feature git switch feature
Create and switch to a new branch git checkout -b feature git switch -c feature
Switch to another commit git checkout abc123 Not its primary purpose
Restore a file git checkout -- file.txt Not supported for this purpose

5. Creating a New Branch

Both commands can create a new branch and immediately switch to it.

Using git checkout

git checkout -b feature-payment

The -b option tells checkout to create the branch and then move to it.

Using git switch

git switch -c feature-payment

Here, -c means create a new branch and switch to it.

The result is essentially the same: a new branch named feature-payment is created and becomes the current branch.

6. The Important Difference: Checkout Does More

The biggest difference between the two commands is not what they can do when switching branches, but what checkout can do beyond branch switching.

Historically, git checkout has been used for several different tasks:

  • Switching between branches.
  • Creating and switching to a new branch.
  • Checking out a particular commit.
  • Restoring files from another commit or branch.

By contrast, git switch focuses on branches. It does not replace every capability of git checkout.

7. Checkout Can Move to a Specific Commit

One common use of git checkout is moving to a particular commit rather than a branch.

git checkout abc123

This places Git at the specified commit. Because that commit is not necessarily the tip of a branch, you may end up in what Git calls a detached HEAD state.

git switch is intentionally focused on branch switching, so checking out an arbitrary commit is not its primary role.

Important: Being in a detached HEAD state is not inherently an error. It is useful when you want to inspect or experiment with a particular commit without moving an existing branch pointer. However, commits created there can become difficult to find if you do not create a branch to keep them.

8. Checkout Was Also Used to Restore Files

Another source of confusion was that git checkout could operate on files. For example:

git checkout -- README.md

Historically, this was a way to replace the working copy of README.md with the version from the current commit.

Modern Git provides git restore specifically for file restoration:

git restore README.md

This separation makes Git's commands easier to understand:

git switch   → work with branches
git restore  → restore files
git checkout → older, multi-purpose command

9. Switching to a Remote Branch

git switch also provides a convenient way to create a local branch that tracks a remote branch.

For example:

git switch --track origin/feature-login

This creates a local branch associated with the remote-tracking branch and switches to it.

With modern Git versions, Git can often infer the remote branch when the local branch does not yet exist:

git switch feature-login

If Git finds an appropriate remote-tracking branch, it can create the local branch and establish the tracking relationship.

10. Why Git Switch Is Easier to Understand

Consider the following two commands:

git checkout feature-login
git switch feature-login

Both can switch branches, but the second command communicates its intention more explicitly. When you see git switch, you immediately know that the operation concerns branches.

This is particularly useful for beginners because it reduces the number of unrelated meanings they need to remember for one command.

11. Are They Completely Interchangeable?

No. They overlap when the task is switching branches, but they are not interchangeable in every situation.

Capability git checkout git switch
Switch branches Yes Yes
Create and switch to a branch Yes, with -b Yes, with -c
Track a remote branch Yes Yes
Move directly to a commit Yes Not its intended role
Restore files Historically yes No
Dedicated to branch operations No Yes

12. Which Command Should You Use?

For everyday branch operations, git switch is generally the clearer choice in modern Git.

For example, prefer:

git switch main
git switch feature-login
git switch -c feature-payment

rather than relying on git checkout for every branch-related operation.

However, you should still understand git checkout. You will encounter it frequently in older documentation, scripts, tutorials, Stack Overflow answers, and existing projects.

13. A Simple Mental Model

A useful way to remember the difference is to think about the verbs represented by the commands:

git switch → "I want to switch branches."

git restore → "I want to restore files."

git checkout → "I am using the older, multi-purpose command that historically handled both kinds of operations."

14. Final Comparison

git checkout and git switch overlap significantly when it comes to changing branches. If you run:

git checkout develop

or:

git switch develop

the intended result is the same: your working tree moves to the develop branch.

The difference is that git checkout is a broader, historically overloaded command, while git switch was introduced to make branch switching a distinct and easier-to-understand operation.

Therefore, a good modern rule of thumb is: use git switch when your intention is to work with branches, and learn git checkout so you can understand existing Git commands and older workflows.


See All Posts on GitHub    « Previously

Fast-Forwarding Merge vs. Non-Fast-Forwarding Merge in Git

See All Posts on GitHub    « Previously    Next »

Fast-Forwarding Merge vs. Non-Fast-Forwarding Merge in Git

When you merge branches in Git, Git has to decide how to combine the histories of those branches. Sometimes it can simply move a branch pointer forward. Other times, it must create a new commit to record the merge.

The key difference: A fast-forward merge does not create a new merge commit. A non-fast-forward merge creates a new merge commit that explicitly joins two lines of development.

First, Understand What a Git Branch Really Is

Before understanding the two types of merges, it helps to remember that a Git branch is essentially a movable pointer to a commit.

Suppose you start with a main branch:

A --- B --- C
              ^
             main

You then create a branch called feature from commit C and make two commits:

A --- B --- C --- D --- E
              ^           ^
             main       feature

Notice something important: main is still pointing to C, while feature is ahead of it.

This particular situation is what makes a fast-forward merge possible.

What Is a Fast-Forward Merge?

A fast-forward merge happens when the branch you are merging into has not moved forward since the feature branch was created. In other words, the target branch is an ancestor of the branch being merged.

Git does not need to create a new commit because there are no competing changes to combine. It can simply move the target branch pointer forward.

Before the Merge

A --- B --- C --- D --- E
              ^           ^
             main       feature

If you run:

git switch main
git merge feature

Git can simply move main from C to E.

After the Merge

A --- B --- C --- D --- E
                          ^
                    main, feature

No new commit was created. The history is still a straight line.

Think of it this way: Git is saying, "There is nothing to merge. The target branch is simply behind. I can move its pointer forward to the latest commit."

Why Is It Called "Fast-Forward"?

The term comes from what Git does to the branch pointer. It does not perform a complicated three-way merge or create a new commit. It simply fast-forwards the branch reference to a later commit.

Imagine that main is pointing at page 3 of a book and feature has continued the same story through page 5. There is no second story to reconcile. Git can simply move the bookmark from page 3 to page 5.

What Is a Non-Fast-Forwarding Merge?

A non-fast-forward merge is required when both branches have developed independently.

For example, suppose main contains commit D, while the feature branch was created earlier from commit C and contains commits F and G:

              D --- E
             /
A --- B --- C
             \
              F --- G
                    ^
                  feature

Here, main and feature have diverged. The feature branch cannot simply replace main's pointer, because main contains commits that are not part of the feature branch.

Git therefore needs to combine the two histories.

The Merge Commit

When you run:

git switch main
git merge feature

Git can create a new merge commit:

              D --- E
             /         \
A --- B --- C           M
             \         /
              F --- G
                    ^
                  feature

The new commit M has two parents: one from the existing main history and one from the feature history. It records the point at which the two lines of development were brought together.

Think of it this way: Git is saying, "These branches have both moved forward independently, so I need a new commit that joins their histories."

A Simple Real-World Example

Imagine you are working on a website.

You create a login-page branch from main and work on the login page:

git switch main
git switch -c login-page

You make several commits:

git commit -m "Add login form"
git commit -m "Add login validation"

Meanwhile, nobody makes any new commits to main.

The history looks like this:

main
  |
  v
A --- B --- C --- D
              ^
          login-page

Merging login-page into main can be a fast-forward:

A --- B --- C --- D
                  ^
             main, login-page

Now consider a different situation. While you were working on the login page, another developer added commits to main:

              X --- Y
             /
A --- B --- C
             \
              D --- E
                    ^
                login-page

Now the branches have diverged. Git cannot simply move main forward to E, because that would leave commits X and Y out of the resulting history.

A merge commit can join both histories:

              X --- Y
             /         \
A --- B --- C           M
             \         /
              D --- E
                    ^
                login-page

Fast-Forward vs. Non-Fast-Forward

Characteristic Fast-Forward Merge Non-Fast-Forward Merge
Branches diverged? No Yes
Creates a merge commit? No Usually yes
History shape Straight line Branches join together
What Git does Moves the branch pointer forward Creates a commit combining the histories
Useful for Simple linear development Preserving explicit branch/merge history

Forcing a Non-Fast-Forward Merge

There is an important Git option that lets you create a merge commit even when a fast-forward merge would be possible.

git merge --no-ff feature

The --no-ff option means "do not fast-forward."

Suppose the history is:

A --- B --- C --- D
              ^       ^
             main   feature

A normal merge could simply move main to D. But with:

git merge --no-ff feature

Git creates a merge commit:

A --- B --- C --- D
              \       /
                --- M
                    ^
                   main

The exact visual layout of the graph depends on the history, but the important point is that M is an explicit merge commit.

Why Would You Use --no-ff?

At first, creating an extra commit may seem unnecessary. However, it can make the history easier to understand.

Suppose every feature branch is merged with --no-ff. The history can show clearly that a group of commits represented one feature:

--- A --- B ----------- M1 --- N -------- M2 --->
          \             /              /
           C --- D --- /              /
                                      /
                       E --- F -------

The merge commits provide visible boundaries between pieces of work. This can be particularly useful in team environments where understanding the development history matters.

Important: --no-ff does not mean that Git will ignore the actual changes from the branch. It simply tells Git to preserve the merge as an explicit commit instead of reducing it to a pointer movement.

Fast-Forward Is Not the Same as "No Merge"

This is a common source of confusion.

When Git performs a fast-forward, people sometimes say that "nothing was merged." Technically, the changes from the feature branch become part of the target branch, but Git does not need to create a merge commit.

The important distinction is between integrating the changes and creating a merge commit.

A fast-forward integrates the branch by moving the target branch pointer. A non-fast-forward merge integrates the histories by creating a new commit with both histories as parents.

How Git Decides Which One to Use

When you run:

git merge feature

Git examines the relationship between the current branch and feature.

  • If the current branch is an ancestor of feature, Git can fast-forward.
  • If the branches have diverged, Git needs to perform a real merge and create a merge commit, assuming the merge is successful.
  • If you use --no-ff, Git creates a merge commit even when fast-forwarding would otherwise be possible.

What About Conflicts?

A non-fast-forward merge may result in merge conflicts when Git cannot automatically determine how to combine changes made on the two branches.

For example, if both branches modify the same lines of the same file, Git may stop and ask you to resolve the conflict.

Fast-forward merges generally do not encounter this type of merge conflict because there is no divergent history to reconcile. Git is simply advancing the branch pointer along an existing line of commits.

A Useful Mental Model

Fast-forward

Think of two people reading the same book. One person stopped at chapter 3, while the other continued to chapter 5. To catch up, the first person's bookmark simply moves from chapter 3 to chapter 5.

Non-fast-forward

Now imagine two people started from chapter 3 and wrote different endings. Their work has diverged. Someone has to combine the two versions and record that combination. The merge commit represents that joining point.

Common Commands

Allow Fast-Forward When Possible

git merge feature

This is the normal merge command. Git will fast-forward if possible; otherwise it performs a non-fast-forward merge.

Require a Merge Commit

git merge --no-ff feature

This prevents Git from fast-forwarding and creates a merge commit.

Allow Only Fast-Forwarding

git merge --ff-only feature

This tells Git that the merge must be a fast-forward. If the branches have diverged, Git refuses to perform the merge rather than creating a merge commit.

Why This Matters in Team Development

The choice between fast-forward and non-fast-forward merging is not just about Git mechanics. It affects how your project's history looks.

A project that favors fast-forward merges tends to maintain a cleaner, linear history. A project that favors explicit merge commits preserves more information about when separate branches were integrated.

Neither approach is universally better. Teams often choose a strategy based on how they want their Git history to communicate the development process.

In Summary

The easiest way to remember the difference is:

  • Fast-forward merge: the target branch is behind the feature branch, so Git can simply move the target pointer forward.
  • Non-fast-forward merge: the branches have diverged, so Git needs a new merge commit to join their histories.
  • --no-ff: forces Git to create a merge commit even when a fast-forward would be possible.
  • --ff-only: allows the merge only when Git can fast-forward.

In short: fast-forwarding moves a pointer; non-fast-forwarding creates a new commit to join two histories.


See All Posts on GitHub    « Previously    Next »

Why You Cannot Directly Check Out a Remote Branch in Git

See All Posts on GitHub    « Previously    Next »

Why You Cannot Directly Check Out a Remote Branch in Git

A common point of confusion in Git is the difference between a remote branch and a local branch. You may see a branch such as origin/feature-login and naturally think, "I should be able to check it out."

The important idea is this: origin/feature-login is not a normal local branch. It is a remote-tracking reference that tells your local Git repository what the corresponding branch on the remote repository looked like when Git last updated its information.

1. What Is a Remote Branch?

Suppose your team has a remote repository called origin. Someone has pushed a branch called feature-login to that repository.

After fetching the latest information, your repository might show:

origin/main
origin/feature-login
origin/develop

At first glance, origin/feature-login looks like a branch that you can simply switch to. But it is better to think of it as a remote-tracking reference.

It represents your local record of the branch feature-login on the remote named origin. It is not the same thing as having a local working branch named feature-login.

Remote repository | | branch: feature-login v origin/feature-login | | remote-tracking reference v Local repository feature-login | | local branch v Your working directory

2. What Does git fetch Actually Do?

When you run:

git fetch origin

Git contacts the remote repository and downloads information about commits and branches that you do not yet have locally.

It then updates remote-tracking references such as:

origin/main
origin/feature-login

Importantly, git fetch does not normally create or switch your local working branch.

Think of fetching as saying:

"Tell me what exists on the remote and bring the new commits into my local repository, but don't change the branch I'm currently working on."

3. Why Can't You Treat origin/feature-login Like Your Local Branch?

A local branch is something you normally work on. It has a branch name, moves forward as you create commits, and is associated with your working directory when you check it out.

A remote-tracking reference such as origin/feature-login serves a different purpose. It is Git's local representation of where the remote branch was last observed.

Local branch Remote-tracking reference
feature-login origin/feature-login
Used for local development Represents the remote branch locally
Can be checked out normally Not intended to be your normal working branch
Moves as you make commits Moves when Git updates it from the remote
Can have an upstream branch Usually identifies the upstream branch itself

4. The Solution: Create a Local Branch That Tracks It

If you want to work on the remote branch, the usual approach is to create a local branch that tracks the remote branch.

For example:

git switch -c feature-login --track origin/feature-login

This command does two things:

  1. Creates a local branch called feature-login.
  2. Configures it to track origin/feature-login.

You now have a normal local branch that you can work on.

Remote branch origin/feature-login | | -- tracks --> | Local branch feature-login | v Working directory

5. What Does "Tracking" Mean?

Tracking is one of the most useful concepts to understand when working with Git branches.

When your local feature-login branch tracks origin/feature-login, Git knows that these two branches are related.

This allows Git to understand what you mean when you run commands such as:

git pull

Instead of having to specify the remote and branch every time, Git can use the configured upstream branch.

Similarly, when you run:

git push

Git can know where the local branch is intended to push its commits.

Tracking does not mean that the two branches are permanently identical. It simply tells Git which remote branch is the upstream counterpart of your local branch.

6. An Easier Way to Create the Tracking Branch

Git provides a convenient shortcut. If the remote branch exists and there is no conflicting local branch with the same name, you can often simply run:

git switch feature-login

Git can recognize that origin/feature-login exists and automatically create a local feature-login branch that tracks it.

The older, widely used equivalent is:

git checkout -b feature-login origin/feature-login

This explicitly says:

  • Create a local branch named feature-login.
  • Start it from origin/feature-login.
  • Check out the newly created local branch.

7. What Happens When You Pull?

Suppose you have created:

feature-login → tracks → origin/feature-login

Someone else then adds commits to the remote branch.

You can update your knowledge of the remote with:

git fetch origin

Your local remote-tracking reference now moves:

origin/feature-login

Your local branch may still be where it was:

feature-login

When you subsequently run:

git pull

Git uses the tracking relationship to determine which remote branch to fetch from and integrate into your current branch.

Before fetch: feature-login -------- A -------- B origin/feature-login -- A -------- B Someone pushes C to remote: feature-login -------- A -------- B origin/feature-login -- A -------- B -------- C After git pull: feature-login -------- A -------- B -------- C origin/feature-login -- A -------- B -------- C

8. What Does "Merge With It" Mean?

The phrase "merge with the remote branch" can be slightly misleading. You do not normally merge directly with a server-side branch.

Instead, Git first represents the remote branch locally as a remote-tracking reference such as:

origin/feature-login

You can then merge that reference into your local branch:

git merge origin/feature-login

For example, imagine your local branch contains:

A --- B --- C
          \
           D --- E    (feature-login)

Meanwhile, the remote-tracking branch has advanced:

A --- B --- C --- F --- G
          \
           D --- E    (feature-login)

Running:

git merge origin/feature-login

tells Git to integrate the commits represented by origin/feature-login into your current local branch.

9. A Typical Workflow

A practical workflow might look like this:

Step 1: Fetch the remote information

git fetch origin

Step 2: See the remote branches

git branch -r

You might see:

origin/main
origin/develop
origin/feature-login

Step 3: Create a local tracking branch

git switch -c feature-login --track origin/feature-login

Step 4: Work normally

git add .
git commit -m "Add login validation"

Step 5: Push your local commits

git push

Because the local branch is tracking origin/feature-login, Git knows where the commits should be pushed.

10. One Important Correction to the Original Statement

The statement:

"You cannot check out a remote branch."

is useful as a beginner-friendly rule, but it is technically a little too absolute.

Git can check out a remote-tracking reference directly. For example, commands such as:

git checkout origin/feature-login

can put you into a state where HEAD is detached.

You can inspect the code, but you are not working on a normal local branch. If you make commits there, Git does not have a local branch name that automatically moves forward with those commits.

This is why the better practical advice is:

Don't use a remote-tracking reference as your normal working branch. Create a local branch that tracks it instead.

11. The Mental Model to Remember

The easiest way to remember the distinction is to think of the three names as different things:

Name Meaning
feature-login Your local working branch.
origin/feature-login Your local record of the remote branch.
origin The name of the remote repository.

So when someone says:

feature-login tracks origin/feature-login

it means:

Your computer Local branch feature-login | | tracks v Remote-tracking reference origin/feature-login | | represents v Branch on remote repository feature-login

12. The Key Takeaway

A remote branch and a local branch are not the same thing. After git fetch, Git gives you a remote-tracking reference such as origin/feature-login. This lets you see and work with information about the remote branch without making that reference your local working branch.

If you want to develop on that branch, create a local branch from it and configure the local branch to track the remote branch:

git switch -c feature-login --track origin/feature-login

Once the tracking relationship exists, commands such as git pull and git push become much more convenient because Git knows the relationship between your local branch and its remote counterpart.

In one sentence:

origin/feature-login is Git's local reference to a remote branch; to work on it normally, create a local feature-login branch that tracks origin/feature-login.


See All Posts on GitHub    « Previously    Next »

Difference between "git pull" and "git fetch"

See All Posts on GitHub    « Previously    Next »

Difference Between git fetch and git pull

When working with Git, you often need to get the latest changes from a remote repository. Two commands commonly used for this are git fetch and git pull. Although they are related, they behave quite differently.

What Does git fetch Do?

git fetch downloads the latest commits and other changes from the remote repository, but it does not change your current working branch.

git fetch origin

Think of git fetch as saying: “Show me what has changed on the remote, but don't apply those changes yet.”

This makes git fetch a safer option when you want to inspect incoming changes before integrating them into your work.

What Does git pull Do?

git pull downloads changes from the remote repository and then immediately integrates them into your current branch.

git pull origin main

In simple terms, git pull is roughly equivalent to:

git fetch
git merge

Depending on your Git configuration and the situation, the integration step may use a merge or rebase.

Key Difference

Feature git fetch git pull
Downloads remote changes Yes Yes
Changes your current branch No Yes
Lets you inspect changes first Yes Not by default
Can cause merge conflicts No Yes
Easy way to remember:
git fetch = “Download the changes.”
git pull = “Download and integrate the changes.”

Which One Should You Use?

Use git fetch when you want more control and want to review remote changes before incorporating them. Use git pull when you are comfortable bringing the latest remote changes directly into your current branch.

For beginners, a good habit is to use git fetch when you are unsure about incoming changes, and then decide whether to merge or rebase them after reviewing what has changed.


See All Posts on GitHub    « Previously    Next »