Revision 564d72ca474fd6f650ad59bac0a2c0f68b9f35bf authored by Ahil PonArul on 14 February 2022, 20:34:11 UTC, committed by GitHub on 14 February 2022, 20:34:11 UTC
updated named query docs to inclue nested case. Example might need to be altered, but this setting should be documented else where than independent stackoverflow posts.
1 parent 8906af2
Raw File
atomic_push.sh
#!/usr/bin/env bash
set -e

if [ "$#" -eq 0 ]; then
    printf 'Usage: %s <origin> <branch> <branch> ...\n' "$(basename "$0")"
    exit 0;
fi

REMOTE="$1"
WORKING_DIR=$(pwd)

if ! git ls-remote --exit-code "${REMOTE}" > /dev/null 2>&1; then
    echo >&2 "Remote '${REMOTE}' is not valid."
    exit 1;
fi

if [ "$#" -lt 3 ]; then
    echo >&2 "You must specify at least two branches to push."
    exit 1;
fi

if ! git diff-index --quiet HEAD -- ; then
    echo >&2 "Found uncommitted changes in working copy."
    exit 1;
fi

ATOMIC_COMMIT_DATE="$(date)"

for BRANCH in "${@:2}"
do
    echo "Validating branch '${BRANCH}'..."

    # Validate that script arguments are valid local branch names
    if ! git show-ref --verify --quiet "refs/heads/${BRANCH}"; then
        echo >&2 "No such branch named '${BRANCH}'."
        exit 1;
    fi

    # Determine if the branch is checked out to a worktree directory
    WORKTREE_DIR=$(git worktree list | grep -F [${BRANCH}] | awk '{print $1}')

    # If the branch is checked out to a worktree directory change directory to there
    if [ -n "${WORKTREE_DIR}" -a "${WORKTREE_DIR}" != "${WORKING_DIR}" ]; then
      echo "Switching to ${BRANCH} worktree in ${WORKTREE_DIR}";
      cd ${WORKTREE_DIR}
    fi

    # Pull and rebase all branches to ensure we've incorporated any new upstream commits
    git checkout --quiet ${BRANCH}
    git pull "${REMOTE}" "${BRANCH}" --rebase --quiet

    PENDING_COMMITS=$(git log ${REMOTE}/${BRANCH}..HEAD --oneline | grep "^.*$" -c || true)

    # Ensure that there is exactly 1 unpushed commit in the branch
    if [ "${PENDING_COMMITS}" -ne 1 ]; then
        echo >&2 "Expected exactly 1 pending commit for branch '${BRANCH}' but ${PENDING_COMMITS} exist."
        exit 1;
    fi

    # Amend HEAD commit to ensure all branch commit dates are the same
    GIT_COMMITTER_DATE="${ATOMIC_COMMIT_DATE}" git commit --amend --no-edit --quiet

    # Change back to original working directory if necessary
    cd ${WORKING_DIR}
done

echo "Pushing to remote '${REMOTE}'..."
git push --atomic "${REMOTE}" "${@:2}"
back to top