gvm icon indicating copy to clipboard operation
gvm copied to clipboard

use git worktree instead of local git clone

Open shinenelson opened this issue 1 year ago • 1 comments

The purpose of git worktree is to Manage multiple working trees attached to the same repository.

This is precisely what gvm is doing currently. Except that it uses git clone from the archive repository. Operationally, there is no difference between using git clone and git worktree, but under the hood ( of git objects ), the different versions are different copies of the same repository with multiple copies ( the number of go versions that are installed on the machine ) of the same binary git objects. git worktree simplifies the management of this and makes it easier to manage the git objects associated with the repository.

The difference of using git clone vs git worktree is the amount of storage space that is consumed. The golang source has about 200+MB of git objects that is consumed per clone of the repository. This means that if one has 5 different versions installed without any extra packages installed, then that is 1GB of storage consumed. However, using git worktree, the storage stays at ~200 MB. I saw the storage increase by ~150MB after I had installed over 15 versions ( 1.4 through 1.20 ).

Now, the interesting aspect to this ( and the main reason I am opening this issue ) is that switching from git clone to git worktree is a single line of code.

diff --git a/scripts/install b/scripts/install
index a039c27..2b45cbe 100755
--- a/scripts/install
+++ b/scripts/install
@@ -74,7 +74,7 @@ update_source() {
 }
 
 copy_source() {
-       git clone -b "$version" "$GO_CACHE_PATH" "$GO_INSTALL_ROOT" >> "$GVM_ROOT/logs/go-$GO_NAME-install.log" 2>&1 ||
+       git -C "$GO_CACHE_PATH" worktree add "$GO_INSTALL_ROOT" "$version" >> "$GVM_ROOT/logs/go-$GO_NAME-install.log" 2>&1 ||
                display_fatal "Couldn't copy source to target folder. Check the logs $GVM_ROOT/logs/go-$GO_NAME-install.log"
 }

If this seems feasible, and interesting to the project, let me know and I can open a pull request for this change.

shinenelson avatar Feb 20 '25 13:02 shinenelson

I was experimenting with creating a docker image with gvm when I ran into an issue.

$ gvm install go1.22.6
Installing go1.22.6...
ERROR: Couldn't copy source to target folder. Check the logs /root/.gvm/logs/go-go1.22.6-install.log

$ cat /root/.gvm/logs/go-go1.22.6-install.log
Cloning into '/root/.gvm/gos/go1.22.6'...
fatal: hardlink different from source at '/root/.gvm/gos/go1.22.6/.git/objects/pack/pack-56d2327dc48f2b705110bfd8ad91730e563d4858.pack'

Reinstalling gvm within the docker container would fix the issue, but that defeated the purpose.

However, changing gvm to use worktree as suggested here fixed the issue for me.

jadutter avatar Apr 17 '25 02:04 jadutter