Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Shell script to perform git feature branch merge with squash preserving author
#!/bin/bash
set -e
function select_branch() {
echo "Not merged branches on origin:"
branches=`git branch --list -r --no-merged`
IFS=$'\n' read -d '' -r -a branches_arr <<< "$branches" || true # dunno why, IFS raises error code
if [ ${#branches_arr[@]} -eq 0 ]; then
echo "\e[93mNo unmerged remote branches found\e[0m"
exit
fi
for i in "${!branches_arr[@]}"; do
branch=${branches_arr[$i]}
branch="$(echo -e "${branch}" | sed -e 's/^[[:space:]]*//')"
branch=${branch#origin/}
branches_arr[$i]=$branch
echo "$((i + 1)). $branch"
done
selected_index=-1
while [ $selected_index -lt 0 ] || [ $selected_index -gt ${#branches_arr[@]} ]; do
echo -n "Enter number of branch you want to merge> "
read selected_index
if [ $selected_index -lt 0 ]; then
echo "Negative number? Seriously?"
elif [ $selected_index -gt ${#branches_arr[@]} ]; then
echo "Number greater than last branch's index? Why?"
else
selected_index=$((selected_index - 1))
fi
done
selected_branch=${branches_arr[$selected_index]}
eval "$1=$selected_branch"
}
merge_target_branch=master
if [ ! -z "`git status --porcelain`" ]; then
echo -e "\e[93mYou have uncommited changes in your repository local copy. Commit or stash them before running this script\e[0m"
exit
fi
cur_branch=`git rev-parse --abbrev-ref HEAD`
if [ "$cur_branch" != "$merge_target_branch" ]; then
git checkout "$merge_target_branch" --quiet
fi
git pull origin "$merge_target_branch" --ff-only --quiet
git fetch --quiet
select_branch merge_source_branch
merge_source_branch_head_sha=`git show-ref $merge_source_branch -s`
merge_source_branch_author=`git show --quiet --format="%aN <%aE>" "$merge_source_branch_head_sha"`
# echo "Source branch: $merge_source_branch"
# echo "Source branch HEAD: $merge_source_branch_head_sha"
# echo "Source branch author: $merge_source_branch_author"
git merge --quiet --squash origin/$merge_source_branch
git commit --author="$merge_source_branch_author" --quiet
git push origin $merge_target_branch --quiet
if [ $cur_branch != "$merge_target_branch" ]; then
git checkout "$cur_branch" --quiet
fi
git push origin :$merge_source_branch --quiet
echo -e "\e[92mDone\e[0m"
@EvAlex
Copy link
Author

EvAlex commented Jul 8, 2017

The general idea:

  1. User selects branch to merge
  2. git merge --squash BRANCH_NAME
  3. Script determines AUTHOR_NAME for BRANCH_NAME - it is one who performed HEAD commit on that branch
  4. git commit --author=AUTHOR_NAME
  5. Push and delete BRANCH_NAME on remote.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment