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
This commit is contained in:
Colin Percival committed 2026-10-17 08:50:15 -07:00
1 parent 19a5023e45
commit a8be899289
4 files changed
+93 -5

No files matched your search

+31
View File
@@ -539,6 +539,15 @@ GIT_CMD= ${_P}/git
.export GIT_CMD .export GIT_CMD
.endif .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 !defined(OSRELDATE)
.if exists(/usr/include/osreldate.h) .if exists(/usr/include/osreldate.h)
OSRELDATE!= awk '/^\#define[[:space:]]*__FreeBSD_version/ { print $$3 }' \ OSRELDATE!= awk '/^\#define[[:space:]]*__FreeBSD_version/ { print $$3 }' \
@@ -606,6 +615,8 @@ PKG_WORKERS_COUNT?= 1
.if !defined(PKG_TIMESTAMP) .if !defined(PKG_TIMESTAMP)
.if !empty(GIT_CMD) && exists(${GIT_CMD}) && exists(${SRCDIR}/.git) .if !empty(GIT_CMD) && exists(${GIT_CMD}) && exists(${SRCDIR}/.git)
SOURCE_DATE_EPOCH!= ${GIT_CMD} -C ${SRCDIR} show -s --format=%ct HEAD 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 .else
TIMEEPOCHNOW= %s TIMEEPOCHNOW= %s
SOURCE_DATE_EPOCH= ${TIMEEPOCHNOW:gmtime} SOURCE_DATE_EPOCH= ${TIMEEPOCHNOW:gmtime}
@@ -2216,11 +2227,21 @@ create-packages: .PHONY create-packages-world create-packages-kernel create-pack
create-source-src-package: _pkgbootstrap .PHONY create-source-src-package: _pkgbootstrap .PHONY
rm -f ${SSTAGEDIR}/src.plist rm -f ${SSTAGEDIR}/src.plist
.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) .if !empty(GIT_CMD) && exists(${GIT_CMD}) && exists(${SRCDIR}/.git)
@cd ${SRCDIR}; \ @cd ${SRCDIR}; \
( echo "@override_prefix /usr/src" ; \ ( echo "@override_prefix /usr/src" ; \
${GIT_CMD} ls-files --recurse-submodules ":!:sys/" ) \ ${GIT_CMD} ls-files --recurse-submodules ":!:sys/" ) \
> ${SSTAGEDIR}/src.plist > ${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 \ flua ${SRCDIR}/release/packages/generate-ucl.lua \
PKGNAME "src" \ PKGNAME "src" \
PKGGENNAME "src" \ PKGGENNAME "src" \
@@ -2242,11 +2263,21 @@ create-source-src-package: _pkgbootstrap .PHONY
create-source-src-sys-package: _pkgbootstrap .PHONY create-source-src-sys-package: _pkgbootstrap .PHONY
rm -f ${SSTAGEDIR}/src-sys.plist rm -f ${SSTAGEDIR}/src-sys.plist
.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) .if !empty(GIT_CMD) && exists(${GIT_CMD}) && exists(${SRCDIR}/.git)
@cd ${SRCDIR}; \ @cd ${SRCDIR}; \
( echo "@override_prefix /usr/src" ; \ ( echo "@override_prefix /usr/src" ; \
${GIT_CMD} ls-files --recurse-submodules "sys/" ) \ ${GIT_CMD} ls-files --recurse-submodules "sys/" ) \
> ${SSTAGEDIR}/src-sys.plist > ${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 \ flua ${SRCDIR}/release/packages/generate-ucl.lua \
PKGNAME "src-sys" \ PKGNAME "src-sys" \
PKGGENNAME "src-sys" \ PKGGENNAME "src-sys" \
+2 -2
View File
@@ -186,7 +186,7 @@ src.txz:
ln -s ${WORLDDIR} ${DISTDIR}/usr/src ln -s ${WORLDDIR} ${DISTDIR}/usr/src
( cd ${DISTDIR} && ${TAR_XZ_CMD} -cLvf ${.OBJDIR}/src.txz \ ( cd ${DISTDIR} && ${TAR_XZ_CMD} -cLvf ${.OBJDIR}/src.txz \
--exclude .svn --exclude .zfs \ --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 ) --exclude usr/src/release/obj usr/src )
ports.txz: ports.txz:
@@ -194,7 +194,7 @@ ports.txz:
rm -f ${DISTDIR}/usr/ports rm -f ${DISTDIR}/usr/ports
ln -s ${PORTSDIR} ${DISTDIR}/usr/ports ln -s ${PORTSDIR} ${DISTDIR}/usr/ports
( cd ${DISTDIR} && ${TAR_XZ_CMD} -cLvf ${.OBJDIR}/ports.txz \ ( 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/distfiles --exclude usr/ports/packages \
--exclude 'usr/ports/INDEX*' --exclude work usr/ports ) --exclude 'usr/ports/INDEX*' --exclude work usr/ports )
+27 -1
View File
@@ -7,7 +7,16 @@ GIT_CMD= ${_P}/git
. endif . endif
.endfor .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. # Set the git branch and hash to export where needed.
. if !defined(GITBRANCH) || empty(GITBRANCH) . if !defined(GITBRANCH) || empty(GITBRANCH)
GITBRANCH!= ${GIT_CMD} -C ${.CURDIR} rev-parse --abbrev-ref HEAD 2>/dev/null | sed -e 's/\^\///' 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 GITEPOCH!= ${GIT_CMD} -C ${.CURDIR} show -s --format=%ct HEAD 2>/dev/null || true
. export GITEPOCH . export GITEPOCH
. endif . 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 .else
GITBRANCH= nullbranch GITBRANCH= nullbranch
GITREV= nullhash GITREV= nullhash
+33 -2
View File
@@ -182,6 +182,11 @@ git_tree_modified()
! $git_cmd "--work-tree=${VCSTOP}" -c core.checkStat=minimal -c core.fileMode=off diff --quiet HEAD ! $git_cmd "--work-tree=${VCSTOP}" -c core.checkStat=minimal -c core.fileMode=off diff --quiet HEAD
} }
got_tree_modified()
{
( cd ${VCSTOP} && $got_cmd status -S '?m' | grep -q . )
}
LC_ALL=C; export LC_ALL LC_ALL=C; export LC_ALL
if [ ! -r version ] if [ ! -r version ]
then then
@@ -233,6 +238,15 @@ if findvcs .gituprevision; then
gituprevision="${VCSTOP}/.gituprevision" gituprevision="${VCSTOP}/.gituprevision"
fi 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 if findvcs .hg; then
for dir in /usr/bin /usr/local/bin; do for dir in /usr/bin /usr/local/bin; do
if [ -x "${dir}/hg" ] ; then if [ -x "${dir}/hg" ] ; then
@@ -279,6 +293,23 @@ if [ -n "$git_cmd" ] ; then
fi fi
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 if [ -n "$gituprevision" ] ; then
gitup=" $(awk -F: '{print $2}' $gituprevision)" gitup=" $(awk -F: '{print $2}' $gituprevision)"
fi fi
@@ -297,10 +328,10 @@ fi
[ ${include_metadata} = "if-modified" -a ${modified} = "yes" ] && include_metadata=yes [ ${include_metadata} = "if-modified" -a ${modified} = "yes" ] && include_metadata=yes
if [ ${include_metadata} != "yes" ]; then if [ ${include_metadata} != "yes" ]; then
VERINFO="${VERSION}${svn}${git}${gitup}${hg} ${i}" VERINFO="${VERSION}${svn}${git}${gitup}${got}${hg} ${i}"
VERSTR="${VERINFO}\\n" VERSTR="${VERINFO}\\n"
else 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" VERSTR="${VERINFO}\\n ${u}@${h}:${d}\\n"
fi fi