git: 0c6096749a3b - stable/15 - build: Support got

From: Colin Percival <cperciva_at_FreeBSD.org>
Date: Wed, 28 Oct 2026 05:52:31 UTC
The branch stable/15 has been updated by cperciva:

URL: https://cgit.FreeBSD.org/src/commit/?id=0c6096749a3be01a63dec56593cbce8b9f48f315

commit 0c6096749a3be01a63dec56593cbce8b9f48f315
Author:     Colin Percival <cperciva@FreeBSD.org>
AuthorDate: 2026-10-14 01:12:07 +0000
Commit:     Colin Percival <cperciva@FreeBSD.org>
CommitDate: 2026-10-28 01:07:03 +0000

    build: Support got
    
    Add code for using got(1), matching how git(1) is currently used:
    1. Determining the git branch,
    2. Determining the checked-out hash,
    3. Determining the commit count,
    4. Determining the timestamp of the most recent commit,
    5. Determining if the tree is "dirty",
    6. Generating lists of files for the src and src-sys packages, and
    7. Excluding .got directories from src.txz and ports.txz.
    
    The release engineer hopes to use this functionality in release builds,
    since got's minimalism makes it a far more manageable build tool than
    git.
    
    Reviewed by:    naddy
    MFC after:      1 week
    Sponsored by:   Amazon
    Differential Revision:  https://reviews.freebsd.org/D60606
    
    (cherry picked from commit a8be899289303c9f83813cfd96d1a62abba09685)
---
 Makefile.inc1         | 31 +++++++++++++++++++++++++++++++
 release/Makefile      |  4 ++--
 release/Makefile.inc1 | 28 +++++++++++++++++++++++++++-
 sys/conf/newvers.sh   | 35 +++++++++++++++++++++++++++++++++--
 4 files changed, 93 insertions(+), 5 deletions(-)

diff --git a/Makefile.inc1 b/Makefile.inc1
index c6501016729a..2fbbea26a3af 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -530,6 +530,15 @@ GIT_CMD=   ${_P}/git
 .export GIT_CMD
 .endif
 
+.if !defined(GOT_CMD) || empty(GOT_CMD)
+. for _P in /usr/bin /usr/local/bin
+.  if exists(${_P}/got)
+GOT_CMD=   ${_P}/got
+.  endif
+. endfor
+.export GOT_CMD
+.endif
+
 .if !defined(OSRELDATE)
 .if exists(/usr/include/osreldate.h)
 OSRELDATE!=	awk '/^\#define[[:space:]]*__FreeBSD_version/ { print $$3 }' \
@@ -597,6 +606,8 @@ PKG_WORKERS_COUNT?=	1
 .if !defined(PKG_TIMESTAMP)
 .if !empty(GIT_CMD) && exists(${GIT_CMD}) && exists(${SRCDIR}/.git)
 SOURCE_DATE_EPOCH!=	${GIT_CMD} -C ${SRCDIR} show -s --format=%ct HEAD
+.elif !empty(GOT_CMD) && exists(${GOT_CMD}) && exists(${SRCDIR}/.got)
+SOURCE_DATE_EPOCH!=	( cd ${SRCDIR} && ${GOT_CMD} cat HEAD | awk '$$1 == "committer" { print $$(NF-1); exit }' )
 .else
 TIMEEPOCHNOW=		%s
 SOURCE_DATE_EPOCH=	${TIMEEPOCHNOW:gmtime}
@@ -2207,11 +2218,21 @@ create-packages: .PHONY create-packages-world create-packages-kernel create-pack
 
 create-source-src-package: _pkgbootstrap .PHONY
 	rm -f ${SSTAGEDIR}/src.plist 2>/dev/null || :
+.if ( !empty(GIT_CMD) && exists(${GIT_CMD}) && exists(${SRCDIR}/.git) ) || \
+    ( !empty(GOT_CMD) && exists(${GOT_CMD}) && exists(${SRCDIR}/.got) )
 .if !empty(GIT_CMD) && exists(${GIT_CMD}) && exists(${SRCDIR}/.git)
 	@cd ${SRCDIR}; \
 		( echo "@override_prefix /usr/src" ;  \
 		${GIT_CMD} ls-files --recurse-submodules ":!:sys/" ) \
 		> ${SSTAGEDIR}/src.plist
