Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pushing Squashed subtree change to gerrit

While adding a subtree:

git subtree add --prefix=vendor https://example.com/repo master --squash

There are two commits created. One for the squashed subtree commits

Squashed 'vendor' changes from 15fc2b6..c6dc29b

and a merge commit

Merge commit 'SHA1' into master

When I want to push this change to gerrit, it needs a changeID. But git doesn't allow me to do a

git rebase -i HEAD~2

and rework like I do for any other commit as it is a squashed commit.

Now I can't push this change to gerrit because of this. I can't commit the changes to heads (git) directly and break stuff on the supermodule. It has to go through build and testing. Any suggestion or help is appreciated.

like image 953
LizzeBennet Avatar asked Oct 29 '22 17:10

LizzeBennet


1 Answers

git filter-branch can do lots of things, while at the same time updating the commit pointers so the commit graph stays intact. One of these is running a command to edit all the commit messages, such as Gerrit's commit-msg hook.

git filter-branch HEAD...HEAD~1 grabs all the commits in HEAD but not HEAD~1, which for a git-subtree merge is just the merge and squash commit.

git filter-branch --msg-filter takes a command to run which gets the commit message piped in on stdin, and writes a new one to stdout. commit-msg hook scripts work on a file, so a bit of shell scripting is necessary to write the original message to a file, run the hook, and then cat the file to stdout.

I've put this all in a script to run before pushing to Gerrit:

# This command re-writes the history after doing a git subtree {pull|add}
# to add Gerrit Change-Id lines to the squash commit message.
#
# It assumes that HEAD is the merge commit merging the subtree into HEAD.
# The original HEAD commit will be backed up under refs/original, which
# is helpful if something goes wrong.

set -e
set -o pipefail

GIT_DIR=$(readlink -f "$(git rev-parse --git-dir)")
TMP_MSG="${GIT_DIR}/COMMIT_MSG_REWRITE"

git filter-branch --msg-filter \
  "cat > ${TMP_MSG} && \"${GIT_DIR}/hooks/commit-msg\" ${TMP_MSG} && \
  cat \"${TMP_MSG}\"" HEAD...HEAD~1

rm -rf "${TMP_MSG}"
like image 173
Brian Silverman Avatar answered Nov 15 '22 06:11

Brian Silverman