Git Commands to Remove Merged or Nonexistent Local Branches

Discover git commands to delete local branches that have been removed from remote or merged into the main branch.

Over time, your local git branches list can become overwhelming, particularly if you develop on a single branch, generate a pull request, merge it into the main branch, and then remove the remote git branch once it has been merged. After the branch is removed from the remote repository, there is no need to keep it on your local machine.

The following git command will delete all local branches that have been merged into the main branch. If your git trunk branch is not named main or you wish to remove all branches that have been merged into a branch other than main, simply modify the two instances of the word main in the command to reflect the name of your branch.

List of git commands to remove local merged git branches

To remove all the local branches, which are merged into the main branch, navigate to the root of the repository and run the following git commands,

  • Fetch the latest updates from the git repository
git fetch
  • See the list of local branches available in the repository
git branch
  • Delete all local branches that have been merged to main branch
git branch --merged main | grep -v "^\* main" | xargs -n 1 -r git branch -d

Explanation:

This command is a combination of several Git commands and shell commands that work together to delete all the local Git branches that have been merged into the main branch, except for the main branch itself.

Here’s a breakdown of the individual commands and what they do:

  1. git branch --merged main: This command lists all the local branches that have been merged into the main branch. The --merged option tells Git to only list branches that have been fully merged into main.
  2. grep -v "^\* main": This command filters out the main branch from the list of branches. The -v option tells grep to invert the match, i.e., show only the lines that do not match the pattern. The pattern in this case is "^\* main", which matches lines that start with an asterisk (\*) followed by the text main.
  3. xargs -n 1 -r git branch -d: This command passes the list of merged branches (excluding main) to the git branch -d command, which deletes each branch. The -n 1 option tells xargs to pass one branch name at a time to the git branch -d command. The -r option tells xargs to only run the git branch -d command if there is at least one branch name to pass to it. The -d option tells Git to delete the branches, but only if they have been fully merged into the current branch (in this case, main). Note that this option will fail if the branch has unmerged changes, in which case the -D option could be used instead to force-delete the branch.

Want to learn such useful commands? Get a Mastering Git book from https://amzn.to/3Hp527B

List of git commands to remove local nonexistent git branches

Similarly, run the following git commands to remove all the deleted branches from the local computer:

  • Fetch the latest updates from the git repository
git fetch
  • See the list of local branches available in the repository
git branch
  • Delete all local branches that have been merged to main branch
git branch -vv | grep ': gone]' | grep -v '\*' | awk '{ print $1; }' | xargs -r git branch -d

Explanation:

This command is a combination of several commands in a shell pipeline that work together to delete Git branches that are marked as "gone".

Here’s a breakdown of the individual commands and what they do:

  1. git branch -vv: This command lists all the Git branches in the local repository, with additional information about their upstream branches (if any). The -vv option adds more information about whether each branch is “up to date”, “behind”, or “ahead” of its upstream branch.
  2. grep ': gone]': This command filters the output of the git branch -vv command to only show the branches that are marked as "gone". The grep command searches for lines that contain the text ": gone]", which indicates that a branch is gone.
  3. grep -v '\*': This command further filters the output to exclude any branches that are currently checked out (indicated by the asterisk symbol). The -v option tells grep to invert the match, i.e., show only the lines that do not contain an asterisk.
  4. awk '{ print $1; }': This command extracts only the branch names from the filtered output. The awk command splits each line of input into fields and prints only the first field, which is the branch name.
  5. xargs -r git branch -d: This command passes the branch names to the git branch -d command, which deletes each branch. The -r option tells xargs to only run the git branch -d command if there is at least one branch name to pass to it. The -d option tells Git to delete the branches. Note that this option will fail if the branch has unmerged changes, in which case the -D option could be used instead to force-delete the branch.

Note: you can test these git commands by creating temporary repository on any git platform like, GitHub, GitLab or Bitbucket.

Disclaimer: This post contains affiliate links. If you use these links to buy something, I may earn a commission at no extra cost to you.

Laravel Middleware Explained: What It Is & How to Create One

