]> git.ipfire.org Git - thirdparty/git.git/commitdiff
git-gui: Add support of SHA256 repo
authorTakashi Iwai <tiwai@suse.de>
Wed, 16 Jul 2025 07:32:25 +0000 (09:32 +0200)
committerJohannes Sixt <j6t@kdbg.org>
Wed, 16 Jul 2025 16:52:38 +0000 (18:52 +0200)
This patch adds the basic support of SHA256 Git repositories.
Most of changes are idiomatic replacement of the hard-coded hash ID
length, but there are subtle things:

* The hash length is determined on startup, and stored in $hashlength
  global variable (either 40 or 64).
* The hard-coded "40" are replaced with $hashlength;
  for regexp patterns, the ugly string map is used.
* Some code have the fixed numbers like 39 and 45, and those are
  replaced with the $hashlength and the offset correction.
* $nullid and $nullid2 are generated for the hash length.

A caveat is that repository picker dialog is performed before
evaluating the repo type, hence $hashlength isn't set there yet.
So the code dealing with the hard-coded "40" are handled differently;
namely, the regexp range is expanded, and the null id is generated
from the HEAD id length locally.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
git-gui.sh
lib/blame.tcl
lib/choose_repository.tcl
lib/commit.tcl
lib/remote_branch_delete.tcl

