Re: [PATCH v9 01/11] ref-filter: print output to strbuf for formatting

2015-08-06 Thread Eric Sunshine
On Tue, Aug 4, 2015 at 8:42 AM, Karthik Nayak karthik@gmail.com wrote:
 Introduce a strbuf `output` which will act as a substitute rather than
 printing directly to stdout. This will be used for formatting
 eventually.

 Signed-off-by: Karthik Nayak karthik@gmail.com
 ---
 diff --git a/ref-filter.c b/ref-filter.c
 index 46963a5..91482c9 100644
 --- a/ref-filter.c
 +++ b/ref-filter.c
 @@ -1278,9 +1275,12 @@ void show_ref_array_item(struct ref_array_item *info, 
 const char *format, int qu
 if (color_parse(reset, color)  0)
 die(BUG: couldn't parse 'reset' as a color);
 resetv.s = color;
 -   print_value(resetv, quote_style);
 +   print_value(resetv, quote_style, output);
 }
 +   for (i = 0; i  output.len; i++)
 +   printf(%c, output.buf[i]);

Everything up to this point seems straightforward, however, it's not
clear why you need to emit 'output' one character at a time. Is it
because it might contain a NUL '\0' character and therefore you can't
use the simpler printf(%s, output.buf)?

If that's the case, then why not just use fwrite() to emit it all at once?

fwrite(output.buf, output.len, 1, stdout);

 putchar('\n');
 +   strbuf_release(output);
  }

  /*  If no sorting option is given, use refname to sort as default */
 --
 2.5.0
--
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] submodule: implement `module_name` as a builtin helper

2015-08-06 Thread Jens Lehmann

Am 05.08.2015 um 23:08 schrieb Stefan Beller:

This implements the helper `module_name` in C instead of shell,
yielding a nice performance boost.

Before this patch, I measured a time (best out of three):

   $ time ./t7400-submodule-basic.sh  /dev/null
 real   0m11.066s
 user   0m3.348s
 sys0m8.534s

With this patch applied I measured (also best out of three)

   $ time ./t7400-submodule-basic.sh  /dev/null
 real   0m10.063s
 user   0m3.044s
 sys0m7.487s

Signed-off-by: Stefan Beller sbel...@google.com
---

Is this what you had in mind, Jens?


Yup, thanks!

Just some small nits, please see below (and also in the fixup! commit
I pushed on the submodule--helper branch in my Github repo).


Jonathan pointed me to https://github.com/jlehmann/git-submod-enhancements/wiki
Does it reflect reality (i.e. as time passes code changes)?



I also noticed that you have made quite some changes to submodules on different
branches which are not upstream. Soem changes look familiar (as in I believe
this is upstream alreaday? while others look new and exciting to me).
I could not quite get the order yet, though.


I think the Wiki should be pretty much up to date, but I'll try to check
that and the state of the branches on the weekend to see if it needs an
update. If you see some branches you believe are already upstream, it'd
be great if you could mention them so I can double check.


  builtin/submodule--helper.c | 23 +++
  git-submodule.sh| 32 +++-
  submodule.c | 18 +-
  submodule.h |  1 +
  4 files changed, 44 insertions(+), 30 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index cb18ddf..3713c4c 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -5,6 +5,8 @@
  #include pathspec.h
  #include dir.h
  #include utf8.h
+#include submodule.h
+#include string-list.h

  static char *ps_matched;
  static const struct cache_entry **ce_entries;
@@ -98,6 +100,24 @@ static int module_list(int argc, const char **argv, const 
char *prefix)
return 0;
  }

+static int module_name(int argc, const char **argv, const char *prefix)
+{
+   const char *name;
+
+   if (argc != 1)
+   usage(git submodule--helper module_name path\n);
+
+   gitmodules_config();
+   name = submodule_name_for_path(argv[0]);
+
+   if (name)
+   printf(%s\n, name);
+   else
+   die(No submodule mapping found in .gitmodules for path '%s', 
argv[0]);


Hmm, I prefer the pattern to bail out inside if() and continue with the
expected case without else:

+   if (!name)
+   die(No submodule mapping found in .gitmodules for path '%s', 
argv[0]);
+
+   printf(%s\n, name);

But maybe that's just me.


+   return 0;
+}
+
  int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
  {
if (argc  2)
@@ -106,6 +126,9 @@ int cmd_submodule__helper(int argc, const char **argv, 
const char *prefix)
if (!strcmp(argv[1], module_list))
return module_list(argc - 1, argv + 1, prefix);

+   if (!strcmp(argv[1], module_name))
+   return module_name(argc - 2, argv + 2, prefix);
+
  usage:
usage(git submodule--helper module_list\n);
  }
diff --git a/git-submodule.sh b/git-submodule.sh
index af9ecef..e6ff38d 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -178,24 +178,6 @@ get_submodule_config () {
printf '%s' ${value:-$default}
  }

-
-#
-# Map submodule path to submodule name
-#
-# $1 = path
-#
-module_name()
-{
-   # Do we have submodule.something.path = $1 defined in .gitmodules 
file?
-   sm_path=$1
-   re=$(printf '%s\n' $1 | sed -e 's/[].[^$\\*]/\\/g')
-   name=$( git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
-   sed -n -e 's|^submodule\.\(.*\)\.path '$re'$|\1|p' )
-   test -z $name 
-   die $(eval_gettext No submodule mapping found in .gitmodules for path 
'\$sm_path')
-   printf '%s\n' $name
-}
-
  #
  # Clone a submodule
  #
@@ -498,7 +480,7 @@ cmd_foreach()
then
displaypath=$(relative_path $sm_path)
say $(eval_gettext Entering '\$prefix\$displaypath')
-   name=$(module_name $sm_path)
+   name=$(git submodule--helper module_name $sm_path)
(
prefix=$prefix$sm_path/
clear_local_git_env
@@ -554,7 +536,7 @@ cmd_init()
while read mode sha1 stage sm_path
do
die_if_unmatched $mode
-   name=$(module_name $sm_path) || exit
+   name=$(git submodule--helper module_name $sm_path) || exit

displaypath=$(relative_path $sm_path)

@@ -636,7 +618,7 @@ cmd_deinit()

Re: [RFC/PATCH 0/4] parallel fetch for submodules

2015-08-06 Thread Jens Lehmann

Am 06.08.2015 um 19:35 schrieb Stefan Beller:

When I was looking at the branches of Jens for work done on submodules
not yet upstream I found a commit WIP threaded submodule fetching[1],
and I was side tracked wanting to present a different approach to that.


Cool. I didn't follow that route further than building a proof of
concept because I ran into a nasty DNS-timeout on my router at home
and at work we host all repos on a not-so-beefy server making parallel
fetch rather pointless. But I suspect this approach will bring down
fetch times for some users.

Maybe we could also re-use parallel fetch for multiple upstreams in
the superproject when doing a git fetch --all without too much
extra work?
--
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 0/4] parallel fetch for submodules

2015-08-06 Thread Stefan Beller
On Thu, Aug 6, 2015 at 1:08 PM, Jens Lehmann jens.lehm...@web.de wrote:
 Am 06.08.2015 um 19:35 schrieb Stefan Beller:

 When I was looking at the branches of Jens for work done on submodules
 not yet upstream I found a commit WIP threaded submodule fetching[1],
 and I was side tracked wanting to present a different approach to that.


 Cool. I didn't follow that route further than building a proof of
 concept because I ran into a nasty DNS-timeout on my router at home
 and at work we host all repos on a not-so-beefy server making parallel
 fetch rather pointless. But I suspect this approach will bring down
 fetch times for some users.

The difference between your proof of concept and mine is to have the number
of threads easier configurable. (Think of git fetch --recurse-submodules=yes
 -j4, similar to make -j4 splitting work up to 4 different programs
at the same
time. And that thing would be possible to add in this series)

If you fetch lots of submodules, both the client and server load should come
in an ping-pong on-off pattern as the client waits for the server to
prepare stuff
and get it sent to it and then the client needs time to resolve deltas
and write to
disk. Depending on the duty cycle of each, a different number of
parallel threads
make sense (I would expected that they shift their phases against each other
by pure randomness, i.e. one thread is currently resolving deltas
while the other
thread is telling the server to get some work done, so both the client
and server
get utilized at the same time).


 Maybe we could also re-use parallel fetch for multiple upstreams in
 the superproject when doing a git fetch --all without too much
 extra work?

That's why I tried advertising RFC patch 2/4 as I believe it could be
easily reused for such things like git fetch --all, but maybe other
people see problems with it (over/under engineered, wrong things
added, but other critical things missing) so I'd like to hear opinions
on that. :)
--
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/3] test_terminal: redirect child process' stdin to a pty

2015-08-06 Thread Eric Sunshine
On Tue, Aug 4, 2015 at 10:08 AM, Paul Tan pyoka...@gmail.com wrote:
 When resuming, git-am detects if we are trying to feed it patches or not
 by checking if stdin is a TTY.

 However, the test library redirects stdin to /dev/null. This makes it
 difficult, for instance, to test the behavior of git am -3 when
 resuming, as git-am will think we are trying to feed it patches and
 error out.

 Support this use case by extending test-terminal.perl to create a
 pseudo-tty for the child process' standard input as well.

An alternative would be to have git-am detect that it is being tested
and pretend that isatty() returns true. There is some precedent for
having core functionality recognize that it is being tested. See, for
instance, environment variable TEST_DATE_NOW, and rev-list
--test-bitmap. Doing so would allow the tests work on non-Unix
platforms, as well.

 Note that due to the way the code is structured, the child's stdin
 pseudo-tty will be closed when we finish reading from our stdin. This
 means that in the common case, where our stdin is attached to /dev/null,
 the child's stdin pseudo-tty will be closed immediately. Some operations
 like isatty(), which git-am uses, require the file descriptor to be
 open, and hence if the success of the command depends on such functions,
 test_terminal's stdin should be redirected to a source with large amount
 of data to ensure that the child's stdin is not closed, e.g.

 test_terminal git am --3way /dev/zero

 Signed-off-by: Paul Tan pyoka...@gmail.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 1/4] submodule: implement `module_name` as a builtin helper

2015-08-06 Thread Jens Lehmann

Am 06.08.2015 um 19:35 schrieb Stefan Beller:

This implements the helper `module_name` in C instead of shell,
yielding a nice performance boost.

Before this patch, I measured a time (best out of three):

   $ time ./t7400-submodule-basic.sh  /dev/null
 real   0m11.066s
 user   0m3.348s
 sys0m8.534s

With this patch applied I measured (also best out of three)

   $ time ./t7400-submodule-basic.sh  /dev/null
 real   0m10.063s
 user   0m3.044s
 sys0m7.487s

Signed-off-by: Stefan Beller sbel...@google.com
---


Please see my comments in the other thread concerning this patch.

And wouldn't it make more sense to keep this patch together with
the submodule: implement `module_list` as a builtin helper in
its own submodule-helper series and have the following three
patches in a separate parallel fetch for submodules series?


  builtin/submodule--helper.c | 23 +++
  git-submodule.sh| 32 +++-
  submodule.c | 18 +-
  submodule.h |  1 +
  4 files changed, 44 insertions(+), 30 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index cb18ddf..3713c4c 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -5,6 +5,8 @@
  #include pathspec.h
  #include dir.h
  #include utf8.h
+#include submodule.h
+#include string-list.h

  static char *ps_matched;
  static const struct cache_entry **ce_entries;
@@ -98,6 +100,24 @@ static int module_list(int argc, const char **argv, const 
char *prefix)
return 0;
  }

+static int module_name(int argc, const char **argv, const char *prefix)
+{
+   const char *name;
+
+   if (argc != 1)
+   usage(git submodule--helper module_name path\n);
+
+   gitmodules_config();
+   name = submodule_name_for_path(argv[0]);
+
+   if (name)
+   printf(%s\n, name);
+   else
+   die(No submodule mapping found in .gitmodules for path '%s', 
argv[0]);
+
+   return 0;
+}
+
  int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
  {
if (argc  2)
@@ -106,6 +126,9 @@ int cmd_submodule__helper(int argc, const char **argv, 
const char *prefix)
if (!strcmp(argv[1], module_list))
return module_list(argc - 1, argv + 1, prefix);

+   if (!strcmp(argv[1], module_name))
+   return module_name(argc - 2, argv + 2, prefix);
+
  usage:
usage(git submodule--helper module_list\n);
  }
diff --git a/git-submodule.sh b/git-submodule.sh
index af9ecef..e6ff38d 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -178,24 +178,6 @@ get_submodule_config () {
printf '%s' ${value:-$default}
  }

