From daa364cfb7a1cda324ec5c5cdaf92bcad429cfbd Mon Sep 17 00:00:00 2001 From: YOKOTA Hiroshi Date: Mon, 5 May 2025 02:57:07 +0900 Subject: [PATCH 001/290] gitk: Legacy widgets doesn't have combobox Use "proc makedroplist" function to support combobox on legacy widgets mode. "proc makedroplist" uses "ttk::combobox" for themed mode, and uses "tk_optionMenu" for legacy mode to get rid of the problem. Signed-off-by: YOKOTA Hiroshi Signed-off-by: Johannes Sixt --- gitk | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gitk b/gitk index 11ad639d0622ae..966833a19eb8c5 100755 --- a/gitk +++ b/gitk @@ -11736,13 +11736,11 @@ proc prefspage_general {notebook} { grid x $page.tabstopl $page.tabstop -sticky w ${NS}::label $page.wrapcommentl -text [mc "Wrap comment text"] - ${NS}::combobox $page.wrapcomment -values {none char word} -state readonly \ - -textvariable wrapcomment + makedroplist $page.wrapcomment wrapcomment none char word grid x $page.wrapcommentl $page.wrapcomment -sticky w ${NS}::label $page.wrapdefaultl -text [mc "Wrap other text"] - ${NS}::combobox $page.wrapdefault -values {none char word} -state readonly \ - -textvariable wrapdefault + makedroplist $page.wrapdefault wrapdefault none char word grid x $page.wrapdefaultl $page.wrapdefault -sticky w ${NS}::checkbutton $page.ntag -text [mc "Display nearby tags/heads"] \ From 3271d2e9e71678cdc22378b1fd58c07641f8c424 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 12 May 2025 11:25:05 +0200 Subject: [PATCH 002/290] git-gui: replace GIT-GUI-VARS with GIT-GUI-BUILD-OPTIONS The GIT-GUI-VARS file is used to track whether any of our build options has changed. Unfortunately, the format of that file does not allow us to propagate those build options to other scripts. But as we are about to introduce support for the Meson build system, we will extract a couple of scripts to deduplicate core build logic across Makefiles and Meson. With this refactoring, it will become necessary to make build options more widely accessible. Replace GIT-GUI-VARS with a new GIT-GUI-BUILD-OPTIONS file that is being populated from a template. This file can easily be sourced from build scripts in subsequent steps. Signed-off-by: Patrick Steinhardt --- .gitignore | 2 +- GIT-GUI-BUILD-OPTIONS.in | 6 ++++++ Makefile | 36 ++++++++++++++++-------------------- 3 files changed, 23 insertions(+), 21 deletions(-) create mode 100644 GIT-GUI-BUILD-OPTIONS.in diff --git a/.gitignore b/.gitignore index 6483b21cbfc736..ff6e0be4b4126c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ config.mak Git Gui.app* git-gui.tcl +GIT-GUI-BUILD-OPTIONS GIT-VERSION-FILE -GIT-GUI-VARS git-gui lib/tclIndex diff --git a/GIT-GUI-BUILD-OPTIONS.in b/GIT-GUI-BUILD-OPTIONS.in new file mode 100644 index 00000000000000..3c112af57803a0 --- /dev/null +++ b/GIT-GUI-BUILD-OPTIONS.in @@ -0,0 +1,6 @@ +GITGUI_GITEXECDIR=@GITGUI_GITEXECDIR@ +GITGUI_LIBDIR=@GITGUI_LIBDIR@ +GITGUI_RELATIVE=@GITGUI_RELATIVE@ +SHELL_PATH=@SHELL_PATH@ +TCLTK_PATH=@TCLTK_PATH@ +TCL_PATH=@TCL_PATH@ diff --git a/Makefile b/Makefile index 9f9389aea99cd0..f4f98961b2eec5 100644 --- a/Makefile +++ b/Makefile @@ -158,7 +158,7 @@ endif ifdef GITGUI_MACOSXAPP GITGUI_MAIN := git-gui.tcl -git-gui: GIT-VERSION-FILE GIT-GUI-VARS +git-gui: GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS $(QUIET_GEN)rm -f $@ $@+ && \ echo '#!$(SHELL_PATH_SQ)' >$@+ && \ echo 'if test "z$$*" = zversion ||' >>$@+ && \ @@ -173,7 +173,7 @@ git-gui: GIT-VERSION-FILE GIT-GUI-VARS chmod +x $@+ && \ mv $@+ $@ -Git\ Gui.app: GIT-VERSION-FILE GIT-GUI-VARS \ +Git\ Gui.app: GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS \ macosx/Info.plist \ macosx/git-gui.icns \ macosx/AppMain.tcl \ @@ -202,7 +202,7 @@ git-gui: windows/git-gui.sh cp $< $@ endif -$(GITGUI_MAIN): git-gui.sh GIT-VERSION-FILE GIT-GUI-VARS +$(GITGUI_MAIN): git-gui.sh GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS $(QUIET_GEN)rm -f $@ $@+ && \ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ -e 's|@@SHELL_PATH@@|$(SHELL_PATH_SQ)|' \ @@ -238,7 +238,7 @@ update-po:: $(PO_TEMPLATE) $(ALL_MSGFILES): %.msg : %.po $(QUIET_MSGFMT0)$(MSGFMT) --statistics --tcl -l $(basename $(notdir $<)) -d $(dir $@) $< $(QUIET_MSGFMT1) -lib/tclIndex: $(ALL_LIBFILES) GIT-GUI-VARS +lib/tclIndex: $(ALL_LIBFILES) GIT-GUI-BUILD-OPTIONS $(QUIET_INDEX)if echo \ $(foreach p,$(PRELOAD_FILES),source $p\;) \ auto_mkindex lib $(patsubst lib/%,%,$(sort $(ALL_LIBFILES))) \ @@ -252,21 +252,17 @@ lib/tclIndex: $(ALL_LIBFILES) GIT-GUI-VARS echo >>$@ ; \ fi -TRACK_VARS = \ - $(subst ','\'',SHELL_PATH='$(SHELL_PATH_SQ)') \ - $(subst ','\'',TCL_PATH='$(TCL_PATH_SQ)') \ - $(subst ','\'',TCLTK_PATH='$(TCLTK_PATH_SQ)') \ - $(subst ','\'',gitexecdir='$(gitexecdir_SQ)') \ - $(subst ','\'',gg_libdir='$(libdir_SQ)') \ - GITGUI_MACOSXAPP=$(GITGUI_MACOSXAPP) \ -#end TRACK_VARS - -GIT-GUI-VARS: FORCE - @VARS='$(TRACK_VARS)'; \ - if test x"$$VARS" != x"`cat $@ 2>/dev/null`" ; then \ - echo >&2 " * new locations or Tcl/Tk interpreter"; \ - echo >$@ "$$VARS"; \ - fi +GIT-GUI-BUILD-OPTIONS: FORCE + @sed \ + -e 's|@GITGUI_GITEXECDIR@|$(gitexecdir_SQ)|' \ + -e 's|@GITGUI_LIBDIR@|$(libdir_SQ)|' \ + -e 's|@GITGUI_RELATIVE@|$(GITGUI_RELATIVE)|' \ + -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \ + -e 's|@TCLTK_PATH@|$(TCLTK_PATH_SQ)|' \ + -e 's|@TCL_PATH@|$(TCL_PATH_SQ)|' \ + $@.in >$@+ + @if grep -q '^[A-Z][A-Z_]*=@.*@$$' $@+; then echo "Unsubstituted build options in $@" >&2 && exit 1; fi + @if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi ifdef GITGUI_MACOSXAPP all:: git-gui Git\ Gui.app @@ -322,7 +318,7 @@ dist-version: clean:: $(RM_RF) $(GITGUI_MAIN) lib/tclIndex po/*.msg $(PO_TEMPLATE) - $(RM_RF) GIT-VERSION-FILE GIT-GUI-VARS + $(RM_RF) GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS ifdef GITGUI_MACOSXAPP $(RM_RF) 'Git Gui.app'* git-gui endif From 3ef470fa5127b9858d203990211f4375d38d5dd6 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 11 Mar 2025 11:06:37 +0100 Subject: [PATCH 003/290] git-gui: prepare GIT-VERSION-GEN for out-of-tree builds The GIT-VERSION-GEN unconditionally writes version information into the source directory in the form of the "GIT-VERSION-FILE". We are about to introduce the Meson build system though, which enforces out-of-tree builds by default, and in that context we cannot continue to write version information into the source tree. Prepare the script for out-of-tree builds by treating the source directory different from the output file. Signed-off-by: Patrick Steinhardt --- GIT-VERSION-GEN | 42 ++++++++++++++++++++++++++++-------------- Makefile | 2 +- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 92373d251a84f4..e40a09b6fd6553 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,19 +1,33 @@ #!/bin/sh -GVF=GIT-VERSION-FILE DEF_VER=0.21.GITGUI LF=' ' +if test "$#" -ne 2 +then + echo >&2 "usage: $0 " + exit 1 +fi + +SOURCE_DIR="$1" +OUTPUT="$2" + +# Protect us from reading Git version information outside of the Git directory +# in case it is not a repository itself, but embedded in an unrelated +# repository. +GIT_CEILING_DIRECTORIES="$SOURCE_DIR/.." +export GIT_CEILING_DIRECTORIES + tree_search () { head=$1 tree=$2 - for p in $(git rev-list --parents --max-count=1 $head 2>/dev/null) + for p in $(git -C "$SOURCE_DIR" rev-list --parents --max-count=1 $head 2>/dev/null) do - test $tree = $(git rev-parse $p^{tree} 2>/dev/null) && - vn=$(git describe --abbrev=4 $p 2>/dev/null) && + test $tree = $(git -C "$SOURCE_DIR" rev-parse $p^{tree} 2>/dev/null) && + vn=$(git -C "$SOURCE_DIR" describe --abbrev=4 $p 2>/dev/null) && case "$vn" in gitgui-[0-9]*) echo $vn; break;; esac @@ -34,14 +48,14 @@ tree_search () # If we are at the toplevel or the merge assumption fails # try looking for a gitgui-* tag. -if test -f version && - VN=$(cat version) +if test -f "$SOURCE_DIR"/version && + VN=$(cat "$SOURCE_DIR"/version) then : happy -elif prefix="$(git rev-parse --show-prefix 2>/dev/null)" +elif prefix="$(git -C "$SOURCE_DIR" rev-parse --show-prefix 2>/dev/null)" test -n "$prefix" && - head=$(git rev-list --max-count=1 HEAD -- . 2>/dev/null) && - tree=$(git rev-parse --verify "HEAD:$prefix" 2>/dev/null) && + head=$(git -C "$SOURCE_DIR" rev-list --max-count=1 HEAD -- . 2>/dev/null) && + tree=$(git -C "$SOURCE_DIR" rev-parse --verify "HEAD:$prefix" 2>/dev/null) && VN=$(tree_search $head $tree) case "$VN" in gitgui-[0-9]*) : happy ;; @@ -49,7 +63,7 @@ elif prefix="$(git rev-parse --show-prefix 2>/dev/null)" esac then VN=$(echo "$VN" | sed -e 's/^gitgui-//;s/-/./g'); -elif VN=$(git describe --abbrev=4 HEAD 2>/dev/null) && +elif VN=$(git -C "$SOURCE_DIR" describe --abbrev=4 HEAD 2>/dev/null) && case "$VN" in gitgui-[0-9]*) : happy ;; *) (exit 1) ;; @@ -60,7 +74,7 @@ else VN="$DEF_VER" fi -dirty=$(sh -c 'git diff-index --name-only HEAD' 2>/dev/null) || dirty= +dirty=$(git -C "$SOURCE_DIR" diff-index --name-only HEAD 2>/dev/null) || dirty= case "$dirty" in '') ;; @@ -68,13 +82,13 @@ case "$dirty" in VN="$VN-dirty" ;; esac -if test -r $GVF +if test -r "$OUTPUT" then - VC=$(sed -e 's/^GITGUI_VERSION = //' <$GVF) + VC=$(sed -e 's/^GITGUI_VERSION = //' <"$OUTPUT") else VC=unset fi test "$VN" = "$VC" || { echo >&2 "GITGUI_VERSION = $VN" - echo "GITGUI_VERSION = $VN" >$GVF + echo "GITGUI_VERSION = $VN" >"$OUTPUT" } diff --git a/Makefile b/Makefile index f4f98961b2eec5..ea22b3af5d8ea2 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ all:: # GIT-VERSION-FILE: FORCE - @$(SHELL_PATH) ./GIT-VERSION-GEN + @$(SHELL_PATH) ./GIT-VERSION-GEN . $@ ifneq ($(MAKECMDGOALS),clean) -include GIT-VERSION-FILE endif From caf5fbe9af77488175b5baf2404b1bb6d4d78653 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 12 May 2025 11:27:37 +0200 Subject: [PATCH 004/290] git-gui: make output of GIT-VERSION-GEN source'able The output of GIT-VERSION-GEN can be sourced by our Makefile to make the version available there. The output has a couple of spaces around the equals sign, which is perfectly valid for parsing it in our Makefile. But in subsequent steps we'll also want to source the file in a couple of newly-introduced shell scripts, but having spaces around variable assignments is invalid there. Prepare for this step by dropping the spaces surrounding the equals sign. Like this, we can easily use the same file both in our Makefile and in shell scripts. Signed-off-by: Patrick Steinhardt --- GIT-VERSION-GEN | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index e40a09b6fd6553..c2767b4136cbbf 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -84,11 +84,11 @@ esac if test -r "$OUTPUT" then - VC=$(sed -e 's/^GITGUI_VERSION = //' <"$OUTPUT") + VC=$(sed -e 's/^GITGUI_VERSION=//' <"$OUTPUT") else VC=unset fi test "$VN" = "$VC" || { - echo >&2 "GITGUI_VERSION = $VN" - echo "GITGUI_VERSION = $VN" >"$OUTPUT" + echo >&2 "GITGUI_VERSION=$VN" + echo "GITGUI_VERSION=$VN" >"$OUTPUT" } From 3e656a43567b7d0f82e99d56b1a268feb789abff Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 11 Mar 2025 11:07:08 +0100 Subject: [PATCH 005/290] git-gui: drop no-op GITGUI_SCRIPT replacement The value of the GITGUI_SCRIPT variable is only used in a single place as part of an sed(1) script that massages the "git-gui.sh" script. Interestingly, this specific replacement does seem to be a no-op: we replace "^ argv0=$$0" with " argv=$(GITGUI_SCRIPT)", which has a value of "$$0". The result would thus be completely unchanged. Drop the replacement and its variable. Signed-off-by: Patrick Steinhardt --- Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile b/Makefile index ea22b3af5d8ea2..1cbb16a92196a1 100644 --- a/Makefile +++ b/Makefile @@ -134,7 +134,6 @@ libdir_SQ = $(subst ','\'',$(gg_libdir)) libdir_SED = $(subst ','\'',$(subst \,\\,$(gg_libdir_sed_in))) exedir = $(dir $(gitexecdir))share/git-gui/lib -GITGUI_SCRIPT := $$0 GITGUI_RELATIVE := GITGUI_MACOSXAPP := @@ -206,7 +205,6 @@ $(GITGUI_MAIN): git-gui.sh GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS $(QUIET_GEN)rm -f $@ $@+ && \ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ -e 's|@@SHELL_PATH@@|$(SHELL_PATH_SQ)|' \ - -e '1,30s|^ argv0=$$0| argv0=$(GITGUI_SCRIPT)|' \ -e '1,30s|^ exec wish | exec '\''$(TCLTK_PATH_SED)'\'' |' \ -e 's/@@GITGUI_VERSION@@/$(GITGUI_VERSION)/g' \ -e 's|@@GITGUI_RELATIVE@@|$(GITGUI_RELATIVE)|' \ From 854e88335a3e68af46f62ce72037293920bd06f2 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 11 Mar 2025 11:07:19 +0100 Subject: [PATCH 006/290] git-gui: extract script to generate "git-gui" Extract script to generate "git-gui". This change allows us to reuse the build logic with the Meson build system. Signed-off-by: Patrick Steinhardt --- Makefile | 12 +----------- generate-git-gui.sh | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 11 deletions(-) create mode 100755 generate-git-gui.sh diff --git a/Makefile b/Makefile index 1cbb16a92196a1..58a65dba245706 100644 --- a/Makefile +++ b/Makefile @@ -127,7 +127,6 @@ gitexecdir_SQ = $(subst ','\'',$(gitexecdir)) SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) TCL_PATH_SQ = $(subst ','\'',$(TCL_PATH)) TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH)) -TCLTK_PATH_SED = $(subst ','\'',$(subst \,\\,$(TCLTK_PATH))) gg_libdir ?= $(sharedir)/git-gui/lib libdir_SQ = $(subst ','\'',$(gg_libdir)) @@ -202,16 +201,7 @@ git-gui: windows/git-gui.sh endif $(GITGUI_MAIN): git-gui.sh GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS - $(QUIET_GEN)rm -f $@ $@+ && \ - sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ - -e 's|@@SHELL_PATH@@|$(SHELL_PATH_SQ)|' \ - -e '1,30s|^ exec wish | exec '\''$(TCLTK_PATH_SED)'\'' |' \ - -e 's/@@GITGUI_VERSION@@/$(GITGUI_VERSION)/g' \ - -e 's|@@GITGUI_RELATIVE@@|$(GITGUI_RELATIVE)|' \ - -e '$(GITGUI_RELATIVE)s|@@GITGUI_LIBDIR@@|$(libdir_SED)|' \ - git-gui.sh >$@+ && \ - chmod +x $@+ && \ - mv $@+ $@ + $(QUIET_GEN)$(SHELL_PATH) generate-git-gui.sh "$<" "$@" ./GIT-GUI-BUILD-OPTIONS ./GIT-VERSION-FILE XGETTEXT ?= xgettext ifdef NO_MSGFMT diff --git a/generate-git-gui.sh b/generate-git-gui.sh new file mode 100755 index 00000000000000..39dfafdc4adc14 --- /dev/null +++ b/generate-git-gui.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +set -e + +if test "$#" -ne 4 +then + echo >&2 "usage: $0 " + exit 1 +fi + +INPUT="$1" +OUTPUT="$2" +BUILD_OPTIONS="$3" +VERSION_FILE="$4" + +. "${BUILD_OPTIONS}" +. "${VERSION_FILE}" + +rm -f "$OUTPUT" "$OUTPUT+" +sed \ + -e "1s|#!.*/sh|#!$SHELL_PATH|" \ + -e "s|@@SHELL_PATH@@|$SHELL_PATH|" \ + -e "1,30s|^ exec wish | exec '$TCLTK_PATH' |" \ + -e "s|@@GITGUI_VERSION@@|$GITGUI_VERSION|g" \ + -e "s|@@GITGUI_RELATIVE@@|$GITGUI_RELATIVE|" \ + -e "${GITGUI_RELATIVE}s|@@GITGUI_LIBDIR@@|$GITGUI_LIBDIR|" \ + "$INPUT" >"$OUTPUT"+ +chmod +x "$OUTPUT"+ +mv "$OUTPUT"+ "$OUTPUT" From 2cc5b0facfa4781b7dd4d572bdf22ec448054023 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 11 Mar 2025 11:07:19 +0100 Subject: [PATCH 007/290] git-gui: extract script to generate "tclIndex" Extract script to generate "tclIndex". This change allows us to reuse the build logic with the Meson build system. Signed-off-by: Patrick Steinhardt --- Makefile | 16 ++-------------- generate-tclindex.sh | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 14 deletions(-) create mode 100755 generate-tclindex.sh diff --git a/Makefile b/Makefile index 58a65dba245706..5166bba1f2a90b 100644 --- a/Makefile +++ b/Makefile @@ -75,7 +75,6 @@ ifndef V QUIET_INDEX = $(QUIET)echo ' ' INDEX $(dir $@) && QUIET_MSGFMT0 = $(QUIET)printf ' MSGFMT %12s ' $@ && v=` QUIET_MSGFMT1 = 2>&1` && echo "$$v" | sed -e 's/fuzzy translations/fuzzy/' | sed -e 's/ messages*//g' - QUIET_2DEVNULL = 2>/dev/null INSTALL_D0 = dir= INSTALL_D1 = && echo ' ' DEST $$dir && $(INSTALL) -d -m 755 "$$dir" @@ -226,19 +225,8 @@ update-po:: $(PO_TEMPLATE) $(ALL_MSGFILES): %.msg : %.po $(QUIET_MSGFMT0)$(MSGFMT) --statistics --tcl -l $(basename $(notdir $<)) -d $(dir $@) $< $(QUIET_MSGFMT1) -lib/tclIndex: $(ALL_LIBFILES) GIT-GUI-BUILD-OPTIONS - $(QUIET_INDEX)if echo \ - $(foreach p,$(PRELOAD_FILES),source $p\;) \ - auto_mkindex lib $(patsubst lib/%,%,$(sort $(ALL_LIBFILES))) \ - | $(TCL_PATH) $(QUIET_2DEVNULL); then : ok; \ - else \ - echo >&2 " * $(TCL_PATH) failed; using unoptimized loading"; \ - rm -f $@ ; \ - echo '# Autogenerated by git-gui Makefile' >$@ && \ - echo >>$@ && \ - $(foreach p,$(PRELOAD_FILES) $(sort $(ALL_LIBFILES)),echo '$(subst lib/,,$p)' >>$@ &&) \ - echo >>$@ ; \ - fi +lib/tclIndex: $(ALL_LIBFILES) generate-tclindex.sh GIT-GUI-BUILD-OPTIONS + $(QUIET_INDEX)$(SHELL_PATH) generate-tclindex.sh . ./GIT-GUI-BUILD-OPTIONS $(ALL_LIBFILES) GIT-GUI-BUILD-OPTIONS: FORCE @sed \ diff --git a/generate-tclindex.sh b/generate-tclindex.sh new file mode 100755 index 00000000000000..36e3a0bd90eefa --- /dev/null +++ b/generate-tclindex.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +if test "$#" -lt 3 +then + echo >&2 "usage: $0 [...]" + exit 1 +fi + +BUILD_DIR="$1" +BUILD_OPTIONS="$2" +shift 2 +LIBFILES="$(echo "$@" | sort | sed 's|lib/||g')" + +. "$BUILD_OPTIONS" + +cd "$BUILD_DIR" + +if { + echo "source lib/class.tcl;" + echo "auto_mkindex lib $LIBFILES" +} | "$TCL_PATH" +then + : ok +else + echo >&2 " * $TCL_PATH failed; using unoptimized loading" + rm -f $@ + echo '# Autogenerated by git-gui Makefile' >lib/tclIndex + echo >>lib/tclIndex + echo "class.tcl" >>lib/tclIndex + printf "%s\n" $LIBFILES >>lib/tclIndex + echo >>lib/tclIndex +fi From 743e1cbd7e2b26380be25cd73ded57b08cb6b409 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 11 Mar 2025 11:07:19 +0100 Subject: [PATCH 008/290] git-gui: extract script to generate macOS wrapper Extract script to generate the macOS wrapper for git-gui. This change allows us to reuse the build logic with the Meson build system. Signed-off-by: Patrick Steinhardt --- GIT-GUI-BUILD-OPTIONS.in | 1 + Makefile | 18 ++++-------------- generate-macos-wrapper.sh | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 14 deletions(-) create mode 100755 generate-macos-wrapper.sh diff --git a/GIT-GUI-BUILD-OPTIONS.in b/GIT-GUI-BUILD-OPTIONS.in index 3c112af57803a0..5fd885c2bf73e9 100644 --- a/GIT-GUI-BUILD-OPTIONS.in +++ b/GIT-GUI-BUILD-OPTIONS.in @@ -4,3 +4,4 @@ GITGUI_RELATIVE=@GITGUI_RELATIVE@ SHELL_PATH=@SHELL_PATH@ TCLTK_PATH=@TCLTK_PATH@ TCL_PATH=@TCL_PATH@ +TKEXECUTABLE=@TKEXECUTABLE@ diff --git a/Makefile b/Makefile index 5166bba1f2a90b..722df4ae3fb429 100644 --- a/Makefile +++ b/Makefile @@ -113,6 +113,7 @@ ifeq ($(uname_S),Darwin) endif endif TKEXECUTABLE = $(shell basename "$(TKFRAMEWORK)" .app) + TKEXECUTABLE_SQ = $(subst ','\'',$(TKEXECUTABLE)) endif ifeq ($(findstring $(firstword -$(MAKEFLAGS)),s),s) @@ -155,20 +156,8 @@ endif ifdef GITGUI_MACOSXAPP GITGUI_MAIN := git-gui.tcl -git-gui: GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS - $(QUIET_GEN)rm -f $@ $@+ && \ - echo '#!$(SHELL_PATH_SQ)' >$@+ && \ - echo 'if test "z$$*" = zversion ||' >>$@+ && \ - echo ' test "z$$*" = z--version' >>$@+ && \ - echo then >>$@+ && \ - echo ' 'echo \'git-gui version '$(GITGUI_VERSION)'\' >>$@+ && \ - echo else >>$@+ && \ - echo ' libdir="$${GIT_GUI_LIB_DIR:-$(libdir_SQ)}"' >>$@+ && \ - echo ' 'exec \"'$$libdir/Git Gui.app/Contents/MacOS/$(subst \,,$(TKEXECUTABLE))'\" \ - '"$$0" "$$@"' >>$@+ && \ - echo fi >>$@+ && \ - chmod +x $@+ && \ - mv $@+ $@ +git-gui: generate-macos-wrapper.sh GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS + $(QUIET_GEN)$(SHELL_PATH) generate-macos-wrapper.sh "$@" ./GIT-GUI-BUILD-OPTIONS ./GIT-VERSION-FILE Git\ Gui.app: GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS \ macosx/Info.plist \ @@ -236,6 +225,7 @@ GIT-GUI-BUILD-OPTIONS: FORCE -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \ -e 's|@TCLTK_PATH@|$(TCLTK_PATH_SQ)|' \ -e 's|@TCL_PATH@|$(TCL_PATH_SQ)|' \ + -e 's|@TKEXECUTABLE@|$(TKEXECUTABLE_SQ)|' \ $@.in >$@+ @if grep -q '^[A-Z][A-Z_]*=@.*@$$' $@+; then echo "Unsubstituted build options in $@" >&2 && exit 1; fi @if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi diff --git a/generate-macos-wrapper.sh b/generate-macos-wrapper.sh new file mode 100755 index 00000000000000..da7e4782f7241e --- /dev/null +++ b/generate-macos-wrapper.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +set -e + +if test "$#" -ne 3 +then + echo >&2 "usage: $0 " + exit 1 +fi + +OUTPUT="$1" +BUILD_OPTIONS="$2" +VERSION_FILE="$3" + +. "$BUILD_OPTIONS" + +rm -f "$OUTPUT" "$OUTPUT+" + +( + echo "#!$SHELL_PATH" + cat "$BUILD_OPTIONS" "$VERSION_FILE" + cat <<-'EOF' + if test "z$*" = zversion || + test "z$*" = z--version + then + echo "git-gui version $GITGUI_VERSION" + else + libdir="${GIT_GUI_LIB_DIR:-$GITGUI_LIBDIR}" + exec "$libdir/Git Gui.app/Contents/MacOS/$TKEXECUTABLE" "$0" "$@" + fi + EOF +) >"$OUTPUT+" + +chmod +x "$OUTPUT+" +mv "$OUTPUT+" "$OUTPUT" From 28a8e5c8849e158abaf49d86b5ae7c9249d3e483 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 13 May 2025 08:48:07 +0200 Subject: [PATCH 009/290] git-gui: extract script to generate macOS app Extract script to generate the macOS app. This change allows us to reuse the build logic with the Meson build system. Note that as part of this change we also modify the TKEXECUTABLE variable to track its full path. Like this we don't have to propagate both the TKEXECUTABLE and TKFRAMEWORK variables into the script, and the basename can be trivially computed from TKEXECUTABLE anyway. Signed-off-by: Patrick Steinhardt --- Makefile | 22 +++------------------- generate-macos-app.sh | 30 ++++++++++++++++++++++++++++++ generate-macos-wrapper.sh | 2 +- 3 files changed, 34 insertions(+), 20 deletions(-) create mode 100755 generate-macos-app.sh diff --git a/Makefile b/Makefile index 722df4ae3fb429..cde1b7e607d8b7 100644 --- a/Makefile +++ b/Makefile @@ -112,7 +112,7 @@ ifeq ($(uname_S),Darwin) TKFRAMEWORK = /System/Library/Frameworks/Tk.framework/Resources/Wish\ Shell.app endif endif - TKEXECUTABLE = $(shell basename "$(TKFRAMEWORK)" .app) + TKEXECUTABLE = $(TKFRAMEWORK)/Contents/MacOS/$(shell basename "$(TKFRAMEWORK)" .app) TKEXECUTABLE_SQ = $(subst ','\'',$(TKEXECUTABLE)) endif @@ -130,7 +130,6 @@ TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH)) gg_libdir ?= $(sharedir)/git-gui/lib libdir_SQ = $(subst ','\'',$(gg_libdir)) -libdir_SED = $(subst ','\'',$(subst \,\\,$(gg_libdir_sed_in))) exedir = $(dir $(gitexecdir))share/git-gui/lib GITGUI_RELATIVE := @@ -139,7 +138,6 @@ GITGUI_MACOSXAPP := ifeq ($(exedir),$(gg_libdir)) GITGUI_RELATIVE := 1 endif -gg_libdir_sed_in := $(gg_libdir) ifeq ($(uname_S),Darwin) ifeq ($(shell test -d $(TKFRAMEWORK) && echo y),y) GITGUI_MACOSXAPP := YesPlease @@ -163,22 +161,8 @@ Git\ Gui.app: GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS \ macosx/Info.plist \ macosx/git-gui.icns \ macosx/AppMain.tcl \ - $(TKFRAMEWORK)/Contents/MacOS/$(TKEXECUTABLE) - $(QUIET_GEN)rm -rf '$@' '$@'+ && \ - mkdir -p '$@'+/Contents/MacOS && \ - mkdir -p '$@'+/Contents/Resources/Scripts && \ - cp '$(subst ','\'',$(subst \,,$(TKFRAMEWORK)/Contents/MacOS/$(TKEXECUTABLE)))' \ - '$@'+/Contents/MacOS && \ - cp macosx/git-gui.icns '$@'+/Contents/Resources && \ - sed -e 's/@@GITGUI_VERSION@@/$(GITGUI_VERSION)/g' \ - -e 's/@@GITGUI_TKEXECUTABLE@@/$(TKEXECUTABLE)/g' \ - macosx/Info.plist \ - >'$@'+/Contents/Info.plist && \ - sed -e 's|@@gitexecdir@@|$(gitexecdir_SQ)|' \ - -e 's|@@GITGUI_LIBDIR@@|$(libdir_SED)|' \ - macosx/AppMain.tcl \ - >'$@'+/Contents/Resources/Scripts/AppMain.tcl && \ - mv '$@'+ '$@' + $(TKEXECUTABLE) + $(QUIET_GEN)$(SHELL_PATH) generate-macos-app.sh . "$@" ./GIT-GUI-BUILD-OPTIONS ./GIT-VERSION-FILE endif ifdef GITGUI_WINDOWS_WRAPPER diff --git a/generate-macos-app.sh b/generate-macos-app.sh new file mode 100755 index 00000000000000..71b9fa67a4be7f --- /dev/null +++ b/generate-macos-app.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +set -e + +SOURCE_DIR="$1" +OUTPUT="$2" +BUILD_OPTIONS="$3" +VERSION_FILE="$4" + +. "$BUILD_OPTIONS" +. "$VERSION_FILE" + +rm -rf "$OUTPUT" "$OUTPUT+" + +mkdir -p "$OUTPUT+/Contents/MacOS" +mkdir -p "$OUTPUT+/Contents/Resources/Scripts" + +cp "$TKEXECUTABLE" "$OUTPUT+/Contents/MacOS" +cp "$SOURCE_DIR/macosx/git-gui.icns" "$OUTPUT+/Contents/Resources" +sed \ + -e "s/@@GITGUI_VERSION@@/$GITGUI_VERSION/g" \ + -e "s/@@GITGUI_TKEXECUTABLE@@/$(basename "$TKEXECUTABLE")/g" \ + "$SOURCE_DIR/macosx/Info.plist" \ + >"$OUTPUT+/Contents/Info.plist" +sed \ + -e "s|@@gitexecdir@@|$GITGUI_GITEXECDIR|" \ + -e "s|@@GITGUI_LIBDIR@@|$GITGUI_LIBDIR|" \ + "$SOURCE_DIR/macosx/AppMain.tcl" \ + >"$OUTPUT+/Contents/Resources/Scripts/AppMain.tcl" +mv "$OUTPUT+" "$OUTPUT" diff --git a/generate-macos-wrapper.sh b/generate-macos-wrapper.sh index da7e4782f7241e..0304937f41e169 100755 --- a/generate-macos-wrapper.sh +++ b/generate-macos-wrapper.sh @@ -26,7 +26,7 @@ rm -f "$OUTPUT" "$OUTPUT+" echo "git-gui version $GITGUI_VERSION" else libdir="${GIT_GUI_LIB_DIR:-$GITGUI_LIBDIR}" - exec "$libdir/Git Gui.app/Contents/MacOS/$TKEXECUTABLE" "$0" "$@" + exec "$libdir/Git Gui.app/Contents/MacOS/$(basename "$TKEXECUTABLE")" "$0" "$@" fi EOF ) >"$OUTPUT+" From d821fc62691680df6454d62b4f9e9409086b2873 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 11 Mar 2025 11:26:48 +0100 Subject: [PATCH 010/290] git-gui: stop including GIT-VERSION-FILE file The "GITGUI_VERSION" variable is made available by generating and including the "GIT-VERSION-FILE" file. Its value has been used in various build steps, but in the preceding commits we have refactored those to instead source the "GIT-VERSION-FILE" directly. As a result, the variable is now only used in a single recipe, and this use can be trivially replaced with sed(1). Refactor the recipe to do so and stop including "GIT-VERSION-FILE" to simplify the build process. Signed-off-by: Patrick Steinhardt --- Makefile | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index cde1b7e607d8b7..315888f302b050 100644 --- a/Makefile +++ b/Makefile @@ -9,9 +9,6 @@ all:: GIT-VERSION-FILE: FORCE @$(SHELL_PATH) ./GIT-VERSION-GEN . $@ -ifneq ($(MAKECMDGOALS),clean) --include GIT-VERSION-FILE -endif uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not') @@ -262,9 +259,9 @@ endif $(QUIET)$(REMOVE_D0)'$(DESTDIR_SQ)$(libdir_SQ)' $(REMOVE_D1) $(QUIET)$(REMOVE_D0)`dirname '$(DESTDIR_SQ)$(libdir_SQ)'` $(REMOVE_D1) -dist-version: +dist-version: GIT-VERSION-FILE @mkdir -p $(TARDIR) - @echo $(GITGUI_VERSION) > $(TARDIR)/version + @sed 's|^GITGUI_VERSION=||' $(TARDIR)/version clean:: $(RM_RF) $(GITGUI_MAIN) lib/tclIndex po/*.msg $(PO_TEMPLATE) From 8bf062dd147146c4bd76c7344ee5fcb5fbd0834c Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 11 Mar 2025 11:09:23 +0100 Subject: [PATCH 011/290] git-gui: wire up support for the Meson build system The Git project has started to wire up Meson as a build system in Git v2.48.0. Wire up support for Meson in "git-gui" so that we can trivially include it as a subproject in Git. Signed-off-by: Patrick Steinhardt --- .gitattributes | 1 + lib/meson.build | 74 ++++++++++++++++++++++++ meson.build | 148 ++++++++++++++++++++++++++++++++++++++++++++++++ po/meson.build | 38 +++++++++++++ 4 files changed, 261 insertions(+) create mode 100644 lib/meson.build create mode 100644 meson.build create mode 100644 po/meson.build diff --git a/.gitattributes b/.gitattributes index 118d56cfbdcb90..889d58257fb3c8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,3 +4,4 @@ git-gui.sh encoding=UTF-8 /po/*.po encoding=UTF-8 /GIT-VERSION-GEN eol=lf Makefile whitespace=!indent,trail,space +meson.build whitespace=space diff --git a/lib/meson.build b/lib/meson.build new file mode 100644 index 00000000000000..4b9efab774dc97 --- /dev/null +++ b/lib/meson.build @@ -0,0 +1,74 @@ +libfiles = [ + 'about.tcl', + 'blame.tcl', + 'branch_checkout.tcl', + 'branch_create.tcl', + 'branch_delete.tcl', + 'branch_rename.tcl', + 'branch.tcl', + 'browser.tcl', + 'checkout_op.tcl', + 'choose_font.tcl', + 'choose_repository.tcl', + 'choose_rev.tcl', + 'chord.tcl', + 'class.tcl', + 'commit.tcl', + 'console.tcl', + 'database.tcl', + 'date.tcl', + 'diff.tcl', + 'encoding.tcl', + 'error.tcl', + 'index.tcl', + 'line.tcl', + 'logo.tcl', + 'merge.tcl', + 'mergetool.tcl', + 'option.tcl', + 'remote_add.tcl', + 'remote_branch_delete.tcl', + 'remote.tcl', + 'search.tcl', + 'shortcut.tcl', + 'spellcheck.tcl', + 'sshkey.tcl', + 'status_bar.tcl', + 'themed.tcl', + 'tools_dlg.tcl', + 'tools.tcl', + 'transport.tcl', + 'win32.tcl', +] + +nontcl_libfiles = [ + 'git-gui.ico', + 'win32_shortcut.js', +] + +foreach file : libfiles + nontcl_libfiles + configure_file( + input: file, + output: file, + copy: true, + install: true, + install_dir: get_option('datadir') / 'git-gui/lib', + ) +endforeach + +custom_target( + output: 'tclIndex', + command: [ + shell, + meson.project_source_root() / 'generate-tclindex.sh', + meson.project_build_root(), + meson.project_build_root() / 'GIT-GUI-BUILD-OPTIONS', + libfiles, + ], + depend_files: [ + libfiles, + build_options, + ], + install: true, + install_dir: get_option('datadir') / 'git-gui/lib', +) diff --git a/meson.build b/meson.build new file mode 100644 index 00000000000000..cdae85e4b9dce7 --- /dev/null +++ b/meson.build @@ -0,0 +1,148 @@ +project('git-gui', + meson_version: '>=0.61.0', +) + +fs = import('fs') + +shell = find_program('sh') +tclsh = find_program('tclsh') +wish = find_program('wish') + +build_options_config = configuration_data() +if target_machine.system() == 'windows' + build_options_config.set('GITGUI_RELATIVE', '1') +else + build_options_config.set('GITGUI_RELATIVE', '') +endif +build_options_config.set_quoted('GITGUI_GITEXECDIR', get_option('prefix') / get_option('libexecdir') / 'git-core') +build_options_config.set_quoted('GITGUI_LIBDIR', get_option('prefix') / get_option('datadir') / 'git-gui/lib') +build_options_config.set_quoted('SHELL_PATH', fs.as_posix(shell.full_path())) +build_options_config.set_quoted('TCLTK_PATH', fs.as_posix(wish.full_path())) +build_options_config.set_quoted('TCL_PATH', fs.as_posix(tclsh.full_path())) +if target_machine.system() == 'darwin' + tkexecutables = [ + '/Library/Frameworks/Tk.framework/Resources/Wish.app/Contents/MacOS/Wish', + '/System/Library/Frameworks/Tk.framework/Resources/Wish.app/Contents/MacOS/Wish', + '/System/Library/Frameworks/Tk.framework/Resources/Wish Shell.app/Contents/MacOS/Wish Shell', + ] + tkexecutable = find_program(tkexecutables) + build_options_config.set_quoted('TKEXECUTABLE', tkexecutable.full_path()) +else + build_options_config.set('TKEXECUTABLE', '') +endif + +build_options = configure_file( + input: 'GIT-GUI-BUILD-OPTIONS.in', + output: 'GIT-GUI-BUILD-OPTIONS', + configuration: build_options_config, +) + +version_file = custom_target( + input: 'GIT-VERSION-GEN', + output: 'GIT-VERSION-FILE', + command: [ + shell, + '@INPUT@', + meson.current_source_dir(), + '@OUTPUT@', + ], + build_always_stale: true, +) + +configure_file( + input: 'git-gui--askpass', + output: 'git-gui--askpass', + copy: true, + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +gitgui_main = 'git-gui' +gitgui_main_install_dir = get_option('libexecdir') / 'git-core' + +if target_machine.system() == 'windows' + gitgui_main = 'git-gui.tcl' + + configure_file( + input: 'windows/git-gui.sh', + output: 'git-gui', + copy: true, + install: true, + install_dir: get_option('libexecdir') / 'git-core', + ) +elif target_machine.system() == 'darwin' + gitgui_main = 'git-gui.tcl' + gitgui_main_install_dir = get_option('datadir') / 'git-gui/lib' + + custom_target( + output: 'git-gui', + command: [ + shell, + meson.current_source_dir() / 'generate-macos-wrapper.sh', + '@OUTPUT@', + meson.current_build_dir() / 'GIT-GUI-BUILD-OPTIONS', + meson.current_build_dir() / 'GIT-VERSION-FILE', + ], + depends: [ + version_file, + ], + depend_files: [ + build_options, + ], + install: true, + install_dir: get_option('libexecdir') / 'git-core', + ) + + custom_target( + output: 'Git Gui.app', + command: [ + shell, + meson.current_source_dir() / 'generate-macos-app.sh', + meson.current_source_dir(), + meson.current_build_dir() / 'Git Gui.app', + meson.current_build_dir() / 'GIT-GUI-BUILD-OPTIONS', + meson.current_build_dir() / 'GIT-VERSION-FILE', + ], + depends: [ + version_file, + ], + depend_files: [ + build_options, + 'macosx/AppMain.tcl', + 'macosx/Info.plist', + 'macosx/git-gui.icns', + ], + build_by_default: true, + install: true, + install_dir: get_option('datadir') / 'git-gui/lib', + ) +endif + +custom_target( + input: 'git-gui.sh', + output: gitgui_main, + command: [ + shell, + meson.current_source_dir() / 'generate-git-gui.sh', + '@INPUT@', + '@OUTPUT@', + meson.current_build_dir() / 'GIT-GUI-BUILD-OPTIONS', + meson.current_build_dir() / 'GIT-VERSION-FILE', + ], + depends: [ + version_file, + ], + depend_files: [ + build_options, + ], + install: true, + install_dir: gitgui_main_install_dir, +) + +install_symlink('git-citool', + install_dir: get_option('libexecdir') / 'git-core', + pointing_to: 'git-gui', +) + +subdir('lib') +subdir('po') diff --git a/po/meson.build b/po/meson.build new file mode 100644 index 00000000000000..00cae7433859ad --- /dev/null +++ b/po/meson.build @@ -0,0 +1,38 @@ +languages = [ + 'bg', + 'de', + 'el', + 'fr', + 'hu', + 'it', + 'ja', + 'nb', + 'pt_br', + 'pt_pt', + 'ru', + 'sv', + 'vi', + 'zh_cn', +] + +msgfmt = find_program('msgfmt', required: false) +if not msgfmt.found() + subdir_done() +endif + +foreach language : languages + custom_target( + input: language + '.po', + output: language + '.msg', + command: [ + msgfmt, + '--statistics', + '--tcl', + '--locale=' + language, + '-d', meson.current_build_dir(), + '@INPUT@', + ], + install: true, + install_dir: get_option('datadir') / 'git-gui/lib/msgs', + ) +endforeach From 9f27318f148f7dbf6d837caea094dbd6490b8baa Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Tue, 13 May 2025 22:38:41 +0200 Subject: [PATCH 012/290] gitk: place file name arguments after options in msgfmt call The build process fails in POSIXLY_CORRECT mode: $ gitk@master:1005> POSIXLY_CORRECT=1 make * new Tcl/Tk interpreter location GEN gitk-wish Generating catalog po/zh_cn.msg msgfmt --statistics --tcl po/zh_cn.po -l zh_cn -d po/ msgfmt: --tcl requires a "-l locale" specification Try 'msgfmt --help' for more information. make: *** [Makefile:76: po/zh_cn.msg] Error 1 The reason is that option arguments cannot occur after the first non-option argument. Move the file name last. Reported-by: Nathan Royce Signed-off-by: Johannes Sixt --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3a3c56c318bad6..cc32dcab4b2a6b 100644 --- a/Makefile +++ b/Makefile @@ -73,7 +73,7 @@ update-po:: $(PO_TEMPLATE) $(foreach p, $(ALL_POFILES), echo Updating $p ; msgmerge -U $p $(PO_TEMPLATE) ; ) $(ALL_MSGFILES): %.msg : %.po @echo Generating catalog $@ - $(MSGFMT) --statistics --tcl $< -l $(basename $(notdir $<)) -d $(dir $@) + $(MSGFMT) --statistics --tcl -l $(basename $(notdir $<)) -d $(dir $@) $< .PHONY: all install uninstall clean update-po .PHONY: FORCE From 9cad4a9dc0358c959db42186eb40736e5fb5e788 Mon Sep 17 00:00:00 2001 From: Alexander Ogorodov Date: Tue, 18 Mar 2025 13:27:04 +0700 Subject: [PATCH 013/290] gitk: do not hard-code color of search results in commit list A global variable exists that holds the color name used to highlight search results everywhere, except that in the commit list the color is still hard-coded to "yellow". Use the global variable there as well. Signed-off-by: Alexander Ogorodov --- gitk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gitk b/gitk index bc9efa18566fb8..02a8b8eb8140aa 100755 --- a/gitk +++ b/gitk @@ -7139,7 +7139,7 @@ proc findselectline {l} { # mark the bits of a headline or author that match a find string proc markmatches {canv l str tag matches font row} { - global selectedline + global selectedline foundbgcolor set bbox [$canv bbox $tag] set x0 [lindex $bbox 0] @@ -7153,7 +7153,7 @@ proc markmatches {canv l str tag matches font row} { set xlen [font measure $font [string range $str 0 [expr {$end}]]] set t [$canv create rect [expr {$x0+$xoff}] $y0 \ [expr {$x0+$xlen+2}] $y1 \ - -outline {} -tags [list match$l matches] -fill yellow] + -outline {} -tags [list match$l matches] -fill $foundbgcolor] $canv lower $t if {$row == $selectedline} { $canv raise $t secsel From 2e60aabc759e3467e21a98f4e739c5e9f221cd9f Mon Sep 17 00:00:00 2001 From: Alex Mironov Date: Wed, 21 May 2025 21:29:31 +0000 Subject: [PATCH 014/290] name-hash: don't add sparse directories in threaded lazy init Ensure that logic added in 5f11669586 (name-hash: don't add directories to name_hash, 2021-04-12) also applies in multithreaded hashtable init path. As per the original single-threaded change above: sparse directory entries represent a directory that is outside the sparse-checkout definition. These are not paths to blobs, so should not be added to the name_hash table. Instead, they should be added to the directory hashtable when 'ignore_case' is true. Add a condition to avoid placing sparse directories into the name_hash hashtable. This avoids filling the table with extra entries that will never be queried. Signed-off-by: Alex Mironov Signed-off-by: Junio C Hamano --- name-hash.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/name-hash.c b/name-hash.c index d66de1cdfd5633..b91e276267891e 100644 --- a/name-hash.c +++ b/name-hash.c @@ -492,8 +492,10 @@ static void *lazy_name_thread_proc(void *_data) for (k = 0; k < d->istate->cache_nr; k++) { struct cache_entry *ce_k = d->istate->cache[k]; ce_k->ce_flags |= CE_HASHED; - hashmap_entry_init(&ce_k->ent, d->lazy_entries[k].hash_name); - hashmap_add(&d->istate->name_hash, &ce_k->ent); + if (!S_ISSPARSEDIR(ce_k->ce_mode)) { + hashmap_entry_init(&ce_k->ent, d->lazy_entries[k].hash_name); + hashmap_add(&d->istate->name_hash, &ce_k->ent); + } } return NULL; From b103881d4f4b157d86813ba5f91acd7ed6c888d0 Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Thu, 22 May 2025 16:55:20 +0100 Subject: [PATCH 015/290] midx repack: avoid integer overflow on 32 bit systems On a 32 bit system "git multi-pack-index --repack --batch-size=120M" failed with fatal: size_t overflow: 6038786 * 1289 The calculation to estimated size of the objects in the pack referenced by the multi-pack-index uses st_mult() to multiply the pack size by the number of referenced objects before dividing by the total number of objects in the pack. As size_t is 32 bits on 32 bit systems this calculation easily overflows. Fix this by using 64bit arithmetic instead. Also fix a potential overflow when caluculating the total size of the objects referenced by the multipack index with a batch size larger than SIZE_MAX / 2. In that case total_size += estimated_size can overflow as both total_size and estimated_size can be greater that SIZE_MAX / 2. This is addressed by using saturating arithmetic for the addition. Although estimated_size is of type uint64_t by the time we reach this sum it is bounded by the batch size which is of type size_t and so casting estimated_size to size_t does not truncate the value. Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- git-compat-util.h | 16 ++++++++++++++++ midx-write.c | 12 ++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/git-compat-util.h b/git-compat-util.h index 36b9577c8d4b3b..4678e21c4cb80b 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -668,6 +668,22 @@ static inline int cast_size_t_to_int(size_t a) return (int)a; } +static inline uint64_t u64_mult(uint64_t a, uint64_t b) +{ + if (unsigned_mult_overflows(a, b)) + die("uint64_t overflow: %"PRIuMAX" * %"PRIuMAX, + (uintmax_t)a, (uintmax_t)b); + return a * b; +} + +static inline uint64_t u64_add(uint64_t a, uint64_t b) +{ + if (unsigned_add_overflows(a, b)) + die("uint64_t overflow: %"PRIuMAX" + %"PRIuMAX, + (uintmax_t)a, (uintmax_t)b); + return a + b; +} + /* * Limit size of IO chunks, because huge chunks only cause pain. OS X * 64-bit is buggy, returning EINVAL if len >= INT_MAX; and even in diff --git a/midx-write.c b/midx-write.c index dd3b3070e55dfc..105014a2792266 100644 --- a/midx-write.c +++ b/midx-write.c @@ -1699,19 +1699,23 @@ static void fill_included_packs_batch(struct repository *r, for (i = 0; total_size < batch_size && i < m->num_packs; i++) { int pack_int_id = pack_info[i].pack_int_id; struct packed_git *p = m->packs[pack_int_id]; - size_t expected_size; + uint64_t expected_size; if (!want_included_pack(r, m, pack_kept_objects, pack_int_id)) continue; - expected_size = st_mult(p->pack_size, - pack_info[i].referenced_objects); + expected_size = uint64_mult(p->pack_size, + pack_info[i].referenced_objects); expected_size /= p->num_objects; if (expected_size >= batch_size) continue; - total_size += expected_size; + if (unsigned_add_overflows(total_size, (size_t)expected_size)) + total_size = SIZE_MAX; + else + total_size += expected_size; + include_pack[pack_int_id] = 1; } From f874c0ed90c63276e0ebc445ad6fee5dcbfacb86 Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Thu, 22 May 2025 16:55:21 +0100 Subject: [PATCH 016/290] midx repack: avoid potential integer overflow on 64 bit systems On a 64 bit system the calculation p->pack_size * pack_info[i].referenced_objects could overflow. If a pack file contains 2^28 objects with an average compressed size of 1KB then the pack size will be 2^38B. If all of the objects are referenced by the multi-pack index the sum above will overflow. Avoid this by using shifted integer arithmetic and changing the order of the calculation so that the pack size is divided by the total number of objects in the pack before multiplying by the number of objects referenced by the multi-pack index. Using a shift of 14 bits should give reasonable accuracy while avoiding overflow for pack sizes less that 1PB. Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- midx-write.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/midx-write.c b/midx-write.c index 105014a2792266..8121e96f4fda00 100644 --- a/midx-write.c +++ b/midx-write.c @@ -1704,9 +1704,15 @@ static void fill_included_packs_batch(struct repository *r, if (!want_included_pack(r, m, pack_kept_objects, pack_int_id)) continue; - expected_size = uint64_mult(p->pack_size, - pack_info[i].referenced_objects); + /* + * Use shifted integer arithmetic to calculate the + * expected pack size to ~4 significant digits without + * overflow for packsizes less that 1PB. + */ + expected_size = (uint64_t)pack_info[i].referenced_objects << 14; expected_size /= p->num_objects; + expected_size = u64_mult(expected_size, p->pack_size); + expected_size = u64_add(expected_size, 1u << 13) >> 14; if (expected_size >= batch_size) continue; From 3aa98a61da6e1403081b4dfaa0c644614d228bac Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Thu, 22 May 2025 16:55:22 +0100 Subject: [PATCH 017/290] midx: avoid negative array index nth_midxed_pack_int_id() returns the index of the pack file in the multi pack index's list of packfiles that the specified object. The index is returned as a uint32_t. Storing this in an int will make the index negative if the most significant bit is set. Fix this by using uint32_t as the rest of the code does. This is unlikely to be a practical problem as it requires the multipack index to reference 2^31 packfiles. Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- midx-write.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/midx-write.c b/midx-write.c index 8121e96f4fda00..ba4a94950a8314 100644 --- a/midx-write.c +++ b/midx-write.c @@ -1566,7 +1566,7 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla _("Counting referenced objects"), m->num_objects); for (i = 0; i < m->num_objects; i++) { - int pack_int_id = nth_midxed_pack_int_id(m, i); + uint32_t pack_int_id = nth_midxed_pack_int_id(m, i); count[pack_int_id]++; display_progress(progress, i + 1); } @@ -1697,7 +1697,7 @@ static void fill_included_packs_batch(struct repository *r, total_size = 0; for (i = 0; total_size < batch_size && i < m->num_packs; i++) { - int pack_int_id = pack_info[i].pack_int_id; + uint32_t pack_int_id = pack_info[i].pack_int_id; struct packed_git *p = m->packs[pack_int_id]; uint64_t expected_size; From 70b128c57635183761df8a52a56f43dc30468ded Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Thu, 22 May 2025 16:55:23 +0100 Subject: [PATCH 018/290] midx docs: clarify tie breaking Clarify what happens when an object exists in more than one pack, but not in the preferred pack. "git multi-pack-index repack" relies on ties for objects that are not in the preferred pack being resolved in favor of the newest pack that contains a copy of the object. If ties were resolved in favor of the oldest pack as the current documentation suggests the multi-pack index would not reference any of the objects in the pack created by "git multi-pack-index repack". Helped-by: Taylor Blau Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- Documentation/git-multi-pack-index.adoc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Documentation/git-multi-pack-index.adoc b/Documentation/git-multi-pack-index.adoc index 631d5c7d15c0de..b6cd0d7f855d5f 100644 --- a/Documentation/git-multi-pack-index.adoc +++ b/Documentation/git-multi-pack-index.adoc @@ -38,10 +38,13 @@ write:: + -- --preferred-pack=:: - Optionally specify the tie-breaking pack used when - multiple packs contain the same object. `` must - contain at least one object. If not given, ties are - broken in favor of the pack with the lowest mtime. + When specified, break ties in favor of this pack when + there are additional copies of its objects in other + packs. Ties for objects not found in the preferred + pack are always resolved in favor of the copy in the + pack with the highest mtime. If unspecified, the pack + with the lowest mtime is used by default. The + preferred pack must have at least one object. --[no-]bitmap:: Control whether or not a multi-pack bitmap is written. From 2cc8c17d67265f1912b79f8e57fc2718597ca686 Mon Sep 17 00:00:00 2001 From: Mark Mentovai Date: Fri, 23 May 2025 23:40:45 -0400 Subject: [PATCH 019/290] t4129: test that git apply warns for unexpected mode changes There is no test covering what commit 01aff0a (apply: correctly reverse patch's pre- and post-image mode bits, 2023-12-26) addressed. Prior to that commit, git apply was erroneously unaware of a file's expected mode while reverse-patching a file whose mode was not changing. Add the missing test coverage to assure that git apply is aware of the expected mode of a file being patched when the patch does not indicate that the file's mode is changing. This is achieved by arranging a file mode so that it doesn't agree with patch being applied, and checking git apply's output for the warning it's supposed to raise in this situation. Test in both reverse and normal (forward) directions. Signed-off-by: Mark Mentovai Signed-off-by: Junio C Hamano --- t/t4129-apply-samemode.sh | 70 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 5 deletions(-) diff --git a/t/t4129-apply-samemode.sh b/t/t4129-apply-samemode.sh index 2149ad5da44cde..bf4e7609dc335b 100755 --- a/t/t4129-apply-samemode.sh +++ b/t/t4129-apply-samemode.sh @@ -102,15 +102,23 @@ test_expect_success POSIXPERM 'do not use core.sharedRepository for working tree ) ' +test_file_mode_staged () { + git ls-files --stage -- "$2" >ls-files-output && + test_grep "^$1 " ls-files-output +} + +test_file_mode_HEAD () { + git ls-tree HEAD -- "$2" >ls-tree-output && + test_grep "^$1 " ls-tree-output +} + test_expect_success 'git apply respects core.fileMode' ' test_config core.fileMode false && echo true >script.sh && git add --chmod=+x script.sh && - git ls-files -s script.sh >ls-files-output && - test_grep "^100755" ls-files-output && + test_file_mode_staged 100755 script.sh && test_tick && git commit -m "Add script" && - git ls-tree -r HEAD script.sh >ls-tree-output && - test_grep "^100755" ls-tree-output && + test_file_mode_HEAD 100755 script.sh && echo true >>script.sh && test_tick && git commit -m "Modify script" script.sh && @@ -126,7 +134,59 @@ test_expect_success 'git apply respects core.fileMode' ' test_grep ! "has type 100644, expected 100755" err && git apply --cached patch 2>err && - test_grep ! "has type 100644, expected 100755" err + test_grep ! "has type 100644, expected 100755" err && + git reset --hard +' + +test_expect_success 'setup: git apply [--reverse] warns about incorrect file modes' ' + test_config core.fileMode false && + + >mode_test && + git add --chmod=-x mode_test && + test_file_mode_staged 100644 mode_test && + test_tick && git commit -m "add mode_test" && + test_file_mode_HEAD 100644 mode_test && + git tag mode_test_forward_initial && + + echo content >>mode_test && + test_tick && git commit -m "append to mode_test" mode_test && + test_file_mode_HEAD 100644 mode_test && + git tag mode_test_reverse_initial && + + git format-patch -1 --stdout >patch && + test_grep "^index .* 100644$" patch +' + +test_expect_success 'git apply warns about incorrect file modes' ' + test_config core.fileMode false && + git reset --hard mode_test_forward_initial && + + git add --chmod=+x mode_test && + test_file_mode_staged 100755 mode_test && + test_tick && git commit -m "make mode_test executable" && + test_file_mode_HEAD 100755 mode_test && + + git apply --index patch 2>err && + test_grep "has type 100755, expected 100644" err && + test_file_mode_staged 100755 mode_test && + test_tick && git commit -m "redo: append to mode_test" && + test_file_mode_HEAD 100755 mode_test +' + +test_expect_success 'git apply --reverse warns about incorrect file modes' ' + test_config core.fileMode false && + git reset --hard mode_test_reverse_initial && + + git add --chmod=+x mode_test && + test_file_mode_staged 100755 mode_test && + test_tick && git commit -m "make mode_test executable" && + test_file_mode_HEAD 100755 mode_test && + + git apply --index --reverse patch 2>err && + test_grep "has type 100755, expected 100644" err && + test_file_mode_staged 100755 mode_test && + test_tick && git commit -m "undo: append to mode_test" && + test_file_mode_HEAD 100755 mode_test ' test_expect_success POSIXPERM 'patch mode for new file is canonicalized' ' From 1d9a66493be9fef38e531da587dd47f6f17ea483 Mon Sep 17 00:00:00 2001 From: Mark Mentovai Date: Fri, 23 May 2025 23:40:46 -0400 Subject: [PATCH 020/290] apply: set file mode when --reverse creates a deleted file Commit 01aff0a (apply: correctly reverse patch's pre- and post-image mode bits, 2023-12-26) revised reverse_patches() to maintain the desired property that when only one of patch::old_mode and patch::new_mode is set, the mode will be carried in old_mode. That property is generally correct, with one notable exception: when creating a file, only new_mode will be set. Since reversing a deletion results in a creation, new_mode must be set in that case. Omitting handling for this case means that reversing a patch that removes an executable file will not result in the executable permission being set on the re-created file. Existing test coverage for file modes focuses only on mode changes of existing files. Swap old_mode and new_mode in reverse_patches() for what's represented in the patch as a file deletion, as it is transformed into a file creation under reversal. This causes git apply --reverse to set the executable permission properly when re-creating a deleted executable file. Add tests ensuring that git apply sets file modes correctly on file creation, both in the forward and reverse directions. Signed-off-by: Mark Mentovai Signed-off-by: Junio C Hamano --- apply.c | 2 +- t/t4129-apply-samemode.sh | 165 +++++++++++++++++++++++++++++++++++++- 2 files changed, 164 insertions(+), 3 deletions(-) diff --git a/apply.c b/apply.c index 381d2e3652f4e0..8bbe6ed224032e 100644 --- a/apply.c +++ b/apply.c @@ -2219,7 +2219,7 @@ static void reverse_patches(struct patch *p) struct fragment *frag = p->fragments; SWAP(p->new_name, p->old_name); - if (p->new_mode) + if (p->new_mode || p->is_delete) SWAP(p->new_mode, p->old_mode); SWAP(p->is_new, p->is_delete); SWAP(p->lines_added, p->lines_deleted); diff --git a/t/t4129-apply-samemode.sh b/t/t4129-apply-samemode.sh index bf4e7609dc335b..1d6317bd7141e0 100755 --- a/t/t4129-apply-samemode.sh +++ b/t/t4129-apply-samemode.sh @@ -102,14 +102,23 @@ test_expect_success POSIXPERM 'do not use core.sharedRepository for working tree ) ' +test_file_mode_common () { + if test "$1" = "000000" + then + test_must_be_empty "$2" + else + test_grep "^$1 " "$2" + fi +} + test_file_mode_staged () { git ls-files --stage -- "$2" >ls-files-output && - test_grep "^$1 " ls-files-output + test_file_mode_common "$1" ls-files-output } test_file_mode_HEAD () { git ls-tree HEAD -- "$2" >ls-tree-output && - test_grep "^$1 " ls-tree-output + test_file_mode_common "$1" ls-tree-output } test_expect_success 'git apply respects core.fileMode' ' @@ -189,6 +198,158 @@ test_expect_success 'git apply --reverse warns about incorrect file modes' ' test_file_mode_HEAD 100755 mode_test ' +test_expect_success 'setup: git apply [--reverse] restores file modes (change_x_to_notx)' ' + test_config core.fileMode false && + + touch change_x_to_notx && + git add --chmod=+x change_x_to_notx && + test_file_mode_staged 100755 change_x_to_notx && + test_tick && git commit -m "add change_x_to_notx as executable" && + test_file_mode_HEAD 100755 change_x_to_notx && + + git add --chmod=-x change_x_to_notx && + test_file_mode_staged 100644 change_x_to_notx && + test_tick && git commit -m "make change_x_to_notx not executable" && + test_file_mode_HEAD 100644 change_x_to_notx && + + git rm change_x_to_notx && + test_file_mode_staged 000000 change_x_to_notx && + test_tick && git commit -m "remove change_x_to_notx" && + test_file_mode_HEAD 000000 change_x_to_notx && + + git format-patch -o patches -3 && + mv patches/0001-* change_x_to_notx-0001-create-0755.patch && + mv patches/0002-* change_x_to_notx-0002-chmod-0644.patch && + mv patches/0003-* change_x_to_notx-0003-delete.patch && + + test_grep "^new file mode 100755$" change_x_to_notx-0001-create-0755.patch && + test_grep "^old mode 100755$" change_x_to_notx-0002-chmod-0644.patch && + test_grep "^new mode 100644$" change_x_to_notx-0002-chmod-0644.patch && + test_grep "^deleted file mode 100644$" change_x_to_notx-0003-delete.patch && + + git tag change_x_to_notx_initial +' + +test_expect_success 'git apply restores file modes (change_x_to_notx)' ' + test_config core.fileMode false && + git reset --hard change_x_to_notx_initial && + + git apply --index change_x_to_notx-0001-create-0755.patch && + test_file_mode_staged 100755 change_x_to_notx && + test_tick && git commit -m "redo: add change_x_to_notx as executable" && + test_file_mode_HEAD 100755 change_x_to_notx && + + git apply --index change_x_to_notx-0002-chmod-0644.patch 2>err && + test_grep ! "has type 100.*, expected 100.*" err && + test_file_mode_staged 100644 change_x_to_notx && + test_tick && git commit -m "redo: make change_x_to_notx not executable" && + test_file_mode_HEAD 100644 change_x_to_notx && + + git apply --index change_x_to_notx-0003-delete.patch 2>err && + test_grep ! "has type 100.*, expected 100.*" err && + test_file_mode_staged 000000 change_x_to_notx && + test_tick && git commit -m "redo: remove change_notx_to_x" && + test_file_mode_HEAD 000000 change_x_to_notx +' + +test_expect_success 'git apply --reverse restores file modes (change_x_to_notx)' ' + test_config core.fileMode false && + git reset --hard change_x_to_notx_initial && + + git apply --index --reverse change_x_to_notx-0003-delete.patch && + test_file_mode_staged 100644 change_x_to_notx && + test_tick && git commit -m "undo: remove change_x_to_notx" && + test_file_mode_HEAD 100644 change_x_to_notx && + + git apply --index --reverse change_x_to_notx-0002-chmod-0644.patch 2>err && + test_grep ! "has type 100.*, expected 100.*" err && + test_file_mode_staged 100755 change_x_to_notx && + test_tick && git commit -m "undo: make change_x_to_notx not executable" && + test_file_mode_HEAD 100755 change_x_to_notx && + + git apply --index --reverse change_x_to_notx-0001-create-0755.patch 2>err && + test_grep ! "has type 100.*, expected 100.*" err && + test_file_mode_staged 000000 change_x_to_notx && + test_tick && git commit -m "undo: add change_x_to_notx as executable" && + test_file_mode_HEAD 000000 change_x_to_notx +' + +test_expect_success 'setup: git apply [--reverse] restores file modes (change_notx_to_x)' ' + test_config core.fileMode false && + + touch change_notx_to_x && + git add --chmod=-x change_notx_to_x && + test_file_mode_staged 100644 change_notx_to_x && + test_tick && git commit -m "add change_notx_to_x as not executable" && + test_file_mode_HEAD 100644 change_notx_to_x && + + git add --chmod=+x change_notx_to_x && + test_file_mode_staged 100755 change_notx_to_x && + test_tick && git commit -m "make change_notx_to_x executable" && + test_file_mode_HEAD 100755 change_notx_to_x && + + git rm change_notx_to_x && + test_file_mode_staged 000000 change_notx_to_x && + test_tick && git commit -m "remove change_notx_to_x" && + test_file_mode_HEAD 000000 change_notx_to_x && + + git format-patch -o patches -3 && + mv patches/0001-* change_notx_to_x-0001-create-0644.patch && + mv patches/0002-* change_notx_to_x-0002-chmod-0755.patch && + mv patches/0003-* change_notx_to_x-0003-delete.patch && + + test_grep "^new file mode 100644$" change_notx_to_x-0001-create-0644.patch && + test_grep "^old mode 100644$" change_notx_to_x-0002-chmod-0755.patch && + test_grep "^new mode 100755$" change_notx_to_x-0002-chmod-0755.patch && + test_grep "^deleted file mode 100755$" change_notx_to_x-0003-delete.patch && + + git tag change_notx_to_x_initial +' + +test_expect_success 'git apply restores file modes (change_notx_to_x)' ' + test_config core.fileMode false && + git reset --hard change_notx_to_x_initial && + + git apply --index change_notx_to_x-0001-create-0644.patch && + test_file_mode_staged 100644 change_notx_to_x && + test_tick && git commit -m "redo: add change_notx_to_x as not executable" && + test_file_mode_HEAD 100644 change_notx_to_x && + + git apply --index change_notx_to_x-0002-chmod-0755.patch 2>err && + test_grep ! "has type 100.*, expected 100.*" err && + test_file_mode_staged 100755 change_notx_to_x && + test_tick && git commit -m "redo: make change_notx_to_x executable" && + test_file_mode_HEAD 100755 change_notx_to_x && + + git apply --index change_notx_to_x-0003-delete.patch && + test_grep ! "has type 100.*, expected 100.*" err && + test_file_mode_staged 000000 change_notx_to_x && + test_tick && git commit -m "undo: remove change_notx_to_x" && + test_file_mode_HEAD 000000 change_notx_to_x +' + +test_expect_success 'git apply --reverse restores file modes (change_notx_to_x)' ' + test_config core.fileMode false && + git reset --hard change_notx_to_x_initial && + + git apply --index --reverse change_notx_to_x-0003-delete.patch && + test_file_mode_staged 100755 change_notx_to_x && + test_tick && git commit -m "undo: remove change_notx_to_x" && + test_file_mode_HEAD 100755 change_notx_to_x && + + git apply --index --reverse change_notx_to_x-0002-chmod-0755.patch 2>err && + test_grep ! "has type 100.*, expected 100.*" err && + test_file_mode_staged 100644 change_notx_to_x && + test_tick && git commit -m "undo: make change_notx_to_x executable" && + test_file_mode_HEAD 100644 change_notx_to_x && + + git apply --index --reverse change_notx_to_x-0001-create-0644.patch 2>err && + test_grep ! "has type 100.*, expected 100.*" err && + test_file_mode_staged 000000 change_notx_to_x && + test_tick && git commit -m "undo: add change_notx_to_x as not executable" && + test_file_mode_HEAD 000000 change_notx_to_x +' + test_expect_success POSIXPERM 'patch mode for new file is canonicalized' ' cat >patch <<-\EOF && diff --git a/non-canon b/non-canon From 3d26ec171567ef205648380fb621ab0369f910e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= Date: Sun, 25 May 2025 20:27:01 +0000 Subject: [PATCH 021/290] doc: convert git-checkout manpage to new style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Switch the synopsis to a synopsis block which will automatically format placeholders in italics and keywords in monospace - Use __ instead of in the description - Use `backticks` for keywords and more complex option descriptions. The new rendering engine will apply synopsis rules to these spans. Signed-off-by: Jean-Noël Avila Signed-off-by: Junio C Hamano --- Documentation/config/checkout.adoc | 14 +- Documentation/git-checkout.adoc | 228 ++++++++++++++--------------- 2 files changed, 121 insertions(+), 121 deletions(-) diff --git a/Documentation/config/checkout.adoc b/Documentation/config/checkout.adoc index a3230229938055..e35d21296978fe 100644 --- a/Documentation/config/checkout.adoc +++ b/Documentation/config/checkout.adoc @@ -1,9 +1,9 @@ -checkout.defaultRemote:: +`checkout.defaultRemote`:: When you run `git checkout ` or `git switch ` and only have one remote, it may implicitly fall back on checking out and tracking e.g. `origin/`. This stops working as soon - as you have more than one remote with a `` + as you have more than one remote with a __ reference. This setting allows for setting the name of a preferred remote that should always win when it comes to disambiguation. The typical use-case is to set this to @@ -12,17 +12,17 @@ checkout.defaultRemote:: Currently this is used by linkgit:git-switch[1] and linkgit:git-checkout[1] when `git checkout ` or `git switch ` -will checkout the `` branch on another remote, +will checkout the __ branch on another remote, and by linkgit:git-worktree[1] when `git worktree add` refers to a remote branch. This setting might be used for other checkout-like commands or functionality in the future. -checkout.guess:: +`checkout.guess`:: Provides the default value for the `--guess` or `--no-guess` option in `git checkout` and `git switch`. See linkgit:git-switch[1] and linkgit:git-checkout[1]. -checkout.workers:: +`checkout.workers`:: The number of parallel workers to use when updating the working tree. The default is one, i.e. sequential execution. If set to a value less than one, Git will use as many workers as the number of logical cores @@ -30,13 +30,13 @@ checkout.workers:: all commands that perform checkout. E.g. checkout, clone, reset, sparse-checkout, etc. + -Note: Parallel checkout usually delivers better performance for repositories +NOTE: Parallel checkout usually delivers better performance for repositories located on SSDs or over NFS. For repositories on spinning disks and/or machines with a small number of cores, the default sequential checkout often performs better. The size and compression level of a repository might also influence how well the parallel version performs. -checkout.thresholdForParallelism:: +`checkout.thresholdForParallelism`:: When running parallel checkout with a small number of files, the cost of subprocess spawning and inter-process communication might outweigh the parallelization gains. This setting allows you to define the minimum diff --git a/Documentation/git-checkout.adoc b/Documentation/git-checkout.adoc index a66c53a5cd1e0a..ee83b6d9ba9a9b 100644 --- a/Documentation/git-checkout.adoc +++ b/Documentation/git-checkout.adoc @@ -7,54 +7,54 @@ git-checkout - Switch branches or restore working tree files SYNOPSIS -------- -[verse] -'git checkout' [-q] [-f] [-m] [] -'git checkout' [-q] [-f] [-m] --detach [] -'git checkout' [-q] [-f] [-m] [--detach] -'git checkout' [-q] [-f] [-m] [[-b|-B|--orphan] ] [] -'git checkout' [-f] [--] ... -'git checkout' [-f] --pathspec-from-file= [--pathspec-file-nul] -'git checkout' [-f|--ours|--theirs|-m|--conflict=