git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] contrib/workdir: add a simple script to create a working directory

From
Julian Phillips <julian@quantumfyre.co.uk>
Date
Mar 26, 2007, 23:15 UTC
Message-ID
<20070327003033.4226.8413.julian@quantumfyre.co.uk>
In-Reply-To
<7vtzw7tvvv.fsf@assigned-by-dhcp.cox.net>

Add a simple script to create a working directory that uses symlinks to point at an exisiting repository. This allows having different branches in different working directories but all from the same repository.

Based on a description from Junio of how he creates multiple working directories[1]. With the following caveat:

"This risks confusion for an uninitiated if you update a ref that is checked out in another working tree, but modulo that caveat it works reasonably well."

[1] http://article.gmane.org/gmane.comp.version-control.git/41513/
Signed-off-by: Julian Phillips <julian@quantumfyre.co.uk>
---
On Mon, 26 Mar 2007, Junio C Hamano wrote:
Show 10 quoted lines
> Julian Phillips <julian@quantumfyre.co.uk> writes:
>
>> Add a simple script to create a working directory that uses symlinks
>> to point at an exisiting repository.  This allows having different
>> branches in different working directories but all from the same
>> repository.  A poor-man's .gitlink if you will.
>
> I would not call it poor-man's.  It is 'without complexity' and
> that is a good thing, especially when you are not doing any
> submodule stuff.

True, it may not be as wizzy as .gitlink no doubt will be, but I think it will suit me nicely.

I also thought it was worth a reference to your caveat, but perhaps that would be better as a comment in the code?

>
>> +# create the links to the original repo
>> +for x in config refs logs/refs objects info hooks packed-refs remotes
rr-cache
Show 12 quoted lines
>> +do
>> +	case ${x} in
>> +	*/*)
>> +		mkdir -p $(dirname ${new_workdir}/.git/${x});
>> +		;;
>> +	esac
>> +	ln -s ${orig_git}/.git/${x} ${new_workdir}/.git/${x};
>> +done
>
> I think the above list "for x" is correct, but probably the code
> wants to comment on why it specifically excludes logs/HEAD from
> the symlinked set ;-).
Good point.
Show 11 quoted lines
>
>> +# now setup the workdir
>> +cd ${new_workdir};
>> +# create a fake HEAD, to stop checkout complaining
>> +echo "ref: refs/heads/master" > .git/HEAD;
>> +# now checkout the branch that was asked for
>> +git checkout ${branch};
>
> If ${branch} was 'master', does this do a checkout?  I think -f
> might be needed.
>
It worked when I tried it ... but -f might be worth it anyway.
 contrib/workdir/git-new-workdir |   55 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 55 insertions(+), 0 deletions(-)
 create mode 100755 contrib/workdir/git-new-workdir
diff --git a/contrib/workdir/git-new-workdir b/contrib/workdir/git-new-workdir
new file mode 100755
index 0000000..5bfd87e
--- /dev/null
+++ b/contrib/workdir/git-new-workdir
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+function usage () {
+	echo "usage:" $1;
+	exit 127;
+}
+
+function die () {
+	echo $1;
+	exit 128;
+}
+
+test $# -eq 3 || usage "$0 <original> <new_workdir> <branch>";
+
+orig_git=$1;
+new_workdir=$2;
+branch=$3;
+
+# want to make sure that what is pointed to has a .git directory ...
+test -d ${orig_git}/.git || die "${original_git} is not a git repository!";
+
+# don't link to a workdir, link to the original repo the workdir is linked to
+if test -L ${orig_git}/.git/config
+then
+	orig_git=$(dirname $(dirname $(readlink -f gm/.git/config)));
+fi
+
+# make sure the the links use full paths
+orig_git=$(cd ${orig_git}; pwd);
+
+# create the workdir
+mkdir -p ${new_workdir}/.git || die "unable to create new dir ${new_workdir}!";
+
+# create the links to the original repo.  explictly exclude index, HEAD and
+# logs/HEAD from the list since they are purely related to the current working
+# directory, and should not be shared.
+for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache
+do
+	case ${x} in
+	*/*)
+		mkdir -p $(dirname ${new_workdir}/.git/${x});
+		;;
+	esac
+	ln -s ${orig_git}/.git/${x} ${new_workdir}/.git/${x};
+done
+
+# now setup the workdir
+cd ${new_workdir};
+# create a fake HEAD, to stop checkout complaining
+echo "ref: refs/heads/master" > .git/HEAD;
+# now checkout the branch that was asked for
+git checkout -f ${branch};
+
+# vim: tabstop=8
+# vim: noexpandtab
-- 
1.5.0.5
Previous: Junio C HamanoNext: Eric Lesh
Message 3 of 9 in “contrib/workdir: add a simple script to create a working directory”
  1. contrib/workdir: add a simple script to create a working directoryJulian Phillips, Mar 26, 2007
  2. Junio C HamanoMar 26, 2007
  3. contrib/workdir: add a simple script to create a working directoryJulian Phillips, Mar 26, 2007
  4. Eric LeshMar 27, 2007
  5. Junio C HamanoMar 27, 2007
  6. Julian PhillipsMar 27, 2007
  7. Eric LeshMar 27, 2007
  8. Junio C HamanoMar 27, 2007
  9. contrib/workdir: add a simple script to create a working directoryJulian Phillips, Mar 26, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.