<commit_before>#!/usr/bin/env bash
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
# $Source: src/build/tools/update_subtree.sh $
#
# OpenPOWER HostBoot Project
#
# Contributors Listed Below - COPYRIGHT 2021,2022
# [+] International Business Machines Corp.
#
#
# Licensed 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.
#
# IBM_PROLOG_END_TAG

#    update_subtree.sh
#
#    Author: <NAME> (<EMAIL>)
#
#    Hostboot developers sometimes want to make changes to the local
#    subtree that are not in the upstream repo yet. This can make
#    pulling in the latest upstream changes difficult. This script
#    eases that process.

function usage()
{
    echo "Hostboot developers sometimes want to make changes to the local"
    echo "subtree that are not in the upstream repo yet. This can make"
    echo "pulling in the latest upstream changes difficult. This script"
    echo "eases that process."
    echo ""
    echo "update_subtree.sh"
    echo "    -h --help"
    echo "    -p --push"
    echo "    -r --reviewer=<reviewer email>"
    echo "    -s --subtree=<subtree>"
    echo ""
    echo "Subtrees that are currently supported: $SUPPORTED_SUBTREES"
}

PUSH_COMMITS="0"
PUSH_BRANCH="master-p10"
SUPPORTED_SUBTREES="pldm,libmctp"
REVIEWER=""
SUBTREE="wrong"

while [ "$1" != "" ]; do
    PARAM=`echo $1 | awk -F= '{print $1}'`
    VALUE=`echo $1 | awk -F= '{print $2}'`
    case $PARAM in
        -h | --help)
            usage
            exit
            ;;
        -p | --push)
            PUSH_COMMITS="1";
            ;;
        -r | --reviewer)
            REVIEWER=$VALUE;
            ;;
        -s | --subtree)
            SUBTREE=$VALUE;
            ;;
        *)
            echo "ERROR: unknown parameter \"$PARAM\""
            usage
            exit 1
            ;;
    esac
    shift
done

