-
-
Notifications
You must be signed in to change notification settings - Fork 9.5k
Description
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:
- It fetches all tags, when most of the time I only want the latest one
- It fetches the entire commit history of the project, increasing the
$NVM_DIRdirectory 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/.nvmAs 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:
- The latest tag is assigned to the
nvm_latest_tagvariable viagit ls-remote(listing all remote tags),tail(parsing the newest tag at the bottom of the output), andgrep(the regex'v\d+\.\d+\.\d+'outputs the semantic tag) - Fetch only gets the latest tagged state of the project while ignoring other tags, hence
--no-tags --depth=1 - 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/.nvmThe size difference this time is now only 0.3M over the original 4.4M for the same upgrade.
Benefits:
- Shallow fetch means
$NVM_DIRdoes not keep the entire history of the repository in the end-user's machine - Smaller
$NVM_DIRsize - If something breaks and reversion is necessary the previous tag is still kept for checkout
- Only the tags which were actually used are kept in history
Drawbacks:
- More moving parts to fetch the latest tag (
tail,grep, variables) - 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.