On Mon, Mar 22, 2010 at 7:42 PM, Jonathan Nieder <jrnieder@xxxxxxxxx> wrote: > Chris Packham wrote: > >> I would like to have base somehow find the objects it doesn't have in >> its object store and either download them or just copy them from the >> object store of projecta. > [...] >> From reading [2] I think 'rm >> .git/objects/info/alternates && git repack -a' might do the trick but >> I'm not sure. > > Almost. Try ‘git repack -a && rm .git/objects/info/alternates’ instead. :) > > (Please back up the repository or try with something less important > first, since I am not sure.) > > Hope that helps, > Jonathan > git repack -a did the correct thing. It occurs to me that the UI around alternates is a bit lacking i.e. there isn't a git command to display the alternates in use or to add them to an existing repository (or at least I couldn't find one skimming the docs or googling). So here's my attempt to add a 'git alternates' command which can display, add or remove an alternate. The adding and removing could be done with standard shell commands but I've found the recursive displaying quite useful and couldn't think of a simple command line to achieve the same thing . ------8<------ >From a5c64de20937da132376d717f19a1d52b54701d2 Mon Sep 17 00:00:00 2001 From: Chris Packham <judge.packham@xxxxxxxxx> Date: Wed, 24 Mar 2010 11:34:11 -0700 Subject: [PATCH] Add git alternates command Provides a friendlier UI for displaying and configuring alternates. Signed-off-by: Chris Packham <judge.packham@xxxxxxxxx> --- This patch assumes multiple alterates are possible. If this is not correct then it could be simplfied as there would be no need for walk_alternates. Makefile | 1 + git-alternates.sh | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+), 0 deletions(-) create mode 100755 git-alternates.sh diff --git a/Makefile b/Makefile index 3a6c6ea..1a7b084 100644 --- a/Makefile +++ b/Makefile @@ -334,6 +334,7 @@ TEST_PROGRAMS_NEED_X = unexport CDPATH SCRIPT_SH += git-am.sh +SCRIPT_SH += git-alternates.sh SCRIPT_SH += git-bisect.sh SCRIPT_SH += git-difftool--helper.sh SCRIPT_SH += git-filter-branch.sh diff --git a/git-alternates.sh b/git-alternates.sh new file mode 100755 index 0000000..74ec707 --- /dev/null +++ b/git-alternates.sh @@ -0,0 +1,159 @@ +#!/bin/sh +# +# This file is licensed under the GPL v2 +# + +USAGE='[-r|--recursive] [-a|--add <dir>] [-f|--force -d|--delete <dir>]' + +. git-sh-setup + +# +# Runs through the alternates file calling the callback function $1 +# with the name of the alternate as the first argument to the callback +# any additional arguments are passed to the callback function. +# +walk_alternates() +{ + local alternates=$GIT_DIR/objects/info/alternates + local callback=$1 + shift + + if [ -e $alternates ]; then + while read line + do + $callback $line $* + done < $alternates + fi +} + +# +# Walk function to display one alternate object store and, if the user +# has specified -r, recursively call show_alternates on the git +# repository that the object store belongs to. +# +show_alternates_walk() +{ + say "Object store $1" + say " referenced via $GIT_DIR" + + local new_git_dir=${line%%/objects} + if [ "$recursive" == "true" -a "$GIT_DIR" != "$new_git_dir" ] + then + GIT_DIR=$new_git_dir show_alternates + fi +} + +show_alternates() +{ + walk_alternates show_alternates_walk +} + +# +# Walk function to check that the specified alternate does not +# already exist. +# +check_current_alternate_walk() +{ + if test "$1" = "$2"; then + die "fatal: Object store $2 is already used by $GIT_DIR" + fi +} + +add_alternate() +{ + if test ! -d $dir; then + die "fatal: $dir is not a directory" + fi + + walk_alternates check_current_alternate_walk $dir + + # At this point we know that $dir is a directory that exists + # and that its not already being used as an alternate. We could + # go further and verify that $dir has valid objects. + + # if we're still going we can safely add the alternate + touch $GIT_DIR/objects/info/alternates + echo "$(readlink -f $dir)" >> $GIT_DIR/objects/info/alternates + say "$dir added as an alternate" + say " use 'git repack -adl' to remove duplicate objects" +} + +rewrite_alternates() +{ + if test "$1" != "$2"; then + echo $2 >> $3 + fi +} + +del_alternate() +{ + if test ! $force = "true"; then + say "Not forced, use" + say " 'git repack -a' to fetch missing objects, then " + say " '$dashless -f -d $dir' to remove the alternate" + die + fi + + local alternates=$GIT_DIR/objects/info/alternates + + new_alts_file=$(mktemp $alternates-XXXXXX) + touch $new_alts_file + + walk_alternates rewrite_alternates $dir $new_alts_file + mv $new_alts_file $alternates + + # save the git from repeatedly reading a 0 length file + if test $(stat -c "%s" $alternates) -eq 0; then + rm $alternates + fi +} + +dir="" +oper="" +force="false" + +# Option parsing +while test $# != 0 +do + case "$1" in + -r|--recursive) + recursive="true" + ;; + -a|--add) + if test ! -z "$oper"; then + usage + fi + oper="add" + case "$#,$1" in + 1,*) usage ;; + *) dir=$2; shift ;; + esac + ;; + -d|--delete) + if test ! -z "$oper"; then + usage + fi + oper="del" + case "$#,$1" in + 1,*) usage ;; + *) dir=$2; shift ;; + esac + ;; + -f|--force) + force="true" + ;; + -*) + usage + ;; + *) + ;; + esac + shift +done + +# Now go and do it +case $oper in + add) add_alternate ;; + del) del_alternate ;; + *) show_alternates ;; +esac -- 1.7.0.3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html