Git development
 help / color / mirror / Atom feed
* [PATCH] Accept dates before 2000/01/01 when specified as seconds since the epoch
From: Johannes Sixt @ 2007-06-06  8:11 UTC (permalink / raw)
  To: git, junkio; +Cc: Johannes Sixt

Tests with git-filter-branch on a repository that was converted from
CVS and that has commits reaching back to 1999 revealed that it is
necessary to parse dates before 2000/01/01 when they are specified
as seconds since 1970/01/01. There is now still a limit, 100000000,
which is 1973/03/03 09:46:40 UTC, in order to allow that dates are
represented as 8 digits.

Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
---
 date.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/date.c b/date.c
index a9b59a2..4690371 100644
--- a/date.c
+++ b/date.c
@@ -414,9 +414,11 @@ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt
 	num = strtoul(date, &end, 10);
 
 	/*
-	 * Seconds since 1970? We trigger on that for anything after Jan 1, 2000
+	 * Seconds since 1970? We trigger on that for any numbers with
+	 * more than 8 digits. This is because we don't want to rule out
+	 * numbers like 20070606 as a YYYYMMDD date.
 	 */
-	if (num > 946684800) {
+	if (num >= 100000000) {
 		time_t time = num;
 		if (gmtime_r(&time, tm)) {
 			*tm_gmt = 1;
-- 
1.5.2.1.120.gd732

^ permalink raw reply related

* Re: [PATCH] git-mergetool: Make default smarter by considering user's desktop environment and editor
From: Junio C Hamano @ 2007-06-06  8:08 UTC (permalink / raw)
  To: Josh Triplett; +Cc: git
In-Reply-To: <466637E2.5040303@freedesktop.org>

Josh Triplett <josh@freedesktop.org> writes:

> Make git-mergetool prefer meld under GNOME, and kdiff3 under KDE.  When
> considering emerge and vimdiff, check $VISUAL and $EDITOR to see which the
> user might prefer.
>
> Signed-off-by: Josh Triplett <josh@freedesktop.org>

The basic idea is sound.  However...

 (1) I wonder if we can get rid of the horribly long if .. elif
     chain by using shell function and then iterate a list of them;

 (2) echo "${VISUAL-$EDITOR}" | grep '^emacs'???

     Some people may have explicit path (/home/me/bin/emacs),
     and/or runs a variant of emacs called 'xemacs'.  Same for
     vim.

Something like...

        test_xstuff () {
                test -n "$DISPLAY" && type "$1" >/dev/null 2>&1
        test_kdiff3 () {
                test_xstuff kdiff3
        }
        test_tkdiff () {
                test_xstuff tkdiff
        }
        test_estuff() {
                type "$1" >/dev/null 2>&1 &&
                case "${VISUAL-$EDITOR}" in *"$1"*) : ;; *) false ;; esac
        }
        test_emerge () {
                test_estuff emacs
        }
        test_vimdiff () {
                test_estuff vim
        }

        choose_merge_tool () {
                for t in "$@"
                do
                        if test_$t
                        then
                                echo "$t"
                                break
                        fi
                done
        }

        if test -z "$merge_tool"
        then
                merge_tool_candidates='kdiff3 tkdiff xxdiff meld opendiff ...'
                if test -n "$GNOME_DESCTOP_SESSION_ID"
                then
                        merge_tool_candidates="meld $merge_tool_candidates"
                elif test -n "$KDE_FULL_SESSION"
                then
                        merge_tool_candidates="kdiff3 $merge_tool_candidates"
                elif
                        ...
                fi
                merge_tool=$(choose_merge_tool $merge_tool_candidates)
        fi

^ permalink raw reply

* [PATCH 3/6] git-fsck: Do thorough verification of tag objects.
From: Johan Herland @ 2007-06-06  8:06 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Matthias Lederhofer, git
In-Reply-To: <7vtztl7dqi.fsf@assigned-by-dhcp.cox.net>

Teach git-fsck to do the same kind of verification on tag objects that is
already done by git-mktag.

Signed-off-by: Johan Herland <johan@herland.net>
---

On Wednesday 06 June 2007, Junio C Hamano wrote:
> The tagger field was introduced mid July 2005; any repository
> with a tag object older than that would now get non-zero exit
> from fsck.
> 
> This won't practically be problem in newer repositories, but it
> is somewhat annoying.  Perhaps do this only under the new -v
> option to git-fsck, say "warning" not "error", and not exit with
> non-zero because of this?

Like this?

Or would you rather switch around the "verbose" and the
"parse_and_verify_tag_buffer()" (i.e. not even attempt the thorough
verification unless in verbose mode)?


Have fun!

...Johan

 builtin-fsck.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/builtin-fsck.c b/builtin-fsck.c
index bacae5d..fb9a8bb 100644
--- a/builtin-fsck.c
+++ b/builtin-fsck.c
@@ -359,11 +359,24 @@ static int fsck_commit(struct commit *commit)
 static int fsck_tag(struct tag *tag)
 {
 	struct object *tagged = tag->tagged;
+	enum object_type type;
+	unsigned long size;
+	char *data = (char *) read_sha1_file(tag->object.sha1, &type, &size);
 
 	if (verbose)
 		fprintf(stderr, "Checking tag %s\n",
 			sha1_to_hex(tag->object.sha1));
 
+	if (!data)
+		return objerror(&tag->object, "could not read tag");
+	if (type != OBJ_TAG) {
+		free(data);
+		return objerror(&tag->object, "not a tag (internal error)");
+	}
+	if (parse_and_verify_tag_buffer(0, data, size, 1) && verbose)
+		objwarning(&tag->object, "failed thorough tag object verification");
+	free(data);
+
 	if (!tagged) {
 		return objerror(&tag->object, "could not load tagged object");
 	}
-- 
1.5.2



-- 
Johan Herland, <johan@herland.net>
www.herland.net

^ permalink raw reply related

* Re: [PATCH] Add the --numbered-files option to git-format-patch.
From: Junio C Hamano @ 2007-06-06  7:50 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: Git List
In-Reply-To: <1181074013.2585.14.camel@ld0161-tx32>

Jon Loeliger <jdl@freescale.com> writes:

> With this option, git-format-patch will generate simple
> numbered files as output instead of the default using
> with the first commit line appended.
>
> This simplifies the ability to generate an MH-style
> drafts folder with each message to be sent.

I'll take the patch but wouldn't something like:

	git-format-patch --stdout $args |
        FILENO=7 formail -s sh -c 'cat >.junk/$FILENO'

be equivalent to

	git-format-patch -o .junk/ --numbered-files --start-number=7 $args

and more flexible?

^ permalink raw reply

* [PATCH] Fix the remote note the fetch-tool prints after storing a fetched reference
From: Alex Riesen @ 2007-06-06  7:45 UTC (permalink / raw)
  To: Git Mailing List; +Cc: Junio C Hamano

[-- Attachment #1: Type: text/plain, Size: 456 bytes --]

Otherwise ".git" is removed from every remote name which has it:

  $ git fetch -v
    * refs/heads/origin: same as branch 'master' of /home/user/linux
      commit: 5ecd310
  $ ls /home/user/linux
  ls: /home/user/linux: No such file or directory
  $ ls /home/user/linux.git
  HEAD  objects  packed-refs  ...

Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
---
 builtin-fetch--tool.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

[-- Attachment #2: 0001-Fix-the-remote-note-the-fetch-tool-prints-after-stor.txt --]
[-- Type: text/plain, Size: 1536 bytes --]

From 100742821619fdd83e75aa8dcb88489aa4b60648 Mon Sep 17 00:00:00 2001
From: Alex Riesen <raa@limbo.localdomain>
Date: Wed, 6 Jun 2007 00:16:14 +0200
Subject: [PATCH] Fix the remote note the fetch-tool prints after storing a fetched reference

Otherwise ".git" is removed from every remote name which has it:

  $ git fetch -v
    * refs/heads/origin: same as branch 'master' of /home/user/linux
      commit: 5ecd310
  $ ls /home/user/linux
  ls: /home/user/linux: No such file or directory
  $ ls /home/user/linux.git
  HEAD  objects  packed-refs  ...

Signed-off-by: Alex Riesen <raa@limbo.localdomain>
---
 builtin-fetch--tool.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c
index ed4d5de..22ca125 100644
--- a/builtin-fetch--tool.c
+++ b/builtin-fetch--tool.c
@@ -140,7 +140,7 @@ static int append_fetch_head(FILE *fp,
 			     int verbose, int force)
 {
 	struct commit *commit;
-	int remote_len, i, note_len;
+	int remote_len, note_len;
 	unsigned char sha1[20];
 	char note[1024];
 	const char *what, *kind;
@@ -173,11 +173,11 @@ static int append_fetch_head(FILE *fp,
 	}
 
 	remote_len = strlen(remote);
-	for (i = remote_len - 1; remote[i] == '/' && 0 <= i; i--)
-		;
-	remote_len = i + 1;
-	if (4 < i && !strncmp(".git", remote + i - 3, 4))
-		remote_len = i - 3;
+	if (remote_len > 5) {
+		char *p = strrchr(remote, '/');
+		if (p && !strcmp(p, "/.git"))
+		    remote_len -= 4;
+	}
 
 	note_len = 0;
 	if (*what) {
-- 
1.5.2.1.134.g352b


^ permalink raw reply related

* Re: [PATCH] Add git-filter-branch
From: Johannes Sixt @ 2007-06-06  7:43 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0706051537360.4046@racer.site>

Johannes Schindelin wrote:
> Okay, then. Are you okay with keeping the same options? (See proposed
> patch below.)

I can live with it. But what do you think of this in addtion? It
replaces -k, -r, -s in favor of rev-list arguments.

> Just out of curiousity, do you have any timing data?

I did one test run through 8118 commits which took 18 minutes. But it
turns out that I have a buglet here in git-commit-tree, which would
not accept committer dates before 2000-1-1 00:00:01 UTC, but since the
first commit is from 1999, this test rewrote the entire history, which
was not intended.

--- 8< ---
From: Johannes Sixt <johannes.sixt@telecom.at>

filter-branch: Use rev-list arguments to specify revision ranges.

A subset of commits in a branch used to be specified by options (-k, -r)
as well as the branch tip itself (-s). It is more natural (for git users)
to specify revision ranges like 'master..next' instead. This makes it so.
If no range is specified it defaults to 'HEAD'.

As a consequence, the new name of the filtered branch must be the first
non-option argument. All remaining arguments are passed to 'git rev-list'
unmodified.

The tip of the branch that gets filtered is implied: It is the first
commit that git rev-list would print for the specified range.

Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
---
 git-filter-branch.sh     |   39 ++++++++++++---------------------------
 t/t7003-filter-branch.sh |    2 +-
 2 files changed, 13 insertions(+), 28 deletions(-)

diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index 9e12a6c..190a492 100644
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -42,15 +42,6 @@
 #	does this in the '.git-rewrite/' directory but you can override
 #	that choice by this parameter.
 #
-# -r STARTREV:: The commit id to start the rewrite at
-#	Normally, the command will rewrite the entire history. If you
-#	pass this argument, though, this will be the first commit it
-#	will rewrite and keep the previous commits intact.
-#
-# -k KEEPREV:: A commit id until which _not_ to rewrite history
-#	If you pass this argument, this commit and all of its
-#	predecessors are kept intact.
-#
 # Filters
 # ~~~~~~~
 # The filters are applied in the order as listed below. The COMMAND
@@ -164,27 +155,31 @@
 # and all children of the merge will become merge commits with P1,P2
 # as their parents instead of the merge commit.
 #
-# To restrict rewriting to only part of the history, use -r or -k or both.
+# To restrict rewriting to only part of the history, specify a revision
+# range in addition to the new branch name. The new branch name will
+# point to the top-most revision that a 'git rev-list' of this range
+# will print.
+#
 # Consider this history:
 #
 #	     D--E--F--G--H
 #	    /     /
 #	A--B-----C
 #
-# To rewrite only commits F,G,H, use:
+# To rewrite commits D,E,F,G,H, use:
 #
-#	git-filter-branch -r F ...
+#	git-filter-branch ... new-H C..H
 #
 # To rewrite commits E,F,G,H, use one of these:
 #
-#	git-filter-branch -r E -k C ...
-#	git-filter-branch -k D -k C ...
+#	git-filter-branch ... new-H C..H --not D
+#	git-filter-branch ... new-H D..H --not C
 
 # Testsuite: TODO
 
 set -e
 
-USAGE="git-filter-branch [-d TEMPDIR] [-r STARTREV]... [-k KEEPREV]... [-s SRCBRANCH] [FILTERS] DESTBRANCH"
+USAGE="git-filter-branch [-d TEMPDIR] [FILTERS] DESTBRANCH [REV-RANGE]"
 . git-sh-setup
 
 map()
@@ -233,7 +228,6 @@ get_parents () {
 }
 
 tempdir=.git-rewrite
-unchanged=" "
 filter_env=
 filter_tree=
 filter_index=
@@ -241,7 +235,6 @@ filter_parent=
 filter_msg=cat
 filter_commit='git-commit-tree "$@"'
 filter_tag_name=
-srcbranch=HEAD
 while case "$#" in 0) usage;; esac
 do
 	case "$1" in
@@ -266,12 +259,6 @@ do
 	-d)
 		tempdir="$OPTARG"
 		;;
-	-r)
-		unchanged="$(get_parents "$OPTARG") $unchanged"
-		;;
-	-k)
-		unchanged="$(git-rev-parse "$OPTARG"^{commit}) $unchanged"
-		;;
 	--env-filter)
 		filter_env="$OPTARG"
 		;;
@@ -293,9 +280,6 @@ do
 	--tag-name-filter)
 		filter_tag_name="$OPTARG"
 		;;
-	-s)
-		srcbranch="$OPTARG"
-		;;
 	*)
 		usage
 		;;