+.else
+	@cd ${SRCDIR}; \
+		( echo "@override_prefix /usr/src" ;  \
+		${GOT_CMD} tree -R | \
+		    awk '/^sys\// { next } { sub(/ -> .*/, "") } /\/$/ { next } { sub(/[*@$]$/, "") } { print }' | \
+		    sort ) \
+		> ${SSTAGEDIR}/src.plist
+.endif
 	flua ${SRCDIR}/release/packages/generate-ucl.lua \
 		PKGNAME "src" \
 		PKGGENNAME "src" \
@@ -2233,11 +2254,21 @@ create-source-src-package: _pkgbootstrap .PHONY
 
 create-source-src-sys-package: _pkgbootstrap .PHONY
 	rm -f ${SSTAGEDIR}/src-sys.plist 2>/dev/null || :
+.if ( !empty(GIT_CMD) && exists(${GIT_CMD}) && exists(${SRCDIR}/.git) ) || \
+    ( !empty(GOT_CMD) && exists(${GOT_CMD}) && exists(${SRCDIR}/.got) )
 .if !empty(GIT_CMD) && exists(${GIT_CMD}) && exists(${SRCDIR}/.git)
 	@cd ${SRCDIR}; \
 		( echo "@override_prefix /usr/src" ; \
 		${GIT_CMD} ls-files --recurse-submodules "sys/" ) \
 		> ${SSTAGEDIR}/src-sys.plist
+.else
+	@cd ${SRCDIR}; \
+		( echo "@override_prefix /usr/src" ;  \
+		${GOT_CMD} tree -R | \
+		    awk '!/^sys\// { next } { sub(/ -> .*/, "") } /\/$/ { next } { sub(/[*@$]$/, "") } { print }' | \
+		    sort ) \
+		> ${SSTAGEDIR}/src-sys.plist
+.endif
 	flua ${SRCDIR}/release/packages/generate-ucl.lua \
 		PKGNAME "src-sys" \
 		PKGGENNAME "src-sys" \
diff --git a/release/Makefile b/release/Makefile
index c6112faff947..220dd84178d3 100644
--- a/release/Makefile
+++ b/release/Makefile
@@ -186,7 +186,7 @@ src.txz:
 	ln -s ${WORLDDIR} ${DISTDIR}/usr/src
 	( cd ${DISTDIR} && ${TAR_XZ_CMD} -cLvf ${.OBJDIR}/src.txz \
 	    --exclude .svn --exclude .zfs \
-	    --exclude .git --exclude @ --exclude usr/src/release/dist \
+	    --exclude .git --exclude .got --exclude @ --exclude usr/src/release/dist \
 	    --exclude usr/src/release/obj usr/src )
 
 ports.txz:
@@ -194,7 +194,7 @@ ports.txz:
 	rm -f ${DISTDIR}/usr/ports
 	ln -s ${PORTSDIR} ${DISTDIR}/usr/ports
 	( cd ${DISTDIR} && ${TAR_XZ_CMD} -cLvf ${.OBJDIR}/ports.txz \
-	    --exclude .git --exclude .svn \
+	    --exclude .git --exclude .got --exclude .svn \
 	    --exclude usr/ports/distfiles --exclude usr/ports/packages \
 	    --exclude 'usr/ports/INDEX*' --exclude work usr/ports )
 
diff --git a/release/Makefile.inc1 b/release/Makefile.inc1
index 569b72df5106..df00a24603c8 100644
--- a/release/Makefile.inc1
+++ b/release/Makefile.inc1
@@ -7,7 +7,16 @@ GIT_CMD=   ${_P}/git
 . endif
 .endfor
 
-.if !empty(GIT_CMD) && exists(${GIT_CMD})
+# Figure out where the got binary is.
+.for _P in /usr/bin /usr/local/bin
+. if !defined(GOT_CMD) || empty(GOT_CMD)
+.  if exists(${_P}/got)
+GOT_CMD=   ${_P}/got
+.  endif
+. endif
+.endfor
+
+.if !empty(GIT_CMD) && exists(${GIT_CMD}) && exists(${.CURDIR}/../.git)
 # Set the git branch and hash to export where needed.
 . if !defined(GITBRANCH) || empty(GITBRANCH)
 GITBRANCH!=	${GIT_CMD} -C ${.CURDIR} rev-parse --abbrev-ref HEAD 2>/dev/null | sed -e 's/\^\///'
