Git development
 help / color / mirror / Atom feed
* Re: What's cooking in git.git (Oct 2011, #01; Tue, 4)
From: Junio C Hamano @ 2011-10-05 16:32 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: git
In-Reply-To: <4E8BFF26.5050504@viscovery.net>

Johannes Sixt <j.sixt@viscovery.net> writes:

> Am 10/5/2011 4:12, schrieb Junio C Hamano:
>> * il/archive-err-signal (2011-10-03) 1 commit
>>  - transport: do not allow to push over git:// protocol
>
> Kindly fix up the commit message (delete the cruft) before you merge to next.

Thanks for noticing.

^ permalink raw reply

* Re: [PATCH 3/3] Windows: teach getenv to do a case-sensitive search
From: Karsten Blees @ 2011-10-05 16:21 UTC (permalink / raw)
  To: git
In-Reply-To: <4DEC7CDD.10403@viscovery.net>

Hmm...this looks like a pretty fragile solution to me. Wouldn't it be simpler
and safer to just fix the conflicting variables, instead of inventing entirely
new environment semantics for Windows?

I looked at the eval_gettext occurences, and only found '$path' in
git-submodule.sh to obviously conflict with existing environment variables. So
the straightforward solution IMO would be to fix the variable in that script.

Small solution (only affects gettext): in git-submodule.sh, replace all
'eval_gettext...$path' with 'modulepath=$path eval_gettext...$modulepath'

Big solution (enables git-submodule-foreach scripts on Windows, but is a
breaking change for existing foreach scripts on Unix): in git-submodule.sh,
t/t7407-submodule-foreach.sh, Documentation/git-submodule.txt, replace all
'$path' with '$modulepath' (also a few 'path=...' and 'while read...path')


Just a few failure scenarios that come to mind with the current solution:
- Given environment variables "Path" and "path", the 'case-sensitive first'
approach works fine for 'getenv("path")', but 'getenv("PATH")' still has a 50%
chance of failure.
- The other environment functions have not been changed to reflect the
'case-sensitive first' logic: setenv("path"...) and setenv("PATH"...) both have
a chance of overwriting the wrong entry, same for putenv.
- Windows applications generally don't support case-sensitive environment
variables, e.g. all MSYS and Cygwin programs convert environment variable names
to upper case on startup, eliminating duplicates in the process. With git.exe
beeing the only case-sensitive tool, any change to git-sh-i18n.sh (e.g.
replacing git-envsubst with a real gettext-envsubst) is likely to break again.
- As you already mentioned, Windows doesn't support case-sensitive environment
variable names, MSDN is pretty clear on that. Expressly violating this
documentation may cease to work with any new Windows version or patch.

Cheers,
Karsten

^ permalink raw reply

* Re: [RFC/PATCH] Add multiple workdir support to branch/checkout
From: Jay Soffian @ 2011-10-05 16:01 UTC (permalink / raw)
  To: git; +Cc: Jay Soffian, Nguyen Thai Ngoc Duy, Junio C Hamano
In-Reply-To: <1317828285-66581-1-git-send-email-jaysoffian@gmail.com>

> I was more looking for feedback on the idea than the implementation, but
> here's a better implementation. Still an RFC so no tests yet.

Oops. Let's try that again. Sent the wrong thing.

-- >8 --
Subject: [RFC/PATCH] Teach branch/checkout about workdirs

When using 'git new-workdir', there is no safety mechanism to prevent the
same branch from being checked out twice, nor to prevent a checked out
branch from being deleted.

Teach 'checkout' to record the workdir path using 'branch.<name>.checkout'
when switching branches. We can then easily check if a branch is already
checked out in another workdir before switching to that branch. Add a
similar check before deleting a branch.

Allow 'checkout -f' to force the checkout and issue a warning instead of
an error.

Guard this behavior behind 'core.recordCheckouts', which we will teach
'git new-workdir' to set in a followup commit.

Note: when switching away from a branch, we set 'branch.<name>.checkout'
to the empty string, instead of deleting it entirely, since git_config()
otherwise leaves behind an empty section which it does not re-use.

Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
---
 builtin/branch.c   |   10 ++++++++++
 builtin/checkout.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 remote.c           |    4 ++++
 remote.h           |    1 +
 4 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/builtin/branch.c b/builtin/branch.c
index f49596f826..6ce1a5b133 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -182,6 +182,16 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)
 			ret = 1;
 			continue;
 		}
+		if (kinds == REF_LOCAL_BRANCH) {
+			struct branch *branch = branch_get(bname.buf);
+			if (branch->work_tree && strlen(branch->work_tree)) {
+				error(_("Cannot delete the branch '%s' "
+					"which is currently checked out in '%s'"),
+				      bname.buf, branch->work_tree);
+				ret = 1;
+				continue;
+			}
+		}
 
 		free(name);
 
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 5e356a6c61..75510befde 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -33,6 +33,7 @@ struct checkout_opts {
 	int force_detach;
 	int writeout_stage;
 	int writeout_error;
+	int record_checkouts;
 
 	/* not set by parse_options */
 	int branch_exists;
@@ -508,6 +509,21 @@ static void detach_advice(const char *old_path, const char *new_name)
 	fprintf(stderr, fmt, new_name);
 }
 
+static void record_checkout(const char *name, const char *new_work_tree)
+{
+	struct strbuf key = STRBUF_INIT;
+	strbuf_addf(&key, "branch.%s.checkout", name);
+	if (new_work_tree) { /* reserve name */
+		git_config_set(key.buf, new_work_tree);
+	} else { /* release name if we reserved it */
+		struct branch *branch = branch_get(name);
+		if (branch->work_tree &&
+		    !strcmp(branch->work_tree, get_git_work_tree()))
+			git_config_set(key.buf, "");
+	}
+	strbuf_release(&key);
+}
+
 static void update_refs_for_switch(struct checkout_opts *opts,
 				   struct branch_info *old,
 				   struct branch_info *new)
@@ -556,6 +572,8 @@ static void update_refs_for_switch(struct checkout_opts *opts,
 				detach_advice(old->path, new->name);
 			describe_detached_head(_("HEAD is now at"), new->commit);
 		}
+		if (opts->record_checkouts && old->name)
+			record_checkout(old->name, NULL);
 	} else if (new->path) {	/* Switch branches. */
 		create_symref("HEAD", new->path, msg.buf);
 		if (!opts->quiet) {
@@ -580,6 +598,11 @@ static void update_refs_for_switch(struct checkout_opts *opts,
 			if (!file_exists(ref_file) && file_exists(log_file))
 				remove_path(log_file);
 		}
+		if (opts->record_checkouts) {
+			if (old->name)
+				record_checkout(old->name, NULL);
+			record_checkout(new->name, get_git_work_tree());
+		}
 	}
 	remove_branch_state();
 	strbuf_release(&msg);
@@ -709,6 +732,20 @@ static void orphaned_commit_warning(struct commit *commit)
 	for_each_ref(clear_commit_marks_from_one_ref, NULL);
 }
 