@@ -303,6 +287,7 @@ do
 done
 
 dstbranch="$1"
+shift
 test -n "$dstbranch" || die "missing branch name"
 git-show-ref "refs/heads/$dstbranch" 2> /dev/null &&
 	die "branch $dstbranch already exists"
@@ -328,7 +313,7 @@ ret=0
 
 mkdir ../map # map old->new commit ids for rewriting parents
 
-git-rev-list --reverse --topo-order $srcbranch --not $unchanged >../revs
+git-rev-list --reverse --topo-order --default HEAD "$@" >../revs
 commits=$(cat ../revs | wc -l | tr -d " ")
 
 test $commits -eq 0 && die "Found nothing to rewrite"
diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh
index 520963a..89b405b 100755
--- a/t/t7003-filter-branch.sh
+++ b/t/t7003-filter-branch.sh
@@ -46,7 +46,7 @@ test_expect_success 'test that the file was renamed' '
 
 git tag oldD H3~4
 test_expect_success 'rewrite one branch, keeping a side branch' '
-	git-filter-branch --tree-filter "mv b boh || :" -k D -s oldD modD
+	git-filter-branch --tree-filter "mv b boh || :" modD D..oldD
 '
 
 test_expect_success 'common ancestor is still common (unchanged)' '
-- 
1.5.2.1.114.gc6c36

^ permalink raw reply related

* [PATCH] chmod +x git-filter-branch.sh
From: Matthias Lederhofer @ 2007-06-06  7:29 UTC (permalink / raw)
  To: git

Signed-off-by: Matthias Lederhofer <matled@gmx.net>
---
All other shell scripts are executable too and it is quite handy for
testing.
---
 0 files changed, 0 insertions(+), 0 deletions(-)
 mode change 100644 => 100755 git-filter-branch.sh

diff --git a/git-filter-branch.sh b/git-filter-branch.sh
old mode 100644
new mode 100755
-- 
1.5.2.1.116.g9f308

^ permalink raw reply

* Re: [PATCH 3/6] git-fsck: Do thorough verification of tag objects.
From: Junio C Hamano @ 2007-06-06  7:18 UTC (permalink / raw)
  To: Johan Herland; +Cc: Matthias Lederhofer, git
In-Reply-To: <200706040951.06620.johan@herland.net>

Johan Herland <johan@herland.net> writes:

> Teach git-fsck to do the same kind of verification on tag objects that is
> already done by git-mktag.

The tagger field was introduced mid July 2005; any repository
with a tag object older than that would now get non-zero exit
from fsck.

This won't practically be problem in newer repositories, but it
is somewhat annoying.  Perhaps do this only under the new -v
option to git-fsck, say "warning" not "error", and not exit with
non-zero because of this?

^ permalink raw reply

* [PATCH (amend)] filter-branch: always export GIT_DIR if it is set
From: Matthias Lederhofer @ 2007-06-06  7:16 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <20070605164957.GA12358@moooo.ath.cx>

Currently filter-branch exports GIT_DIR only if it is an
relative path but git-sh-setup might also set GIT_DIR to an
absolute path that is not exported yet.  Additionally export
GIT_WORK_TREE with GIT_DIR to ensure that cwd is used as
working tree even for bare repositories.

