Re: Question about .git/objects/info/alternates

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]