]> git.ipfire.org Git - thirdparty/git.git/commitdiff
git-gui: default to full copy for linked worktrees
authorMark Levedahl <mlevedahl@gmail.com>
Mon, 21 Jul 2025 15:12:18 +0000 (11:12 -0400)
committerMark Levedahl <mlevedahl@gmail.com>
Mon, 21 Jul 2025 22:22:33 +0000 (18:22 -0400)
git-gui's default clone method is git-clone's default, and this uses
hardlinks rather than copying the objects directory for local
repositories. However, this method explicitly fails if a symlink (or
.gitfile) exists in the path to the objects directory. Thus, the default
clone option fails for worktrees created by git-new-workdir or
git-worktree.  git-gui's original do_clone trapped this error for a
symlinked git-new-workdir tree, directly falling back to a full clone,
while the updated git-gui using git-clone does not. (The old do_clone
could not handle gitfile linked worktrees, however).

Let's apply the more friendly fallback to a full clone in both these
cases where git-clone behavior throws an error on the default method.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
lib/choose_repository.tcl

index e74c39c34c525b7e5a7b4c983b5f9a28d9c68660..2bd230b5d2bac7f1976f817785ab43832edb7222 100644 (file)
@@ -557,6 +557,25 @@ method _update_clone {args} {
 method _do_clone2 {} {
        if {[file isdirectory $origin_url]} {
                set origin_url [file normalize $origin_url]
+               if {$clone_type eq {hardlink}} {
+                       # cannot use hardlinks if this is a linked worktree (.gitfile or git-new-workdir)
+                       if {[git -C $origin_url rev-parse --is-inside-work-tree] == {true}} {
+                               set islink 0
+                               set dotgit [file join $origin_url .git]
+                               if {[file isfile $dotgit]} {
+                                       set islink 1
+                               } else {
+                                       set objdir [file join $dotgit objects]
+                                       if {[file exists $objdir] && [file type $objdir] == {link}} {
+                                               set islink 1
+                                       }
+                               }
+                               if {$islink} {
+                                       info_popup [mc "Hardlinks are unavailable.  Falling back to copying."]
+                                       set clone_type full
+                               }
+                       }
+               }
        }
 
        if {$clone_type eq {hardlink} && ![file isdirectory $origin_url]} {