Signed-off-by: Matthias Lederhofer <matled@gmx.net>
---
The last one was a bit bloated :)
---
 git-filter-branch.sh |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index 0c8a7df..acd52bd 100644
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -315,9 +315,10 @@ case "$GIT_DIR" in
 /*)
 	;;
 *)
-	export GIT_DIR="$(pwd)/../../$GIT_DIR"
+	GIT_DIR="$(pwd)/../../$GIT_DIR"
 	;;
 esac
+export GIT_DIR GIT_WORK_TREE=.
 
 export GIT_INDEX_FILE="$(pwd)/../index"
 git-read-tree # seed the index file
-- 
1.5.2.1.116.g9f308

^ permalink raw reply related

* [PATCH 7/7 (amend)] test GIT_WORK_TREE
From: Matthias Lederhofer @ 2007-06-06  7:14 UTC (permalink / raw)
  To: Git Mailing List
In-Reply-To: <20070603144925.GG20061@moooo.ath.cx>

Signed-off-by: Matthias Lederhofer <matled@gmx.net>
---
Remove test for fallback work tree with GIT_DIR, this is now in
t1500-rev-parse.sh.
---
 t/t1501-worktree.sh |   92 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 92 insertions(+), 0 deletions(-)
 create mode 100755 t/t1501-worktree.sh

diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh
new file mode 100755
index 0000000..aadeeab
--- /dev/null
+++ b/t/t1501-worktree.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+
+test_description='test separate work tree'
+. ./test-lib.sh
+
+test_rev_parse() {
+	name=$1
+	shift
+
+	test_expect_success "$name: is-bare-repository" \
+	"test '$1' = \"\$(git rev-parse --is-bare-repository)\""
+	shift
+	[ $# -eq 0 ] && return
+
+	test_expect_success "$name: is-inside-git-dir" \
+	"test '$1' = \"\$(git rev-parse --is-inside-git-dir)\""
+	shift
+	[ $# -eq 0 ] && return
+
+	test_expect_success "$name: is-inside-work-tree" \
+	"test '$1' = \"\$(git rev-parse --is-inside-work-tree)\""
+	shift
+	[ $# -eq 0 ] && return
+
+	test_expect_success "$name: prefix" \
+	"test '$1' = \"\$(git rev-parse --show-prefix)\""
+	shift
+	[ $# -eq 0 ] && return
+}
+
+mkdir -p work/sub/dir || exit 1
+mv .git repo.git || exit 1
+
+say "core.worktree = relative path"
+export GIT_DIR=repo.git
+export GIT_CONFIG=$GIT_DIR/config
+unset GIT_WORK_TREE
+git config core.worktree ../work
+test_rev_parse 'outside'      false false false
+cd work || exit 1
+export GIT_DIR=../repo.git
+export GIT_CONFIG=$GIT_DIR/config
+test_rev_parse 'inside'       false false true ''
+cd sub/dir || exit 1
+export GIT_DIR=../../../repo.git
+export GIT_CONFIG=$GIT_DIR/config
+test_rev_parse 'subdirectory' false false true sub/dir/
+cd ../../.. || exit 1
+
+say "core.worktree = absolute path"
+export GIT_DIR=$(pwd)/repo.git
+export GIT_CONFIG=$GIT_DIR/config
+git config core.worktree "$(pwd)/work"
+test_rev_parse 'outside'      false false false
+cd work || exit 1
+test_rev_parse 'inside'       false false true ''
+cd sub/dir || exit 1
+test_rev_parse 'subdirectory' false false true sub/dir/
+cd ../../.. || exit 1
+
+say "GIT_WORK_TREE=relative path (override core.worktree)"
+export GIT_DIR=$(pwd)/repo.git
+export GIT_CONFIG=$GIT_DIR/config
+git config core.worktree non-existent
+export GIT_WORK_TREE=work
+test_rev_parse 'outside'      false false false
+cd work || exit 1
+export GIT_WORK_TREE=.
+test_rev_parse 'inside'       false false true ''
+cd sub/dir || exit 1
+export GIT_WORK_TREE=../..
+test_rev_parse 'subdirectory' false false true sub/dir/
+cd ../../.. || exit 1
+
+mv work repo.git/work
+
+say "GIT_WORK_TREE=absolute path, work tree below git dir"
+export GIT_DIR=$(pwd)/repo.git
+export GIT_CONFIG=$GIT_DIR/config
+export GIT_WORK_TREE=$(pwd)/repo.git/work
+test_rev_parse 'outside'              false false false
+cd repo.git || exit 1
+test_rev_parse 'in repo.git'              false true  false
+cd objects || exit 1
+test_rev_parse 'in repo.git/objects'      false true  false
+cd ../work || exit 1
+test_rev_parse 'in repo.git/work'         false false true ''
+cd sub/dir || exit 1
+test_rev_parse 'in repo.git/sub/dir' false false true sub/dir/
+cd ../../../.. || exit 1
+
+test_done
-- 
1.5.2.1.116.g9f308

^ permalink raw reply related

* [PATCH 6/7 (amend)] extend rev-parse test for --is-inside-work-tree
From: Matthias Lederhofer @ 2007-06-06  7:13 UTC (permalink / raw)
  To: Git Mailing List, Nguyen Thai Ngoc Duy
In-Reply-To: <20070603144846.GF20061@moooo.ath.cx>

Signed-off-by: Matthias Lederhofer <matled@gmx.net>
---
New: tests that cwd is used as working tree when GIT_DIR is set (and
GIT_WORK_TREE/core.worktree are unspecified).
---
 t/t1500-rev-parse.sh |   29 +++++++++++++++++------------
 1 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh
index 66b0e58..ec49966 100755
--- a/t/t1500-rev-parse.sh
+++ b/t/t1500-rev-parse.sh
@@ -17,30 +17,35 @@ test_rev_parse() {
 	shift
 	[ $# -eq 0 ] && return
 
+	test_expect_success "$name: is-inside-work-tree" \
+	"test '$1' = \"\$(git rev-parse --is-inside-work-tree)\""
+	shift
+	[ $# -eq 0 ] && return
+
 	test_expect_success "$name: prefix" \
 	"test '$1' = \"\$(git rev-parse --show-prefix)\""
 	shift
 	[ $# -eq 0 ] && return
 }
 
-test_rev_parse toplevel false false ''
+test_rev_parse toplevel false false true ''
 
 cd .git || exit 1
-test_rev_parse .git/ false true .git/
+test_rev_parse .git/ false true true .git/
 cd objects || exit 1
-test_rev_parse .git/objects/ false true .git/objects/
+test_rev_parse .git/objects/ false true true .git/objects/
 cd ../.. || exit 1
 
 mkdir -p sub/dir || exit 1
 cd sub/dir || exit 1
-test_rev_parse subdirectory false false sub/dir/
+test_rev_parse subdirectory false false true sub/dir/
 cd ../.. || exit 1
 
 git config core.bare true
-test_rev_parse 'core.bare = true' true
+test_rev_parse 'core.bare = true' true false true
 
 git config --unset core.bare
-test_rev_parse 'core.bare undefined' false
+test_rev_parse 'core.bare undefined' false false true
 
 mkdir work || exit 1
 cd work || exit 1
@@ -48,25 +53,25 @@ export GIT_DIR=../.git
 export GIT_CONFIG="$GIT_DIR"/config
 
 git config core.bare false
-test_rev_parse 'GIT_DIR=../.git, core.bare = false' false false ''
+test_rev_parse 'GIT_DIR=../.git, core.bare = false' false false true ''
 
 git config core.bare true
-test_rev_parse 'GIT_DIR=../.git, core.bare = true' true
+test_rev_parse 'GIT_DIR=../.git, core.bare = true' true false true ''
 
 git config --unset core.bare
-test_rev_parse 'GIT_DIR=../.git, core.bare undefined' false false ''
+test_rev_parse 'GIT_DIR=../.git, core.bare undefined' false false true ''
 
 mv ../.git ../repo.git || exit 1
 export GIT_DIR=../repo.git
 export GIT_CONFIG="$GIT_DIR"/config
 
 git config core.bare false
-test_rev_parse 'GIT_DIR=../repo.git, core.bare = false' false false ''
+test_rev_parse 'GIT_DIR=../repo.git, core.bare = false' false false true ''
 
 git config core.bare true
-test_rev_parse 'GIT_DIR=../repo.git, core.bare = true' true
+test_rev_parse 'GIT_DIR=../repo.git, core.bare = true' true false true ''
 
 git config --unset core.bare
-test_rev_parse 'GIT_DIR=../repo.git, core.bare undefined' true
+test_rev_parse 'GIT_DIR=../repo.git, core.bare undefined' true false true ''
 
 test_done
-- 
1.5.2.1.116.g9f308

^ permalink raw reply related

* [PATCH 4/7 (amend)] introduce GIT_WORK_TREE to specify the work tree
From: Matthias Lederhofer @ 2007-06-06  7:10 UTC (permalink / raw)
  To: Git Mailing List
In-Reply-To: <20070603144714.GD20061@moooo.ath.cx>

Dscho, Junio and me discussed about this in #git and it seems that the
best way to handle GIT_DIR is to use the current working directory as
fallback for the working tree always, ignoring if the repository is
bare.  With this change all scripts that worked before this series
should still work as long as the user does not set GIT_WORK_TREE or
core.worktree.

With this series scripts which want to use a specific repository with
a specific working tree should just set GIT_DIR and GIT_WORK_TREE.
This tells git explicitly which directory should be used as work tree.

The problem before this change was:
Some scripts export GIT_DIR (set by git-sh-setup) and expect that the
current working directory is used as working tree after this.  This
did not work anymore if the repository was bare.  Even before the
patch series there were cases where this did not work but after this
change to the patch the new behaviour should be less strict.

-----8<-----
introduce GIT_WORK_TREE to specify the work tree

setup_gdg is used as abbreviation for setup_git_directory_gently.

The work tree can be specified using the environment variable
GIT_WORK_TREE and the config option core.worktree (the environment
variable has precendence over the config option).  Additionally
there is a command line option --work-tree which sets the
environment variable.

setup_gdg does the following now:

GIT_DIR unspecified
repository in .git directory
    parent directory of the .git directory is used as work tree,
    GIT_WORK_TREE is ignored

GIT_DIR unspecified
repository in cwd
    GIT_DIR is set to cwd
    see the cases with GIT_DIR specified what happens next and
    also see the note below

GIT_DIR specified
GIT_WORK_TREE/core.worktree unspecified
    cwd is used as work tree

GIT_DIR specified
GIT_WORK_TREE/core.worktree specified
    the specified work tree is used

Note on the case where GIT_DIR is unspecified and repository is in cwd:
    GIT_WORK_TREE is used but is_inside_git_dir is always true.
    I did it this way because setup_gdg might be called multiple
    times (e.g. when doing alias expansion) and in successive calls
    setup_gdg should do the same thing every time.

Meaning of is_bare/is_inside_work_tree/is_inside_git_dir:

(1) is_bare_repository
    A repository is bare if core.bare is true or core.bare is
    unspecified and the name suggests it is bare (directory not
    named .git).  The bare option disables a few protective
    checks which are useful with a working tree.  Currently
    this changes if a repository is bare:
        updates of HEAD are allowed
        git gc packs the refs
        the reflog is disabled by default
        cwd is not used as fallback work tree

(2) is_inside_work_tree
    True if the cwd is inside the associated working tree (if there
    is one), false otherwise.

(3) is_inside_git_dir
    True if the cwd is inside the git directory, false otherwise.
    Before this patch is_inside_git_dir was always true for bare
    repositories.

When setup_gdg finds a repository git_config(git_default_config) is
always called.  This ensure that is_bare_repository makes use of
core.bare and does not guess even though core.bare is specified.

inside_work_tree and inside_git_dir are set if setup_gdg finds a
repository.  The is_inside_work_tree and is_inside_git_dir functions
will die if they are called before a successful call to setup_gdg.

Signed-off-by: Matthias Lederhofer <matled@gmx.net>
---
 Documentation/config.txt        |    7 ++
 Documentation/git-rev-parse.txt |    4 +
 Documentation/git.txt           |   18 +++-
 builtin-rev-parse.c             |    5 +
 cache.h                         |    2 +
 connect.c                       |    1 +
 git.c                           |   12 ++-
 setup.c                         |  211 +++++++++++++++++++++++++++++----------
 t/test-lib.sh                   |    1 +
 9 files changed, 204 insertions(+), 57 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 5868d58..4d0bd37 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -172,6 +172,13 @@ repository that ends in "/.git" is assumed to be not bare (bare =
 false), while all other repositories are assumed to be bare (bare
 = true).
 
+core.worktree::
+	Set the path to the working tree.  The value will not be
+	used in combination with repositories found automatically in
+	a .git directory (i.e. $GIT_DIR is not set).
+	This can be overriden by the GIT_WORK_TREE environment
+	variable and the '--work-tree' command line option.
+
 core.logAllRefUpdates::
 	Updates to a ref <ref> is logged to the file
 	"$GIT_DIR/logs/<ref>", by appending the new and old
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index c817d16..6e4d158 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -93,6 +93,10 @@ OPTIONS
 	When the current working directory is below the repository
 	directory print "true", otherwise "false".
 
+--is-inside-work-tree::
+	When the current working directory is inside the work tree of the
+	repository print "true", otherwise "false".
+
 --is-bare-repository::
 	When the repository is bare print "true", otherwise "false".
 
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 98860af..4b567d8 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -10,7 +10,8 @@ SYNOPSIS
 --------
 [verse]
 'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate]
-    [--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS]
+    [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE]
+    [--help] COMMAND [ARGS]
 
 DESCRIPTION
 -----------
@@ -101,6 +102,14 @@ OPTIONS
 	Set the path to the repository. This can also be controlled by
 	setting the GIT_DIR environment variable.
 
+--work-tree=<path>::
+	Set the path to the working tree.  The value will not be
+	used in combination with repositories found automatically in
+	a .git directory (i.e. $GIT_DIR is not set).
+	This can also be controlled by setting the GIT_WORK_TREE
+	environment variable and the core.worktree configuration
+	variable.
+
 --bare::
 	Same as --git-dir=`pwd`.
 
@@ -345,6 +354,13 @@ git so take care if using Cogito etc.
 	specifies a path to use instead of the default `.git`
 	for the base of the repository.
 
+'GIT_WORK_TREE'::
+	Set the path to the working tree.  The value will not be
+	used in combination with repositories found automatically in
+	a .git directory (i.e. $GIT_DIR is not set).
+	This can also be controlled by the '--work-tree' command line
+	option and the core.worktree configuration variable.
+
 git Commits
 ~~~~~~~~~~~
 'GIT_AUTHOR_NAME'::
diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c
index 71d5162..497903a 100644
--- a/builtin-rev-parse.c
+++ b/builtin-rev-parse.c
@@ -352,6 +352,11 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 						: "false");
 				continue;
 			}
+			if (!strcmp(arg, "--is-inside-work-tree")) {
+				printf("%s\n", is_inside_work_tree() ? "true"
+						: "false");
+				continue;
+			}
 			if (!strcmp(arg, "--is-bare-repository")) {
 				printf("%s\n", is_bare_repository() ? "true"
 						: "false");
diff --git a/cache.h b/cache.h
index 8a9d1f3..ae1990a 100644
--- a/cache.h
+++ b/cache.h
@@ -192,6 +192,7 @@ enum object_type {
 };
 
 #define GIT_DIR_ENVIRONMENT "GIT_DIR"
+#define GIT_WORK_TREE_ENVIRONMENT "GIT_WORK_TREE"
 #define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
 #define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
 #define INDEX_ENVIRONMENT "GIT_INDEX_FILE"
@@ -207,6 +208,7 @@ enum object_type {
 extern int is_bare_repository_cfg;
 extern int is_bare_repository(void);
 extern int is_inside_git_dir(void);
+extern int is_inside_work_tree(void);
 extern const char *get_git_dir(void);
 extern char *get_object_directory(void);
 extern char *get_refs_directory(void);
diff --git a/connect.c b/connect.c
index 8cbda88..aafa416 100644
--- a/connect.c
+++ b/connect.c
@@ -589,6 +589,7 @@ pid_t git_connect(int fd[2], char *url, const char *prog, int flags)
 			unsetenv(ALTERNATE_DB_ENVIRONMENT);
 			unsetenv(DB_ENVIRONMENT);
 			unsetenv(GIT_DIR_ENVIRONMENT);
+			unsetenv(GIT_WORK_TREE_ENVIRONMENT);
 			unsetenv(GRAFT_ENVIRONMENT);
 			unsetenv(INDEX_ENVIRONMENT);
 			execlp("sh", "sh", "-c", command, NULL);
diff --git a/git.c b/git.c
index 29b55a1..05a391b 100644
--- a/git.c
+++ b/git.c
@@ -4,7 +4,7 @@
 #include "quote.h"
 
 const char git_usage_string[] =
-	"git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate] [--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS]";
+	"git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]";
 
 static void prepend_to_path(const char *dir, int len)
 {
@@ -69,6 +69,16 @@ static int handle_options(const char*** argv, int* argc)
 			handled++;
 		} else if (!prefixcmp(cmd, "--git-dir=")) {
 			setenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1);
+		} else if (!strcmp(cmd, "--work-tree")) {
+			if (*argc < 2) {
+				fprintf(stderr, "No directory given for --work-tree.\n" );
+				usage(git_usage_string);
+			}
+			setenv(GIT_WORK_TREE_ENVIRONMENT, (*argv)[1], 1);
+			(*argv)++;
+			(*argc)--;
+		} else if (!prefixcmp(cmd, "--work-tree=")) {
+			setenv(GIT_WORK_TREE_ENVIRONMENT, cmd + 12, 1);
 		} else if (!strcmp(cmd, "--bare")) {
 			static char git_dir[PATH_MAX+1];
 			setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 1);
diff --git a/setup.c b/setup.c
index a45ea83..7e32de2 100644
--- a/setup.c
+++ b/setup.c
@@ -174,41 +174,93 @@ static int inside_git_dir = -1;
 
 int is_inside_git_dir(void)
 {
-	if (inside_git_dir < 0) {
-		char buffer[1024];
-
-		if (is_bare_repository())
-			return (inside_git_dir = 1);
-		if (getcwd(buffer, sizeof(buffer))) {
-			const char *git_dir = get_git_dir(), *cwd = buffer;
-			while (*git_dir && *git_dir == *cwd) {
-				git_dir++;
-				cwd++;
-			}
-			inside_git_dir = !*git_dir;
-		} else
-			inside_git_dir = 0;
+	if (inside_git_dir >= 0)
+		return inside_git_dir;
+	die("BUG: is_inside_git_dir called before setup_git_directory");
+}
+
+static int inside_work_tree = -1;
+
+int is_inside_work_tree(void)
+{
+	if (inside_git_dir >= 0)
+		return inside_work_tree;
+	die("BUG: is_inside_work_tree called before setup_git_directory");
+}
+
+static char *gitworktree_config;
+
+static int git_setup_config(const char *var, const char *value)
+{
+	if (!strcmp(var, "core.worktree")) {
+		if (gitworktree_config)
+			strlcpy(gitworktree_config, value, PATH_MAX);
+		return 0;
 	}
-	return inside_git_dir;
+	return git_default_config(var, value);
 }
 
 const char *setup_git_directory_gently(int *nongit_ok)
 {
 	static char cwd[PATH_MAX+1];
-	const char *gitdirenv;
-	int len, offset;
+	char worktree[PATH_MAX+1], gitdir[PATH_MAX+1];
+	const char *gitdirenv, *gitworktree;
+	int wt_rel_gitdir = 0;
 
-	/*
-	 * If GIT_DIR is set explicitly, we're not going
-	 * to do any discovery, but we still do repository
-	 * validation.
-	 */
 	gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