+static void check_if_checked_out(struct checkout_opts *opts, const char *name)
+{
+	struct branch *branch = branch_get(name);
+	if (branch->work_tree && strlen(branch->work_tree) &&
+	    strcmp(branch->work_tree, get_git_work_tree())) {
+		if (opts->force)
+			warning(_("branch '%s' is currently checked out"
+				  " in '%s'"), name, branch->work_tree);
+		else
+			die(_("branch '%s' is currently checked out"
+			      " in '%s'"), name, branch->work_tree);
+	}
+}
+
 static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
 {
 	int ret = 0;
@@ -732,6 +769,8 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
 		if (!new->commit)
 			die(_("You are on a branch yet to be born"));
 		parse_commit(new->commit);
+	} else if (opts->record_checkouts) {
+		check_if_checked_out(opts, new->name);
 	}
 
 	ret = merge_working_tree(opts, &old, new);
@@ -756,6 +795,10 @@ static int git_checkout_config(const char *var, const char *value, void *cb)
 		return 0;
 	}
 
+	if (!strcmp(var, "core.recordcheckouts")) {
+		struct checkout_opts *opts = cb;
+		opts->record_checkouts = git_config_bool(var, value);
+	}
 	if (!prefixcmp(var, "submodule."))
 		return parse_submodule_config_option(var, value);
 
diff --git a/remote.c b/remote.c
index b8ecfa5d95..2bc063dae8 100644
--- a/remote.c
+++ b/remote.c
@@ -364,6 +364,10 @@ static int handle_config(const char *key, const char *value, void *cb)
 			if (!value)
 				return config_error_nonbool(key);
 			add_merge(branch, xstrdup(value));
+		} else if (!strcmp(subkey, ".checkout")) {
+			if (!value)
+				return config_error_nonbool(key);
+			branch->work_tree = xstrdup(value);
 		}
 		return 0;
 	}
diff --git a/remote.h b/remote.h
index 9a30a9dba6..4103ec7e31 100644
--- a/remote.h
+++ b/remote.h
@@ -126,6 +126,7 @@ int remote_find_tracking(struct remote *remote, struct refspec *refspec);
 struct branch {
 	const char *name;
 	const char *refname;
+	const char *work_tree;
 
 	const char *remote_name;
 	struct remote *remote;
-- 
1.7.7.5.gd207e.dirty

^ permalink raw reply related

* Re: [RFC/PATCH] Add multiple workdir support to branch/checkout
From: Jay Soffian @ 2011-10-05 15:24 UTC (permalink / raw)
  To: git, Junio C Hamano; +Cc: Jay Soffian, Nguyen Thai Ngoc Duy
In-Reply-To: <7vmxdg9j3r.fsf@alter.siamese.dyndns.org>

On Wed, Oct 5, 2011 at 12:07 AM, Junio C Hamano <gitster@pobox.com> wrote:
> Jay Soffian <jaysoffian@gmail.com> writes:
>> @@ -734,6 +758,9 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
>>               parse_commit(new->commit);
>>       }
>>
>> +     if (opts->record_checkouts)
>> +             check_if_checked_out(opts, new->name);
>
> The close brace we can see in the context closes "if (!new->name) {", so
> this codepath is very well prepared to be called with new->name == NULL.
>
> Is check_if_checked_out() prepared to be called with name == NULL and do
> the right thing?
>
>> @@ -743,6 +770,14 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
>>
>>       update_refs_for_switch(opts, &old, new);
>>
>> +     if (opts->record_checkouts) {
>> +             const char *work_tree = get_git_work_tree();
>> +             struct branch *branch = branch_get(old.name);
>> +             if (branch->work_tree && !strcmp(branch->work_tree, work_tree))
>> +                     record_checkout(old.name, "");
>> +             record_checkout(new->name, work_tree);
>> +     }
>> +
>
> Likewise for new->name, but also old.name which is only set when old.path
> is set and begins with "refs/heads/" and otherwise NULL.

I was more looking for feedback on the idea than the implementation, but
here's a better implementation. Still an RFC so no tests yet.

-- >8 --
Subject: [RFC/PATCH] Teach branch/checkout about workdirs

When using 'git new-workdir', there is no safety mechanism to prevent the
same branch from being checked out twice, nor to prevent a checked out
branch from being deleted.

Teach 'checkout' to record the workdir path using 'branch.<name>.checkout'
when switching branches. We can then easily check if a branch is already
checked out in another workdir before switching to that branch. Add a
similar check before deleting a branch.

Allow 'checkout -f' to force the checkout and issue a warning instead of
an error.

Guard this behavior behind 'core.recordCheckouts', which we will teach
'git new-workdir' to set in a followup commit.

Note: when switching away from a branch, we set 'branch.<name>.checkout'
to the empty string, instead of deleting it entirely, since git_config()
otherwise leaves behind an empty section which it does not re-use.

Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
---
 builtin/branch.c   |   10 ++++++++++
 builtin/checkout.c |   45 +++++++++++++++++++++++++++++++++++++++++++++
 remote.c           |    4 ++++
 remote.h           |    1 +
 4 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/builtin/branch.c b/builtin/branch.c
index f49596f826..6ce1a5b133 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -182,6 +182,16 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)
 			ret = 1;
 			continue;
 		}
+		if (kinds == REF_LOCAL_BRANCH) {
+			struct branch *branch = branch_get(bname.buf);
+			if (branch->work_tree && strlen(branch->work_tree)) {
+				error(_("Cannot delete the branch '%s' "
+					"which is currently checked out in '%s'"),
+				      bname.buf, branch->work_tree);
+				ret = 1;
+				continue;
+			}
+		}
 
 		free(name);
 
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 5e356a6c61..b3c658ffd4 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -33,6 +33,7 @@ struct checkout_opts {
 	int force_detach;
 	int writeout_stage;
 	int writeout_error;
+	int record_checkouts;
 
 	/* not set by parse_options */
 	int branch_exists;
@@ -508,6 +509,20 @@ static void detach_advice(const char *old_path, const char *new_name)
 	fprintf(stderr, fmt, new_name);
 }
 
+static void record_checkout(const char *name, const char *new_work_tree)
+{
+	struct strbuf key = STRBUF_INIT;
+	strbuf_addf(&key, "branch.%s.checkout", name);
+	if (new_work_tree) { /* reserve name */
+		git_config_set(key.buf, new_work_tree);
+	} else { /* release name if we reserved it */
+		struct branch *branch = branch_get(name);
+		if (!strcmp(branch->work_tree, get_git_work_tree()))
+			git_config_set(key.buf, "");
+	}
+	strbuf_release(&key);
+}
+
 static void update_refs_for_switch(struct checkout_opts *opts,
 				   struct branch_info *old,
 				   struct branch_info *new)
@@ -556,6 +571,8 @@ static void update_refs_for_switch(struct checkout_opts *opts,
 				detach_advice(old->path, new->name);
 			describe_detached_head(_("HEAD is now at"), new->commit);
 		}
+		if (opts->record_checkouts && old->name)
+			record_checkout(old->name, NULL);
 	} else if (new->path) {	/* Switch branches. */
 		create_symref("HEAD", new->path, msg.buf);
 		if (!opts->quiet) {
@@ -580,6 +597,11 @@ static void update_refs_for_switch(struct checkout_opts *opts,
 			if (!file_exists(ref_file) && file_exists(log_file))
 				remove_path(log_file);
 		}
+		if (opts->record_checkouts) {
+			if (old->name)
+				record_checkout(old->name, NULL);
+			record_checkout(new->name, get_git_work_tree());
+		}
 	}
 	remove_branch_state();
 	strbuf_release(&msg);
@@ -709,6 +731,23 @@ static void orphaned_commit_warning(struct commit *commit)
 	for_each_ref(clear_commit_marks_from_one_ref, NULL);
 }
 
