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