-	if (gitdirenv) {
-		if (PATH_MAX - 40 < strlen(gitdirenv))
-			die("'$%s' too big", GIT_DIR_ENVIRONMENT);
-		if (is_git_directory(gitdirenv))
+	if (!gitdirenv) {
+		int len, offset;
+
+		if (!getcwd(cwd, sizeof(cwd)-1) || cwd[0] != '/')
+			die("Unable to read current working directory");
+
+		offset = len = strlen(cwd);
+		for (;;) {
+			if (is_git_directory(".git"))
+				break;
+			if (offset == 0) {
+				offset = -1;
+				break;
+			}
+			chdir("..");
+			while (cwd[--offset] != '/')
+				; /* do nothing */
+		}
+
+		if (offset >= 0) {
+			inside_work_tree = 1;
+			git_config(git_default_config);
+			if (offset == len) {
+				inside_git_dir = 0;
+				return NULL;
+			}
+
+			cwd[len++] = '/';
+			cwd[len] = '\0';
+			inside_git_dir = !prefixcmp(cwd + offset + 1, ".git/");
+			return cwd + offset + 1;
+		}
+
+		if (chdir(cwd))
+			die("Cannot come back to cwd");
+		if (!is_git_directory(".")) {
+			if (nongit_ok) {
+				*nongit_ok = 1;
+				return NULL;
+			}
+			die("Not a git repository");
+		}
+		setenv(GIT_DIR_ENVIRONMENT, cwd, 1);
+	}
+
+	if (PATH_MAX - 40 < strlen(gitdirenv)) {
+		if (nongit_ok) {
+			*nongit_ok = 1;
 			return NULL;
+		}
+		die("$%s too big", GIT_DIR_ENVIRONMENT);
+	}
+	if (!is_git_directory(gitdirenv)) {
 		if (nongit_ok) {
 			*nongit_ok = 1;
 			return NULL;
@@ -218,41 +270,90 @@ const char *setup_git_directory_gently(int *nongit_ok)
 
 	if (!getcwd(cwd, sizeof(cwd)-1) || cwd[0] != '/')
 		die("Unable to read current working directory");
+	if (chdir(gitdirenv)) {
+		if (nongit_ok) {
+			*nongit_ok = 1;
+			return NULL;
+		}
+		die("Cannot change directory to $%s '%s'",
+			GIT_DIR_ENVIRONMENT, gitdirenv);
+	}
+	if (!getcwd(gitdir, sizeof(gitdir)-1) || gitdir[0] != '/')
+		die("Unable to read current working directory");
+	if (chdir(cwd))
+		die("Cannot come back to cwd");
 
-	offset = len = strlen(cwd);
-	for (;;) {
-		if (is_git_directory(".git"))
-			break;
-		chdir("..");
-		do {
-			if (!offset) {
-				if (is_git_directory(cwd)) {
-					if (chdir(cwd))
-						die("Cannot come back to cwd");
-					setenv(GIT_DIR_ENVIRONMENT, cwd, 1);
-					inside_git_dir = 1;
-					return NULL;
-				}
-				if (nongit_ok) {
-					if (chdir(cwd))
-						die("Cannot come back to cwd");
-					*nongit_ok = 1;
-					return NULL;
-				}
-				die("Not a git repository");
+	/*
+	 * In case there is a work tree we may change the directory,
+	 * therefore make GIT_DIR an absolute path.
+	 */
+	if (gitdirenv[0] != '/') {
+		setenv(GIT_DIR_ENVIRONMENT, gitdir, 1);
+		gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
+		if (PATH_MAX - 40 < strlen(gitdirenv)) {
+			if (nongit_ok) {
+				*nongit_ok = 1;
+				return NULL;
 			}
-		} while (cwd[--offset] != '/');
+			die("$%s too big after expansion to absolute path",
+				GIT_DIR_ENVIRONMENT);
+		}
+	}
+
+	strcat(cwd, "/");
+	strcat(gitdir, "/");
+	inside_git_dir = !prefixcmp(cwd, gitdir);
+
+	gitworktree = getenv(GIT_WORK_TREE_ENVIRONMENT);
+	if (!gitworktree) {
+		gitworktree_config = worktree;
+		worktree[0] = '\0';
+	}
+	git_config(git_setup_config);
+	if (!gitworktree) {
+		gitworktree_config = NULL;
+		if (worktree[0])
+			gitworktree = worktree;
+		if (gitworktree && gitworktree[0] != '/')
+			wt_rel_gitdir = 1;
+	}
+
+	if (wt_rel_gitdir && chdir(gitdirenv))
+		die("Cannot change directory to $%s '%s'",
+			GIT_DIR_ENVIRONMENT, gitdirenv);
+	if (gitworktree && chdir(gitworktree)) {
+		if (nongit_ok) {
+			if (wt_rel_gitdir && chdir(cwd))
+				die("Cannot come back to cwd");
+			*nongit_ok = 1;
+			return NULL;
+		}
+		if (wt_rel_gitdir)
+			die("Cannot change directory to working tree '%s'"
+				" from $%s", gitworktree, GIT_DIR_ENVIRONMENT);
+		else
+			die("Cannot change directory to working tree '%s'",
+				gitworktree);
 	}
+	if (!getcwd(worktree, sizeof(worktree)-1) || worktree[0] != '/')
+		die("Unable to read current working directory");
+	strcat(worktree, "/");
+	inside_work_tree = !prefixcmp(cwd, worktree);
 
-	if (offset == len)
+	if (gitworktree && inside_work_tree && !prefixcmp(worktree, gitdir) &&
+	    strcmp(worktree, gitdir)) {
+		inside_git_dir = 0;
+	}
+
+	if (!inside_work_tree) {
+		if (chdir(cwd))
+			die("Cannot come back to cwd");
 		return NULL;
+	}
 
-	/* Make "offset" point to past the '/', and add a '/' at the end */
-	offset++;
-	cwd[len++] = '/';
-	cwd[len] = 0;
-	inside_git_dir = !prefixcmp(cwd + offset, ".git/");
-	return cwd + offset;
+	if (!strcmp(cwd, worktree))
+		return NULL;
+	return cwd+strlen(worktree);
 }
 
 int git_config_perm(const char *var, const char *value)
diff --git a/t/test-lib.sh b/t/test-lib.sh
index dee3ad7..b61e1d5 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -26,6 +26,7 @@ GIT_COMMITTER_EMAIL=committer@example.com
 GIT_COMMITTER_NAME='C O Mitter'
 unset GIT_DIFF_OPTS
 unset GIT_DIR
+unset GIT_WORK_TREE
 unset GIT_EXTERNAL_DIFF
 unset GIT_INDEX_FILE
 unset GIT_OBJECT_DIRECTORY
-- 
1.5.2.1.116.g9f308

^ permalink raw reply related

* [PATCH 3/7 (amend)] test git rev-parse
From: Matthias Lederhofer @ 2007-06-06  7:01 UTC (permalink / raw)
  To: Git Mailing List
In-Reply-To: <20070603144700.GC20061@moooo.ath.cx>

Signed-off-by: Matthias Lederhofer <matled@gmx.net>
---
The amended version has a new test:
When GIT_DIR is set and the repository is not bare the current working
directory should be used as working tree.
---
 t/t1500-rev-parse.sh |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 72 insertions(+), 0 deletions(-)
 create mode 100755 t/t1500-rev-parse.sh

diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh
new file mode 100755
index 0000000..66b0e58
--- /dev/null
+++ b/t/t1500-rev-parse.sh
@@ -0,0 +1,72 @@
+#!/bin/sh
+
+test_description='test git rev-parse'
+. ./test-lib.sh
+
+test_rev_parse() {
+	name=$1
+	shift
+
+	test_expect_success "$name: is-bare-repository" \
+	"test '$1' = \"\$(git rev-parse --is-bare-repository)\""
+	shift
+	[ $# -eq 0 ] && return
+
+	test_expect_success "$name: is-inside-git-dir" \
+	"test '$1' = \"\$(git rev-parse --is-inside-git-dir)\""
+	shift
+	[ $# -eq 0 ] && return
+
+	test_expect_success "$name: prefix" \
+	"test '$1' = \"\$(git rev-parse --show-prefix)\""
+	shift
+	[ $# -eq 0 ] && return
+}
+
+test_rev_parse toplevel false false ''
+
+cd .git || exit 1
+test_rev_parse .git/ false true .git/
+cd objects || exit 1
+test_rev_parse .git/objects/ false true .git/objects/
+cd ../.. || exit 1
+
+mkdir -p sub/dir || exit 1
+cd sub/dir || exit 1
+test_rev_parse subdirectory false false sub/dir/
+cd ../.. || exit 1
+
+git config core.bare true
+test_rev_parse 'core.bare = true' true
+
+git config --unset core.bare
+test_rev_parse 'core.bare undefined' false
+
+mkdir work || exit 1
+cd work || exit 1
+export GIT_DIR=../.git
+export GIT_CONFIG="$GIT_DIR"/config
+
+git config core.bare false
+test_rev_parse 'GIT_DIR=../.git, core.bare = false' false false ''
+
+git config core.bare true
+test_rev_parse 'GIT_DIR=../.git, core.bare = true' true
+
+git config --unset core.bare
+test_rev_parse 'GIT_DIR=../.git, core.bare undefined' false false ''
+
+mv ../.git ../repo.git || exit 1
+export GIT_DIR=../repo.git
+export GIT_CONFIG="$GIT_DIR"/config
+
+git config core.bare false
+test_rev_parse 'GIT_DIR=../repo.git, core.bare = false' false false ''
+
+git config core.bare true
+test_rev_parse 'GIT_DIR=../repo.git, core.bare = true' true
+
+git config --unset core.bare
+test_rev_parse 'GIT_DIR=../repo.git, core.bare undefined' true
+
+test_done
-- 
1.5.2.1.116.g9f308

^ permalink raw reply related

* Re: [PATCH] Remove useless uses of cat, and replace with filename arguments or redirection
From: Martin Langhoff @ 2007-06-06  6:38 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: Michael Poole, Josh Triplett, git
In-Reply-To: <20070606145436.b8907cf0.git@ozlabs.org>

On 6/6/07, Stephen Rothwell <git@ozlabs.org> wrote:
> On Wed, 6 Jun 2007 15:58:09 +1200 "Martin Langhoff" <martin.langhoff@gmail.com> wrote:
> >
> > Josh is right. The output *is* different because it contains the
>   ^^^^
> My name is Stephen  :-) and that is indeed what I meant.

Sorry! Cross-eyed over the email thread, but not over posix behaviour ;-)

...cleans those glasses now


martin

^ permalink raw reply

* Re: [PATCH] New selection indication and softer colors
From: Shawn O. Pearce @ 2007-06-06  5:24 UTC (permalink / raw)
  To: Matthijs Melchior; +Cc: git
In-Reply-To: <11810802023668-git-send-email-mmelchior@xs4all.nl>

Matthijs Melchior <mmelchior@xs4all.nl> wrote:
> The default font was already bold, so marking the selected file with bold
> font did not work.  Change that to lightgray background.
> Also, the header colors are now softer, giving better readability.

Thanks, this is actually kind of nice.  I've applied it to my
maint and pushed it out.  I feel a gitgui-0.7.3 coming real soon
(maint has 8 new commits on it already).

-- 
Shawn.

^ permalink raw reply

* Re: clarify git clone --local --shared --reference
From: Shawn O. Pearce @ 2007-06-06  5:11 UTC (permalink / raw)
  To: Brandon Casey; +Cc: git
In-Reply-To: <46658F98.6020001@nrlssc.navy.mil>

Brandon Casey <casey@nrlssc.navy.mil> wrote:
> Shawn O. Pearce wrote:
> >
> >  b) Don't repack the source repository without accounting for the
> >  refs and reflogs of all --shared repositories that came from it.
> >  Otherwise you may delete objects that the source repository no
> >  longer needs, but that one or more of the --shared repositories
> >  still needs.
> 
> How should this be accomplished? Does this mean never run 
> git-gc/git-repack on the source repository? Or is there a way to
> cause the sharing repositories to copy over objects no longer
> required by the source repository?

Well, you can repack, but only if if you account for everything.
The easiest way to do this is push every branch from the --shared
repos to the source repository, repack the source repository, then
you can run `git prune-packed` in the --shared repos to remove
loose objects that the source repository now has.

You can account for the refs by hand when you run pack-objects
by hand, but its horribly difficult compared to the push and then
repack I just described.  I think that long-lived --shared isn't that
common of a workflow; most people use --shared for shortterm things.
For example contrib/continuous uses --shared when it clones the
repository to create a temporary build area.
 
> >>4) is space savings obtained only at initial clone? or is it on going?
> >>   does a future git pull from the source repository create new hard
> >>   links where possible?
> >
> >Only on initial clone.  Later pulls will copy.  You can try using
> >git-relink to redo the hardlinks after the pull.
> 
> How about with --shared? Particularly with a fast-forward not much
> would need to be copied over. Do later pulls into a repository with
> configured objects/info/alternates take advantage of space savings
> when possible?

Yes.  Recently a --shared avoids copying the objects if at all
possible.  This makes fetches from the source repository into the
--shared repository very, very fast, and uses no additional disk.
 
> If the answer above is "yes", then this brings up an interesting use 
> case. I assume that clone, fetch, etc follow the alternates of the 
> source repository? Otherwise a --shared repository would be unclone-able 
> right? And only pull-able from the source repository? So if that is the 
> case (that remote alternates are followed),

Alternates are followed as many as 5 deep.  So you can do something like
this:

	git clone --shared source share1
	git clone --shared share1 share2
	git clone --shared share2 share3
	git clone --shared share3 share4
	git clone --shared share4 share5
	git clone --shared share5 corrupt

I think corrupt is corrupt; it doesn't have access to the source anymore
and therefore is missing 90%+ of the object database.  To help make this
case work the objects/info/alternates should always contain absolute paths;
we store them absolute in git-clone by default but you could set them up
by hand.  The other repositories should however be intact and usable, but
you cannot clone from share5.

Normal fetch/push/pull will work fine against any of those working
repos, as they are all using the normal Git object transport methods,
which means we copy objects unless they are available to us already
(see above).

> then a group of developers 
> could add all of the other developers to their alternates list (if 
> multiple alternates are supported)

Yes, they are.  I don't think we have a limit on the number of
alternates you are allowed to have.  However each additional
alternate adds some cost to starting up any given Git process.
The more alternates you have (or the more deeply nested they are)
the slower Git will initialize itself.  For 1 or 2 alternates its
within the fork+exec noise of any good UNIX system; for 50 alternates
I think you would notice it.

> and reference their objects when 
> possible. To the extent that it is possible, each developer would end up 
> only storing their commit objects. This would then create a distributed 
> repository.

Yes, but that has very high risk.  If developer Joe Smith quits and
then the administrator `rm -rf /home/jsmith` everyone is hosed as
they can no longer access the objects that were originally created
by Joe.  Then the administrator is off looking for backup tapes,
assuming he has them and they are valid.  One nice property of Git
(really any DVCS) is that the data is automatically backed up by
every developer participating in the project.  Its unlikely you
will lose the project that way.

Also this scheme doesn't really work well for packing.  I don't
think we'll pack the loose objects that we borrow from the other
developers, and Git packfiles are a major performance improvement
for all Git operations.  Plus they are very small, so they save a
lot of disk.

You might find that it takes up less total disk to have everyone
keep a complete (non --shared) copy of the project, but repack
regularly, then to have everyone using alternates against each
other and nobody repacks.
 
> Of course, this new distributed repository may be somewhat fragile since 
> the entire thing could become unusable if any portion was corrupted. 
> Just because you can do a thing, doesn't mean you should.

Yes, exactly.  ;-)

In my day-job repositories I have about 150 MiB of blobs that
are very common across a number of Git repositories.  I've made a
single repo that has all of those packed, and then setup that as an
alternate for everything else.  It saves a huge chunk of disk for us.
But that common-blob.git thing that I created never gets changed,
and never gets repacked.  Its sort of a "historical archive" for us.
Works very nicely.  Alternates have their uses...

-- 
Shawn.

^ permalink raw reply

* Re: [PATCH] Remove useless uses of cat, and replace with filename arguments or redirection
From: Stephen Rothwell @ 2007-06-06  4:54 UTC (permalink / raw)
  To: Martin Langhoff; +Cc: Michael Poole, Stephen Rothwell, Josh Triplett, git
In-Reply-To: <46a038f90706052058h1c823278o78ce0d8edce3caab@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 254 bytes --]

On Wed, 6 Jun 2007 15:58:09 +1200 "Martin Langhoff" <martin.langhoff@gmail.com> wrote:
>
> Josh is right. The output *is* different because it contains the
  ^^^^
My name is Stephen  :-) and that is indeed what I meant.

