Submodules are needed to atomically control permissions to folders under git. As of now, I don't know of any viable alternative, hence had to make it work with git flow
Git flow with submodules:
- Initialize/checkout feature branch
BRANCH_NAME=feature/some-feature-name
bash git-checkout-with-submodules.sh "${BRANCH_NAME}"
- Do commits in your IDE(like Rider from JetBrains or VisualStudio from Microsoft)
- Push feature branch
bash git-push-with-submodules.sh
- Merge branch
main
into current branch
BRANCH_NAME=main
bash git-merge-with-submodules.sh "${BRANCH_NAME}"
- Create PR in your git provider(like github), code review will contain only changed submodules, and will look like on screenshot
(Please upvote this discussion which proposes to support atomic merges in PR-s in github https://github.com/github/feedback/discussions/10968)
- After PR is merged into main branch and feature branch is no longer needed, delete branch with
BRANCH_NAME=feature/some-feature-name
bash git-delete-branch-with-submodules.sh "${BRANCH_NAME}"
Scripts
- git-checkout-with-submodules.sh
BRANCH_NAME="${1:-main}"
COMMAND="git fetch && (git checkout \"${BRANCH_NAME}\" || git checkout -b \"${BRANCH_NAME}\")"
# Running command in parent repository
eval "$COMMAND"
# Running command in submodules
bash git-submodule-foreach-parallel.sh "$COMMAND"
- git-clean-with-submodules.sh
COMMAND="git clean -dfx -e \"**/.idea\""
# Running command in parent repository
eval "$COMMAND"
# Running command in submodules
bash git-submodule-foreach-parallel.sh "$COMMAND"
- git-delete-branch-with-submodules.sh
BRANCH_NAME="${1}"
REMOTE="${2:-origin}"
COMMAND="git fetch && (git push -d ${REMOTE} ${BRANCH_NAME}; git branch -d ${BRANCH_NAME})"
# Running command in parent repository
eval "$COMMAND"
# Running command in submodules
bash git-submodule-foreach-parallel.sh "$COMMAND"
- git-pull-with-submodules.sh
COMMAND="git fetch && git pull"
# Running command in parent repository
eval "$COMMAND"
# Running command in submodules
bash git-submodule-foreach-parallel.sh "$COMMAND"
- git-push-with-submodules.sh
REMOTE="${1:-origin}"
COMMAND="git fetch && git push --set-upstream ${REMOTE} HEAD"
# Running command in parent repository
eval "$COMMAND"
# Running command in submodules
bash git-submodule-foreach-parallel.sh "$COMMAND"
- git-merge-with-submodules.sh
BRANCH_NAME="${1:-main}"
COMMAND="git merge \"${BRANCH_NAME}\""
# Running command in parent repository
eval "$COMMAND"
# Running command in submodules
bash git-submodule-foreach-parallel.sh "$COMMAND"
- git-submodule-foreach-parallel.sh
#!/bin/bash
if [ -z "$1" ]; then
echo "Missing Command" >&2
exit 1
fi
COMMAND="$@"
IFS=$'\n'
for DIR in $(git submodule foreach --recursive -q sh -c pwd); do
printf "\n\nStarted running command \"${COMMAND}\" in directory \"${DIR}\"\n\n" \
&& \
cd "$DIR" \
&& \
eval "$COMMAND" \
&& \
printf "\nFinished running command \"${COMMAND}\" in directory \"${DIR}\"\n\n" \
&
done
wait