git-gui: Windows tk_getSaveFile is not useful for shortcuts

git-gui invokes the tk_getSaveFile dialog to determine the full path-name of the shortcut file to create. But, on Windows, this dialog always dereferences a shortcut (.lnk) file, as this is essentially a soft-link to its target. If the shortcut file already exists, the dialog returns the path-name of the target (i.e., GIT/cmd/git-gui.exe), and not the desired shortcut file selected by the user. There is no Windows file chooser available in Tcl/Tk that does not dereference .lnk files, so this patch avoids using a dialog: the shortcut to be created is on the desktop and named as "Git + Repository Name". If this .lnk file already exists, the user must give permission to overwrite it or the process terminates. Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>

Mark Levedahl committed Apr 13, 2025 at 14:31 UTC 3c8e1fe0eaaa976aace243680b825099f687a9bd
1 file changed +30 -19
lib/shortcut.tcl
+30 -19
@@ -3,27 +3,38 @@
3
4 proc do_windows_shortcut {} {
5 global _gitworktree
6 - set fn [tk_getSaveFile \
7 - -parent . \
8 - -title [mc "%s (%s): Create Desktop Icon" [appname] [reponame]] \
9 - -initialfile "Git [reponame].lnk"]
10 - if {$fn != {}} {
11 - if {[file extension $fn] ne {.lnk}} {
12 - set fn ${fn}.lnk
13 - }
14 - # Use git-gui.exe if available (ie: git-for-windows)
15 - set cmdLine [list [_which git-gui]]
16 - if {$cmdLine eq {}} {
17 - set cmdLine [list [info nameofexecutable] \
18 - [file normalize $::argv0]]
19 - }
20 - if {[catch {
21 - win32_create_lnk $fn $cmdLine \
22 - [file normalize $_gitworktree]
23 - } err]} {
24 - error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"]
6 +
7 + set desktop [safe_exec [list cygpath -mD]]
8 + set link_file "Git [reponame].lnk"
9 + set link_path [file normalize [file join $desktop $link_file]]
10 +
11 + # on Windows, tk_getSaveFile dereferences .lnk files, so no simple
12 + # filename chooser is available. Use the default or quit.
13 + if {[file exists $link_path]} {
14 + set answer [tk_messageBox \
15 + -type yesno \
16 + -title [mc "%s (%s): Create Desktop Icon" [appname] [reponame]] \
17 + -default yes \
18 + -message [mc "Replace existing shortcut: %s?" $link_file]]
19 + if {$answer == no} {
20 + return
21 }
22 }
23 +
24 + # Use git-gui.exe if found, fall back to wish + launcher
25 + set link_arguments {}
26 + set link_target [_which git-gui]
27 + if {![file executable $link_target]} {
28 + set link_target [file normalize [info nameofexecutable]]
29 + set link_arguments [file normalize $::argv0]
30 + }
31 + set cmdLine [list $link_target $link_arguments]
32 + if {[catch {
33 + win32_create_lnk $link_path $cmdLine \
34 + [file normalize $_gitworktree]
35 + } err]} {
36 + error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"]
37 + }
38 }
39
40 proc do_cygwin_shortcut {} {