Cheers,
Stephen Rothwell

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* [PATCH v2] Remove useless uses of cat, and replace with filename arguments or redirection
From: Josh Triplett @ 2007-06-06  4:36 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 3706 bytes --]

Replace all uses of cat that do nothing other than read a single file.  In the
case of git-quilt-import, this occurs once per patch.

Signed-off-by: Josh Triplett <josh@freedesktop.org>
---

This revised version fixes a bug caught by Stephen Rothwell: the output of wc
-l changes when it has a filename on the command line.  The same bug occurred
in one other place as well.

 git-commit.sh        |    2 +-
 git-filter-branch.sh |    4 ++--
 git-ls-remote.sh     |    2 +-
 git-quiltimport.sh   |    4 ++--
 git-verify-tag.sh    |    3 +--
 5 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/git-commit.sh b/git-commit.sh
index e8b60f7..06b6cd7 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -617,7 +617,7 @@ then
 		tree=$(GIT_INDEX_FILE="$TMP_INDEX" git-write-tree) &&
 		rm -f "$TMP_INDEX"
 	fi &&
-	commit=$(cat "$GIT_DIR"/COMMIT_MSG | git-commit-tree $tree $PARENTS) &&
+	commit=$(git-commit-tree $tree $PARENTS < "$GIT_DIR"/COMMIT_MSG) &&
 	rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
 	git-update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" &&
 	rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" &&
diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index 0c8a7df..346cf3f 100644
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -333,7 +333,7 @@ for commit in $unchanged; do
 done
 
 git-rev-list --reverse --topo-order $srcbranch --not $unchanged >../revs
-commits=$(cat ../revs | wc -l | tr -d " ")
+commits=$(wc -l ../revs | tr -d -c 0-9)
 
 test $commits -eq 0 && die "Found nothing to rewrite"
 
@@ -386,7 +386,7 @@ while read commit; do
 done <../revs
 
 git-update-ref refs/heads/"$dstbranch" $(head -n 1 ../map/$(tail -n 1 ../revs))
-if [ "$(cat ../map/$(tail -n 1 ../revs) | wc -l)" -gt 1 ]; then
+if [ "$(wc -l < ../map/$(tail -n 1 ../revs))" -gt 1 ]; then
 	echo "WARNING: Your commit filter caused the head commit to expand to several rewritten commits. Only the first such commit was recorded as the current $dstbranch head but you will need to resolve the situation now (probably by manually merging the other commits). These are all the commits:" >&2
 	sed 's/^/	/' ../map/$(tail -n 1 ../revs) >&2
 	ret=1
diff --git a/git-ls-remote.sh b/git-ls-remote.sh
index a6ed99a..f5b2e77 100755
--- a/git-ls-remote.sh
+++ b/git-ls-remote.sh
@@ -82,7 +82,7 @@ rsync://* )
 	(cd $tmpdir && find refs -type f) |
 	while read path
 	do