Learn what middleware is in Laravel, why it’s essential, and how to create custom middleware for handling requests efficiently. Step-by-step guide included.

Middleware provides a convenient mechanism for inspecting and filtering HTTP requests entering your application. It’s best to envision middleware as a series of “layers” for HTTP requests that must pass through before they hit your application. Each layer can examine the request and even reject it entirely.

For example, Laravel includes a middleware that verifies the authenticity of the user of your application. If the user is not authenticated, the middleware will redirect the user to your application’s login screen. However, if the user is authenticated, the middleware will allow the request to proceed further into the application.

To perform different tasks, we can develop many middlewares besides authentication. For example, a logging middleware might log all incoming requests to your application. 

Laravel framework has included many middlewares, including middleware for authentication and CSRF protection. All of these middlewares are located in the app/Http/Middleware directory.

Create a custom middleware

To create a middleware, we can use the following command,

php artisan make:middleware <middleware-name>

For example, if we want to create a middleware for checking transactions, we can run the following command,

php artisan make:middleware CheckTransaction

 After successful execution of the command, a middleware class will be created under the app/Http/Middleware directory.

In this class, we can define methods to check transactions. If the transaction is not completed, we can redirect the user back to the failed transaction page. However, on the successful transactions, we can allow users to proceed to the next page.

<?php
 
namespace App\Http\Middleware;
 
use Closure;
 
class CheckTransaction
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->input('status') !== 'completed') {
            return redirect('transaction-failed');
        }
 
        return $next($request);
    }
}

As you can see, if the transaction status does not set to “completed”, the middleware will return an HTTP redirect to the client; otherwise, the request will be passed further into the application.

To pass the request deeper into the application (allowing the middleware to “pass”), you should call the $next callback with the $request.

What are accessors and mutators?

Understand accessors and mutators with real-world examples. Learn how to format and modify model data automatically.

In object‑oriented programming, accessors (also known as getters) and mutators (also known as setters) are public methods whose only job is to retrieve or update the value of a class member variable.

Why not use public variables directly?

While it’s technically easier to declare member variables as public, using getters and setters brings major advantages in terms of:

Encapsulation: Data and the methods that operate on it are bundled, and implementation details remain hidden from external code. This separation makes the internal workings of a class changeable without breaking external usage.

Data validation: Setters allow you to enforce rules before updating a value—for instance, preventing setting a value outside an acceptable range.

Naming Conventions

Getter: getVariableName() — returns the value of a private variable.

Setter: setVariableName(newValue) — modifies the value, optionally with validation logic.

Examples

This example shows how getters and setters can be used in Java.

public class Account {
    private int balance;

    public int getBalance() {
        return balance;
    }

    public void setBalance(int newBalance) {
        if (newBalance >= 0) {
            balance = newBalance;
        }
    }
}

Similarly, this example shows usage og getters and setters using Python.

class Person:
    def __init__(self, name):
        self.__name = name

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, new_name):
        if new_name:
            self.__name = new_name

In this Python example, the @property decorator defines an accessor, while the @name.setter decorator defines a mutator.

Same accessors and mutators can be defined in other languages as well like PHP, Ruby, C#, etc.

Why Use Accessors/Mutators?

Better Encapsulation: Clients of your class interact through methods, not direct access to data.

Safe Updates: Setters can catch invalid data before it gets saved (e.g., negative numbers, abusive inputs).

Maintain Interface Stability: You can refactor or change internal data structures later without affecting external callers.

Customization & Control: Getters can return derived values, or trigger lazy computation; Setters can log events, enforce thread safety, etc.

Community Insight

In everyday developer conversations—such as on forums or Stack Overflow—it’s common to see that “accessor” = getter and “mutator” = setter. Many fall back to the more familiar terms “getters and setters,” and treat them interchangeably.

Conclusion

Accessors and mutators are foundational to good object‑oriented design. They help you build robust, maintainable, and secure classes. Instead of exposing variables directly, these methods provide controlled interaction with internal data, enforcing rules, maintaining invariants, and preserving encapsulation.