This is an automated email from the ASF dual-hosted git repository.
mridulpathak pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
The following commit(s) were added to refs/heads/trunk by this push:
new 553f6af7af Improved: Populate plugins/ in linked git worktrees
(OFBIZ-13471) (#1519)
553f6af7af is described below
commit 553f6af7afaa225f4fe0f8b4cc04ae765423e089
Author: Mridul Pathak <[email protected]>
AuthorDate: Fri Jul 31 12:25:05 2026 +0530
Improved: Populate plugins/ in linked git worktrees (OFBIZ-13471) (#1519)
Improved: Populate plugins/ in linked git worktrees (OFBIZ-13471)
plugins/ is gitignored and is itself an independent git repository, so
`git worktree add` never populates it. A fresh linked worktree either
builds silently with zero plugin subprojects, or (if plugins/ happens
to be on the wrong branch) fails with a misleading Gradle Groovy-version
dependency conflict instead of an obvious branch-mismatch error.
Adds setup-worktree-plugins.sh, run once from inside a new worktree: it
creates a linked worktree of the existing plugins/ git repository,
checked out to a branch matching the current worktree -- by exact name
first, then by walking the repo's own branch ancestry to find the
branch it was cut from. Falls back to a detached checkout if that
branch is already checked out elsewhere, and fails loudly rather than
leaving plugins/ half set up.
---
setup-worktree-plugins.sh | 135 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 135 insertions(+)
diff --git a/setup-worktree-plugins.sh b/setup-worktree-plugins.sh
new file mode 100755
index 0000000000..c514af1d56
--- /dev/null
+++ b/setup-worktree-plugins.sh
@@ -0,0 +1,135 @@
+#!/usr/bin/env sh
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Syntax: ./setup-worktree-plugins.sh [plugins-branch]
+#
+# plugins/ is listed in .gitignore and is itself an independent git
+# repository (see pullPluginSource.sh / pullAllPluginsSource.sh). Because
+# it's gitignored, `git worktree add` for this repo does not populate it --
+# a freshly created linked worktree gets no plugins/ directory at all, which
+# later fails the build (missing-plugins-dir builds silently skip all plugin
+# subprojects; a wrong-branch plugins/ instead fails with a misleading
+# Groovy-version dependency conflict).
+#
+# Run this script from inside a linked worktree of *this* repo (i.e. after
+# `git worktree add ../some-path -b some-branch`) to give that worktree a
+# plugins/ checkout on a matching branch, without re-cloning: it adds a
+# linked worktree of the *existing* plugins/ git repository found via the
+# main checkout.
+#
+# The matching plugins/ branch is found by name first, then (for a
+# feature/ticket branch with no plugins/ branch of the same name) by
+# walking this repo's actual branch ancestry to find the branch it was cut
+# from -- no assumption is made about branch-naming conventions.
+
+set -e
+
+if [ -e "plugins" ]; then
+ echo "ERROR: plugins/ already exists here ($(pwd)/plugins) -- refusing to
overwrite it. Remove it first if you want this script to (re)create it." >&2
+ exit 1
+fi
+
+git_common_dir=$(git rev-parse --git-common-dir 2>/dev/null) || {
+ echo "ERROR: not inside a git repository." >&2
+ exit 1
+}
+main_worktree=$(cd "$(dirname "$git_common_dir")" && pwd)
+plugins_repo="$main_worktree/plugins"
+
+if [ ! -e "$plugins_repo/.git" ]; then
+ echo "ERROR: no plugins/ git repository found at $plugins_repo -- expected
the main ofbiz checkout to have a working plugins/ git checkout to branch off
of." >&2
+ exit 1
+fi
+
+branch_exists() {
+ git -C "$plugins_repo" show-ref --verify --quiet "refs/heads/$1" ||
+ git -C "$plugins_repo" show-ref --verify --quiet
"refs/remotes/origin/$1"
+}
+
+ofbiz_branch=$(git branch --show-current)
+plugins_branch=""
+
+if [ -n "$1" ]; then
+ plugins_branch=$1
+ if ! branch_exists "$plugins_branch"; then
+ echo "ERROR: plugins branch '$plugins_branch' not found (checked
refs/heads and refs/remotes/origin in $plugins_repo)." >&2
+ exit 1
+ fi
+elif [ -z "$ofbiz_branch" ]; then
+ echo "ERROR: this worktree is in detached HEAD state, so the matching
plugins branch can't be inferred. Pass it explicitly:
./setup-worktree-plugins.sh <branch>" >&2
+ exit 1
+elif branch_exists "$ofbiz_branch"; then
+ plugins_branch=$ofbiz_branch
+else
+ # No plugins branch shares this worktree's exact branch name -- it's
+ # presumably a feature/ticket branch. Rather than guess from naming
+ # conventions (which vary per team/fork), walk this repo's own branch
+ # ancestry, nearest first, to find the branch it was actually cut from,
+ # and use that name in plugins/ instead. Keep walking further back
+ # (e.g. past an intermediate release branch to trunk) until one of
+ # them has a matching plugins branch.
+ candidates=$(
+ for ref in $(git for-each-ref --format='%(refname:short)' refs/heads
refs/remotes/origin); do
+ if [ "$ref" = "$ofbiz_branch" ] || [ "$ref" =
"origin/$ofbiz_branch" ] || [ "$ref" = "origin/HEAD" ]; then
+ continue
+ fi
+ if git merge-base --is-ancestor "$ref" HEAD 2>/dev/null; then
+ distance=$(git rev-list --count "$ref"..HEAD 2>/dev/null) &&
echo "$distance $ref"
+ fi
+ done | sort -n
+ )
+ old_ifs=$IFS
+ IFS='
+'
+ for line in $candidates; do
+ ref=${line#* }
+ candidate=${ref#origin/}
+ if branch_exists "$candidate"; then
+ plugins_branch=$candidate
+ break
+ fi
+ done
+ IFS=$old_ifs
+fi
+
+if [ -z "$plugins_branch" ]; then
+ echo "ERROR: could not determine a plugins/ branch matching ofbiz branch
'$ofbiz_branch'." >&2
+ echo "Pass one explicitly: ./setup-worktree-plugins.sh <branch>" >&2
+ echo "Branches available in $plugins_repo:" >&2
+ git -C "$plugins_repo" branch -a --format=' %(refname:short)' >&2
+ exit 1
+fi
+
+echo "Setting up plugins/ as a linked worktree of $plugins_repo on branch
'$plugins_branch'..."
+
+# If that branch is already checked out elsewhere (e.g. in the main
+# checkout this was branched from), git refuses a second worktree on the
+# same branch -- fall back to a detached checkout of the same commit,
+# which is fine for building since we only need matching source, not to
+# commit from inside this worktree's plugins/.
+if worktree_add_output=$(git -C "$plugins_repo" worktree add "$(pwd)/plugins"
"$plugins_branch" 2>&1); then
+ echo "$worktree_add_output"
+elif echo "$worktree_add_output" | grep -q "already checked out"; then
+ echo "Branch '$plugins_branch' is already checked out elsewhere; using a
detached checkout of the same commit instead."
+ git -C "$plugins_repo" worktree add --detach "$(pwd)/plugins"
"$plugins_branch"
+else
+ echo "$worktree_add_output" >&2
+ exit 1
+fi
+
+echo "Done: plugins/ is ready on '$plugins_branch'."