git-repack.shon commit Optimize "diff --cached" performance. (af3785d)
   1#!/bin/sh
   2#
   3# Copyright (c) 2005 Linus Torvalds
   4#
   5
   6USAGE='[-a] [-d] [-f] [-l] [-n] [-q] [--max-pack-size=N] [--window=N] [--window-memory=N] [--depth=N]'
   7SUBDIRECTORY_OK='Yes'
   8. git-sh-setup
   9
  10no_update_info= all_into_one= remove_redundant=
  11local= quiet= no_reuse= extra=
  12while case "$#" in 0) break ;; esac
  13do
  14        case "$1" in
  15        -n)     no_update_info=t ;;
  16        -a)     all_into_one=t ;;
  17        -d)     remove_redundant=t ;;
  18        -q)     quiet=-q ;;
  19        -f)     no_reuse=--no-reuse-object ;;
  20        -l)     local=--local ;;
  21        --max-pack-size=*) extra="$extra $1" ;;
  22        --window=*) extra="$extra $1" ;;
  23        --window-memory=*) extra="$extra $1" ;;
  24        --depth=*) extra="$extra $1" ;;
  25        *)      usage ;;
  26        esac
  27        shift
  28done
  29
  30# Later we will default repack.UseDeltaBaseOffset to true
  31default_dbo=false
  32
  33case "`git config --bool repack.usedeltabaseoffset ||
  34       echo $default_dbo`" in
  35true)
  36        extra="$extra --delta-base-offset" ;;
  37esac
  38
  39PACKDIR="$GIT_OBJECT_DIRECTORY/pack"
  40PACKTMP="$GIT_OBJECT_DIRECTORY/.tmp-$$-pack"
  41rm -f "$PACKTMP"-*
  42trap 'rm -f "$PACKTMP"-*' 0 1 2 3 15
  43
  44# There will be more repacking strategies to come...
  45case ",$all_into_one," in
  46,,)
  47        args='--unpacked --incremental'
  48        ;;
  49,t,)
  50        if [ -d "$PACKDIR" ]; then
  51                for e in `cd "$PACKDIR" && find . -type f -name '*.pack' \
  52                        | sed -e 's/^\.\///' -e 's/\.pack$//'`
  53                do
  54                        if [ -e "$PACKDIR/$e.keep" ]; then
  55                                : keep
  56                        else
  57                                args="$args --unpacked=$e.pack"
  58                                existing="$existing $e"
  59                        fi
  60                done
  61        fi
  62        [ -z "$args" ] && args='--unpacked --incremental'
  63        ;;
  64esac
  65
  66args="$args $local $quiet $no_reuse$extra"
  67names=$(git pack-objects --non-empty --all --reflog $args </dev/null "$PACKTMP") ||
  68        exit 1
  69if [ -z "$names" ]; then
  70        if test -z "$quiet"; then
  71                echo Nothing new to pack.
  72        fi
  73fi
  74for name in $names ; do
  75        fullbases="$fullbases pack-$name"
  76        chmod a-w "$PACKTMP-$name.pack"
  77        chmod a-w "$PACKTMP-$name.idx"
  78        if test "$quiet" != '-q'; then
  79            echo "Pack pack-$name created."
  80        fi
  81        mkdir -p "$PACKDIR" || exit
  82
  83        for sfx in pack idx
  84        do
  85                if test -f "$PACKDIR/pack-$name.$sfx"
  86                then
  87                        mv -f "$PACKDIR/pack-$name.$sfx" \
  88                                "$PACKDIR/old-pack-$name.$sfx"
  89                fi
  90        done &&
  91        mv -f "$PACKTMP-$name.pack" "$PACKDIR/pack-$name.pack" &&
  92        mv -f "$PACKTMP-$name.idx"  "$PACKDIR/pack-$name.idx" &&
  93        test -f "$PACKDIR/pack-$name.pack" &&
  94        test -f "$PACKDIR/pack-$name.idx" || {
  95                echo >&2 "Couldn't replace the existing pack with updated one."
  96                echo >&2 "The original set of packs have been saved as"
  97                echo >&2 "old-pack-$name.{pack,idx} in $PACKDIR."
  98                exit 1
  99        }
 100        rm -f "$PACKDIR/old-pack-$name.pack" "$PACKDIR/old-pack-$name.idx"
 101done
 102
 103if test "$remove_redundant" = t
 104then
 105        # We know $existing are all redundant.
 106        if [ -n "$existing" ]
 107        then
 108                sync
 109                ( cd "$PACKDIR" &&
 110                  for e in $existing
 111                  do
 112                        case " $fullbases " in
 113                        *" $e "*) ;;
 114                        *)      rm -f "$e.pack" "$e.idx" "$e.keep" ;;
 115                        esac
 116                  done
 117                )
 118        fi
 119        git prune-packed $quiet
 120fi
 121
 122case "$no_update_info" in
 123t) : ;;
 124*) git-update-server-info ;;
 125esac