+static void check_if_checked_out(struct checkout_opts *opts, const char *name)
+{
+	struct branch *branch;
+	if (!opts->record_checkouts)
+		return;
+	branch = branch_get(name);
+	if (branch->work_tree && strlen(branch->work_tree) &&
+	    strcmp(branch->work_tree, get_git_work_tree())) {
+		if (opts->force)
+			warning(_("branch '%s' is currently checked out"
+				  " in '%s'"), name, branch->work_tree);
+		else
+			die(_("branch '%s' is currently checked out"
+			      " in '%s'"), name, branch->work_tree);
+	}
+}
+
 static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
 {
 	int ret = 0;
@@ -732,6 +771,8 @@ static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
 		if (!new->commit)
 			die(_("You are on a branch yet to be born"));
 		parse_commit(new->commit);
+	} else if (opts->record_checkouts) {
+		check_if_checked_out(opts, new->name);
 	}
 
 	ret = merge_working_tree(opts, &old, new);
@@ -756,6 +797,10 @@ static int git_checkout_config(const char *var, const char *value, void *cb)
 		return 0;
 	}
 
+	if (!strcmp(var, "core.recordcheckouts")) {
+		struct checkout_opts *opts = cb;
+		opts->record_checkouts = git_config_bool(var, value);
+	}
 	if (!prefixcmp(var, "submodule."))
 		return parse_submodule_config_option(var, value);
 
diff --git a/remote.c b/remote.c
index b8ecfa5d95..2bc063dae8 100644
--- a/remote.c
+++ b/remote.c
@@ -364,6 +364,10 @@ static int handle_config(const char *key, const char *value, void *cb)
 			if (!value)
 				return config_error_nonbool(key);
 			add_merge(branch, xstrdup(value));
+		} else if (!strcmp(subkey, ".checkout")) {
+			if (!value)
+				return config_error_nonbool(key);
+			branch->work_tree = xstrdup(value);
 		}
 		return 0;
 	}
diff --git a/remote.h b/remote.h
index 9a30a9dba6..4103ec7e31 100644
--- a/remote.h
+++ b/remote.h
@@ -126,6 +126,7 @@ int remote_find_tracking(struct remote *remote, struct refspec *refspec);
 struct branch {
 	const char *name;
 	const char *refname;
+	const char *work_tree;
 
 	const char *remote_name;
 	struct remote *remote;
-- 
1.7.7.4.g39e02c

^ permalink raw reply related

* [BUG] git stash -k show the help message for diff-index
From: Matthieu Moy @ 2011-10-05 15:13 UTC (permalink / raw)
  To: git

Everything is in the title. No time to bisect/fix this now, but:

$ git status
# On branch master
nothing to commit (working directory clean)
$ git stash -k
usage: git diff-index [-m] [--cached] [<common diff options>] <tree-ish> [<path>...]
common diff options:
  -z            output diff-raw with lines terminated with NUL.
  -p            output patch format.
  -u            synonym for -p.
  --patch-with-raw
                output both a patch and the diff-raw format.
  --stat        show diffstat instead of patch.
  --numstat     show numeric diffstat instead of patch.
  --patch-with-stat
                output a patch and prepend its diffstat.
  --name-only   show only names of changed files.
  --name-status show names and status of changed files.
  --full-index  show full object name on index lines.
  --abbrev=<n>  abbreviate object names in diff-tree header and diff-raw.
  -R            swap input file pairs.
  -B            detect complete rewrites.
  -M            detect renames.
  -C            detect copies.
  --find-copies-harder
                try unchanged files as candidate for copy detection.
  -l<n>         limit rename attempts up to <n> paths.
  -O<file>      reorder diffs according to the <file>.
  -S<string>    find filepair whose only one side contains the string.
  --pickaxe-all
                show all files diff when -S is used and hit is found.
  -a  --text    treat all files as text.

usage: git diff-index [-m] [--cached] [<common diff options>] <tree-ish> [<path>...]
common diff options:
  -z            output diff-raw with lines terminated with NUL.
  -p            output patch format.
  -u            synonym for -p.
  --patch-with-raw
                output both a patch and the diff-raw format.
  --stat        show diffstat instead of patch.
  --numstat     show numeric diffstat instead of patch.
  --patch-with-stat
                output a patch and prepend its diffstat.
  --name-only   show only names of changed files.
  --name-status show names and status of changed files.
  --full-index  show full object name on index lines.
  --abbrev=<n>  abbreviate object names in diff-tree header and diff-raw.
  -R            swap input file pairs.
  -B            detect complete rewrites.
  -M            detect renames.
  -C            detect copies.
  --find-copies-harder
                try unchanged files as candidate for copy detection.
  -l<n>         limit rename attempts up to <n> paths.
  -O<file>      reorder diffs according to the <file>.
  -S<string>    find filepair whose only one side contains the string.
  --pickaxe-all
                show all files diff when -S is used and hit is found.
  -a  --text    treat all files as text.

Saved working directory and index state WIP on master: 977c790 foo
HEAD is now at 977c790 foo


-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply

* git-cherry-pick and git-commit --amend in version 1.7.6.4
From: Nicolas Dichtel @ 2011-10-05 14:52 UTC (permalink / raw)
  To: git

Hi,

still with version 1.7.6.4, when I do a cherry-pick, that succeeded, I cannot do 
a commit --amend after:

# git cherry-pick 3f78d1f210ff89af77f042ab7f4a8fee39feb1c9
[dev 1a04a23] drivers/net/usb/asix.c: Fix unaligned accesses
  1 files changed, 33 insertions(+), 1 deletions(-)
# echo $?
0
# git commit --amend
fatal: You are in the middle of a cherry-pick -- cannot amend.
#

The same operations (with the same patch), with version 1.7.3.4 is ok.


Regards,
Nicolas

^ permalink raw reply

* git-cherry-pick and author field in version 1.7.6.4
From: Nicolas Dichtel @ 2011-10-05 14:51 UTC (permalink / raw)
  To: git

Hi all,

in the last stable version (1.7.6.4), when I perform a git-cherry-pick, the 
initial author of the patch is erased whith my name (it was not the case in 
version 1.7.3.4 and prior). Is this behavior intended ? Is there an option to 
keep the initial author of the patch?


Regards,
Nicolas

^ permalink raw reply

* Re: Git attributes ignored for root directory
From: Gioele Barabucci @ 2011-10-05 14:47 UTC (permalink / raw)
  To: Michael Haggerty; +Cc: git
In-Reply-To: <4E8C481A.1070808@alum.mit.edu>

On 05/10/2011 14:05, Michael Haggerty wrote:
> On 10/04/2011 08:52 PM, Gioele Barabucci wrote:
>> With the newer v1.7.7 I get this, instead:
>>
>>      .: show_in_prompt: unspecified
>>
>> I see in the release notes of 1.7.7-rc1 that `check-attr` has been
>> changed to allow relative paths to be specified. Maybe this error is
>> related to that change.
>
> Indeed, your use case is broken by
>
> f5114a40c0d0276ce6ff215a3dc51eb19da5b420

Wow, debug-by-changelog :)