-		cat "$tmpdir/$path" | tr -d '\012'
+		tr -d '\012' < "$tmpdir/$path"
 		echo "	$path"
 	done &&
 	rm -fr $tmpdir
diff --git a/git-quiltimport.sh b/git-quiltimport.sh
index a7a6757..bd540cd 100755
--- a/git-quiltimport.sh
+++ b/git-quiltimport.sh
@@ -70,9 +70,9 @@ tmp_info="$tmp_dir/info"
 commit=$(git-rev-parse HEAD)
 
 mkdir $tmp_dir || exit 2
-for patch_name in $(cat "$QUILT_PATCHES/series" | grep -v '^#'); do
+for patch_name in $(grep -v '^#' "$QUILT_PATCHES/series"); do
 	echo $patch_name
-	(cat $QUILT_PATCHES/$patch_name | git-mailinfo "$tmp_msg" "$tmp_patch" > "$tmp_info") || exit 3
+	git-mailinfo "$tmp_msg" "$tmp_patch" < "$QUILT_PATCHES/$patch_name" > "$tmp_info" || exit 3
 	test -s .dotest/patch || {
 		echo "Patch is empty.  Was it split wrong?"
 		exit 1
diff --git a/git-verify-tag.sh b/git-verify-tag.sh
index 8db7dd0..11ce947 100755
--- a/git-verify-tag.sh
+++ b/git-verify-tag.sh
@@ -38,8 +38,7 @@ trap 'rm -f "$GIT_DIR/.tmp-vtag"' 0
 
 git-cat-file tag "$1" >"$GIT_DIR/.tmp-vtag" || exit 1
 
-cat "$GIT_DIR/.tmp-vtag" |
-sed '/-----BEGIN PGP/Q' |
+sed '/-----BEGIN PGP/Q' "$GIT_DIR/.tmp-vtag" |
 gpg --verify "$GIT_DIR/.tmp-vtag" - || exit 1
 rm -f "$GIT_DIR/.tmp-vtag"
 
-- 
1.5.2.1



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 252 bytes --]

^ permalink raw reply related

* [PATCH] git-mergetool: Make default smarter by considering user's desktop environment and editor
From: Josh Triplett @ 2007-06-06  4:28 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 1985 bytes --]

Make git-mergetool prefer meld under GNOME, and kdiff3 under KDE.  When
considering emerge and vimdiff, check $VISUAL and $EDITOR to see which the
user might prefer.

Signed-off-by: Josh Triplett <josh@freedesktop.org>
---

Arguably, kdiff3 should now move down next to meld, below the other
non-graphical tools, so that if the user doesn't run KDE or GNOME they get a
non-KDE, non-GNOME tool.  This patch doesn't do that, though.

 git-mergetool.sh |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/git-mergetool.sh b/git-mergetool.sh
index bb21b03..2053d43 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -304,7 +304,13 @@ if test -z "$merge_tool"; then
 fi
 
 if test -z "$merge_tool" ; then
-    if type kdiff3 >/dev/null 2>&1 && test -n "$DISPLAY"; then
+    # Try tools that match the user's desktop environment
+    if test x"$KDE_FULL_SESSION" = x"true" && type kdiff3 >/dev/null 2>&1 && test -n "$DISPLAY"; then
+        merge_tool="kdiff3";
+    elif test x"$GNOME_DESKTOP_SESSION_ID" != x"" && type meld >/dev/null 2>&1 && test -n "$DISPLAY"; then
+        merge_tool=meld
+    # Try any graphical tool
+    elif type kdiff3 >/dev/null 2>&1 && test -n "$DISPLAY"; then
 	merge_tool="kdiff3";
     elif type tkdiff >/dev/null 2>&1 && test -n "$DISPLAY"; then
 	merge_tool=tkdiff
