git-repack.shon commit builtin-fast-export.c: handle nested tags (1982467)
   1#!/bin/sh
   2#
   3# Copyright (c) 2005 Linus Torvalds
   4#
   5
   6OPTIONS_KEEPDASHDASH=
   7OPTIONS_SPEC="\
   8git repack [options]
   9--
  10a               pack everything in a single pack
  11A               same as -a, and turn unreachable objects loose
  12d               remove redundant packs, and run git-prune-packed
  13f               pass --no-reuse-object to git-pack-objects
  14n               do not run git-update-server-info
  15q,quiet         be quiet
  16l               pass --local to git-pack-objects
  17 Packing constraints
  18window=         size of the window used for delta compression
  19window-memory=  same as the above, but limit memory size instead of entries count
  20depth=          limits the maximum delta depth
  21max-pack-size=  maximum size of each packfile
  22"
  23SUBDIRECTORY_OK='Yes'
  24. git-sh-setup
  25
  26no_update_info= all_into_one= remove_redundant= unpack_unreachable=
  27local= quiet= no_reuse= extra=
  28while test $# != 0
  29do
  30        case "$1" in
  31        -n)     no_update_info=t ;;
  32        -a)     all_into_one=t ;;
  33        -A)     all_into_one=t
  34                unpack_unreachable=--unpack-unreachable ;;
  35        -d)     remove_redundant=t ;;
  36        -q)     quiet=-q ;;
  37        -f)     no_reuse=--no-reuse-object ;;
  38        -l)     local=--local ;;
  39        --max-pack-size|--window|--window-memory|--depth)
  40                extra="$extra $1=$2"; shift ;;
  41        --) shift; break;;
  42        *)      usage ;;
  43        esac
  44        shift
  45done
  46
  47case "`git config --bool repack.usedeltabaseoffset || echo true`" in
  48true)
  49        extra="$extra --delta-base-offset" ;;
  50esac
  51
  52PACKDIR="$GIT_OBJECT_DIRECTORY/pack"
  53PACKTMP="$GIT_OBJECT_DIRECTORY/.tmp-$$-pack"
  54rm -f "$PACKTMP"-*
  55trap 'rm -f "$PACKTMP"-*' 0 1 2 3 15
  56
  57# There will be more repacking strategies to come...
  58case ",$all_into_one," in
  59,,)
  60        args='--unpacked --incremental'
  61        ;;
  62,t,)
  63        args= existing=
  64        if [ -d "$PACKDIR" ]; then
  65                for e in `cd "$PACKDIR" && find . -type f -name '*.pack' \
  66                        | sed -e 's/^\.\///' -e 's/\.pack$//'`
  67                do
  68                        if [ -e "$PACKDIR/$e.keep" ]; then
  69                                : keep
  70                        else
  71                                existing="$existing $e"
  72                        fi
  73                done
  74                if test -n "$existing"
  75                then
  76                        args="--kept-pack-only"
  77                fi
  78                if test -n "$args" -a -n "$unpack_unreachable" -a \
  79                        -n "$remove_redundant"
  80                then
  81                        args="$args $unpack_unreachable"
  82                fi
  83        fi
  84        ;;
  85esac
  86
  87args="$args $local $quiet $no_reuse$extra"
  88names=$(git pack-objects --honor-pack-keep --non-empty --all --reflog $args </dev/null "$PACKTMP") ||
  89        exit 1
  90if [ -z "$names" ]; then
  91        if test -z "$quiet"; then
  92                echo Nothing new to pack.
  93        fi
  94fi
  95
  96# Ok we have prepared all new packfiles.
  97mkdir -p "$PACKDIR" || exit
  98
  99# First see if there are packs of the same name and if so
 100# if we can move them out of the way (this can happen if we
 101# repacked immediately after packing fully.
 102rollback=
 103failed=
 104for name in $names
 105do
 106        for sfx in pack idx
 107        do
 108                file=pack-$name.$sfx
 109                test -f "$PACKDIR/$file" || continue
 110                rm -f "$PACKDIR/old-$file" &&
 111                mv "$PACKDIR/$file" "$PACKDIR/old-$file" || {
 112                        failed=t
 113                        break
 114                }
 115                rollback="$rollback $file"
 116        done
 117        test -z "$failed" || break
 118done
 119
 120# If renaming failed for any of them, roll the ones we have
 121# already renamed back to their original names.
 122if test -n "$failed"
 123then
 124        rollback_failure=
 125        for file in $rollback
 126        do
 127                mv "$PACKDIR/old-$file" "$PACKDIR/$file" ||
 128                rollback_failure="$rollback_failure $file"
 129        done
 130        if test -n "$rollback_failure"
 131        then
 132                echo >&2 "WARNING: Some packs in use have been renamed by"
 133                echo >&2 "WARNING: prefixing old- to their name, in order to"
 134                echo >&2 "WARNING: replace them with the new version of the"
 135                echo >&2 "WARNING: file.  But the operation failed, and"
 136                echo >&2 "WARNING: attempt to rename them back to their"
 137                echo >&2 "WARNING: original names also failed."
 138                echo >&2 "WARNING: Please rename them in $PACKDIR manually:"
 139                for file in $rollback_failure
 140                do
 141                        echo >&2 "WARNING:   old-$file -> $file"
 142                done
 143        fi
 144        exit 1
 145fi
 146
 147# Now the ones with the same name are out of the way...
 148fullbases=
 149for name in $names
 150do
 151        fullbases="$fullbases pack-$name"
 152        chmod a-w "$PACKTMP-$name.pack"
 153        chmod a-w "$PACKTMP-$name.idx"
 154        mv -f "$PACKTMP-$name.pack" "$PACKDIR/pack-$name.pack" &&
 155        mv -f "$PACKTMP-$name.idx"  "$PACKDIR/pack-$name.idx" ||
 156        exit
 157done
 158
 159# Remove the "old-" files
 160for name in $names
 161do
 162        rm -f "$PACKDIR/old-pack-$name.idx"
 163        rm -f "$PACKDIR/old-pack-$name.pack"
 164done
 165
 166# End of pack replacement.
 167
 168if test "$remove_redundant" = t
 169then
 170        # We know $existing are all redundant.
 171        if [ -n "$existing" ]
 172        then
 173                ( cd "$PACKDIR" &&
 174                  for e in $existing
 175                  do
 176                        case " $fullbases " in
 177                        *" $e "*) ;;
 178                        *)      rm -f "$e.pack" "$e.idx" "$e.keep" ;;
 179                        esac
 180                  done
 181                )
 182        fi
 183        git prune-packed $quiet
 184fi
 185
 186case "$no_update_info" in
 187t) : ;;
 188*) git-update-server-info ;;
 189esac