> In fact the support for gitattributes using patterns involving "." was
> pretty spotty in v1.7.6 too.  For example,

[...]

> It's not to hard to fix your particular use case.  But for a real fix,
> we would need to decide what is the correct behavior in all of the lines
> above marked "?"; specifically, should "." match every subdirectory
> under a given directory, does it match only the directory containing the
> .gitattributes file, or is this construct illegal?

I do not know what the correct behavior should be, but here is my use case.

I use git to version almost all my $HOME dir. In addition to my usual 
files there are also separate project repositories under $HOME. I enjoy 
using a git-enabled prompt in those projects' dirs but not in my $HOME dir.

So I have this code somewhere in my `~/.bashrc`:

     local show_status="$(git check-attr show_in_prompt -- .)"
     local show_pattern='^\.: show_in_prompt: (.*)$'

     # add the following line to .gitattributes
     #
     #     /. show_in_prompt=no
     local show_in_prompt='yes'
     if [[ ${show_status} =~ ${show_pattern} ]]; then
            show_in_prompt="${BASH_REMATCH[1]}"
     fi

     if [ "${show_in_prompt}" == 'no' ]; then
             return
     fi

As you see in my the line of this code, I exploit the fact that "." 
refers to the root git dir, not to the current dir, to simplify the 
code. Otherwise I would had to discover what is the path of the current 
dir relative to its root git dir, something that I'd like to avoid as 
this code runs every time the prompt is shown.

This is just my personal use case. On the other hand, the first time I 
looked at check-attr I found it strange that paths were meant as 
relative to the root git dir ("." in "/foo" = "/") and not expanded from 
the current dir ("." in "/foo" = "/foo").

Bye,

-- 
Gioele Barabucci <gioele@svario.it>

^ permalink raw reply

* Re: git commit -a reports untracked files after a clone
From: Joerg Rosenkranz @ 2011-10-05 14:26 UTC (permalink / raw)
  To: git
In-Reply-To: <20110527181321.GB29119@sigill.intra.peff.net>

> On Fri, May 27, 2011 at 02:00:45PM -0400, Jeff King wrote:
>   1. We load the index, and for each entry, insert it into the index's
>      name_hash. In addition, if ignorecase is turned on, we make an
>      entry in the name_hash for the directory (e.g., "contrib/"), which
>      uses the following code from 5102c61's hash_index_entry_directories:

Sorry for reactivating this old thread.
We are running in this problem too. The behavior is the same in msysgit and on 
Linux. Your patch resolves that problem for us.

Is there any chance to drive this patch forward? 

Thanks,
Joerg

^ permalink raw reply

* Re: [PATCHv3 1/5] enter_repo: do not modify input
From: Thomas Adam @ 2011-10-05 14:02 UTC (permalink / raw)
  To: Phil Hord
  Cc: git@vger.kernel.org, Phil Hord, Junio C Hamano, Erik Faye-Lund,
	Nguyen Thai Ngoc Duy
In-Reply-To: <4E8C6233.8040906@cisco.com>

On 5 October 2011 14:57, Phil Hord <hordp@cisco.com> wrote:
> From: Erik Faye-Lund <kusmabite@gmail.com>
>
> entr_repo(..., 0) currently modifies the input to strip away

enter_repo???

-- Thomas Adam

^ permalink raw reply

* Re: [PATCHv3 1/5] enter_repo: do not modify input
From: Phil Hord @ 2011-10-05 13:57 UTC (permalink / raw)
  To: git@vger.kernel.org, Phil Hord
  Cc: Junio C Hamano, Erik Faye-Lund, Nguyen Thai Ngoc Duy
In-Reply-To: <4E8C5D4A.7060900@cisco.com>

From: Erik Faye-Lund <kusmabite@gmail.com>

entr_repo(..., 0) currently modifies the input to strip away
trailing slashes. This means that we some times need to copy the
input to keep the original.

Change it to unconditionally copy it into the used_path buffer so
we can safely use the input without having to copy it. Also store
a working copy in validated_path up-front before we start
resolving anything.

Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Phil Hord <hordp@cisco.com>

---

Don't know why I keep screwing up this one commit.  Here's another try with Word-Wrap in the Really, Really Off position.

diff --git a/cache.h b/cache.h
index 9994a3c..7eeb8cf 100644
--- a/cache.h
+++ b/cache.h
@@ -734,7 +734,7 @@ int safe_create_leading_directories(char *path);
 int safe_create_leading_directories_const(const char *path);
 int mkdir_in_gitdir(const char *path);
 extern char *expand_user_path(const char *path);
-char *enter_repo(char *path, int strict);
+const char *enter_repo(const char *path, int strict);
 static inline int is_absolute_path(const char *path)
 {
 	return is_dir_sep(path[0]) || has_dos_drive_prefix(path);
diff --git a/daemon.c b/daemon.c
index 4c8346d..9253192 100644
--- a/daemon.c
+++ b/daemon.c
@@ -108,11 +108,11 @@ static void NORETURN daemon_die(const char *err, va_list params)
 	exit(1);
 }
 
