diff --git a/.git.metadata b/.git.metadata
index 23e9687..1f2e864 100644
--- a/.git.metadata
+++ b/.git.metadata
@@ -1,2 +1,2 @@
-a66f98f88bf7734f8463446ac0735cee190da1dc SOURCES/git-2.31.1.tar.xz
+3a35d0571c517f7f4cb2e1dfbd315e7c32023e2b SOURCES/git-2.39.1.tar.xz
 87d3a395bad523277647f8614fbd9fefe0450fc6 SOURCES/gpgkey-junio.asc
diff --git a/.gitignore b/.gitignore
index 69936fb..4b5ee86 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
-SOURCES/git-2.31.1.tar.xz
+SOURCES/git-2.39.1.tar.xz
 SOURCES/gpgkey-junio.asc
diff --git a/SOURCES/0001-t-lib-httpd-try-harder-to-find-a-port-for-apache.patch b/SOURCES/0001-t-lib-httpd-try-harder-to-find-a-port-for-apache.patch
new file mode 100644
index 0000000..f7c1509
--- /dev/null
+++ b/SOURCES/0001-t-lib-httpd-try-harder-to-find-a-port-for-apache.patch
@@ -0,0 +1,73 @@
+From aedeaaf788bd8a7fc5a1887196b6f6d8a5c31362 Mon Sep 17 00:00:00 2001
+From: Todd Zullinger <tmz@pobox.com>
+Date: Sun, 21 Aug 2022 13:49:57 -0400
+Subject: [PATCH] t/lib-httpd: try harder to find a port for apache
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When running multiple builds concurrently, tests which run daemons, like
+apache httpd, sometimes conflict with each other, leading to spurious
+failures:
+
+    ++ /usr/sbin/httpd -d '/tmp/git-t.ck9I/trash directory.t9118-git-svn-funky-branch-names/httpd' \
+       -f /builddir/build/BUILD/git-2.37.2/t/lib-httpd/apache.conf -DDAV -DSVN -c 'Listen 127.0.0.1:9118' \
+       -k start
+    (98)Address already in use: AH00072: make_sock: could not bind to address 127.0.0.1:9118
+    no listening sockets available, shutting down
+    AH00015: Unable to open logs
+    ++ test 1 -ne 0
+
+Try a bit harder to find an open port to use to avoid these intermittent
+failures.  If we fail to start httpd, increment the port number and try
+again.  By default, we make 3 attempts.  This may be overridden by
+setting GIT_TEST_START_HTTPD_TRIES to a different value.
+
+Helped-by: Ondřej Pohořelský <opohorel@redhat.com>
+Signed-off-by: Todd Zullinger <tmz@pobox.com>
+---
+ t/lib-httpd.sh | 29 ++++++++++++++++++-----------
+ 1 file changed, 18 insertions(+), 11 deletions(-)
+
+diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
+index 1f6b9b08d1..9279dcd659 100644
+--- a/t/lib-httpd.sh
++++ b/t/lib-httpd.sh
+@@ -175,19 +175,26 @@ prepare_httpd() {
+ }
+ 
+ start_httpd() {
+-	prepare_httpd >&3 2>&4
+-
+ 	test_atexit stop_httpd
+ 
+-	"$LIB_HTTPD_PATH" -d "$HTTPD_ROOT_PATH" \
+-		-f "$TEST_PATH/apache.conf" $HTTPD_PARA \
+-		-c "Listen 127.0.0.1:$LIB_HTTPD_PORT" -k start \
+-		>&3 2>&4
+-	if test $? -ne 0
+-	then
+-		cat "$HTTPD_ROOT_PATH"/error.log >&4 2>/dev/null
+-		test_skip_or_die GIT_TEST_HTTPD "web server setup failed"
+-	fi
++	i=0
++	while test $i -lt ${GIT_TEST_START_HTTPD_TRIES:-3}
++	do
++		i=$(($i + 1))
++		prepare_httpd >&3 2>&4
++		say >&3 "Starting httpd on port $LIB_HTTPD_PORT"
++		"$LIB_HTTPD_PATH" -d "$HTTPD_ROOT_PATH" \
++			-f "$TEST_PATH/apache.conf" $HTTPD_PARA \
++			-c "Listen 127.0.0.1:$LIB_HTTPD_PORT" -k start \
++			>&3 2>&4
++		test $? -eq 0 && return
++		LIB_HTTPD_PORT=$(($LIB_HTTPD_PORT + 1))
++		export LIB_HTTPD_PORT
++		# clean up modules symlink, prepare_httpd will re-create it
++		rm -f "$HTTPD_ROOT_PATH/modules"
++	done
++	cat "$HTTPD_ROOT_PATH"/error.log >&4 2>/dev/null
++	test_skip_or_die GIT_TEST_HTTPD "web server setup failed"
+ }
+ 
+ stop_httpd() {
diff --git a/SOURCES/0002-t-lib-git-daemon-try-harder-to-find-a-port.patch b/SOURCES/0002-t-lib-git-daemon-try-harder-to-find-a-port.patch
new file mode 100644
index 0000000..4540b63
--- /dev/null
+++ b/SOURCES/0002-t-lib-git-daemon-try-harder-to-find-a-port.patch
@@ -0,0 +1,88 @@
+From 16750d024ce038b019ab2e9ee5639901e445af37 Mon Sep 17 00:00:00 2001
+From: Todd Zullinger <tmz@pobox.com>
+Date: Fri, 26 Aug 2022 18:28:44 -0400
+Subject: [PATCH] t/lib-git-daemon: try harder to find a port
+
+As with the previous commit, try harder to find an open port to avoid
+intermittent failures on busy/shared build systems.
+
+By default, we make 3 attempts.  This may be overridden by setting
+GIT_TEST_START_GIT_DAEMON_TRIES to a different value.
+
+Signed-off-by: Todd Zullinger <tmz@pobox.com>
+---
+ t/lib-git-daemon.sh | 60 ++++++++++++++++++++++++++++-----------------
+ 1 file changed, 37 insertions(+), 23 deletions(-)
+
+diff --git a/t/lib-git-daemon.sh b/t/lib-git-daemon.sh
+index e62569222b..c3e8dda9ff 100644
+--- a/t/lib-git-daemon.sh
++++ b/t/lib-git-daemon.sh
+@@ -51,30 +51,44 @@ start_git_daemon() {
+ 		registered_stop_git_daemon_atexit_handler=AlreadyDone
+ 	fi
+ 
+-	say >&3 "Starting git daemon ..."
+-	mkfifo git_daemon_output
+-	${LIB_GIT_DAEMON_COMMAND:-git daemon} \
+-		--listen=127.0.0.1 --port="$LIB_GIT_DAEMON_PORT" \
+-		--reuseaddr --verbose --pid-file="$GIT_DAEMON_PIDFILE" \
+-		--base-path="$GIT_DAEMON_DOCUMENT_ROOT_PATH" \
+-		"$@" "$GIT_DAEMON_DOCUMENT_ROOT_PATH" \
+-		>&3 2>git_daemon_output &
+-	GIT_DAEMON_PID=$!
+-	{
+-		read -r line <&7
+-		printf "%s\n" "$line" >&4
+-		cat <&7 >&4 &
+-	} 7<git_daemon_output &&
++	i=0
++	while test $i -lt ${GIT_TEST_START_GIT_DAEMON_TRIES:-3}
++	do
++		say >&3 "Starting git daemon on port $LIB_GIT_DAEMON_PORT ..."
++		mkfifo git_daemon_output
++		${LIB_GIT_DAEMON_COMMAND:-git daemon} \
++			--listen=127.0.0.1 --port="$LIB_GIT_DAEMON_PORT" \
++			--reuseaddr --verbose --pid-file="$GIT_DAEMON_PIDFILE" \
++			--base-path="$GIT_DAEMON_DOCUMENT_ROOT_PATH" \
++			"$@" "$GIT_DAEMON_DOCUMENT_ROOT_PATH" \
++			>&3 2>git_daemon_output &
++		GIT_DAEMON_PID=$!
++		{
++			read -r line <&7
++			printf "%s\n" "$line" >&4
++			cat <&7 >&4 &
++		} 7<git_daemon_output &&
+ 
+-	# Check expected output
+-	if test x"$(expr "$line" : "\[[0-9]*\] \(.*\)")" != x"Ready to rumble"
+-	then
+-		kill "$GIT_DAEMON_PID"
+-		wait "$GIT_DAEMON_PID"
+-		unset GIT_DAEMON_PID
+-		test_skip_or_die GIT_TEST_GIT_DAEMON \
+-			"git daemon failed to start"
+-	fi
++		# Check expected output
++		output="$(expr "$line" : "\[[0-9]*\] \(.*\)")"
++		# Return if found
++		test x"$output" = x"Ready to rumble" && return
++		# Increment port for retry if not found
++		LIB_GIT_DAEMON_PORT=$(($LIB_GIT_DAEMON_PORT + 1))
++		export LIB_GIT_DAEMON_PORT
++		GIT_DAEMON_HOST_PORT=127.0.0.1:$LIB_GIT_DAEMON_PORT
++		GIT_DAEMON_URL=git://$GIT_DAEMON_HOST_PORT
++		# unset GIT_DAEMON_PID; remove the fifo & pid file
++		GIT_DAEMON_PID=
++		rm -f git_daemon_output "$GIT_DAEMON_PIDFILE"
++	done
++
++	# Clean up and return failure
++	kill "$GIT_DAEMON_PID"
++	wait "$GIT_DAEMON_PID"
++	unset GIT_DAEMON_PID
++	test_skip_or_die GIT_TEST_GIT_DAEMON \
++		"git daemon failed to start"
+ }
+ 
+ stop_git_daemon() {
diff --git a/SOURCES/0003-t-lib-git-svn-try-harder-to-find-a-port.patch b/SOURCES/0003-t-lib-git-svn-try-harder-to-find-a-port.patch
new file mode 100644
index 0000000..56624e2
--- /dev/null
+++ b/SOURCES/0003-t-lib-git-svn-try-harder-to-find-a-port.patch
@@ -0,0 +1,85 @@
+From aa5105dc115b43edc6c9c11714b092583f1221aa Mon Sep 17 00:00:00 2001
+From: Todd Zullinger <tmz@pobox.com>
+Date: Fri, 26 Aug 2022 18:28:44 -0400
+Subject: [PATCH] t/lib-git-svn: try harder to find a port
+
+As with the previous commits, try harder to find an open port to avoid
+intermittent failures on busy/shared build systems.
+
+By default, we make 3 attempts.  This may be overridden by setting
+GIT_TEST_START_SVNSERVE_TRIES to a different value.
+
+Run svnserve in daemon mode and use 'test_atexit' to stop it.  This is
+cleaner than running in the foreground with --listen-once and having to
+manage the PID ourselves.
+
+Signed-off-by: Todd Zullinger <tmz@pobox.com>
+---
+ t/lib-git-svn.sh                    | 34 +++++++++++++++++++++++++----
+ t/t9113-git-svn-dcommit-new-file.sh |  1 -
+ 2 files changed, 30 insertions(+), 5 deletions(-)
+
+diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
+index ea28971e8e..04e660e2ba 100644
+--- a/t/lib-git-svn.sh
++++ b/t/lib-git-svn.sh
+@@ -17,6 +17,7 @@ fi
+ GIT_DIR=$PWD/.git
+ GIT_SVN_DIR=$GIT_DIR/svn/refs/remotes/git-svn
+ SVN_TREE=$GIT_SVN_DIR/svn-tree
++SVNSERVE_PIDFILE="$PWD"/daemon.pid
+ test_set_port SVNSERVE_PORT
+ 
+ svn >/dev/null 2>&1
+@@ -119,10 +120,35 @@ require_svnserve () {
+ }
+ 
+ start_svnserve () {
+-	svnserve --listen-port $SVNSERVE_PORT \
+-		 --root "$rawsvnrepo" \
+-		 --listen-once \
+-		 --listen-host 127.0.0.1 &
++	test_atexit stop_svnserve
++
++	i=0
++	while test $i -lt ${GIT_TEST_START_SVNSERVE_TRIES:-3}
++	do
++		say >&3 "Starting svnserve on port $SVNSERVE_PORT ..."
++		svnserve --listen-port $SVNSERVE_PORT \
++			 --root "$rawsvnrepo" \
++			 --daemon --pid-file="$SVNSERVE_PIDFILE" \
++			 --listen-host 127.0.0.1
++		ret=$?
++		# increment port and retry if unsuccessful
++		if test $ret -ne 0
++		then
++			SVNSERVE_PORT=$(($SVNSERVE_PORT + 1))
++			export SVNSERVE_PORT
++		else
++			break
++		fi
++	done
++}
++
++stop_svnserve () {
++	say >&3 "Stopping svnserve ..."
++	SVNSERVE_PID="$(cat "$SVNSERVE_PIDFILE")"
++	if test -n "$SVNSERVE_PID"
++	then
++		kill "$SVNSERVE_PID" 2>/dev/null
++	fi
+ }
+ 
+ prepare_utf8_locale () {
+diff --git a/t/t9113-git-svn-dcommit-new-file.sh b/t/t9113-git-svn-dcommit-new-file.sh
+index e8479cec7a..5925891f5d 100755
+--- a/t/t9113-git-svn-dcommit-new-file.sh
++++ b/t/t9113-git-svn-dcommit-new-file.sh
+@@ -28,7 +28,6 @@ test_expect_success 'create files in new directory with dcommit' "
+ 	echo hello > git-new-dir/world &&
+ 	git update-index --add git-new-dir/world &&
+ 	git commit -m hello &&
+-	start_svnserve &&
+ 	git svn dcommit
+ 	"
+ 
diff --git a/SOURCES/git-2.27.0-core-crypto-hmac.patch b/SOURCES/git-2.27.0-core-crypto-hmac.patch
deleted file mode 100644
index c99ced2..0000000
--- a/SOURCES/git-2.27.0-core-crypto-hmac.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-diff -ur a/builtin/receive-pack.c b/builtin/receive-pack.c
---- a/builtin/receive-pack.c	2020-06-01 17:49:27.000000000 +0200
-+++ b/builtin/receive-pack.c	2020-06-15 15:28:48.149268576 +0200
-@@ -29,6 +29,8 @@
- #include "commit-reach.h"
- #include "worktree.h"
- #include "shallow.h"
-+#include <openssl/hmac.h>	
-+#include <openssl/evp.h>
- 
- static const char * const receive_pack_usage[] = {
- 	N_("git receive-pack <git-dir>"),
-@@ -419,43 +421,11 @@
- 	return 0;
- }
- 
--static void hmac_hash(unsigned char *out,
-+static inline void hmac_hash(unsigned char *out,
- 		      const char *key_in, size_t key_len,
- 		      const char *text, size_t text_len)
- {
--	unsigned char key[GIT_MAX_BLKSZ];
--	unsigned char k_ipad[GIT_MAX_BLKSZ];
--	unsigned char k_opad[GIT_MAX_BLKSZ];
--	int i;
--	git_hash_ctx ctx;
--
--	/* RFC 2104 2. (1) */
--	memset(key, '\0', GIT_MAX_BLKSZ);
--	if (the_hash_algo->blksz < key_len) {
--		the_hash_algo->init_fn(&ctx);
--		the_hash_algo->update_fn(&ctx, key_in, key_len);
--		the_hash_algo->final_fn(key, &ctx);
--	} else {
--		memcpy(key, key_in, key_len);
--	}
--
--	/* RFC 2104 2. (2) & (5) */
--	for (i = 0; i < sizeof(key); i++) {
--		k_ipad[i] = key[i] ^ 0x36;
--		k_opad[i] = key[i] ^ 0x5c;
--	}
--
--	/* RFC 2104 2. (3) & (4) */
--	the_hash_algo->init_fn(&ctx);
--	the_hash_algo->update_fn(&ctx, k_ipad, sizeof(k_ipad));
--	the_hash_algo->update_fn(&ctx, text, text_len);
--	the_hash_algo->final_fn(out, &ctx);
--
--	/* RFC 2104 2. (6) & (7) */
--	the_hash_algo->init_fn(&ctx);
--	the_hash_algo->update_fn(&ctx, k_opad, sizeof(k_opad));
--	the_hash_algo->update_fn(&ctx, out, the_hash_algo->rawsz);
--	the_hash_algo->final_fn(out, &ctx);
-+	HMAC(EVP_sha1(), key_in, key_len, text, text_len, out, NULL);
- }
- 
- static char *prepare_push_cert_nonce(const char *path, timestamp_t stamp)
-diff -ur a/Makefile b/Makefile
---- a/Makefile	2020-06-01 17:49:27.000000000 +0200
-+++ b/Makefile	2020-06-15 15:00:45.212758547 +0200
-@@ -1830,6 +1830,8 @@
- 	BASIC_CFLAGS += -DHAVE_GETDELIM
- endif
- 
-+EXTLIBS += -lcrypto
-+
- ifneq ($(PROCFS_EXECUTABLE_PATH),)
- 	procfs_executable_path_SQ = $(subst ','\'',$(PROCFS_EXECUTABLE_PATH))
- 	BASIC_CFLAGS += '-DPROCFS_EXECUTABLE_PATH="$(procfs_executable_path_SQ)"'
diff --git a/SOURCES/git-2.31.1.tar.sign b/SOURCES/git-2.31.1.tar.sign
deleted file mode 100644
index a7b42c1..0000000
Binary files a/SOURCES/git-2.31.1.tar.sign and /dev/null differ
diff --git a/SOURCES/git-2.38.1-core-crypto-hmac.patch b/SOURCES/git-2.38.1-core-crypto-hmac.patch
new file mode 100644
index 0000000..b908ced
--- /dev/null
+++ b/SOURCES/git-2.38.1-core-crypto-hmac.patch
@@ -0,0 +1,70 @@
+diff -ur a/builtin/receive-pack.c b/builtin/receive-pack.c
+--- a/builtin/receive-pack.c	2022-10-07 06:48:26.000000000 +0200
++++ b/builtin/receive-pack.c	2022-11-21 16:34:02.417278135 +0100
+@@ -30,6 +30,8 @@
+ #include "commit-reach.h"
+ #include "worktree.h"
+ #include "shallow.h"
++#include <openssl/hmac.h>	
++#include <openssl/evp.h>
+ 
+ static const char * const receive_pack_usage[] = {
+ 	N_("git receive-pack <git-dir>"),
+@@ -528,43 +530,11 @@
+ 	return 0;
+ }
+ 
+-static void hmac_hash(unsigned char *out,
++static inline void hmac_hash(unsigned char *out,
+ 		      const char *key_in, size_t key_len,
+ 		      const char *text, size_t text_len)
+ {
+-	unsigned char key[GIT_MAX_BLKSZ];
+-	unsigned char k_ipad[GIT_MAX_BLKSZ];
+-	unsigned char k_opad[GIT_MAX_BLKSZ];
+-	int i;
+-	git_hash_ctx ctx;
+-
+-	/* RFC 2104 2. (1) */
+-	memset(key, '\0', GIT_MAX_BLKSZ);
+-	if (the_hash_algo->blksz < key_len) {
+-		the_hash_algo->init_fn(&ctx);
+-		the_hash_algo->update_fn(&ctx, key_in, key_len);
+-		the_hash_algo->final_fn(key, &ctx);
+-	} else {
+-		memcpy(key, key_in, key_len);
+-	}
+-
+-	/* RFC 2104 2. (2) & (5) */
+-	for (i = 0; i < sizeof(key); i++) {
+-		k_ipad[i] = key[i] ^ 0x36;
+-		k_opad[i] = key[i] ^ 0x5c;
+-	}
+-
+-	/* RFC 2104 2. (3) & (4) */
+-	the_hash_algo->init_fn(&ctx);
+-	the_hash_algo->update_fn(&ctx, k_ipad, sizeof(k_ipad));
+-	the_hash_algo->update_fn(&ctx, text, text_len);
+-	the_hash_algo->final_fn(out, &ctx);
+-
+-	/* RFC 2104 2. (6) & (7) */
+-	the_hash_algo->init_fn(&ctx);
+-	the_hash_algo->update_fn(&ctx, k_opad, sizeof(k_opad));
+-	the_hash_algo->update_fn(&ctx, out, the_hash_algo->rawsz);
+-	the_hash_algo->final_fn(out, &ctx);
++	HMAC(EVP_sha1(), key_in, key_len, text, text_len, out, NULL);
+ }
+ 
+ static char *prepare_push_cert_nonce(const char *path, timestamp_t stamp)
+diff -ur a/Makefile b/Makefile
+--- a/Makefile	2022-10-07 06:48:26.000000000 +0200
++++ b/Makefile	2022-11-21 16:35:56.986792752 +0100
+@@ -2008,6 +2008,8 @@
+ 	EXTLIBS += -lcrypto -lssl
+ endif
+ 
++EXTLIBS += -lcrypto
++
+ ifneq ($(PROCFS_EXECUTABLE_PATH),)
+ 	procfs_executable_path_SQ = $(subst ','\'',$(PROCFS_EXECUTABLE_PATH))
+ 	BASIC_CFLAGS += '-DPROCFS_EXECUTABLE_PATH="$(procfs_executable_path_SQ)"'
diff --git a/SOURCES/git-2.39.1.tar.sign b/SOURCES/git-2.39.1.tar.sign
new file mode 100644
index 0000000..e6ed440
Binary files /dev/null and b/SOURCES/git-2.39.1.tar.sign differ
diff --git a/SPECS/git.spec b/SPECS/git.spec
index ef70075..dd3b13e 100644
--- a/SPECS/git.spec
+++ b/SPECS/git.spec
@@ -92,12 +92,15 @@
 %global build_ldflags       -Wl,-z,relro -Wl,-z,now
 %endif
 
+# Set path to the package-notes linker script
+%global _package_note_file  %{_builddir}/%{name}-%{version}/.package_note-%{name}-%{version}-%{release}.%{_arch}.ld
+
 # Define for release candidates
 #global rcrev   .rc0
 
 Name:           git
-Version:        2.31.1
-Release:        2%{?rcrev}%{?dist}.2
+Version:        2.39.1
+Release:        1%{?rcrev}%{?dist}
 Summary:        Fast Version Control System
 License:        GPLv2
 URL:            https://git-scm.com/
@@ -129,7 +132,17 @@ Source99:       print-failed-test-output
 # https://bugzilla.redhat.com/490602
 Patch0:         git-cvsimport-Ignore-cvsps-2.2b1-Branches-output.patch
 # https://bugzilla.redhat.com/1956345
-Patch1:         git-2.27.0-core-crypto-hmac.patch
+Patch1:         git-2.38.1-core-crypto-hmac.patch
+
+# https://bugzilla.redhat.com/2114531
+# tests: try harder to find open ports for apache, git, and svn
+#
+# https://github.com/tmzullinger/git/commit/aedeaaf788
+Patch2:         0001-t-lib-httpd-try-harder-to-find-a-port-for-apache.patch
+# https://github.com/tmzullinger/git/commit/16750d024c
+Patch3:         0002-t-lib-git-daemon-try-harder-to-find-a-port.patch
+# https://github.com/tmzullinger/git/commit/aa5105dc11
+Patch4:         0003-t-lib-git-svn-try-harder-to-find-a-port.patch
 
 %if %{with docs}
 # pod2man is needed to build Git.3pm
@@ -141,6 +154,7 @@ BuildRequires:  rubygem-asciidoctor
 BuildRequires:  asciidoc >= 8.4.1
 %endif
 # endif with asciidoctor
+BuildRequires:  perl(File::Compare)
 BuildRequires:  xmlto
 %if %{with linkcheck}
 BuildRequires:  linkchecker
@@ -204,6 +218,8 @@ BuildRequires:  acl
 %if 0%{?fedora} >= 27 || 0%{?rhel} > 7
 # Needed by t5540-http-push-webdav.sh
 BuildRequires: apr-util-bdb
+# Needed by t5559-http-fetch-smart-http2.sh
+BuildRequires: mod_http2 
 %endif
 # endif fedora >= 27
 BuildRequires:  bash
@@ -419,7 +435,22 @@ Summary:        Git tools for sending patches via email
 BuildArch:      noarch
 Requires:       git = %{version}-%{release}
 Requires:       perl(Authen::SASL)
+Requires:       perl(Cwd)
+Requires:       perl(File::Spec)
+Requires:       perl(File::Spec::Functions)
+Requires:       perl(File::Temp)
+Requires:       perl(IO::Socket::SSL)
+Requires:       perl(Mail::Address)
+Requires:       perl(MIME::Base64)
+Requires:       perl(MIME::QuotedPrint)
+Requires:       perl(Net::Domain)
+Requires:       perl(Net::SMTP)
 Requires:       perl(Net::SMTP::SSL)
+Requires:       perl(POSIX)
+Requires:       perl(Sys::Hostname)
+Requires:       perl(Term::ANSIColor)
+Requires:       perl(Term::ReadLine)
+Requires:       perl(Text::ParseWords)
 %description email
 %{summary}.
 
@@ -639,25 +670,17 @@ export SOURCE_DATE_EPOCH=$(date -r version +%%s 2>/dev/null)
 # Fix shebang in a few places to silence rpmlint complaints
 %if %{with python2}
 sed -i -e '1s@#! */usr/bin/env python$@#!%{__python2}@' \
-    contrib/fast-import/import-zips.py \
-    contrib/hooks/multimail/git_multimail.py \
-    contrib/hooks/multimail/migrate-mailhook-config \
-    contrib/hooks/multimail/post-receive.example
+    contrib/fast-import/import-zips.py
 %else
 # Remove contrib/fast-import/import-zips.py which requires python2.
 rm -rf contrib/fast-import/import-zips.py
 %endif
 # endif with python2
 
-# The multimail hook is installed with git.  Use python3 to avoid an
-# unnecessary python2 dependency, if possible.  Also fix contrib/hg-to-git
-# while here.
+# Use python3 to avoid an unnecessary python2 dependency, if possible.
 %if %{with python3}
 sed -i -e '1s@#!\( */usr/bin/env python\|%{__python2}\)$@#!%{__python3}@' \
-    contrib/hg-to-git/hg-to-git.py \
-    contrib/hooks/multimail/git_multimail.py \
-    contrib/hooks/multimail/migrate-mailhook-config \
-    contrib/hooks/multimail/post-receive.example
+    contrib/hg-to-git/hg-to-git.py
 %endif
 # endif with python3
 
@@ -702,6 +725,9 @@ install -Dpm 0755 contrib/diff-highlight/diff-highlight \
     %{buildroot}%{_datadir}/git-core/contrib/diff-highlight
 rm -rf contrib/diff-highlight/{Makefile,diff-highlight,*.perl,t}
 
+# Remove contrib/scalar to avoid cruft in the git-core-doc docdir
+rm -rf contrib/scalar
+
 # Clean up contrib/subtree to avoid cruft in the git-core-doc docdir
 rm -rf contrib/subtree/{INSTALL,Makefile,git-subtree*,t}
 
@@ -765,9 +791,6 @@ mkdir -p %{buildroot}%{_datadir}/git-core/contrib/completion
 install -pm 644 contrib/completion/git-completion.tcsh \
     %{buildroot}%{_datadir}/git-core/contrib/completion/
 
-# Drop .py extension from git_multimail to avoid byte-compiling
-mv contrib/hooks/multimail/git_multimail{.py,}
-
 # Move contrib/hooks out of %%docdir
 mkdir -p %{buildroot}%{_datadir}/git-core/contrib
 mv contrib/hooks %{buildroot}%{_datadir}/git-core/contrib
@@ -855,8 +878,11 @@ find %{buildroot}%{_pkgdocdir} -name "*.html" -print0 | xargs -r0 linkchecker
 %endif
 # endif with docs && with linkcheck
 
+# t5559-http-fetch-smart-http2 runs t5551-http-fetch-smart with
+# HTTP_PROTO=HTTP/2.  Unfortunately, it fails quite regularly.
+# https://lore.kernel.org/git/Y4fUntdlc1mqwad5@pobox.com/ 
 # Tests to skip on all releases and architectures
-GIT_SKIP_TESTS=""
+GIT_SKIP_TESTS="t5559"
 
 %ifarch aarch64 %{arm} %{power64}
 # Skip tests which fail on aarch64, arm, and ppc
@@ -865,20 +891,39 @@ GIT_SKIP_TESTS=""
 # to limit the maximum stack size.
 # t5541.35 'push 2000 tags over http'
 # t5551.25 'clone the 2,000 tag repo to check OS command line overflow'
-GIT_SKIP_TESTS="$GIT_SKIP_TESTS t5541.35 t5551.25"
+GIT_SKIP_TESTS="$GIT_SKIP_TESTS t5541.37 t5551.25"
 %endif
 # endif aarch64 %%{arm} %%{power64}
 
-%ifarch %{power64}
-# Skip tests which fail on ppc
+%if 0%{?rhel} == 8 && "%{_arch}" == "s390x"
+# Skip tests which fail on s390x on rhel-8
 #
-# t9115-git-svn-dcommit-funky-renames is disabled because it frequently fails.
-# The port it uses (9115) is already in use.  It is unclear if this is
-# due to an issue in the test suite or a conflict with some other process on
-# the build host.  It only appears to occur on ppc-arches.
-GIT_SKIP_TESTS="$GIT_SKIP_TESTS t9115"
-%endif
-# endif %%{power64}
+# The following tests fail on s390x & el8.  The cause should be investigated.
+# However, it's a lower priority since the same tests work consistently on
+# s390x with Fedora and RHEL-9.  The failures seem to originate in t5300.
+#
+# t5300.10 'unpack without delta'
+# t5300.12 'unpack with REF_DELTA'
+# t5300.13 'unpack with REF_DELTA'
+# t5300.14 'unpack with OFS_DELTA'
+# t5300.18 'compare delta flavors'
+# t5300.20 'use packed deltified (REF_DELTA) objects'
+# t5300.23 'verify pack'
+# t5300.24 'verify pack -v'
+# t5300.25 'verify-pack catches mismatched .idx and .pack files'
+# t5300.29 'verify-pack catches a corrupted sum of the index file itself'
+# t5300.30 'build pack index for an existing pack'
+# t5300.45 'make sure index-pack detects the SHA1 collision'
+# t5300.46 'make sure index-pack detects the SHA1 collision (large blobs)'
+# t5303.5  'create corruption in data of first object'
+# t5303.7  '... and loose copy of second object allows for partial recovery'
+# t5303.11 'create corruption in data of first delta'
+# t6300.35 'basic atom: head objectsize:disk'
+# t6300.91 'basic atom: tag objectsize:disk'
+# t6300.92 'basic atom: tag *objectsize:disk'
+GIT_SKIP_TESTS="$GIT_SKIP_TESTS t5300.1[02348] t5300.2[03459] t5300.30 t5300.4[56] t5303.[57] t5303.11 t6300.35 t6300.9[12]"
+%endif
+# endif rhel == 8 && arch == s390x
 
 export GIT_SKIP_TESTS
 
@@ -886,11 +931,13 @@ export GIT_SKIP_TESTS
 export LANG=en_US.UTF-8
 
 # Explicitly enable tests which may be skipped opportunistically
-# (Check for variables set via test_tristate in the test suite)
-export GIT_SVN_TEST_HTTPD=true
+# Check for variables set via test_bool_env in the test suite:
+#   git grep 'test_bool_env GIT_' -- t/{lib-,t[0-9]}*.sh |
+#       sed -r 's/.* (GIT_[^ ]+) .*/\1/g' | sort -u
 export GIT_TEST_GIT_DAEMON=true
 export GIT_TEST_HTTPD=true
 export GIT_TEST_SVNSERVE=true
+export GIT_TEST_SVN_HTTPD=true
 
 # Create tmpdir for test output and update GIT_TEST_OPTS
 # Also update GIT-BUILD-OPTIONS to keep make from any needless rebuilding
@@ -930,7 +977,6 @@ rmdir --ignore-fail-on-non-empty "$testdir"
 %endif
 # endif with emacs && emacs_filesystem
 %{_datadir}/git-core/contrib/diff-highlight
-%{_datadir}/git-core/contrib/hooks/multimail
 %{_datadir}/git-core/contrib/hooks/update-paranoid
 %{_datadir}/git-core/contrib/hooks/setgitperms.perl
 %{_datadir}/git-core/templates/hooks/fsmonitor-watchman.sample
@@ -947,7 +993,6 @@ rmdir --ignore-fail-on-non-empty "$testdir"
 %license COPYING
 # exclude is best way here because of troubles with symlinks inside git-core/
 %exclude %{_datadir}/git-core/contrib/diff-highlight
-%exclude %{_datadir}/git-core/contrib/hooks/multimail
 %exclude %{_datadir}/git-core/contrib/hooks/update-paranoid
 %exclude %{_datadir}/git-core/contrib/hooks/setgitperms.perl
 %exclude %{_datadir}/git-core/templates/hooks/fsmonitor-watchman.sample
@@ -1072,14 +1117,29 @@ rmdir --ignore-fail-on-non-empty "$testdir"
 %{?with_docs:%{_pkgdocdir}/git-svn.html}
 
 %changelog
+* Thu Jan 19 2023 Ondřej Pohořelský <opohorel@redhat.com> - 2.39.1-1
+- Update to 2.39.1
+- Resolves: #2162070
+
+* Wed Dec 14 2022 Ondřej Pohořelský <opohorel@redhat.com> - 2.39.0-2
+- Remove perl(Email::Valid) require from git-email
+- Related: #2139379
+
+* Tue Dec 13 2022 Ondřej Pohořelský <opohorel@redhat.com> - 2.39.0-1
+- Update to 2.39.0
+- Related: #2139379
+
+* Wed Dec 07 2022 Ondřej Pohořelský <opohorel@redhat.com> - 2.38.1-1
+- Update to 2.38.1
+- Resolves: #2139379
+
 * Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 2.31.1-2.2
 - Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
   Related: rhbz#1991688
 
 * Tue Jun 15 2021 Mohan Boddu <mboddu@redhat.com> - 2.31.1-2.1
 - Rebuilt for RHEL 9 BETA for openssl 3.0
-
-Related: rhbz#1971065
+  Related: rhbz#1971065
 
 * Mon May 03 2021 Ondřej Pohořelský <opohorel@redhat.com> - 2.31.1-2
 - Use HMAC from libcrypto instead of git's implementation