npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

git-stacked

v1.0.4

Published

A command to automatically rebase stacked branches in git.

Readme

Stacked

A command to automatically rebase stacked branches in git.

This is useful for when you have multiple branches in the review process that are all based on each other. When you get some feedback and make some changes in one of the base branches, this command is helpful to automatically rebase the dependent branches onto the new base branch.

Installation

If you're using npm: npm install -g git-stacked

Otherwise, paste the shell script at the bottom of this README into your .zshrc or .bashrc file.

Config

It's important that you set the name of the main development branch that you initally branched from and will eventually merge your features into. The default is main and you can change it like this:

$ stacked set-main <branch name>

Usage

  1. Make your changes anywhere in the branch you want to change and commit.
  2. Run stacked to automatically rebase and force push all dependent branches.

Detailed description of what this actually does

It's important to understand what this command actually does so you don't accidentally mess up your branches. It does this:

  1. For each of the historical tips of the new base-branch in reverse chronological order and:
  2. For each of the the child-branches that still contain the historical tip it:
  3. Rebases everything from after the historical tip to the end of the child-branch onto the new base-branch.
  4. git push --force after rebasing, for each child-branch.

I think git only holds a limited number of historical reflogs or only for a limited amount of time. This should work reliably if it is run within a few weeks of making the changes with a normal amount of git activity.

Shell script

stacked() {
  if [[ "$1" == "set-main" ]]
  then
    echo "${2:-main}" > "$HOME/.stackedrc"
    echo "Updated main branch to ${2:-main}"
    return
  fi

  stacked_main_branch="$(cat "$HOME/.stackedrc" 2> /dev/null || echo main)"

  current_branch="$(git rev-parse --abbrev-ref HEAD)"

  commit_date="$(date +%s) +0000"

  # For all the historical tips of this branch
  for tip in $(git rev-list --walk-reflogs "$current_branch")
  do
    # If this tip was not part of the development branch
    if ! git merge-base --is-ancestor "$tip" "$stacked_main_branch"
    then
      # For each branch containing that tip
      for branch in $(git for-each-ref --format='%(refname)' --contains "$tip" refs/heads | sed s=^refs/heads/==)
      do
        # If these branches are not already on the same line
        if ! git merge-base --is-ancestor "$current_branch" "$branch" && ! git merge-base --is-ancestor "$branch" "$current_branch"
        then
          echo "$branch used to be a descendent of previous tip $tip, and is not currently in line with $current_branch"

          # Rebase branch onto the current branch
          # (only commits after the historical tip)
          if ! GIT_COMMITTER_DATE="$commit_date" git rebase --onto "$current_branch" "$tip" "$branch"
          then
            echo
            echo "There was a conflict when rebasing one of the child branches"
            echo "Please resolve the conflicts and finish rebasing."
            echo "After that, check out the original branch and run stacked again to continue."
            echo
            return
          fi
          git push --force 2> /dev/null
        fi
      done
    fi
  done

  git checkout "$current_branch"
}