[RFC PATCH v1] tools: update-subtree.sh improve user experience
E Shattow
e at freeshell.de
Wed Oct 15 10:38:34 CEST 2025
Makeover of the script:
- Usage now explains at each step what is expected from the user.
- Default branch name is no longer hard-coded and is queried when omitted.
- Additional operations 'update' and 'log' close the logic gap between
expecting the user to provide a commit id and where from this commit id
should be obtained.
- Use 'set -x' context to show git invocation where appropriate
- Sort options for usage output
- 'pick' operation detects merge commit id and displays suggested commits
Additionally the LwIP remote is now using the Savannah mirror system:
https://lists.gnu.org/archive/html/savannah-users/2025-05/msg00002.html
Signed-off-by: E Shattow <e at freeshell.de>
---
TODO v1:
- 'update dts <tag>' should attempt to substitute tag with the branch containing the suspected tag. How to do this?
- 'log dts <tag>' should attempt to substitute tag with the branch containing the suspected tag. How to do this?
- list branch names where branch name given is invalid or possibly as an info operation i.e. "see info operation for list of tags and/or/branches". How to do this?
- 'pull dts invalid' takes awhile to fail, maybe pre-check if the tag exists before doing the pull action but only if that would be faster to fail. How to do this?
- behavior of operations when disconnected from network is not well-characterized, yet.
I think this script can add value by making it give helpful output and guide the user to a successful outcome. In most situations it should not be necessary to read documentation to use the script properly.
-E
---
tools/update-subtree.sh | 187 +++++++++++++++++++++++++++++-----------
1 file changed, 138 insertions(+), 49 deletions(-)
diff --git a/tools/update-subtree.sh b/tools/update-subtree.sh
index 536b3318573..e0c59330f16 100755
--- a/tools/update-subtree.sh
+++ b/tools/update-subtree.sh
@@ -1,42 +1,39 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0+
#
-# Copyright (c) 2024 Linaro Limited
+# update-subtree.sh: Pull changes from subtree repo into U-Boot
#
-# Usage: from the top level U-Boot source tree, run:
-# $ ./tools/update-subtree.sh pull <subtree-name> <release-tag>
-# Or:
-# $ ./tools/update-subtree.sh pick <subtree-name> <commit-id>
+# Copyright (c) 2024 Linaro Limited
#
-# The script will pull changes from subtree repo into U-Boot.
-# It will automatically create a squash/merge commit listing the commits
-# imported.
-
-set -e
-
-print_usage() {
- echo "usage: $0 <op> <subtree-name> <ref>"
- echo " <op> pull or pick"
- echo " <subtree-name> mbedtls or dts or lwip"
- echo " <ref> release tag [pull] or commit id [pick]"
-}
-
-if [ $# -ne 3 ]; then
- print_usage
- exit 1
-fi
op=$1
subtree_name=$2
ref=$3
+print_usage() {
+ echo "usage: $0 <op> <subtree> [ref]"
+ echo " op update fetch <subtree> for [ref] branch"
+ echo " add remote <subtree> as needed"
+ echo " query default branch from remote if omitted"
+ echo " log view log for <subtree>/[ref] branch"
+ echo " add remote <subtree> as needed"
+ echo " query default branch from remote if omitted"
+ echo " pick create cherry-pick commit into U-Boot with"
+ echo " <subtree> for <ref> commit-id"
+ echo " pull create squash/merge commit into U-Boot with"
+ echo " <subtree> for <ref> release-tag"
+ echo " add remote <subtree> as needed"
+ echo ""
+ echo " subtree dts device tree definitions extracted from the"
+ echo " Linux kernel source tree"
+ echo " lwip A Lightweight TCPIP stack"
+ echo " mbedtls C library that implements cryptographic"
+ echo " primatives, X.509 certificate manipulation"
+ echo " and the SSL/TLS and DTLS protocols"
+}
+
set_params() {
case "$subtree_name" in
- mbedtls)
- path=lib/mbedtls/external/mbedtls
- repo_url=https://github.com/Mbed-TLS/mbedtls.git
- remote_name="mbedtls_upstream"
- ;;
dts)
path=dts/upstream
repo_url=https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git
@@ -44,9 +41,14 @@ set_params() {
;;
lwip)
path=lib/lwip/lwip
- repo_url=https://git.savannah.gnu.org/git/lwip.git
+ repo_url=https://https.git.savannah.gnu.org/git/lwip.git
remote_name="lwip_upstream"
;;
+ mbedtls)
+ path=lib/mbedtls/external/mbedtls
+ repo_url=https://github.com/Mbed-TLS/mbedtls.git
+ remote_name="mbedtls_upstream"
+ ;;
*)
echo "Invalid subtree name: $subtree_name"
print_usage
@@ -54,32 +56,119 @@ set_params() {
esac
}
-set_params
-
-merge_commit_msg=$(cat << EOF
-Subtree merge tag '$ref' of $subtree_name repo [1] into $path
+set_remote() {
+ if [ -z "$(git remote get-url $remote_name 2>/dev/null)" ]; then
+ (set -x
+ git remote add $remote_name $repo_url
+ )
+ fi
+}
-[1] $repo_url
-EOF
-)
+set_branch() {
+ if [ -z "$ref" ]; then
+ echo -n "Branch name omitted, query remote for default branch name... "
+ ref=$(git remote show $remote_name | grep -Po '(?<=HEAD branch:\s).*')
+ if [ $? -eq 0 ]; then
+ echo "$ref"
+ else
+ echo "Failed to query."
+ exit 1
+ fi
+ fi
+}
-remote_add_and_fetch() {
- if [ -z "$(git remote get-url $remote_name 2>/dev/null)" ]; then
- echo "Warning: Script automatically adds new git remote via:"
- echo " git remote add $remote_name \\"
- echo " $repo_url"
- git remote add $remote_name $repo_url
+check_branch() {
+ (set -x
+ git show-ref --quiet "$remote_name"/"$ref"
+ )
+ if [ $? -ne 0 ] ; then
+ echo "TODO: lookup remote to determine if branch exists there"
+ echo "No such branch $remote_name/$ref"
+ echo "TODO: resolve if $ref is a tag and what branch it is from"
+ echo "Did you run \"$0 update $subtree_name $ref\" ?"
+ exit 1
fi
- git fetch $remote_name master
}
-if [ "$op" = "pull" ]; then
- remote_add_and_fetch
- git subtree pull --prefix $path $remote_name "$ref" --squash -m "$merge_commit_msg"
-elif [ "$op" = "pick" ]; then
- remote_add_and_fetch
- git cherry-pick -x --strategy=subtree -Xsubtree=$path/ "$ref"
-else
+if [ $# -lt 1 ]; then
print_usage
exit 1
fi
+
+case "$op" in
+ update)
+ if [ $# -lt 2 ]; then
+ print_usage
+ exit 1
+ fi
+ set_params
+ set_remote
+ set_branch
+ (set -x
+ git fetch $remote_name $ref
+ )
+ ;;
+ log)
+ if [ $# -lt 2 ]; then
+ print_usage
+ exit 1
+ fi
+ set_params
+ set_remote
+ set_branch
+ check_branch
+ (set -x
+ git log $remote_name/$ref
+ )
+ ;;
+ pick)
+ if [ $# -lt 3 ]; then
+ print_usage
+ exit 1
+ fi
+ set_params
+ is_merge=$(set -x
+ git rev-list --no-walk --count --merges "$ref" 2>/dev/null
+ )
+ if [ $? -ne 0 ]; then
+ echo "Merge commit detection in pick failed for $ref."
+ echo "TODO: resolve if $ref exists in remote to guide suggestion."
+ echo "Did you run \"$0 update $subtree_name\" ?"
+ exit 1
+ fi
+ if [ $(($is_merge)) -gt 0 ]; then
+ echo "Merge commits are not allowed for pick operation."
+ echo "Did you want to pick one of the following commit-id instead?"
+ (set -x
+ git log --oneline "$ref"^1.."$ref"^2
+ )
+ exit 1
+ fi
+ (set -x
+ git cherry-pick -x --strategy=subtree -Xsubtree=$path/ "$ref"
+ )
+ ;;
+ pull)
+ if [ $# -lt 3 ]; then
+ print_usage
+ exit 1
+ fi
+ set_params
+ set_remote
+ # HEREDOC with tabs indent and syntax to ignore tabs:
+ merge_msg=$(cat <<-EOF
+ Subtree merge tag '$ref' of $subtree_name repo [1] into $path
+
+ [1] $repo_url
+ EOF
+ )
+ (set -x
+ git subtree pull --prefix $path $remote_name "$ref" --squash -m "$merge_msg"
+ )
+ ;;
+ *)
+ echo "Invalid op: $op"
+ print_usage
+ exit 1
+ ;;
+esac
base-commit: b1cc9a53d7ba8b85e77980417242420889273e86
--
2.50.0
More information about the U-Boot
mailing list