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'."

Reply via email to