The following script tries to find the newest common commit of two branches. The commits should have the same subject, same author and same author date. but commit date and hash are different. Because of this, git rebase
cannot find this branch automatically.
#!/bin/bash
lastbr=
lastrest=
revU= # Update
revB= # Base
rm -f rev.*.tmp
(
git log --format='format:b %H %at %an %ae %f' master
echo
git log --format='format:u %H %at %an %ae %f' master_tmpnew
) | sort -r -t' ' -k3 | while read br rev rest; do
echo "? $br $rev $rest"
[ "$br" != "u" ] || revU="$rev"
[ "$br" != "b" ] || revB="$rev"
if [ "$lastrest" = "$rest" -a "$lastbr" != "$br" ]; then
echo "found match: base $revB updae $revU"
echo "$revB" >rev.base.tmp
echo "$revU" >rev.update.tmp
break
fi
lastrest="$rest"
lastbr="$br"
done
if [ ! -f rev.base.tmp ]; then
echo "No matching revision found"
exit 1
fi
revB="`cat rev.base.tmp`"
revU="`cat rev.update.tmp`"
git rebase --onto $revB $revU master_tmpnew
The question: This solution doesn't look very nice to me. Does anyone of you have a better idea how to implement this problem or is there already a solution available?
The background: I try to implement an incremental CVS-to-GIT import using the tool cvs2git. Officially, it doesn't support incremental imports, but I found a solution which is similar to this workaround. The only problem: I had problems doing a simple git rebase
. Because the branches don't match together (different hash & commit dates due to the nature of git2svn), it often rewrites more commits than necessary if I use it without detailed references (the common commit). Check this for a ready-to-run test scenario of the script above.
Perhaps git-cherry can be of use. It will compare the change sets rather than commit hash to determine whether or not two commits contain the same thing.
http://www.kernel.org/pub//software/scm/git/docs/git-cherry.html