2 # Copyright © 2013,2014 Géraud Meyer <graud@gmx.com>
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License version 2 as
6 # published by the Free Software Foundation.
8 # This program is distributed in the hope that it will be useful, but
9 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 # You should have received a copy of the GNU General Public License along
14 # with this program. If not, see <http://www.gnu.org/licenses/>.
16 PROGRAM_NAME
="archives2git"
17 PROGRAM_VERSION
="0.1+"
21 $PROGRAM_NAME - generate a Git history from a series of release tarballs
23 $PROGRAM_NAME [<options>] [--] <archives_and_directories>
25 $PROGRAM_NAME replaces the contents of a Git repository subdir with that of
26 an <archive> file (or of another <directory>) and commits the changes.
28 --repo <work_tree_subdir>
30 How to rename the current \$file in the root directory.
31 --keep-filter <sh_code>
32 Decide whether to ignore the current \$file in the root directory.
35 Author date to use when commiting the current \$arch.
38 It can also expand to a body.
40 Appended to the title as a new paragraph.
42 --gitfilter <nl_separated_args>
46 Eval <sh_code> after having commited and tagged the current \$arch.
51 The following shell variables are usable if appropriate in the shell code
52 snippets passed as command line options: \$arch, \$archdir, \$archname,
53 \$file, \$date, \$author, \$title, \$tagname.
61 An example file is distributed.
65 git-commit-tree(1), git_load_dirs(1)
72 _base
=$
( printf "%s\n" "$_file" |
73 LC_ALL
=C
sed -e 's;\(\([0-9]\{1,\}\.\)\|[-_]\)[0-9]\{1,\}\([-_.]\{0,1\}\([0-9]\{1,\}\|[ab]\|alpha\|beta\|gamma\)\)*$;;' )
74 _version
=${_file#"$_base"}
75 _version
=${_version#"-"}; _version=${_version#"."}; _version=${_version#"_"}
76 printf "%s\n" "${_version}"
80 RENAME
='' # $file $arch $archname
81 FILTER
='false' # $file $arch $archname
82 DATE
='' # $arch $archname
83 TITLE
='echo "$arch"' # $arch $archname
84 BODY
="" # message taken as is
87 FILTERHEAD
= # line separated arguments
89 TAGDEF
='printf version/; get_version "$archname"'
91 # config (file, environment, command line)
92 [ -f "$HOME"/.archives2gitrc
] && .
"$HOME"/.archives2gitrc
93 GIT_WORK_TREE
=${GIT_WORK_TREE-.}
94 # may be a subdir of the top level
99 shift; GIT_WORK_TREE
=$1 ;;
105 shift; ADDARGS
="$ADDARGS $1" ;;
115 shift; CIARGS
="$CIARGS $1" ;;
117 shift; FILTERHEAD
=$1 ;;
130 echo "$PROGRAM_NAME version $PROGRAM_VERSION"
133 echo >&2 "$PROGRAM_NAME: error: unknown option $1"
145 TMPDIR
=$
(mktemp
-d) ||
147 echo >&2 "$PROGRAM_NAME: error: cannot create a temporary directory"
151 # git repository check
152 cd "$GIT_WORK_TREE" &&
153 { test -d .git || git rev-parse
--git-dir >/dev
/null
; } ||
155 echo >&2 "$PROGRAM_NAME: error: not in a git repository ($(pwd))"
158 test -z "$(git status --porcelain)" &&
159 git update-index
-q --refresh ||
161 echo >&2 "$PROGRAM_NAME: error: unstaged files or dirty index"
170 # put the files in the archive dir
174 cp -R "$arch" "$TMPDIR"
176 aunpack
-X "$TMPDIR" "$arch"
179 archname
=$
( printf "%s\n" "$arch" | LC_ALL
=C
sed \
180 -e 's;^\([^/]*/\)*\([^/]\{1,\}\)/\{0,1\}$;\2;' \
181 -e 's;\.\([Zz]\|lzo\|bz\|gz\|bz2\|xz\|lzma\|7z\|lz\|rz\|lrz\)$;;' \
182 -e 's;\.\(tar\|t[Zz]\|tzo\|tbz\|tgz\|tbz2\|txz\|t7z\|tlz\|lha\|lzh\|7z\|alz\|arj\|zip\|rar\|jar\|war\|ace\|cab\|a\|cpio\|shar\|rpm\|deb\)$;;' \
183 -e 's;\.\(orig\)$;;' )
184 # remove (almost) everything from the repository dir
188 [ -e "$file" ] ||
continue
189 [ x
"$file" = x
"." ] ||
[ x
"$file" = x
".." ] ||
[ x
"$file" = x
".git" ] && continue
190 eval "$FILTER" ||
{ git
rm -r "$file" ||
rm -R "$file"; }
192 # move the content of the temp dir to the repository and stage it
193 for file in "$archdir"/* "$archdir"/.
*
195 [ -e "$file" ] ||
continue
196 file=${file#$archdir/}
197 [ x
"$file" = x
"." ] ||
[ x
"$file" = x
".." ] && continue
198 [ -n "$RENAME" ] && name
=$
(eval "$RENAME") || name
=$file
201 [ ! -e .
/"$name" ] ||
rm -R .
/"$name"
202 # remove conflicting file (previously kept or renamed to the same name)
203 mv "$archdir"/"$file" .
/"$name"
204 git add
$ADDARGS .
/"$name"
206 rm -R "$archdir"/"$file"
210 # commit, filter and clean up
212 author
=$
(eval "$AUTHOR")
213 title
=$
(eval "$TITLE")
214 git commit
${AUTHOR:+--author "$author"} -m "$title"${BODY:+"$NL$NL$BODY"} ${DATE:+--date "$date"} $CIARGS
215 if [ -n "$FILTERHEAD" ]
218 git filter-branch
$FILTERHEAD -- HEAD^..HEAD
219 rm -R "$(git rev-parse --git-dir)"/refs
/original
/
224 tagmessage
=$
(eval "$TAG" | LC_ALL
=C
tail -n +2)
225 tagname
=$
(eval "$TAG" | LC_ALL
=C
head -1)
226 git tag
${tagmessage:+-m "$tagmessage"} "$tagname"
232 unset title
date author tagname tagmessage