Skip to content

Reduce $NVM_DIR size with a different manual upgrade script #3676

@ganiulis

Description

@ganiulis

Operating system and version: Ubuntu 24.04

The suggested manual upgrade (see https://github.com/nvm-sh/nvm?tab=readme-ov-file#manual-upgrade) is as follows:

(
  cd "$NVM_DIR"
  git fetch --tags origin
  git checkout `git describe --abbrev=0 --tags --match "v[0-9]*" $(git rev-list --tags --max-count=1)`
) && \. "$NVM_DIR/nvm.sh"

However, I noticed two things I didn't like:

  1. It fetches all tags, when most of the time I only want the latest one
  2. It fetches the entire commit history of the project, increasing the $NVM_DIR directory size

Proof:

~ $ rm -rf $NVM_DIR
~ $ wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
...
~ $ . "$NVM_DIR/nvm.sh"
~ $ nvm --version
0.40.1
~ $ du -sh "$NVM_DIR"
3.4M    /home/hello/.nvm
~ $ (
  cd "$NVM_DIR"
  git fetch --tags origin
  git checkout `git describe --abbrev=0 --tags --match "v[0-9]*" $(git rev-list --tags --max-count=1)`
) && \. "$NVM_DIR/nvm.sh"
remote: Enumerating objects: 9641, done.
...
From https://github.com/nvm-sh/nvm
 * [new tag]         v0.0.1     -> v0.0.1
...
 * [new tag]         v0.9.0     -> v0.9.0
Previous HEAD position was 179d450 v0.40.1
HEAD is now at 977563e v0.40.3
~ $ nvm --version
0.40.3
~ $ du -sh "$NVM_DIR"
7.8M    /home/hello/.nvm

As the checkout fetched the entire commit history and all available tags, the upgrade on a patch version increased the size of $NVM_DIR from 3.4M to 7.8M!

I suggest an adjustment to the upgrade script:

(
  cd "$NVM_DIR"
  nvm_latest_tag=$(git ls-remote --tags --refs --sort='v:refname' origin | tail -n1 | grep -Po 'v\d+\.\d+\.\d+')
  git fetch origin --no-tags --depth=1 tag "$nvm_latest_tag"
  git checkout "$nvm_latest_tag"
) && \. "$NVM_DIR/nvm.sh"

What happens:

  1. The latest tag is assigned to the nvm_latest_tag variable via git ls-remote (listing all remote tags), tail (parsing the newest tag at the bottom of the output), and grep (the regex 'v\d+\.\d+\.\d+' outputs the semantic tag)
  2. Fetch only gets the latest tagged state of the project while ignoring other tags, hence --no-tags --depth=1
  3. Checkout as usual

Since it's in a subshell, the nvm_latest_tag variable is destroyed after the upgrade is complete.

Proof:

~ $ rm -rf $NVM_DIR
~ $ wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
...
~ $ . "$NVM_DIR/nvm.sh"
~ $ nvm --version
0.40.1
~ $ du -sh "$NVM_DIR"
3.4M    /home/hello/.nvm
~ $ (
  cd "$NVM_DIR"
  nvm_latest_tag=$(git ls-remote --tags --refs --sort='v:refname' origin | tail -n1 | grep -Po 'v\d+\.\d+\.\d+')
  git fetch origin --no-tags --depth=1 tag "$nvm_latest_tag"
  git checkout "$nvm_latest_tag"
) && \. "$NVM_DIR/nvm.sh"
remote: Enumerating objects: 20, done.
...
From https://github.com/nvm-sh/nvm
 * [new tag]         v0.40.3    -> v0.40.3
Previous HEAD position was 179d450 v0.40.1
HEAD is now at 977563e v0.40.3
~ $ nvm --version
0.40.3
~ $ du -sh "$NVM_DIR"
3.7M    /home/hello/.nvm

The size difference this time is now only 0.3M over the original 4.4M for the same upgrade.

Benefits:

  1. Shallow fetch means $NVM_DIR does not keep the entire history of the repository in the end-user's machine
  2. Smaller $NVM_DIR size
  3. If something breaks and reversion is necessary the previous tag is still kept for checkout
  4. Only the tags which were actually used are kept in history

Drawbacks:

  1. More moving parts to fetch the latest tag (tail, grep, variables)
  2. May not be obvious why only the latest tag is available

I have added this to a script that I regularly run in my personal dotfiles and it works fine for me. I would consider this approach a good alternative if keeping the size of $NVM_DIR at a minimum is important for the end-user.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions