ref: f10ded757ffea343cf07e27cb0c504653444659f
dir: /pull/
#!/bin/rc -e rfork en nl=' ' fn update{ update=$1 branch=$2 upstream=$3 url=$4 dir=$5 fetch=`{git/fetch -b $branch -u $upstream $url} |[2] tr '\x0d' '\x0a' st=$status if(! ~ $st ''){ echo fetch failed: $st exit $st } echo $fetch | awk -v 'update='^$update ' function writeref(ref, hash) { outfile = ".git/"ref # we have local commits: nothing to do if(system("~ `{git/query ''HEAD "hash" @''} `{git/query "hash"}") == 0) exit(""); # we have local commits *and* remote commits: request a merge if(system("~ `{git/query ''HEAD "hash" @''} `{git/query HEAD}") != 0){ printf("git/merge %s\n", hash) > "/fd/2"; exit("merge"); } # we only have remote commits: update head system("mkdir -p `{basename -d "outfile"}"); print hash > outfile; close(outfile); } /^remote/{ if($2=="HEAD") next if(update) writeref($2, $3) gsub("^refs/heads", "refs/remotes/'$upstream'", $2) writeref($2, $3) } ' } fn usage{ echo usage: $0 '[-a] [-u upstream] [-b branch] -u up: pull from upstream "up" (default: origin) -f: fetch without updating working copy' >[1=2] exit usage } git/fs branch=`{awk '$1=="branch"{print $2}' < /mnt/git/ctl} remote=() update='true' upstream=origin while(~ $1 -*){ switch($1){ case -u upstream=SOMEONE remote=$2 shift case -b branch=$2 shift case -f update='' case * usage } shift } if(! ~ $#* 0) usage if(~ $#remote 0) remote=`{git/conf 'remote "'$upstream'".url'} if(~ $#remote 0){ echo 'no idea from where to pull' exit upstream } if(! cd `{git/conf -r}) exit 'not in git repository' dir=/mnt/git/branch/$branch/tree if(! ~ git/walk -q){ echo 'repository is dirty; commit before pulling' >[1=2] exit 'dirty' } oldfiles=`$nl{git/walk -cfT} update $update $branch $upstream $remote $dir if(! ~ $update 0){ rm -f $oldfiles tree=/mnt/git/HEAD/tree @{builtin cd $tree && tar cif /fd/1 .} | @{tar xf /fd/0} for(f in `$nl{walk -f $tree | sed 's@^'$tree'/*@@'}){ if(! ~ $#f 0){ idx=.git/index9/tracked/$f mkdir -p `{basename -d $idx} walk -eq $f > $idx } } }