@@ -312,6 +318,12 @@ if test -z "$merge_tool" ; then
 	merge_tool=xxdiff
     elif type meld >/dev/null 2>&1 && test -n "$DISPLAY"; then
 	merge_tool=meld
+    # Try tools specific to the user's editor
+    elif echo "${VISUAL:-$EDITOR}" | grep '^emacs' > /dev/null 2>&1 && type emacs >/dev/null 2>&1; then
+	merge_tool=emerge
+    elif echo "${VISUAL:-$EDITOR}" | grep '^vim' > /dev/null 2>&1 && type vimdiff >/dev/null 2>&1; then
+	merge_tool=vimdiff
+    # Try other tools
     elif type opendiff >/dev/null 2>&1; then
 	merge_tool=opendiff
     elif type emacs >/dev/null 2>&1; then
-- 
1.5.2.1



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 252 bytes --]

^ permalink raw reply related

* [PATCH] Fix typo in git-mergetool
From: Josh Triplett @ 2007-06-06  4:24 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 545 bytes --]

Signed-off-by: Josh Triplett <josh@freedesktop.org>
---
 git-mergetool.sh |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/git-mergetool.sh b/git-mergetool.sh
index e62351b..bb21b03 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -5,7 +5,7 @@
 # Copyright (c) 2006 Theodore Y. Ts'o
 #
 # This file is licensed under the GPL v2, or a later version
-# at the discretion of Junio C Hammano.
+# at the discretion of Junio C Hamano.
 #
 
 USAGE='[--tool=tool] [file to merge] ...'
-- 
1.5.2.1



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 252 bytes --]

^ permalink raw reply related

* Re: [PATCH] Remove useless uses of cat, and replace with filename arguments or redirection
From: Martin Langhoff @ 2007-06-06  3:58 UTC (permalink / raw)
  To: Michael Poole; +Cc: Stephen Rothwell, Josh Triplett, git
In-Reply-To: <87sl957naf.fsf@graviton.dyn.troilus.org>

On 6/6/07, Michael Poole <mdpoole@troilus.org> wrote:
> Stephen Rothwell writes:
>
> > On Tue, 05 Jun 2007 18:34:59 -0700 Josh Triplett <josh@freedesktop.org> wrote:
> >>
> >> -commits=$(cat ../revs | wc -l | tr -d " ")
> >> +commits=$(wc -l ../revs | tr -d " ")
> >
> > This is not equivalent, you probably wanted:
> >
> > commits=$(wc -l <../revs | tr -d " ")
>
> Which relevant version(s) of wc do not accept filename arguments?
> POSIX[1] seems to specify it.  Or do you mean that there is some
> subtle difference in its processing of stdin vs specified files?

Josh is right. The output *is* different because it contains the
filename as well. See

  $ wc < .gitk | tr -d " "
  2177551
  $ wc .gitk | tr -d " "
  2177551.gitk

cheers


m

^ permalink raw reply

* Re: [PATCH] Remove useless uses of cat, and replace with filename arguments or redirection
From: Michael Poole @ 2007-06-06  3:51 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: Josh Triplett, git
In-Reply-To: <20070606133915.d72e4afe.git@ozlabs.org>

Stephen Rothwell writes:

> On Tue, 05 Jun 2007 18:34:59 -0700 Josh Triplett <josh@freedesktop.org> wrote:
>>
>> -commits=$(cat ../revs | wc -l | tr -d " ")
>> +commits=$(wc -l ../revs | tr -d " ")
>
> This is not equivalent, you probably wanted:
>
> commits=$(wc -l <../revs | tr -d " ")

Which relevant version(s) of wc do not accept filename arguments?
POSIX[1] seems to specify it.  Or do you mean that there is some
subtle difference in its processing of stdin vs specified files?

[1]- http://www.opengroup.org/onlinepubs/000095399/utilities/wc.html

Michael Poole

^ permalink raw reply

* Re: [PATCH] Remove useless uses of cat, and replace with filename arguments or redirection
From: Stephen Rothwell @ 2007-06-06  3:39 UTC (permalink / raw)
  To: Josh Triplett; +Cc: git
In-Reply-To: <46660F43.4060402@freedesktop.org>

[-- Attachment #1: Type: text/plain, Size: 289 bytes --]

On Tue, 05 Jun 2007 18:34:59 -0700 Josh Triplett <josh@freedesktop.org> wrote:
>
> -commits=$(cat ../revs | wc -l | tr -d " ")
> +commits=$(wc -l ../revs | tr -d " ")

This is not equivalent, you probably wanted:

commits=$(wc -l <../revs | tr -d " ")

Cheers,
Stephen Rothwell

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH] git-mergetool: Allow gvimdiff to be used as a mergetool
From: Theodore Tso @ 2007-06-06  2:45 UTC (permalink / raw)
  To: Dan McGee; +Cc: git
In-Reply-To: <11810938823594-git-send-email-dpmcgee@gmail.com>

Dan, your patch didn't add a gvimdiff check to the code which
determins which merge tool to use if one isn't specified in the config
file:

if test -z "$merge_tool" ; then
    if type kdiff3 >/dev/null 2>&1 && test -n "$DISPLAY"; then
	merge_tool="kdiff3";
    elif type tkdiff >/dev/null 2>&1 && test -n "$DISPLAY"; then
	merge_tool=tkdiff
    elif type xxdiff >/dev/null 2>&1 && test -n "$DISPLAY"; then
	merge_tool=xxdiff
    elif type meld >/dev/null 2>&1 && test -n "$DISPLAY"; then
	merge_tool=meld
    elif type opendiff >/dev/null 2>&1; then
	merge_tool=opendiff
    ...

Was this interntional?

Regards,

						- Ted

^ permalink raw reply

* [PATCH] git-mergetool: Allow gvimdiff to be used as a mergetool
From: Dan McGee @ 2007-06-06  1:38 UTC (permalink / raw)
  To: git; +Cc: Dan McGee

Signed-off-by: Dan McGee <dpmcgee@gmail.com>
---
 Documentation/config.txt        |    2 +-
 Documentation/git-mergetool.txt |    2 +-
 git-mergetool.sh                |    6 +++---
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 5868d58..3ca01af 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -531,7 +531,7 @@ merge.summary::
 merge.tool::
 	Controls which merge resolution program is used by
 	gitlink:git-mergetool[l].  Valid values are: "kdiff3", "tkdiff",
-	"meld", "xxdiff", "emerge", "vimdiff", and "opendiff"
+	"meld", "xxdiff", "emerge", "vimdiff", "gvimdiff", and "opendiff".
 
 merge.verbosity::
 	Controls the amount of output shown by the recursive merge
diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt
index add01e8..34c4c1c 100644
--- a/Documentation/git-mergetool.txt
+++ b/Documentation/git-mergetool.txt
@@ -25,7 +25,7 @@ OPTIONS
 -t or --tool=<tool>::
 	Use the merge resolution program specified by <tool>.
 	Valid merge tools are:
-	kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, and opendiff
+	kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, and opendiff
 +
 If a merge resolution program is not specified, 'git mergetool'
 will use the configuration variable merge.tool.  If the
diff --git a/git-mergetool.sh b/git-mergetool.sh
index e62351b..1e4807b 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -209,7 +209,7 @@ merge_file () {
 	    status=$?
 	    save_backup
 	    ;;
-	meld|vimdiff)
+	meld|vimdiff|gvimdiff)
 	    touch "$BACKUP"
 	    $merge_tool -- "$LOCAL" "$path" "$REMOTE"
 	    check_unchanged
@@ -293,7 +293,7 @@ done
 if test -z "$merge_tool"; then
     merge_tool=`git-config merge.tool`
     case "$merge_tool" in
-	kdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | "")
+	kdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | "")
 	    ;; # happy
 	*)
 	    echo >&2 "git config option merge.tool set to unknown tool: $merge_tool"
@@ -325,7 +325,7 @@ if test -z "$merge_tool" ; then
 fi
 
 case "$merge_tool" in
-    kdiff3|tkdiff|meld|xxdiff|vimdiff|opendiff)
+    kdiff3|tkdiff|meld|xxdiff|vimdiff|gvimdiff|opendiff)
 	if ! type "$merge_tool" > /dev/null 2>&1; then
 	    echo "The merge tool $merge_tool is not available"
 	    exit 1
-- 
1.5.2.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox