Re: ZSH segmentation fault while completing git mv dir/

2013-03-12 Thread Matthieu Moy
Jeff Epler jep...@unpythonic.net writes:

 If it's dependent on eval `dircolors`, it suggests it might be
 dependent on the size of the environment.  Maybe try with FOO=`perl -e
 'print xx1000'` for various values of 1000...

It's not this, but I could reduce the problem to a slightly simpler
.zshrc:

-
fpath=(${HOME}/usr/etc/zsh ${fpath})

autoload -Uz compinit
compinit

zstyle ':completion:*' list-colors 'rs=0' 'di=01;34' 'ln=01;36' \
 'mh=00' 'pi=40;33' 'so=01;35' 'do=01;35' 'bd=40;33;01' 'cd=40;33;01' \
 'or=40;31;01' 'su=37;41' 'sg=30;43' 'ca=30;41' 'tw=30;42' 'ow=34;42' \
 'st=37;44' 'ex=01;32' '*.tar=01;31' '*.tgz=01;31' '*.arj=01;31'  \
 '*.taz=01;31' '*.lzh=01;31' '*.lzma=01;31' '*.tlz=01;31' '*.txz=01;31' \
 '*.zip=01;31' '*.z=01;31' '*.Z=01;31' '*.dz=01;31' '*.gz=01;31'  \
 '*.lz=01;31' '*.xz=01;31' '*.bz2=01;31' '*.bz=01;31' '*.tbz=01;31'  \
 '*.tbz2=01;31' '*.tz=01;31' '*.deb=01;31' '*.rpm=01;31' '*.jar=01;31' \
 '*.rar=01;31' '*.ace=01;31' '*.pgm=01;35' '*.ppm=01;35'  \
 '*.tga=01;35' '*.xbm=01;35' '*.zoo=01;31' '*.cpio=01;31' '*.7z=01;31' \
 '*.rz=01;31' '*.jpg=01;35' '*.jpeg=01;35' '*.gif=01;35' \
 '*.bmp=01;35' '*.pbm=01;35'
-

The problem disapears if I remove one of the arguments after list-colors
(I didn't try with each of them, but picking 5 of them randomly and
removing it worked), so it seems to be a matter of number of arguments.

On git-completion.bash's side, it's really strange. If I comment out the
case statement in _git_mv like this, the problem disapears:


_git_mv ()
{
# case $cur in
# --*)
#   __gitcomp --dry-run
#   return
#   ;;
# esac

if [ $(__git_count_arguments mv) -gt 0 ]; then
# We need to show both cached and untracked files (including
# empty directories) since this may not be the last argument.
__git_complete_index_file --cached --others --directory
else
__git_complete_index_file --cached
fi
}

If I add a simple 'echo $cur 2' instead of the case, the problem
reappears. Somehow, the fact that I'm accessing $cur seems to create the
segfault. Actually, the minimalistic _git_mv reproducing the problem is:

_git_mv ()
{
echo $cur
[ $(__git_count_arguments mv) = 1 ]
__git_complete_index_file --cached --others --directory
}

gdb doesn't say much interesting since my ZSH isn't compile with debug:

(gdb) r
Starting program: /usr/bin/zsh 
anie$ cd /tmp/git
anie$ git mv subdir/
Program received signal SIGSEGV, Segmentation fault.
__strlen_sse2 () at ../sysdeps/i386/i686/multiarch/strlen.S:87
87  ../sysdeps/i386/i686/multiarch/strlen.S: No such file or directory.
in ../sysdeps/i386/i686/multiarch/strlen.S
Current language:  auto
The current source language is auto; currently asm.
(gdb) where
#0  __strlen_sse2 () at ../sysdeps/i386/i686/multiarch/strlen.S:87
#1  0x080ae31d in ztrdup ()
#2  0xb7b9d287 in permmatches () from /usr/lib/zsh/4.3.10/zsh/complete.so
#3  0xb7b9a22e in ?? () from /usr/lib/zsh/4.3.10/zsh/complete.so
#4  0x08098f33 in getstrvalue ()
#5  0x08099e9d in ?? ()
#6  0x0809acd7 in getindex ()
#7  0x0809b3d9 in fetchvalue ()
#8  0x080b0f84 in ?? ()
#9  0x080b49a7 in prefork ()
#10 0x08066cb9 in ?? ()
#11 0x08067151 in ?? ()
#12 0x0806cfc0 in execlist ()
#13 0x0808984c in execif ()
#14 0x080670c6 in ?? ()
#15 0x0806cfc0 in execlist ()
#16 0x0806d69a in execode ()
#17 0x0806d785 in runshfunc ()
#18 0xb7b99a7a in ?? () from /usr/lib/zsh/4.3.10/zsh/complete.so
#19 0x0806d724 in runshfunc ()
#20 0x0806db92 in doshfunc ()
#21 0xb7ba3363 in ?? () from /usr/lib/zsh/4.3.10/zsh/complete.so
#22 0xb7ba44dc in do_completion () from /usr/lib/zsh/4.3.10/zsh/complete.so
#23 0xb7bdaf47 in ?? () from /usr/lib/zsh/4.3.10/zsh/zle.so
#24 0xb7bd5b40 in completecall () from /usr/lib/zsh/4.3.10/zsh/zle.so
#25 0xb7bc6f6e in execzlefunc () from /usr/lib/zsh/4.3.10/zsh/zle.so
#26 0xb7bc72a2 in zlecore () from /usr/lib/zsh/4.3.10/zsh/zle.so
#27 0xb7bc78d5 in zleread () from /usr/lib/zsh/4.3.10/zsh/zle.so
#28 0xb7bc96ff in ?? () from /usr/lib/zsh/4.3.10/zsh/zle.so
#29 0x0807d462 in zleentry ()
#30 0x08080a31 in ingetc ()
#31 0x0807b03c in ?? ()
#32 0x08087fb6 in zshlex ()
#33 0x080a3b4a in parse_event ()
#34 0x0807f2f1 in loop ()
#35 0x080800c6 in zsh_main ()
#36 0x08054cbb in main ()

I can't reproduce the problem with the exact same config and a freshly
compiled ZSH (so it's no use reporting the issue to the ZSH developers).

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: rebase: strange failures to apply patc 3-way

2013-03-12 Thread Heiko Voigt
On Mon, Mar 11, 2013 at 09:10:04PM -0400, Jeff King wrote:
 On Mon, Mar 11, 2013 at 09:03:42PM -0400, Andrew Wong wrote:
 
  On 03/11/13 21:01, Jeff King wrote:
   From git help config:
  
 core.trustctime
   If false, the ctime differences between the index and the working
   tree are ignored; useful when the inode change time is regularly
   modified by something outside Git (file system crawlers and some
   backup systems). See git-update- index(1). True by default.
 
  In an earlier email, Max did mention setting the config does workaround
  the issue. But it's still strange that it only happens to a few specific
  files in this particular repo. The issue never popped up in other repos
  that he has, which I assume has all been excluded from Time Machine...
 
 Ah, sorry, I missed the earlier reference to it. trustctime is the only
 sensible thing to do from the git side. I think figuring out the rest is
 deep Apple magic that I'm not qualified to comment on.

From what I read isn't the ctime the only thing that changes? I read
that you tried this option and the issues disappeared? Maybe the
resolution (or part of it) is to change the default of core.trustctime
to false on osx?

Cheers Heiko
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Proposal: sharing .git/config

2013-03-12 Thread Jeff King
On Tue, Mar 12, 2013 at 01:01:08AM +0530, Ramkumar Ramachandra wrote:

  But it was pointed out that you could also just do:
 
$ git config include.ref upstream-config
$ git show origin/config ;# make sure it looks reasonable
$ git show origin/config .git/upstream-config
 
  and so forth. There are some ways that a pure ref can be more
  convenient (e.g., if you are carrying local changes on top of the
  upstream config and want to merge), but ultimately, you can replicate
  any include.ref workflow with include.path by adding a deploy step
  where you copy the file into $GIT_DIR.
 
 This seems to be unnecessarily complex and inelegant.  Maybe this
 functionality is best managed as a separate git repository: `repo`
 from depot_tools uses a manifest repository containing all the project
 metadata.  Maybe we can extend it/ write an more general version?

I don't think you can avoid the 3-step problem and retain the safety in
the general case.  Forgetting implementation details for a minute, you
have either a 1-step system:

  1. Fetch and start using config from the remote.

which is subject to fetching and executing malicious config, or:

  1. Fetch config from remote.
  2. Inspect it.
  3. Integrate it into the current config.

We can automate the sequence to remove as much friction as possible, but
fundamentally step 2 requires some effort from the user.  Moving the
config to a separate repo does not get rid of those steps.  The user
either does not look at the config before using it, in which case we are
no better than the 1-step scenario, or they do, in which case they are
replicating the 3-step scenario.

The other alternative is to automate step 2. The simplest way would be
to have a whitelist of ok to share config, that would not include
things like diff.external that can run arbitrary code. I don't know
whether that would make the system too limited for what people want to
do. Do we have a concrete example of what config people would like to
share in this manner?

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH] Documentation/technical/api-fswatch.txt: start with outline

2013-03-12 Thread Ramkumar Ramachandra
Heiko Voigt wrote:
 While talking about platform independence. How about Windows? AFAIK
 there are no file based sockets. How about using shared memory, thats
 available, instead? It would greatly reduce the needed porting effort.

What about the git credential helper: it uses UNIX sockets, no?  How
does git-credential-winstore [1] work?

[1]: https://github.com/anurse/git-credential-winstore
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH] Documentation/technical/api-fswatch.txt: start with outline

2013-03-12 Thread Erik Faye-Lund
On Tue, Mar 12, 2013 at 10:43 AM, Ramkumar Ramachandra
artag...@gmail.com wrote:
 Heiko Voigt wrote:
 While talking about platform independence. How about Windows? AFAIK
 there are no file based sockets. How about using shared memory, thats
 available, instead? It would greatly reduce the needed porting effort.

 What about the git credential helper: it uses UNIX sockets, no?  How
 does git-credential-winstore [1] work?

 [1]: https://github.com/anurse/git-credential-winstore

First, we have a proper credential helper for Windows in
contrib/credential/wincred these days. As the one who wrote that, we
communicate using stdin/stdout. The credential-helper doesn't maintain
state in itself, the Windows Credential Manager does. I suspect
git-credential-winstore works the same way.

As for Windows support, AFAIK there is no support for Unix domain
sockets in Windows. But there is support for named pipes, which is
almost the same thing. What we have support for in compat/mingw.[ch]
is a different matter, but we can extend that if needed.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH] Documentation/technical/api-fswatch.txt: start with outline

2013-03-12 Thread Jeff King
On Tue, Mar 12, 2013 at 03:13:39PM +0530, Ramkumar Ramachandra wrote:

 Heiko Voigt wrote:
  While talking about platform independence. How about Windows? AFAIK
  there are no file based sockets. How about using shared memory, thats
  available, instead? It would greatly reduce the needed porting effort.
 
 What about the git credential helper: it uses UNIX sockets, no?  How
 does git-credential-winstore [1] work?

No, the main credential protocol happens over pipes to a child process's
stdin/stdout. The credential-cache helper does use unix sockets (since
it needs to contact a long-running daemon that caches the credentials),
and AFAIK is not available under Windows (but that's OK, because
Windows-specific helpers that use secure storage are better anyway).

When I introduced credential-cache, I recall somebody mentioned that
there is some Windows-equivalent IPC that can be used to emulate unix
domain sockets. The calls aren't the same, but as long as your
requirements are basically get messages to/from the daemon, you can
probably abstract away the details on a per-platform basis.

Unfortunately I can't seem to find the original message or any details
in the archive (and I know next to nothing about Windows IPC).

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Questions/investigations on git-subtree and tags

2013-03-12 Thread Jeremy Rosen
Paul, I'm not quite sure where I should go from here...

should I send you a patch so you make it a V3 of your patch ? should I
send a patch superseeding yours ? 

I have also found a similar problem in git-subtree pull, which needs 
the same fix. 

in the mean time, attached is the current version of my changes

Cordialement

Jérémy Rosen

fight key loggers : write some perl using vim

From 12490724ae955719694d825dff4fa9e0d2709c1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Rosen?= jeremy.ro...@openwide.fr
Date: Tue, 12 Mar 2013 10:56:54 +0100
Subject: [PATCH 1/2] git-subtree: make sure the SHA saved as ancestor is a
 commit
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When adding or merging the first parameter might not be a commit, it can also be a tag SHA.
This needs to be fixed by using the underlying commit or the ancestor finding code will croak at split time