-
-#
-# Map submodule path to submodule name
-#
-# $1 = path
-#
-module_name()
-{
-   # Do we have submodule.something.path = $1 defined in .gitmodules 
file?
-   sm_path=$1
-   re=$(printf '%s\n' $1 | sed -e 's/[].[^$\\*]/\\/g')
-   name=$( git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
-   sed -n -e 's|^submodule\.\(.*\)\.path '$re'$|\1|p' )
-   test -z $name 
-   die $(eval_gettext No submodule mapping found in .gitmodules for path 
'\$sm_path')
-   printf '%s\n' $name
-}
-
  #
  # Clone a submodule
  #
@@ -498,7 +480,7 @@ cmd_foreach()
then
displaypath=$(relative_path $sm_path)
say $(eval_gettext Entering '\$prefix\$displaypath')
-   name=$(module_name $sm_path)
+   name=$(git submodule--helper module_name $sm_path)
(
prefix=$prefix$sm_path/
clear_local_git_env
@@ -554,7 +536,7 @@ cmd_init()
while read mode sha1 stage sm_path
do
die_if_unmatched $mode
-   name=$(module_name $sm_path) || exit
+   name=$(git submodule--helper module_name $sm_path) || exit

displaypath=$(relative_path $sm_path)

@@ -636,7 +618,7 @@ cmd_deinit()
while read mode sha1 stage sm_path
do
die_if_unmatched $mode
-   name=$(module_name $sm_path) || exit
+   name=$(git submodule--helper module_name $sm_path) || exit

displaypath=$(relative_path $sm_path)

@@ -758,7 +740,7 @@ cmd_update()
echo 2 Skipping unmerged submodule $prefix$sm_path
continue
fi
-   name=$(module_name $sm_path) || exit
+   name=$(git submodule--helper module_name $sm_path) || exit
url=$(git config submodule.$name.url)
branch=$(get_submodule_config $name branch master)
if ! test -z $update
@@ -1022,7 +1004,7 @@ cmd_summary() {
# Respect the ignore setting for --for-status.
 

Re: Draft of Git Rev News edition 6

2015-08-06 Thread Thomas Ferris Nicolaisen
On Mon, Aug 3, 2015 at 10:49 PM, Thomas Ferris Nicolaisen
tfn...@gmail.com wrote:
 I hope we can attract more contributors in the future, so the weight
 of this doesn't lie too much on his shoulders. Perhaps we should send
 out the draft earlier next time, and beckon for more contributions
 from the list.

Just to follow up on this point: The draft for the next edition is
available here (still empty):

https://github.com/git/git.github.io/blob/master/rev_news/drafts/edition-7.md

Suggestions and comments can go here:
https://github.com/git/git.github.io/issues/94

 We could also add a call-for-help at the bottom of the respective
 section, asking people who are trawling the mailing list to
 contribute.

You may have spotted that I added this in the recently published
edition, but I think it can bear repeating here for git@vger:

 Before we move on to the link section of this edition,
 we want to make a call-to-arms for people reading
 the Git mailing list. We didn't get enough material in
 this edition on what was really discussed on the list
 the last month. In order to to be the window into the
 Git community that we set out to be, we need your help.

 So please, the next time you read through an interesting
 discussion on the mailing list, note down a few lines
 about it and share them with us.

So, thanks in advance for the contributions we get for #7 and later editions!
--
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] builtin/mv: remove get_pathspec()

2015-08-06 Thread Stefan Beller
On Thu, Aug 6, 2015 at 1:18 PM, Eric Sunshine sunsh...@sunshineco.com wrote:
 On Thu, Aug 6, 2015 at 2:58 PM, Stefan Beller sbel...@google.com wrote:
 On Thu, Aug 6, 2015 at 11:46 AM, Eric Sunshine sunsh...@sunshineco.com 
 wrote:
 On Thu, Aug 6, 2015 at 2:27 PM, Stefan Beller sbel...@google.com wrote:
 `get_pathspec` is deprecated and builtin/mv.c is its last caller, so
 reimplement `get_pathspec` literally in builtin/mv.c

 Curious. Since this is just moving code around, rather than doing the
 actual work to complete the final step as stated by the NEEDSWORK
 comment, isn't it just moving the problem from one location to
 another? Is it worth the code churn?

 Yeah it is moving around the problem a bit. And the code churn is
 unfortunate. Though when I was reading the documentation on
 pathspecs, literally the first sentence was Do not use get_pathspec,
 it is out dated. And that was a sad taste for reading documentation.

 By loudly warning you about deprecation and, more importantly,
 pointing you at the accepted alternative, this documentation saves you
 from wasting time (both time spent reading and time spent going down a
 dead-end path). It would be a sad taste if it warned you quietly
 only at the end of the documentation or not at all.

 It's ok to have such warnings in the docs, but as the first sentence as if
 there was nothing more important than avoiding the out dated stuff?

 From a documentation standpoint, there is nothing more important than
 warning you to avoid it since it is outdated and likely to go away in
 the future.

 I mean I want to understand the actual code and how I can use it, right?

 No. It's deprecated and not meant for your use.

I need to be more precise:
I mean I want to learn how to deal with pathspec things in code.
Assume I know nothing of the history of that code and its deprecated
earlier attempts. So I would expect a documentation like:

foo-bar(int arg): bars the foos with the specific thing equal `arg`

foobaz(int a, int b, int c): Note: this is outdated, bars the foos with ...

in that order, so if I were to start reading from top to bottom, I would find
the current version first and could jump off starting writing code based on
foo-bar.

If I was reading code and wonder: What does foobaz exactly do? Oh
I know! I'll consult the documentation, then I would find the note about
it being out dated and preferably its suggested new replacement.

However I perceived the documentation I read more like this:

some words on foo-bar, a bit too shallow (a good overview,
but I'd like to know more details, so keep reading)

note on foobaz being outdated

more words on foo-bar


 It's a different matter if you want to understand what the function
 does because you've encountered a call in existing code, but that case
 is covered by the existing documentation still being intact (that is,
 it wasn't removed when the deprecation notice was added).

 And there are different approaches to solving the problem.
 I could have just reworded or even just rearranged the documentation.

 The documentation seems fine as-is.

 The approach I take here includes a bit of code churn, but it moves the
 problematic pieces all in one spot.

 Indeed, I had the localizing the problem to one spot argument in
 mind, and even wrote it as an answer to my own question, but deleted
 it before hitting Send. The counterargument (aside from code churn)
 is, that by leaving it alone, it serves as a good reminder of the
 problem and is more likely to get noticed and (perhaps) fixed by
 someone than if it is hidden away in builtin/mv.c.

Having code just in one ugly spot however helps people in the other areas,
where they can see the shiny new thing in action and don't have the mental
burden of seeing a NEEDSWORK comment and thinking about that instead
of the feature they want to add there.
--
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] sha1_file.c: fix a declaration-after-statement

2015-08-06 Thread Ramsay Jones
On 06/08/15 10:53, Ramsay Jones wrote:
 
 Signed-off-by: Ramsay Jones ram...@ramsay1.demon.co.uk
 ---
 
 Hi Junio,
 
 Sorry for this hit-n-run patch, but I'm in a hurry ... :-D
 Could you please squash this (or something like it) into
 the relevant patch; Thanks!

Ah, I've just read your 'What's Cooking' email and I see that
you are already aware of this.

Sorry for the noise!

ATB,
Ramsay Jones

 
 [I noticed this simply because I have '-Wdeclaration-after-statement'
 and '-Werror' (among others) set in CFLAGS (via config.mak).]
 
 HTH
 
 ATB,
 Ramsay Jones
 
  sha1_file.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/sha1_file.c b/sha1_file.c
 index 43386a8..a0af574 100644
 --- a/sha1_file.c
 +++ b/sha1_file.c
 @@ -1462,8 +1462,9 @@ int git_open_noatime(const char *name)
   static int sha1_file_open_flag = O_NOATIME;
  
   for (;;) {
 + int fd;
   errno = 0;
 - int fd = open(name, O_RDONLY | sha1_file_open_flag);
 + fd = open(name, O_RDONLY | sha1_file_open_flag);
   if (fd = 0)
   return fd;
  
 

--
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: What's cooking in git.git

2015-08-06 Thread Johannes Schindelin
Hi Junio,

On 2015-08-06 00:55, Junio C Hamano wrote:

 * sb/submodule-helper (2015-08-05) 1 commit
  - submodule: implement `module_list` as a builtin helper
 
  The beginning of git submodule rewritten in C.

I am really looking forward to that, with my Windows performance hat firmly on 
my head.

 * tb/complete-rebase-i-edit-todo (2015-08-05) 1 commit
  - completion: offer '--edit-todo' during interactive rebase
 
  Comments?

The problem fixed by this one has bugged me plenty of times. I often need to 
edit the TODO e.g. when I managed to get the reordering wrong and want to 
insert a `pick commit` later in the `git-rebase-todo` and then call `git 
rebase --skip`.

Read: I am very much in favor of fast-tracking this topic.

Thanks,
Dscho
--
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 1/3] clone: do not include authentication data in guessed dir

2015-08-06 Thread Patrick Steinhardt
On Wed, Aug 05, 2015 at 12:41:27PM -0700, Junio C Hamano wrote:
 Junio C Hamano gits...@pobox.com writes:
 
  For completeness, here is what I think the end result (together with
  Peff's series) of the test should look like.
  ...
  Note that ssh://user:passw@rd@host:1234/ and user:passw@rd@host:/
  tests fail for the same reason (finding @ should be greedy, I think).
 
 And I think this should make it pass.  Just remember the last
 occurrence of '@' by moving the 'start' every time we see an '@'
 sign.
 
  builtin/clone.c | 11 +--
  1 file changed, 5 insertions(+), 6 deletions(-)
 
 diff --git a/builtin/clone.c b/builtin/clone.c
 index cae288f..5d86439 100644
 --- a/builtin/clone.c
 +++ b/builtin/clone.c
 @@ -160,13 +160,12 @@ static char *guess_dir_name(const char *repo, int 
 is_bundle, int is_bare)
   start += 3;
  
   /*
 -  * Skip authentication data.
 +  * Skip authentication data, if exists.
*/
 - ptr = start;
 - while (ptr  end  !is_dir_sep(*ptr)  *ptr != '@')
 - ptr++;
 - if (*ptr == '@')
 - start = ptr + 1;
 + for (ptr = start; ptr  end  !is_dir_sep(*ptr); ptr++) {
 + if (*ptr == '@')
 + start = ptr + 1;
 + }
  
   /*
* Strip trailing spaces, slashes and /.git

I guess it makes sense to skip over @-signs greedily. Is there
anything I need to do here or will you squash those changes in?


signature.asc
Description: Digital signature


[PATCH] sha1_file.c: fix a declaration-after-statement

2015-08-06 Thread Ramsay Jones

Signed-off-by: Ramsay Jones ram...@ramsay1.demon.co.uk
---

Hi Junio,

Sorry for this hit-n-run patch, but I'm in a hurry ... :-D
Could you please squash this (or something like it) into
the relevant patch; Thanks!

[I noticed this simply because I have '-Wdeclaration-after-statement'
and '-Werror' (among others) set in CFLAGS (via config.mak).]

HTH

ATB,
Ramsay Jones

 sha1_file.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sha1_file.c b/sha1_file.c
index 43386a8..a0af574 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1462,8 +1462,9 @@ int git_open_noatime(const char *name)
static int sha1_file_open_flag = O_NOATIME;
 
for (;;) {
+   int fd;
errno = 0;
-   int fd = open(name, O_RDONLY | sha1_file_open_flag);
+   fd = open(name, O_RDONLY | sha1_file_open_flag);
if (fd = 0)
return fd;
 
-- 
2.5.0
--
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] submodule: implement `module_name` as a builtin helper

2015-08-06 Thread Stefan Beller
This implements the helper `module_name` in C instead of shell,
yielding a nice performance boost.

Before this patch, I measured a time (best out of three):

  $ time ./t7400-submodule-basic.sh  /dev/null
real0m11.066s
user0m3.348s
sys 0m8.534s

With this patch applied I measured (also best out of three)

  $ time ./t7400-submodule-basic.sh  /dev/null
real0m10.063s
user0m3.044s
sys 0m7.487s

Helped-by: Jens Lehmann jens.lehm...@web.de
Signed-off-by: Stefan Beller sbel...@google.com
---

This incorporates the changes from Jens fixup! commit
(which addresses all issues he pointed out).

I agree this looks much cleaner. :)

This patch advances origin/sb/submodule-helper (d2c6c09ac8,
submodule: implement `module_list` as a builtin helper)

 builtin/submodule--helper.c | 22 ++
 git-submodule.sh| 32 +++-
 submodule.c | 19 ++-
 submodule.h |  1 +
 4 files changed, 44 insertions(+), 30 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index cb18ddf..bc37b74 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -5,6 +5,8 @@
 #include pathspec.h
 #include dir.h
 #include utf8.h
+#include submodule.h
+#include string-list.h
 
 static char *ps_matched;
 static const struct cache_entry **ce_entries;
@@ -98,6 +100,23 @@ static int module_list(int argc, const char **argv, const 
char *prefix)
return 0;
 }
 
+static int module_name(int argc, const char **argv, const char *prefix)
+{
+   const char *name;
+
+   if (argc != 1)
+   usage(git submodule--helper module_name path\n);
+
+   gitmodules_config();
+   name = submodule_name_for_path(argv[0]);
+
+   if (!name)
+   die(No submodule mapping found in .gitmodules for path '%s', 
argv[0]);
+
+   printf(%s\n, name);
+   return 0;
+}
+
 int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
 {
if (argc  2)
@@ -106,6 +125,9 @@ int cmd_submodule__helper(int argc, const char **argv, 
const char *prefix)
if (!strcmp(argv[1], module_list))
return module_list(argc - 1, argv + 1, prefix);
 
+   if (!strcmp(argv[1], module_name))
+   return module_name(argc - 2, argv + 2, prefix);
+
 usage:
usage(git submodule--helper module_list\n);
 }
diff --git a/git-submodule.sh b/git-submodule.sh
index af9ecef..e6ff38d 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -178,24 +178,6 @@ get_submodule_config () {
printf '%s' ${value:-$default}
 }
 
-
-#
-# Map submodule path to submodule name
-#
-# $1 = path
-#
-module_name()
-{
-   # Do we have submodule.something.path = $1 defined in .gitmodules 
file?
-   sm_path=$1
-   re=$(printf '%s\n' $1 | sed -e 's/[].[^$\\*]/\\/g')
-   name=$( git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
-   sed -n -e 's|^submodule\.\(.*\)\.path '$re'$|\1|p' )
-   test -z $name 
-   die $(eval_gettext No submodule mapping found in .gitmodules for path 
'\$sm_path')
-   printf '%s\n' $name
-}
-
 #
 # Clone a submodule
 #
@@ -498,7 +480,7 @@ cmd_foreach()
then
displaypath=$(relative_path $sm_path)
say $(eval_gettext Entering '\$prefix\$displaypath')
-   name=$(module_name $sm_path)
+   name=$(git submodule--helper module_name $sm_path)
(
prefix=$prefix$sm_path/
clear_local_git_env
@@ -554,7 +536,7 @@ cmd_init()
while read mode sha1 stage sm_path
do
die_if_unmatched $mode
-   name=$(module_name $sm_path) || exit
+   name=$(git submodule--helper module_name $sm_path) || exit
 
displaypath=$(relative_path $sm_path)
 
@@ -636,7 +618,7 @@ cmd_deinit()
while read mode sha1 stage sm_path
do
die_if_unmatched $mode
-   name=$(module_name $sm_path) || exit
+   name=$(git submodule--helper module_name $sm_path) || exit
 
displaypath=$(relative_path $sm_path)
 
@@ -758,7 +740,7 @@ cmd_update()
echo 2 Skipping unmerged submodule $prefix$sm_path
continue
fi
-   name=$(module_name $sm_path) || exit
+   name=$(git submodule--helper module_name $sm_path) || exit
url=$(git config submodule.$name.url)
branch=$(get_submodule_config $name branch master)
if ! test -z $update
@@ -1022,7 +1004,7 @@ cmd_summary() {
# Respect the ignore setting for --for-status.
if test -n $for_status
then
-   

Re: [PATCH v9 02/11] ref-filter: introduce ref_formatting_state

2015-08-06 Thread Eric Sunshine
On Thu, Aug 6, 2015 at 11:53 PM, Karthik Nayak karthik@gmail.com wrote:
 On Fri, Aug 7, 2015 at 5:49 AM, Eric Sunshine sunsh...@sunshineco.com wrote:
 On Tue, Aug 4, 2015 at 8:42 AM, Karthik Nayak karthik@gmail.com wrote:
 +static void apply_formatting_state(struct ref_formatting_state *state, 
 struct strbuf *final)
 +{
 +   /* More formatting options to be evetually added */
 +   strbuf_addbuf(final, state-output);
 +   strbuf_release(state-output);

 I guess the idea here is that you intend state-output to be re-used
 and it is convenient to clear it here rather than making that the
 responsibility of each caller. For re-use, it is more typical to use
 strbuf_reset() than strbuf_release() (though Junio may disagree[1]).

 it seems like a smarter way to around this without much overhead But it
 was more of to release it as its no longer required unless another modifier 
 atom
 is encountered. Is it worth keeping hoping for another modifier atom 
 eventually,
 and release it at the end like you suggested below?

If I understand your question correctly, it sounds like you're asking
about a memory micro-optimization. From an architectural standpoint,
it's cleaner for the entity which allocates a resource to also release
it. In this case, show_ref_array_item() allocates the strbuf, thus it
should be the one to release it.

And, although we shouldn't be worrying about micro-optimizations at
this point, if it were to be an issue, resetting the strbuf via
strbuf_reset(), which doesn't involve slow memory
deallocation/reallocation, is likely to be a winner over repeated
strbuf_release().

 +   memset(state, 0, sizeof(state));
 +   state.quote_style = quote_style;
 +   state.output = value;

 It feels strange to assign a local variable reference to state.output,
 and there's no obvious reason why you should need to do so. I would
 have instead expected ref_format_state to be declared as:

 struct ref_formatting_state {
int quote_style;
struct strbuf output;
 };

 and initialized as so:

 memset(state, 0, sizeof(state));
 state.quote_style = quote_style;
 strbuf_init(state.output, 0);

 This looks neater, thanks. It'll go along with the previous patch.

 (In fact, the memset() isn't even necessary here since you're
 initializing all fields explicitly, though perhaps you want the
 memset() because a future patch adds more fields which are not
 initialized explicitly?)

 Yea the memset is needed for bit fields evnetually added in the future.

Perhaps move the memset() to the first patch which actually requires
it, where it won't be (effectively) dead code, as it becomes here once
you make the above change.

 for (cp = format; *cp  (sp = find_next(cp)); cp = ep + 1) {
 -   struct atom_value *atomv;
 +   struct atom_value *atomv = NULL;

 What is this change about?

 To remove the warning about atomv being unassigned before usage.

Hmm, where were you seeing that warning? The first use of 'atomv'
following its declaration is in the get_ref_atom_value() below, and
(as far as the compiler knows) that should be setting its value.

 ep = strchr(sp, ')');
 -   if (cp  sp)
 -   emit(cp, sp, output);
 +   if (cp  sp) {
 +   emit(cp, sp, state);
 +   apply_formatting_state(state, final_buf);
 +   }
 get_ref_atom_value(info, parse_ref_filter_atom(sp + 2, ep), 
 atomv);
 -   print_value(atomv, quote_style, output);
 +   process_formatting_state(atomv, state);
 +   print_value(atomv, state);
 +   apply_formatting_state(state, final_buf);
 }
 if (*cp) {
 sp = cp + strlen(cp);
 -   emit(cp, sp, output);
 +   emit(cp, sp, state);
 +   apply_formatting_state(state, final_buf);

 I'm getting the feeling that these functions
 (process_formatting_state, print_value, emit, apply_formatting_state)
 are becoming misnamed (again) with the latest structural changes (but
 perhaps I haven't read far enough into the series yet?).

 process_formatting_state() is rather generic.

 perhaps set_formatting_state()?

I don't know. I don't have a proper high-level overview of the
functionality yet to say if that is a good name or not (which is one
reason I didn't suggest an alternative).

 print_value() and emit() both imply outputting something, but neither
 does so anymore.

 I think I'll append a to_state to each of them.

Meh. print_value() might be better named format_value(). emit() might
become append_literal() or append_non_atom() or something.

 apply_formatting_state() seems to be more about finalizing the
 already-formatted output.

 perform_state_formatting()? perhaps.

Dunno.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More 

Re: [PATCH v9 01/11] ref-filter: print output to strbuf for formatting

2015-08-06 Thread Karthik Nayak
On Fri, Aug 7, 2015 at 3:51 AM, Eric Sunshine sunsh...@sunshineco.com wrote:
 On Tue, Aug 4, 2015 at 8:42 AM, Karthik Nayak karthik@gmail.com wrote:
 Introduce a strbuf `output` which will act as a substitute rather than
 printing directly to stdout. This will be used for formatting
 eventually.

 Signed-off-by: Karthik Nayak karthik@gmail.com
 ---
 diff --git a/ref-filter.c b/ref-filter.c
 index 46963a5..91482c9 100644
 --- a/ref-filter.c
 +++ b/ref-filter.c
 @@ -1278,9 +1275,12 @@ void show_ref_array_item(struct ref_array_item *info, 
 const char *format, int qu
 if (color_parse(reset, color)  0)
 die(BUG: couldn't parse 'reset' as a color);
 resetv.s = color;
 -   print_value(resetv, quote_style);
 +   print_value(resetv, quote_style, output);
 }
 +   for (i = 0; i  output.len; i++)
 +   printf(%c, output.buf[i]);

 Everything up to this point seems straightforward, however, it's not
 clear why you need to emit 'output' one character at a time. Is it
 because it might contain a NUL '\0' character and therefore you can't
 use the simpler printf(%s, output.buf)?

 If that's the case, then why not just use fwrite() to emit it all at once?

 fwrite(output.buf, output.len, 1, stdout);


It was to avoid the printing to stop at '\0' as you mentioned.
I've never come across such a situation before, so I looked for
similar implementations online, and found the individual character printing.
Thanks `fwrite` seems neater.


-- 
Regards,
Karthik Nayak
--
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 v9 02/11] ref-filter: introduce ref_formatting_state

2015-08-06 Thread Eric Sunshine
On Tue, Aug 4, 2015 at 8:42 AM, Karthik Nayak karthik@gmail.com wrote:
 Introduce a ref_formatting_state which will eventually hold the values
 of modifier atoms. Implement this within ref-filter.

 Signed-off-by: Karthik Nayak karthik@gmail.com
 ---
 diff --git a/ref-filter.c b/ref-filter.c
 index 91482c9..2c074a1 100644
 --- a/ref-filter.c
 +++ b/ref-filter.c
 @@ -1238,35 +1238,58 @@ static void emit(const char *cp, const char *ep, 
 struct strbuf *output)
 +static void apply_formatting_state(struct ref_formatting_state *state, 
 struct strbuf *final)
 +{
 +   /* More formatting options to be evetually added */

I forgot to mention this in my earlier review of this patch:

s/evetually/eventually/

 +   strbuf_addbuf(final, state-output);
 +   strbuf_release(state-output);
 +}
--
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 v9 02/11] ref-filter: introduce ref_formatting_state

2015-08-06 Thread Karthik Nayak
On Fri, Aug 7, 2015 at 5:49 AM, Eric Sunshine sunsh...@sunshineco.com wrote:
 On Tue, Aug 4, 2015 at 8:42 AM, Karthik Nayak karthik@gmail.com wrote:
 Introduce a ref_formatting_state which will eventually hold the values
 of modifier atoms. Implement this within ref-filter.

 Signed-off-by: Karthik Nayak karthik@gmail.com
 ---
 +static void apply_formatting_state(struct ref_formatting_state *state, 
 struct strbuf *final)
 +{
 +   /* More formatting options to be evetually added */
 +   strbuf_addbuf(final, state-output);
 +   strbuf_release(state-output);

 I guess the idea here is that you intend state-output to be re-used
 and it is convenient to clear it here rather than making that the
 responsibility of each caller. For re-use, it is more typical to use
 strbuf_reset() than strbuf_release() (though Junio may disagree[1]).

 [1]: http://article.gmane.org/gmane.comp.version-control.git/273094


it seems like a smarter way to around this without much overhead But it
was more of to release it as its no longer required unless another modifier atom
is encountered. Is it worth keeping hoping for another modifier atom eventually,
and release it at the end like you suggested below?

 +}
 +
  void show_ref_array_item(struct ref_array_item *info, const char *format, 
 int quote_style)
  {
 const char *cp, *sp, *ep;
 -   struct strbuf output = STRBUF_INIT;
 +   struct strbuf value = STRBUF_INIT;
 +   struct strbuf final_buf = STRBUF_INIT;
 +   struct ref_formatting_state state;
 int i;

 +   memset(state, 0, sizeof(state));
 +   state.quote_style = quote_style;
 +   state.output = value;

 It feels strange to assign a local variable reference to state.output,
 and there's no obvious reason why you should need to do so. I would
 have instead expected ref_format_state to be declared as:

 struct ref_formatting_state {
int quote_style;
struct strbuf output;
 };

 and initialized as so:

 memset(state, 0, sizeof(state));
 state.quote_style = quote_style;
 strbuf_init(state.output, 0);


This looks neater, thanks. It'll go along with the previous patch.

 (In fact, the memset() isn't even necessary here since you're
 initializing all fields explicitly, though perhaps you want the
 memset() because a future patch adds more fields which are not
 initialized explicitly?)


Yea the memset is needed for bit fields evnetually added in the future.

 This still allows re-use via strbuf_reset() mentioned above.

 And, of course, you'd want to strbuf_release() it at the end of this
 function where you're already releasing final_buf.


Addressed this above.

 for (cp = format; *cp  (sp = find_next(cp)); cp = ep + 1) {
 -   struct atom_value *atomv;
 +   struct atom_value *atomv = NULL;

 What is this change about?


To remove the warning about atomv being unassigned before usage.

 ep = strchr(sp, ')');
 -   if (cp  sp)
 -   emit(cp, sp, output);
 +   if (cp  sp) {
 +   emit(cp, sp, state);
 +   apply_formatting_state(state, final_buf);
 +   }
 get_ref_atom_value(info, parse_ref_filter_atom(sp + 2, ep), 
 atomv);
 -   print_value(atomv, quote_style, output);
 +   process_formatting_state(atomv, state);
 +   print_value(atomv, state);
 +   apply_formatting_state(state, final_buf);
 }
 if (*cp) {
 sp = cp + strlen(cp);
 -   emit(cp, sp, output);
 +   emit(cp, sp, state);
 +   apply_formatting_state(state, final_buf);

 I'm getting the feeling that these functions
 (process_formatting_state, print_value, emit, apply_formatting_state)
 are becoming misnamed (again) with the latest structural changes (but
 perhaps I haven't read far enough into the series yet?).

 process_formatting_state() is rather generic.


perhaps set_formatting_state()?

 print_value() and emit() both imply outputting something, but neither
 does so anymore.


I think I'll append a to_state to each of them.

 apply_formatting_state() seems to be more about finalizing the
 already-formatted output.

perform_state_formatting()? perhaps.

-- 
Regards,
Karthik Nayak
--
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 v9 03/11] ref-filter: implement an `align` atom

2015-08-06 Thread Eric Sunshine
On Wed, Aug 5, 2015 at 2:54 PM, Karthik Nayak karthik@gmail.com wrote:
 Implement an `align` atom which will act as a modifier atom and align
 any string with or without an %(atom) appearing before a %(end) atom
 to the right, left or middle.

 It is followed by `:type,paddinglength`, where the `type` is
 either left, right or middle and `paddinglength` is the total length
 of the padding to be performed. If the atom length is more than the
 padding length then no padding is performed. e.g. to pad a succeeding
 atom to the middle with a total padding size of 40 we can do a
 --format=%(align:middle,40)..

 Add documentation and tests for the same.

I forgot to mention in my earlier review of this patch that you should
explain in the commit message, and probably the documentation, this
this implementation (assuming I'm understanding the code) does not
correctly support nested %(foo)...%(end) constructs, where %(foo)
might be %(if:), %(truncate:), %(cut:), or even a nested %(align:), or
some as yet unimagined modifier. Supporting nesting of these
constructs will require pushing the formatting states onto a stack (or
invoking the parser recursively).

 Signed-off-by: Karthik Nayak karthik@gmail.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 v9 03/11] ref-filter: implement an `align` atom

2015-08-06 Thread Eric Sunshine
On Wed, Aug 5, 2015 at 2:54 PM, Karthik Nayak karthik@gmail.com wrote:
 Implement an `align` atom which will act as a modifier atom and align
 any string with or without an %(atom) appearing before a %(end) atom
 to the right, left or middle.

For someone not familiar with the evolution of this patch series,
align any string with or without an %(atom) is confusing and
distracting and seems to imply that something extra mysterious is
going on behind the scenes. Keeping it simple makes it easier to
understand:

Add an `align` atom which left-, middle-, or right-aligns the
content between %(align:...) and %(end).

 It is followed by `:type,paddinglength`, where the `type` is

'type' may not be the best name. Perhaps 'style' or 'position' or
something else would be better?

 either left, right or middle and `paddinglength` is the total length

'paddinglength' is misleading. You're really describing the container
width in which alignment takes places, so perhaps call it 'width' or
'fieldwidth' or something.

 of the padding to be performed. If the atom length is more than the
 padding length then no padding is performed. e.g. to pad a succeeding
 atom to the middle with a total padding size of 40 we can do a

It's odd to have alignment described in terms of padding and
padding length, especially in the case of center alignment. It
might be better to rephrase the discussion in terms of field width or
such.

 --format=%(align:middle,40)..

I may have missed the discussion, but why was comma chosen as a
separator here, rather than, say, colon? For instance:

%(align:middle:40)

 Add documentation and tests for the same.

 Signed-off-by: Karthik Nayak karthik@gmail.com
 ---
 diff --git a/Documentation/git-for-each-ref.txt 
 b/Documentation/git-for-each-ref.txt
 index e49d578..d865f98 100644
 --- a/Documentation/git-for-each-ref.txt
 +++ b/Documentation/git-for-each-ref.txt
 @@ -127,6 +127,14 @@ color::
 +align::
 +   Align any string with or without %(atom) before the %(end)
 +   atom to the right, left or middle. Followed by

Ditto regarding any string with or without %(atom) being confusing
to someone not familiar with the evolution of this patch series.
Instead, perhaps:

Left-, middle-, or right-align content between %(align:...)
and %(end).

 +   `:type,paddinglength`, where the `type` is either left,
 +   right or middle and `paddinglength` is the total length of
 +   the padding to be performed. If the string length is more than
 +   the padding length then no padding is performed.

Ditto regarding above observations about 'type', 'paddinglength', and padding.

 diff --git a/ref-filter.c b/ref-filter.c
 index 2c074a1..d123299 100644
 --- a/ref-filter.c
 +++ b/ref-filter.c
 @@ -620,7 +623,7 @@ static void populate_value(struct ref_array_item *ref)
 const char *name = used_atom[i];
 struct atom_value *v = ref-value[i];
 int deref = 0;
 -   const char *refname;
 +   const char *refname = NULL;

What is this change about?

 const char *formatp;
 struct branch *branch = NULL;

 @@ -687,6 +690,29 @@ static void populate_value(struct ref_array_item *ref)
 else
 v-s =  ;
 continue;
 +   } else if (starts_with(name, align:)) {
 +   const char *valp = NULL;

Unnecessary NULL assignment.

 +   struct align *align = xmalloc(sizeof(struct align));
 +
 +   skip_prefix(name, align:, valp);

You could simplify the code by combining this skip_prefix() with the
earlier starts_with() in the conditional:

} else if (skip_prefix(name, align:, valp)) {
struct align *align = xmalloc(sizeof(struct align));
...

 +   if (skip_prefix(valp, left,, valp))
 +   align-align_type = ALIGN_LEFT;
 +   else if (skip_prefix(valp, right,, valp))
 +   align-align_type = ALIGN_RIGHT;
 +   else if (skip_prefix(valp, middle,, valp))
 +   align-align_type = ALIGN_MIDDLE;
 +   else
 +   die(_(align: improper format));

You could do a better job of helping the user track down the offending
improper format by actually including it in the error message.

 +   if (strtoul_ui(valp, 10, align-align_value))
 +   die(_(align: positive value expected));

Ditto.

 +   v-align = align;
 +   v-modifier_atom = 1;
 +   continue;
 +   } else if (starts_with(name, end)) {
 +   v-end = 1;
 +   v-modifier_atom = 1;
 +   continue;
 } else
 

Re: Draft of Git Rev News edition 6

2015-08-06 Thread Mikael Magnusson
On Fri, Aug 7, 2015 at 12:18 AM, Thomas Ferris Nicolaisen
tfn...@gmail.com wrote:
 On Mon, Aug 3, 2015 at 10:49 PM, Thomas Ferris Nicolaisen
 tfn...@gmail.com wrote:
 I hope we can attract more contributors in the future, so the weight
 of this doesn't lie too much on his shoulders. Perhaps we should send
 out the draft earlier next time, and beckon for more contributions
 from the list.

 Just to follow up on this point: The draft for the next edition is
 available here (still empty):

 https://github.com/git/git.github.io/blob/master/rev_news/drafts/edition-7.md

 Suggestions and comments can go here:
 https://github.com/git/git.github.io/issues/94

 We could also add a call-for-help at the bottom of the respective
 section, asking people who are trawling the mailing list to
 contribute.

 You may have spotted that I added this in the recently published
 edition, but I think it can bear repeating here for git@vger:

It is surprisingly difficult to get to the actual post of edition 6
from this thread. The link in the original post is just a 404, and to
get to it from the link in this mail, which you might not have sent at
all, I had to click like 5 things, and a few of those turned out to be
dead ends. I suppose once you know where they are published, it is
easy to find, but I did not :).

-- 
Mikael Magnusson
--
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 3/4] notes: add notes.merge option to select default strategy

2015-08-06 Thread Eric Sunshine
On Sun, Aug 2, 2015 at 6:10 AM, Jacob Keller jacob.e.kel...@intel.com wrote:
 Teach git-notes about a new configuration option notes.merge for
 selecting the default notes merge strategy. Document the option in
 config.txt and git-notes.txt

 Add tests for use of the configuration option. Include a test to ensure
 that --strategy correctly overrides the configured setting.

 Signed-off-by: Jacob Keller jacob.kel...@gmail.com
 ---
 diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt
 index 674682b34b83..9c4f8536182f 100644
 --- a/Documentation/git-notes.txt
 +++ b/Documentation/git-notes.txt
 @@ -101,7 +101,7 @@ merge::
  If conflicts arise and a strategy for automatically resolving
 -conflicting notes (see the -s/--strategy option) is not given,
 +conflicting notes (see the NOTES MERGE STRATEGIES section) is not given,
  the manual resolver is used. This resolver checks out the
  conflicting notes in a special worktree (`.git/NOTES_MERGE_WORKTREE`),
  and instructs the user to manually resolve the conflicts there.
 @@ -183,6 +183,7 @@ OPTIONS
 When merging notes, resolve notes conflicts using the given
 strategy. The following strategies are recognized: manual
 (default), ours, theirs, union and cat_sort_uniq.
 +   This option overrides the notes.merge configuration setting.
 See the NOTES MERGE STRATEGIES section below for more
 information on each notes merge strategy.

These two documentation updates are much easier to digest than the
noisy-diff versions of the previous attempt; and the patch overall is
a more pleasant read than v1.

 diff --git a/builtin/notes.c b/builtin/notes.c
 index 63f95fc55439..de0caa00df1b 100644
 --- a/builtin/notes.c
 +++ b/builtin/notes.c
 @@ -945,6 +955,20 @@ static int get_ref(int argc, const char **argv, const 
 char *prefix)
 return 0;
  }

 +static int git_notes_config(const char *var, const char *value, void *cb)
 +{
 +   if (!strcmp(var, notes.merge)) {
 +   if (!value)
 +   return config_error_nonbool(var);
 +   if (parse_notes_strategy(value, merge_strategy))
 +   return error(Unknown notes merge strategy: %s, 
 value);
 +   else
 +   return 0;

A purely subjective stylistic suggestion, which you can freely ignore
if your preference differs:

if (!value)
return ...;
if (parse_notes_strategy(...))
return ...;
return 0;

 +   }
 +
 +   return git_default_config(var, value, cb);
 +}
 +
--
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: Draft of Git Rev News edition 6

2015-08-06 Thread Thomas Ferris Nicolaisen
On Fri, Aug 7, 2015 at 1:44 AM, Mikael Magnusson mika...@gmail.com wrote:
 It is surprisingly difficult to get to the actual post of edition 6
 from this thread. The link in the original post is just a 404, and to
 get to it from the link in this mail, which you might not have sent at
 all, I had to click like 5 things, and a few of those turned out to be
 dead ends. I suppose once you know where they are published, it is
 easy to find, but I did not :).

Sorry about this. It's because at the time of publishing, we move the
draft into the CMS' (Jekyll) blogging directory, and as we have no
nice and easy way of making redirects in that system, the link ends up
dead.

The current live edition 6 is here:
http://git.github.io/rev_news/2015/08/05/edition-6/

The source page is now here:
https://github.com/git/git.github.io/blob/master/_posts/2015-08-05-edition-6.markdown

You can always find the latest published edition, as well as an
archive here: http://git.github.io/rev_news/

We'll make sure to include fresh links in our emails in the future.
--
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 v9 02/11] ref-filter: introduce ref_formatting_state

2015-08-06 Thread Eric Sunshine
On Tue, Aug 4, 2015 at 8:42 AM, Karthik Nayak karthik@gmail.com wrote:
 Introduce a ref_formatting_state which will eventually hold the values
 of modifier atoms. Implement this within ref-filter.

 Signed-off-by: Karthik Nayak karthik@gmail.com
 ---
 +static void apply_formatting_state(struct ref_formatting_state *state, 
 struct strbuf *final)
 +{
 +   /* More formatting options to be evetually added */
 +   strbuf_addbuf(final, state-output);
 +   strbuf_release(state-output);

I guess the idea here is that you intend state-output to be re-used
and it is convenient to clear it here rather than making that the
responsibility of each caller. For re-use, it is more typical to use
strbuf_reset() than strbuf_release() (though Junio may disagree[1]).

[1]: http://article.gmane.org/gmane.comp.version-control.git/273094

 +}
 +
  void show_ref_array_item(struct ref_array_item *info, const char *format, 
 int quote_style)
  {
 const char *cp, *sp, *ep;
 -   struct strbuf output = STRBUF_INIT;
 +   struct strbuf value = STRBUF_INIT;
 +   struct strbuf final_buf = STRBUF_INIT;
 +   struct ref_formatting_state state;
 int i;

 +   memset(state, 0, sizeof(state));
 +   state.quote_style = quote_style;
 +   state.output = value;

It feels strange to assign a local variable reference to state.output,
and there's no obvious reason why you should need to do so. I would
have instead expected ref_format_state to be declared as:

struct ref_formatting_state {
   int quote_style;
   struct strbuf output;
};

and initialized as so:

memset(state, 0, sizeof(state));
state.quote_style = quote_style;
strbuf_init(state.output, 0);

(In fact, the memset() isn't even necessary here since you're
initializing all fields explicitly, though perhaps you want the
memset() because a future patch adds more fields which are not
initialized explicitly?)

This still allows re-use via strbuf_reset() mentioned above.

And, of course, you'd want to strbuf_release() it at the end of this
function where you're already releasing final_buf.

 for (cp = format; *cp  (sp = find_next(cp)); cp = ep + 1) {
 -   struct atom_value *atomv;
 +   struct atom_value *atomv = NULL;

What is this change about?

 ep = strchr(sp, ')');
 -   if (cp  sp)
 -   emit(cp, sp, output);
 +   if (cp  sp) {
 +   emit(cp, sp, state);
 +   apply_formatting_state(state, final_buf);
 +   }
 get_ref_atom_value(info, parse_ref_filter_atom(sp + 2, ep), 
 atomv);
 -   print_value(atomv, quote_style, output);
 +   process_formatting_state(atomv, state);
 +   print_value(atomv, state);
 +   apply_formatting_state(state, final_buf);
 }
 if (*cp) {
 sp = cp + strlen(cp);
 -   emit(cp, sp, output);
 +   emit(cp, sp, state);
 +   apply_formatting_state(state, final_buf);

I'm getting the feeling that these functions
(process_formatting_state, print_value, emit, apply_formatting_state)
are becoming misnamed (again) with the latest structural changes (but
perhaps I haven't read far enough into the series yet?).

process_formatting_state() is rather generic.

print_value() and emit() both imply outputting something, but neither
does so anymore.

apply_formatting_state() seems to be more about finalizing the
already-formatted output.
--
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


wishlist: make it possible to amend commit messages after push to remote

2015-08-06 Thread Jarkko Hietaniemi

Not for the first time, and probably not for the last, I pushed a commit
upstream without adding a link for the bug report as I was meaning to.

Or it could have been...

- Simple typos.

- Broken URLs.

- The impossibility of two consecutive commits referring to each other
because the older one cannot know what the newer one will be called.

- The following morning / 5 minutes / 5 second later thinking of
an additional factoid that would've been great to have in the
commit message.

In general, I find the fact that once a commit has left the building,
it goes into your permanent record, and cannot be changed, ever, to be
very, very annoying. I get the cryptographic sealing with all the
preceding changes, but...

Not that I've thought this through... but couldn't there be a bunch of
aliases (new SHAs) for a commit?  The original one being the
master, but as/if the commit message is changed, it could get new
SHAs.  Sort of separating the real data of the commit, and the metadata?





--
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


[RFC PATCH 2/4] Add a workdispatcher to get work done in parallel

2015-08-06 Thread Stefan Beller
This adds infrastructure code to work a set of tasks from a thread pool.

The whole life cycle of such a thread pool would look like

struct workdispatcher *wd;
struct return_values *rv;

wd = create_workdispatcher(command_for_task, max_parallel_jobs);
for (...) {
prepare(pointer_to_task);
add_task(wd, pointer_to_task);
}
rv = wait_workdispatcher(wd);

Signed-off-by: Stefan Beller sbel...@google.com
---
 Makefile |   1 +
 workdispatcher.c | 184 +++
 workdispatcher.h |  29 +
 3 files changed, 214 insertions(+)
 create mode 100644 workdispatcher.c
 create mode 100644 workdispatcher.h

diff --git a/Makefile b/Makefile
index 6fb7484..2d8803c 100644
--- a/Makefile
+++ b/Makefile
@@ -805,6 +805,7 @@ LIB_OBJS += version.o
 LIB_OBJS += versioncmp.o
 LIB_OBJS += walker.o
 LIB_OBJS += wildmatch.o
+LIB_OBJS += workdispatcher.o
 LIB_OBJS += wrapper.o
 LIB_OBJS += write_or_die.o
 LIB_OBJS += ws.o
diff --git a/workdispatcher.c b/workdispatcher.c
new file mode 100644
index 000..adfedd9
--- /dev/null
+++ b/workdispatcher.c
@@ -0,0 +1,184 @@
+#include cache.h
+#include workdispatcher.h
+
+#ifndef NO_PTHREADS
+#include pthread.h
+#include semaphore.h
+#include stdio.h
+#include unistd.h
+
+#include git-compat-util.h
+struct job_list {
+   void *item;
+   struct job_list *next;
+};
+#endif
+
+struct workdispatcher {
+#ifndef NO_PTHREADS
+   /*
+* To avoid deadlocks always aquire the semaphores with lowest priority
+* first, priorites are in descending order as listed.
+*
+* The `mutex` is a general purpose lock for modifying data in the work
+* dispatcher, such as adding a new task or adding a return value from
+* an already run task.
+*
+* `workingcount` and `freecount` are opposing semaphores, the sum of
+* their values should equal `max_threads` at any time while the `mutex`
+* is available.
+*/
+   sem_t mutex;
+   sem_t workingcount;
+   sem_t freecount;
+
+   pthread_t *threads;
+   unsigned max_threads;
+
+   struct job_list *first;
+   struct job_list *last;
+#endif
+   void *(*function)(void*);
+   struct return_values *ret;
+};
+
+#ifndef NO_PTHREADS
+static unsigned number_cores(void)
+{
+   int count = sysconf(_SC_NPROCESSORS_ONLN);
+   if (count  1) {
+   fprintf(stderr, Number of CPUs online reported %d. 
+   Using one core.\n, count);
+   count = 1;
+   }
+   return count;
+}
+
+void *get_task(struct workdispatcher *wd)
+{
+   void *ret;
+   struct job_list *job;
+
+   sem_wait(wd-workingcount);
+   sem_wait(wd-mutex);
+
+   if (!wd-first)
+   die(BUG: internal error with dequeuing jobs for threads);
+   job = wd-first;
+   ret = job-item;
+   wd-first = job-next;
+   if (!wd-first)
+   wd-last = NULL;
+
+   sem_post(wd-freecount);
+   sem_post(wd-mutex);
+
+   free(job);
+   return ret;
+}
+
+void* dispatcher(void *args)
+{
+   struct workdispatcher *wd = args;
+   void *job = get_task(wd);
+   while (job) {
+   void *retvalue = wd-function(job);
+
+   sem_wait(wd-mutex);
+   struct return_values *rv = wd-ret;
+   ALLOC_GROW(rv-ret, rv-count + 1, rv-alloc);
+   wd-ret-ret[rv-count++] = retvalue;
+   sem_post(wd-mutex);
+
+   job = get_task(wd);
+   }
+
+   pthread_exit(0);
+}
+#endif
+
+struct workdispatcher *create_workdispatcher(void *function(void*),
+unsigned max_threads)
+{
+   struct workdispatcher *wd = xmalloc(sizeof(*wd));
+
+#ifndef NO_PTHREADS
+   int i;
+   if (!max_threads)
+   wd-max_threads = number_cores();
+   else
+   wd-max_threads = max_threads;
+
+   sem_init(wd-mutex, 0, 1);
+   sem_init(wd-workingcount, 0, 0);
+   sem_init(wd-freecount, 0, wd-max_threads);
+   wd-threads = xmalloc(wd-max_threads * sizeof(pthread_t));
+
+   for (i = 0; i  wd-max_threads; i++)
+   pthread_create(wd-threads[i], 0, dispatcher, wd);
+
+   wd-first = NULL;
+   wd-last = NULL;
+#endif
+   wd-function = function;
+   wd-ret = xmalloc(sizeof(*wd-ret));
+   wd-ret-ret = NULL;
+   wd-ret-count = 0;
+   wd-ret-alloc = 0;
+
+   return wd;
+}
+
+void add_task(struct workdispatcher *wd, void *job)
+{
+#ifndef NO_PTHREADS
+   struct job_list *job_list;
+
+   job_list = xmalloc(sizeof(*job_list));
+   job_list-item = job;
+   job_list-next = NULL;
+
+   sem_wait(wd-freecount);
+   sem_wait(wd-mutex);
+
+   if (!wd-last) {
+   wd-last = job_list;
+   wd-first = wd-last;
+   } else {
+   wd-last-next = job_list;
+  

Re: fetching from an hg remote fails with bare git repositories

2015-08-06 Thread Taylor Braun-Jones
On Tue, Aug 4, 2015 at 7:03 PM, Mike Hommey m...@glandium.org wrote:
 Another missing detail is what you're using for mercurial support in
 git. I would guess https://github.com/felipec/git-remote-hg.

Yes. I was going off some outdated information on the web that told me
the felipec/git-remote-hg had moved to mainline git. I now see that
has been undone.

 Shameless plug, you may want to give a try to
 https://github.com/glandium/git-cinnabar.

Thanks, I'll keep an eye on the project for support for pushing merge
commits. That missing feature is a show-stopper for me right now.
Since git-cinnabar is not doing a full hg clone under the hood, is
there a chance that it will support shallow clones? (even before the
native hg client has this feature...)

 Anyways, your error looks like what I fixed in 33cae54, which git
 describe tells me made it to git 2.3.2.

Yep, grabbing the latest version of git (2.5.0) solved the problem.
Sorry for the bother.

Taylor
--
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] builtin/mv: remove get_pathspec()

2015-08-06 Thread Stefan Beller
On Thu, Aug 6, 2015 at 11:46 AM, Eric Sunshine sunsh...@sunshineco.com wrote:
 On Thu, Aug 6, 2015 at 2:27 PM, Stefan Beller sbel...@google.com wrote:
  builtin/mv: remove get_pathspec()

 Misleading. Perhaps rephrase as:

 mv: drop dependency upon deprecated get_pathspec

 `get_pathspec` is deprecated and builtin/mv.c is its last caller, so
 reimplement `get_pathspec` literally in builtin/mv.c

 Curious. Since this is just moving code around, rather than doing the
 actual work to complete the final step as stated by the NEEDSWORK
 comment, isn't it just moving the problem from one location to
 another? Is it worth the code churn?

Yeah it is moving around the problem a bit. And the code churn is
unfortunate. Though when I was reading the documentation on
pathspecs, literally the first sentence was Do not use get_pathspec,
it is out dated. And that was a sad taste for reading documentation.

It's ok to have such warnings in the docs, but as the first sentence as if
there was nothing more important than avoiding the out dated stuff? I
mean I want to understand the actual code and how I can use it, right?

And there are different approaches to solving the problem.
I could have just reworded or even just rearranged the documentation.

The approach I take here includes a bit of code churn, but it moves the
problematic pieces all in one spot.


 Signed-off-by: Stefan Beller sbel...@google.com
 ---
 diff --git a/builtin/mv.c b/builtin/mv.c
 index d1d4316..99e9b3c 100644
 --- a/builtin/mv.c
 +++ b/builtin/mv.c
 @@ -10,6 +10,7 @@
  #include string-list.h
  #include parse-options.h
  #include submodule.h
 +#include pathspec.h

  static const char * const builtin_mv_usage[] = {
 N_(git mv [options] source... destination),
 @@ -20,13 +21,16 @@ static const char * const builtin_mv_usage[] = {
  #define KEEP_TRAILING_SLASH 2

  static const char **internal_copy_pathspec(const char *prefix,
 -  const char **pathspec,
 +  const char **argv,

 What is this change about? It doesn't seem to be related to anything
 else in the patch or to its stated purpose, and makes the argument's
 purpose less clear, so it's not obvious why it is a good change.

int count, unsigned flags)
  {
 int i;
 +   struct pathspec ps;
 const char **result = xmalloc((count + 1) * sizeof(const char *));
 -   memcpy(result, pathspec, count * sizeof(const char *));
 +   memcpy(result, argv, count * sizeof(const char *));
 result[count] = NULL;
 +
 +   /* NEEDSWORK: Move these preprocessing steps into parse_pathspec */
 for (i = 0; i  count; i++) {
 int length = strlen(result[i]);
 int to_copy = length;
 @@ -42,7 +46,13 @@ static const char **internal_copy_pathspec(const char 
 *prefix,
 result[i] = it;
 }
 }
 -   return get_pathspec(prefix, result);
 +
 +   parse_pathspec(ps,
 +  PATHSPEC_ALL_MAGIC 
 +  ~(PATHSPEC_FROMTOP | PATHSPEC_LITERAL),
 +  PATHSPEC_PREFER_CWD,
 +  prefix, result);
 +   return ps._raw;
  }

  static const char *add_slash(const char *path)
 --
 2.5.0.239.g9728e1d.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 3/4] argv_array: add argv_array_copy

2015-08-06 Thread Jeff King
On Thu, Aug 06, 2015 at 02:18:26PM -0400, Eric Sunshine wrote:

 However, that begs the question: Why do you need argv_array_copy() at
 all? Isn't the same functionality already provided by
 argv_array_pushv()? To wit, a caller which wants to copy from 'src' to
 'dst' can already do:
 
 struct argv_array src = ...;
 struct argv_array dst = ARGV_ARRAY_INIT;
 argv_array_pushv(dst, src-argv);

Thanks for reviewing this, Eric. Everything you said is exactly what I
was thinking, too, especially this last part.

-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 3/4] argv_array: add argv_array_copy

2015-08-06 Thread Eric Sunshine
On Thu, Aug 6, 2015 at 1:35 PM, Stefan Beller sbel...@google.com wrote:
 The copied argv array shall be an identical deep copy except for
 the internal allocation value.

 Signed-off-by: Stefan Beller sbel...@google.com
 ---
 diff --git a/argv-array.c b/argv-array.c
 index 256741d..6d9c1dd 100644
 --- a/argv-array.c
 +++ b/argv-array.c
 @@ -68,3 +68,16 @@ void argv_array_clear(struct argv_array *array)
 +void argv_array_copy(struct argv_array *src, struct argv_array *dst)

'src' should be 'const'.

Typical Unix argument order has 'dst' first and 'src' second, i.e
strcpy(dst, src). Is it worth deviating from that precedent?

 +{
 +   int i;
 +
 +   dst-argv = xmalloc((src-argc + 1) * sizeof(*dst-argv));

What happens if 'dst' already has content? Isn't that being leaked
here? At the very least, don't you want to argv_array_clear(dst)?

 +   dst-argc = src-argc;
 +   dst-alloc = src-argc;

This is wrong, of course. The number allocated is actually argc+1, not argc.

 +   for (i = 0; i  dst-argc ; i++)

While it's not wrong per se to use dst-argc as the terminating
condition, it is potentially misleading and confusing. Instead using
src-argc as the terminating condition will better telegraph that the
copy process is indeed predicated upon 'src'.

 +   dst-argv[i] = xstrdup(src-argv[i]);
 +   dst-argv[dst-argc] = NULL;

It's not clear why you want to hand-code the low-level functionality
again (such as array allocation and string duplication), risking (and
indeed making) errors in the process, when you could instead re-use
existing argv_array code. I would have expected to see
argv_array_copy() implemented as:

argv_array_clear(dst);
for (i = 0; i  src-argc; i++)
argv_array_push(dst, src-argv[i]);

which provides far fewer opportunities for errors to creep in.

Moreover, this function might be too special-purpose. That is, why
does it need to overwrite 'dst'? Can't you achieve the same
functionality by merely appending to 'dst', and leave it up to the
caller to decide whether 'dst' should be cleared beforehand or not? If
so, then you can drop the argv_array_clear(dst) from the above.

However, that begs the question: Why do you need argv_array_copy() at
all? Isn't the same functionality already provided by
argv_array_pushv()? To wit, a caller which wants to copy from 'src' to
'dst' can already do:

struct argv_array src = ...;
struct argv_array dst = ARGV_ARRAY_INIT;
argv_array_pushv(dst, src-argv);

 +}
 +
 diff --git a/argv-array.h b/argv-array.h
 index c65e6e8..247627da 100644
 --- a/argv-array.h
 +++ b/argv-array.h
 @@ -19,5 +19,6 @@ LAST_ARG_MUST_BE_NULL
  void argv_array_pushl(struct argv_array *, ...);
  void argv_array_pop(struct argv_array *);
  void argv_array_clear(struct argv_array *);
 +void argv_array_copy(struct argv_array *src, struct argv_array *dst);

  #endif /* ARGV_ARRAY_H */
 --
 2.5.0.239.g9728e1d.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


[RFC PATCH 4/4] submodule: add infrastructure to fetch submodules in parallel

2015-08-06 Thread Stefan Beller
This makes use of the new workdispatcher to fetch a number
of submodules at the same time.

Still todo: sort the output of the fetch commands. I am unsure
if this should be hooked into the workdispatcher as the problem
of sorted output will appear likely again, so a general solution
would not hurt.

Signed-off-by: Stefan Beller sbel...@google.com
---
 builtin/fetch.c |  3 ++-
 submodule.c | 74 -
 submodule.h |  2 +-
 3 files changed, 60 insertions(+), 19 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 8d5b2db..9053e8b 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -1207,7 +1207,8 @@ int cmd_fetch(int argc, const char **argv, const char 
*prefix)
result = fetch_populated_submodules(options,
submodule_prefix,
recurse_submodules,
-   verbosity  0);
+   verbosity  0,
+   1);
argv_array_clear(options);
}
 
diff --git a/submodule.c b/submodule.c
index 872967f..0b2842b 100644
--- a/submodule.c
+++ b/submodule.c
@@ -11,6 +11,7 @@
 #include sha1-array.h
 #include argv-array.h
 #include blob.h
+#include workdispatcher.h
 
 static struct string_list config_name_for_path;
 static struct string_list config_fetch_recurse_submodules_for_name;
@@ -696,13 +697,49 @@ const char* submodule_name_for_path(const char* path)
return NULL;
 }
 
+struct submodule_parallel_fetch {
+   struct child_process cp;
+   struct argv_array argv;
+   struct strbuf sb;
+   int quiet;
+};
+
+void submodule_parallel_fetch_init(struct submodule_parallel_fetch *spf)
+{
+   child_process_init(spf-cp);
+   argv_array_init(spf-argv);
+   strbuf_init(spf-sb, 0);
+   spf-quiet = 0;
+}
+
+void *run_command_and_cleanup(void *arg)
+{
+   struct submodule_parallel_fetch *spf = arg;
+   void *ret = NULL;
+
+   if (!spf-quiet)
+   puts(spf-sb.buf);
+
+   spf-cp.argv = spf-argv.argv;
+
+   if (run_command(spf-cp))
+   ret = (void *)1;
+
+   strbuf_release(spf-cp);
+   argv_array_clear(spf-argv);
+   free(spf);
+   return ret;
+}
+
 int fetch_populated_submodules(const struct argv_array *options,
   const char *prefix, int command_line_option,
-  int quiet)
+  int quiet, int max_parallel_jobs)
 {
int i, result = 0;
-   struct child_process cp = CHILD_PROCESS_INIT;
+   struct workdispatcher *wd;
+   struct return_values *rv;
struct argv_array argv = ARGV_ARRAY_INIT;
+   struct submodule_parallel_fetch *spf;
const char *name_for_path;
const char *work_tree = get_git_work_tree();
if (!work_tree)
@@ -717,12 +754,9 @@ int fetch_populated_submodules(const struct argv_array 
*options,
argv_array_push(argv, --recurse-submodules-default);
/* default value, --submodule-prefix and its value are added later */
 
-   cp.env = local_repo_env;
-   cp.git_cmd = 1;
-   cp.no_stdin = 1;
-
calculate_changed_submodule_paths();
 
+   wd = create_workdispatcher(run_command_and_cleanup, max_parallel_jobs);
for (i = 0; i  active_nr; i++) {
struct strbuf submodule_path = STRBUF_INIT;
struct strbuf submodule_git_dir = STRBUF_INIT;
@@ -771,24 +805,30 @@ int fetch_populated_submodules(const struct argv_array 
*options,
if (!git_dir)
git_dir = submodule_git_dir.buf;
if (is_directory(git_dir)) {
+   spf = xmalloc(sizeof(*spf));
+   submodule_parallel_fetch_init(spf);
+   spf-cp.env = local_repo_env;
+   spf-cp.git_cmd = 1;
+   spf-cp.no_stdin = 1;
+   spf-cp.dir = strbuf_detach(submodule_path, NULL);
+   spf-quiet = quiet;
if (!quiet)
-   printf(Fetching submodule %s%s\n, prefix, 
ce-name);
-   cp.dir = submodule_path.buf;
-   argv_array_push(argv, default_argv);
-   argv_array_push(argv, --submodule-prefix);
-   argv_array_push(argv, submodule_prefix.buf);
-   cp.argv = argv.argv;
-   if (run_command(cp))
-   result = 1;
-   argv_array_pop(argv);
-   argv_array_pop(argv);
-   argv_array_pop(argv);
+   strbuf_addf(spf-sb, Fetching submodule 
%s%s, prefix, ce-name);
+   argv_array_copy(argv, spf-argv);

[RFC/PATCH 0/4] parallel fetch for submodules

2015-08-06 Thread Stefan Beller
When I was looking at the branches of Jens for work done on submodules
not yet upstream I found a commit WIP threaded submodule fetching[1],
and I was side tracked wanting to present a different approach to that.

The first patch is a bit unrelated as it relates to the rewrite of 
git-submodule.sh
but also has code in submodule.c and the following patches modify code just 
around
that, so I did not remove that patch from this series. It is the same I sent 
yesterday.

The next patch 2/4 presents a framework for parallel threaded work.
It allows to setup a worker pool of n threads and then have a queue
of tasks which are worked on by the threads. The patch is a the one which
I'd request most comments on as I think that can be reused in a variety of
situations (parallel checkout of files, parallel fetch of different remotes,
or such).

I consider the third patch farely boring as it adds argv_array_copy, so I
would not expect much discussion there.

The last patch 4/4 presents the new workdispatcher from 2/4 in use
with just one unsolved problem of how to handle the output of the
parallel commands to stdout and stderr. It may be useful to put
handling of parallel outputs into the work dispatcher.

[1] 
https://github.com/jlehmann/git-submod-enhancements/commit/47597753206d40e234a47392e258065c9489e2b3

This series applies on top of origin/sb/submodule-helper (d2c6c09ac819,
submodule: implement `module_list` as a builtin helper) and can also be found
at https://github.com/stefanbeller/git/tree/parallel-submodule-fetch

Stefan Beller (4):
  submodule: implement `module_name` as a builtin helper
  Add a workdispatcher to get work done in parallel
  argv_array: add argv_array_clone to clone an existing argv array
  submodule: add infrastructure to fetch submodules in parallel

 Makefile|   1 +
 argv-array.c|  13 
 argv-array.h|   1 +
 builtin/fetch.c |   3 +-
 builtin/submodule--helper.c |  23 ++
 git-submodule.sh|  32 ++--
 submodule.c |  92 --
 submodule.h |   3 +-
 workdispatcher.c| 184 
 workdispatcher.h|  29 +++
 10 files changed, 332 insertions(+), 49 deletions(-)
 create mode 100644 workdispatcher.c
 create mode 100644 workdispatcher.h

-- 
2.5.0.239.g9728e1d.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


[PATCH 3/4] argv_array: add argv_array_copy

2015-08-06 Thread Stefan Beller
The copied argv array shall be an identical deep copy except for
the internal allocation value.

CC: Jeff King p...@peff.net
Signed-off-by: Stefan Beller sbel...@google.com
---
 argv-array.c | 13 +
 argv-array.h |  1 +
 2 files changed, 14 insertions(+)

diff --git a/argv-array.c b/argv-array.c
index 256741d..6d9c1dd 100644
--- a/argv-array.c
+++ b/argv-array.c
@@ -68,3 +68,16 @@ void argv_array_clear(struct argv_array *array)
}
argv_array_init(array);
 }
+
+void argv_array_copy(struct argv_array *src, struct argv_array *dst)
+{
+   int i;
+
+   dst-argv = xmalloc((src-argc + 1) * sizeof(*dst-argv));
+   dst-argc = src-argc;
+   dst-alloc = src-argc;
+   for (i = 0; i  dst-argc ; i++)
+   dst-argv[i] = xstrdup(src-argv[i]);
+   dst-argv[dst-argc] = NULL;
+}
+
diff --git a/argv-array.h b/argv-array.h
index c65e6e8..247627da 100644
--- a/argv-array.h
+++ b/argv-array.h
@@ -19,5 +19,6 @@ LAST_ARG_MUST_BE_NULL
 void argv_array_pushl(struct argv_array *, ...);
 void argv_array_pop(struct argv_array *);
 void argv_array_clear(struct argv_array *);
+void argv_array_copy(struct argv_array *src, struct argv_array *dst);
 
 #endif /* ARGV_ARRAY_H */
-- 
2.5.0.239.g9728e1d.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


[PATCH 1/4] submodule: implement `module_name` as a builtin helper

2015-08-06 Thread Stefan Beller
This implements the helper `module_name` in C instead of shell,
yielding a nice performance boost.

Before this patch, I measured a time (best out of three):

  $ time ./t7400-submodule-basic.sh  /dev/null
real0m11.066s
user0m3.348s
sys 0m8.534s

With this patch applied I measured (also best out of three)

  $ time ./t7400-submodule-basic.sh  /dev/null
real0m10.063s
user0m3.044s
sys 0m7.487s

Signed-off-by: Stefan Beller sbel...@google.com
---
 builtin/submodule--helper.c | 23 +++
 git-submodule.sh| 32 +++-
 submodule.c | 18 +-
 submodule.h |  1 +
 4 files changed, 44 insertions(+), 30 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index cb18ddf..3713c4c 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -5,6 +5,8 @@
 #include pathspec.h
 #include dir.h
 #include utf8.h
+#include submodule.h
+#include string-list.h
 
 static char *ps_matched;
 static const struct cache_entry **ce_entries;
@@ -98,6 +100,24 @@ static int module_list(int argc, const char **argv, const 
char *prefix)
return 0;
 }
 
+static int module_name(int argc, const char **argv, const char *prefix)
+{
+   const char *name;
+
+   if (argc != 1)
+   usage(git submodule--helper module_name path\n);
+
+   gitmodules_config();
+   name = submodule_name_for_path(argv[0]);
+
+   if (name)
+   printf(%s\n, name);
+   else
+   die(No submodule mapping found in .gitmodules for path '%s', 
argv[0]);
+
+   return 0;
+}
+
 int cmd_submodule__helper(int argc, const char **argv, const char *prefix)
 {
if (argc  2)
@@ -106,6 +126,9 @@ int cmd_submodule__helper(int argc, const char **argv, 
const char *prefix)
if (!strcmp(argv[1], module_list))
return module_list(argc - 1, argv + 1, prefix);
 
+   if (!strcmp(argv[1], module_name))
+   return module_name(argc - 2, argv + 2, prefix);
+
 usage:
usage(git submodule--helper module_list\n);
 }
diff --git a/git-submodule.sh b/git-submodule.sh
index af9ecef..e6ff38d 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -178,24 +178,6 @@ get_submodule_config () {
printf '%s' ${value:-$default}
 }
 
-
-#
-# Map submodule path to submodule name
-#
-# $1 = path
-#
-module_name()
-{
-   # Do we have submodule.something.path = $1 defined in .gitmodules 
file?
-   sm_path=$1
-   re=$(printf '%s\n' $1 | sed -e 's/[].[^$\\*]/\\/g')
-   name=$( git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
-   sed -n -e 's|^submodule\.\(.*\)\.path '$re'$|\1|p' )
-   test -z $name 
-   die $(eval_gettext No submodule mapping found in .gitmodules for path 
'\$sm_path')
-   printf '%s\n' $name
-}
-
 #
 # Clone a submodule
 #
@@ -498,7 +480,7 @@ cmd_foreach()
then
displaypath=$(relative_path $sm_path)
say $(eval_gettext Entering '\$prefix\$displaypath')
-   name=$(module_name $sm_path)
+   name=$(git submodule--helper module_name $sm_path)
(
prefix=$prefix$sm_path/
clear_local_git_env
@@ -554,7 +536,7 @@ cmd_init()
while read mode sha1 stage sm_path
do
die_if_unmatched $mode
-   name=$(module_name $sm_path) || exit
+   name=$(git submodule--helper module_name $sm_path) || exit
 
displaypath=$(relative_path $sm_path)
 
@@ -636,7 +618,7 @@ cmd_deinit()
while read mode sha1 stage sm_path
do
die_if_unmatched $mode
-   name=$(module_name $sm_path) || exit
+   name=$(git submodule--helper module_name $sm_path) || exit
 
displaypath=$(relative_path $sm_path)
 
@@ -758,7 +740,7 @@ cmd_update()
echo 2 Skipping unmerged submodule $prefix$sm_path
continue
fi
-   name=$(module_name $sm_path) || exit
+   name=$(git submodule--helper module_name $sm_path) || exit
url=$(git config submodule.$name.url)
branch=$(get_submodule_config $name branch master)
if ! test -z $update
@@ -1022,7 +1004,7 @@ cmd_summary() {
# Respect the ignore setting for --for-status.
if test -n $for_status
then
-   name=$(module_name $sm_path)
+   name=$(git submodule--helper module_name 
$sm_path)
ignore_config=$(get_submodule_config $name 
ignore none)
test $status != A  test $ignore_config = all 
 continue
   

Re: [PATCH 1/2] builtin/mv: remove get_pathspec()

2015-08-06 Thread Eric Sunshine
On Thu, Aug 6, 2015 at 2:27 PM, Stefan Beller sbel...@google.com wrote:
  builtin/mv: remove get_pathspec()

Misleading. Perhaps rephrase as:

mv: drop dependency upon deprecated get_pathspec

 `get_pathspec` is deprecated and builtin/mv.c is its last caller, so
 reimplement `get_pathspec` literally in builtin/mv.c

Curious. Since this is just moving code around, rather than doing the
actual work to complete the final step as stated by the NEEDSWORK
comment, isn't it just moving the problem from one location to
another? Is it worth the code churn?

 Signed-off-by: Stefan Beller sbel...@google.com
 ---
 diff --git a/builtin/mv.c b/builtin/mv.c
 index d1d4316..99e9b3c 100644
 --- a/builtin/mv.c
 +++ b/builtin/mv.c
 @@ -10,6 +10,7 @@
  #include string-list.h
  #include parse-options.h
  #include submodule.h
 +#include pathspec.h

  static const char * const builtin_mv_usage[] = {
 N_(git mv [options] source... destination),
 @@ -20,13 +21,16 @@ static const char * const builtin_mv_usage[] = {
  #define KEEP_TRAILING_SLASH 2

  static const char **internal_copy_pathspec(const char *prefix,
 -  const char **pathspec,
 +  const char **argv,

What is this change about? It doesn't seem to be related to anything
else in the patch or to its stated purpose, and makes the argument's
purpose less clear, so it's not obvious why it is a good change.

int count, unsigned flags)
  {
 int i;
 +   struct pathspec ps;
 const char **result = xmalloc((count + 1) * sizeof(const char *));
 -   memcpy(result, pathspec, count * sizeof(const char *));
 +   memcpy(result, argv, count * sizeof(const char *));
 result[count] = NULL;
 +
 +   /* NEEDSWORK: Move these preprocessing steps into parse_pathspec */
 for (i = 0; i  count; i++) {
 int length = strlen(result[i]);
 int to_copy = length;
 @@ -42,7 +46,13 @@ static const char **internal_copy_pathspec(const char 
 *prefix,
 result[i] = it;
 }
 }
 -   return get_pathspec(prefix, result);
 +
 +   parse_pathspec(ps,
 +  PATHSPEC_ALL_MAGIC 
 +  ~(PATHSPEC_FROMTOP | PATHSPEC_LITERAL),
 +  PATHSPEC_PREFER_CWD,
 +  prefix, result);
 +   return ps._raw;
  }

  static const char *add_slash(const char *path)
 --
 2.5.0.239.g9728e1d.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


[PATCH 2/2] pathspec: remove deprecated get_pathspec

2015-08-06 Thread Stefan Beller
The function `get_pathspec` is no longer used, so remove it.

The NEEDSWORK comment in pathspec.c is outdated as that happened in
(fadf96aba, 2013-09-09, Merge branch 'nd/magic-pathspec')

Signed-off-by: Stefan Beller sbel...@google.com
---
 Documentation/technical/api-setup.txt |  2 --
 cache.h   |  1 -
 pathspec.c| 36 ---
 pathspec.h|  2 +-
 4 files changed, 1 insertion(+), 40 deletions(-)

diff --git a/Documentation/technical/api-setup.txt 
b/Documentation/technical/api-setup.txt
index 540e455..eb1fa98 100644
--- a/Documentation/technical/api-setup.txt
+++ b/Documentation/technical/api-setup.txt
@@ -27,8 +27,6 @@ parse_pathspec(). This function takes several arguments:
 
 - prefix and args come from cmd_* functions
 
-get_pathspec() is obsolete and should never be used in new code.
-
 parse_pathspec() helps catch unsupported features and reject them
 politely. At a lower level, different pathspec-related functions may
 not support the same set of features. Such pathspec-sensitive
diff --git a/cache.h b/cache.h
index 4f55466..d4e22e2 100644
--- a/cache.h
+++ b/cache.h
@@ -452,7 +452,6 @@ extern void set_git_work_tree(const char *tree);
 
 #define ALTERNATE_DB_ENVIRONMENT GIT_ALTERNATE_OBJECT_DIRECTORIES
 
-extern const char **get_pathspec(const char *prefix, const char **pathspec);
 extern void setup_work_tree(void);
 extern const char *setup_git_directory_gently(int *);
 extern const char *setup_git_directory(void);
diff --git a/pathspec.c b/pathspec.c
index 9304ee3..abaec0a 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -94,12 +94,6 @@ static void prefix_short_magic(struct strbuf *sb, int 
prefixlen,
  *
  * For now, we only parse the syntax and throw out anything other than
  * top magic.
- *
- * NEEDSWORK: This needs to be rewritten when we start migrating
- * get_pathspec() users to use the struct pathspec interface.  For
- * example, a pathspec element may be marked as case-insensitive, but
- * the prefix part must always match literally, and a single stupid
- * string cannot express such a case.
  */
 static unsigned prefix_pathspec(struct pathspec_item *item,
unsigned *p_short_magic,
@@ -450,36 +444,6 @@ void parse_pathspec(struct pathspec *pathspec,
}
 }
 
-/*
- * N.B. get_pathspec() is deprecated in favor of the struct pathspec
- * based interface - see pathspec.c:parse_pathspec().
- *
- * Arguments:
- *  - prefix - a path relative to the root of the working tree
- *  - pathspec - a list of paths underneath the prefix path
- *
- * Iterates over pathspec, prepending each path with prefix,
- * and return the resulting list.
- *
- * If pathspec is empty, return a singleton list containing prefix.
- *
- * If pathspec and prefix are both empty, return an empty list.
- *
- * This is typically used by built-in commands such as add.c, in order
- * to normalize argv arguments provided to the built-in into a list of
- * paths to process, all relative to the root of the working tree.
- */
-const char **get_pathspec(const char *prefix, const char **pathspec)
-{
-   struct pathspec ps;
-   parse_pathspec(ps,
-  PATHSPEC_ALL_MAGIC 
-  ~(PATHSPEC_FROMTOP | PATHSPEC_LITERAL),
-  PATHSPEC_PREFER_CWD,
-  prefix, pathspec);
-   return ps._raw;
-}
-
 void copy_pathspec(struct pathspec *dst, const struct pathspec *src)
 {
*dst = *src;
diff --git a/pathspec.h b/pathspec.h
index 0c11262..b345df6 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -19,7 +19,7 @@
 #define PATHSPEC_ONESTAR 1 /* the pathspec pattern satisfies GFNM_ONESTAR 
*/
 
 struct pathspec {
-   const char **_raw; /* get_pathspec() result, not freed by 
free_pathspec() */
+   const char **_raw; /* not freed by free_pathspec() */
int nr;
unsigned int has_wildcard:1;
unsigned int recursive:1;
-- 
2.5.0.239.g9728e1d.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


[PATCH 0/2] Remove get_pathspec finally

2015-08-06 Thread Stefan Beller
Remove the last caller of the get_pathspec function and the get_pathspec 
function
itself.

I stumbled into this as I was reading the documentation on pathspec, and the
first sentence

  get_pathspec() is obsolete and should never be used in new code.

made me wonder.

This replaces sb/remove-get-pathspec

Stefan Beller (2):
  builtin/mv: remove get_pathspec()
  pathspec: remove deprecated get_pathspec

 Documentation/technical/api-setup.txt |  2 --
 builtin/mv.c  | 16 +---
 cache.h   |  1 -
 pathspec.c| 36 ---
 pathspec.h|  2 +-
 5 files changed, 14 insertions(+), 43 deletions(-)

-- 
2.5.0.239.g9728e1d.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


[PATCH 1/2] builtin/mv: remove get_pathspec()

2015-08-06 Thread Stefan Beller
`get_pathspec` is deprecated and builtin/mv.c is its last caller, so
reimplement `get_pathspec` literally in builtin/mv.c

Signed-off-by: Stefan Beller sbel...@google.com
---
 builtin/mv.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/builtin/mv.c b/builtin/mv.c
index d1d4316..99e9b3c 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -10,6 +10,7 @@
 #include string-list.h
 #include parse-options.h
 #include submodule.h
+#include pathspec.h
 
 static const char * const builtin_mv_usage[] = {
N_(git mv [options] source... destination),
@@ -20,13 +21,16 @@ static const char * const builtin_mv_usage[] = {
 #define KEEP_TRAILING_SLASH 2
 
 static const char **internal_copy_pathspec(const char *prefix,
-  const char **pathspec,
+  const char **argv,
   int count, unsigned flags)
 {
int i;
+   struct pathspec ps;
const char **result = xmalloc((count + 1) * sizeof(const char *));
-   memcpy(result, pathspec, count * sizeof(const char *));
+   memcpy(result, argv, count * sizeof(const char *));
result[count] = NULL;
+
+   /* NEEDSWORK: Move these preprocessing steps into parse_pathspec */
for (i = 0; i  count; i++) {
int length = strlen(result[i]);
int to_copy = length;
@@ -42,7 +46,13 @@ static const char **internal_copy_pathspec(const char 
*prefix,
result[i] = it;
}
}
-   return get_pathspec(prefix, result);
+
+   parse_pathspec(ps,
+  PATHSPEC_ALL_MAGIC 
+  ~(PATHSPEC_FROMTOP | PATHSPEC_LITERAL),
+  PATHSPEC_PREFER_CWD,
+  prefix, result);
+   return ps._raw;
 }
 
 static const char *add_slash(const char *path)
-- 
2.5.0.239.g9728e1d.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/RFC] gitweb: Don't pass --full-history to git-log(1)

2015-08-06 Thread Junio C Hamano
Junio C Hamano gits...@pobox.com writes:

 Heh, in 2008 we already had more than a few dozen.

 I think

  (1) It is perfectly OK to add an UI option to let the web visitor
  choose between simplified and full history at runtime,
  optionally with a new gitweb.conf option to let the project
  owner choose which one is the default;

  (2) It is also OK to add gitweb.conf option to let the project/site
  choose between the two, optionally allowing the web visitor to
  override it with something like (1).

 Anything else would not give the same out-of-the-box experience and
 would probably not fly well.

Just to make sure, would not fly well is not an outright rejection
(given enough thrust, even a pig could fly).

An alternative with a bit more friction may be to do a variant of
(2), without UI but only with gitweb.conf tweakability, _and_
flipped default.  That will break the out-of-the-box experience but
I suspect that many people would not notice (because their history
is linear), some people who do notice would like the change, and the
remainder can tweak their installation back to the full-history
version, as long the change of the default is prominently
advertised.
--
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: Error when cloning with weird local directory

2015-08-06 Thread Junio C Hamano
Junio C Hamano gits...@pobox.com writes:

 Torsten Bögershausen tbo...@web.de writes:

 It looks as if
 static char *get_repo_path(const char *repo, int *is_bundle)
 in built/clone.c
 checks if there is a local directory structure looking like a
 .git directory.
 This is wrong.

 It is as designed, though, to allow cloning from a local directory
 with any name.

 There should be a check for the scheme first.

 That will be wrong.

It matters mostly when dealing with scp-like syntax, word:path.

I _think_ taking notice of word:// (with doubled slashes) and
treating it specially will not introduce any new issue; while it is
still OK for users to have a local directory called word:, if they
meant a subdirectory of it, they wouldn't have typed double-slashes
there.
--
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: Error when cloning with weird local directory

2015-08-06 Thread Junio C Hamano
Torsten Bögershausen tbo...@web.de writes:

 It looks as if
 static char *get_repo_path(const char *repo, int *is_bundle)
 in built/clone.c
 checks if there is a local directory structure looking like a
 .git directory.
 This is wrong.

It is as designed, though, to allow cloning from a local directory
with any name.

 There should be a check for the scheme first.

That will be wrong.
--
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 0/6] fix repo name when cloning a server's root

2015-08-06 Thread Torsten Bögershausen
On 2015-08-05 23.19, Jeff King wrote:
 On Wed, Aug 05, 2015 at 10:34:34AM -0700, Junio C Hamano wrote:
 
 As you can see, there is a lot of complexity in there and I'm not
 convinced this is better than just exposing
 'parse_connect_url()', which already handles everything for us.
I try expose and use parse_connect_url():
It handles the scp-like syntax host:/path,
literall IPV6 addresses, port numbers,
':' without a port number and all other Git specific parsing,
which is inside and outside the RFC 3986.
(I should know, because I managed to break the parser twice,
and fix it)

I added a diagnostics to connect.c, and if you run the a simply test,
we can see that the colon slash logic is often unsufficient:

tb@mypc:~/projects/git/tb.150731_connect ./git fetch-pack --diag-url 
ssh://host/
Diag: url=ssh://host/
Diag: protocol=ssh
Diag: userandhost=host
Diag: port=NONE
Diag: path=/
Diag: guesseddir=host/
tb@macce:~/projects/git/tb.150731_connect ./git fetch-pack --diag-url 
ssh://host:/
Diag: url=ssh://host:/
Diag: protocol=ssh
Diag: userandhost=host
Diag: port=NONE
Diag: path=/
Diag: guesseddir=/


On top of that, you can easily write test cases in t5601, as many as you want.
The (minor) drawback is that it doesn't handle http:// or https://,
but that is easy to add in the parser, and doesn't break existing code.

The major which remains is to search for '@' in userandhost,
and strip that off.
(Or when there is a '@', search for a ':' before the '@', and strip that off)
After that, all non-printable characters should be %-escaped.
If we replace ':' as non-printable as well, we can make Windows users 1% more 
happy.



 If the function handles everything for us, that's fine, but the
 primary reason I am hesitant is because parse_connect_url() was
 designed specifically not to have to worry about some protocols
 (e.g. I think feeding it a http://; would fail, and more
 importantly, its current callers want such a call to fail).  Also it
 is meant to handle some non-protocols (e.g. scp style host:path that
 does not follow scheme://...).
 
 True, but the transport code _is_ handling that at some point. It makes
 me wonder if it would be possible to push the call to transport_get
 further up inside cmd_clone(), and then provide some way to query the
 remote path and hostname from the transport code. Then guess_dir_name
 could just go away entirely, in favor of something like:
 
   dir_name = transport_get_path(transport);
   if (!*dir_name)
   dir_name = transport_get_host(transport);
 
 That may be overly simplistic or unworkable, though. I haven't dug into
 the code.
 
 Also does it handle the  case above?  I do not think
 parse_connect_url() even calls get_host_and_port() to be able to
 tell what  means in these examples.
 
 Speaking of which, has anyone tested whether the old or new code handles
 external remote helpers? Certainly:
 
   foo::https://host/repo.git
 
 should still use repo.git. But technically the string handed to
 git-remote-foo does not have to look anything like a URL. In those cases
 neither guess_dir_name nor the transport code have any idea what anything
 to the right of the :: means; we probably have to resort to blind
 guessing based on characters like colon and slash.
 
It is easy to strip the foo:: part of the url, assume that
the remote helper uses a RFC 3986 similar url syntax, so that we
can feed the reminding https://host/repo.git into the parser (see above).

If the remote helper doesn't do this, we can't guess anything, can we ?
So error out and tell the user seems the right thing to do.

In the hope that this is useful, pushed my prototype branch to
https://github.com/tboegi/git/tree/150731_connect_diag_guess_name









--
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 0/6] fix repo name when cloning a server's root

2015-08-06 Thread Junio C Hamano
Torsten Bögershausen tbo...@web.de writes:

 It is easy to strip the foo:: part of the url, assume that
 the remote helper uses a RFC 3986 similar url syntax, so that we
 can feed the reminding https://host/repo.git into the parser (see above).

The thing that worries me is that foo:: syntax and external helper
interface was invented by Daniel Barkalow primarily because he
wanted to allow things that do *not* fit in that URL-like scheme,
for example see:

  http://thread.gmane.org/gmane.comp.version-control.git/125374/focus=125405

 If the remote helper doesn't do this, we can't guess anything, can we ?
 So error out and tell the user seems the right thing to do.

Yes.  A blind guess that fails spectacularly is far worse than an
outright rejection that is cautious.
--
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] contrib: teach completion about git-worktree options and arguments

2015-08-06 Thread Eric Sunshine
On Thu, Jul 23, 2015 at 4:49 PM, Eric Sunshine sunsh...@sunshineco.com wrote:
 Complete subcommands 'add' and 'prune', as well as their respective
 options --force, --detach, --dry-run, --verbose, and --expire. Also
 complete 'refname' in git worktree add [-b newbranch] path
 refname.

Ping[1]?

[1]: http://article.gmane.org/gmane.comp.version-control.git/274526

 Signed-off-by: Eric Sunshine sunsh...@sunshineco.com
 ---

 This is RFC since this is my first foray into the Git completion script,
 and there are likely better and more idiomatic ways to accomplish this.

  contrib/completion/git-completion.bash | 32 
  1 file changed, 32 insertions(+)

 diff --git a/contrib/completion/git-completion.bash 
 b/contrib/completion/git-completion.bash
 index c97c648..07c34ef 100644
 --- a/contrib/completion/git-completion.bash
 +++ b/contrib/completion/git-completion.bash
 @@ -2564,6 +2564,38 @@ _git_whatchanged ()
 _git_log
  }

 +_git_worktree ()
 +{
 +   local subcommands='add prune'
 +   local subcommand=$(__git_find_on_cmdline $subcommands)
 +   local c=2 n=0 refpos=2
 +   if [ -z $subcommand ]; then
 +   __gitcomp $subcommands
 +   else
 +   case $subcommand,$cur in
 +   add,--*)
 +   __gitcomp --force --detach
 +   ;;
 +   add,*)
 +   while [ $c -lt $cword ]; do
 +   case ${words[c]} in
 +   --*) ;;
 +   -[bB]) ((refpos++)) ;;
 +   *) ((n++)) ;;
 +   esac
 +   ((c++))
 +   done
 +   if [ $n -eq $refpos ]; then
 +   __gitcomp_nl $(__git_refs)
 +   fi
 +   ;;
 +   prune,--*)
 +   __gitcomp --dry-run --verbose --expire
 +   ;;
 +   esac
 +   fi
 +}
 +
  __git_main ()
  {
 local i c=1 command __git_dir
 --
 2.5.0.rc3.407.g68aafd0
--
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