#!/bin/bash COPYRIGHT_NOTICE=" Fixing the svn:ignore subversion property automatically Copyright (C) 2008 Jeremy Buisson, TELECOM Bretagne This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA This file is part of Dynaco - Dynamic Adaptation for Components Dynaco is Developed at IRISA (PARIS team) and others INRIA-Rennes / INSA de Rennes / Université de Rennes 1 Campus universitaire de Rennes 1 avenue du Général Leclerc 35042 RENNES CEDEX, France " IFS=$'\t\n' # phase 1: « svn ls » du dépot pour récupérer la liste des fichiers # il s'agit normalement du seul accès au dépot # n'effectuer qu'un seul et unique « svn ls » est impératif lorsque # le dépot est distant et que l'authentification est coûteuse, # notamment avec les accès « svn+ssh ». echo -n "Retrieving the list of files from the repository: " file_list=$(svn ls -R | sed -e 's/^\(.*[^\/]\)\/\?$/.\/\1/') echo "done" # phase 2: trie les noms des fichiers par répertoire # l'idée consiste à avoir une variable par répertoire qui liste les # noms des fichiers contenus. # le nom de la variable d'un répertoire est généré par canonical_name function canonical_name_() { echo -n c # en espérant que ce soit suffisant pour éviter les collisions for algo in md5sum sha1sum sha512sum; do echo -n "_" part=$(echo -n "$1" | $algo | cut -d " " -f 1) echo -n $part done } function canonical_name() { c_name=$(canonical_name_ "$1") from_name=from_$c_name # au cas où, on vérifie qu'il n'y a pas de collision if eval "[[ -z \"\$$from_name\" ]]"; then eval "$from_name=\"\$1\"" elif eval "[[ \"\$$from_name\" != \"\$1\" ]]"; then echo echo echo "Collision in the cache:" echo "$1" eval "echo \"\$$from_name" exit 1 fi } echo -n "Caching directory listings: " max=$(echo $file_list | wc -w) i=0 prev="" canonical_prev="" prev_pc=0 for f in $file_list; do base="${f%/*}" name="${f##*/}" if [[ "$prev" == "$base" ]]; then canonical_base="$canonical_prev" else canonical_name "$base" canonical_base=$c_name canonical_prev="$canonical_base" prev="$base" fi eval "$canonical_base=\"\$$canonical_base\"\$'\\n'\"\$name\"" i=$(($i+1)) pc=$(($i*100/$max)) if [[ "$prev_pc" != "$pc" ]]; then echo -n -e "\rCaching directory listings: $pc%" prev_pc="$pc" fi done echo -e "\rCaching directory listings: done" # phase 3: calcule pour chaque répertoire une « bonne » valeur pour # la propriété svn:ignore, à savoir la liste des fichiers présents # dans la copie locale qui ne sont pas connus de svn # bien sûr, on fusionne avec la valeur précédente de svn:ignore, # puisque les fichiers déjà listés dans svn:ignore sont considérés # comme connus de svn. function fix_current_directory() { prefix="$1" echo -n "Fixing $prefix: " old_ign_list=$(svn propget svn:ignore . | sort -u | sed '/^$/d') ign_list=$( (svn status -N | grep '^?' | sed -e 's/^? //'; echo "$old_ign_list") | sort -u | sed '/^$/d') if [[ ! -z "$ign_list" ]]; then if [[ "$ign_list" != "$old_ign_list" ]]; then svn propset svn:ignore "$ign_list" . else echo "unchanged svn:ignore property" fi else echo "no file to ignore" fi } function fix_and_recurse() { prefix="$1" fix_current_directory "$prefix" # limite le parcours aux répertoires du dépot canonical_name "$prefix" eval subs=\$$c_name for sub in $subs; do if [[ -d "$sub" && ! -h "$sub" ]]; then ( cd "$sub" && fix_and_recurse "$prefix/$sub" ) fi done } fix_and_recurse "."