# Expecting input format to be in a format like '2.10.0'.
# Will return success (i.e. 0) if the current git version is greater than or
# equal to the given version (meaning the feature is supported). Otherwise,
# this will return a non-zero value.
function check_git_version()
{
    local given=(${1//./ })

    local current=`git version | awk '{print $3}'`
    current=(${current//./ })

    if [ ${current[0]} -gt ${given[0]} ]; then
        return 0
    elif [ ${current[0]} -eq ${given[0]} ]; then
        if [ ${current[1]} -gt ${given[1]} ]; then
            return 0
        elif [ ${current[1]} -eq ${given[1]} ]; then
            if [ ${current[2]} -ge ${given[2]} ]; then
                return 0
            fi
        fi
    fi

    return 1
}

if !(echo "$SUPPORTED_SUBTREES" | grep -w -q "$SUBTREE") ; then
  echo "  Error! Must specify a valid subtree to use!"
  echo "  Subtrees that are currently supported: $SUPPORTED_SUBTREES"
  exit 1
fi


# Check if we are in a hostboot repository directory
if [ `ls ./example_customrc 2>/dev/null | wc -c` -eq 0 ] > /dev/null 2>&1; then
  echo "Error! This script is expected to be ran from the top-level of a hostboot repository. cd to that directory and try again."
  exit 1
fi

# Just in case the tool is not run in a hb workon.
if [ -z "${HOSTBOOT_INSIDE_WORKON}" ]; then
    . ./env.bash
fi

# Check if there are any outstanding changes in the current branch
if ! git diff-index --quiet HEAD --; then
  echo "Error! Outstanding changes in this branch are detected. Clean up the outstanding changes in your current branch and try again."
  exit 1
fi

# Check if there are any untracked files in the current branch
if [ `git status --porcelain 2>/dev/null| grep "^??" | wc -l` -gt 0 ]; then
  echo "Error! An untracked file(s) is detected in this branch. Clean up this untracked file(s) and try again."
  exit 1
fi

# Keep track of the current top commit's ID.
CURRENT_TOP_COMMIT=$(git rev-parse --short HEAD)

# Find the Change-Id of the subtree's last sync with the upstream repo.
LAST_SYNC_CHANGE_ID=$(grep $SUBTREE src/subtree/latest_commit_sync | awk '{print $2}')
if [ -z $LAST_SYNC_CHANGE_ID ]; then
    echo "Unable to find Change-Id subtree: $SUBTREE"
    exit 1
fi

# Get the commit ID of the last synched commit from the current working tree.
LAST_SYNC_COMMIT=$(git log --grep $LAST_SYNC_CHANGE_ID --format="%h")
if [ -z $LAST_SYNC_COMMIT ]; then
    echo "Unable to find commit ID for Change-Id: $LAST_SYNC_CHANGE_ID"
    exit 1
fi

# Figure out all of the changes we have made to the subtree between now and
# the last sync commit. Note this command will create outstanding changes
# that undo all of the downstream work hostboot has done on the subtree
# that has not been upstreamed yet
git checkout $LAST_SYNC_COMMIT -- src/subtree/openbmc/$SUBTREE/*
diff_found=0

# If outstanding changes are detected we know there are some changes
# that we want to try to patch after updating from upstream
if ! git diff-index --quiet HEAD --; then
    echo "Changes have been made to src/subtree/openbmc/$SUBTREE locally since the last sync, creating a patch that apply these changes post sync"
    diff_found=1
    git add --a
    # temporarily commit the changes, this will undo all of the downstream edits hostboot has done
    git commit -m "Revert $SUBTREE changes from $LAST_SYNC_COMMIT to $CURRENT_TOP_COMMIT"  > /dev/null 2>&1
    # revert the commit we just did so we can build a single patch with all of the edits we have done
    git revert HEAD --no-edit > /dev/null 2>&1
    # commit the revert
    git commit --amend -m "Reapply $SUBTREE subtree changes made from $LAST_SYNC_COMMIT to $CURRENT_TOP_COMMIT"  > /dev/null 2>&1
    # generate a patch of the revert, this patch will allow us to reapply all of
    # the downstream edits after syncing to latest openbmc/subtree
    git format-patch HEAD~1
    # reset back to the state prior to the temporary commit we created above
    git reset HEAD~2 --hard
fi

echo "Updating subtree with changes from remote.."
# add the bmc-subtree remote repository
git remote add bmc-$SUBTREE  https://github.com/openbmc/$SUBTREE.git > /dev/null 2>&1
# update the bmc-subtree remote repository
git fetch bmc-$SUBTREE > /dev/null 2>&1
# we will put the top level commit from the BMC repo in the commit message of the subtree update commit
BMC_SUBTREE_TOP_COMMIT=`git rev-parse --short bmc-$SUBTREE/master`

# Forcefully subtree update to the latest openbmc/subtree master branch, discard all local changes
CMD="git merge --squash -s recursive -Xsubtree=src/subtree/openbmc/$SUBTREE -Xtheirs bmc-$SUBTREE/master"
if check_git_version '2.10.0'; then
    CMD="${CMD} --allow-unrelated-histories"
fi
$CMD

# Check for any new changes.
if [ -z "$(git status --porcelain)" ]; then
    echo "No changes since last sync commit: $LAST_SYNC_COMMIT"

    # Reset the history back to the were we began.
    git reset --hard $CURRENT_TOP_COMMIT

    # Clean up patch files, if they exist.
    rm -f 0001-Reapply-$SUBTREE-subtree-changes-made-from-*

    # Nothing more to do.
    exit 0
fi

# If there are still merge conflicts because git thinks 'both' parties have added the
# file, explicitly checkout 'our' version of the file(s) and then add the files.
BOTH=$(git status --porcelain | grep 'AA' | awk '{print $2}')
if [ -n "$BOTH" ]; then<commit_msg>update_subtree.sh: add upstream revision input<commit_after>#!/usr/bin/env bash
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
# $Source: src/build/tools/update_subtree.sh $
#
# OpenPOWER HostBoot Project
#
# Contributors Listed Below - COPYRIGHT 2021,2022
# [+] International Business Machines Corp.
#
#
# Licensed 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.
#
# IBM_PROLOG_END_TAG

#    update_subtree.sh
#
#    Author: <NAME> (<EMAIL>)
#
#    Hostboot developers sometimes want to make changes to the local
#    subtree that are not in the upstream repo yet. This can make
#    pulling in the latest upstream changes difficult. This script
#    eases that process.

function usage()
{
    echo "Hostboot developers sometimes want to make changes to the local"
    echo "subtree that are not in the upstream repo yet. This can make"
    echo "pulling in the latest upstream changes difficult. This script"
    echo "eases that process."
    echo ""
    echo "update_subtree.sh"
    echo "    -h --help"
    echo "    -p --push"
    echo "    -r --reviewer=<reviewer email>"
    echo "    -s --subtree=<subtree>"
    echo "    -u --upstream-rev=<commit>"
    echo ""
    echo "Subtrees that are currently supported: $SUPPORTED_SUBTREES"
}

PUSH_COMMITS="0"
PUSH_BRANCH="master-p10"
SUPPORTED_SUBTREES="pldm,libmctp"
REVIEWER=""
SUBTREE="wrong"
UPSTREAM_REV=""

while [ "$1" != "" ]; do
    PARAM=`echo $1 | awk -F= '{print $1}'`
    VALUE=`echo $1 | awk -F= '{print $2}'`
    case $PARAM in
        -h | --help)
            usage
            exit
            ;;
        -p | --push)
            PUSH_COMMITS="1";
            ;;
        -r | --reviewer)
            REVIEWER=$VALUE;
            ;;
        -s | --subtree)
            SUBTREE=$VALUE;
            ;;
        -u | --upstream-rev)
            UPSTREAM_REV=$VALUE;
            ;;
        *)
            echo "ERROR: unknown parameter \"$PARAM\""
            usage
            exit 1
            ;;
    esac
    shift
done

UPSTREAM_REMOTE="bmc-$SUBTREE"
if [ -z $UPSTREAM_REV ]; then
    UPSTREAM_REV="$UPSTREAM_REMOTE/master"
fi

# Expecting input format to be in a format like '2.10.0'.
# Will return success (i.e. 0) if the current git version is greater than or
# equal to the given version (meaning the feature is supported). Otherwise,
# this will return a non-zero value.
function check_git_version()
{
    local given=(${1//./ })

    local current=`git version | awk '{print $3}'`
    current=(${current//./ })

    if [ ${current[0]} -gt ${given[0]} ]; then
        return 0
    elif [ ${current[0]} -eq ${given[0]} ]; then
        if [ ${current[1]} -gt ${given[1]} ]; then
            return 0
        elif [ ${current[1]} -eq ${given[1]} ]; then
            if [ ${current[2]} -ge ${given[2]} ]; then
                return 0
            fi
        fi
    fi

    return 1
}

if !(echo "$SUPPORTED_SUBTREES" | grep -w -q "$SUBTREE") ; then
  echo "  Error! Must specify a valid subtree to use!"
  echo "  Subtrees that are currently supported: $SUPPORTED_SUBTREES"
  exit 1
fi


# Check if we are in a hostboot repository directory
if [ `ls ./example_customrc 2>/dev/null | wc -c` -eq 0 ] > /dev/null 2>&1; then
  echo "Error! This script is expected to be ran from the top-level of a hostboot repository. cd to that directory and try again."
  exit 1
fi

# Just in case the tool is not run in a hb workon.
if [ -z "${HOSTBOOT_INSIDE_WORKON}" ]; then
    . ./env.bash
fi

# Check if there are any outstanding changes in the current branch
if ! git diff-index --quiet HEAD --; then
  echo "Error! Outstanding changes in this branch are detected. Clean up the outstanding changes in your current branch and try again."
  exit 1
fi

# Check if there are any untracked files in the current branch
if [ `git status --porcelain 2>/dev/null| grep "^??" | wc -l` -gt 0 ]; then
  echo "Error! An untracked file(s) is detected in this branch. Clean up this untracked file(s) and try again."
  exit 1
fi

# Keep track of the current top commit's ID.
CURRENT_TOP_COMMIT=$(git rev-parse --short HEAD)

# Find the Change-Id of the subtree's last sync with the upstream repo.
LAST_SYNC_CHANGE_ID=$(grep $SUBTREE src/subtree/latest_commit_sync | awk '{print $2}')
if [ -z $LAST_SYNC_CHANGE_ID ]; then
    echo "Unable to find Change-Id subtree: $SUBTREE"
    exit 1
fi

# Get the commit ID of the last synched commit from the current working tree.
LAST_SYNC_COMMIT=$(git log --grep $LAST_SYNC_CHANGE_ID --format="%h")
if [ -z $LAST_SYNC_COMMIT ]; then
    echo "Unable to find commit ID for Change-Id: $LAST_SYNC_CHANGE_ID"
    exit 1
fi

# Figure out all of the changes we have made to the subtree between now and
# the last sync commit. Note this command will create outstanding changes
# that undo all of the downstream work hostboot has done on the subtree
# that has not been upstreamed yet
git checkout $LAST_SYNC_COMMIT -- src/subtree/openbmc/$SUBTREE/*
diff_found=0

# If outstanding changes are detected we know there are some changes
# that we want to try to patch after updating from upstream
if ! git diff-index --quiet HEAD --; then
    echo "Changes have been made to src/subtree/openbmc/$SUBTREE locally since the last sync, creating a patch that apply these changes post sync"
    diff_found=1
    git add --a
    # temporarily commit the changes, this will undo all of the downstream edits hostboot has done
    git commit -m "Revert $SUBTREE changes from $LAST_SYNC_COMMIT to $CURRENT_TOP_COMMIT"  > /dev/null 2>&1
    # revert the commit we just did so we can build a single patch with all of the edits we have done
    git revert HEAD --no-edit > /dev/null 2>&1
    # commit the revert
    git commit --amend -m "Reapply $SUBTREE subtree changes made from $LAST_SYNC_COMMIT to $CURRENT_TOP_COMMIT"  > /dev/null 2>&1
    # generate a patch of the revert, this patch will allow us to reapply all of
    # the downstream edits after syncing to latest openbmc/subtree
    git format-patch HEAD~1
    # reset back to the state prior to the temporary commit we created above
    git reset HEAD~2 --hard
fi

echo "Updating subtree with changes from remote.."
# add the bmc-subtree remote repository
git remote add $UPSTREAM_REMOTE  https://github.com/openbmc/$SUBTREE.git > /dev/null 2>&1
# update the bmc-subtree remote repository
git fetch $UPSTREAM_REMOTE > /dev/null 2>&1
# we will put the target revision from the BMC repo in the commit message of the subtree update commit
BMC_SUBTREE_TOP_COMMIT=`git rev-parse --short $UPSTREAM_REV`

# Forcefully subtree update to the target upstream revision, discard all local changes
CMD="git merge --squash -s recursive -Xsubtree=src/subtree/openbmc/$SUBTREE -Xtheirs $UPSTREAM_REV"
if check_git_version '2.10.0'; then
    CMD="${CMD} --allow-unrelated-histories"
fi
$CMD

# Check for any new changes.
if [ -z "$(git status --porcelain)" ]; then
    echo "No changes since last sync commit: $LAST_SYNC_COMMIT"

    # Reset the history back to the were we began.
    git reset --hard $CURRENT_TOP_COMMIT

    # Clean up patch files, if they exist.
    rm -f 0001-Reapply-$SUBTREE-subtree-changes-made-from-*

    # Nothing more to do.
    exit 0
fi

# If there are still merge conflicts because git thinks 'both' parties have added the
# file, explicitly checkout 'our' version of the file(s) and then add the files.
BOTH=$(git status --porcelain | grep 'AA' | awk '{print $2}')
if [ -n "$BOTH" ]; then
{'fraction_non_alphanumeric': 0.09877571950515993, 'fraction_numerical': 0.010255752836356644, 'mean_word_length': 2.9994873109459115, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 40, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1059737', 'n_tokens_mistral': 4974, 'n_tokens_neox': 4772, 'n_words': 1979}