git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Chris Packham <judge.packham@gmail.com>
To: git@vger.kernel.org
Cc: jrnieder@gmail.com, gitster@pobox.com, j.sixt@viscovery.net,
	bebarino@gmail.com, Chris Packham <judge.packham@gmail.com>
Subject: [PATCHv3 1/2] Add git alternate command
Date: Mon, 29 Mar 2010 14:39:40 -0700	[thread overview]
Message-ID: <1269898781-18564-2-git-send-email-judge.packham@gmail.com> (raw)
In-Reply-To: <1269898781-18564-1-git-send-email-judge.packham@gmail.com>

The current UI around alternates is lacking. There are commands to add
an alternate at the time of a clone (e.g. 'git clone --reference') but
no commands to see what alternates have been configured or to add an
alternate after a repository has been cloned. This patch adds a
friendlier UI for displaying and configuring alternates.

Signed-off-by: Chris Packham <judge.packham@gmail.com>
---
 Makefile         |    1 +
 git-alternate.sh |  156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 157 insertions(+), 0 deletions(-)
 create mode 100755 git-alternate.sh

diff --git a/Makefile b/Makefile
index 3a6c6ea..0dc5e42 100644
--- a/Makefile
+++ b/Makefile
@@ -334,6 +334,7 @@ TEST_PROGRAMS_NEED_X =
 unexport CDPATH
 
 SCRIPT_SH += git-am.sh
+SCRIPT_SH += git-alternate.sh
 SCRIPT_SH += git-bisect.sh
 SCRIPT_SH += git-difftool--helper.sh
 SCRIPT_SH += git-filter-branch.sh
diff --git a/git-alternate.sh b/git-alternate.sh
new file mode 100755
index 0000000..ea9925b
--- /dev/null
+++ b/git-alternate.sh
@@ -0,0 +1,156 @@
+#!/bin/sh
+#
+# This file is licensed under the GPL v2
+#
+# Copyright (c) Chris Packham
+
+dashless=$(basename "$0" | sed -e 's/-/ /')
+OPTIONS_KEEPDASHDASH=
+OPTIONS_SPEC="\
+$dashless [-r|--recursive]
+$dashless [-a|--add <dir>]
+$dashless [-f|--force] [-d|delete <dir>]
+--
+r,recursive                    recursively follow alternates
+a,add=                         add dir as an alternate
+d,del=                         delete dir as an alternate
+f,force                        force a delete operation
+"
+. git-sh-setup
+
+#
+# Given the path in $1, which may or may not be a relative path,
+# convert it to an absolute path
+#
+abspath()
+{
+	cd "$1"
+	pwd
+	cd - > /dev/null
+}
+
+#
+# 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()
+{
+	alternates=$GIT_DIR/objects/info/alternates
+	callback=$1
+	shift
+
+	if test -f "$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"
+
+	new_git_dir=${line%%/objects}
+	if test "$recursive" = "true" && test "$GIT_DIR" != "$new_git_dir"
+	then
+	(
+		export GIT_DIR=$new_git_dir
+		show_alternates
+	)
+	fi
+}
+
+# Display alternates currently configured
+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 a new alternate
+add_alternate()
+{
+	if test ! -d "$dir"; then
+		die "fatal: $dir is not a directory"
+	fi
+
+	abs_dir=$(abspath "$dir")
+	walk_alternates check_current_alternate_walk "$abs_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
+	echo "$abs_dir" >> $GIT_DIR/objects/info/alternates
+	say "$abs_dir added as an alternate"
+	say "    use 'git repack -adl' to remove duplicate objects"
+}
+
+# Deletes the name alternate from the alternates file.
+# If there are no more alternates the alternates file will be removed
+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
+
+	alternates=$GIT_DIR/objects/info/alternates
+	new_alternates=$alternates.tmp
+
+	grep -v -F "$dir" <"$alternates" >"$new_alternates"
+	if test -s "$new_alternates"
+	then
+		mv "$new_alternates" "$alternates"
+	else
+		# save the git from repeatedly reading a 0 length file
+		rm -f "$alternates" "$new_alternates"
+	fi
+}
+
+dir=""
+oper=""
+force="false"
+
+# Option parsing
+while test $# != 0
+do
+	case "$1" in
+	-r|--recursive)  recursive="true" ;;
+	-a|--add)        oper="add"; dir="$2"; shift ;;
+	-d|--delete)     oper="del"; dir="$2"; shift ;;
+	-f|--force)      force="true" ;;
+	--)              shift; break ;;
+	*)               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

  reply	other threads:[~2010-03-29 21:42 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-29 21:39 git alternate command Chris Packham
2010-03-29 21:39 ` Chris Packham [this message]
2010-03-29 21:39 ` [PATCHv3 2/2] tests for " Chris Packham

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1269898781-18564-2-git-send-email-judge.packham@gmail.com \
    --to=judge.packham@gmail.com \
    --cc=bebarino@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=j.sixt@viscovery.net \
    --cc=jrnieder@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).