All of lore.kernel.org
 help / color / mirror / Atom feed
* git alternate command
@ 2010-03-29 21:39 Chris Packham
  2010-03-29 21:39 ` [PATCHv3 1/2] Add " Chris Packham
  2010-03-29 21:39 ` [PATCHv3 2/2] tests for " Chris Packham
  0 siblings, 2 replies; 3+ messages in thread
From: Chris Packham @ 2010-03-29 21:39 UTC (permalink / raw)
  To: git; +Cc: jrnieder, gitster, j.sixt, bebarino

Here is the latest version of my git alternate command. The major difference to
the last update is additional tests for deleting alternates and some updates to
the test based on Hannes' feedback.

I still am intending to add documentation and to look into Stephens suggestions
for changing the UI to use add|delete|show instead of -a|-d.

I'm also interested in any feedback regarding the actual output from the command.

Cheers,
Chris

---

 Makefile                 |    1 +
 git-alternate.sh         |  156 ++++++++++++++++++++++++++++++++++++++++++++++
 t/t1430-alternate-cmd.sh |  154 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 311 insertions(+), 0 deletions(-)

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCHv3 1/2] Add git alternate command
  2010-03-29 21:39 git alternate command Chris Packham
@ 2010-03-29 21:39 ` Chris Packham
  2010-03-29 21:39 ` [PATCHv3 2/2] tests for " Chris Packham
  1 sibling, 0 replies; 3+ messages in thread
From: Chris Packham @ 2010-03-29 21:39 UTC (permalink / raw)
  To: git; +Cc: jrnieder, gitster, j.sixt, bebarino, Chris Packham

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

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCHv3 2/2] tests for git alternate command
  2010-03-29 21:39 git alternate command Chris Packham
  2010-03-29 21:39 ` [PATCHv3 1/2] Add " Chris Packham
@ 2010-03-29 21:39 ` Chris Packham
  1 sibling, 0 replies; 3+ messages in thread
From: Chris Packham @ 2010-03-29 21:39 UTC (permalink / raw)
  To: git; +Cc: jrnieder, gitster, j.sixt, bebarino, Chris Packham

Signed-off-by: Chris Packham <judge.packham@gmail.com>
---
 t/t1430-alternate-cmd.sh |  154 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 154 insertions(+), 0 deletions(-)
 create mode 100644 t/t1430-alternate-cmd.sh

diff --git a/t/t1430-alternate-cmd.sh b/t/t1430-alternate-cmd.sh
new file mode 100644
index 0000000..ba27633
--- /dev/null
+++ b/t/t1430-alternate-cmd.sh
@@ -0,0 +1,154 @@
+#!/bin/sh
+#
+# Copyright (c) Chris Packham
+#
+
+test_description='Test of git alternate command'
+
+. ./test-lib.sh
+
+test_expect_success 'setup for rest of the test' '
+
+	mkdir -p base &&
+	(
+		cd base &&
+		git init &&
+		echo test > a.txt &&
+		echo test > b.txt &&
+		echo test > c.txt &&
+		git add *.txt &&
+		git commit -a -m "Initial Commit"
+	)
+	git clone base A &&
+	git clone A B &&
+	git clone A C &&
+	git clone A D
+	testbase=$(pwd)
+'
+
+test_expect_success 'can add alternate after clone' '
+
+	(
+		cd B &&
+		git alternate -a ../base/.git/objects &&
+
+		echo "$testbase/base/.git/objects" > expect &&
+		cp .git/objects/info/alternates actual   &&
+
+		test_cmp expect actual
+
+	)
+'
+
+test_expect_success 'add same alternate fails (absolute path)' '
+
+	(
+		cd B &&
+		test_must_fail git alternate -a $(pwd)/base/.git/objects
+	)
+'
+
+test_expect_success 'add same alternate fails (relative path)' '
+
+	(
+		cd B &&
+		test_must_fail git alternate -a ../base/.git/objects
+	)
+'
+
+test_expect_success 'can add multiple alternates' '
+
+	(
+		cd C &&
+		git alternate -a ../base/.git/objects &&
+		git alternate -a ../B/.git/objects &&
+
+		{
+			echo "$testbase/base/.git/objects"
+			echo "$testbase/B/.git/objects"
+		} > expect &&
+
+		cp .git/objects/info/alternates actual   &&
+
+		test_cmp expect actual
+	)
+'
+
+test_expect_success 'can add recursive alternate' '
+
+	(
+		cd D &&
+		git alternate -a ../C/.git/objects
+
+		echo "$testbase/C/.git/objects" > expect &&
+		cp .git/objects/info/alternates actual   &&
+
+		test_cmp expect actual
+	)
+'
+
+test_expect_success 'simple display' '
+
+	(
+		cd B &&
+		git alternate >actual &&
+		{
+			echo "Object store $testbase/base/.git/objects"
+			echo "    referenced via $testbase/B/.git"
+		} >expect &&
+
+		test_cmp expect actual
+	)
+'
+
+test_expect_success 'recursive display' '
+
+	(
+		cd D &&
+		git alternate -r >actual &&
+
+		{
+			echo "Object store $testbase/C/.git/objects"
+			echo "    referenced via $testbase/D/.git"
+			echo "Object store $testbase/base/.git/objects"
+			echo "    referenced via $testbase/C/.git"
+			echo "Object store $testbase/B/.git/objects"
+			echo "    referenced via $testbase/C/.git"
+			echo "Object store $testbase/base/.git/objects"
+			echo "    referenced via $testbase/B/.git"
+		} >expect &&
+
+		test_cmp expect actual
+	)
+'
+
+test_expect_success 'cannot delete unless --forced' '
+	(
+		cd C &&
+		test_must_fail git alternate -d "$testbase/B/.git/objects"
+	)
+'
+
+test_expect_success 'can delete one alternate' '
+	(
+		cd C &&
+		git alternate -f -d "$testbase/B/.git/objects" &&
+
+		echo "$testbase/base/.git/objects" > expect &&
+		cp .git/objects/info/alternates actual   &&
+
+		test_cmp expect actual
+	)
+'
+
+test_expect_success 'last alternate deleted removes file' '
+	(
+		cd C &&
+		git alternate -f -d "$testbase/base/.git/objects" &&
+
+		test ! -e .git/objects/info/alternates
+
+	)
+'
+
+test_done
-- 
1.7.0.3

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-03-29 21:42 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-29 21:39 git alternate command Chris Packham
2010-03-29 21:39 ` [PATCHv3 1/2] Add " Chris Packham
2010-03-29 21:39 ` [PATCHv3 2/2] tests for " Chris Packham

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.