@@ -25,6 +34,23 @@ GITCOUNT!=	${GIT_CMD} -C ${.CURDIR} rev-list --first-parent --count HEAD 2>/dev/
 GITEPOCH!=	${GIT_CMD} -C ${.CURDIR} show -s --format=%ct HEAD 2>/dev/null || true
 . export GITEPOCH
 . endif
+.elif !empty(GOT_CMD) && exists(${GOT_CMD}) && exists(${.CURDIR}/../.got)
+. if !defined(GITBRANCH) || empty(GITBRANCH)
+GITBRANCH!=	( cd ${.CURDIR} && ${GOT_CMD} branch )
+. export GITBRANCH
+. endif
+. if !defined(GITREV) || empty(GITREV)
+GITREV!=	( cd ${.CURDIR} && ${GOT_CMD} info | awk '/^work tree base commit:/ { print $$NF; exit }' | cut -c 1-12 )
+. export GITREV
+. endif
+. if !defined(GITCOUNT) || empty(GITCOUNT)
+GITCOUNT!=	( cd ${.CURDIR} && ${GOT_CMD} log -s | wc -l | tr -d ' ' )
+. export GITCOUNT
+. endif
+. if !defined(GITEPOCH) || empty(GITEPOCH)
+GITEPOCH!=	( cd ${.CURDIR} && ${GOT_CMD} cat HEAD | awk '$$1 == "committer" { print $$(NF-1); exit }' )
+. export GITEPOCH
+. endif
 .else
 GITBRANCH=	nullbranch
 GITREV=		nullhash
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 6180a4a99ab0..dae4cab3f3d1 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -182,6 +182,11 @@ git_tree_modified()
 	! $git_cmd "--work-tree=${VCSTOP}" -c core.checkStat=minimal -c core.fileMode=off diff --quiet
 }
 
+got_tree_modified()
+{
+	( cd ${VCSTOP} && $got_cmd status -S '?m' | grep -q . )
+}
+
 LC_ALL=C; export LC_ALL
 if [ ! -r version ]
 then
@@ -233,6 +238,15 @@ if findvcs .gituprevision; then
 	gituprevision="${VCSTOP}/.gituprevision"
 fi
 
+if findvcs .got; then
+	for dir in /usr/bin /usr/local/bin; do
+		if [ -x "${dir}/got" ] ; then
+			got_cmd="${dir}/got"
+			break
+		fi
+	done
+fi
+
 if findvcs .hg; then
 	for dir in /usr/bin /usr/local/bin; do
 		if [ -x "${dir}/hg" ] ; then
@@ -279,6 +293,23 @@ if [ -n "$git_cmd" ] ; then
 	fi
 fi
 
+if [ -n "$got_cmd" ] ; then
+	got=$(cd ${VCSTOP} && ${got_cmd} info | awk '/^work tree base commit:/ { print $NF; exit }' | cut -c 1-12 )
+	got_cnt=$(cd ${VCSTOP} && ${got_cmd} log -s | wc -l)
+	if [ -n "$got_cnt" ] ; then
+		got="n$(echo ${got_cnt})-${got}"
+	fi
+	got_b=$(cd ${VCSTOP} && ${got_cmd} branch )
+	if [ -n "$got_b" -a "$got_b" != "HEAD" ] ; then
+		got="${got_b}-${got}"
+	fi
+	if got_tree_modified; then
+		got="${got}-dirty"
+		modified=yes
+	fi
+	got=" ${got}"
+fi
+
 if [ -n "$gituprevision" ] ; then
 	gitup=" $(awk -F: '{print $2}' $gituprevision)"
 fi
@@ -297,10 +328,10 @@ fi
 
 [ ${include_metadata} = "if-modified" -a ${modified} = "yes" ] && include_metadata=yes
 if [ ${include_metadata} != "yes" ]; then
-	VERINFO="${VERSION}${svn}${git}${gitup}${hg} ${i}"
+	VERINFO="${VERSION}${svn}${git}${gitup}${got}${hg} ${i}"
 	VERSTR="${VERINFO}\\n"
 else
-	VERINFO="${VERSION} #${v}${svn}${git}${gitup}${hg}: ${t}"
+	VERINFO="${VERSION} #${v}${svn}${git}${gitup}${got}${hg}: ${t}"
 	VERSTR="${VERINFO}\\n    ${u}@${h}:${d}\\n"
 fi