index 413a8a9abc1f3176d596f41fb2c0b1f815975f66..523e4df8069ac91402ca94dd627353b0f1a7bb5a 100755 (executable)
@@ -1298,6 +1298,17 @@ if {[catch {
        set picked 1
 }
 
+# Use object format as hash algorithm (either "sha1" or "sha256")
+set hashalgorithm [git rev-parse --show-object-format]
+if {$hashalgorithm eq "sha1"} {
+       set hashlength 40
+} elseif {$hashalgorithm eq "sha256"} {
+       set hashlength 64
+} else {
+       puts stderr "Unknown hash algorithm: $hashalgorithm"
+       exit 1
+}
+
 # we expand the _gitdir when it's just a single dot (i.e. when we're being
 # run from the .git dir itself) lest the routines to find the worktree
 # get confused
@@ -1391,8 +1402,8 @@ set is_conflict_diff 0
 set last_revert {}
 set last_revert_enc {}
 
-set nullid "0000000000000000000000000000000000000000"
-set nullid2 "0000000000000000000000000000000000000001"
+set nullid [string repeat 0 $hashlength]
+set nullid2 "[string repeat 0 [expr $hashlength - 1]]1"
 
 ######################################################################
 ##
@@ -3202,7 +3213,7 @@ blame {
        if {$head eq {}} {
                load_current_branch
        } else {
-               if {[regexp {^[0-9a-f]{1,39}$} $head]} {
+               if {[regexp [string map "@@ [expr $hashlength - 1]" {^[0-9a-f]{1,@@}$}] $head]} {
                        if {[catch {
                                        set head [git rev-parse --verify $head]
                                } err]} {
index d6fd8bea91ff531cbec890c13523de575efc46ca..5507681da7ba8f6c582a73dff3eb766e7ce41a72 100644 (file)
@@ -426,6 +426,7 @@ method _kill {} {
 
 method _load {jump} {
        variable group_colors
+       global hashlength
 
        _hide_tooltip $this
 
@@ -436,7 +437,7 @@ method _load {jump} {
                        $i conf -state normal
                        $i delete 0.0 end
                        foreach g [$i tag names] {
-                               if {[regexp {^g[0-9a-f]{40}$} $g]} {
+                               if {[regexp [string map "@@ $hashlength" {^g[0-9a-f]{@@}$}] $g]} {
                                        $i tag delete $g
                                }
                        }
@@ -500,6 +501,8 @@ method _load {jump} {
 }
 
 method _history_menu {} {
+       global hashlength
+
        set m $w.backmenu
        if {[winfo exists $m]} {
                $m delete 0 end
@@ -513,7 +516,7 @@ method _history_menu {} {
                set c [lindex $e 0]
                set f [lindex $e 1]
 
-               if {[regexp {^[0-9a-f]{40}$} $c]} {
+               if {[regexp [string map "@@ $hashlength" {^[0-9a-f]{@@}$}] $c]} {
                        set t [string range $c 0 8]...
                } elseif {$c eq {}} {
                        set t {Working Directory}
@@ -627,6 +630,7 @@ method _exec_blame {cur_w cur_d options cur_s} {
 method _read_blame {fd cur_w cur_d} {
        upvar #0 $cur_d line_data
        variable group_colors
+       global hashlength nullid
 
        if {$fd ne $current_fd} {
                catch {close $fd}
@@ -635,7 +639,7 @@ method _read_blame {fd cur_w cur_d} {
 
        $cur_w conf -state normal
        while {[gets $fd line] >= 0} {
-               if {[regexp {^([a-z0-9]{40}) (\d+) (\d+) (\d+)$} $line line \
+               if {[regexp [string map "@@ $hashlength" {^([a-z0-9]{@@}) (\d+) (\d+) (\d+)$}] $line line \
                        cmit original_line final_line line_count]} {
                        set r_commit     $cmit
                        set r_orig_line  $original_line
@@ -648,7 +652,7 @@ method _read_blame {fd cur_w cur_d} {
                        set oln  $r_orig_line
                        set cmit $r_commit
 
-                       if {[regexp {^0{40}$} $cmit]} {
+                       if {$cmit eq $nullid} {
                                set commit_abbr work
                                set commit_type curr_commit
                        } elseif {$cmit eq $commit} {
index 5b361cc424a6f659b9a1a2d4915efe28769919cb..877ca4888f7a94b16d3bcd42931df8310daafab3 100644 (file)
@@ -879,7 +879,7 @@ method _do_clone_full_end {ok} {
                if {[file exists [gitdir FETCH_HEAD]]} {
                        set fd [safe_open_file [gitdir FETCH_HEAD] r]
                        while {[gets $fd line] >= 0} {
-                               if {[regexp "^(.{40})\t\t" $line line HEAD]} {
+                               if {[regexp "^(.{40,64})\t\t" $line line HEAD]} {
                                        break
                                }
                        }
@@ -987,8 +987,9 @@ method _readtree_wait {fd} {
 
        # -- Run the post-checkout hook.
        #
-       set fd_ph [githook_read post-checkout [string repeat 0 40] \
-               [git rev-parse HEAD] 1]
+       set head_id [git rev-parse HEAD]
+       set fd_ph [githook_read post-checkout \
+               [string repeat 0 [string length $head_id]] $head_id 1]
        if {$fd_ph ne {}} {
                global pch_error
                set pch_error {}
index 37b3808f7e72f61a113a87468b69779f63a2b111..2fd57a51fb085a4750290e76f6466b1b1de6b9b2 100644 (file)
@@ -346,6 +346,7 @@ proc commit_committree {fd_wt curHEAD msg_p} {
        global file_states selected_paths rescan_active
        global repo_config
        global env
+       global hashlength
 
        gets $fd_wt tree_id
        if {[catch {close $fd_wt} err]} {
@@ -365,7 +366,7 @@ proc commit_committree {fd_wt curHEAD msg_p} {
                close $fd_ot
 
                if {[string equal -length 5 {tree } $old_tree]
-                       && [string length $old_tree] == 45} {
+                       && [string length $old_tree] == [expr {$hashlength + 5}]} {
                        set old_tree [string range $old_tree 5 end]
                } else {
                        error [mc "Commit %s appears to be corrupt" $PARENT]
index c8c99b17a8da39f6564855f67aeb6a35d4e610ac..781980d66cc8f1c37248f627dea07ddc923b1158 100644 (file)
@@ -323,6 +323,8 @@ method _load {cache uri} {
 }
 
 method _read {cache fd} {
+       global hashlength
+
        if {$fd ne $active_ls} {
                catch {close $fd}
                return
@@ -330,7 +332,7 @@ method _read {cache fd} {
 
        while {[gets $fd line] >= 0} {
                if {[string match {*^{}} $line]} continue
-               if {[regexp {^([0-9a-f]{40})    (.*)$} $line _junk obj ref]} {
+               if {[regexp [string map "@@ $hashlength" {^([0-9a-f]{@@})       (.*)$}] $line _junk obj ref]} {
                        if {[regsub ^refs/heads/ $ref {} abr]} {
                                lappend head_list $abr
                                lappend head_cache($cache) $abr