-static char *path_ok(char *directory)
+static const char *path_ok(char *directory)
 {
 	static char rpath[PATH_MAX];
 	static char interp_path[PATH_MAX];
-	char *path;
+	const char *path;
 	char *dir;
 
 	dir = directory;
diff --git a/path.c b/path.c
index 6f3f5d5..f3d96aa 100644
--- a/path.c
+++ b/path.c
@@ -283,7 +283,7 @@ return_null:
  * links.  User relative paths are also returned as they are given,
  * except DWIM suffixing.
  */
-char *enter_repo(char *path, int strict)
+const char *enter_repo(const char *path, int strict)
 {
 	static char used_path[PATH_MAX];
 	static char validated_path[PATH_MAX];
@@ -297,14 +297,17 @@ char *enter_repo(char *path, int strict)
 		};
 		int len = strlen(path);
 		int i;
-		while ((1 < len) && (path[len-1] == '/')) {
-			path[len-1] = 0;
+		while ((1 < len) && (path[len-1] == '/'))
 			len--;
-		}
+
 		if (PATH_MAX <= len)
 			return NULL;
-		if (path[0] == '~') {
-			char *newpath = expand_user_path(path);
+		strncpy(used_path, path, len);
+		used_path[len] = 0;
+		strcpy(validated_path, used_path);
+
+		if (used_path[0] == '~') {
+			char *newpath = expand_user_path(used_path);
 			if (!newpath || (PATH_MAX - 10 < strlen(newpath))) {
 				free(newpath);
 				return NULL;
@@ -316,24 +319,18 @@ char *enter_repo(char *path, int strict)
 			 * anyway.
 			 */
 			strcpy(used_path, newpath); free(newpath);
-			strcpy(validated_path, path);
-			path = used_path;
 		}
 		else if (PATH_MAX - 10 < len)
 			return NULL;
-		else {
-			path = strcpy(used_path, path);
-			strcpy(validated_path, path);
-		}
-		len = strlen(path);
+		len = strlen(used_path);
 		for (i = 0; suffix[i]; i++) {
-			strcpy(path + len, suffix[i]);
-			if (!access(path, F_OK)) {
+			strcpy(used_path + len, suffix[i]);
+			if (!access(used_path, F_OK)) {
 				strcat(validated_path, suffix[i]);
 				break;
 			}
 		}
-		if (!suffix[i] || chdir(path))
+		if (!suffix[i] || chdir(used_path))
 			return NULL;
 		path = validated_path;
 	}
-- 
1.7.7.505.ga09f6

^ permalink raw reply related

* Re: [PATCH 0/9] i18n: add PO files to po/
From: Peter Krefting @ 2011-10-05 13:44 UTC (permalink / raw)
  To: Git Mailing List
  Cc: Ævar Arnfjörð Bjarmason, Jonathan Nieder,
	Junio C Hamano, Ramkumar Ramachandra, Marcin Cieślak,
	Sam Reed, Jan Engelhardt, Jan Krüger,
	Nguyễn Thái Ngọc
In-Reply-To: <CACBZZX5uz5cdoWebYOY-Omu0drnQasJB-12DMZyZ_NX17jzhmg@mail.gmail.com>

Ævar Arnfjörð Bjarmason:

> While we could set up some "i18n maintainer" infrastructure why not just 
> have people submit patches to the list like we do for every other file in 
> git?

As mentioned, that infrastructure already exists in Translation Project - 
http://translationproject.org/html/welcome.html

Submit the POT file at "string freeze" before a stable release, and pull the 
translated PO files when the release happens. TP handles the rest.

-- 
\\// Peter - http://www.softwolves.pp.se/

^ permalink raw reply

* [PATCHv3 1/5] enter_repo: do not modify input
From: Phil Hord @ 2011-10-05 13:36 UTC (permalink / raw)
  To: git@vger.kernel.org, Phil Hord
  Cc: Junio C Hamano, Erik Faye-Lund, Nguyen Thai Ngoc Duy

From: Erik Faye-Lund <kusmabite@gmail.com>

entr_repo(..., 0) currently modifies the input to strip away
trailing slashes. This means that we some times need to copy the
input to keep the original.

Change it to unconditionally copy it into the used_path buffer so
we can safely use the input without having to copy it. Also store
a working copy in validated_path up-front before we start
resolving anything.

Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Phil Hord <hordp@cisco.com>

diff --git a/cache.h b/cache.h
index 9994a3c..7eeb8cf 100644
--- a/cache.h
+++ b/cache.h
@@ -734,7 +734,7 @@ int safe_create_leading_directories(char *path);
 int safe_create_leading_directories_const(const char *path);
 int mkdir_in_gitdir(const char *path);
 extern char *expand_user_path(const char *path);
-char *enter_repo(char *path, int strict);
+const char *enter_repo(const char *path, int strict);
 static inline int is_absolute_path(const char *path)
 {
     return is_dir_sep(path[0]) || has_dos_drive_prefix(path);
diff --git a/daemon.c b/daemon.c
index 4c8346d..9253192 100644
--- a/daemon.c
+++ b/daemon.c
@@ -108,11 +108,11 @@ static void NORETURN daemon_die(const char *err,
va_list params)
     exit(1);
 }
 -static char *path_ok(char *directory)
+static const char *path_ok(char *directory)
 {
     static char rpath[PATH_MAX];
     static char interp_path[PATH_MAX];
-    char *path;
+    const char *path;
     char *dir;
      dir = directory;
diff --git a/path.c b/path.c
index 6f3f5d5..f3d96aa 100644
--- a/path.c
+++ b/path.c
@@ -283,7 +283,7 @@ return_null:
  * links.  User relative paths are also returned as they are given,
  * except DWIM suffixing.
  */
-char *enter_repo(char *path, int strict)
+const char *enter_repo(const char *path, int strict)
 {
     static char used_path[PATH_MAX];
     static char validated_path[PATH_MAX];
@@ -297,14 +297,17 @@ char *enter_repo(char *path, int strict)
         };
         int len = strlen(path);
         int i;
-        while ((1 < len) && (path[len-1] == '/')) {
-            path[len-1] = 0;
+        while ((1 < len) && (path[len-1] == '/'))
             len--;
-        }
+
         if (PATH_MAX <= len)
             return NULL;
-        if (path[0] == '~') {
-            char *newpath = expand_user_path(path);
+        strncpy(used_path, path, len);
+        used_path[len] = 0;
+        strcpy(validated_path, used_path);
+
+        if (used_path[0] == '~') {
+            char *newpath = expand_user_path(used_path);
             if (!newpath || (PATH_MAX - 10 < strlen(newpath))) {
                 free(newpath);
                 return NULL;
@@ -316,24 +319,18 @@ char *enter_repo(char *path, int strict)
              * anyway.
              */
             strcpy(used_path, newpath); free(newpath);
-            strcpy(validated_path, path);
-            path = used_path;
         }
         else if (PATH_MAX - 10 < len)
             return NULL;
-        else {
-            path = strcpy(used_path, path);
-            strcpy(validated_path, path);
-        }
-        len = strlen(path);
+        len = strlen(used_path);
         for (i = 0; suffix[i]; i++) {
-            strcpy(path + len, suffix[i]);
-            if (!access(path, F_OK)) {
+            strcpy(used_path + len, suffix[i]);
+            if (!access(used_path, F_OK)) {
                 strcat(validated_path, suffix[i]);
                 break;
             }
         }
-        if (!suffix[i] || chdir(path))
+        if (!suffix[i] || chdir(used_path))
             return NULL;
         path = validated_path;
     }
-- 
1.7.7.505.ga09f6

^ permalink raw reply related

* [PATCHv3 5/5] Add test showing git-fetch groks gitfiles
From: Phil Hord @ 2011-10-05 13:35 UTC (permalink / raw)
  To: git@vger.kernel.org, Phil Hord
  Cc: Junio C Hamano, Erik Faye-Lund, Nguyen Thai Ngoc Duy

Add a test for two subtly different cases: 'git fetch path/.git'
and 'git fetch path' to confirm that transport recognizes both
paths as git repositories when using the gitfile mechanism.

Signed-off-by: Phil Hord <hordp@cisco.com>

diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index e810314..87ee016 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -206,6 +206,20 @@ test_expect_success 'clone from .git file' '
 	git clone dst/.git dst2
 '
 
+test_expect_success 'fetch from .git gitfile' '
+	(
+		cd dst2 &&
+		git fetch ../dst/.git
+	)
+'
+
+test_expect_success 'fetch from gitfile parent' '
+	(
+		cd dst2 &&
+		git fetch ../dst
+	)
+'
+
 test_expect_success 'clone separate gitdir where target already exists' '
 	rm -rf dst &&
 	test_must_fail git clone --separate-git-dir realgitdir src dst
-- 
1.7.7.505.ga09f6

^ permalink raw reply related

* [PATCHv3 4/5] Teach transport about the gitfile mechanism
From: Phil Hord @ 2011-10-05 13:35 UTC (permalink / raw)
  To: git@vger.kernel.org, Phil Hord
  Cc: Junio C Hamano, Erik Faye-Lund, Nguyen Thai Ngoc Duy

The transport_get() function assumes that a regular file is a
bundle rather than a local git directory. Check if the file is
actually a gitfile.  If so, do not try to process it as a
bundle, but treat it as a local repository instead.

Signed-off-by: Phil Hord <hordp@cisco.com>

diff --git a/transport.c b/transport.c
index cd49a25..2ff2d68 100644
--- a/transport.c
+++ b/transport.c
@@ -915,7 +915,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
 		ret->fetch = fetch_objs_via_rsync;
 		ret->push = rsync_transport_push;
 		ret->smart_options = NULL;
-	} else if (is_local(url) && is_file(url)) {
+	} else if (is_local(url) && is_file(url) && !is_gitfile(url)) {
 		struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
 		ret->data = data;
 		ret->get_refs_list = get_refs_from_bundle;
-- 
1.7.7.505.ga09f6

^ permalink raw reply related

* [PATCHv3 3/5] Add a common is_gitfile function
From: Phil Hord @ 2011-10-05 13:33 UTC (permalink / raw)
  To: git@vger.kernel.org, Phil Hord
  Cc: Junio C Hamano, Erik Faye-Lund, Nguyen Thai Ngoc Duy

There are at least two locations in the code that check for
gitfiles.  Each one is slightly different for pretty good
reasons.  Work towards a common API by abstracting the
"is this a gitfile" question into a single function.

Signed-off-by: Phil Hord <hordp@cisco.com>

diff --git a/builtin/clone.c b/builtin/clone.c
index 488f48e..5110399 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -120,13 +120,7 @@ static char *get_repo_path(const char *repo, int *is_bundle)
 			return xstrdup(absolute_path(path));
 		} else if (S_ISREG(st.st_mode) && st.st_size > 8) {
 			/* Is it a "gitfile"? */
-			char signature[8];
-			int len, fd = open(path, O_RDONLY);
-			if (fd < 0)
-				continue;
-			len = read_in_full(fd, signature, 8);
-			close(fd);
-			if (len != 8 || strncmp(signature, "gitdir: ", 8))
+			if (!is_gitfile(path))
 				continue;
 			path = read_gitfile(path);
 			if (path) {
diff --git a/cache.h b/cache.h
index 7eeb8cf..61e1b0f 100644
--- a/cache.h
+++ b/cache.h
@@ -441,6 +441,7 @@ extern const char *get_git_work_tree(void);
 extern const char *read_gitfile(const char *path);
 extern const char *resolve_gitdir(const char *suspect);
 extern void set_git_work_tree(const char *tree);
+extern int is_gitfile(const char *path);
 
 #define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
 
diff --git a/setup.c b/setup.c
index 61c22e6..a3d5a41 100644
--- a/setup.c
+++ b/setup.c
@@ -358,7 +358,7 @@ const char *read_gitfile(const char *path)
 
 	if (stat(path, &st))
 		return NULL;
-	if (!S_ISREG(st.st_mode))
+	if (!is_gitfile(path))
 		return NULL;
 	fd = open(path, O_RDONLY);
 	if (fd < 0)
@@ -368,9 +368,6 @@ const char *read_gitfile(const char *path)
 	close(fd);
 	if (len != st.st_size)
 		die("Error reading %s", path);
-	buf[len] = '\0';
-	if (prefixcmp(buf, "gitdir: "))
-		die("Invalid gitfile format: %s", path);
 	while (buf[len - 1] == '\n' || buf[len - 1] == '\r')
 		len--;
 	if (len < 9)
@@ -397,6 +394,32 @@ const char *read_gitfile(const char *path)
 	return path;
 }
 
+/*
+ * See if the referenced file looks like a 'gitfile'.
+ * Does not try to determine if the referenced gitdir is actually valid.
+ */
+int is_gitfile(const char *path)
+{
+	struct stat st;
+	char buf[9];
+	int fd, len;
+	if (stat(path, &st))
+		return 0;
+	if (!S_ISREG(st.st_mode))
+		return 0;
+	if (st.st_size < 10 || st.st_size > PATH_MAX)
+		return 0;
+
+	fd = open(path, O_RDONLY);
+	if (fd < 0)
+		return 0;
+	len = read_in_full(fd, buf, sizeof(buf));
+	close(fd);
+	if (len != sizeof(buf))
+		return 0;
+	return !prefixcmp(buf, "gitdir: ");
+}
+
 static const char *setup_explicit_git_dir(const char *gitdirenv,
 					  char *cwd, int len,
 					  int *nongit_ok)
-- 
1.7.7.505.ga09f6

^ permalink raw reply related

* [PATCHv3 2/5] Learn to handle gitfiles in enter_repo
From: Phil Hord @ 2011-10-05 13:31 UTC (permalink / raw)
  To: git@vger.kernel.org, Phil Hord
  Cc: Junio C Hamano, Erik Faye-Lund, Nguyen Thai Ngoc Duy

The enter_repo() function is used to navigate into a .git
directory.  It knows how to find standard alternatives (DWIM) but
it doesn't handle gitfiles created by git init --separate-git-dir.
This means that git-fetch and others do not work with repositories
using the separate-git-dir mechanism.

Teach enter_repo() to deal with the gitfile mechanism by resolving
the path to the redirected path and continuing tests on that path
instead of the found file.

Signed-off-by: Phil Hord <hordp@cisco.com>

---

Not sure how to resolve this for the 'strict' case.

The actual path followed may be different than the version spelled
out on the input path because of resolved symlinks and whatnot.
This function normally returns the unmolested "original" path
that was validated.  In case of a gitfile, I think that means
we should return the url resolved from the gitfile contents.

But should we?

The returned path is only used in git-daemon where it gets
further checks for path restrictions.

A. If we return the gitfile-resolved path, this may cause these
   path restrictions to fail since the path gets canonicalized
   when the gitfile is created by git.

B. If we do not return the gitfile-resolved path, this can create
   a security-hole by allowing remote users to access files they
   would otherwise have been restricted from.  In effect it creates
   an alternate symlink mechanism of which the administator might
   not be aware.


diff --git a/path.c b/path.c
index f3d96aa..46ba326 100644
--- a/path.c
+++ b/path.c
@@ -295,6 +295,7 @@ const char *enter_repo(const char *path, int strict)
 		static const char *suffix[] = {
 			".git/.git", "/.git", ".git", "", NULL,
 		};
+		const char *gitfile;
 		int len = strlen(path);
 		int i;
 		while ((1 < len) && (path[len-1] == '/'))
@@ -330,7 +331,12 @@ const char *enter_repo(const char *path, int strict)
 				break;
 			}
 		}
-		if (!suffix[i] || chdir(used_path))
+		if (!suffix[i])
+			return NULL;
+		gitfile = read_gitfile(used_path) ;
+		if (gitfile)
+			strcpy(used_path, gitfile);
+		if (chdir(used_path))
 			return NULL;
 		path = validated_path;
 	}
-- 
1.7.7.505.ga09f6

^ permalink raw reply related

* Re: [RFC/PATCH] Add multiple workdir support to branch/checkout
From: Jay Soffian @ 2011-10-05 13:11 UTC (permalink / raw)
  To: Nguyen Thai Ngoc Duy; +Cc: git
In-Reply-To: <CACsJy8AqYq+YF+rvUp=BBeFUAtUz783iF2jbUp3fO58yLp9ptQ@mail.gmail.com>

On Wed, Oct 5, 2011 at 12:02 AM, Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:
> Could you please consider a more generic approach? What I have in mind
> is a mechanism to "lock" a branch, so that only commands that have the
> key can update it.
>
> So instead of branch.<name>.checkout, I would have something like
> branch.<name>.locked = <key>, where <key> is just a string. Only
> commands that provide the matching <key> are allowed to update the
> branch. In checkout case, <key> could be "checkout: worktree".

In this case, each workdir needs its own key, so I'd have to record
the key somewhere, unless you meant using a key of "checkout:
</path/to/workdir>".

> This approach addresses more cases than just multiple workdir. We
> could relax restrictions on pushing to a non-bare repository: we only
> disallow pushing to locked branches.

Isn't that another case where you only care if the branch is checked
out and where? So using "branch.<name>.checkout = </path/to/workdir>"
should be fine there too.

> We can also use this to prevent
> users from checking out another branch (by locking HEAD) while in the
> middle of interactive rebase/bisect/...

I dunno, that seems like a really different use case.

j.

^ permalink raw reply

* Re: Git attributes ignored for root directory
From: Michael Haggerty @ 2011-10-05 12:05 UTC (permalink / raw)
  To: Gioele Barabucci; +Cc: git
In-Reply-To: <4E8B55FB.1050203@svario.it>

On 10/04/2011 08:52 PM, Gioele Barabucci wrote:
> I just updated to git v1.7.7 using the Ubuntu Lucid PPA and I found that
> `git check-attr` is broken now.
> 
> I have this attribute in my `$HOME/.gitattributes` file:
> 
>     /. show_in_prompt=no
> 
> Now, if I go to `$HOME` and run
> 
>     git check-attr show_in_prompt -- .
> 
> With git v1.7.6 this is the answer I got:
> 
>     .: show_in_prompt: no
> 
> With the newer v1.7.7 I get this, instead:
> 
>     .: show_in_prompt: unspecified
> 
> Also, if I use the `--all` option, `check-attr` does not show any
> attribute at all.
> 
> I see in the release notes of 1.7.7-rc1 that `check-attr` has been
> changed to allow relative paths to be specified. Maybe this error is
> related to that change.

Indeed, your use case is broken by

f5114a40c0d0276ce6ff215a3dc51eb19da5b420

In fact the support for gitattributes using patterns involving "." was
pretty spotty in v1.7.6 too.  For example,

-------------------------------------------
echo ". foo" >./.gitattributes
git check-attr foo -- . ./ ./. x x/ ./x x/.
.: foo: set
./: foo: unspecified      WRONG
./.: foo: set
x: foo: unspecified       WRONG?
x/: foo: unspecified      WRONG?
./x: foo: unspecified     WRONG?
x/.: foo: set             RIGHT?

-------------------------------------------
echo "/. foo" >./.gitattributes
git check-attr foo -- . ./ ./. x x/ ./x x/.
.: foo: set
./: foo: unspecified      WRONG
./.: foo: set
x: foo: unspecified
x/: foo: unspecified
./x: foo: unspecified
x/.: foo: unspecified

-------------------------------------------
echo ". foo" >x/.gitattributes
git check-attr foo -- . ./ ./. x x/ ./x x/.
.: foo: unspecified
./: foo: unspecified
./.: foo: unspecified
x: foo: unspecified       WRONG?
x/: foo: unspecified      WRONG?
./x: foo: unspecified     WRONG?
x/.: foo: set             RIGHT?

-------------------------------------------
echo "/. foo" >x/.gitattributes
git check-attr foo -- . ./ ./. x x/ ./x x/.
.: foo: unspecified
./: foo: unspecified
./.: foo: unspecified
x: foo: unspecified       WRONG
x/: foo: unspecified      WRONG
./x: foo: unspecified     WRONG
x/.: foo: set

-------------------------------------------

I conclude that this functionality was never really defined correctly,
and you were pretty lucky that your case worked at all :-)

It's not to hard to fix your particular use case.  But for a real fix,
we would need to decide what is the correct behavior in all of the lines
above marked "?"; specifically, should "." match every subdirectory
under a given directory, does it match only the directory containing the
.gitattributes file, or is this construct illegal?

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

^ permalink raw reply

* [PATCH] git-svn: On MSYS, escape and quote SVN_SSH also if set by the user
From: Sebastian Schuberth @ 2011-10-05  9:14 UTC (permalink / raw)
  To: git; +Cc: msysgit

While GIT_SSH does not require any escaping / quoting (e.g. for paths
containing spaces), SVN_SSH requires it due to its use in a Perl script.

Previously, SVN_SSH has only been escaped and quoted automatically if it
was unset and thus derived from GIT_SSH. For user convenience, do the
escaping and quoting also for a SVN_SSH set by the user. This way, the
user is able to use the same unescaped and unquoted syntax for GIT_SSH
and SVN_SSH.

Signed-off-by: Sebastian Schuberth <sschuberth@gmail.com>
---
 git-svn.perl |   15 +++++++--------
 1 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/git-svn.perl b/git-svn.perl
index 89f83fd..c3b4b58 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -22,14 +22,13 @@ $Git::SVN::default_ref_id = $ENV{GIT_SVN_ID} || 'git-svn';
 $Git::SVN::Ra::_log_window_size = 100;
 $Git::SVN::_minimize_url = 'unset';
 
-if (! exists $ENV{SVN_SSH}) {
-	if (exists $ENV{GIT_SSH}) {
-		$ENV{SVN_SSH} = $ENV{GIT_SSH};
-		if ($^O eq 'msys') {
-			$ENV{SVN_SSH} =~ s/\\/\\\\/g;
-			$ENV{SVN_SSH} =~ s/(.*)/"$1"/;
-		}
-	}
+if (! exists $ENV{SVN_SSH} && exists $ENV{GIT_SSH}) {
+	$ENV{SVN_SSH} = $ENV{GIT_SSH};
+}
+
+if (exists $ENV{SVN_SSH} && $^O eq 'msys') {
+	$ENV{SVN_SSH} =~ s/\\/\\\\/g;
+	$ENV{SVN_SSH} =~ s/(.*)/"$1"/;
 }
 
 $Git::SVN::Log::TZ = $ENV{TZ};
-- 
1.7.6.GIT

^ permalink raw reply related

* Re: pack-object poor performance (with large number of objects?)
From: Piotr Krukowiecki @ 2011-10-05  8:48 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Shawn Pearce, Git Mailing List, Ingo Molnar
In-Reply-To: <20111004180829.GB31671@sigill.intra.peff.net>

On Tue, Oct 4, 2011 at 8:08 PM, Jeff King <peff@peff.net> wrote:
> On Tue, Oct 04, 2011 at 03:21:24PM +0200, Piotr Krukowiecki wrote:
>
>> I have 4GB ram + 4GB swap. Is it possible the RAM is the problem if I
>> always have free RAM left and my swap is almost not used?
>> For example at the moment repack finished counting objects ("Counting
>> objects: 1742200, done."):
>>
>> $ free -m
>>              total       used       free     shared    buffers     cached
>> Mem:          3960       3814        146          0        441        215
>> -/+ buffers/cache:       3157        803
>> Swap:         6143        694       5449
>
[...]
> I have no idea if this will actually go faster for you. But it might be
> worth trying, instead of just redoing the svn import with auto-gc turned
> on.

I've left it to run over night and it finished (took almost 12 hours),
so hopefully I'm not going to run into this problem anymore.

$ time git repack -a -d -f
Counting objects: 1742200, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (1291909/1291909), done.
Writing objects: 100% (1742200/1742200), done.
Total 1742200 (delta 1094325), reused 39192 (delta 0)
Removing duplicate objects: 100% (256/256), done.

real	704m3.477s
user	65m35.960s
sys	9m50.880s

$ du -sh .git/objects/pack
3.9G	.git/objects/pack

$ git count-objects -v
count: 0
size: 0
in-pack: 1742200
packs: 1
size-pack: 4078245
prune-packable: 0
garbage: 0


-- 
Piotr Krukowiecki

^ permalink raw reply

* Re: [PATCH WIP 0/3] git log --exclude
From: Nguyen Thai Ngoc Duy @ 2011-10-05  8:28 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: git, Jonathan Nieder
In-Reply-To: <vpqd3ebn9nc.fsf@bauges.imag.fr>

2011/10/5 Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>:
> Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
>
>> This series adds --exclude that uses .gitignore mechanism remove
>> commits whose changes that are _entirely_ excluded.
>
> I'd see this --exclude as the opposite of specifying files, i.e. in a
> repository containing directories A, B and C,
>
> git log --exclude=B
>
> would be the same as
>
> git log A C

I think I emphasized it too much. "git log --exclude=B/ A B C" should
be equivalent to "git log A C". If changes touch A or C, then no
matter they touch B, the commit will always be in. If changes only
touch B, neither A nor B, then the commit is removed, exactly the same
case with "git log A C".

>> Because it uses .gitignore mechanism, beware that these patterns do
>> not behave exactly like pathspecs

if you specify --exclude=B, then A/.../B, C/.../B are all removed. A
subtle difference between pathspec and .gitignore.

> and because "git log --stat A C" (or --patch) will show the diff only
> for A and C for commits touching all directories.

I'll take care of --patch and friends later. They both (--patch and
commit pruning) use the same diff mechanism, if we get it right for
for commit pruning, --patch will come nicely.
-- 
Duy

^ permalink raw reply

* [PATCH] Report errors related to .git access during repository discovery
From: Nguyễn Thái Ngọc Duy @ 2011-10-05  8:17 UTC (permalink / raw)
  To: Johannes Sixt
  Cc: git, Federico Lucifredi, Nguyễn Thái Ngọc Duy
In-Reply-To: <4E8BF519.8090509@viscovery.net>

If $GIT_DIR is not given, we go up step by step and look for potential
repository directory, may see .git directory but for some reasons we
decide to skip and move on.

It's probably better to report along the line, so users can stop
wondering "hey, but I have .git directory _there_".

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 On Wed, Oct 5, 2011 at 5:11 PM, Johannes Sixt <j.sixt@viscovery.net> wrote:
 > Am 10/4/2011 23:24, schrieb Federico Lucifredi:
 >> Hello Git list,
 >>  Found a minor bug in git today - the error message reported is not
 >> correct when trying to access a repo that is not accessible
 >> permission-wise:
 >>
 >>> federico@skyplex:/etc$ git log
 >>> fatal: Not a git repository (or any of the parent directories): .git
 >>
 >> with correct access permissions, everything works as expected.
 >
 > And the correct error message is...?

 That's a correct message. But it'd be even better if we help diagnose
 why. Even when you have proper access to .git dir, git can still
 refuse to accept the directory as a repository, because "HEAD" is
 invalid for example.

 I think a patch like this is an improvement. There may be many
 situations git refuses a directory but I don't cover here. Well, we
 may when users report them

 setup.c |   23 +++++++++++++++++++----
 1 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/setup.c b/setup.c
index 27c1d47..b6028e5 100644
--- a/setup.c
+++ b/setup.c
@@ -269,6 +269,19 @@ const char *pathspec_prefix(const char *prefix, const char **pathspec)
 }
 
 /*
+ * This function is used during .git detection phase. If .git does not
+ * exist, it's OK not to report because that happens a lot if you stay
+ * inside a subdirectory and git checks every level back to topdir.
+ */
+static int access_and_warn(const char *path, int perm)
+{
+	int ret = access(path, perm);
+	if (ret && errno != ENOENT)
+		error("%s: %s", absolute_path(path), strerror(errno));
+	return ret;
+}
+
+/*
  * Test if it looks like we're at a git directory.
  * We want to see:
  *
@@ -288,22 +301,24 @@ static int is_git_directory(const char *suspect)
 		die("Too long path: %.*s", 60, suspect);
 	strcpy(path, suspect);
 	if (getenv(DB_ENVIRONMENT)) {
-		if (access(getenv(DB_ENVIRONMENT), X_OK))
+		if (access_and_warn(getenv(DB_ENVIRONMENT), X_OK))
 			return 0;
 	}
 	else {
 		strcpy(path + len, "/objects");
-		if (access(path, X_OK))
+		if (access_and_warn(path, X_OK))
 			return 0;
 	}
 
 	strcpy(path + len, "/refs");
-	if (access(path, X_OK))
+	if (access_and_warn(path, X_OK))
 		return 0;
 
 	strcpy(path + len, "/HEAD");
-	if (validate_headref(path))
+	if (validate_headref(path)) {
+		error("invalid HEAD at %s", absolute_path(path));
 		return 0;
+	}
 
 	return 1;
 }
-- 
1.7.3.1.256.g2539c.dirty

^ permalink raw reply related

* Re: [PATCH WIP 0/3] git log --exclude
From: Matthieu Moy @ 2011-10-05  8:08 UTC (permalink / raw)
  To: Nguyễn Thái Ngọc Duy; +Cc: git, Jonathan Nieder
In-Reply-To: <1317799088-26626-1-git-send-email-pclouds@gmail.com>

Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:

> This series adds --exclude that uses .gitignore mechanism remove
> commits whose changes that are _entirely_ excluded.

I'd see this --exclude as the opposite of specifying files, i.e. in a
repository containing directories A, B and C,

git log --exclude=B

would be the same as

git log A C

If I understand correctly, it's not the case with your implementation
because

> Because it uses .gitignore mechanism, beware that these patterns do
> not behave exactly like pathspecs

and because "git log --stat A C" (or --patch) will show the diff only
for A and C for commits touching all directories.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

^ permalink raw reply

* Re: Git Bug report
From: Fredrik Gustafsson @ 2011-10-05  7:22 UTC (permalink / raw)
  To: Federico Lucifredi; +Cc: git
In-Reply-To: <1317763443.17036.15.camel@skyplex>

On Tue, Oct 04, 2011 at 05:24:03PM -0400, Federico Lucifredi wrote:
>  Found a minor bug in git today - the error message reported is not
> correct when trying to access a repo that is not accessible
> permission-wise:
> 
> > federico@skyplex:/etc$ git log
> > fatal: Not a git repository (or any of the parent directories): .git
> 
> with correct access permissions, everything works as expected.

So if:
.git/ is a directory with not enought permissions.
../.git/ is a directory with enought permissions.

git would today use ../.git. You suggest that git instead would die
because a .git/ exists? (I'm not saying this is wrong or right).

-- 
Med vänliga hälsningar
Fredrik Gustafsson

E-post: iveqy@iveqy.com
Tel. nr.: 0733 60 82 74

^ permalink raw reply


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