diff options
author | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-02-27 17:47:52 -0500 |
---|---|---|
committer | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-02-27 17:47:52 -0500 |
commit | 15b67942e56de4e0068f0870f257e852cd8b7c00 (patch) | |
tree | 6f595e3710164218a0aa812bac34fd77422eead9 | |
parent | 99df5644235e2afd2e29fa895e037c910521fd61 (diff) |
wip; files were sitting here
32 files changed, 1458 insertions, 328 deletions
diff --git a/modules/Makefile b/modules/Makefile index ddd3928..8235bf3 100644 --- a/modules/Makefile +++ b/modules/Makefile @@ -19,6 +19,6 @@ include $(topsrcdir)/common.top.mk dirs += $(DESTDIR)$(pkglibexecdir)/modules src_files += Makefile module.mk -subdirs = comments date.author files tags tree +subdirs = comments date.author blobs tags tree include $(topsrcdir)/common.bottom.mk diff --git a/modules/blobs/.#get.f.sh b/modules/blobs/.#get.f.sh new file mode 120000 index 0000000..c2c97da --- /dev/null +++ b/modules/blobs/.#get.f.sh @@ -0,0 +1 @@ +luke@build64-par.lan.670:1436421582
\ No newline at end of file diff --git a/modules/files/Makefile b/modules/blobs/Makefile index fa7273c..fa7273c 120000 --- a/modules/files/Makefile +++ b/modules/blobs/Makefile diff --git a/modules/blobs/Makefile.inc.mk b/modules/blobs/Makefile.inc.mk new file mode 100644 index 0000000..8fd2d6f --- /dev/null +++ b/modules/blobs/Makefile.inc.mk @@ -0,0 +1,8 @@ +src_files += commit.d.sh commit.f.sh commit.sh get.d.sh get.f.sh get.sh ls.sh print.sh tree.sh +out_files += commit.d commit.f commit get.d get.f get ls print tree + +src_files += _stdio.sh +sys_files += $(pkglibexecdir)/modules/$(name)/_stdio.sh + +$(DESTDIR)$(pkglibexecdir)/modules/$(name)/_stdio.sh: $(srcdir)/_stdio.sh | $(DESTDIR)$(pkglibexecdir)/modules/$(name) + $(INSTALL_DATA) $< $@ diff --git a/modules/files/Module.mk b/modules/blobs/Module.mk index e69de29..e69de29 100644 --- a/modules/files/Module.mk +++ b/modules/blobs/Module.mk diff --git a/modules/files/_stdio.sh b/modules/blobs/_stdio.sh index 0da03f0..0da03f0 100644 --- a/modules/files/_stdio.sh +++ b/modules/blobs/_stdio.sh diff --git a/modules/blobs/commit.d.sh b/modules/blobs/commit.d.sh new file mode 100644 index 0000000..620a88f --- /dev/null +++ b/modules/blobs/commit.d.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# rvs blobs/commit.d - add a directory to the repository +# Copyright (C) 2009-2010, 2015 Luke Shumaker +# +# This file is part of rvs. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +. "${0%/*}/_stdio.sh" + +usage='DIRECTORY' +[[ $# -eq 1 ]] || errusage +dir="$1" + +shopt -s dotglob +cd "$dir" +tmpfile="$(mktemp -t "${0##*/}.XXXXXXXXXX")" +for file in *; do + id="$("$RVS" commit "$file")" + stat -c $'%a\t%u (%U)\t%g (%G)\t' -- "$file" + printf $'%s\t%s\n' "$id" "$file" +done > "$tmpfile" +"$RVS" commit.f "$tmpfile" d diff --git a/modules/blobs/commit.f.sh b/modules/blobs/commit.f.sh new file mode 100644 index 0000000..8a97c2a --- /dev/null +++ b/modules/blobs/commit.f.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# rvs blobs/commit.f - add a plain file to the repository +# Copyright (C) 2009-2010, 2015 Luke Shumaker +# +# This file is part of rvs. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +. "${0%/*}/_stdio.sh" + +usage='FILENAME [TYPE]' +case $# in + 0) errusage;; + 1) infile=$1; type=f;; + 2) infile=$1; type=$2;; + *) errusage;; +esac + +hash="$(<"$file" sha1sum | cut -d ' ' -f1)" +outfile="$RVS_REPO/blobs/$hash" +if [ ! -f "$outfile" ]; then + mkdir -p -- "${outfile%/*}" + < "$infile" gzip -9 > "$outfile" +fi +printf '%s:%s\n' "$type" "$hash" + diff --git a/modules/files/commit.sh b/modules/blobs/commit.sh index 70573a6..e23af27 100644 --- a/modules/files/commit.sh +++ b/modules/blobs/commit.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# rvs inner.sh - The main RVS program +# rvs blobs/commit - add a file to the repository # Copyright (C) 2009-2010, 2015 Luke Shumaker # # This file is part of rvs. @@ -17,8 +17,9 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -. "$(dirname "$0")/_stdio.sh" +. "${0%/*}/_stdio.sh" +usage='[FILES...]' if [[ $# -lt 1 ]]; then set -- . fi diff --git a/modules/blobs/get.d.sh b/modules/blobs/get.d.sh new file mode 100644 index 0000000..989dbe8 --- /dev/null +++ b/modules/blobs/get.d.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# rvs blobs/get.d - get a directory from the repository +# Copyright (C) 2009-2010, 2015 Luke Shumaker +# +# This file is part of rvs. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +. "${0%/*}/_stdio.sh" + +usage="DIRNAME ID" +[[ $# -eq 2 ]] || errusage +name=$1 +id=$2 + +tmpfile="$(mktemp -t "${0##*/}.XXXXXXXXXX")" +"$RVS" get.f "$tmpfile" "$id" + +mkdir -p -- "$name" +cd "$name" + +IFS=$'\t' +while read -r perm user group id name; do + "$RVS" get "$name" "$id" + chmod "$perm" "$name" +done < "$tmpfile" diff --git a/modules/blobs/get.f.sh b/modules/blobs/get.f.sh new file mode 100644 index 0000000..02185a6 --- /dev/null +++ b/modules/blobs/get.f.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# rvs blobs/get.f - get a plain file from the repository +# Copyright (C) 2009-2010, 2015 Luke Shumaker +# +# This file is part of rvs. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +. "${0%/*}/_stdio.sh" + +. "$LIBDIR/@ID@/stdio" + +usage="FILENAME ID" +[[ $# -eq 2 ]] || errusage +name=$1 +id=$2 + +mkdir -p -- "${name%/*}" +< "$REPO/blobs/${id#*:}" gunzip > "$name" + diff --git a/modules/blobs/get.sh b/modules/blobs/get.sh new file mode 100644 index 0000000..4be2732 --- /dev/null +++ b/modules/blobs/get.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# rvs blobs/get - get a file from the repository +# Copyright (C) 2009-2010, 2015 Luke Shumaker +# +# This file is part of rvs. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +. "${0%/*}/_stdio.sh" + +usage="FILENAME ID" +[[ $# -eq 2 ]] || errusage +name=$1 +id=$2 + +"$RVS" "get.${id%%:*}" "$name" "$id" + diff --git a/modules/files/ls.sh b/modules/blobs/ls.sh index 1c4d620..1c4d620 100644 --- a/modules/files/ls.sh +++ b/modules/blobs/ls.sh diff --git a/modules/blobs/print.sh b/modules/blobs/print.sh new file mode 100644 index 0000000..0e23adc --- /dev/null +++ b/modules/blobs/print.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# rvs files/print - ??? +# Copyright (C) 2010, 2015 Luke Shumaker +# +# This file is part of rvs. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +. "${0%/*}/_stdio.sh" + +usage='ID' +[[ $# -eq 1 ]] || errusage +id=$1 + +hash="${id#*:}" +file="$REPO/blobs/$hash" + +if [ -e "$file" ]; then + t="${id%%:*}" + type='' + case "$t" in + f) type='regular file';; + d) type='directory';; + l) type='link';; + esac + printf 'File Type: %s (%s)\n' "$t" "$type" +else + fatal 'no object with ID `%s'\' "$id" +fi + diff --git a/modules/files/tree.sh b/modules/blobs/tree.sh index 4092582..80202ea 100644 --- a/modules/files/tree.sh +++ b/modules/blobs/tree.sh @@ -17,7 +17,7 @@ ver=0.1 # along with this program; see the file COPYING. # If not, see <http://www.gnu.org/licenses>. -. "$LIBDIR/@ID@/stdio" +. "${0%/*}/_stdio.sh" usage="DIR_ID [NAME] [PREFIX] [LAST]" id="`getvar "$1"`" diff --git a/modules/comments/Module.mk b/modules/comments/Module.mk index 600df63..3fa49ac 100644 --- a/modules/comments/Module.mk +++ b/modules/comments/Module.mk @@ -1 +1 @@ -commit/comments : commit/files +commit/comments : commit/blobs diff --git a/modules/date.author/Module.mk b/modules/date.author/Module.mk index 52ac0cc..30cd2e0 100644 --- a/modules/date.author/Module.mk +++ b/modules/date.author/Module.mk @@ -1 +1 @@ -commit/date.author : commit/files +commit/date.author : commit/blobs diff --git a/modules/files/Makefile.inc.mk b/modules/files/Makefile.inc.mk deleted file mode 100644 index 99c739e..0000000 --- a/modules/files/Makefile.inc.mk +++ /dev/null @@ -1,8 +0,0 @@ -src_files += blob-gethash.sh blob-gettype.sh commit.d.sh commit.f.sh commit.sh file-gettype.sh get.d.sh get.f.sh get.sh ls.sh print.sh tree.sh -out_files += blob-gethash blob-gettype commit.d commit.f commit file-gettype get.d get.f get ls print tree - -src_files += _stdio.sh -sys_files += $(pkglibexecdir)/modules/$(name)/_stdio.sh - -$(DESTDIR)$(pkglibexecdir)/modules/$(name)/_stdio.sh: $(srcdir)/_stdio.sh | $(DESTDIR)$(pkglibexecdir)/modules/$(name) - $(INSTALL_DATA) $< $@ diff --git a/modules/files/blob-gethash.sh b/modules/files/blob-gethash.sh deleted file mode 100644 index 74a3f59..0000000 --- a/modules/files/blob-gethash.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -name='blob-gethash' -ver=0.9 -# Copyright (C) 2009-2010 Luke Shumaker -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. -# If not, see <http://www.gnu.org/licenses>. - -. "$LIBDIR/@ID@/stdio" - -usage="ID" -id="`getvar "$1"`" - -echo $id | sed 's/.*://' - diff --git a/modules/files/blob-gettype.sh b/modules/files/blob-gettype.sh deleted file mode 100644 index 0dd924d..0000000 --- a/modules/files/blob-gettype.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -name='blob-gettype' -ver=0.9 -# Copyright (C) 2009-2010 Luke Shumaker -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. -# If not, see <http://www.gnu.org/licenses>. - -. "$LIBDIR/@ID@/stdio" - -usage="ID" -id="`getvar "$1"`" - -echo $id | sed 's/:.*//' - diff --git a/modules/files/commit.d.sh b/modules/files/commit.d.sh deleted file mode 100644 index 67263ec..0000000 --- a/modules/files/commit.d.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh -name='commit.d' -ver=0.9 -# Copyright (C) 2009-2010 Luke Shumaker -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. -# If not, see <http://www.gnu.org/licenses>. - -. "$LIBDIR/@ID@/stdio" - -usage="DIRNAME" -dir="`getvar "$1"`" - -tmp=`mktemp` -t=' '; - -cd "$dir" -for file in *; do - p="`stat "$file" -c'%a' `" # permissions - o="`stat "$file" -c'%u (%U)'`" # owner - g="`stat "$file" -c'%g (%G)'`" # group - i="`"$RVS" commit "$file"`" # ID - n="$file" # name - - # %p %o %g %i %n - echo "$p$t$o$t$g$t$i$t$n" >> "$tmp" -done - -"$RVS" commit.f "$tmp" d -rm "$tmp" - diff --git a/modules/files/commit.f.sh b/modules/files/commit.f.sh deleted file mode 100644 index 4effab3..0000000 --- a/modules/files/commit.f.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -name='commit.f' -ver=0.9 -# Copyright (C) 2009-2010 Luke Shumaker -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. -# If not, see <http://www.gnu.org/licenses>. - -. "$LIBDIR/@ID@/stdio" - -usage="FILENAME [TYPE]" -file="`getvar "$1"`" -prefix="${2-f}" - -hash=`sha1sum $file | sed "s/ .*$//"` -if [ ! -f "$REPO/@ID@/$hash" ]; then - mkdir -p "$REPO/@ID@/" - install -m 644 -o $USER -g $USER -T "$file" "$REPO/@ID@/$hash" -fi -echo "$prefix:$hash" - diff --git a/modules/files/file-gettype.sh b/modules/files/file-gettype.sh deleted file mode 100644 index ac1ba4e..0000000 --- a/modules/files/file-gettype.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh -name='file-gettype' -ver=0.9 -# Copyright (C) 2009-2010 Luke Shumaker -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. -# If not, see <http://www.gnu.org/licenses>. - -. "$LIBDIR/@ID@/stdio" - -usage="FILE" -file="`getvar "$1"`" - -if [ ! -e "$file" ]; then - fatal "file \`$file' does not exist"; -else - type='' - for check in "$ETCDIR/@ID@/"*; do - type=`"$check" "$file"` - if [ -n "$type" ]; then break; fi - done - if [ -n "$type" ]; then - echo "$type" - else - fatal "cannot handle file type of \`$file'" - fi -fi - diff --git a/modules/files/get.d.sh b/modules/files/get.d.sh deleted file mode 100644 index 9aa493c..0000000 --- a/modules/files/get.d.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -name='get.d' -ver=0.9 -# Copyright (C) 2009-2010 Luke Shumaker -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. -# If not, see <http://www.gnu.org/licenses>. - -. "$LIBDIR/@ID@/stdio" - -usage="DIRNAME ID" -dir="`getvar "$1"`" - id="`getvar "$2"`" - -tmp=`mktemp` -"$RVS" get.f "$tmp" "$id" - -#install -d "$dir" -mkdir -p "$dir" - -cd "$dir" -rm -rf ./* -while read line; do - p="`echo "$line" | cut -f1`" # permissions - o="`echo "$line" | cut -f2`" # owner - g="`echo "$line" | cut -f3`" # group - i="`echo "$line" | cut -f4`" # ID - n="`echo "$line" | cut -f5-`" # name - "$RVS" get "$n" "$i" - chmod "$p" "$n" - #chown "$o:$g" "$n" -done < "$tmp" - -rm "$tmp" - diff --git a/modules/files/get.f.sh b/modules/files/get.f.sh deleted file mode 100644 index d5d889d..0000000 --- a/modules/files/get.f.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh -name='get.f' -ver=0.9 -# Copyright (C) 2009-2010 Luke Shumaker -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. -# If not, see <http://www.gnu.org/licenses>. - -. "$LIBDIR/@ID@/stdio" - -usage="FILENAME ID" -name="`getvar "$1"`" - id="`getvar "$2"`" - -hash="`"$RVS" blob-gethash "$id"`" - -install -T "$REPO/@ID@/$hash" "$name" - diff --git a/modules/files/get.sh b/modules/files/get.sh deleted file mode 100644 index 7dd0f1d..0000000 --- a/modules/files/get.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -name='get' -ver=0.9 -# Copyright (C) 2009-2010 Luke Shumaker -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. -# If not, see <http://www.gnu.org/licenses>. - -. "$LIBDIR/@ID@/stdio" - -usage="FILENAME ID" -name="`getvar "$1"`" - id="`getvar "$2"`" - -file="$REPO/@ID@/$id" - -type="`"$RVS" blob-gettype "$id"`" -#hash="`"$RVS" blob-gethash "$id"`" - -"$RVS" "get.$type" "$name" "$id" - diff --git a/modules/files/print.sh b/modules/files/print.sh deleted file mode 100644 index 9a03469..0000000 --- a/modules/files/print.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh -name='print' -ver=0.1 -# Copyright (C) 2010 Luke Shumaker -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. -# If not, see <http://www.gnu.org/licenses>. - -. "$LIBDIR/@ID@/stdio" - -usage='ID' -id="`getvar "$1"`" - -hash="`"$RVS" blob-gethash "$id"`" -file="$REPO/@ID@/$hash" - -if [ -e "$file" ]; then - t="`"$RVS" blob-gettype "$id"`" - type='' - case "$t" in - f) type='regular file';; - d) type='directory';; - esac - echo "File Type: $t ($type)" -else - fatal "no object with ID \`$id'" -fi - diff --git a/modules/git-fast-import/.#parse.sh b/modules/git-fast-import/.#parse.sh new file mode 120000 index 0000000..c2c97da --- /dev/null +++ b/modules/git-fast-import/.#parse.sh @@ -0,0 +1 @@ +luke@build64-par.lan.670:1436421582
\ No newline at end of file diff --git a/modules/git-fast-import/gen-parser.mk b/modules/git-fast-import/gen-parser.mk new file mode 100644 index 0000000..7837e5c --- /dev/null +++ b/modules/git-fast-import/gen-parser.mk @@ -0,0 +1,154 @@ +# (See Documentation/git-fast-import.txt for maintained documentation.) +# Format of STDIN stream: +# +# stream ::= cmd*; +# +# cmd ::= new_blob +# | new_commit +# | new_tag +# | reset_branch +# | checkpoint +# | progress +# ; +# +# new_blob ::= 'blob' lf +# mark? +# file_content; +# file_content ::= data; +# +# new_commit ::= 'commit' sp ref_str lf +# mark? +# ('author' (sp name)? sp '<' email '>' sp when lf)? +# 'committer' (sp name)? sp '<' email '>' sp when lf +# commit_msg +# ('from' sp commit-ish lf)? +# ('merge' sp commit-ish lf)* +# (file_change | ls)* +# lf?; +# commit_msg ::= data; +# +# ls ::= 'ls' sp '"' quoted(path) '"' lf; +# +# file_change ::= file_clr +# | file_del +# | file_rnm +# | file_cpy +# | file_obm +# | file_inm; +# file_clr ::= 'deleteall' lf; +# file_del ::= 'D' sp path_str lf; +# file_rnm ::= 'R' sp path_str sp path_str lf; +# file_cpy ::= 'C' sp path_str sp path_str lf; +# file_obm ::= 'M' sp mode sp (hexsha1 | idnum) sp path_str lf; +# file_inm ::= 'M' sp mode sp 'inline' sp path_str lf +# data; +# note_obm ::= 'N' sp (hexsha1 | idnum) sp commit-ish lf; +# note_inm ::= 'N' sp 'inline' sp commit-ish lf +# data; +# +# new_tag ::= 'tag' sp tag_str lf +# 'from' sp commit-ish lf +# ('tagger' (sp name)? sp '<' email '>' sp when lf)? +# tag_msg; +# tag_msg ::= data; +# +# reset_branch ::= 'reset' sp ref_str lf +# ('from' sp commit-ish lf)? +# lf?; +# +# checkpoint ::= 'checkpoint' lf +# lf?; +# +# progress ::= 'progress' sp not_lf* lf +# lf?; +# +# # note: the first idnum in a stream should be 1 and subsequent +# # idnums should not have gaps between values as this will cause +# # the stream parser to reserve space for the gapped values. An +# # idnum can be updated in the future to a new object by issuing +# # a new mark directive with the old idnum. +# # +# mark ::= 'mark' sp idnum lf; +# data ::= (delimited_data | exact_data) +# lf?; +# +# # note: delim may be any string but must not contain lf. +# # data_line may contain any data but must not be exactly +# # delim. +# delimited_data ::= 'data' sp '<<' delim lf +# (data_line lf)* +# delim lf; +# +# # note: declen indicates the length of binary_data in bytes. +# # declen does not include the lf preceding the binary data. +# # +# exact_data ::= 'data' sp declen lf +# binary_data; +# +# # note: quoted strings are C-style quoting supporting \c for +# # common escapes of 'c' (e..g \n, \t, \\, \") or \nnn where nnn +# # is the signed byte value in octal. Note that the only +# # characters which must actually be escaped to protect the +# # stream formatting is: \, " and LF. Otherwise these values +# # are UTF8. +# # +# commit-ish ::= (ref_str | hexsha1 | sha1exp_str | idnum); +# ref_str ::= ref; +# sha1exp_str ::= sha1exp; +# tag_str ::= tag; +# path_str ::= path | '"' quoted(path) '"' ; +# mode ::= '100644' | '644' +# | '100755' | '755' +# | '120000' +# ; +# +# declen ::= # unsigned 32 bit value, ascii base10 notation; +# bigint ::= # unsigned integer value, ascii base10 notation; +# binary_data ::= # file content, not interpreted; +# +# when ::= raw_when | rfc2822_when; +# raw_when ::= ts sp tz; +# rfc2822_when ::= # Valid RFC 2822 date and time; +# +# sp ::= # ASCII space character; +# lf ::= # ASCII newline (LF) character; +# +# # note: a colon (':') must precede the numerical value assigned to +# # an idnum. This is to distinguish it from a ref or tag name as +# # GIT does not permit ':' in ref or tag strings. +# # +# idnum ::= ':' bigint; +# path ::= # GIT style file path, e.g. "a/b/c"; +# ref ::= # GIT ref name, e.g. "refs/heads/MOZ_GECKO_EXPERIMENT"; +# tag ::= # GIT tag name, e.g. "FIREFOX_1_5"; +# sha1exp ::= # Any valid GIT SHA1 expression; +# hexsha1 ::= # SHA1 in hexadecimal format; +# +# # note: name and email are UTF8 strings, however name must not +# # contain '<' or lf and email must not contain any of the +# # following: '<', '>', lf. +# # +# name ::= # valid GIT author/committer name; +# email ::= # valid GIT author/committer email; +# ts ::= # time since the epoch in seconds, ascii base10 notation; +# tz ::= # GIT style timezone; +# +# # note: comments, ls and cat requests may appear anywhere +# # in the input, except within a data command. Any form +# # of the data command always escapes the related input +# # from comment processing. +# # +# # In case it is not clear, the '#' that starts the comment +# # must be the first character on that line (an lf +# # preceded it). +# # +# +# cat_blob ::= 'cat-blob' sp (hexsha1 | idnum) lf; +cat_blob = cat-blob${sp}(${hexsha1}|${idnum})${lf} +# ls_tree ::= 'ls' sp (hexsha1 | idnum) sp path_str lf; +ls_tree = ls${sp}(${hexsha1}|${idnum})${sp}${path_str}${lf} +# +# comment ::= '#' not_lf* lf; +comment = \#$(not_lf) +# not_lf ::= # Any byte that is not ASCII newline (LF); +not_lf = [^\n] diff --git a/modules/git-fast-import/parse.sh b/modules/git-fast-import/parse.sh new file mode 100644 index 0000000..16bc5d2 --- /dev/null +++ b/modules/git-fast-import/parse.sh @@ -0,0 +1,1077 @@ +#!/bin/bash + +program_invocation_name=$0 +if type gettext &>/dev/null; then + _() { gettext -- "$@"; } +else + _() { echo "$*"; } +fi + +IFS= + +die() { + printf "$(_ "$1")" "${@:2}" + exit 2 +} + + +# Input Format +# ------------ +# With the exception of raw file data (which Git does not interpret) +# the fast-import input format is text (ASCII) based. This text based +# format simplifies development and debugging of frontend programs, +# especially when a higher level language such as Perl, Python or +# Ruby is being used. +# +# fast-import is very strict about its input. Where we say SP below we mean +# *exactly* one space. Likewise LF means one (and only one) linefeed +# and HT one (and only one) horizontal tab. +# Supplying additional whitespace characters will cause unexpected +# results, such as branch names or file names with leading or trailing +# spaces in their name, or early termination of fast-import when it encounters +# unexpected input. +# +# Stream Comments +# ~~~~~~~~~~~~~~~ +# To aid in debugging frontends fast-import ignores any line that +# begins with `#` (ASCII pound/hash) up to and including the line +# ending `LF`. A comment line may contain any sequence of bytes +# that does not contain an LF and therefore may be used to include +# any detailed debugging information that might be specific to the +# frontend and useful when inspecting a fast-import data stream. + +get_line() { + line='#' + while [[ ${line:0:1} == '#' ]]; do + read -r line || break + done +} + +# +# Date Formats +# ~~~~~~~~~~~~ +# The following date formats are supported. A frontend should select +# the format it will use for this import by passing the format name +# in the --date-format=<fmt> command-line option. +# +# `raw`:: +# This is the Git native format and is `<time> SP <offutc>`. +# It is also fast-import's default format, if --date-format was +# not specified. +# + +# The time of the event is specified by `<time>` as the number of +# seconds since the UNIX epoch (midnight, Jan 1, 1970, UTC) and is +# written as an ASCII decimal integer. +# + +# The local offset is specified by `<offutc>` as a positive or negative +# offset from UTC. For example EST (which is 5 hours behind UTC) +# would be expressed in `<tz>` by ``-0500'' while UTC is ``+0000''. +# The local offset does not affect `<time>`; it is used only as an +# advisement to help formatting routines display the timestamp. +# + +# If the local offset is not available in the source material, use +# ``+0000'', or the most common local offset. For example many +# organizations have a CVS repository which has only ever been accessed +# by users who are located in the same location and time zone. In this +# case a reasonable offset from UTC could be assumed. +# + +# Unlike the `rfc2822` format, this format is very strict. Any +# variation in formatting will cause fast-import to reject the value. +# +# `rfc2822`:: +# This is the standard email format as described by RFC 2822. +# + +# An example value is ``Tue Feb 6 11:22:18 2007 -0500''. The Git +# parser is accurate, but a little on the lenient side. It is the +# same parser used by 'git am' when applying patches +# received from email. +# + +# Some malformed strings may be accepted as valid dates. In some of +# these cases Git will still be able to obtain the correct date from +# the malformed string. There are also some types of malformed +# strings which Git will parse wrong, and yet consider valid. +# Seriously malformed strings will be rejected. +# + +# Unlike the `raw` format above, the time zone/UTC offset information +# contained in an RFC 2822 date string is used to adjust the date +# value to UTC prior to storage. Therefore it is important that +# this information be as accurate as possible. +# + +# If the source material uses RFC 2822 style dates, +# the frontend should let fast-import handle the parsing and conversion +# (rather than attempting to do it itself) as the Git parser has +# been well tested in the wild. +# + +# Frontends should prefer the `raw` format if the source material +# already uses UNIX-epoch format, can be coaxed to give dates in that +# format, or its format is easily convertible to it, as there is no +# ambiguity in parsing. +# +# `now`:: +# Always use the current time and time zone. The literal +# `now` must always be supplied for `<when>`. +# + +# This is a toy format. The current time and time zone of this system +# is always copied into the identity string at the time it is being +# created by fast-import. There is no way to specify a different time or +# time zone. +# + +# This particular format is supplied as it's short to implement and +# may be useful to a process that wants to create a new commit +# right now, without needing to use a working directory or +# 'git update-index'. +# + +# If separate `author` and `committer` commands are used in a `commit` +# the timestamps may not match, as the system clock will be polled +# twice (once for each command). The only way to ensure that both +# author and committer identity information has the same timestamp +# is to omit `author` (thus copying from `committer`) or to use a +# date format other than `now`. +# +# Commands +# ~~~~~~~~ +# fast-import accepts several commands to update the current repository +# and control the current import process. More detailed discussion +# (with examples) of each command follows later. +# +parse() { + while get_line; do + case "$line" in +# `commit`:: +# Creates a new branch or updates an existing branch by +# creating a new commit and updating the branch to point at +# the newly created commit. + 'commit '*) cmd_commit "${line#commit }";; +# +# `tag`:: +# Creates an annotated tag object from an existing commit or +# branch. Lightweight tags are not supported by this command, +# as they are not recommended for recording meaningful points +# in time. + 'tag '*) cmd_tag "${line#tag }";; +# +# `reset`:: +# Reset an existing branch (or a new branch) to a specific +# revision. This command must be used to change a branch to +# a specific revision without making a commit on it. + 'reset '*) cmd_reset "${line#reset }";; +# +# `blob`:: +# Convert raw file data into a blob, for future use in a +# `commit` command. This command is optional and is not +# needed to perform an import. + 'blob '*) cmd_blob "${line#blob }";; +# +# `checkpoint`:: +# Forces fast-import to close the current packfile, generate its +# unique SHA-1 checksum and index, and start a new packfile. +# This command is optional and is not needed to perform +# an import. + 'checkpoint '*) cmd_checkpoint "${line#checkpoint }";; +# +# `progress`:: +# Causes fast-import to echo the entire line to its own +# standard output. This command is optional and is not needed +# to perform an import. + 'progress '*) cmd_progress "${line#progress }";; +# +# `done`:: +# Marks the end of the stream. This command is optional +# unless the `done` feature was requested using the +# `--done` command-line option or `feature done` command. + 'done '*) cmd_done "${line#done }";; +# +# `cat-blob`:: +# Causes fast-import to print a blob in 'cat-file --batch' +# format to the file descriptor set with `--cat-blob-fd` or +# `stdout` if unspecified. + 'cat-blob '*) cmd_cat-blob "${line#cat-blob }";; +# +# `ls`:: +# Causes fast-import to print a line describing a directory +# entry in 'ls-tree' format to the file descriptor set with +# `--cat-blob-fd` or `stdout` if unspecified. + 'ls '*) cmd_ls "${line#ls }";; +# +# `feature`:: +# Enable the specified feature. This requires that fast-import +# supports the specified feature, and aborts if it does not. + 'feature '*) cmd_feature "${line#feature }";; +# +# `option`:: +# Specify any of the options listed under OPTIONS that do not +# change stream semantic to suit the frontend's needs. This +# command is optional and is not needed to perform an import. + 'option '*) cmd_option "${line#option }";; + *) die 'Unsupported command: %s' "$line";; + esac + done +# +} +# `commit` +# ~~~~~~~~ +# Create or update a branch with a new commit, recording one logical +# change to the project. +# +cmd_commit() { +# .... +# 'commit' SP <ref> LF + local ref=$1 + get_line +# mark? + get_mark || true +# ('author' (SP <name>)? SP LT <email> GT SP <when> LF)? + if [[ $line = 'author '* ]]; then + author="${line#author }" + get_line + fi +# 'committer' (SP <name>)? SP LT <email> GT SP <when> LF + if [[ $line = 'committer '* ]]; then + committer="${line#committer }" + get_line + else + die "Expected committer but didn't get one"; + fi +# data + get_data +# ('from' SP <commit-ish> LF)? + if [[ $line = 'from '* ]]; then + from="${line#from }" + get_line + fi +# ('merge' SP <commit-ish> LF)* + while [[ $line = 'merge '* ]]; do + parents+=("${line#merge }") + get_line + done +# (filemodify | filedelete | filecopy | filerename | filedeleteall | notemodify)* + while cmd_commit--filemodify || + cmd_commit--filedelete || + cmd_commit--filecopy || + cmd_commit--filerename || + cmd_commit--filedeleteall || + cmd_commit--notemodify + do :; done +# LF? + [[ -n $line ]] || get_line +# .... +} +# +# where `<ref>` is the name of the branch to make the commit on. +# Typically branch names are prefixed with `refs/heads/` in +# Git, so importing the CVS branch symbol `RELENG-1_0` would use +# `refs/heads/RELENG-1_0` for the value of `<ref>`. The value of +# `<ref>` must be a valid refname in Git. As `LF` is not valid in +# a Git refname, no quoting or escaping syntax is supported here. +# +# A `mark` command may optionally appear, requesting fast-import to save a +# reference to the newly created commit for future use by the frontend +# (see below for format). It is very common for frontends to mark +# every commit they create, thereby allowing future branch creation +# from any imported commit. +# +# The `data` command following `committer` must supply the commit +# message (see below for `data` command syntax). To import an empty +# commit message use a 0 length data. Commit messages are free-form +# and are not interpreted by Git. Currently they must be encoded in +# UTF-8, as fast-import does not permit other encodings to be specified. +# +# Zero or more `filemodify`, `filedelete`, `filecopy`, `filerename`, +# `filedeleteall` and `notemodify` commands +# may be included to update the contents of the branch prior to +# creating the commit. These commands may be supplied in any order. +# However it is recommended that a `filedeleteall` command precede +# all `filemodify`, `filecopy`, `filerename` and `notemodify` commands in +# the same commit, as `filedeleteall` wipes the branch clean (see below). +# +# The `LF` after the command is optional (it used to be required). +# +# `author` +# ^^^^^^^^ +# An `author` command may optionally appear, if the author information +# might differ from the committer information. If `author` is omitted +# then fast-import will automatically use the committer's information for +# the author portion of the commit. See below for a description of +# the fields in `author`, as they are identical to `committer`. +# +# `committer` +# ^^^^^^^^^^^ +# The `committer` command indicates who made this commit, and when +# they made it. +# +# Here `<name>` is the person's display name (for example +# ``Com M Itter'') and `<email>` is the person's email address +# (``\cm@example.com''). `LT` and `GT` are the literal less-than (\x3c) +# and greater-than (\x3e) symbols. These are required to delimit +# the email address from the other fields in the line. Note that +# `<name>` and `<email>` are free-form and may contain any sequence +# of bytes, except `LT`, `GT` and `LF`. `<name>` is typically UTF-8 encoded. +# +# The time of the change is specified by `<when>` using the date format +# that was selected by the --date-format=<fmt> command-line option. +# See ``Date Formats'' above for the set of supported formats, and +# their syntax. +# +# `from` +# ^^^^^^ +# The `from` command is used to specify the commit to initialize +# this branch from. This revision will be the first ancestor of the +# new commit. The state of the tree built at this commit will begin +# with the state at the `from` commit, and be altered by the content +# modifications in this commit. +# +# Omitting the `from` command in the first commit of a new branch +# will cause fast-import to create that commit with no ancestor. This +# tends to be desired only for the initial commit of a project. +# If the frontend creates all files from scratch when making a new +# branch, a `merge` command may be used instead of `from` to start +# the commit with an empty tree. +# Omitting the `from` command on existing branches is usually desired, +# as the current commit on that branch is automatically assumed to +# be the first ancestor of the new commit. +# +# As `LF` is not valid in a Git refname or SHA-1 expression, no +# quoting or escaping syntax is supported within `<commit-ish>`. +# +# Here `<commit-ish>` is any of the following: +# +# * The name of an existing branch already in fast-import's internal branch +# table. If fast-import doesn't know the name, it's treated as a SHA-1 +# expression. +# +# * A mark reference, `:<idnum>`, where `<idnum>` is the mark number. +# + +# The reason fast-import uses `:` to denote a mark reference is this character +# is not legal in a Git branch name. The leading `:` makes it easy +# to distinguish between the mark 42 (`:42`) and the branch 42 (`42` +# or `refs/heads/42`), or an abbreviated SHA-1 which happened to +# consist only of base-10 digits. +# + +# Marks must be declared (via `mark`) before they can be used. +# +# * A complete 40 byte or abbreviated commit SHA-1 in hex. +# +# * Any valid Git SHA-1 expression that resolves to a commit. See +# ``SPECIFYING REVISIONS'' in linkgit:gitrevisions[7] for details. +# +# * The special null SHA-1 (40 zeros) specifies that the branch is to be +# removed. +# +# The special case of restarting an incremental import from the +# current branch value should be written as: +# ---- +# from refs/heads/branch^0 +# ---- +# The `^0` suffix is necessary as fast-import does not permit a branch to +# start from itself, and the branch is created in memory before the +# `from` command is even read from the input. Adding `^0` will force +# fast-import to resolve the commit through Git's revision parsing library, +# rather than its internal branch table, thereby loading in the +# existing value of the branch. +# +# `merge` +# ^^^^^^^ +# Includes one additional ancestor commit. The additional ancestry +# link does not change the way the tree state is built at this commit. +# If the `from` command is +# omitted when creating a new branch, the first `merge` commit will be +# the first ancestor of the current commit, and the branch will start +# out with no files. An unlimited number of `merge` commands per +# commit are permitted by fast-import, thereby establishing an n-way merge. +# +# Here `<commit-ish>` is any of the commit specification expressions +# also accepted by `from` (see above). +# +# `filemodify` +# ^^^^^^^^^^^^ +# Included in a `commit` command to add a new file or change the +# content of an existing file. This command has two different means +# of specifying the content of the file. +# +cmd_commit--filemodify() { +# External data format:: +# The data content for the file was already supplied by a prior +# `blob` command. The frontend just needs to connect it. +# + +# .... +# 'M' SP <mode> SP <dataref> SP <path> LF +# .... +# + +# Here usually `<dataref>` must be either a mark reference (`:<idnum>`) +# set by a prior `blob` command, or a full 40-byte SHA-1 of an +# existing Git blob object. If `<mode>` is `040000`` then +# `<dataref>` must be the full 40-byte SHA-1 of an existing +# Git tree object or a mark reference set with `--import-marks`. + local re='^M ([0-7]+) (\S+) (.+)' + if [[ $line =~ $re ]]; then + local mode=${BASH_REMATCH[1]} + local dataref=${BASH_REMATCH[2]} + local ifs=$IFS + IFS=$' \t\n' + local path=($(parse_path "${BASH_REMATCH[3]}")) + IFS=$ifs + if [[ -n "${path[1]}" ]]; then + error + fi + get_line + else + return 1 + fi +# +# Inline data format:: +# The data content for the file has not been supplied yet. +# The frontend wants to supply it as part of this modify +# command. +# + +# .... +# 'M' SP <mode> SP 'inline' SP <path> LF +# data +# .... +# + +# See below for a detailed description of the `data` command. + if [[ $dataref = 'inline' ]]; then + get_data + fi +# +# In both formats `<mode>` is the type of file entry, specified +# in octal. Git only supports the following modes: +# +# * `100644` or `644`: A normal (not-executable) file. The majority +# of files in most projects use this mode. If in doubt, this is +# what you want. +# * `100755` or `755`: A normal, but executable, file. +# * `120000`: A symlink, the content of the file will be the link target. +# * `160000`: A gitlink, SHA-1 of the object refers to a commit in +# another repository. Git links can only be specified by SHA or through +# a commit mark. They are used to implement submodules. +# * `040000`: A subdirectory. Subdirectories can only be specified by +# SHA or through a tree mark set with `--import-marks`. +# +} +# In both formats `<path>` is the complete path of the file to be added +# (if not already existing) or modified (if already existing). +# +# A `<path>` string must use UNIX-style directory separators (forward +# slash `/`), may contain any byte other than `LF`, and must not +# start with double quote (`"`). +# +# A path can use C-style string quoting; this is accepted in all cases +# and mandatory if the filename starts with double quote or contains +# `LF`. In C-style quoting, the complete name should be surrounded with +# double quotes, and any `LF`, backslash, or double quote characters +# must be escaped by preceding them with a backslash (e.g., +# `"path/with\n, \\ and \" in it"`). +# +# The value of `<path>` must be in canonical form. That is it must not: +# +# * contain an empty directory component (e.g. `foo//bar` is invalid), +# * end with a directory separator (e.g. `foo/` is invalid), +# * start with a directory separator (e.g. `/foo` is invalid), +# * contain the special component `.` or `..` (e.g. `foo/./bar` and +# `foo/../bar` are invalid). +# +# The root of the tree can be represented by an empty string as `<path>`. +# +# It is recommended that `<path>` always be encoded using UTF-8. +unquote_c_style() { # this is based on the function from git:quote.c + local in=$1 + local out='' + if [[ "${in:0:1}" != '"' ]]; then + return 1 + fi + in=${in:1} + while true; do + #local add="${in%%['"\']*}" + in=${in:${#add}} + out+=$add + case "${in:0:1}" in + '"') + in=${in:1} + printf '%q %q' "$out" "$in" + return 0 + ;; + "\\") + in=${in:1};; + *) + return 1;; + esac + local ch="${in:0:1}" + in=${in:1}; + case "$ch" in + a) ch=$'\a';; + b) ch=$'\b';; + f) ch=$'\f';; + n) ch=$'\n';; + r) ch=$'\r';; + t) ch=$'\t';; + v) ch=$'\v';; + ['"\']) :;; # verbatim + # octal values with first digit over 4 overflow + [0-3]) + ch+="$ch${in:0:2}" + in=${in:2}; + if [[ $ch != [0-3][0-7][0-7] ]]; then + return 1 + fi + ;; + esac + out+=$ch + fi +} +parse_path() { + local str=$1 + local split + if unquote_c_style "$str"; then + : + else + local path="${str%% *}" + local rest="${str#"$path"}" + printf '%q %q' "$path" "$rest" + fi +} +# +# `filedelete` +# ^^^^^^^^^^^^ +# Included in a `commit` command to remove a file or recursively +# delete an entire directory from the branch. If the file or directory +# removal makes its parent directory empty, the parent directory will +# be automatically removed too. This cascades up the tree until the +# first non-empty directory or the root is reached. +# +cmd_commit--filedelete() { +# .... +# 'D' SP <path> LF +# .... + if [[ $line != 'D '* ]]; then + return 1 + fi + local path=${line#D } +# +# here `<path>` is the complete path of the file or subdirectory to +# be removed from the branch. +# See `filemodify` above for a detailed description of `<path>`. +# +} +# `filecopy` +# ^^^^^^^^^^ +# Recursively copies an existing file or subdirectory to a different +# location within the branch. The existing file or directory must +# exist. If the destination exists it will be completely replaced +# by the content copied from the source. +# +cmd_commit--filecopy() { +# .... +# 'C' SP <path> SP <path> LF +# .... +# +# here the first `<path>` is the source location and the second +# `<path>` is the destination. See `filemodify` above for a detailed +# description of what `<path>` may look like. To use a source path +# that contains SP the path must be quoted. +# +# A `filecopy` command takes effect immediately. Once the source +# location has been copied to the destination any future commands +# applied to the source location will not impact the destination of +# the copy. +# +# `filerename` +# ^^^^^^^^^^^^ +# Renames an existing file or subdirectory to a different location +# within the branch. The existing file or directory must exist. If +# the destination exists it will be replaced by the source directory. +# +# .... +# 'R' SP <path> SP <path> LF +# .... +# +# here the first `<path>` is the source location and the second +# `<path>` is the destination. See `filemodify` above for a detailed +# description of what `<path>` may look like. To use a source path +# that contains SP the path must be quoted. +# +# A `filerename` command takes effect immediately. Once the source +# location has been renamed to the destination any future commands +# applied to the source location will create new files there and not +# impact the destination of the rename. +# +# Note that a `filerename` is the same as a `filecopy` followed by a +# `filedelete` of the source location. There is a slight performance +# advantage to using `filerename`, but the advantage is so small +# that it is never worth trying to convert a delete/add pair in +# source material into a rename for fast-import. This `filerename` +# command is provided just to simplify frontends that already have +# rename information and don't want bother with decomposing it into a +# `filecopy` followed by a `filedelete`. +# +# `filedeleteall` +# ^^^^^^^^^^^^^^^ +# Included in a `commit` command to remove all files (and also all +# directories) from the branch. This command resets the internal +# branch structure to have no files in it, allowing the frontend +# to subsequently add all interesting files from scratch. +# +# .... +# 'deleteall' LF +# .... +# +# This command is extremely useful if the frontend does not know +# (or does not care to know) what files are currently on the branch, +# and therefore cannot generate the proper `filedelete` commands to +# update the content. +# +# Issuing a `filedeleteall` followed by the needed `filemodify` +# commands to set the correct content will produce the same results +# as sending only the needed `filemodify` and `filedelete` commands. +# The `filedeleteall` approach may however require fast-import to use slightly +# more memory per active branch (less than 1 MiB for even most large +# projects); so frontends that can easily obtain only the affected +# paths for a commit are encouraged to do so. +# +# `notemodify` +# ^^^^^^^^^^^^ +# Included in a `commit` `<notes_ref>` command to add a new note +# annotating a `<commit-ish>` or change this annotation contents. +# Internally it is similar to filemodify 100644 on `<commit-ish>` +# path (maybe split into subdirectories). It's not advised to +# use any other commands to write to the `<notes_ref>` tree except +# `filedeleteall` to delete all existing notes in this tree. +# This command has two different means of specifying the content +# of the note. +# +# External data format:: +# The data content for the note was already supplied by a prior +# `blob` command. The frontend just needs to connect it to the +# commit that is to be annotated. +# + +# .... +# 'N' SP <dataref> SP <commit-ish> LF +# .... +# + +# Here `<dataref>` can be either a mark reference (`:<idnum>`) +# set by a prior `blob` command, or a full 40-byte SHA-1 of an +# existing Git blob object. +# +# Inline data format:: +# The data content for the note has not been supplied yet. +# The frontend wants to supply it as part of this modify +# command. +# + +# .... +# 'N' SP 'inline' SP <commit-ish> LF +# data +# .... +# + +# See below for a detailed description of the `data` command. +# +# In both formats `<commit-ish>` is any of the commit specification +# expressions also accepted by `from` (see above). +# +# `mark` +# ~~~~~~ +# Arranges for fast-import to save a reference to the current object, allowing +# the frontend to recall this object at a future point in time, without +# knowing its SHA-1. Here the current object is the object creation +# command the `mark` command appears within. This can be `commit`, +# `tag`, and `blob`, but `commit` is the most common usage. +# +# .... +# 'mark' SP ':' <idnum> LF +# .... +# +# where `<idnum>` is the number assigned by the frontend to this mark. +# The value of `<idnum>` is expressed as an ASCII decimal integer. +# The value 0 is reserved and cannot be used as +# a mark. Only values greater than or equal to 1 may be used as marks. +# +# New marks are created automatically. Existing marks can be moved +# to another object simply by reusing the same `<idnum>` in another +# `mark` command. +# +# `tag` +# ~~~~~ +# Creates an annotated tag referring to a specific commit. To create +# lightweight (non-annotated) tags see the `reset` command below. +# +# .... +# 'tag' SP <name> LF +# 'from' SP <commit-ish> LF +# 'tagger' (SP <name>)? SP LT <email> GT SP <when> LF +# data +# .... +# +# where `<name>` is the name of the tag to create. +# +# Tag names are automatically prefixed with `refs/tags/` when stored +# in Git, so importing the CVS branch symbol `RELENG-1_0-FINAL` would +# use just `RELENG-1_0-FINAL` for `<name>`, and fast-import will write the +# corresponding ref as `refs/tags/RELENG-1_0-FINAL`. +# +# The value of `<name>` must be a valid refname in Git and therefore +# may contain forward slashes. As `LF` is not valid in a Git refname, +# no quoting or escaping syntax is supported here. +# +# The `from` command is the same as in the `commit` command; see +# above for details. +# +# The `tagger` command uses the same format as `committer` within +# `commit`; again see above for details. +# +# The `data` command following `tagger` must supply the annotated tag +# message (see below for `data` command syntax). To import an empty +# tag message use a 0 length data. Tag messages are free-form and are +# not interpreted by Git. Currently they must be encoded in UTF-8, +# as fast-import does not permit other encodings to be specified. +# +# Signing annotated tags during import from within fast-import is not +# supported. Trying to include your own PGP/GPG signature is not +# recommended, as the frontend does not (easily) have access to the +# complete set of bytes which normally goes into such a signature. +# If signing is required, create lightweight tags from within fast-import with +# `reset`, then create the annotated versions of those tags offline +# with the standard 'git tag' process. +# +# `reset` +# ~~~~~~~ +# Creates (or recreates) the named branch, optionally starting from +# a specific revision. The reset command allows a frontend to issue +# a new `from` command for an existing branch, or to create a new +# branch from an existing commit without creating a new commit. +# +# .... +# 'reset' SP <ref> LF +# ('from' SP <commit-ish> LF)? +# LF? +# .... +# +# For a detailed description of `<ref>` and `<commit-ish>` see above +# under `commit` and `from`. +# +# The `LF` after the command is optional (it used to be required). +# +# The `reset` command can also be used to create lightweight +# (non-annotated) tags. For example: +# +# ==== +# reset refs/tags/938 +# from :938 +# ==== +# +# would create the lightweight tag `refs/tags/938` referring to +# whatever commit mark `:938` references. +# +# `blob` +# ~~~~~~ +# Requests writing one file revision to the packfile. The revision +# is not connected to any commit; this connection must be formed in +# a subsequent `commit` command by referencing the blob through an +# assigned mark. +# +# .... +# 'blob' LF +# mark? +# data +# .... +# +# The mark command is optional here as some frontends have chosen +# to generate the Git SHA-1 for the blob on their own, and feed that +# directly to `commit`. This is typically more work than it's worth +# however, as marks are inexpensive to store and easy to use. +# +# `data` +# ~~~~~~ +# Supplies raw data (for use as blob/file content, commit messages, or +# annotated tag messages) to fast-import. Data can be supplied using an exact +# byte count or delimited with a terminating line. Real frontends +# intended for production-quality conversions should always use the +# exact byte count format, as it is more robust and performs better. +# The delimited format is intended primarily for testing fast-import. +# +# Comment lines appearing within the `<raw>` part of `data` commands +# are always taken to be part of the body of the data and are therefore +# never ignored by fast-import. This makes it safe to import any +# file/message content whose lines might start with `#`. +# +# Exact byte count format:: +# The frontend must specify the number of bytes of data. +# + +# .... +# 'data' SP <count> LF +# <raw> LF? +# .... +# + +# where `<count>` is the exact number of bytes appearing within +# `<raw>`. The value of `<count>` is expressed as an ASCII decimal +# integer. The `LF` on either side of `<raw>` is not +# included in `<count>` and will not be included in the imported data. +# + +# The `LF` after `<raw>` is optional (it used to be required) but +# recommended. Always including it makes debugging a fast-import +# stream easier as the next command always starts in column 0 +# of the next line, even if `<raw>` did not end with an `LF`. +get_data--exact-byte-count() { + declare -i count="${line#data }" + blob="$(head -c "${count}" | "$RVS" commit.f -)" + get_line + [[ -n $line ]] || get_line +} +# +# Delimited format:: +# A delimiter string is used to mark the end of the data. +# fast-import will compute the length by searching for the delimiter. +# This format is primarily useful for testing and is not +# recommended for real data. +# + +# .... +# 'data' SP '<<' <delim> LF +# <raw> LF +# <delim> LF +# LF? +# .... +# + +# where `<delim>` is the chosen delimiter string. The string `<delim>` +# must not appear on a line by itself within `<raw>`, as otherwise +# fast-import will think the data ends earlier than it really does. The `LF` +# immediately trailing `<raw>` is part of `<raw>`. This is one of +# the limitations of the delimited format, it is impossible to supply +# a data chunk which does not have an LF as its last byte. +# + +# The `LF` after `<delim> LF` is optional (it used to be required). +get_data--delimited() { + local delim="${line#'data <<'}" + blob="$( + while get_line && [[ $line != "$delim" ]]; do + printf '%s\n' "$line" + done | "$RVS" commit.f -)" + get_line + [[ -n $line ]] || get_line +} +get_data() { + if [[ $line = 'data <<'* ]]; then get_data--delimited + elif [[ $line = 'data '+([0-9]) ]]; then get_data--exact-byte-count + else false; fi +} +# +# `checkpoint` +# ~~~~~~~~~~~~ +# Forces fast-import to close the current packfile, start a new one, and to +# save out all current branch refs, tags and marks. +# +# .... +# 'checkpoint' LF +# LF? +# .... +# +# Note that fast-import automatically switches packfiles when the current +# packfile reaches --max-pack-size, or 4 GiB, whichever limit is +# smaller. During an automatic packfile switch fast-import does not update +# the branch refs, tags or marks. +# +# As a `checkpoint` can require a significant amount of CPU time and +# disk IO (to compute the overall pack SHA-1 checksum, generate the +# corresponding index file, and update the refs) it can easily take +# several minutes for a single `checkpoint` command to complete. +# +# Frontends may choose to issue checkpoints during extremely large +# and long running imports, or when they need to allow another Git +# process access to a branch. However given that a 30 GiB Subversion +# repository can be loaded into Git through fast-import in about 3 hours, +# explicit checkpointing may not be necessary. +# +# The `LF` after the command is optional (it used to be required). +# +# `progress` +# ~~~~~~~~~~ +# Causes fast-import to print the entire `progress` line unmodified to +# its standard output channel (file descriptor 1) when the command is +# processed from the input stream. The command otherwise has no impact +# on the current import, or on any of fast-import's internal state. +# +# .... +# 'progress' SP <any> LF +# LF? +# .... +# +# The `<any>` part of the command may contain any sequence of bytes +# that does not contain `LF`. The `LF` after the command is optional. +# Callers may wish to process the output through a tool such as sed to +# remove the leading part of the line, for example: +# +# ==== +# frontend | git fast-import | sed 's/^progress //' +# ==== +# +# Placing a `progress` command immediately after a `checkpoint` will +# inform the reader when the `checkpoint` has been completed and it +# can safely access the refs that fast-import updated. +# +# `cat-blob` +# ~~~~~~~~~~ +# Causes fast-import to print a blob to a file descriptor previously +# arranged with the `--cat-blob-fd` argument. The command otherwise +# has no impact on the current import; its main purpose is to +# retrieve blobs that may be in fast-import's memory but not +# accessible from the target repository. +# +# .... +# 'cat-blob' SP <dataref> LF +# .... +# +# The `<dataref>` can be either a mark reference (`:<idnum>`) +# set previously or a full 40-byte SHA-1 of a Git blob, preexisting or +# ready to be written. +# +# Output uses the same format as `git cat-file --batch`: +# +# ==== +# <sha1> SP 'blob' SP <size> LF +# <contents> LF +# ==== +# +# This command can be used anywhere in the stream that comments are +# accepted. In particular, the `cat-blob` command can be used in the +# middle of a commit but not in the middle of a `data` command. +# +# See ``Responses To Commands'' below for details about how to read +# this output safely. +# +# `ls` +# ~~~~ +# Prints information about the object at a path to a file descriptor +# previously arranged with the `--cat-blob-fd` argument. This allows +# printing a blob from the active commit (with `cat-blob`) or copying a +# blob or tree from a previous commit for use in the current one (with +# `filemodify`). +# +# The `ls` command can be used anywhere in the stream that comments are +# accepted, including the middle of a commit. +# +# Reading from the active commit:: +# This form can only be used in the middle of a `commit`. +# The path names a directory entry within fast-import's +# active commit. The path must be quoted in this case. +# + +# .... +# 'ls' SP <path> LF +# .... +# +# Reading from a named tree:: +# The `<dataref>` can be a mark reference (`:<idnum>`) or the +# full 40-byte SHA-1 of a Git tag, commit, or tree object, +# preexisting or waiting to be written. +# The path is relative to the top level of the tree +# named by `<dataref>`. +# + +# .... +# 'ls' SP <dataref> SP <path> LF +# .... +# +# See `filemodify` above for a detailed description of `<path>`. +# +# Output uses the same format as `git ls-tree <tree> -- <path>`: +# +# ==== +# <mode> SP ('blob' | 'tree' | 'commit') SP <dataref> HT <path> LF +# ==== +# +# The <dataref> represents the blob, tree, or commit object at <path> +# and can be used in later 'cat-blob', 'filemodify', or 'ls' commands. +# +# If there is no file or subtree at that path, 'git fast-import' will +# instead report +# +# ==== +# missing SP <path> LF +# ==== +# +# See ``Responses To Commands'' below for details about how to read +# this output safely. +# +# `feature` +# ~~~~~~~~~ +# Require that fast-import supports the specified feature, or abort if +# it does not. +# +# .... +# 'feature' SP <feature> ('=' <argument>)? LF +# .... +# +# The <feature> part of the command may be any one of the following: +# +# date-format:: +# export-marks:: +# relative-marks:: +# no-relative-marks:: +# force:: +# Act as though the corresponding command-line option with +# a leading '--' was passed on the command line +# (see OPTIONS, above). +# +# import-marks:: +# import-marks-if-exists:: +# Like --import-marks except in two respects: first, only one +# "feature import-marks" or "feature import-marks-if-exists" +# command is allowed per stream; second, an --import-marks= +# or --import-marks-if-exists command-line option overrides +# any of these "feature" commands in the stream; third, +# "feature import-marks-if-exists" like a corresponding +# command-line option silently skips a nonexistent file. +# +# cat-blob:: +# ls:: +# Require that the backend support the 'cat-blob' or 'ls' command. +# Versions of fast-import not supporting the specified command +# will exit with a message indicating so. +# This lets the import error out early with a clear message, +# rather than wasting time on the early part of an import +# before the unsupported command is detected. +# +# notes:: +# Require that the backend support the 'notemodify' (N) +# subcommand to the 'commit' command. +# Versions of fast-import not supporting notes will exit +# with a message indicating so. +# +# done:: +# Error out if the stream ends without a 'done' command. +# Without this feature, errors causing the frontend to end +# abruptly at a convenient point in the stream can go +# undetected. This may occur, for example, if an import +# front end dies in mid-operation without emitting SIGTERM +# or SIGKILL at its subordinate git fast-import instance. +# +# `option` +# ~~~~~~~~ +# Processes the specified option so that git fast-import behaves in a +# way that suits the frontend's needs. +# Note that options specified by the frontend are overridden by any +# options the user may specify to git fast-import itself. +# +# .... +# 'option' SP <option> LF +# .... +# +# The `<option>` part of the command may contain any of the options +# listed in the OPTIONS section that do not change import semantics, +# without the leading '--' and is treated in the same way. +# +# Option commands must be the first commands on the input (not counting +# feature commands), to give an option command after any non-option +# command is an error. +# +# The following command-line options change import semantics and may therefore +# not be passed as option: +# +# * date-format +# * import-marks +# * export-marks +# * cat-blob-fd +# * force +# +# `done` +# ~~~~~~ +# If the `done` feature is not in use, treated as if EOF was read. +# This can be used to tell fast-import to finish early. +# +# If the `--done` command-line option or `feature done` command is +# in use, the `done` command is mandatory and marks the end of the +# stream. diff --git a/modules/tags/Module.mk b/modules/tags/Module.mk index 2a05718..2ef7ffb 100644 --- a/modules/tags/Module.mk +++ b/modules/tags/Module.mk @@ -1,2 +1 @@ -commit/tags : commit/files -commit/tags : commit/tree +commit/tags : commit/blobs commit/tree diff --git a/modules/tree/Module.mk b/modules/tree/Module.mk index 6b0076e..c214a35 100644 --- a/modules/tree/Module.mk +++ b/modules/tree/Module.mk @@ -1 +1 @@ -commit/tree : commit/files +commit/tree : commit/blobs |