plan9fox/sys/src/cmd/git/import
Ori Bernstein 926be5e34e git/import: use patch(1)
we have a new, pretty patch(1), lets use it.
2022-06-04 23:35:49 +00:00

117 lines
2.3 KiB
Bash
Executable file

#!/bin/rc
rfork ne
. /sys/lib/git/common.rc
diffpath=/tmp/gitimport.$pid.diff
fn sigexit {
rm -f $diffpath
}
fn apply @{
git/fs
amail=''
aname=''
msg=''
whoami
parents='-p'^`{git/query HEAD}
branch=`{git/branch}
if(test -e $gitfs/branch/$branch/tree)
refpath=.git/refs/$branch
if not if(test -e $gitfs/object/$branch/tree)
refpath=.git/HEAD
if not
die 'invalid branch:' $branch
awk '
BEGIN{
state="headers"
}
state=="headers" && /^From:/ {
sub(/^From:[ \t]*/, "", $0);
aname=$0;
amail=$0;
sub(/[ \t]*<.*$/, "", aname);
sub(/^[^<]*</, "", amail);
sub(/>[^>]*$/, "", amail);
}
state=="headers" && /^Date:/{
sub(/^Date:[ \t]*/, "", $0)
date=$0
}
state=="headers" && /^Subject:/{
sub(/^Subject:[ \t]*(\[[^\]]*\][ \t]*)*/, "", $0);
gotmsg = 1
print > "/env/msg"
}
state=="headers" && /^$/ {
state="body"
}
(state=="headers" || state=="body") && (/^diff / || /^---( |$)/){
state="diff"
}
state=="body" && /^[ ]*$/ {
empty=1
next
}
state=="body" {
if(empty)
printf "\n" > "/env/msg"
empty=0
sub(/[ ]+$/, "")
print > "/env/msg"
}
state=="diff" {
print > ENVIRON["diffpath"]
}
END{
if(state != "diff")
exit("malformed patch: " state);
if(aname == "" || amail == "" || date == "" || gotmsg == "")
exit("missing headers");
printf "%s", aname > "/env/aname"
printf "%s", amail > "/env/amail"
printf "%s", date > "/env/date"
}
' || die 'could not import:' $status
# force re-reading env
rc -c '
echo applying $msg | sed 1q
date=`{seconds $date}
if(! files=`$nl{patch -p1 < $diffpath})
die ''patch failed''
for(f in $files){
if(test -e $f)
git/add $f
if not
git/add -r $f
}
git/walk -fRMA $files
if(~ $#nocommit 0){
if(hash=`{git/save -n $aname -e $amail -N $name -E $email -m $msg -d $date $parents $files})
echo $hash > $refpath
}
status=''''
'
}
gitup
flagfmt='n:nocommit'; args='file ...'
eval `''{aux/getflags $*} || exec aux/usage
patches=(/fd/0)
if(! ~ $#* 0)
patches=$*
for(p in $patches){
# upas serves the decoded header and body separately,
# so we cat them together when applying a upas message.
#
# this allows mime-encoded or line-wrapped patches.
if(test -d $p && test -f $p/header && test -f $p/body)
{{cat $p/header; echo; cat $p/body} | apply} || die $status
if not
apply < $p || die $status
}
exit ''