#!/bin/sh

cat >&2 <<'EOT'
WARNING: git-remote-hg is now maintained independently.
WARNING: For more information visit https://github.com/felipec/git-remote-hg
WARNING:
WARNING: You can pick a directory on your $PATH and download it, e.g.:
WARNING:   $ wget -O $HOME/bin/git-remote-hg \
WARNING:     https://raw.github.com/felipec/git-remote-hg/master/git-remote-hg
WARNING:   $ chmod +x $HOME/bin/git-remote-hg
EOT
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                #!/bin/sh

# Use this tool to rewrite your .git/remotes/ files into the config.

. git-sh-setup

if [ -d "$GIT_DIR"/remotes ]; then
	echo "Rewriting $GIT_DIR/remotes" >&2
	error=0
	# rewrite into config
	{
		cd "$GIT_DIR"/remotes
		ls | while read f; do
			name=$(printf "$f" | tr -c "A-Za-z0-9-" ".")
			sed -n \
			-e "s/^URL:[ 	]*\(.*\)$/remote.$name.url \1 ./p" \
			-e "s/^Pull:[ 	]*\(.*\)$/remote.$name.fetch \1 ^$ /p" \
			-e "s/^Push:[ 	]*\(.*\)$/remote.$name.push \1 ^$ /p" \
			< "$f"
		done
		echo done
	} | while read key value regex; do
		case $key in
		done)
			if [ $error = 0 ]; then
				mv "$GIT_DIR"/remotes "$GIT_DIR"/remotes.old
			fi ;;
		*)
			echo "git config $key "$value" $regex"
			git config $key "$value" $regex || error=1 ;;
		esac
	done
fi
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              #!/bin/sh
# Copyright (c) 2008, Nanako Shiraishi
# Prime rerere database from existing merge commits

me=rerere-train
USAGE=$(cat <<-EOF
usage: $me [--overwrite] <rev-list-args>

    -h, --help            show the help
    -o, --overwrite       overwrite any existing rerere cache
EOF
)

SUBDIRECTORY_OK=Yes

overwrite=0

while test $# -gt 0
do
	opt="$1"
	case "$opt" in
	-h|--help)
		echo "$USAGE"
		exit 0
		;;
	-o|--overwrite)
		overwrite=1
		shift
		break
		;;
	--)
		shift
		break
		;;
	*)
		break
		;;
	esac
done

# Overwrite or help options are not valid except as first arg
for opt in "$@"
do
	case "$opt" in
	-h|--help)
		echo "$USAGE"
		exit 0
		;;
	-o|--overwrite)
		echo "$USAGE"
		exit 0
		;;
	esac
done

. "$(git --exec-path)/git-sh-setup"
require_work_tree
cd_to_toplevel

# Remember original branch
branch=$(git symbolic-ref -q HEAD) ||
original_HEAD=$(git rev-parse --verify HEAD) || {
	echo >&2 "Not on any branch and no commit yet?"
	exit 1
}

mkdir -p "$GIT_DIR/rr-cache" || exit

git rev-list --parents "$@" |
while read commit parent1 other_parents
do
	if test -z "$other_parents"
	then
		# Skip non-merges
		continue
	fi
	git checkout -q "$parent1^0"
	if git merge --no-gpg-sign $other_parents >/dev/null 2>&1
	then
		# Cleanly merges
		continue
	fi
	if test $overwrite = 1
	then
		git rerere forget .
	fi
	if test -s "$GIT_DIR/MERGE_RR"
	then
		git --no-pager show -s --format="Learning from %h %s" "$commit"
		git rerere
		git checkout -q $commit -- .
		git rerere
	fi
	git reset -q --hard  # Might nuke untracked files...
done

if test -z "$branch"
then
	git checkout "$original_HEAD"
else
	git checkout "${branch#refs/heads/}"
fi
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       #!/bin/sh

# This script displays the distribution of longest common hash prefixes.
# This can be used to determine the minimum prefix length to use
# for object names to be unique.

git rev-list --objects --all | sort | perl -lne '
  substr($_, 40) = "";
  # uncomment next line for a distribution of bits instead of hex chars
  # $_ = unpack("B*",pack("H*",$_));
  if (defined $p) {
    ($p ^ $_) =~ /^(\0*)/;
    $common = length $1;
    if (defined $pcommon) {
      $count[$pcommon > $common ? $pcommon : $common]++;
    } else {
      $count[$common]++; # first item
    }
  }
  $p = $_;
  $pcommon = $common;
  END {
    $count[$common]++; # last item
    print "$_: $count[$_]" for 0..$#count;
  }
'
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            #!/usr/bin/perl

use warnings 'all';
use strict;
use Getopt::Long;

my $match_emails;
my $match_names;
my $order_by = 'count';
Getopt::Long::Configure(qw(bundling));
GetOptions(
	'emails|e!' => \$match_emails,
	'names|n!'  => \$match_names,
	'count|c'   => sub { $order_by = 'count' },
	'time|t'    => sub { $order_by = 'stamp' },
) or exit 1;
$match_emails = 1 unless $match_names;

my $email = {};
my $name = {};

open(my $fh, '-|', "git log --format='%at <%aE> %aN'");
while(<$fh>) {
	my ($t, $e, $n) = /(\S+) <(\S+)> (.*)/;
	mark($email, $e, $n, $t);
	mark($name, $n, $e, $t);
}
close($fh);

if ($match_emails) {
	foreach my $e (dups($email)) {
		foreach my $n (vals($email->{$e})) {
			show($n, $e, $email->{$e}->{$n});
		}
		print "\n";
	}
}
if ($match_names) {
	foreach my $n (dups($name)) {
		foreach my $e (vals($name->{$n})) {
			show($n, $e, $name->{$n}->{$e});
		}
		print "\n";
	}
}
exit 0;

sub mark {
	my ($h, $k, $v, $t) = @_;
	my $e = $h->{$k}->{$v} ||= { count => 0, stamp => 0 };
	$e->{count}++;
	$e->{stamp} = $t unless $t < $e->{stamp};
}

sub dups {
	my $h = shift;
	return grep { keys($h->{$_}) > 1 } keys($h);
}

sub vals {
	my $h = shift;
	return sort {
		$h->{$b}->{$order_by} <=> $h->{$a}->{$order_by}
	} keys($h);
}

sub show {
	my ($n, $e, $h) = @_;
	print "$n <$e> ($h->{$order_by})\n";
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         #!/usr/bin/perl
#
# This tool will print vaguely pretty information about a pack.  It
# expects the output of "git verify-pack -v" as input on stdin.
#
# $ git verify-pack -v | packinfo.pl
#
# This prints some full-pack statistics; currently "all sizes", "all
# path sizes", "tree sizes", "tree path sizes", and "depths".
#
# * "all sizes" stats are across every object size in the file;
#   full sizes for base objects, and delta size for deltas.
# * "all path sizes" stats are across all object's "path sizes".
#   A path size is the sum of the size of the delta chain, including the
#   base object.  In other words, it's how many bytes need be read to
#   reassemble the file from deltas.
# * "tree sizes" are object sizes grouped into delta trees.
# * "tree path sizes" are path sizes grouped into delta trees.
# * "depths" should be obvious.
#
# When run as:
#
# $ git verify-pack -v | packinfo.pl -tree
#
# the trees of objects are output along with the stats.  This looks
# like:
#
#   0 commit 031321c6...      803      803
#
#   0   blob 03156f21...     1767     1767
#   1    blob f52a9d7f...       10     1777
#   2     blob a8cc5739...       51     1828
#   3      blob 660e90b1...       15     1843
#   4       blob 0cb8e3bb...       33     1876
#   2     blob e48607f0...      311     2088
#      size: count 6 total 2187 min 10 max 1767 mean 364.50 median 51 std_dev 635.85
# path size: count 6 total 11179 min 1767 max 2088 mean 1863.17 median 1843 std_dev 107.26
#
# The first number after the sha1 is the object size, the second
# number is the path size.  The statistics are across all objects in
# the previous delta tree.  Obviously they are omitted for trees of
# one object.
#
# When run as:
#
# $ git verify-pack -v | packinfo.pl -tree -filenames
#
# it adds filenames to the tree.  Getting this information is slow:
#
#   0   blob 03156f21...     1767     1767 Documentation/git-lost-found.txt @ tags/v1.2.0~142
#   1    blob f52a9d7f...       10     1777 Documentation/git-lost-found.txt @ tags/v1.5.0-rc1~74
#   2     blob a8cc5739...       51     1828 Documentation/git-lost+found.txt @ tags/v0.99.9h^0
#   3      blob 660e90b1...       15     1843 Documentation/git-lost+found.txt @ master~3222^2~2
#   4       blob 0cb8e3bb...       33     1876 Documentation/git-lost+found.txt @ master~3222^2~3
#   2     blob e48607f0...      311     2088 Documentation/git-lost-found.txt @ tags/v1.5.2-rc3~4
#      size: count 6 total 2187 min 10 max 1767 mean 364.50 median 51 std_dev 635.85
# path size: count 6 total 11179 min 1767 max 2088 mean 1863.17 median 1843 std_dev 107.26
#
# When run as:
#
# $ git verify-pack -v | packinfo.pl -dump
#
# it prints out "sha1 size pathsize depth" for each sha1 in lexical
# order.
#
# 000079a2eaef17b7eae70e1f0f635557ea67b644 30 472 7
# 00013cafe6980411aa6fdd940784917b5ff50f0a 44 1542 4
# 000182eacf99cde27d5916aa415921924b82972c 499 499 0
# ...
#
# This is handy for comparing two packs.  Adding "-filenames" will add
# filenames, as per "-tree -filenames" above.

use strict;
use Getopt::Long;

my $filenames = 0;
my $tree = 0;
my $dump = 0;
GetOptions("tree" => \$tree,
           "filenames" => \$filenames,
           "dump" => \$dump);

my %parents;
my %children;
my %sizes;
my @roots;
my %paths;
my %types;
my @commits;
my %names;
my %depths;
my @depths;

while (<STDIN>) {
    my ($sha1, $type, $size, $space, $offset, $depth, $parent) = split(/\s+/, $_);
    next unless ($sha1 =~ /^[0-9a-f]{40}$/);
    $depths{$sha1} = $depth || 0;
    push(@depths, $depth || 0);
    push(@commits, $sha1) if ($type eq 'commit');
    push(@roots, $sha1) unless $parent;
    $parents{$sha1} = $parent;
    $types{$sha1} = $type;
    push(@{$children{$parent}}, $sha1);
    $sizes{$sha1} = $size;
}

if ($filenames && ($tree || $dump)) {
    open(NAMES, "git name-rev --all|");
    while (<NAMES>) {
        if (/^(\S+)\s+(.*)$/) {
            my ($sha1, $name) = ($1, $2);
            $names{$sha1} = $name;
        }
    }
    close NAMES;

    for my $commit (@commits) {
        my $name = $names{$commit};
        open(TREE, "git ls-tree -t -r $commit|");
        print STDERR "Plumbing tree $name\n";
        while (<TREE>) {
            if (/^(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/) {
                my ($mode, $type, $sha1, $path) = ($1, $2, $3, $4);
                $paths{$sha1} = "$path @ $name";
            }
        }
        close TREE;
    }
}

sub stats {
    my @data = sort {$a <=> $b} @_;
    my $min = $data[0];
    my $max = $data[$#data];
    my $total = 0;
    my $count = scalar @data;
    for my $datum (@data) {
        $total += $datum;
    }
    my $mean = $total / $count;
    my $median = $data[int(@data / 2)];
    my $diff_sum = 0;
    for my $datum (@data) {
        $diff_sum += ($datum - $mean)**2;
    }
    my $std_dev = sqrt($diff_sum / $count);
    return ($count, $total, $min, $max, $mean, $median, $std_dev);
}

sub print_stats {
    my $name = shift;
    my ($count, $total, $min, $max, $mean, $median, $std_dev) = stats(@_);
    printf("%s: count %s total %s min %s max %s mean %.2f median %s std_dev %.2f\n",
           $name, $count, $total, $min, $max, $mean, $median, $std_dev);
}

my @sizes;
my @path_sizes;
my @all_sizes;
my @all_path_sizes;
my %path_sizes;

sub dig {
    my ($sha1, $depth, $path_size) = @_;
    $path_size += $sizes{$sha1};
    push(@sizes, $sizes{$sha1});
    push(@all_sizes, $sizes{$sha1});
    push(@path_sizes, $path_size);
    push(@all_path_sizes, $path_size);
    $path_sizes{$sha1} = $path_size;
    if ($tree) {
        printf("%3d%s %6s %s %8d %8d %s\n",
               $depth, (" " x $depth), $types{$sha1},
               $sha1, $sizes{$sha1}, $path_size, $paths{$sha1});
    }
    for my $child (@{$children{$sha1}}) {
        dig($child, $depth + 1, $path_size);
    }
}

my @tree_sizes;
my @tree_path_sizes;

for my $root (@roots) {
    undef @sizes;
    undef @path_sizes;
    dig($root, 0, 0);
    my ($aa, $sz_total) = stats(@sizes);
    my ($bb, $psz_total) = stats(@path_sizes);
    push(@tree_sizes, $sz_total);
    push(@tree_path_sizes, $psz_total);
    if ($tree) {
        if (@sizes > 1) {
            print_stats("     size", @sizes);
            print_stats("path size", @path_sizes);
        }
        print "\n";
    }
}

if ($dump) {
    for my $sha1 (sort keys %sizes) {
        print "$sha1 $sizes{$sha1} $path_sizes{$sha1} $depths{$sha1} $paths{$sha1}\n";
    }
} else {
    print_stats("      all sizes", @all_sizes);
    print_stats(" all path sizes", @all_path_sizes);
    print_stats("     tree sizes", @tree_sizes);
    print_stats("tree path sizes", @tree_path_sizes);
    print_stats("         depths", @depths);
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             HOW TO INSTALL git-subtree
==========================

First, build from the top source directory.

Then, in contrib/subtree, run:

  make
  make install
  make install-doc

If you used configure to do the main build the git-subtree build will
pick up those settings.  If not, you will likely have to provide a
value for prefix:

  make prefix=<some dir>
  make prefix=<some dir> install
  make prefix=<some dir> install-doc

To run tests first copy git-subtree to the main build area so the
newly-built git can find it:

  cp git-subtree ../..

Then:

  make test

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          # The default target of this Makefile is...
all::

-include ../../config.mak.autogen
-include ../../config.mak

prefix ?= /usr/local
gitexecdir ?= $(prefix)/libexec/git-core
mandir ?= $(prefix)/share/man
man1dir ?= $(mandir)/man1
htmldir ?= $(prefix)/share/doc/git-doc

../../GIT-VERSION-FILE: FORCE
	$(MAKE) -C ../../ GIT-VERSION-FILE

-include ../../GIT-VERSION-FILE

# this should be set to a 'standard' bsd-type install program
INSTALL  ?= install
RM       ?= rm -f

ASCIIDOC         = asciidoc
ASCIIDOC_CONF    = -f ../../Documentation/asciidoc.conf
ASCIIDOC_HTML    = xhtml11
ASCIIDOC_DOCBOOK = docbook
ASCIIDOC_EXTRA   =
XMLTO            = xmlto
XMLTO_EXTRA      =

ifdef USE_ASCIIDOCTOR
ASCIIDOC         = asciidoctor
ASCIIDOC_CONF    =
ASCIIDOC_HTML    = xhtml5
ASCIIDOC_DOCBOOK = docbook
ASCIIDOC_EXTRA  += -I../../Documentation -rasciidoctor-extensions
ASCIIDOC_EXTRA  += -alitdd='&\#x2d;&\#x2d;'
XMLTO_EXTRA     += --skip-validation
endif

ifndef SHELL_PATH
	SHELL_PATH = /bin/sh
endif
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))

MANPAGE_XSL   = ../../Documentation/manpage-normal.xsl

GIT_SUBTREE_SH := git-subtree.sh
GIT_SUBTREE    := git-subtree

GIT_SUBTREE_DOC := git-subtree.1
GIT_SUBTREE_XML := git-subtree.xml
GIT_SUBTREE_TXT := git-subtree.txt
GIT_SUBTREE_HTML := git-subtree.html
GIT_SUBTREE_TEST := ../../git-subtree

all:: $(GIT_SUBTREE)

$(GIT_SUBTREE): $(GIT_SUBTREE_SH)
	sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' $< >$@
	chmod +x $@

doc: $(GIT_SUBTREE_DOC) $(GIT_SUBTREE_HTML)

man: $(GIT_SUBTREE_DOC)

html: $(GIT_SUBTREE_HTML)

install: $(GIT_SUBTREE)
	$(INSTALL) -d -m 755 $(DESTDIR)$(gitexecdir)
	$(INSTALL) -m 755 $(GIT_SUBTREE) $(DESTDIR)$(gitexecdir)

install-doc: install-man install-html

install-man: $(GIT_SUBTREE_DOC)
	$(INSTALL) -d -m 755 $(DESTDIR)$(man1dir)
	$(INSTALL) -m 644 $^ $(DESTDIR)$(man1dir)

install-html: $(GIT_SUBTREE_HTML)
	$(INSTALL) -d -m 755 $(DESTDIR)$(htmldir)
	$(INSTALL) -m 644 $^ $(DESTDIR)$(htmldir)

$(GIT_SUBTREE_DOC): $(GIT_SUBTREE_XML)
	$(XMLTO) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $^

$(GIT_SUBTREE_XML): $(GIT_SUBTREE_TXT)
	$(ASCIIDOC) -b $(ASCIIDOC_DOCBOOK) -d manpage $(ASCIIDOC_CONF) \
		-agit_version=$(GIT_VERSION) $(ASCIIDOC_EXTRA) $^

$(GIT_SUBTREE_HTML): $(GIT_SUBTREE_TXT)
	$(ASCIIDOC) -b $(ASCIIDOC_HTML) -d manpage $(ASCIIDOC_CONF) \
		-agit_version=$(GIT_VERSION) $(ASCIIDOC_EXTRA) $^

$(GIT_SUBTREE_TEST): $(GIT_SUBTREE)
	cp $< $@

test: $(GIT_SUBTREE_TEST)
	$(MAKE) -C t/ test

clean:
	$(RM) $(GIT_SUBTREE)
	$(RM) *.xml *.html *.1

.PHONY: FORCE
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
Please read git-subtree.txt for documentation.

Please don't contact me using github mail; it's slow, ugly, and worst of
all, redundant. Email me instead at apenwarr@gmail.com and I'll be happy to
help.

Avery
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             #!/bin/sh
#
# git-subtree.sh: split/join git repositories in subdirectories of this one
#
# Copyright (C) 2009 Avery Pennarun <apenwarr@gmail.com>
#

if test -z "$GIT_EXEC_PATH" || ! test -f "$GIT_EXEC_PATH/git-sh-setup" || {
	test "${PATH#"${GIT_EXEC_PATH}:"}" = "$PATH" &&
	test ! "$GIT_EXEC_PATH" -ef "${PATH%%:*}" 2>/dev/null
}
then
	basename=${0##*[/\\]}
	echo >&2 'It looks like either your git installation or your'
	echo >&2 'git-subtree installation is broken.'
	echo >&2
	echo >&2 "Tips:"
	echo >&2 " - If \`git --exec-path\` does not print the correct path to"
	echo >&2 "   your git install directory, then set the GIT_EXEC_PATH"
	echo >&2 "   environment variable to the correct directory."
	echo >&2 " - Make sure that your \`$basename\` file is either in your"
	echo >&2 "   PATH or in your git exec path (\`$(git --exec-path)\`)."
	echo >&2 " - You should run git-subtree as \`git ${basename#git-}\`,"
	echo >&2 "   not as \`$basename\`." >&2
	exit 126
fi

OPTS_SPEC="\
git subtree add   --prefix=<prefix> <commit>
git subtree add   --prefix=<prefix> <repository> <ref>
git subtree merge --prefix=<prefix> <commit>
git subtree split --prefix=<prefix> [<commit>]
git subtree pull  --prefix=<prefix> <repository> <ref>
git subtree push  --prefix=<prefix> <repository> <refspec>
--
h,help        show the help
q             quiet
d             show debug messages
P,prefix=     the name of the subdir to split out
 options for 'split' (also: 'push')
annotate=     add a prefix to commit message of new commits
b,branch=     create a new branch from the split subtree
ignore-joins  ignore prior --rejoin commits
onto=         try connecting new tree to an existing one
rejoin        merge the new branch back into HEAD
 options for 'add' and 'merge' (also: 'pull', 'split --rejoin', and 'push --rejoin')
squash        merge subtree changes as a single commit
m,message=    use the given message as the commit message for the merge commit
"

indent=0

# Usage: say [MSG...]
say () {
	if test -z "$arg_quiet"
	then
		printf '%s\n' "$*"
	fi
}

# Usage: debug [MSG...]
debug () {
	if test -n "$arg_debug"
	then
		printf "%$(($indent * 2))s%s\n" '' "$*" >&2
	fi
}

# Usage: progress [MSG...]
progress () {
	if test -z "$arg_quiet"
	then
		if test -z "$arg_debug"
		then
			# Debug mode is off.
			#
			# Print one progress line that we keep updating (use
			# "\r" to return to the beginning of the line, rather
			# than "\n" to start a new line).  This only really
			# works when stderr is a terminal.
			printf "%s\r" "$*" >&2
		else
			# Debug mode is on.  The `debug` function is regularly
			# printing to stderr.
			#
			# Don't do the one-line-with-"\r" thing, because on a
			# terminal the debug output would overwrite and hide the
			# progress output.  Add a "progress:" prefix to make the
			# progress output and the debug output easy to
			# distinguish.  This ensures maximum readability whether
			# stderr is a terminal or a file.
			printf "progress: %s\n" "$*" >&2
		fi
	fi
}

# Usage: assert CMD...
assert () {
	if ! "$@"
	then
		die "fatal: assertion failed: $*"
	fi
}

# Usage: die_incompatible_opt OPTION COMMAND
die_incompatible_opt () {
	assert test "$#" = 2
	opt="$1"
	arg_command="$2"
	die "fatal: the '$opt' flag does not make sense with 'git subtree $arg_command'."
}

main () {
	if test $# -eq 0
	then
		set -- -h
	fi
	set_args="$(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)"
	eval "$set_args"
	. git-sh-setup
	require_work_tree

	# First figure out the command and whether we use --rejoin, so
	# that we can provide more helpful validation when we do the
	# "real" flag parsing.
	arg_split_rejoin=
	allow_split=
	allow_addmerge=
	while test $# -gt 0
	do
		opt="$1"
		shift
		case "$opt" in
			--annotate|-b|-P|-m|--onto)
				shift
				;;
			--rejoin)
				arg_split_rejoin=1
				;;
			--no-rejoin)
				arg_split_rejoin=
				;;
			--)
				break
				;;
		esac
	done
	arg_command=$1
	case "$arg_command" in
	add|merge|pull)
		allow_addmerge=1
		;;
	split|push)
		allow_split=1
		allow_addmerge=$arg_split_rejoin
		;;
	*)
		die "fatal: unknown command '$arg_command'"
		;;
	esac
	# Reset the arguments array for "real" flag parsing.
	eval "$set_args"

	# Begin "real" flag parsing.
	arg_quiet=
	arg_debug=
	arg_prefix=
	arg_split_branch=
	arg_split_onto=
	arg_split_ignore_joins=
	arg_split_annotate=
	arg_addmerge_squash=
	arg_addmerge_message=
	while test $# -gt 0
	do
		opt="$1"
		shift

		case "$opt" in
		-q)
			arg_quiet=1
			;;
		-d)
			arg_debug=1
			;;
		--annotate)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			arg_split_annotate="$1"
			shift
			;;
		--no-annotate)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			arg_split_annotate=
			;;
		-b)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			arg_split_branch="$1"
			shift
			;;
		-P)
			arg_prefix="${1%/}"
			shift
			;;
		-m)
			test -n "$allow_addmerge" || die_incompatible_opt "$opt" "$arg_command"
			arg_addmerge_message="$1"
			shift
			;;
		--no-prefix)
			arg_prefix=
			;;
		--onto)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			arg_split_onto="$1"
			shift
			;;
		--no-onto)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			arg_split_onto=
			;;
		--rejoin)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			;;
		--no-rejoin)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			;;
		--ignore-joins)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			arg_split_ignore_joins=1
			;;
		--no-ignore-joins)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			arg_split_ignore_joins=
			;;
		--squash)
			test -n "$allow_addmerge" || die_incompatible_opt "$opt" "$arg_command"
			arg_addmerge_squash=1
			;;
		--no-squash)
			test -n "$allow_addmerge" || die_incompatible_opt "$opt" "$arg_command"
			arg_addmerge_squash=
			;;
		--)
			break
			;;
		*)
			die "fatal: unexpected option: $opt"
			;;
		esac
	done
	shift

	if test -z "$arg_prefix"
	then
		die "fatal: you must provide the --prefix option."
	fi

	case "$arg_command" in
	add)
		test -e "$arg_prefix" &&
			die "fatal: prefix '$arg_prefix' already exists."
		;;
	*)
		test -e "$arg_prefix" ||
			die "fatal: '$arg_prefix' does not exist; use 'git subtree add'"
		;;
	esac

	dir="$(dirname "$arg_prefix/.")"

	debug "command: {$arg_command}"
	debug "quiet: {$arg_quiet}"
	debug "dir: {$dir}"
	debug "opts: {$*}"
	debug

	"cmd_$arg_command" "$@"
}

# Usage: cache_setup
cache_setup () {
	assert test $# = 0
	cachedir="$GIT_DIR/subtree-cache/$$"
	rm -rf "$cachedir" ||
		die "fatal: can't delete old cachedir: $cachedir"
	mkdir -p "$cachedir" ||
		die "fatal: can't create new cachedir: $cachedir"
	mkdir -p "$cachedir/notree" ||
		die "fatal: can't create new cachedir: $cachedir/notree"
	debug "Using cachedir: $cachedir" >&2
}

# Usage: cache_get [REVS...]
cache_get () {
	for oldrev in "$@"
	do
		if test -r "$cachedir/$oldrev"
		then
			read newrev <"$cachedir/$oldrev"
			echo $newrev
		fi
	done
}

# Usage: cache_miss [REVS...]
cache_miss () {
	for oldrev in "$@"
	do
		if ! test -r "$cachedir/$oldrev"
		then
			echo $oldrev
		fi
	done
}

# Usage: check_parents [REVS...]
check_parents () {
	missed=$(cache_miss "$@") || exit $?
	local indent=$(($indent + 1))
	for miss in $missed
	do
		if ! test -r "$cachedir/notree/$miss"
		then
			debug "incorrect order: $miss"
			process_split_commit "$miss" ""
		fi
	done
}

# Usage: set_notree REV
set_notree () {
	assert test $# = 1
	echo "1" > "$cachedir/notree/$1"
}

# Usage: cache_set OLDREV NEWREV
cache_set () {
	assert test $# = 2
	oldrev="$1"
	newrev="$2"
	if test "$oldrev" != "latest_old" &&
		test "$oldrev" != "latest_new" &&
		test -e "$cachedir/$oldrev"
	then
		die "fatal: cache for $oldrev already exists!"
	fi
	echo "$newrev" >"$cachedir/$oldrev"
}

# Usage: rev_exists REV
rev_exists () {
	assert test $# = 1
	if git rev-parse "$1" >/dev/null 2>&1
	then
		return 0
	else
		return 1
	fi
}

# Usage: try_remove_previous REV
#
# If a commit doesn't have a parent, this might not work.  But we only want
# to remove the parent from the rev-list, and since it doesn't exist, it won't
# be there anyway, so do nothing in that case.
try_remove_previous () {
	assert test $# = 1
	if rev_exists "$1^"
	then
		echo "^$1^"
	fi
}

# Usage: process_subtree_split_trailer SPLIT_HASH MAIN_HASH [REPOSITORY]
process_subtree_split_trailer () {
	assert test $# = 2 -o $# = 3
	b="$1"
	sq="$2"
	repository=""
	if test "$#" = 3
	then
		repository="$3"
	fi
	fail_msg="fatal: could not rev-parse split hash $b from commit $sq"
	if ! sub="$(git rev-parse --verify --quiet "$b^{commit}")"
	then
		# if 'repository' was given, try to fetch the 'git-subtree-split' hash
		# before 'rev-parse'-ing it again, as it might be a tag that we do not have locally
		if test -n "${repository}"
		then
			git fetch "$repository" "$b"
			sub="$(git rev-parse --verify --quiet "$b^{commit}")" ||
				die "$fail_msg"
		else
			hint1=$(printf "hint: hash might be a tag, try fetching it from the subtree repository:")
			hint2=$(printf "hint:    git fetch <subtree-repository> $b")
			fail_msg=$(printf "$fail_msg\n$hint1\n$hint2")
			die "$fail_msg"
		fi
	fi
}

# Usage: find_latest_squash DIR [REPOSITORY]
find_latest_squash () {
	assert test $# = 1 -o $# = 2
	dir="$1"
	repository=""
	if test "$#" = 2
	then
		repository="$2"
	fi
	debug "Looking for latest squash (dir=$dir, repository=$repository)..."
	local indent=$(($indent + 1))

	sq=
	main=
	sub=
	git log --grep="^git-subtree-dir: $dir/*\$" \
		--no-show-signature --pretty=format:'START %H%n%s%n%n%b%nEND%n' HEAD |
	while read a b junk
	do
		debug "$a $b $junk"
		debug "{{$sq/$main/$sub}}"
		case "$a" in
		START)
			sq="$b"
			;;
		git-subtree-mainline:)
			main="$b"
			;;
		git-subtree-split:)
			process_subtree_split_trailer "$b" "$sq" "$repository"
			;;
		END)
			if test -n "$sub"
			then
				if test -n "$main"
				then
					# a rejoin commit?
					# Pretend its sub was a squash.
					sq=$(git rev-parse --verify "$sq^2") ||
						die
				fi
				debug "Squash found: $sq $sub"
				echo "$sq" "$sub"
				break
			fi
			sq=
			main=
			sub=
			;;
		esac
	done || exit $?
}

# Usage: find_existing_splits DIR REV [REPOSITORY]
find_existing_splits () {
	assert test $# = 2 -o $# = 3
	debug "Looking for prior splits..."
	local indent=$(($indent + 1))

	dir="$1"
	rev="$2"
	repository=""
	if test "$#" = 3
	then
		repository="$3"
	fi
	main=
	sub=
	local grep_format="^git-subtree-dir: $dir/*\$"
	if test -n "$arg_split_ignore_joins"
	then
		grep_format="^Add '$dir/' from commit '"
	fi
	git log --grep="$grep_format" \
		--no-show-signature --pretty=format:'START %H%n%s%n%n%b%nEND%n' "$rev" |
	while read a b junk
	do
		case "$a" in
		START)
			sq="$b"
			;;
		git-subtree-mainline:)
			main="$b"
			;;
		git-subtree-split:)
			process_subtree_split_trailer "$b" "$sq" "$repository"
			;;
		END)
			debug "Main is: '$main'"
			if test -z "$main" -a -n "$sub"
			then
				# squash commits refer to a subtree
				debug "  Squash: $sq from $sub"
				cache_set "$sq" "$sub"
			fi
			if test -n "$main" -a -n "$sub"
			then
				debug "  Prior: $main -> $sub"
				cache_set $main $sub
				cache_set $sub $sub
				try_remove_previous "$main"
				try_remove_previous "$sub"
			fi
			main=
			sub=
			;;
		esac
	done || exit $?
}

# Usage: copy_commit REV TREE FLAGS_STR
copy_commit () {
	assert test $# = 3
	# We're going to set some environment vars here, so
	# do it in a subshell to get rid of them safely later
	debug copy_commit "{$1}" "{$2}" "{$3}"
	git log -1 --no-show-signature --pretty=format:'%an%n%ae%n%aD%n%cn%n%ce%n%cD%n%B' "$1" |
	(
		read GIT_AUTHOR_NAME
		read GIT_AUTHOR_EMAIL
		read GIT_AUTHOR_DATE
		read GIT_COMMITTER_NAME
		read GIT_COMMITTER_EMAIL
		read GIT_COMMITTER_DATE
		export  GIT_AUTHOR_NAME \
			GIT_AUTHOR_EMAIL \
			GIT_AUTHOR_DATE \
			GIT_COMMITTER_NAME \
			GIT_COMMITTER_EMAIL \
			GIT_COMMITTER_DATE
		(
			printf "%s" "$arg_split_annotate"
			cat
		) |
		git commit-tree "$2" $3  # reads the rest of stdin
	) || die "fatal: can't copy commit $1"
}

# Usage: add_msg DIR LATEST_OLD LATEST_NEW
add_msg () {
	assert test $# = 3
	dir="$1"
	latest_old="$2"
	latest_new="$3"
	if test -n "$arg_addmerge_message"
	then
		commit_message="$arg_addmerge_message"
	else
		commit_message="Add '$dir/' from commit '$latest_new'"
	fi
	if test -n "$arg_split_rejoin"
	then
		# If this is from a --rejoin, then rejoin_msg has
		# already inserted the `git-subtree-xxx:` tags
		echo "$commit_message"
		return
	fi
	cat <<-EOF
		$commit_message

		git-subtree-dir: $dir
		git-subtree-mainline: $latest_old
		git-subtree-split: $latest_new
	EOF
}

# Usage: add_squashed_msg REV DIR
add_squashed_msg () {
	assert test $# = 2
	if test -n "$arg_addmerge_message"
	then
		echo "$arg_addmerge_message"
	else
		echo "Merge commit '$1' as '$2'"
	fi
}

# Usage: rejoin_msg DIR LATEST_OLD LATEST_NEW
rejoin_msg () {
	assert test $# = 3
	dir="$1"
	latest_old="$2"
	latest_new="$3"
	if test -n "$arg_addmerge_message"
	then
		commit_message="$arg_addmerge_message"
	else
		commit_message="Split '$dir/' into commit '$latest_new'"
	fi
	cat <<-EOF
		$commit_message

		git-subtree-dir: $dir
		git-subtree-mainline: $latest_old
		git-subtree-split: $latest_new
	EOF
}

# Usage: squash_msg DIR OLD_SUBTREE_COMMIT NEW_SUBTREE_COMMIT
squash_msg () {
	assert test $# = 3
	dir="$1"
	oldsub="$2"
	newsub="$3"
	newsub_short=$(git rev-parse --short "$newsub")

	if test -n "$oldsub"
	then
		oldsub_short=$(git rev-parse --short "$oldsub")
		echo "Squashed '$dir/' changes from $oldsub_short..$newsub_short"
		echo
		git log --no-show-signature --pretty=tformat:'%h %s' "$oldsub..$newsub"
		git log --no-show-signature --pretty=tformat:'REVERT: %h %s' "$newsub..$oldsub"
	else
		echo "Squashed '$dir/' content from commit $newsub_short"
	fi

	echo
	echo "git-subtree-dir: $dir"
	echo "git-subtree-split: $newsub"
}

# Usage: toptree_for_commit COMMIT
toptree_for_commit () {
	assert test $# = 1
	commit="$1"
	git rev-parse --verify "$commit^{tree}" || exit $?
}

# Usage: subtree_for_commit COMMIT DIR
subtree_for_commit () {
	assert test $# = 2
	commit="$1"
	dir="$2"
	git ls-tree "$commit" -- "$dir" |
	while read mode type tree name
	do
		assert test "$name" = "$dir"
		assert test "$type" = "tree" -o "$type" = "commit"
		test "$type" = "commit" && continue  # ignore submodules
		echo $tree
		break
	done || exit $?
}

# Usage: tree_changed TREE [PARENTS...]
tree_changed () {
	assert test $# -gt 0
	tree=$1
	shift
	if test $# -ne 1
	then
		return 0   # weird parents, consider it changed
	else
		ptree=$(toptree_for_commit $1) || exit $?
		if test "$ptree" != "$tree"
		then
			return 0   # changed
		else
			return 1   # not changed
		fi
	fi
}

# Usage: new_squash_commit OLD_SQUASHED_COMMIT OLD_NONSQUASHED_COMMIT NEW_NONSQUASHED_COMMIT
new_squash_commit () {
	assert test $# = 3
	old="$1"
	oldsub="$2"
	newsub="$3"
	tree=$(toptree_for_commit $newsub) || exit $?
	if test -n "$old"
	then
		squash_msg "$dir" "$oldsub" "$newsub" |
		git commit-tree "$tree" -p "$old" || exit $?
	else
		squash_msg "$dir" "" "$newsub" |
		git commit-tree "$tree" || exit $?
	fi
}

# Usage: copy_or_skip REV TREE NEWPARENTS
copy_or_skip () {
	assert test $# = 3
	rev="$1"
	tree="$2"
	newparents="$3"
	assert test -n "$tree"

	identical=
	nonidentical=
	p=
	gotparents=
	copycommit=
	for parent in $newparents
	do
		ptree=$(toptree_for_commit $parent) || exit $?
		test -z "$ptree" && continue
		if test "$ptree" = "$tree"
		then
			# an identical parent could be used in place of this rev.
			if test -n "$identical"
			then
				# if a previous identical parent was found, check whether
				# one is already an ancestor of the other
				mergebase=$(git merge-base $identical $parent)
				if test "$identical" = "$mergebase"
				then
					# current identical commit is an ancestor of parent
					identical="$parent"
				elif test "$parent" != "$mergebase"
				then
					# no common history; commit must be copied
					copycommit=1
				fi
			else
				# first identical parent detected
				identical="$parent"
			fi
		else
			nonidentical="$parent"
		fi

		# sometimes both old parents map to the same newparent;
		# eliminate duplicates
		is_new=1
		for gp in $gotparents
		do
			if test "$gp" = "$parent"
			then
				is_new=
				break
			fi
		done
		if test -n "$is_new"
		then
			gotparents="$gotparents $parent"
			p="$p -p $parent"
		fi
	done

	if test -n "$identical" && test -n "$nonidentical"
	then
		extras=$(git rev-list --count $identical..$nonidentical)
		if test "$extras" -ne 0
		then
			# we need to preserve history along the other branch
			copycommit=1
		fi
	fi
	if test -n "$identical" && test -z "$copycommit"
	then
		echo $identical
	else
		copy_commit "$rev" "$tree" "$p" || exit $?
	fi
}

# Usage: ensure_clean
ensure_clean () {
	assert test $# = 0
	if ! git diff-index HEAD --exit-code --quiet 2>&1
	then
		die "fatal: working tree has modifications.  Cannot add."
	fi
	if ! git diff-index --cached HEAD --exit-code --quiet 2>&1
	then
		die "fatal: index has modifications.  Cannot add."
	fi
}

# Usage: ensure_valid_ref_format REF
ensure_valid_ref_format () {
	assert test $# = 1
	git check-ref-format "refs/heads/$1" ||
		die "fatal: '$1' does not look like a ref"
}

# Usage: process_split_commit REV PARENTS
process_split_commit () {
	assert test $# = 2
	local rev="$1"
	local parents="$2"

	if test $indent -eq 0
	then
		revcount=$(($revcount + 1))
	else
		# processing commit without normal parent information;
		# fetch from repo
		parents=$(git rev-parse "$rev^@")
		extracount=$(($extracount + 1))
	fi

	progress "$revcount/$revmax ($createcount) [$extracount]"

	debug "Processing commit: $rev"
	local indent=$(($indent + 1))
	exists=$(cache_get "$rev") || exit $?
	if test -n "$exists"
	then
		debug "prior: $exists"
		return
	fi
	createcount=$(($createcount + 1))
	debug "parents: $parents"
	check_parents $parents
	newparents=$(cache_get $parents) || exit $?
	debug "newparents: $newparents"

	tree=$(subtree_for_commit "$rev" "$dir") || exit $?
	debug "tree is: $tree"

	# ugly.  is there no better way to tell if this is a subtree
	# vs. a mainline commit?  Does it matter?
	if test -z "$tree"
	then
		set_notree "$rev"
		if test -n "$newparents"
		then
			cache_set "$rev" "$rev"
		fi
		return
	fi

	newrev=$(copy_or_skip "$rev" "$tree" "$newparents") || exit $?
	debug "newrev is: $newrev"
	cache_set "$rev" "$newrev"
	cache_set latest_new "$newrev"
	cache_set latest_old "$rev"
}

# Usage: cmd_add REV
#    Or: cmd_add REPOSITORY REF
cmd_add () {

	ensure_clean

	if test $# -eq 1
	then
		git rev-parse -q --verify "$1^{commit}" >/dev/null ||
			die "fatal: '$1' does not refer to a commit"

		cmd_add_commit "$@"

	elif test $# -eq 2
	then
		# Technically we could accept a refspec here but we're
		# just going to turn around and add FETCH_HEAD under the
		# specified directory.  Allowing a refspec might be
		# misleading because we won't do anything with any other
		# branches fetched via the refspec.
		ensure_valid_ref_format "$2"

		cmd_add_repository "$@"
	else
		say >&2 "fatal: parameters were '$*'"
		die "Provide either a commit or a repository and commit."
	fi
}

# Usage: cmd_add_repository REPOSITORY REFSPEC
cmd_add_repository () {
	assert test $# = 2
	echo "git fetch" "$@"
	repository=$1
	refspec=$2
	git fetch "$@" || exit $?
	cmd_add_commit FETCH_HEAD
}

# Usage: cmd_add_commit REV
cmd_add_commit () {
	# The rev has already been validated by cmd_add(), we just
	# need to normalize it.
	assert test $# = 1
	rev=$(git rev-parse --verify "$1^{commit}") || exit $?

	debug "Adding $dir as '$rev'..."
	if test -z "$arg_split_rejoin"
	then
		# Only bother doing this if this is a genuine 'add',
		# not a synthetic 'add' from '--rejoin'.
		git read-tree --prefix="$dir" $rev || exit $?
	fi
	git checkout -- "$dir" || exit $?
	tree=$(git write-tree) || exit $?

	headrev=$(git rev-parse --verify HEAD) || exit $?
	if test -n "$headrev" && test "$headrev" != "$rev"
	then
		headp="-p $headrev"
	else
		headp=
	fi

	if test -n "$arg_addmerge_squash"
	then
		rev=$(new_squash_commit "" "" "$rev") || exit $?
		commit=$(add_squashed_msg "$rev" "$dir" |
			git commit-tree "$tree" $headp -p "$rev") || exit $?
	else
		revp=$(peel_committish "$rev") || exit $?
		commit=$(add_msg "$dir" $headrev "$rev" |
			git commit-tree "$tree" $headp -p "$revp") || exit $?
	fi
	git reset "$commit" || exit $?

	say >&2 "Added dir '$dir'"
}

# Usage: cmd_split [REV] [REPOSITORY]
cmd_split () {
	if test $# -eq 0
	then
		rev=$(git rev-parse HEAD)
	elif test $# -eq 1 -o $# -eq 2
	then
		rev=$(git rev-parse -q --verify "$1^{commit}") ||
			die "fatal: '$1' does not refer to a commit"
	else
		die "fatal: you must provide exactly one revision, and optionnally a repository.  Got: '$*'"
	fi
	repository=""
	if test "$#" = 2
	then
		repository="$2"
	fi

	if test -n "$arg_split_rejoin"
	then
		ensure_clean
	fi

	debug "Splitting $dir..."
	cache_setup || exit $?

	if test -n "$arg_split_onto"
	then
		debug "Reading history for --onto=$arg_split_onto..."
		git rev-list $arg_split_onto |
		while read rev
		do
			# the 'onto' history is already just the subdir, so
			# any parent we find there can be used verbatim
			debug "cache: $rev"
			cache_set "$rev" "$rev"
		done || exit $?
	fi

	unrevs="$(find_existing_splits "$dir" "$rev" "$repository")" || exit $?

	# We can't restrict rev-list to only $dir here, because some of our
	# parents have the $dir contents the root, and those won't match.
	# (and rev-list --follow doesn't seem to solve this)
	grl='git rev-list --topo-order --reverse --parents $rev $unrevs'
	revmax=$(eval "$grl" | wc -l)
	revcount=0
	createcount=0
	extracount=0
	eval "$grl" |
	while read rev parents
	do
		process_split_commit "$rev" "$parents"
	done || exit $?

	latest_new=$(cache_get latest_new) || exit $?
	if test -z "$latest_new"
	then
		die "fatal: no new revisions were found"
	fi

	if test -n "$arg_split_rejoin"
	then
		debug "Merging split branch into HEAD..."
		latest_old=$(cache_get latest_old) || exit $?
		arg_addmerge_message="$(rejoin_msg "$dir" "$latest_old" "$latest_new")" || exit $?
		if test -z "$(find_latest_squash "$dir")"
		then
			cmd_add "$latest_new" >&2 || exit $?
		else
			cmd_merge "$latest_new" >&2 || exit $?
		fi
	fi
	if test -n "$arg_split_branch"
	then
		if rev_exists "refs/heads/$arg_split_branch"
		then
			if ! git merge-base --is-ancestor "$arg_split_branch" "$latest_new"
			then
				die "fatal: branch '$arg_split_branch' is not an ancestor of commit '$latest_new'."
			fi
			action='Updated'
		else
			action='Created'
		fi
		git update-ref -m 'subtree split' \
			"refs/heads/$arg_split_branch" "$latest_new" || exit $?
		say >&2 "$action branch '$arg_split_branch'"
	fi
	echo "$latest_new"
	exit 0
}

# Usage: cmd_merge REV [REPOSITORY]
cmd_merge () {
	test $# -eq 1 -o $# -eq 2 ||
		die "fatal: you must provide exactly one revision, and optionally a repository. Got: '$*'"
	rev=$(git rev-parse -q --verify "$1^{commit}") ||
		die "fatal: '$1' does not refer to a commit"
	repository=""
	if test "$#" = 2
	then
		repository="$2"
	fi
	ensure_clean

	if test -n "$arg_addmerge_squash"
	then
		first_split="$(find_latest_squash "$dir" "$repository")" || exit $?
		if test -z "$first_split"
		then
			die "fatal: can't squash-merge: '$dir' was never added."
		fi
		set $first_split
		old=$1
		sub=$2
		if test "$sub" = "$rev"
		then
			say >&2 "Subtree is already at commit $rev."
			exit 0
		fi
		new=$(new_squash_commit "$old" "$sub" "$rev") || exit $?
		debug "New squash commit: $new"
		rev="$new"
	fi

	if test -n "$arg_addmerge_message"
	then
		git merge --no-ff -Xsubtree="$arg_prefix" \
			--message="$arg_addmerge_message" "$rev"
	else
		git merge --no-ff -Xsubtree="$arg_prefix" $rev
	fi
}

# Usage: cmd_pull REPOSITORY REMOTEREF
cmd_pull () {
	if test $# -ne 2
	then
		die "fatal: you must provide <repository> <ref>"
	fi
	repository="$1"
	ref="$2"
	ensure_clean
	ensure_valid_ref_format "$ref"
	git fetch "$repository" "$ref" || exit $?
	cmd_merge FETCH_HEAD "$repository"
}

# Usage: cmd_push REPOSITORY [+][LOCALREV:]REMOTEREF
cmd_push () {
	if test $# -ne 2
	then
		die "fatal: you must provide <repository> <refspec>"
	fi
	if test -e "$dir"
	then
		repository=$1
		refspec=${2#+}
		remoteref=${refspec#*:}
		if test "$remoteref" = "$refspec"
		then
			localrevname_presplit=HEAD
		else
			localrevname_presplit=${refspec%%:*}
		fi
		ensure_valid_ref_format "$remoteref"
		localrev_presplit=$(git rev-parse -q --verify "$localrevname_presplit^{commit}") ||
			die "fatal: '$localrevname_presplit' does not refer to a commit"

		echo "git push using: " "$repository" "$refspec"
		localrev=$(cmd_split "$localrev_presplit" "$repository") || die
		git push "$repository" "$localrev":"refs/heads/$remoteref"
	else
		die "fatal: '$dir' must already exist. Try 'git subtree add'."
	fi
}

main "$@"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     #!/bin/sh
#
# git-subtree.sh: split/join git repositories in subdirectories of this one
#
# Copyright (C) 2009 Avery Pennarun <apenwarr@gmail.com>
#

if test -z "$GIT_EXEC_PATH" || ! test -f "$GIT_EXEC_PATH/git-sh-setup" || {
	test "${PATH#"${GIT_EXEC_PATH}:"}" = "$PATH" &&
	test ! "$GIT_EXEC_PATH" -ef "${PATH%%:*}" 2>/dev/null
}
then
	basename=${0##*[/\\]}
	echo >&2 'It looks like either your git installation or your'
	echo >&2 'git-subtree installation is broken.'
	echo >&2
	echo >&2 "Tips:"
	echo >&2 " - If \`git --exec-path\` does not print the correct path to"
	echo >&2 "   your git install directory, then set the GIT_EXEC_PATH"
	echo >&2 "   environment variable to the correct directory."
	echo >&2 " - Make sure that your \`$basename\` file is either in your"
	echo >&2 "   PATH or in your git exec path (\`$(git --exec-path)\`)."
	echo >&2 " - You should run git-subtree as \`git ${basename#git-}\`,"
	echo >&2 "   not as \`$basename\`." >&2
	exit 126
fi

OPTS_SPEC="\
git subtree add   --prefix=<prefix> <commit>
git subtree add   --prefix=<prefix> <repository> <ref>
git subtree merge --prefix=<prefix> <commit>
git subtree split --prefix=<prefix> [<commit>]
git subtree pull  --prefix=<prefix> <repository> <ref>
git subtree push  --prefix=<prefix> <repository> <refspec>
--
h,help        show the help
q             quiet
d             show debug messages
P,prefix=     the name of the subdir to split out
 options for 'split' (also: 'push')
annotate=     add a prefix to commit message of new commits
b,branch=     create a new branch from the split subtree
ignore-joins  ignore prior --rejoin commits
onto=         try connecting new tree to an existing one
rejoin        merge the new branch back into HEAD
 options for 'add' and 'merge' (also: 'pull', 'split --rejoin', and 'push --rejoin')
squash        merge subtree changes as a single commit
m,message=    use the given message as the commit message for the merge commit
"

indent=0

# Usage: say [MSG...]
say () {
	if test -z "$arg_quiet"
	then
		printf '%s\n' "$*"
	fi
}

# Usage: debug [MSG...]
debug () {
	if test -n "$arg_debug"
	then
		printf "%$(($indent * 2))s%s\n" '' "$*" >&2
	fi
}

# Usage: progress [MSG...]
progress () {
	if test -z "$arg_quiet"
	then
		if test -z "$arg_debug"
		then
			# Debug mode is off.
			#
			# Print one progress line that we keep updating (use
			# "\r" to return to the beginning of the line, rather
			# than "\n" to start a new line).  This only really
			# works when stderr is a terminal.
			printf "%s\r" "$*" >&2
		else
			# Debug mode is on.  The `debug` function is regularly
			# printing to stderr.
			#
			# Don't do the one-line-with-"\r" thing, because on a
			# terminal the debug output would overwrite and hide the
			# progress output.  Add a "progress:" prefix to make the
			# progress output and the debug output easy to
			# distinguish.  This ensures maximum readability whether
			# stderr is a terminal or a file.
			printf "progress: %s\n" "$*" >&2
		fi
	fi
}

# Usage: assert CMD...
assert () {
	if ! "$@"
	then
		die "fatal: assertion failed: $*"
	fi
}

# Usage: die_incompatible_opt OPTION COMMAND
die_incompatible_opt () {
	assert test "$#" = 2
	opt="$1"
	arg_command="$2"
	die "fatal: the '$opt' flag does not make sense with 'git subtree $arg_command'."
}

main () {
	if test $# -eq 0
	then
		set -- -h
	fi
	set_args="$(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)"
	eval "$set_args"
	. git-sh-setup
	require_work_tree

	# First figure out the command and whether we use --rejoin, so
	# that we can provide more helpful validation when we do the
	# "real" flag parsing.
	arg_split_rejoin=
	allow_split=
	allow_addmerge=
	while test $# -gt 0
	do
		opt="$1"
		shift
		case "$opt" in
			--annotate|-b|-P|-m|--onto)
				shift
				;;
			--rejoin)
				arg_split_rejoin=1
				;;
			--no-rejoin)
				arg_split_rejoin=
				;;
			--)
				break
				;;
		esac
	done
	arg_command=$1
	case "$arg_command" in
	add|merge|pull)
		allow_addmerge=1
		;;
	split|push)
		allow_split=1
		allow_addmerge=$arg_split_rejoin
		;;
	*)
		die "fatal: unknown command '$arg_command'"
		;;
	esac
	# Reset the arguments array for "real" flag parsing.
	eval "$set_args"

	# Begin "real" flag parsing.
	arg_quiet=
	arg_debug=
	arg_prefix=
	arg_split_branch=
	arg_split_onto=
	arg_split_ignore_joins=
	arg_split_annotate=
	arg_addmerge_squash=
	arg_addmerge_message=
	while test $# -gt 0
	do
		opt="$1"
		shift

		case "$opt" in
		-q)
			arg_quiet=1
			;;
		-d)
			arg_debug=1
			;;
		--annotate)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			arg_split_annotate="$1"
			shift
			;;
		--no-annotate)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			arg_split_annotate=
			;;
		-b)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			arg_split_branch="$1"
			shift
			;;
		-P)
			arg_prefix="${1%/}"
			shift
			;;
		-m)
			test -n "$allow_addmerge" || die_incompatible_opt "$opt" "$arg_command"
			arg_addmerge_message="$1"
			shift
			;;
		--no-prefix)
			arg_prefix=
			;;
		--onto)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			arg_split_onto="$1"
			shift
			;;
		--no-onto)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			arg_split_onto=
			;;
		--rejoin)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			;;
		--no-rejoin)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			;;
		--ignore-joins)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			arg_split_ignore_joins=1
			;;
		--no-ignore-joins)
			test -n "$allow_split" || die_incompatible_opt "$opt" "$arg_command"
			arg_split_ignore_joins=
			;;
		--squash)
			test -n "$allow_addmerge" || die_incompatible_opt "$opt" "$arg_command"
			arg_addmerge_squash=1
			;;
		--no-squash)
			test -n "$allow_addmerge" || die_incompatible_opt "$opt" "$arg_command"
			arg_addmerge_squash=
			;;
		--)
			break
			;;
		*)
			die "fatal: unexpected option: $opt"
			;;
		esac
	done
	shift

	if test -z "$arg_prefix"
	then
		die "fatal: you must provide the --prefix option."
	fi

	case "$arg_command" in
	add)
		test -e "$arg_prefix" &&
			die "fatal: prefix '$arg_prefix' already exists."
		;;
	*)
		test -e "$arg_prefix" ||
			die "fatal: '$arg_prefix' does not exist; use 'git subtree add'"
		;;
	esac

	dir="$(dirname "$arg_prefix/.")"

	debug "command: {$arg_command}"
	debug "quiet: {$arg_quiet}"
	debug "dir: {$dir}"
	debug "opts: {$*}"
	debug

	"cmd_$arg_command" "$@"
}

# Usage: cache_setup
cache_setup () {
	assert test $# = 0
	cachedir="$GIT_DIR/subtree-cache/$$"
	rm -rf "$cachedir" ||
		die "fatal: can't delete old cachedir: $cachedir"
	mkdir -p "$cachedir" ||
		die "fatal: can't create new cachedir: $cachedir"
	mkdir -p "$cachedir/notree" ||
		die "fatal: can't create new cachedir: $cachedir/notree"
	debug "Using cachedir: $cachedir" >&2
}

# Usage: cache_get [REVS...]
cache_get () {
	for oldrev in "$@"
	do
		if test -r "$cachedir/$oldrev"
		then
			read newrev <"$cachedir/$oldrev"
			echo $newrev
		fi
	done
}

# Usage: cache_miss [REVS...]
cache_miss () {
	for oldrev in "$@"
	do
		if ! test -r "$cachedir/$oldrev"
		then
			echo $oldrev
		fi
	done
}

# Usage: check_parents [REVS...]
check_parents () {
	missed=$(cache_miss "$@") || exit $?
	local indent=$(($indent + 1))
	for miss in $missed
	do
		if ! test -r "$cachedir/notree/$miss"
		then
			debug "incorrect order: $miss"
			process_split_commit "$miss" ""
		fi
	done
}

# Usage: set_notree REV
set_notree () {
	assert test $# = 1
	echo "1" > "$cachedir/notree/$1"
}

# Usage: cache_set OLDREV NEWREV
cache_set () {
	assert test $# = 2
	oldrev="$1"
	newrev="$2"
	if test "$oldrev" != "latest_old" &&
		test "$oldrev" != "latest_new" &&
		test -e "$cachedir/$oldrev"
	then
		die "fatal: cache for $oldrev already exists!"
	fi
	echo "$newrev" >"$cachedir/$oldrev"
}

# Usage: rev_exists REV
rev_exists () {
	assert test $# = 1
	if git rev-parse "$1" >/dev/null 2>&1
	then
		return 0
	else
		return 1
	fi
}

# Usage: try_remove_previous REV
#
# If a commit doesn't have a parent, this might not work.  But we only want
# to remove the parent from the rev-list, and since it doesn't exist, it won't
# be there anyway, so do nothing in that case.
try_remove_previous () {
	assert test $# = 1
	if rev_exists "$1^"
	then
		echo "^$1^"
	fi
}

# Usage: process_subtree_split_trailer SPLIT_HASH MAIN_HASH [REPOSITORY]
process_subtree_split_trailer () {
	assert test $# = 2 -o $# = 3
	b="$1"
	sq="$2"
	repository=""
	if test "$#" = 3
	then
		repository="$3"
	fi
	fail_msg="fatal: could not rev-parse split hash $b from commit $sq"
	if ! sub="$(git rev-parse --verify --quiet "$b^{commit}")"
	then
		# if 'repository' was given, try to fetch the 'git-subtree-split' hash
		# before 'rev-parse'-ing it again, as it might be a tag that we do not have locally
		if test -n "${repository}"
		then
			git fetch "$repository" "$b"
			sub="$(git rev-parse --verify --quiet "$b^{commit}")" ||
				die "$fail_msg"
		else
			hint1=$(printf "hint: hash might be a tag, try fetching it from the subtree repository:")
			hint2=$(printf "hint:    git fetch <subtree-repository> $b")
			fail_msg=$(printf "$fail_msg\n$hint1\n$hint2")
			die "$fail_msg"
		fi
	fi
}

# Usage: find_latest_squash DIR [REPOSITORY]
find_latest_squash () {
	assert test $# = 1 -o $# = 2
	dir="$1"
	repository=""
	if test "$#" = 2
	then
		repository="$2"
	fi
	debug "Looking for latest squash (dir=$dir, repository=$repository)..."
	local indent=$(($indent + 1))

	sq=
	main=
	sub=
	git log --grep="^git-subtree-dir: $dir/*\$" \
		--no-show-signature --pretty=format:'START %H%n%s%n%n%b%nEND%n' HEAD |
	while read a b junk
	do
		debug "$a $b $junk"
		debug "{{$sq/$main/$sub}}"
		case "$a" in
		START)
			sq="$b"
			;;
		git-subtree-mainline:)
			main="$b"
			;;
		git-subtree-split:)
			process_subtree_split_trailer "$b" "$sq" "$repository"
			;;
		END)
			if test -n "$sub"
			then
				if test -n "$main"
				then
					# a rejoin commit?
					# Pretend its sub was a squash.
					sq=$(git rev-parse --verify "$sq^2") ||
						die
				fi
				debug "Squash found: $sq $sub"
				echo "$sq" "$sub"
				break
			fi
			sq=
			main=
			sub=
			;;
		esac
	done || exit $?
}

# Usage: find_existing_splits DIR REV [REPOSITORY]
find_existing_splits () {
	assert test $# = 2 -o $# = 3
	debug "Looking for prior splits..."
	local indent=$(($indent + 1))

	dir="$1"
	rev="$2"
	repository=""
	if test "$#" = 3
	then
		repository="$3"
	fi
	main=
	sub=
	local grep_format="^git-subtree-dir: $dir/*\$"
	if test -n "$arg_split_ignore_joins"
	then
		grep_format="^Add '$dir/' from commit '"
	fi
	git log --grep="$grep_format" \
		--no-show-signature --pretty=format:'START %H%n%s%n%n%b%nEND%n' "$rev" |
	while read a b junk
	do
		case "$a" in
		START)
			sq="$b"
			;;
		git-subtree-mainline:)
			main="$b"
			;;
		git-subtree-split:)
			process_subtree_split_trailer "$b" "$sq" "$repository"
			;;
		END)
			debug "Main is: '$main'"
			if test -z "$main" -a -n "$sub"
			then
				# squash commits refer to a subtree
				debug "  Squash: $sq from $sub"
				cache_set "$sq" "$sub"
			fi
			if test -n "$main" -a -n "$sub"
			then
				debug "  Prior: $main -> $sub"
				cache_set $main $sub
				cache_set $sub $sub
				try_remove_previous "$main"
				try_remove_previous "$sub"
			fi
			main=
			sub=
			;;
		esac
	done || exit $?
}

# Usage: copy_commit REV TREE FLAGS_STR
copy_commit () {
	assert test $# = 3
	# We're going to set some environment vars here, so
	# do it in a subshell to get rid of them safely later
	debug copy_commit "{$1}" "{$2}" "{$3}"
	git log -1 --no-show-signature --pretty=format:'%an%n%ae%n%aD%n%cn%n%ce%n%cD%n%B' "$1" |
	(
		read GIT_AUTHOR_NAME
		read GIT_AUTHOR_EMAIL
		read GIT_AUTHOR_DATE
		read GIT_COMMITTER_NAME
		read GIT_COMMITTER_EMAIL
		read GIT_COMMITTER_DATE
		export  GIT_AUTHOR_NAME \
			GIT_AUTHOR_EMAIL \
			GIT_AUTHOR_DATE \
			GIT_COMMITTER_NAME \
			GIT_COMMITTER_EMAIL \
			GIT_COMMITTER_DATE
		(
			printf "%s" "$arg_split_annotate"
			cat
		) |
		git commit-tree "$2" $3  # reads the rest of stdin
	) || die "fatal: can't copy commit $1"
}

# Usage: add_msg DIR LATEST_OLD LATEST_NEW
add_msg () {
	assert test $# = 3
	dir="$1"
	latest_old="$2"
	latest_new="$3"
	if test -n "$arg_addmerge_message"
	then
		commit_message="$arg_addmerge_message"
	else
		commit_message="Add '$dir/' from commit '$latest_new'"
	fi
	if test -n "$arg_split_rejoin"
	then
		# If this is from a --rejoin, then rejoin_msg has
		# already inserted the `git-subtree-xxx:` tags
		echo "$commit_message"
		return
	fi
	cat <<-EOF
		$commit_message

		git-subtree-dir: $dir
		git-subtree-mainline: $latest_old
		git-subtree-split: $latest_new
	EOF
}

# Usage: add_squashed_msg REV DIR
add_squashed_msg () {
	assert test $# = 2
	if test -n "$arg_addmerge_message"
	then
		echo "$arg_addmerge_message"
	else
		echo "Merge commit '$1' as '$2'"
	fi
}

# Usage: rejoin_msg DIR LATEST_OLD LATEST_NEW
rejoin_msg () {
	assert test $# = 3
	dir="$1"
	latest_old="$2"
	latest_new="$3"
	if test -n "$arg_addmerge_message"
	then
		commit_message="$arg_addmerge_message"
	else
		commit_message="Split '$dir/' into commit '$latest_new'"
	fi
	cat <<-EOF
		$commit_message

		git-subtree-dir: $dir
		git-subtree-mainline: $latest_old
		git-subtree-split: $latest_new
	EOF
}

# Usage: squash_msg DIR OLD_SUBTREE_COMMIT NEW_SUBTREE_COMMIT
squash_msg () {
	assert test $# = 3
	dir="$1"
	oldsub="$2"
	newsub="$3"
	newsub_short=$(git rev-parse --short "$newsub")

	if test -n "$oldsub"
	then
		oldsub_short=$(git rev-parse --short "$oldsub")
		echo "Squashed '$dir/' changes from $oldsub_short..$newsub_short"
		echo
		git log --no-show-signature --pretty=tformat:'%h %s' "$oldsub..$newsub"
		git log --no-show-signature --pretty=tformat:'REVERT: %h %s' "$newsub..$oldsub"
	else
		echo "Squashed '$dir/' content from commit $newsub_short"
	fi

	echo
	echo "git-subtree-dir: $dir"
	echo "git-subtree-split: $newsub"
}

# Usage: toptree_for_commit COMMIT
toptree_for_commit () {
	assert test $# = 1
	commit="$1"
	git rev-parse --verify "$commit^{tree}" || exit $?
}

# Usage: subtree_for_commit COMMIT DIR
subtree_for_commit () {
	assert test $# = 2
	commit="$1"
	dir="$2"
	git ls-tree "$commit" -- "$dir" |
	while read mode type tree name
	do
		assert test "$name" = "$dir"
		assert test "$type" = "tree" -o "$type" = "commit"
		test "$type" = "commit" && continue  # ignore submodules
		echo $tree
		break
	done || exit $?
}

# Usage: tree_changed TREE [PARENTS...]
tree_changed () {
	assert test $# -gt 0
	tree=$1
	shift
	if test $# -ne 1
	then
		return 0   # weird parents, consider it changed
	else
		ptree=$(toptree_for_commit $1) || exit $?
		if test "$ptree" != "$tree"
		then
			return 0   # changed
		else
			return 1   # not changed
		fi
	fi
}

# Usage: new_squash_commit OLD_SQUASHED_COMMIT OLD_NONSQUASHED_COMMIT NEW_NONSQUASHED_COMMIT
new_squash_commit () {
	assert test $# = 3
	old="$1"
	oldsub="$2"
	newsub="$3"
	tree=$(toptree_for_commit $newsub) || exit $?
	if test -n "$old"
	then
		squash_msg "$dir" "$oldsub" "$newsub" |
		git commit-tree "$tree" -p "$old" || exit $?
	else
		squash_msg "$dir" "" "$newsub" |
		git commit-tree "$tree" || exit $?
	fi
}

# Usage: copy_or_skip REV TREE NEWPARENTS
copy_or_skip () {
	assert test $# = 3
	rev="$1"
	tree="$2"
	newparents="$3"
	assert test -n "$tree"

	identical=
	nonidentical=
	p=
	gotparents=
	copycommit=
	for parent in $newparents
	do
		ptree=$(toptree_for_commit $parent) || exit $?
		test -z "$ptree" && continue
		if test "$ptree" = "$tree"
		then
			# an identical parent could be used in place of this rev.
			if test -n "$identical"
			then
				# if a previous identical parent was found, check whether
				# one is already an ancestor of the other
				mergebase=$(git merge-base $identical $parent)
				if test "$identical" = "$mergebase"
				then
					# current identical commit is an ancestor of parent
					identical="$parent"
				elif test "$parent" != "$mergebase"
				then
					# no common history; commit must be copied
					copycommit=1
				fi
			else
				# first identical parent detected
				identical="$parent"
			fi
		else
			nonidentical="$parent"
		fi

		# sometimes both old parents map to the same newparent;
		# eliminate duplicates
		is_new=1
		for gp in $gotparents
		do
			if test "$gp" = "$parent"
			then
				is_new=
				break
			fi
		done
		if test -n "$is_new"
		then
			gotparents="$gotparents $parent"
			p="$p -p $parent"
		fi
	done

	if test -n "$identical" && test -n "$nonidentical"
	then
		extras=$(git rev-list --count $identical..$nonidentical)
		if test "$extras" -ne 0
		then
			# we need to preserve history along the other branch
			copycommit=1
		fi
	fi
	if test -n "$identical" && test -z "$copycommit"
	then
		echo $identical
	else
		copy_commit "$rev" "$tree" "$p" || exit $?
	fi
}

# Usage: ensure_clean
ensure_clean () {
	assert test $# = 0
	if ! git diff-index HEAD --exit-code --quiet 2>&1
	then
		die "fatal: working tree has modifications.  Cannot add."
	fi
	if ! git diff-index --cached HEAD --exit-code --quiet 2>&1
	then
		die "fatal: index has modifications.  Cannot add."
	fi
}

# Usage: ensure_valid_ref_format REF
ensure_valid_ref_format () {
	assert test $# = 1
	git check-ref-format "refs/heads/$1" ||
		die "fatal: '$1' does not look like a ref"
}

# Usage: process_split_commit REV PARENTS
process_split_commit () {
	assert test $# = 2
	local rev="$1"
	local parents="$2"

	if test $indent -eq 0
	then
		revcount=$(($revcount + 1))
	else
		# processing commit without normal parent information;
		# fetch from repo
		parents=$(git rev-parse "$rev^@")
		extracount=$(($extracount + 1))
	fi

	progress "$revcount/$revmax ($createcount) [$extracount]"

	debug "Processing commit: $rev"
	local indent=$(($indent + 1))
	exists=$(cache_get "$rev") || exit $?
	if test -n "$exists"
	then
		debug "prior: $exists"
		return
	fi
	createcount=$(($createcount + 1))
	debug "parents: $parents"
	check_parents $parents
	newparents=$(cache_get $parents) || exit $?
	debug "newparents: $newparents"

	tree=$(subtree_for_commit "$rev" "$dir") || exit $?
	debug "tree is: $tree"

	# ugly.  is there no better way to tell if this is a subtree
	# vs. a mainline commit?  Does it matter?
	if test -z "$tree"
	then
		set_notree "$rev"
		if test -n "$newparents"
		then
			cache_set "$rev" "$rev"
		fi
		return
	fi

	newrev=$(copy_or_skip "$rev" "$tree" "$newparents") || exit $?
	debug "newrev is: $newrev"
	cache_set "$rev" "$newrev"
	cache_set latest_new "$newrev"
	cache_set latest_old "$rev"
}

# Usage: cmd_add REV
#    Or: cmd_add REPOSITORY REF
cmd_add () {

	ensure_clean

	if test $# -eq 1
	then
		git rev-parse -q --verify "$1^{commit}" >/dev/null ||
			die "fatal: '$1' does not refer to a commit"

		cmd_add_commit "$@"

	elif test $# -eq 2
	then
		# Technically we could accept a refspec here but we're
		# just going to turn around and add FETCH_HEAD under the
		# specified directory.  Allowing a refspec might be
		# misleading because we won't do anything with any other
		# branches fetched via the refspec.
		ensure_valid_ref_format "$2"

		cmd_add_repository "$@"
	else
		say >&2 "fatal: parameters were '$*'"
		die "Provide either a commit or a repository and commit."
	fi
}

# Usage: cmd_add_repository REPOSITORY REFSPEC
cmd_add_repository () {
	assert test $# = 2
	echo "git fetch" "$@"
	repository=$1
	refspec=$2
	git fetch "$@" || exit $?
	cmd_add_commit FETCH_HEAD
}

# Usage: cmd_add_commit REV
cmd_add_commit () {
	# The rev has already been validated by cmd_add(), we just
	# need to normalize it.
	assert test $# = 1
	rev=$(git rev-parse --verify "$1^{commit}") || exit $?

	debug "Adding $dir as '$rev'..."
	if test -z "$arg_split_rejoin"
	then
		# Only bother doing this if this is a genuine 'add',
		# not a synthetic 'add' from '--rejoin'.
		git read-tree --prefix="$dir" $rev || exit $?
	fi
	git checkout -- "$dir" || exit $?
	tree=$(git write-tree) || exit $?

	headrev=$(git rev-parse --verify HEAD) || exit $?
	if test -n "$headrev" && test "$headrev" != "$rev"
	then
		headp="-p $headrev"
	else
		headp=
	fi

	if test -n "$arg_addmerge_squash"
	then
		rev=$(new_squash_commit "" "" "$rev") || exit $?
		commit=$(add_squashed_msg "$rev" "$dir" |
			git commit-tree "$tree" $headp -p "$rev") || exit $?
	else
		revp=$(peel_committish "$rev") || exit $?
		commit=$(add_msg "$dir" $headrev "$rev" |
			git commit-tree "$tree" $headp -p "$revp") || exit $?
	fi
	git reset "$commit" || exit $?

	say >&2 "Added dir '$dir'"
}

# Usage: cmd_split [REV] [REPOSITORY]
cmd_split () {
	if test $# -eq 0
	then
		rev=$(git rev-parse HEAD)
	elif test $# -eq 1 -o $# -eq 2
	then
		rev=$(git rev-parse -q --verify "$1^{commit}") ||
			die "fatal: '$1' does not refer to a commit"
	else
		die "fatal: you must provide exactly one revision, and optionnally a repository.  Got: '$*'"
	fi
	repository=""
	if test "$#" = 2
	then
		repository="$2"
	fi

	if test -n "$arg_split_rejoin"
	then
		ensure_clean
	fi

	debug "Splitting $dir..."
	cache_setup || exit $?

	if test -n "$arg_split_onto"
	then
		debug "Reading history for --onto=$arg_split_onto..."
		git rev-list $arg_split_onto |
		while read rev
		do
			# the 'onto' history is already just the subdir, so
			# any parent we find there can be used verbatim
			debug "cache: $rev"
			cache_set "$rev" "$rev"
		done || exit $?
	fi

	unrevs="$(find_existing_splits "$dir" "$rev" "$repository")" || exit $?

	# We can't restrict rev-list to only $dir here, because some of our
	# parents have the $dir contents the root, and those won't match.
	# (and rev-list --follow doesn't seem to solve this)
	grl='git rev-list --topo-order --reverse --parents $rev $unrevs'
	revmax=$(eval "$grl" | wc -l)
	revcount=0
	createcount=0
	extracount=0
	eval "$grl" |
	while read rev parents
	do
		process_split_commit "$rev" "$parents"
	done || exit $?

	latest_new=$(cache_get latest_new) || exit $?
	if test -z "$latest_new"
	then
		die "fatal: no new revisions were found"
	fi

	if test -n "$arg_split_rejoin"
	then
		debug "Merging split branch into HEAD..."
		latest_old=$(cache_get latest_old) || exit $?
		arg_addmerge_message="$(rejoin_msg "$dir" "$latest_old" "$latest_new")" || exit $?
		if test -z "$(find_latest_squash "$dir")"
		then
			cmd_add "$latest_new" >&2 || exit $?
		else
			cmd_merge "$latest_new" >&2 || exit $?
		fi
	fi
	if test -n "$arg_split_branch"
	then
		if rev_exists "refs/heads/$arg_split_branch"
		then
			if ! git merge-base --is-ancestor "$arg_split_branch" "$latest_new"
			then
				die "fatal: branch '$arg_split_branch' is not an ancestor of commit '$latest_new'."
			fi
			action='Updated'
		else
			action='Created'
		fi
		git update-ref -m 'subtree split' \
			"refs/heads/$arg_split_branch" "$latest_new" || exit $?
		say >&2 "$action branch '$arg_split_branch'"
	fi
	echo "$latest_new"
	exit 0
}

# Usage: cmd_merge REV [REPOSITORY]
cmd_merge () {
	test $# -eq 1 -o $# -eq 2 ||
		die "fatal: you must provide exactly one revision, and optionally a repository. Got: '$*'"
	rev=$(git rev-parse -q --verify "$1^{commit}") ||
		die "fatal: '$1' does not refer to a commit"
	repository=""
	if test "$#" = 2
	then
		repository="$2"
	fi
	ensure_clean

	if test -n "$arg_addmerge_squash"
	then
		first_split="$(find_latest_squash "$dir" "$repository")" || exit $?
		if test -z "$first_split"
		then
			die "fatal: can't squash-merge: '$dir' was never added."
		fi
		set $first_split
		old=$1
		sub=$2
		if test "$sub" = "$rev"
		then
			say >&2 "Subtree is already at commit $rev."
			exit 0
		fi
		new=$(new_squash_commit "$old" "$sub" "$rev") || exit $?
		debug "New squash commit: $new"
		rev="$new"
	fi

	if test -n "$arg_addmerge_message"
	then
		git merge --no-ff -Xsubtree="$arg_prefix" \
			--message="$arg_addmerge_message" "$rev"
	else
		git merge --no-ff -Xsubtree="$arg_prefix" $rev
	fi
}

# Usage: cmd_pull REPOSITORY REMOTEREF
cmd_pull () {
	if test $# -ne 2
	then
		die "fatal: you must provide <repository> <ref>"
	fi
	repository="$1"
	ref="$2"
	ensure_clean
	ensure_valid_ref_format "$ref"
	git fetch "$repository" "$ref" || exit $?
	cmd_merge FETCH_HEAD "$repository"
}

# Usage: cmd_push REPOSITORY [+][LOCALREV:]REMOTEREF
cmd_push () {
	if test $# -ne 2
	then
		die "fatal: you must provide <repository> <refspec>"
	fi
	if test -e "$dir"
	then
		repository=$1
		refspec=${2#+}
		remoteref=${refspec#*:}
		if test "$remoteref" = "$refspec"
		then
			localrevname_presplit=HEAD
		else
			localrevname_presplit=${refspec%%:*}
		fi
		ensure_valid_ref_format "$remoteref"
		localrev_presplit=$(git rev-parse -q --verify "$localrevname_presplit^{commit}") ||
			die "fatal: '$localrevname_presplit' does not refer to a commit"

		echo "git push using: " "$repository" "$refspec"
		localrev=$(cmd_split "$localrev_presplit" "$repository") || die
		git push "$repository" "$localrev":"refs/heads/$remoteref"
	else
		die "fatal: '$dir' must already exist. Try 'git subtree add'."
	fi
}

main "$@"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     git-subtree(1)
==============

NAME
----
git-subtree - Merge subtrees together and split repository into subtrees


SYNOPSIS
--------
[verse]
'git subtree' [<options>] -P <prefix> add <local-commit>
'git subtree' [<options>] -P <prefix> add <repository> <remote-ref>
'git subtree' [<options>] -P <prefix> merge <local-commit> [<repository>]
'git subtree' [<options>] -P <prefix> split [<local-commit>]

[verse]
'git subtree' [<options>] -P <prefix> pull <repository> <remote-ref>
'git subtree' [<options>] -P <prefix> push <repository> <refspec>

DESCRIPTION
-----------
Subtrees allow subprojects to be included within a subdirectory
of the main project, optionally including the subproject's
entire history.

For example, you could include the source code for a library
as a subdirectory of your application.

Subtrees are not to be confused with submodules, which are meant for
the same task. Unlike submodules, subtrees do not need any special
constructions (like '.gitmodules' files or gitlinks) be present in
your repository, and do not force end-users of your
repository to do anything special or to understand how subtrees
work. A subtree is just a subdirectory that can be
committed to, branched, and merged along with your project in
any way you want.

They are also not to be confused with using the subtree merge
strategy. The main difference is that, besides merging
the other project as a subdirectory, you can also extract the
entire history of a subdirectory from your project and make it
into a standalone project. Unlike the subtree merge strategy
you can alternate back and forth between these
two operations. If the standalone library gets updated, you can
automatically merge the changes into your project; if you
update the library inside your project, you can "split" the
changes back out again and merge them back into the library
project.

For example, if a library you made for one application ends up being
useful elsewhere, you can extract its entire history and publish
that as its own git repository, without accidentally
intermingling the history of your application project.

[TIP]
In order to keep your commit messages clean, we recommend that
people split their commits between the subtrees and the main
project as much as possible.  That is, if you make a change that
affects both the library and the main application, commit it in
two pieces.  That way, when you split the library commits out
later, their descriptions will still make sense.  But if this
isn't important to you, it's not *necessary*.  'git subtree' will
simply leave out the non-library-related parts of the commit
when it splits it out into the subproject later.


COMMANDS
--------
add <local-commit>::
add <repository> <remote-ref>::
	Create the <prefix> subtree by importing its contents
	from the given <local-commit> or <repository> and <remote-ref>.
	A new commit is created	automatically, joining the imported
	project's history with your own.  With '--squash', import
	only a single commit from the subproject, rather than its
	entire history.

merge <local-commit> [<repository>]::
	Merge recent changes up to <local-commit> into the <prefix>
	subtree.  As with normal 'git merge', this doesn't
	remove your own local changes; it just merges those
	changes into the latest <local-commit>.  With '--squash',
	create only one commit that contains all the changes,
	rather than merging in the entire history.
+
If you use '--squash', the merge direction doesn't always have to be
forward; you can use this command to go back in time from v2.5 to v2.4,
for example.  If your merge introduces a conflict, you can resolve it in
the usual ways.
+
When using '--squash', and the previous merge with '--squash' merged an
annotated tag of the subtree repository, that tag needs to be available locally.
If <repository> is given, a missing tag will automatically be fetched from that
repository.

split [<local-commit>] [<repository>]::
	Extract a new, synthetic project history from the
	history of the <prefix> subtree of <local-commit>, or of
	HEAD if no <local-commit> is given.  The new history
	includes only the commits (including merges) that
	affected <prefix>, and each of those commits now has the
	contents of <prefix> at the root of the project instead
	of in a subdirectory.  Thus, the newly created history
	is suitable for export as a separate git repository.
+
After splitting successfully, a single commit ID is printed to stdout.
This corresponds to the HEAD of the newly created tree, which you can
manipulate however you want.
+
Repeated splits of exactly the same history are guaranteed to be
identical (i.e. to produce the same commit IDs) as long as the
settings passed to 'split' (such as '--annotate') are the same.
Because of this, if you add new commits and then re-split, the new
commits will be attached as commits on top of the history you
generated last time, so 'git merge' and friends will work as expected.
+
When a previous merge with '--squash' merged an annotated tag of the
subtree repository, that tag needs to be available locally.
If <repository> is given, a missing tag will automatically be fetched from that
repository.

pull <repository> <remote-ref>::
	Exactly like 'merge', but parallels 'git pull' in that
	it fetches the given ref from the specified remote
	repository.

push <repository> [+][<local-commit>:]<remote-ref>::
	Does a 'split' using the <prefix> subtree of <local-commit>
	and then does a 'git push' to push the result to the
	<repository> and <remote-ref>.  This can be used to push your
	subtree to different branches of the remote repository.  Just
	as with 'split', if no <local-commit> is given, then HEAD is
	used.  The optional leading '+' is ignored.

OPTIONS FOR ALL COMMANDS
------------------------
-q::
--quiet::
	Suppress unnecessary output messages on stderr.

-d::
--debug::
	Produce even more unnecessary output messages on stderr.

-P <prefix>::
--prefix=<prefix>::
	Specify the path in the repository to the subtree you
	want to manipulate.  This option is mandatory
	for all commands.

OPTIONS FOR 'add' AND 'merge' (ALSO: 'pull', 'split --rejoin', AND 'push --rejoin')
-----------------------------------------------------------------------------------
These options for 'add' and 'merge' may also be given to 'pull' (which
wraps 'merge'), 'split --rejoin' (which wraps either 'add' or 'merge'
as appropriate), and 'push --rejoin' (which wraps 'split --rejoin').

--squash::
	Instead of merging the entire history from the subtree project, produce
	only a single commit that contains all the differences you want to
	merge, and then merge that new commit into your project.
+
Using this option helps to reduce log clutter. People rarely want to see
every change that happened between v1.0 and v1.1 of the library they're
using, since none of the interim versions were ever included in their
application.
+
Using '--squash' also helps avoid problems when the same subproject is
included multiple times in the same project, or is removed and then
re-added.  In such a case, it doesn't make sense to combine the
histories anyway, since it's unclear which part of the history belongs
to which subtree.
+
Furthermore, with '--squash', you can switch back and forth between
different versions of a subtree, rather than strictly forward.  'git
subtree merge --squash' always adjusts the subtree to match the exactly
specified commit, even if getting to that commit would require undoing
some changes that were added earlier.
+
Whether or not you use '--squash', changes made in your local repository
remain intact and can be later split and send upstream to the
subproject.

-m <message>::
--message=<message>::
	Specify <message> as the commit message for the merge commit.

OPTIONS FOR 'split' (ALSO: 'push')
----------------------------------
These options for 'split' may also be given to 'push' (which wraps
'split').

--annotate=<annotation>::
	When generating synthetic history, add <annotation> as a prefix to each
	commit message.  Since we're creating new commits with the same commit
	message, but possibly different content, from the original commits, this
	can help to differentiate them and avoid confusion.
+
Whenever you split, you need to use the same <annotation>, or else you
don't have a guarantee that the new re-created history will be identical
to the old one.  That will prevent merging from working correctly.  git
subtree tries to make it work anyway, particularly if you use '--rejoin',
but it may not always be effective.

-b <branch>::
--branch=<branch>::
	After generating the synthetic history, create a new branch called
	<branch> that contains the new history.  This is suitable for immediate
	pushing upstream.  <branch> must not already exist.

--ignore-joins::
	If you use '--rejoin', git subtree attempts to optimize its history
	reconstruction to generate only the new commits since the last
	'--rejoin'.  '--ignore-joins' disables this behavior, forcing it to
	regenerate the entire history.  In a large project, this can take a long
	time.

--onto=<onto>::
	If your subtree was originally imported using something other than git
	subtree, its history may not match what git subtree is expecting.  In
	that case, you can specify the commit ID <onto> that corresponds to the
	first revision of the subproject's history that was imported into your
	project, and git subtree will attempt to build its history from there.
+
If you used 'git subtree add', you should never need this option.

--rejoin::
	After splitting, merge the newly created synthetic history back into
	your main project.  That way, future splits can search only the part of
	history that has been added since the most recent '--rejoin'.
+
If your split commits end up merged into the upstream subproject, and
then you want to get the latest upstream version, this will allow git's
merge algorithm to more intelligently avoid conflicts (since it knows
these synthetic commits are already part of the upstream repository).
+
Unfortunately, using this option results in 'git log' showing an extra
copy of every new commit that was created (the original, and the
synthetic one).
+
If you do all your merges with '--squash', make sure you also use
'--squash' when you 'split --rejoin'.


EXAMPLE 1. 'add' command
------------------------
Let's assume that you have a local repository that you would like
to add an external vendor library to. In this case we will add the
git-subtree repository as a subdirectory of your already existing
git-extensions repository in ~/git-extensions/:

	$ git subtree add --prefix=git-subtree --squash \
		git://github.com/apenwarr/git-subtree.git master

'master' needs to be a valid remote ref and can be a different branch
name

You can omit the '--squash' flag, but doing so will increase the number
of commits that are included in your local repository.

We now have a ~/git-extensions/git-subtree directory containing code
from the master branch of git://github.com/apenwarr/git-subtree.git
in our git-extensions repository.

EXAMPLE 2. Extract a subtree using 'commit', 'merge' and 'pull'
---------------------------------------------------------------
Let's use the repository for the git source code as an example.
First, get your own copy of the git.git repository:

	$ git clone git://git.kernel.org/pub/scm/git/git.git test-git
	$ cd test-git

gitweb (commit 1130ef3) was merged into git as of commit
0a8f4f0, after which it was no longer maintained separately.
But imagine it had been maintained separately, and we wanted to
extract git's changes to gitweb since that time, to share with
the upstream.  You could do this:

	$ git subtree split --prefix=gitweb --annotate='(split) ' \
        	0a8f4f0^.. --onto=1130ef3 --rejoin \
        	--branch gitweb-latest
        $ gitk gitweb-latest
        $ git push git@github.com:whatever/gitweb.git gitweb-latest:master

(We use '0a8f4f0^..' because that means "all the changes from
0a8f4f0 to the current version, including 0a8f4f0 itself.")

If gitweb had originally been merged using 'git subtree add' (or
a previous split had already been done with '--rejoin' specified)
then you can do all your splits without having to remember any
weird commit IDs:

	$ git subtree split --prefix=gitweb --annotate='(split) ' --rejoin \
		--branch gitweb-latest2

And you can merge changes back in from the upstream project just
as easily:

	$ git subtree pull --prefix=gitweb \
		git@github.com:whatever/gitweb.git master

Or, using '--squash', you can actually rewind to an earlier
version of gitweb:

	$ git subtree merge --prefix=gitweb --squash gitweb-latest~10

Then make some changes:

	$ date >gitweb/myfile
	$ git add gitweb/myfile
	$ git commit -m 'created myfile'

And fast forward again:

	$ git subtree merge --prefix=gitweb --squash gitweb-latest

And notice that your change is still intact:

	$ ls -l gitweb/myfile

And you can split it out and look at your changes versus
the standard gitweb:

	git log gitweb-latest..$(git subtree split --prefix=gitweb)

EXAMPLE 3. Extract a subtree using a branch
-------------------------------------------
Suppose you have a source directory with many files and
subdirectories, and you want to extract the lib directory to its own
git project. Here's a short way to do it:

First, make the new repository wherever you want:

	$ <go to the new location>
	$ git init --bare

Back in your original directory:

	$ git subtree split --prefix=lib --annotate="(split)" -b split

Then push the new branch onto the new empty repository:

	$ git push <new-repo> split:master


AUTHOR
------
Written by Avery Pennarun <apenwarr@gmail.com>


GIT
---
Part of the linkgit:git[1] suite
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         # Run tests
#
# Copyright (c) 2005 Junio C Hamano
#

-include ../../../config.mak.autogen
-include ../../../config.mak

#GIT_TEST_OPTS=--verbose --debug
SHELL_PATH ?= $(SHELL)
PERL_PATH ?= /usr/bin/perl
TAR ?= $(TAR)
RM ?= rm -f
PROVE ?= prove
DEFAULT_TEST_TARGET ?= test
TEST_LINT ?= test-lint

ifdef TEST_OUTPUT_DIRECTORY
TEST_RESULTS_DIRECTORY = $(TEST_OUTPUT_DIRECTORY)/test-results
else
TEST_RESULTS_DIRECTORY = ../../../t/test-results
endif

# Shell quote;
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
TEST_RESULTS_DIRECTORY_SQ = $(subst ','\'',$(TEST_RESULTS_DIRECTORY))

T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))
TSVN = $(sort $(wildcard t91[0-9][0-9]-*.sh))
TGITWEB = $(sort $(wildcard t95[0-9][0-9]-*.sh))
THELPERS = $(sort $(filter-out $(T),$(wildcard *.sh)))

all: $(DEFAULT_TEST_TARGET)

test: pre-clean $(TEST_LINT)
	$(MAKE) aggregate-results-and-cleanup

prove: pre-clean $(TEST_LINT)
	@echo "*** prove ***"; GIT_CONFIG=.git/config $(PROVE) --exec '$(SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)
	$(MAKE) clean-except-prove-cache

$(T):
	@echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)

pre-clean:
	$(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)'

clean-except-prove-cache:
	$(RM) -r 'trash directory'.*
	$(RM) -r valgrind/bin

clean: clean-except-prove-cache
	$(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)'
	$(RM) .prove

test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax

test-lint-duplicates:
	@dups=`echo $(T) | tr ' ' '\n' | sed 's/-.*//' | sort | uniq -d` && \
		test -z "$$dups" || { \
		echo >&2 "duplicate test numbers:" $$dups; exit 1; }

test-lint-executable:
	@bad=`for i in $(T); do test -x "$$i" || echo $$i; done` && \
		test -z "$$bad" || { \
		echo >&2 "non-executable tests:" $$bad; exit 1; }

test-lint-shell-syntax:
	@'$(PERL_PATH_SQ)' ../../../t/check-non-portable-shell.pl $(T) $(THELPERS)

aggregate-results-and-cleanup: $(T)
	$(MAKE) aggregate-results
	$(MAKE) clean

aggregate-results:
	for f in '$(TEST_RESULTS_DIRECTORY_SQ)'/t*-*.counts; do \
		echo "$$f"; \
	done | '$(SHELL_PATH_SQ)' ../../../t/aggregate-results.sh

valgrind:
	$(MAKE) GIT_TEST_OPTS="$(GIT_TEST_OPTS) --valgrind"

test-results:
	mkdir -p test-results

.PHONY: pre-clean $(T) aggregate-results clean valgrind
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    #!/bin/sh
#
# Copyright (c) 2012 Avery Pennaraum
# Copyright (c) 2015 Alexey Shumkin
#
test_description='Basic porcelain support for subtrees

This test verifies the basic operation of the add, merge, split, pull,
and push subcommands of git subtree.
'

TEST_DIRECTORY=$(pwd)/../../../t
. "$TEST_DIRECTORY"/test-lib.sh

# Use our own wrapper around test-lib.sh's test_create_repo, in order
# to set log.date=relative.  `git subtree` parses the output of `git
# log`, and so it must be careful to not be affected by settings that
# change the `git log` output.  We test this by setting
# log.date=relative for every repo in the tests.
subtree_test_create_repo () {
	test_create_repo "$1" &&
	git -C "$1" config log.date relative
}

test_create_commit () (
	repo=$1 &&
	commit=$2 &&
	cd "$repo" &&
	mkdir -p "$(dirname "$commit")" \
	|| error "Could not create directory for commit"
	echo "$commit" >"$commit" &&
	git add "$commit" || error "Could not add commit"
	git commit -m "$commit" || error "Could not commit"
)

test_wrong_flag() {
	test_must_fail "$@" >out 2>err &&
	test_must_be_empty out &&
	grep "flag does not make sense with" err
}

last_commit_subject () {
	git log --pretty=format:%s -1
}

# Upon 'git subtree add|merge --squash' of an annotated tag,
# pre-2.32.0 versions of 'git subtree' would write the hash of the tag
# (sub1 below), instead of the commit (sub1^{commit}) in the
# "git-subtree-split" trailer.
# We immitate this behaviour below using a replace ref.
# This function creates 3 repositories:
# - $1
# - $1-sub (added as subtree "sub" in $1)
# - $1-clone (clone of $1)
test_create_pre2_32_repo () {
	subtree_test_create_repo "$1" &&
	subtree_test_create_repo "$1-sub" &&
	test_commit -C "$1" main1 &&
	test_commit -C "$1-sub" --annotate sub1 &&
	git -C "$1" subtree add --prefix="sub" --squash "../$1-sub" sub1 &&
	tag=$(git -C "$1" rev-parse FETCH_HEAD) &&
	commit=$(git -C "$1" rev-parse FETCH_HEAD^{commit}) &&
	git -C "$1" log -1 --format=%B HEAD^2 >msg &&
	test_commit -C "$1-sub" --annotate sub2 &&
	git clone --no-local "$1" "$1-clone" &&
	new_commit=$(cat msg | sed -e "s/$commit/$tag/" | git -C "$1-clone" commit-tree HEAD^2^{tree}) &&
	git -C "$1-clone" replace HEAD^2 $new_commit
}

test_expect_success 'shows short help text for -h' '
	test_expect_code 129 git subtree -h >out 2>err &&
	test_must_be_empty err &&
	grep -e "^ *or: git subtree pull" out &&
	grep -e --annotate out
'

#
# Tests for 'git subtree add'
#

test_expect_success 'no merge from non-existent subtree' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		test_must_fail git subtree merge --prefix="sub dir" FETCH_HEAD
	)
'

test_expect_success 'no pull from non-existent subtree' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		test_must_fail git subtree pull --prefix="sub dir" ./"sub proj" HEAD
	)
'

test_expect_success 'add rejects flags for split' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		test_wrong_flag git subtree add --prefix="sub dir" --annotate=foo FETCH_HEAD &&
		test_wrong_flag git subtree add --prefix="sub dir" --branch=foo FETCH_HEAD &&
		test_wrong_flag git subtree add --prefix="sub dir" --ignore-joins FETCH_HEAD &&
		test_wrong_flag git subtree add --prefix="sub dir" --onto=foo FETCH_HEAD &&
		test_wrong_flag git subtree add --prefix="sub dir" --rejoin FETCH_HEAD
	)
'

test_expect_success 'add subproj as subtree into sub dir/ with --prefix' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD &&
		test "$(last_commit_subject)" = "Add '\''sub dir/'\'' from commit '\''$(git rev-parse FETCH_HEAD)'\''"
	)
'

test_expect_success 'add subproj as subtree into sub dir/ with --prefix and --message' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" --message="Added subproject" FETCH_HEAD &&
		test "$(last_commit_subject)" = "Added subproject"
	)
'

test_expect_success 'add subproj as subtree into sub dir/ with --prefix as -P and --message as -m' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add -P "sub dir" -m "Added subproject" FETCH_HEAD &&
		test "$(last_commit_subject)" = "Added subproject"
	)
'

test_expect_success 'add subproj as subtree into sub dir/ with --squash and --prefix and --message' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" --message="Added subproject with squash" --squash FETCH_HEAD &&
		test "$(last_commit_subject)" = "Added subproject with squash"
	)
'

#
# Tests for 'git subtree merge'
#

test_expect_success 'merge rejects flags for split' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count/sub proj" sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		test_wrong_flag git subtree merge --prefix="sub dir" --annotate=foo FETCH_HEAD &&
		test_wrong_flag git subtree merge --prefix="sub dir" --branch=foo FETCH_HEAD &&
		test_wrong_flag git subtree merge --prefix="sub dir" --ignore-joins FETCH_HEAD &&
		test_wrong_flag git subtree merge --prefix="sub dir" --onto=foo FETCH_HEAD &&
		test_wrong_flag git subtree merge --prefix="sub dir" --rejoin FETCH_HEAD
	)
'

test_expect_success 'merge new subproj history into sub dir/ with --prefix' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count/sub proj" sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		test "$(last_commit_subject)" = "Merge commit '\''$(git rev-parse FETCH_HEAD)'\''"
	)
'

test_expect_success 'merge new subproj history into sub dir/ with --prefix and --message' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count/sub proj" sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" --message="Merged changes from subproject" FETCH_HEAD &&
		test "$(last_commit_subject)" = "Merged changes from subproject"
	)
'

test_expect_success 'merge new subproj history into sub dir/ with --squash and --prefix and --message' '
	subtree_test_create_repo "$test_count/sub proj" &&
	subtree_test_create_repo "$test_count" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count/sub proj" sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" --message="Merged changes from subproject using squash" --squash FETCH_HEAD &&
		test "$(last_commit_subject)" = "Merged changes from subproject using squash"
	)
'

test_expect_success 'merge the added subproj again, should do nothing' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD &&
		# this shouldn not actually do anything, since FETCH_HEAD
		# is already a parent
		result=$(git merge -s ours -m "merge -s -ours" FETCH_HEAD) &&
		test "${result}" = "Already up to date."
	)
'

test_expect_success 'merge new subproj history into subdir/ with a slash appended to the argument of --prefix' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/subproj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/subproj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./subproj HEAD &&
		git subtree add --prefix=subdir/ FETCH_HEAD
	) &&
	test_create_commit "$test_count/subproj" sub2 &&
	(
		cd "$test_count" &&
		git fetch ./subproj HEAD &&
		git subtree merge --prefix=subdir/ FETCH_HEAD &&
		test "$(last_commit_subject)" = "Merge commit '\''$(git rev-parse FETCH_HEAD)'\''"
	)
'

test_expect_success 'merge with --squash after annotated tag was added/merged with --squash pre-v2.32.0 ' '
	test_create_pre2_32_repo "$test_count" &&
	git -C "$test_count-clone" fetch "../$test_count-sub" sub2  &&
	test_must_fail git -C "$test_count-clone" subtree merge --prefix="sub" --squash FETCH_HEAD &&
	git -C "$test_count-clone" subtree merge --prefix="sub" --squash FETCH_HEAD  "../$test_count-sub"
'

#
# Tests for 'git subtree split'
#

test_expect_success 'split requires option --prefix' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD &&
		echo "fatal: you must provide the --prefix option." >expected &&
		test_must_fail git subtree split >actual 2>&1 &&
		test_debug "printf '"expected: "'" &&
		test_debug "cat expected" &&
		test_debug "printf '"actual: "'" &&
		test_debug "cat actual" &&
		test_cmp expected actual
	)
'

test_expect_success 'split requires path given by option --prefix must exist' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD &&
		echo "fatal: '\''non-existent-directory'\'' does not exist; use '\''git subtree add'\''" >expected &&
		test_must_fail git subtree split --prefix=non-existent-directory >actual 2>&1 &&
		test_debug "printf '"expected: "'" &&
		test_debug "cat expected" &&
		test_debug "printf '"actual: "'" &&
		test_debug "cat actual" &&
		test_cmp expected actual
	)
'

test_expect_success 'split rejects flags for add' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		split_hash=$(git subtree split --prefix="sub dir" --annotate="*") &&
		test_wrong_flag git subtree split --prefix="sub dir" --squash &&
		test_wrong_flag git subtree split --prefix="sub dir" --message=foo
	)
'

test_expect_success 'split sub dir/ with --rejoin' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		split_hash=$(git subtree split --prefix="sub dir" --annotate="*") &&
		git subtree split --prefix="sub dir" --annotate="*" --rejoin &&
		test "$(last_commit_subject)" = "Split '\''sub dir/'\'' into commit '\''$split_hash'\''"
	)
'

test_expect_success 'split sub dir/ with --rejoin from scratch' '
	subtree_test_create_repo "$test_count" &&
	test_create_commit "$test_count" main1 &&
	(
		cd "$test_count" &&
		mkdir "sub dir" &&
		echo file >"sub dir"/file &&
		git add "sub dir/file" &&
		git commit -m"sub dir file" &&
		split_hash=$(git subtree split --prefix="sub dir" --rejoin) &&
		git subtree split --prefix="sub dir" --rejoin &&
		test "$(last_commit_subject)" = "Split '\''sub dir/'\'' into commit '\''$split_hash'\''"
	)
'

test_expect_success 'split sub dir/ with --rejoin and --message' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		git subtree split --prefix="sub dir" --message="Split & rejoin" --annotate="*" --rejoin &&
		test "$(last_commit_subject)" = "Split & rejoin"
	)
'

test_expect_success 'split "sub dir"/ with --rejoin and --squash' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" --squash FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git subtree pull --prefix="sub dir" --squash ./"sub proj" HEAD &&
		MAIN=$(git rev-parse --verify HEAD) &&
		SUB=$(git -C "sub proj" rev-parse --verify HEAD) &&

		SPLIT=$(git subtree split --prefix="sub dir" --annotate="*" --rejoin --squash) &&

		test_must_fail git merge-base --is-ancestor $SUB HEAD &&
		test_must_fail git merge-base --is-ancestor $SPLIT HEAD &&
		git rev-list HEAD ^$MAIN >commit-list &&
		test_line_count = 2 commit-list &&
		test "$(git rev-parse --verify HEAD:)"           = "$(git rev-parse --verify $MAIN:)" &&
		test "$(git rev-parse --verify HEAD:"sub dir")"  = "$(git rev-parse --verify $SPLIT:)" &&
		test "$(git rev-parse --verify HEAD^1)"          = $MAIN &&
		test "$(git rev-parse --verify HEAD^2)"         != $SPLIT &&
		test "$(git rev-parse --verify HEAD^2:)"         = "$(git rev-parse --verify $SPLIT:)" &&
		test "$(last_commit_subject)" = "Split '\''sub dir/'\'' into commit '\''$SPLIT'\''"
	)
'

test_expect_success 'split then pull "sub dir"/ with --rejoin and --squash' '
	# 1. "add"
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	git -C "$test_count" subtree --prefix="sub dir" add --squash ./"sub proj" HEAD &&

	# 2. commit from parent
	test_create_commit "$test_count" "sub dir"/main-sub1 &&

	# 3. "split --rejoin --squash"
	git -C "$test_count" subtree --prefix="sub dir" split --rejoin --squash &&

	# 4. "pull --squash"
	test_create_commit "$test_count/sub proj" sub2 &&
	git -C "$test_count" subtree -d --prefix="sub dir" pull --squash ./"sub proj" HEAD &&

	test_must_fail git merge-base HEAD FETCH_HEAD
'

test_expect_success 'split "sub dir"/ with --branch' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		split_hash=$(git subtree split --prefix="sub dir" --annotate="*") &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br &&
		test "$(git rev-parse subproj-br)" = "$split_hash"
	)
'

test_expect_success 'check hash of split' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		split_hash=$(git subtree split --prefix="sub dir" --annotate="*") &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br &&
		test "$(git rev-parse subproj-br)" = "$split_hash" &&
		# Check hash of split
		new_hash=$(git rev-parse subproj-br^2) &&
		(
			cd ./"sub proj" &&
			subdir_hash=$(git rev-parse HEAD) &&
			test "$new_hash" = "$subdir_hash"
		)
	)
'

test_expect_success 'split "sub dir"/ with --branch for an existing branch' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git branch subproj-br FETCH_HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		split_hash=$(git subtree split --prefix="sub dir" --annotate="*") &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br &&
		test "$(git rev-parse subproj-br)" = "$split_hash"
	)
'

test_expect_success 'split "sub dir"/ with --branch for an incompatible branch' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git branch init HEAD &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		test_must_fail git subtree split --prefix="sub dir" --branch init
	)
'

test_expect_success 'split after annotated tag was added/merged with --squash pre-v2.32.0' '
	test_create_pre2_32_repo "$test_count" &&
	test_must_fail git -C "$test_count-clone" subtree split --prefix="sub" HEAD &&
	git -C "$test_count-clone" subtree split --prefix="sub" HEAD "../$test_count-sub"
'

#
# Tests for 'git subtree pull'
#

test_expect_success 'pull requires option --prefix' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count/sub proj" sub2 &&
	(
		cd "$test_count" &&
		test_must_fail git subtree pull ./"sub proj" HEAD >out 2>err &&

		echo "fatal: you must provide the --prefix option." >expected &&
		test_must_be_empty out &&
		test_cmp expected err
	)
'

test_expect_success 'pull requires path given by option --prefix must exist' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		test_must_fail git subtree pull --prefix="sub dir" ./"sub proj" HEAD >out 2>err &&

		echo "fatal: '\''sub dir'\'' does not exist; use '\''git subtree add'\''" >expected &&
		test_must_be_empty out &&
		test_cmp expected err
	)
'

test_expect_success 'pull basic operation' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count/sub proj" sub2 &&
	(
		cd "$test_count" &&
		exp=$(git -C "sub proj" rev-parse --verify HEAD:) &&
		git subtree pull --prefix="sub dir" ./"sub proj" HEAD &&
		act=$(git rev-parse --verify HEAD:"sub dir") &&
		test "$act" = "$exp"
	)
'

test_expect_success 'pull rejects flags for split' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count/sub proj" sub2 &&
	(
		test_must_fail git subtree pull --prefix="sub dir" --annotate=foo ./"sub proj" HEAD &&
		test_must_fail git subtree pull --prefix="sub dir" --branch=foo ./"sub proj" HEAD &&
		test_must_fail git subtree pull --prefix="sub dir" --ignore-joins ./"sub proj" HEAD &&
		test_must_fail git subtree pull --prefix="sub dir" --onto=foo ./"sub proj" HEAD &&
		test_must_fail git subtree pull --prefix="sub dir" --rejoin ./"sub proj" HEAD
	)
'

test_expect_success 'pull with --squash after annotated tag was added/merged with --squash pre-v2.32.0 ' '
	test_create_pre2_32_repo "$test_count" &&
	git -C "$test_count-clone" subtree -d pull --prefix="sub" --squash "../$test_count-sub" sub2
'

#
# Tests for 'git subtree push'
#

test_expect_success 'push requires option --prefix' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD &&
		echo "fatal: you must provide the --prefix option." >expected &&
		test_must_fail git subtree push "./sub proj" from-mainline >actual 2>&1 &&
		test_debug "printf '"expected: "'" &&
		test_debug "cat expected" &&
		test_debug "printf '"actual: "'" &&
		test_debug "cat actual" &&
		test_cmp expected actual
	)
'

test_expect_success 'push requires path given by option --prefix must exist' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD &&
		echo "fatal: '\''non-existent-directory'\'' does not exist; use '\''git subtree add'\''" >expected &&
		test_must_fail git subtree push --prefix=non-existent-directory "./sub proj" from-mainline >actual 2>&1 &&
		test_debug "printf '"expected: "'" &&
		test_debug "cat expected" &&
		test_debug "printf '"actual: "'" &&
		test_debug "cat actual" &&
		test_cmp expected actual
	)
'

test_expect_success 'push rejects flags for add' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		test_wrong_flag git subtree split --prefix="sub dir" --squash ./"sub proj" from-mainline &&
		test_wrong_flag git subtree split --prefix="sub dir" --message=foo ./"sub proj" from-mainline
	)
'

test_expect_success 'push basic operation' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		before=$(git rev-parse --verify HEAD) &&
		split_hash=$(git subtree split --prefix="sub dir") &&
		git subtree push --prefix="sub dir" ./"sub proj" from-mainline &&
		test "$before" = "$(git rev-parse --verify HEAD)" &&
		test "$split_hash" = "$(git -C "sub proj" rev-parse --verify refs/heads/from-mainline)"
	)
'

test_expect_success 'push sub dir/ with --rejoin' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		split_hash=$(git subtree split --prefix="sub dir" --annotate="*") &&
		git subtree push --prefix="sub dir" --annotate="*" --rejoin ./"sub proj" from-mainline &&
		test "$(last_commit_subject)" = "Split '\''sub dir/'\'' into commit '\''$split_hash'\''" &&
		test "$split_hash" = "$(git -C "sub proj" rev-parse --verify refs/heads/from-mainline)"
	)
'

test_expect_success 'push sub dir/ with --rejoin from scratch' '
	subtree_test_create_repo "$test_count" &&
	test_create_commit "$test_count" main1 &&
	(
		cd "$test_count" &&
		mkdir "sub dir" &&
		echo file >"sub dir"/file &&
		git add "sub dir/file" &&
		git commit -m"sub dir file" &&
		split_hash=$(git subtree split --prefix="sub dir" --rejoin) &&
		git init --bare "sub proj.git" &&
		git subtree push --prefix="sub dir" --rejoin ./"sub proj.git" from-mainline &&
		test "$(last_commit_subject)" = "Split '\''sub dir/'\'' into commit '\''$split_hash'\''" &&
		test "$split_hash" = "$(git -C "sub proj.git" rev-parse --verify refs/heads/from-mainline)"
	)
'

test_expect_success 'push sub dir/ with --rejoin and --message' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		git subtree push --prefix="sub dir" --message="Split & rejoin" --annotate="*" --rejoin ./"sub proj" from-mainline &&
		test "$(last_commit_subject)" = "Split & rejoin" &&
		split_hash="$(git rev-parse --verify HEAD^2)" &&
		test "$split_hash" = "$(git -C "sub proj" rev-parse --verify refs/heads/from-mainline)"
	)
'

test_expect_success 'push "sub dir"/ with --rejoin and --squash' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" --squash FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git subtree pull --prefix="sub dir" --squash ./"sub proj" HEAD &&
		MAIN=$(git rev-parse --verify HEAD) &&
		SUB=$(git -C "sub proj" rev-parse --verify HEAD) &&

		SPLIT=$(git subtree split --prefix="sub dir" --annotate="*") &&
		git subtree push --prefix="sub dir" --annotate="*" --rejoin --squash ./"sub proj" from-mainline &&

		test_must_fail git merge-base --is-ancestor $SUB HEAD &&
		test_must_fail git merge-base --is-ancestor $SPLIT HEAD &&
		git rev-list HEAD ^$MAIN >commit-list &&
		test_line_count = 2 commit-list &&
		test "$(git rev-parse --verify HEAD:)"           = "$(git rev-parse --verify $MAIN:)" &&
		test "$(git rev-parse --verify HEAD:"sub dir")"  = "$(git rev-parse --verify $SPLIT:)" &&
		test "$(git rev-parse --verify HEAD^1)"          = $MAIN &&
		test "$(git rev-parse --verify HEAD^2)"         != $SPLIT &&
		test "$(git rev-parse --verify HEAD^2:)"         = "$(git rev-parse --verify $SPLIT:)" &&
		test "$(last_commit_subject)" = "Split '\''sub dir/'\'' into commit '\''$SPLIT'\''" &&
		test "$SPLIT" = "$(git -C "sub proj" rev-parse --verify refs/heads/from-mainline)"
	)
'

test_expect_success 'push "sub dir"/ with --branch' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		split_hash=$(git subtree split --prefix="sub dir" --annotate="*") &&
		git subtree push --prefix="sub dir" --annotate="*" --branch subproj-br ./"sub proj" from-mainline &&
		test "$(git rev-parse subproj-br)" = "$split_hash" &&
		test "$split_hash" = "$(git -C "sub proj" rev-parse --verify refs/heads/from-mainline)"
	)
'

test_expect_success 'check hash of push' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		split_hash=$(git subtree split --prefix="sub dir" --annotate="*") &&
		git subtree push --prefix="sub dir" --annotate="*" --branch subproj-br ./"sub proj" from-mainline &&
		test "$(git rev-parse subproj-br)" = "$split_hash" &&
		# Check hash of split
		new_hash=$(git rev-parse subproj-br^2) &&
		(
			cd ./"sub proj" &&
			subdir_hash=$(git rev-parse HEAD) &&
			test "$new_hash" = "$subdir_hash"
		) &&
		test "$split_hash" = "$(git -C "sub proj" rev-parse --verify refs/heads/from-mainline)"
	)
'

test_expect_success 'push "sub dir"/ with --branch for an existing branch' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git branch subproj-br FETCH_HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		split_hash=$(git subtree split --prefix="sub dir" --annotate="*") &&
		git subtree push --prefix="sub dir" --annotate="*" --branch subproj-br ./"sub proj" from-mainline &&
		test "$(git rev-parse subproj-br)" = "$split_hash" &&
		test "$split_hash" = "$(git -C "sub proj" rev-parse --verify refs/heads/from-mainline)"
	)
'

test_expect_success 'push "sub dir"/ with --branch for an incompatible branch' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git branch init HEAD &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		test_must_fail git subtree push --prefix="sub dir" --branch init "./sub proj" from-mainline
	)
'

test_expect_success 'push "sub dir"/ with a local rev' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		bad_tree=$(git rev-parse --verify HEAD:"sub dir") &&
		good_tree=$(git rev-parse --verify HEAD^:"sub dir") &&
		git subtree push --prefix="sub dir" --annotate="*" ./"sub proj" HEAD^:from-mainline &&
		split_tree=$(git -C "sub proj" rev-parse --verify refs/heads/from-mainline:) &&
		test "$split_tree" = "$good_tree"
	)
'

test_expect_success 'push after annotated tag was added/merged with --squash pre-v2.32.0' '
	test_create_pre2_32_repo "$test_count" &&
	test_create_commit "$test_count-clone" sub/main-sub1 &&
	git -C "$test_count-clone" subtree push --prefix="sub" "../$test_count-sub" from-mainline
'

#
# Validity checking
#

test_expect_success 'make sure exactly the right set of files ends up in the subproj' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	test_create_commit "$test_count/sub proj" sub3 &&
	test_create_commit "$test_count" "sub dir"/main-sub3 &&
	(
		cd "$test_count/sub proj" &&
		git fetch .. subproj-br &&
		git merge FETCH_HEAD
	) &&
	test_create_commit "$test_count/sub proj" sub4 &&
	(
		cd "$test_count" &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub4 &&
	(
		cd "$test_count" &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	(
		cd "$test_count/sub proj" &&
		git fetch .. subproj-br &&
		git merge FETCH_HEAD &&

		test_write_lines main-sub1 main-sub2 main-sub3 main-sub4 \
			sub1 sub2 sub3 sub4 >expect &&
		git ls-files >actual &&
		test_cmp expect actual
	)
'

test_expect_success 'make sure the subproj *only* contains commits that affect the "sub dir"' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	test_create_commit "$test_count/sub proj" sub3 &&
	test_create_commit "$test_count" "sub dir"/main-sub3 &&
	(
		cd "$test_count/sub proj" &&
		git fetch .. subproj-br &&
		git merge FETCH_HEAD
	) &&
	test_create_commit "$test_count/sub proj" sub4 &&
	(
		cd "$test_count" &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub4 &&
	(
		cd "$test_count" &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	(
		cd "$test_count/sub proj" &&
		git fetch .. subproj-br &&
		git merge FETCH_HEAD &&

		test_write_lines main-sub1 main-sub2 main-sub3 main-sub4 \
			sub1 sub2 sub3 sub4 >expect &&
		git log --name-only --pretty=format:"" >log &&
		sort <log | sed "/^\$/ d" >actual &&
		test_cmp expect actual
	)
'

test_expect_success 'make sure exactly the right set of files ends up in the mainline' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	test_create_commit "$test_count/sub proj" sub3 &&
	test_create_commit "$test_count" "sub dir"/main-sub3 &&
	(
		cd "$test_count/sub proj" &&
		git fetch .. subproj-br &&
		git merge FETCH_HEAD
	) &&
	test_create_commit "$test_count/sub proj" sub4 &&
	(
		cd "$test_count" &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub4 &&
	(
		cd "$test_count" &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	(
		cd "$test_count/sub proj" &&
		git fetch .. subproj-br &&
		git merge FETCH_HEAD
	) &&
	(
		cd "$test_count" &&
		git subtree pull --prefix="sub dir" ./"sub proj" HEAD &&

		test_write_lines main1 main2 >chkm &&
		test_write_lines main-sub1 main-sub2 main-sub3 main-sub4 >chkms &&
		sed "s,^,sub dir/," chkms >chkms_sub &&
		test_write_lines sub1 sub2 sub3 sub4 >chks &&
		sed "s,^,sub dir/," chks >chks_sub &&

		cat chkm chkms_sub chks_sub >expect &&
		git ls-files >actual &&
		test_cmp expect actual
	)
'

test_expect_success 'make sure each filename changed exactly once in the entire history' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git config log.date relative &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	test_create_commit "$test_count/sub proj" sub3 &&
	test_create_commit "$test_count" "sub dir"/main-sub3 &&
	(
		cd "$test_count/sub proj" &&
		git fetch .. subproj-br &&
		git merge FETCH_HEAD
	) &&
	test_create_commit "$test_count/sub proj" sub4 &&
	(
		cd "$test_count" &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub4 &&
	(
		cd "$test_count" &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	(
		cd "$test_count/sub proj" &&
		git fetch .. subproj-br &&
		git merge FETCH_HEAD
	) &&
	(
		cd "$test_count" &&
		git subtree pull --prefix="sub dir" ./"sub proj" HEAD &&

		test_write_lines main1 main2 >chkm &&
		test_write_lines sub1 sub2 sub3 sub4 >chks &&
		test_write_lines main-sub1 main-sub2 main-sub3 main-sub4 >chkms &&
		sed "s,^,sub dir/," chkms >chkms_sub &&

		# main-sub?? and /"sub dir"/main-sub?? both change, because those are the
		# changes that were split into their own history.  And "sub dir"/sub?? never
		# change, since they were *only* changed in the subtree branch.
		git log --name-only --pretty=format:"" >log &&
		sort <log >sorted-log &&
		sed "/^$/ d" sorted-log >actual &&

		cat chkms chkm chks chkms_sub >expect-unsorted &&
		sort expect-unsorted >expect &&
		test_cmp expect actual
	)
'

test_expect_success 'make sure the --rejoin commits never make it into subproj' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	test_create_commit "$test_count/sub proj" sub3 &&
	test_create_commit "$test_count" "sub dir"/main-sub3 &&
	(
		cd "$test_count/sub proj" &&
		git fetch .. subproj-br &&
		git merge FETCH_HEAD
	) &&
	test_create_commit "$test_count/sub proj" sub4 &&
	(
		cd "$test_count" &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub4 &&
	(
		cd "$test_count" &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	(
		cd "$test_count/sub proj" &&
		git fetch .. subproj-br &&
		git merge FETCH_HEAD
	) &&
	(
		cd "$test_count" &&
		git subtree pull --prefix="sub dir" ./"sub proj" HEAD &&
		test "$(git log --pretty=format:"%s" HEAD^2 | grep -i split)" = ""
	)
'

test_expect_success 'make sure no "git subtree" tagged commits make it into subproj' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	test_create_commit "$test_count/sub proj" sub3 &&
	test_create_commit "$test_count" "sub dir"/main-sub3 &&
	(
		cd "$test_count/sub proj" &&
		git fetch .. subproj-br &&
		 git merge FETCH_HEAD
	) &&
	test_create_commit "$test_count/sub proj" sub4 &&
	(
		cd "$test_count" &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub4 &&
	(
		cd "$test_count" &&
		git subtree split --prefix="sub dir" --annotate="*" --branch subproj-br --rejoin
	) &&
	(
		cd "$test_count/sub proj" &&
		git fetch .. subproj-br &&
		git merge FETCH_HEAD
	) &&
	(
		cd "$test_count" &&
		git subtree pull --prefix="sub dir" ./"sub proj" HEAD &&

		# They are meaningless to subproj since one side of the merge refers to the mainline
		test "$(git log --pretty=format:"%s%n%b" HEAD^2 | grep "git-subtree.*:")" = ""
	)
'

#
# A new set of tests
#

test_expect_success 'make sure "git subtree split" find the correct parent' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count/sub proj" sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git branch subproj-ref FETCH_HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	(
		cd "$test_count" &&
		git subtree split --prefix="sub dir" --branch subproj-br &&

		# at this point, the new commit parent should be subproj-ref, if it is
		# not, something went wrong (the "newparent" of "HEAD~" commit should
		# have been sub2, but it was not, because its cache was not set to
		# itself)
		test "$(git log --pretty=format:%P -1 subproj-br)" = "$(git rev-parse subproj-ref)"
	)
'

test_expect_success 'split a new subtree without --onto option' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count/sub proj" sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	(
		cd "$test_count" &&
		git subtree split --prefix="sub dir" --branch subproj-br
	) &&
	mkdir "$test_count"/"sub dir2" &&
	test_create_commit "$test_count" "sub dir2"/main-sub2 &&
	(
		cd "$test_count" &&

		# also test that we still can split out an entirely new subtree
		# if the parent of the first commit in the tree is not empty,
		# then the new subtree has accidentally been attached to something
		git subtree split --prefix="sub dir2" --branch subproj2-br &&
		test "$(git log --pretty=format:%P -1 subproj2-br)" = ""
	)
'

test_expect_success 'verify one file change per commit' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git branch sub1 FETCH_HEAD &&
		git subtree add --prefix="sub dir" sub1
	) &&
	test_create_commit "$test_count/sub proj" sub2 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	(
		cd "$test_count" &&
		git subtree split --prefix="sub dir" --branch subproj-br
	) &&
	mkdir "$test_count"/"sub dir2" &&
	test_create_commit "$test_count" "sub dir2"/main-sub2 &&
	(
		cd "$test_count" &&
		git subtree split --prefix="sub dir2" --branch subproj2-br &&

		git log --format="%H" >commit-list &&
		while read commit
		do
			git log -n1 --format="" --name-only "$commit" >file-list &&
			test_line_count -le 1 file-list || return 1
		done <commit-list
	)
'

test_expect_success 'push split to subproj' '
	subtree_test_create_repo "$test_count" &&
	subtree_test_create_repo "$test_count/sub proj" &&
	test_create_commit "$test_count" main1 &&
	test_create_commit "$test_count/sub proj" sub1 &&
	(
		cd "$test_count" &&
		git fetch ./"sub proj" HEAD &&
		git subtree add --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub1 &&
	test_create_commit "$test_count" main2 &&
	test_create_commit "$test_count/sub proj" sub2 &&
	test_create_commit "$test_count" "sub dir"/main-sub2 &&
	(
		cd $test_count/"sub proj" &&
		git branch sub-branch-1 &&
		cd .. &&
		git fetch ./"sub proj" HEAD &&
		git subtree merge --prefix="sub dir" FETCH_HEAD
	) &&
	test_create_commit "$test_count" "sub dir"/main-sub3 &&
	(
		cd "$test_count" &&
		git subtree push ./"sub proj" --prefix "sub dir" sub-branch-1 &&
		cd ./"sub proj" &&
		git checkout sub-branch-1 &&
		test "$(last_commit_subject)" = "sub dir/main-sub3"
	)
'

#
# This test covers 2 cases in subtree split copy_or_skip code
# 1) Merges where one parent is a superset of the changes of the other
#    parent regarding changes to the subtree, in this case the merge
#    commit should be copied
# 2) Merges where only one parent operate on the subtree, and the merge
#    commit should be skipped
#
# (1) is checked by ensuring subtree_tip is a descendent of subtree_branch
# (2) should have a check added (not_a_subtree_change shouldn't be present
#     on the produced subtree)
#
# Other related cases which are not tested (or currently handled correctly)
# - Case (1) where there are more than 2 parents, it will sometimes correctly copy
#   the merge, and sometimes not
# - Merge commit where both parents have same tree as the merge, currently
#   will always be skipped, even if they reached that state via different
#   set of commits.
#

test_expect_success 'subtree descendant check' '
	subtree_test_create_repo "$test_count" &&
	defaultBranch=$(sed "s,ref: refs/heads/,," "$test_count/.git/HEAD") &&
	test_create_commit "$test_count" folder_subtree/a &&
	(
		cd "$test_count" &&
		git branch branch
	) &&
	test_create_commit "$test_count" folder_subtree/0 &&
	test_create_commit "$test_count" folder_subtree/b &&
	cherry=$(cd "$test_count" && git rev-parse HEAD) &&
	(
		cd "$test_count" &&
		git checkout branch
	) &&
	test_create_commit "$test_count" commit_on_branch &&
	(
		cd "$test_count" &&
		git cherry-pick $cherry &&
		git checkout $defaultBranch &&
		git merge -m "merge should be kept on subtree" branch &&
		git branch no_subtree_work_branch
	) &&
	test_create_commit "$test_count" folder_subtree/d &&
	(
		cd "$test_count" &&
		git checkout no_subtree_work_branch
	) &&
	test_create_commit "$test_count" not_a_subtree_change &&
	(
		cd "$test_count" &&
		git checkout $defaultBranch &&
		git merge -m "merge should be skipped on subtree" no_subtree_work_branch &&

		git subtree split --prefix folder_subtree/ --branch subtree_tip $defaultBranch &&
		git subtree split --prefix folder_subtree/ --branch subtree_branch branch &&
		test $(git rev-list --count subtree_tip..subtree_branch) = 0
	)
'

test_done
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
	delete tempdir

	'git subtree rejoin' option to do the same as --rejoin, eg. after a
	  rebase

	--prefix doesn't force the subtree correctly in merge/pull:
	"-s subtree" should be given an explicit subtree option?
		There doesn't seem to be a way to do this.  We'd have to
		patch git-merge-subtree.  Ugh.
		(but we could avoid this problem by generating squashes with
		exactly the right subtree structure, rather than using
		subtree merge...)

	add a 'log' subcommand to see what's new in a subtree?

	add to-submodule and from-submodule commands

	automated tests for --squash stuff

	"add" command non-obviously requires a commitid; would be easier if
		it had a "pull" sort of mode instead

	"pull" and "merge" commands should fail if you've never merged
		that --prefix before

	docs should provide an example of "add"

	note that the initial split doesn't *have* to have a commitid
		specified... that's just an optimization

	if you try to add (or maybe merge?) with an invalid commitid, you
		get a misleading "prefix must end with /" message from
		one of the other git tools that git-subtree calls.  Should
		detect this situation and print the *real* problem.

	"pull --squash" should do fetch-synthesize-merge, but instead just
		does "pull" directly, which doesn't work at all.

	make a 'force-update' that does what 'add' does even if the subtree
		already exists.  That way we can help people who imported
		subtrees "incorrectly" (eg. by just copying in the files) in
		the past.

	guess --prefix automatically if possible based on pwd

	make a 'git subtree grafts' that automatically expands --squash'd
		commits so you can see the full history if you want it.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             appp.sh is a script that is supposed to be used together with ExternalEditor
for Mozilla Thunderbird. It will let you include patches inline in e-mails
in an easy way.

Usage:
- Generate the patch with git format-patch.
- Start writing a new e-mail in Thunderbird.
- Press the external editor button (or Ctrl-E) to run appp.sh
- Select the previously generated patch file.
- Finish editing the e-mail.

Any text that is entered into the message editor before appp.sh is called
will be moved to the section between the --- and the diffstat.

All S-O-B:s and Cc:s in the patch will be added to the CC list.

To set it up, just install External Editor and tell it to use appp.sh as the
editor.

Zenity is a required dependency.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           #!/bin/sh
# Copyright 2008 Lukas Sandström <luksan@gmail.com>
#
# AppendPatch - A script to be used together with ExternalEditor
# for Mozilla Thunderbird to properly include patches inline in e-mails.

# ExternalEditor can be downloaded at http://globs.org/articles.php?lng=en&pg=2

CONFFILE=~/.appprc

SEP="-=-=-=-=-=-=-=-=-=# Don't remove this line #=-=-=-=-=-=-=-=-=-"
if [ -e "$CONFFILE" ] ; then
	LAST_DIR=$(grep -m 1 "^LAST_DIR=" "${CONFFILE}"|sed -e 's/^LAST_DIR=//')
	cd "${LAST_DIR}"
else
	cd > /dev/null
fi

PATCH=$(zenity --file-selection)

if [ "$?" != "0" ] ; then
	#zenity --error --text "No patchfile given."
	exit 1
fi

cd - > /dev/null

SUBJECT=$(sed -n -e '/^Subject: /p' "${PATCH}")
HEADERS=$(sed -e '/^'"${SEP}"'$/,$d' $1)
BODY=$(sed -e "1,/${SEP}/d" $1)
CMT_MSG=$(sed -e '1,/^$/d' -e '/^---$/,$d' "${PATCH}")
DIFF=$(sed -e '1,/^---$/d' "${PATCH}")

CCS=$(echo -e "$CMT_MSG\n$HEADERS" | sed -n -e 's/^Cc: \(.*\)$/\1,/gp' \
	-e 's/^Signed-off-by: \(.*\)/\1,/gp')

echo "$SUBJECT" > $1
echo "Cc: $CCS" >> $1
echo "$HEADERS" | sed -e '/^Subject: /d' -e '/^Cc: /d' >> $1
echo "$SEP" >> $1

echo "$CMT_MSG" >> $1
echo "---" >> $1
if [ "x${BODY}x" != "xx" ] ; then
	echo >> $1
	echo "$BODY" >> $1
	echo >> $1
fi
echo "$DIFF" >> $1

LAST_DIR=$(dirname "${PATCH}")

grep -v "^LAST_DIR=" "${CONFFILE}" > "${CONFFILE}_"
echo "LAST_DIR=${LAST_DIR}" >> "${CONFFILE}_"
mv "${CONFFILE}_" "${CONFFILE}"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              TL;DR: Run update_unicode.sh after the publication of a new Unicode
standard and commit the resulting unicode-widths.h file.

The long version
================

The Git source code ships the file unicode-widths.h which contains
tables of zero and double width Unicode code points, respectively.
These tables are generated using update_unicode.sh in this directory.
update_unicode.sh itself uses a third-party tool, uniset, to query two
Unicode data files for the interesting code points.

On first run, update_unicode.sh clones uniset from Github and builds it.
This requires a current-ish version of autoconf (2.69 works per December
2016).

On each run, update_unicode.sh checks whether more recent Unicode data
files are available from the Unicode consortium, and rebuilds the header
unicode-widths.h with the new data. The new header can then be
committed.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   #!/bin/sh
#See http://www.unicode.org/reports/tr44/
#
#Me Enclosing_Mark  an enclosing combining mark
#Mn Nonspacing_Mark a nonspacing combining mark (zero advance width)
#Cf Format          a format control character
#
cd "$(dirname "$0")"
UNICODEWIDTH_H=$(git rev-parse --show-toplevel)/unicode-width.h

wget -N http://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt \
	http://www.unicode.org/Public/UCD/latest/ucd/EastAsianWidth.txt &&
if ! test -d uniset; then
	git clone https://github.com/depp/uniset.git &&
	( cd uniset && git checkout 4b186196dd )
fi &&
(
	cd uniset &&
	if ! test -x uniset; then
		autoreconf -i &&
		./configure --enable-warnings=-Werror CFLAGS='-O0 -ggdb'
	fi &&
	make
) &&
UNICODE_DIR=. && export UNICODE_DIR &&
cat >$UNICODEWIDTH_H <<-EOF
static const struct interval zero_width[] = {
	$(uniset/uniset --32 cat:Me,Mn,Cf + U+1160..U+11FF - U+00AD)
};
static const struct interval double_width[] = {
	$(uniset/uniset --32 eaw:F,W)
};
EOF
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Configuration for VS Code
=========================

[VS Code](https://code.visualstudio.com/) is a lightweight but powerful source
code editor which runs on your desktop and is available for
[Windows](https://code.visualstudio.com/docs/setup/windows),
[macOS](https://code.visualstudio.com/docs/setup/mac) and
[Linux](https://code.visualstudio.com/docs/setup/linux). Among other languages,
it has [support for C/C++ via an extension](https://github.com/Microsoft/vscode-cpptools) with
[debugging support](https://code.visualstudio.com/docs/editor/debugging)

To get help about "how to personalize your settings" read:
[How to set up your settings](https://code.visualstudio.com/docs/getstarted/settings)

To start developing Git with VS Code, simply run the Unix shell script called
`init.sh` in this directory, which creates the configuration files in
`.vscode/` that VS Code consumes. `init.sh` needs access to `make` and `gcc`,
so run the script in a Git SDK shell if you are using Windows.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             #!/bin/sh

die () {
	echo "$*" >&2
	exit 1
}

cd "$(dirname "$0")"/../.. ||
die "Could not cd to top-level directory"

mkdir -p .vscode ||
die "Could not create .vscode/"

# General settings

cat >.vscode/settings.json.new <<\EOF ||
{
    "C_Cpp.intelliSenseEngine": "Default",
    "C_Cpp.intelliSenseEngineFallback": "Disabled",
    "[git-commit]": {
        "editor.wordWrap": "wordWrapColumn",
        "editor.wordWrapColumn": 72
    },
    "[c]": {
        "editor.detectIndentation": false,
        "editor.insertSpaces": false,
        "editor.tabSize": 8,
        "files.trimTrailingWhitespace": true
    },
    "[txt]": {
        "editor.detectIndentation": false,
        "editor.insertSpaces": false,
        "editor.tabSize": 8,
        "files.trimTrailingWhitespace": true
    },
    "files.associations": {
        "*.h": "c",
        "*.c": "c"
    },
    "cSpell.ignorePaths": [
    ],
    "cSpell.words": [
        "DATAW",
        "DBCACHED",
        "DFCHECK",
        "DTYPE",
        "Hamano",
        "HCAST",
        "HEXSZ",
        "HKEY",
        "HKLM",
        "IFGITLINK",
        "IFINVALID",
        "ISBROKEN",
        "ISGITLINK",
        "ISSYMREF",
        "Junio",
        "LPDWORD",
        "LPPROC",
        "LPWSTR",
        "MSVCRT",
        "NOARG",
        "NOCOMPLETE",
        "NOINHERIT",
        "RENORMALIZE",
        "STARTF",
        "STARTUPINFOEXW",
        "Schindelin",
        "UCRT",
        "YESNO",
        "argcp",
        "beginthreadex",
        "committish",
        "contentp",
        "cpath",
        "cpidx",
        "ctim",
        "dequote",
        "envw",
        "ewah",
        "fdata",
        "fherr",
        "fhin",
        "fhout",
        "fragp",
        "fsmonitor",
        "hnsec",
        "idents",
        "includeif",
        "interpr",
        "iprog",
        "isexe",
        "iskeychar",
        "kompare",
        "mksnpath",
        "mktag",
        "mktree",
        "mmblob",
        "mmbuffer",
        "mmfile",
        "noenv",
        "nparents",
        "ntpath",
        "ondisk",
        "ooid",
        "oplen",
        "osdl",
        "pnew",
        "pold",
        "ppinfo",
        "pushf",
        "pushv",
        "rawsz",
        "rebasing",
        "reencode",
        "repo",
        "rerere",
        "scld",
        "sharedrepo",
        "spawnv",
        "spawnve",
        "spawnvpe",
        "strdup'ing",
        "submodule",
        "submodules",
        "topath",
        "topo",
        "tpatch",
        "unexecutable",
        "unhide",
        "unkc",
        "unkv",
        "unmark",
        "unmatch",
        "unsets",
        "unshown",
        "untracked",
        "untrackedcache",
        "unuse",
        "upos",
        "uval",
        "vreportf",
        "wargs",
        "wargv",
        "wbuffer",
        "wcmd",
        "wcsnicmp",
        "wcstoutfdup",
        "wdeltaenv",
        "wdir",
        "wenv",
        "wenvblk",
        "wenvcmp",
        "wenviron",
        "wenvpos",
        "wenvsz",
        "wfile",
        "wfilename",
        "wfopen",
        "wfreopen",
        "wfullpath",
        "which'll",
        "wlink",
        "wmain",
        "wmkdir",
        "wmktemp",
        "wnewpath",
        "wotype",
        "wpath",
        "wpathname",
        "wpgmptr",
        "wpnew",
        "wpointer",
        "wpold",
        "wpos",
        "wputenv",
        "wrmdir",
        "wship",
        "wtarget",
        "wtemplate",
        "wunlink",
        "xcalloc",
        "xgetcwd",
        "xmallocz",
        "xmemdupz",
        "xmmap",
        "xopts",
        "xrealloc",
        "xsnprintf",
        "xutftowcs",
        "xutftowcsn",
        "xwcstoutf"
    ],
    "cSpell.ignoreRegExpList": [
        "\\\"(DIRC|FSMN|REUC|UNTR)\\\"",
        "\\\\u[0-9a-fA-Fx]{4}\\b",
        "\\b(filfre|frotz|xyzzy)\\b",
        "\\bCMIT_FMT_DEFAULT\\b",
        "\\bde-munge\\b",
        "\\bGET_OID_DISAMBIGUATORS\\b",
        "\\bHASH_RENORMALIZE\\b",
        "\\bTREESAMEness\\b",
        "\\bUSE_STDEV\\b",
        "\\Wchar *\\*\\W*utfs\\W",
        "cURL's",
        "nedmalloc'ed",
        "ntifs\\.h",
    ],
}
EOF
die "Could not write settings.json"

# Infer some setup-specific locations/names

GCCPATH="$(which gcc)"
GDBPATH="$(which gdb)"
MAKECOMMAND="make -j5 DEVELOPER=1"
OSNAME=
X=
case "$(uname -s)" in
MINGW*)
	GCCPATH="$(cygpath -am "$GCCPATH")"
	GDBPATH="$(cygpath -am "$GDBPATH")"
	MAKE_BASH="$(cygpath -am /git-cmd.exe) --command=usr\\\\bin\\\\bash.exe"
	MAKECOMMAND="$MAKE_BASH -lc \\\"$MAKECOMMAND\\\""
	OSNAME=Win32
	X=.exe
	;;
Linux)
	OSNAME=Linux
	;;
Darwin)
	OSNAME=macOS
	;;
esac

# Default build task

cat >.vscode/tasks.json.new <<EOF ||
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "make",
            "type": "shell",
            "command": "$MAKECOMMAND",
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}
EOF
die "Could not install default build task"

# Debugger settings

cat >.vscode/launch.json.new <<EOF ||
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit:
    // https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "\${workspaceFolder}/git$X",
            "args": [],
            "stopAtEntry": false,
            "cwd": "\${workspaceFolder}",
            "environment": [],
            "MIMode": "gdb",
            "miDebuggerPath": "$GDBPATH",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}
EOF
die "Could not write launch configuration"

# C/C++ extension settings

make -f - OSNAME=$OSNAME GCCPATH="$GCCPATH" vscode-init \
	>.vscode/c_cpp_properties.json <<\EOF ||
include Makefile

vscode-init:
	@mkdir -p .vscode && \
	incs= && defs= && \
	for e in $(ALL_CFLAGS) \
			'-DGIT_EXEC_PATH="$(gitexecdir_SQ)"' \
			'-DGIT_LOCALE_PATH="$(localedir_relative_SQ)"' \
			'-DBINDIR="$(bindir_relative_SQ)"' \
			'-DFALLBACK_RUNTIME_PREFIX="$(prefix_SQ)"' \
			'-DDEFAULT_GIT_TEMPLATE_DIR="$(template_dir_SQ)"' \
			'-DETC_GITCONFIG="$(ETC_GITCONFIG_SQ)"' \
			'-DETC_GITATTRIBUTES="$(ETC_GITATTRIBUTES_SQ)"' \
			'-DGIT_LOCALE_PATH="$(localedir_relative_SQ)"' \
			'-DCURL_DISABLE_TYPECHECK', \
			'-DGIT_HTML_PATH="$(htmldir_relative_SQ)"' \
			'-DGIT_MAN_PATH="$(mandir_relative_SQ)"' \
			'-DGIT_INFO_PATH="$(infodir_relative_SQ)"'; do \
		case "$$e" in \
		-I.) \
			incs="$$(printf '% 16s"$${workspaceRoot}",\n%s' \
				"" "$$incs")" \
			;; \
		-I/*) \
			incs="$$(printf '% 16s"%s",\n%s' \
				"" "$${e#-I}" "$$incs")" \
			;; \
		-I*) \
			incs="$$(printf '% 16s"$${workspaceRoot}/%s",\n%s' \
				"" "$${e#-I}" "$$incs")" \
			;; \
		-D*) \
			defs="$$(printf '% 16s"%s",\n%s' \
				"" "$$(echo "$${e#-D}" | sed 's/"/\\&/g')" \
				"$$defs")" \
			;; \
		esac; \
	done && \
	echo '{' && \
	echo '    "configurations": [' && \
	echo '        {' && \
	echo '            "name": "$(OSNAME)",' && \
	echo '            "intelliSenseMode": "clang-x64",' && \
	echo '            "includePath": [' && \
	echo "$$incs" | sort | sed '$$s/,$$//' && \
	echo '            ],' && \
	echo '            "defines": [' && \
	echo "$$defs" | sort | sed '$$s/,$$//' && \
	echo '            ],' && \
	echo '            "browse": {' && \
	echo '                "limitSymbolsToIncludedHeaders": true,' && \
	echo '                "databaseFilename": "",' && \
	echo '                "path": [' && \
	echo '                    "$${workspaceRoot}"' && \
	echo '                ]' && \
	echo '            },' && \
	echo '            "cStandard": "c11",' && \
	echo '            "cppStandard": "c++17",' && \
	echo '            "compilerPath": "$(GCCPATH)"' && \
	echo '        }' && \
	echo '    ],' && \
	echo '    "version": 4' && \
	echo '}'
EOF
die "Could not write settings for the C/C++ extension"

for file in .vscode/settings.json .vscode/tasks.json .vscode/launch.json
do
	if test -f $file
	then
		if git diff --no-index --quiet --exit-code $file $file.new
		then
			rm $file.new
		else
			printf "The file $file.new has these changes:\n\n"
			git --no-pager diff --no-index $file $file.new
			printf "\n\nMaybe \`mv $file.new $file\`?\n\n"
		fi
	else
		mv $file.new $file
	fi
done
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        #!/bin/sh

usage () {
	echo "usage:" $@
	exit 127
}

die () {
	echo $@
	exit 128
}

failed () {
	die "unable to create new workdir '$new_workdir'!"
}

if test $# -lt 2 || test $# -gt 3
then
	usage "$0 <repository> <new_workdir> [<branch>]"
fi

orig_git=$1
new_workdir=$2
branch=$3

# want to make sure that what is pointed to has a .git directory ...
git_dir=$(cd "$orig_git" 2>/dev/null &&
  git rev-parse --git-dir 2>/dev/null) ||
  die "Not a git repository: \"$orig_git\""

case "$git_dir" in
.git)
	git_dir="$orig_git/.git"
	;;
.)
	git_dir=$orig_git
	;;
esac

# don't link to a configured bare repository
isbare=$(git --git-dir="$git_dir" config --bool --get core.bare)
if test ztrue = "z$isbare"
then
	die "\"$git_dir\" has core.bare set to true," \
		" remove from \"$git_dir/config\" to use $0"
fi

# don't link to a workdir
if test -h "$git_dir/config"
then
	die "\"$orig_git\" is a working directory only, please specify" \
		"a complete repository."
fi

# make sure the links in the workdir have full paths to the original repo
git_dir=$(cd "$git_dir" && pwd) || exit 1

# don't recreate a workdir over an existing directory, unless it's empty
if test -d "$new_workdir"
then
	if test $(ls -a1 "$new_workdir/." | wc -l) -ne 2
	then
		die "destination directory '$new_workdir' is not empty."
	fi
	cleandir="$new_workdir/.git"
else
	cleandir="$new_workdir"
fi

mkdir -p "$new_workdir/.git" || failed
cleandir=$(cd "$cleandir" && pwd) || failed

cleanup () {
	rm -rf "$cleandir"
}
siglist="0 1 2 15"
trap cleanup $siglist

# create the links to the original repo.  explicitly exclude index, HEAD and
# logs/HEAD from the list since they are purely related to the current working
# directory, and should not be shared.
for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn
do
	# create a containing directory if needed
	case $x in
	*/*)
		mkdir -p "$new_workdir/.git/${x%/*}"
		;;
	esac

	ln -s "$git_dir/$x" "$new_workdir/.git/$x" || failed
done

# commands below this are run in the context of the new workdir
cd "$new_workdir" || failed

# copy the HEAD from the original repository as a default branch
cp "$git_dir/HEAD" .git/HEAD || failed

# the workdir is set up.  if the checkout fails, the user can fix it.
trap - $siglist

# checkout the branch (either the same as HEAD from the original repository,
# or the one that was asked for)
git checkout -f $branch
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Contact: git@vger.kernel.org
Source: https://www.kernel.org/pub/software/scm/git/

Files: *
Copyright: © 2005-2022, Linus Torvalds and others.
License: GPL-2

Files: reftable/* t/t0032-reftable-unittest.sh
Copyright: © 2020 Google LLC
License: BSD-3-clause
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
 .
 1. Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.
 3. Neither the name of the copyright holder nor the names of its contributors
    may be used to endorse or promote products derived from this software
    without specific prior written permission.
 .
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Files: compat/zlib-uncompress2.c
Copyright: © 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler
License: Zlib
 This software is provided 'as-is', without any express or implied warranty. In
 no event will the authors be held liable for any damages arising from the use
 of this software.
 .
 Permission is granted to anyone to use this software for any purpose, including
 commercial applications, and to alter it and redistribute it freely, subject to
 the following restrictions:
 .
 1. The origin of this software must not be misrepresented; you must not claim
    that you wrote the original software. If you use this software in a product,
    an acknowledgment in the product documentation would be appreciated but is
    not required.
 2. Altered source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.
 3. This notice may not be removed or altered from any source distribution.

Files: xdiff/*
Copyright: © 2003-2009, Davide Libenzi, Johannes E. Schindelin
License: LGPL-2.1+

Files: xdiff/xhistogram.c
Copyright: © 2010, Google Inc.
           and other copyright owners as documented in JGit's IP log.
License: EDL-1.0

Files: ewah/*
Copyright: © 2013, GitHub Inc.
           © 2009-2013, Daniel Lemire, Cliff Moon,
	       David McIntosh, Rober Becho, Google Inc. and Veronika Zenz
License: GPL-2+

Files: sha1dc/*
Copyright: © 2017,
	Marc Stevens
	Cryptology Group
	Centrum Wiskunde & Informatica
	P.O. Box 94079, 1090 GB Amsterdam, Netherlands
	marc@marc-stevens.nl
 .
	Dan Shumow
	Microsoft Research
	danshu@microsoft.com
License: Expat

Files: gitk-git/*
Copyright: © 2005-2016, Paul Mackerras, et al.
License: GPL-2+

Files: gitk-git/po/bg.po
Copyright: © 2014, 2015, 2016, 2017, 2018 Alexander Shopov <ash@kambanaria.org>
License: GPL-2
Comment: This file is distributed under the same license as the git package.

Files: git-gui/*
Copyright: © 2005-2010, Shawn Pearce, et. al.
License: GPL-2+

Files: git-gui/po/bg.po git-gui/po/de.po git-gui/po/fr.po git-gui/po/glossary/*
Copyright: © 2007-2008, Shawn Pearce, et al.
           © 2012-2015, Alexander Shopov <ash@kambanaria.org>
License: GPL-2
Comment: This file is distributed under the same license as the git package.

Files: git-gui/po/glossary/el.po git-gui/po/glossary/pt_br.po
Copyright: © 2007, Shawn Pearce, et al.
           © 2009, Jimmy Angelakos
License: GPL-2+
Comment: This file is distributed under the same license as the git-gui package.

Files: gitweb/static/js/*
Copyright: © 2007, Fredrik Kuivinen <frekui@gmail.com>
           © 2007, Petr Baudis <pasky@suse.cz>
      © 2008-2011, Jakub Narebski <jnareb@gmail.com>
           © 2011, John 'Warthog9' Hawley <warthog9@eaglescrag.net>
License: GPL-2+

Files: git-p4
Copyright: © 2007, Simon Hausmann <simon@lst.de>
           © 2007, Trolltech ASA
License: Expat

Files: git-svn.perl
Copyright: © 2006, Eric Wong <normalperson@yhbt.net>
License: GPL-2+

Files: imap-send.c
Copyright: © 2000-2002, Michael R. Elkins <me@mutt.org>
           © 2002-2004, Oswald Buddenhagen <ossi@users.sf.net>
           © 2004, Theodore Y. Ts'o <tytso@mit.edu>
           © 2006, Mike McCormack
Name: git-imap-send - drops patches into an imap Drafts folder
  derived from isync/mbsync - mailbox synchronizer
License: GPL-2+

Files: perl/Git.pm
Copyright: © 2006, by Petr Baudis <pasky@suse.cz>
License: GPL-2+

Files: perl/private-Error.pm
Copyright: © 1997-8, Graham Barr <gbarr@ti.com>
License: GPL-1+ or Artistic-1
 This program is free software; you can redistribute it and/or modify
 it under the terms of either:
 .
    a) the GNU General Public License as published by the Free Software
       Foundation; either version 1, or (at your option) any later
       version, or
 .
    b) the "Artistic License" which comes with Perl.
 .
 On Debian GNU/Linux systems, the complete text of the GNU General
 Public License can be found in '/usr/share/common-licenses/GPL' and
 the Artistic Licence in '/usr/share/common-licenses/Artistic'.

Files: kwset.c kwset.h
Copyright: © 1989, 1998, 2000, 2005, Free Software Foundation, Inc.
License: GPL-2+

Files: khash.h
Copyright: © 2008, 2009, 2011 by Attractive Chaos <attractor@live.co.uk>
License: Expat

Files: trace.c
Copyright: © 2000-2002, Michael R. Elkins <me@mutt.org>
           © 2002-2004, Oswald Buddenhagen <ossi@users.sf.net>
           © 2004, Theodore Y. Ts'o <tytso@mit.edu>
           © 2006, Mike McCormack
           © 2006, Christian Couder
License: GPL-2+

Files: sh-i18n--envsubst.c
Copyright: © 2010, Ævar Arnfjörð Bjarmason
           © 1998-2007, Free Software Foundation, Inc.
License: GPL-2+

Files: t/test-lib.sh
Copyright: © 2005, Junio C Hamano
License: GPL-2+

Files: t/test-lib-github-workflow-markup.sh t/test-lib-junit.sh
Copyright: © 2022, Johannes Schindelin
License: GPL-2+

Files: compat/inet_ntop.c compat/inet_pton.c
Copyright: © 1996-2001, Internet Software Consortium.
License: ISC

Files: compat/poll/poll.c compat/poll/poll.h
Copyright: © 2001-2003, 2006-2011, Free Software Foundation, Inc.
Name: Emulation for poll(2) from gnulib.
License: GPL-2+

Files: compat/vcbuild/include/sys/utime.h
Copyright: ?
License: mingw-runtime

Files: compat/nedmalloc/*
Copyright: © 2005-2006 Niall Douglas
License: Boost

Files: compat/nedmalloc/malloc.c.h
Copyright: © 2006, KJK::Hyperion <hackbunny@reactos.com>
License: dlmalloc

Files: compat/regex/*
Copyright: © 1985, 1989-93, 1995-2010, Free Software Foundation, Inc.
Name: Extended regular expression matching and search library
License: LGPL-2.1+

Files: compat/obstack.c compat/obstack.h
Copyright: © 1988-1994, 1996-2005, 2009, Free Software Foundation, Inc.
Name: Object stack macros.
License: LGPL-2.1+

Files: contrib/persistent-https/*
Copyright: © 2012, Google Inc.
License: Apache-2.0

Files: contrib/credential/gnome-keyring/git-credential-gnome-keyring.c
Copyright: © 2011, John Szakmeister <john@szakmeister.net>
           © 2012, Philipp A. Hartmann <pah@qo.cx>
License: GPL-2+

Files: contrib/hg-to-git/hg-to-git.py
Copyright: © 2007, Stelian Pop <stelian@popies.net>
Name: hg-to-git.py - A Mercurial to GIT converter
License: GPL-2+

Files: contrib/mw-to-git/git-*.perl contrib/mw-to-git/t/t*
Copyright: © 2011
		Jérémie Nikaes <jeremie.nikaes@ensimag.imag.fr>
		Arnaud Lacurie <arnaud.lacurie@ensimag.imag.fr>
		Claire Fousse <claire.fousse@ensimag.imag.fr>
		David Amouyal <david.amouyal@ensimag.imag.fr>
		Matthieu Moy <matthieu.moy@grenoble-inp.fr>
           © 2012
		Charles Roussel <charles.roussel@ensimag.imag.fr>
		Simon Cathebras <simon.cathebras@ensimag.imag.fr>
		Julien Khayat <julien.khayat@ensimag.imag.fr>
		Guillaume Sasdy <guillaume.sasdy@ensimag.imag.fr>
		Simon Perrat <simon.perrat@ensimag.imag.fr>
	   © 2013
		Benoit Person <benoit.person@ensimag.imag.fr>
		Celestin Matte <celestin.matte@ensimag.imag.fr>
License: GPL-2+

Files: debian/*
Copyright: © 2005, Sebastian Kuzminsky <seb@highlab.com>
           © 2005-2006, Andres Salomon <dilinger@debian.org>
           © 2005-2012, Gerrit Pape <pape@smarden.org>
License: GPL-2

License: GPL-2
 You can redistribute this software and/or modify it under the terms of
 the GNU General Public License as published by the Free Software
 Foundation; version 2 dated June, 1991.
 .
 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.
 .
 On Debian systems, the complete text of the GNU General Public License
 can be found in /usr/share/common-licenses/GPL-2 file.

License: GPL-2+
 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, 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.
 .
 On Debian systems, the complete text of the GNU General Public License
 can be found in /usr/share/common-licenses/GPL-2 file.

License: LGPL-2+
 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public License as
 published by the Free Software Foundation; either version 2 of the
 License, or (at your option) any later version.
 .
 This library 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
 Library General Public License for more details.
 .
 On Debian systems, the complete text of the GNU Library General Public License
 can be found in the /usr/share/common-licenses/LGPL-2 file.

License: LGPL-2.1+
 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.
 .
 This library 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
 Lesser General Public License for more details.
 .
 On Debian systems, the complete text of the GNU Lesser General Public License
 can be found in /usr/share/common-licenses/LGPL-2.1.

License: Apache-2.0
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 .
     http://www.apache.org/licenses/LICENSE-2.0
 .
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 .
 On Debian systems, the full text of the Apache License version 2 can
 be found in /usr/share/common-licenses/Apache-2.0.

License: ISC
 Permission to use, copy, modify, and distribute this software for any
 purpose with or without fee is hereby granted, provided that the above
 copyright notice and this permission notice appear in all copies.
 .
 THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
 ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
 OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
 CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 SOFTWARE.

License: Expat
 <http://www.opensource.org/licenses/mit-license.php>:
 .
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:
 .
 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.
 .
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.

License: EDL-1.0
 Redistribution and use in source and binary forms, with or
 without modification, are permitted provided that the following
 conditions are met:
 .
 - Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
 .
 - Redistributions in binary form must reproduce the above
   copyright notice, this list of conditions and the following
   disclaimer in the documentation and/or other materials provided
   with the distribution.
 .
 - Neither the name of the Eclipse Foundation, Inc. nor the
   names of its contributors may be used to endorse or promote
   products derived from this software without specific prior
   written permission.
 .
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

License: mingw-runtime
 This file has no copyright assigned and is placed in the Public Domain.
 This file is a part of the mingw-runtime package.
 .
 The mingw-runtime package and its code is distributed in the hope that it
 will be useful but WITHOUT ANY WARRANTY.  ALL WARRANTIES, EXPRESSED OR
 IMPLIED ARE HEREBY DISCLAIMED.  This includes but is not limited to
 warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 .
 You are free to use this package and its code without limitation.

License: Boost
 It is licensed under the Boost Software License which basically means
 you can do anything you like with it. This does not apply to the malloc.c.h
 file which remains copyright to others.
 .
 Boost Software License - Version 1.0 - August 17th, 2003
 .
 Permission is hereby granted, free of charge, to any person or organization
 obtaining a copy of the software and accompanying documentation covered by
 this license (the "Software") to use, reproduce, display, distribute,
 execute, and transmit the Software, and to prepare derivative works of the
 Software, and to permit third-parties to whom the Software is furnished to
 do so, all subject to the following:
 .
 The copyright notices in the Software and this entire statement, including
 the above license grant, this restriction and the following disclaimer,
 must be included in all copies of the Software, in whole or in part, and
 all derivative works of the Software, unless such copies or derivative
 works are solely in the form of machine-executable object code generated by
 a source language processor.
 .
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.

License: dlmalloc
 This is a version (aka dlmalloc) of malloc/free/realloc written by
 Doug Lea and released to the public domain, as explained at
 http://creativecommons.org/licenses/publicdomain.  Send questions,
 comments, complaints, performance data, etc to dl@cs.oswego.edu
 .
 Incorporates code from intrin_x86.h, which bears the following notice:
 .
 Compatibility <intrin_x86.h> header for GCC -- GCC equivalents of intrinsic
 Microsoft Visual C++ functions. Originally developed for the ReactOS
 (<http://www.reactos.org/>) and TinyKrnl (<http://www.tinykrnl.org/>)
 projects.
 .
 Copyright (c) 2006 KJK::Hyperion <hackbunny@reactos.com>
 .
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
 to deal in the Software without restriction, including without limitation
 the rights to use, copy, modify, merge, publish, distribute, sublicense,
 and/or sell copies of the Software, and to permit persons to whom the
 Software is furnished to do so, subject to the following conditions:
 .
 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.
 .
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      #!/bin/sh
#
# Copyright (c) 2007 Andy Parkins
#
# An example hook script to mail out commit update information.
#
# NOTE: This script is no longer under active development.  There
# is another script, git-multimail, which is more capable and
# configurable and is largely backwards-compatible with this script;
# please see "contrib/hooks/multimail/".  For instructions on how to
# migrate from post-receive-email to git-multimail, please see
# "README.migrate-from-post-receive-email" in that directory.
#
# This hook sends emails listing new revisions to the repository
# introduced by the change being reported.  The rule is that (for
# branch updates) each commit will appear on one email and one email
# only.
#
# This hook is stored in the contrib/hooks directory.  Your distribution
# will have put this somewhere standard.  You should make this script
# executable then link to it in the repository you would like to use it in.
# For example, on debian the hook is stored in
# /usr/share/git-core/contrib/hooks/post-receive-email:
#
#  cd /path/to/your/repository.git
#  ln -sf /usr/share/git-core/contrib/hooks/post-receive-email hooks/post-receive
#
# This hook script assumes it is enabled on the central repository of a
# project, with all users pushing only to it and not between each other.  It
# will still work if you don't operate in that style, but it would become
# possible for the email to be from someone other than the person doing the
# push.
#
# To help with debugging and use on pre-v1.5.1 git servers, this script will
# also obey the interface of hooks/update, taking its arguments on the
# command line.  Unfortunately, hooks/update is called once for each ref.
# To avoid firing one email per ref, this script just prints its output to
# the screen when used in this mode.  The output can then be redirected if
# wanted.
#
# Config
# ------
# hooks.mailinglist
#   This is the list that all pushes will go to; leave it blank to not send
#   emails for every ref update.
# hooks.announcelist
#   This is the list that all pushes of annotated tags will go to.  Leave it
#   blank to default to the mailinglist field.  The announce emails lists
#   the short log summary of the changes since the last annotated tag.
# hooks.envelopesender
#   If set then the -f option is passed to sendmail to allow the envelope
#   sender address to be set
# hooks.emailprefix
#   All emails have their subjects prefixed with this prefix, or "[SCM]"
#   if emailprefix is unset, to aid filtering
# hooks.showrev
#   The shell command used to format each revision in the email, with
#   "%s" replaced with the commit id.  Defaults to "git rev-list -1
#   --pretty %s", displaying the commit id, author, date and log
#   message.  To list full patches separated by a blank line, you
#   could set this to "git show -C %s; echo".
#   To list a gitweb/cgit URL *and* a full patch for each change set, use this:
#     "t=%s; printf 'http://.../?id=%%s' \$t; echo;echo; git show -C \$t; echo"
#   Be careful if "..." contains things that will be expanded by shell "eval"
#   or printf.
# hooks.emailmaxlines
#   The maximum number of lines that should be included in the generated
#   email body. If not specified, there is no limit.
#   Lines beyond the limit are suppressed and counted, and a final
#   line is added indicating the number of suppressed lines.
# hooks.diffopts
#   Alternate options for the git diff-tree invocation that shows changes.
#   Default is "--stat --summary --find-copies-harder". Add -p to those
#   options to include a unified diff of changes in addition to the usual
#   summary output.
#
# Notes
# -----
# All emails include the headers "X-Git-Refname", "X-Git-Oldrev",
# "X-Git-Newrev", and "X-Git-Reftype" to enable fine tuned filtering and
# give information for debugging.
#

# ---------------------------- Functions

#
# Function to prepare for email generation. This decides what type
# of update this is and whether an email should even be generated.
#
prep_for_email()
{
	# --- Arguments
	oldrev=$(git rev-parse $1)
	newrev=$(git rev-parse $2)
	refname="$3"

	# --- Interpret
	# 0000->1234 (create)
	# 1234->2345 (update)
	# 2345->0000 (delete)
	if expr "$oldrev" : '0*$' >/dev/null
	then
		change_type="create"
	else
		if expr "$newrev" : '0*$' >/dev/null
		then
			change_type="delete"
		else
			change_type="update"
		fi
	fi

	# --- Get the revision types
	newrev_type=$(git cat-file -t $newrev 2> /dev/null)
	oldrev_type=$(git cat-file -t "$oldrev" 2> /dev/null)
	case "$change_type" in
	create|update)
		rev="$newrev"
		rev_type="$newrev_type"
		;;
	delete)
		rev="$oldrev"
		rev_type="$oldrev_type"
		;;
	esac

	# The revision type tells us what type the commit is, combined with
	# the location of the ref we can decide between
	#  - working branch
	#  - tracking branch
	#  - unannoted tag
	#  - annotated tag
	case "$refname","$rev_type" in
		refs/tags/*,commit)
			# un-annotated tag
			refname_type="tag"
			short_refname=${refname##refs/tags/}
			;;
		refs/tags/*,tag)
			# annotated tag
			refname_type="annotated tag"
			short_refname=${refname##refs/tags/}
			# change recipients
			if [ -n "$announcerecipients" ]; then
				recipients="$announcerecipients"
			fi
			;;
		refs/heads/*,commit)
			# branch
			refname_type="branch"
			short_refname=${refname##refs/heads/}
			;;
		refs/remotes/*,commit)
			# tracking branch
			refname_type="tracking branch"
			short_refname=${refname##refs/remotes/}
			echo >&2 "*** Push-update of tracking branch, $refname"
			echo >&2 "***  - no email generated."
			return 1
			;;
		*)
			# Anything else (is there anything else?)
			echo >&2 "*** Unknown type of update to $refname ($rev_type)"
			echo >&2 "***  - no email generated"
			return 1
			;;
	esac

	# Check if we've got anyone to send to
	if [ -z "$recipients" ]; then
		case "$refname_type" in
			"annotated tag")
				config_name="hooks.announcelist"
				;;
			*)
				config_name="hooks.mailinglist"
				;;
		esac
		echo >&2 "*** $config_name is not set so no email will be sent"
		echo >&2 "*** for $refname update $oldrev->$newrev"
		return 1
	fi

	return 0
}

#
# Top level email generation function.  This calls the appropriate
# body-generation routine after outputting the common header.
#
# Note this function doesn't actually generate any email output, that is
# taken care of by the functions it calls:
#  - generate_email_header
#  - generate_create_XXXX_email
#  - generate_update_XXXX_email
#  - generate_delete_XXXX_email
#  - generate_email_footer
#
# Note also that this function cannot 'exit' from the script; when this
# function is running (in hook script mode), the send_mail() function
# is already executing in another process, connected via a pipe, and
# if this function exits without, whatever has been generated to that
# point will be sent as an email... even if nothing has been generated.
#
generate_email()
{
	# Email parameters
	# The email subject will contain the best description of the ref
	# that we can build from the parameters
	describe=$(git describe $rev 2>/dev/null)
	if [ -z "$describe" ]; then
		describe=$rev
	fi

	generate_email_header

	# Call the correct body generation function
	fn_name=general
	case "$refname_type" in
	"tracking branch"|branch)
		fn_name=branch
		;;
	"annotated tag")
		fn_name=atag
		;;
	esac

	if [ -z "$maxlines" ]; then
		generate_${change_type}_${fn_name}_email
	else
		generate_${change_type}_${fn_name}_email | limit_lines $maxlines
	fi

	generate_email_footer
}

generate_email_header()
{
	# --- Email (all stdout will be the email)
	# Generate header
	cat <<-EOF
	To: $recipients
	Subject: ${emailprefix}$projectdesc $refname_type $short_refname ${change_type}d. $describe
	MIME-Version: 1.0
	Content-Type: text/plain; charset=utf-8
	Content-Transfer-Encoding: 8bit
	X-Git-Refname: $refname
	X-Git-Reftype: $refname_type
	X-Git-Oldrev: $oldrev
	X-Git-Newrev: $newrev
	Auto-Submitted: auto-generated

	This is an automated email from the git hooks/post-receive script. It was
	generated because a ref change was pushed to the repository containing
	the project "$projectdesc".

	The $refname_type, $short_refname has been ${change_type}d
	EOF
}

generate_email_footer()
{
	SPACE=" "
	cat <<-EOF


	hooks/post-receive
	--${SPACE}
	$projectdesc
	EOF
}

# --------------- Branches

#
# Called for the creation of a branch
#
generate_create_branch_email()
{
	# This is a new branch and so oldrev is not valid
	echo "        at  $newrev ($newrev_type)"
	echo ""

	echo $LOGBEGIN
	show_new_revisions
	echo $LOGEND
}

#
# Called for the change of a pre-existing branch
#
generate_update_branch_email()
{
	# Consider this:
	#   1 --- 2 --- O --- X --- 3 --- 4 --- N
	#
	# O is $oldrev for $refname
	# N is $newrev for $refname
	# X is a revision pointed to by some other ref, for which we may
	#   assume that an email has already been generated.
	# In this case we want to issue an email containing only revisions
	# 3, 4, and N.  Given (almost) by
	#
	#  git rev-list N ^O --not --all
	#
	# The reason for the "almost", is that the "--not --all" will take
	# precedence over the "N", and effectively will translate to
	#
	#  git rev-list N ^O ^X ^N
	#
	# So, we need to build up the list more carefully.  git rev-parse
	# will generate a list of revs that may be fed into git rev-list.
	# We can get it to make the "--not --all" part and then filter out
	# the "^N" with:
	#
	#  git rev-parse --not --all | grep -v N
	#
	# Then, using the --stdin switch to git rev-list we have effectively
	# manufactured
	#
	#  git rev-list N ^O ^X
	#
	# This leaves a problem when someone else updates the repository
	# while this script is running.  Their new value of the ref we're
	# working on would be included in the "--not --all" output; and as
	# our $newrev would be an ancestor of that commit, it would exclude
	# all of our commits.  What we really want is to exclude the current
	# value of $refname from the --not list, rather than N itself.  So:
	#
	#  git rev-parse --not --all | grep -v $(git rev-parse $refname)
	#
	# Gets us to something pretty safe (apart from the small time
	# between refname being read, and git rev-parse running - for that,
	# I give up)
	#
	#
	# Next problem, consider this:
	#   * --- B --- * --- O ($oldrev)
	#          \
	#           * --- X --- * --- N ($newrev)
	#
	# That is to say, there is no guarantee that oldrev is a strict
	# subset of newrev (it would have required a --force, but that's
	# allowed).  So, we can't simply say rev-list $oldrev..$newrev.
	# Instead we find the common base of the two revs and list from
	# there.
	#
	# As above, we need to take into account the presence of X; if
	# another branch is already in the repository and points at some of
	# the revisions that we are about to output - we don't want them.
	# The solution is as before: git rev-parse output filtered.
	#
	# Finally, tags: 1 --- 2 --- O --- T --- 3 --- 4 --- N
	#
	# Tags pushed into the repository generate nice shortlog emails that
	# summarise the commits between them and the previous tag.  However,
	# those emails don't include the full commit messages that we output
	# for a branch update.  Therefore we still want to output revisions
	# that have been output on a tag email.
	#
	# Luckily, git rev-parse includes just the tool.  Instead of using
	# "--all" we use "--branches"; this has the added benefit that
	# "remotes/" will be ignored as well.

	# List all of the revisions that were removed by this update, in a
	# fast-forward update, this list will be empty, because rev-list O
	# ^N is empty.  For a non-fast-forward, O ^N is the list of removed
	# revisions
	fast_forward=""
	rev=""
	for rev in $(git rev-list $newrev..$oldrev)
	do
		revtype=$(git cat-file -t "$rev")
		echo "  discards  $rev ($revtype)"
	done
	if [ -z "$rev" ]; then
		fast_forward=1
	fi

	# List all the revisions from baserev to newrev in a kind of
	# "table-of-contents"; note this list can include revisions that
	# have already had notification emails and is present to show the
	# full detail of the change from rolling back the old revision to
	# the base revision and then forward to the new revision
	for rev in $(git rev-list $oldrev..$newrev)
	do
		revtype=$(git cat-file -t "$rev")
		echo "       via  $rev ($revtype)"
	done

	if [ "$fast_forward" ]; then
		echo "      from  $oldrev ($oldrev_type)"
	else
		#  1. Existing revisions were removed.  In this case newrev
		#     is a subset of oldrev - this is the reverse of a
		#     fast-forward, a rewind
		#  2. New revisions were added on top of an old revision,
		#     this is a rewind and addition.

		# (1) certainly happened, (2) possibly.  When (2) hasn't
		# happened, we set a flag to indicate that no log printout
		# is required.

		echo ""

		# Find the common ancestor of the old and new revisions and
		# compare it with newrev
		baserev=$(git merge-base $oldrev $newrev)
		rewind_only=""
		if [ "$baserev" = "$newrev" ]; then
			echo "This update discarded existing revisions and left the branch pointing at"
			echo "a previous point in the repository history."
			echo ""
			echo " * -- * -- N ($newrev)"
			echo "            \\"
			echo "             O -- O -- O ($oldrev)"
			echo ""
			echo "The removed revisions are not necessarily gone - if another reference"
			echo "still refers to them they will stay in the repository."
			rewind_only=1
		else
			echo "This update added new revisions after undoing existing revisions.  That is"
			echo "to say, the old revision is not a strict subset of the new revision.  This"
			echo "situation occurs when you --force push a change and generate a repository"
			echo "containing something like this:"
			echo ""
			echo " * -- * -- B -- O -- O -- O ($oldrev)"
			echo "            \\"
			echo "             N -- N -- N ($newrev)"
			echo ""
			echo "When this happens we assume that you've already had alert emails for all"
			echo "of the O revisions, and so we here report only the revisions in the N"
			echo "branch from the common base, B."
		fi
	fi

	echo ""
	if [ -z "$rewind_only" ]; then
		echo "Those revisions listed above that are new to this repository have"
		echo "not appeared on any other notification email; so we list those"
		echo "revisions in full, below."

		echo ""
		echo $LOGBEGIN
		show_new_revisions

		# XXX: Need a way of detecting whether git rev-list actually
		# outputted anything, so that we can issue a "no new
		# revisions added by this update" message

		echo $LOGEND
	else
		echo "No new revisions were added by this update."
	fi

	# The diffstat is shown from the old revision to the new revision.
	# This is to show the truth of what happened in this change.
	# There's no point showing the stat from the base to the new
	# revision because the base is effectively a random revision at this
	# point - the user will be interested in what this revision changed
	# - including the undoing of previous revisions in the case of
	# non-fast-forward updates.
	echo ""
	echo "Summary of changes:"
	git diff-tree $diffopts $oldrev..$newrev
}

#
# Called for the deletion of a branch
#
generate_delete_branch_email()
{
	echo "       was  $oldrev"
	echo ""
	echo $LOGBEGIN
	git diff-tree -s --always --encoding=UTF-8 --pretty=oneline $oldrev
	echo $LOGEND
}

# --------------- Annotated tags

#
# Called for the creation of an annotated tag
#
generate_create_atag_email()
{
	echo "        at  $newrev ($newrev_type)"

	generate_atag_email
}

#
# Called for the update of an annotated tag (this is probably a rare event
# and may not even be allowed)
#
generate_update_atag_email()
{
	echo "        to  $newrev ($newrev_type)"
	echo "      from  $oldrev (which is now obsolete)"

	generate_atag_email
}

#
# Called when an annotated tag is created or changed
#
generate_atag_email()
{
	# Use git for-each-ref to pull out the individual fields from the
	# tag
	eval $(git for-each-ref --shell --format='
	tagobject=%(*objectname)
	tagtype=%(*objecttype)
	tagger=%(taggername)
	tagged=%(taggerdate)' $refname
	)

	echo "   tagging  $tagobject ($tagtype)"
	case "$tagtype" in
	commit)

		# If the tagged object is a commit, then we assume this is a
		# release, and so we calculate which tag this tag is
		# replacing
		prevtag=$(git describe --abbrev=0 $newrev^ 2>/dev/null)

		if [ -n "$prevtag" ]; then
			echo "  replaces  $prevtag"
		fi
		;;
	*)
		echo "    length  $(git cat-file -s $tagobject) bytes"
		;;
	esac
	echo " tagged by  $tagger"
	echo "        on  $tagged"

	echo ""
	echo $LOGBEGIN

	# Show the content of the tag message; this might contain a change
	# log or release notes so is worth displaying.
	git cat-file tag $newrev | sed -e '1,/^$/d'

	echo ""
	case "$tagtype" in
	commit)
		# Only commit tags make sense to have rev-list operations
		# performed on them
		if [ -n "$prevtag" ]; then
			# Show changes since the previous release
			git shortlog "$prevtag..$newrev"
		else
			# No previous tag, show all the changes since time
			# began
			git shortlog $newrev
		fi
		;;
	*)
		# XXX: Is there anything useful we can do for non-commit
		# objects?
		;;
	esac

	echo $LOGEND
}

#
# Called for the deletion of an annotated tag
#
generate_delete_atag_email()
{
	echo "       was  $oldrev"
	echo ""
	echo $LOGBEGIN
	git diff-tree -s --always --encoding=UTF-8 --pretty=oneline $oldrev
	echo $LOGEND
}

# --------------- General references

#
# Called when any other type of reference is created (most likely a
# non-annotated tag)
#
generate_create_general_email()
{
	echo "        at  $newrev ($newrev_type)"

	generate_general_email
}

#
# Called when any other type of reference is updated (most likely a
# non-annotated tag)
#
generate_update_general_email()
{
	echo "        to  $newrev ($newrev_type)"
	echo "      from  $oldrev"

	generate_general_email
}

#
# Called for creation or update of any other type of reference
#
generate_general_email()
{
	# Unannotated tags are more about marking a point than releasing a
	# version; therefore we don't do the shortlog summary that we do for
	# annotated tags above - we simply show that the point has been
	# marked, and print the log message for the marked point for
	# reference purposes
	#
	# Note this section also catches any other reference type (although
	# there aren't any) and deals with them in the same way.

	echo ""
	if [ "$newrev_type" = "commit" ]; then
		echo $LOGBEGIN
		git diff-tree -s --always --encoding=UTF-8 --pretty=medium $newrev
		echo $LOGEND
	else
		# What can we do here?  The tag marks an object that is not
		# a commit, so there is no log for us to display.  It's
		# probably not wise to output git cat-file as it could be a
		# binary blob.  We'll just say how big it is
		echo "$newrev is a $newrev_type, and is $(git cat-file -s $newrev) bytes long."
	fi
}

#
# Called for the deletion of any other type of reference
#
generate_delete_general_email()
{
	echo "       was  $oldrev"
	echo ""
	echo $LOGBEGIN
	git diff-tree -s --always --encoding=UTF-8 --pretty=oneline $oldrev
	echo $LOGEND
}


# --------------- Miscellaneous utilities

#
# Show new revisions as the user would like to see them in the email.
#
show_new_revisions()
{
	# This shows all log entries that are not already covered by
	# another ref - i.e. commits that are now accessible from this
	# ref that were previously not accessible
	# (see generate_update_branch_email for the explanation of this
	# command)

	# Revision range passed to rev-list differs for new vs. updated
	# branches.
	if [ "$change_type" = create ]
	then
		# Show all revisions exclusive to this (new) branch.
		revspec=$newrev
	else
		# Branch update; show revisions not part of $oldrev.
		revspec=$oldrev..$newrev
	fi

	other_branches=$(git for-each-ref --format='%(refname)' refs/heads/ |
	    grep -F -v $refname)
	git rev-parse --not $other_branches |
	if [ -z "$custom_showrev" ]
	then
		git rev-list --pretty --stdin $revspec
	else
		git rev-list --stdin $revspec |
		while read onerev
		do
			eval $(printf "$custom_showrev" $onerev)
		done
	fi
}


limit_lines()
{
	lines=0
	skipped=0
	while IFS="" read -r line; do
		lines=$((lines + 1))
		if [ $lines -gt $1 ]; then
			skipped=$((skipped + 1))
		else
			printf "%s\n" "$line"
		fi
	done
	if [ $skipped -ne 0 ]; then
		echo "... $skipped lines suppressed ..."
	fi
}


send_mail()
{
	if [ -n "$envelopesender" ]; then
		/usr/sbin/sendmail -t -f "$envelopesender"
	else
		/usr/sbin/sendmail -t
	fi
}

# ---------------------------- main()

# --- Constants
LOGBEGIN="- Log -----------------------------------------------------------------"
LOGEND="-----------------------------------------------------------------------"

# --- Config
# Set GIT_DIR either from the working directory, or from the environment
# variable.
GIT_DIR=$(git rev-parse --git-dir 2>/dev/null)
if [ -z "$GIT_DIR" ]; then
	echo >&2 "fatal: post-receive: GIT_DIR not set"
	exit 1
fi

projectdesc=$(sed -ne '1p' "$GIT_DIR/description" 2>/dev/null)
# Check if the description is unchanged from it's default, and shorten it to
# a more manageable length if it is
if expr "$projectdesc" : "Unnamed repository.*$" >/dev/null
then
	projectdesc="UNNAMED PROJECT"
fi

recipients=$(git config hooks.mailinglist)
announcerecipients=$(git config hooks.announcelist)
envelopesender=$(git config hooks.envelopesender)
emailprefix=$(git config hooks.emailprefix || echo '[SCM] ')
custom_showrev=$(git config hooks.showrev)
maxlines=$(git config hooks.emailmaxlines)
diffopts=$(git config hooks.diffopts)
: ${diffopts:="--stat --summary --find-copies-harder"}

# --- Main loop
# Allow dual mode: run from the command line just like the update hook, or
# if no arguments are given then run as a hook script
if [ -n "$1" -a -n "$2" -a -n "$3" ]; then
	# Output to the terminal in command line mode - if someone wanted to
	# resend an email; they could redirect the output to sendmail
	# themselves
	prep_for_email $2 $3 $1 && PAGER= generate_email
else
	while read oldrev newrev refname
	do
		prep_for_email $oldrev $newrev $refname || continue
		generate_email $maxlines | send_mail
	done
fi
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           #!/bin/sh
#
# An example hook script to verify if you are on battery, in case you
# are running Linux or OS X. Called by git-gc --auto with no arguments.
# The hook should exit with non-zero status after issuing an appropriate
# message if it wants to stop the auto repacking.
#
# This hook is stored in the contrib/hooks directory. Your distribution
# may have put this somewhere else. If you want to use this hook, you
# should make this script executable then link to it in the repository
# you would like to use it in.
#
# For example, if the hook is stored in
# /usr/share/git-core/contrib/hooks/pre-auto-gc-battery:
#
# cd /path/to/your/repository.git
# ln -sf /usr/share/git-core/contrib/hooks/pre-auto-gc-battery \
#	hooks/pre-auto-gc

if test -x /sbin/on_ac_power && (/sbin/on_ac_power;test $? -ne 1)
then
	exit 0
elif test "$(cat /sys/class/power_supply/AC/online 2>/dev/null)" = 1
then
	exit 0
elif grep -q 'on-line' /proc/acpi/ac_adapter/AC/state 2>/dev/null
then
	exit 0
elif grep -q '0x01$' /proc/apm 2>/dev/null
then
	exit 0
elif grep -q "AC Power \+: 1" /proc/pmu/info 2>/dev/null
then
	exit 0
elif test -x /usr/bin/pmset && /usr/bin/pmset -g batt |
	grep -q "drawing from 'AC Power'"
then
	exit 0
fi

echo "Auto packing deferred; not on AC"
exit 1
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               #!/usr/bin/perl
#
# Copyright (c) 2006 Josh England
#
# This script can be used to save/restore full permissions and ownership data
# within a git working tree.
#
# To save permissions/ownership data, place this script in your .git/hooks
# directory and enable a `pre-commit` hook with the following lines:
#      #!/bin/sh
#     SUBDIRECTORY_OK=1 . git-sh-setup
#     $GIT_DIR/hooks/setgitperms.perl -r
#
# To restore permissions/ownership data, place this script in your .git/hooks
# directory and enable a `post-merge` and `post-checkout` hook with the
# following lines:
#      #!/bin/sh
#     SUBDIRECTORY_OK=1 . git-sh-setup
#     $GIT_DIR/hooks/setgitperms.perl -w
#
use strict;
use Getopt::Long;
use File::Find;
use File::Basename;

my $usage =
"usage: setgitperms.perl [OPTION]... <--read|--write>
This program uses a file `.gitmeta` to store/restore permissions and uid/gid
info for all files/dirs tracked by git in the repository.

---------------------------------Read Mode-------------------------------------
-r,  --read         Reads perms/etc from working dir into a .gitmeta file
-s,  --stdout       Output to stdout instead of .gitmeta
-d,  --diff         Show unified diff of perms file (XOR with --stdout)

---------------------------------Write Mode------------------------------------
-w,  --write        Modify perms/etc in working dir to match the .gitmeta file
-v,  --verbose      Be verbose

\n";

my ($stdout, $showdiff, $verbose, $read_mode, $write_mode);

if ((@ARGV < 0) || !GetOptions(
			       "stdout",         \$stdout,
			       "diff",           \$showdiff,
			       "read",           \$read_mode,
			       "write",          \$write_mode,
			       "verbose",        \$verbose,
			      )) { die $usage; }
die $usage unless ($read_mode xor $write_mode);

my $topdir = `git rev-parse --show-cdup` or die "\n"; chomp $topdir;
my $gitdir = $topdir . '.git';
my $gitmeta = $topdir . '.gitmeta';

if ($write_mode) {
    # Update the working dir permissions/ownership based on data from .gitmeta
    open (IN, "<$gitmeta") or die "Could not open $gitmeta for reading: $!\n";
    while (defined ($_ = <IN>)) {
	chomp;
	if (/^(.*)  mode=(\S+)\s+uid=(\d+)\s+gid=(\d+)/) {
	    # Compare recorded perms to actual perms in the working dir
	    my ($path, $mode, $uid, $gid) = ($1, $2, $3, $4);
	    my $fullpath = $topdir . $path;
	    my (undef,undef,$wmode,undef,$wuid,$wgid) = lstat($fullpath);
	    $wmode = sprintf "%04o", $wmode & 07777;
	    if ($mode ne $wmode) {
		$verbose && print "Updating permissions on $path: old=$wmode, new=$mode\n";
		chmod oct($mode), $fullpath;
	    }
	    if ($uid != $wuid || $gid != $wgid) {
		if ($verbose) {
		    # Print out user/group names instead of uid/gid
		    my $pwname  = getpwuid($uid);
		    my $grpname  = getgrgid($gid);
		    my $wpwname  = getpwuid($wuid);
		    my $wgrpname  = getgrgid($wgid);
		    $pwname = $uid if !defined $pwname;
		    $grpname = $gid if !defined $grpname;
		    $wpwname = $wuid if !defined $wpwname;
		    $wgrpname = $wgid if !defined $wgrpname;

		    print "Updating uid/gid on $path: old=$wpwname/$wgrpname, new=$pwname/$grpname\n";
		}
		chown $uid, $gid, $fullpath;
	    }
	}
	else {
	    warn "Invalid input format in $gitmeta:\n\t$_\n";
	}
    }
    close IN;
}
elsif ($read_mode) {
    # Handle merge conflicts in the .gitperms file
    if (-e "$gitdir/MERGE_MSG") {
	if (`grep ====== $gitmeta`) {
	    # Conflict not resolved -- abort the commit
	    print "PERMISSIONS/OWNERSHIP CONFLICT\n";
	    print "    Resolve the conflict in the $gitmeta file and then run\n";
	    print "    `.git/hooks/setgitperms.perl --write` to reconcile.\n";
	    exit 1;
	}
	elsif (`grep $gitmeta $gitdir/MERGE_MSG`) {
	    # A conflict in .gitmeta has been manually resolved. Verify that
	    # the working dir perms matches the current .gitmeta perms for
	    # each file/dir that conflicted.
	    # This is here because a `setgitperms.perl --write` was not
	    # performed due to a merge conflict, so permissions/ownership
	    # may not be consistent with the manually merged .gitmeta file.
	    my @conflict_diff = `git show \$(cat $gitdir/MERGE_HEAD)`;
	    my @conflict_files;
	    my $metadiff = 0;

	    # Build a list of files that conflicted from the .gitmeta diff
	    foreach my $line (@conflict_diff) {
		if ($line =~ m|^diff --git a/$gitmeta b/$gitmeta|) {
		    $metadiff = 1;
		}
		elsif ($line =~ /^diff --git/) {
		    $metadiff = 0;
		}
		elsif ($metadiff && $line =~ /^\+(.*)  mode=/) {
		    push @conflict_files, $1;
		}
	    }

	    # Verify that each conflict file now has permissions consistent
	    # with the .gitmeta file
	    foreach my $file (@conflict_files) {
		my $absfile = $topdir . $file;
		my $gm_entry = `grep "^$file  mode=" $gitmeta`;
		if ($gm_entry =~ /mode=(\d+)  uid=(\d+)  gid=(\d+)/) {
		    my ($gm_mode, $gm_uid, $gm_gid) = ($1, $2, $3);
		    my (undef,undef,$mode,undef,$uid,$gid) = lstat("$absfile");
		    $mode = sprintf("%04o", $mode & 07777);
		    if (($gm_mode ne $mode) || ($gm_uid != $uid)
			|| ($gm_gid != $gid)) {
			print "PERMISSIONS/OWNERSHIP CONFLICT\n";
			print "    Mismatch found for file: $file\n";
			print "    Run `.git/hooks/setgitperms.perl --write` to reconcile.\n";
			exit 1;
		    }
		}
		else {
		    print "Warning! Permissions/ownership no longer being tracked for file: $file\n";
		}
	    }
	}
    }

    # No merge conflicts -- write out perms/ownership data to .gitmeta file
    unless ($stdout) {
	open (OUT, ">$gitmeta.tmp") or die "Could not open $gitmeta.tmp for writing: $!\n";
    }

    my @files = `git ls-files`;
    my %dirs;

    foreach my $path (@files) {
	chomp $path;
	# We have to manually add stats for parent directories
	my $parent = dirname($path);
	while (!exists $dirs{$parent}) {
	    $dirs{$parent} = 1;
	    next if $parent eq '.';
	    printstats($parent);
	    $parent = dirname($parent);
	}
	# Now the git-tracked file
	printstats($path);
    }

    # diff the temporary metadata file to see if anything has changed
    # If no metadata has changed, don't overwrite the real file
    # This is just so `git commit -a` doesn't try to commit a bogus update
    unless ($stdout) {
	if (! -e $gitmeta) {
	    rename "$gitmeta.tmp", $gitmeta;
	}
	else {
	    my $diff = `diff -U 0 $gitmeta $gitmeta.tmp`;
	    if ($diff ne '') {
		rename "$gitmeta.tmp", $gitmeta;
	    }
	    else {
		unlink "$gitmeta.tmp";
	    }
	    if ($showdiff) {
		print $diff;
	    }
	}
	close OUT;
    }
    # Make sure the .gitmeta file is tracked
    system("git add $gitmeta");
}


sub printstats {
    my $path = $_[0];
    $path =~ s/@/\@/g;
    my (undef,undef,$mode,undef,$uid,$gid) = lstat($path);
    $path =~ s/%/\%/g;
    if ($stdout) {
	print $path;
	printf "  mode=%04o  uid=$uid  gid=$gid\n", $mode & 07777;
    }
    else {
	print OUT $path;
	printf OUT "  mode=%04o  uid=$uid  gid=$gid\n", $mode & 07777;
    }
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        #!/usr/bin/perl

use strict;
use File::Spec;

$ENV{PATH}     = '/opt/git/bin';
my $acl_git    = '/vcs/acls.git';
my $acl_branch = 'refs/heads/master';
my $debug      = 0;

=doc
Invoked as: update refname old-sha1 new-sha1

This script is run by git-receive-pack once for each ref that the
client is trying to modify.  If we exit with a non-zero exit value
then the update for that particular ref is denied, but updates for
other refs in the same run of receive-pack may still be allowed.

We are run after the objects have been uploaded, but before the
ref is actually modified.  We take advantage of that fact when we
look for "new" commits and tags (the new objects won't show up in
`rev-list --all`).

This script loads and parses the content of the config file
"users/$this_user.acl" from the $acl_branch commit of $acl_git ODB.
The acl file is a git-config style file, but uses a slightly more
restricted syntax as the Perl parser contained within this script
is not nearly as permissive as git-config.

Example:

  [user]
    committer = John Doe <john.doe@example.com>
    committer = John R. Doe <john.doe@example.com>

  [repository "acls"]
    allow = heads/master
    allow = CDUR for heads/jd/
    allow = C    for ^tags/v\\d+$

For all new commit or tag objects the committer (or tagger) line
within the object must exactly match one of the user.committer
values listed in the acl file ("HEAD:users/$this_user.acl").

For a branch to be modified an allow line within the matching
repository section must be matched for both the refname and the
opcode.

Repository sections are matched on the basename of the repository
(after removing the .git suffix).

The opcode abbreviations are:

  C: create new ref
  D: delete existing ref
  U: fast-forward existing ref (no commit loss)
  R: rewind/rebase existing ref (commit loss)

if no opcodes are listed before the "for" keyword then "U" (for
fast-forward update only) is assumed as this is the most common
usage.

Refnames are matched by always assuming a prefix of "refs/".
This hook forbids pushing or deleting anything not under "refs/".

Refnames that start with ^ are Perl regular expressions, and the ^
is kept as part of the regexp.  \\ is needed to get just one \, so
\\d expands to \d in Perl.  The 3rd allow line above is an example.

Refnames that don't start with ^ but that end with / are prefix
matches (2nd allow line above); all other refnames are strict
equality matches (1st allow line).

Anything pushed to "heads/" (ok, really "refs/heads/") must be
a commit.  Tags are not permitted here.

Anything pushed to "tags/" (err, really "refs/tags/") must be an
annotated tag.  Commits, blobs, trees, etc. are not permitted here.
Annotated tag signatures aren't checked, nor are they required.

The special subrepository of 'info/new-commit-check' can
be created and used to allow users to push new commits and
tags from another local repository to this one, even if they
aren't the committer/tagger of those objects.  In a nut shell
the info/new-commit-check directory is a Git repository whose
objects/info/alternates file lists this repository and all other
possible sources, and whose refs subdirectory contains symlinks
to this repository's refs subdirectory, and to all other possible
sources refs subdirectories.  Yes, this means that you cannot
use packed-refs in those repositories as they won't be resolved
correctly.

=cut

my $git_dir = $ENV{GIT_DIR};
my $new_commit_check = "$git_dir/info/new-commit-check";
my $ref = $ARGV[0];
my $old = $ARGV[1];
my $new = $ARGV[2];
my $new_type;
my ($this_user) = getpwuid $<; # REAL_USER_ID
my $repository_name;
my %user_committer;
my @allow_rules;
my @path_rules;
my %diff_cache;

sub deny ($) {
	print STDERR "-Deny-    $_[0]\n" if $debug;
	print STDERR "\ndenied: $_[0]\n\n";
	exit 1;
}

sub grant ($) {
	print STDERR "-Grant-   $_[0]\n" if $debug;
	exit 0;
}

sub info ($) {
	print STDERR "-Info-    $_[0]\n" if $debug;
}

sub git_value (@) {
	open(T,'-|','git',@_); local $_ = <T>; chop; close T; $_;
}

sub match_string ($$) {
	my ($acl_n, $ref) = @_;
	   ($acl_n eq $ref)
	|| ($acl_n =~ m,/$, && substr($ref,0,length $acl_n) eq $acl_n)
	|| ($acl_n =~ m,^\^, && $ref =~ m:$acl_n:);
}

sub parse_config ($$$$) {
	my $data = shift;
	local $ENV{GIT_DIR} = shift;
	my $br = shift;
	my $fn = shift;
	return unless git_value('rev-list','--max-count=1',$br,'--',$fn);
	info "Loading $br:$fn";
	open(I,'-|','git','cat-file','blob',"$br:$fn");
	my $section = '';
	while (<I>) {
		chomp;
		if (/^\s*$/ || /^\s*#/) {
		} elsif (/^\[([a-z]+)\]$/i) {
			$section = lc $1;
		} elsif (/^\[([a-z]+)\s+"(.*)"\]$/i) {
			$section = join('.',lc $1,$2);
		} elsif (/^\s*([a-z][a-z0-9]+)\s*=\s*(.*?)\s*$/i) {
			push @{$data->{join('.',$section,lc $1)}}, $2;
		} else {
			deny "bad config file line $. in $br:$fn";
		}
	}
	close I;
}

sub all_new_committers () {
	local $ENV{GIT_DIR} = $git_dir;
	$ENV{GIT_DIR} = $new_commit_check if -d $new_commit_check;

	info "Getting committers of new commits.";
	my %used;
	open(T,'-|','git','rev-list','--pretty=raw',$new,'--not','--all');
	while (<T>) {
		next unless s/^committer //;
		chop;
		s/>.*$/>/;
		info "Found $_." unless $used{$_}++;
	}
	close T;
	info "No new commits." unless %used;
	keys %used;
}

sub all_new_taggers () {
	my %exists;
	open(T,'-|','git','for-each-ref','--format=%(objectname)','refs/tags');
	while (<T>) {
		chop;
		$exists{$_} = 1;
	}
	close T;

	info "Getting taggers of new tags.";
	my %used;
	my $obj = $new;
	my $obj_type = $new_type;
	while ($obj_type eq 'tag') {
		last if $exists{$obj};
		$obj_type = '';
		open(T,'-|','git','cat-file','tag',$obj);
		while (<T>) {
			chop;
			if (/^object ([a-z0-9]{40})$/) {
				$obj = $1;
			} elsif (/^type (.+)$/) {
				$obj_type = $1;
			} elsif (s/^tagger //) {
				s/>.*$/>/;
				info "Found $_." unless $used{$_}++;
				last;
			}
		}
		close T;
	}
	info "No new tags." unless %used;
	keys %used;
}

sub check_committers (@) {
	my @bad;
	foreach (@_) { push @bad, $_ unless $user_committer{$_}; }
	if (@bad) {
		print STDERR "\n";
		print STDERR "You are not $_.\n" foreach (sort @bad);
		deny "You cannot push changes not committed by you.";
	}
}

sub load_diff ($) {
	my $base = shift;
	my $d = $diff_cache{$base};
	unless ($d) {
		local $/ = "\0";
		my %this_diff;
		if ($base =~ /^0{40}$/) {
			# Don't load the diff at all; we are making the
			# branch and have no base to compare to in this
			# case.  A file level ACL makes no sense in this
			# context.  Having an empty diff will allow the
			# branch creation.
			#
		} else {
			open(T,'-|','git','diff-tree',
				'-r','--name-status','-z',
				$base,$new) or return undef;
			while (<T>) {
				my $op = $_;
				chop $op;

				my $path = <T>;
				chop $path;

				$this_diff{$path} = $op;
			}
			close T or return undef;
		}
		$d = \%this_diff;
		$diff_cache{$base} = $d;
	}
	return $d;
}

deny "No GIT_DIR inherited from caller" unless $git_dir;
deny "Need a ref name" unless $ref;
deny "Refusing funny ref $ref" unless $ref =~ s,^refs/,,;
deny "Bad old value $old" unless $old =~ /^[a-z0-9]{40}$/;
deny "Bad new value $new" unless $new =~ /^[a-z0-9]{40}$/;
deny "Cannot determine who you are." unless $this_user;
grant "No change requested." if $old eq $new;

$repository_name = File::Spec->rel2abs($git_dir);
$repository_name =~ m,/([^/]+)(?:\.git|/\.git)$,;
$repository_name = $1;
info "Updating in '$repository_name'.";

my $op;
if    ($old =~ /^0{40}$/) { $op = 'C'; }
elsif ($new =~ /^0{40}$/) { $op = 'D'; }
else                      { $op = 'R'; }

# This is really an update (fast-forward) if the
# merge base of $old and $new is $old.
#
$op = 'U' if ($op eq 'R'
	&& $ref =~ m,^heads/,
	&& $old eq git_value('merge-base',$old,$new));

# Load the user's ACL file. Expand groups (user.memberof) one level.
{
	my %data = ('user.committer' => []);
	parse_config(\%data,$acl_git,$acl_branch,"external/$repository_name.acl");

	%data = (
		'user.committer' => $data{'user.committer'},
		'user.memberof' => [],
	);
	parse_config(\%data,$acl_git,$acl_branch,"users/$this_user.acl");

	%user_committer = map {$_ => $_} @{$data{'user.committer'}};
	my $rule_key = "repository.$repository_name.allow";
	my $rules = $data{$rule_key} || [];

	foreach my $group (@{$data{'user.memberof'}}) {
		my %g;
		parse_config(\%g,$acl_git,$acl_branch,"groups/$group.acl");
		my $group_rules = $g{$rule_key};
		push @$rules, @$group_rules if $group_rules;
	}

RULE:
	foreach (@$rules) {
		while (/\${user\.([a-z][a-zA-Z0-9]+)}/) {
			my $k = lc $1;
			my $v = $data{"user.$k"};
			next RULE unless defined $v;
			next RULE if @$v != 1;
			next RULE unless defined $v->[0];
			s/\${user\.$k}/$v->[0]/g;
		}

		if (/^([AMD ]+)\s+of\s+([^\s]+)\s+for\s+([^\s]+)\s+diff\s+([^\s]+)$/) {
			my ($ops, $pth, $ref, $bst) = ($1, $2, $3, $4);
			$ops =~ s/ //g;
			$pth =~ s/\\\\/\\/g;
			$ref =~ s/\\\\/\\/g;
			push @path_rules, [$ops, $pth, $ref, $bst];
		} elsif (/^([AMD ]+)\s+of\s+([^\s]+)\s+for\s+([^\s]+)$/) {
			my ($ops, $pth, $ref) = ($1, $2, $3);
			$ops =~ s/ //g;
			$pth =~ s/\\\\/\\/g;
			$ref =~ s/\\\\/\\/g;
			push @path_rules, [$ops, $pth, $ref, $old];
		} elsif (/^([CDRU ]+)\s+for\s+([^\s]+)$/) {
			my $ops = $1;
			my $ref = $2;
			$ops =~ s/ //g;
			$ref =~ s/\\\\/\\/g;
			push @allow_rules, [$ops, $ref];
		} elsif (/^for\s+([^\s]+)$/) {
			# Mentioned, but nothing granted?
		} elsif (/^[^\s]+$/) {
			s/\\\\/\\/g;
			push @allow_rules, ['U', $_];
		}
	}
}

if ($op ne 'D') {
	$new_type = git_value('cat-file','-t',$new);

	if ($ref =~ m,^heads/,) {
		deny "$ref must be a commit." unless $new_type eq 'commit';
	} elsif ($ref =~ m,^tags/,) {
		deny "$ref must be an annotated tag." unless $new_type eq 'tag';
	}

	check_committers (all_new_committers);
	check_committers (all_new_taggers) if $new_type eq 'tag';
}

info "$this_user wants $op for $ref";
foreach my $acl_entry (@allow_rules) {
	my ($acl_ops, $acl_n) = @$acl_entry;
	next unless $acl_ops =~ /^[CDRU]+$/; # Uhh.... shouldn't happen.
	next unless $acl_n;
	next unless $op =~ /^[$acl_ops]$/;
	next unless match_string $acl_n, $ref;

	# Don't test path rules on branch deletes.
	#
	grant "Allowed by: $acl_ops for $acl_n" if $op eq 'D';

	# Aggregate matching path rules; allow if there aren't
	# any matching this ref.
	#
	my %pr;
	foreach my $p_entry (@path_rules) {
		my ($p_ops, $p_n, $p_ref, $p_bst) = @$p_entry;
		next unless $p_ref;
		push @{$pr{$p_bst}}, $p_entry if match_string $p_ref, $ref;
	}
	grant "Allowed by: $acl_ops for $acl_n" unless %pr;

	# Allow only if all changes against a single base are
	# allowed by file path rules.
	#
	my @bad;
	foreach my $p_bst (keys %pr) {
		my $diff_ref = load_diff $p_bst;
		deny "Cannot difference trees." unless ref $diff_ref;

		my %fd = %$diff_ref;
		foreach my $p_entry (@{$pr{$p_bst}}) {
			my ($p_ops, $p_n, $p_ref, $p_bst) = @$p_entry;
			next unless $p_ops =~ /^[AMD]+$/;
			next unless $p_n;

			foreach my $f_n (keys %fd) {
				my $f_op = $fd{$f_n};
				next unless $f_op;
				next unless $f_op =~ /^[$p_ops]$/;
				delete $fd{$f_n} if match_string $p_n, $f_n;
			}
			last unless %fd;
		}

		if (%fd) {
			push @bad, [$p_bst, \%fd];
		} else {
			# All changes relative to $p_bst were allowed.
			#
			grant "Allowed by: $acl_ops for $acl_n diff $p_bst";
		}
	}

	foreach my $bad_ref (@bad) {
		my ($p_bst, $fd) = @$bad_ref;
		print STDERR "\n";
		print STDERR "Not allowed to make the following changes:\n";
		print STDERR "(base: $p_bst)\n";
		foreach my $f_n (sort keys %$fd) {
			print STDERR "  $fd->{$f_n} $f_n\n";
		}
	}
	deny "You are not permitted to $op $ref";
}
close A;
deny "You are not permitted to $op $ref";
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Unnamed repository; edit this file 'description' to name the repository.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       #!/bin/sh
#
# An example hook script to check the commit log message taken by
# applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.  The hook is
# allowed to edit the commit message file.
#
# To enable this hook, rename this file to "applypatch-msg".

. git-sh-setup
commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  #!/bin/sh
#
# An example hook script to check the commit log message.
# Called by "git commit" with one argument, the name of the file
# that has the commit message.  The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit.  The hook is allowed to edit the commit message file.
#
# To enable this hook, rename this file to "commit-msg".

# Uncomment the below to add a Signed-off-by line to the message.
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
# hook is more suited to it.
#
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

# This example catches duplicate Signed-off-by lines.

test "" = "$(grep '^Signed-off-by: ' "$1" |
	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
	echo >&2 Duplicate Signed-off-by lines.
	exit 1
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                #!/usr/bin/perl

use strict;
use warnings;
use IPC::Open2;

# An example hook script to integrate Watchman
# (https://facebook.github.io/watchman/) with git to speed up detecting
# new and modified files.
#
# The hook is passed a version (currently 2) and last update token
# formatted as a string and outputs to stdout a new update token and
# all files that have been modified since the update token. Paths must
# be relative to the root of the working tree and separated by a single NUL.
#
# To enable this hook, rename this file to "query-watchman" and set
# 'git config core.fsmonitor .git/hooks/query-watchman'
#
my ($version, $last_update_token) = @ARGV;

# Uncomment for debugging
# print STDERR "$0 $version $last_update_token\n";

# Check the hook interface version
if ($version ne 2) {
	die "Unsupported query-fsmonitor hook version '$version'.\n" .
	    "Falling back to scanning...\n";
}

my $git_work_tree = get_working_dir();

my $retry = 1;

my $json_pkg;
eval {
	require JSON::XS;
	$json_pkg = "JSON::XS";
	1;
} or do {
	require JSON::PP;
	$json_pkg = "JSON::PP";
};

launch_watchman();

sub launch_watchman {
	my $o = watchman_query();
	if (is_work_tree_watched($o)) {
		output_result($o->{clock}, @{$o->{files}});
	}
}

sub output_result {
	my ($clockid, @files) = @_;

	# Uncomment for debugging watchman output
	# open (my $fh, ">", ".git/watchman-output.out");
	# binmode $fh, ":utf8";
	# print $fh "$clockid\n@files\n";
	# close $fh;

	binmode STDOUT, ":utf8";
	print $clockid;
	print "\0";
	local $, = "\0";
	print @files;
}

sub watchman_clock {
	my $response = qx/watchman clock "$git_work_tree"/;
	die "Failed to get clock id on '$git_work_tree'.\n" .
		"Falling back to scanning...\n" if $? != 0;

	return $json_pkg->new->utf8->decode($response);
}

sub watchman_query {
	my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty')
	or die "open2() failed: $!\n" .
	"Falling back to scanning...\n";

	# In the query expression below we're asking for names of files that
	# changed since $last_update_token but not from the .git folder.
	#
	# To accomplish this, we're using the "since" generator to use the
	# recency index to select candidate nodes and "fields" to limit the
	# output to file names only. Then we're using the "expression" term to
	# further constrain the results.
	my $last_update_line = "";
	if (substr($last_update_token, 0, 1) eq "c") {
		$last_update_token = "\"$last_update_token\"";
		$last_update_line = qq[\n"since": $last_update_token,];
	}
	my $query = <<"	END";
		["query", "$git_work_tree", {$last_update_line
			"fields": ["name"],
			"expression": ["not", ["dirname", ".git"]]
		}]
	END

	# Uncomment for debugging the watchman query
	# open (my $fh, ">", ".git/watchman-query.json");
	# print $fh $query;
	# close $fh;

	print CHLD_IN $query;
	close CHLD_IN;
	my $response = do {local $/; <CHLD_OUT>};

	# Uncomment for debugging the watch response
	# open ($fh, ">", ".git/watchman-response.json");
	# print $fh $response;
	# close $fh;

	die "Watchman: command returned no output.\n" .
	"Falling back to scanning...\n" if $response eq "";
	die "Watchman: command returned invalid output: $response\n" .
	"Falling back to scanning...\n" unless $response =~ /^\{/;

	return $json_pkg->new->utf8->decode($response);
}

sub is_work_tree_watched {
	my ($output) = @_;
	my $error = $output->{error};
	if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) {
		$retry--;
		my $response = qx/watchman watch "$git_work_tree"/;
		die "Failed to make watchman watch '$git_work_tree'.\n" .
		    "Falling back to scanning...\n" if $? != 0;
		$output = $json_pkg->new->utf8->decode($response);
		$error = $output->{error};
		die "Watchman: $error.\n" .
		"Falling back to scanning...\n" if $error;

		# Uncomment for debugging watchman output
		# open (my $fh, ">", ".git/watchman-output.out");
		# close $fh;

		# Watchman will always return all files on the first query so
		# return the fast "everything is dirty" flag to git and do the
		# Watchman query just to get it over with now so we won't pay
		# the cost in git to look up each individual file.
		my $o = watchman_clock();
		$error = $output->{error};

		die "Watchman: $error.\n" .
		"Falling back to scanning...\n" if $error;

		output_result($o->{clock}, ("/"));
		$last_update_token = $o->{clock};

		eval { launch_watchman() };
		return 0;
	}

	die "Watchman: $error.\n" .
	"Falling back to scanning...\n" if $error;

	return 1;
}

sub get_working_dir {
	my $working_dir;
	if ($^O =~ 'msys' || $^O =~ 'cygwin') {
		$working_dir = Win32::GetCwd();
		$working_dir =~ tr/\\/\//;
	} else {
		require Cwd;
		$working_dir = Cwd::cwd();
	}

	return $working_dir;
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          #!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".

exec git update-server-info
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   #!/bin/sh
#
# An example hook script to verify what is about to be committed
# by applypatch from an e-mail message.
#
# The hook should exit with non-zero status after issuing an
# appropriate message if it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-applypatch".

. git-sh-setup
precommit="$(git rev-parse --git-path hooks/pre-commit)"
test -x "$precommit" && exec "$precommit" ${1+"$@"}
:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        #!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
	against=HEAD
else
	# Initial commit: diff against an empty tree object
	against=$(git hash-object -t tree /dev/null)
fi

# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config --type=bool hooks.allownonascii)

# Redirect output to stderr.
exec 1>&2

# Cross platform projects tend to avoid non-ASCII filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
	# Note that the use of brackets around a tr range is ok here, (it's
	# even required, for portability to Solaris 10's /usr/bin/tr), since
	# the square bracket bytes happen to fall in the designated range.
	test $(git diff --cached --name-only --diff-filter=A -z $against |
	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
	cat <<\EOF
Error: Attempt to add a non-ASCII file name.

This can cause problems if you want to work with people on other platforms.

To be portable it is advisable to rename the file.

If you know what you are doing you can disable this check using:

  git config hooks.allownonascii true
EOF
	exit 1
fi

# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached $against --
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     #!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git merge" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message to
# stderr if it wants to stop the merge commit.
#
# To enable this hook, rename this file to "pre-merge-commit".

. git-sh-setup
test -x "$GIT_DIR/hooks/pre-commit" &&
        exec "$GIT_DIR/hooks/pre-commit"
:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                #!/bin/sh

# An example hook script to verify what is about to be pushed.  Called by "git
# push" after it has checked the remote status, but before anything has been
# pushed.  If this script exits with a non-zero status nothing will be pushed.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If pushing without using a named remote those arguments will be equal.
#
# Information about the commits which are being pushed is supplied as lines to
# the standard input in the form:
#
#   <local ref> <local oid> <remote ref> <remote oid>
#
# This sample shows how to prevent push of commits where the log message starts
# with "WIP" (work in progress).

remote="$1"
url="$2"

zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')

while read local_ref local_oid remote_ref remote_oid
do
	if test "$local_oid" = "$zero"
	then
		# Handle delete
		:
	else
		if test "$remote_oid" = "$zero"
		then
			# New branch, examine all commits
			range="$local_oid"
		else
			# Update to existing branch, examine new commits
			range="$remote_oid..$local_oid"
		fi

		# Check for WIP commit
		commit=$(git rev-list -n 1 --grep '^WIP' "$range")
		if test -n "$commit"
		then
			echo >&2 "Found WIP commit in $local_ref, not pushing"
			exit 1
		fi
	fi
done

exit 0
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  #!/bin/sh
#
# Copyright (c) 2006, 2008 Junio C Hamano
#
# The "pre-rebase" hook is run just before "git rebase" starts doing
# its job, and can prevent the command from running by exiting with
# non-zero status.
#
# The hook is called with the following parameters:
#
# $1 -- the upstream the series was forked from.
# $2 -- the branch being rebased (or empty when rebasing the current branch).
#
# This sample shows how to prevent topic branches that are already
# merged to 'next' branch from getting rebased, because allowing it
# would result in rebasing already published history.

publish=next
basebranch="$1"
if test "$#" = 2
then
	topic="refs/heads/$2"
else
	topic=`git symbolic-ref HEAD` ||
	exit 0 ;# we do not interrupt rebasing detached HEAD
fi

case "$topic" in
refs/heads/??/*)
	;;
*)
	exit 0 ;# we do not interrupt others.
	;;
esac

# Now we are dealing with a topic branch being rebased
# on top of master.  Is it OK to rebase it?

# Does the topic really exist?
git show-ref -q "$topic" || {
	echo >&2 "No such branch $topic"
	exit 1
}

# Is topic fully merged to master?
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
if test -z "$not_in_master"
then
	echo >&2 "$topic is fully merged to master; better remove it."
	exit 1 ;# we could allow it, but there is no point.
fi

# Is topic ever merged to next?  If so you should not be rebasing it.
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
only_next_2=`git rev-list ^master           ${publish} | sort`
if test "$only_next_1" = "$only_next_2"
then
	not_in_topic=`git rev-list "^$topic" master`
	if test -z "$not_in_topic"
	then
		echo >&2 "$topic is already up to date with master"
		exit 1 ;# we could allow it, but there is no point.
	else
		exit 0
	fi
else
	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
	/usr/bin/perl -e '
		my $topic = $ARGV[0];
		my $msg = "* $topic has commits already merged to public branch:\n";
		my (%not_in_next) = map {
			/^([0-9a-f]+) /;
			($1 => 1);
		} split(/\n/, $ARGV[1]);
		for my $elem (map {
				/^([0-9a-f]+) (.*)$/;
				[$1 => $2];
			} split(/\n/, $ARGV[2])) {
			if (!exists $not_in_next{$elem->[0]}) {
				if ($msg) {
					print STDERR $msg;
					undef $msg;
				}
				print STDERR " $elem->[1]\n";
			}
		}
	' "$topic" "$not_in_next" "$not_in_master"
	exit 1
fi

<<\DOC_END

This sample hook safeguards topic branches that have been
published from being rewound.

The workflow assumed here is:

 * Once a topic branch forks from "master", "master" is never
   merged into it again (either directly or indirectly).

 * Once a topic branch is fully cooked and merged into "master",
   it is deleted.  If you need to build on top of it to correct
   earlier mistakes, a new topic branch is created by forking at
   the tip of the "master".  This is not strictly necessary, but
   it makes it easier to keep your history simple.

 * Whenever you need to test or publish your changes to topic
   branches, merge them into "next" branch.

The script, being an example, hardcodes the publish branch name
to be "next", but it is trivial to make it configurable via
$GIT_DIR/config mechanism.

With this workflow, you would want to know:

(1) ... if a topic branch has ever been merged to "next".  Young
    topic branches can have stupid mistakes you would rather
    clean up before publishing, and things that have not been
    merged into other branches can be easily rebased without
    affecting other people.  But once it is published, you would
    not want to rewind it.

(2) ... if a topic branch has been fully merged to "master".
    Then you can delete it.  More importantly, you should not
    build on top of it -- other people may already want to
    change things related to the topic as patches against your
    "master", so if you need further changes, it is better to
    fork the topic (perhaps with the same name) afresh from the
    tip of "master".

Let's look at this example:

		   o---o---o---o---o---o---o---o---o---o "next"
		  /       /           /           /
		 /   a---a---b A     /           /
		/   /               /           /
	       /   /   c---c---c---c B         /
	      /   /   /             \         /
	     /   /   /   b---b C     \       /
	    /   /   /   /             \     /
    ---o---o---o---o---o---o---o---o---o---o---o "master"


A, B and C are topic branches.

 * A has one fix since it was merged up to "next".

 * B has finished.  It has been fully merged up to "master" and "next",
   and is ready to be deleted.

 * C has not merged to "next" at all.

We would want to allow C to be rebased, refuse A, and encourage
B to be deleted.

To compute (1):

	git rev-list ^master ^topic next
	git rev-list ^master        next

	if these match, topic has not merged in next at all.

To compute (2):

	git rev-list master..topic

	if this is empty, it is fully merged to "master".

DOC_END
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              #!/bin/sh
#
# An example hook script to make use of push options.
# The example simply echoes all push options that start with 'echoback='
# and rejects all pushes when the "reject" push option is used.
#
# To enable this hook, rename this file to "pre-receive".

if test -n "$GIT_PUSH_OPTION_COUNT"
then
	i=0
	while test "$i" -lt "$GIT_PUSH_OPTION_COUNT"
	do
		eval "value=\$GIT_PUSH_OPTION_$i"
		case "$value" in
		echoback=*)
			echo "echo from the pre-receive-hook: ${value#*=}" >&2
			;;
		reject)
			exit 1
		esac
		i=$((i + 1))
	done
fi
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                #!/bin/sh
#
# An example hook script to prepare the commit log message.
# Called by "git commit" with the name of the file that has the
# commit message, followed by the description of the commit
# message's source.  The hook's purpose is to edit the commit
# message file.  If the hook fails with a non-zero status,
# the commit is aborted.
#
# To enable this hook, rename this file to "prepare-commit-msg".

# This hook includes three examples. The first one removes the
# "# Please enter the commit message..." help message.
#
# The second includes the output of "git diff --name-status -r"
# into the message, just before the "git status" output.  It is
# commented because it doesn't cope with --amend or with squashed
# commits.
#
# The third example adds a Signed-off-by line to the message, that can
# still be edited.  This is rarely a good idea.

COMMIT_MSG_FILE=$1
COMMIT_SOURCE=$2
SHA1=$3

/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE"

# case "$COMMIT_SOURCE,$SHA1" in
#  ,|template,)
#    /usr/bin/perl -i.bak -pe '
#       print "\n" . `git diff --cached --name-status -r`
# 	 if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;;
#  *) ;;
# esac

# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE"
# if test -z "$COMMIT_SOURCE"
# then
#   /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE"
# fi
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            #!/bin/sh

# An example hook script to update a checked-out tree on a git push.
#
# This hook is invoked by git-receive-pack(1) when it reacts to git
# push and updates reference(s) in its repository, and when the push
# tries to update the branch that is currently checked out and the
# receive.denyCurrentBranch configuration variable is set to
# updateInstead.
#
# By default, such a push is refused if the working tree and the index
# of the remote repository has any difference from the currently
# checked out commit; when both the working tree and the index match
# the current commit, they are updated to match the newly pushed tip
# of the branch. This hook is to be used to override the default
# behaviour; however the code below reimplements the default behaviour
# as a starting point for convenient modification.
#
# The hook receives the commit with which the tip of the current
# branch is going to be updated:
commit=$1

# It can exit with a non-zero status to refuse the push (when it does
# so, it must not modify the index or the working tree).
die () {
	echo >&2 "$*"
	exit 1
}

# Or it can make any necessary changes to the working tree and to the
# index to bring them to the desired state when the tip of the current
# branch is updated to the new commit, and exit with a zero status.
#
# For example, the hook can simply run git read-tree -u -m HEAD "$1"
# in order to emulate git fetch that is run in the reverse direction
# with git push, as the two-tree form of git read-tree -u -m is
# essentially the same as git switch or git checkout that switches
# branches while keeping the local changes in the working tree that do
# not interfere with the difference between the branches.

# The below is a more-or-less exact translation to shell of the C code
# for the default behaviour for git's push-to-checkout hook defined in
# the push_to_deploy() function in builtin/receive-pack.c.
#
# Note that the hook will be executed from the repository directory,
# not from the working tree, so if you want to perform operations on
# the working tree, you will have to adapt your code accordingly, e.g.
# by adding "cd .." or using relative paths.

if ! git update-index -q --ignore-submodules --refresh
then
	die "Up-to-date check failed"
fi

if ! git diff-files --quiet --ignore-submodules --
then
	die "Working directory has unstaged changes"
fi

# This is a rough translation of:
#
#   head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX
if git cat-file -e HEAD 2>/dev/null
then
	head=HEAD
else
	head=$(git hash-object -t tree --stdin </dev/null)
fi

if ! git diff-index --quiet --cached --ignore-submodules $head --
then
	die "Working directory has staged changes"
fi

if ! git read-tree -u -m "$commit"
then
	die "Could not update working tree to new HEAD"
fi
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 #!/bin/sh
#
# An example hook script to block unannotated tags from entering.
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
# Config
# ------
# hooks.allowunannotated
#   This boolean sets whether unannotated tags will be allowed into the
#   repository.  By default they won't be.
# hooks.allowdeletetag
#   This boolean sets whether deleting tags will be allowed in the
#   repository.  By default they won't be.
# hooks.allowmodifytag
#   This boolean sets whether a tag may be modified after creation. By default
#   it won't be.
# hooks.allowdeletebranch
#   This boolean sets whether deleting branches will be allowed in the
#   repository.  By default they won't be.
# hooks.denycreatebranch
#   This boolean sets whether remotely creating branches will be denied
#   in the repository.  By default this is allowed.
#

# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"

# --- Safety check
if [ -z "$GIT_DIR" ]; then
	echo "Don't run this script from the command line." >&2
	echo " (if you want, you could supply GIT_DIR then run" >&2
	echo "  $0 <ref> <oldrev> <newrev>)" >&2
	exit 1
fi

if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
	echo "usage: $0 <ref> <oldrev> <newrev>" >&2
	exit 1
fi

# --- Config
allowunannotated=$(git config --type=bool hooks.allowunannotated)
allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch)
denycreatebranch=$(git config --type=bool hooks.denycreatebranch)
allowdeletetag=$(git config --type=bool hooks.allowdeletetag)
allowmodifytag=$(git config --type=bool hooks.allowmodifytag)

# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
case "$projectdesc" in
"Unnamed repository"* | "")
	echo "*** Project description file hasn't been set" >&2
	exit 1
	;;
esac

# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')
if [ "$newrev" = "$zero" ]; then
	newrev_type=delete
else
	newrev_type=$(git cat-file -t $newrev)
fi

case "$refname","$newrev_type" in
	refs/tags/*,commit)
		# un-annotated tag
		short_refname=${refname##refs/tags/}
		if [ "$allowunannotated" != "true" ]; then
			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
			exit 1
		fi
		;;
	refs/tags/*,delete)
		# delete tag
		if [ "$allowdeletetag" != "true" ]; then
			echo "*** Deleting a tag is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/tags/*,tag)
		# annotated tag
		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
		then
			echo "*** Tag '$refname' already exists." >&2
			echo "*** Modifying a tag is not allowed in this repository." >&2
			exit 1
		fi
		;;
	refs/heads/*,commit)
		# branch
		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
			echo "*** Creating a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/heads/*,delete)
		# delete branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	refs/remotes/*,commit)
		# tracking branch
		;;
	refs/remotes/*,delete)
		# delete tracking branch
		if [ "$allowdeletebranch" != "true" ]; then
			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
			exit 1
		fi
		;;
	*)
		# Anything else (is there anything else?)
		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
		exit 1
		;;
esac

# --- Finished
exit 0
                                                                                                                                                                                                                                                                                                                                                                                                                                                              # git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                PNG

   
IHDR         b   	PLTE    |   %IDATcX؈&[2+ajjd sQ #[ov    IENDB`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             PNG

   
IHDR   H      )9,   PLTE``]    G   rIDATx
 CwKK4tC!EɦI$-4
VNTC0mFB)yV6׊PhS'jjiWqD_H"F'<pG S    IENDB`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 body {
	font-family: sans-serif;
	font-size: small;
	border: solid #d9d8d1;
	border-width: 1px;
	margin: 10px;
	background-color: #ffffff;
	color: #000000;
}

a {
	color: #0000cc;
}

a:hover, a:visited, a:active {
	color: #880000;
}

span.cntrl {
	border: dashed #aaaaaa;
	border-width: 1px;
	padding: 0px 2px 0px 2px;
	margin:  0px 2px 0px 2px;
}

img.logo {
	float: right;
	border-width: 0px;
}

img.avatar {
	vertical-align: middle;
}

img.blob {
	max-height: 100%;
	max-width: 100%;
}

a.list img.avatar {
	border-style: none;
}

div.page_header {
	height: 25px;
	padding: 8px;
	font-size: 150%;
	font-weight: bold;
	background-color: #d9d8d1;
}

div.page_header a:visited, a.header {
	color: #0000cc;
}

div.page_header a:hover {
	color: #880000;
}

div.page_nav {
	padding: 8px;
}

div.page_nav a:visited {
	color: #0000cc;
}

div.page_path {
	padding: 8px;
	font-weight: bold;
	border: solid #d9d8d1;
	border-width: 0px 0px 1px;
}

div.page_footer {
	height: 22px;
	padding: 4px 8px;
	background-color: #d9d8d1;
}

div.page_footer_text {
	line-height: 22px;
	float: left;
	color: #555555;
	font-style: italic;
}

div#generating_info {
	margin: 4px;
	font-size: smaller;
	text-align: center;
	color: #505050;
}

div.page_body {
	padding: 8px;
	font-family: monospace;
}

div.title, a.title {
	display: block;
	padding: 6px 8px;
	font-weight: bold;
	background-color: #edece6;
	text-decoration: none;
	color: #000000;
}

div.readme {
	padding: 8px;
}

a.title:hover {
	background-color: #d9d8d1;
}

div.title_text {
	padding: 6px 0px;
	border: solid #d9d8d1;
	border-width: 0px 0px 1px;
	font-family: monospace;
}

div.log_body {
	padding: 8px 8px 8px 150px;
}

span.age {
	position: relative;
	float: left;
	width: 142px;
	font-style: italic;
}

span.signoff {
	color: #888888;
}

div.log_link {
	padding: 0px 8px;
	font-size: 70%;
	font-family: sans-serif;
	font-style: normal;
	position: relative;
	float: left;
	width: 136px;
}

div.list_head {
	padding: 6px 8px 4px;
	border: solid #d9d8d1;
	border-width: 1px 0px 0px;
	font-style: italic;
}

.author_date, .author {
	font-style: italic;
}

div.author_date {
	padding: 8px;
	border: solid #d9d8d1;
	border-width: 0px 0px 1px 0px;
}

a.list {
	text-decoration: none;
	color: #000000;
}

a.subject, a.name {
	font-weight: bold;
}

table.tags a.subject {
	font-weight: normal;
}

a.list:hover {
	text-decoration: underline;
	color: #880000;
}

a.text {
	text-decoration: none;
	color: #0000cc;
}

a.text:visited {
	text-decoration: none;
	color: #880000;
}

a.text:hover {
	text-decoration: underline;
	color: #880000;
}

table {
	padding: 8px 4px;
	border-spacing: 0;
}

table.diff_tree {
	font-family: monospace;
}

table.combined.diff_tree th {
	text-align: center;
}

table.combined.diff_tree td {
	padding-right: 24px;
}

table.combined.diff_tree th.link,
table.combined.diff_tree td.link {
	padding: 0px 2px;
}

table.combined.diff_tree td.nochange a {
	color: #6666ff;
}

table.combined.diff_tree td.nochange a:hover,
table.combined.diff_tree td.nochange a:visited {
	color: #d06666;
}

table.blame {
	border-collapse: collapse;
}

table.blame td {
	padding: 0px 5px;
	font-size: 100%;
	vertical-align: top;
}

th {
	padding: 2px 5px;
	font-size: 100%;
	text-align: left;
}

/* do not change row style on hover for 'blame' view */
tr.light,
table.blame .light:hover {
	background-color: #ffffff;
}

tr.dark,
table.blame .dark:hover {
	background-color: #f6f6f0;
}

/* currently both use the same, but it can change */
tr.light:hover,
tr.dark:hover {
	background-color: #edece6;
}

/* boundary commits in 'blame' view */
/* and commits without "previous" */
tr.boundary td.sha1,
tr.no-previous td.linenr {
	font-weight: bold;
}

/* for 'blame_incremental', during processing */
tr.color1 { background-color: #f6fff6; }
tr.color2 { background-color: #f6f6ff; }
tr.color3 { background-color: #fff6f6; }

td {
	padding: 2px 5px;
	font-size: 100%;
	vertical-align: top;
}

td.link, td.selflink {
	padding: 2px 5px;
	font-family: sans-serif;
	font-size: 70%;
}

td.selflink {
	padding-right: 0px;
}

td.sha1 {
	font-family: monospace;
}

.error {
	color: red;
	background-color: yellow;
}

td.current_head {
	text-decoration: underline;
}

td.category {
	background-color: #d9d8d1;
	border-top: 1px solid #000000;
	border-left: 1px solid #000000;
	font-weight: bold;
}

table.diff_tree span.file_status.new {
	color: #008000;
}

table.diff_tree span.file_status.deleted {
	color: #c00000;
}

table.diff_tree span.file_status.moved,
table.diff_tree span.file_status.mode_chnge {
	color: #777777;
}

table.diff_tree span.file_status.copied {
  color: #70a070;
}

/* noage: "No commits" */
table.project_list td.noage {
	color: #808080;
	font-style: italic;
}

/* age2: 60*60*24*2 <= age */
table.project_list td.age2, table.blame td.age2 {
	font-style: italic;
}

/* age1: 60*60*2 <= age < 60*60*24*2 */
table.project_list td.age1 {
	color: #009900;
	font-style: italic;
}

table.blame td.age1 {
	color: #009900;
	background: transparent;
}

/* age0: age < 60*60*2 */
table.project_list td.age0 {
	color: #009900;
	font-style: italic;
	font-weight: bold;
}

table.blame td.age0 {
	color: #009900;
	background: transparent;
	font-weight: bold;
}

td.pre, div.pre, div.diff {
	font-family: monospace;
	font-size: 12px;
	white-space: pre;
}

td.mode {
	font-family: monospace;
}

/* progress of blame_interactive */
div#progress_bar {
	height: 2px;
	margin-bottom: -2px;
	background-color: #d8d9d0;
}
div#progress_info {
	float: right;
	text-align: right;
}

/* format of (optional) objects size in 'tree' view */
td.size {
	font-family: monospace;
	text-align: right;
}

/* styling of diffs (patchsets): commitdiff and blobdiff views */
div.diff.header,
div.diff.extended_header {
	white-space: normal;
}

div.diff.header {
	font-weight: bold;

	background-color: #edece6;

	margin-top: 4px;
	padding: 4px 0px 2px 0px;
	border: solid #d9d8d1;
	border-width: 1px 0px 1px 0px;
}

div.diff.header a.path {
	text-decoration: underline;
}

div.diff.extended_header,
div.diff.extended_header a.path,
div.diff.extended_header a.hash {
	color: #777777;
}

div.diff.extended_header .info {
	color: #b0b0b0;
}

div.diff.extended_header {
	background-color: #f6f5ee;
	padding: 2px 0px 2px 0px;
}

div.diff a.list,
div.diff a.path,
div.diff a.hash {
	text-decoration: none;
}

div.diff a.list:hover,
div.diff a.path:hover,
div.diff a.hash:hover {
	text-decoration: underline;
}

div.diff.to_file a.path,
div.diff.to_file {
	color: #007000;
}

div.diff.add {
	color: #008800;
}

div.diff.add span.marked {
	background-color: #aaffaa;
}

div.diff.from_file a.path,
div.diff.from_file {
	color: #aa0000;
}

div.diff.rem {
	color: #cc0000;
}

div.diff.rem span.marked {
	background-color: #ffaaaa;
}

div.diff.chunk_header a,
div.diff.chunk_header {
	color: #990099;
}

div.diff.chunk_header {
	border: dotted #ffe0ff;
	border-width: 1px 0px 0px 0px;
	margin-top: 2px;
}

div.diff.chunk_header span.chunk_info {
	background-color: #ffeeff;
}

div.diff.chunk_header span.section {
	color: #aa22aa;
}

div.diff.incomplete {
	color: #cccccc;
}

div.diff.nodifferences {
	font-weight: bold;
	color: #600000;
}

/* side-by-side diff */
div.chunk_block {
	overflow: hidden;
}

div.chunk_block div.old {
	float: left;
	width: 50%;
	overflow: hidden;
}

div.chunk_block div.new {
	margin-left: 50%;
	width: 50%;
}

div.chunk_block.rem div.old div.diff.rem {
	background-color: #fff5f5;
}
div.chunk_block.add div.new div.diff.add {
	background-color: #f8fff8;
}
div.chunk_block.chg div     div.diff {
	background-color: #fffff0;
}
div.chunk_block.ctx div     div.diff.ctx {
	color: #404040;
}


div.index_include {
	border: solid #d9d8d1;
	border-width: 0px 0px 1px;
	padding: 12px 8px;
}

div.search {
	font-size: 100%;
	font-weight: normal;
	margin: 4px 8px;
	float: right;
	top: 56px;
	right: 12px
}

div.projsearch {
	text-align: center;
	margin: 20px 0px;
}

div.projsearch form {
	margin-bottom: 2px;
}

td.linenr {
	text-align: right;
}

a.linenr {
	color: #999999;
	text-decoration: none
}

a.rss_logo {
	float: right;
	padding: 3px 5px;
	line-height: 10px;
	border: 1px solid;
	border-color: #fcc7a5 #7d3302 #3e1a01 #ff954e;
	color: #ffffff;
	background-color: #ff6600;
	font-weight: bold;
	font-family: sans-serif;
	font-size: 70%;
	text-align: center;
	text-decoration: none;
}

a.rss_logo:hover {
	background-color: #ee5500;
}

a.rss_logo.generic {
	background-color: #ff8800;
}

a.rss_logo.generic:hover {
	background-color: #ee7700;
}

span.refs span {
	padding: 0px 4px;
	font-size: 70%;
	font-weight: normal;
	border: 1px solid;
	background-color: #ffaaff;
	border-color: #ffccff #ff00ee #ff00ee #ffccff;
}

span.refs span a {
	text-decoration: none;
	color: inherit;
}

span.refs span a:hover {
	text-decoration: underline;
}

span.refs span.indirect {
	font-style: italic;
}

span.refs span.ref {
	background-color: #aaaaff;
	border-color: #ccccff #0033cc #0033cc #ccccff;
}

span.refs span.tag {
	background-color: #ffffaa;
	border-color: #ffffcc #ffee00 #ffee00 #ffffcc;
}

span.refs span.head {
	background-color: #aaffaa;
	border-color: #ccffcc #00cc33 #00cc33 #ccffcc;
}

span.atnight {
	color: #cc0000;
}

span.match {
	color: #e00000;
}

div.binary {
	font-style: italic;
}

div.remote {
	margin: .5em;
	border: 1px solid #d9d8d1;
	display: inline-block;
}

/* JavaScript-based timezone manipulation */

.popup { /* timezone selection UI */
	position: absolute;
	/* "top: 0; right: 0;" would be better, if not for bugs in browsers */
	top: 0; left: 0;
	border: 1px solid;
	padding: 2px;
	background-color: #f0f0f0;
	font-style: normal;
	color: #000000;
	cursor: auto;
}

.close-button { /* close timezone selection UI without selecting */
	/* float doesn't work within absolutely positioned container,
	 * if width of container is not set explicitly */
	/* float: right; */
	position: absolute;
	top: 0px; right: 0px;
	border:  1px solid green;
	margin:  1px 1px 1px 1px;
	padding-bottom: 2px;
	width:     12px;
	height:    10px;
	font-size:  9px;
	font-weight: bold;
	text-align: center;
	background-color: #fff0f0;
	cursor: pointer;
}


/* Style definition generated by highlight 2.4.5, http://www.andre-simon.de/ */

/* Highlighting theme definition: */

.num    { color:#2928ff; }
.esc    { color:#ff00ff; }
.str    { color:#ff0000; }
.dstr   { color:#818100; }
.slc    { color:#838183; font-style:italic; }
.com    { color:#838183; font-style:italic; }
.dir    { color:#008200; }
.sym    { color:#000000; }
.line   { color:#555555; }
.kwa    { color:#000000; font-weight:bold; }
.kwb    { color:#830000; }
.kwc    { color:#000000; font-weight:bold; }
.kwd    { color:#010181; }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   // Copyright (C) 2007, Fredrik Kuivinen <frekui@gmail.com>
//               2007, Petr Baudis <pasky@suse.cz>
//          2008-2011, Jakub Narebski <jnareb@gmail.com>

/**
 * @fileOverview Generic JavaScript code (helper functions)
 * @license GPLv2 or later
 */


/* ============================================================ */
/* ............................................................ */
/* Padding */

/**
 * pad INPUT on the left with STR that is assumed to have visible
 * width of single character (for example nonbreakable spaces),
 * to WIDTH characters
 *
 * example: padLeftStr(12, 3, '\u00A0') == '\u00A012'
 *          ('\u00A0' is nonbreakable space)
 *
 * @param {Number|String} input: number to pad
 * @param {Number} width: visible width of output
 * @param {String} str: string to prefix to string, defaults to '\u00A0'
 * @returns {String} INPUT prefixed with STR x (WIDTH - INPUT.length)
 */
function padLeftStr(input, width, str) {
	var prefix = '';
	if (typeof str === 'undefined') {
		ch = '\u00A0'; // using '&nbsp;' doesn't work in all browsers
	}

	width -= input.toString().length;
	while (width > 0) {
		prefix += str;
		width--;
	}
	return prefix + input;
}

/**
 * Pad INPUT on the left to WIDTH, using given padding character CH,
 * for example padLeft('a', 3, '_') is '__a'
 *             padLeft(4, 2) is '04' (same as padLeft(4, 2, '0'))
 *
 * @param {String} input: input value converted to string.
 * @param {Number} width: desired length of output.
 * @param {String} ch: single character to prefix to string, defaults to '0'.
 *
 * @returns {String} Modified string, at least SIZE length.
 */
function padLeft(input, width, ch) {
	var s = input + "";
	if (typeof ch === 'undefined') {
		ch = '0';
	}

	while (s.length < width) {
		s = ch + s;
	}
	return s;
}


/* ............................................................ */
/* Handling browser incompatibilities */

/**
 * Create XMLHttpRequest object in cross-browser way
 * @returns XMLHttpRequest object, or null
 */
function createRequestObject() {
	try {
		return new XMLHttpRequest();
	} catch (e) {}
	try {
		return window.createRequest();
	} catch (e) {}
	try {
		return new ActiveXObject("Msxml2.XMLHTTP");
	} catch (e) {}
	try {
		return new ActiveXObject("Microsoft.XMLHTTP");
	} catch (e) {}

	return null;
}


/**
 * Insert rule giving specified STYLE to given SELECTOR at the end of
 * first CSS stylesheet.
 *
 * @param {String} selector: CSS selector, e.g. '.class'
 * @param {String} style: rule contents, e.g. 'background-color: red;'
 */
function addCssRule(selector, style) {
	var stylesheet = document.styleSheets[0];

	var theRules = [];
	if (stylesheet.cssRules) {     // W3C way
		theRules = stylesheet.cssRules;
	} else if (stylesheet.rules) { // IE way
		theRules = stylesheet.rules;
	}

	if (stylesheet.insertRule) {    // W3C way
		stylesheet.insertRule(selector + ' { ' + style + ' }', theRules.length);
	} else if (stylesheet.addRule) { // IE way
		stylesheet.addRule(selector, style);
	}
}


/* ............................................................ */
/* Support for legacy browsers */

/**
 * Provides getElementsByClassName method, if there is no native
 * implementation of this method.
 *
 * NOTE that there are limits and differences compared to native
 * getElementsByClassName as defined by e.g.:
 *   https://developer.mozilla.org/en/DOM/document.getElementsByClassName
 *   http://www.whatwg.org/specs/web-apps/current-work/multipage/dom.html#dom-getelementsbyclassname
 *   http://www.whatwg.org/specs/web-apps/current-work/multipage/dom.html#dom-document-getelementsbyclassname
 *
 * Namely, this implementation supports only single class name as
 * argument and not set of space-separated tokens representing classes,
 * it returns Array of nodes rather than live NodeList, and has
 * additional optional argument where you can limit search to given tags
 * (via getElementsByTagName).
 *
 * Based on
 *   http://code.google.com/p/getelementsbyclassname/
 *   http://www.dustindiaz.com/getelementsbyclass/
 *   http://stackoverflow.com/questions/1818865/do-we-have-getelementsbyclassname-in-javascript
 *
 * See also http://ejohn.org/blog/getelementsbyclassname-speed-comparison/
 *
 * @param {String} class: name of _single_ class to find
 * @param {String} [taghint] limit search to given tags
 * @returns {Node[]} array of matching elements
 */
if (!('getElementsByClassName' in document)) {
	document.getElementsByClassName = function (classname, taghint) {
		taghint = taghint || "*";
		var elements = (taghint === "*" && document.all) ?
		               document.all :
		               document.getElementsByTagName(taghint);
		var pattern = new RegExp("(^|\\s)" + classname + "(\\s|$)");
		var matches= [];
		for (var i = 0, j = 0, n = elements.length; i < n; i++) {
			var el= elements[i];
			if (el.className && pattern.test(el.className)) {
				// matches.push(el);
				matches[j] = el;
				j++;
			}
		}
		return matches;
	};
} // end if


/* ............................................................ */
/* unquoting/unescaping filenames */

/**#@+
 * @constant
 */
var escCodeRe = /\\([^0-7]|[0-7]{1,3})/g;
var octEscRe = /^[0-7]{1,3}$/;
var maybeQuotedRe = /^\"(.*)\"$/;
/**#@-*/

/**
 * unquote maybe C-quoted filename (as used by git, i.e. it is
 * in double quotes '"' if there is any escape character used)
 * e.g. 'aa' -> 'aa', '"a\ta"' -> 'a	a'
 *
 * @param {String} str: git-quoted string
 * @returns {String} Unquoted and unescaped string
 *
 * @globals escCodeRe, octEscRe, maybeQuotedRe
 */
function unquote(str) {
	function unq(seq) {
		var es = {
			// character escape codes, aka escape sequences (from C)
			// replacements are to some extent JavaScript specific
			t: "\t",   // tab            (HT, TAB)
			n: "\n",   // newline        (NL)
			r: "\r",   // return         (CR)
			f: "\f",   // form feed      (FF)
			b: "\b",   // backspace      (BS)
			a: "\x07", // alarm (bell)   (BEL)
			e: "\x1B", // escape         (ESC)
			v: "\v"    // vertical tab   (VT)
		};

		if (seq.search(octEscRe) !== -1) {
			// octal char sequence
			return String.fromCharCode(parseInt(seq, 8));
		} else if (seq in es) {
			// C escape sequence, aka character escape code
			return es[seq];
		}
		// quoted ordinary character
		return seq;
	}

	var match = str.match(maybeQuotedRe);
	if (match) {
		str = match[1];
		// perhaps str = eval('"'+str+'"'); would be enough?
		str = str.replace(escCodeRe,
			function (substr, p1, offset, s) { return unq(p1); });
	}
	return str;
}

/* end of common-lib.js */
// Copyright (C) 2007, Fredrik Kuivinen <frekui@gmail.com>
//               2007, Petr Baudis <pasky@suse.cz>
//          2008-2011, Jakub Narebski <jnareb@gmail.com>

/**
 * @fileOverview Datetime manipulation: parsing and formatting
 * @license GPLv2 or later
 */


/* ............................................................ */
/* parsing and retrieving datetime related information */

/**
 * used to extract hours and minutes from timezone info, e.g '-0900'
 * @constant
 */
var tzRe = /^([+\-])([0-9][0-9])([0-9][0-9])$/;

/**
 * convert numeric timezone +/-ZZZZ to offset from UTC in seconds
 *
 * @param {String} timezoneInfo: numeric timezone '(+|-)HHMM'
 * @returns {Number} offset from UTC in seconds for timezone
 *
 * @globals tzRe
 */
function timezoneOffset(timezoneInfo) {
	var match = tzRe.exec(timezoneInfo);
	var tz_sign = (match[1] === '-' ? -1 : +1);
	var tz_hour = parseInt(match[2],10);
	var tz_min  = parseInt(match[3],10);

	return tz_sign*(((tz_hour*60) + tz_min)*60);
}

/**
 * return local (browser) timezone as offset from UTC in seconds
 *
 * @returns {Number} offset from UTC in seconds for local timezone
 */
function localTimezoneOffset() {
	// getTimezoneOffset returns the time-zone offset from UTC,
	// in _minutes_, for the current locale
	return ((new Date()).getTimezoneOffset() * -60);
}

/**
 * return local (browser) timezone as numeric timezone '(+|-)HHMM'
 *
 * @returns {String} locat timezone as -/+ZZZZ
 */
function localTimezoneInfo() {
	var tzOffsetMinutes = (new Date()).getTimezoneOffset() * -1;

	return formatTimezoneInfo(0, tzOffsetMinutes);
}


/**
 * Parse RFC-2822 date into a Unix timestamp (into epoch)
 *
 * @param {String} date: date in RFC-2822 format, e.g. 'Thu, 21 Dec 2000 16:01:07 +0200'
 * @returns {Number} epoch i.e. seconds since '00:00:00 1970-01-01 UTC'
 */
function parseRFC2822Date(date) {
	// Date.parse accepts the IETF standard (RFC 1123 Section 5.2.14 and elsewhere)
	// date syntax, which is defined in RFC 2822 (obsoletes RFC 822)
	// and returns number of _milli_seconds since January 1, 1970, 00:00:00 UTC
	return Date.parse(date) / 1000;
}


/* ............................................................ */
/* formatting date */

/**
 * format timezone offset as numerical timezone '(+|-)HHMM' or '(+|-)HH:MM'
 *
 * @param {Number} hours:    offset in hours, e.g. 2 for '+0200'
 * @param {Number} [minutes] offset in minutes, e.g. 30 for '-4030';
 *                           it is split into hours if not 0 <= minutes < 60,
 *                           for example 1200 would give '+0100';
 *                           defaults to 0
 * @param {String} [sep] separator between hours and minutes part,
 *                       default is '', might be ':' for W3CDTF (rfc-3339)
 * @returns {String} timezone in '(+|-)HHMM' or '(+|-)HH:MM' format
 */
function formatTimezoneInfo(hours, minutes, sep) {
	minutes = minutes || 0; // to be able to use formatTimezoneInfo(hh)
	sep = sep || ''; // default format is +/-ZZZZ

	if (minutes < 0 || minutes > 59) {
		hours = minutes > 0 ? Math.floor(minutes / 60) : Math.ceil(minutes / 60);
		minutes = Math.abs(minutes - 60*hours); // sign of minutes is sign of hours
		// NOTE: this works correctly because there is no UTC-00:30 timezone
	}

	var tzSign = hours >= 0 ? '+' : '-';
	if (hours < 0) {
		hours = -hours; // sign is stored in tzSign
	}

	return tzSign + padLeft(hours, 2, '0') + sep + padLeft(minutes, 2, '0');
}

/**
 * translate 'utc' and 'local' to numerical timezone
 * @param {String} timezoneInfo: might be 'utc' or 'local' (browser)
 */
function normalizeTimezoneInfo(timezoneInfo) {
	switch (timezoneInfo) {
	case 'utc':
		return '+0000';
	case 'local': // 'local' is browser timezone
		return localTimezoneInfo();
	}
	return timezoneInfo;
}


/**
 * return date in local time formatted in iso-8601 like format
 * 'yyyy-mm-dd HH:MM:SS +/-ZZZZ' e.g. '2005-08-07 21:49:46 +0200'
 *
 * @param {Number} epoch: seconds since '00:00:00 1970-01-01 UTC'
 * @param {String} timezoneInfo: numeric timezone '(+|-)HHMM'
 * @returns {String} date in local time in iso-8601 like format
 */
function formatDateISOLocal(epoch, timezoneInfo) {
	// date corrected by timezone
	var localDate = new Date(1000 * (epoch +
		timezoneOffset(timezoneInfo)));
	var localDateStr = // e.g. '2005-08-07'
		localDate.getUTCFullYear()                 + '-' +
		padLeft(localDate.getUTCMonth()+1, 2, '0') + '-' +
		padLeft(localDate.getUTCDate(),    2, '0');
	var localTimeStr = // e.g. '21:49:46'
		padLeft(localDate.getUTCHours(),   2, '0') + ':' +
		padLeft(localDate.getUTCMinutes(), 2, '0') + ':' +
		padLeft(localDate.getUTCSeconds(), 2, '0');

	return localDateStr + ' ' + localTimeStr + ' ' + timezoneInfo;
}

/**
 * return date in local time formatted in rfc-2822 format
 * e.g. 'Thu, 21 Dec 2000 16:01:07 +0200'
 *
 * @param {Number} epoch: seconds since '00:00:00 1970-01-01 UTC'
 * @param {String} timezoneInfo: numeric timezone '(+|-)HHMM'
 * @param {Boolean} [padDay] e.g. 'Sun, 07 Aug' if true, 'Sun, 7 Aug' otherwise
 * @returns {String} date in local time in rfc-2822 format
 */
function formatDateRFC2882(epoch, timezoneInfo, padDay) {
	// A short textual representation of a month, three letters
	var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
	// A textual representation of a day, three letters
	var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
	// date corrected by timezone
	var localDate = new Date(1000 * (epoch +
		timezoneOffset(timezoneInfo)));
	var localDateStr = // e.g. 'Sun, 7 Aug 2005' or 'Sun, 07 Aug 2005'
		days[localDate.getUTCDay()] + ', ' +
		(padDay ? padLeft(localDate.getUTCDate(),2,'0') : localDate.getUTCDate()) + ' ' +
		months[localDate.getUTCMonth()] + ' ' +
		localDate.getUTCFullYear();
	var localTimeStr = // e.g. '21:49:46'
		padLeft(localDate.getUTCHours(),   2, '0') + ':' +
		padLeft(localDate.getUTCMinutes(), 2, '0') + ':' +
		padLeft(localDate.getUTCSeconds(), 2, '0');

	return localDateStr + ' ' + localTimeStr + ' ' + timezoneInfo;
}

/* end of datetime.js */
/**
 * @fileOverview Accessing cookies from JavaScript
 * @license GPLv2 or later
 */

/*
 * Based on subsection "Cookies in JavaScript" of "Professional
 * JavaScript for Web Developers" by Nicholas C. Zakas and cookie
 * plugin from jQuery (dual licensed under the MIT and GPL licenses)
 */


/**
 * Create a cookie with the given name and value,
 * and other optional parameters.
 *
 * @example
 *   setCookie('foo', 'bar'); // will be deleted when browser exits
 *   setCookie('foo', 'bar', { expires: new Date(Date.parse('Jan 1, 2012')) });
 *   setCookie('foo', 'bar', { expires: 7 }); // 7 days = 1 week
 *   setCookie('foo', 'bar', { expires: 14, path: '/' });
 *
 * @param {String} sName:    Unique name of a cookie (letters, numbers, underscores).
 * @param {String} sValue:   The string value stored in a cookie.
 * @param {Object} [options] An object literal containing key/value pairs
 *                           to provide optional cookie attributes.
 * @param {String|Number|Date} [options.expires] Either literal string to be used as cookie expires,
 *                            or an integer specifying the expiration date from now on in days,
 *                            or a Date object to be used as cookie expiration date.
 *                            If a negative value is specified or a date in the past),
 *                            the cookie will be deleted.
 *                            If set to null or omitted, the cookie will be a session cookie
 *                            and will not be retained when the browser exits.
 * @param {String} [options.path] Restrict access of a cookie to particular directory
 *                               (default: path of page that created the cookie).
 * @param {String} [options.domain] Override what web sites are allowed to access cookie
 *                                  (default: domain of page that created the cookie).
 * @param {Boolean} [options.secure] If true, the secure attribute of the cookie will be set
 *                                   and the cookie would be accessible only from secure sites
 *                                   (cookie transmission will require secure protocol like HTTPS).
 */
function setCookie(sName, sValue, options) {
	options = options || {};
	if (sValue === null) {
		sValue = '';
		option.expires = 'delete';
	}

	var sCookie = sName + '=' + encodeURIComponent(sValue);

	if (options.expires) {
		var oExpires = options.expires, sDate;
		if (oExpires === 'delete') {
			sDate = 'Thu, 01 Jan 1970 00:00:00 GMT';
		} else if (typeof oExpires === 'string') {
			sDate = oExpires;
		} else {
			var oDate;
			if (typeof oExpires === 'number') {
				oDate = new Date();
				oDate.setTime(oDate.getTime() + (oExpires * 24 * 60 * 60 * 1000)); // days to ms
			} else {
				oDate = oExpires;
			}
			sDate = oDate.toGMTString();
		}
		sCookie += '; expires=' + sDate;
	}

	if (options.path) {
		sCookie += '; path=' + (options.path);
	}
	if (options.domain) {
		sCookie += '; domain=' + (options.domain);
	}
	if (options.secure) {
		sCookie += '; secure';
	}
	document.cookie = sCookie;
}

/**
 * Get the value of a cookie with the given name.
 *
 * @param {String} sName: Unique name of a cookie (letters, numbers, underscores)
 * @returns {String|null} The string value stored in a cookie
 */
function getCookie(sName) {
	var sRE = '(?:; )?' + sName + '=([^;]*);?';
	var oRE = new RegExp(sRE);
	if (oRE.test(document.cookie)) {
		return decodeURIComponent(RegExp['$1']);
	} else {
		return null;
	}
}

/**
 * Delete cookie with given name
 *
 * @param {String} sName:    Unique name of a cookie (letters, numbers, underscores)
 * @param {Object} [options] An object literal containing key/value pairs
 *                           to provide optional cookie attributes.
 * @param {String} [options.path]   Must be the same as when setting a cookie
 * @param {String} [options.domain] Must be the same as when setting a cookie
 */
function deleteCookie(sName, options) {
	options = options || {};
	options.expires = 'delete';

	setCookie(sName, '', options);
}

/* end of cookies.js */
// Copyright (C) 2007, Fredrik Kuivinen <frekui@gmail.com>
//               2007, Petr Baudis <pasky@suse.cz>
//          2008-2011, Jakub Narebski <jnareb@gmail.com>

/**
 * @fileOverview Detect if JavaScript is enabled, and pass it to server-side
 * @license GPLv2 or later
 */


/* ============================================================ */
/* Manipulating links */

/**
 * used to check if link has 'js' query parameter already (at end),
 * and other reasons to not add 'js=1' param at the end of link
 * @constant
 */
var jsExceptionsRe = /[;?]js=[01](#.*)?$/;

/**
 * Add '?js=1' or ';js=1' to the end of every link in the document
 * that doesn't have 'js' query parameter set already.
 *
 * Links with 'js=1' lead to JavaScript version of given action, if it
 * exists (currently there is only 'blame_incremental' for 'blame')
 *
 * To be used as `window.onload` handler
 *
 * @globals jsExceptionsRe
 */
function fixLinks() {
	var allLinks = document.getElementsByTagName("a") || document.links;
	for (var i = 0, len = allLinks.length; i < len; i++) {
		var link = allLinks[i];
		if (!jsExceptionsRe.test(link)) {
			link.href = link.href.replace(/(#|$)/,
				(link.href.indexOf('?') === -1 ? '?' : ';') + 'js=1$1');
		}
	}
}

/* end of javascript-detection.js */
// Copyright (C) 2011, John 'Warthog9' Hawley <warthog9@eaglescrag.net>
//               2011, Jakub Narebski <jnareb@gmail.com>

/**
 * @fileOverview Manipulate dates in gitweb output, adjusting timezone
 * @license GPLv2 or later
 */

/**
 * Get common timezone, add UI for changing timezones, and adjust
 * dates to use requested common timezone.
 *
 * This function is called during onload event (added to window.onload).
 *
 * @param {String} tzDefault: default timezone, if there is no cookie
 * @param {Object} tzCookieInfo: object literal with info about cookie to store timezone
 * @param {String} tzCookieInfo.name: name of cookie to store timezone
 * @param {String} tzClassName: denotes elements with date to be adjusted
 */
function onloadTZSetup(tzDefault, tzCookieInfo, tzClassName) {
	var tzCookieTZ = getCookie(tzCookieInfo.name, tzCookieInfo);
	var tz = tzDefault;

	if (tzCookieTZ) {
		// set timezone to value saved in a cookie
		tz = tzCookieTZ;
		// refresh cookie, so its expiration counts from last use of gitweb
		setCookie(tzCookieInfo.name, tzCookieTZ, tzCookieInfo);
	}

	// add UI for changing timezone
	addChangeTZ(tz, tzCookieInfo, tzClassName);

	// server-side of gitweb produces datetime in UTC,
	// so if tz is 'utc' there is no need for changes
	var nochange = tz === 'utc';

	// adjust dates to use specified common timezone
	fixDatetimeTZ(tz, tzClassName, nochange);
}


/* ...................................................................... */
/* Changing dates to use requested timezone */

/**
 * Replace RFC-2822 dates contained in SPAN elements with tzClassName
 * CSS class with equivalent dates in given timezone.
 *
 * @param {String} tz: numeric timezone in '(-|+)HHMM' format, or 'utc', or 'local'
 * @param {String} tzClassName: specifies elements to be changed
 * @param {Boolean} nochange: markup for timezone change, but don't change it
 */
function fixDatetimeTZ(tz, tzClassName, nochange) {
	// sanity check, method should be ensured by common-lib.js
	if (!document.getElementsByClassName) {
		return;
	}

	// translate to timezone in '(-|+)HHMM' format
	tz = normalizeTimezoneInfo(tz);

	// NOTE: result of getElementsByClassName should probably be cached
	var classesFound = document.getElementsByClassName(tzClassName, "span");
	for (var i = 0, len = classesFound.length; i < len; i++) {
		var curElement = classesFound[i];

		curElement.title = 'Click to change timezone';
		if (!nochange) {
			// we use *.firstChild.data (W3C DOM) instead of *.innerHTML
			// as the latter doesn't always work everywhere in every browser
			var epoch = parseRFC2822Date(curElement.firstChild.data);
			var adjusted = formatDateRFC2882(epoch, tz);

			curElement.firstChild.data = adjusted;
		}
	}
}


/* ...................................................................... */
/* Adding triggers, generating timezone menu, displaying and hiding */

/**
 * Adds triggers for UI to change common timezone used for dates in
 * gitweb output: it marks up and/or creates item to click to invoke
 * timezone change UI, creates timezone UI fragment to be attached,
 * and installs appropriate onclick trigger (via event delegation).
 *
 * @param {String} tzSelected: pre-selected timezone,
 *                             'utc' or 'local' or '(-|+)HHMM'
 * @param {Object} tzCookieInfo: object literal with info about cookie to store timezone
 * @param {String} tzClassName: specifies elements to install trigger
 */
function addChangeTZ(tzSelected, tzCookieInfo, tzClassName) {
	// make link to timezone UI discoverable
	addCssRule('.'+tzClassName + ':hover',
	           'text-decoration: underline; cursor: help;');

	// create form for selecting timezone (to be saved in a cookie)
	var tzSelectFragment = document.createDocumentFragment();
	tzSelectFragment = createChangeTZForm(tzSelectFragment,
	                                      tzSelected, tzCookieInfo, tzClassName);

	// event delegation handler for timezone selection UI (clicking on entry)
	// see http://www.nczonline.net/blog/2009/06/30/event-delegation-in-javascript/
	// assumes that there is no existing document.onclick handler
	document.onclick = function onclickHandler(event) {
		//IE doesn't pass in the event object
		event = event || window.event;

		//IE uses srcElement as the target
		var target = event.target || event.srcElement;

		switch (target.className) {
		case tzClassName:
			// don't display timezone menu if it is already displayed
			if (tzSelectFragment.childNodes.length > 0) {
				displayChangeTZForm(target, tzSelectFragment);
			}
			break;
		} // end switch
	};
}

/**
 * Create DocumentFragment with UI for changing common timezone in
 * which dates are shown in.
 *
 * @param {DocumentFragment} documentFragment: where attach UI
 * @param {String} tzSelected: default (pre-selected) timezone
 * @param {Object} tzCookieInfo: object literal with info about cookie to store timezone
 * @returns {DocumentFragment}
 */
function createChangeTZForm(documentFragment, tzSelected, tzCookieInfo, tzClassName) {
	var div = document.createElement("div");
	div.className = 'popup';

	/* '<div class="close-button" title="(click on this box to close)">X</div>' */
	var closeButton = document.createElement('div');
	closeButton.className = 'close-button';
	closeButton.title = '(click on this box to close)';
	closeButton.appendChild(document.createTextNode('X'));
	closeButton.onclick = closeTZFormHandler(documentFragment, tzClassName);
	div.appendChild(closeButton);

	/* 'Select timezone: <br clear="all">' */
	div.appendChild(document.createTextNode('Select timezone: '));
	var br = document.createElement('br');
	br.clear = 'all';
	div.appendChild(br);

	/* '<select name="tzoffset">
	 *    ...
	 *    <option value="-0700">UTC-07:00</option>
	 *    <option value="-0600">UTC-06:00</option>
	 *    ...
	 *  </select>' */
	var select = document.createElement("select");
	select.name = "tzoffset";
	//select.style.clear = 'all';
	select.appendChild(generateTZOptions(tzSelected));
	select.onchange = selectTZHandler(documentFragment, tzCookieInfo, tzClassName);
	div.appendChild(select);

	documentFragment.appendChild(div);

	return documentFragment;
}


/**
 * Hide (remove from DOM) timezone change UI, ensuring that it is not
 * garbage collected and that it can be re-enabled later.
 *
 * @param {DocumentFragment} documentFragment: contains detached UI
 * @param {HTMLSelectElement} target: select element inside of UI
 * @param {String} tzClassName: specifies element where UI was installed
 * @returns {DocumentFragment} documentFragment
 */
function removeChangeTZForm(documentFragment, target, tzClassName) {
	// find containing element, where we appended timezone selection UI
	// `target' is somewhere inside timezone menu
	var container = target.parentNode, popup = target;
	while (container &&
	       container.className !== tzClassName) {
		popup = container;
		container = container.parentNode;
	}
	// safety check if we found correct container,
	// and if it isn't deleted already
	if (!container || !popup ||
	    container.className !== tzClassName ||
	    popup.className     !== 'popup') {
		return documentFragment;
	}

	// timezone selection UI was appended as last child
	// see also displayChangeTZForm function
	var removed = popup.parentNode.removeChild(popup);
	if (documentFragment.firstChild !== removed) { // the only child
		// re-append it so it would be available for next time
		documentFragment.appendChild(removed);
	}
	// all of inline style was added by this script
	// it is not really needed to remove it, but it is a good practice
	container.removeAttribute('style');

	return documentFragment;
}


/**
 * Display UI for changing common timezone for dates in gitweb output.
 * To be used from 'onclick' event handler.
 *
 * @param {HTMLElement} target: where to install/display UI
 * @param {DocumentFragment} tzSelectFragment: timezone selection UI
 */
function displayChangeTZForm(target, tzSelectFragment) {
	// for absolute positioning to be related to target element
	target.style.position = 'relative';
	target.style.display = 'inline-block';

	// show/display UI for changing timezone
	target.appendChild(tzSelectFragment);
}


/* ...................................................................... */
/* List of timezones for timezone selection menu */

/**
 * Generate list of timezones for creating timezone select UI
 *
 * @returns {Object[]} list of e.g. { value: '+0100', descr: 'GMT+01:00' }
 */
function generateTZList() {
	var timezones = [
		{ value: "utc",   descr: "UTC/GMT"},
		{ value: "local", descr: "Local (per browser)"}
	];

	// generate all full hour timezones (no fractional timezones)
	for (var x = -12, idx = timezones.length; x <= +14; x++, idx++) {
		var hours = (x >= 0 ? '+' : '-') + padLeft(x >=0 ? x : -x, 2);
		timezones[idx] = { value: hours + '00', descr: 'UTC' + hours + ':00'};
		if (x === 0) {
			timezones[idx].descr = 'UTC\u00B100:00'; // 'UTC&plusmn;00:00'
		}
	}

	return timezones;
}

/**
 * Generate <options> elements for timezone select UI
 *
 * @param {String} tzSelected: default timezone
 * @returns {DocumentFragment} list of options elements to appendChild
 */
function generateTZOptions(tzSelected) {
	var elems = document.createDocumentFragment();
	var timezones = generateTZList();

	for (var i = 0, len = timezones.length; i < len; i++) {
		var tzone = timezones[i];
		var option = document.createElement("option");
		if (tzone.value === tzSelected) {
			option.defaultSelected = true;
		}
		option.value = tzone.value;
		option.appendChild(document.createTextNode(tzone.descr));

		elems.appendChild(option);
	}

	return elems;
}


/* ...................................................................... */
/* Event handlers and/or their generators */

/**
 * Create event handler that select timezone and closes timezone select UI.
 * To be used as $('select[name="tzselect"]').onchange handler.
 *
 * @param {DocumentFragment} tzSelectFragment: timezone selection UI
 * @param {Object} tzCookieInfo: object literal with info about cookie to store timezone
 * @param {String} tzCookieInfo.name: name of cookie to save result of selection
 * @param {String} tzClassName: specifies element where UI was installed
 * @returns {Function} event handler
 */
function selectTZHandler(tzSelectFragment, tzCookieInfo, tzClassName) {
	//return function selectTZ(event) {
	return function (event) {
		event = event || window.event;
		var target = event.target || event.srcElement;

		var selected = target.options.item(target.selectedIndex);
		removeChangeTZForm(tzSelectFragment, target, tzClassName);

		if (selected) {
			selected.defaultSelected = true;
			setCookie(tzCookieInfo.name, selected.value, tzCookieInfo);
			fixDatetimeTZ(selected.value, tzClassName);
		}
	};
}

/**
 * Create event handler that closes timezone select UI.
 * To be used e.g. as $('.closebutton').onclick handler.
 *
 * @param {DocumentFragment} tzSelectFragment: timezone selection UI
 * @param {String} tzClassName: specifies element where UI was installed
 * @returns {Function} event handler
 */
function closeTZFormHandler(tzSelectFragment, tzClassName) {
	//return function closeTZForm(event) {
	return function (event) {
		event = event || window.event;
		var target = event.target || event.srcElement;

		removeChangeTZForm(tzSelectFragment, target, tzClassName);
	};
}

/* end of adjust-timezone.js */
// Copyright (C) 2007, Fredrik Kuivinen <frekui@gmail.com>
//               2007, Petr Baudis <pasky@suse.cz>
//          2008-2011, Jakub Narebski <jnareb@gmail.com>

/**
 * @fileOverview JavaScript side of Ajax-y 'blame_incremental' view in gitweb
 * @license GPLv2 or later
 */

/* ============================================================ */
/*
 * This code uses DOM methods instead of (nonstandard) innerHTML
 * to modify page.
 *
 * innerHTML is non-standard IE extension, though supported by most
 * browsers; however Firefox up to version 1.5 didn't implement it in
 * a strict mode (application/xml+xhtml mimetype).
 *
 * Also my simple benchmarks show that using elem.firstChild.data =
 * 'content' is slightly faster than elem.innerHTML = 'content'.  It
 * is however more fragile (text element fragment must exists), and
 * less feature-rich (we cannot add HTML).
 *
 * Note that DOM 2 HTML is preferred over generic DOM 2 Core; the
 * equivalent using DOM 2 Core is usually shown in comments.
 */


/* ............................................................ */
/* utility/helper functions (and variables) */

var projectUrl; // partial query + separator ('?' or ';')

// 'commits' is an associative map. It maps SHA1s to Commit objects.
var commits = {};

/**
 * constructor for Commit objects, used in 'blame'
 * @class Represents a blamed commit
 * @param {String} sha1: SHA-1 identifier of a commit
 */
function Commit(sha1) {
	if (this instanceof Commit) {
		this.sha1 = sha1;
		this.nprevious = 0; /* number of 'previous', effective parents */
	} else {
		return new Commit(sha1);
	}
}

/* ............................................................ */
/* progress info, timing, error reporting */

var blamedLines = 0;
var totalLines  = '???';
var div_progress_bar;
var div_progress_info;

/**
 * Detects how many lines does a blamed file have,
 * This information is used in progress info
 *
 * @returns {Number|String} Number of lines in file, or string '...'
 */
function countLines() {
	var table =
		document.getElementById('blame_table') ||
		document.getElementsByTagName('table')[0];

	if (table) {
		return table.getElementsByTagName('tr').length - 1; // for header
	} else {
		return '...';
	}
}

/**
 * update progress info and length (width) of progress bar
 *
 * @globals div_progress_info, div_progress_bar, blamedLines, totalLines
 */
function updateProgressInfo() {
	if (!div_progress_info) {
		div_progress_info = document.getElementById('progress_info');
	}
	if (!div_progress_bar) {
		div_progress_bar = document.getElementById('progress_bar');
	}
	if (!div_progress_info && !div_progress_bar) {
		return;
	}

	var percentage = Math.floor(100.0*blamedLines/totalLines);

	if (div_progress_info) {
		div_progress_info.firstChild.data  = blamedLines + ' / ' + totalLines +
			' (' + padLeftStr(percentage, 3, '\u00A0') + '%)';
	}

	if (div_progress_bar) {
		//div_progress_bar.setAttribute('style', 'width: '+percentage+'%;');
		div_progress_bar.style.width = percentage + '%';
	}
}


var t_interval_server = '';
var cmds_server = '';
var t0 = new Date();

/**
 * write how much it took to generate data, and to run script
 *
 * @globals t0, t_interval_server, cmds_server
 */
function writeTimeInterval() {
	var info_time = document.getElementById('generating_time');
	if (!info_time || !t_interval_server) {
		return;
	}
	var t1 = new Date();
	info_time.firstChild.data += ' + (' +
		t_interval_server + ' sec server blame_data / ' +
		(t1.getTime() - t0.getTime())/1000 + ' sec client JavaScript)';

	var info_cmds = document.getElementById('generating_cmd');
	if (!info_time || !cmds_server) {
		return;
	}
	info_cmds.firstChild.data += ' + ' + cmds_server;
}

/**
 * show an error message alert to user within page (in progress info area)
 * @param {String} str: plain text error message (no HTML)
 *
 * @globals div_progress_info
 */
function errorInfo(str) {
	if (!div_progress_info) {
		div_progress_info = document.getElementById('progress_info');
	}
	if (div_progress_info) {
		div_progress_info.className = 'error';
		div_progress_info.firstChild.data = str;
	}
}

/* ............................................................ */
/* coloring rows during blame_data (git blame --incremental) run */

/**
 * used to extract N from 'colorN', where N is a number,
 * @constant
 */
var colorRe = /\bcolor([0-9]*)\b/;

/**
 * return N if <tr class="colorN">, otherwise return null
 * (some browsers require CSS class names to begin with letter)
 *
 * @param {HTMLElement} tr: table row element to check
 * @param {String} tr.className: 'class' attribute of tr element
 * @returns {Number|null} N if tr.className == 'colorN', otherwise null
 *
 * @globals colorRe
 */
function getColorNo(tr) {
	if (!tr) {
		return null;
	}
	var className = tr.className;
	if (className) {
		var match = colorRe.exec(className);
		if (match) {
			return parseInt(match[1], 10);
		}
	}
	return null;
}

var colorsFreq = [0, 0, 0];
/**
 * return one of given possible colors (currently least used one)
 * example: chooseColorNoFrom(2, 3) returns 2 or 3
 *
 * @param {Number[]} arguments: one or more numbers
 *        assumes that  1 <= arguments[i] <= colorsFreq.length
 * @returns {Number} Least used color number from arguments
 * @globals colorsFreq
 */
function chooseColorNoFrom() {
	// choose the color which is least used
	var colorNo = arguments[0];
	for (var i = 1; i < arguments.length; i++) {
		if (colorsFreq[arguments[i]-1] < colorsFreq[colorNo-1]) {
			colorNo = arguments[i];
		}
	}
	colorsFreq[colorNo-1]++;
	return colorNo;
}

/**
 * given two neighbor <tr> elements, find color which would be different
 * from color of both of neighbors; used to 3-color blame table
 *
 * @param {HTMLElement} tr_prev
 * @param {HTMLElement} tr_next
 * @returns {Number} color number N such that
 * colorN != tr_prev.className && colorN != tr_next.className
 */
function findColorNo(tr_prev, tr_next) {
	var color_prev = getColorNo(tr_prev);
	var color_next = getColorNo(tr_next);


	// neither of neighbors has color set
	// THEN we can use any of 3 possible colors
	if (!color_prev && !color_next) {
		return chooseColorNoFrom(1,2,3);
	}

	// either both neighbors have the same color,
	// or only one of neighbors have color set
	// THEN we can use any color except given
	var color;
	if (color_prev === color_next) {
		color = color_prev; // = color_next;
	} else if (!color_prev) {
		color = color_next;
	} else if (!color_next) {
		color = color_prev;
	}
	if (color) {
		return chooseColorNoFrom((color % 3) + 1, ((color+1) % 3) + 1);
	}

	// neighbors have different colors
	// THEN there is only one color left
	return (3 - ((color_prev + color_next) % 3));
}

/* ............................................................ */
/* coloring rows like 'blame' after 'blame_data' finishes */

/**
 * returns true if given row element (tr) is first in commit group
 * to be used only after 'blame_data' finishes (after processing)
 *
 * @param {HTMLElement} tr: table row
 * @returns {Boolean} true if TR is first in commit group
 */
function isStartOfGroup(tr) {
	return tr.firstChild.className === 'sha1';
}

/**
 * change colors to use zebra coloring (2 colors) instead of 3 colors
 * concatenate neighbor commit groups belonging to the same commit
 *
 * @globals colorRe
 */
function fixColorsAndGroups() {
	var colorClasses = ['light', 'dark'];
	var linenum = 1;
	var tr, prev_group;
	var colorClass = 0;
	var table =
		document.getElementById('blame_table') ||
		document.getElementsByTagName('table')[0];

	while ((tr = document.getElementById('l'+linenum))) {
	// index origin is 0, which is table header; start from 1
	//while ((tr = table.rows[linenum])) { // <- it is slower
		if (isStartOfGroup(tr, linenum, document)) {
			if (prev_group &&
			    prev_group.firstChild.firstChild.href ===
			            tr.firstChild.firstChild.href) {
				// we have to concatenate groups
				var prev_rows = prev_group.firstChild.rowSpan || 1;
				var curr_rows =         tr.firstChild.rowSpan || 1;
				prev_group.firstChild.rowSpan = prev_rows + curr_rows;
				//tr.removeChild(tr.firstChild);
				tr.deleteCell(0); // DOM2 HTML way
			} else {
				colorClass = (colorClass + 1) % 2;
				prev_group = tr;
			}
		}
		var tr_class = tr.className;
		tr.className = tr_class.replace(colorRe, colorClasses[colorClass]);
		linenum++;
	}
}


/* ============================================================ */
/* main part: parsing response */

/**
 * Function called for each blame entry, as soon as it finishes.
 * It updates page via DOM manipulation, adding sha1 info, etc.
 *
 * @param {Commit} commit: blamed commit
 * @param {Object} group: object representing group of lines,
 *                        which blame the same commit (blame entry)
 *
 * @globals blamedLines
 */
function handleLine(commit, group) {
	/*
	   This is the structure of the HTML fragment we are working
	   with:

	   <tr id="l123" class="">
	     <td class="sha1" title=""><a href=""> </a></td>
	     <td class="linenr"><a class="linenr" href="">123</a></td>
	     <td class="pre"># times (my ext3 doesn&#39;t).</td>
	   </tr>
	*/

	var resline = group.resline;

	// format date and time string only once per commit
	if (!commit.info) {
		/* e.g. 'Kay Sievers, 2005-08-07 21:49:46 +0200' */
		commit.info = commit.author + ', ' +
			formatDateISOLocal(commit.authorTime, commit.authorTimezone);
	}

	// color depends on group of lines, not only on blamed commit
	var colorNo = findColorNo(
		document.getElementById('l'+(resline-1)),
		document.getElementById('l'+(resline+group.numlines))
	);

	// loop over lines in commit group
	for (var i = 0; i < group.numlines; i++, resline++) {
		var tr = document.getElementById('l'+resline);
		if (!tr) {
			break;
		}
		/*
			<tr id="l123" class="">
			  <td class="sha1" title=""><a href=""> </a></td>
			  <td class="linenr"><a class="linenr" href="">123</a></td>
			  <td class="pre"># times (my ext3 doesn&#39;t).</td>
			</tr>
		*/
		var td_sha1  = tr.firstChild;
		var a_sha1   = td_sha1.firstChild;
		var a_linenr = td_sha1.nextSibling.firstChild;

		/* <tr id="l123" class=""> */
		var tr_class = '';
		if (colorNo !== null) {
			tr_class = 'color'+colorNo;
		}
		if (commit.boundary) {
			tr_class += ' boundary';
		}
		if (commit.nprevious === 0) {
			tr_class += ' no-previous';
		} else if (commit.nprevious > 1) {
			tr_class += ' multiple-previous';
		}
		tr.className = tr_class;

		/* <td class="sha1" title="?" rowspan="?"><a href="?">?</a></td> */
		if (i === 0) {
			td_sha1.title = commit.info;
			td_sha1.rowSpan = group.numlines;

			a_sha1.href = projectUrl + 'a=commit;h=' + commit.sha1;
			if (a_sha1.firstChild) {
				a_sha1.firstChild.data = commit.sha1.substr(0, 8);
			} else {
				a_sha1.appendChild(
					document.createTextNode(commit.sha1.substr(0, 8)));
			}
			if (group.numlines >= 2) {
				var fragment = document.createDocumentFragment();
				var br   = document.createElement("br");
				var match = commit.author.match(/\b([A-Z])\B/g);
				if (match) {
					var text = document.createTextNode(
							match.join(''));
				}
				if (br && text) {
					var elem = fragment || td_sha1;
					elem.appendChild(br);
					elem.appendChild(text);
					if (fragment) {
						td_sha1.appendChild(fragment);
					}
				}
			}
		} else {
			//tr.removeChild(td_sha1); // DOM2 Core way
			tr.deleteCell(0); // DOM2 HTML way
		}

		/* <td class="linenr"><a class="linenr" href="?">123</a></td> */
		var linenr_commit =
			('previous' in commit ? commit.previous : commit.sha1);
		var linenr_filename =
			('file_parent' in commit ? commit.file_parent : commit.filename);
		a_linenr.href = projectUrl + 'a=blame_incremental' +
			';hb=' + linenr_commit +
			';f='  + encodeURIComponent(linenr_filename) +
			'#l' + (group.srcline + i);

		blamedLines++;

		//updateProgressInfo();
	}
}

// ----------------------------------------------------------------------

/**#@+
 * @constant
 */
var sha1Re = /^([0-9a-f]{40}) ([0-9]+) ([0-9]+) ([0-9]+)/;
var infoRe = /^([a-z-]+) ?(.*)/;
var endRe  = /^END ?([^ ]*) ?(.*)/;
/**@-*/

var curCommit = new Commit();
var curGroup  = {};

/**
 * Parse output from 'git blame --incremental [...]', received via
 * XMLHttpRequest from server (blamedataUrl), and call handleLine
 * (which updates page) as soon as blame entry is completed.
 *
 * @param {String[]} lines: new complete lines from blamedata server
 *
 * @globals commits, curCommit, curGroup, t_interval_server, cmds_server
 * @globals sha1Re, infoRe, endRe
 */
function processBlameLines(lines) {
	var match;

	for (var i = 0, len = lines.length; i < len; i++) {

		if ((match = sha1Re.exec(lines[i]))) {
			var sha1 = match[1];
			var srcline  = parseInt(match[2], 10);
			var resline  = parseInt(match[3], 10);
			var numlines = parseInt(match[4], 10);

			var c = commits[sha1];
			if (!c) {
				c = new Commit(sha1);
				commits[sha1] = c;
			}
			curCommit = c;

			curGroup.srcline = srcline;
			curGroup.resline = resline;
			curGroup.numlines = numlines;

		} else if ((match = infoRe.exec(lines[i]))) {
			var info = match[1];
			var data = match[2];
			switch (info) {
			case 'filename':
				curCommit.filename = unquote(data);
				// 'filename' information terminates the entry
				handleLine(curCommit, curGroup);
				updateProgressInfo();
				break;
			case 'author':
				curCommit.author = data;
				break;
			case 'author-time':
				curCommit.authorTime = parseInt(data, 10);
				break;
			case 'author-tz':
				curCommit.authorTimezone = data;
				break;
			case 'previous':
				curCommit.nprevious++;
				// store only first 'previous' header
				if (!('previous' in curCommit)) {
					var parts = data.split(' ', 2);
					curCommit.previous    = parts[0];
					curCommit.file_parent = unquote(parts[1]);
				}
				break;
			case 'boundary':
				curCommit.boundary = true;
				break;
			} // end switch

		} else if ((match = endRe.exec(lines[i]))) {
			t_interval_server = match[1];
			cmds_server = match[2];

		} else if (lines[i] !== '') {
			// malformed line

		} // end if (match)

	} // end for (lines)
}

/**
 * Process new data and return pointer to end of processed part
 *
 * @param {String} unprocessed: new data (from nextReadPos)
 * @param {Number} nextReadPos: end of last processed data
 * @return {Number} end of processed data (new value for nextReadPos)
 */
function processData(unprocessed, nextReadPos) {
	var lastLineEnd = unprocessed.lastIndexOf('\n');
	if (lastLineEnd !== -1) {
		var lines = unprocessed.substring(0, lastLineEnd).split('\n');
		nextReadPos += lastLineEnd + 1 /* 1 == '\n'.length */;

		processBlameLines(lines);
	} // end if

	return nextReadPos;
}

/**
 * Handle XMLHttpRequest errors
 *
 * @param {XMLHttpRequest} xhr: XMLHttpRequest object
 * @param {Number} [xhr.pollTimer] ID of the timeout to clear
 *
 * @globals commits
 */
function handleError(xhr) {
	errorInfo('Server error: ' +
		xhr.status + ' - ' + (xhr.statusText || 'Error contacting server'));

	if (typeof xhr.pollTimer === "number") {
		clearTimeout(xhr.pollTimer);
		delete xhr.pollTimer;
	}
	commits = {}; // free memory
}

/**
 * Called after XMLHttpRequest finishes (loads)
 *
 * @param {XMLHttpRequest} xhr: XMLHttpRequest object
 * @param {Number} [xhr.pollTimer] ID of the timeout to clear
 *
 * @globals commits
 */
function responseLoaded(xhr) {
	if (typeof xhr.pollTimer === "number") {
		clearTimeout(xhr.pollTimer);
		delete xhr.pollTimer;
	}

	fixColorsAndGroups();
	writeTimeInterval();
	commits = {}; // free memory
}

/**
 * handler for XMLHttpRequest onreadystatechange event
 * @see startBlame
 *
 * @param {XMLHttpRequest} xhr: XMLHttpRequest object
 * @param {Number} xhr.prevDataLength: previous value of xhr.responseText.length
 * @param {Number} xhr.nextReadPos: start of unread part of xhr.responseText
 * @param {Number} [xhr.pollTimer] ID of the timeout (to reset or cancel)
 * @param {Boolean} fromTimer: if handler was called from timer
 */
function handleResponse(xhr, fromTimer) {

	/*
	 * xhr.readyState
	 *
	 *  Value  Constant (W3C)    Description
	 *  -------------------------------------------------------------------
	 *  0      UNSENT            open() has not been called yet.
	 *  1      OPENED            send() has not been called yet.
	 *  2      HEADERS_RECEIVED  send() has been called, and headers
	 *                           and status are available.
	 *  3      LOADING           Downloading; responseText holds partial data.
	 *  4      DONE              The operation is complete.
	 */

	if (xhr.readyState !== 4 && xhr.readyState !== 3) {
		return;
	}

	// the server returned error
	// try ... catch block is to work around bug in IE8
	try {
		if (xhr.readyState === 3 && xhr.status !== 200) {
			return;
		}
	} catch (e) {
		return;
	}
	if (xhr.readyState === 4 && xhr.status !== 200) {
		handleError(xhr);
		return;
	}

	// In konqueror xhr.responseText is sometimes null here...
	if (xhr.responseText === null) {
		return;
	}


	// extract new whole (complete) lines, and process them
	if (xhr.prevDataLength !== xhr.responseText.length) {
		xhr.prevDataLength = xhr.responseText.length;
		var unprocessed = xhr.responseText.substring(xhr.nextReadPos);
		xhr.nextReadPos = processData(unprocessed, xhr.nextReadPos);
	}

	// did we finish work?
	if (xhr.readyState === 4) {
		responseLoaded(xhr);
		return;
	}

	// if we get from timer, we have to restart it
	// otherwise onreadystatechange gives us partial response, timer not needed
	if (fromTimer) {
		setTimeout(function () {
			handleResponse(xhr, true);
		}, 1000);

	} else if (typeof xhr.pollTimer === "number") {
		clearTimeout(xhr.pollTimer);
		delete xhr.pollTimer;
	}
}

// ============================================================
// ------------------------------------------------------------

/**
 * Incrementally update line data in blame_incremental view in gitweb.
 *
 * @param {String} blamedataUrl: URL to server script generating blame data.
 * @param {String} bUrl: partial URL to project, used to generate links.
 *
 * Called from 'blame_incremental' view after loading table with
 * file contents, a base for blame view.
 *
 * @globals t0, projectUrl, div_progress_bar, totalLines
*/
function startBlame(blamedataUrl, bUrl) {

	var xhr = createRequestObject();
	if (!xhr) {
		errorInfo('ERROR: XMLHttpRequest not supported');
		return;
	}

	t0 = new Date();
	projectUrl = bUrl + (bUrl.indexOf('?') === -1 ? '?' : ';');
	if ((div_progress_bar = document.getElementById('progress_bar'))) {
		//div_progress_bar.setAttribute('style', 'width: 100%;');
		div_progress_bar.style.cssText = 'width: 100%;';
	}
	totalLines = countLines();
	updateProgressInfo();

	/* add extra properties to xhr object to help processing response */
	xhr.prevDataLength = -1;  // used to detect if we have new data
	xhr.nextReadPos = 0;      // where unread part of response starts

	xhr.onreadystatechange = function () {
		handleResponse(xhr, false);
	};

	xhr.open('GET', blamedataUrl);
	xhr.setRequestHeader('Accept', 'text/plain');
	xhr.send(null);

	// not all browsers call onreadystatechange event on each server flush
	// poll response using timer every second to handle this issue
	xhr.pollTimer = setTimeout(function () {
		handleResponse(xhr, true);
	}, 1000);
}

/* end of blame_incremental.js */
                                                                                                                                                                                                                                                                                                                                                # the git manual pages are in the git-man package.
git binary: binary-without-manpage usr/bin/git
git binary: binary-without-manpage usr/bin/git-receive-pack
git binary: binary-without-manpage usr/bin/git-shell
git binary: binary-without-manpage usr/bin/git-upload-archive
git binary: binary-without-manpage usr/bin/git-upload-pack
# every new .git dir contains empty branches/ to support old scripts.
git binary: package-contains-empty-directory usr/share/git-core/templates/branches/
# False positive.
git binary: spelling-error-in-readme-debian DocumentRoot DocumentRoot (duplicate word) DocumentRoot
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          h  )   i  0     .     5     B   )     l                              	       *   4  k  _        -             8  A   V                 0     9   #      ]     ~       8   2                               
                         
   	                     Initialized empty Git repository in %s%s
 Initialized empty shared Git repository in %s%s
 Reinitialized existing Git repository in %s%s
 Reinitialized existing shared Git repository in %s%s
 See 'git help COMMAND' for more information on a specific command. TEST: A C test string TEST: A C test string %s TEST: A Perl test string TEST: A Perl test variable %s TEST: A Shell test $variable TEST: A Shell test string TEST: Hello World! TEST: Old English Runes TEST: ‘single’ and “double” quotes Project-Id-Version: Git
Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>
PO-Revision-Date: 2016-06-17 19:17+0000
Last-Translator: Vasco Almeida <vascomalmeida@sapo.pt>
Language-Team: Git Mailing List <git@vger.kernel.org>
Language: is
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Generator: Poedit 1.8.5
 Bjó til tóma Git lind í %s%s
 Bjó til tóma sameiginlega Git lind í %s%s
 Endurgerði Git lind í %s%s
 Endurgerði Git lind í %s%s
 Sjá 'git help SKIPUN' til að sjá hjálp fyrir tiltekna skipun. TILRAUN: C tilraunastrengur TILRAUN: C tilraunastrengur %s TILRAUN: Perl tilraunastrengur TILRAUN: Perl tilraunastrengur með breytunni %s TILRAUN: Skeljartilraunastrengur með breytunni $variable TILRAUN: Skeljartilraunastrengur TILRAUN: Halló Heimur! TILRAUN: ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ TILRAUN: ‚einfaldar‘ og „tvöfaldar“ gæsalappir                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      package Git::I18N;
use 5.008;
use strict;
use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : ();
BEGIN {
	require Exporter;
	if ($] < 5.008003) {
		*import = \&Exporter::import;
	} else {
		# Exporter 5.57 which supports this invocation was
		# released with perl 5.8.3
		Exporter->import('import');
	}
}

our @EXPORT = qw(__ __n N__);
our @EXPORT_OK = @EXPORT;

# See Git::LoadCPAN's NO_PERL_CPAN_FALLBACKS_STR for a description of
# this "'@@' [...] '@@'" pattern.
use constant NO_GETTEXT_STR => '@@' . 'NO_GETTEXT' . '@@';
use constant NO_GETTEXT => (
	q[] ne ''
	and
	q[] ne NO_GETTEXT_STR
);

sub __bootstrap_locale_messages {
	our $TEXTDOMAIN = 'git';
	our $TEXTDOMAINDIR ||= $ENV{GIT_TEXTDOMAINDIR} || '/usr/share/locale';
	die "NO_GETTEXT=" . NO_GETTEXT_STR if NO_GETTEXT;

	require POSIX;
	POSIX->import(qw(setlocale));
	# Non-core prerequisite module
	require Locale::Messages;
	Locale::Messages->import(qw(:locale_h :libintl_h));

	setlocale(LC_MESSAGES(), '');
	setlocale(LC_CTYPE(), '');
	textdomain($TEXTDOMAIN);
	bindtextdomain($TEXTDOMAIN => $TEXTDOMAINDIR);

	return;
}

BEGIN
{
	# Used by our test script to see if it should test fallbacks or
	# not.
	our $__HAS_LIBRARY = 1;

	local $@;
	eval {
		__bootstrap_locale_messages();
		*__ = \&Locale::Messages::gettext;
		*__n = \&Locale::Messages::ngettext;
		1;
	} or do {
		# Tell test.pl that we couldn't load the gettext library.
		$Git::I18N::__HAS_LIBRARY = 0;

		# Just a fall-through no-op
		*__ = sub ($) { $_[0] };
		*__n = sub ($$$) { $_[2] == 1 ? $_[0] : $_[1] };
	};

	sub N__($) { return shift; }
}

1;

__END__

=head1 NAME

Git::I18N - Perl interface to Git's Gettext localizations

=head1 SYNOPSIS

	use Git::I18N;

	print __("Welcome to Git!\n");

	printf __("The following error occurred: %s\n"), $error;

	printf __n("committed %d file\n", "committed %d files\n", $files), $files;


=head1 DESCRIPTION

Git's internal Perl interface to gettext via L<Locale::Messages>. If
L<Locale::Messages> can't be loaded (it's not a core module) we
provide stub passthrough fallbacks.

This is a distilled interface to gettext, see C<info '(gettext)Perl'>
for the full interface. This module implements only a small part of
it.

=head1 FUNCTIONS

=head2 __($)

L<Locale::Messages>'s gettext function if all goes well, otherwise our
passthrough fallback function.

=head2 __n($$$)

L<Locale::Messages>'s ngettext function or passthrough fallback function.

=head2 N__($)

No-operation that only returns its argument. Use this if you want xgettext to
extract the text to the pot template but do not want to trigger retrival of the
translation at run time.

=head1 AUTHOR

E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason <avarab@gmail.com>

=head1 COPYRIGHT

Copyright 2010 E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason <avarab@gmail.com>

=cut
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  package Git::IndexInfo;
use strict;
use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : ();
use Git qw/command_input_pipe command_close_pipe/;

sub new {
	my ($class) = @_;
	my $hash_algo = Git::config('extensions.objectformat') || 'sha1';
	my ($gui, $ctx) = command_input_pipe(qw/update-index -z --index-info/);
	bless { gui => $gui, ctx => $ctx, nr => 0, hash_algo => $hash_algo}, $class;
}

sub remove {
	my ($self, $path) = @_;
	my $length = $self->{hash_algo} eq 'sha256' ? 64 : 40;
	if (print { $self->{gui} } '0 ', 0 x $length, "\t", $path, "\0") {
		return ++$self->{nr};
	}
	undef;
}

sub update {
	my ($self, $mode, $hash, $path) = @_;
	if (print { $self->{gui} } $mode, ' ', $hash, "\t", $path, "\0") {
		return ++$self->{nr};
	}
	undef;
}

sub DESTROY {
	my ($self) = @_;
	command_close_pipe($self->{gui}, $self->{ctx});
}

1;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                package Git::LoadCPAN::Error;
use 5.008;
use strict;
use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : ();
use Git::LoadCPAN (
	module => 'Error',
	import => 1,
);

1;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             package Git::LoadCPAN::Mail::Address;
use 5.008;
use strict;
use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : ();
use Git::LoadCPAN (
	module => 'Mail::Address',
	import => 0,
);

1;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             package Git::LoadCPAN;
use 5.008;
use strict;
use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : ();

=head1 NAME

Git::LoadCPAN - Wrapper for loading modules from the CPAN (OS) or Git's own copy

=head1 DESCRIPTION

The Perl code in Git depends on some modules from the CPAN, but we
don't want to make those a hard requirement for anyone building from
source.

Therefore the L<Git::LoadCPAN> namespace shipped with Git contains
wrapper modules like C<Git::LoadCPAN::Module::Name> that will first
attempt to load C<Module::Name> from the OS, and if that doesn't work
will fall back on C<FromCPAN::Module::Name> shipped with Git itself.

Usually distributors will not ship with Git's Git::FromCPAN tree at
all via the C<NO_PERL_CPAN_FALLBACKS> option, preferring to use their
own packaging of CPAN modules instead.

This module is only intended to be used for code shipping in the
C<git.git> repository. Use it for anything else at your peril!

=cut

# NO_PERL_CPAN_FALLBACKS_STR evades the sed search-replace from the
# Makefile, and allows for detecting whether the module is loaded from
# perl/Git as opposed to perl/build/Git, which is useful for one-off
# testing without having Error.pm et al installed.
use constant NO_PERL_CPAN_FALLBACKS_STR => '@@' . 'NO_PERL_CPAN_FALLBACKS' . '@@';
use constant NO_PERL_CPAN_FALLBACKS => (
	q[1] ne ''
	and
	q[1] ne NO_PERL_CPAN_FALLBACKS_STR
);

sub import {
	shift;
	my $caller = caller;
	my %args = @_;
	my $module = exists $args{module} ? delete $args{module} : die "BUG: Expected 'module' parameter!";
	my $import = exists $args{import} ? delete $args{import} : die "BUG: Expected 'import' parameter!";
	die "BUG: Too many arguments!" if keys %args;

	# Foo::Bar to Foo/Bar.pm
	my $package_pm = $module;
	$package_pm =~ s[::][/]g;
	$package_pm .= '.pm';

	eval {
		require $package_pm;
		1;
	} or do {
		my $error = $@ || "Zombie Error";

		if (NO_PERL_CPAN_FALLBACKS) {
			chomp(my $error = sprintf <<'THEY_PROMISED', $module);
BUG: The '%s' module is not here, but NO_PERL_CPAN_FALLBACKS was set!

Git needs this Perl module from the CPAN, and will by default ship
with a copy of it. This Git was built with NO_PERL_CPAN_FALLBACKS,
meaning that whoever built it promised to provide this module.

You're seeing this error because they broke that promise, and we can't
load our fallback version, since we were asked not to install it.

If you're seeing this error and didn't package Git yourself the
package you're using is broken, or your system is broken. This error
won't appear if Git is built without NO_PERL_CPAN_FALLBACKS (instead
we'll use our fallback version of the module).
THEY_PROMISED
			die $error;
		}

		my $Git_LoadCPAN_pm_path = $INC{"Git/LoadCPAN.pm"} || die "BUG: Should have our own path from %INC!";

		require File::Basename;
		my $Git_LoadCPAN_pm_root = File::Basename::dirname($Git_LoadCPAN_pm_path) || die "BUG: Can't figure out lib/Git dirname from '$Git_LoadCPAN_pm_path'!";

		require File::Spec;
		my $Git_pm_FromCPAN_root = File::Spec->catdir($Git_LoadCPAN_pm_root, '..', 'FromCPAN');
		die "BUG: '$Git_pm_FromCPAN_root' should be a directory!" unless -d $Git_pm_FromCPAN_root;

		local @INC = ($Git_pm_FromCPAN_root, @INC);
		require $package_pm;
	};

	if ($import) {
		no strict 'refs';
		*{"${caller}::import"} = sub {
			shift;
			use strict 'refs';
			unshift @_, $module;
			goto &{"${module}::import"};
		};
		use strict 'refs';
	}
}

1;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     package Git::Packet;
use 5.008;
use strict;
use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : ();
BEGIN {
	require Exporter;
	if ($] < 5.008003) {
		*import = \&Exporter::import;
	} else {
		# Exporter 5.57 which supports this invocation was
		# released with perl 5.8.3
		Exporter->import('import');
	}
}

our @EXPORT = qw(
			packet_compare_lists
			packet_bin_read
			packet_txt_read
			packet_key_val_read
			packet_bin_write
			packet_txt_write
			packet_flush
			packet_initialize
			packet_read_capabilities
			packet_read_and_check_capabilities
			packet_check_and_write_capabilities
		);
our @EXPORT_OK = @EXPORT;

sub packet_compare_lists {
	my ($expect, @result) = @_;
	my $ix;
	if (scalar @$expect != scalar @result) {
		return undef;
	}
	for ($ix = 0; $ix < $#result; $ix++) {
		if ($expect->[$ix] ne $result[$ix]) {
			return undef;
		}
	}
	return 1;
}

sub packet_bin_read {
	my $buffer;
	my $bytes_read = read STDIN, $buffer, 4;
	if ( $bytes_read == 0 ) {
		# EOF - Git stopped talking to us!
		return ( -1, "" );
	} elsif ( $bytes_read != 4 ) {
		die "invalid packet: '$buffer'";
	}
	my $pkt_size = hex($buffer);
	if ( $pkt_size == 0 ) {
		return ( 1, "" );
	} elsif ( $pkt_size > 4 ) {
		my $content_size = $pkt_size - 4;
		$bytes_read = read STDIN, $buffer, $content_size;
		if ( $bytes_read != $content_size ) {
			die "invalid packet ($content_size bytes expected; $bytes_read bytes read)";
		}
		return ( 0, $buffer );
	} else {
		die "invalid packet size: $pkt_size";
	}
}

sub remove_final_lf_or_die {
	my $buf = shift;
	if ( $buf =~ s/\n$// ) {
		return $buf;
	}
	die "A non-binary line MUST be terminated by an LF.\n"
	    . "Received: '$buf'";
}

sub packet_txt_read {
	my ( $res, $buf ) = packet_bin_read();
	if ( $res != -1 and $buf ne '' ) {
		$buf = remove_final_lf_or_die($buf);
	}
	return ( $res, $buf );
}

# Read a text packet, expecting that it is in the form "key=value" for
# the given $key.  An EOF does not trigger any error and is reported
# back to the caller (like packet_txt_read() does).  Die if the "key"
# part of "key=value" does not match the given $key, or the value part
# is empty.
sub packet_key_val_read {
	my ( $key ) = @_;
	my ( $res, $buf ) = packet_txt_read();
	if ( $res == -1 or ( $buf =~ s/^$key=// and $buf ne '' ) ) {
		return ( $res, $buf );
	}
	die "bad $key: '$buf'";
}

sub packet_bin_write {
	my $buf = shift;
	print STDOUT sprintf( "%04x", length($buf) + 4 );
	print STDOUT $buf;
	STDOUT->flush();
}

sub packet_txt_write {
	packet_bin_write( $_[0] . "\n" );
}

sub packet_flush {
	print STDOUT sprintf( "%04x", 0 );
	STDOUT->flush();
}

sub packet_initialize {
	my ($name, $version) = @_;

	packet_compare_lists([0, $name . "-client"], packet_txt_read()) ||
		die "bad initialize";
	packet_compare_lists([0, "version=" . $version], packet_txt_read()) ||
		die "bad version";
	packet_compare_lists([1, ""], packet_bin_read()) ||
		die "bad version end";

	packet_txt_write( $name . "-server" );
	packet_txt_write( "version=" . $version );
	packet_flush();
}

sub packet_read_capabilities {
	my @cap;
	while (1) {
		my ( $res, $buf ) = packet_bin_read();
		if ( $res == -1 ) {
			die "unexpected EOF when reading capabilities";
		}
		return ( $res, @cap ) if ( $res != 0 );
		$buf = remove_final_lf_or_die($buf);
		unless ( $buf =~ s/capability=// ) {
			die "bad capability buf: '$buf'";
		}
		push @cap, $buf;
	}
}

# Read remote capabilities and check them against capabilities we require
sub packet_read_and_check_capabilities {
	my @required_caps = @_;
	my ($res, @remote_caps) = packet_read_capabilities();
	my %remote_caps = map { $_ => 1 } @remote_caps;
	foreach (@required_caps) {
		unless (exists($remote_caps{$_})) {
			die "required '$_' capability not available from remote" ;
		}
	}
	return %remote_caps;
}

# Check our capabilities we want to advertise against the remote ones
# and then advertise our capabilities
sub packet_check_and_write_capabilities {
	my ($remote_caps, @our_caps) = @_;
	foreach (@our_caps) {
		unless (exists($remote_caps->{$_})) {
			die "our capability '$_' is not available from remote"
		}
		packet_txt_write( "capability=" . $_ );
	}
	packet_flush();
}

1;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            =head1 NAME

Git - Perl interface to the Git version control system

=cut


package Git;

use 5.008;
use strict;
use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : ();

BEGIN {

our ($VERSION, @ISA, @EXPORT, @EXPORT_OK);

# Totally unstable API.
$VERSION = '0.01';


=head1 SYNOPSIS

  use Git;

  my $version = Git::command_oneline('version');

  git_cmd_try { Git::command_noisy('update-server-info') }
              '%s failed w/ code %d';

  my $repo = Git->repository (Directory => '/srv/git/cogito.git');


  my @revs = $repo->command('rev-list', '--since=last monday', '--all');

  my ($fh, $c) = $repo->command_output_pipe('rev-list', '--since=last monday', '--all');
  my $lastrev = <$fh>; chomp $lastrev;
  $repo->command_close_pipe($fh, $c);

  my $lastrev = $repo->command_oneline( [ 'rev-list', '--all' ],
                                        STDERR => 0 );

  my $sha1 = $repo->hash_and_insert_object('file.txt');
  my $tempfile = tempfile();
  my $size = $repo->cat_blob($sha1, $tempfile);

=cut


require Exporter;

@ISA = qw(Exporter);

@EXPORT = qw(git_cmd_try);

# Methods which can be called as standalone functions as well:
@EXPORT_OK = qw(command command_oneline command_noisy
                command_output_pipe command_input_pipe command_close_pipe
                command_bidi_pipe command_close_bidi_pipe
                version exec_path html_path hash_object git_cmd_try
                remote_refs prompt
                get_tz_offset get_record
                credential credential_read credential_write
                temp_acquire temp_is_locked temp_release temp_reset temp_path
                unquote_path);


=head1 DESCRIPTION

This module provides Perl scripts easy way to interface the Git version control
system. The modules have an easy and well-tested way to call arbitrary Git
commands; in the future, the interface will also provide specialized methods
for doing easily operations which are not totally trivial to do over
the generic command interface.

While some commands can be executed outside of any context (e.g. 'version'
or 'init'), most operations require a repository context, which in practice
means getting an instance of the Git object using the repository() constructor.
(In the future, we will also get a new_repository() constructor.) All commands
called as methods of the object are then executed in the context of the
repository.

Part of the "repository state" is also information about path to the attached
working copy (unless you work with a bare repository). You can also navigate
inside of the working copy using the C<wc_chdir()> method. (Note that
the repository object is self-contained and will not change working directory
of your process.)

TODO: In the future, we might also do

	my $remoterepo = $repo->remote_repository (Name => 'cogito', Branch => 'master');
	$remoterepo ||= Git->remote_repository ('http://git.or.cz/cogito.git/');
	my @refs = $remoterepo->refs();

Currently, the module merely wraps calls to external Git tools. In the future,
it will provide a much faster way to interact with Git by linking directly
to libgit. This should be completely opaque to the user, though (performance
increase notwithstanding).

=cut


sub carp { require Carp; goto &Carp::carp }
sub croak { require Carp; goto &Carp::croak }
use Git::LoadCPAN::Error qw(:try);
}


=head1 CONSTRUCTORS

=over 4

=item repository ( OPTIONS )

=item repository ( DIRECTORY )

=item repository ()

Construct a new repository object.
C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
Possible options are:

B<Repository> - Path to the Git repository.

B<WorkingCopy> - Path to the associated working copy; not strictly required
as many commands will happily crunch on a bare repository.

B<WorkingSubdir> - Subdirectory in the working copy to work inside.
Just left undefined if you do not want to limit the scope of operations.

B<Directory> - Path to the Git working directory in its usual setup.
The C<.git> directory is searched in the directory and all the parent
directories; if found, C<WorkingCopy> is set to the directory containing
it and C<Repository> to the C<.git> directory itself. If no C<.git>
directory was found, the C<Directory> is assumed to be a bare repository,
C<Repository> is set to point at it and C<WorkingCopy> is left undefined.
If the C<$GIT_DIR> environment variable is set, things behave as expected
as well.

You should not use both C<Directory> and either of C<Repository> and
C<WorkingCopy> - the results of that are undefined.

Alternatively, a directory path may be passed as a single scalar argument
to the constructor; it is equivalent to setting only the C<Directory> option
field.

Calling the constructor with no options whatsoever is equivalent to
calling it with C<< Directory => '.' >>. In general, if you are building
a standard porcelain command, simply doing C<< Git->repository() >> should
do the right thing and setup the object to reflect exactly where the user
is right now.

=cut

sub repository {
	my $class = shift;
	my @args = @_;
	my %opts = ();
	my $self;

	if (defined $args[0]) {
		if ($#args % 2 != 1) {
			# Not a hash.
			$#args == 0 or throw Error::Simple("bad usage");
			%opts = ( Directory => $args[0] );
		} else {
			%opts = @args;
		}
	}

	if (not defined $opts{Repository} and not defined $opts{WorkingCopy}
		and not defined $opts{Directory}) {
		$opts{Directory} = '.';
	}

	if (defined $opts{Directory}) {
		-d $opts{Directory} or throw Error::Simple("Directory not found: $opts{Directory} $!");

		my $search = Git->repository(WorkingCopy => $opts{Directory});

		# This rev-parse will throw an exception if we're not in a
		# repository, which is what we want, but it's kind of noisy.
		# Ideally we'd capture stderr and relay it, but doing so is
		# awkward without depending on it fitting in a pipe buffer. So
		# we just reproduce a plausible error message ourselves.
		my $out;
		try {
		  # Note that "--is-bare-repository" must come first, as
		  # --git-dir output could contain newlines.
		  $out = $search->command([qw(rev-parse --is-bare-repository --git-dir)],
			                  STDERR => 0);
		} catch Git::Error::Command with {
			throw Error::Simple("fatal: not a git repository: $opts{Directory}");
		};

		chomp $out;
		my ($bare, $dir) = split /\n/, $out, 2;

		require Cwd;
		if ($bare ne 'true') {
			require File::Spec;
			File::Spec->file_name_is_absolute($dir) or $dir = $opts{Directory} . '/' . $dir;
			$opts{Repository} = Cwd::abs_path($dir);

			# If --git-dir went ok, this shouldn't die either.
			my $prefix = $search->command_oneline('rev-parse', '--show-prefix');
			$dir = Cwd::abs_path($opts{Directory}) . '/';
			if ($prefix) {
				if (substr($dir, -length($prefix)) ne $prefix) {
					throw Error::Simple("rev-parse confused me - $dir does not have trailing $prefix");
				}
				substr($dir, -length($prefix)) = '';
			}
			$opts{WorkingCopy} = $dir;
			$opts{WorkingSubdir} = $prefix;

		} else {
			$opts{Repository} = Cwd::abs_path($dir);
		}

		delete $opts{Directory};
	}

	$self = { opts => \%opts };
	bless $self, $class;
}

=back

=head1 METHODS

=over 4

=item command ( COMMAND [, ARGUMENTS... ] )

=item command ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )

Execute the given Git C<COMMAND> (specify it without the 'git-'
prefix), optionally with the specified extra C<ARGUMENTS>.

The second more elaborate form can be used if you want to further adjust
the command execution. Currently, only one option is supported:

B<STDERR> - How to deal with the command's error output. By default (C<undef>)
it is delivered to the caller's C<STDERR>. A false value (0 or '') will cause
it to be thrown away. If you want to process it, you can get it in a filehandle
you specify, but you must be extremely careful; if the error output is not
very short and you want to read it in the same process as where you called
C<command()>, you are set up for a nice deadlock!

The method can be called without any instance or on a specified Git repository
(in that case the command will be run in the repository context).

In scalar context, it returns all the command output in a single string
(verbatim).

In array context, it returns an array containing lines printed to the
command's stdout (without trailing newlines).

In both cases, the command's stdin and stderr are the same as the caller's.

=cut

sub command {
	my ($fh, $ctx) = command_output_pipe(@_);

	if (not defined wantarray) {
		# Nothing to pepper the possible exception with.
		_cmd_close($ctx, $fh);

	} elsif (not wantarray) {
		local $/;
		my $text = <$fh>;
		try {
			_cmd_close($ctx, $fh);
		} catch Git::Error::Command with {
			# Pepper with the output:
			my $E = shift;
			$E->{'-outputref'} = \$text;
			throw $E;
		};
		return $text;

	} else {
		my @lines = <$fh>;
		defined and chomp for @lines;
		try {
			_cmd_close($ctx, $fh);
		} catch Git::Error::Command with {
			my $E = shift;
			$E->{'-outputref'} = \@lines;
			throw $E;
		};
		return @lines;
	}
}


=item command_oneline ( COMMAND [, ARGUMENTS... ] )

=item command_oneline ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )

Execute the given C<COMMAND> in the same way as command()
does but always return a scalar string containing the first line
of the command's standard output.

=cut

sub command_oneline {
	my ($fh, $ctx) = command_output_pipe(@_);

	my $line = <$fh>;
	defined $line and chomp $line;
	try {
		_cmd_close($ctx, $fh);
	} catch Git::Error::Command with {
		# Pepper with the output:
		my $E = shift;
		$E->{'-outputref'} = \$line;
		throw $E;
	};
	return $line;
}


=item command_output_pipe ( COMMAND [, ARGUMENTS... ] )

=item command_output_pipe ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )

Execute the given C<COMMAND> in the same way as command()
does but return a pipe filehandle from which the command output can be
read.

The function can return C<($pipe, $ctx)> in array context.
See C<command_close_pipe()> for details.

=cut

sub command_output_pipe {
	_command_common_pipe('-|', @_);
}


=item command_input_pipe ( COMMAND [, ARGUMENTS... ] )

=item command_input_pipe ( [ COMMAND, ARGUMENTS... ], { Opt => Val ... } )

Execute the given C<COMMAND> in the same way as command_output_pipe()
does but return an input pipe filehandle instead; the command output
is not captured.

The function can return C<($pipe, $ctx)> in array context.
See C<command_close_pipe()> for details.

=cut

sub command_input_pipe {
	_command_common_pipe('|-', @_);
}


=item command_close_pipe ( PIPE [, CTX ] )

Close the C<PIPE> as returned from C<command_*_pipe()>, checking
whether the command finished successfully. The optional C<CTX> argument
is required if you want to see the command name in the error message,
and it is the second value returned by C<command_*_pipe()> when
called in array context. The call idiom is:

	my ($fh, $ctx) = $r->command_output_pipe('status');
	while (<$fh>) { ... }
	$r->command_close_pipe($fh, $ctx);

Note that you should not rely on whatever actually is in C<CTX>;
currently it is simply the command name but in future the context might
have more complicated structure.

=cut

sub command_close_pipe {
	my ($self, $fh, $ctx) = _maybe_self(@_);
	$ctx ||= '<unknown>';
	_cmd_close($ctx, $fh);
}

=item command_bidi_pipe ( COMMAND [, ARGUMENTS... ] )

Execute the given C<COMMAND> in the same way as command_output_pipe()
does but return both an input pipe filehandle and an output pipe filehandle.

The function will return C<($pid, $pipe_in, $pipe_out, $ctx)>.
See C<command_close_bidi_pipe()> for details.

=cut

sub command_bidi_pipe {
	my ($pid, $in, $out);
	my ($self) = _maybe_self(@_);
	local %ENV = %ENV;
	my $cwd_save = undef;
	if ($self) {
		shift;
		require Cwd;
		$cwd_save = Cwd::getcwd();
		_setup_git_cmd_env($self);
	}
	require IPC::Open2;
	$pid = IPC::Open2::open2($in, $out, 'git', @_);
	chdir($cwd_save) if $cwd_save;
	return ($pid, $in, $out, join(' ', @_));
}

=item command_close_bidi_pipe ( PID, PIPE_IN, PIPE_OUT [, CTX] )

Close the C<PIPE_IN> and C<PIPE_OUT> as returned from C<command_bidi_pipe()>,
checking whether the command finished successfully. The optional C<CTX>
argument is required if you want to see the command name in the error message,
and it is the fourth value returned by C<command_bidi_pipe()>.  The call idiom
is:

	my ($pid, $in, $out, $ctx) = $r->command_bidi_pipe('cat-file --batch-check');
	print $out "000000000\n";
	while (<$in>) { ... }
	$r->command_close_bidi_pipe($pid, $in, $out, $ctx);

Note that you should not rely on whatever actually is in C<CTX>;
currently it is simply the command name but in future the context might
have more complicated structure.

C<PIPE_IN> and C<PIPE_OUT> may be C<undef> if they have been closed prior to
calling this function.  This may be useful in a query-response type of
commands where caller first writes a query and later reads response, eg:

	my ($pid, $in, $out, $ctx) = $r->command_bidi_pipe('cat-file --batch-check');
	print $out "000000000\n";
	close $out;
	while (<$in>) { ... }
	$r->command_close_bidi_pipe($pid, $in, undef, $ctx);

This idiom may prevent potential dead locks caused by data sent to the output
pipe not being flushed and thus not reaching the executed command.

=cut

sub command_close_bidi_pipe {
	local $?;
	my ($self, $pid, $in, $out, $ctx) = _maybe_self(@_);
	_cmd_close($ctx, (grep { defined } ($in, $out)));
	waitpid $pid, 0;
	if ($? >> 8) {
		throw Git::Error::Command($ctx, $? >>8);
	}
}


=item command_noisy ( COMMAND [, ARGUMENTS... ] )

Execute the given C<COMMAND> in the same way as command() does but do not
capture the command output - the standard output is not redirected and goes
to the standard output of the caller application.

While the method is called command_noisy(), you might want to as well use
it for the most silent Git commands which you know will never pollute your
stdout but you want to avoid the overhead of the pipe setup when calling them.

The function returns only after the command has finished running.

=cut

sub command_noisy {
	my ($self, $cmd, @args) = _maybe_self(@_);
	_check_valid_cmd($cmd);

	my $pid = fork;
	if (not defined $pid) {
		throw Error::Simple("fork failed: $!");
	} elsif ($pid == 0) {
		_cmd_exec($self, $cmd, @args);
	}
	if (waitpid($pid, 0) > 0 and $?>>8 != 0) {
		throw Git::Error::Command(join(' ', $cmd, @args), $? >> 8);
	}
}


=item version ()

Return the Git version in use.

=cut

sub version {
	my $verstr = command_oneline('--version');
	$verstr =~ s/^git version //;
	$verstr;
}


=item exec_path ()

Return path to the Git sub-command executables (the same as
C<git --exec-path>). Useful mostly only internally.

=cut

sub exec_path { command_oneline('--exec-path') }


=item html_path ()

Return path to the Git html documentation (the same as
C<git --html-path>). Useful mostly only internally.

=cut

sub html_path { command_oneline('--html-path') }


=item get_tz_offset ( TIME )

Return the time zone offset from GMT in the form +/-HHMM where HH is
the number of hours from GMT and MM is the number of minutes.  This is
the equivalent of what strftime("%z", ...) would provide on a GNU
platform.

If TIME is not supplied, the current local time is used.

=cut

sub get_tz_offset {
	# some systems don't handle or mishandle %z, so be creative.
	my $t = shift || time;
	my @t = localtime($t);
	$t[5] += 1900;
	require Time::Local;
	my $gm = Time::Local::timegm(@t);
	my $sign = qw( + + - )[ $gm <=> $t ];
	return sprintf("%s%02d%02d", $sign, (gmtime(abs($t - $gm)))[2,1]);
}

=item get_record ( FILEHANDLE, INPUT_RECORD_SEPARATOR )

Read one record from FILEHANDLE delimited by INPUT_RECORD_SEPARATOR,
removing any trailing INPUT_RECORD_SEPARATOR.

=cut

sub get_record {
	my ($fh, $rs) = @_;
	local $/ = $rs;
	my $rec = <$fh>;
	chomp $rec if defined $rec;
	$rec;
}

=item prompt ( PROMPT , ISPASSWORD  )

Query user C<PROMPT> and return answer from user.

Honours GIT_ASKPASS and SSH_ASKPASS environment variables for querying
the user. If no *_ASKPASS variable is set or an error occurred,
the terminal is tried as a fallback.
If C<ISPASSWORD> is set and true, the terminal disables echo.

=cut

sub prompt {
	my ($prompt, $isPassword) = @_;
	my $ret;
	if (exists $ENV{'GIT_ASKPASS'}) {
		$ret = _prompt($ENV{'GIT_ASKPASS'}, $prompt);
	}
	if (!defined $ret && exists $ENV{'SSH_ASKPASS'}) {
		$ret = _prompt($ENV{'SSH_ASKPASS'}, $prompt);
	}
	if (!defined $ret) {
		print STDERR $prompt;
		STDERR->flush;
		if (defined $isPassword && $isPassword) {
			require Term::ReadKey;
			Term::ReadKey::ReadMode('noecho');
			$ret = '';
			while (defined(my $key = Term::ReadKey::ReadKey(0))) {
				last if $key =~ /[\012\015]/; # \n\r
				$ret .= $key;
			}
			Term::ReadKey::ReadMode('restore');
			print STDERR "\n";
			STDERR->flush;
		} else {
			chomp($ret = <STDIN>);
		}
	}
	return $ret;
}

sub _prompt {
	my ($askpass, $prompt) = @_;
	return unless length $askpass;
	$prompt =~ s/\n/ /g;
	my $ret;
	open my $fh, "-|", $askpass, $prompt or return;
	$ret = <$fh>;
	$ret =~ s/[\015\012]//g; # strip \r\n, chomp does not work on all systems (i.e. windows) as expected
	close ($fh);
	return $ret;
}

=item repo_path ()

Return path to the git repository. Must be called on a repository instance.

=cut

sub repo_path { $_[0]->{opts}->{Repository} }


=item wc_path ()

Return path to the working copy. Must be called on a repository instance.

=cut

sub wc_path { $_[0]->{opts}->{WorkingCopy} }


=item wc_subdir ()

Return path to the subdirectory inside of a working copy. Must be called
on a repository instance.

=cut

sub wc_subdir { $_[0]->{opts}->{WorkingSubdir} ||= '' }


=item wc_chdir ( SUBDIR )

Change the working copy subdirectory to work within. The C<SUBDIR> is
relative to the working copy root directory (not the current subdirectory).
Must be called on a repository instance attached to a working copy
and the directory must exist.

=cut

sub wc_chdir {
	my ($self, $subdir) = @_;
	$self->wc_path()
		or throw Error::Simple("bare repository");

	-d $self->wc_path().'/'.$subdir
		or throw Error::Simple("subdir not found: $subdir $!");
	# Of course we will not "hold" the subdirectory so anyone
	# can delete it now and we will never know. But at least we tried.

	$self->{opts}->{WorkingSubdir} = $subdir;
}


=item config ( VARIABLE )

Retrieve the configuration C<VARIABLE> in the same manner as C<config>
does. In scalar context requires the variable to be set only one time
(exception is thrown otherwise), in array context returns allows the
variable to be set multiple times and returns all the values.

=cut

sub config {
	return _config_common({}, @_);
}


=item config_bool ( VARIABLE )

Retrieve the bool configuration C<VARIABLE>. The return value
is usable as a boolean in perl (and C<undef> if it's not defined,
of course).

=cut

sub config_bool {
	my $val = scalar _config_common({'kind' => '--bool'}, @_);

	# Do not rewrite this as return (defined $val && $val eq 'true')
	# as some callers do care what kind of falsehood they receive.
	if (!defined $val) {
		return undef;
	} else {
		return $val eq 'true';
	}
}


=item config_path ( VARIABLE )

Retrieve the path configuration C<VARIABLE>. The return value
is an expanded path or C<undef> if it's not defined.

=cut

sub config_path {
	return _config_common({'kind' => '--path'}, @_);
}


=item config_int ( VARIABLE )

Retrieve the integer configuration C<VARIABLE>. The return value
is simple decimal number.  An optional value suffix of 'k', 'm',
or 'g' in the config file will cause the value to be multiplied
by 1024, 1048576 (1024^2), or 1073741824 (1024^3) prior to output.
It would return C<undef> if configuration variable is not defined.

=cut

sub config_int {
	return scalar _config_common({'kind' => '--int'}, @_);
}

=item config_regexp ( RE )

Retrieve the list of configuration key names matching the regular
expression C<RE>. The return value is a list of strings matching
this regex.

=cut

sub config_regexp {
	my ($self, $regex) = _maybe_self(@_);
	try {
		my @cmd = ('config', '--name-only', '--get-regexp', $regex);
		unshift @cmd, $self if $self;
		my @matches = command(@cmd);
		return @matches;
	} catch Git::Error::Command with {
		my $E = shift;
		if ($E->value() == 1) {
			my @matches = ();
			return @matches;
		} else {
			throw $E;
		}
	};
}

# Common subroutine to implement bulk of what the config* family of methods
# do. This currently wraps command('config') so it is not so fast.
sub _config_common {
	my ($opts) = shift @_;
	my ($self, $var) = _maybe_self(@_);

	try {
		my @cmd = ('config', $opts->{'kind'} ? $opts->{'kind'} : ());
		unshift @cmd, $self if $self;
		if (wantarray) {
			return command(@cmd, '--get-all', $var);
		} else {
			return command_oneline(@cmd, '--get', $var);
		}
	} catch Git::Error::Command with {
		my $E = shift;
		if ($E->value() == 1) {
			# Key not found.
			return;
		} else {
			throw $E;
		}
	};
}

=item get_colorbool ( NAME )

Finds if color should be used for NAMEd operation from the configuration,
and returns boolean (true for "use color", false for "do not use color").

=cut

sub get_colorbool {
	my ($self, $var) = @_;
	my $stdout_to_tty = (-t STDOUT) ? "true" : "false";
	my $use_color = $self->command_oneline('config', '--get-colorbool',
					       $var, $stdout_to_tty);
	return ($use_color eq 'true');
}

=item get_color ( SLOT, COLOR )

Finds color for SLOT from the configuration, while defaulting to COLOR,
and returns the ANSI color escape sequence:

	print $repo->get_color("color.interactive.prompt", "underline blue white");
	print "some text";
	print $repo->get_color("", "normal");

=cut

sub get_color {
	my ($self, $slot, $default) = @_;
	my $color = $self->command_oneline('config', '--get-color', $slot, $default);
	if (!defined $color) {
		$color = "";
	}
	return $color;
}

=item remote_refs ( REPOSITORY [, GROUPS [, REFGLOBS ] ] )

This function returns a hashref of refs stored in a given remote repository.
The hash is in the format C<refname =\> hash>. For tags, the C<refname> entry
contains the tag object while a C<refname^{}> entry gives the tagged objects.

C<REPOSITORY> has the same meaning as the appropriate C<git-ls-remote>
argument; either a URL or a remote name (if called on a repository instance).
C<GROUPS> is an optional arrayref that can contain 'tags' to return all the
tags and/or 'heads' to return all the heads. C<REFGLOB> is an optional array
of strings containing a shell-like glob to further limit the refs returned in
the hash; the meaning is again the same as the appropriate C<git-ls-remote>
argument.

This function may or may not be called on a repository instance. In the former
case, remote names as defined in the repository are recognized as repository
specifiers.

=cut

sub remote_refs {
	my ($self, $repo, $groups, $refglobs) = _maybe_self(@_);
	my @args;
	if (ref $groups eq 'ARRAY') {
		foreach (@$groups) {
			if ($_ eq 'heads') {
				push (@args, '--heads');
			} elsif ($_ eq 'tags') {
				push (@args, '--tags');
			} else {
				# Ignore unknown groups for future
				# compatibility
			}
		}
	}
	push (@args, $repo);
	if (ref $refglobs eq 'ARRAY') {
		push (@args, @$refglobs);
	}

	my @self = $self ? ($self) : (); # Ultra trickery
	my ($fh, $ctx) = Git::command_output_pipe(@self, 'ls-remote', @args);
	my %refs;
	while (<$fh>) {
		chomp;
		my ($hash, $ref) = split(/\t/, $_, 2);
		$refs{$ref} = $hash;
	}
	Git::command_close_pipe(@self, $fh, $ctx);
	return \%refs;
}


=item ident ( TYPE | IDENTSTR )

=item ident_person ( TYPE | IDENTSTR | IDENTARRAY )

This suite of functions retrieves and parses ident information, as stored
in the commit and tag objects or produced by C<var GIT_type_IDENT> (thus
C<TYPE> can be either I<author> or I<committer>; case is insignificant).

The C<ident> method retrieves the ident information from C<git var>
and either returns it as a scalar string or as an array with the fields parsed.
Alternatively, it can take a prepared ident string (e.g. from the commit
object) and just parse it.

C<ident_person> returns the person part of the ident - name and email;
it can take the same arguments as C<ident> or the array returned by C<ident>.

The synopsis is like:

	my ($name, $email, $time_tz) = ident('author');
	"$name <$email>" eq ident_person('author');
	"$name <$email>" eq ident_person($name);
	$time_tz =~ /^\d+ [+-]\d{4}$/;

=cut

sub ident {
	my ($self, $type) = _maybe_self(@_);
	my $identstr;
	if (lc $type eq lc 'committer' or lc $type eq lc 'author') {
		my @cmd = ('var', 'GIT_'.uc($type).'_IDENT');
		unshift @cmd, $self if $self;
		$identstr = command_oneline(@cmd);
	} else {
		$identstr = $type;
	}
	if (wantarray) {
		return $identstr =~ /^(.*) <(.*)> (\d+ [+-]\d{4})$/;
	} else {
		return $identstr;
	}
}

sub ident_person {
	my ($self, @ident) = _maybe_self(@_);
	$#ident == 0 and @ident = $self ? $self->ident($ident[0]) : ident($ident[0]);
	return "$ident[0] <$ident[1]>";
}

=item hash_object ( TYPE, FILENAME )

Compute the SHA1 object id of the given C<FILENAME> considering it is
of the C<TYPE> object type (C<blob>, C<commit>, C<tree>).

The method can be called without any instance or on a specified Git repository,
it makes zero difference.

The function returns the SHA1 hash.

=cut

# TODO: Support for passing FILEHANDLE instead of FILENAME
sub hash_object {
	my ($self, $type, $file) = _maybe_self(@_);
	command_oneline('hash-object', '-t', $type, $file);
}


=item hash_and_insert_object ( FILENAME )

Compute the SHA1 object id of the given C<FILENAME> and add the object to the
object database.

The function returns the SHA1 hash.

=cut

# TODO: Support for passing FILEHANDLE instead of FILENAME
sub hash_and_insert_object {
	my ($self, $filename) = @_;

	carp "Bad filename \"$filename\"" if $filename =~ /[\r\n]/;

	$self->_open_hash_and_insert_object_if_needed();
	my ($in, $out) = ($self->{hash_object_in}, $self->{hash_object_out});

	unless (print $out $filename, "\n") {
		$self->_close_hash_and_insert_object();
		throw Error::Simple("out pipe went bad");
	}

	chomp(my $hash = <$in>);
	unless (defined($hash)) {
		$self->_close_hash_and_insert_object();
		throw Error::Simple("in pipe went bad");
	}

	return $hash;
}

sub _open_hash_and_insert_object_if_needed {
	my ($self) = @_;

	return if defined($self->{hash_object_pid});

	($self->{hash_object_pid}, $self->{hash_object_in},
	 $self->{hash_object_out}, $self->{hash_object_ctx}) =
		$self->command_bidi_pipe(qw(hash-object -w --stdin-paths --no-filters));
}

sub _close_hash_and_insert_object {
	my ($self) = @_;

	return unless defined($self->{hash_object_pid});

	my @vars = map { 'hash_object_' . $_ } qw(pid in out ctx);

	command_close_bidi_pipe(@$self{@vars});
	delete @$self{@vars};
}

=item cat_blob ( SHA1, FILEHANDLE )

Prints the contents of the blob identified by C<SHA1> to C<FILEHANDLE> and
returns the number of bytes printed.

=cut

sub cat_blob {
	my ($self, $sha1, $fh) = @_;

	$self->_open_cat_blob_if_needed();
	my ($in, $out) = ($self->{cat_blob_in}, $self->{cat_blob_out});

	unless (print $out $sha1, "\n") {
		$self->_close_cat_blob();
		throw Error::Simple("out pipe went bad");
	}

	my $description = <$in>;
	if ($description =~ / missing$/) {
		carp "$sha1 doesn't exist in the repository";
		return -1;
	}

	if ($description !~ /^[0-9a-fA-F]{40}(?:[0-9a-fA-F]{24})? \S+ (\d+)$/) {
		carp "Unexpected result returned from git cat-file";
		return -1;
	}

	my $size = $1;

	my $blob;
	my $bytesLeft = $size;

	while (1) {
		last unless $bytesLeft;

		my $bytesToRead = $bytesLeft < 1024 ? $bytesLeft : 1024;
		my $read = read($in, $blob, $bytesToRead);
		unless (defined($read)) {
			$self->_close_cat_blob();
			throw Error::Simple("in pipe went bad");
		}
		unless (print $fh $blob) {
			$self->_close_cat_blob();
			throw Error::Simple("couldn't write to passed in filehandle");
		}
		$bytesLeft -= $read;
	}

	# Skip past the trailing newline.
	my $newline;
	my $read = read($in, $newline, 1);
	unless (defined($read)) {
		$self->_close_cat_blob();
		throw Error::Simple("in pipe went bad");
	}
	unless ($read == 1 && $newline eq "\n") {
		$self->_close_cat_blob();
		throw Error::Simple("didn't find newline after blob");
	}

	return $size;
}

sub _open_cat_blob_if_needed {
	my ($self) = @_;

	return if defined($self->{cat_blob_pid});

	($self->{cat_blob_pid}, $self->{cat_blob_in},
	 $self->{cat_blob_out}, $self->{cat_blob_ctx}) =
		$self->command_bidi_pipe(qw(cat-file --batch));
}

sub _close_cat_blob {
	my ($self) = @_;

	return unless defined($self->{cat_blob_pid});

	my @vars = map { 'cat_blob_' . $_ } qw(pid in out ctx);

	command_close_bidi_pipe(@$self{@vars});
	delete @$self{@vars};
}


=item credential_read( FILEHANDLE )

Reads credential key-value pairs from C<FILEHANDLE>.  Reading stops at EOF or
when an empty line is encountered.  Each line must be of the form C<key=value>
with a non-empty key.  Function returns hash with all read values.  Any white
space (other than new-line character) is preserved.

=cut

sub credential_read {
	my ($self, $reader) = _maybe_self(@_);
	my %credential;
	while (<$reader>) {
		chomp;
		if ($_ eq '') {
			last;
		} elsif (!/^([^=]+)=(.*)$/) {
			throw Error::Simple("unable to parse git credential data:\n$_");
		}
		$credential{$1} = $2;
	}
	return %credential;
}

=item credential_write( FILEHANDLE, CREDENTIAL_HASHREF )

Writes credential key-value pairs from hash referenced by
C<CREDENTIAL_HASHREF> to C<FILEHANDLE>.  Keys and values cannot contain
new-lines or NUL bytes characters, and key cannot contain equal signs nor be
empty (if they do Error::Simple is thrown).  Any white space is preserved.  If
value for a key is C<undef>, it will be skipped.

If C<'url'> key exists it will be written first.  (All the other key-value
pairs are written in sorted order but you should not depend on that).  Once
all lines are written, an empty line is printed.

=cut

sub credential_write {
	my ($self, $writer, $credential) = _maybe_self(@_);
	my ($key, $value);

	# Check if $credential is valid prior to writing anything
	while (($key, $value) = each %$credential) {
		if (!defined $key || !length $key) {
			throw Error::Simple("credential key empty or undefined");
		} elsif ($key =~ /[=\n\0]/) {
			throw Error::Simple("credential key contains invalid characters: $key");
		} elsif (defined $value && $value =~ /[\n\0]/) {
			throw Error::Simple("credential value for key=$key contains invalid characters: $value");
		}
	}

	for $key (sort {
		# url overwrites other fields, so it must come first
		return -1 if $a eq 'url';
		return  1 if $b eq 'url';
		return $a cmp $b;
	} keys %$credential) {
		if (defined $credential->{$key}) {
			print $writer $key, '=', $credential->{$key}, "\n";
		}
	}
	print $writer "\n";
}

sub _credential_run {
	my ($self, $credential, $op) = _maybe_self(@_);
	my ($pid, $reader, $writer, $ctx) = command_bidi_pipe('credential', $op);

	credential_write $writer, $credential;
	close $writer;

	if ($op eq "fill") {
		%$credential = credential_read $reader;
	}
	if (<$reader>) {
		throw Error::Simple("unexpected output from git credential $op response:\n$_\n");
	}

	command_close_bidi_pipe($pid, $reader, undef, $ctx);
}

=item credential( CREDENTIAL_HASHREF [, OPERATION ] )

=item credential( CREDENTIAL_HASHREF, CODE )

Executes C<git credential> for a given set of credentials and specified
operation.  In both forms C<CREDENTIAL_HASHREF> needs to be a reference to
a hash which stores credentials.  Under certain conditions the hash can
change.

In the first form, C<OPERATION> can be C<'fill'>, C<'approve'> or C<'reject'>,
and function will execute corresponding C<git credential> sub-command.  If
it's omitted C<'fill'> is assumed.  In case of C<'fill'> the values stored in
C<CREDENTIAL_HASHREF> will be changed to the ones returned by the C<git
credential fill> command.  The usual usage would look something like:

	my %cred = (
		'protocol' => 'https',
		'host' => 'example.com',
		'username' => 'bob'
	);
	Git::credential \%cred;
	if (try_to_authenticate($cred{'username'}, $cred{'password'})) {
		Git::credential \%cred, 'approve';
		... do more stuff ...
	} else {
		Git::credential \%cred, 'reject';
	}

In the second form, C<CODE> needs to be a reference to a subroutine.  The
function will execute C<git credential fill> to fill the provided credential
hash, then call C<CODE> with C<CREDENTIAL_HASHREF> as the sole argument.  If
C<CODE>'s return value is defined, the function will execute C<git credential
approve> (if return value yields true) or C<git credential reject> (if return
value is false).  If the return value is undef, nothing at all is executed;
this is useful, for example, if the credential could neither be verified nor
rejected due to an unrelated network error.  The return value is the same as
what C<CODE> returns.  With this form, the usage might look as follows:

	if (Git::credential {
		'protocol' => 'https',
		'host' => 'example.com',
		'username' => 'bob'
	}, sub {
		my $cred = shift;
		return !!try_to_authenticate($cred->{'username'},
		                             $cred->{'password'});
	}) {
		... do more stuff ...
	}

=cut

sub credential {
	my ($self, $credential, $op_or_code) = (_maybe_self(@_), 'fill');

	if ('CODE' eq ref $op_or_code) {
		_credential_run $credential, 'fill';
		my $ret = $op_or_code->($credential);
		if (defined $ret) {
			_credential_run $credential, $ret ? 'approve' : 'reject';
		}
		return $ret;
	} else {
		_credential_run $credential, $op_or_code;
	}
}

{ # %TEMP_* Lexical Context

my (%TEMP_FILEMAP, %TEMP_FILES);

=item temp_acquire ( NAME )

Attempts to retrieve the temporary file mapped to the string C<NAME>. If an
associated temp file has not been created this session or was closed, it is
created, cached, and set for autoflush and binmode.

Internally locks the file mapped to C<NAME>. This lock must be released with
C<temp_release()> when the temp file is no longer needed. Subsequent attempts
to retrieve temporary files mapped to the same C<NAME> while still locked will
cause an error. This locking mechanism provides a weak guarantee and is not
threadsafe. It does provide some error checking to help prevent temp file refs
writing over one another.

In general, the L<File::Handle> returned should not be closed by consumers as
it defeats the purpose of this caching mechanism. If you need to close the temp
file handle, then you should use L<File::Temp> or another temp file faculty
directly. If a handle is closed and then requested again, then a warning will
issue.

=cut

sub temp_acquire {
	my $temp_fd = _temp_cache(@_);

	$TEMP_FILES{$temp_fd}{locked} = 1;
	$temp_fd;
}

=item temp_is_locked ( NAME )

Returns true if the internal lock created by a previous C<temp_acquire()>
call with C<NAME> is still in effect.

When temp_acquire is called on a C<NAME>, it internally locks the temporary
file mapped to C<NAME>.  That lock will not be released until C<temp_release()>
is called with either the original C<NAME> or the L<File::Handle> that was
returned from the original call to temp_acquire.

Subsequent attempts to call C<temp_acquire()> with the same C<NAME> will fail
unless there has been an intervening C<temp_release()> call for that C<NAME>
(or its corresponding L<File::Handle> that was returned by the original
C<temp_acquire()> call).

If true is returned by C<temp_is_locked()> for a C<NAME>, an attempt to
C<temp_acquire()> the same C<NAME> will cause an error unless
C<temp_release> is first called on that C<NAME> (or its corresponding
L<File::Handle> that was returned by the original C<temp_acquire()> call).

=cut

sub temp_is_locked {
	my ($self, $name) = _maybe_self(@_);
	my $temp_fd = \$TEMP_FILEMAP{$name};

	defined $$temp_fd && $$temp_fd->opened && $TEMP_FILES{$$temp_fd}{locked};
}

=item temp_release ( NAME )

=item temp_release ( FILEHANDLE )

Releases a lock acquired through C<temp_acquire()>. Can be called either with
the C<NAME> mapping used when acquiring the temp file or with the C<FILEHANDLE>
referencing a locked temp file.

Warns if an attempt is made to release a file that is not locked.

The temp file will be truncated before being released. This can help to reduce
disk I/O where the system is smart enough to detect the truncation while data
is in the output buffers. Beware that after the temp file is released and
truncated, any operations on that file may fail miserably until it is
re-acquired. All contents are lost between each release and acquire mapped to
the same string.

=cut

sub temp_release {
	my ($self, $temp_fd, $trunc) = _maybe_self(@_);

	if (exists $TEMP_FILEMAP{$temp_fd}) {
		$temp_fd = $TEMP_FILES{$temp_fd};
	}
	unless ($TEMP_FILES{$temp_fd}{locked}) {
		carp "Attempt to release temp file '",
			$temp_fd, "' that has not been locked";
	}
	temp_reset($temp_fd) if $trunc and $temp_fd->opened;

	$TEMP_FILES{$temp_fd}{locked} = 0;
	undef;
}

sub _temp_cache {
	my ($self, $name) = _maybe_self(@_);

	my $temp_fd = \$TEMP_FILEMAP{$name};
	if (defined $$temp_fd and $$temp_fd->opened) {
		if ($TEMP_FILES{$$temp_fd}{locked}) {
			throw Error::Simple("Temp file with moniker '" .
				$name . "' already in use");
		}
	} else {
		if (defined $$temp_fd) {
			# then we're here because of a closed handle.
			carp "Temp file '", $name,
				"' was closed. Opening replacement.";
		}
		my $fname;

		my $tmpdir;
		if (defined $self) {
			$tmpdir = $self->repo_path();
		}

		my $n = $name;
		$n =~ s/\W/_/g; # no strange chars

		require File::Temp;
		($$temp_fd, $fname) = File::Temp::tempfile(
			"Git_${n}_XXXXXX", UNLINK => 1, DIR => $tmpdir,
			) or throw Error::Simple("couldn't open new temp file");

		$$temp_fd->autoflush;
		binmode $$temp_fd;
		$TEMP_FILES{$$temp_fd}{fname} = $fname;
	}
	$$temp_fd;
}

=item temp_reset ( FILEHANDLE )

Truncates and resets the position of the C<FILEHANDLE>.

=cut

sub temp_reset {
	my ($self, $temp_fd) = _maybe_self(@_);

	truncate $temp_fd, 0
		or throw Error::Simple("couldn't truncate file");
	sysseek($temp_fd, 0, Fcntl::SEEK_SET()) and seek($temp_fd, 0, Fcntl::SEEK_SET())
		or throw Error::Simple("couldn't seek to beginning of file");
	sysseek($temp_fd, 0, Fcntl::SEEK_CUR()) == 0 and tell($temp_fd) == 0
		or throw Error::Simple("expected file position to be reset");
}

=item temp_path ( NAME )

=item temp_path ( FILEHANDLE )

Returns the filename associated with the given tempfile.

=cut

sub temp_path {
	my ($self, $temp_fd) = _maybe_self(@_);

	if (exists $TEMP_FILEMAP{$temp_fd}) {
		$temp_fd = $TEMP_FILEMAP{$temp_fd};
	}
	$TEMP_FILES{$temp_fd}{fname};
}

sub END {
	unlink values %TEMP_FILEMAP if %TEMP_FILEMAP;
}

} # %TEMP_* Lexical Context

=item prefix_lines ( PREFIX, STRING [, STRING... ])

Prefixes lines in C<STRING> with C<PREFIX>.

=cut

sub prefix_lines {
	my $prefix = shift;
	my $string = join("\n", @_);
	$string =~ s/^/$prefix/mg;
	return $string;
}

=item unquote_path ( PATH )

Unquote a quoted path containing c-escapes as returned by ls-files etc.
when not using -z or when parsing the output of diff -u.

=cut

{
	my %cquote_map = (
		"a" => chr(7),
		"b" => chr(8),
		"t" => chr(9),
		"n" => chr(10),
		"v" => chr(11),
		"f" => chr(12),
		"r" => chr(13),
		"\\" => "\\",
		"\042" => "\042",
	);

	sub unquote_path {
		local ($_) = @_;
		my ($retval, $remainder);
		if (!/^\042(.*)\042$/) {
			return $_;
		}
		($_, $retval) = ($1, "");
		while (/^([^\\]*)\\(.*)$/) {
			$remainder = $2;
			$retval .= $1;
			for ($remainder) {
				if (/^([0-3][0-7][0-7])(.*)$/) {
					$retval .= chr(oct($1));
					$_ = $2;
					last;
				}
				if (/^([\\\042abtnvfr])(.*)$/) {
					$retval .= $cquote_map{$1};
					$_ = $2;
					last;
				}
				# This is malformed
				throw Error::Simple("invalid quoted path $_[0]");
			}
			$_ = $remainder;
		}
		$retval .= $_;
		return $retval;
	}
}

=item get_comment_line_char ( )

Gets the core.commentchar configuration value.
The value falls-back to '#' if core.commentchar is set to 'auto'.

=cut

sub get_comment_line_char {
	my $comment_line_char = config("core.commentchar") || '#';
	$comment_line_char = '#' if ($comment_line_char eq 'auto');
	$comment_line_char = '#' if (length($comment_line_char) != 1);
	return $comment_line_char;
}

=item comment_lines ( STRING [, STRING... ])

Comments lines following core.commentchar configuration.

=cut

sub comment_lines {
	my $comment_line_char = get_comment_line_char;
	return prefix_lines("$comment_line_char ", @_);
}

=back

=head1 ERROR HANDLING

All functions are supposed to throw Perl exceptions in case of errors.
See the L<Error> module on how to catch those. Most exceptions are mere
L<Error::Simple> instances.

However, the C<command()>, C<command_oneline()> and C<command_noisy()>
functions suite can throw C<Git::Error::Command> exceptions as well: those are
thrown when the external command returns an error code and contain the error
code as well as access to the captured command's output. The exception class
provides the usual C<stringify> and C<value> (command's exit code) methods and
in addition also a C<cmd_output> method that returns either an array or a
string with the captured command output (depending on the original function
call context; C<command_noisy()> returns C<undef>) and $<cmdline> which
returns the command and its arguments (but without proper quoting).

Note that the C<command_*_pipe()> functions cannot throw this exception since
it has no idea whether the command failed or not. You will only find out
at the time you C<close> the pipe; if you want to have that automated,
use C<command_close_pipe()>, which can throw the exception.

=cut

{
	package Git::Error::Command;

	@Git::Error::Command::ISA = qw(Error);

	sub new {
		my $self = shift;
		my $cmdline = '' . shift;
		my $value = 0 + shift;
		my $outputref = shift;
		my(@args) = ();

		local $Error::Depth = $Error::Depth + 1;

		push(@args, '-cmdline', $cmdline);
		push(@args, '-value', $value);
		push(@args, '-outputref', $outputref);

		$self->SUPER::new(-text => 'command returned error', @args);
	}

	sub stringify {
		my $self = shift;
		my $text = $self->SUPER::stringify;
		$self->cmdline() . ': ' . $text . ': ' . $self->value() . "\n";
	}

	sub cmdline {
		my $self = shift;
		$self->{'-cmdline'};
	}

	sub cmd_output {
		my $self = shift;
		my $ref = $self->{'-outputref'};
		defined $ref or undef;
		if (ref $ref eq 'ARRAY') {
			return @$ref;
		} else { # SCALAR
			return $$ref;
		}
	}
}

=over 4

=item git_cmd_try { CODE } ERRMSG

This magical statement will automatically catch any C<Git::Error::Command>
exceptions thrown by C<CODE> and make your program die with C<ERRMSG>
on its lips; the message will have %s substituted for the command line
and %d for the exit status. This statement is useful mostly for producing
more user-friendly error messages.

In case of no exception caught the statement returns C<CODE>'s return value.

Note that this is the only auto-exported function.

=cut

sub git_cmd_try(&$) {
	my ($code, $errmsg) = @_;
	my @result;
	my $err;
	my $array = wantarray;
	try {
		if ($array) {
			@result = &$code;
		} else {
			$result[0] = &$code;
		}
	} catch Git::Error::Command with {
		my $E = shift;
		$err = $errmsg;
		$err =~ s/\%s/$E->cmdline()/ge;
		$err =~ s/\%d/$E->value()/ge;
		# We can't croak here since Error.pm would mangle
		# that to Error::Simple.
	};
	$err and croak $err;
	return $array ? @result : $result[0];
}


=back

=head1 COPYRIGHT

Copyright 2006 by Petr Baudis E<lt>pasky@suse.czE<gt>.

This module is free software; it may be used, copied, modified
and distributed under the terms of the GNU General Public Licence,
either version 2, or (at your option) any later version.

=cut


# Take raw method argument list and return ($obj, @args) in case
# the method was called upon an instance and (undef, @args) if
# it was called directly.
sub _maybe_self {
	UNIVERSAL::isa($_[0], 'Git') ? @_ : (undef, @_);
}

# Check if the command id is something reasonable.
sub _check_valid_cmd {
	my ($cmd) = @_;
	$cmd =~ /^[a-z0-9A-Z_-]+$/ or throw Error::Simple("bad command: $cmd");
}

# Common backend for the pipe creators.
sub _command_common_pipe {
	my $direction = shift;
	my ($self, @p) = _maybe_self(@_);
	my (%opts, $cmd, @args);
	if (ref $p[0]) {
		($cmd, @args) = @{shift @p};
		%opts = ref $p[0] ? %{$p[0]} : @p;
	} else {
		($cmd, @args) = @p;
	}
	_check_valid_cmd($cmd);

	my $fh;
	if ($^O eq 'MSWin32') {
		# ActiveState Perl
		#defined $opts{STDERR} and
		#	warn 'ignoring STDERR option - running w/ ActiveState';
		$direction eq '-|' or
			die 'input pipe for ActiveState not implemented';
		# the strange construction with *ACPIPE is just to
		# explain the tie below that we want to bind to
		# a handle class, not scalar. It is not known if
		# it is something specific to ActiveState Perl or
		# just a Perl quirk.
		tie (*ACPIPE, 'Git::activestate_pipe', $cmd, @args);
		$fh = *ACPIPE;

	} else {
		my $pid = open($fh, $direction);
		if (not defined $pid) {
			throw Error::Simple("open failed: $!");
		} elsif ($pid == 0) {
			if ($opts{STDERR}) {
				open (STDERR, '>&', $opts{STDERR})
					or die "dup failed: $!";
			} elsif (defined $opts{STDERR}) {
				open (STDERR, '>', '/dev/null')
					or die "opening /dev/null failed: $!";
			}
			_cmd_exec($self, $cmd, @args);
		}
	}
	return wantarray ? ($fh, join(' ', $cmd, @args)) : $fh;
}

# When already in the subprocess, set up the appropriate state
# for the given repository and execute the git command.
sub _cmd_exec {
	my ($self, @args) = @_;
	_setup_git_cmd_env($self);
	_execv_git_cmd(@args);
	die qq[exec "@args" failed: $!];
}

# set up the appropriate state for git command
sub _setup_git_cmd_env {
	my $self = shift;
	if ($self) {
		$self->repo_path() and $ENV{'GIT_DIR'} = $self->repo_path();
		$self->repo_path() and $self->wc_path()
			and $ENV{'GIT_WORK_TREE'} = $self->wc_path();
		$self->wc_path() and chdir($self->wc_path());
		$self->wc_subdir() and chdir($self->wc_subdir());
	}
}

# Execute the given Git command ($_[0]) with arguments ($_[1..])
# by searching for it at proper places.
sub _execv_git_cmd { exec('git', @_); }

sub _is_sig {
	my ($v, $n) = @_;

	# We are avoiding a "use POSIX qw(SIGPIPE SIGABRT)" in the hot
	# Git.pm codepath.
	require POSIX;
	no strict 'refs';
	$v == *{"POSIX::$n"}->();
}

# Close pipe to a subprocess.
sub _cmd_close {
	my $ctx = shift @_;
	foreach my $fh (@_) {
		if (close $fh) {
			# nop
		} elsif ($!) {
			# It's just close, no point in fatalities
			carp "error closing pipe: $!";
		} elsif ($? >> 8) {
			# The caller should pepper this.
			throw Git::Error::Command($ctx, $? >> 8);
		} elsif ($? & 127 && _is_sig($? & 127, "SIGPIPE")) {
			# we might e.g. closed a live stream; the command
			# dying of SIGPIPE would drive us here.
		} elsif ($? & 127 && _is_sig($? & 127, "SIGABRT")) {
			die sprintf('BUG?: got SIGABRT ($? = %d, $? & 127 = %d) when closing pipe',
				    $?, $? & 127);
		} elsif ($? & 127) {
			die sprintf('got signal ($? = %d, $? & 127 = %d) when closing pipe',
				    $?, $? & 127);
		}
	}
}


sub DESTROY {
	my ($self) = @_;
	$self->_close_hash_and_insert_object();
	$self->_close_cat_blob();
}


# Pipe implementation for ActiveState Perl.

package Git::activestate_pipe;

sub TIEHANDLE {
	my ($class, @params) = @_;
	# FIXME: This is probably horrible idea and the thing will explode
	# at the moment you give it arguments that require some quoting,
	# but I have no ActiveState clue... --pasky
	# Let's just hope ActiveState Perl does at least the quoting
	# correctly.
	my @data = qx{git @params};
	bless { i => 0, data => \@data }, $class;
}

sub READLINE {
	my $self = shift;
	if ($self->{i} >= scalar @{$self->{data}}) {
		return undef;
	}
	my $i = $self->{i};
	if (wantarray) {
		$self->{i} = $#{$self->{'data'}} + 1;
		return splice(@{$self->{'data'}}, $i);
	}
	$self->{i} = $i + 1;
	return $self->{'data'}->[ $i ];
}

sub CLOSE {
	my $self = shift;
	delete $self->{data};
	delete $self->{i};
}

sub EOF {
	my $self = shift;
	return ($self->{i} >= scalar @{$self->{data}});
}


1; # Famous last words
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Package: gnupg-utils
Status: install reinstreq unpacked
Priority: optional
Section: utils
Installed-Size: 1836
Maintainer: Debian GnuPG Maintainers <pkg-gnupg-maint@lists.alioth.debian.org>
Architecture: amd64
Multi-Arch: foreign
Source: gnupg2
Version: 2.2.40-1.1+deb12u1
Replaces: gnupg (<< 2.1.21-4), gnupg-agent (<< 2.1.21-4)
Depends: libassuan0 (>= 2.5.0), libbz2-1.0, libc6 (>= 2.34), libgcrypt20 (>= 1.10.0), libgpg-error0 (>= 1.42), libksba8 (>= 1.3.5), libreadline8 (>= 6.0), zlib1g (>= 1:1.1.4)
Recommends: gpg, gpg-agent, gpgconf, gpgsm
Breaks: gnupg (<< 2.1.21-4), gnupg-agent (<< 2.1.21-4)
Description: GNU privacy guard - utility programs
 GnuPG is GNU's tool for secure communication and data storage.
 .
 This package contains several useful utilities for manipulating
 OpenPGP data and other related cryptographic elements.  It includes:
 .
  * addgnupghome -- create .gnupg home directories
  * applygnupgdefaults -- run gpgconf --apply-defaults for all users
  * gpgcompose -- an experimental tool for constructing arbitrary
                  sequences of OpenPGP packets (e.g. for testing)
  * gpgparsemail -- parse an e-mail message into annotated format
  * gpgsplit -- split a sequence of OpenPGP packets into files
  * gpgtar -- encrypt or sign files in an archive
  * kbxutil -- list, export, import Keybox data
  * lspgpot -- convert PGP ownertrust values to GnuPG
  * migrate-pubring-from-classic-gpg -- use only "modern" formats
  * symcryptrun -- use simple symmetric encryption tool in GnuPG framework
  * watchgnupg -- watch socket-based logs
Homepage: https://www.gnupg.org/
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         Package: gnupg-utils
Status: install ok unpacked
Priority: optional
Section: utils
Installed-Size: 1836
Maintainer: Debian GnuPG Maintainers <pkg-gnupg-maint@lists.alioth.debian.org>
Architecture: amd64
Multi-Arch: foreign
Source: gnupg2
Version: 2.2.40-1.1+deb12u1
Replaces: gnupg (<< 2.1.21-4), gnupg-agent (<< 2.1.21-4)
Depends: libassuan0 (>= 2.5.0), libbz2-1.0, libc6 (>= 2.34), libgcrypt20 (>= 1.10.0), libgpg-error0 (>= 1.42), libksba8 (>= 1.3.5), libreadline8 (>= 6.0), zlib1g (>= 1:1.1.4)
Recommends: gpg, gpg-agent, gpgconf, gpgsm
Breaks: gnupg (<< 2.1.21-4), gnupg-agent (<< 2.1.21-4)
Description: GNU privacy guard - utility programs
 GnuPG is GNU's tool for secure communication and data storage.
 .
 This package contains several useful utilities for manipulating
 OpenPGP data and other related cryptographic elements.  It includes:
 .
  * addgnupghome -- create .gnupg home directories
  * applygnupgdefaults -- run gpgconf --apply-defaults for all users
  * gpgcompose -- an experimental tool for constructing arbitrary
                  sequences of OpenPGP packets (e.g. for testing)
  * gpgparsemail -- parse an e-mail message into annotated format
  * gpgsplit -- split a sequence of OpenPGP packets into files
  * gpgtar -- encrypt or sign files in an archive
  * kbxutil -- list, export, import Keybox data
  * lspgpot -- convert PGP ownertrust values to GnuPG
  * migrate-pubring-from-classic-gpg -- use only "modern" formats
  * symcryptrun -- use simple symmetric encryption tool in GnuPG framework
  * watchgnupg -- watch socket-based logs
Homepage: https://www.gnupg.org/
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                f1445cb83237fafa43a7f68e3ae84444  usr/bin/gpg
6b9684184004bcc1c23f712e7a057733  usr/share/doc/gpg/NEWS.Debian.gz
b3341ed1b34fecd0d9713d614918af3d  usr/share/doc/gpg/changelog.Debian.gz
a0f5ed1ea32f61695d73b5994cbfea2f  usr/share/doc/gpg/changelog.gz
804812f818f3adf1ce87b47311b32bf0  usr/share/doc/gpg/copyright
d06671bc58b0ea3e723e0bfa2252b562  usr/share/man/man1/gpg.1.gz
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Package: gpg
Source: gnupg2
Version: 2.2.40-1.1+deb12u1
Architecture: amd64
Maintainer: Debian GnuPG Maintainers <pkg-gnupg-maint@lists.alioth.debian.org>
Installed-Size: 1581
Depends: gpgconf (= 2.2.40-1.1+deb12u1), libassuan0 (>= 2.5.0), libbz2-1.0, libc6 (>= 2.34), libgcrypt20 (>= 1.10.0), libgpg-error0 (>= 1.42), libreadline8 (>= 6.0), libsqlite3-0 (>= 3.7.15), zlib1g (>= 1:1.1.4)
Recommends: gnupg (= 2.2.40-1.1+deb12u1)
Breaks: gnupg (<< 2.1.21-4)
Replaces: gnupg (<< 2.1.21-4)
Section: utils
Priority: optional
Multi-Arch: foreign
Homepage: https://www.gnupg.org/
Description: GNU Privacy Guard -- minimalist public key operations
 GnuPG is GNU's tool for secure communication and data storage.
 It can be used to encrypt data and to create digital signatures.
 It includes an advanced key management facility and is compliant
 with the proposed OpenPGP Internet standard as described in RFC4880.
 .
 This package contains /usr/bin/gpg itself, and is useful on its own
 only for public key operations (encryption, signature verification,
 listing OpenPGP certificates, etc).  If you want full capabilities
 (including secret key operations, network access, etc), please
 install the "gnupg" package, which pulls in the full suite of tools.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Package: gpg
Status: install reinstreq half-installed
Priority: optional
Section: utils
Architecture: amd64
Multi-Arch: foreign
Version: 2.2.40-1.1+deb12u1
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         TMo8WridKi6whwhEi3-ā)U߾CqZ6 	͛857H&D$?#JJ}>`>5p۬R@5=
ɋB3DAF1a-|YC&Pg#_[1P cA[3pE2kwE@hĈnOz0a+ 10
?pİ]!_sU(O!ZoBO;y9
өQLXKJ+h[x<jmlJ\ŸȍO I/ ]OTexX3t#i&{;68xp߳zwt@_E,Kgd$1n_bɵ,).wx} <	ӄӠ-ˤFy4g2(,W;6B1qwa^njи6̠G1o]t1D2IYr?g$Kr2Vs6if(bL4h_?xdBLVh'#mS;6oufQ}NCS-%-!`WK}	~_%X:(b-m^5˰bgS>i=%{Vp3BY0eئZ32p?쩏JYyH_9x5'q۴TߦzGi@=S,[Űy{ G0󑏿$/EBQGðM"hyEԝgn[Ow\o/GqD0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           Yks_tb-x|Nǎ,ǘN2N;YKbK`D1.HAd&Lf,"y{MY8cӌ-	d)f+UҨ5e)="0X*˒L),F\
1Wn
]Ҝ,<*v醮]â?=<&$fkh٨%?0.thfvq
眊>%|^݀\R3G	y_
3LPT9	$Ø~NpN?zgipL,XKᕔ?ظ
I}Zq%rLDoxEܡ<k+}蹍k8茊ޞ׊i2a;zpN0" )BlX猰,`n
v ;M e N(tJma]c\9/9S9;^VRդ+p^FRqddyXʔP0Yd\b,jvxIgyKsAEQbl~:ϥҬUaYvN`im Hy2Z%hp`{u2k<1nLehтG$Lx[3?G,"܄ժ \D:vN	Y5$Oxkrf\#9Nha;LrmmfI'6&eůfix#p,(e} 9gÒ	8ʴeBMY'À	IRmZ0MAKO0+ŭ43&~Q\ [i:y4zDJP[?qaLݗR!
YbO%eK b[i0p|"3MXE&;p	g.
9q|*ӎ>KO}P:GR4W3В ()G
XF@r[cY2@}VV[V9 lMPiVW4z?*h0e[Ot7o@f
#cTT9A1Xњ'ߕQ0Eb9h\YuAXJ\㲹Q*~EǀJ7!6 "MFT}5Gtu҄+4^m7 Uj"ɳxǋ4K'_B@"*wdS#7x<}5afPӍ͜Ed%sZHs4*i1krfiqH@q)8CF8I٦v.eS;+l\`$+d(٩w:$b-8_醶ޟb&M1uvUmu.%`oK3`0{>2%O>k^BlTAdLh(W&ltEpkN|2"ܙmy/H,$zJV5+8v5j	Ng[b4t`&P߿t~Ha
jbH^I#[iFASbd*q%2-߈ePj
fGǐf;캺5kj^iТH:jBGvAd!]:ds!ém}"ɭۣ13]Y|z=5¡X؏+pJŮN;'˖q+:o6űq<2ύ+
,7L<T
%w.6QI\,z YBBA%{m7WS
r,	><PqypbDѾGQ ꉎعunĆUS ߈+(a<gdp2;Cn>U-_퐏bZW&ۥ+O-\)ln&3ue-r{_Xi7&0p0?H?5}I@\IY+l罴iw➜kyQ<89Lkݚ-,u0u܊w2@qQ876v]+z ,r2Z8Iso
q;
NZ['>n{uq`y%~
zܖ-l,qf&4%att{sR3-2-)eF|Lo֚R!f
{r]նFL764ڼ\ZAʴ$z%AHMuI $
2ѪS e1uѦ2px>]6
?xYTue"
ؠ%; /ZX-zL;qn_TkU{5;Z}`6傹P/-_Q}]=6ua۶_׉y?'5\-<p2:ɦ[ݎ[JyU4/C<<}ܦ"܃_-t+ƽF偠xU獏NNyJ 	vt0zɵlq.p1vs|REf6̂o<8.eyZz?bid652&n*eR4ɯdƶf֘ mUk߇tbv+HӰ65u9?C/evq'5X$XºS%ڽN-Ŏ+2*:
M8<"27
FڊZ!CL,o^p"3W|8Vu+OG4                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: GnuPG - The GNU Privacy Guard (modern version)
Upstream-Contact: GnuPG development mailing list <gnupg-devel@gnupg.org>
Source: https://gnupg.org/download/

Files: *
Copyright: 1992, 1995-2020, Free Software Foundation, Inc
License: GPL-3+

Files: agent/command.c
 agent/command-ssh.c
 agent/gpg-agent.c
 common/homedir.c
 common/sysutils.c
 g10/mainproc.c
Copyright: 1998-2007, 2009, 2012, Free Software Foundation, Inc
  2013, Werner Koch
License: GPL-3+

Files: autogen.sh
Copyright: 2003, g10 Code GmbH
License: permissive

Files: common/gc-opt-flags.h
 common/i18n.h
 tools/clean-sat.c
 tools/no-libgcrypt.c
Copyright: 1998-2001, 2003, 2004, 2006, 2007 Free Software Foundation, Inc
License: permissive

Files: common/localename.c
Copyright: 1985, 1989-1993, 1995-2003, 2007, 2008 Free Software Foundation, Inc.
License: LGPL-2.1+

Files: dirmngr/dns.c
 dirmngr/dns.h
Copyright: 2008-2010, 2012-2016 William Ahern
License: Expat

Files: doc/yat2m.c
 scd/app-geldkarte.c
Copyright: 2004, 2005, g10 Code GmbH
  2006, 2008, 2009, 2011, Free Software Foundation, Inc
License: GPL-3+

Files: scd/ccid-driver.h
 scd/ccid-driver.c
Copyright: 2003-2007, Free Software Foundation, Inc
License: GPL-3+ or BSD-3-clause

Files: tools/rfc822parse.c
 tools/rfc822parse.h
Copyright: 1999-2000, Werner Koch, Duesseldorf
  2003-2004, g10 Code GmbH
License: LGPL-3+

Files: tools/sockprox.c
Copyright: 2007, g10 Code GmbH
License: GPL-3+

Files: doc/OpenPGP
Copyright: 1998-2013 Free Software Foundation, Inc.
           1997, 1998, 2013 Werner Koch
           1998 The Internet Society
License: RFC-Reference

Files: tests/gpgscm/*
Copyright: 2000, Dimitrios Souflis
           2016, Justus Winter, Werner Koch
License: TinySCHEME

Files: debian/*
Copyright: 1998-2022 Debian GnuPG packagers, including
 Eric Dorland <eric@debian.org>
 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
 NIIBE Yutaka <gniibe@fsij.org>
License: GPL-3+

Files: debian/org.gnupg.scdaemon.metainfo.xml
Copyright: 2017 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
Comment: This file is licensed permissively for the sake of AppStream
License: CC0-1.0

License: TinySCHEME
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
 .
 Redistributions of source code must retain the above copyright notice,
 this list of conditions and the following disclaimer.
 .
 Redistributions in binary form must reproduce the above copyright
 notice, this list of conditions and the following disclaimer in the
 documentation and/or other materials provided with the distribution.
 .
 Neither the name of Dimitrios Souflis nor the names of the
 contributors may be used to endorse or promote products derived from
 this software without specific prior written permission.
 .
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


License: permissive
 This file is free software; as a special exception the author gives
 unlimited permission to copy and/or distribute it, with or without
 modifications, as long as this notice is preserved.
 .
 This file is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY, to the extent permitted by law; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.

License: RFC-Reference
 doc/OpenPGP merely cites and references IETF Draft
 draft-ietf-openpgp-formats-07.txt. This is believed to be fair use;
 but if not, it's covered by the source document's license under
 the 'comment on' clause. The license statement follows.
 .
 This document and translations of it may be copied and furnished to
 others, and derivative works that comment on or otherwise explain it
 or assist in its implementation may be prepared, copied, published
 and distributed, in whole or in part, without restriction of any
 kind, provided that the above copyright notice and this paragraph
 are included on all such copies and derivative works.  However, this
 document itself may not be modified in any way, such as by removing
 the copyright notice or references to the Internet Society or other
 Internet organizations, except as needed for the purpose of
 developing Internet standards in which case the procedures for
 copyrights defined in the Internet Standards process must be
 followed, or as required to translate it into languages other than
 English.
 .
 The limited permissions granted above are perpetual and will not be
 revoked by the Internet Society or its successors or assigns.


License: GPL-3+
 GnuPG 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 3 of the License, or
 (at your option) any later version.
 .
 GnuPG 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; if not, see <https://www.gnu.org/licenses/>.
 .
 On Debian systems, the full text of the GNU General Public
 License version 3 can be found in the file
 `/usr/share/common-licenses/GPL-3'.

License: LGPL-3+
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser 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
 Lesser General Public License for more details.
 .
 You should have received a copy of the GNU Lesser General Public
 License along with this program; if not, see <https://www.gnu.org/licenses/>.
 .
 On Debian systems, the full text of the GNU Lesser General Public
 License version 3 can be found in the file
 `/usr/share/common-licenses/LGPL-3'.

License: LGPL-2.1+
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as
 published by the Free Software Foundation; either version 2.1 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
 Lesser General Public License for more details.
 .
 You should have received a copy of the GNU Lesser General Public
 License along with this program; if not, see <https://www.gnu.org/licenses/>.
 .
 On Debian systems, the full text of the GNU Lesser General Public
 License version 2.1 can be found in the file
 `/usr/share/common-licenses/LGPL-2.1'.

License: BSD-3-clause
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
    notice, and the entire permission notice in its entirety,
    including the disclaimer of warranties.
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
 3. The name of the author may not be used to endorse or promote
    products derived from this software without specific prior
    written permission.
 .
 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 OF THE POSSIBILITY OF SUCH DAMAGE.

License: Expat
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to permit
 persons to whom the Software is furnished to do so, subject to the
 following conditions:
 .
 The above copyright notice and this permission notice shall be included
 in all copies or substantial portions of the Software.
 .
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 USE OR OTHER DEALINGS IN THE SOFTWARE.

License: CC0-1.0
 To the extent possible under law, the author(s) have dedicated all
 copyright and related and neighboring rights to this software to the public
 domain worldwide. This software is distributed without any warranty.
 .
 On Debian systems, the complete text of the CC0 license, version 1.0,
 can be found in /usr/share/common-licenses/CC0-1.0.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ɑ& d]TVO'dUHnfRjU-1 2C	D@&Q*͚8kr$33w@ Rg͞{Q1_gGȻb-z]jYgmmE6e{L?M/ɾ~u {xj?{8}8d|:{ٔo.z7jdO=sG}?^l/7MWUW-ʺ^᱋?ųW?dO\bQ6nz*~0hwrUs|Agzo>G/~rvG/_eeuE&o^avy9F'4rQ^_]:4	mѼ-Em[um1bߖ~)fUtEvS2?XUGm|Bogjmeۭcz"+myǛ"ϖ[ؕ4Sw]^MȺڿEb`
]nwn7l]/JfeuU7ew.w6kY᧳XMS,\_[S]vYU]~3FdU-fuV:K8ү38u޹Tv٢1gj:..r
o3?˓/]gwèS<owP\YZl+?X*oN>~ju~~]Oh⺰[˯Bݴc/߃U~9јO,3AXSߴ?}4e3|~'c<rYα}-iwߵ7U}zUs~ܬ(*4g^ۭ Y35
Mt8~U5,4_=?m0tmMΛrMYAd۶25EJ+ D_
%CjnT;
M/w?¹}yvU/bl;i|>,LUc-[Rw^R[?ύ_[*t:+\wnQ+U]{90}L-'&OHhBGv=gƐ^ztξ+*`jzUT^s[Ut,ܘ:3Jkw㗒$_+sAH 8۬؝e勷eVE*)jBu/.ΏX]horcN'O۬av_eo٫F%jb"V~l?O?zrqS& mF$ΏlA/"3p[Df{Cǔ~(vՙo %F^^vyp+6[-]/36UAoX~ p-N:6>u
w״PDF8UmC	ɼ^h?dFieHd}12s|GkEAK;eU!7uO.Oϟ]V3*=TJĸ0Bzj~}{N:f<|5zn&Æ6仜T?+gM%{F3aY?(𝛵]pr7E(?<{٫G/D蚒ޑ}5wlD;q
k9߮f,i$O? ɤ_|s:CaG|H=ߦt_osQtoWm95]}+n.um=w{hB;|uKt'Y
Ʃ_2]*7?K/6_`rx>f^:וLs4;3Vrh7zT+7Da_?IQ}o~y"kZxQ肶erqZv;kq+2%u6Z?y]W1)G:83'kh?2pTKlӖ1oCxi;N/=&69f?>l5/mIbE:%	r'.mEjԫ*ʿn-+>zՎ:<^6KQC'u/nI`YuF͘jWLE0&8:(*(5*ߙơ˼AT/.x2_>)]m4}%َ
vF`Zͷe
VVNi?zt;	'ɶ}FdQFRi;OfV,,m^GS.ܮK2`¦!
%VE5 Zdlz	ju<V
4@:^B9R,y}N.0R*UJñVl#/jqEa*NrWJ2=CBBқ+<|ŖmpCa0e:ʃw]%G٪qc`Eg^WM{Ɇzxh~85ﮦ}_s!ُbSfu[oEk"-"Z~]S5/\=D:W&M-&}_
%3 ɬɀ&Ywm$]gx5.V^sWAN{?ٔ?eB{_nWlp]!6fVz)>9w]۫k}ZC
Ŏ5/q2W|v23(v	K6m!/t	D_xr1>}?Vż'3Z^2ocz>.R8Hv^^!8
P^0O~sA	sAXΑ[ݿ5ϢXKu`~yE$Fٮ x'$}4	.'L|k8r$Ͼ%JAW38	>Rjg4.Ұsiɽ@ȫmHٟT?CFw]$xo
{#L%d*SW2Rŋ7nPa@eh,ZE2t=A},ܙluIy- p}]<#xNEP4|wDi{|,4^B4@ee&]ԯ,IV4$<)VQv>vڲnc7@UbSw)Z2&\AlHme9&yZK{7$wNzﻱ>zNǛSVZM}kF/1"uHcU"-{Uӆ􃘠}gohlVQEnKwAWњEzrudðڐK1c<Dl#?aM9D&W\޲%/?7_/mmV8؊kkH$[eѺ:auo] 2|{P%I(jc#K"10deM{6xq.ˆ<NUwcO?>f9SkʻG=_d@[v\<au2*i.Y?*yxh.$WۢN\McL#[fԔ)Lθa
]uIB!Z{;-hd'烙a%$/k[n~-z$8JVG07^u*zk}pN	F5"`XvziiK!YI $]Iڏ6.(@ ;wF
uQKYͤe-_7xٰMͦ=:&Οl
kb|eDo%淢8yԧ[F~\gY*[>yG'3V"[]Khh+eۺ\>~,.
eVPEqk
;`?%rl!d	¬oIP,\ AȾEW9Wk9`w
(ڈ M}[I<m2_%v:nSXz(67>|+$ee*)^~odVMֻcx8iWHD^ޔ\AN.ߚQx3)h*6o]n}!xh(|=ckr+3ӖunkԝS8Lj!sH&̬&hS9Fux_5|gtR傭oѼ.Ç1C[7ėjY^]`5I@X"Ń0iDQshp
<(xQeh$8SW;D8\.Ԃ)y2~"88b[-\4>l*],;y؞KƼjבzW-A0&jpjZv. X;]#k	mYg87z-z)ׄG>0Kz3a[%~o٤Ni-~fGcj&0k~)*.<lv)o&QYǪ~պyVPs~Ǜ@8&rrf-1&y߇@ѵw8z_⣥K*1F7ǹoGQ<bWHU~77<:h])'XYd[;Q{cQx=A{;ZRzvIp49pEor_|4l	Sz8809:}+b b(EmP0	^Ż{+#C0r4u~|8Ш/Lʊo!,eS`.%`bQ2ę`ћI֪XG8Ƙ{3v=#ɃjIng:M0"_gg#C'OͿ-$Kyg_ʅ'ݑHA?UU㌨Zll~ׯ^ald Kkf 赥KK1rhɟؔMOYsϊ?Eztɝ{poV-	Siώ35hw8#JTZn Eȝ8 }Y&o
04F$\i0j $Q
t:*Gt8E~%v5Zfwp^SO @GR	A+:섫pMD.`۪.FKAݡH"stawaJ0qu{wh=π-YkT*nMqݛ[2{%N0:!)*4M2
Mq+M)TvPQ

	#m=yMwepV^AEsy!6	+~qxLeXk""
V7<TFq/RmE&בܙ+VVxJ]/̒FZ=6I0R(6ޢ=6N Q	L-.(vא>u64+X9C°˦ٷ䂥)n =׶~Φ37>Ym9/aX&-;D@K(ǮgDAQ[7j?hߺ䐄BR[yAP6\Rb"Tg~}ƜYg/ϝȚC%	՞R]u?,A_XR<q=.e2ǬQ_<zYmᓭL,\;i&-}?H>9­B"UI)vlYl8X>cw/wujZ7W5Y"]N =̤awYpӐ39Pi'2y9yyi2GX""T#l1AºmvhDs3U&nL["̃SMk[wC{В8qKEA
w=4]K=@4	Ż*_kv}!(K¾:|
;>{/z33zjЈoM߶7
qojhz/^F9E8^>ɑ}xK#ˍГ]XPvVO"epqgmGy3#	9{`ݸ"?,CKه%w^r?{{eu6L6G(E{/qE|o2h! m߳SA5;Q݁ܗ8h1/)HD>۫mW	5NݖQΙ!
NX'О.,e.V(JUS7SqÄ@-bEVެldr$
; U{F*%eh:/=FS2VSԪ6L.'@Ppl5.OT$7h^؜HFcFD5'	]$ŗo}2D
]\)Cde8r)>RY83`8N3?HDXYgۻZ]:Vv{[yOGZx/tgڝ|Cnm]!DS0v&%2 +î5eO}d;9DT8#@S72Zk8*VxdA:rBʥsImWMSB\14uU˙;!4%Lnqd68wV2rULPI+[T3PW!恌F5;Tv3:,蒼4ٙQW7$}+xA〨WCn`(%15t%xB䛭j:$rk7lr;QPX%]SwEz(= ]dWG{ic#!>7$S} aR@;@fpo@bG2L#PBvjU\;ߥȷ1A-"Jb
1uNER3::am%Ͼ˖^O뢹*l^mKdN--NoXn%LWaN9i-cn~'F eԄq0$jH77"7L)ux3X'H
q5o&U:.> 
+1b'!2ygb>|wE"OT:)$s`^>M+3L:q*Ba'?fߪ7ymضC/%vd
|m}.9DVV11yl	DNЅ1))Bt7x9f뺜iQB$2fDOlKsz),](UUE/Էj	OE=Z	c[?-'g54!m?U$ā0 tP+ׯ[v6}[9m2#dd/0 F ¨)3pQsP\^gO8iJxpӌo.?!!E0N?JR`Pb
HzEWsCS턒iHRfr%wi%j\k[6ԪurJQ}StrIA%Gy(kUY/A"k	*ZVUoQUc(C&* ^.;")v,w
Y%.GhWtlz5@EIZ9HEP=g8< hAAskGOem%ΫiJ\!qbQ4r+,K"Ps҄WDkIo-&!uQ+UqqULE*SCX=<
!C{>:aC23`Q"1	Xcɏ"Q4o oPs:=oYLTMV8NMtySY3G|ę2b8&xQ>\	ˠ>
o}5%y
d>&\઻b7"MK3~馯.eݴZ:
(7/ mw^_3}klLqM@(Jn #a֟$
W&#DWxtR0YRpAB"!>3@%KȘٙ	6F{Wh)BfV
DMKŌSf[ǚT
vz2v4ׇ#t]T^#MrebL	4Knu;&kRm!V	N4 db\4!w9]ϣw$yF<Ru[=׶ھdi~WE5iO~zH}Q*
l]vL~?uE?:cKOJw!;ۂx%S~,z̙	fA!uN%Jg|i8B54EbOLXCpg/^%ϗ=mfJ-ЊV+Q3f^~(MqahĿO?9^x8{MTr11m=ٗc$ep1M-dVQzM2{Q'/oExфgh'(8bB\341ue:34.]$2-$_dfVi_H~VH.i/~J_3<)勧'T%h22Y'6-J/қ+KˢZFCHWh-talQ`?_^MJK
9jT.ćjŧL ?vE%c
TtЈ5P%@10ʷP?`dh4z%}	@\ 8:ɑGA{n@~6"yޒjW@^(V{p"TWAR X|#]m#3Y^dp޼y\Sm[{\VEq[h5h[pfD0Yajl89Ö3JMN_jrxN3"A4~szCy͒l;!G
Y;ohOo0$~x>L
Qǥ4G/r&a!YrCnڙa2GYW;_ [p=A~	Zz9|.
]hld
36|nƟ|'u{
0V1x.ۼ}wmQusoF
B~y7?_ok/|4'ZLp*%3?}̈́`Fn37eBim%vЛ7rط-!ZiQ7T_6eEjnW
Yn!SrUPqSzW
'k96يBnQcBkFe+@2O
.:ݻd"1c4U|5>ʥQ8-),w $,*lEb AdICIypspVy$ZR=xxm|Hi
q ]XkBuRr>:*)Py
]a,sDVU[\Taho.Hxa-[9܈Db]tEc%qz%gE?UU%7~KR~[FDU+fQ<Emx	H>bd2:m*DQuSج4M8үnLޣ%Nf|9Ȍ	e`HlW.af1u#1Dti"eJ"Vt⒌.^"V{b\ҽF :n<=A.plz c^)Ӧ&ǀpEbiq#|
gZɁn+iZ(4H[Xmy+It1}Pc&EA[޼iڜX]??a4?~{xCV|^]BW`Ƨ?93X@G!L?{Ğ5QJM2o疵v܉Bdb	p5mdSU^U`	;$N[`2f}S)PB7b*	I@gep
:ۄq6e_n)'HB7˳ؤd
\뒖 B>fN8vܦ*Z헾iXyA/r=MV}'ÞGwW<G\Hj
YC؆g&N3^F/~}jRm򲱬=lFu@xm4zJ$s_*:
y;](ڔ5Ժ1w)-EI)IicZ4oW!P
6Es5ud!$kun#
:$vt:߼yi@t^?o]WQ6ޚ%4[c~oPc3hX8ftyr%,2c[a;ijg͡n5{Lc
)!J-=3Z:R8QێC6ux{ u1*	M]Y;)ޥ|Gv؉B7{Lǘ
6  '(2n (Ф.x:h@9J~	uU_M?ZBɤпg[%N)"UEM޽ckw Y!pTMѬ˶MjQ4f[R&bZ.~>ɸ^9O!bq	LĈS xY1r!rI+Mg#r[@D"_Q$3Iu
w?|9
ﴙ)"~$
J<oI	{d,[r/ ߌlenvEbN24:[N-5u8[x:P6"LUv7qR`Ar2ߋAxɭxߦ4|_Bb()ySe,Pk"06f|#͹?ЫbaR,ߖM]IZlbCߛ^&0á7vqA~롦is	W(Qb1EH"GtUfVJJmЁɮzi!X<Oa՟8z߼y%#8{6KQe>|'SƘċjĬ{{٪F~,!pF|Y9o@TDB=]E6_r%cC)42[ATܛ&B@48ϵzVnks9.~ZsS"}hf[<(䨜Sm!)JE5W)?sOwD?>^?Z!ډx=(tCӦ '$+yGы_mGCKFOzdT]W3	Z1<j~zy5뚠ҎY*/BCqI`/
ngE=ATcB(
aorh:pe9lZ\eY
=3[٬~BsDlT2S-	qG}QҘQ}ߘ1sO)}:aM;$%Z~AwD^F
)2}|	5L(z
^+ PK⛓|C2DBk׸zDAJ!v=&^:ب}́êbm2p #1*81\^%
n0X8hCu]Ս] Y
isQH~Q.lz%RW?Q&̆p5I
cSARC`
cBF#7ڶɱ9:\\+-m3ΑAD:pޚ'`sRՆu+6en
3i%lڗԗokw`'_ƥkW[.a$'T~م;t2#Nu35L\:Y\zjc+wǃ
`b02 T`Ax&شdSql,7umzw:4-W^GzޖK)7#|/|+Yµ_ׁͅZ *ʼ9#VAVE3;?ޖ]vHXQ4M\5pΣb`EzΜs_;4;#̛
Q!,Dg3YP19
{-/CԐ&P!Ǒ#v$'li'"9A	uW)]լgϯiDl;-j._SjVrAIBlԏA`EL<Y5$V=rzߙy7Z	23.hƙ:	,Qja[W5:l0n ٫/^>:v~oߜi^zo/BD5$O`A\$%z6Kj\X(M^tIl^iX]	X
j7FTX	}ZCJ[GsvYypbr3)`!a4&u\f|)ԳH٘F4(4jFt(Wܘ]i.5D]ԟ55y13ם^LTIA%lw`nCZJ h-F~6r'WPUņۥO#$)
'Ήѕ\N9,(5`R#+
!j*MERiAes\|N6dڽ9*7".}i{` 49]x\ّÞO<t܅6e!*A;<=sqM?bfB־Naqri\7!TѽZ,$']WP6b06b"ȸ7Ca+aSC,f\UvDlN
!TaUr1®O7J$E/W	F,6ZF^h4G5"3qtr]	&5h20
"g"&@*J{d~r2!^v
YzgTPd˭6~q^uzr[/f,
Mt>PVBc-S-o#"	qǆ`}&htNPy!;%qNx[P%wy0DFѮ~Rn7:#@PV,V'#/KlkZv0Խҫ}.2ǂ!ܒ.GϘ!{:oL'P%Uq[0Ri$?0vu8K1 P:)JytIc$icw8db3t:Eh7y#
?:@|$LgqY`BG[;.OMX^s*NA
ŢlXƯDx !'kU݃ˆkdYMIL	hm;y*7d("bN\#(l.XB/4#n6nFwMT[aN2ð_۲ВȈ|+3/ũ)Ea~IYtmN~EݩYN
ΞXTLL$Te!C(	 LjcA8 ?ᧁkw{;V BkA3<4y#OW{IA EѳɵImgථ_0H-T4-
AyR{W]5 h:nrrb'ByKTlrۄK4^^!("mX &Ȍ!P:
Ϳ\R'Vd3YilR?sK"IʅL{Ash@&ySweC6b?dh๒; p{sh; [A2z8S{5eL?KM5wY%l%QOy&؂@czhUn;l0sԆ1AbQMi HRagޏie4
@X~P(ݠtL*
g\GCOA({ LRQ"g	̀ `ECy16iX+ΊE(%(B43cQmI /^_>|]c 8Ւ^ˬU3&ӁI&]-ۛj jh`P.tXqF"? NEy"{i2A)Q0ԓ{%/fh}Z>&vL85!ZR_WΟ,Mʗ7uWo:_ikkx_%I	{څ*P	/\Ij܏1zBR
ޓǒjz0²-|POo;.^|:O7b	Kqsvc(-:
]l
`-hA|lE,]@ct Kc9N7O܀|:!!Z{w^wUa"Ϙ\.c,ĸmL rsCELф:,LbYn8(|dڷɆњ@(QEn!آڦir斏/yeEUmnq;S& !F¿o//_<p.8Nt䓒4Pͬߖdijz9-h67iO͌tpδP)}"
&GRa:DXtF`JR&ٷ2GfO(r\xu#(F,$څȆ3П!CkdvthP&PmS	HE>cca*XKBKʑ1zgxW	y"Oĸ޴Vν\5h Gn#m|_93aKBk.DYVEq1f&;V/e|1o-8/XtN I*=27aؖd)BĽuj,L&p`K,vLҥ&F3g	
=XUVlBX>
&Mb5g#JNwZW0B<@4'"mM.ۖPQ Sr: tA8&çpbU;^W/\&VuB s$+TNZgN>MZy֤+ w{B
B(ovس;66xȬtМƾ]R'hLѥ&c
;.؈ F{K=y;BUs5{wʑLxpF%j.g"`?s$e?ԲҀnifUdAfNgU2S6B		b/s@5\
&BagXu!*/8*9!#],
n@i^\H
"uT4p2I[XR<wѵ;cE1;411=E~];k?via!PЖk3f<N* 	W{[QY[] z./uDEPcͱE^#i)"f͛
b,2UAQǮhiz5hBohU6m䉘Tq#;=xfKX):mP;"kHtE!rWcaqm7o`M[GƜB^ zzj(U 6Kso	S -d
	}Rdb
!O oy΋;8/,
uZS;Abx^v<BGlKOOޖbID:ΐ/]p΅DaoCux5$H2cwk*zяD?I@2`<ZjuP*T!
G2IHA&ƙ3?D>+>xL$ )}Vl%e!(ɐZ_=#>akBSP.q-}S})eiXK?WCYSJu`8Q$	ڧj7'm("ɉ>
rۊ|V!
dcCCo0@dԆ)ŵmp\#.VSr	c{ջ;B\Mn왴>^_c~MᵚsI]_,3Iх AډXjMw\ڄ@K.<	dxloXYO\TrFO݃Sڟ9p,7d=p`radUTAưlb\>SB8|_k_iBot/TVw~dP؇ުSp$B4dzp #20}aO}ϼJ{`ӸtdP.8b\;wl`"mZp p[4`ԐQL妎6l{
lM>YvӺ3F G4`4HS"K"ɕ'БXEHEJ(nvGWt̋z>kЍz<z|+vy]Hm1f۫TZ"lPYHiu?s挡eEeRO& ؒ.Ԗ&I6ՙ7cM/"+hҴedr+(^f!P"M/1x 	(BLlxBB`;jI4嚀qpzNxv^FG]mX(,ow:Ш[aq~KEʇq]%{:\68RX(B~Uhx-{ڿ>m߻'?E	B4S=Ĩ~{/taR(Yc'
Ӄ=_
IuR:[Y1(&a|D'}T"E׻MWvꠈW^V6f
]'^.8PfNJ@
G7#q{;6~9~Yzvҷ]|.֤\a)GoϿ=c1yӦ裷AR; n,KbC@	^~H8-<zP%~H9BԺ[H~QIwGRwuJ;N7Z(n%lE0?/uUKΧݪ<o68ĔM2﵎w1TR*#yġG?*9 ɟO
yLߕՂx~˙ ,>99៩qk{xayk)wA!@<[Lb^R"%
_>e2xJM"FWL*d7cS
8iu)iY)ݒS=Qyߖ2{C%T-ޡWdߗLz_''	id*})jEX*te[?@.<Vה 0+P]ʥ`]ey2?WeZh?cɛ]^߼+2^X4D|pQVrq-<ȎkqO_?kʟbڛI1\}׉$t$<7l@k4o1 kUۆB@'z<'9Z`G@ 
M8oɕs-DVܮ_U俗H
x;SyHZib"b:G;j]8p&:xS
徝}KdY&8@߂7Xk{7=2zu5|aWq2M?,
&߿{xa\uݒeͮy97Q\ "`%4J~.\DqGu6|{LہL+Cy%|ǯ^v~#}o->>)b2I#Qd2/$ZOC%CQlsЈeq~
W_RE;PmۑcuS,{eh.t1B[_⛦KBR+{+0qӹ纕Eλ;`#wxIs8$M_z+^Z#js(^Km.%ϕ$z*Iv!14%KW/^\ާqcd2ܟS=\]X^EQa1/f4!*6L<bё)gJjg|m$H'\@Aw-Ѣ6|V_PCȅh4E#g$I~MFm.#4;n J!@C:5|BfEɨu/DuB<e[O>/&3BBdٸH=<&#!ec7oï^\j&</콺햓ݣY!DvRНy}qb>͜b/o%.,H[i\@R۾@gʼ*iݩCtC6T*@e
0mo4oc2@Ք I;{`~ >@Y<AI̱ӕސ ݿJ%1V/+.]ǐKKY&/+(A|SJep-_7w8^2 :&0EL|h<蚝u(E7m4UmcgT4S_^[v~P&k~Bo+$Am/>&%Ň
Voeт8ݦ!{)h:?vX?QQ(~,7qCZzJU<%g$L;S㪜@QT=GN#k->L7,Q> Wq1A\8%t$=DL,*הE#]k(A1FÀg5e8Fpe'{P	\rl],9i|R( #xaӻW*DpfG]wBH#	~)긕ܼl5ɉVn)JݵRA;-u;QBSRH,V+!	qj,(/=zƼ
gHvtS84E%]}2%G[GKHbT*
Nu| y{,'sc,_gRv'%Qu@_OkM
=)wO;LdB0!Qz!	8Ot^'sCƒKǒ=ܐ?տRD\/v~C3_>c%>&ܡ=o$V'$2#vGj~d"[U-Zf
%k:5lįG	nglj M59Ŧ-fdԏy&AXֵ^Ȝi,
v
\jVw%v6Dǽ(y[6:WHB݋AQҜmx )usEupVq18z
R*Ȉh+яc=+AݟYjJ]#kb'y`UcY!,e"OX/Trh|Fd=U_:}lKTaP93:jX/([##M3M{vX'рHڻ,Qw3,kRSZe(pC׀CA
?|(%))fk	47{B)af|o
.|NȒ^FW,4 BHÄE#a	a9v<x? p
B4@4(6}5" ;7Fyʦ<T̻J%nsʞ=9}ibp3q7c!hŀF^-Y	el6?⛙-_Sv,'0! nC&y_æ{wŌ&JVe MbT&1A,ԋHDAYmt5 i>wMJ<L[/^<}-~QeO"O1| K,pˤ`ɔH5OޥaxEp%
Bd6oXwNz׫^*)(&qߏA:-m*YW#q79YsяKBV)"m)[:Pϼ4_EJv(8ΝbqKy[1(r%<EtI ĥ~=$e&hZ ,]Q'j
;ڍ$oqZ#s]SlɁEF8t ZNoG1bx4I!'ϴiF\-%/?HŦ-	$B?d+]j5lQ-˙LD	 D탕'&HmMjKJpmBDItrr,o5ߙpJ.2+[VH$ˁ]&Rߦx뻔NĮ@.:ע.>V!Zwy"" 	#7dޒꗄDo&y$&4I۵!rb|
BQk
݄.jgYלnw
[yw]~ :br]1ncE#Tmy	!
'K0SQB!i<	α.gdiWD5t0rfXsM
.$
bY5G
5caL/AM{[QJg%+L#OEv1|&<,^cL6s(b~Fݱ: @{-cS
1}BtTT}?;-ӕdԹ
+:{G(ȝ$$28  d8vq\:px	P<Έ{el8/οh̓Q%֛_|
'9z bxlNО/Ai(-KȈDv3vaoԚ7*\u+wzN
P),T%fg<W
	vOصhS:p1ǝLKE#!z%%kve[miaI898i^9l%)D׃)H-<E]PX֡-D
+8-~\m^IBjJL.BoH@h	\mmͮdZCzkeqb
3=.nJ}L'A"-V804LNB=v~]1Ht ZTmaU`/9LBag%3p &1)Y~ 
\ }lQ9[,YKkp80p$
ނ&q2	r&BD;&NFC']*fX@
S
;B!|H NXٮ4OR=`JR*17gjRhmT 
DvĀ<d_NHZGKZЪ~
ΐz4Gr9iْTc;N>gIAY"]2\&Y!z6遀L83%-oiԌ@H7HB`<X6Zr
9aRǷ7Ѵ#An8}E8E	%8'y|=7y,}/|Mʢ[NA9Y9tڽ@?UIRz^$"߸סE។LF&Cٺwk{]* F=o$WW#몤vPSG,~y>$v,<:[:={/N1ϑ"aqR6c4F7&*i8K|<&#L<SǱ2Y?RyeZ?HjP59Ck"fgqG2yy$e4 ŋuuL4X 4493_s7F zڸ̺Ŵ$Jc+%	$mrD+Mj1B2d0	};9Ft756X#)/FX/`R@zʧ!$)F8gI
ОqvZt@֎Ǳ:%Ԝ$;főƇAV3<'aTL]#H\Ui(i;YbFK0\"HAX$CL1: )S[m42,Y{L)ȬerV,8TX:puyq«{@ս99ۋ=<hqj]*A#3SɛHnEԁl$(ҫӕ_H?kh6 I:Pm y	Z0ʖn!Vf{$+%-PGE2Mt,Xh/{zuh0}V[9d!bLjv=}ܤYnRb0% #82[/q}[?[q$+@{2B8qXk
HgAhO8w#rc/(pI~1wo)TBqvt׉ۍ{*E[&$#DBp5N'꓁((Y$[CJUW|*Q"QAHs"wkF1,j1]!>;ߡ9B]C> j䶕q
MNgEJsG0?l&ϘKX)Mf;a
4RFmQ1r*!"=e{Vbhǿ\L'Xp?0AzDR0l450b+hE1:_13Қ_&=~c!!sCMSgCIdrrPGnRR\+Bg>j(Op
S:D`
|P ?䮵O .e''?da;C՗=!&|iD(bՓlŐIiD5e}ծb8<s`GI H
W:Fu6K #St[q#tXF3}Jq}^KgB
ׯοto8!~/ȕ+K7ٌ!˗ґ,;"FИȱ&Mկ&7Ku$)k!x!;ۺ0]5njeC\T2&ڎ"1SN,v54,:JYqHVHb4f 2Ww}%iBq7Q;sل	pR;2a<g-6 '{Nu:%_jinmG6I;JN>8bM<j*ųV&Kq?uuec@؀\4E0Ay8t/oCPspuG$frKPP-ql %2w\<]cfWyK=TV
$NѶ
LI?7fj[OdBUT2˦ٰk6iص'
<=a2+rt)ѡVd*1HCk֨Ge_I;\wK	tC$|+ؐ@KtJc0wA:N.A)tQ%+cK1Hlt4m"nHrɴwl
I{Jw<̻lTt:Mf	mN^3LyPiklL
C(l|jn߶9@n`Dvz΄=I%^	&+6n34ZN^~s2S"Dz%jVl<)q{Dی]-	K6WVw;V$T4jǮwGS
%aXcd9ȼ]!)s+ci^r5A.|'M?U0i!I7sM>q';޺o8ɐڇf!aAp4O|S5,K_LVھI
wu='DjLCo4Ӹb¾&45q~M#$OBT}9.,_a/u>Ya+!ք0b2МdǄ3d"$ 5
#{ܯ~O=7v"ŮGKdaq!FDN O	P~gj٫̵sqC܏ذ(́Mr/JnG
o$:nhH2ޛ,9H(<r,pT4 ABU/?zy 9C$5=ۛЄh]H
#c!4v.]Hhp}Wp/1!DZ4rt%cinuD~DS3<Ơ~}ˍ?5^I8\I	X&oST\8Qga2%`]ΩGXSsސӦUZmsVVYw<$Y!$XqzD4/~&%"pFE )uzaZtP
B+2~
2W;EFԕ[Cn2N`eG1[[Ai
3ĵ%ިK!Q	I.9(:lAT5*u*bOA'`[^tu8C|Wn֕+emmWP;Ju*CUC8֥ 3ՖX؂|O逈YЄ]KSzdznCkUFR@s><+$+[9잤@B;u9kzh9Mi@zU_(WS }+I蜽Ȑ_OTϹ`"0S7IȄP/XWOhaOr㮲{m5dEȵ-`z;CZi9*YnX;Xp"gdXlΗzN5E~cY[M6DU'S'"ſwJW
m}V>)ȁ'.C:1Y2eW56'u*M++rfW;j]
Rd>#Hۼ!zn;EI?y>y0>HzONCTfh2U|5Q.*'GD@xH߀:ODVQ> SF5:ieUva8}pKR ^{X`aC(CtK?-<Ԁ TqU  䇦,2b?DcgoMIXh^iZg?!~r\Hǔp577A`{!*PM!mD)x)G|P!ܐ!z3<3{.6N:iJso1QB+Er˔
3%S籫:=wr!ˣ.=`0&,8K:V}aҀ),m*0/I"s&Y:$Ûߜ :.;jmt@ǮLT%LYc!PCE}^y1^V-sI$+޺rZLYN6L'Ŀ3ǡ~.-Kٳ92
ϫ	ÒF(
E˱+ͶdGB6D?
ȅY*98tUU6E,-F h8P6Znd] <B3GB<4`@Y(gLlV
1}i$~֍0>X^
id#
LĒUL_XB
mFTQDqT췅(etrtt..2`zL,)la5T˽*ἤsDl]U=jQ-qRPDFL﵃z?',~4:u_RQ0
vꃂ2əbnN9q"{y
_`EtM$jlN64(e3g999^p~CQHfKYVaîd)(@e.Gp 0P% C<^ץ`k$I'«%T#y;5PmeuT9Mh՗,@)$^Q#R&HK`ù?*F$+|ʒZ[I`M=bnO)v&/^ŢS]uM8ݹ&to7C;3KJvsyϕy$R@[3
N+qB"3X)-DmѺpMoX
^ ~޺h_	5xɚRҖe8P>I6@2AihiLIv[1M	Q1f`ev6%	O)`PaI`Pb2hl8DxfaUMCL6<ws!ƚX)9UAלky[SV9"Pm)
Jf#
сX8'	V<#^Ut\.aZMPE칐hfV+4Ami&H!%t; 8XuSMx֤DY-%a6E<*%IWsHRp_Z|_JDh'NB&rV'Z͢8[([IH4;Sbp4Dr GGoǨ,z;SBٰCN-h4uB@C
mi\O܅W sG
uHV 84z%<]5+` jq}Jz'bD ,*-xE>ږ]Y1LzKm0d1S3AaQ c^ t6&>"e#XAirZL-Y@Dw˽$uOo4Jڞev,uyYgۆA=nƱg?Yn@AfԤNT0>v͉B<VXQ/H/mm)7{o9'[ ̔1CS;s썐< $˓e!B/1ʆ2c04	aИ;=\X6h+#WEv %29E=n&_keT
3&IHޫ,uZpl<wk;}xe;^P7^>
;S^<>?mѫʴu1bSTD/"Kk~%)4qxٯWÇDä{TdC>T}5`9GaCѳ]'vRpSm\(L@hC65{ՑCnwD
n.!V:pY%
oJ&C!ܪƠݞK6T0[):e1n9cS/NƌNp +zi5zf$yi?r`޳<ҟZjD̩Bzw(sWN*
DkIPðPl[
϶dB
Xe] 
@D,lxW/~uvqqe[PJ7o:b?00Sc'ɬX~愷(M&'Yab*)N}c6uc|SpPH%2[E5A\ǒ	~=PB{{LѺ$0\
&sYsNuq'К~&w悢28G9	t~=k
;۾*lG(?O;m8J qTz9+}>:4u6.r8Ė8eHl3J#%A(r)0&GR_.IjYm{rUD_\`cE*E8ńPVrD§0$eD,qr\#
A+"Vأq1p"'>k29\Kj
٠T.g} %62.͙΄b/zdLa`>jɄՒ/5\mN0h@ϤWly\S`o"l,]S-t:}9=uK3o
ĎPk+JSe@XI9R9.dӽN'A?Fo^HuSEo-	WpYzuz"oZ7Jؙp]ڀ8oL4!3u|!
%xl7FXQ;Gy^Nɵ ^mKvaDaaeAWF'nnrSWB>$]
2=`)sP&|DW>Cfz}ٗD&KI'{ZIjQvd v92c6dES|_.G_4%v[`Qq.}SZxC[u&y6g-}=k.ЈzH<)TbQ-u5Kﾃ&SX|
ZcD9NCd\N"sňr=mCq ܭ=q^,BϿvWO(}5꜁G.UL!i3rQ%RKތ	9lBBb(E [[/6tЕk.\29f|lzjW
M'b}Cy|L3fԐݭ$sG&d]VVy4Z^f0q	M|=9n@$f脺9ޞú:|(
̂~, )${~"!l__|i_JZ!Zߡx^(D#v+ ᜑ>P_
p{-{~01I ~}Xy!Nxe6uDv4FkB܋+Lz"F!oM72$5!-x`eƇpc,Zn2Iؾkr[.ZkR2{nȈ"ȱ!|YW:
\\&|z#&R\V֋{=Uěq{/+_W&{ѻdU=uM>RlwUS#p|C===vy*;;bEI<mB[(7C{ӠuBB!E 5Ym=yy9hϝ(Fv;TPT_X4g9nT6u}'5ݗlꆚKG*f$Ч;`
7{	@h>]Z%$i{<ȱWRLI3"bUV3p8H	Mʘ_;x@GO|69|ףiv`M~^{Mxk'~c@YkƑ"x[iL
<VpWqC:\0/(9$?7g,y7K%8x* P)]ұ/t33cy웖y}E5҄-JqySݻb5K߲c_2HNN9k\,5#(d~nycnwPDgɉvxoش?[|EIehD#Q#orJŬE
["hg#b	(	>F'w1{aVt$8(nR<xrnn
x~۱9#O@=pU$ZzA,L0@&&8	
2)JXi|O%_EuMi4S3S+.w;)j9;Tdn0kbք_m=VѼJkC^^I^nPdJ,z]K@Q
HIze7$C;${y/LJ&+zT=aDg##T<P:EB\R92g<Į#A)&;le+:n3=ZPc艾Q<n75Wlo^#~H6/ӑ!^FKA s_\YW/P}t9Nfڹ0b2அ$Jrwfo"+ Zi,Z|@

v*XT!qVLE=ߊD=H
g-fDa.QڌO
Rvo#_҉!(M&^aRA5H -p>'dĔ6{=WLLy
xf
o
u)Pi~
Ә9yE^5hl8ʾ뭗]{Xuù/4K%@==#I%FvA%*rW+Jǚm|4WH!I,0~ʽt6[*Bx~dbxiE mj`
0aS2 *ПpY=LK
-Ѭ
kL-KjH<Da}+5WF=ǧ/2|he0׳p]#D>SrIPAͪFKI.;"ʤ/PM|3ɨ-jtE Fl9W=$uyd)<fQ] ,W)(Ts~|no뼽%(?&DJmgUG9j@gM`8?^0+Kn8]$ZZ\
)qz@5c1sStc*uؙIJZgI(v,
j(]]벎zGK^wL9u`M%ygN5;%b2\60P#
pUm@OG%+VS"aE[IuL΅%>&q*^??	\cC:ǑLF.ɗ*VtL~d=	芆1
1	wP
I^>%oz8\$>yS+S|U9T(5<L!To62ރ6O>9!TR-o77tB	f*uGxYN+JN)T}NA
Uɵ-Ř,1u+F1&#jR/TğKx{:v43Rٯ9<`ٍ^Iʭ?0/1}6"L/s[T{|*QP.Ӑ)(>И/fʡr1V@W?6(ѓ{ CdG cg`¥4ID3cRv$Ol*#%wKj	WKM1#&Ry03 Lm!kfM7
cLxUIjf)3׫N #$r"c̜x+E3>`(+		$,tКfrHe
뺼&W+)U!̍\@=&0k:s#ō9dE߰{1B.I\Kq'{qQJ|gB@31;Bs3{#
oEAV7A
	:-
$3[I7GF/ꀥfm{s]۷
:Nٶ\7_
Rd:9.bӳɃ
O
oﴪIl<8]|s:y94!(l^rx^ ulANswN3h\#\qL(@	` NARp-{@(b!|ǱWT>ΎUuu#dM%u
<ʻ*iFûS)%Ah*'O6R'rWkOy?_?x.
m?@"`CF5
m2سDِOBU*O&֙5V-^"6dBjdsC'~DPl{UzgR3z$1#<^()umӲD(Yۡ>*}e9$J9Ų?<{٫G/}w~{q٫t{d~{A/笠h$EJJÐaӢ#~27X
_m6LI7J72%K7*3, )p*](+&>idIP'L%lۡT3`!#3WL9y
<U*(8Ut!
$Y2."eMlZhK cBk 4o~_
L=9!L-.0I LhqO>oWOOx[8`fɅ.סͼZx!'$dʻd jȐVOMwLVum`-/DSL#߰#$Ɖ.7
g`x\5l&4wF5Id8CE!WUJ*ф:@EDZN*/r)Ez'W`m7֌hd=S޼wU6;rvlV[
Q\ FO/.?e(E~۫g>yIk)y΅a7yrW~]l,^Mӭ
B'l0J3bBGx큕{WwE\9zЍUӎTt*-{lTV]~#ݫ(dxf~}go8K`W. F7i`{RK]渰}XaG~6T'4lZ<%_GOp>~O-FP'C4J&?f12Jga7rCЯ%tdm-{dńp67hvⰲ4m>YՕ)1X.( `Bt GbwTkpJ9	ڨ3UΛUm+"Pw'fBUW"$yƌCD4MqA]BSzS@#!LT3M6!.ѪeWO_%ƵxRouB-]  k"0p\V,}g~_,Ȼwݯi5ߩ^(XUuf<*4$cuуA%Խ.*Lԭ	VRI-J	EJ1dр*l9PTQS,ə<k;>x,MtQ9܂)jF[	>\4w|ù UVx'<˪4)3ܔg*=CI~TpP2¶8{*j}Fvi& :KTSc=Jy<;&`W?ap/i'Ѭ8X<,pV0ٲ7!+/i+.KcWLM^E[8Orw$Cg䋷Hyp4}xէ?UR6FFZڡ}}^tmݥD.}_RQ_}P@i"Ps0Ԇ؅nS	`ZTc$*
dmҪ@
BG#Yѐ,¦СCJJ@TLA]xg5!'NN>yYRuWuju30BW n$FX#D}0%R/Vjcu	w;d	k{]W %q-}0kD}Q_"r^@lC[LP$*kxç,
4/V@)ovE8B3:UcK7m[䠢O?Ku'_<|ra3g^!eɎ~u<c-tbu~^I
Q8XߪK)٩evWOk/\ ol纑GX (0E|BKɰ̋kRZ4XohZ^Z+V\eIfzI.ш8>yzkWIE!;;6Y]oa
c3ȯHW~^gn>%哳W{m|`C/z1Dbښ_޿/I1_X9Tp0W&IhZL`;Kv=(M>H{2A!vcm={1pFT x7;(J8@w1UL	ʟeZ*>F[7pM][YWIڬat$ZE}} 0nKh7O8ǆxZnҠs$lFj\:Ԧ$GE" M$PmY!NH]$ӌRHԖ:ί$:|3fk7Rm#_@KFB<Ե%Us	ѫkyJi
ׁ[EK9/V5/"$Ur'kT!ڍ.!'
Tg-W7@担H"yx#g[kji½7qiĽ)
v[f~|3r,W1A}3/EPbغmp-L¡=[5|Պ tX<)C%4vP޿ߋ?tU͚?TTܫSfܑ^a!ן@dO+hùmq K(XWmgSB?댠&exB)/GsEW$5>>w_%BC0bP9.hx(kX*0ō	ʽ{u{Uӛ_E3Gi=\Tm>R?9%MWQRJ
(Zy1Li@TeUn볊fc:}t3´8[05[0XH?QbVyd`rC$P9LS}EGWw࣊CU'jkFmw|om>*B_Zr7}F}4"N9(FG7/?Z ꒞-|,L
ANmZǃ*l`GO	iuqa=禟ڒ 1eXppJ/],Vo$(|ѯi lf1;3lY/rl!-B?#tWKA(}ڇ'Ǭ!_v7(ՙHoy
hD};@kQ3	K溍xbC$>dw}T{;"i:2\H.,
kfp=)jױJ*$G6QtvGS)lӨĤ{n{Ud۩:!mR
!gܕ7(|n{}EZr6Վ"\;΅,tƣ9	NtL~[RDed*/HBp
]܆P-Ug}ƍ[PtZn-&NWb'\F2.ؗ[,۩-Tjh\O=#2f	aΑLWKM@bzWEkp(?=d,8&UC0)fbC5~4 ǷeRpLS&=@l	 9IHG/
g$h6z?hp\_~y'9|8g&8Axxj޳яr6dҏʍB&7M<*lzw 8A
͊.}価syͫ/]#eA2)An+X
䂄N~~WUt4_Sx/Im7)-Πh*p
+TF
)TLDNՆ L2vbVǆ*$NJUhTP9?o#"rkў<ϋ/K5L`Z}^xNJ<p[W;ː|T[v["g
Ħ~D0NKkT7rbIۏ*A"$ee,ˍ1ˍ@wkI7#?ose_5RIO9Pj.m! ]̥	l ߓU]ѣxz7M>u:OKE6*s@R2iޣUfpZ
^:\brR
M"2_7cohr#69+˸{)3)(*; .e]Lv(I%i|I_*AğP뢺c0DcAEƀ V7/j,\|8#Zw{
֔[BLBydt|RKnU4}
6I=@Lr>;ג
HS1Q
En$-lEV}
IdP!m{s"v93H
#=_C%\FJ[p*frVY	)G,ulAS8_F!qs<jP.>grE~$D: gt31nS2NGtF&.BL:qOӥόsڒCKh_[	< l%}5 ٙyg;Mt8ԧ{f""c>`Rb[h-
zbWJ5؀IC%;7/VLٯlqwu!$$pD[~Cԛl wЯ,lc@& jFQh]wKd+ W^!O&a
u
"P
m&==K؉:a雱b͋'ύ-ɡ-<#m\
S`	JDɓ
V`޸#(Ի~<vy_jzVq۫78K5كݽ8!@[I؝?{1C2jGiG!0WoN<8zm^1
\hɜ2N{'Djce	nX!wY-e,W#[ЀK̬Y6f5m*I[!8<S87n4W@#ХnbՈD|ҩۏR:'ʝλ[ݽV~@|GBH"f/(疂:<;zy[w9.@(;)X+
R:B֢
aO"xT~|>2IfeԑLl=JOxթݭɦ
sODj|o9errr.Tj2iaarGtL%!
#vN"V iRNȩj<
|pN)-h`aLN5%DI)ԟu
H
ERbQLݯ(~Ӗ`CR/T	˔v/GhqaÙ7`=f|ɌK!춘e=Tb5Pr.
o:p5Q>6oǒloT!&)JBpЅ[Y|L/eD*n+#ѐ,q[Z𤂙o]yqY
U.^ldIsbipIx$TQ0zV,)UabPpRnyo%3*x\OƲ)(YzD yB0 <&y90xf3R]bEz[6u^Bϓe>ЎHu59|Ȭ5ލ$'4HԤh
<FZXW+^
lA6R=~;P
+.j[sTIFV2|e(%SJM#35	"]։*lXH7L%4|>0;7jhxrtͩxw]J)CyLO	}ݞ:(='vL^V	d&q&Y$C͒<{걬v7KjץT#~y1ӜңWZP0vWh`sv/ ]W|w4ks!+1Uh`"=נG8YQD\5B=(a~8z
t)ƹi/ʸ/Cޔ#Hu?)5 v_
B[H)aZ#0#^ai[P4__ro%%TB
캜0~m
iצi:7m'}~AUj:)[Ooޔ3w/ajEB	3AVOca?k6$tz2$.S1{s׉h"I8jNk_9"%tI-=f$E	gi}`$E׎Ʒ'(<KT89m{2GM(Rs"skVMD@f1!㹱<`4y(M2rJңkKU~eX&EBe{ԯn A*@b7|kU=WAiґCKXՊᐭi
;4Ia-bZs,Ǎ7#qp4bY$|嶾_˔,]=DQ5)!yb)J	\3נ-'hm^~O}ނW(:BVvDcef
csi/zқwa:y1_pK-\)7,]%eB"Mяi.iROf$ٚE^JKPu`U8EO{fģao}L"UR{O3GZqJuRȒmBQ&^W^{vmdAL"u[W,]O(Wfp"CyȲnZ-]a:닳W){}̛l?>oFQOCe)GF+BO{n,>\ɦ.%VqI`GJ͍b)F)Il"g(
Y~t>P26}5dvR[+7N|4@;e&<Zagףs@i_)0l1徨\4Y8G3\T@9Ӳ˖`HC_sUAtRi,V)lw
˸>.J]|@SIBҜgoٵ(_êjaNL'fdlbͩ32km
8LyCNkCB-Uw"~Ɋ 3?T8)PQ }Л0@q^ˢ?<@U^U*QVnZ@pHA-s&gPAaQuu  e#
IfQ)pmѡסJtnrgcɍnHX5
\w4* 
i0jʕ&0AA;)u;aND}w.ܴd\fHB {:{E;,jwɡ7ӢazQ;HxL6W]iʈ#pPʿŒ(Pj=$8DmyϷBײ .OSvh]GR,9sinKpgpK) l
= R)IioYʧ~$,$MSpG'#ơ(N
t┙;b=g-s~);?"v*fka<2tǟ/I6d>ՏvDY	cMv4qm.$`]SA/]GW_vRF6Yo2,7/dN7Y7o2ݪ =bN#߉O 0AcFv*5j@
eXI<3j	-L2Ϛ&GB6ژͿ'th._A?G0eRx2pஆb~[=AjsP᧟>te?ѮL\7ܛZYL`I'$$52}5K\hY
Y| xsm	KbfYsm&V{WjY^\Mj)V,.l"U8@Q/FHcweooV.&~NFj6TK-Ś[KWG> gƲXQխ9g!M"h7l8btԴ%@eއ~ĨC[8a&Dr
%`fnGA	 玪jHsJ;w"JgWՉrlPu'_/P?M"hzoki.@TweEL_nfA^69: _dk	7*a%AJ!	+]I@Ii+Kl:TMD 5ٺ3[i
	ǍR"`Z1g
k`Qe8+?#tlx^=..{JfzՅ`O%/Bm
oA?y$?vp{4L3! Gꄲ]Vm>TP#72;ohi	a$xuDpl]K^"ƴ_T-ORv|We
Ŕnʄ-k-0(?ьeL;`XUAT7 "h
OEKq+IW+zoʩ~=4"obc7iW4A,kNG]P{A
\FY
.خ;qMtlyTi,pF\!:&Uz3ƲbIgt1.;Wn7PmZ47{U28
B_5{D-wo/3@/~.~G+r4IXgMɶ7qmTDռ>LK-a[&L)3`GM CПKpHʤ\|\K$(Lf5nMӇعD_ to%w?5A;^FGHZ8G67Kxǆ.A8Gv́*uEgصC<|g:s=5uwqrH
/1c̦gͦ!,}ޟO{(;#qNCQo8峳#kG	)D:o2^3$c>m\n(ߍc@zj{O>ןp	]i?pP4??ЎXG'yaզ_N?I'JW)jH
BPsn;Si	aQՅ(q$Z{cb[1.]ɐGEpt*Bfe
c)e
J}9
*]׫h6P=*(~?y;gʵ)ZcfF-eSm#ZqcҖ	˦PXZk]-*W<65e/gϟ>;ڇ.=ź@CvP%v&I$#9PUR`dI`7R7DJ-|!y'ƭ-ep"pROB;yGgaK8~ӓ/H\͍B)dBj^+CxFo'@}i:QE\mWz`=$Wd?Kr+9a )rpm=J\2+o<KPJvWg#+ۡ|	h
Q	vϰP6GYg^?%REgwqFBRz;y'g~ٙ;y'>Sw_[~xzs>>yCci
nGCxU!,%xx⧻tJ1Wiʃ쨜zJmALw8d
F=n$f(}g:֗e˄-S;gp/ّQ(- %&yaҖOҿ?xk/NÓ~['Mn7
|N)ĭ2lBPa*ņݢ=^P6jLx'۟H~ge~5{^|NyZ{tZ@X@I馥	C,9%]#VEsNMR!ݓ~{	wۥ{7eƧٿ^bKaբnEoQ	EWXg` ޸YՆ<$)c
Udp,)r&|hm%gg=Т$ֿApLmFlXJ D*5\&8!ogu͞<?0޸Z_C@}D~ӢOOcI3 I9NW  en8[Ւ9! ̋zcC`u%]o*b8Y+y_em7/lǏՇҚ[*ܾtXS5_TEXJ$zAm?ФǄ5{0/IZL[mrZJ!sӓdUSnMkpHLcp]jkYJ܇~]']o ן>}O?O?׿&E?yGO>8ypr'"
]l8dMEdD64OeƎI.p@	AΔ6BeŅ){R\%i[ )$g޲MoE
#ikB(sίק/1RFAtBer..MtZu*/	BЗGϛ8:"Կ-,Qos|Q`JmX!Ƙ1Ղ2 xma?,DÎw$tj&;Qm].b]pz#6d-Ƀ 
"p	d,^*6yBb:`6$[sfcPH.wwM٫?^R/Q:o f%̵bL!ǗP[ 5!̣+McT%or	;liʗy8N`F`wNmH1'%vXP@_>?w"g_yę4NT^>$&IuRXM4ybYR?2ӛuMY`>? ۙWhz[9 l(m(b`܂jaSr	)WL:BwJz>y[wQ:fPFıjZZ2?S=BˑJq0
QIF\BKΕT^mljiV`:ԭmFJhU(&jn|]δ_ewa,OqBEDVh	ɵ8S>,7+EEe)+'Or",*V6Cr%
cWWCn%WBe8xxFwQ
.zDE5ow46F*p:zǏ[B| *zڟgg;?K\ο}x;_w
lY;aڈ
]}hC	Oևr)nPq=y?;yg?ΝʜAFo]>;pMPU9S%5DeR[Hn]Doj.A@GvX)LXI21fJhs =\CVXQ"SU	gVrCI⛦2A+G𓴤'SÒ?-u
C^ℜ& $<
Vi^/6Dde>wOW=zĝ?,٤Du!fo\X;4PM/
"~pGE
6$\x~TʛȔG'@Gb\z}q=:`0*x&o+3g@(RE/,`E5%E8Ńn5I l+ЮuVP=BX399q#_nGf*s}Ŝ;	ݥdrɴgCQO"'^]'tkM[WK,H;y}+B%'==lG$uo}~o?$:~{xi%kR
8.tg<e.,BD
![z8ruD1DAjv`x+r( 'W&壶( Ʉp<M!rSo6 !P rN}Hj5l`,0p,5v>ΘEX_䳙_ҖdQy
$YͰxP8qL,-DdTaݘ	bl?˅No !ҼndbՓdE7ӫj	Gƃ%w02Vܐߤt,՜:%lOzÎ$U!D蔘,Stv"d5lͦn;T+>{SW"-}b1=_١ٳe
]ڽNW\	@H <|~߼3X=gE5߿+r4R;ɹ{+yNa=̈́|FF(u.}ۣ=ӝHHLmc`sH!"-{$9/
Ȭظ߻xO9wЬrCb拂+cJ-Y
%#i?#dS߻_bė܌EG+4#/,jc4tV95ǁO,0Aʷ
܅}HM{}JL#JkO!|́Q'>b='Lh])Bh0ꌯ:Ĭt	-m/~&
ǄrBWŜw	6 "_yCn"qu?\*0.
KeiéLKO;\t	?fE(XtGZ!ĚSV_?=`ƇAy5t,(c%"zy3ދF!D_VF,9'61PvG{	.18ۇ&
%A!>J	kj3`!YX|dC95WJoògEջ7/}/Vwͫi9lfƽUm6tq?U6GJRT}A700Ĵ=^= GqEV:!Mn
vKnέ^JQmUxxb-HAqrS`ϙ~ӆ;eA3K	6 ;LB[N}3dkߞF*DT<MH21V$܋P%˶.vJAEdisx*U"DWa.l R[TI,oG-/g/xƠtOaj yܷ?>9<HHJ3wiR+.{^a9,n̽|*<~/'Er"ReW	q>Zad^'vԳ_sNᢇOtD=mP廏ʏڢJ*Ā`-8J3R/wFvH
BPP>AqT5iU_4/ccMU{߶:]&> B*%:8:J5;1xIh9KR8;TmPb8i|ٓ?zrTOFmP~.djdd8PЊ\2\Є/4!gp=z>;7Ϥ:,WU퍂9hV:."i6Di]N/#X'G#iL]كzJU v,B%A9j @u*pcJd k+r[0򟱪lN
*D:yH~Qv}w7vE&(S
\Rj^Y8f(Ϊw#\\lQS1SQRU:T0I3Q]-*qF+L2Q	l8qp%뤨(rv75xU;-$j~1^GAh =\4S3ЗCA%*EHF\d-eM?	N'.K.Q!W^MsiP ȓMm)J'޽r0w$_W^Y}溜q,$@l+说U\kAV
_.Qĺ@$r1I5՟a
'|Pęb4:ĄV\0m;ItU
7-h:*εRkUZI	=	4?G M􏮻n~yemnZ73qpqv>x!AcefYğkZspjHש#w"yvY$roPC
[=2^#J(:>~)o* R4Η e
&2*Xsm8ŝ'WnΈT                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            /.
/usr
/usr/bin
/usr/bin/gpg
/usr/share
/usr/share/doc
/usr/share/doc/gpg
/usr/share/doc/gpg/NEWS.Debian.gz
/usr/share/doc/gpg/changelog.Debian.gz
/usr/share/doc/gpg/changelog.gz
/usr/share/doc/gpg/copyright
/usr/share/man
/usr/share/man/man1
/usr/share/man/man1/gpg.1.gz
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               Package: gpg
Status: install reinstreq unpacked
Priority: optional
Section: utils
Installed-Size: 1581
Maintainer: Debian GnuPG Maintainers <pkg-gnupg-maint@lists.alioth.debian.org>
Architecture: amd64
Multi-Arch: foreign
Source: gnupg2
Version: 2.2.40-1.1+deb12u1
Replaces: gnupg (<< 2.1.21-4)
Depends: gpgconf (= 2.2.40-1.1+deb12u1), libassuan0 (>= 2.5.0), libbz2-1.0, libc6 (>= 2.34), libgcrypt20 (>= 1.10.0), libgpg-error0 (>= 1.42), libreadline8 (>= 6.0), libsqlite3-0 (>= 3.7.15), zlib1g (>= 1:1.1.4)
Recommends: gnupg (= 2.2.40-1.1+deb12u1)
Breaks: gnupg (<< 2.1.21-4)
Description: GNU Privacy Guard -- minimalist public key operations
 GnuPG is GNU's tool for secure communication and data storage.
 It can be used to encrypt data and to create digital signatures.
 It includes an advanced key management facility and is compliant
 with the proposed OpenPGP Internet standard as described in RFC4880.
 .
 This package contains /usr/bin/gpg itself, and is useful on its own
 only for public key operations (encryption, signature verification,
 listing OpenPGP certificates, etc).  If you want full capabilities
 (including secret key operations, network access, etc), please
 install the "gnupg" package, which pulls in the full suite of tools.
Homepage: https://www.gnupg.org/
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           Package: gpg
Status: install ok unpacked
Priority: optional
Section: utils
Installed-Size: 1581
Maintainer: Debian GnuPG Maintainers <pkg-gnupg-maint@lists.alioth.debian.org>
Architecture: amd64
Multi-Arch: foreign
Source: gnupg2
Version: 2.2.40-1.1+deb12u1
Replaces: gnupg (<< 2.1.21-4)
Depends: gpgconf (= 2.2.40-1.1+deb12u1), libassuan0 (>= 2.5.0), libbz2-1.0, libc6 (>= 2.34), libgcrypt20 (>= 1.10.0), libgpg-error0 (>= 1.42), libreadline8 (>= 6.0), libsqlite3-0 (>= 3.7.15), zlib1g (>= 1:1.1.4)
Recommends: gnupg (= 2.2.40-1.1+deb12u1)
Breaks: gnupg (<< 2.1.21-4)
Description: GNU Privacy Guard -- minimalist public key operations
 GnuPG is GNU's tool for secure communication and data storage.
 It can be used to encrypt data and to create digital signatures.
 It includes an advanced key management facility and is compliant
 with the proposed OpenPGP Internet standard as described in RFC4880.
 .
 This package contains /usr/bin/gpg itself, and is useful on its own
 only for public key operations (encryption, signature verification,
 listing OpenPGP certificates, etc).  If you want full capabilities
 (including secret key operations, network access, etc), please
 install the "gnupg" package, which pulls in the full suite of tools.
Homepage: https://www.gnupg.org/
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  #! /bin/sh

set -e

if [ "$1" = configure ]; then
	update-alternatives --quiet \
	  --install /usr/bin/pinentry pinentry /usr/bin/pinentry-curses 50 \
	  --slave /usr/share/man/man1/pinentry.1.gz pinentry.1.gz /usr/share/man/man1/pinentry-curses.1.gz
fi


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                #! /bin/sh

set -e

if [ "$1" = remove ]; then
	update-alternatives --quiet --remove pinentry /usr/bin/pinentry-curses
fi


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    d41c0162f0e0de20622405ad22702767  usr/bin/pinentry-curses
6299308dfdae2cb789988d943eeec9b1  usr/share/doc/pinentry-curses/AUTHORS
1d8cb324fbdd15f46f2078be04f3bf1a  usr/share/doc/pinentry-curses/NEWS.gz
cb4a2db2402f03b3ef4c79c025712a90  usr/share/doc/pinentry-curses/README.Debian
a1c36ae7da257e9c9e4514b3994bc4c7  usr/share/doc/pinentry-curses/changelog.Debian.gz
0da065fb10297de993b2a389c9db6736  usr/share/doc/pinentry-curses/changelog.gz
69344716d6ce32f72ffc59b0cd97a5b7  usr/share/doc/pinentry-curses/copyright
d00451766e7bc75465884f75fb29ba21  usr/share/man/man1/pinentry-curses.1.gz
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Package: pinentry-curses
Source: pinentry
Version: 1.2.1-1
Architecture: amd64
Maintainer: Debian GnuPG Maintainers <pkg-gnupg-maint@lists.alioth.debian.org>
Installed-Size: 140
Depends: libassuan0 (>= 2.1.0), libc6 (>= 2.34), libgpg-error0 (>= 1.16), libncursesw6 (>= 6), libtinfo6 (>= 6)
Suggests: pinentry-doc
Enhances: gnupg-agent
Provides: pinentry
Section: utils
Priority: optional
Multi-Arch: foreign
Homepage: https://www.gnupg.org/related_software/pinentry/
Description: curses-based PIN or pass-phrase entry dialog for GnuPG
 This package contains a program that allows for secure entry of PINs or
 pass phrases.  That means it tries to take care that the entered
 information is not swapped to disk or temporarily stored anywhere.
 This functionality is particularly useful for entering pass phrases
 when using encryption software such as GnuPG or e-mail clients using
 the same.  It uses an open protocol and is therefore not tied to
 particular software.
 .
 The program contained in this package implements a PIN entry dialog
 using the curses tool kit, meaning that it is useful for users
 working in text mode without the X Window System.  There are sibling
 packages that implement PIN entry dialogs that use an X tool kit.  If
 you install any of the graphical packages then this package is not
 necessary because the sibling packages automatically fall back to
 text mode if X is not active.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Package: pinentry-curses
Status: install reinstreq half-installed
Priority: optional
Section: utils
Architecture: amd64
Multi-Arch: foreign
Version: 1.2.1-1
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Using "Modern" GnuPG
====================

As of version 2.1.11-7+exp1, the gnupg package is provided by the "modern"
version of GnuPG.

This means:

  * supporting daemons are auto-launched as needed

  * all access to secret key material is handled by gpg-agent

  * all smartcard access is handled by scdaemon

  * all network access is handled by dirmngr

  * PGPv3 keys are no longer supported

  * secret keys are no longer stored in $GNUPGHOME/secring.gpg, but
    instead in $GNUPGHOME/private-keys-v1.d/

  * public keyrings are stored in keybox format (~/.gnupg/pubring.kbx) by
    default for new users.  Upgrading users will continue to use
    pubring.gpg until they decide to explicitly convert.

Converting an existing installation
-----------------------------------

If you have an existing GnuPG homedir from "classic" GnuPG, secret
keys should be migrated automatically upon the first run of the
"modern" version.

If you have any secret keys that are stored only in a smartcard, after
your first use of "modern" gpg you should insert the card and run:

   gpg --card-status

 (see https://bugs.debian.org/795881)

Public keys will not be automatically migrated from pubring.gpg to
pubring.kbx, however.  If you want to migrate your public keyring, you
can use a script like /usr/bin/migrate-pubring-from-classic-gpg

 -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>, Mon, 18 Apr 2016 19:08:36 -0400
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           Zks6_UR;)$3lتUީld}{ )~XMFzg4V]Uv:itÝG{?3T:wz#rSŲVo~;<?xLJTF1ꦘk]hDXeOM8zqW4P-<޳5^_~=N./Hɓ:Q)"+SSDiYK2׼*檆/K_\)Wc )کmn5ۨG_ݾթ+C^s9,5jSx]6_bبg,kr~FMeH̎7Qf)Vnjk[ǱqNeERe3Km''2q]Tָ	=
6H{WuQjmeCnl^E%AY)]ߙuTv3(0'gF)YpViR[蕶)kX ?uUeyUUeUlq)ˢ271wcbl,ɒvH˛іGm{nf4,khk0Sߒ"LjufJGgf.F$Օ55GH䚵2TAğNՕMkzQ`40WΰI٠X0,aSm2줦E9˧PB95Np:Ъ#菷ԛMgWC܉#MHyŚLN50K,~vu]w"oETTѼ.G
YE?l~5ۡ7~h7Q;2S1S(,4Q#NAtu8E>	We,e𽟸f>B~i]!cC7gV콂A_UB>HU#(QV Ջp5?KVEn|8R0Mj0N2Rf6p1MpFʨyu)=$,5!fŉ&[x⥟7RxĐ(~h>n rVLJ{q]\|7tH{D vH2$ W&_]/
; CNK&4I{]:78ѕ]#VRPDC+&
x?tz%v1:S;H`'@s$XdM \
U5©ȊPIZ%BXkrC_Nqu *dNUzI"\`o4Vz@
˝O{ʹk0.CBA(o"h!3kMCEq!Efs q}XEǉ+fcA4,$  =!$!tFR186jTM,2ܞ<)֮%yCt|$qF$N "I>Ԅ<8`X 
]OU`Zo %&9LfI7I-ma˨-Dtqd\",
c-g<Vj D	E!iB'ݘ-Z<')XIAC:!ttʬYP&Dp)$4lÓFne[=ܔD0&a=gzOx8sY`ǑQ #"Vf'8B[m˻D=.;DH3WgO#y		qDCJ]g&?^?_ru# ٛB7o&1Hr㖩"F>H
QV: 
,s'EජUiUVKd$
0rg+b𤸖oqZ@n%6",1xugHQܻ_0j\Ki<GFIRrdbPb.]v~p-6W@Jr9G-dz1#	RB~>81x''c*pwT@Gߓ_<^|A%|;g'UkNl1EvOpղS03:y-E`,Ȍ B~Jf
PXpF1$&]_9 :TEF%5|j3$1A$_ح8))
e.Z<ZNܧ(	$}=E[`JIа"a~rrʑ0TGP1|XV; pDΉnT+[9wSV IW'%EQP+nnNǷˣzi!gk[J$"VY$
z@ZEt:TPº(ntdTdZb4P|BfXJby*]ll3\&EC0x/
8[ٞ	QJ*^Ä́ufiat1aG{1LBrN8/n~.Ϗ/>}˂ =q`͑l1NhR ςj6
go+T&k~ggX!E[-EQޔt>x'e'%=BMOknԮ{^Shq!J
q$B$Us-^mT=O+9޺3:0;Qjb#𴊗VmEU/kZ\`HlY<XH>.~SF08^ˉ'ׁsZ<2u<∬.4VRÄw=bQ0{~|eJ:QJp}WC}6G"!P%K	WzJ΃vVї0P-Ϯͣ
ԊW~zPw5ˣ[Dtn
P5mFVySumJH^;ϹgZ^f5%)d08gpIX'TbDs?P&;VIti,QU^5hXgbψ|;Bz%jDm|=	4[n7;_矟wg$Suѓ'Ҁ>
KK$pJԊ0VB_ۿbl+H+S|	rta
BM@FxN¡*RMw86mQyI"=t?멶rNZ}B9hyG[RHNmBQuM~#-V
,<)8l{-AမQhuU)m鴎~i^ީ:9cE\E1(LwD=q) 5^o"OG58BCLZ݇/4o'LT8Qώ\`
Gcͷk\?[T:W0A;Ra*ݏQf[c_<#(/mWr.-	YU.듲wFo_p_u\Bwp,?P8HlFmZ+~HXO_~nML &(}VҲ/qٲ$i	b:WijG<EF[xڢ2_zrEe|vIK{/y~NLE`}d[_}vV'VtA_S\ vmfF6c] 	oJ+<h%0YzRGISfZG\я '{)[Ir_XC`%*G'
Raf\ɥP55kO;ӍBY[_<:S"umKח`rdcvG- [TES$}Ȗh%!DgjqָM{D\;#聋֣	
B$[Of':,/%u|tri*f{^[ ʢ҉(0"1쥛~G5ʐ%/xJR(:L,FT!rsx.m-]Bxר{H]r'?UQܦGmr\߶$x_JPɗ_J.-o&IM"r.K<y
0bG@,c^<F3swƋ/f?dIXIJ*U+ Ϫпf8G7̴7^bL'AHOBh;&
]^}\ ϕ<]"KC1o6ȼA-KwwT/>Az|1<TqjiL}{{w4>\_ +Kͥ)$Mn'Ӌ}5Nn8Bθ17߾u<ɻ2L)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        m[rܺ>n9>I%-Y"V97)p  g42{bu78qrYdA LuT>:u6%TQO&8ԕR/K㗝Qw)rH3ɺF-/;7*Mc"W:X?De{4Lo\1R
,3]Awnm0ֹ	F٨lLUZh-T6*ߣ!]cB!ֽZ&Nsۯ֩&$GwYԍ(}='?hx!,ԵuԹ.mÓYCoE9ߛ/}Mxng;ԇNVIq#]
}Yֶ6*iBc

rx%܄/1N¿Vz>Q($1)l[AGX!n>l_We-K{ٷf*(^y\Lk::)jٱz0N7T`i|{u8ilu(&(y"Q
-:С&efrA%zWԆىv2F^ڥ)Q*>v,@ƦכXMYr纋f3!ӒzKu28TfDifЎAd'}n 0cxL
eg-t_apbt8^~mE=P
S
L)Ha@K"vǹK#~)7?ibH,Oث<\Zt2Cl#geԭuID^I3Ϗns'^=V?ЅBتzaN&W+c"#\GKpVݡ۵Ya,*r+	ꮅ{W6!
ues/Ճ%_
<+Y7d>YQ9תL}k7!f^ETr!-j[^iL[aDb;!B=v+hOl)hG3Z
]b9KȳƗzH
smkge1wdve^Mg_;^SC{jz,"*-z!{J/  а<^DӓHLc?ooyc}}2۵Z&\7uD]EO`؍^P:9N+N6mf',el>k~xC_,mֿAucE,kb?! LG6sތN#vxbǉ.+yaz#b{X0/.ӓϙ8Og<	M,BԺ#.41=X;z}`u$*uk_cRgZ;7N9rck8hvZ`(<,Ć
0 8uwV# b#_U蹉u޼ԉjQ?&mu&jv⇦ Ĭ9ek5B:T/gL\U@g7ק_fg:w Pt
7%S+ESh}hWW9 4OCL^ !J%;ǣ@}j4.9z;j޲cћؽ్V_1#uA_}$N,9 <ڮhBs
`wEwa)~cEn*r~1
)54GHeި;(<-!tO絼^ٮ5B~Js?z%&gc'Ӫ&2Q(R X}iS=ۡIs{&e<ڰHLe453:f%ZtzHAqj:4Ϧ9J15Dae[3&+ybdj*bndCgowf7<k̻-l#Ѭ(ќv	$k];`P{x82Q~<كm
[aNș =1#5f(K7#{HH ?9lCĎ, VYF<םbXC=ĩ'Br:Ҝln}\}q!Mɍ<CXSb8_Rf@0
/1!$aW\\lE"e/ǠK\^(Ds0l[nwpiCPd"Nky_rc04A>,}:pJ3Jbs}⿩YGM4P$9-]8U`Zjyd*n.VEOmڽO%ň0P`^pҰDDX
.m8p1D?>=z+iœn^A;bICܪB}%V[)[O0bف5üg~'x`,K>LSp+2e ]:<@i#\9hnj`_8[WwR:Hnl פy#F`pXg4Ei!%mC2I{q6%K[274
G&k]+A:+
0,noV?Y]o(ū4Y]_ڞOzܰ?d8<k
GPKX t  S267"{Jν3M3Y7&Z2Oy%FS|^}.00χnK3]KSAdH{Ξ!Jn G2JJ	^-%[ʞHķ dM_YAaFrpdY.#4Z=G-PrZWZéW7Fwsnt/In_8@pH%W^~=^>79szdanL
PF쑎S@¿He0-6޾*)ɡO,BC*vP_xw>%yª+Z=CntF9}MRU
W4{ԍ^IW]S֕YojsX37bwޕ􇎡Ek~- HlJnb-7>@WoajiPtBGxg3&56ZQMs|W#^J$ʙ5V8,|lZ17$MR]jS'K+vx&U'Ԃs'w9=$*">XNp4?8[#Ik{'Zu\w;R-:
1iW&J)a;8u{BE
Bd]BJ4J!	ޜ؍IE+|{H+5ӳ,._c\!tCb2kzXŘE=Gz="zߚD݄v(4IZ]T/lu<QW [4/@aL%\R_K6#~IqfdrJhuHS.Lcc
ttlW^9o(S_ӑ܏܍=i!K	^<L/}gVJGPYfBԑFGh3?Kvru'blrQ)r7:pjP{B=c
{n<-Z4-ݩsbsh"3rtC8vk8K?/7?x5,_qk͡\TȾ%
!25^\?U_V̢qf4YHnmK="ޱ7`;0|
|@Rp- t|%,$fV]b6rC̕%9#v̰4.I֟`4Z'e۷Wٝ𺴙[RngyWHD }hEc0NJY6Q#!,:;ѠK>V ]mgwwC>5I%䀍xriԵ|/W
7Qw`p:RvCe\gC'2iY5!I.,@ԁiS{6PkF&Ye*`i\kY-$BPŰKT,IJoac54n*r("aBwc0H
pDAf +g}o 2oxt@@JٽN]h; yʽvq/!zp^4kO
덺V	C|rL=IMXO(fw_3Ä&
P'%z}@	ޛ;-
~0k@Hul7WF\:V"ptzi"
+rq/?Pyd㓡W5ՕR;<%붗HxJ.+eAi@R?f&yP]S{EDO&3 L'K	w}*iaaƩӫN5"p)Aa""b\"q1`)dr'ytFSvХ_? EKn7H<&Э&u>ͭ<ɥՕZM&۝$I'*yO>Pq-TlrWX]7FzDimiwemDgv_×TIRXV-*>e0#*}MZL &Lj qNCOR
:#B'&R9y+oۇbCG[Dpg9r?w<BnT^8x\4rh^Z*Sc?I;^G
V=4~J5<k=:1j	Q1Cg*pHnՏk5D¬'ڝI`j^NGŮE.^H.;2VkmepO2Pސ1&9ެz\">*z=Xs&'ZȐ7XZ8׺H.^$wp̧k'RHQ|Iiy7q,un"/tQA}Y|&&tvt '<iţUQƷ*O+|50yR; +brvfk9wB2]:l"fM1mEB|]j.Sszg/ƥWZ+M^M#d2l/v%Sa;
 Ttym1ض븏i+O*y2RQ$-Ju;<;`k?)]]Q@*1dXG`^!T!#_P8=Q`Go;O-	
',N*.RI=vZRN4;'`{l+Ѫ8vgkoa,:_)״2G0܁w$vbS᫏VCy..Nּ}|yWlg+-?1Pܝ.$3(vm^Rj$)IJ!6aoE>f^xK	܆((r-2GscP&%ߋ?th6F-L!67sƑhN)rM ,ٞRV'W|l3@\w?_#$
%
vr#uD X!gO~l	k% δ\Y	Іf@M")oQ}>S/I$?z,ߨW $9͆~(*(yHLSiu6veľ-b
	Z(ް$h7rm74Qd+>!Q4Yp\f>to`Gu|U=>~}3yID:8m._u)І49>x+Ã^ǋO>4                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  -*- outline -*-

* src/base64                                                  
** Make parsing more robust
   Currently we don't cope with overlong lines in the best way.
** Check that we really release the ksba reader/writer objects.

* sm/call-agent.c
** Some code should go into import.c
** When we allow concurrent service request in gpgsm, we
   might want to have an agent context for each service request
   (i.e. Assuan context).

* sm/certchain.c
** Try to keep certificate references somewhere
  This will help with some of our caching code.  We also need to test
  that caching; in particular "regtp_ca_chainlen".

* sm/decrypt.c
** replace leading zero in integer hack by a cleaner solution

* sm/gpgsm.c
** Implement --default-key
** support the anyPolicy semantic
** Should we prefer nonRepudiation certs over plain signing certs?
   Also: Do we need a way to allow the selection of a qualSig cert
   over a plain one?  The background is that the Telesec cards have 3
   certs capable of signing all with the same subject name.

* sm/keydb.c
** Check file permissions
** Check that all error code mapping is done.
** Remove the inter-module dependencies between gpgsm and keybox
** Add an source_of_key field

* agent/
** If we detect that a private key has been deleted
   Bump the key event counter.

* agent/command.c
** Make sure that secure memory is used where appropriate

* agent/pkdecrypt.c, agent/pksign.c
** Support DSA

* Move pkcs-1 encoding into libgcrypt.

* Use a MAC to protect sensitive files.
  The problem here is that we need yet another key and it is unlikely
  that users are willing to remember that key too.  It is possible to
  do this with a smartcard, though.

* sm/export.c
** Return an error code or a status info per user ID.

* common/tlv.c
  The parse_sexp function should not go into this file.  Check whether
  we can change all S-expression handling code to make use of this
  function.

* scd
** Application context vs. reader slot
  We have 2 concurrent method of tracking whether a reader is in use:
  Using the session_list in command.c and the lock_table in app.c.  It
  would be better to do this just at one place. First we need to see
  how we can support cards with multiple applications.
** Resolve fixme in do_sign of app-dinsig.
** Disconnect 
  Card timeout is currently used as a boolean.  
  Add disconnect support for the ccid driver.

* Regression tests
** Add a regression test to check the extkeyusage.

* Windows port (W32)
** Regex support is disabled
  We need to adjust the test to find the regex we have anyway in 
  gpg4win.  Is that regex compatible to the OpenPGP requirement?


* sm/
** check that we issue NO_SECKEY xxx if a -u key was not found
   We don't. The messages returned are also wrong (recipient vs. signer).

* g10/
** issue a NO_SECKEY xxxx if a -u key was not found.

* Extend selinux support to other modules
  See also http://etbe.coker.com.au/2008/06/06/se-linux-support-gpg/

* UTF-8 specific TODOs
  None.

* Manual
** Document all gpgsm options.
   

* Pinpad Reader
  We do not yet support P15 applications.  The trivial thing using
  ASCII characters will be easy to implement but the other cases need
  some more work.

* Bugs


* Howtos
** Migrate OpenPGP keys to another system

* Gpg-Agent Locale
  Although we pass LC_MESSAGE from gpgsm et al. to Pinentry, this has
  only an effect on the stock GTK strings (e.g. "OK") and not on any
  strings gpg-agent generates and passes to Pinentry.  This defeats
  our design goal to allow changing the locale without changing
  gpg-agent's default locale (e.g. by the command updatestartuptty).

* RFC 4387: Operational Protocols: Certificate Store Access via HTTP
  Do we support this?

                                                                                                                                                                                                                                                                                                          $Id$

Note for translators
--------------------

Some strings in GnuPG are for matching user input against.  These
strings can accept multiple values that mean essentially the same
thing.

For example, the string "yes" in English is "sí" in Spanish.  However,
some users will type "si" (without the accent).  To accommodate both
users, you can translate the string "yes" as "sí|si".  You can have
any number of alternate matches separated by the | character like
"sí|si|seguro".

The strings that can be handled in this way are of the form "yes|yes",
(or "no|no", etc.) There should also be a comment in the .po file
directing you to this file.


Help files
----------

GnuPG provides a little help feature (entering a ? on a prompt).  This
help used to be translated the usual way with gettext but it turned
out that this is too inflexible and does for example not allow
correcting little mistakes in the English text.  For some newer features
we require editable help files anyway and thus the existing help
strings have been moved to plain text files names "help.LL.txt".  We
distribute these files and allow overriding them by files of that name
in /etc/gnupg.  The syntax of these files is documented in
doc/help.txt.  This is also the original we use to describe new
possible online help keys.  The source files are located in doc/ and
need to be in encoded in UTF-8.  Strings which require a translation
are disabled like this

   .#gpgsm.some.help-item
   This string is not translated.

After translation you should remove the hash mark so that the
entry looks like.

   .gpgsm.some.help-item
   This string has been translated.

The percent sign is not a special character and if there is something
to watch out there will be a remark.



Sending new or updated translations
-----------------------------------

Please note that we do not use the TP Robot but require that
translations are to be send by mail to translations@gnupg.org.  We
also strongly advise to get subscribed to i18n@gnupg.org and request
assistance if it is not clear on how to translate certain strings.  A
wrongly translated string may lead to a security problem.

A copyright disclaimer to the FSF is not anymore required since
December 2012.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               Yks_tb-x|Nǎ,ǘN2N;YKbK`D1.HAd&Lf,"y{MY8cӌ-	d)f+UҨ5e)="0X*˒L),F\
1Wn
]Ҝ,<*v醮]â?=<&$fkh٨%?0.thfvq
眊>%|^݀\R3G	y_
3LPT9	$Ø~NpN?zgipL,XKᕔ?ظ
I}Zq%rLDoxEܡ<k+}蹍k8茊ޞ׊i2a;zpN0" )BlX猰,`n
v ;M e N(tJma]c\9/9S9;^VRդ+p^FRqddyXʔP0Yd\b,jvxIgyKsAEQbl~:ϥҬUaYvN`im Hy2Z%hp`{u2k<1nLehтG$Lx[3?G,"܄ժ \D:vN	Y5$Oxkrf\#9Nha;LrmmfI'6&eůfix#p,(e} 9gÒ	8ʴeBMY'À	IRmZ0MAKO0+ŭ43&~Q\ [i:y4zDJP[?qaLݗR!
YbO%eK b[i0p|"3MXE&;p	g.
9q|*ӎ>KO}P:GR4W3В ()G
XF@r[cY2@}VV[V9 lMPiVW4z?*h0e[Ot7o@f
#cTT9A1Xњ'ߕQ0Eb9h\YuAXJ\㲹Q*~EǀJ7!6 "MFT}5Gtu҄+4^m7 Uj"ɳxǋ4K'_B@"*wdS#7x<}5afPӍ͜Ed%sZHs4*i1krfiqH@q)8CF8I٦v.eS;+l\`$+d(٩w:$b-8_醶ޟb&M1uvUmu.%`oK3`0{>2%O>k^BlTAdLh(W&ltEpkN|2"ܙmy/H,$zJV5+8v5j	Ng[b4t`&P߿t~Ha
jbH^I#[iFASbd*q%2-߈ePj
fGǐf;캺5kj^iТH:jBGvAd!]:ds!ém}"ɭۣ13]Y|z=5¡X؏+pJŮN;'˖q+:o6űq<2ύ+
,7L<T
%w.6QI\,z YBBA%{m7WS
r,	><PqypbDѾGQ ꉎعunĆUS ߈+(a<gdp2;Cn>U-_퐏bZW&ۥ+O-\)ln&3ue-r{_Xi7&0p0?H?5}I@\IY+l罴iw➜kyQ<89Lkݚ-,u0u܊w2@qQ876v]+z ,r2Z8Iso
q;
NZ['>n{uq`y%~
zܖ-l,qf&4%att{sR3-2-)eF|Lo֚R!f
{r]նFL764ڼ\ZAʴ$z%AHMuI $
2ѪS e1uѦ2px>]6
?xYTue"
ؠ%; /ZX-zL;qn_TkU{5;Z}`6傹P/-_Q}]=6ua۶_׉y?'5\-<p2:ɦ[ݎ[JyU4/C<<}ܦ"܃_-t+ƽF偠xU獏NNyJ 	vt0zɵlq.p1vs|REf6̂o<8.eyZz?bid652&n*eR4ɯdƶf֘ mUk߇tbv+HӰ65u9?C/evq'5X$XºS%ڽN-Ŏ+2*:
M8<"27
FڊZ!CL,o^p"3W|8Vu+?
x6                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: GnuPG - The GNU Privacy Guard (modern version)
Upstream-Contact: GnuPG development mailing list <gnupg-devel@gnupg.org>
Source: https://gnupg.org/download/

Files: *
Copyright: 1992, 1995-2020, Free Software Foundation, Inc
License: GPL-3+

Files: agent/command.c
 agent/command-ssh.c
 agent/gpg-agent.c
 common/homedir.c
 common/sysutils.c
 g10/mainproc.c
Copyright: 1998-2007, 2009, 2012, Free Software Foundation, Inc
  2013, Werner Koch
License: GPL-3+

Files: autogen.sh
Copyright: 2003, g10 Code GmbH
License: permissive

Files: common/gc-opt-flags.h
 common/i18n.h
 tools/clean-sat.c
 tools/no-libgcrypt.c
Copyright: 1998-2001, 2003, 2004, 2006, 2007 Free Software Foundation, Inc
License: permissive

Files: common/localename.c
Copyright: 1985, 1989-1993, 1995-2003, 2007, 2008 Free Software Foundation, Inc.
License: LGPL-2.1+

Files: dirmngr/dns.c
 dirmngr/dns.h
Copyright: 2008-2010, 2012-2016 William Ahern
License: Expat

Files: doc/yat2m.c
 scd/app-geldkarte.c
Copyright: 2004, 2005, g10 Code GmbH
  2006, 2008, 2009, 2011, Free Software Foundation, Inc
License: GPL-3+

Files: scd/ccid-driver.h
 scd/ccid-driver.c
Copyright: 2003-2007, Free Software Foundation, Inc
License: GPL-3+ or BSD-3-clause

Files: tools/rfc822parse.c
 tools/rfc822parse.h
Copyright: 1999-2000, Werner Koch, Duesseldorf
  2003-2004, g10 Code GmbH
License: LGPL-3+

Files: tools/sockprox.c
Copyright: 2007, g10 Code GmbH
License: GPL-3+

Files: doc/OpenPGP
Copyright: 1998-2013 Free Software Foundation, Inc.
           1997, 1998, 2013 Werner Koch
           1998 The Internet Society
License: RFC-Reference

Files: tests/gpgscm/*
Copyright: 2000, Dimitrios Souflis
           2016, Justus Winter, Werner Koch
License: TinySCHEME

Files: debian/*
Copyright: 1998-2022 Debian GnuPG packagers, including
 Eric Dorland <eric@debian.org>
 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
 NIIBE Yutaka <gniibe@fsij.org>
License: GPL-3+

Files: debian/org.gnupg.scdaemon.metainfo.xml
Copyright: 2017 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
Comment: This file is licensed permissively for the sake of AppStream
License: CC0-1.0

License: TinySCHEME
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 met:
 .
 Redistributions of source code must retain the above copyright notice,
 this list of conditions and the following disclaimer.
 .
 Redistributions in binary form must reproduce the above copyright
 notice, this list of conditions and the following disclaimer in the
 documentation and/or other materials provided with the distribution.
 .
 Neither the name of Dimitrios Souflis nor the names of the
 contributors may be used to endorse or promote products derived from
 this software without specific prior written permission.
 .
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


License: permissive
 This file is free software; as a special exception the author gives
 unlimited permission to copy and/or distribute it, with or without
 modifications, as long as this notice is preserved.
 .
 This file is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY, to the extent permitted by law; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.

License: RFC-Reference
 doc/OpenPGP merely cites and references IETF Draft
 draft-ietf-openpgp-formats-07.txt. This is believed to be fair use;
 but if not, it's covered by the source document's license under
 the 'comment on' clause. The license statement follows.
 .
 This document and translations of it may be copied and furnished to
 others, and derivative works that comment on or otherwise explain it
 or assist in its implementation may be prepared, copied, published
 and distributed, in whole or in part, without restriction of any
 kind, provided that the above copyright notice and this paragraph
 are included on all such copies and derivative works.  However, this
 document itself may not be modified in any way, such as by removing
 the copyright notice or references to the Internet Society or other
 Internet organizations, except as needed for the purpose of
 developing Internet standards in which case the procedures for
 copyrights defined in the Internet Standards process must be
 followed, or as required to translate it into languages other than
 English.
 .
 The limited permissions granted above are perpetual and will not be
 revoked by the Internet Society or its successors or assigns.


License: GPL-3+
 GnuPG 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 3 of the License, or
 (at your option) any later version.
 .
 GnuPG 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; if not, see <https://www.gnu.org/licenses/>.
 .
 On Debian systems, the full text of the GNU General Public
 License version 3 can be found in the file
 `/usr/share/common-licenses/GPL-3'.

License: LGPL-3+
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser 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
 Lesser General Public License for more details.
 .
 You should have received a copy of the GNU Lesser General Public
 License along with this program; if not, see <https://www.gnu.org/licenses/>.
 .
 On Debian systems, the full text of the GNU Lesser General Public
 License version 3 can be found in the file
 `/usr/share/common-licenses/LGPL-3'.

License: LGPL-2.1+
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as
 published by the Free Software Foundation; either version 2.1 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
 Lesser General Public License for more details.
 .
 You should have received a copy of the GNU Lesser General Public
 License along with this program; if not, see <https://www.gnu.org/licenses/>.
 .
 On Debian systems, the full text of the GNU Lesser General Public
 License version 2.1 can be found in the file
 `/usr/share/common-licenses/LGPL-2.1'.

License: BSD-3-clause
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
    notice, and the entire permission notice in its entirety,
    including the disclaimer of warranties.
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
 3. The name of the author may not be used to endorse or promote
    products derived from this software without specific prior
    written permission.
 .
 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 OF THE POSSIBILITY OF SUCH DAMAGE.

License: Expat
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to permit
 persons to whom the Software is furnished to do so, subject to the
 following conditions:
 .
 The above copyright notice and this permission notice shall be included
 in all copies or substantial portions of the Software.
 .
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 USE OR OTHER DEALINGS IN THE SOFTWARE.

License: CC0-1.0
 To the extent possible under law, the author(s) have dedicated all
 copyright and related and neighboring rights to this software to the public
 domain worldwide. This software is distributed without any warranty.
 .
 On Debian systems, the complete text of the CC0 license, version 1.0,
 can be found in /usr/share/common-licenses/CC0-1.0.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     # Automatic.prf - Configure options for a more automatic mode  -*- conf -*-
#
# The options for each tool are configured in a section ("[TOOL]");
# see the respective man page for a description of these options and
# the gpgconf manpage for a description of this file's syntax.

[gpg]
auto-key-locate local,wkd,dane
auto-key-retrieve
trust-model tofu+pgp$\r$\n'

[gpg-agent]
default-cache-ttl 900
max-cache-ttl 3600
min-passphrase-nonalpha 0
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Files in this directory:


scd-event       A handler script used with scdaemon

trustlist.txt   A list of trustworthy root certificates
                (Please check yourself whether you actually trust them)

gpgconf.conf    A sample configuration file for gpgconf.

systemd-user    Sample files for a Linux-only init system.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          # VS-NfD.prf - Configure options for the VS-NfD mode           -*- conf -*-
#
# The options for each tool are configured in a section ("[TOOL]");
# see the respective man page for a description of these options and
# the gpgconf manpage for a description of this file's syntax.

[gpg]
compliance de-vs

[gpgsm]
compliance de-vs
enable-crl-checks

[gpg-agent]
default-cache-ttl 900
max-cache-ttl 3600
no-allow-mark-trusted
no-allow-external-cache
enforce-passphrase-constraints
min-passphrase-len 9
min-passphrase-nonalpha 0

[dirmngr]
allow-ocsp
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              # debug.prf - Configure options for easier debugging       -*- conf -*-
#
# Note that the actual debug options for each component need to be set
# manually.  Running the component with "--debug help" shows a list of
# supported values.  To watch the logs this command can be used:
#
#   watchgnupg --time-only --force $(gpgconf --list-dirs socketdir)/S.log
#

[gpg]
log-file socket://
verbose
#debug ipc

[gpgsm]
log-file socket://
verbose
#debug ipc

[gpg-agent]
log-file socket://
verbose
#debug ipc
#debug-pinentry

[dirmngr]
log-file socket://
verbose
#debug ipc,dns
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     # gpgconf.conf - configuration for gpgconf
#----------------------------------------------------------------------
# This file is read by gpgconf(1) to setup defaults for all or
# specified users and groups.  It may be used to change the hardwired
# defaults in gpgconf and to enforce certain values for the various
# GnuPG related configuration files.
#
# NOTE: This is a legacy mechanism.  The modern way is to use global
#       configuration files like /etc/gnupg/gpg.conf which are more
#       flexible and better integrated into the configuration system.
#
# Empty lines and comment lines, indicated by a hash mark as first non
# white space character, are ignored.  The line is separated by white
# space into fields. The first field is used to match the user or
# group and must start at the first column, the file is processed
# sequential until a matching rule is found.  A rule may contain
# several lines; continuation lines are indicated by a indenting them.
#
# Syntax of a line:
# <key>|WS  <component> <option> ["["<flag>"]"] [<value>]
#
# Examples for the <key> field:
#   foo         - Matches the user "foo".
#   foo:        - Matches the user "foo".
#   foo:staff   - Matches the user "foo" or the group "staff".
#   :staff      - Matches the group "staff".
#   *           - Matches any user.
# All other variants are not defined and reserved for future use.
#
# <component> and <option> are as specified by gpgconf.
# <flag> may be one of:
#   default     - Delete the option so that the default is used.
#   no-change   - Mark the field as non changeable by gpgconf.
#   change      - Mark the field as changeable by gpgconf.
#
# Example file:
#==========
# :staff  gpg-agent min-passphrase-len 6 [change]
#
# *       gpg-agent min-passphrase-len [no-change] 8
#         gpg-agent min-passphrase-nonalpha [no-change] 1
#         gpg-agent max-passphrase-days [no-change] 700
#         gpg-agent enable-passphrase-history [no-change]
#         gpg-agent enforce-passphrase-constraints [default]
#         gpg-agent enforce-passphrase-constraints [no-change]
#         gpg-agent max-cache-ttl [no-change] 10800
#         gpg-agent max-cache-ttl-ssh [no-change] 10800
#         gpgsm     enable-ocsp
#         gpg       compliance [no-change]
#         gpgsm     compliance [no-change]
#===========
# All users in the group "staff" are allowed to change the value for
# --allow-mark-trusted; gpgconf's default is not to allow a change
# through its interface.  When "gpgconf --apply-defaults" is used,
# "allow-mark-trusted" will get enabled and "min-passphrase-len" set
# to 6.  All other users are not allowed to change
# "min-passphrase-len" and "allow-mark-trusted".  When "gpgconf
# --apply-defaults" is used for them, "min-passphrase-len" is set to
# 8, "allow-mark-trusted" deleted from the config file and
# "enable-ocsp" is put into the config file of gpgsm.  The latter may
# be changed by any user.
#-------------------------------------------------------------------
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        # gpgconf-rnames.lst
# Additional registry settings to be shown by "gpgconf -X".
#
# Example: HKCU\Software\GNU\GnuPG:FooBar
#
#  HKCU := The class.  Other supported classes are HKLM, HKCR, HKU,
#          and HKCC.  If no class is given and the string thus starts
#          with a backslash HKCU with a fallback to HKLM is used.
#  Software\GNU\GnuPG := The actual key.
#  FooBar := The name of the item.  if a name is not given the default
#            value is used.
#
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       # pwpattern.list                                   -*- default-generic -*-
#
# This is an example for a pattern file as used by gpg-check-pattern.
# The file is line based with comment lines beginning on the *first*
# position with a '#'.  Empty lines and lines with just spaces are
# ignored.  The other lines may be verbatim patterns and match as they
# are (trailing spaces are ignored) or extended regular expressions
# indicated by a / in the first column and terminated by another / or
# end of line.  All comparisons are case insensitive.
 
# Reject the usual metavariables.  Usual not required because
# gpg-agent can be used to reject all passphrases shorter than 8
# charactes.
foo
bar
baz

# As well as very common passwords.  Note that gpg-agent can be used
# to reject them due to missing non-alpha characters.
password
passwort
passphrase
mantra
test
abc
egal

# German number plates.
/^[A-Z]{1,3}[ ]*-[ ]*[A-Z]{1,2}[ ]*[0-9]+/

# Dates (very limited, only ISO dates). */
/^[012][0-9][0-9][0-9]-[012][0-9]-[0123][0-9]$/

# Arbitrary strings
the quick brown fox jumps over the lazy dogs back
no-password
no password

12345678
123456789
1234567890
87654321
987654321
0987654321
qwertyuiop
qwertzuiop
asdfghjkl
zxcvbnm
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  #!/bin/sh
# Sample script for scdaemon event mechanism.

#exec >>/tmp/scd-event.log

PGM=scd-event

reader_port=
old_code=0x0000
new_code=0x0000
status=

tick='`'
prev=
while [ $# -gt 0 ]; do
  arg="$1"
  case $arg in
      -*=*) optarg=$(echo "X$arg" | sed -e '1s/^X//' -e 's/[-_a-zA-Z0-9]*=//')
            ;;
         *) optarg=
            ;;
  esac
  if [ -n "$prev" ]; then
    eval "$prev=\$arg"
    prev=
    shift
    continue
  fi
  case $arg in
      --help|-h)
          cat <<EOF
Usage: $PGM [options]
$PGM is called by scdaemon on card reader status changes

Options:
  --reader-port N        Reports change for port N
  --old-code 0xNNNN      Previous status code
  --old-code 0xNNNN      Current status code
  --status USABLE|ACTIVE|PRESENT|NOCARD 
                         Human readable status code

Environment:

GNUPGHOME=DIR            Set to the active homedir

EOF
          exit 0
          ;;
    
      --reader-port)  
          prev=reader_port
          ;;
      --reader-port=*)
          reader_port="$optarg"
          ;;
      --old-code)  
          prev=old_code
          ;;
      --old-code=*)
          old_code="$optarg"
          ;;
      --new-code)  
          prev=new_code
          ;;
      --new-code=*)
          new_code="$optarg"
          ;;
      --status)  
          prev=status
          ;;
      --new-code=*)
          status="$optarg"
          ;;

      -*)
          echo "$PGM: invalid option $tick$arg'" >&2
          exit 1
          ;;

      *)
          break
          ;;
  esac
  shift
done
if [ -n "$prev" ]; then
  echo "$PGM: argument missing for option $tick$prev'" >&2
  exit 1
fi

cat <<EOF
========================
port:     $reader_port
old-code: $old_code
new-code: $new_code
status:   $status
EOF

if [ x$status = xUSABLE ]; then
    gpg --batch --card-status 2>&1
fi

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Socket-activated dirmngr and gpg-agent with systemd
===================================================

When used on a GNU/Linux system supervised by systemd, you can ensure
that the GnuPG daemons dirmngr and gpg-agent are launched
automatically the first time they're needed, and shut down cleanly at
session logout.  This is done by enabling user services via
socket-activation.

System distributors
-------------------

The *.service and *.socket files (from this directory) should be
placed in /usr/lib/systemd/user/ alongside other user-session services
and sockets.

To enable socket-activated dirmngr for all accounts on the system,
use:

    systemctl --user --global enable dirmngr.socket

To enable socket-activated gpg-agent for all accounts on the system,
use:

    systemctl --user --global enable gpg-agent.socket

Additionally, you can enable socket-activated gpg-agent ssh-agent
emulation for all accounts on the system with:

    systemctl --user --global enable gpg-agent-ssh.socket

You can also enable restricted ("--extra-socket"-style) gpg-agent
sockets for all accounts on the system with:

    systemctl --user --global enable gpg-agent-extra.socket

Individual users
----------------

A user on a system with systemd where this has not been installed
system-wide can place these files in ~/.config/systemd/user/ to make
them available.

If a given service isn't installed system-wide, or if it's installed
system-wide but not globally enabled, individual users will still need
to enable them.  For example, to enable socket-activated dirmngr for
all future sessions:

    systemctl --user enable dirmngr.socket

To enable socket-activated gpg-agent with ssh support, do:

    systemctl --user enable gpg-agent.socket gpg-agent-ssh.socket

These changes won't take effect until your next login after you've
fully logged out (be sure to terminate any running daemons before
logging out).

If you'd rather try a socket-activated GnuPG daemon in an
already-running session without logging out (with or without enabling
it for all future sessions), kill any existing daemon and start the
user socket directly.  For example, to set up socket-activated dirmgnr
in the current session:

    gpgconf --kill dirmngr
    systemctl --user start dirmngr.socket
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              [Unit]
Description=GnuPG network certificate management daemon
Documentation=man:dirmngr(8)
Requires=dirmngr.socket

[Service]
ExecStart=/usr/bin/dirmngr --supervised
ExecReload=/usr/bin/gpgconf --reload dirmngr
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            [Unit]
Description=GnuPG network certificate management daemon
Documentation=man:dirmngr(8)

[Socket]
ListenStream=%t/gnupg/S.dirmngr
SocketMode=0600
DirectoryMode=0700

[Install]
WantedBy=sockets.target
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    [Unit]
Description=GnuPG cryptographic agent and passphrase cache (access for web browsers)
Documentation=man:gpg-agent(1)

[Socket]
ListenStream=%t/gnupg/S.gpg-agent.browser
FileDescriptorName=browser
Service=gpg-agent.service
SocketMode=0600
DirectoryMode=0700

[Install]
WantedBy=sockets.target
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [Unit]
Description=GnuPG cryptographic agent and passphrase cache (restricted)
Documentation=man:gpg-agent(1)

[Socket]
ListenStream=%t/gnupg/S.gpg-agent.extra
FileDescriptorName=extra
Service=gpg-agent.service
SocketMode=0600
DirectoryMode=0700

[Install]
WantedBy=sockets.target
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       [Unit]
Description=GnuPG cryptographic agent (ssh-agent emulation)
Documentation=man:gpg-agent(1) man:ssh-add(1) man:ssh-agent(1) man:ssh(1)

[Socket]
ListenStream=%t/gnupg/S.gpg-agent.ssh
FileDescriptorName=ssh
Service=gpg-agent.service
SocketMode=0600
DirectoryMode=0700

[Install]
WantedBy=sockets.target
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            [Unit]
Description=GnuPG cryptographic agent and passphrase cache
Documentation=man:gpg-agent(1)
Requires=gpg-agent.socket

[Service]
ExecStart=/usr/bin/gpg-agent --supervised
ExecReload=/usr/bin/gpgconf --reload gpg-agent
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 [Unit]
Description=GnuPG cryptographic agent and passphrase cache
Documentation=man:gpg-agent(1)

[Socket]
ListenStream=%t/gnupg/S.gpg-agent
FileDescriptorName=std
SocketMode=0600
DirectoryMode=0700

[Install]
WantedBy=sockets.target
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      # This is the global list of trusted keys.  Comment lines, like this
# one, as well as empty lines are ignored.  Lines have a length limit
# but this is not serious limitation as the format of the entries is
# fixed and checked by gpg-agent.  A non-comment line starts with
# optional white space, followed by the SHA-1 fingerpint in hex,
# optionally followed by a flag character which my either be 'P', 'S'
# or '*'.  This file will be read by gpg-agent if no local trustlist
# is available or if the statement "include-default" is used in the
# local list. You should give the gpg-agent(s) a HUP after editing
# this file.


#Serial number: 32D18D
#       Issuer: /CN=6R-Ca 1:PN/NameDistinguisher=1/O=RegulierungsbehÈorde
#               fÈur Telekommunikation und Post/C=DE
EA:8D:99:DD:36:AA:2D:07:1A:3C:7B:69:00:9E:51:B9:4A:2E:E7:60  S

#Serial number: 00C48C8D
#       Issuer: /CN=7R-CA 1:PN/NameDistinguisher=1/O=RegulierungsbehÈorde
#               fÈur Telekommunikation und Post/C=DE
DB:45:3D:1B:B0:1A:F3:23:10:6B:DE:D0:09:61:57:AA:F4:25:E0:5B  S

#Serial number: 01
#       Issuer: /CN=8R-CA 1:PN/O=Regulierungsbehörde für
#               Telekommunikation und Post/C=DE
42:6A:F6:78:30:E9:CE:24:5B:EF:41:A2:C1:A8:51:DA:C5:0A:6D:F5  S

#Serial number: 02
#       Issuer: /CN=9R-CA 1:PN/O=Regulierungsbehörde für
#               Telekommunikation und Post/C=DE
75:9A:4A:CE:7C:DA:7E:89:1B:B2:72:4B:E3:76:EA:47:3A:96:97:24  S

#Serial number: 2A
#       Issuer: /CN=10R-CA 1:PN/O=Bundesnetzagentur/C=DE
31:C9:D2:E6:31:4D:0B:CC:2C:1A:45:00:A6:6B:97:98:27:18:8E:CD  S

#Serial number: 2D
#       Issuer: /CN=11R-CA 1:PN/O=Bundesnetzagentur/C=DE
A0:8B:DF:3B:AA:EE:3F:9D:64:6C:47:81:23:21:D4:A6:18:81:67:1D  S

#          S/N: 0139
#       Issuer: /CN=12R-CA 1:PN/O=Bundesnetzagentur/C=DE
44:7E:D4:E3:9A:D7:92:E2:07:FA:53:1A:2E:F5:B8:02:5B:47:57:B0  de

#          S/N: 013C
#       Issuer: /CN=13R-CA 1:PN/O=Bundesnetzagentur/C=DE
AC:A7:BE:45:1F:A6:BF:09:F2:D1:3F:08:7B:BC:EB:7F:46:A2:CC:8A  de


#          S/N: 00B3963E0E6C2D65125853E970665402E5
#       Issuer: /CN=S-TRUST Qualified Root CA 2008-001:PN
#               /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE
C9:2F:E6:50:DB:32:59:E0:CE:65:55:F3:8C:76:E0:B8:A8:FE:A3:CA  S

#          S/N: 00C4216083F35C54F67B09A80C3C55FE7D
#       Issuer: /CN=S-TRUST Qualified Root CA 2008-002:PN
#               /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE
D5:C7:50:F2:FE:4E:EE:D7:C7:B1:E4:13:7B:FB:54:84:3A:7D:97:9B  S


#Serial number: 00
#       Issuer: /CN=CA Cert Signing Authority/OU=http:\x2f\x2fwww.
#               cacert.org/O=Root CA/EMail=support@cacert.org
13:5C:EC:36:F4:9C:B8:E9:3B:1A:B2:70:CD:80:88:46:76:CE:8F:33  S


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             PNG

   
IHDR       Q>"   PLTE       `mw@    IDATx	*ӆ._Q ³_WL<`}jPĬ|$ADDo36 H@r\Hey/*%HHI_KEz\@^-e_^o/?VG}l_.st:VH+K/DD$ѕ'wQ躈2Kvu1hZX@=$-L~拾|[99Dw	M3:HJݿ_J#ݿ!A3XBk,OZݿ"	LTuL	Lӫu7M`bSjPM$" ɧH>E@)gWF!;ttNXgHJRaI)//:#4Z)$wo>JrU'!xGHF};^bb$%ꣂNr9Qʌ}܀$OC)0]Iz]T|-$$#j<+üHE0KY-l	}]ahLR=\E)IZ7b$ʱu$#}&p&)1eD2Ga	KrDC@0"@r`9H~Qf[(|CAXʌHEoi'p&)L+$[$UL@rI$@+%IH7`}7M`b$W!|Ɂ匮>yc/bhy=(6DHErQ,GTAz{_z)w$f[˦sX!5s}ŘL#Y y-ISlb$⃰⋘DiÒ<
eČXĤf6'^@rPjh}2c:K@r(ue9&5%1vm$G!Y	L|S$" i$z-=.<On:$	EJn:$ y`t[bHuH'$@A1(i]G? d䫛$)VɁ䎮:$Iň 9<$@E(IȋyCI'ɚ7#E`!>6d@o/zr4$uaruEF@iuO|S&xc$Ղ1W=JxO>FJ#@$#:D?{&̝V@)($|ۈjI1von+*$&Og
$L>E6}L3;J )5{|RJ yH>E+<5w.@RԅH*PIU3J 
H>E3W iB	$5M\(& ^y%$i+4P@дHOѬ%45kE	$MZQIK@)&(I+J iH>EsV@|l I[s6yC@)ɧh&j3ts}
HmXHQ^ol*E<RA7c=/d ́*-Gk,$n9~rH`%Fn#dG?VH&
H	H$K$$}2OC$r@ҧlD3rIӐ(Iʫ>Ւ$yHzK$$!i4^ddW@P@N@+ Y( YHk{Àd$u3mtTH YL5dd!iO@P@N@+ YH]@2U@N@/ Y& Y' ,H	H	H$$$eu~2G@l$@l$~eJ%IL:5ˤ=HN|J@/ YT]Szԓ!)!IgJ: ڪ?ՐLIĊ,"j:Gr5IJn޺$.Va&!Z6ЪBcEhIRzC05(0ӘmF\>GBn($Y>a{b
UH$[7`j%0GQI-|Cg!,$)L$($BW##I})
;owdGAV,Ys"I'I,'T,_J2n9-E:LXPzV~K$J2^;Q^]&"d
g!uL#؝dg o0#aILk5#V=II[*G$$>gGUF$Y<g"Z[<S:i#ɫ$g!w3Y>II~#4xu0nZ/!n׶iJ;ZbBzIsU9dpl'W,,?nl>:IQcC3{Е5w\x%'d?]ك#cH>n$"WLK\]i>Ӱ$L%5o곁w	I
Eg1RO!	mH=
m<.&	m2ٹP=N!	m\]Gr=́k"I!ܹ$ONؾ*%IeѮٚ޵P$H~iCSꬬg$1'ٵPW$*;t$Y\zz(dLJ96T1n]Y$_ #+
Y!iQnJNѫP@2Y?z9,TT:S#$O]n3xdڮkB	$U<r̦k$]N2
$O\3 Y*HA:B$*Hǰ"	 _G@dQN	$UC8Ր$UUSMN
$UE	
':$]"I]u$#B7:=dv@E9$Gh9=@zU$KTqJUNI'9C2w([H> $Y!gqGUSDKH)3pо6D㚗f$w JH!Ih1Ls	
${)FL"tFWBSape>'O"$a1$d#: IC1V#tc$1}0Bg( ėA1
Hꊒt3$(vHhVt-T$JrMJ Z<+-a$N \FBk]T~B6$q՞{2Y_&א$QH~BR)%$դ`y珚|$ǑLrwӗtVJP!$MG(v*$S`zSGWDzWta#~IEt|׫Y-; IKÐ$cog=$;:Έ;4ɕ?$U\ I\AH'yIE#yjۈ$S;3:<,Lآ	]%xJT!-Vt%D}IEƃ}]mC}LylPE[ Rأ}Ϗ`T:j9ڂG%b%Q2H$KMzLrW yaf},8{U}!In };{च2IfT$%FWtF7[4j@RNDCUgZi\L/I"vRV1b$u=#J
!|`I?Ŕ$ZO򎮃$ңfCBrGׂ	>")}$*l$I|]E>Dp}IQ[<YgIʲr-:()T.l'oX?fOFǞ>\@R^v$,kG.c$g$F+ΒeדuZϮ[LSK2GS;$3mZ0m_]0tWgV'IH!IԓgvVďUo7!Y֑EI:sM#>4
;<!'IO>q)>X+I IbgI,*Ig,z֣MhJ"G2:@u<;lG~2d)2H{,H
#9I!wμTjtuιʩW,3f bBG?bʗ=HKPFWm!))1N]k"j}(3fM5gHHbYh,T@$aݙEzdX$ףSgte ={\6c$+xSI*ǜ]{LB$W>E\E"~p<I$Z&${ʅ2gl\]$R&H®L𖏒:Qkk,HP֑鹵>GpB{<	FW2&b%oh=T(V
>2Q<;jOR>=ZKFGҚV$A&e3|l	>^7h]T?iծHgKcd^!S:
JQmiAHj2X0'˵d}+E+U5[.78#$69ϵg6s& ޛ]{_HenVUjZ}"鸒+VJҶ~fX|LG&I8?Y+ǈ=kkJ(O:#VOv*!82IyIJV$rż"-d>6YfIrt-@Rg-Lҍ%Om+p$ Io,+[$.\{H~Rpe>琱!8<o!p++[!{"IǉM]WV i?^\`HGñӌ҉Er8#E>|GLotԋŮOf /HI.adHR{Hjbsw[J\ʺ?S&I8NZo$o+	UI!{^:콘!8I`tUHŽIEÐ\H6ɔH@C/7I$?^IzO/"~Iw(I>HЎ$CqIRiw'^%\
n].T?wm5bR ?r2IE֏$uR)$WrD"$ٳ5'b?=s҆$[;0@Rυ9=3DM"~teB*+
}MΤ"GĘ[99H||Qa46I'oq`a,Ð\F8I$'*rd?c&o&eٰ}nrv9IՁ} TI|L"~1뼖
iL|"?PI
z!EȩL,誕hIBDg"+YA7Ov6zI"Ιŧ(ѕMf/HđAmtN@=)/?%=,!U1`Ӂx]ʽ]?(w>SiN9B 8vԡQ&wn<Kx73PV&YjKb~qb>8lOB@|I=/\nK<=uT$Abz,i"'Ih,Y$8a:StyiIҿ0>d]Cu ^) 0I@ uIW؊O>IKID':P8LrDWq]tE$=
xQQ,"fsnz?'oG9ߘ>D`/r^BÁ5$I~.ܰs$L^II`6rH&(dտʋ@Ԥ$=@kbFnDCۮ#d!mWǍ-sсtBjۮfaEI@b Tۮ͌ˁ"w/(DkoI@	iNlgp4߬dmI]W;5I$#I#y̋$uGrO
HvD}I]p>Y>$d 8	NhY);2]#6]#]Y4.0%e==<'Ck!CH)zzpk8uJ+pN2vyX;G/6[mIfM$$@$@Ht$oK?IBEkУHK$EψI$o5q]$,t'>Fj"3ETG⇐ޠNm]$Y˫tDcyH|>-%7=?$J_IrFÁd=:CRltH=DY$#8%)HKIDY$8c6U>;$>O'h(ѕp`$IY$?Akb$

Cr=H($DmH҃'דzL&&G92Ij%H'
IIhY$-Z<|LxAvkexɹ:y>+tZvNI{z"y$YjӁ$Huwݚ+ 	$H' 	$$d왰@2%q2I#,IYILy$CCĳʼn,d86{$UdWÇwo39񮻻p]΍YӜ=E/{;ntw߼|r8?O7C<93.O$\
$՗d$@r5I19el#*
Hz JS$SW+DIR'^*pS8^7	b$_skp4}%9  \uy>[yYϩ-.rXpߚOf!S*Se=Iz;uK<: 9IixRmuM<~a$" Hf5yGWWl2-)GWh	ny7!	W]Q7YH>ɬr˽>)V5W--Ifɗ_-E/tIPPt8^d _Х\Xm_ܲv6O@$7$?/d@?2Ӿ^XI>MXI/"ݴ!TEқi`]φg,ݳ_J<g^$SY JDw+p@$D$k-o+yC- &'XDw3Qn$bO_|jIyOOGJx\r2+{5*mikC
ɲ|~cߤX%y$Du5-e?ɴTNrdne,J)Q[Rb%N2+;IX^]T܃27y3We׏: ݲHI5\#&̧{MrKIT;=ߣ$$cZB}eg[R*{O82f
".).Rg,pnE9U0W~ޞVgA'/$YY͎$:#VeGƻ")a8trV[mѦyI&x?=6ahv#پX7gI}Gfu]ԋd._j]H&2YĦ}7ffeuJ>ɴ=E-+trX?mxٿB2h9-V^كl_ׇV#KuG2䒬qHe["{3M^@0=ej[eH^Q-YjyL+?nI٣b}7J9ĳةz2'nYJֲ_{_kT$7ѫ{cűQvmvFt#LWOv6a;!CiֱEβH{ds-:V}l$7LVqڎUEO@!j,'{KfYY]hRR;-
͛(detngIS&iiUdU㣖䝝oqeсLַZDi$i}UҤ\:z]{IG!\~1'ͯ*eq KzoJу}iӺrG"_V1Ag6\q/s4A}  IDAT{6^crUJ':\6"ěV}:䚤p-6:Z4{]7TBr`ڡSjɨ$hJAMS2R52!zʨ5RTL}2y4qHIv7֢H^{}VmeRjx:W?}^ &*'ٵ)ަ1ΑMSU-~M8tn(ۄn mT5?@2g61tg@2k&MCX$PnrJ\.$s7l|*#lH~RoUi/BՌdMler+6H6PZ3$q=$y
ԡe$YHn8ln9QHP+~%'+M ɱ0"HN 2$B?AH+k
oqB4CtO64BtRy2A@)O>E@)O|Sw<EI$Kmn)(,W1J8dNPL&C,ɧY0l    IENDB`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Yr:}'FutO3kPIӔcb,Ɨįϒel9u*7vqN6-ۛ8ou5y$M]dy,SxdiE!~7ꤦ	
?g/daI0[0-On؍e~#󨐯"0E2JioUNU?I2!H 7G	r'tPLfPkPY*2(tJ7uGr3_j{Yl[YpP!I$:΋,~-AtO\ǛO8$k
k{V Js"7/c	YI8i'9ՑQk~tiZI7;eFA
?IBVd]UڝieX."q?FSnLgwsc<]dg_8X`5\-4? Öݒ/U}!HleTHoS^)<}ˍpUf o⓬C˰bgt]n׍md|6dp*#JfWV27loi
]m߳οܴ-ǒU%5/jᖬᨖֿMӼJ#M[oo{cxc6UC@~3G42=RlnOIIC Nl=zP"&NđZsz`*
A~0{3QGjS߿,ZX@2yOVvD.
a9=މ0z3q
dGQzYh2zőYܵ
;#/A,S!X[0^/F&ޖY`<@yI~6g]d+q.d!#mօǓbum:=,ώU=^GuMhU`|	V10Yg1rLţpy.bSb9	jl}h>./r80>QGw+ߋb<\MfX>4_f*{mqk^o@zCo|19=*DV=ȸHe!zDyѪ?krI4Ytn{MCW>/@Շtt~ks&G|=ק@u}YK
 }NunjK+s{nMiJWqtfr}}!r׺rqJV{r3]EkdSA,mrޮ7?~+f2kS-qPTyY*p;ܔS9DY	EHW	MCYyYGqGVsP\9Y8L#qgjj2V1ӝqMl箣T>:3;-f
(MAaQ05yJ,U1ۤjQR`ȘҲsuvH
,V{ڔ5!CYSVcF+C饕(jٶJ6wx#sYm3sϹ,ثekP7&V:8tlt}>L/+"ܱ dWuI\-uYA^
0
܁2#څY.*WLd <{02/sОfFUYmr˫(;o]hw|Zde!U%,ĴND*we,F]k|;ִ:Nt\=rA@d>YN~:ȉuc<
(uBDuD;W0ZVrpJk;	H!mL\
_HEϖ(rQXn͜Gܮu5ս&gp#Q=]&O9c)Qo5wL`8WSnRb
5=WnYpLg\}(;qh;b~3fYTێYP4Y@Y6ӲjDyAƣni'"c&krH}#یr2W[&5t,zaV=%{	ꒄ/^@-I_?դ-ռT]{=p6?+ХOTw1U&6y
"Ru! 'W:?By-dk@VBx!&9#4}Z \d%e5KcdoѮzQ3e+Eq[HӜm_07JZ#h~+&Gٺmo礐N]l1;2" _A\G Ry(azn.؟5sیvautW0)-7zl?,Bw1>hfkGaafN+DS\qUYm JF%`_Su!綬FE&(cb9;A}'G5RfiWUpt7Y
zj
D[̴o~Vؚ<ȏBG]FF	ZVY1_)ϼ{2CM@ڰ~p?cܪg־ϧG3f믲P޳p\("\6.Dzvf..J
Ǡ!>(BzW"sT2oADw`%j&3hE-3%5<Hp)g@QM#syN?&{day| q&/5ުOhضz)\=?{K~;ޒ,
I                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                eSMo0W9@FnǶ K)C.-dGRvD=r?0*Zة7m+%_(xǘp-o{e[Y60YDLff>^aЗ42z!=b?]tT*輫=a(Wi#Ɩ: BP<*KFWl.jgm	uD#-U0xօ)(਍#qEJ}.pm˘F[E)LbKV}L@nT)Jwp>L|Q؀uܫd>ѱ2R8kzF S`ڒS^'HoW.ؽjZ/.pF;8W5gX+G a]㑜b[:)͑ZUK*.h4ps F/p;zM)Q9)Xjs{(#1M^*&H-82*64xߒ>2ٍ_V$bUk?xÊ׏C?`<͔g0R~EmTSX:!sPmSWYizXL	>(F ,
К@:5,L*i?7IL]-eM
,m2                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            /.
/usr
/usr/share
/usr/share/doc
/usr/share/doc/gnupg
/usr/share/doc/gnupg/DCO
/usr/share/doc/gnupg/DETAILS.gz
/usr/share/doc/gnupg/FAQ
/usr/share/doc/gnupg/HACKING.gz
/usr/share/doc/gnupg/KEYSERVER
/usr/share/doc/gnupg/NEWS.Debian.gz
/usr/share/doc/gnupg/NEWS.gz
/usr/share/doc/gnupg/OpenPGP.gz
/usr/share/doc/gnupg/README.Debian
/usr/share/doc/gnupg/README.gz
/usr/share/doc/gnupg/THANKS.gz
/usr/share/doc/gnupg/TODO
/usr/share/doc/gnupg/TRANSLATE
/usr/share/doc/gnupg/changelog.Debian.gz
/usr/share/doc/gnupg/changelog.gz
/usr/share/doc/gnupg/copyright
/usr/share/doc/gnupg/examples
/usr/share/doc/gnupg/examples/Automatic.prf
/usr/share/doc/gnupg/examples/README
/usr/share/doc/gnupg/examples/VS-NfD.prf
/usr/share/doc/gnupg/examples/debug.prf
/usr/share/doc/gnupg/examples/gpgconf.conf
/usr/share/doc/gnupg/examples/gpgconf.rnames
/usr/share/doc/gnupg/examples/pwpattern.list
/usr/share/doc/gnupg/examples/scd-event
/usr/share/doc/gnupg/examples/systemd-user
/usr/share/doc/gnupg/examples/systemd-user/README
/usr/share/doc/gnupg/examples/systemd-user/dirmngr.service
/usr/share/doc/gnupg/examples/systemd-user/dirmngr.socket
/usr/share/doc/gnupg/examples/systemd-user/gpg-agent-browser.socket
/usr/share/doc/gnupg/examples/systemd-user/gpg-agent-extra.socket
/usr/share/doc/gnupg/examples/systemd-user/gpg-agent-ssh.socket
/usr/share/doc/gnupg/examples/systemd-user/gpg-agent.service
/usr/share/doc/gnupg/examples/systemd-user/gpg-agent.socket
/usr/share/doc/gnupg/examples/trustlist.txt
/usr/share/info
/usr/share/info/gnupg-card-architecture.png
/usr/share/info/gnupg-module-overview.png
/usr/share/info/gnupg.info-1.gz
/usr/share/info/gnupg.info-2.gz
/usr/share/info/gnupg.info.gz
/usr/share/man
/usr/share/man/man7
/usr/share/man/man7/gnupg.7.gz
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Package: gnupg
Status: install reinstreq unpacked
Priority: optional
Section: utils
Installed-Size: 885
Maintainer: Debian GnuPG Maintainers <pkg-gnupg-maint@lists.alioth.debian.org>
Architecture: all
Multi-Arch: foreign
Source: gnupg2
Version: 2.2.40-1.1+deb12u1
Replaces: gnupg2 (<< 2.1.11-7+exp1)
Depends: dirmngr (<< 2.2.40-1.1+deb12u1.1~), dirmngr (>= 2.2.40-1.1+deb12u1), gnupg-l10n (= 2.2.40-1.1+deb12u1), gnupg-utils (<< 2.2.40-1.1+deb12u1.1~), gnupg-utils (>= 2.2.40-1.1+deb12u1), gpg (<< 2.2.40-1.1+deb12u1.1~), gpg (>= 2.2.40-1.1+deb12u1), gpg-agent (<< 2.2.40-1.1+deb12u1.1~), gpg-agent (>= 2.2.40-1.1+deb12u1), gpg-wks-client (<< 2.2.40-1.1+deb12u1.1~), gpg-wks-client (>= 2.2.40-1.1+deb12u1), gpg-wks-server (<< 2.2.40-1.1+deb12u1.1~), gpg-wks-server (>= 2.2.40-1.1+deb12u1), gpgsm (<< 2.2.40-1.1+deb12u1.1~), gpgsm (>= 2.2.40-1.1+deb12u1), gpgv (<< 2.2.40-1.1+deb12u1.1~), gpgv (>= 2.2.40-1.1+deb12u1)
Suggests: parcimonie, xloadimage
Breaks: debsig-verify (<< 0.15), dirmngr (<< 2.2.40-1.1+deb12u1), gnupg2 (<< 2.1.11-7+exp1), libgnupg-interface-perl (<< 0.52-3), libgnupg-perl (<= 0.19-1), libmail-gnupg-perl (<= 0.22-1), monkeysphere (<< 0.38~), php-crypt-gpg (<= 1.4.1-1), python-apt (<= 1.1.0~beta4), python-gnupg (<< 0.3.8-3), python3-apt (<= 1.1.0~beta4)
Description: GNU privacy guard - a free PGP replacement
 GnuPG is GNU's tool for secure communication and data storage.
 It can be used to encrypt data and to create digital signatures.
 It includes an advanced key management facility and is compliant
 with the proposed OpenPGP Internet standard as described in RFC4880.
 .
 This package contains the full suite of GnuPG tools for cryptographic
 communications and data storage.
Homepage: https://www.gnupg.org/
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Package: gnupg
Status: install ok unpacked
Priority: optional
Section: utils
Installed-Size: 885
Maintainer: Debian GnuPG Maintainers <pkg-gnupg-maint@lists.alioth.debian.org>
Architecture: all
Multi-Arch: foreign
Source: gnupg2
Version: 2.2.40-1.1+deb12u1
Replaces: gnupg2 (<< 2.1.11-7+exp1)
Depends: dirmngr (<< 2.2.40-1.1+deb12u1.1~), dirmngr (>= 2.2.40-1.1+deb12u1), gnupg-l10n (= 2.2.40-1.1+deb12u1), gnupg-utils (<< 2.2.40-1.1+deb12u1.1~), gnupg-utils (>= 2.2.40-1.1+deb12u1), gpg (<< 2.2.40-1.1+deb12u1.1~), gpg (>= 2.2.40-1.1+deb12u1), gpg-agent (<< 2.2.40-1.1+deb12u1.1~), gpg-agent (>= 2.2.40-1.1+deb12u1), gpg-wks-client (<< 2.2.40-1.1+deb12u1.1~), gpg-wks-client (>= 2.2.40-1.1+deb12u1), gpg-wks-server (<< 2.2.40-1.1+deb12u1.1~), gpg-wks-server (>= 2.2.40-1.1+deb12u1), gpgsm (<< 2.2.40-1.1+deb12u1.1~), gpgsm (>= 2.2.40-1.1+deb12u1), gpgv (<< 2.2.40-1.1+deb12u1.1~), gpgv (>= 2.2.40-1.1+deb12u1)
Suggests: parcimonie, xloadimage
Breaks: debsig-verify (<< 0.15), dirmngr (<< 2.2.40-1.1+deb12u1), gnupg2 (<< 2.1.11-7+exp1), libgnupg-interface-perl (<< 0.52-3), libgnupg-perl (<= 0.19-1), libmail-gnupg-perl (<= 0.22-1), monkeysphere (<< 0.38~), php-crypt-gpg (<= 1.4.1-1), python-apt (<= 1.1.0~beta4), python-gnupg (<< 0.3.8-3), python3-apt (<= 1.1.0~beta4)
Description: GNU privacy guard - a free PGP replacement
 GnuPG is GNU's tool for secure communication and data storage.
 It can be used to encrypt data and to create digital signatures.
 It includes an advanced key management facility and is compliant
 with the proposed OpenPGP Internet standard as described in RFC4880.
 .
 This package contains the full suite of GnuPG tools for cryptographic
 communications and data storage.
Homepage: https://www.gnupg.org/
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           libnl-3.so.200 libnl-3-200 #MINVER#
 __flags2str@Base 3.2.7
 __list_str2type@Base 3.2.7
 __list_type2str@Base 3.2.7
 __nl_cache_mngt_require@Base 3.2.7
 __nl_cache_ops_lookup@Base 3.2.21
 __nl_read_num_str_file@Base 3.2.7
 __str2flags@Base 3.2.7
 __str2type@Base 3.2.7
 __trans_list_add@Base 3.2.7
 __trans_list_clear@Base 3.2.7
 __type2str@Base 3.2.7
 _nl_socket_generate_local_port_no_release@Base 3.2.26
 _nl_socket_is_local_port_unspecified@Base 3.2.26
 _nl_socket_set_local_port_no_release@Base 3.2.27
 _nl_socket_used_ports_release_all@Base 3.2.26
 _nl_socket_used_ports_set@Base 3.2.26
 dump_from_ops@Base 3.2.7
 mpls_ntop@Base 3.4.0
 mpls_pton@Base 3.4.0
 nl_addr2str@Base 3.2.7
 nl_addr_alloc@Base 3.2.7
 nl_addr_alloc_attr@Base 3.2.7
 nl_addr_build@Base 3.2.7
 nl_addr_clone@Base 3.2.7
 nl_addr_cmp@Base 3.2.7
 nl_addr_cmp_prefix@Base 3.2.7
 nl_addr_fill_sockaddr@Base 3.2.7
 nl_addr_get@Base 3.2.7
 nl_addr_get_binary_addr@Base 3.2.7
 nl_addr_get_family@Base 3.2.7
 nl_addr_get_len@Base 3.2.7
 nl_addr_get_prefixlen@Base 3.2.7
 nl_addr_guess_family@Base 3.2.7
 nl_addr_info@Base 3.2.7
 nl_addr_iszero@Base 3.2.7
 nl_addr_parse@Base 3.2.7
 nl_addr_put@Base 3.2.7
 nl_addr_resolve@Base 3.2.7
 nl_addr_set_binary_addr@Base 3.2.7
 nl_addr_set_family@Base 3.2.7
 nl_addr_set_prefixlen@Base 3.2.7
 nl_addr_shared@Base 3.2.7
 nl_addr_valid@Base 3.2.7
 nl_af2str@Base 3.2.7
 nl_auto_complete@Base 3.2.7
 nl_cache_add@Base 3.2.7
 nl_cache_alloc@Base 3.2.7
 nl_cache_alloc_and_fill@Base 3.2.7
 nl_cache_alloc_name@Base 3.2.7
 nl_cache_clear@Base 3.2.7
 nl_cache_clone@Base 3.2.21
 nl_cache_dump@Base 3.2.7
 nl_cache_dump_filter@Base 3.2.7
 nl_cache_find@Base 3.2.21
 nl_cache_foreach@Base 3.2.7
 nl_cache_foreach_filter@Base 3.2.7
 nl_cache_free@Base 3.2.7
 nl_cache_get@Base 3.2.21
 nl_cache_get_first@Base 3.2.7
 nl_cache_get_last@Base 3.2.7
 nl_cache_get_next@Base 3.2.7
 nl_cache_get_ops@Base 3.2.7
 nl_cache_get_prev@Base 3.2.7
 nl_cache_include@Base 3.2.7
 nl_cache_include_v2@Base 3.4.0
 nl_cache_is_empty@Base 3.2.7
 nl_cache_mark_all@Base 3.2.7
 nl_cache_mngr_add@Base 3.2.7
 nl_cache_mngr_add_cache@Base 3.2.21
 nl_cache_mngr_add_cache_v2@Base 3.4.0
 nl_cache_mngr_alloc@Base 3.2.7
 nl_cache_mngr_data_ready@Base 3.2.7
 nl_cache_mngr_free@Base 3.2.7
 nl_cache_mngr_get_fd@Base 3.2.7
 nl_cache_mngr_info@Base 3.2.21
 nl_cache_mngr_poll@Base 3.2.7
 nl_cache_mngt_provide@Base 3.2.7
 nl_cache_mngt_register@Base 3.2.7
 nl_cache_mngt_require@Base 3.2.7
 nl_cache_mngt_require_safe@Base 3.2.21
 nl_cache_mngt_unprovide@Base 3.2.7
 nl_cache_mngt_unregister@Base 3.2.7
 nl_cache_move@Base 3.2.7
 nl_cache_nitems@Base 3.2.7
 nl_cache_nitems_filter@Base 3.2.7
 nl_cache_ops_associate@Base 3.2.7
 nl_cache_ops_associate_safe@Base 3.2.21
 nl_cache_ops_foreach@Base 3.2.7
 nl_cache_ops_get@Base 3.2.21
 nl_cache_ops_lookup@Base 3.2.7
 nl_cache_ops_lookup_safe@Base 3.2.21
 nl_cache_ops_put@Base 3.2.21
 nl_cache_ops_set_flags@Base 3.2.21
 nl_cache_parse@Base 3.2.7
 nl_cache_parse_and_add@Base 3.2.7
 nl_cache_pickup@Base 3.2.7
 nl_cache_pickup_checkdup@Base 3.2.26
 nl_cache_put@Base 3.2.21
 nl_cache_refill@Base 3.2.7
 nl_cache_remove@Base 3.2.7
 nl_cache_resync@Base 3.2.7
 nl_cache_search@Base 3.2.7
 nl_cache_set_arg1@Base 3.2.7
 nl_cache_set_arg2@Base 3.2.7
 nl_cache_set_flags@Base 3.2.21
 nl_cache_subset@Base 3.2.7
 nl_cancel_down_bits@Base 3.2.7
 nl_cancel_down_bytes@Base 3.2.7
 nl_cancel_down_us@Base 3.2.7
 nl_cb_active_type@Base 3.2.24
 nl_cb_alloc@Base 3.2.7
 nl_cb_clone@Base 3.2.7
 nl_cb_err@Base 3.2.7
 nl_cb_get@Base 3.2.7
 nl_cb_overwrite_recv@Base 3.2.7
 nl_cb_overwrite_recvmsgs@Base 3.2.7
 nl_cb_overwrite_send@Base 3.2.7
 nl_cb_put@Base 3.2.7
 nl_cb_set@Base 3.2.7
 nl_cb_set_all@Base 3.2.7
 nl_close@Base 3.2.7
 nl_complete_msg@Base 3.2.7
 nl_connect@Base 3.2.7
 nl_data_alloc@Base 3.2.7
 nl_data_alloc_attr@Base 3.2.7
 nl_data_append@Base 3.2.7
 nl_data_clone@Base 3.2.7
 nl_data_cmp@Base 3.2.7
 nl_data_free@Base 3.2.7
 nl_data_get@Base 3.2.7
 nl_data_get_size@Base 3.2.7
 nl_debug@Base 3.2.7
 nl_debug_dp@Base 3.2.7
 nl_dump@Base 3.2.7
 nl_dump_line@Base 3.2.7
 nl_ether_proto2str@Base 3.2.7
 nl_get_psched_hz@Base 3.2.21
 nl_get_user_hz@Base 3.2.7
 nl_geterror@Base 3.2.7
 nl_has_capability@Base 3.2.26
 nl_hash@Base 3.2.21
 nl_hash_any@Base 3.2.21
 nl_hash_table_add@Base 3.2.21
 nl_hash_table_alloc@Base 3.2.21
 nl_hash_table_del@Base 3.2.21
 nl_hash_table_free@Base 3.2.21
 nl_hash_table_lookup@Base 3.2.21
 nl_ip_proto2str@Base 3.2.7
 nl_join_groups@Base 3.2.7
 nl_llproto2str@Base 3.2.7
 nl_msec2str@Base 3.2.7
 nl_msg_dump@Base 3.2.7
 nl_msg_parse@Base 3.2.7
 nl_msgtype_lookup@Base 3.2.7
 nl_new_line@Base 3.2.7
 nl_nlfamily2str@Base 3.2.7
 nl_nlmsg_flags2str@Base 3.2.7
 nl_nlmsgtype2str@Base 3.2.7
 nl_object_alloc@Base 3.2.7
 nl_object_alloc_name@Base 3.2.7
 nl_object_attr_list@Base 3.2.7
 nl_object_attrs2str@Base 3.2.7
 nl_object_clone@Base 3.2.7
 nl_object_diff64@Base 3.4.0
 nl_object_diff@Base 3.2.7
 nl_object_dump@Base 3.2.7
 nl_object_dump_buf@Base 3.2.7
 nl_object_free@Base 3.2.7
 nl_object_get@Base 3.2.7
 nl_object_get_cache@Base 3.2.7
 nl_object_get_id_attrs@Base 3.2.21
 nl_object_get_msgtype@Base 3.2.21
 nl_object_get_ops@Base 3.2.21
 nl_object_get_refcnt@Base 3.2.7
 nl_object_get_type@Base 3.2.21
 nl_object_identical@Base 3.2.7
 nl_object_is_marked@Base 3.2.7
 nl_object_keygen@Base 3.2.21
 nl_object_mark@Base 3.2.7
 nl_object_match_filter@Base 3.2.7
 nl_object_put@Base 3.2.7
 nl_object_shared@Base 3.2.7
 nl_object_unmark@Base 3.2.7
 nl_object_update@Base 3.2.21
 nl_perror@Base 3.2.7
 nl_pickup@Base 3.2.7
 nl_pickup_keep_syserr@Base 3.2.26
 nl_prob2int@Base 3.2.7
 nl_rate2str@Base 3.2.7
 nl_recv@Base 3.2.7
 nl_recvmsgs@Base 3.2.7
 nl_recvmsgs_default@Base 3.2.7
 nl_recvmsgs_report@Base 3.2.21
 nl_send@Base 3.2.7
 nl_send_auto@Base 3.2.7
 nl_send_auto_complete@Base 3.2.7
 nl_send_iovec@Base 3.2.7
 nl_send_simple@Base 3.2.7
 nl_send_sync@Base 3.2.7
 nl_sendmsg@Base 3.2.7
 nl_sendto@Base 3.2.7
 nl_size2int@Base 3.2.7
 nl_size2str@Base 3.2.7
 nl_socket_add_membership@Base 3.2.7
 nl_socket_add_memberships@Base 3.2.7
 nl_socket_alloc@Base 3.2.7
 nl_socket_alloc_cb@Base 3.2.7
 nl_socket_disable_auto_ack@Base 3.2.7
 nl_socket_disable_msg_peek@Base 3.2.7
 nl_socket_disable_seq_check@Base 3.2.7
 nl_socket_drop_membership@Base 3.2.7
 nl_socket_drop_memberships@Base 3.2.7
 nl_socket_enable_auto_ack@Base 3.2.7
 nl_socket_enable_msg_peek@Base 3.2.7
 nl_socket_free@Base 3.2.7
 nl_socket_get_cb@Base 3.2.7
 nl_socket_get_fd@Base 3.2.7
 nl_socket_get_local_port@Base 3.2.7
 nl_socket_get_msg_buf_size@Base 3.2.21
 nl_socket_get_peer_groups@Base 3.2.7
 nl_socket_get_peer_port@Base 3.2.7
 nl_socket_modify_cb@Base 3.2.7
 nl_socket_modify_err_cb@Base 3.2.7
 nl_socket_recv_pktinfo@Base 3.2.7
 nl_socket_set_buffer_size@Base 3.2.7
 nl_socket_set_cb@Base 3.2.7
 nl_socket_set_fd@Base 3.2.26
 nl_socket_set_local_port@Base 3.2.7
 nl_socket_set_msg_buf_size@Base 3.2.21
 nl_socket_set_nonblocking@Base 3.2.7
 nl_socket_set_passcred@Base 3.2.7
 nl_socket_set_peer_groups@Base 3.2.7
 nl_socket_set_peer_port@Base 3.2.7
 nl_socket_use_seq@Base 3.2.7
 nl_str2af@Base 3.2.7
 nl_str2ether_proto@Base 3.2.7
 nl_str2ip_proto@Base 3.2.7
 nl_str2llproto@Base 3.2.7
 nl_str2msec@Base 3.2.7
 nl_str2nlfamily@Base 3.2.7
 nl_str2nlmsgtype@Base 3.2.7
 nl_strerror_l@Base 3.4.0
 nl_syserr2nlerr@Base 3.2.7
 nl_ticks2us@Base 3.2.7
 nl_us2ticks@Base 3.2.7
 nl_ver_maj@Base 3.2.21
 nl_ver_mic@Base 3.2.21
 nl_ver_min@Base 3.2.21
 nl_ver_num@Base 3.2.21
 nl_wait_for_ack@Base 3.2.7
 nla_attr_size@Base 3.2.7
 nla_data@Base 3.2.7
 nla_find@Base 3.2.7
 nla_get_flag@Base 3.2.7
 nla_get_msecs@Base 3.2.7
 nla_get_s16@Base 3.2.27
 nla_get_s32@Base 3.2.27
 nla_get_s64@Base 3.2.27
 nla_get_s8@Base 3.2.27
 nla_get_string@Base 3.2.7
 nla_get_u16@Base 3.2.7
 nla_get_u32@Base 3.2.7
 nla_get_u64@Base 3.2.7
 nla_get_u8@Base 3.2.7
 nla_is_nested@Base 3.2.24
 nla_len@Base 3.2.7
 nla_memcmp@Base 3.2.7
 nla_memcpy@Base 3.2.7
 nla_nest_cancel@Base 3.2.24
 nla_nest_end@Base 3.2.7
 nla_nest_end_keep_empty@Base 3.5.0
 nla_nest_start@Base 3.2.7
 nla_next@Base 3.2.7
 nla_ok@Base 3.2.7
 nla_padlen@Base 3.2.7
 nla_parse@Base 3.2.7
 nla_parse_nested@Base 3.2.7
 nla_put@Base 3.2.7
 nla_put_addr@Base 3.2.7
 nla_put_data@Base 3.2.7
 nla_put_flag@Base 3.2.7
 nla_put_msecs@Base 3.2.7
 nla_put_nested@Base 3.2.7
 nla_put_s16@Base 3.2.27
 nla_put_s32@Base 3.2.27
 nla_put_s64@Base 3.2.27
 nla_put_s8@Base 3.2.27
 nla_put_string@Base 3.2.7
 nla_put_u16@Base 3.2.7
 nla_put_u32@Base 3.2.7
 nla_put_u64@Base 3.2.7
 nla_put_u8@Base 3.2.7
 nla_reserve@Base 3.2.7
 nla_strcmp@Base 3.2.7
 nla_strdup@Base 3.2.7
 nla_strlcpy@Base 3.2.7
 nla_total_size@Base 3.2.7
 nla_type@Base 3.2.7
 nla_validate@Base 3.2.7
 nlmsg_alloc@Base 3.2.7
 nlmsg_alloc_simple@Base 3.2.7
 nlmsg_alloc_size@Base 3.2.7
 nlmsg_append@Base 3.2.7
 nlmsg_attrdata@Base 3.2.7
 nlmsg_attrlen@Base 3.2.7
 nlmsg_convert@Base 3.2.7
 nlmsg_data@Base 3.2.7
 nlmsg_datalen@Base 3.2.7
 nlmsg_expand@Base 3.2.7
 nlmsg_find_attr@Base 3.2.7
 nlmsg_free@Base 3.2.7
 nlmsg_get@Base 3.2.7
 nlmsg_get_creds@Base 3.2.7
 nlmsg_get_dst@Base 3.2.7
 nlmsg_get_max_size@Base 3.2.7
 nlmsg_get_proto@Base 3.2.7
 nlmsg_get_src@Base 3.2.7
 nlmsg_hdr@Base 3.2.7
 nlmsg_inherit@Base 3.2.7
 nlmsg_next@Base 3.2.7
 nlmsg_ok@Base 3.2.7
 nlmsg_padlen@Base 3.2.7
 nlmsg_parse@Base 3.2.7
 nlmsg_put@Base 3.2.7
 nlmsg_reserve@Base 3.2.7
 nlmsg_set_creds@Base 3.2.7
 nlmsg_set_default_size@Base 3.2.7
 nlmsg_set_dst@Base 3.2.7
 nlmsg_set_proto@Base 3.2.7
 nlmsg_set_src@Base 3.2.7
 nlmsg_size@Base 3.2.7
 nlmsg_tail@Base 3.2.7
 nlmsg_total_size@Base 3.2.7
 nlmsg_valid_hdr@Base 3.2.7
 nlmsg_validate@Base 3.2.7
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         libnl-3 200 libnl-3-200
udeb: libnl-3 200 libnl-3-200-udeb
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     /etc/libnl-3/classid
/etc/libnl-3/pktloc
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       # Triggers added by dh_makeshlibs/13.9.1
activate-noawait ldconfig
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             bb566756c93e2dcf05694ae7bca2b57c  lib/x86_64-linux-gnu/libnl-3.so.200.26.0
8b809cc1ff3c44bb7aa9b565ea7cd37c  usr/share/doc/libnl-3-200/README.Debian
9af0251cda249c6ab8d1aeb501f50534  usr/share/doc/libnl-3-200/changelog.Debian.amd64.gz
2d18220e96cf5243f982b8c2c690e561  usr/share/doc/libnl-3-200/changelog.Debian.gz
1b9bb423be48ed37bf4962db54160b7a  usr/share/doc/libnl-3-200/changelog.gz
9875206ea37bb5800e057145fe033b97  usr/share/doc/libnl-3-200/copyright
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Package: libnl-3-200
Source: libnl3 (3.7.0-0.2)
Version: 3.7.0-0.2+b1
Architecture: amd64
Maintainer: Heiko Stuebner <mmind@debian.org>
Installed-Size: 182
Depends: libc6 (>= 2.34)
Section: libs
Priority: optional
Multi-Arch: same
Homepage: http://www.infradead.org/~tgr/libnl/
Description: library for dealing with netlink sockets
 This is a library for applications dealing with netlink sockets.
 The library provides an interface for raw netlink messaging and various
 netlink family specific interfaces.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Package: libnl-3-200
Status: install reinstreq half-installed
Priority: optional
Section: libs
Architecture: amd64
Multi-Arch: same
Version: 3.7.0-0.2+b1
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ###############################################################################
#
# ClassID <-> Name Translation Table
#
# This file can be used to assign names to classids for easier reference
# in all libnl tools.
#
# Format:
#   <MAJ:>		<NAME>		# qdisc definition
#   <MAJ:MIN>		<NAME>		# class deifnition
#   <NAME:MIN>		<NAME>		# class definition referencing an
#					  existing qdisc definition.
#
# Example:
#   1:			top		# top -> 1:0
#   top:1		interactive	# interactive -> 1:1
#   top:2		www		# www -> 1:2
#   top:3		bulk		# bulk -> 1:3
#   2:1			test_class	# test_class -> 2:1
#
# Illegal Example:
#   30:1                classD
#   classD:2            invalidClass    # classD refers to a class, not a qdisc
#
###############################################################################

# <CLASSID>		<NAME>

# Reserved default classids
0:0			none
ffff:ffff		root
ffff:fff1		ingress

#
# List your classid definitions here:
#



###############################################################################
# List of auto-generated classids
#
# DO NOT ADD CLASSID DEFINITIONS BELOW THIS LINE
#
# <CLASSID>		<NAME>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      #
# Location definitions for packet matching
#

# name		alignment	offset		mask		shift
ip.version	u8		net+0		0xF0		4
ip.hdrlen	u8		net+0		0x0F
ip.diffserv	u8		net+1
ip.length	u16		net+2
ip.id		u16		net+4
ip.flag.res	u8		net+6		0xff		7
ip.df		u8		net+6		0x40		6
ip.mf		u8		net+6		0x20		5
ip.offset	u16		net+6		0x1FFF
ip.ttl		u8		net+8
ip.proto	u8		net+9
ip.chksum	u16		net+10
ip.src		u32		net+12
ip.dst		u32		net+16

# if ip.ihl > 5
ip.opts		u32		net+20


#
# IP version 6
#
# name		alignment	offset		mask		shift
ip6.version	u8		net+0		0xF0		4
ip6.tc		u16		net+0		0xFF0		4
ip6.flowlabel	u32		net+0		0xFFFFF
ip6.length	u16		net+4
ip6.nexthdr	u8		net+6
ip6.hoplimit	u8		net+7
ip6.src		16		net+8
ip6.dst		16		net+24

#
# Transmission Control Protocol (TCP)
#
# name		alignment	offset		mask		shift
tcp.sport	u16		tcp+0
tcp.dport	u16		tcp+2
tcp.seq		u32		tcp+4
tcp.ack		u32		tcp+8

# Data offset (4 bits)
tcp.off		u8		tcp+12		0xF0		4

# Reserved [0 0 0] (3 bits)
tcp.reserved	u8		tcp+12		0x04		1

# ECN [N C E] (3 bits)
tcp.ecn		u16		tcp+12		0x01C00		6

# Individual TCP flags (0|1) (6 bits in total)
tcp.flag.urg	u8		tcp+13		0x20		5
tcp.flag.ack	u8		tcp+13		0x10		4
tcp.flag.psh	u8		tcp+13		0x08		3
tcp.flag.rst	u8		tcp+13		0x04		2
tcp.flag.syn	u8		tcp+13		0x02		1
tcp.flag.fin	u8		tcp+13		0x01

tcp.win		u16		tcp+14
tcp.csum	u16		tcp+16
tcp.urg		u16		tcp+18
tcp.opts	u32		tcp+20

#
# User Datagram Protocol (UDP)
#
# name		alignment	offset		mask		shift
udp.sport	u16		tcp+0
udp.dport	u16		tcp+2
udp.length	u16		tcp+4
udp.csum	u16		tcp+6
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
libnl versions explained
========================

Once libnl3 hits the archive there will exist 3 versions of libnl.
libnl1 with libnl-dev  - up until March 2011 the stable version
libnl2 with libnl2-dev - development version that resulted in
libnl3 with libnl3-dev - the new stable (API and ABI wise) version

libnl1 has currently a lot of users in the archive and a lot of changes
happened since its last upstream release in 2008-01.

The plan is therefore to introduce libnl3, port the two users of libnl2
(freesmartphone.org libs and powertop) to it, remove libnl2 and don't touch
libnl1 and libnl-dev for now.

 -- Heiko Stuebner <mmind@debian.org>  Sat, 21 May 2011 19:25:13 +0200
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    En0Dz&I
RU_^XrȉZJ{yuV{WaULr9"Ŗ|3\nWqf4X>x+맼%D
C
oit@98N0;rCF\i+op72;^⼤cuKtD~}ϻsU~ 6?4e	;PWX<ESs)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Zksȱ_1jEG&l6ue$97U-	Pb=3 z{Z̠tr6)sv,)L&93i-_
x󆐷/"a&M$եK(dN	qC/dEj*4-3A,ń\;O?|xv>G~9@W˷<Ǳx$K2R5yMĬȭI"(9ȹ"V"Dq4A~"nr:Ll~YRڼ@세9kfs<x~q?9ߛ7h>rb[pn>]dk" ݧ'4̓%%JKI"b=M%p%vt

DsiCZK@0_ŏ

	q
T0 *U x3W@+p[
R;؋ $R   } yiR`9{hD}RVek3AuD=DV6ffrExX&Cy6+1teni@ {*?ڕ%SSmfLΛ	ɹ6iIejD65%`t'پ@ !co듞
oGp٦lCO\#J2!\kɴchXy?xw
=!P4EUCqswTMշK͗L%u:ER`_*IɌ
jhQRӺuR ӴZ@%uR
؎^4'k5l=9#oѪ.i)	o	3mA
l9ȡ(qIc;Ih	JbCa?}ԂW59!>|
\`Osw#B9Q'N!2_z|:od))T$^$̌K٫F䬪Fw'l>Ed댈R
xMEMؗA%3tF`+\}"nƣqS0}a0G^||&ֿ}ß!plЂ/2i&5,]S5(=LPg<m3O\71|ZC+x&^Xuo ;es+i$i)Bp
Bb!x}&![_/Y#;%Yj0&'ϒLb6=Ok{%|u)Π"}7|F%mٸ	
YY7uq597(/U)ُUJ%?+-98#e5xΦ	@#ڗr	+S>	9$f<LI'g~ٝ}hi#-Jcl^	^.&WXiG+}խFIV3ٶu\]Y=*s
KUdu&w8_cCc&Ρ(} 㖾Mݏ >BcT̟E{"\	XwAC:uɝGAh`uX;x#'4JOTal&M);?B<r:hUN+ݰBoZ@Ϭ9'.{g,,L䅛}/&O-Z*" s5*j R\يghdMnsF|r00Ȍ1:0\dvVPdִDҿ	<to᪕CO_fqB)T4IsVQmT'RƐ4HnNBfbԓ8⚂%O[kz& V1|t͎*ѷ63KyPG^jxJew:Q0 }Xaᯂt
($g%l}n.$YND>IZ.2_wO弐; bFq2Y;̹Lc$V
 'M*"]Lk^lIΘaziJ/0ߎ7D8v>M#)tPob޸]!809{Jnޝ]^/4JA`\yRvSL;?oj.xj:02\$P*.GYvJU'ԆUr[nQgK7~RRʚWbfAԊY,-%MtRr*Jqha4E4f0k1	]ύ^
X= Ȑ'Xԙ\TJZNWoJ`x(<*e* T\卥csGQJv"&ʤE&{;̀mWP[JIX	ORfYŢV#mfS)fPiNlfj Ћ.MCc+~9L=qO5'0՚?%^ow{f980*`p%xZHAkfa8XDCgge\+|qLѝlZ3~왘{4 (vIФOa(\	<3v-lyST}ڇhW2l1Bw
}tIUC4[v 6<jCZ&#/&-j}1.c ctamwSuUMَ5QS*B(Nv~֑U)vH:ӭF+:u|0cιM0RS<Q5tA4۠*,Lʅ(źUd]C
FA&tFs*ф#n?{|C{	uz
1GL(ٗ[U%N 6sÔoR<$`\ ʵv-V$C!ux(3>!'f뽟Fde,:ZCן,Mѧ:k.&$mf+ 4{WZ8kσYOWn(6w!wt{7

|A۲mȴUV7:V³췐iH ?2e)LW9z-
ŘǭSWR߽ƫ"[IgR<z@qµ`O{b'to Yy䪢>0-|i@n{*Ȍ(Nq
纭"9FmbW!zvlpb#{qf'3M:5B;(=̗!qpXp>'`(G?#+h{QєM59ZGכxP+)|>f0+D%TUeGc2n**j˫գ$-
\7N7Q}aD7 	XmCCˊxIO0%ze:Kmmb9ʸ<y5^jufxn*0%b9#ך/`I#!Zۇ0X,xu>Y#j613}В'&8|LAPZz#XQA5sMn9yU4Ze(٘[7;r>b%
ݱ$i;LEN̡14F[\`S~Fin^-
k\kE8[JAG*憄m'GAvn~߰aF,7#L 9vbؿ_:UPIiMJB@9I d{
sk"xael}:hճ~bz:{/)-.3~|#;Z)it_RB9XobY/[y,qdf.?I=<!{̃,Y!N	3)&pNm鱁131cj4\&@UG J:yzެ")_iZ[ǡ52Il{i\wU
'|rڈ)cN0[eWGAuku7Ruׁb׃vP&b%p\^2֑fCԯYGWD5xƒqv}]h4|P;kM!0?2)uTZ@PYv ^$o2;t=)5q-pj@Jt7LyܼXzg;@
0R=qd؎"u\<>
ڴP%Q4
7#?/c3                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           [ko7
b0%ܲ'@Զ5d$gvg(գC$u`os%X-q>]Ey#GK,iPEeәbW-J]\7jfԼB-5ޯ=L[vI{~߾xWںZvx涭Ջg+kWc?nکwVվ_uIaZ4ƖjFnj˶FE˶;62צPM:_u3g׷&Y^Q1])~M#R۲Y(ݬUSjmU$+jsش^ʹIFi%\2VyQ߶ef©3.ʦU3S/үМ-YWVEִٲ;XyU&Nk
f90;y[K:W/¤opм 3.+e[˼Èr+ssita<*Adԥitd#/ov.NLIoa"H?nYV&)PBp<7Bޝ1Aoq%P%*:ow6t̻=Hg8L+mn
|䛏Ψw_SKD	!u9Q2!-f^o9n;둯[Byv.x~9 $vbw+m0$GSB$s<p4;S6RrC:jr][FCm~-oSܖ=IXլq|7NO˲h/;Z_ 02ʩZa`YdIu+$c6W'D'f)L?Ev$<k[0ړt¦w:??^.Nw?X}I	BW:>It*VBfDV3h>>s36J+H=QfCfR?\ʝǓϮ5JI!bla-Y.B[*1G:Fo&`Дhя_v
/`}X%Kk]?OA0ުwKZm"<ԦqࢯIS#2_'Vݷ/`.lATǍY1w[Y/mOا1Ϯ?7pЇ]RVxG
AmGw^v]_eC~X<ꬽ-HJYE$]k[f+8ͭoޛʗZ}&R<']12XoBګoo[N`bOy>4a+qy$=︭SMe9?(sNN|$Ìv+vUKǅ-Wr5z0&tQXs]80-&D ,=lNv2B3:e;N@GG<n|w#9k@s*8%X]hi	!8okq`M>4nCPc]"ߡ`EW~JC'[OiY^ul,4^ωJ-!B]3B;S7zqRZ, &rzHɸ7~8o/z^o e*V"M{;k9RH& ,vҖ(코C)t^.62 =+;ޒǏ]8Su-#66Kn^ޙj+grb1aIJ 'Ed,`h^β
dVQۼ{9 "24@h	֐Ap_<CtЋ7
u /
$K=)7q">
-9F.Vv P*V(qep2_@LF{ck#93V(a؜[ʋ>()m99-(= CBqz2Sr0%ɔѤ?湹K y}J4v}vyvx~3lC <IW1~!iGG|BΟ ᑡ'ږmAePi9qY
\AtKJ,@U8)p|ْYXFA' 틆('tf~'N7"R@U&2?0qN#A` 8LM('K1eXm
ka"`
6Jc0CBi$΂C
F.O]^PT	
2Odtf~ۘJ8Lډ #i7R
M=VBT,Y^f/{F&K28WdѬ	)/A-"&1هoWӣ҄NaDH
y89# '[MQXUJ@,F
=l\V?]dô:iś*?ۉ):_+s~uo]ٺ~2'+PUlbv
_]nWe|r>Y;<QDo\9`!mL73"2%$(8b95ÇmBW_CZF!(*qx"xW00	mrcݨ^i
+@/닩rnHż.&xp8ew3	W# m$`S.6m,Z{*2)uHVF[;/eokC|)/MA:#"]DY=ȅId4T*`a'iR/ʗ	^3]V`P8)f#"J}􏜞ZP><F{R?&ˑ<Rf#5JmAq$LqZWt0R6(Jqꧯ[1N9gW֫Te!?$Tqr	HBT,6/`S*g4ppP_NyQb%1iZ~mEjl-cQ~*lF;K-ėU>ac0lUU,l
%=c+`d7}ϸƶw]&A	0Ӥ)	NJ(O;Km3ג팿rp|&2@",fUD= AE7u6s$Ü3>
pFX0	d^$0xg$F!-0v";IJS;)M>4dz5&i1S2"ܤty*o$,K%ЛUTd\TS 7IcJP	NSޯ#d_og0ޔ%R/+uV\Z4R.Lf=*jzat"II9P]C[44(_yFvp{m_M
CKuހ"S&_G%JRH	;8Lau[B5S3/#`È&;[$fEX w1C=IX%EQg6ʯ٥0ksa3bĲE+0HUlv @&]$!ɛϧ׻!_+,.LS}&DK
g}9;18wr4L\Vz3EDi6$Q
8y(ާP	s=mNkΒ&
KcTyԭ!%mvX5+"d-^5M	45q&$WO	ޘD WSoMZN)$	/;PvL0a`KxwXs7fM&tLSWN>^}
]
C-"tu3Uk	 sb(l4tnrc3dݗ4#RwzbG.ކ*F1$#pfvȖs)ZNyȋ!\Iҫr5 KRn db;,JVڞn׵u޷L*L_;GІrBhcJ7ھT[0`}Lߙ)JJu߫kʠ.O-m:'UHJ+rsP`$?	|
ei[&4q
!۞A?ͻD[F@ӤM<;^'2֡7u
`7'ICW-xO/PD;-tĀEkh4,?H؏g*ǫ* <otݴX"[oRf6[1܍#KM!FSoQf8|+M'}6qBQZ=mFPd{n,t.h,bzHGfBNG33C;Ptu!i'د-Y^b'Gi\ulG(>^L>/
A*JڄdOׁyx }]RA#Ǎ; FY*nu 3.xGzzfPCu{m0Ȗ/"_2~J;RzEPcbjCv*h_1bcǩA|5@ncj
n	6($`w-OtT?2mڀqBm- @x]Acٴ#1F	/{$ݭz]?R!Ija0.RpL[ۖʲ
CjhC8ͦ.ë -"DWw8711㾺 \*?d#bޅV ݺGT{K7OK^^fMOgW"{33A| d"@\Õ MLH@<0i力v0}:"1|4[g2҈+7c ]Kn3q/ɽYNri/LJ
*{f"NV%ұ }ҝd$t3{Kݰ҅=tC#!RxLF!<]z-{	N%YZ/k.JuAR\	_"wv76                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    This package was debianized by Heiko Stuebner <heiko@sntech.de> on
Tue, 16 Jan 2006 12:00:46 +0000.
The packaging is based on Michael Biebl's <biebl@teco.edu> original packaging
of libnl1.

It was downloaded from https://github.com/thom311/libnl/releases

Upstream Author:
   Thomas Graf <tgraf@suug.ch>


Copyright: 

lib/route/addr.c 
include/netlink/route/addr.h

   Copyright (c) Thomas Graf <tgraf@suug.ch>
                 Baruch Even <baruch@ev-en.org>


lib/route/cls/u32.c
lib/route/cls/fw.c
lib/route/sch/htb.c
include/netlink/route/cls/fw.h
include/netlink/route/sch/htb.h

   Copyright (c) Thomas Graf <tgraf@suug.ch>
   Copyright (c) Petr Gotthard <petr.gotthard@siemens.com>
   Copyright (c) Siemens AG Oesterreich



lib/netfilter/log_msg.c
lib/netfilter/ct.c
include/netlink/netfilter/log_msg.h
include/netlink/netfilter/log.h
lib/netfilter/log_obj.c

   Copyright (c) Thomas Graf <tgraf@suug.ch>
   Copyright (c) Philip Craig <philipc@snapgear.com>
   Copyright (c) Patrick McHardy <kaber@trash.net>
   Copyright (c) Secure Computing Corporation



include/netlink/netfilter/queue_msg.h
lib/netfilter/queue_msg_obj.c
lib/netfilter/queue_msg.c
lib/netfilter/queue.c
lib/netfilter/netfilter.c
lib/netfilter/queue_obj.c
include/netlink/netfilter/netfilter.h
include/netlink/netfilter/queue.h
src/nf-queue.c

   Copyright (c) Patrick McHardy <kaber@trash.net>



include/netlink/xfrm/selector.h
include/netlink/xfrm/sa.h
include/netlink/xfrm/ae.h
include/netlink/xfrm/sp.h
include/netlink/xfrm/template.h
include/netlink/xfrm/lifetime.h
lib/xfrm/sa.c
lib/xfrm/template.c
lib/xfrm/ae.c
lib/xfrm/sp.c
lib/xfrm/selector.c
lib/xfrm/lifetime.c

   Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/


All other *.c and *.h files not mentioned above are copyright of:

   Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>


License:

src/nl-addr-add.c
src/nl-addr-list.c
src/nl-cls-add.c
src/cls/utils.c
src/cls/cgroup.c
src/cls/utils.h
src/cls/basic.c
src/nl-addr-delete.c:

   This library 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 version 2 of the License.

   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.

On Debian GNU/Linux systems, the complete text of the GNU General
Public License can be found in /usr/share/common-licenses/GPL-2


include/netlink/xfrm/selector.h
include/netlink/xfrm/sa.h
include/netlink/xfrm/ae.h
include/netlink/xfrm/sp.h
include/netlink/xfrm/template.h
include/netlink/xfrm/lifetime.h
lib/xfrm/sa.c
lib/xfrm/template.c
lib/xfrm/ae.c
lib/xfrm/sp.c
lib/xfrm/selector.c
lib/xfrm/lifetime.c

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

     Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.

     Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the
     distribution.

     Neither the name of Texas Instruments Incorporated nor the names of
     its contributors may be used to endorse or promote products derived
     from this software without specific prior written permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


All other *.c and *.h files not mentioned above:

   This library is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published 
   by the Free Software Foundation version 2.1 of the License.

   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.

On Debian GNU/Linux systems, the complete text of the GNU Lesser General
Public License can be found in /usr/share/common-licenses/LGPL-2.1 

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      /.
/etc
/etc/libnl-3
/etc/libnl-3/classid
/etc/libnl-3/pktloc
/lib
/lib/x86_64-linux-gnu
/lib/x86_64-linux-gnu/libnl-3.so.200.26.0
/usr
/usr/share
/usr/share/doc
/usr/share/doc/libnl-3-200
/usr/share/doc/libnl-3-200/README.Debian
/usr/share/doc/libnl-3-200/changelog.Debian.amd64.gz
/usr/share/doc/libnl-3-200/changelog.Debian.gz
/usr/share/doc/libnl-3-200/changelog.gz
/usr/share/doc/libnl-3-200/copyright
/lib/x86_64-linux-gnu/libnl-3.so.200
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Package: libnl-3-200
Status: install reinstreq unpacked
Priority: optional
Section: libs
Installed-Size: 182
Maintainer: Heiko Stuebner <mmind@debian.org>
Architecture: amd64
Multi-Arch: same
Source: libnl3 (3.7.0-0.2)
Version: 3.7.0-0.2+b1
Depends: libc6 (>= 2.34)
Conffiles:
 /etc/libnl-3/classid newconffile
 /etc/libnl-3/pktloc newconffile
Description: library for dealing with netlink sockets
 This is a library for applications dealing with netlink sockets.
 The library provides an interface for raw netlink messaging and various
 netlink family specific interfaces.
Homepage: http://www.infradead.org/~tgr/libnl/
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Package: libnl-3-200
Status: install ok unpacked
Priority: optional
Section: libs
Installed-Size: 182
Maintainer: Heiko Stuebner <mmind@debian.org>
Architecture: amd64
Multi-Arch: same
Source: libnl3 (3.7.0-0.2)
Version: 3.7.0-0.2+b1
Depends: libc6 (>= 2.34)
Conffiles:
 /etc/libnl-3/classid newconffile
 /etc/libnl-3/pktloc newconffile
Description: library for dealing with netlink sockets
 This is a library for applications dealing with netlink sockets.
 The library provides an interface for raw netlink messaging and various
 netlink family specific interfaces.
Homepage: http://www.infradead.org/~tgr/libnl/
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          libnl-genl-3.so.200 libnl-genl-3-200 #MINVER#
 genl_connect@Base 3.2.7
 genl_ctrl_alloc_cache@Base 3.2.7
 genl_ctrl_resolve@Base 3.2.7
 genl_ctrl_resolve_grp@Base 3.2.7
 genl_ctrl_search@Base 3.2.7
 genl_ctrl_search_by_name@Base 3.2.7
 genl_family_add_grp@Base 3.2.7
 genl_family_add_op@Base 3.2.7
 genl_family_alloc@Base 3.2.7
 genl_family_get_hdrsize@Base 3.2.7
 genl_family_get_id@Base 3.2.7
 genl_family_get_maxattr@Base 3.2.7
 genl_family_get_name@Base 3.2.7
 genl_family_get_version@Base 3.2.7
 genl_family_ops@Base 3.2.7
 genl_family_put@Base 3.2.7
 genl_family_set_hdrsize@Base 3.2.7
 genl_family_set_id@Base 3.2.7
 genl_family_set_maxattr@Base 3.2.7
 genl_family_set_name@Base 3.2.7
 genl_family_set_version@Base 3.2.7
 genl_handle_msg@Base 3.2.21
 genl_mngt_resolve@Base 3.2.7
 genl_op2name@Base 3.2.7
 genl_ops_resolve@Base 3.2.7
 genl_register@Base 3.2.7
 genl_register_family@Base 3.2.21
 genl_resolve_id@Base 3.2.24
 genl_send_simple@Base 3.2.7
 genl_unregister@Base 3.2.7
 genl_unregister_family@Base 3.2.21
 genlmsg_attrdata@Base 3.2.7
 genlmsg_attrlen@Base 3.2.7
 genlmsg_data@Base 3.2.7
 genlmsg_hdr@Base 3.2.21
 genlmsg_len@Base 3.2.7
 genlmsg_parse@Base 3.2.7
 genlmsg_put@Base 3.2.7
 genlmsg_user_data@Base 3.2.21
 genlmsg_user_datalen@Base 3.2.21
 genlmsg_user_hdr@Base 3.2.21
 genlmsg_valid_hdr@Base 3.2.7
 genlmsg_validate@Base 3.2.7
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  libnl-genl-3 200 libnl-genl-3-200
udeb: libnl-genl-3 200 libnl-genl-3-200-udeb
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 # Triggers added by dh_makeshlibs/13.9.1
activate-noawait ldconfig
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ad5d752a10094151c5945fcb288c2538  lib/x86_64-linux-gnu/libnl-genl-3.so.200.26.0
9af0251cda249c6ab8d1aeb501f50534  usr/share/doc/libnl-genl-3-200/changelog.Debian.amd64.gz
2d18220e96cf5243f982b8c2c690e561  usr/share/doc/libnl-genl-3-200/changelog.Debian.gz
1b9bb423be48ed37bf4962db54160b7a  usr/share/doc/libnl-genl-3-200/changelog.gz
9875206ea37bb5800e057145fe033b97  usr/share/doc/libnl-genl-3-200/copyright
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       Package: libnl-genl-3-200
Source: libnl3 (3.7.0-0.2)
Version: 3.7.0-0.2+b1
Architecture: amd64
Maintainer: Heiko Stuebner <mmind@debian.org>
Installed-Size: 58
Depends: libnl-3-200 (= 3.7.0-0.2+b1), libc6 (>= 2.4)
Section: libs
Priority: optional
Multi-Arch: same
Homepage: http://www.infradead.org/~tgr/libnl/
Description: library for dealing with netlink sockets - generic netlink
 This is a library for applications dealing with netlink sockets.
 The library provides an interface for raw netlink messaging and various
 netlink family specific interfaces.
 .
 API to the generic netlink protocol, an extended version of the netlink
 protocol.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Package: libnl-genl-3-200
Status: install reinstreq half-installed
Priority: optional
Section: libs
Architecture: amd64
Multi-Arch: same
Version: 3.7.0-0.2+b1
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 464602a2275282fb39130d4a242b212f  usr/lib/x86_64-linux-gnu/libip6tc.so.2.0.0
374ebb5ef26d0e9a4c52cba108c42645  usr/share/doc/libip6tc2/NEWS.Debian.gz
908ea862e5e7056d6cb06f6a04190511  usr/share/doc/libip6tc2/changelog.Debian.gz
b4f9b68cfc5f8a5c3290db3fd0984df1  usr/share/doc/libip6tc2/copyright
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Package: libip6tc2
Source: iptables
Version: 1.8.9-2
Architecture: amd64
Maintainer: Debian Netfilter Packaging Team <pkg-netfilter-team@lists.alioth.debian.org>
Installed-Size: 66
Depends: libc6 (>= 2.28)
Section: libs
Priority: optional
Multi-Arch: same
Homepage: https://www.netfilter.org/
Description: netfilter libip6tc library
 The iptables/xtables framework has been replaced by nftables. You should
 consider migrating now.
 .
 This package contains the user-space iptables (IPv6) C library from the
 Netfilter xtables framework.
 .
 iptables IPv6 ruleset ADT and kernel interface.
 .
 This library has been considered private for years (and still is), in the
 sense of changing symbols and backward compatibility not guaranteed.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Package: libip6tc2
Status: install reinstreq half-installed
Priority: optional
Section: libs
Architecture: amd64
Multi-Arch: same
Version: 1.8.9-2
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ELF          >            @       P          @ 8 	 @                                                                                  6      6                    `       `       `                               p{      p{      p{                                |       |       |                               8      8      8      $       $              Ptd   0e      0e      0e      t      t             Qtd                                                  Rtd   p{      p{      p{                                  GNU _FW,iυjd                 B >p $  D  f#K
HH      "   #   %   )   *       ,   .       0   4   5   7   ;       My\r)QאKd\dGUDyI*SقR?L5!۴@h
EWM
46'9IZRִZ.y+6Qꙣ[                            d                     g                     s                                                                                                           X                     _                     +                     6                     P                     l                                          r                     y                     n                                            $                                                               K                                                               ,                       G                     F   "                                                             a    #                  R      9            T                 4      .      {    ;      ?           A             g     "      3            C            
    @.      ,           @L      q          (      G       0    +                 pB                `*                  (      }           ;      B       x      #      ;       
    `)             U     "      ;           {      `       =     6                >      (      A    @#                 -      w            A                  -                 J                 `(      %             @            
    U              __gmon_start__ _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize ip6tc_first_chain ip6tc_next_chain ip6tc_next_rule ip6tc_init ip6tc_delete_chain ip6tc_create_chain ip6tc_insert_entry ip6tc_replace_entry ip6tc_delete_num_entry ip6tc_read_counter ip6tc_zero_counter ip6tc_delete_entry ip6tc_set_policy ip6tc_strerror __stack_chk_fail ip6tc_free close calloc strcmp stderr __fprintf_chk ip6tc_is_chain ip6tc_first_rule __errno_location strncpy ip6tc_set_counter abort ip6tc_get_target ip6tc_zero_entries ip6tc_commit __strcpy_chk memcpy setsockopt strlen dump_entries6 __printf_chk stdout puts inet_ntop putc putchar ip6tc_get_references ip6tc_builtin ip6tc_rename_chain ip6tc_get_policy ip6tc_flush_entries ip6tc_append_entry malloc socket fcntl64 getsockopt ip6tc_check_entry ip6tc_ops libc.so.6 libip6tc.so.2 GLIBC_2.28 GLIBC_2.3.4 GLIBC_2.14 GLIBC_2.4 GLIBC_2.2.5                                                                  &            >     ti	   I        U     ii
   `     ui	   j      p{             p"      x{             0"      {             d      {             d      {             d      {             d      {             e                           0              `      H             Qb      `             (`      x             ib                   |b                   X`                   b      ؀             b                   b                   b                    b      8             b      P             c      h             ,c                   `                   ;c                   Sc      ȁ             cc                   `                   `                   c      (             a      {         &                    &           {         '                    '                     '           8         '           P         '           {                    x                    {         -                    -           {         9           p         9           {         #                    #           {         !           8         !                    !           {         0           ~         0            |         $                    $           |         6           @         6           |         )                    )                    )                    )           |         4           ~         7           ~                    ~                              5                    %           Ȁ         %           @         %           X         %                                                            "                     *           (                                          0         8           p         8           H         2           P         .           X         3           `                    h         ,                    ,                    +                    :           h         :                    :                    :                    /           (         /                                        (                                                   (~                    0~                    8~                    @~                    H~                    P~                    X~         	           `~         
           h~                    p~                    x~         
           ~                    ~                    ~                    ~                    ~                    ~                    ~                    ~                    ~                    ~                    ~                    ~                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            HHU_  HtH         5]  %]  @ %]  h    %]  h   %]  h   %]  h   %]  h   %]  h   %]  h   %]  h   p%]  h   `%]  h	   P%]  h
   @%]  h   0%]  h    %]  h
   %]  h    %z]  h   %r]  h   %j]  h   %b]  h   %Z]  h   %R]  h   %J]  h   %B]  h   %r]  f%]  f%^  f%^  fH=i`  Hb`  H9tH]  Ht	        H=9`  H52`  H)HH?HHHtH]  HtfD      =_   u+UH=]   HtH=]  ad_  ]     w    HY\  HGHOH_  H9tHH9ѹ    HDHHWD  1D  H	]  HGHf_  HtHHOH9ʹ    HDHHWff.     fHI\  HV H&_  Ht!HHRH`H9t	HF H@HF     1D  H(  AB   1dH%(   H$  1HH5\  HHH5^   H9tHt7HHuD9@uHRHDH$  dH+%(   u/H(  D  H$  dH+%(   uDH(  AWAVIAUMnATUSHHl[  ?H#^  InLe L9tIf     H}`H]`L?H9tLM?H9uHLI$M9tI    I~0I   HL[]A\A]A^A_D  AT̾   U1SG(HHHH%9@ō<    IHC0EtHt
   k8[]A\1ff.      AWAVIAUATUSH(Di8H|$t$HT$E   DLy0EI,HthD  A   H|$HuHL$tc   AF89tRCI4AtWH|$HYx3DI,HuHZ  پ   Hh;  H81InH(H[]A\A]A^A_ËD$+Ft    D$+Etd@ tA݉두AWL~HE1AVAUILATI1USHdH%(   HD$1HT$D$   L$HÅuIm0LHE Hp|   ImH9   AT$0uLsII9uRfIEfHnMefHnflA$L HD$dH+%(      H[]A\A]A^A_    HI9tC0uHsL~)H9ufI]Le ImH9dI][fHSHfHnfHnL`flA$L"hUD  AUATLfUSHH^dH%(   HD$1D$    I9   HID  H{HDtpHI9tK0uHT$E11LH,AU(I9HDÅt]LhI] I9uNfD  ~C0t?I9t:HI9t2H{HufHD$dH+%(   uHH[]A\A]f1g    HHW  HY  HHff.     SH0W  HHY  HtHP`H`H9tHS HB@[D      1[f     SHV  HHDY  wHtPHP`H`H9t$t0   f     9tHH9u<    1[fHtH   [    1 UHSHHH;V  HX  HtzHH`H`H9tt0   9t!H	H9u    1H[]D  HtytE   H   []f.     A       k    1뭐ATI   U   SHHt%Hx   L?HC`k0fHnflC`H[]A\ ATHU  IUHSHHW  HtqHp`H`H9tt/   9t!H6H9u    1[]A\    HtF   Ao$      E   []A\fD  s    1f     AUIATIHUHSHH[T  HW  7H   HË@0   H5\8  Lu=C81MtAoE    C@CP   E   H[]A\A]D  H58  LQ¸t    1H[]A\A]fD      1f     Hy~1D  ǃ=   tjHcҋrލW~t[щHcɃs+ щHcɋr   ufD  ÿ   1   뷸   D     HD@f8(tH    1H     f@ @@ p @   G(    ff.     HHR  H\4     H81]H     HQ  WHU  tJwt$   HD    1u'HGH   | t@|uAH?6  ÐH7       tuH6  fD  H5  H5  P2fSH8Q  HHfT  HtLxPu@P   HP`H`H9tf.     zuB   HH9uC      [D  C    1[f     HYQ  HS  Gu   D  AWIAVAUATLgUSH8LwM9  L11    D_0GtE(  V   HG`HO`H9tf.     X$X8P H H9u_|   rWxH?L9uBD$Lc\    H$IHx`   LL$LL$HH+  A   I   LL$IE(HD$HLL$HHEX  H|$   LL$vLL$HI  IA@    HLL$HHD$ LL$fnt$]TD}(DN5  H]`fAnA`fbfE M9?  LL$(D$Ll$MAE0AMt  AU|L,T@M}`Mu`M9u8       A$AW8uA   L HM?M9t\AG(Iw@uA   fHP@ PIW0A$@ RtH߁   P AW8M?M9u     AE|
Z4  (   Hƀ    EE0   f   EtAU8Ao]@Mm       M9E(D$Ll$LL$(H$H$@   R   A9R   L$HD   f   @   f   Hf   )   ǀ   ERROǀ   ERROE(D@`  Ht$ L    L$D$fIyAE L9   G0t9GP    /  GTWxHHEXHo8B|*( HG`Hw`H9u/aX  PH HHUXHo"Bd)(H H9t4P@  vƃuP o   HBl*(H H9u@ H?L9DA9DD$LA   )   
   H}XHL              $L4Iu   AR   A@   Aǆ   ERROI   A   fE   fE   ^AƆ    L	H}X H1H8[]A\A]A^A_    f.     P HBD*(fD  HP HHHMXLLL+   LB(HIH+   HJ0u8GxoO@HBL((!WTGxHHHUXH
LH+O@HH(HRH+WHHP0GxfHBL((H$   H  A   A   D$           @ DO8EtSHGLGI9tF1AfP0u-IH%D9s&ifffw
Hw0HփH L9u UHSHHHUJ  HNM  Htw    1H[]     H5.  HtH5.  HtH5e.  HtH5K.  HtHLHH v    D  1HHHt6E(HE8E()=c  %E      =@     'E8    H}0XHxHtfAWH-  H5-  AVAUATUSHXdH%(   HD$HHI  H|$HK  H      H 1LT$H5-  1   IR@LT$HH5+     ABtAJhARdPEJp1EBlLT$LT$   H5*  A   AJ|LT$ARx$E   1E   nLT$XZI   K d  LT$H(E11D$    L5G  Ll$ L%U-  @ L   1H5,  H=,  D(   LH޿
   L'I6/   LC Lne  H5},     1I6
   cH=`,  Hs(   L
   aLI6/   ,LC0L   H5,     1BI6
   L{`HkpHS@   1H5+  fD  A?IփXI9uHSPH5+     1H        A?IփXL9u   H5+     1   T  H5+     1y   H5w+  1   _H      1H   H5(  >   H5M+  1   %   f= v7A   fDL   1HHUE    AHA9rH,H5+  1   M HUHT$} HT$   U   H)  t!H)  tH)  H)  HEHH5*     1`
   VHL$   D$D$H   y 9?  H(AJH9$  H11   9sHH9   9rHpE  L$   Hh'  H81H5$*  HaIHU H5*     /    (   LLƿ
   SL$fD  (   LLƿ
   +LfD     H5 )     1   fH5h)     11HD$HdH+%(   uHX[]A\A]A^A_=ff.     fSHC  HHHHF  Ht@4   [f    1[ÐHHC  HVF  Ht@0H@ k    1Hff.      AUATUSHH   Hl@}    HH5e'  IAHtpH5Q'  HtXH5'  Htt@H5&  H\t(LHtI    1H[]A\A]ÐHH[]A\A]f     F(      fLHeHtC(   HC0@4    H   1H)HHs-ufHt	E  uiC(   EuAD$    HMHE     HD    HH)HHHrH1H4HH9rE     D    fD*       ATHE1UH1SHHHdH%(   HD$1HL#fo'  HHCID$L H9t$HD$dH+%(      H[]A\    HEI9toHT$I|$E1H1$;D$uHU0L$D  E8    H}0HxHD$dH+%(   uHH[]A\@ m8[fAUATIUHSHHHHHh@  HAC  tHtj    1H[]A\A]    H5$  HtH5y$  HtH5U$  HtH5;$  HtHLIHt1HL&u"HHH v     \    LHLI}   HLH9E           ATIUSHHdH%(   HD$Hu?  HB  AH   HLHjt.!    1HT$dH+%(      H[]A\@ H|$HLtɋT$uLEXuUH9kt_k(HH HC      f.         u    e{ '   UHE HSH9к    HDHCSH>  HHHA  6HtQP0tUo@@x8tJ}t uDH6"  [fu7HD"  [D  H"  [        1[ÐH"  [BfAUIATUSHH=  Hm@  Ht{Hx`Hh`IHH9u&>fD  HGHCH@HHH9tHÃ(uHG0HtӃh4D  AD$X       AE   H[]A\A]        H1[]A\A]     AWAVAUIHATIUSHH<  H?  H   E   HI@yHH   fHx@LL@@0HhDx8 @ 31HLC   t{HEhHM`H]hfHnfHnflH   EXAD$   H[]A\A]A^A_f.         1H[]A\A]A^A_    1D  H1@ AWAVAUIHATIUSHHX;  H>  Hk  Hŋ@X9   Lu`t?S9   HE`L9t$G     
J95  H L9uE1A   Hz@T$I T$HH  fHx@L@@0HhP8L @ 1HLC      IFfInI^fHnflH   EXAD$   H[]A\A]A^A_fD      1H[]A\A]A^A_@ )؉HEhL9tB   
 9t1H@L9u H1@ ;    1떐I#    1{fD  AWAVAUIHATUHSDH   H9  HT$H<  H  A   IHz@T$IwT$HI  fLX@L@L@0LpP8L @ L\$&LHL\$[  E|$(A  IV`IF`H9trI3Lt$XEHD$8Ht$IsHl$`LHt$\$pHHT$HL$HC@H3SHH3K@H	uHMPHUXH3KPH3SXH	tBHHD$8H9uD  ILD      1HĈ   []A\A]A^A_ÐHM`HUhH3K`H3ShH	uHMpHUxH3KpH3SxH	uH   H   H3   H!IpH   H   L   D  J :N ID
>A!!A94J0:N0'DJ~A!!A9HHL9u   9   Ht$D   L   DfA s  HD$hL   A   LLT$xH   Dl$@EH\$HLHl$PDfDD$vMfD  AHT$0ILD$(MHL$ E>M)IfE;<$uoIt$I~u]HT$0EHL$ I LD$(H fA    11E1fD  DNLLM9syCD C2D ":tf     IH\$HHD$8Dl$@Hl$PHH9         IT$0H6j4-f     LDD9IDl$@H\$HIHl$PHD$ht$vLT$xK(A9OD   A      DIME6  AfA;$L$(LT$0T$ I~It$L\$@gL\$@T$ L$(H f tU1LT$01H    zHIH9s2AD> A2D< C"D t A   HC0H9E0~Hڋ\$pILt$XHl$`u-H;U tbAnXtHH
HBHHAHE   L   Vf     L> HB0Hth4멐HBHE fD  AD$ A9F aH%5  D   H  H81    E1x     HGHufD  SHHxhfn   T`@P   P8VPTo   H@fnW$HCfbf@x(t%HGHHBHHChX[     HG0Ht҃h4̐AVAUIATAUHSH1LwQDctS0E Cpt0IEIUI]fHnfHnflHI][]A\A]A^ H{Iv~/IEIMI]fHnfHnflHI][]A\A]A^fAF0uHLAE<     AWIAVAUATUSH   dH%(   H$   1HD$0HD$    H)3  LH5  "H        
   Ņ  Ǻ   1     H\$    LD$$T   HQLD$$Hى@   )        IH  HxH@    Me    HfInHǀ       )fl   1HAEI}@Ht$$   HH(I   H  Ht$    Hfod$0Am LD$ Hfol$@A   $   Y )   (fot$Pfo|$`Ae@A   fod$pAmPAu`A}pA   \$ h  M   D$(    1AE<   AF   Ld$L|$    I(I,D   LMH9M     H54  HHyH$iH$  A}`1ɸ   tADdLH9^  HHuEI|$@M}D$IIH0  L$(D$ffnHHx@LHfnH0LxfbD@8H f@ $   $AF   HANx T  f8(     @ Ӆx9AF(IGhIw`MwhfHnfHnflAL0AGXM   L$(AF 9Ld$L|$L   LImI9   HD$,LMHD$Lu`Le`M9   H,$LILMf     M6M9|   A~(uA   Ed`HEH9t+U<   HPHH9tD;`trD9`|s,H H9uMIL811@ IF0M6@4M9uILIH,$Hm I92LH$   dH+%(     HĘ   H[]A\A]A^A_    HT$A   H1D?HT*  DvH<DHH   Dp0HL$(L%D   MfD  1Hy HHtmAE(HL$(L   L$(       AF(   L$(LΉ$   IE    ${Ld$L|$ a    1HLd$L|$    .LLd$L|$    p1    dJL8H     HH>-  H81ff.     @ UHSHHH;,  H\/  H   D@XD9   DƍSHH`9rqHx`H9t!t   D  r9tH?H9u1HWH9}    A(D@XtyHHPHE   H   []    HxhD)H9tt   
fD  9tHH9ufD      1H[]@ HG0Hzh4qf    1ΐHU H    AWAVAUIHATIUSHH+  H.  DH  HXI9=  HP`E9   I^`H9t"t    fD  H9tHH9u1E   I@L|$HT$HH%  fHx@L@@0LpDx8 @ O1HLE   ;   HfHn˃{(fHnHhflE    HCHHEH(   AD$   H[]A\A]A^A_I^h)H92+   9H[H9u        1H[]A\A]A^A_@ HC0Hch4Zf.         1    1fHX1@ A   e HH                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           Permission denied (you must be root)    Table does not exist (do you need to insmod?)   Can't delete chain with references left Bad rule (does a matching rule exist in that chain?)    iptables who? (do you need to insmod?)  Will be implemented real soon.  I promise ;)    No chain/target/match by that name      ERROR: NULL pointer chain_index[%d]
    ERROR: %d not a valid target)
  Hooks: pre/in/fwd/out/post = %x/%x/%x/%x/%x
    Underflows: pre/in/fwd/out/post = %x/%x/%x/%x/%x
       ERROR: offset %u not an entry!
 Counters: %llu packets, %llu bytes
     Could not set close on exec: %s
 Module is wrong version Chain is not empty Can't delete built-in chain Chain already exists Index of insertion too big Index of replacement too big Index of deletion too big Index of counter too big Loop found in table Target problem Bad built-in chain name Bad policy name Incompatible with this kernel Memory allocation problem RETURN QUEUE UNKNOWN NF_ACCEPT NF_DROP libxtables.so.12 libiptc v%s. %u bytes.
 Table `%s'
 Entry %u (%lu):
 SRC IP:  %d DST IP:  Interface: `%s'/ to `%s'/ 
Protocol: %u
 TOS: %u
 Flags: %02X
 Invflags: %02X
 Cache: %08X
 Match name: `%s'
 Target name: `%s' [%u]
 verdict=%s
 verdict=%u
 ERROR error=`%s'
 ERROR: bad type %i
 PREROUTING INPUT FORWARD OUTPUT POSTROUTING                             ;t  -     p  P    н    0  px      @@  0|  `    0    0<  x    `         @  @      `,  L  l       <  p    @  `X  0  	   	  P@	  	  	  
  
             zR x  $      X   FJw ?;*3$"       D                  \   x;          p   3             л;                  G{
F]
E  D          BBE F(A0A8D@8D0A(B BBB,     b    BKC E
ABA   H   4  0   BBE B(A0A8D`
8D0A(B BBBA H     K   BLB H(F0A8DP
8A0A(B BBBH 8         BBE A(D@
(D ABBC      %    D]       ĿG    Aq
FN     @  }    A\
CM
A 4   d  P    ADI R
AAFV
FAK (     M    BIH vAB   8         BKD L
ABHf
ABG   L     `    BEG D(D0n
(A ABBFk
(A ABBG      T            h  |T    VQ      (    D                 hw    Aa
FNH     ,   bEB B(E0A8Dp
8A0A(B BBBA     ]       (   ,  .   ADG i
AAI  \   X     BPB B(A0A8D\YWA
8A0A(B BBBA      ,?    Al
CN      LB    Dd
HQ   L     |   BBA A(G0
(A ABBBI
(D ABBN   @   H      BGF K0R
 AABHh
 DABI 8     (   BBD D(M0i
(A ABBH  0        BDA G0a
 AABE 4     x    AL
CJ
FH
HN
BH
A   H   4      BEA A(D0
(A ABBHO(C ABB  `     D   BBB H(D0A8D@
8A0A(B BBBKQ
8A0A(B BBBA `         BBB H(D0A8FP
8A0A(B BBBGQ
8A0A(B BBBEL   H  ly   BBB H(A0D8JG
8A0A(B BBBB                        Qf
I   L         BBE D(D0D
(A BBBDv
(A BBBC L     xq   BEB B(A0A8G
8D0A(B BBBH   4   l  9   ADI 
FAHI
AAEd        BBB H(D0C8DP
8A0A(B BBBAQ
8A0A(B BBBE      	  8                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   p"      0"      d      d      d      d      e                                                                                                                                     &             0                     
       U             p{                           x{                    o    `                          P      
       v                           ~             (                                        @
                   	                            o           o          o           o    f      o                                                                                            |                      6       F       V       f       v                                                               !      !      &!      6!      F!      V!      f!      v!      !      !                                                                                                                                                                                                                                                                                                                                                     `                     Qb                     (`              '       ib                     |b                     X`                     b                     b                     b                     b                     b                     b              (       c                     ,c                     `                     ;c                     Sc                      cc              \       `              &       `                     c                     a      965f465706e62c94f51b0b9e69cf85a06a6418.debug    :ҋ .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame .init_array .fini_array .data.rel.ro .dynamic .data .bss .gnu_debuglink                                                                               8      8      $                                 o       `      `                                   (             P      P                                0                         v                             8   o       f      f      x                            E   o                   `                            T             @
      @
                                 ^      B                   (                          h                                                           c                                                         n             !      !                                    w             !      !      ;4                             }             U      U      	                                            `       `      0                                          0e      0e      t                                          f      f       	                                          p{      p{                                                x{      x{                                                {      {                                                   |       |                                 r             ~      ~                                                             0                                           0      0                                                          0      4                                                    d                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         TMo@W
 CBTqdk&_I[T\g޼fu48)ֳyC_tl'߹1}H,EAIdu;R{fK9k;F|mV"k5/d=M!춼bui~s-޻+&< } TAVKus_=08 

n硽qv#TY;@6phZB+	aȑG1xj&|wAXU`E*I59.3wxkEF[8޼Lj
X%UZ,Oa<[-tZ,&},k	s*iW;~0P0+Nolq#D]bcMTzHVLT\3P$	,W/_5zµjNIB>zme[2PJ0tɳ
\cR1T/	cJEms̗UC'W﯊<DW&$#}@342+.	Zo"˫9h:΢f :8ܽcZE|ZMJˍUMLFWMos%}w|(
R%8H\WSER`h692YҒx'af;q}ώ? gIT                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Xn$}WG=]/l`]{>&3
[C=žmGENf]Ū:TuQ}K%+RZIݯ/.VU*Yqj^72UF"kQ]Žp],ziS'kF}A?!UYX7\! )C$.d&_\祒fot6%jR!.5A֭yBV
5Ik?GFY0`
պQ#cRX
u- u)$+JVݡS|n!)4%u6
wjmo$+j}U;f1XY,H
Fv}:kV8ǜ2KQ|Vְ}*XA\oНmčuhR_Hxop?աJ&xQ"lBZ+YJa{
]+kޚdLUAЅ߬+DĴ$(?Gke>kE"1AFA\΃!
腂NЋRpF~oA&,f&Տ䝚eO&ƪ`-V,<o]AFwj'qrH8Oa>c-U*pd/@Jhᛀ(,Я1=AhSeC)r1IlfA(qRB'>!BV#ѦS9i\I`e 	7ς
`iRg7;QTg0-顕\L!KR,%{BML%Ǉu'so4dA yzNЋ~#I$9sVd2UPA
iF}.E,y<bcH3	
Ɓj3Y]%ǌס)AF-D
6Z<IӺJ$;˟ctJ3_>uoP_R<T߳`>ȃL&	
XhP~0pD
RCDȿ 
LD	iqp.#@wEWmg3JI%Ocx%Hp	}'jD7]*i0~b6NR RM\$gaG+u2s
vyƋI v)EiZcotK@Ժ6 ,*L/tЏNKG:SIrŘLi@XA)M؄"gGU 3c+
%G$=(L2߫k`y9W[?iC"IQm7N/Wݸ<v㰽C9,B(㝆9`dI^S o>ah&m#᣿LCe(EMBc6FU8h_&Xc5ͫqzlX Wæ=Ô}nN!>Iwӳ)Ps/#{F
2.)ɾ?`5]`ƀWJGP`ajiN>¹>]%-'[7_= DPbb)iJ)9U;֌Xt-~^Fz9/2W;OV\[hF7w4_>{>5ףy~IA  0 ^~uچ5uk4Srr΍rq`VxYXΫT~	9Sw9Y\G&i> 3غymK)FTG˻hzhDnobz2^xX&䂴ho,SpkEn0a?w Y@jXXӐeOI&V9;2~	o#2KҀ#<ZqhRfS%54Zw^`	.[ĐFAO٭Wni'Fwt                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: iptables
Upstream-Contact: Netfilter Developer List <netfilter@vger.kernel.org>
Source: https://www.netfilter.org/

Files: *
Copyright: 2000-2002, the netfilter coreteam <coreteam@netfilter.org>
                      Paul 'Rusty' Russell <rusty@rustcorp.com.au>
                      Marc Boucher <marc+nf@mbsi.ca>
                      James Morris <jmorris@intercode.com.au>
                      Harald Welte <laforge@gnumonks.org>
                      Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
License: GPL-2

Files: extensions/libebt_802_3.c
Copyright: 2003 Chris Vitale <csv@bluetail.com>
License: GPL-2

Files: extensions/libebt_ip.c extensions/libebt_log.c extensions/libebt_mark*.c
Copyright: 2002 Bart De Schuymer <bdschuym@pandora.be>
License: GPL-2

Files: extensions/libebt_limit.c
Copyright: 2003 Tom Marshall <tommy@home.tig-grr.com>
License: GPL-2

Files: extensions/libebt_nflog.c
Copyright: 2008 Peter Warasin <peter@endian.com>
License: GPL-2

Files: extensions/libip6t_DNAT.c
Copyright: 2011, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libip6t_DNPT.c
Copyright: 2012-2013, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libip6t_MASQUERADE.c
Copyright: 2011, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libip6t_NETMAP.c
Copyright: 2011, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libip6t_REDIRECT.c
Copyright: 2011, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libip6t_REJECT.c
Copyright: 2000, Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
License: GPL-2

Files: extensions/libip6t_SNAT.c
Copyright: 2011, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libip6t_SNPT.c
Copyright: 2012-2013, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libip6t_mh.c
Copyright: 2006, USAGI/WIDE Project
License: GPL-2

Files: extensions/libipt_CLUSTERIP.c
Copyright: 2003, Harald Welte <laforge@gnumonks.org>
License: GPL-2

Files: extensions/libipt_ECN.c
Copyright: 2002, by Harald Welte <laforge@gnumonks.org>
License: GPL-2

Files: extensions/libipt_REJECT.c
Copyright: 2000, Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
License: GPL-2

Files: extensions/libipt_TTL.c
Copyright: 2000, Harald Welte <laforge@gnumonks.org>
License: GPL-2

Files: extensions/libipt_ULOG.c
Copyright: 2000, Harald Welte <laforge@gnumonks.org>
License: GPL-2

Files: extensions/libipt_ttl.c
Copyright: 2000, Harald Welte <laforge@gnumonks.org>
License: GPL-2

Files: extensions/libxt_AUDIT.c
Copyright: 2010-2011, Thomas Graf <tgraf@redhat.com>
           2010-2011, Red Hat, Inc.
License: GPL-2

Files: extensions/libxt_CHECKSUM.c
Copyright: 2002, Harald Welte <laforge@gnumonks.org>
           2010, Red Hat, Inc
License: GPL-2

Files: extensions/libxt_CLASSIFY.c
Copyright: 2003-2013, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libxt_CONNMARK.c
Copyright: 2002, 2004, MARA Systems AB <http://www.marasystems.com> by Henrik Nordstrom <hno@marasystems.com>
License: GPL-2

Files: extensions/libxt_CONNSECMARK.c
Copyright: 2006, Red Hat, Inc., James Morris <jmorris@redhat.com>
License: GPL-2

Files: extensions/libxt_CT.c
Copyright: 2010-2013, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libxt_DSCP.c
Copyright: 2000-2002, Matthew G. Marsh <mgm@paktronix.com>
                      Harald Welte <laforge@gnumonks.org>
License: GPL-2

Files: extensions/libxt_HMARK.c
Copyright: 2012, Hans Schillstrom <hans.schillstrom@ericsson.com>
           2012, Pablo Neira Ayuso <pablo@netfilter.org>
License: GPL-2

Files: extensions/libxt_IDLETIMER.c
Copyright: 2010, Nokia Corporation
License: GPL-2

Files: extensions/libxt_LED.c
Copyright: 2008, Adam Nielsen <a.nielsen@shikadi.net>
License: GPL-2

Files: extensions/libxt_NFQUEUE.c
Copyright: 2005, by Harald Welte <laforge@netfilter.org>
License: GPL-2

Files: extensions/libxt_RATEEST.c
Copyright: 2008-2013, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libxt_SECMARK.c
Copyright: 2006, Red Hat, Inc., James Morris <jmorris@redhat.com>
License: GPL-2

Files: extensions/libxt_SET.c
Copyright: 2000-2002, Joakim Axelsson <gozem@linux.nu>
                      Patrick Schaaf <bof@bof.de>
                      Martin Josefsson <gandalf@wlug.westbo.se>
           2003-2010, Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
License: GPL-2

Files: extensions/libxt_SYNPROXY.c
Copyright: 2013, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libxt_TCPMSS.c
Copyright: 2000, Marc Boucher
License: GPL-2

Files: extensions/libxt_TCPOPTSTRIP.c
Copyright: 2007, Sven Schnelle <svens@bitebene.org>
           2007, CC Computer Consultants GmbH
License: GPL-2

Files: extensions/libxt_TEE.c
Copyright: 2007, Sebastian Claßen <sebastian.classen [at] freenet.ag>
           2007-2010, Jan Engelhardt <jengelh [at] medozas de>
License: GPL-2

Files: extensions/libxt_TOS.c
Copyright: 2007, CC Computer Consultants GmbH
License: GPL-2

Files: extensions/libxt_TPROXY.c
Copyright: 2002-2008, BalaBit IT Ltd.
License: GPL-2

Files: extensions/libxt_addrtype.c
Copyright: 2003-2013, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libxt_bpf.c
Copyright: 2013, Google, Inc.
License: GPL-2

Files: extensions/libxt_cluster.c
Copyright: 2009, Pablo Neira Ayuso <pablo@netfilter.org>
License: GPL-2

Files: extensions/libxt_connmark.c
Copyright: 2002, 2004, MARA Systems AB <http://www.marasystems.com> by Henrik Nordstrom <hno@marasystems.com>
License: GPL-2

Files: extensions/libxt_conntrack.c
Copyright: 2001, Marc Boucher (marc@mbsi.ca).
           2007-2008, CC Computer Consultants GmbH
License: GPL-2

Files: extensions/libxt_dccp.c
Copyright: 2005, by Harald Welte <laforge@netfilter.org>
License: GPL-2

Files: extensions/libxt_devgroup.c
Copyright: 2011, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libxt_dscp.c
Copyright: 2002, Harald Welte <laforge@gnumonks.org>
License: GPL-2

Files: extensions/libxt_ecn.c
Copyright: 2002, Harald Welte <laforge@netfilter.org>
           2011, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libxt_hashlimit.c
Copyright: 2003-2004, Harald Welte <laforge@netfilter.org>
License: GPL-2

Files: extensions/libxt_osf.c
Copyright: 2003+, Evgeniy Polyakov <zbr@ioremap.net>
License: GPL-2

Files: extensions/libxt_owner.c
Copyright: 2007-2008, CC Computer Consultants GmbH
License: GPL-2

Files: extensions/libxt_policy.c
Copyright: 2005-2013, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libxt_rateest.c
Copyright: 2008-2013, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libxt_sctp.c
Copyright: 2003, Harald Welte <laforge@gnumonks.org>
License: GPL-2

Files: extensions/libxt_set.c
Copyright: 2000-2002, Joakim Axelsson <gozem@linux.nu>
                      Patrick Schaaf <bof@bof.de>
                      Martin Josefsson <gandalf@wlug.westbo.se>
           2003-2010, Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
License: GPL-2

Files: extensions/libxt_socket.c
Copyright: 2007, BalaBit IT Ltd.
License: GPL-2

Files: extensions/libxt_statistic.c
Copyright: 2006-2013, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: extensions/libxt_string.c
Copyright: 2000, Emmanuel Roger <winfield@freegates.be>
           2005-08-05, Pablo Neira Ayuso <pablo@eurodev.net>
License: GPL-2

Files: extensions/libxt_time.c
Copyright: 2007, CC Computer Consultants GmbH
License: GPL-2

Files: extensions/libxt_tos.c
Copyright: 2007, CC Computer Consultants GmbH
License: GPL-2

Files: extensions/libxt_u32.c
Copyright: 2002, Don Cohen <don-netf@isis.cs3-inc.com>
           2007, CC Computer Consultants GmbH
License: GPL-2

Files: include/linux/netfilter/ipset/ip_set.h
Copyright: 2000-2002, Joakim Axelsson <gozem@linux.nu>
                      Patrick Schaaf <bof@bof.de>
                      Martin Josefsson <gandalf@wlug.westbo.se>
           2003-2011, Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
License: GPL-2

Files: include/linux/netfilter/xt_AUDIT.h
Copyright: 2010-2011, Thomas Graf <tgraf@redhat.com>
           2010-2011, Red Hat, Inc.
License: GPL-2

Files: include/linux/netfilter/xt_CHECKSUM.h
Copyright: 2002, Harald Welte <laforge@gnumonks.org>
           2010, Red Hat Inc
License: GPL-2

Files: include/linux/netfilter/xt_DSCP.h
Copyright: 2002, Harald Welte <laforge@gnumonks.org>
License: GPL-2

Files: include/linux/netfilter/xt_IDLETIMER.h
Copyright: 2004, 2010,  Nokia Corporation
License: GPL-2

Files: include/linux/netfilter/xt_NFQUEUE.h
Copyright: 2005, Harald Welte <laforge@netfilter.org>
License: GPL-2

Files: include/linux/netfilter/xt_connmark.h
Copyright: 2002, 2004, MARA Systems AB <http://www.marasystems.com> by Henrik Nordstrom <hno@marasystems.com>
License: GPL-2

Files: include/linux/netfilter/xt_conntrack.h
Copyright: 2001, Marc Boucher (marc@mbsi.ca)
License: GPL-2

Files: include/linux/netfilter/xt_dscp.h
Copyright: 2002, Harald Welte <laforge@gnumonks.org>
License: GPL-2

Files: include/linux/netfilter/xt_ecn.h
Copyright: 2002, Harald Welte <laforge@netfilter.org>
License: GPL-2

Files: include/linux/netfilter/xt_osf.h
Copyright: 2003+, Evgeniy Polyakov <johnpol@2ka.mxt.ru>
License: GPL-2

Files: include/linux/netfilter_ipv4.h
Copyright: 1998, Rusty Russell
License: GPL-2

Files: include/linux/netfilter_ipv4/ip_queue.h
Copyright: 2000, James Morris
License: GPL-2

Files: include/linux/netfilter_ipv4/ipt_ECN.h
Copyright: 2002, Harald Welte <laforge@gnumonks.org>
License: GPL-2

Files: include/linux/netfilter_ipv4/ipt_TTL.h
Copyright: 2000, Harald Welte <laforge@netfilter.org>
License: GPL-2

Files: include/linux/netfilter_ipv4/ipt_ULOG.h
Copyright: 2000-2002, Harald Welte <laforge@gnumonks.org>
License: GPL-2

Files: include/linux/netfilter_ipv4/ipt_ttl.h
Copyright: 2000, Harald Welte <laforge@gnumonks.org>
License: GPL-2

Files: include/linux/netfilter_ipv6.h
Copyright: 1998, Rusty Russell
           1999, David Jeffery
License: GPL-2

Files: iptables/iptables-apply
Copyright: 2006, Martin F. Krafft <madduck@madduck.net>
           2010, GW <gw.2010@tnode.com or http://gw.tnode.com/>
License: Artistic

Files: iptables/iptables-save.c
Copyright: 1999, Paul 'Rusty' Russell <rusty@rustcorp.com.au>
           2000-2002, Harald Welte <laforge@gnumonks.org>
License: GPL-2

Files: iptables/iptables-xml.c
Copyright: 2006, Ufo Mechanic <azez@ufomechanic.net>
License: GPL-2

Files: iptables/nft.c
Copyright: 2012 Pablo Neira Ayuso <pablo@netfilter.org>
License: GPL-2+

Files: iptables/nft-arp.c
Copyright: 2013 Pablo Neira Ayuso <pablo@netfilter.org>
           2013 Giuseppe Longo <giuseppelng@gmail.com>
License: GPL-2+

Files: iptables/nft-bridge.c
Copyright: 2014 Giuseppe Longo <giuseppelng@gmail.com>
License: GPL-2+

Files: iptables/nft-ipv4.c iptables/nft-ipv6.c iptables/nft-shared.c
Copyright: 2012-2013 Pablo Neira Ayuso <pablo@netfilter.org>
           2013 Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
License: GPL-2+

Files: iptables/xtables-arp.c iptables/xtables-eb.c
Copyright: 2002 Bart De Schuymer <bdschuym@pandora.be>
License: GPL-2+

Files: libiptc/libip4tc.c
Copyright: 1999, Paul ``Rusty'' Russell
License: GPL-2

Files: libiptc/libip6tc.c
Copyright: 1999, Paul ``Rusty'' Russell
License: GPL-2

Files: libiptc/libiptc.c
Copyright: 1999, Paul ``Rusty'' Russell
           2000-2004, by the Netfilter Core Team <coreteam@netfilter.org>
           2003, 2004, Harald Welte <laforge@netfilter.org>
           2008, Jesper Dangaard Brouer <hawk@comx.dk>
License: GPL-2

Files: libxtables/xtables.c
Copyright: 2000-2006, by the netfilter coreteam <coreteam@netfilter.org>
License: GPL-2

Files: libxtables/xtoptions.c
Copyright: 2011, Jan Engelhardt
License: GPL-2

Files: utils/nfsynproxy.c
Copyright: 2013, Patrick McHardy <kaber@trash.net>
License: GPL-2

Files: utils/pf.os
Copyright: 2000-2003, Michal Zalewski <lcamtuf@coredump.cx>
           2003, Mike Frantzen <frantzen@w4g.org>
License: custom
 Permission to use, copy, modify, and distribute this software for any
 purpose with or without fee is hereby granted, provided that the above
 copyright notice and this permission notice appear in all copies.
 .
 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF

License: GPL-2
 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 package; if not, write to the Free
 Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 Boston, MA  02110-1301 USA
 .
 On Debian systems, the full text of the GNU General Public
 License version 2 can be found in the file
 `/usr/share/common-licenses/GPL-2'.

License: GPL-2+
 This package 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 package 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. If not, see <http://www.gnu.org/licenses/>
 .
 On Debian systems, the complete text of the GNU General
 Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".

License: Artistic
 On Debian systems, the full text can be found in the file "/usr/share/common-licenses/Artistic"
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 /.
/usr
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/libip6tc.so.2.0.0
/usr/share
/usr/share/doc
/usr/share/doc/libip6tc2
/usr/share/doc/libip6tc2/NEWS.Debian.gz
/usr/share/doc/libip6tc2/changelog.Debian.gz
/usr/share/doc/libip6tc2/copyright
/usr/lib/x86_64-linux-gnu/libip6tc.so.2
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Package: libip6tc2
Status: install reinstreq unpacked
Priority: optional
Section: libs
Installed-Size: 66
Maintainer: Debian Netfilter Packaging Team <pkg-netfilter-team@lists.alioth.debian.org>
Architecture: amd64
Multi-Arch: same
Source: iptables
Version: 1.8.9-2
Depends: libc6 (>= 2.28)
Description: netfilter libip6tc library
 The iptables/xtables framework has been replaced by nftables. You should
 consider migrating now.
 .
 This package contains the user-space iptables (IPv6) C library from the
 Netfilter xtables framework.
 .
 iptables IPv6 ruleset ADT and kernel interface.
 .
 This library has been considered private for years (and still is), in the
 sense of changing symbols and backward compatibility not guaranteed.
Homepage: https://www.netfilter.org/
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           Package: libip6tc2
Status: install ok unpacked
Priority: optional
Section: libs
Installed-Size: 66
Maintainer: Debian Netfilter Packaging Team <pkg-netfilter-team@lists.alioth.debian.org>
Architecture: amd64
Multi-Arch: same
Source: iptables
Version: 1.8.9-2
Depends: libc6 (>= 2.28)
Description: netfilter libip6tc library
 The iptables/xtables framework has been replaced by nftables. You should
 consider migrating now.
 .
 This package contains the user-space iptables (IPv6) C library from the
 Netfilter xtables framework.
 .
 iptables IPv6 ruleset ADT and kernel interface.
 .
 This library has been considered private for years (and still is), in the
 sense of changing symbols and backward compatibility not guaranteed.
Homepage: https://www.netfilter.org/
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  libnfnetlink.so.0 libnfnetlink0 #MINVER#
* Build-Depends-Package: libnfnetlink-dev
 NFNETLINK_1.0.1@NFNETLINK_1.0.1 1.0.2
 nfnl_addattr16@NFNETLINK_1.0.1 1.0.2
 nfnl_addattr32@NFNETLINK_1.0.1 1.0.2
 nfnl_addattr8@NFNETLINK_1.0.1 1.0.2
 nfnl_addattr_l@NFNETLINK_1.0.1 1.0.2
 nfnl_build_nfa_iovec@NFNETLINK_1.0.1 1.0.2
 nfnl_callback_register@NFNETLINK_1.0.1 1.0.2
 nfnl_callback_unregister@NFNETLINK_1.0.1 1.0.2
 nfnl_catch@NFNETLINK_1.0.1 1.0.2
 nfnl_check_attributes@NFNETLINK_1.0.1 1.0.2
 nfnl_close@NFNETLINK_1.0.1 1.0.2
 nfnl_dump_packet@NFNETLINK_1.0.1 1.0.2
 nfnl_fd@NFNETLINK_1.0.1 1.0.2
 nfnl_fill_hdr@NFNETLINK_1.0.1 1.0.2
 nfnl_get_msg_first@NFNETLINK_1.0.1 1.0.2
 nfnl_get_msg_next@NFNETLINK_1.0.1 1.0.2
 nfnl_handle_packet@NFNETLINK_1.0.1 1.0.2
 nfnl_iterator_create@NFNETLINK_1.0.1 1.0.2
 nfnl_iterator_destroy@NFNETLINK_1.0.1 1.0.2
 nfnl_iterator_next@NFNETLINK_1.0.1 1.0.2
 nfnl_iterator_process@NFNETLINK_1.0.1 1.0.2
 nfnl_join@NFNETLINK_1.0.1 1.0.2
 nfnl_listen@NFNETLINK_1.0.1 1.0.2
 nfnl_nfa_addattr16@NFNETLINK_1.0.1 1.0.2
 nfnl_nfa_addattr32@NFNETLINK_1.0.1 1.0.2
 nfnl_nfa_addattr_l@NFNETLINK_1.0.1 1.0.2
 nfnl_open@NFNETLINK_1.0.1 1.0.2
 nfnl_parse_attr@NFNETLINK_1.0.1 1.0.2
 nfnl_parse_hdr@NFNETLINK_1.0.1 1.0.2
 nfnl_portid@NFNETLINK_1.0.1 1.0.2
 nfnl_process@NFNETLINK_1.0.1 1.0.2
 nfnl_query@NFNETLINK_1.0.1 1.0.2
 nfnl_rcvbufsiz@NFNETLINK_1.0.1 1.0.2
 nfnl_recv@NFNETLINK_1.0.1 1.0.2
 nfnl_send@NFNETLINK_1.0.1 1.0.2
 nfnl_sendiov@NFNETLINK_1.0.1 1.0.2
 nfnl_sendmsg@NFNETLINK_1.0.1 1.0.2
 nfnl_set_rcv_buffer_size@NFNETLINK_1.0.1 1.0.2
 nfnl_set_sequence_tracking@NFNETLINK_1.0.1 1.0.2
 nfnl_subsys_close@NFNETLINK_1.0.1 1.0.2
 nfnl_subsys_open@NFNETLINK_1.0.1 1.0.2
 nfnl_talk@NFNETLINK_1.0.1 1.0.2
 nfnl_unset_sequence_tracking@NFNETLINK_1.0.1 1.0.2
 nlif_catch@NFNETLINK_1.0.1 1.0.2
 nlif_close@NFNETLINK_1.0.1 1.0.2
 nlif_fd@NFNETLINK_1.0.1 1.0.2
 nlif_get_ifflags@NFNETLINK_1.0.1 1.0.2
 nlif_index2name@NFNETLINK_1.0.1 1.0.2
 nlif_open@NFNETLINK_1.0.1 1.0.2
 nlif_query@NFNETLINK_1.0.1 1.0.2
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     libnfnetlink 0 libnfnetlink0 (>= 1.0.2)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        # Triggers added by dh_makeshlibs/13.6
activate-noawait ldconfig
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               fc48b2d6c920ffac0438700f12dff83b  usr/lib/x86_64-linux-gnu/libnfnetlink.so.0.2.0
b9e71737365493d8db5e528efd3266bd  usr/share/doc/libnfnetlink0/changelog.Debian.gz
3b51a7d52a82c430fa0b6b4b5ec1f7ea  usr/share/doc/libnfnetlink0/copyright
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Package: libnfnetlink0
Source: libnfnetlink
Version: 1.0.2-2
Architecture: amd64
Maintainer: Debian Netfilter Packaging Team <pkg-netfilter-team@lists.alioth.debian.org>
Installed-Size: 51
Depends: libc6 (>= 2.14)
Section: libs
Priority: optional
Multi-Arch: same
Homepage: https://git.netfilter.org/libnfnetlink
Description: Netfilter netlink library
 libnfnetlink is the low-level library for netfilter related
 kernel/userspace communication. It provides a generic messaging
 infrastructure for in-kernel netfilter subsystems (such as
 nfnetlink_log, nfnetlink_queue, nfnetlink_conntrack) and their
 respective users and/or management tools in userspace.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Package: libnfnetlink0
Status: install reinstreq half-installed
Priority: optional
Section: libs
Architecture: amd64
Multi-Arch: same
Version: 1.0.2-2
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         ELF          >            @                 @ 8 	 @                                                                                  1      1                    `       `       `      0      0                   }                                           }                                           8      8      8      $       $              Ptd   f      f      f                         Qtd                                                  Rtd   }                                              GNU WY8pHN]u,    %         	    d"    @8   H DA		 $                        !   #   &   '                   )           *   ,   -   0   1   4   5   7   8   :   =   >   A   B   D   E   H   I       J   _;8jA1Y4=
;8N5Eǒ=Vy>	>6EJ,|J7
A*#*":88ZVUYEv&=C/"W!LhEImaV$P{2]@vC-oYK37?G68/SX9%?{VJ+4;vye	98                                                  o                                           @                                                                                     '                                           4                                          ~                     K                                           e                      )                     |                                                                j                                           Y                                                                                     R                          .            Z    :      y            6                 <             *    '      f       F    C             o    @;                 6             o    D             
    &      l           L      V       5     #      )            `#      (            @"                +      X           P%             r    P*      &      \    0D      j                          U     )                 4                  &      K           pA                 `L      F           K                 `B                  p%      +           @%                 3            0    PC      *           J            J    @8                 >      =      (     7                 I                 <                 `'      M       ;     (      X           p5                 I             z    pE      m       ;    7                  `%             c    *      7       H    (                 ?                0>      a           =                 M      >       A     #      v       nfnl_dump_packet __printf_chk nfnl_fd __assert_fail nfnl_portid nfnl_open calloc socket getsockname time bind __errno_location free __stack_chk_fail nfnl_set_sequence_tracking nfnl_unset_sequence_tracking nfnl_set_rcv_buffer_size nfnl_subsys_open nfnl_subsys_close nfnl_close nfnl_join setsockopt nfnl_send sendto nfnl_sendmsg nfnl_sendiov nfnl_fill_hdr nfnl_parse_hdr nfnl_recv recvfrom nfnl_listen recvmsg strerror stderr __fprintf_chk nfnl_talk memcpy perror nfnl_addattr_l memset nfnl_nfa_addattr_l nfnl_addattr8 nfnl_nfa_addattr16 nfnl_addattr16 nfnl_nfa_addattr32 nfnl_addattr32 nfnl_parse_attr nfnl_build_nfa_iovec nfnl_rcvbufsiz getsockopt nfnl_get_msg_first nfnl_get_msg_next nfnl_callback_register nfnl_callback_unregister nfnl_check_attributes nfnl_handle_packet nfnl_process nfnl_iterator_create malloc nfnl_iterator_destroy nfnl_iterator_process nfnl_iterator_next nfnl_catch nfnl_query strcpy nlif_index2name nlif_get_ifflags nlif_open nlif_close nlif_catch nlif_query nlif_fd getpid libc.so.6 libnfnetlink.so.0 NFNETLINK_1.0.1 GLIBC_2.3.4 GLIBC_2.14 GLIBC_2.4 GLIBC_2.2.5                                                                                         	                 s                        ti	                ii
   *     ui	   4                                                       7                                        1                                                                                 0                                (                    0         #           8                    @         	           H         
           P                    X                    `         
           h         :           p         +           x                                                                     ;                                                                                /                                                   ȏ         @           Џ                    ؏                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                5n  %n  @ %n  h    %n  h   %n  h   %n  h   %n  h   %n  h   %n  h   %n  h   p%n  h   `%n  h	   P%zn  h
   @%rn  h   0%jn  h    %bn  h
   %Zn  h    %Rn  h   %Jn  h   %Bn  h   %:n  h   %2n  h   %*n  h   %"n  h   %n  h   %n  h   p%
n  h   `%n  h   P%m  h   @%m  h   0%m  h    %m  h   %m  h    %m  h   %m  h    %m  h!   %m  h"   AUHAHC  ATH5=  UHSH_H   D`1IHD   H5'?  10HU   1H56?        H1H5C?     D   1H5;=  UDM1DEM    H55?  H-v?  E;DfE9=KHH   1  A)HHE~DfAwH[]A\A] HtPH
B     H5<  H=&>  8     HtGPH
gB     H5<  H==      AU     ATUSHdH%(   HD$1'IH            'A$ǃ        Il$D$   fAT$Ll$HfAD$L   |$   fA|$   1A\$AD$(    I$  AD$ ID$@fD  HH9uA\$A<$   Ht]A\$A<$LHD$   &u=|$u+AL$,D  HD$dH+%(   u1HL[]A\A]f    A<$LE1jf.     O,ff.     g,ff.     w(ff.     AWAVAUATUSHH   A@   DHKHLsHM      T$ALHCHHtWT$Hk8HE@Dk@SEH  DcD]fHH9u]} Hu   tLE]KdLt8HL[]A\A]A^A_f.     E1    E1    KH\ H{HHCH    H
m?  1  H59  H=9  %D  SHt&G    HG
 HHt
NHC    [H
>  Z  H5M9  H=[9  D  ATUSHtDIH_8H  f     HHdH9uA<$x
L1[]A\H
t>  o  H58  H=8  d@ Ht$Ht!?HL$A        HH
>    H58  H=8   HHtHt9LG?A   1
HH
=    H5A8  H=I8  H
=    H5"8  H=48  f.     HHtHt+?+HH
G=    H57  H=7  gH
(=    H57  H=7  H     HHЉdH%(   HL$81HtQHt$HOHH$D$   HD$HD$     HD$(    D$0    HT$8dH+%(   u$HHH
<    H5+7  H=37  ff.      AUAATUHL$0H   H   HEĉGfNF    A	HfDN@,u(F    fADnF fDfH]A\A]D  x WP Vu1Ht$HU Ht$B FH
;    H5T6  H=b6  H
};    H556  H=7  ff.     fvtHtHFHHF 1D  1HtHH2f     H(dH%(   HD$1H   H   H   Hv{?1LL$LD$D$   ~|$u=T$uHHT$dH+%(      H(] *   HfD  C    H@ + J   HH
=:    H55  H=J6  H
:    H54  H=4  nH
9    H54  H==6  O*f.     AWfAVAUATUHSH   H|$Ll$$H4$dH%(   H$   1HD$0D$HHD$P   HD$$    fD$$H$   HD$HD$0HD$@D$XLl$@D$H   HD$X   D$,    HD$8    HD$D$hHD$Ht$1ҋ8eyO8tۉ	   1H$   dH+%(   _  HĘ   []A\A]A^A_f.       DD$HA  W  D$   D   A9   HD$1AIS@ f   H$HLLЅ\A	AE)MDA   E<$DxNE9IAD$fuH
7     H2  IHb  H81    Hyb  H8D$p tWH
7  H2     1m AD$fD  D$p utE   P~EH
^7  H2  1   VD$p    Ha  H
(7     HP2  H81Ha  H
6     H'2  H81lHa  H
6     H1  H81H
6  H 4  HQa     H81ZAH
~6  H1       AWHfAVAUATUHSLH   H$   LD$Ld$4H|$    dH4%(   H$   10L$<M D$XHt$HHt$@Ht$`1M D$hHD$@Ld$PD$X   HD$h   ft$6f|$4T$8L$HD$xMK  HD$P} 1HHD$  H$   HD$H    HD$(HD$@Ht$} 1   
  DD$XA    D$   AVA9     L|$(Ll$ H,$HLAO@ HtLHLՅ  AAE)LDA  D3D   E9   H$@9CuD$;Cuf{  H|$   H:_  H
s4     HZ0  H815xKH
L4  H/  8H^     H81f     H^  H8$       H
3  H/     1AH$   dH+%(     HĨ   D[]A\A]A^A_@ HH,$$       E)HK^  Aо   H
|3  H/  H81CfD  AxfHfD  EH
>3  H0  1   A@$    H
3  H/  I߃v[D[D$D$DډE   H|$HDHD$H|$DHE1HU]  H
2     HM.  H81PE_H(]  H
a2     H/  H81#A`H\  H
22     HV-  H81A1H=-  8H
1     Hh-  IH\  H81A(     AUATUSHH         EhIXAD 9weHDHfSH{IcfD+EdUJ<+1)HcA$DEADA$1H[]A\A]         H
0  9  H5+  H=4-  oH
0  8  H5+  H=
-  PH
0  7  H5+  H=+  1USHH      xeH?AhH΃/99HcHfWHIcfo_f1H[]     +    H
/  [  H5+  H=T,  H
/  Z  H5*  H=*,  pH
/  Y  H5*  H= ,  QHL$Ht~Wx4HL$A   HH
W/  u  H5*  H=*  H
8/  w  H5`*  H=+  H
/  v  H5A*  H=+  f     HfL$Ht~Wx4HL$A   HH
.    H5)  H=E+  vH
.    H5)  H=+  WH
p.    H5)  H=*  8     HfL$Ht~Wx4HL$A   jHH
.    H5^)  H=p)  H
-    H5?)  H=*  H
-    H5 )  H=b*       HL$Ht~Wx4HL$A   kHH
_-    H5(  H=&*  WH
@-    H5(  H=)  8H
!-    H5(  H=)  f     HL$Ht~Wx4HL$A   KHH
,    H5?(  H=Q(  H
,    H5 (  H=m)  H
,    H5(  H=C)  f     ATUSHt}   HH   Hc1AH`HE=DfD  D99Sс  f9H\A)HHE~	fwD[]A\H
+    H5S'  H=(  H
+    H54'  H=(  H
+    H5'  H=s(  ff.     fUHAWAVAUATISH(dH%(   HE1Fftfftm   f  HRL4A8FE  L,@IFHIBt(   fu~HUdH+%(      He[A\A]A^A_]@ Ft2MHvAD$؉
@ J   
fe    D  ƍKIT$IH   % H)ILLEtMnHIE HtIUHuLL.@    L     ff.      HHt2HtLHyfVf>H0H@   L@HPHH
n)    H5%  H=&  H
O)    H5$  H=V&      ATSH(t$dH%(   HD$1D$   D$    Ht{HLd$?A   L!      x:;HL$LD$      OD$HT$dH+%(   uEH([A\ DD$;L      H
f(    H5.$  H=%  HHttHtPHt,HvvH9wHw0HH    1HH
'  7  H5#  H=%  RH
'  6  H5#  H=#  3H
'  5  H5#  H=%  @ HH   H   HtpHG0HHt[H<H9sPH9rKfxtD@u>HH)H)8wH)HHv!0vH9ֺ    HGHA0HD  1HA0HH
&  K  H5"  H=#$  fH
&  J  H5"  H="  GH
&  I  H5"  H=$  (     HHthHtD@8w
v,HG@oHvH HRHP1HfD  K    H
&  y  H5'"  H=#  H
%  x  H5"  H="  HHt9@8w
v!HW@HvHH     1H     H
g%    H5!  H=!  /ff.     @ USHH  HH   IH   Fff=   HRH4IHHJHH,8BEv;vzU1LH3IvUHS=H     9<J)HHftf9Mr
ɃIȅ~Hfw@ 1H[]øH
9$    H5   H=!  !H
$    H5z   H=!  H
#    H5[   H=!   UHAWAVAUATSH8dH%(   HE1G  I   I9v/    DD)Iă  A$9      A9GAAD$ff=   ҃   HRIL :AE   L<@HAHIBD8fyILLHMH   LE% H)ILLMLExqHMLyHIHtAIWHuLHeHUdH+%(   u9He[A\A]A^A_]D  DD)LIă 1@ L>ff.      ATUSH   HH   IHtfFHuE1Iw-2 L9w*HHx~JI)HIvw[]A\@ ;G tF T   H
!  y  H5"  H=g  H
!  x  H5  H=  H
l!  w  H5  H=Z  lff.     ATUSH   HH   HHtj   IHtKHv'E vH9wI,$A\$L[]A\f     LE1E` J   L[]A\M    H
     H5.  H=s  H
     H5  H='  H
`     H5  H=f  x     HtPH
     H5  H=+  FfD  HH   LMtXA@u#Fv;Av39r/LHs ;G tf T   HfD  K J   H
\    H5,  H=  H
=    H5
  H=  D  HHt#Ht=H)FH¸   HHH
    H5  H=3  EH
    H5  H=  &fD  UHAVAUATSHHdH%(   HE1Huz     [8uILS(IHHBHHH)Ll$IL*AƃtHcLH$AƅHEdH+%(   u/HeD[A\A]A^]H
    H5  H=M  _:f.     UHtHHt$H
tH]    ]H
j  8  H5z  H=  H
K  7  H5[  H=   UASH  dH%(   H$  w)H$  dH+%(      H  D[]D  HHHW HH9   v  sHHL H9HH9u@     HHH9t-H;wuHHGHBHzA   f    E1Wff.     fu	@ f.     AVAUATUSH  dH%(   H$  1w/H$  dH+%(     H  []A\A]A^ HW IH H9   n  Lt$MtEeDHHH] H9u  D  HH9   D;cuA   AEHT$HK CAECH      9CHGHrsZ   H{(tR   @ IvO   EHU HZHHkH] f     HRHH|H|H{(IIL)H)΃r1҉уLM9rf.     8   HHsDcE1fD  C    H{(HC     8RH{(TT"TfTfD  fu	@ f.     HH   HtptZHHHHH9u)H H9t 9puHp(H   HD      H *   f   HH
'     H5  H=  H
     H5m  H=p  HHt{HtWt>HHHH9u(     H H9t9pu@   H@     HH
d     H5  H=  lH
E     H5  H=  Mff.     fATH     UHzH   IH       H H@HH9u      M$   fA$  HI$  HfA$0  I$8  M$@  Q  I$   HHtfI$  H!  x=I$   I$(    xHL]A\I$   H	  f     I$     LE1HL]A\ff.     fAUATUSHH   IH  H   LM     I   I(    I   ~  fD  H} HH9t@ HGHCHHHH9uHL9uHL[]A\A]H
C    H5  H=  c Ht!H   HtZ  f.     PH
  +  H5  H=  f.     SHt1HH      f  xH   Ht[`  [H
z  C  H57  H=:  f.     HtH   Ht @ PH
*  R  H5  H=  rfHGH   Hwff.     @ HGHt8H9u$H9tHH Hu    HH   H HG   1ff.     ATAUSHHc1HHǃ'<@ 9&KD9Hσ)HÃ~fw[]A\@ []A\    H8A  1dH%(   HD$(1   fDD$Ht$fT$A      LD$HD$    fD$GHD$    D$    GG?D$   D$D$ *HT$(dH+%(   uH8ATf1USHHp   ?dH%(   H$h   1HD$Hl$`D$(HD$ Ht$ HD$D$8Hl$HD$    D$(   HD$0HD$8   D$HV      |$(   Aă~bD  U vUD9wPMf   ftCHCHu@ H Htf;HuHpHPU A)HA   !#vRIEA     H$h   dH+%(   u&Hp   []A\@ 81mff.     fSH@ H   [D  AT       UHdH%(   HD$1IH   D$      1Ҿ   AD${A$ǅxz1   AD$    Il$fAT$T$HfAD$AD$   x7A<$HT$Hx"|$ufA|$u1+AD$@ A<$LE1HD$dH+%(   uHL]A\<ff.     UH?uH]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            %s called from %s
   NFM_PAYLOAD(nlh) = %u
 libnfnetlink.c nfnlh ssh n msg buf %s: recvmsg overrun: %s
 %s: EOF on netlink
 %s: MSG_TRUNC
 %s: Malformed msg (len=%d)
 %s: remnant size %d
 %s: sendmsg(netlink) %s
 %s: recvmsg over-run
 %s: Truncated message

 %s: ERROR truncated

 NFNETLINK answers %s: Unexpected reply!

 %s: Messages truncated

 %s: Remnant of size %d

 maxlen > 0 type >= 0 nfa tb max > 0 iov cb it it->nlh        nlmsghdr = %p, received_len = %u
       NLMSG_DATA(nlh) = %p (+%td bytes)
      NFM_NFA(NLMSG_DATA(nlh)) = %p (+%td bytes)
     nlmsg_type = %u, nlmsg_len = %u, nlmsg_seq = %u nlmsg_flags = 0x%x
       nfa@%p: nfa_type=%u, nfa_len=%u
    %s: Bad sender address len (%d)
        %s: Bad sender address len %d
  %s: Malformed message: len=%d

         nfnl_query      nfnl_catch      nfnl_iterator_next              nfnl_iterator_process           nfnl_iterator_destroy           nfnl_iterator_create    nfnl_process            nfnl_check_attributes           nfnl_callback_unregister        nfnl_callback_register          nfnl_get_msg_next               nfnl_get_msg_first      nfnl_rcvbufsiz          nfnl_build_nfa_iovec            nfnl_parse_attr nfnl_addattr32  nfnl_nfa_addattr32      nfnl_addattr16          nfnl_nfa_addattr16      nfnl_addattr8           nfnl_nfa_addattr_l      nfnl_addattr_l  nfnl_talk       nfnl_listen     nfnl_recv       nfnl_fill_hdr   nfnl_sendiov    nfnl_sendmsg    nfnl_send       nfnl_join       nfnl_close              nfnl_subsys_close               nfnl_subsys_open        nfnl_portid     nfnl_fd nfnl_dump_packet iftable.c h != NULL name != NULL flags != NULL nlif_fd nlif_query      nlif_catch      nlif_close              nlif_get_ifflags                nlif_index2name ;  ?   0  p   X  l    p        пD   `      P    P   @4  H  d       <  h  0    P    p  `$  T  pp  @      `    D  t        `  0  \         ,	  @@	   h	  	  	  	  
  @4
  H
  \
  p
  `
   
  p
    D             zR x  4      H   BOH D(H0(A ABB   T   0(    I   h   L)    J8   |   hv   BLA A(D@0
(D ABBC                                       H      +   BBB B(A0A8DP
8D0A(B BBBK    @  K    Aj
A,   \  l    BAA E
ABA        M    D i
A       ,f    Dc
A       X    DU
A       Ľ    DPi
A 0     H    BEA D0a
 ABBF    0  7          D  0&   D0y
A H   `  DX   BFB B(A0D8GA
8A0A(B BBBKL     X   BIB B(A0D8JAx
8D0A(B BBBE   8        BBA A(D0
(A ABBI (   8  |    AAD _
AAI    d  0    D e
A           D f
A           D f
A           D e
A            D e
A  ,     t    BAA ~
ABA   ,      4   AC
HH
E      P  y    Dv
A  (   l      BAD@
ABD          Dl
HF
A          Dv
FJ
A            Du
G       \a    Dh
D  (     =   AAD 
AAA ,   @     AC
MA
F   ,   p  $    BAA d
ABE   8         BAA O
ABJZ
ABA        *    K         Dt
HY
G     Dj    Dg
A  (   ,      AC
G
A      X  <m    A[
LF
A  $   |  @   FJw ?;*3$"    (     `    AGGv
DAF             @      
   BBB A(A0G}
0A(A BBBD    (         $   <      DN
FT
DQ
A     d      DG
ET
A   0        BKD 
DBAuDB8         BBA A(D0
(D ABBE      F    g      V    Aj
EF
A     0  >    _   D  0          X  <D       4   l  xi    BDC J
FBECAD           D@
A 4     4c   BGA JA+
 AABE        l    AY   (   	  p   BKD0
DBA    @	  T    AN                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     o    `             H                   
       @                           Ȏ             H                                                            	              o    (      o                         o           o    `      o           o                                                                                                                                       &       6       F       V       f       v                                                               !      !      &!      6!      F!      V!      f!      v!      !      !      !      !      !      !      !      !      "      "      &"      6"              5790915938ab70f380d048b6e6a0c24e5d752c.debug    y .shstrtab .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_d .gnu.version_r .rela.dyn .rela.plt .text .rodata .eh_frame_hdr .eh_frame .dynamic .got .gnu_debuglink                                                                                8      8      $                                 o       `      `                                  (                         8                          0             H      H      @                             8   o                                               E   o       (      (      8                            T   o       `      `      P                            c                                                     m      B                   H                          r                             @                            w             @"      @"      D/                             }              `       `                                                f      f                                                h      h      X	                                                }                                              Ȏ      ~      8                                                         4                                                    4                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         Wms6_iCF[Qn4Mڴx!I)e͕TJ~ )מSgvm Hɲl)[`l
^bSmF!' ìΒķUU8Qa}G͗
hڅ
:`ݲҸn/< F۠moWJ}sRr䩟rGUةdG!gm\((@=o?b[3I0iex
>=5[.9_39Ze-}]@9J%cN~
zA8àfї]?hkˆ#lR}vۋVX
OaV$u)C?txxD.9Kb.Wr@Ppʪr\w@r&1w>?|x|2ŜƬv/ͺlUk7;v
D%#^b`y&Z
TWJ|8y	
Hx%ר?j^u?EE<Q{=\X_Z#}kk&nTQz6\AҫbVBPRQQk]D(7L0\S~_QňuY$.X]WS&8#{fX&qA'i@B?v]Kl
yx*YU@e*`ݒ04zڪѱ@T5ΜZ&Annkρt^ZnYZwL&U#nt_zI,"Ȋ,d^EsNzuBu@#Hܫ՛IEmdV)\~ӞzSJnA1&Qѝ/R	Wj0`F|,aaE}y O*>%6tCl7nH<𣃉F|mnmׄ䀺I(N.|K%Q:YdUU9q|@W
Ow4,؞g "*YVgpYѠq˲C&%axyG*#~dh2  4c]u($'4-1WP⨮Y<+Vtxq;sx"!2dͲv!H&,{iX7MX!E,"g>2|Ԩ(04[<>R?;MrM-Aj6)cUXƺc5
}Z,.7INՋ~v'ϱyA
ɝ3.y>o)_4\ۡ[܂)k맰Y\ŁćP״PIGԛ|x'%χ~~szxL1*eIu0'ۂ솷$	Fm`eUJ@Gj)FVcOY64>ڜtsv7*NۄTKST>C|Nìd1FԺ]oGI"r+*UXJuN/?ptmM3ջ]
F	>EZr#{iC[]x{'VH)q+)=M:s>xTߛ~ XN#|VDaYD t [aUj|<enp@㳬kŗ=
~bv_Q`/m`߄ A~?a ؝v21ef1eeٟă"N8z }sӝ3
9W)p.$i_FmOm_lVF
7<wj(~jke	
hJoYЗhei>DCR	(҈
ʌ*6^x;hvT<k{u?ǭJ&GQ|n@d"L1/ȡvnDwŚ_#yuM&yi"%_jwOm,KXxc4jM3ͻvn]Qi                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            