Signed-off-by: Jérémy Rosen jeremy.ro...@openwide.fr
---
 contrib/subtree/git-subtree.sh |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 8a23f58..8b9d114 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -531,7 +531,7 @@ cmd_add_repository()
 
 cmd_add_commit()
 {
-	revs=$(git rev-parse $default --revs-only $@) || exit $?
+	revs=$(git rev-parse $default --revs-only $1^{commit}) || exit $?
 	set -- $revs
 	rev=$1
 	
@@ -655,7 +655,7 @@ cmd_split()
 
 cmd_merge()
 {
-	revs=$(git rev-parse $default --revs-only $@) || exit $?
+	revs=$(git rev-parse $default --revs-only $1^{commit}) || exit $?
 	ensure_clean
 	
 	set -- $revs
-- 
1.7.10.4

From 05d1dd56217be59d69952a41d97e204cc7821948 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Rosen?= jeremy.ro...@openwide.fr
Date: Tue, 12 Mar 2013 10:57:56 +0100
Subject: [PATCH 2/2] git-subtree: use ls-remote to check the refspec passed
 to pull and add
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

ls-remote is the correct way to check that a parameter is a valid fetchable target


Signed-off-by: Jérémy Rosen jeremy.ro...@openwide.fr
---
 contrib/subtree/git-subtree.sh |   11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 8b9d114..61d4eab 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -503,13 +503,8 @@ cmd_add()
 
 	cmd_add_commit $@
 	elif [ $# -eq 2 ]; then
-	# Technically we could accept a refspec here but we're
-	# just going to turn around and add FETCH_HEAD under the
-	# specified directory.  Allowing a refspec might be
-	# misleading because we won't do anything with any other
-	# branches fetched via the refspec.
-	git rev-parse -q --verify $2^{commit} /dev/null ||
-	die '$2' does not refer to a commit
+		git ls-remote --exit-code $1 $2 ||
+		die '$2' is not a correct reference on '$1'
 
 	cmd_add_repository $@
 	else
@@ -700,6 +695,8 @@ cmd_merge()
 cmd_pull()
 {
 	ensure_clean
+	git ls-remote --exit-code $1 $2 ||
+		die '$2' is not a correct reference on '$1'
 	git fetch $@ || exit $?
 	revs=FETCH_HEAD
 	set -- $revs
-- 
1.7.10.4



Re: [PATCH v3 0/2] shell: allow 'no-interactive-login' command to disable interactive shell

2013-03-12 Thread Jeff King
On Sat, Mar 09, 2013 at 01:52:37PM -0800, Jonathan Nieder wrote:

 Here's a reroll along the lines described at
 http://thread.gmane.org/gmane.comp.version-control.git/216229
 
 As before, this series is meant to give users of basic 'git shell'
 setups a chance to imitate some nice behaviors that GitHub and
 gitolite offer in more complicated ways.  Thanks for your help on it
 so far.

Thanks, this version looks good to me.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/4] config: factor out config file stack management

2013-03-12 Thread Jeff King
On Sun, Mar 10, 2013 at 05:57:53PM +0100, Heiko Voigt wrote:

 Because a config callback may start parsing a new file, the
 global context regarding the current config file is stored
 as a stack. Currently we only need to manage that stack from
 git_config_from_file. Let's factor it out to allow new
 sources of config data.

 [...]

 +static int do_config_from(struct config_file *top, config_fn_t fn, void 
 *data)
 +{
 + int ret;
 +
 + /* push config-file parsing state stack */
 + top-prev = cf;
 + top-linenr = 1;
 + top-eof = 0;
 + strbuf_init(top-value, 1024);
 + strbuf_init(top-var, 1024);
 + cf = top;
 +
 + ret = git_parse_file(fn, data);
 +
 + /* pop config-file parsing state stack */
 + strbuf_release(top-value);
 + strbuf_release(top-var);
 + cf = top-prev;
 +
 + return ret;
 +}

Can we throw in a comment at the top here with the expected usage? In
particular, do_config_from is expecting the caller to have filled in
certain fields (at this point, top-f and top-name), but there is
nothing to make that clear.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/4] config: drop file pointer validity check in get_next_char()

2013-03-12 Thread Jeff King
On Sun, Mar 10, 2013 at 05:58:57PM +0100, Heiko Voigt wrote:

 The only location where cf is set in this file is in do_config_from().
 This function has only one callsite which is config_from_file(). In
 config_from_file() its ensured that the f member is set to non-zero.
 [...]
 - if (cf  ((f = cf-f) != NULL)) {
 + if (cf) {

I still think we can drop this conditional entirely. The complete call
graph looks like:

  git_config_from_file
- git_parse_file
  - get_next_char
  - get_value
  - get_next_char
  - parse_value
  - get_next_char
  - get_base_var
  - get_next_char
  - get_extended_base_var
  - get_next_char

That is, every path to get_next_char happens while we are in
git_config_from_file, and that function guarantees that cf = top, and
that top.f != NULL.  We do not have to even do any analysis of the
conditions for each call, because we never change cf nor top.f
except when we set them in git_config_from_file.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 3/4] config: make parsing stack struct independent from actual data source

2013-03-12 Thread Jeff King
On Sun, Mar 10, 2013 at 05:59:40PM +0100, Heiko Voigt wrote:

 diff --git a/config.c b/config.c
 index f55c43d..fe1c0e5 100644
 --- a/config.c
 +++ b/config.c
 @@ -10,20 +10,42 @@
  #include strbuf.h
  #include quote.h
  
 -typedef struct config_file {
 - struct config_file *prev;
 - FILE *f;
 +struct config_source {
 + struct config_source *prev;
 + void *data;

Would a union be more appropriate here? We do not ever have to pass it
directly as a parameter, since we pass the struct config_source to the
method functions.

It's still possible to screw up using a union, but it's slightly harder
than screwing up using a void pointer. And I do not think we need the
run-time flexibility offered by the void pointer in this case.

 +static int config_file_fgetc(struct config_source *conf)
 +{
 + FILE *f = conf-data;
 + return fgetc(f);
 +}

This could become just:

  return fgetc(conf-u.f);

and so forth (might it make sense to give f a more descriptive name,
as we are adding other sources?).

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] require pathspec for git add -u/-A

2013-03-12 Thread Jeff King
On Sun, Mar 10, 2013 at 04:49:09PM +0100, Matthieu Moy wrote:

 Junio C Hamano gits...@pobox.com writes:
 
  As promised in 0fa2eb530fb7 (add: warn when -u or -A is used without
  pathspec, 2013-01-28), git add -u/-A that is run without pathspec
  in a subdirectory will stop working sometime before Git 2.0, to wean
  users off of the old default, in preparation for adopting the new
  default in Git 2.0.
 
 I originally thought this step was necessary, but I changed my mind. The
 warning is big enough and doesn't need to be turned into an error.
 
 If this step is applied, it should be applied at 2.0, not before, as
 this is the big incompatible change. Re-introducing a new behavior won't
 harm users OTOH.

FWIW, I agree with this. The warning is enough without an error period
(unless the intent was to switch to the error and stay there forever,
but I do not think that is the proposal).

-Peff

PS I wonder how others are finding the warning? I'm finding it slightly
   annoying. Perhaps I just haven't retrained my fingers yet. But one
   problem with that retraining is that I type git add -u from the
   root _most_ of the time, and it just works. But occasionally, I get
   the hey, do not do that warning, because I'm in a subdir, even
   though I would be happy to have the full-tree behavior. I guess we
   already rejected the idea of being able to shut off the warning and
   just get the new behavior, in favor of having people specify it
   manually each time?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 01/13] dir.c: add MEASURE_EXCLUDE code for tracking exclude performance

2013-03-12 Thread Nguyễn Thái Ngọc Duy
Hot read_directory() codepaths are tracked. This could be helpful to
see how changes affect read_directory() performance.

Results are printed when environment variable GIT_MEASURE_EXCLUDE is set.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 dir.c | 109 --
 1 file changed, 100 insertions(+), 9 deletions(-)

diff --git a/dir.c b/dir.c
index 57394e4..69c045b 100644
--- a/dir.c
+++ b/dir.c
@@ -12,6 +12,32 @@
 #include refs.h
 #include wildmatch.h
 
+#ifdef MEASURE_EXCLUDE
+static uint32_t tv_treat_leading_path;
+static uint32_t tv_read_directory;
+static uint32_t tv_treat_one_path;
+static uint32_t tv_is_excluded;
+static uint32_t tv_prep_exclude;
+static uint32_t tv_last_exclude_matching;
+static uint32_t tv_dir_add_name;
+static uint32_t tv_directory_exists_in_index;
+static uint32_t tv_simplify_away;
+static uint32_t tv_index_name_exists;
+static uint32_t tv_lazy_init_name_hash;
+#define START_CLOCK() \
+   { \
+   struct timeval tv1, tv2; \
+   gettimeofday(tv1, NULL);
+#define STOP_CLOCK(v) \
+   gettimeofday(tv2, NULL); \
+   v += (uint64_t)tv2.tv_sec * 100 + tv2.tv_usec - \
+   (uint64_t)tv1.tv_sec * 100 - tv1.tv_usec; \
+   }
+#else
+#define START_CLOCK()
+#define STOP_CLOCK(v)
+#endif
+
 struct path_simplify {
int len;
const char *path;
@@ -768,8 +794,11 @@ static struct exclude *last_exclude_matching(struct 
dir_struct *dir,
const char *basename = strrchr(pathname, '/');
basename = (basename) ? basename+1 : pathname;
 
+   START_CLOCK();
prep_exclude(dir, pathname, basename-pathname);
+   STOP_CLOCK(tv_prep_exclude);
 
+   START_CLOCK();
for (i = EXC_CMDL; i = EXC_FILE; i++) {
group = dir-exclude_list_group[i];
for (j = group-nr - 1; j = 0; j--) {
@@ -780,6 +809,7 @@ static struct exclude *last_exclude_matching(struct 
dir_struct *dir,
return exclude;
}
}
+   STOP_CLOCK(tv_last_exclude_matching);
return NULL;
 }
 
@@ -897,9 +927,14 @@ static struct dir_entry *dir_entry_new(const char 
*pathname, int len)
 
 static struct dir_entry *dir_add_name(struct dir_struct *dir, const char 
*pathname, int len)
 {
-   if (!(dir-flags  DIR_SHOW_IGNORED) 
-   cache_name_exists(pathname, len, ignore_case))
-   return NULL;
+   if (!(dir-flags  DIR_SHOW_IGNORED)) {
+   struct cache_entry *ce;
+   START_CLOCK();
+   ce = cache_name_exists(pathname, len, ignore_case);
+   STOP_CLOCK(tv_index_name_exists);
+   if (ce)
+   return NULL;
+   }
 
ALLOC_GROW(dir-entries, dir-nr+1, dir-alloc);
return dir-entries[dir-nr++] = dir_entry_new(pathname, len);
@@ -1034,8 +1069,12 @@ static enum directory_treatment treat_directory(struct 
dir_struct *dir,
const char *dirname, int len, int exclude,
const struct path_simplify *simplify)
 {
+   int ret;
+   START_CLOCK();
/* The len-1 is to strip the final '/' */
-   switch (directory_exists_in_index(dirname, len-1)) {
+   ret = directory_exists_in_index(dirname, len-1);
+   STOP_CLOCK(tv_directory_exists_in_index);
+   switch (ret) {
case index_directory:
if ((dir-flags  DIR_SHOW_OTHER_DIRECTORIES)  exclude)
break;
@@ -1179,7 +1218,9 @@ static int get_index_dtype(const char *path, int len)
int pos;
struct cache_entry *ce;
 
+   START_CLOCK();
ce = cache_name_exists(path, len, 0);
+   STOP_CLOCK(tv_index_name_exists);
if (ce) {
if (!ce_uptodate(ce))
return DT_UNKNOWN;
@@ -1244,7 +1285,12 @@ static enum path_treatment treat_one_path(struct 
dir_struct *dir,
  const struct path_simplify *simplify,
  int dtype, struct dirent *de)
 {
-   int exclude = is_excluded(dir, path-buf, dtype);
+   int exclude;
+
+   START_CLOCK();
+   exclude = is_excluded(dir, path-buf,  dtype);
+   STOP_CLOCK(tv_is_excluded);
+
if (exclude  (dir-flags  DIR_COLLECT_IGNORED)
 exclude_matches_pathspec(path-buf, path-len, simplify))
dir_add_ignored(dir, path-buf, path-len);
@@ -1292,17 +1338,23 @@ static enum path_treatment treat_path(struct dir_struct 
*dir,
  int baselen,
  const struct path_simplify *simplify)
 {
-   int dtype;
+   int dtype, ret;
 
if (is_dot_or_dotdot(de-d_name) || !strcmp(de-d_name, .git))
return path_ignored;
strbuf_setlen(path, baselen);
strbuf_addstr(path, de-d_name);
-   if (simplify_away(path-buf, path-len, 

[PATCH v3 02/13] match_pathname: avoid calling strncmp if baselen is 0

2013-03-12 Thread Nguyễn Thái Ngọc Duy
This reduces git status user time by a little bit. This is the
sorted results of 10 consecutive runs of git ls-files
--exclude-standard -o on webkit.git, compiled with gcc -O2:

treat_leading_path:   0.000  0.000
read_directory:   4.102  3.674
+treat_one_path:  2.843  2.427
++is_excluded:2.632  2.221
+++prep_exclude:  0.225  0.224
+++matching:  2.054  1.650
++dir_exist:  0.035  0.035
++index_name_exists:  0.292  0.288
lazy_init_name_hash:  0.258  0.257
+simplify_away:   0.085  0.085
+dir_add_name:0.446  0.441

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 dir.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/dir.c b/dir.c
index 69c045b..32a3adb 100644
--- a/dir.c
+++ b/dir.c
@@ -688,8 +688,8 @@ int match_pathname(const char *pathname, int pathlen,
 * may not end with a trailing slash though.
 */
if (pathlen  baselen + 1 ||
-   (baselen  pathname[baselen] != '/') ||
-   strncmp_icase(pathname, base, baselen))
+   (baselen  (pathname[baselen] != '/' ||
+strncmp_icase(pathname, base, baselen
return 0;
 
namelen = baselen ? pathlen - baselen - 1 : pathlen;
-- 
1.8.1.2.536.gf441e6d

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 00/13] Exclude optimizations

2013-03-12 Thread Nguyễn Thái Ngọc Duy
Result of today. I cherry-picked nd/read-directory-recursive-optim to
see how far I can get after pulling all the tricks. This is a slower
machine so time is longer. Anyway, read_directory time is reduced
about 70% in the end.

function  before after
--
treat_leading_path:   0.000  0.000
read_directory:   4.102  1.235
+treat_one_path:  2.843  0.531
++is_excluded:2.632  0.102
+++prep_exclude:  0.225  0.040
+++matching:  2.054  0.035
++dir_exist:  0.035  0.035
++index_name_exists:  0.292  0.225
lazy_init_name_hash:  0.258  0.155
+simplify_away:   0.085  0.083
+dir_add_name:0.446  0.000

I don't expect all these patches to go in. The meat is
nd/read-directory-recursive-optim (or 10/13) and 09/13. Some other
patches are safe even if they do not contribute much to the gain. The
last two are probably not worth the trouble.


Nguyễn Thái Ngọc Duy (13):
  dir.c: add MEASURE_EXCLUDE code for tracking exclude performance
  match_pathname: avoid calling strncmp if baselen is 0
  dir.c: inline convenient *_icase helpers
  match_basename: use strncmp instead of strcmp
  match_{base,path}name: replace strncmp_icase with memequal_icase
  dir: pass pathname length to last_exclude_matching
  exclude: avoid calling prep_exclude on entries of the same directory
  exclude: record baselen in the pattern
  exclude: filter out patterns not applicable to the current directory
  read_directory: avoid invoking exclude machinery on tracked files
  Preallocate hash tables when the number of inserts are known in advance
  name-hash: allow to lookup a name with precalculated base hash
  read_directory: calculate name hashes incrementally

 Makefile  |   1 +
 attr.c|   6 +-
 cache.h   |   2 -
 diffcore-rename.c |   1 +
 dir.c | 392 --
 dir.h |  26 +++-
 hash.h|   7 +
 name-hash.c   |  49 ---
 name-hash.h (new) |  45 +++
 read-cache.c  |   1 +
 unpack-trees.c|   1 +
 11 files changed, 431 insertions(+), 100 deletions(-)
 create mode 100644 name-hash.h

-- 
1.8.1.2.536.gf441e6d

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 03/13] dir.c: inline convenient *_icase helpers

2013-03-12 Thread Nguyễn Thái Ngọc Duy
Like the previous patch, this cuts down the number of str*cmp calls in
read_directory (which does _a lot_). Again sorted results on webkit.git:

treat_leading_path:   0.000  0.000
read_directory:   3.674  3.558
+treat_one_path:  2.427  2.305
++is_excluded:2.221  2.098
+++prep_exclude:  0.224  0.223
+++matching:  1.650  1.529
++dir_exist:  0.035  0.035
++index_name_exists:  0.288  0.291
lazy_init_name_hash:  0.257  0.257
+simplify_away:   0.085  0.086
+dir_add_name:0.441  0.445

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 dir.c | 16 
 dir.h | 18 +++---
 2 files changed, 15 insertions(+), 19 deletions(-)

diff --git a/dir.c b/dir.c
index 32a3adb..a69c8ac 100644
--- a/dir.c
+++ b/dir.c
@@ -47,22 +47,6 @@ static int read_directory_recursive(struct dir_struct *dir, 
const char *path, in
int check_only, const struct path_simplify *simplify);
 static int get_dtype(struct dirent *de, const char *path, int len);
 
-/* helper string functions with support for the ignore_case flag */
-int strcmp_icase(const char *a, const char *b)
-{
-   return ignore_case ? strcasecmp(a, b) : strcmp(a, b);
-}
-
-int strncmp_icase(const char *a, const char *b, size_t count)
-{
-   return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
-}
-
-int fnmatch_icase(const char *pattern, const char *string, int flags)
-{
-   return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 
0));
-}
-
 inline int git_fnmatch(const char *pattern, const char *string,
   int flags, int prefix)
 {
diff --git a/dir.h b/dir.h
index c3eb4b5..560ade4 100644
--- a/dir.h
+++ b/dir.h
@@ -200,9 +200,21 @@ extern int remove_dir_recursively(struct strbuf *path, int 
flag);
 /* tries to remove the path with empty directories along it, ignores ENOENT */
 extern int remove_path(const char *path);
 
-extern int strcmp_icase(const char *a, const char *b);
-extern int strncmp_icase(const char *a, const char *b, size_t count);
-extern int fnmatch_icase(const char *pattern, const char *string, int flags);
+/* helper string functions with support for the ignore_case flag */
+static inline int strcmp_icase(const char *a, const char *b)
+{
+   return ignore_case ? strcasecmp(a, b) : strcmp(a, b);
+}
+
+static inline int strncmp_icase(const char *a, const char *b, size_t count)
+{
+   return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
+}
+
+static inline int fnmatch_icase(const char *pattern, const char *string, int 
flags)
+{
+   return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 
0));
+}
 
 /*
  * The prefix part of pattern must not contains wildcards.
-- 
1.8.1.2.536.gf441e6d

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 04/13] match_basename: use strncmp instead of strcmp

2013-03-12 Thread Nguyễn Thái Ngọc Duy
strncmp provides length information, compared to strcmp, which could
be taken advantage by the implementation. Even better, we could check
if the lengths are equal before calling strncmp, eliminating a bit of
strncmp calls.

treat_leading_path:   0.000  0.000
read_directory:   3.558  3.578
+treat_one_path:  2.305  2.323
++is_excluded:2.098  2.117
+++prep_exclude:  0.223  0.224
+++matching:  1.529  1.544
++dir_exist:  0.035  0.035
++index_name_exists:  0.291  0.290
lazy_init_name_hash:  0.257  0.258
+simplify_away:   0.086  0.087
+dir_add_name:0.445  0.445

While at there, fix an inconsistency about pattern/patternlen in how
attr handles EXC_FLAG_MUSTBEDIR. When parse_exclude_pattern detects
this flag, it sets patternlen _not_ to include the trailing slash and
expects the caller to trim it. add_exclude does, parse_attr_line does
not.

In attr.c, the pattern could be foo/ while patternlen tells us it
only has 3 chars. Some functions do not care about patternlen and will
see the pattern as foo/ while others may see it as foo. This patch
makes patternlen 4 in this case. (Although for a piece of mind,
perhaps we should trim it to foo like exclude, and never pass a
pathname like abc/ to match_{base,path}name)

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 attr.c | 2 ++
 dir.c  | 8 +---
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/attr.c b/attr.c
index e2f9377..1818ba5 100644
--- a/attr.c
+++ b/attr.c
@@ -255,6 +255,8 @@ static struct match_attr *parse_attr_line(const char *line, 
const char *src,
  res-u.pat.patternlen,
  res-u.pat.flags,
  res-u.pat.nowildcardlen);
+   if (res-u.pat.flags  EXC_FLAG_MUSTBEDIR)
+   res-u.pat.patternlen++;
if (res-u.pat.flags  EXC_FLAG_NEGATIVE) {
warning(_(Negative patterns are ignored in git 
attributes\n
  Use '\\!' for literal leading 
exclamation.));
diff --git a/dir.c b/dir.c
index a69c8ac..a2ab200 100644
--- a/dir.c
+++ b/dir.c
@@ -636,12 +636,14 @@ int match_basename(const char *basename, int basenamelen,
   int flags)
 {
if (prefix == patternlen) {
-   if (!strcmp_icase(pattern, basename))
+   if (patternlen == basenamelen 
+   !strncmp_icase(pattern, basename, patternlen))
return 1;
} else if (flags  EXC_FLAG_ENDSWITH) {
if (patternlen - 1 = basenamelen 
-   !strcmp_icase(pattern + 1,
- basename + basenamelen - patternlen + 1))
+   !strncmp_icase(pattern + 1,
+  basename + basenamelen - patternlen + 1,
+  patternlen - 1))
return 1;
} else {
if (fnmatch_icase(pattern, basename, 0) == 0)
-- 
1.8.1.2.536.gf441e6d

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 05/13] match_{base,path}name: replace strncmp_icase with memequal_icase

2013-03-12 Thread Nguyễn Thái Ngọc Duy
treat_leading_path:   0.000  0.000
read_directory:   3.578  3.501
+treat_one_path:  2.323  2.257
++is_excluded:2.117  2.056
+++prep_exclude:  0.224  0.216
+++matching:  1.544  1.493
++dir_exist:  0.035  0.035
++index_name_exists:  0.290  0.292
lazy_init_name_hash:  0.258  0.256
+simplify_away:   0.087  0.084
+dir_add_name:0.445  0.447

Suggested-by: Fredrik Gustafsson iv...@iveqy.com
Suggested-by: Antoine Pelisse apeli...@gmail.com
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 dir.c | 31 +++
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/dir.c b/dir.c
index a2ab200..26c3b3a 100644
--- a/dir.c
+++ b/dir.c
@@ -47,6 +47,29 @@ static int read_directory_recursive(struct dir_struct *dir, 
const char *path, in
int check_only, const struct path_simplify *simplify);
 static int get_dtype(struct dirent *de, const char *path, int len);
 
+static inline int memequal_icase(const char *a, const char *b, int n)
+{
+   if (!memcmp(a, b, n))
+   return 1;
+
+   if (!ignore_case)
+   return 0;
+
+   /*
+* This assumes that ASCII is used in most repositories. We
+* try the ascii-only version first (i.e. Git's
+* toupper). Failing that, fall back to normal strncasecmp.
+*/
+   while (n  toupper(*a) == toupper(*b)) {
+   a++;
+   b++;
+   n--;
+   }
+   if (!n)
+   return 1;
+   return !strncasecmp(a, b, n);
+}
+
 inline int git_fnmatch(const char *pattern, const char *string,
   int flags, int prefix)
 {
@@ -637,11 +660,11 @@ int match_basename(const char *basename, int basenamelen,
 {
if (prefix == patternlen) {
if (patternlen == basenamelen 
-   !strncmp_icase(pattern, basename, patternlen))
+   memequal_icase(pattern, basename, patternlen))
return 1;
} else if (flags  EXC_FLAG_ENDSWITH) {
if (patternlen - 1 = basenamelen 
-   !strncmp_icase(pattern + 1,
+   memequal_icase(pattern + 1,
   basename + basenamelen - patternlen + 1,
   patternlen - 1))
return 1;
@@ -675,7 +698,7 @@ int match_pathname(const char *pathname, int pathlen,
 */
if (pathlen  baselen + 1 ||
(baselen  (pathname[baselen] != '/' ||
-strncmp_icase(pathname, base, baselen
+!memequal_icase(pathname, base, baselen
return 0;
 
namelen = baselen ? pathlen - baselen - 1 : pathlen;
@@ -689,7 +712,7 @@ int match_pathname(const char *pathname, int pathlen,
if (prefix  namelen)
return 0;
 
-   if (strncmp_icase(pattern, name, prefix))
+   if (!memequal_icase(pattern, name, prefix))
return 0;
pattern += prefix;
name+= prefix;
-- 
1.8.1.2.536.gf441e6d

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 07/13] exclude: avoid calling prep_exclude on entries of the same directory

2013-03-12 Thread Nguyễn Thái Ngọc Duy
prep_exclude is only necessary when we enter or leave a directory. Now
it's called for every entry in a directory. With this patch, the
number of prep_exclude calls in webkit.git goes from 188k down to
11k. This patch does not make exclude any faster, but it prepares for
making prep_exclude heavier in terms of computation, where a large
number of calls may have bigger impacts.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 dir.c | 10 +-
 dir.h |  1 +
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/dir.c b/dir.c
index 58739f3..f8f7a7e 100644
--- a/dir.c
+++ b/dir.c
@@ -804,7 +804,10 @@ static struct exclude *last_exclude_matching(struct 
dir_struct *dir,
basename = (basename) ? basename+1 : pathname;
 
START_CLOCK();
-   prep_exclude(dir, pathname, basename-pathname);
+   if (!dir-exclude_prepared) {
+   prep_exclude(dir, pathname, basename-pathname);
+   dir-exclude_prepared = 1;
+   }
STOP_CLOCK(tv_prep_exclude);
 
START_CLOCK();
@@ -894,6 +897,7 @@ struct exclude *last_exclude_matching_path(struct 
path_exclude_check *check,
 
if (ch == '/') {
int dt = DT_DIR;
+   check-dir-exclude_prepared = 0;
exclude = last_exclude_matching(check-dir,
path-buf, path-len,
dt);
@@ -908,6 +912,7 @@ struct exclude *last_exclude_matching_path(struct 
path_exclude_check *check,
/* An entry in the index; cannot be a directory with subentries */
strbuf_setlen(path, 0);
 
+   check-dir-exclude_prepared = 0;
return last_exclude_matching(check-dir, name, namelen, dtype);
 }
 
@@ -1394,6 +1399,7 @@ static int read_directory_recursive(struct dir_struct 
*dir,
if (!fdir)
goto out;
 
+   dir-exclude_prepared = 0;
while ((de = readdir(fdir)) != NULL) {
switch (treat_path(dir, de, path, baselen, simplify)) {
case path_recurse:
@@ -1415,6 +1421,7 @@ static int read_directory_recursive(struct dir_struct 
*dir,
}
closedir(fdir);
  out:
+   dir-exclude_prepared = 0;
strbuf_release(path);
 
return contents;
@@ -1486,6 +1493,7 @@ static int treat_leading_path(struct dir_struct *dir,
break;
if (simplify_away(sb.buf, sb.len, simplify))
break;
+   dir-exclude_prepared = 0;
if (treat_one_path(dir, sb, simplify,
   DT_DIR, NULL) == path_ignored)
break; /* do not recurse into it */
diff --git a/dir.h b/dir.h
index 560ade4..0748407 100644
--- a/dir.h
+++ b/dir.h
@@ -86,6 +86,7 @@ struct dir_struct {
 
/* Exclude info */
const char *exclude_per_dir;
+   int exclude_prepared;
 
/*
 * We maintain three groups of exclude pattern lists:
-- 
1.8.1.2.536.gf441e6d

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 08/13] exclude: record baselen in the pattern

2013-03-12 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 attr.c |  4 +++-
 dir.c  | 19 ++-
 dir.h  |  6 +-
 3 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/attr.c b/attr.c
index 1818ba5..b89da33 100644
--- a/attr.c
+++ b/attr.c
@@ -249,12 +249,14 @@ static struct match_attr *parse_attr_line(const char 
*line, const char *src,
res-u.attr = git_attr_internal(name, namelen);
else {
char *p = (char *)(res-state[num_attr]);
+   int pattern_baselen;
memcpy(p, name, namelen);
res-u.pat.pattern = p;
parse_exclude_pattern(res-u.pat.pattern,
  res-u.pat.patternlen,
  res-u.pat.flags,
- res-u.pat.nowildcardlen);
+ res-u.pat.nowildcardlen,
+ pattern_baselen);
if (res-u.pat.flags  EXC_FLAG_MUSTBEDIR)
res-u.pat.patternlen++;
if (res-u.pat.flags  EXC_FLAG_NEGATIVE) {
diff --git a/dir.c b/dir.c
index f8f7a7e..932fd2f 100644
--- a/dir.c
+++ b/dir.c
@@ -390,10 +390,11 @@ static int no_wildcard(const char *string)
 void parse_exclude_pattern(const char **pattern,
   int *patternlen,
   int *flags,
-  int *nowildcardlen)
+  int *nowildcardlen,
+  int *pattern_baselen)
 {
const char *p = *pattern;
-   size_t i, len;
+   int i, len;
 
*flags = 0;
if (*p == '!') {
@@ -405,12 +406,15 @@ void parse_exclude_pattern(const char **pattern,
len--;
*flags |= EXC_FLAG_MUSTBEDIR;
}
-   for (i = 0; i  len; i++) {
+   for (i = len - 1; i = 0; i--) {
if (p[i] == '/')
break;
}
-   if (i == len)
+   if (i  0) {
*flags |= EXC_FLAG_NODIR;
+   *pattern_baselen = -1;
+   } else
+   *pattern_baselen = i;
*nowildcardlen = simple_length(p);
/*
 * we should have excluded the trailing slash from 'p' too,
@@ -421,6 +425,8 @@ void parse_exclude_pattern(const char **pattern,
*nowildcardlen = len;
if (*p == '*'  no_wildcard(p + 1))
*flags |= EXC_FLAG_ENDSWITH;
+   else if (*nowildcardlen != len)
+   *pattern_baselen = -1;
*pattern = p;
*patternlen = len;
 }
@@ -432,8 +438,10 @@ void add_exclude(const char *string, const char *base,
int patternlen;
int flags;
int nowildcardlen;
+   int pattern_baselen;
 
-   parse_exclude_pattern(string, patternlen, flags, nowildcardlen);
+   parse_exclude_pattern(string, patternlen, flags,
+ nowildcardlen, pattern_baselen);
if (flags  EXC_FLAG_MUSTBEDIR) {
char *s;
x = xmalloc(sizeof(*x) + patternlen + 1);
@@ -449,6 +457,7 @@ void add_exclude(const char *string, const char *base,
x-nowildcardlen = nowildcardlen;
x-base = base;
x-baselen = baselen;
+   x-pattern_baselen = pattern_baselen;
x-flags = flags;
x-srcpos = srcpos;
ALLOC_GROW(el-excludes, el-nr + 1, el-alloc);
diff --git a/dir.h b/dir.h
index 0748407..cb50a85 100644
--- a/dir.h
+++ b/dir.h
@@ -44,6 +44,7 @@ struct exclude_list {
int nowildcardlen;
const char *base;
int baselen;
+   int pattern_baselen;
int flags;
 
/*
@@ -172,7 +173,10 @@ extern struct exclude_list *add_exclude_list(struct 
dir_struct *dir,
 extern int add_excludes_from_file_to_list(const char *fname, const char *base, 
int baselen,
  struct exclude_list *el, int 
check_index);
 extern void add_excludes_from_file(struct dir_struct *, const char *fname);
-extern void parse_exclude_pattern(const char **string, int *patternlen, int 
*flags, int *nowildcardlen);
+extern void parse_exclude_pattern(const char **string,
+ int *patternlen, int *flags,
+ int *nowildcardlen,
+ int *pattern_baselen);
 extern void add_exclude(const char *string, const char *base,
int baselen, struct exclude_list *el, int srcpos);
 extern void clear_exclude_list(struct exclude_list *el);
-- 
1.8.1.2.536.gf441e6d

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 09/13] exclude: filter out patterns not applicable to the current directory

2013-03-12 Thread Nguyễn Thái Ngọc Duy
.gitignore files are spread over directories (*) so that when we check
for ignored files at foo, we are not bothered by foo/bar/.gitignore,
which contains ignore rules for foo/bar only.

This is not enough. foo/.gitignore can contain the pattern
foo/bar/*.c. When we stay at foo, we know that the pattern cannot
match anything. Similarly, the pattern /autom4te.cache at root
directory cannot match anything in foo. This patch attempts to filter
out such patterns to drive down matching cost.

The algorithm implemented here is a naive one. Patterns can be either
active or passive:

 - When we enter a new directory (e.g. from root to foo), currently
   active patterns may no longer be applicable and can be turned to
   passive.

 - On the opposite, when we leave a directory (foo back to roo),
   passive patterns may come alive again.

We could do smarter things. But this implementation cuts a big portion
of cost already (and solves the root .gitignore is evil problem).
There's probably no need to be smart.

(*) this design forces us to try to find .gitignore at every
directory. On webkit.git that equals to 6k open syscalls. It feels
like .svn on every directory again. I suggest we add
~/.gitignore.master, containing the list .gitignore files in
worktree. If this file exists, we don't poke at every directory for
.gitignore.

treat_leading_path:   0.000  0.000
read_directory:   3.455  2.879
+treat_one_path:  2.203  1.620
++is_excluded:2.000  1.416
+++prep_exclude:  0.171  0.198
+++matching:  1.509  0.904
++dir_exist:  0.036  0.035
++index_name_exists:  0.292  0.289
lazy_init_name_hash:  0.257  0.257
+simplify_away:   0.084  0.085
+dir_add_name:0.446  0.446

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 dir.c | 93 +--
 dir.h |  1 +
 2 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/dir.c b/dir.c
index 932fd2f..c57bf06 100644
--- a/dir.c
+++ b/dir.c
@@ -458,7 +458,7 @@ void add_exclude(const char *string, const char *base,
x-base = base;
x-baselen = baselen;
x-pattern_baselen = pattern_baselen;
-   x-flags = flags;
+   x-flags = flags | EXC_FLAG_ACTIVE;
x-srcpos = srcpos;
ALLOC_GROW(el-excludes, el-nr + 1, el-alloc);
el-excludes[el-nr++] = x;
@@ -591,6 +591,87 @@ void add_excludes_from_file(struct dir_struct *dir, const 
char *fname)
die(cannot use %s as an exclude file, fname);
 }
 
+static int pattern_match_base(struct dir_struct *dir,
+ const char *base, int baselen,
+ const struct exclude *exc)
+{
+   const char *pattern;
+
+   /*
+* TODO: if a patterns come from a .gitignore, exc-base would
+* be the same for all of them. We could compare once and
+* reuse the result, instead of perform the comparison per
+* pattern like this.
+*/
+   if (exc-baselen) {
+   if (baselen  exc-baselen + 1)
+   return 0;
+
+   if (base[exc-baselen] != '/' ||
+   memcmp(base, exc-base, exc-baselen))
+   return 0;
+
+   base += exc-baselen + 1;
+   baselen -= exc-baselen + 1;
+   }
+
+   if (baselen != exc-pattern_baselen)
+   return 0;
+
+   if (exc-pattern_baselen) {
+   pattern = exc-pattern;
+   if (*pattern == '/')
+   pattern++;
+   if (memcmp(base, pattern, exc-pattern_baselen))
+   return 0;
+   }
+
+   return 1;
+}
+
+/*
+ * If pushed is non-zero, we have entered a new directory. Some
+ * pathname patterns may no longer applicable. Go over all active
+ * patterns and disable them if so.
+ *
+ * If popped is non-zero, we have left a directory. Inactive patterns
+ * may be applicable again. Go over them and re-enable if so.
+ */
+static void scan_patterns(struct dir_struct *dir,
+ const char *base, int baselen,
+ int pushed, int popped)
+{
+   int i, j, k;
+
+   for (i = EXC_CMDL; i = EXC_FILE; i++) {
+   struct exclude_list_group *group = dir-exclude_list_group[i];
+   for (j = group-nr - 1; j = 0; j--) {
+   struct exclude_list *list = group-el[j];
+   for (k = 0; k  list-nr; k++) {
+   struct exclude *exc = list-excludes[k];
+
+   /*
+* No base (i.e. EXC_FLAG_NODIR) or
+* applicable to many bases (**
+* patterns)
+*/
+   if (exc-pattern_baselen == -1)
+   continue;
+
+   if (exc-flags  EXC_FLAG_ACTIVE) {
+  

[PATCH v3 10/13] read_directory: avoid invoking exclude machinery on tracked files

2013-03-12 Thread Nguyễn Thái Ngọc Duy
read_directory() (and its friendly wrapper fill_directory) collects
untracked/ignored files by traversing through the whole worktree,
feeding every entry to treat_one_path(), where each entry is checked
against .gitignore patterns.

One may see that tracked files can't be excluded and we do not need to
run them through exclude machinery. On repos where there are many
.gitignore patterns and/or a lot of tracked files, this unnecessary
processing can become expensive.

This patch avoids it mostly for normal cases. Directories are still
processed as before. DIR_SHOW_IGNORED and DIR_COLLECT_IGNORED are not
normally used unless some options are given (e.g. checkout
--overwrite-ignore, add -f...)

treat_one_path's behavior changes when taking this shortcut. With
current code, when a non-directory path is not excluded,
treat_one_path calls treat_file, which returns the initial value of
exclude_file and causes treat_one_path to return path_handled. With
this patch, on the same conditions, treat_one_path returns
path_ignored.

read_directory_recursive() cares about this difference. Check out the
snippet:

while (...) {
switch (treat_path(...)) {
case path_ignored:
continue;
case path_handled:
break;
}
contents++;
if (check_only)
break;
dir_add_name(dir, path.buf, path.len);
}

If path_handled is returned, contents goes up. And if check_only is
true, the loop could be broken early. These will not happen when
treat_one_path (and its wrapper treat_path) returns
path_ignored. dir_add_name internally does a cache_name_exists() check
so it makes no difference.

To avoid this behavior change, treat_one_path is instructed to skip
the optimization when check_only or contents is used.

Finally some numbers (best of 20 runs) that shows why it's worth all
the hassle:

git status   | webkit linux-2.6 libreoffice-core gentoo-x86
-+--
before   | 1.097s0.208s   0.399s 0.539s
after| 0.736s0.159s   0.248s 0.501s
nr. patterns |89   376   19  0
nr. tracked  |   182k   40k  63k   101k

treat_leading_path:   0.000  0.000
read_directory:   2.879  1.299
+treat_one_path:  1.620  0.599
++is_excluded:1.416  0.103
+++prep_exclude:  0.198  0.040
+++matching:  0.904  0.036
++dir_exist:  0.035  0.036
++index_name_exists:  0.289  0.291
lazy_init_name_hash:  0.257  0.257
+simplify_away:   0.085  0.082
+dir_add_name:0.446  0.000

Tracked-down-by: Karsten Blees karsten.bl...@gmail.com
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
Signed-off-by: Junio C Hamano gits...@pobox.com

---
 dir.c | 80 ---
 1 file changed, 53 insertions(+), 27 deletions(-)

diff --git a/dir.c b/dir.c
index c57bf06..6809dd2 100644
--- a/dir.c
+++ b/dir.c
@@ -43,8 +43,11 @@ struct path_simplify {
const char *path;
 };
 
-static int read_directory_recursive(struct dir_struct *dir, const char *path, 
int len,
-   int check_only, const struct path_simplify *simplify);
+static void read_directory_recursive(struct dir_struct *dir,
+const char *path, int len,
+int check_only,
+const struct path_simplify *simplify,
+int *contents);
 static int get_dtype(struct dirent *de, const char *path, int len);
 
 static inline int memequal_icase(const char *a, const char *b, int n)
@@ -1184,7 +1187,7 @@ static enum directory_treatment treat_directory(struct 
dir_struct *dir,
const char *dirname, int len, int exclude,
const struct path_simplify *simplify)
 {
-   int ret;
+   int contents = 0, ret;
START_CLOCK();
/* The len-1 is to strip the final '/' */
ret = directory_exists_in_index(dirname, len-1);
@@ -1219,19 +1222,19 @@ static enum directory_treatment treat_directory(struct 
dir_struct *dir,
 * check if it contains only ignored files
 */
if ((dir-flags  DIR_SHOW_IGNORED)  !exclude) {
-   int ignored;
dir-flags = ~DIR_SHOW_IGNORED;
dir-flags |= DIR_HIDE_EMPTY_DIRECTORIES;
-   ignored = read_directory_recursive(dir, dirname, len, 1, 
simplify);
+   read_directory_recursive(dir, dirname, len, 1, simplify, 
contents);
dir-flags = ~DIR_HIDE_EMPTY_DIRECTORIES;
dir-flags |= DIR_SHOW_IGNORED;
 
-   return ignored ? ignore_directory : show_directory;
+   return contents ? ignore_directory : show_directory;
}
if (!(dir-flags  DIR_SHOW_IGNORED) 
!(dir-flags  

[PATCH v3 11/13] Preallocate hash tables when the number of inserts are known in advance

2013-03-12 Thread Nguyễn Thái Ngọc Duy
This avoids unnecessary allocations and reinsertions. On webkit.git
(i.e. about 100k inserts to the name hash table), this reduces about
100ms out of 3s user time.

treat_leading_path:   0.000  0.000
read_directory:   1.299  1.305
+treat_one_path:  0.599  0.599
++is_excluded:0.103  0.103
+++prep_exclude:  0.040  0.040
+++matching:  0.036  0.035
++dir_exist:  0.036  0.035
++index_name_exists:  0.291  0.292
lazy_init_name_hash:  0.257  0.155
+simplify_away:   0.082  0.083
+dir_add_name:0.000  0.000


Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 diffcore-rename.c | 1 +
 hash.h| 7 +++
 name-hash.c   | 1 +
 3 files changed, 9 insertions(+)

diff --git a/diffcore-rename.c b/diffcore-rename.c
index 512d0ac..8d3d9bb 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -389,6 +389,7 @@ static int find_exact_renames(struct diff_options *options)
struct hash_table file_table;
 
init_hash(file_table);
+   preallocate_hash(file_table, (rename_src_nr + rename_dst_nr) * 2);
for (i = 0; i  rename_src_nr; i++)
insert_file_table(file_table, -1, i, rename_src[i].p-one);
 
diff --git a/hash.h b/hash.h
index b875ce6..244d1fe 100644
--- a/hash.h
+++ b/hash.h
@@ -40,4 +40,11 @@ static inline void init_hash(struct hash_table *table)
table-array = NULL;
 }
 
+static inline void preallocate_hash(struct hash_table *table, unsigned int 
size)
+{
+   assert(table-size == 0  table-nr == 0  table-array == NULL);
+   table-size = size;
+   table-array = xcalloc(sizeof(struct hash_table_entry), size);
+}
+
 #endif
diff --git a/name-hash.c b/name-hash.c
index 942c459..1287a19 100644
--- a/name-hash.c
+++ b/name-hash.c
@@ -92,6 +92,7 @@ static void lazy_init_name_hash(struct index_state *istate)
 
if (istate-name_hash_initialized)
return;
+   preallocate_hash(istate-name_hash, istate-cache_nr * 2);
for (nr = 0; nr  istate-cache_nr; nr++)
hash_index_entry(istate, istate-cache[nr]);
istate-name_hash_initialized = 1;
-- 
1.8.1.2.536.gf441e6d

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 12/13] name-hash: allow to lookup a name with precalculated base hash

2013-03-12 Thread Nguyễn Thái Ngọc Duy
index_name_exists_base() differs from index_name_exists() in how the
hash is calculated. It uses the base hash as the seed and skips the
baselen part.

The intention is to reduce hashing cost during directory traversal,
where the hash of the directory is calculated once, and used as base
hash for all entries inside.

This poses a constraint in hash function. The function has not changed
since 2008. With luck it'll never change again. If resuming hashing at
any characters are not feasible with a new (better) hash function,
maybe we could stop at directory boundary.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Makefile  |  1 +
 cache.h   |  2 --
 dir.c |  1 +
 name-hash.c   | 48 ++--
 name-hash.h (new) | 45 +
 read-cache.c  |  1 +
 unpack-trees.c|  1 +
 7 files changed, 71 insertions(+), 28 deletions(-)
 create mode 100644 name-hash.h

diff --git a/Makefile b/Makefile
index 26d3332..8d753af 100644
--- a/Makefile
+++ b/Makefile
@@ -690,6 +690,7 @@ LIB_H += mailmap.h
 LIB_H += merge-blobs.h
 LIB_H += merge-recursive.h
 LIB_H += mergesort.h
+LIB_H += name-hash.h
 LIB_H += notes-cache.h
 LIB_H += notes-merge.h
 LIB_H += notes.h
diff --git a/cache.h b/cache.h
index e493563..cf33c67 100644
--- a/cache.h
+++ b/cache.h
@@ -313,7 +313,6 @@ static inline void remove_name_hash(struct cache_entry *ce)
 #define refresh_cache(flags) refresh_index(the_index, (flags), NULL, NULL, 
NULL)
 #define ce_match_stat(ce, st, options) ie_match_stat(the_index, (ce), (st), 
(options))
 #define ce_modified(ce, st, options) ie_modified(the_index, (ce), (st), 
(options))
-#define cache_name_exists(name, namelen, igncase) 
index_name_exists(the_index, (name), (namelen), (igncase))
 #define cache_name_is_other(name, namelen) index_name_is_other(the_index, 
(name), (namelen))
 #define resolve_undo_clear() resolve_undo_clear_index(the_index)
 #define unmerge_cache_entry_at(at) unmerge_index_entry_at(the_index, at)
@@ -442,7 +441,6 @@ extern int write_index(struct index_state *, int newfd);
 extern int discard_index(struct index_state *);
 extern int unmerged_index(const struct index_state *);
 extern int verify_path(const char *path);
-extern struct cache_entry *index_name_exists(struct index_state *istate, const 
char *name, int namelen, int igncase);
 extern int index_name_pos(const struct index_state *, const char *name, int 
namelen);
 #define ADD_CACHE_OK_TO_ADD 1  /* Ok to add */
 #define ADD_CACHE_OK_TO_REPLACE 2  /* Ok to replace file/directory */
diff --git a/dir.c b/dir.c
index 6809dd2..5fda5af 100644
--- a/dir.c
+++ b/dir.c
@@ -11,6 +11,7 @@
 #include dir.h
 #include refs.h
 #include wildmatch.h
+#include name-hash.h
 
 #ifdef MEASURE_EXCLUDE
 static uint32_t tv_treat_leading_path;
diff --git a/name-hash.c b/name-hash.c
index 1287a19..572d232 100644
--- a/name-hash.c
+++ b/name-hash.c
@@ -7,30 +7,7 @@
  */
 #define NO_THE_INDEX_COMPATIBILITY_MACROS
 #include cache.h
-
-/*
- * This removes bit 5 if bit 6 is set.
- *
- * That will make US-ASCII characters hash to their upper-case
- * equivalent. We could easily do this one whole word at a time,
- * but that's for future worries.
- */
-static inline unsigned char icase_hash(unsigned char c)
-{
-   return c  ~((c  0x40)  1);
-}
-
-static unsigned int hash_name(const char *name, int namelen)
-{
-   unsigned int hash = 0x123;
-
-   while (namelen--) {
-   unsigned char c = *name++;
-   c = icase_hash(c);
-   hash = hash*101 + c;
-   }
-   return hash;
-}
+#include name-hash.h
 
 static void hash_index_entry_directories(struct index_state *istate, struct 
cache_entry *ce)
 {
@@ -152,9 +129,11 @@ static int same_name(const struct cache_entry *ce, const 
char *name, int namelen
return slow_same_name(name, namelen, ce-name, namelen  len ? namelen 
: len);
 }
 
-struct cache_entry *index_name_exists(struct index_state *istate, const char 
*name, int namelen, int icase)
+static inline struct cache_entry *find_entry_by_hash(struct index_state 
*istate,
+const char *name, int 
namelen,
+unsigned int hash,
+int icase)
 {
-   unsigned int hash = hash_name(name, namelen);
struct cache_entry *ce;
 
lazy_init_name_hash(istate);
@@ -189,3 +168,20 @@ struct cache_entry *index_name_exists(struct index_state 
*istate, const char *na
}
return NULL;
 }
+
+struct cache_entry *index_name_exists(struct index_state *istate,
+ const char *name, int namelen,
+ int icase)
+{
+   unsigned int hash = hash_name(name, namelen);
+   return find_entry_by_hash(istate, name, namelen, hash, icase);
+}
+
+struct cache_entry 

[PATCH v3 13/13] read_directory: calculate name hashes incrementally

2013-03-12 Thread Nguyễn Thái Ngọc Duy
Instead of index_name_exists() calculating a hash for full pathname
for every entry, we calculate partial hash per directory, use it as a
seed. The number of characters that icase_hash has to chew will
reduce.

treat_leading_path:   0.000  0.000
read_directory:   1.296  1.235
+treat_one_path:  0.599  0.531
++is_excluded:0.102  0.102
+++prep_exclude:  0.040  0.040
+++matching:  0.035  0.035
++dir_exist:  0.035  0.035
++index_name_exists:  0.292  0.225
lazy_init_name_hash:  0.155  0.155
+simplify_away:   0.082  0.083
+dir_add_name:0.000  0.000

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 dir.c | 44 +---
 1 file changed, 33 insertions(+), 11 deletions(-)

diff --git a/dir.c b/dir.c
index 5fda5af..8638dcd 100644
--- a/dir.c
+++ b/dir.c
@@ -46,6 +46,7 @@ struct path_simplify {
 
 static void read_directory_recursive(struct dir_struct *dir,
 const char *path, int len,
+unsigned int hash,
 int check_only,
 const struct path_simplify *simplify,
 int *contents);
@@ -1044,12 +1045,17 @@ static struct dir_entry *dir_entry_new(const char 
*pathname, int len)
return ent;
 }
 
-static struct dir_entry *dir_add_name(struct dir_struct *dir, const char 
*pathname, int len)
+static struct dir_entry *dir_add_name(struct dir_struct *dir,
+ const char *pathname, int len,
+ unsigned int hash, int baselen)
 {
if (!(dir-flags  DIR_SHOW_IGNORED)) {
struct cache_entry *ce;
START_CLOCK();
-   ce = cache_name_exists(pathname, len, ignore_case);
+   ce = index_name_exists_base(the_index,
+   hash, baselen,
+   pathname, len,
+   ignore_case);
STOP_CLOCK(tv_index_name_exists);
if (ce)
return NULL;
@@ -1225,7 +1231,9 @@ static enum directory_treatment treat_directory(struct 
dir_struct *dir,
if ((dir-flags  DIR_SHOW_IGNORED)  !exclude) {
dir-flags = ~DIR_SHOW_IGNORED;
dir-flags |= DIR_HIDE_EMPTY_DIRECTORIES;
-   read_directory_recursive(dir, dirname, len, 1, simplify, 
contents);
+   read_directory_recursive(dir, dirname, len,
+hash_name(dirname, len),
+1, simplify, contents);
dir-flags = ~DIR_HIDE_EMPTY_DIRECTORIES;
dir-flags |= DIR_SHOW_IGNORED;
 
@@ -1234,7 +1242,9 @@ static enum directory_treatment treat_directory(struct 
dir_struct *dir,
if (!(dir-flags  DIR_SHOW_IGNORED) 
!(dir-flags  DIR_HIDE_EMPTY_DIRECTORIES))
return show_directory;
-   read_directory_recursive(dir, dirname, len, 1, simplify, contents);
+   read_directory_recursive(dir, dirname, len,
+hash_name(dirname, len),
+1, simplify, contents);
if (!contents)
return ignore_directory;
return show_directory;
@@ -1401,6 +1411,8 @@ enum path_treatment {
 
 static enum path_treatment treat_one_path(struct dir_struct *dir,
  struct strbuf *path,
+ unsigned int hash,
+ int baselen,
  const struct path_simplify *simplify,
  int dtype, struct dirent *de,
  int exclude_shortcut_ok)
@@ -1416,7 +1428,8 @@ static enum path_treatment treat_one_path(struct 
dir_struct *dir,
dtype != DT_DIR) {
struct cache_entry *ce;
START_CLOCK();
-   ce = cache_name_exists(path-buf, path-len, ignore_case);
+   ce = index_name_exists_base(the_index, hash, baselen,
+   path-buf, path-len, ignore_case);
STOP_CLOCK(tv_index_name_exists);
if (ce)
return path_ignored;
@@ -1467,6 +1480,7 @@ static enum path_treatment treat_one_path(struct 
dir_struct *dir,
 static enum path_treatment treat_path(struct dir_struct *dir,
  struct dirent *de,
  struct strbuf *path,
+ unsigned int hash,
  int baselen,
  const struct path_simplify *simplify,
  int exclude_shortcut_ok)
@@ -1485,7 +1499,8 @@ static enum 

Updating not actual branch

2013-03-12 Thread Jan Pešta
Hi All,

I have a question if there is a posibility tu update a branch which is not
actual working copy.

I have following situation:

A - B - C - I - J   master
   \ - D - E - F   feature 1
 \ G - H feature 2 (working copy)

I would like tu update whole tree with latest changes in master

A - B - C - I - J  master
   \ - D* - E* - F*  feature 1
   \ G* - H* feature 2
(working copy)


Is there some way how to do it without swithing to each branch and update
them manually?

Thanks,
Jan


--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] require pathspec for git add -u/-A

2013-03-12 Thread Matthieu Moy
Jeff King p...@peff.net writes:

 PS I wonder how others are finding the warning? I'm finding it slightly
annoying. Perhaps I just haven't retrained my fingers yet. But one
problem with that retraining is that I type git add -u from the
root _most_ of the time, and it just works. But occasionally, I get
the hey, do not do that warning, because I'm in a subdir, even
though I would be happy to have the full-tree behavior.

Same here. Not terribly disturbing, but I did get the warning
occasionally, even though I'm the author of the patch introducing
it ;-).

 I guess we already rejected the idea of being able to shut off the
 warning and just get the new behavior, in favor of having people
 specify it manually each time?

Somehow, but we may find a way to do so, as long as it temporary (i.e.
something that will have no effect after the transition period), and
that is is crystal clear that it's temporary.

All proposals up to now were rejected because of the risk of confusing
users (either shutting the warning blindly, or letting people think they
could keep the current behavior after Git 2.0).

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Updating not actual branch

2013-03-12 Thread Konstantin Khomoutov
On Tue, 12 Mar 2013 14:22:00 +0100
Jan Pešta jan.pe...@certicon.cz wrote:

 I have a question if there is a posibility tu update a branch which
 is not actual working copy.
 
 I have following situation:
 
 A - B - C - I - J   master
\ - D - E - F   feature 1
  \ G - H feature 2 (working copy)
 
 I would like tu update whole tree with latest changes in master
 
 A - B - C - I - J  master
\ - D* - E* - F*  feature 1
\ G* - H*
 feature 2 (working copy)
 
 
 Is there some way how to do it without swithing to each branch and
 update them manually?

It's partially possible to do: you are able to forcibly fetch a remote
object into any local branch provided it's not checked out.  Hence, in
your case you'll be able to update any branch excapt for feature 2.

To do this, you could use the explicit refspec when fetching, like this:

$ git fetch origin +src1:dst1 '+blooper 1:feature 1'

(Consult the `git fetch` manual for more info on using refspecs.)

One possible downside is that I'm not sure this approach would play
nicely with remote branches, if you have any.  I mean, direct fetching
into local branches will unlikely to update their matching upstream
remote branches.

So supposedly a better way to go would be to write a script which would
go like this:
1) Do a simple one-argument `git fetch remotename` to fetch from
   the specified remote and update its remote branches.
2) Run `git for-each-ref`, and for each local branch found first check
   whether it's currently checked out (that is, HEAD points at it)
   and ignore the branch if it is; otherwise do `git update-ref`
   updating the branch pointer from its upstream branch -- referring to
   that using the ref@{upstream} syntax.
   (Consult the gitrevisions manual for more info on this syntax.)
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 14/19] Document pull-all and push-all

2013-03-12 Thread Holger Hellmuth (IKS)

Am 09.03.2013 20:28, schrieb Paul Campbell:

 From 7dcd40ab8687a588b7b0c6ff914a7cfb601b6774 Mon Sep 17 00:00:00 2001
From: Herman van Rink r...@initfour.nl
Date: Tue, 27 Mar 2012 13:59:16 +0200
Subject: [PATCH 14/19] Document pull-all and push-all

---
  contrib/subtree/git-subtree.txt | 8 +++-
  1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/contrib/subtree/git-subtree.txt b/contrib/subtree/git-subtree.txt
index e0957ee..c8fc103 100644
--- a/contrib/subtree/git-subtree.txt
+++ b/contrib/subtree/git-subtree.txt
@@ -92,13 +92,19 @@ pull::
Exactly like 'merge', but parallels 'git pull' in that
it fetches the given commit from the specified remote
repository.
-   
+
+pull-all::
+   Perform a pull operation on all in .gittrees registered subtrees.
+
  push::
Does a 'split' (see below) using the prefix supplied
and then does a 'git push' to push the result to the
repository and refspec. This can be used to push your
subtree to different branches of the remote repository.

+push-all::
+   Perform a pull operation on all in .gittrees registered subtrees.

 -
pull-push



+
  split::
Extract a new, synthetic project history from the
history of the prefix subtree.  The new history



--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4] submodule: add 'deinit' command

2013-03-12 Thread Phil Hord
On Wed, Feb 6, 2013 at 4:11 PM, Jens Lehmann jens.lehm...@web.de wrote:
 With git submodule init the user is able to tell git he cares about one
 or more submodules and wants to have it populated on the next call to git
 submodule update. But currently there is no easy way he could tell git he
 does not care about a submodule anymore and wants to get rid of his local
 work tree (except he knows a lot about submodule internals and removes the
 submodule.$name.url setting from .git/config together with the work tree
 himself).

 Help those users by providing a 'deinit' command. This removes the whole
 submodule.name section from .git/config either for the given
 submodule(s) or for all those which have been initialized if '.' is
 given. Fail if the current work tree contains modifications unless
 forced. Complain when for a submodule given on the command line the url
 setting can't be found in .git/config, but nonetheless don't fail.

 Add tests and link the man pages of git submodule deinit and git rm
 to assist the user in deciding whether removing or unregistering the
 submodule is the right thing to do for him.

 Signed-off-by: Jens Lehmann jens.lehm...@web.de


Probably because I was new to this command, I was confused by this output.

  $ git submodule deinit submodule
  rm 'submodule'
  Submodule 'submodule' (gerrit:foo/submodule) unregistered for path 'submodule'

  $ git rm submodule
  rm 'submodule'


This line is confusing to me in the deinit command:

  rm 'submodule'

It doesn't mean what git usually means when it says this to me.  See
how the 'git rm' command says the same thing but means something
different in the next command.

In the deinit case, git removes the workdir contents of 'submodule'
and it reports rm 'submodule'.  In the rm case, git removes the
submodule link from the tree and rmdirs the empty 'submodule'
directory.

I think this would be clearer if 'git deinit' said

rm 'submodule/*'

or maybe

Removed workdir for 'submodule'

Is it just me?

Phil
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/4] config: factor out config file stack management

2013-03-12 Thread Heiko Voigt
On Tue, Mar 12, 2013 at 06:52:00AM -0400, Jeff King wrote:
 On Sun, Mar 10, 2013 at 05:57:53PM +0100, Heiko Voigt wrote:
 
  Because a config callback may start parsing a new file, the
  global context regarding the current config file is stored
  as a stack. Currently we only need to manage that stack from
  git_config_from_file. Let's factor it out to allow new
  sources of config data.
 
  [...]
 
  +static int do_config_from(struct config_file *top, config_fn_t fn, void 
  *data)
  +{
  +   int ret;
  +
  +   /* push config-file parsing state stack */
  +   top-prev = cf;
  +   top-linenr = 1;
  +   top-eof = 0;
  +   strbuf_init(top-value, 1024);
  +   strbuf_init(top-var, 1024);
  +   cf = top;
  +
  +   ret = git_parse_file(fn, data);
  +
  +   /* pop config-file parsing state stack */
  +   strbuf_release(top-value);
  +   strbuf_release(top-var);
  +   cf = top-prev;
  +
  +   return ret;
  +}
 
 Can we throw in a comment at the top here with the expected usage? In
 particular, do_config_from is expecting the caller to have filled in
 certain fields (at this point, top-f and top-name), but there is
 nothing to make that clear.

Of course. Will do that in the next iteration. How about I squash this in:

diff --git a/config.c b/config.c
index b8c8640..b7632c9 100644
--- a/config.c
+++ b/config.c
@@ -948,6 +954,9 @@ int git_default_config(const char *var, const char *value, v
return 0;
 }
 
+/* The fields data, name and the source specific callbacks of top need
+ * to be initialized before calling this function.
+ */
 static int do_config_from_source(struct config_source *top, config_fn_t fn, voi
 {
int ret;


I would add that to the third patch:

config: make parsing stack struct independent from actual data source

because that contains the final modification to config_file/config_source.

Cheers Heiko
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/4] config: drop file pointer validity check in get_next_char()

2013-03-12 Thread Heiko Voigt
On Tue, Mar 12, 2013 at 07:00:03AM -0400, Jeff King wrote:
 On Sun, Mar 10, 2013 at 05:58:57PM +0100, Heiko Voigt wrote:
 
  The only location where cf is set in this file is in do_config_from().
  This function has only one callsite which is config_from_file(). In
  config_from_file() its ensured that the f member is set to non-zero.
  [...]
  -   if (cf  ((f = cf-f) != NULL)) {
  +   if (cf) {
 
 I still think we can drop this conditional entirely. The complete call
 graph looks like:
 
   git_config_from_file
 - git_parse_file
   - get_next_char
   - get_value
   - get_next_char
   - parse_value
   - get_next_char
   - get_base_var
   - get_next_char
   - get_extended_base_var
   - get_next_char
 
 That is, every path to get_next_char happens while we are in
 git_config_from_file, and that function guarantees that cf = top, and
 that top.f != NULL.  We do not have to even do any analysis of the
 conditions for each call, because we never change cf nor top.f
 except when we set them in git_config_from_file.

Ok if you say so I will do that :-). I was thinking about adding a patch
that would remove cf as a global variable and explicitely pass it down
to get_next_char. That makes it more obvious that it actually is != NULL.
Looking at your callgraph I do not think its that much work. What do you
think?

BTW, how did you generate this callgraph? Do you have a nice tool for that?

Cheers Heiko
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH/RFC] Changing submodule foreach --recursive to be depth-first, --parent option to execute command in supermodule as well

2013-03-12 Thread Phil Hord
On Sat, Mar 9, 2013 at 1:18 PM, Jens Lehmann jens.lehm...@web.de wrote:
 Am 05.03.2013 22:17, schrieb Phil Hord:
 On Tue, Mar 5, 2013 at 3:51 PM, Jens Lehmann jens.lehm...@web.de wrote:
 Am 05.03.2013 19:34, schrieb Junio C Hamano:
 Eric Cousineau eacousin...@gmail.com writes:
 ...
 I am not entirely convinced we would want --include-super in the
 first place, though.  It does not belong to submodule foreach;
 it is doing something _outside_ the submoudules.

 I totally agree with that. First, adding --include-super does not
 belong into the --post-order patch at all, as that is a different
 topic (even though it belongs to the same use case Eric has). Also
 the reason why we are thinking about adding the --post-order option
 IMO cuts the other way for --include-super: It is so easy to do
 that yourself I'm not convinced we should add an extra option to
 foreach for that, especially as it has nothing to do with submodules.
 So I think we should just drop --include-super.

 I agree it should not be part of this commit, but I've often found
 myself in need of an --include-super switch.   To me,
 git-submodule-foreach means visit all my .git repos in this project
 and execute $cmd.  It's a pity that the super-project is considered a
 second-class citizen in this regard.

 Hmm, for me the super-project is a very natural second-class citizen
 to git *submodule* foreach. But also I understand that sometimes the
 user wants to apply a command to superproject and submodules alike (I
 just recently did exactly that with git gc on our build server).

 I have to do this sometimes:

${cmd}  git submodule foreach --recursive '${cmd}'

 I often forget the first part in scripts, though, and I've seen others
 do it too.  I usually create a function for it in git-heavy scripts.

 In a shell, it usually goes like this:

git submodule foreach --recursive '${cmd}'
uphomedel{30-ish}endbackspaceenter

 It'd be easier if I could just include a switch for this, and maybe
 even create an alias for it.  But maybe this is different command
 altogether.

 Are you sure you wouldn't forget to provide such a switch too? ;-)

No.  However, when I remember to add the switch, my shell history will
remember it for me.  This does not happen naturally for me in the
uphomedel{30-ish}... workflow.

I also hope this switch grows up into a configuration option someday.
Or maybe a completely different command, like I said before; because I
actually think it could be dangerous as a configuration option since
it would have drastic consequences for users executing scripts or
commands in other users' environments.


 I'm still not convinced we should add a new switch, as it can easily
 be achieved by adding ${cmd}  to your scripts. And on the command
 line you could use an alias like this one to achieve that:

 [alias]
 recurse = !sh -c \$@  git submodule foreach --recursive $@\

Yes, making the feature itself a 2nd-class citizen.  :-)

But this alias also denies me the benefit of the --post-order option.
For 'git recurse git push', for example, I wouldn't want the
superproject push to occur first; I would want it to occur last after
the submodules have been successfully pushed.

I agree this should go in some other commit, but I do not think it is
so trivial it should never be considered as a feature for git.  That's
all I'm trying to say.

Phil
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Updating not actual branch

2013-03-12 Thread Junio C Hamano
Jan Pešta jan.pe...@certicon.cz writes:

 I have following situation:

 A - B - C - I - J   master
\ - D - E - F   feature 1
  \ G - H feature 2 (working copy)

 I would like tu update whole tree with latest changes in master

 A - B - C - I - J  master
\ - D* - E* - F*  feature 1
\ G* - H* feature 2
 (working copy)


 Is there some way how to do it without swithing to each branch and update
 them manually?

With these asterisks I would assume that you are rebasing feature #n
on top of updated master.  As rebasing requires you to have a
working tree, so that you can resolve potential conflicts between
your work and work done on the updated upstream, you fundamentally
would need to check out the branch you work on.

In the case you depicted where feature-1 is a complete subset of
feature-2, you are rebasing both of them, and you do not end up in
a nasty conflict, you could start from this state:

A---B---C master
 \
  D---E---F feature-1
   \
G---H feature-2

update the master from the upstream:

$ git checkout master ; git pull

A---B---C---I---J master
 \
  D---E---F feature-1
   \
G---H feature-2

rebase feature-2 on top of the updated master:

$ git rebase master feature-2

G'--H' feature-2
   /
  D'--E'--F'
 /
A---B---C---I---J master
 \
  D---E---F feature-1
   \
G---H

and finally repoint feature-1 to its updated version:

$ git branch -f feature-1 F'

G'--H' feature-2
   /
  D'--E'--F' feature-1
 /
A---B---C---I---J master
 \
  D---E---F
   \
G---H

Depending on the interaction between commits C..J and C..F, your
rebasing of feature-2 may end up not losing any of D', E' or F'.
Imagine the case where J was committed on the upstream by applying
the same patch as the original E; E' will become redundant and the
result of your git rebase master feature-2 may look like this
instead:

G'--H' feature-2
   /
  D'--F'
 /
A---B---C---I---J master
 \
  D---E---F feature-1
   \
G---H

Or J could remove something E depends on, in which case you may have
to add it back with a new commit X when you rebase feature-2, like
so:

G'--H' feature-2
   /
  D'--X---E'--F'
 /
A---B---C---I---J master
 \
  D---E---F feature-1
   \
G---H

Because you cannot mechanically decide where the tip of updated
feature-1 has to be, you would need to use your brain to decide
where to repoint the tip of feature-1 in the last step.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/4] config: drop file pointer validity check in get_next_char()

2013-03-12 Thread Heiko Voigt
On Tue, Mar 12, 2013 at 05:00:56PM +0100, Heiko Voigt wrote:
 On Tue, Mar 12, 2013 at 07:00:03AM -0400, Jeff King wrote:
  On Sun, Mar 10, 2013 at 05:58:57PM +0100, Heiko Voigt wrote:
  
   The only location where cf is set in this file is in do_config_from().
   This function has only one callsite which is config_from_file(). In
   config_from_file() its ensured that the f member is set to non-zero.
   [...]
   - if (cf  ((f = cf-f) != NULL)) {
   + if (cf) {
  
  I still think we can drop this conditional entirely. The complete call
  graph looks like:
  
git_config_from_file
  - git_parse_file
- get_next_char
- get_value
- get_next_char
- parse_value
- get_next_char
- get_base_var
- get_next_char
- get_extended_base_var
- get_next_char
  
  That is, every path to get_next_char happens while we are in
  git_config_from_file, and that function guarantees that cf = top, and
  that top.f != NULL.  We do not have to even do any analysis of the
  conditions for each call, because we never change cf nor top.f
  except when we set them in git_config_from_file.
 
 Ok if you say so I will do that :-). I was thinking about adding a patch
 that would remove cf as a global variable and explicitely pass it down
 to get_next_char. That makes it more obvious that it actually is != NULL.
 Looking at your callgraph I do not think its that much work. What do you
 think?

I just had a look and unfortunately there are other functions that use
this variable (namely handle_path_include) for which its not that easy
to pass this in. So I will just drop the check here.

Cheers Heiko
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4] submodule: add 'deinit' command

2013-03-12 Thread Junio C Hamano
Phil Hord phil.h...@gmail.com writes:

 I think this would be clearer if 'git deinit' said

 rm 'submodule/*'

 or maybe

 Removed workdir for 'submodule'

 Is it just me?

The latter may probably be better.  

After cloning the superproject, you show interest in individual
submodules by saying git submodule init that submodule and until
then your .git/config in the superproject does not indicate that you
are interested in that submodule, and you won't have a submodule
checkout.

deinit is a way to revert back to that original state; recording
that you are no longer interested in the submodule is the primary
effect, and removal of its checkout is a mere side effect of it.



--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 3/4] config: make parsing stack struct independent from actual data source

2013-03-12 Thread Heiko Voigt
On Tue, Mar 12, 2013 at 07:03:55AM -0400, Jeff King wrote:
 On Sun, Mar 10, 2013 at 05:59:40PM +0100, Heiko Voigt wrote:
 
  diff --git a/config.c b/config.c
  index f55c43d..fe1c0e5 100644
  --- a/config.c
  +++ b/config.c
  @@ -10,20 +10,42 @@
   #include strbuf.h
   #include quote.h
   
  -typedef struct config_file {
  -   struct config_file *prev;
  -   FILE *f;
  +struct config_source {
  +   struct config_source *prev;
  +   void *data;
 
 Would a union be more appropriate here? We do not ever have to pass it
 directly as a parameter, since we pass the struct config_source to the
 method functions.
 
 It's still possible to screw up using a union, but it's slightly harder
 than screwing up using a void pointer. And I do not think we need the
 run-time flexibility offered by the void pointer in this case.

No we do not need the void pointer flexibility. But that means every new
source would need to add to this union. Junio complained about that fact
when I first added the extra members directly to the struct. A union
does not waste that much space and we get some seperation using the
union members. Since this struct is local only I think that should be
ok.

  +static int config_file_fgetc(struct config_source *conf)
  +{
  +   FILE *f = conf-data;
  +   return fgetc(f);
  +}
 
 This could become just:
 
   return fgetc(conf-u.f);
 
 and so forth (might it make sense to give f a more descriptive name,
 as we are adding other sources?).

Will change that.

Cheers Heiko
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 4/4] teach config parsing to read from strbuf

2013-03-12 Thread Heiko Voigt
On Tue, Mar 12, 2013 at 07:18:06AM -0400, Jeff King wrote:
 On Sun, Mar 10, 2013 at 06:00:52PM +0100, Heiko Voigt wrote:
 
  This can be used to read configuration values directly from gits
  database.
  
  Signed-off-by: Heiko Voigt hvo...@hvoigt.net
 
 This is lacking motivation. IIRC, the rest of the story is something
 like ...so we can read .gitmodules directly from the repo or something
 like that?

Will add some more here.

  +struct config_strbuf {
  +   struct strbuf *strbuf;
  +   int pos;
  +};
 
  +static int config_strbuf_fgetc(struct config_source *conf)
  +{
  +   struct config_strbuf *str = conf-data;
 
 Yuck. If you used a union in the previous patch, then this could just go
 inline into the struct config_source.
 
  +int git_config_from_strbuf(config_fn_t fn, const char *name, struct strbuf 
  *strbuf, void *data)
 
 Should this be a const struct strbuf *strbuf? For that matter, is
 there any reason not to take a bare pointer/len combination? It seems
 likely that callers would get the data from read_sha1_file, which means
 they have to stuff it into a strbuf for no good reason.

pointer/len should be fine too. I just used strbuf since when you find
out later that you need to modify the string its easier to handle. A
config parser should not need to do that so I will change that.

  diff --git a/test-config.c b/test-config.c
  new file mode 100644
  index 000..c650837
  --- /dev/null
  +++ b/test-config.c
  @@ -0,0 +1,40 @@
 
 I'm slightly meh on this test-config program.  Having to add a C test
 harness like this is a good indication that we are short-changing users
 of the shell API in favor of builtin C code.

I mainly did this because I needed some test for the config part while
developing the fetch renamed submodules series.

 Your series does not actually add any callers of the new function. The
 obvious patch 5/4 would be to plumb it into git config --blob, and
 then we can just directly test it there (there could be other callers
 besides reading from a blob, of course, but I think the point of the
 series is to head in that direction).

Since this is a split of the series mentioned above there are no real
callers yet. The main reason for the split was that I wanted to reduce
the review burden of one big series into multiple reviews of smaller
chunks. If you think it is useful to add the --blob option I can also
test from there. It could actually be useful to look at certain
.gitmodules options from the submodule script.

Cheers Heiko
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: linux-next: unneeded merge in the security tree

2013-03-12 Thread Linus Torvalds
[ Added Junio and git to the recipients, and leaving a lot of stuff
quoted due to that... ]

On Mon, Mar 11, 2013 at 9:16 PM, Theodore Ts'o ty...@mit.edu wrote:
 On Tue, Mar 12, 2013 at 03:10:53PM +1100, James Morris wrote:
 On Tue, 12 Mar 2013, Stephen Rothwell wrote:
  The top commit in the security tree today is a merge of v3.9-rc2.  This
  is a completely unnecessary merge as the tree before the merge was a
  subset of v3.9-rc1 and so if the merge had been done using anything but
  the tag, it would have just been a fast forward.  I know that this is now
  deliberate behaviour on git's behalf, but isn't there some way we can
  make this easier on maintainers who are just really just trying to pick a
  new starting point for their trees after a release?  (at least I assume
  that is what James was trying to do)

 Yes, and I was merging to a tag as required by Linus.

Now, quite frankly, I'd prefer people not merge -rc tags either, just
real releases. -rc tags are certainly *much* better than merging
random daily stuff, but the basic rule should be don't back-merge AT
ALL rather than back-merge tags.

That said, you didn't really want a merge at all, you just wanted to
sync up and start development. Which is different (but should still
prefer real releases, and only use rc tags if it's fixing stuff that
happened in the merge window - which may be the case here).

 Why not just force the head of the security tree to be v3.9-rc2?  Then
 you don't end up creating a completely unnecessary merge commit, and
 users who were at the previous head of the security tree will
 experience a fast forward when they pull your new head.

So I think that may *technically* be the right solution, but it's a
rather annoying UI issue, partly because you can't just do it in a
single operation (you can't do a pull of the tag to both fetch and
fast-forward it), but partly because git reset --hard is also an
operation that can lose history, so it's something that people should
be nervous about, and shouldn't use as some kind of standard let's
just fast-forward to Linus' tree thing.

At the same time, it's absolutely true that when *I* pull a signed tag
from a downstream developer, I don't want a fast-forward, because then
I'd lose the signature. So when a maintainer pulls a submaintainer
tree, you want the signature to come upstream, but when a
submaintainer wants to just sync up with upstream, you don't want to
generate the pointless signed merge commit, because the signature is
already upstream because it's a public tag. So gthe behavior of git
pull is fundamentally ambiguous.

But git doesn't know the difference between official public upstream
tag and signed tag used to verify the pull request.

I'm adding the git list just to get this issue out there and see if
people have any ideas. I've got a couple of workarounds, but they
aren't wonderful..

One is simple:

git config alias.sync=pull --ff-only

which works fine, but forces submaintainers to be careful when doing
things like this, and using a special command to do back-merges.

And maybe that's the right thing to do? Back-merges *are* special,
after all. But the above alias is particularly fragile, in that
there's both pull and merge that people want to use this for, and
it doesn't really handle both. And --ff-only will obviously fail if
you actually have some work in your tree, and want to do a real merge,
so then you have to do that differently. So I'm mentioning this as a
better model than git reset, but not really a *solution*.

That said, the fact that --ff-only errors out if you have local
development may actually be a big bonus - because you really shouldn't
do merges at all if you have local development, but syncing up to my
tree if you don't have it (and are going to start it) may be something
reasonable.

Now, the other approach - and perhaps preferable, but requiring actual
changes to git itself - is to do the non-fast-forward merge *only* for
FETCH_HEAD, which already has magic semantics in other ways. So if
somebody does

git fetch linus
git merge v3.8

to sync with me, they would *not* get a merge commit with a signature,
just a fast-forward. But if you do

git pull linus v3.8

or a

git fetch linus v3.8
git merge FETCH_HEAD

it would look like a maintainer merge and stash the signature in the
merge commit rather than fast-forward. It would probably work in
practice.

The final approach might be to make it like the merge summary and
simply make it configurable _and_ have a command line flag for it,
defaulting to our current behavior or to the above suggested default
on for FETCH_HEAD, off for anything else.

Hmm?

Linus
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 04/13] match_basename: use strncmp instead of strcmp

2013-03-12 Thread Antoine Pelisse
 --- a/dir.c
 +++ b/dir.c
 @@ -636,12 +636,14 @@ int match_basename(const char *basename, int 
 basenamelen,
int flags)
  {
 if (prefix == patternlen) {
 -   if (!strcmp_icase(pattern, basename))
 +   if (patternlen == basenamelen 
 +   !strncmp_icase(pattern, basename, patternlen))
 return 1;
 } else if (flags  EXC_FLAG_ENDSWITH) {
 if (patternlen - 1 = basenamelen 
 -   !strcmp_icase(pattern + 1,
 - basename + basenamelen - patternlen + 1))
 +   !strncmp_icase(pattern + 1,
 +  basename + basenamelen - patternlen + 1,
 +  patternlen - 1))
 return 1;


I can see that you kept strncmp(), was it worse with memcmp() ?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: linux-next: unneeded merge in the security tree

2013-03-12 Thread Geert Uytterhoeven
On Tue, Mar 12, 2013 at 6:13 PM, Linus Torvalds
torva...@linux-foundation.org wrote:
 Why not just force the head of the security tree to be v3.9-rc2?  Then
 you don't end up creating a completely unnecessary merge commit, and
 users who were at the previous head of the security tree will
 experience a fast forward when they pull your new head.

 So I think that may *technically* be the right solution, but it's a
 rather annoying UI issue, partly because you can't just do it in a
 single operation (you can't do a pull of the tag to both fetch and
 fast-forward it), but partly because git reset --hard is also an
 operation that can lose history, so it's something that people should
 be nervous about, and shouldn't use as some kind of standard let's
 just fast-forward to Linus' tree thing.

In many cases, git rebase x does the exact same thing as
git reset --hard x, with an added safeguard: if you forgot to upstream
something, it'll boil up on top of x.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say programmer or something like that.
-- Linus Torvalds
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: difftool -d symlinks, under what conditions

2013-03-12 Thread Matt McClure
On Tue, Nov 27, 2012 at 7:41 AM, Matt McClure matthewlmccl...@gmail.com wrote:

 On Tuesday, November 27, 2012, David Aguilar wrote:

 It seems that there is an edge case here that we are not
 accounting for: unmodified worktree paths, when checked out
 into the temporary directory, can be edited by the tool when
 comparing against older commits.  These edits will be lost.


 Yes. That is exactly my desired use case. I want to make edits while I'm 
 reviewing the diff.

I took a crack at implementing the change to make difftool -d use
symlinks more aggressively. I've tested it lightly, and it works for
the limited cases I've tried. This is my first foray into the Git
source code, so it's entirely possible that there are unintended side
effects and regressions if other features depend on the same code path
and make different assumptions.

https://github.com/matthewlmcclure/git/compare/difftool-directory-symlink-work-tree

Your thoughts on the change?

--
Matt McClure
http://www.matthewlmcclure.com
http://www.mapmyfitness.com/profile/matthewlmcclure
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/4] config: factor out config file stack management

2013-03-12 Thread Jeff King
On Tue, Mar 12, 2013 at 04:44:35PM +0100, Heiko Voigt wrote:

  Can we throw in a comment at the top here with the expected usage? In
  particular, do_config_from is expecting the caller to have filled in
  certain fields (at this point, top-f and top-name), but there is
  nothing to make that clear.
 
 Of course. Will do that in the next iteration. How about I squash this in:
 [...]
 +/* The fields data, name and the source specific callbacks of top need
 + * to be initialized before calling this function.
 + */
  static int do_config_from_source(struct config_source *top, config_fn_t fn, 
 voi

I think that is OK, but it may be even better to list the fields by
name. Also, our multi-line comment style is:

  /*
   * Multi-line comment.
   */


 I would add that to the third patch:
 
   config: make parsing stack struct independent from actual data source
 
 because that contains the final modification to config_file/config_source.

It does not matter to the end result, but I find it helps with reviewing
when the comment is added along with the function, and then expanded as
the function is changed. It helps to understand the effects of later
patches if they need to tweak comments.

I do not care that much in this instance, since we have already
discussed it, and I know what is going on, though.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/4] config: drop file pointer validity check in get_next_char()

2013-03-12 Thread Jeff King
On Tue, Mar 12, 2013 at 05:00:56PM +0100, Heiko Voigt wrote:

  That is, every path to get_next_char happens while we are in
  git_config_from_file, and that function guarantees that cf = top, and
  that top.f != NULL.  We do not have to even do any analysis of the
  conditions for each call, because we never change cf nor top.f
  except when we set them in git_config_from_file.
 
 Ok if you say so I will do that :-). I was thinking about adding a patch
 that would remove cf as a global variable and explicitely pass it down
 to get_next_char. That makes it more obvious that it actually is != NULL.
 Looking at your callgraph I do not think its that much work. What do you
 think?

Yeah, I think that makes it more obvious what is going on, but you will
run into trouble if you ever want that information to cross the void *
boundary of a config callback, as adding a new parameter there is hard.

The only place we do that now is for git_config_include, and I think you
could get by with stuffing it into the config_include_data struct (which
is already there to deal with this problem).

It would also make something like this patch hard or impossible:

  http://article.gmane.org/gmane.comp.version-control.git/190267

as it wants to access cf from arbitrary callbacks. That is not a patch
that is actively under consideration, but I had considered polishing it
up at some point.

 BTW, how did you generate this callgraph? Do you have a nice tool for that?

I just did it manually in vi, working backwards from every instance of
get_next_char, as it is not that big a graph. I suspect something like
cscope could make it easier, but I don't know of any tool that will
build the graph automatically (it would not be that hard from the data
cscope has, though, so I wouldn't be surprised if such a tool exists).

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: difftool -d symlinks, under what conditions

2013-03-12 Thread David Aguilar
On Tue, Mar 12, 2013 at 12:09 PM, John Keeping j...@keeping.me.uk wrote:
 On Tue, Mar 12, 2013 at 02:12:29PM -0400, Matt McClure wrote:
 On Tue, Nov 27, 2012 at 7:41 AM, Matt McClure matthewlmccl...@gmail.com 
 wrote:
 Your thoughts on the change?

 Please include the patch in your message so that interested parties can
 comment on it here, especially since the compare view on GitHub seems to
 mangle the tabs.

 For others' reference the patch is:

 -- 8 --
 From: Matt McClure matt.mccl...@mapmyfitness.com
 Subject: [PATCH] difftool: Make directory diff symlink work tree

 difftool -d formerly knew how to symlink to the work tree when the work
 tree contains uncommitted changes. In practice, prior to this change, it
 would not symlink to the work tree in case there were no uncommitted
 changes, even when the user invoked difftool with the form:

 git difftool -d [--options] commit [--] [path...]
 This form is to view the changes you have in your working tree
 relative to the named commit. You can use HEAD to compare it
 with the latest commit, or a branch name to compare with the tip
 of a different branch.

 Instead, prior to this change, difftool would use the file's HEAD blob
 sha1 to find its content rather than the work tree content. This change
 teaches `git diff --raw` to emit the null SHA1 for consumption by
 difftool -d, so that difftool -d will use a symlink rather than a copy
 of the file.

 Before:

 $ git diff --raw HEAD^ -- diff-lib.c
 :100644 100644 f35de0f... ead9399... M  diff-lib.c

 After:

 $ ./git diff --raw HEAD^ -- diff-lib.c
 :100644 100644 f35de0f... 000... M  diff-lib.c


Interesting approach.  While this does get the intended behavior
for difftool, I'm afraid this would be a grave regression for
existing git diff --raw users who cannot have such behavior.

I don't think we could do this without adding an additional flag
to trigger this change in behavior (e.g. --null-sha1-for-?)
so that existing users are unaffected by the change.

It feels like forcing the null SHA-1 is heavy-handed, but I
haven't thought it through enough.

While this may be a quick way to get this behavior,
I wonder if there is a better way.

Does anybody else have any comments/suggestions on how to
better accomplish this?


 ---
  diff-lib.c | 4 
  1 file changed, 4 insertions(+)

 diff --git a/diff-lib.c b/diff-lib.c
 index f35de0f..ead9399 100644
 --- a/diff-lib.c
 +++ b/diff-lib.c
 @@ -319,6 +319,10 @@ static int show_modified(struct rev_info *revs,
 return -1;
 }

 +   if (!cached  hashcmp(old-sha1, new-sha1)) {
 +   sha1 = null_sha1;
 +   }
 +
 if (revs-combine_merges  !cached 
 (hashcmp(sha1, old-sha1) || hashcmp(old-sha1, new-sha1))) {
 struct combine_diff_path *p;
 --
 1.8.2.rc2.4.g7799588




-- 
David
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] difftool: Make directory diff symlink work tree

2013-03-12 Thread John Keeping
 difftool -d formerly knew how to symlink to the work tree when the work
 tree contains uncommitted changes. In practice, prior to this change, it
 would not symlink to the work tree in case there were no uncommitted
 changes, even when the user invoked difftool with the form:
 
 git difftool -d [--options] commit [--] [path...]
 This form is to view the changes you have in your working tree
 relative to the named commit. You can use HEAD to compare it
 with the latest commit, or a branch name to compare with the tip
 of a different branch.
 
 Instead, prior to this change, difftool would use the file's HEAD blob
 sha1 to find its content rather than the work tree content. This change
 teaches `git diff --raw` to emit the null SHA1 for consumption by
 difftool -d, so that difftool -d will use a symlink rather than a copy
 of the file.
 
 Before:
 
 $ git diff --raw HEAD^ -- diff-lib.c
 :100644 100644 f35de0f... ead9399... M  diff-lib.c
 
 After:
 
 $ ./git diff --raw HEAD^ -- diff-lib.c
 :100644 100644 f35de0f... 000... M  diff-lib.c

When I tried this I got the expected behaviour even without this patch.

It turns out that an uncommitted, but *staged* change emits the SHA1 of
the blob rather than the null SHA1.  Do you get the desired behaviour if
you git reset before using difftool?

If so I think you want some new mode of operation for difftool instead
of this patch which will also affect unrelated commands.

 ---
  diff-lib.c | 4 
  1 file changed, 4 insertions(+)
 
 diff --git a/diff-lib.c b/diff-lib.c
 index f35de0f..ead9399 100644
 --- a/diff-lib.c
 +++ b/diff-lib.c
 @@ -319,6 +319,10 @@ static int show_modified(struct rev_info *revs,
   return -1;
   }
  
 + if (!cached  hashcmp(old-sha1, new-sha1)) {
 + sha1 = null_sha1;
 + }
 +
   if (revs-combine_merges  !cached 
   (hashcmp(sha1, old-sha1) || hashcmp(old-sha1, new-sha1))) {
   struct combine_diff_path *p;
 -- 
 1.8.2.rc2.4.g7799588
 
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 3/4] config: make parsing stack struct independent from actual data source

2013-03-12 Thread Jeff King
On Tue, Mar 12, 2013 at 05:27:35PM +0100, Heiko Voigt wrote:

  Would a union be more appropriate here? We do not ever have to pass it
  directly as a parameter, since we pass the struct config_source to the
  method functions.
  
  It's still possible to screw up using a union, but it's slightly harder
  than screwing up using a void pointer. And I do not think we need the
  run-time flexibility offered by the void pointer in this case.
 
 No we do not need the void pointer flexibility. But that means every new
 source would need to add to this union. Junio complained about that fact
 when I first added the extra members directly to the struct. A union
 does not waste that much space and we get some seperation using the
 union members. Since this struct is local only I think that should be
 ok.

Right. I think that is not a big deal, as we are not exposing this
struct outside of the config.c; any additions would need to add a new
git_config_from_foo function, anyway.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 4/4] teach config parsing to read from strbuf

2013-03-12 Thread Jeff King
On Tue, Mar 12, 2013 at 05:42:54PM +0100, Heiko Voigt wrote:

  Your series does not actually add any callers of the new function. The
  obvious patch 5/4 would be to plumb it into git config --blob, and
  then we can just directly test it there (there could be other callers
  besides reading from a blob, of course, but I think the point of the
  series is to head in that direction).
 
 Since this is a split of the series mentioned above there are no real
 callers yet. The main reason for the split was that I wanted to reduce
 the review burden of one big series into multiple reviews of smaller
 chunks. If you think it is useful to add the --blob option I can also
 test from there. It could actually be useful to look at certain
 .gitmodules options from the submodule script.

I am on the fence. I do not want to create more work for you, but I do
think it may come in handy, if only for doing submodule things from
shell. And it is hopefully not a very large patch. I'd say try it, and
if starts looking like it will be very ugly, the right thing may be to
leave it until somebody really wants it.

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: linux-next: unneeded merge in the security tree

2013-03-12 Thread Junio C Hamano
Linus Torvalds torva...@linux-foundation.org writes:

 One is simple:

 git config alias.sync=pull --ff-only

Heh, I just wrote that myself after reading the early part of this
message ;-)

 which works fine, but forces submaintainers to be careful when doing
 things like this, and using a special command to do back-merges.

 And maybe that's the right thing to do? Back-merges *are* special,

Yes.

 after all. But the above alias is particularly fragile, in that
 there's both pull and merge that people want to use this for, and
 it doesn't really handle both. And --ff-only will obviously fail if
 you actually have some work in your tree, and want to do a real merge,
 so then you have to do that differently. So I'm mentioning this as a
 better model than git reset, but not really a *solution*.

 That said, the fact that --ff-only errors out if you have local
 development may actually be a big bonus - because you really shouldn't
 do merges at all if you have local development, but syncing up to my
 tree if you don't have it (and are going to start it) may be something
 reasonable.

Yes, that's the reasoning behind all the behaviours you described
above.

 Now, the other approach - and perhaps preferable, but requiring actual
 changes to git itself - is to do the non-fast-forward merge *only* for
 FETCH_HEAD, which already has magic semantics in other ways. So if
 somebody does

 git fetch linus
 git merge v3.8

 to sync with me, they would *not* get a merge commit with a signature,
 just a fast-forward. But if you do

 git pull linus v3.8

 or a

 git fetch linus v3.8
 git merge FETCH_HEAD

 it would look like a maintainer merge

I am not sure I follow.  Are you solving the real problem, the
pointeless merge in the security tree that started this thread?

I would imagine it was made by somebody thinking that pulling a
tagged stable point from you is a good idea, like this:

git pull linus v3.9-rc2

which under your FETCH_HEAD rule would look like a maintainer merge,
no?

An alternative may be to activate the magic mergetag thing only
when you give --no-ff explicitly; otherwise merge would unwrap the
tag, whether it comes from FETCH_HEAD.

The following examples all assume that your HEAD is somewhere
behind v3.9-rc2, perhaps done by

git checkout -b test v3.8^0

Then under the --no-ff activates the magic rule:

git merge v3.9-rc2

will fast-forward, but this

git merge --no-ff v3.9-rc2

creates a real merge with the mergetag signature block.  The one
that caused trouble in the security tree, i.e.

git pull linus v3.9-rc2

or its equivalent

git fetch linus v3.9-rc2
git merge FETCH_HEAD

would still fast-forward under this rule.  The maintainer needs to
do

git pull --no-ff git://git.kernel.org/... for-linus

if the pull could fast-forward under this rule, though.

Having thought this up to this point, I am not sure it generally is
a good change.  It feels that pull --ff-only that prevents people
from creating pointless back-merges may still be a better mechanism.

I dunno.

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: linux-next: unneeded merge in the security tree

2013-03-12 Thread Junio C Hamano
Junio C Hamano gits...@pobox.com writes:

 Then under the --no-ff activates the magic rule:

   git merge v3.9-rc2

 will fast-forward, but this

   git merge --no-ff v3.9-rc2

 creates a real merge with the mergetag signature block.  The one
 that caused trouble in the security tree, i.e.

 git pull linus v3.9-rc2

 or its equivalent

 git fetch linus v3.9-rc2
 git merge FETCH_HEAD

 would still fast-forward under this rule.  The maintainer needs to
 do

   git pull --no-ff git://git.kernel.org/... for-linus

 if the pull could fast-forward under this rule, though.

Scratch the last sentence.  It should have been

whether the pull fast-forwards or not.  You'd always need to.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: difftool -d symlinks, under what conditions

2013-03-12 Thread Junio C Hamano
David Aguilar dav...@gmail.com writes:

 Interesting approach.  While this does get the intended behavior
 for difftool, I'm afraid this would be a grave regression for
 existing git diff --raw users who cannot have such behavior.

The 0{40} in RHS of --raw output is to say that we do not know what
object name the contents at the path hashes to.

If you run git diff HEAD^ for a path that is different between
HEAD and the index for which you do not have a local change in the
working tree, we have to show the path (because it is different
between the working tree and HEAD^), but we know the object name for
copy in the working tree, simply because we know it matches what is
in the index.  Showing 0{40} on the RHS in such a case loses
information, making us say We don't know when we perfectly well
know.  That is a regression.

If the user is allowed to touch any random file in the working tree,
I do not see a workable solution other than John Keeping's follow-up
patch to make symlinks of all paths involved.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: difftool -d symlinks, under what conditions

2013-03-12 Thread Junio C Hamano
John Keeping j...@keeping.me.uk writes:

 How about something like --symlink-all where the everything in the
 right-hand tree is symlink'd?

Does it even have to be conditional?  What is the situation when you
do not want symbolic links?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 3/6] match_basename: use strncmp instead of strcmp

2013-03-12 Thread Junio C Hamano
Duy Nguyen pclo...@gmail.com writes:

 glibc's C strncmp version does 4-byte comparison at a time when n =4,
 then fall back to 1-byte for the rest. I don't know if it's faster
 than a plain always 1-byte comparison though. There's also the hand
 written assembly version that compares n from 1..16, not exactly sure
 how this version works yet.

It sounds to me more like a very popular implementation of
strcmp/strncmp pair found to have more optimized strncmp than
strcmp.  While that may be a good reason to justify this patch,
I do not think it justifies this:

 strncmp is provided length information which could be taken advantage
 by the underlying implementation.

After all, strcmp() could also be optimized to fetch word-at-a-time
while being careful about not overstepping the page boundary.


--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: difftool -d symlinks, under what conditions

2013-03-12 Thread John Keeping
On Tue, Mar 12, 2013 at 01:39:17PM -0700, Junio C Hamano wrote:
 John Keeping j...@keeping.me.uk writes:
 
  How about something like --symlink-all where the everything in the
  right-hand tree is symlink'd?
 
 Does it even have to be conditional?  What is the situation when you
 do not want symbolic links?

When you're not comparing the working tree.

If we can reliably say the RHS is the working tree then it could be
unconditional, but I haven't thought about how to do that - I can't see
a particularly easy way to check for that; is it sufficient to say
there is no more than one non-option to the left of '--' and '--cached'
is not among the options?


John
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: linux-next: unneeded merge in the security tree

2013-03-12 Thread Theodore Ts'o
What if we added the ability to do something like this:

[remote origin]
url = 
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
fetch = +refs/heads/master:refs/heads/master
mergeoptions = --ff-only

This would be an analog to branch.name.mergeoptions, but it would
apply to the source of the pull request, instead of the destination.

That way, people who do a git pull from Linus's tree would get the
protection of --ff-only, while pulls from submaintainer trees would
automatically get a merge commit, which is what we want.

It doesn't handle the case of a submaintainer pulling from a
maintainer in a back-merge scenario, but that should be a pretty rare
case, so maybe that's OK.

- Ted
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: difftool -d symlinks, under what conditions

2013-03-12 Thread Junio C Hamano
John Keeping j...@keeping.me.uk writes:

 Does it even have to be conditional?  What is the situation when you
 do not want symbolic links?

 When you're not comparing the working tree.

OK, so what you want is essentially:

 * If you see 0{40} in diff --raw, you *know* you are showing the working tree
   file on the RHS, and you want to symlink, so that the edit made
   by the user will be reflected back to theh working tree copy.
 
 * If your working tree file match what is in the index, you won't
   see 0{40} but you still want to symlink, for the same reason.

 * If you are comparing two trees, and especially if your RHS is not
   HEAD, you will send everything to a temporary without
   symlinks. Any edit made by the user will be lost.

If that is the case, perhaps the safest way to go may be to write
the object out when you see non 0{40}, compare it with the working
tree version and then turn that into symlink?  That way, you not
only cover the second bullet point, but also cover half of the third
one where the user may find a bug in the RHS, update it in difftool.

I am assuming that you are write-protecting the non-symlink files in
the temporary tree (i.e. those that do not match the working tree)
to prevent users from accidentally modifying something there is no
place to save back to.

Hrm?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: linux-next: unneeded merge in the security tree

2013-03-12 Thread Linus Torvalds
On Tue, Mar 12, 2013 at 2:20 PM, Theodore Ts'o ty...@mit.edu wrote:
 What if we added the ability to do something like this:

 [remote origin]
 url = 
 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
 fetch = +refs/heads/master:refs/heads/master
 mergeoptions = --ff-only

Hmm. Something like this could be interesting for other things:

 - use --rebase when pulling (this is common for people who maintain
a set of patches and do *not* export their git tree - I use it for
projects like git and subsurface where there is an upstream maintainer
and I usually send patches by email rather than git)

 - --no-summary. As a maintainer, you people probably do want to
enable summaries for people they pull from, but *not* from upstream.
So this might even make sense to do by default when you clone a new
repository.

 - I do think that we might want a --no-signatures for the specific
case of merging signed tags without actually taking the signature
(because it's a upstream repo). The --ff-only thing is *too*
strict. Sometimes you really do want to merge in new code, disallowing
it entirely is tough.

Of course, I'm not really sure if we want to list the flags. Maybe
it's better to just introduce the notion of upstream directly, and
make that a flag, and make origin default to that when you clone.
And then have git use different heurstics for pulling upstream (like
warning by default when doing a back-merge, perhaps?)

   Linus
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: linux-next: unneeded merge in the security tree

2013-03-12 Thread Junio C Hamano
Theodore Ts'o ty...@mit.edu writes:

 What if we added the ability to do something like this:

 [remote origin]
   url = 
 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
   fetch = +refs/heads/master:refs/heads/master
   mergeoptions = --ff-only

 This would be an analog to branch.name.mergeoptions, but it would
 apply to the source of the pull request, instead of the destination.

 That way, people who do a git pull from Linus's tree would get the
 protection of --ff-only, while pulls from submaintainer trees would
 automatically get a merge commit, which is what we want.

 It doesn't handle the case of a submaintainer pulling from a
 maintainer in a back-merge scenario, but that should be a pretty rare
 case, so maybe that's OK.

Is there an escape hatch for that rare case?  IOW, how does a
submaintainer who configured the above to override --ff-only?

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: difftool -d symlinks, under what conditions

2013-03-12 Thread Matt McClure
On Tue, Mar 12, 2013 at 5:06 PM, John Keeping j...@keeping.me.uk wrote:
 On Tue, Mar 12, 2013 at 01:39:17PM -0700, Junio C Hamano wrote:

 What is the situation when you do not want symbolic links?

 When you're not comparing the working tree.

 If we can reliably say the RHS is the working tree then it could be
 unconditional, but I haven't thought about how to do that - I can't see
 a particularly easy way to check for that;

Agreed. From what I can see, the only form of the diff options that
compares against the working tree is

git difftool -d [--options] commit [--] [path...]

At first, I thought that the following cases were also working tree
cases, but actually they use the HEAD commit.

git difftool -d commit1..
git difftool -d commit1...

 is it sufficient to say
 there is no more than one non-option to the left of '--' and '--cached'
 is not among the options?

An alternative approach would be to reuse git-diff's option parsing
and make it tell git-difftool when git-diff sees the working tree
case. At this point, I haven't seen an obvious place in the source
where git-diff makes that choice, but if someone could point me in the
right direction, I think I'd actually prefer that approach. What do
you think?

--
Matt McClure
http://www.matthewlmcclure.com
http://www.mapmyfitness.com/profile/matthewlmcclure
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: linux-next: unneeded merge in the security tree

2013-03-12 Thread Junio C Hamano
Linus Torvalds torva...@linux-foundation.org writes:

  - I do think that we might want a --no-signatures for the specific
 case of merging signed tags without actually taking the signature
 (because it's a upstream repo). The --ff-only thing is *too*
 strict. Sometimes you really do want to merge in new code, disallowing
 it entirely is tough.

I agree that --ff-only thing is too strict and sometimes you would
want to allow back-merges, but when you do allow such a back-merge,
is there a reason you want it to be --no-signatures merge?  When a
subtree maintainer decides to merge a stable release point from you
with a good reason, I do not see anything wrong in recording that
the resulting commit _did_ merge what you released with a signature.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: linux-next: unneeded merge in the security tree

2013-03-12 Thread Linus Torvalds
On Tue, Mar 12, 2013 at 2:47 PM, Junio C Hamano gits...@pobox.com wrote:

 I agree that --ff-only thing is too strict and sometimes you would
 want to allow back-merges, but when you do allow such a back-merge,
 is there a reason you want it to be --no-signatures merge?  When a
 subtree maintainer decides to merge a stable release point from you
 with a good reason, I do not see anything wrong in recording that
 the resulting commit _did_ merge what you released with a signature.

No, there's nothing really bad with adding the signature to the merge
commit if you do make a merge. It's the fact that it currently makes a
non-ff merge when that is pointless that hurts.

That said, adding the signature from an upstream tag doesn't really
seem to be hugely useful. I'm not seeing much of an upside, in other
words. I'd *expect* that people would pick up upstream tags
regardless, no?

   Linus
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: linux-next: unneeded merge in the security tree

2013-03-12 Thread Junio C Hamano
Linus Torvalds torva...@linux-foundation.org writes:

 That said, adding the signature from an upstream tag doesn't really
 seem to be hugely useful. I'm not seeing much of an upside, in other
 words. I'd *expect* that people would pick up upstream tags
 regardless, no?

Yes, their git fetch will auto-follow, but mergetag embedded in
the commit objects will give the history auditable trail the same
way as the merges you make your downstream.  You of course could
match out-of-line tags against back-merges and verify your merges
with mergetags, but you do not have to.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: difftool -d symlinks, under what conditions

2013-03-12 Thread Matt McClure
On Tue, Mar 12, 2013 at 5:43 PM, Matt McClure matthewlmccl...@gmail.com wrote:
 On Tue, Mar 12, 2013 at 5:06 PM, John Keeping j...@keeping.me.uk wrote:

 is it sufficient to say
 there is no more than one non-option to the left of '--' and '--cached'
 is not among the options?

 An alternative approach would be to reuse git-diff's option parsing
 and make it tell git-difftool when git-diff sees the working tree
 case. At this point, I haven't seen an obvious place in the source
 where git-diff makes that choice, but if someone could point me in the
 right direction, I think I'd actually prefer that approach. What do
 you think?

There's an interesting comment in cmd_diff:

/*
* We could get N tree-ish in the rev.pending_objects list.
* Also there could be M blobs there, and P pathspecs.
*
* N=0, M=0:
* cache vs files (diff-files)
* N=0, M=2:
*  compare two random blobs.  P must be zero.
* N=0, M=1, P=1:
* compare a blob with a working tree file.
*
* N=1, M=0:
*  tree vs cache (diff-index --cached)
*
* N=2, M=0:
*  tree vs tree (diff-tree)
*
* N=0, M=0, P=2:
*  compare two filesystem entities (aka --no-index).
*
* Other cases are errors.
*/

whereas inspecting rev.pending in the compare against working tree
case, I see:

(gdb) p rev.pending
$3 = {
  nr = 1,
  alloc = 64,
  objects = 0x100807a00
}
(gdb) p *rev.pending.objects
$4 = {
  item = 0x100831a48,
  name = 0x7fff5fbff8f8 HEAD^,
  mode = 12288
}

Given the cases listed in the comment, I assume cmd_diff must
interpret this case as:

* N=1, M=0:
*  tree vs cache (diff-index --cached)

The description of that case is confusing or wrong given that
git-diff-index(1) says:

   --cached
   do not consider the on-disk file at all

***

cmd_diff executes this case:

else if (ents == 1)
result = builtin_diff_index(rev, argc, argv);

So it looks like I could short-circuit in builtin_diff_index or
something it calls -- e.g., run_diff_index -- to get git-diff to tell
git-difftool that it's the working tree case. I see that
run_diff_index does:

diff_set_mnemonic_prefix(revs-diffopt, c/, cached ? i/ : w/);

So that looks like a good place where the code is already deciding
that it's the working tree case -- w/, though surprisingly to me:

(gdb) p revs-diffopt
$12 = {
...
  a_prefix = 0x1001c25aa a/,
  b_prefix = 0x1001c25ad b/,
...

So diff_set_mnemonic_prefix doesn't actually use the w/ value passed
to it because:

if (!options-b_prefix)
options-b_prefix = b;

Maybe if I could prevent b_prefix from getting set earlier, I could
get some variant of git-diff to emit the w/ for git-difftool.

--
Matt McClure
http://www.matthewlmcclure.com
http://www.mapmyfitness.com/profile/matthewlmcclure
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: difftool -d symlinks, under what conditions

2013-03-12 Thread Junio C Hamano
Matt McClure matthewlmccl...@gmail.com writes:

 An alternative approach would be to reuse git-diff's option parsing
 and make it tell git-difftool when git-diff sees the working tree
 case. At this point, I haven't seen an obvious place in the source
 where git-diff makes that choice, but if someone could point me in the
 right direction, I think I'd actually prefer that approach. What do
 you think?

I do not think you want to go there.  That wouldn't solve the third
case in my previous message, no?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v8 2/5] blame: introduce $ as end of file in -L syntax

2013-03-12 Thread Junio C Hamano
Junio C Hamano gits...@pobox.com writes:

 Thomas Rast tr...@student.ethz.ch writes:

 To save the user a lookup of the last line number, introduce $ as a
 shorthand for the last line.  This is mostly useful to spell until
 the end of the file as '-Lbegin,$'.

 Doesn't -L begin or -L begin, do that already?  If it were
 to introduce -L $-4, or -L$-4,+2, I would understand why the
 addition may be useful, but otherwise I do not think it adds much
 value.

It is a quiet-period so there is no need to rush, but did anything
happened further on this series?

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: difftool -d symlinks, under what conditions

2013-03-12 Thread Matt McClure
On Mar 12, 2013, at 4:16 PM, Junio C Hamano gits...@pobox.com wrote:

 Matt McClure matthewlmccl...@gmail.com writes:

 An alternative approach would be to reuse git-diff's option parsing

 I do not think you want to go there.  That wouldn't solve the third
 case in my previous message, no?

I think I don't fully understand your third bullet.

 * If you are comparing two trees, and especially if your RHS is not
   HEAD, you will send everything to a temporary without
   symlinks. Any edit made by the user will be lost.

I think you're suggesting to use a symlink any time the content of any
given RHS revision is the same as the working tree.

I imagine that might confuse me as a user. It would create
circumstances where some files are symlinked and others aren't for
reasons that won't be straightforward.

I imagine solving that case, I might instead implement a copy back to
the working tree with conflict detection/resolution. Some earlier
iterations of the directory diff feature used copy back without
conflict detection and created situations where I clobbered my own
changes by finishing a directory diff after making edits concurrently.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] difftool: Make directory diff symlink work tree

2013-03-12 Thread Matt McClure
On Mar 12, 2013, at 1:25 PM, John Keeping j...@keeping.me.uk wrote:

 When I tried this I got the expected behaviour even without this patch.

git diff --raw commit

emits the null SHA1 if the working tree file's stat differs from the
blob corresponding to commit. Is that the case you observed?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 09/13] exclude: filter out patterns not applicable to the current directory

2013-03-12 Thread Eric Sunshine
On Tue, Mar 12, 2013 at 9:04 AM, Nguyễn Thái Ngọc Duy pclo...@gmail.com wrote:
 The algorithm implemented here is a naive one. Patterns can be either
 active or passive:

  - When we enter a new directory (e.g. from root to foo), currently
active patterns may no longer be applicable and can be turned to
passive.

  - On the opposite, when we leave a directory (foo back to roo),

s/roo/root/

Also, perhaps you meant s/On/Or/ ?

 +/*
 + * If pushed is non-zero, we have entered a new directory. Some
 + * pathname patterns may no longer applicable. Go over all active

s/applicable/be applicable/

-- ES
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH] Documentation/technical/api-fswatch.txt: start with outline

2013-03-12 Thread Karsten Blees
Am 10.03.2013 21:17, schrieb Ramkumar Ramachandra:
 git operations are slow on repositories with lots of files, and lots
 of tiny filesystem calls like lstat(), getdents(), open() are
 reposible for this.  On the linux-2.6 repository, for instance, the
 numbers for git status look like this:
 
   top syscalls sorted top syscalls sorted
   by acc. timeby number
   --
   0.401906 40950 lstat0.401906 40950 lstat
   0.190484 5343 getdents  0.150055 5374 open
   0.150055 5374 open  0.190484 5343 getdents
   0.074843 2806 close 0.074843 2806 close
   0.003216 157 read   0.003216 157 read
 
 To solve this problem, we propose to build a daemon which will watch
 the filesystem using inotify and report batched up events over a UNIX
 socket.

[...]

 +
 +The credential C API is meant to be called by Git code which needs
 +information aboutx filesystem changes.  It is centered around an
 +object representing the changes the filesystem since the last
 +invocation.
 +

Hmmm...I don't see how filesystem changes since last invocation can solve the 
problem, or am I missing something? I think what you mean to say is that the 
daemon should keep track of the filesystem *state* of the working copy, or 
alternatively the deltas/changes to some known state (such as .git/index)?

I'm also still skeptical whether a daemon will improve overall performance. In 
my understanding its essentially a filesystem cache in user-mode. The 
difference to using the OS filesystem cache directly (via lstat/readdir) is 
that we replace ~50k sys-calls with a single IPC call (i.e. the git -- 
fswatch daemon communication is less 'chatty'). However, the 'chattyness' is 
still there between the fswatch daemon and the OS / inotify. Consider 'git 
status; make; make clean; git status'...that's a *lot* of changes to process 
for nothing (potentially slowing down make).

Then there's the issue of stale data in the cache. Modifying porcelain commands 
that use 'git status --porcelain' to compile their changesets will want 100% 
exact data. I'm not saying its not doable, but adding another platform 
specific, caching daemon to the tool chain doesn't exactly simplify things...

But perhaps I'm too pessimistic (or just stigmatized by inherently slow and 
out-of-date TGitCache/TSvnCache on Windows :-)
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] tag: --force is quiet about new tags

2013-03-12 Thread Phil Hord
git tag --force is used to replace an existing tag with
a new reference.  Git helpfully tells the user the old
ref when this happens.  But if the tag name is new and does
not exist, git tells the user the old ref anyway (00).

Teach git to ignore --force if the tag is new.  Add a test
for this and also to ensure --force can replace tags at all.

Signed-off-by: Phil Hord ho...@cisco.com
---
 builtin/tag.c  |  2 +-
 t/t7004-tag.sh | 12 
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/builtin/tag.c b/builtin/tag.c
index f826688..af3af3f 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -582,7 +582,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
die(_(%s: cannot lock the ref), ref.buf);
if (write_ref_sha1(lock, object, NULL)  0)
die(_(%s: cannot update the ref), ref.buf);
-   if (force  hashcmp(prev, object))
+   if (force  !is_null_sha1(prev)  hashcmp(prev, object))
printf(_(Updated tag '%s' (was %s)\n), tag, 
find_unique_abbrev(prev, DEFAULT_ABBREV));
 
strbuf_release(buf);
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index f5a79b1..c8d6e9f 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -104,6 +104,18 @@ test_expect_success 'creating a tag using HEAD directly 
should succeed' '
tag_exists myhead
 '
 
+test_expect_success '--force can create a tag with the name of one existing' '
+   tag_exists mytag 
+   git tag --force mytag 
+   tag_exists mytag'
+
+test_expect_success '--force is moot with a non-existing tag name' '
+   git tag newtag expect 
+   git tag --force forcetag actual 
+   test_cmp expect actual
+'
+git tag -d newtag forcetag
+
 # deleting tags:
 
 test_expect_success 'trying to delete an unknown tag should fail' '
-- 
1.8.2.rc3.394.g2617418.dirty

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] difftool: Make directory diff symlink work tree

2013-03-12 Thread John Keeping
On Tue, Mar 12, 2013 at 05:12:28PM -0600, Matt McClure wrote:
 On Mar 12, 2013, at 1:25 PM, John Keeping j...@keeping.me.uk wrote:
 
  When I tried this I got the expected behaviour even without this patch.
 
 git diff --raw commit
 
 emits the null SHA1 if the working tree file's stat differs from the
 blob corresponding to commit. Is that the case you observed?

Yes, although it's slightly more subtle than that - the null SHA1 only
occurs if the working tree file has unstaged changes; if you add the
changes to the index then the null SHA1 is no longer used since the blob
is now available in Git's object store.


John
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Questions/investigations on git-subtree and tags

2013-03-12 Thread Paul Campbell
On Tue, Mar 12, 2013 at 10:02 AM, Jeremy Rosen jeremy.ro...@openwide.fr wrote:
 Paul, I'm not quite sure where I should go from here...

 should I send you a patch so you make it a V3 of your patch ? should I
 send a patch superseeding yours ?

 I have also found a similar problem in git-subtree pull, which needs
 the same fix.

 in the mean time, attached is the current version of my changes

 Cordialement

 Jérémy Rosen

 fight key loggers : write some perl using vim


Thanks Jérémy.

Nothing in your patches are dependant on anything I'm working on. I'll
gladly take them for my own tree but feel free to submit them (inline,
rather than as attachments) to the list and cc: David Greene
gree...@obbligato.org the subtree area maintainer.

-- 
Paul [W] Campbell
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 14/19] Document pull-all and push-all

2013-03-12 Thread Paul Campbell
On Tue, Mar 12, 2013 at 3:12 PM, Holger Hellmuth (IKS)
hellm...@ira.uka.de wrote:
 Am 09.03.2013 20:28, schrieb Paul Campbell:

  From 7dcd40ab8687a588b7b0c6ff914a7cfb601b6774 Mon Sep 17 00:00:00 2001
 From: Herman van Rink r...@initfour.nl
 Date: Tue, 27 Mar 2012 13:59:16 +0200
 Subject: [PATCH 14/19] Document pull-all and push-all

 ---
   contrib/subtree/git-subtree.txt | 8 +++-
   1 file changed, 7 insertions(+), 1 deletion(-)

 diff --git a/contrib/subtree/git-subtree.txt
 b/contrib/subtree/git-subtree.txt
 index e0957ee..c8fc103 100644
 --- a/contrib/subtree/git-subtree.txt
 +++ b/contrib/subtree/git-subtree.txt
 @@ -92,13 +92,19 @@ pull::
 Exactly like 'merge', but parallels 'git pull' in that
 it fetches the given commit from the specified remote
 repository.
 -
 +
 +pull-all::
 +   Perform a pull operation on all in .gittrees registered subtrees.
 +
   push::
 Does a 'split' (see below) using the prefix supplied
 and then does a 'git push' to push the result to the
 repository and refspec. This can be used to push your
 subtree to different branches of the remote repository.

 +push-all::
 +   Perform a pull operation on all in .gittrees registered subtrees.

  -
 pull-push


Thanks.

 +
   split::
 Extract a new, synthetic project history from the
 history of the prefix subtree.  The new history





-- 
Paul [W] Campbell
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: difftool -d symlinks, under what conditions

2013-03-12 Thread John Keeping
On Tue, Mar 12, 2013 at 04:48:16PM -0600, Matt McClure wrote:
 On Mar 12, 2013, at 4:16 PM, Junio C Hamano gits...@pobox.com wrote:
 
  Matt McClure matthewlmccl...@gmail.com writes:
 
  * If you are comparing two trees, and especially if your RHS is not
HEAD, you will send everything to a temporary without
symlinks. Any edit made by the user will be lost.
 
 I think you're suggesting to use a symlink any time the content of any
 given RHS revision is the same as the working tree.
 
 I imagine that might confuse me as a user. It would create
 circumstances where some files are symlinked and others aren't for
 reasons that won't be straightforward.
 
 I imagine solving that case, I might instead implement a copy back to
 the working tree with conflict detection/resolution. Some earlier
 iterations of the directory diff feature used copy back without
 conflict detection and created situations where I clobbered my own
 changes by finishing a directory diff after making edits concurrently.

The code to copy back working tree files is already there, it just
triggers using the same logic as the creation of symlinks in the first
place and doesn't attempt any conflict detection.  I suspect that any
more comprehensive solution will need to restrict the use of git
difftool -d whenever the index contains unmerged entries or when there
are both staged and unstaged changes, since the merge resolution will
cause these states to be lost.

The implementation of Junio's suggestion is relatively straightforward
(this is untested, although t7800 passes, and can probably be improved
by someone better versed in Perl).  Does this work for your original
scenario?

-- 8 --
diff --git a/git-difftool.perl b/git-difftool.perl
index 0a90de4..5f093ae 100755
--- a/git-difftool.perl
+++ b/git-difftool.perl
@@ -83,6 +83,21 @@ sub exit_cleanup
exit($status | ($status  8));
 }
 
+sub use_wt_file
+{
+   my ($repo, $workdir, $file, $sha1, $symlinks) = @_;
+   my $null_sha1 = '0' x 40;
+
+   if ($sha1 eq $null_sha1) {
+   return 1;
+   } elsif (not $symlinks) {
+   return 0;
+   }
+
+   my $wt_sha1 = $repo-command_oneline('hash-object', $workdir/$file);
+   return $sha1 eq $wt_sha1;
+}
+
 sub setup_dir_diff
 {
my ($repo, $workdir, $symlinks) = @_;
@@ -159,10 +174,10 @@ EOF
}
 
if ($rmode ne $null_mode) {
-   if ($rsha1 ne $null_sha1) {
-   $rindex .= $rmode $rsha1\t$dst_path\0;
-   } else {
+   if (use_wt_file($repo, $workdir, $dst_path, $rsha1, 
$symlinks)) {
push(@working_tree, $dst_path);
+   } else {
+   $rindex .= $rmode $rsha1\t$dst_path\0;
}
}
}
-- 
1.8.2.rc2.4.g7799588

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] difftool: Make directory diff symlink work tree

2013-03-12 Thread Matt McClure
On Tue, Mar 12, 2013 at 3:24 PM, John Keeping j...@keeping.me.uk wrote:
 When I tried this I got the expected behaviour even without this patch.

 It turns out that an uncommitted, but *staged* change emits the SHA1 of
 the blob rather than the null SHA1.  Do you get the desired behaviour if
 you git reset before using difftool?

I tried this:

$ git diff --raw HEAD^
:100644 100644 f35de0f... ead9399... M  diff-lib.c

$ git reset HEAD^
Unstaged changes after reset:
M diff-lib.c

$ git diff --raw
:100644 100644 f35de0f... 000... M  diff-lib.c

$ git difftool -d

and the last command did indeed create symlinks into my working tree
rather than file copies.

So... it seems that using git-reset is at least a workaround to get
the symlink behavior I want as a user, though the dance I have to do
is a little more awkward than `git difftool -d HEAD^` would be.

 If so I think you want some new mode of operation for difftool instead
 of this patch which will also affect unrelated commands.

Are you suggesting that difftool do the reset work above given a new
option or by default?

--
Matt McClure
http://www.matthewlmcclure.com
http://www.mapmyfitness.com/profile/matthewlmcclure
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH] Documentation/technical/api-fswatch.txt: start with outline

2013-03-12 Thread Duy Nguyen
On Wed, Mar 13, 2013 at 6:21 AM, Karsten Blees karsten.bl...@gmail.com wrote:
 Hmmm...I don't see how filesystem changes since last invocation can solve the 
 problem, or am I missing something? I think what you mean to say is that the 
 daemon should keep track of the filesystem *state* of the working copy, or 
 alternatively the deltas/changes to some known state (such as .git/index)?

I think git process can keep track of filesystem state (and save it
down if necessary). But when git process is not running, system state
changes and it cannot know about. The daemon helps filling this gap
(and basically keeps git running (in a light form) throughout a
development session). For example if we know only 5 files have changed
since the last refresh, we only need to re-stat those 5. The same for
untracked/ignored file checking,

 I'm also still skeptical whether a daemon will improve overall performance. 
 In my understanding its essentially a filesystem cache in user-mode. The 
 difference to using the OS filesystem cache directly (via lstat/readdir) is 
 that we replace ~50k sys-calls with a single IPC call (i.e. the git -- 
 fswatch daemon communication is less 'chatty'). However, the 'chattyness' is 
 still there between the fswatch daemon and the OS / inotify.

I think it attempts to reduce unnecessary system calls, not eliminate
them all. In the 5 changed files above, a few IPC calls are done to
retrieve the file list, then 5 lstat will be issued (by git, not the
daemon) instead of thousands of them.

Consider 'git status; make; make clean; git status'...that's a *lot* of 
changes to process for nothing (potentially slowing down make).

Yeah. In my opinion, the daemon should realize that at some point
accumulated changes are too much that it's not worth collecting
anymore, and drop them all. Git will do it the normal/slow way. After
that the daemon picks up again. We only optimize for the case when
little changes are made in filesystem.

 Then there's the issue of stale data in the cache. Modifying porcelain 
 commands that use 'git status --porcelain' to compile their changesets will 
 want 100% exact data. I'm not saying its not doable, but adding another 
 platform specific, caching daemon to the tool chain doesn't exactly simplify 
 things...

 But perhaps I'm too pessimistic (or just stigmatized by inherently slow and 
 out-of-date TGitCache/TSvnCache on Windows :-)

Thanks. I didn't know about TGitCache. Will dig it up. Maybe we can
learn something from it (or realize the daemon approach is futile
after all).
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 04/13] match_basename: use strncmp instead of strcmp

2013-03-12 Thread Duy Nguyen
On Wed, Mar 13, 2013 at 12:40 AM, Antoine Pelisse apeli...@gmail.com wrote:
 --- a/dir.c
 +++ b/dir.c
 @@ -636,12 +636,14 @@ int match_basename(const char *basename, int 
 basenamelen,
int flags)
  {
 if (prefix == patternlen) {
 -   if (!strcmp_icase(pattern, basename))
 +   if (patternlen == basenamelen 
 +   !strncmp_icase(pattern, basename, patternlen))
 return 1;
 } else if (flags  EXC_FLAG_ENDSWITH) {
 if (patternlen - 1 = basenamelen 
 -   !strcmp_icase(pattern + 1,
 - basename + basenamelen - patternlen + 1))
 +   !strncmp_icase(pattern + 1,
 +  basename + basenamelen - patternlen + 1,
 +  patternlen - 1))
 return 1;


 I can see that you kept strncmp(), was it worse with memcmp() ?

One step at a time. 05/13 replace strncmp_icase with memcmp (for when
ignore_case == 0).
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 3/6] match_basename: use strncmp instead of strcmp

2013-03-12 Thread Duy Nguyen
On Wed, Mar 13, 2013 at 3:59 AM, Junio C Hamano gits...@pobox.com wrote:
 strncmp is provided length information which could be taken advantage
 by the underlying implementation.

 After all, strcmp() could also be optimized to fetch word-at-a-time
 while being careful about not overstepping the page boundary.

It boils down to giving more information to the underlying
implementation with hope that it can be useful for something. Although
at this point I think strncmp vs strcmp vs memcmp may be not worth
doing (we keep explicit length comparison to reduce *cmp calls
though). The gain is relatively small and will become even smaller
after we avoid running exclude on tracked files (which eliminates like
2/3 of the processed entries).
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 2/3] mergetools/p4merge: create a base if none available

2013-03-12 Thread Kevin Bracey
Originally, with no base, Git gave P4Merge $LOCAL as a dummy base:

   p4merge $LOCAL $LOCAL $REMOTE $MERGED

Commit 0a0ec7bd changed this to:

   p4merge empty file $LOCAL $REMOTE $MERGED

to avoid the problem of being unable to save in some circumstances with
similar inputs.

Unfortunately this approach produces much worse results on differing
inputs. P4Merge really regards the blank file as the base, and once you
have just a couple of differences between the two branches you end up
with one a massive full-file conflict. The 3-way diff is not readable,
and you have to invoke difftool MERGE_HEAD HEAD manually to get a
useful view.

The original approach appears to have invoked special 2-way merge
behaviour in P4Merge that occurs only if the base filename is  or
equal to the left input.  You get a good visual comparison, and it does
not auto-resolve differences. (Normally if one branch matched the base,
it would autoresolve to the other branch).

But there appears to be no way of getting this 2-way behaviour and being
able to reliably save. Having base==left appears to be triggering other
assumptions. There are tricks the user can use to force the save icon
on, but it's not intuitive.

So we now follow a suggestion given in the original patch's discussion:
generate a virtual base, consisting of the lines common to the two
branches. This is the same as the technique used in resolve and octopus
merges, so we relocate that code to a shared function.

Note that if there are no differences at the same location, this
technique can lead to automatic resolution without conflict, combining
everything from the 2 files.  As with the other merges using this
technique, we assume the user will inspect the result before saving.

Signed-off-by: Kevin Bracey ke...@bracey.fi
---
 Documentation/git-sh-setup.txt |  6 ++
 git-merge-one-file.sh  | 18 +-
 git-sh-setup.sh| 12 
 mergetools/p4merge |  6 +-
 4 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/Documentation/git-sh-setup.txt b/Documentation/git-sh-setup.txt
index 6a9f66d..5d709d0 100644
--- a/Documentation/git-sh-setup.txt
+++ b/Documentation/git-sh-setup.txt
@@ -82,6 +82,12 @@ get_author_ident_from_commit::
outputs code for use with eval to set the GIT_AUTHOR_NAME,
GIT_AUTHOR_EMAIL and GIT_AUTHOR_DATE variables for a given commit.
 
+create_virtual_base::
+   modifies the first file so only lines in common with the
+   second file remain. If there is insufficient common material,
+   then the first file is left empty. The result is suitable
+   as a virtual base input for a 3-way merge.
+
 GIT
 ---
 Part of the linkgit:git[1] suite
diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh
index f612cb8..0f164e5 100755
--- a/git-merge-one-file.sh
+++ b/git-merge-one-file.sh
@@ -104,30 +104,22 @@ case ${1:-.}${2:-.}${3:-.} in
;;
esac
 
-   src2=`git-unpack-file $3`
+   src1=$(git-unpack-file $2)
+   src2=$(git-unpack-file $3)
case $1 in
'')
echo Added $4 in both, but differently.
-   # This extracts OUR file in $orig, and uses git apply to
-   # remove lines that are unique to ours.
-   orig=`git-unpack-file $2`
-   sz0=`wc -c $orig`
-   @@DIFF@@ -u -La/$orig -Lb/$orig $orig $src2 | git apply --no-add
-   sz1=`wc -c $orig`
-
-   # If we do not have enough common material, it is not
-   # worth trying two-file merge using common subsections.
-   expr $sz0 \ $sz1 \* 2 /dev/null || : $orig
+   orig=$(git-unpack-file $2)
+   create_virtual_base $orig $src2
;;
*)
echo Auto-merging $4
-   orig=`git-unpack-file $1`
+   orig=$(git-unpack-file $1)
;;
esac
 
# Be careful for funny filename such as -L in $4, which
# would confuse merge greatly.
-   src1=`git-unpack-file $2`
git merge-file $src1 $orig $src2
ret=$?
msg=
diff --git a/git-sh-setup.sh b/git-sh-setup.sh
index 795edd2..349a5d4 100644
--- a/git-sh-setup.sh
+++ b/git-sh-setup.sh
@@ -249,6 +249,18 @@ clear_local_git_env() {
unset $(git rev-parse --local-env-vars)
 }
 
+# Generate a virtual base file for a two-file merge. Uses git apply to
+# remove lines from $1 that are not in $2, leaving only common lines.
+create_virtual_base() {
+   sz0=$(wc -c $1)
+   @@DIFF@@ -u -La/$1 -Lb/$1 $1 $2 | git apply --no-add
+   sz1=$(wc -c $1)
+
+   # If we do not have enough common material, it is not
+   # worth trying two-file merge using common subsections.
+   expr $sz0 \ $sz1 \* 2 /dev/null || : $1
+}
+
 
 # Platform specific tweaks to work around some commands
 case $(uname -s) in
diff --git a/mergetools/p4merge b/mergetools/p4merge
index 46b3a5a..5a608ab 

[PATCH v3 3/3] git-merge-one-file: revise merge error reporting

2013-03-12 Thread Kevin Bracey
Commit 718135e improved the merge error reporting for the resolve
strategy's merge conflict and permission conflict cases, but led to a
malformed ERROR:  in myfile.c message in the case of a file added
differently.

This commit reverts that change, and uses an alternative approach without
this flaw.

Signed-off-by: Kevin Bracey ke...@bracey.fi
---
 git-merge-one-file.sh | 20 +++-
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh
index 0f164e5..78b07a8 100755
--- a/git-merge-one-file.sh
+++ b/git-merge-one-file.sh
@@ -104,11 +104,13 @@ case ${1:-.}${2:-.}${3:-.} in
;;
esac
 
+   ret=0
src1=$(git-unpack-file $2)
src2=$(git-unpack-file $3)
case $1 in
'')
-   echo Added $4 in both, but differently.
+   echo ERROR: Added $4 in both, but differently.
+   ret=1
orig=$(git-unpack-file $2)
create_virtual_base $orig $src2
;;
@@ -121,10 +123,9 @@ case ${1:-.}${2:-.}${3:-.} in
# Be careful for funny filename such as -L in $4, which
# would confuse merge greatly.
git merge-file $src1 $orig $src2
-   ret=$?
-   msg=
-   if [ $ret -ne 0 ]; then
-   msg='content conflict'
+   if [ $? -ne 0 ]; then
+   echo ERROR: Content conflict in $4
+   ret=1
fi
 
# Create the working tree file, using our tree version from the
@@ -133,18 +134,11 @@ case ${1:-.}${2:-.}${3:-.} in
rm -f -- $orig $src1 $src2
 
if [ $6 != $7 ]; then
-   if [ -n $msg ]; then
-   msg=$msg, 
-   fi
-   msg=${msg}permissions conflict: $5-$6,$7
-   ret=1
-   fi
-   if [ $1 = '' ]; then
+   echo ERROR: Permissions conflict: $5-$6,$7
ret=1
fi
 
if [ $ret -ne 0 ]; then
-   echo ERROR: $msg in $4
exit 1
fi
exec git update-index -- $4
-- 
1.8.2.rc3.7.g1100d09.dirty

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 05/13] match_{base,path}name: replace strncmp_icase with memequal_icase

2013-03-12 Thread Duy Nguyen
On Tue, Mar 12, 2013 at 8:04 PM, Nguyễn Thái Ngọc Duy pclo...@gmail.com wrote:
 +static inline int memequal_icase(const char *a, const char *b, int n)
 +{
 +   if (!memcmp(a, b, n))
 +   return 1;
 +
 +   if (!ignore_case)
 +   return 0;
 +
 +   /*
 +* This assumes that ASCII is used in most repositories. We
 +* try the ascii-only version first (i.e. Git's
 +* toupper). Failing that, fall back to normal strncasecmp.
 +*/
 +   while (n  toupper(*a) == toupper(*b)) {
 +   a++;
 +   b++;
 +   n--;
 +   }
 +   if (!n)
 +   return 1;
 +   return !strncasecmp(a, b, n);
 +}

Note, the ignore_case == 1 codepath was not tested and measured. I
suspect that strncasecmp may be more complex to support locales and
the LANG=C version should suffice in most case. But it's just
guesses at this moment.
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 1/3] mergetools/p4merge: swap LOCAL and REMOTE

2013-03-12 Thread Kevin Bracey
Reverse LOCAL and REMOTE when invoking P4Merge as a mergetool, so that
the incoming branch is now in the left-hand, blue triangle pane, and the
current branch is in the right-hand, green circle pane.

This change makes use of P4Merge consistent with its built-in help, its
reference documentation, and Perforce itself. But most importantly, it
makes merge results clearer. P4Merge is not totally symmetrical between
left and right; despite changing a few text labels from theirs/ours to
left/right when invoked manually, it still retains its original
Perforce theirs/ours viewpoint.

Most obviously, in the result pane P4Merge shows changes that are common
to both branches in green. This is on the basis of the current branch
being green, as it is when invoked from Perforce; it means that lines in
the result are blue if and only if they are being changed by the merge,
making the resulting diff clearer.

Note that P4Merge now shows ours on the right for both diff and merge,
unlike other diff/mergetools, which always have REMOTE on the right.
But observe that REMOTE is the working tree (ie ours) for a diff,
while it's another branch (ie theirs) for a merge.

Ours and theirs are reversed for a rebase - see git help rebase.
However, this does produce the desired show the results of this commit
effect in P4Merge - changes that remain in the rebased commit (in your
branch, but not in the new base) appear in blue; changes that do not
appear in the rebased commit (from the new base, or common to both) are
in green. If Perforce had rebase, they'd probably not swap ours/theirs,
but make P4Merge show common changes in blue, picking out our changes in
green. We can't do that, so this is next best.

Signed-off-by: Kevin Bracey ke...@bracey.fi
---
 mergetools/p4merge | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mergetools/p4merge b/mergetools/p4merge
index 8a36916..46b3a5a 100644
--- a/mergetools/p4merge
+++ b/mergetools/p4merge
@@ -22,7 +22,7 @@ diff_cmd () {
 merge_cmd () {
touch $BACKUP
$base_present || $BASE
-   $merge_tool_path $BASE $LOCAL $REMOTE $MERGED
+   $merge_tool_path $BASE $REMOTE $LOCAL $MERGED
check_unchanged
 }
 
-- 
1.8.2.rc3.7.g1100d09.dirty

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Nike Free Damen

2013-03-12 Thread Momona
Der müde  Nike Free Run 4.0 http://www.nikefreeoutletkaufen.org/   Nacht
ohne Lanna, wie Bohnen Randeng.
Smoke verschwommenes Monaten Yu Xuefei micro.
Ich stand Xianting Central, Rauch Januar weiß gefärbt frost sehen, hören den
Schnee von der Schulter, die Brise in eine Blume Blüte im Ohr, wie ein
Hochhaus schlanke Mond singen, verweilen um die Ohren, an einem seidenen
Faden.
Angemeldet Freizeit Hochwasser, haben eine verstümmelte antike Hand Punkte
gefunden, die Raum und Zeit öffnen Sie die Faser die Augenbraue Jincu, wie
Tuosai betrachten Toggle Wellen meines Herzens, aus meiner Welt, die du
Nieselregen Birne wie die Melancholie.
Schnee, ich heiß auf dem alten Hof Krug Wein, der die flache einsamen
anhaltenden Eingang, Seele-Rühren. Flipping Seiten, das Herz wird
aneinanderreihen Sea Scrolls Text des Geschmacks gebunden, riechen, hören
das Wort des alten  Nike Free Outlet http://www.nikefreeoutletkaufen.org/  
verletzten wenig Tinte v. geträumt Frau sieht aus wie eine absolute
Schönheit, konnte die Stimmung nicht gleichgültig bleiben. Seitdem ist mein
Herz mit dem der Emei wie deine Mutter Organisation Erstarrung, und dann ein
paar Tage warten, die Freude an der Blüte wird es schmelzen, am blühenden
Yidao Pflaume.
Ich Weibi Augen, atemlos, das Leid Ihre Aussicht hat weit bis zur
Abenddämmerung die Haut, dass die Flammen der unruhigen Zeiten zu verbergen,
hält sich der Wind und regen immer im Frühjahr und Herbst Tag Samsara.
Ich klappte das Buch, aus dem Körper aus dem Dachboden, kam zu dem zentralen
Innenhof. Sky dunkel, kalt und windig, auch eine brennende Lampe auf dem
Dachboden, Dengying wiegenden persönlichen schrumpfen. Ich hob meine Augen
blickte zum Himmel auf, fehlt Ihnen das lächelnde Gesicht hing in der Moon
Palace, fliegenden Schnee wenigen Strichen kurze Beschreibung für deine
Augenbraue, Pflaume blühen Jiduo das Lächeln Innenhof. Ich trinke einen Wein
in der Hand, wärmen Magen up, feine Stifte Welle, ein paar Zeilen von Tränen
Sätzen an  Nike Free Run Outlet http://www.nikefreeoutletkaufen.org/   der
Wand.
Am nächsten Tag, ich muss zurück zu kämpfen gelernt haben, ist auch vertraut
mit dem Wort. Tolerieren den Geist Anteil spukt emotional, wenn Pinsel ein
paar Striche, wird es als ein Sakrileg, eine Respektlosigkeit.
Oft sitzen auf dem Dachboden, um den Klang des Frühlings-und Herbst-drifting
snow Zala Schultern Geschmack im Süden, das Schmelzen der klassische Seele
des Teeaufgusses Tee olfaktorischen Hof Mui Geschmack zu hören, setzte eine
alte Ballade.
Lesen Sie die alten Bücher der Zeit, zu wissen, dass Sie lachen, lachen Hong
Rumei offen, der Klang des Lachens, wie Bäche, wie Klavier spielen den Klang
des Lachens haben. Ich kenne einen Mann, der eine lächerliche Art und Weise
zum Lachen zu denken. Er zündete sich eine Bake auf der  Nike Free günstig
http://www.nikefreeoutletkaufen.org/   Rauchsignale, eine peinliche Figur
angezogen Dysfunktion. Als Ergebnis erhalten Sie lachen, er verlor,
Geschichte hinterlassen.
Für Ihr Lächeln, er die ganze Welt verloren, Geschichte Bücher, so dass nur
ein paar Striche, so dass niemand kennt die Wahrheit dieser Geschichte.
Smoke Monat Stille, keine Spuren von Wasser. Ich gehe in der Welt, hat weg
gewesen, und schaute nicht zurück. So bin ich in eurer Welt zu Fuß zu weit,
so dass ich tief unfähig, sich zu befreien, oft in eurer Welt, fügte sich in
meinen Worten.
Nach einer langen Zeit, werden Sie vorbei Figur, wenn auch nicht vergessen,
und ich kann mir vorstellen, dass Sie Allure Lächeln.
Worden bedanken Xuela Nacht. Eine dünne Kleidung Männer trinken ein paar
Schlucke Wein, spielen ein paar Hände von Studenten verbringen Stifte, sind
ihre Geschichten noch in den  Nike Free Run 5.0
http://www.nikefreeoutletkaufen.org/   Schnee Welt stecken.



-
Nike Free Damen 
Nike Free Run 
Nike Free 4.0 
Nike Free Run günstig 
Nike Free Run 2 
--
View this message in context: 
http://git.661346.n2.nabble.com/Nike-Free-Damen-tp7579562.html
Sent from the git mailing list archive at Nabble.com.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3 1/3] mergetools/p4merge: swap LOCAL and REMOTE

2013-03-12 Thread David Aguilar
On Tue, Mar 12, 2013 at 6:12 PM, Kevin Bracey ke...@bracey.fi wrote:
 Reverse LOCAL and REMOTE when invoking P4Merge as a mergetool, so that
 the incoming branch is now in the left-hand, blue triangle pane, and the
 current branch is in the right-hand, green circle pane.

 This change makes use of P4Merge consistent with its built-in help, its
 reference documentation, and Perforce itself. But most importantly, it
 makes merge results clearer. P4Merge is not totally symmetrical between
 left and right; despite changing a few text labels from theirs/ours to
 left/right when invoked manually, it still retains its original
 Perforce theirs/ours viewpoint.

 Most obviously, in the result pane P4Merge shows changes that are common
 to both branches in green. This is on the basis of the current branch
 being green, as it is when invoked from Perforce; it means that lines in
 the result are blue if and only if they are being changed by the merge,
 making the resulting diff clearer.

 Note that P4Merge now shows ours on the right for both diff and merge,
 unlike other diff/mergetools, which always have REMOTE on the right.
 But observe that REMOTE is the working tree (ie ours) for a diff,
 while it's another branch (ie theirs) for a merge.

 Ours and theirs are reversed for a rebase - see git help rebase.
 However, this does produce the desired show the results of this commit
 effect in P4Merge - changes that remain in the rebased commit (in your
 branch, but not in the new base) appear in blue; changes that do not
 appear in the rebased commit (from the new base, or common to both) are
 in green. If Perforce had rebase, they'd probably not swap ours/theirs,
 but make P4Merge show common changes in blue, picking out our changes in
 green. We can't do that, so this is next best.

 Signed-off-by: Kevin Bracey ke...@bracey.fi
 ---

This seems sensible to apply.  The commit message is a bit long,
but I think it's justified since this is exactly the kind of thing
I would tend to forget after enough time has passed.

Ditto on the create_virtual_base patch.  Your latest patch
addressed Junio's note about making it take 2 args.

FWIW, please feel free to add:

Reviewed-by: David Aguilar dav...@gmail.com

Thanks.

  mergetools/p4merge | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

 diff --git a/mergetools/p4merge b/mergetools/p4merge
 index 8a36916..46b3a5a 100644
 --- a/mergetools/p4merge
 +++ b/mergetools/p4merge
 @@ -22,7 +22,7 @@ diff_cmd () {
  merge_cmd () {
 touch $BACKUP
 $base_present || $BASE
 -   $merge_tool_path $BASE $LOCAL $REMOTE $MERGED
 +   $merge_tool_path $BASE $REMOTE $LOCAL $MERGED
 check_unchanged
  }

 --
 1.8.2.rc3.7.g1100d09.dirty




-- 
David
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: linux-next: unneeded merge in the security tree

2013-03-12 Thread Theodore Ts'o
On Tue, Mar 12, 2013 at 02:30:04PM -0700, Junio C Hamano wrote:
 Theodore Ts'o ty...@mit.edu writes:
 
  [remote origin]
  url = 
  git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
  fetch = +refs/heads/master:refs/heads/master
  mergeoptions = --ff-only
 
 
 Is there an escape hatch for that rare case?  IOW, how does a
 submaintainer who configured the above to override --ff-only?

Hmm, maybe we would need to add a --no-ff-only?  Or they could just
do:

git fetch origin
git merge FETCH_HEAD

On Tue, Mar 12, 2013 at 02:28:39PM -0700, Linus Torvalds wrote:

 Of course, I'm not really sure if we want to list the flags. Maybe
 it's better to just introduce the notion of upstream directly, and
 make that a flag, and make origin default to that when you clone.
 And then have git use different heurstics for pulling upstream (like
 warning by default when doing a back-merge, perhaps?)

What if git automaticallly set up the origin branch to have a certain
set of mergeoptions by default?  That would probably be right for most
users, but it makes it obvious what's going on when they take a look
at the .git/config file, and doesn't make the remote that happens to
have the name origin as having certain magic properties.  Using a
set of mergeoptions would also be bit more general, and might have
applications in the future.

   - Ted
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: linux-next: unneeded merge in the security tree

2013-03-12 Thread Junio C Hamano
Theodore Ts'o ty...@mit.edu writes:

 On Tue, Mar 12, 2013 at 02:30:04PM -0700, Junio C Hamano wrote:
 Theodore Ts'o ty...@mit.edu writes:
 
  [remote origin]
 url = 
  git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
 fetch = +refs/heads/master:refs/heads/master
 mergeoptions = --ff-only
 
 
 Is there an escape hatch for that rare case?  IOW, how does a
 submaintainer who configured the above to override --ff-only?

 Hmm, maybe we would need to add a --no-ff-only?  Or they could just
 do:

   git fetch origin
   git merge FETCH_HEAD

Hmm, neither feel quite nice.

I haven't heard any comments on my alternative proposal, by the
way.  Did the message get lost?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] tag: --force is quiet about new tags

2013-03-12 Thread Junio C Hamano
Phil Hord ho...@cisco.com writes:

 git tag --force is used to replace an existing tag with
 a new reference.  Git helpfully tells the user the old
 ref when this happens.  But if the tag name is new and does
 not exist, git tells the user the old ref anyway (00).

 Teach git to ignore --force if the tag is new.  Add a test
 for this and also to ensure --force can replace tags at all.

 Signed-off-by: Phil Hord ho...@cisco.com
 ---

I think we would still want to allow the operation to go through,
even when the --force option is given, to create a new tag.  I agree
that the message should not say Updated.  So teaching Git not to
issue the Updated message makes perfect sense.  It is somewhat
misleading to say we are teaching Git to ignore the option, though.

Thanks.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] require pathspec for git add -u/-A

2013-03-12 Thread Jeff King
On Tue, Mar 12, 2013 at 02:58:44PM +0100, Matthieu Moy wrote:

  I guess we already rejected the idea of being able to shut off the
  warning and just get the new behavior, in favor of having people
  specify it manually each time?
 
 Somehow, but we may find a way to do so, as long as it temporary (i.e.
 something that will have no effect after the transition period), and
 that is is crystal clear that it's temporary.

Yeah, I think this is easy as long as it is enable the new behavior
now and not toggle between new and old behavior. That is, a boolean
rather than a selector, with a note that it will go away at the behavior
switch.

The only downside I see is that a user may switch it on now, saying
Yes, I understand and prefer the new behavior, but some script they
run might not expect it. We can warn against that in the documentation,
but that may or may not be enough.

Here's a series which does that; if it's the direction we want to go, I
think we'd want to rebase Junio's now add -u is full-tree patch on
top.

  [1/2]: t2200: check that add -u limits itself to subdirectory
  [2/2]: add: respect add.updateroot config option

-Peff
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] t2200: check that add -u limits itself to subdirectory

2013-03-12 Thread Jeff King
This behavior is due to change in the future, but let's test
it anyway. That helps make sure we do not accidentally
switch the behavior too soon while we are working in the
area, and it means that we can easily verify the change when
we do make it.

Signed-off-by: Jeff King p...@peff.net
---
We didn't seem to be testing this transition at all. I think it's sane
to do so now, and Junio's now it is 2.0, let's switch patch should
update the test.

 t/t2200-add-update.sh | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh
index 4cdebda..fe4f548 100755
--- a/t/t2200-add-update.sh
+++ b/t/t2200-add-update.sh
@@ -80,6 +80,17 @@ test_expect_success 'change gets noticed' '
 
 '
 
+# Note that this is scheduled to change in Git 2.0, when
+# git add -u will become full-tree by default.
+test_expect_success 'update did not touch files at root' '
+   cat expect -\EOF 
+   check
+   top
+   EOF
+   git diff-files --name-only actual 
+   test_cmp expect actual
+'
+
 test_expect_success SYMLINKS 'replace a file with a symlink' '
 
rm foo 
-- 
1.8.2.rc2.7.gef06216

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] add: respect add.updateroot config option

2013-03-12 Thread Jeff King
The `git add -u` command operates on the current subdir of
the repository, but is transitioning to operate on the whole
repository (see commit 0fa2eb5 for details). During the
transition period, we issue a warning. For users who have
read and accepted the warning, there is no way to jump
directly to the future behavior and silence the warning. The
config option added by this patch gives them such an option.

Signed-off-by: Jeff King p...@peff.net
---
 Documentation/config.txt | 19 +++
 builtin/add.c| 10 --
 t/t2200-add-update.sh| 14 ++
 3 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index bbba728..be0f6fc 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -657,6 +657,25 @@ add.ignoreErrors::
convention for configuration variables.  Newer versions of Git
honor `add.ignoreErrors` as well.
 
+add.updateroot::
+   Historically, when the `git add -u` and `git add -A` commands
+   are run from a subdirectory of the repository and are not given
+   any pathspec, they have operated only on the subdirectory from
+   which they were called. In a future version of git, this behavior
+   will be switched to operate on the full repository instead. In
+   the meantime, issuing `git add -u` (or `-A`) from a subdirectory
+   continues to work on the subdirectory, but will now issue a
+   warning. If you are ready to move to the new behavior now,
+   accepting that you may be breaking existing scripts which expect
+   the old behavior, you can do so by setting `add.updateroot` to
+   `true`.
++
+Note that this is meant to let early adopters move to the new behavior
+immediately; it is not a toggle switch that will work forever.  After
+git transitions to the new behavior, this option will become a no-op;
+`git add -u` will always update the whole tree, and `git add -u .` will
+remain the correct way to limit to the current directory.
+
 alias.*::
Command aliases for the linkgit:git[1] command wrapper - e.g.
after defining alias.last = cat-file commit HEAD, the invocation
diff --git a/builtin/add.c b/builtin/add.c
index ab1c9e8..95fe35e 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -22,6 +22,7 @@ static int take_worktree_changes;
 };
 static int patch_interactive, add_interactive, edit_interactive;
 static int take_worktree_changes;
+static int update_root;
 
 struct update_callback_data {
int flags;
@@ -297,6 +298,10 @@ static int add_config(const char *var, const char *value, 
void *cb)
ignore_add_errors = git_config_bool(var, value);
return 0;
}
+   if (!strcmp(var, add.updateroot)) {
+   update_root = git_config_bool(var, value);
+   return 0;
+   }
return git_default_config(var, value, cb);
 }
 
@@ -390,12 +395,13 @@ int cmd_add(int argc, const char **argv, const char 
*prefix)
short_option_with_implicit_dot = -u;
}
if (option_with_implicit_dot  !argc) {
+   static const char *root[2] = { :/, NULL };
static const char *here[2] = { ., NULL };
-   if (prefix)
+   if (!update_root  prefix)
warn_pathless_add(option_with_implicit_dot,
  short_option_with_implicit_dot);
argc = 1;
-   argv = here;
+   argv = update_root ? root : here;
}
 
add_new_files = !take_worktree_changes  !refresh_only;
diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh
index fe4f548..b9215d3 100755
--- a/t/t2200-add-update.sh
+++ b/t/t2200-add-update.sh
@@ -91,6 +91,20 @@ test_expect_success 'update did not touch files at root' '
test_cmp expect actual
 '
 
+test_expect_success 'update with add.updateroot set' '
+   (
+   cd dir1 
+   echo more sub2 
+   git -c add.updateroot=true add -u
+   )
+'
+
+test_expect_success 'all paths are updated' '
+   expect 
+   git diff-files --name-status actual 
+   test_cmp expect actual
+'
+
 test_expect_success SYMLINKS 'replace a file with a symlink' '
 
rm foo 
-- 
1.8.2.rc2.7.gef06216
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] tag: --force is quiet about new tags

2013-03-12 Thread Phil Hord
On Tue, Mar 12, 2013 at 11:33 PM, Junio C Hamano gits...@pobox.com wrote:
 Phil Hord ho...@cisco.com writes:

 git tag --force is used to replace an existing tag with
 a new reference.  Git helpfully tells the user the old
 ref when this happens.  But if the tag name is new and does
 not exist, git tells the user the old ref anyway (00).

 Teach git to ignore --force if the tag is new.  Add a test
 for this and also to ensure --force can replace tags at all.

 Signed-off-by: Phil Hord ho...@cisco.com
 ---

 I think we would still want to allow the operation to go through,
 even when the --force option is given, to create a new tag.  I agree
 that the message should not say Updated.  So teaching Git not to
 issue the Updated message makes perfect sense.  It is somewhat
 misleading to say we are teaching Git to ignore the option, though.

 Thanks.

My phrasing was too ambiguous.  What you described is exactly what the
patch does.  --force is superfluous when the tag does not already
exist.  It is only checked in two places, and one of those is to
decide whether to print the Updated message.  How's this?

   Teach 'git tag --force' to suppress the update message if
   the tag is new.  Add a test for this and also to ensure
   --force can replace tags at all.

Phil
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html