36dd42a030
If patch fails, let caller resolve it manually before continuing. Can happen if the imported history includes branches and merges with merge conflicts.
84 lines
2.8 KiB
Bash
Executable file
84 lines
2.8 KiB
Bash
Executable file
#! /bin/sh
|
|
#
|
|
# Run this inside the top level of a clean
|
|
# syncevolution git repository with the following
|
|
# parameters:
|
|
# - file system path for foreign git repository
|
|
# - name of local branch for importing changes
|
|
# - a local directory into which the source file(s) is to be placed,
|
|
# preserving all remaining directories after stripping
|
|
# - number of directory levels to strip from source file(s)
|
|
# - one or more source file names, with paths relative to the
|
|
# foreign repository
|
|
|
|
set -e
|
|
set -x
|
|
|
|
FOREIGN="$1"
|
|
shift
|
|
TARGET_BRANCH="$1"
|
|
shift
|
|
TARGET_DIR="$1"
|
|
shift
|
|
SOURCE_LEVELS="$1"
|
|
shift
|
|
SOURCE="$@"
|
|
|
|
FOREIGN_NAME=`basename $FOREIGN`
|
|
TARGET=`for i in $SOURCE; do echo $i | perl -p -e "s;([^/]*/){$SOURCE_LEVELS};$TARGET_DIR/;"; done`
|
|
PATCH=`mktemp`
|
|
MSG=`mktemp`
|
|
|
|
git checkout $TARGET_BRANCH
|
|
|
|
# find lastest imported commit:
|
|
# import everything unless one of the files already exists,
|
|
# in which case we assume that all of the others also exist
|
|
revisions=master
|
|
for i in $TARGET; do
|
|
if [ -f $i ]; then
|
|
revisions="`git log -n 1 -- $TARGET | tail -1`..master"
|
|
break
|
|
fi
|
|
done
|
|
|
|
count=`(cd "$FOREIGN" && git log -p $revisions -- $SOURCE) | grep '^commit' | wc -l`
|
|
|
|
# iterate over all commits from oldest to newest
|
|
i=1
|
|
while [ $i -le $count ]; do
|
|
# get complete patch
|
|
(cd "$FOREIGN" && git log -p --max-count=1 --skip=`expr $count - $i` $revisions -- $SOURCE) >$PATCH
|
|
# get just the commit message
|
|
(cd "$FOREIGN" && git log --max-count=1 --skip=`expr $count - $i` $revisions -- $SOURCE) >$MSG
|
|
# apply patch to file: enter directory and skip pathname from patch
|
|
if ! (cd $TARGET_DIR && patch -p`expr $SOURCE_LEVELS + 1` <$PATCH); then
|
|
echo "patch failed in $TARGET_DIR: patch -p`expr $SOURCE_LEVELS + 1` <$PATCH"
|
|
echo "continue? yes/no [no]"
|
|
read yesno
|
|
if [ "$yesno" != "yes" ]; then
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# now commit it (can't use commit because we want to preserve date):
|
|
# - add to index
|
|
for t in $TARGET; do
|
|
[ -f $t ] && git add $t
|
|
done
|
|
# - write index
|
|
id=`git write-tree`
|
|
# - find information for commit and commit
|
|
parent=`git show-ref --heads --hash $TARGET_BRANCH`
|
|
origid=`grep ^commit $MSG | sed -e 's/commit //'`
|
|
GIT_AUTHOR_NAME="`grep ^Author: $MSG | sed -e 's/Author: \(.*\) <.*/\1/'`"
|
|
GIT_AUTHOR_EMAIL="`grep ^Author: $MSG | sed -e 's/Author: [^<]*<\([^>]*\)>/\1/'`"
|
|
GIT_AUTHOR_DATE="`grep ^Date: $MSG | sed -e 's/Date: *//'`"
|
|
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
|
|
id=`(grep '^ ' $MSG | sed -e 's/^ *//' && echo && echo "$FOREIGN_NAME commit ID:" && echo $origid) | git commit-tree $id -p $parent`
|
|
# - update branch and check it out
|
|
git update-ref refs/heads/$TARGET_BRANCH $id
|
|
git reset --hard $TARGET_BRANCH
|
|
# next patch
|
|
i=`expr $i + 1`
|
|
done
|