Re: [PATCH v2 11/11] ref-filter: introduce objectname_atom_parser()

2015-12-17 Thread Eric Sunshine
On Wed, Dec 16, 2015 at 10:30 AM, Karthik Nayak  wrote:
> Introduce objectname_atom_parser() which will parse the
> '%(objectname)' atom and store information into the 'used_atom'
> structure based on the modifiers used along with the atom.
>
> Helped-by: Ramsay Jones 
> Signed-off-by: Karthik Nayak 
> ---
> diff --git a/ref-filter.c b/ref-filter.c
> @@ -43,6 +43,7 @@ static struct used_atom {
> enum { C_BARE, C_BODY, C_BODY_DEP, C_LINES, C_SIG, 
> C_SUB } option;
> unsigned int no_lines;
> } contents;
> +   enum { O_FULL, O_SHORT } objectname;
> } u;
>  } *used_atom;
> @@ -124,6 +125,21 @@ static void contents_atom_parser(struct used_atom *atom)
> +static void objectname_atom_parser(struct used_atom *atom)
> +{
> +   const char * buf;
> +
> +   if (match_atom_name(atom->str, "objectname", &buf))
> +   atom->u.objectname = O_FULL;
> +   if (!buf)
> +   return;

Let me make sure that I understand this correctly.

make_atom_name("objectname") will return true only for "objectname" or
"objectname:", and will return false for anything else, such as
"objectnamely" or "schmorf". Furthermore, the only way
objectname_atom_parser() can be called is when %(objectname) or
%(objectname:...) is seen, thus match_atom_name() *must* return true
here, which means the above conditional is misleading, suggesting that
it could somehow return false.

And, if match_atom_name() did return false here, then that indicates a
programming error: objectname_atom_parser() somehow got called for
something other than %(objectname) or %(objectname:...). This implies
that the code should instead be structured like this:

if (!match_atom_name(..., "objectname", &buf)
die("BUG: parsing non-'objectname'")
if (!buf)
atom->u.objectname = O_FULL;
else if (!strcmp(buf, "short"))
atom->u.objectname = O_SHORT;
else
die(_("unrecognized %%(objectname) argument: %s"), buf);

However, this can be simplified further by recognizing that, following
this patch series, match_atom_name() is *only* called by these new
parse functions[1], which means that, as a convenience,
match_atom_name() itself could become a void rather than boolean
function and die() if the expected atom name is not found. Thus, the
code would become:

match_atom_name(...);
if (!buf)
...
else if (!strcmp(...))
...
...

By the way, the above commentary isn't specific to this patch and
%(objectname), but is in fact also relevant for all of the preceding
patches which introduce parse functions calling match_atom_name().

More below...

[1]: ...assuming you replace the unnecessary match_atom_name() in
populate_value() with starts_with() as suggested in my patch 7/11
review addendum[2].

[2]: http://article.gmane.org/gmane.comp.version-control.git/282700

> +
> +   if (!strcmp(buf, "short"))
> +   atom->u.objectname = O_SHORT;
> +   else
> +   die(_("unrecognized %%(objectname) argument: %s"), buf);
> +}
> +
> @@ -461,15 +477,16 @@ static void *get_obj(const unsigned char *sha1, struct 
> object **obj, unsigned lo
>  static int grab_objectname(const char *name, const unsigned char *sha1,
> -   struct atom_value *v)
> +  struct atom_value *v, struct used_atom *atom)
>  {
> -   if (!strcmp(name, "objectname")) {
> -   v->s = xstrdup(sha1_to_hex(sha1));
> -   return 1;
> -   }
> -   if (!strcmp(name, "objectname:short")) {
> -   v->s = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV));
> -   return 1;
> +   if (starts_with(name, "objectname")) {
> +   if (atom->u.objectname == O_SHORT) {
> +   v->s = xstrdup(find_unique_abbrev(sha1, 
> DEFAULT_ABBREV));
> +   return 1;
> +   } else if (atom->u.objectname == O_FULL) {
> +   v->s = xstrdup(sha1_to_hex(sha1));
> +   return 1;
> +   }

Since 'objectname' can only ever be O_SHORT or O_FULL wouldn't it be a
programming error if it ever falls through to this point after the
closing brace? Perhaps a die("BUG:...") would be appropriate?

> }
> return 0;
>  }
> @@ -493,7 +510,7 @@ static void grab_common_values(struct atom_value *val, 
> int deref, struct object
> v->s = xstrfmt("%lu", sz);
> }
> else if (deref)
> -   grab_objectname(name, obj->sha1, v);
> +   grab_objectname(name, obj->sha1, v, &used_atom[i]);

This patch hunk is somehow corrupt and doesn't apply. Was there some
hand-editing involved, or were some earlier patches regenerated after
this patch was made or something?

> }
>  }
>
> @@ -999,7 +1016,7 @@ static void populate_value(struct ref_array_item *ref)
>   

Re: [PATCH v2 07/11] ref-filter: introduce align_atom_parser()

2015-12-17 Thread Eric Sunshine
On Wed, Dec 16, 2015 at 10:29 AM, Karthik Nayak  wrote:
> Introduce align_atom_parser() which will parse an "align" atom and
> store the required alignment position and width in the "use_atom"
> structure for further usage in 'populate_value()'.
>
> Helped-by: Ramsay Jones 
> Signed-off-by: Karthik Nayak 
> ---
> diff --git a/ref-filter.c b/ref-filter.c
> @@ -63,6 +69,49 @@ static void color_atom_parser(struct used_atom *atom)
> +static void align_atom_parser(struct used_atom *atom)
> +{
> +   [...]
> +   match_atom_name(atom->str, "align", &buf);
> +   if (!buf)
> +   die(_("expected format: %%(align:,)"));
> +   [...]
> +}
> @@ -880,35 +924,7 @@ static void populate_value(struct ref_array_item *ref)
> v->s = " ";
> continue;
> } else if (match_atom_name(name, "align", &valp)) {

Hmm, align_atom_parser() has already been called before we get here,
right? And it has already invoked match_atom_name() and died if the
argument to "align:" was missing, correct? If so, then this invocation
of match_atom_name() in populate_value() is unnecessary and should be
replaced with a simpler starts_with("align:").

Plus, 'valp' is not used, aside from this unnecessary
match_atom_name(), thus it can be removed as well.

> -   struct align *align = &v->u.align;
> -   struct strbuf **s, **to_free;
> -   int width = -1;
> -
> -   if (!valp)
> -   die(_("expected format: 
> %%(align:,)"));
> -
> -   s = to_free = strbuf_split_str_omit_term(valp, ',', 
> 0);
> -
> -   align->position = ALIGN_LEFT;
> -
> -   while (*s) {
> -   if (!strtoul_ui(s[0]->buf, 10, (unsigned int 
> *)&width))
> -   ;
> -   else if (!strcmp(s[0]->buf, "left"))
> -   align->position = ALIGN_LEFT;
> -   else if (!strcmp(s[0]->buf, "right"))
> -   align->position = ALIGN_RIGHT;
> -   else if (!strcmp(s[0]->buf, "middle"))
> -   align->position = ALIGN_MIDDLE;
> -   else
> -   die(_("improper format entered 
> align:%s"), s[0]->buf);
> -   s++;
> -   }
> -
> -   if (width < 0)
> -   die(_("positive width expected with the 
> %%(align) atom"));
> -   align->width = width;
> -   strbuf_list_free(to_free);
> +   v->u.align = atom->u.align;
> v->handler = align_atom_handler;
> continue;
> } else if (!strcmp(name, "end")) {
> --
> 2.6.4
--
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 02/16] refs: add methods for misc ref operations

2015-12-17 Thread Howard Chu
Junio C Hamano  pobox.com> writes:

> 
> David Turner  twopensource.com> writes:
> 
> >  struct ref_be {
> > struct ref_be *next;
> > const char *name;
> > ref_transaction_commit_fn *transaction_commit;
> > +
> > +   pack_refs_fn *pack_refs;
> > +   peel_ref_fn *peel_ref;
> > +   create_symref_fn *create_symref;
> > +
> > +   resolve_ref_unsafe_fn *resolve_ref_unsafe;
> > +   verify_refname_available_fn *verify_refname_available;
> > +   resolve_gitlink_ref_fn *resolve_gitlink_ref;
> >  };
> 
> This may have been pointed out in the previous reviews by somebody
> else, but I think it is more customary to declare a struct member
> that is a pointer to a customization function without leading '*',
> i.e.
> 
>   typedef TYPE (*customize_fn)(ARGS);
> 
> struct vtable {
>   ...
>   cutomize_fn fn;
>   ...
>   };
> 
> in our codebase (cf. string_list::cmp, prio_queue::compare).

(LMDB author here, just passing by)

IMO you're making a mistake. You should always typedef the thing itself, not
a pointer to the thing. If you only typedef the pointer, you can only use
the typedef to declare pointers and never the thing itself. If you typedef
the actual thing, you can use the typedef to declare both the thing and
pointer to thing.

It's particularly useful to have function typedefs because later on you can
use the actual typedef to declare instances of that function type in header
files, and guarantee that your function definitions match what they're
intended to match. Otherwise, assigning a bare (*func) to something that
mismatches only generates a warning, instead of an error.

-- 
  -- Howard Chu
  CTO, Symas Corp.   http://www.symas.com
  Director, Highland Sun http://highlandsun.com/hyc/
  Chief Architect, OpenLDAP  http://www.openldap.org/project/ 


--
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] Malicously tampering git metadata?

2015-12-17 Thread Jeff King
On Tue, Dec 15, 2015 at 10:26:39PM -0500, Santiago Torres wrote:

> An example of a malicious commit merge follows:
> 
> 1) The attacker controlling or acting as the upstream server identifies
> two branches: one in which the unsuspecting developer is working on, and
> another in which a vulnerable piece of code is located.

One thing to make clear here: the side branch with the vulnerable code
must be a _new_ vulnerability that was not already part of the "main"
branch the developer is working on. That is, I do not immediately see a
way to resurrect an old vulnerability, because a merge of the old,
broken commit would not result in reintroducing it.

This is more about "there was experimental junk on branch X, and you
tricked some developer into pulling X onto Y, and now Y unexpectedly has
the junk on it". And I agree with Stefan that push-certs are the
intended defense against this.

Of course, in the real world things are much easier. Most projects do
not sign commits at all, let alone use push certs. If developers are
pulling from a compromised server, then you can simply make up whatever
broken commits you want, and there's no way to tell the difference
between them and the real commits.

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


Re: [RFC] Malicously tampering git metadata?

2015-12-17 Thread Jeff King
On Thu, Dec 17, 2015 at 08:06:36PM -0500, Santiago Torres wrote:

> > This is what push certificates ought to solve.
> > The server records all pushes and its signed certificates of pushes
> > and by the difference of the
> > refs (either in packed refs or as a loose ref) to the push certificate
> > this tampering of
> > the server can be detected.
> 
> Is there any specification about push certificates? I would like to read
> about them, but I don't seem to find documentation anywhere. Are they a
> part of git's specification?

Try pack-protocol.txt and protocol-capabilities.txt in the
Documentation/technical directory of the git.git repo.

E.g.:

  
https://github.com/git/git/blob/bdfc6b364a51b19efbacbd46fcef5be41a5db50e/Documentation/technical/pack-protocol.txt#L489

-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: [PATCHv2] submodule: Port resolve_relative_url from shell to C

2015-12-17 Thread Jeff King
On Thu, Dec 17, 2015 at 07:55:43PM +0100, Johannes Sixt wrote:

> -static int has_same_dir_prefix(const char *str, const char **out)
> +static int starts_with_dot_slash(const char *str)
>  {
> -#ifdef GIT_WINDOWS_NATIVE
> - return skip_prefix(str, "./", out)
> - || skip_prefix(str, ".\\", out);
> -#else
> - return skip_prefix(str, "./", out);
> -#endif
> + return str[0] == '.' && is_dir_sep(str[1]);
>  }
>  
> -static int has_upper_dir_prefix(const char *str, const char **out)
> +static int starts_with_dot_dot_slash(const char *str)
>  {
> -#ifdef GIT_WINDOWS_NATIVE
> - return skip_prefix(str, "../", out)
> - || skip_prefix(str, "..\\", out);
> -#else
> - return skip_prefix(str, "../", out);
> -#endif
> + return str[0] == '.' && str[1] == '.' && is_dir_sep(str[2]);
>  }

As the set of prefixes you are looking is probably bounded, it may not
be worth generalizing this. But I wondered if something like:

  /*
   * Like skip_prefix, but consider any "/" in the prefix as a
   * directory separator for the platform.
   */
  int skip_prefix_fs(const char *str, const char *prefix, const char **out)
  {
while (1) {
if (!*prefix) {
*out = str;
return 1;
} else if (*prefix == '/') {
if (!is_dir_sep(*str))
return 0;
} else {
if (*str != *prefix)
return 0;
}
str++;
prefix++;
}
  }

  ...
  /* works on all platforms! */
  if (skip_prefix_fs(foo, "./", &out))
...

would be helpful. I don't know if there are other opportunities in the
code base that could make use of this. If it's just these two sites,
it's probably not worth it.

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


Re: [PATCHv2 2/7] xread: poll on non blocking fds

2015-12-17 Thread Jeff King
On Thu, Dec 17, 2015 at 12:51:08PM -0800, Stefan Beller wrote:

> > poll() returns -1; errno = EAGAIN /* poll failed. If the fd was OK, the 
> > failure may be temporaly,
> > as much as poll() can see.
> > But most probably we run out ouf memory 
> > */
> 
> Before this patch we would not have asked poll, but had just a continue here,
> so I think we need to have it here again no matter of the return code
> of the poll.
> 
> If poll determines it is low on memory, this should not make this function 
> fail,
> we can still do as good as we did before by just asking read
> repeatedly again, though?
> 
> So I'd be convinced now we'd want to have:
> 
> poll(&pfd, 1, -1); /* this is only buying time
> for the fd to deliver data, in case it fails
> we don't care but just fall back to old
> behavior before this patch with busy spinning*/
> continue;

Right. I think that is the only sensible thing, and your comment
explains perfectly what is going on.

-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: [PATCHv2 2/7] xread: poll on non blocking fds

2015-12-17 Thread Jeff King
On Thu, Dec 17, 2015 at 09:42:01PM +0100, Torsten Bögershausen wrote:

> > Or do you mean to insert another continue in here?
> I was thinking that we run into similar loop as before:
> read() returns -1; errno = EAGAIN  /* No data to read */
> poll() returns -1; errno = EAGAIN /* poll failed. If the fd was OK, the 
> failure may be temporaly,
> as much as poll() can see.
> But most probably we run out ouf memory */
> 
> So the code would look like this:
> 
>if (!poll(&pfd, 1, -1))
>   return -1;

That changes the semantics of the function. The poll() is just a
convenience to avoid spinning. If it fails, with Stefan's patch[1] the
worst case is that we would spin on read() and poll(), instead of
actually blocking in the poll().

But if we return on poll() failure, now the caller will see errors from
poll() even though they don't know or care that we called poll() in the
first place. Consider what would happen with your code if read got
EAGAIN and then poll got EINTR. We would report an error, even though
the whole point of xread() is to loop on these conditions.

-Peff

[1] Stefan's patch does have a bug. It forgets to "continue" after
calling poll, which means we will block with poll and _then_ exit
with -1, instead of restarting the loop.
--
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: [PATCHv2 2/7] xread: poll on non blocking fds

2015-12-17 Thread Jeff King
On Tue, Dec 15, 2015 at 04:04:07PM -0800, Stefan Beller wrote:

> If we get an EAGAIN or EWOULDBLOCK the fd must have set O_NONBLOCK.
> As the intent of xread is to read as much as possible either until the
> fd is EOF or an actual error occurs, we can ease the feeder of the fd
> by not spinning the whole time, but rather wait for it politely by not
> busy waiting.

I'm not sure this second sentence is true. The point of xread() is to do
a single read that makes forward progress (or returns a real error), not
to read as much as we can.

The rationale seems more to me like:

  The point of xread() is to perform read() until we either get some
  data, or encounter a "real" error. We do not count EINTR or EAGAIN as
  "real" errors, as a reader trying to make forward progress would
  generally just repeat the read, so we loop for them as a convenience.

  In the case of EINTR, trying the read() again immediately is fine; a
  signal interrupted us, but there is no reason to think the read()
  would not succeed if we tried it again.

  For EAGAIN, however, we know that the fd must have set O_NONBLOCK. In
  this case reading again immediately is not likely to produce results,
  and we will chew up CPU spinning on read() calls. Instead, let's
  insert a poll() to block until we actually get data.

I also don't know that this patch necessarily needs to be part of the
parallel-fetch series anymore. We are not setting O_NONBLOCK ourselves,
and I don't think the correctness of the new strbuf_read_once() is
impacted by this. I.e., I think this optimization applies equally well
to the hundreds of existing xread() calls, should they unexpectedly be
fed an O_NONBLOCK descriptor.

That said, I do not mind it here, but I think it could be its own
separate topic if you wanted to reduce the complexity of the
parallel-fetch topic.

> We should not care if the call to poll failed, as we're in an infinite
> loop and can only get out with the correct read().

You might want to expand on "correct" here. I think you mean "can only
get out with a read() that returns data or a "real" error" (I am reusing
the terminology I introduced above; I am fine with other terminology,
depending on how you word the rest of it).

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


Re: RefTree: Alternate ref backend

2015-12-17 Thread Mike Hommey
On Thu, Dec 17, 2015 at 02:28:01PM -0800, Shawn Pearce wrote:
> On Thu, Dec 17, 2015 at 2:10 PM, Jeff King  wrote:
> > On Thu, Dec 17, 2015 at 01:02:50PM -0800, Shawn Pearce wrote:
> >
> >> I started playing around with the idea of storing references directly
> >> in Git. Exploiting the GITLINK tree entry, we can associate a name to
> >> any SHA-1.
> >
> > Gitlink entries don't imply reachability, though. I guess that doesn't
> > matter if your ref backend says "no, really, these are the ref tips, and
> > they are reachable".
> 
> Exactly. This works with existing JGit because it swaps out the ref
> backend. When GC tries to enumerate the roots (current refs), it gets
> these through the ref backend by scanning the tree recursively. The
> packer itself doesn't care where those roots came from.
> 
> Same would be true for any other pluggable ref backend in git-core. GC
> has to ask the ref backend, and then trust its reply. How/where that
> ref backend tracks that is an implementation detail.
> 
> >  But you could not push the whole thing up to
> > another server and expect it to hold the whole graph.
> 
> Correct, pushing this to another repository doesn't transmit the
> graph. If the other repository also used this for its refs backend,
> its now corrupt and confused out of its mind. Just like copying the
> packed-refs file with scp. Don't do that. :)
> 
> > Which is not strictly necessary, but to me seems like the real advantage
> > of using git objects versus some other system.
> 
> One advantage is you can edit HEAD symref remotely. Commit a different
> symlink value and push. :)
> 
> I want to say more, but I'm going to hold back right now. There's more
> going on in my head than just this.
> 
> > Of course, the lack of reachability has advantages, too. You can
> > drop commits pointed to by old reflogs without rewriting the ref
> > history.
> 
> Yes.

Related thread: "Allowing weak references to blobs and strong references
to commits" http://marc.info/?l=git&m=142779648816577&w=2

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


-C option with pull doesn't seem to be respected in aliases in git 2.6.4.

2015-12-17 Thread Cameron Esfahani
I have git project checked out at ~/llvm.  Inside of there, inside of a “tools” 
directory, I have another project checked out as “lldb”:

~/llvm/tools/lldb

I wrote an alias which would help me update all my projects:

all = !find . -type d -name .git | sed 's:/.git::' | xargs -I{} -t git 
-C {} $1 && :

This would allow me to be inside of ~/llvm and type "git all pull" and get all 
my projects updated.

It seems that at some point this broke.  If try to use this alias under git 
2.6.4, it only updates the llvm project.

The interesting thing is that if I pass fetch, instead of pull: "git all 
fetch", then it seems to work correctly.

Here’s the GIT_TRACE output for “git all pull” when in ~/llvm:

[llvm (master)]$ GIT_TRACE=1 git all pull
17:28:43.938363 git.c:558   trace: exec: 'git-all' 'pull'
17:28:43.938813 run-command.c:335   trace: run_command: 'git-all' 'pull'
17:28:43.940167 run-command.c:335   trace: run_command: 'find . -type d 
-name .git | sed '\''s:/.git::'\'' | xargs -I{} -t git -C {} $1 && :' 'pull'
17:28:43.940665 run-command.c:195   trace: exec: '/bin/sh' '-c' 'find . 
-type d -name .git | sed '\''s:/.git::'\'' | xargs -I{} -t git -C {} $1 && : 
"$@"' 'find . -type d -name .git | sed '\''s:/.git::'\'' | xargs -I{} -t git -C 
{} $1 && :' 'pull'
git -C . pull
17:28:44.191670 git.c:558   trace: exec: 'git-pull'
17:28:44.192253 run-command.c:335   trace: run_command: 'git-pull'
17:28:44.197094 git.c:348   trace: built-in: git 'rev-parse' 
'--parseopt' '--stuck-long' '--'
17:28:44.203237 git.c:348   trace: built-in: git 'rev-parse' 
'--git-dir'
17:28:44.207297 git.c:348   trace: built-in: git 'rev-parse' 
'--git-path' 'objects'
17:28:44.210819 git.c:348   trace: built-in: git 'rev-parse' 
'--is-bare-repository'
17:28:44.213666 git.c:348   trace: built-in: git 'rev-parse' 
'--show-toplevel'
17:28:44.216954 git.c:348   trace: built-in: git 'ls-files' '-u'
17:28:44.227604 git.c:348   trace: built-in: git 'symbolic-ref' 
'-q' 'HEAD'
17:28:44.233503 git.c:348   trace: built-in: git 'config' 
'branch.master.rebase'
17:28:44.244334 git.c:348   trace: built-in: git 'config' 'pull.ff'
17:28:44.247510 git.c:348   trace: built-in: git 'rev-parse' '-q' 
'--verify' 'HEAD'
17:28:44.250365 git.c:348   trace: built-in: git 'rev-parse' 
'--verify' 'HEAD'
17:28:44.253328 git.c:348   trace: built-in: git 'update-index' 
'-q' '--ignore-submodules' '--refresh'
17:28:44.282912 git.c:348   trace: built-in: git 'diff-files' 
'--quiet' '--ignore-submodules'
17:28:44.317433 git.c:348   trace: built-in: git 'diff-index' 
'--cached' '--quiet' '--ignore-submodules' 'HEAD' '--'
17:28:44.332900 git.c:348   trace: built-in: git 'rev-parse' '-q' 
'--git-dir'
17:28:44.366055 git.c:348   trace: built-in: git 'rev-parse' '-q' 
'--verify' 'HEAD'
17:28:44.369245 git.c:348   trace: built-in: git 'fetch' 
'--update-head-ok'
17:28:44.380626 run-command.c:335   trace: run_command: 'git-remote-http' 
'origin' 'http://llvm.org/git/llvm.git'
17:28:44.575908 run-command.c:335   trace: run_command: 'rev-list' 
'--objects' '--stdin' '--not' '--all' '--quiet'
17:28:44.583303 run-command.c:335   trace: run_command: 'rev-list' 
'--objects' '--stdin' '--not' '--all'
17:28:44.583756 exec_cmd.c:178  trace: exec: 'git' 'rev-list' 
'--objects' '--stdin' '--not' '--all'
17:28:44.585457 git.c:348   trace: built-in: git 'rev-list' 
'--objects' '--stdin' '--not' '--all'
17:28:44.591116 run-command.c:335   trace: run_command: 'gc' '--auto'
17:28:44.591576 exec_cmd.c:178  trace: exec: 'git' 'gc' '--auto'
17:28:44.593252 git.c:348   trace: built-in: git 'gc' '--auto'
17:28:44.597284 git.c:348   trace: built-in: git 'rev-parse' '-q' 
'--verify' 'HEAD'
17:28:44.604021 git.c:348   trace: built-in: git 'show-branch' 
'--merge-base' 'refs/heads/master' 'ce00641ac5f4ca2a073b732a75169037a2d9bef0' 
'ce00641ac5f4ca2a073b732a75169037a2d9bef0'
17:28:44.610870 git.c:348   trace: built-in: git 'rev-parse' 
'--parseopt' '--stuck-long' '--' '--onto' 
'ce00641ac5f4ca2a073b732a75169037a2d9bef0' 
'ce00641ac5f4ca2a073b732a75169037a2d9bef0'
17:28:44.617283 git.c:348   trace: built-in: git 'rev-parse' 
'--git-dir'
17:28:44.621510 git.c:348   trace: built-in: git 'rev-parse' 
'--git-path' 'objects'
17:28:44.626588 git.c:348   trace: built-in: git 'rev-parse' 
'--is-bare-repository'
17:28:44.629515 git.c:348   trace: built-in: git 'rev-parse' 
'--show-toplevel'
17:28:44.633673 git.c:348   trace: built-in: git 'config' '--bool' 
'rebase.stat'
17:28:44.636888 git.c:348   trace: built-in: git 'config' '--bool' 
'rebase.autostash'
17:28:44.640171 git.c:348   tra

Re: [RFC] Malicously tampering git metadata?

2015-12-17 Thread Santiago Torres
Hi Stefan, thanks for the insight. 

> This is what push certificates ought to solve.
> The server records all pushes and its signed certificates of pushes
> and by the difference of the
> refs (either in packed refs or as a loose ref) to the push certificate
> this tampering of
> the server can be detected.

Is there any specification about push certificates? I would like to read
about them, but I don't seem to find documentation anywhere. Are they a
part of git's specification?

> 
> The push certs can however not be obtained via Git itself (they are
> just stored on the
> server for now for later inspection or similar), because to be really
> sure the client would
> need to learn about these push certificates out of band.

I was thinking that an in-band solution could be integrated as long as
we assume a compromise would result in an complete (unreconcilable)
fork attack; fork attacks aren't subtle and could be detected easily.

> 
> The model there would be:
> * A vulnerable piece of software exists.
> * It get's fixed (and the fix is pushed with a signed push)
> * the MITM server doesn't show the fix (show the code from before fix) nor
>   the push certificate thereof
> * client still pulls vulnerable code

Yes, this is a possible attack vector. However, a server could also
present a branch pointer as different (e.g., point an experimental
branch to an unsigned v1.1 tag). This has other implications, as the
code is pushed/pulled from upstream, it just goes somewhere different.

> 
> This model shows the distribution of push certs via the server itself may not 
> be
> optimal.

Yes, it might not be optimal, but it could provide protection against
the attack I just described, for more complex attacks might not be so
subtle. Adding to this, developers likely coordinate their efforts
through other means (sic), so the lack of a push certificate (withheld
by a server) could raise some yellow flags.

We've made a proof of concept of such tool (in-bandh push certificates),
and would like to share the basic design of it here. However, it follows
our threat model: a compromised server that can't introduce malicious
code (thanks to commit signing), but can modify branch pointers and
other unsigned metadata to alter the repository's state.

> 
> Thanks for researching on Git,

Thanks for working in such a great tool :)
-Santiago

> Stefan
--
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] git-svn: add support for prefixed globs in config

2015-12-17 Thread Eric Wong
Victor Leschuk  wrote:
> --- /dev/null
> +++ b/t/t9168-git-svn-prefixed-glob.sh
> @@ -0,0 +1,136 @@
> +#!/bin/sh
> +test_description='git svn globbing refspecs with prefixed globs'
> +. ./lib-git-svn.sh
> +
> +cat >expect.end < +the end
> +hi
> +start a new branch
> +initial
> +EOF
> +
> +test_expect_success 'test refspec prefixed globbing' '



> +echo try to try >expect.two &&
> +echo nothing to see here >>expect.two &&
> +cat expect.end >>expect.two

What happens when the cat fails?

Should probably be folded into the subsequent test case.
(I used to write tests with "set -e", but it's not descriptive
as far as failure goes).

> +test_expect_success 'test left-hand-side only prefixed globbing' '
> + git config --add svn-remote.two.url "$svnrepo" &&


> +echo "Only one set of wildcard directories" \
> + "(e.g. '*' or '*/*/*') is supported: 'branches/b_*/t/*'" >expect.four &&
> +echo "" >>expect.four

Same with echo...

> +test_expect_success 'test disallow prefixed multi-globs' '
--
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 4/4] git gui: allow for a long recentrepo list

2015-12-17 Thread Philip Oakley

From: "Junio C Hamano" 

Philip Oakley  writes:


The gui.recentrepo list may be longer than the maxrecent setting.
Use the actual length determined earlier, now saved as $lenrecent.

In an ideal world, the git gui would limit the number of entries
to the maxrecent setting, however the recentrepo config list may
have been extended outside of the gui, or the maxrecent setting changed
to a reduced value. Further, when testing the gui's recentrepo
logic it is useful to show these extra, but valid, entries.

The list length will be trimmed to $maxrecent after the user selects
a repo to open.

Signed-off-by: Philip Oakley 
---
V2:
word usage corrected.
Eric's comments $gmane/282432
V3:
Updated list length measure following Junio's comments $gmane/282669

Replaces the previous V2 Patch 4/4.

---
 git-gui/lib/choose_repository.tcl | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/git-gui/lib/choose_repository.tcl 
b/git-gui/lib/choose_repository.tcl

index ad7a888..b4cc7dd 100644
--- a/git-gui/lib/choose_repository.tcl
+++ b/git-gui/lib/choose_repository.tcl
@@ -134,7 +134,8 @@ constructor pick {} {
 $opts conf -state disabled

 set sorted_recent [_get_recentrepos]
- if {[llength $sorted_recent] > 0} {
+ set lenrecent [llength $sorted_recent]
+ if {$lenrecent > 0} {
 if {$m_repo ne {}} {
 $m_repo add separator
 $m_repo add command \
@@ -153,7 +154,7 @@ constructor pick {} {
 -background [get_bg_color $w_body.recentlabel] \
 -wrap none \
 -width 50 \
- -height $maxrecent
+ -height $lenrecent
 $w_recentlist tag conf link \
 -foreground blue \
 -underline 1


Natural questions that come to mind after seeing the above are like
these:

- Does maxrecent still get used after this change?


Yes, essentially as you describe



- Does the remainder of the code get upset if -height is set to too
  small (lenrecent might turn out to be 1, for example)?


No it's OK, the code has at least checked it is positive..



And grepping for maxrecent shows there is _append_recentrepos that
does this:


It does three things:
- removes the current (selected) repo from the list of past repos (and 
removes any duplicates)

- places the current repo at the end
- trims the list to back to max repos.

Nominally, it can't do anything about non-selected valid repos which may be 
listed in the config twice because git config won't selectively remove just 
one of two identical key/values, however in Patch 3 I do remove both older & 
newer entries and re-read the config (some may consider that a small 
regression).


It's not easy working around the contrary assumptions of the gui.recentrepo 
list (once only) and the reality of the .gitconfig (duplicates possible) and 
'git config's --unset/--unset-all limitation.


Exactly how those extra entries get there is an open question, but it does 
happen (so say's google, as well as the user report, I've seen it myself ;-)




proc _append_recentrepos {path} {
set path [file normalize $path]
set recent [get_config gui.recentrepo]

...
if {[set maxrecent [get_config gui.maxrecentrepo]] eq {}} {
set maxrecent 10
}

while {[llength $recent] > $maxrecent} {
_unset_recentrepo [lindex $recent 0]
set recent [lrange $recent 1 end]
}
}

The last while loop looks to me like truncating the overlong recent
list down to maxrecent.


Yes


  Perhaps a similar logic needs to be at the
end of _get_recentrepos?


The logic here is to show what is in the config to the user, *before* we 
trim the list, hence we wait until the user has selected a repo to open and 
do the purging in _append_recentrepos.


As an aside, there's also a long standing 'feature' that if one works both 
on and off network, then network repo paths get trimmed as soon as the user 
starts the gui while off-net (or the network goes down;-) because those 
recent repo paths become 'invalid' and are purged, but let's not go there.


--
Philip 


--
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: Git issue report : issue with capital letter in folder name

2015-12-17 Thread PFDuc

Le 2015-12-17 13:29, Stefan Beller a écrit :

On Thu, Dec 17, 2015 at 7:45 AM, PFDuc
 wrote:

Hello,

first of all thank you for developping git !

I had an issue with a capital block in the folder name inside my git repo.
The folder in my local was named "Display" and the one at origin was named
"display" resulting in error when importing python code from this folder for
users who got the repo from origin.

By any chance, were different operating systems or file systems
involved in creation of
this problem?

It might be the case, a mix between windows7, ubuntu and macOS

There are file systems which care about the capitalization, and others don't.
So if you have a file system which doesn't care about capitalization
of the folder/file name,
you can use a different capitalization and it still works. If you take
the code to
another system then, which is a bit more careful there are problems of course.

The main question which remains, is how is Git involved? i.e. would it
also happen
if you just transfer a tarball? Did Git itself break anything?
I don't think git broke anything it is just that the folder name was not 
being changed to the one with a capital letter when I pushed on origin, 
the only way out I found was the one I described in my initial email. I 
thought then the problem might occur from git, but as you say it is 
probably a cross platform issue. The folder initially created was named 
display, then I changed it locally but git wouldn't recognize it as 
something to commit (platform windows7)


I just wanted to let you know in case it would have been an issue you 
wouldn't be aware of.


Regards,

Pierre-François

I tried to change the folder name on bitbucket.org but I was unable to (or
wasn't smart enough to find how to).

I fixed the issue by deleting the file from my local, then commit, then
push, put the same folder in my local, then commit then push.

I am therefore only writing to tell you that story which is not so
important, but I had the thought that because it is not so important maybe
nobody reports that and the bug (if any) cannot be fixed.

Have a good day and happy end of year season!

Regards,

Pierre-François Duc
PhD candidate Physics McGill university
--
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


--
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 4/4] git gui: allow for a long recentrepo list

2015-12-17 Thread Junio C Hamano
Philip Oakley  writes:

> The gui.recentrepo list may be longer than the maxrecent setting.
> Use the actual length determined earlier, now saved as $lenrecent.
>
> In an ideal world, the git gui would limit the number of entries
> to the maxrecent setting, however the recentrepo config list may
> have been extended outside of the gui, or the maxrecent setting changed
> to a reduced value. Further, when testing the gui's recentrepo
> logic it is useful to show these extra, but valid, entries.
>
> The list length will be trimmed to $maxrecent after the user selects
> a repo to open.
>
> Signed-off-by: Philip Oakley 
> ---
> V2:
> word usage corrected.
> Eric's comments $gmane/282432
> V3: 
> Updated list length measure following Junio's comments $gmane/282669
>
> Replaces the previous V2 Patch 4/4.
>
> ---
>  git-gui/lib/choose_repository.tcl | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/git-gui/lib/choose_repository.tcl 
> b/git-gui/lib/choose_repository.tcl
> index ad7a888..b4cc7dd 100644
> --- a/git-gui/lib/choose_repository.tcl
> +++ b/git-gui/lib/choose_repository.tcl
> @@ -134,7 +134,8 @@ constructor pick {} {
>   $opts conf -state disabled
>  
>   set sorted_recent [_get_recentrepos]
> - if {[llength $sorted_recent] > 0} {
> + set lenrecent [llength $sorted_recent]
> + if {$lenrecent > 0} {
>   if {$m_repo ne {}} {
>   $m_repo add separator
>   $m_repo add command \
> @@ -153,7 +154,7 @@ constructor pick {} {
>   -background [get_bg_color $w_body.recentlabel] \
>   -wrap none \
>   -width 50 \
> - -height $maxrecent
> + -height $lenrecent
>   $w_recentlist tag conf link \
>   -foreground blue \
>   -underline 1

Natural questions that come to mind after seeing the above are like
these:

 - Does maxrecent still get used after this change?

 - Does the remainder of the code get upset if -height is set to too
   small (lenrecent might turn out to be 1, for example)?

And grepping for maxrecent shows there is _append_recentrepos that
does this:

proc _append_recentrepos {path} {
set path [file normalize $path]
set recent [get_config gui.recentrepo]

...
if {[set maxrecent [get_config gui.maxrecentrepo]] eq {}} {
set maxrecent 10
}

while {[llength $recent] > $maxrecent} {
_unset_recentrepo [lindex $recent 0]
set recent [lrange $recent 1 end]
}
}

The last while loop looks to me like truncating the overlong recent
list down to maxrecent.  Perhaps a similar logic needs to be at the
end of _get_recentrepos?
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 4/4] git gui: allow for a long recentrepo list

2015-12-17 Thread Philip Oakley
The gui.recentrepo list may be longer than the maxrecent setting.
Use the actual length determined earlier, now saved as $lenrecent.

In an ideal world, the git gui would limit the number of entries
to the maxrecent setting, however the recentrepo config list may
have been extended outside of the gui, or the maxrecent setting changed
to a reduced value. Further, when testing the gui's recentrepo
logic it is useful to show these extra, but valid, entries.

The list length will be trimmed to $maxrecent after the user selects
a repo to open.

Signed-off-by: Philip Oakley 
---
V2:
word usage corrected.
Eric's comments $gmane/282432
V3: 
Updated list length measure following Junio's comments $gmane/282669

Replaces the previous V2 Patch 4/4.

---
 git-gui/lib/choose_repository.tcl | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/git-gui/lib/choose_repository.tcl 
b/git-gui/lib/choose_repository.tcl
index ad7a888..b4cc7dd 100644
--- a/git-gui/lib/choose_repository.tcl
+++ b/git-gui/lib/choose_repository.tcl
@@ -134,7 +134,8 @@ constructor pick {} {
$opts conf -state disabled
 
set sorted_recent [_get_recentrepos]
-   if {[llength $sorted_recent] > 0} {
+   set lenrecent [llength $sorted_recent]
+   if {$lenrecent > 0} {
if {$m_repo ne {}} {
$m_repo add separator
$m_repo add command \
@@ -153,7 +154,7 @@ constructor pick {} {
-background [get_bg_color $w_body.recentlabel] \
-wrap none \
-width 50 \
-   -height $maxrecent
+   -height $lenrecent
$w_recentlist tag conf link \
-foreground blue \
-underline 1
-- 
2.6.4.windows.1

--
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: RefTree: Alternate ref backend

2015-12-17 Thread Shawn Pearce
On Thu, Dec 17, 2015 at 2:10 PM, Jeff King  wrote:
> On Thu, Dec 17, 2015 at 01:02:50PM -0800, Shawn Pearce wrote:
>
>> I started playing around with the idea of storing references directly
>> in Git. Exploiting the GITLINK tree entry, we can associate a name to
>> any SHA-1.
>
> Gitlink entries don't imply reachability, though. I guess that doesn't
> matter if your ref backend says "no, really, these are the ref tips, and
> they are reachable".

Exactly. This works with existing JGit because it swaps out the ref
backend. When GC tries to enumerate the roots (current refs), it gets
these through the ref backend by scanning the tree recursively. The
packer itself doesn't care where those roots came from.

Same would be true for any other pluggable ref backend in git-core. GC
has to ask the ref backend, and then trust its reply. How/where that
ref backend tracks that is an implementation detail.

>  But you could not push the whole thing up to
> another server and expect it to hold the whole graph.

Correct, pushing this to another repository doesn't transmit the
graph. If the other repository also used this for its refs backend,
its now corrupt and confused out of its mind. Just like copying the
packed-refs file with scp. Don't do that. :)

> Which is not strictly necessary, but to me seems like the real advantage
> of using git objects versus some other system.

One advantage is you can edit HEAD symref remotely. Commit a different
symlink value and push. :)

I want to say more, but I'm going to hold back right now. There's more
going on in my head than just this.

> Of course, the lack of reachability has advantages, too. You can
> drop commits pointed to by old reflogs without rewriting the ref
> history.

Yes.

> Unfortunately you cannot expunge the reflogs at all. That's
> good if you like audit trails. Bad if you are worried that your reflogs
> will grow large. :)

At present our servers do not truncate their reflogs. Yes some are... big.

I considered truncating this graph by just using a shallow marker. Add
a shallow entry and repack. The ancient history will eventually be
garbage collected and disappear.

One advantage of this format is deleted branches can retain a reflog
post deletion. Another is you can trivially copy the reflog using
native Git to another system for backup purposes. Or fetch it over the
network to inspect locally. So a shared group server could be
exporting its reflog, you can fetch it and review locally what
happened to branches without logging into the shared server.

So long as you remember that copying the reflog doesn't mean you
actually copied the commit histories, its works nicely.

Another advantage of this format over LMDB or TDB or whatever is Git
already understands it. The tools already understand it. Plumbing can
inspect and repair things. You can reflog the reflog using traditional
reflog ($GIT_DIR/reflogs/refs/txn/committed).

>> By storing all references in a single tree, atomic transactions are
>> possible. Its a simple compare-and-swap of a single 40 byte SHA-1.
>> This of course leads to a bootstrapping problem, where do we store the
>> 40 byte SHA-1? For this example its just $GIT_DIR/refs/txn/committed
>> as a classical loose reference.
>
> Somehow putting it inside `refs/` seems weird to me, in an infinite
> recursion kind of way.  I would have picked $GIT_DIR/REFSTREE or
> something. But that is a minor point.

I had started with $GIT_DIR/REFS, but see above. I have more going on
in my head. This is only a tiny building block.

>> Configuration:
>>
>>   [core]
>> repositoryformatversion = 1
>>   [extensions]
>> refsBackendType = RefTree
>
> The semantics of extensions config keys are open-ended. The
> formatVersion=1 spec only says "if there is a key you don't know about,
> then you may not proceed". Now we're defining a refsBackendType
> extension. It probably makes sense to write up a few rules (e.g., is
> RefTree case-sensitive?).

In my prototype in JGIt I parse it as case insensitive, but used
CamelCase because the JavaClassNameIsNamedThatWayBecauseJava.
--
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: RefTree: Alternate ref backend

2015-12-17 Thread Shawn Pearce
On Thu, Dec 17, 2015 at 1:57 PM, Junio C Hamano  wrote:
> Shawn Pearce  writes:
>
>> For example, recent git.git has a structure like this:
>>
>>   $ git ls-tree -r refs/txn/committed
>>   12 blob 22e42fc826b437033ca444e09368f53a0b169322 ..HEAD
>>   16 commit 1ff88560c8d22bcdb528a6629239d638f927cb96 heads/maint
>>   16 commit f3adf457e046f92f039353762a78dcb3afb2cb13 heads/master
>>   16 commit 5ee9e94ccfede68f0c386c497dd85c017efa22d6 heads/next
>>   16 commit d3835d54cffb16c4362979a5be3ba9958eab4116 heads/pu
>>   16 commit 68a0f56b615b61afdbd86be01a3ca63dca70edc0 heads/todo
>>   ...
>>   16 commit 17f9f635c101aef03874e1de1d8d0322187494b3 tags/v2.6.0
>>   16 commit 5bebb9057df8287684c763c59c67f25f16884ef6 tags/v2.6.0-rc0
>>   16 commit 16ffa6443e279a9b3b63d7a2bebeb07833506010 tags/v2.6.0-rc0^{}
>>   ...
>>   16 commit be08dee9738eaaa0423885ed189c2b6ad8368cf0 tags/v2.6.0^{}
>>
>> Tags are stored twice, to cache the peel information for network 
>> advertisements.
>
> The object 17f9f635 is not a "commit" but is a "tag".  It is
> somewhat unfortunate that "ls-tree -r" reports it as a commit; as
> the command (or anything that deals with a gitlink) is not allowed
> to look at the actual object, it is the best it could do, though.

Yes; thus far GITLINK is only used for commits in submodules so its
reasonable for it to just hardcode the text "commit".

> The "..HEAD" hack looks somewhat ugly.  I can guess that the
> reasoning went like "if we stored these in the most natural way, we
> always need a top-level tree that hold two and only two entries,
> HEAD and heads/, which would require us one level of tree unwrapping
> to get to most of the refs" and "HEAD is the only oddball that is
> outside refs/ hierarchy,

Correct.

> others like MERGE_HEAD are ephemeral and
> for the purpose of Gerrit that does not even do working tree
> management, those things that are not necessary in order to manage
> only the committed state can be omitted.", but still...

Yes. I was mostly looking at this from a bare repository server
perspective, not a user working tree. On a bare repository you
probably don't have those special refs like MERGE_HEAD, FETCH_HEAD,
etc.

They could be stored as "..MERGE_HEAD", if you had to. But only HEAD
really matters to hint to clients what to checkout by default on
clone.
--
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] revision.c: propagate tag names from pending array

2015-12-17 Thread Jeff King
On Thu, Dec 17, 2015 at 12:28:48PM -0800, Junio C Hamano wrote:

> By the way, a totally unrelated niggle I have with 2073949 is this.
> 
> $ git describe --contains 2073949
> v2.3.1~3^2~4
> 
> while as you said, this dates back to at least v2.2.0-rc0
> 
> $ git tag --contains 2073949
> v2.2.0
> v2.2.0-rc0
> ...
> v2.7.0-rc1
> 
> That "describe --contains" output comes from "name-rev --tags", and
> I need to force it to use v2.2.0-rc0 as the source of naming, i.e.
> 
> $ git name-rev --refs=refs/tags/v2.2.0-rc0 2073949
> 2073949 tags/v2.2.0-rc0~13^2~9
> 
> to get what I would expect to be more useful.
> 
> I know "name-rev --contains" wants to describe a commit based on an
> anchor point that is topologically closest, and even though I do not
> offhand think of any, I am sure there are valid use cases that want
> to see the current behaviour.  But from time to time, I wish it did
> its naming taking the topological age of the anchor points into
> account.  If a commit is contained in v2.2.0-rc0 and onward, even
> though v2.0.0-rc0~13^2~9 describes a longer path from v2.0.0-rc0
> than v2.3.1~3^2~4 is from v2.3.1, I often want to see the name based
> on the "oldest" tag (if such a thing exists, and for older commits
> in this project, it always is the case, I think).

Yes, I agree (and judging by the number of "git describe is confusing"
threads over the years, I think it is not just us). I rarely use "git
describe --contains" myself. What I typically use (and how I arrived at
v2.2.0 in this instance) is:

  git tag --contains "$@" |
  grep ^v |
  grep -v -- -rc |
  sort -V |
  head -1

But there are some git-specific assumptions in there.

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


Re: [PATCH v2 4/4] git gui: allow for a long recentrepo list

2015-12-17 Thread Philip Oakley

From: "Philip Oakley" 

From: "Junio C Hamano" , December 17, 2015 7:32 PM

Philip Oakley  writes:


The gui.recentrepo list may be longer than the maxrecent setting.
Allow extra space to show any extra entries.

In an ideal world, the git gui would limit the number of entries
to the maxrecent setting, however the recentrepo config list may
have been extended outside of the gui, or the maxrecent setting changed
to a reduced value. Further, when testing the gui's recentrepo
logic it is useful to show these extra, but valid, entries.


I do not have a strong objection either way, but the magic number 5
smells like an indication that this is solving a wrong problem or
solving a problem in a wrong approach.  What happens to the entries
beyond $maxrecent-th in the recent list with the current code?  The
list effectively truncated and not shown?  Wouldn't the same thing
happen to the entries beyond ($maxrecent+5)-th in the recent list
with your patch?


True, it was a magic number selected as being a moderate overspill 
allowance.
I tried 3 and 5 as possible values, and 5 didn't look ungainly, even on my 
small netbook, and covered all my test hacking cases.


The issue was that the prior code assumed that the fault could never 
happen and limited the display, which is sorted, to the max value, so in a 
fault condition the most recent repo could fall off the bottom.


As a bit of 'monkey patching' I wasn't sure how the dialog creation could 
know in advance how long the list would be, so I simply added on a small 
margin.




Truncating the list at $maxrecent-th to match the display
(i.e. declare that "$maxrecent" is really the max number of entries
we would keep track of), or allowing the UI to scroll so that
entries beyond $maxrecent-th one can be shown, perhaps?


This would certainly be a reasonable approach, but I don't know enough of 
the tcl to know how to make it happen. If anyone has suggestions...


I think I see the way to do it. V3 Patch 4/4 to follow.






Signed-off-by: Philip Oakley 
---
word usage corrected.
Eric's comments $gmane/282432
---
 git-gui/lib/choose_repository.tcl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/git-gui/lib/choose_repository.tcl 
b/git-gui/lib/choose_repository.tcl

index ad7a888..a08ed4f 100644
--- a/git-gui/lib/choose_repository.tcl
+++ b/git-gui/lib/choose_repository.tcl
@@ -153,7 +153,7 @@ constructor pick {} {
 -background [get_bg_color $w_body.recentlabel] \
 -wrap none \
 -width 50 \
- -height $maxrecent
+ -height [expr {$maxrecent + 5}]
 $w_recentlist tag conf link \
 -foreground blue \
 -underline 1

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



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



--
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: RefTree: Alternate ref backend

2015-12-17 Thread Jeff King
On Thu, Dec 17, 2015 at 01:02:50PM -0800, Shawn Pearce wrote:

> I started playing around with the idea of storing references directly
> in Git. Exploiting the GITLINK tree entry, we can associate a name to
> any SHA-1.

Gitlink entries don't imply reachability, though. I guess that doesn't
matter if your ref backend says "no, really, these are the ref tips, and
they are reachable".  But you could not push the whole thing up to
another server and expect it to hold the whole graph.

Which is not strictly necessary, but to me seems like the real advantage
of using git objects versus some other system.

Of course, the lack of reachability has advantages, too. You can
drop commits pointed to by old reflogs without rewriting the ref
history. Unfortunately you cannot expunge the reflogs at all. That's
good if you like audit trails. Bad if you are worried that your reflogs
will grow large. :)

> By storing all references in a single tree, atomic transactions are
> possible. Its a simple compare-and-swap of a single 40 byte SHA-1.
> This of course leads to a bootstrapping problem, where do we store the
> 40 byte SHA-1? For this example its just $GIT_DIR/refs/txn/committed
> as a classical loose reference.

Somehow putting it inside `refs/` seems weird to me, in an infinite
recursion kind of way.  I would have picked $GIT_DIR/REFSTREE or
something. But that is a minor point.

> Configuration:
> 
>   [core]
> repositoryformatversion = 1
>   [extensions]
> refsBackendType = RefTree

The semantics of extensions config keys are open-ended. The
formatVersion=1 spec only says "if there is a key you don't know about,
then you may not proceed". Now we're defining a refsBackendType
extension. It probably makes sense to write up a few rules (e.g., is
RefTree case-sensitive?).

-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: RefTree: Alternate ref backend

2015-12-17 Thread Junio C Hamano
Shawn Pearce  writes:

> For example, recent git.git has a structure like this:
>
>   $ git ls-tree -r refs/txn/committed
>   12 blob 22e42fc826b437033ca444e09368f53a0b169322 ..HEAD
>   16 commit 1ff88560c8d22bcdb528a6629239d638f927cb96 heads/maint
>   16 commit f3adf457e046f92f039353762a78dcb3afb2cb13 heads/master
>   16 commit 5ee9e94ccfede68f0c386c497dd85c017efa22d6 heads/next
>   16 commit d3835d54cffb16c4362979a5be3ba9958eab4116 heads/pu
>   16 commit 68a0f56b615b61afdbd86be01a3ca63dca70edc0 heads/todo
>   ...
>   16 commit 17f9f635c101aef03874e1de1d8d0322187494b3 tags/v2.6.0
>   16 commit 5bebb9057df8287684c763c59c67f25f16884ef6 tags/v2.6.0-rc0
>   16 commit 16ffa6443e279a9b3b63d7a2bebeb07833506010 tags/v2.6.0-rc0^{}
>   ...
>   16 commit be08dee9738eaaa0423885ed189c2b6ad8368cf0 tags/v2.6.0^{}
>
> Tags are stored twice, to cache the peel information for network 
> advertisements.

The object 17f9f635 is not a "commit" but is a "tag".  It is
somewhat unfortunate that "ls-tree -r" reports it as a commit; as
the command (or anything that deals with a gitlink) is not allowed
to look at the actual object, it is the best it could do, though.

The "..HEAD" hack looks somewhat ugly.  I can guess that the
reasoning went like "if we stored these in the most natural way, we
always need a top-level tree that hold two and only two entries,
HEAD and heads/, which would require us one level of tree unwrapping
to get to most of the refs" and "HEAD is the only oddball that is
outside refs/ hierarchy, others like MERGE_HEAD are ephemeral and
for the purpose of Gerrit that does not even do working tree
management, those things that are not necessary in order to manage
only the committed state can be omitted.", but still...


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


[PATCH v3] git-svn: add support for prefixed globs in config

2015-12-17 Thread Victor Leschuk
Introduce prefixed globs for branches and tags in git-svn.
Globs like 'release_*' allow users to avoid long lines in config like:

branches = branches/{release_20,release_21,release_22,...}

Signed-off-by: Victor Leschuk 
---
Changes from v1 (in v2 I forgot to switch from `` to $() ):
* Joined implementation and test in one patch
* Fixed test code style according to current coding style guide

 Documentation/git-svn.txt|   5 ++
 perl/Git/SVN/GlobSpec.pm |   9 ++-
 t/t9168-git-svn-prefixed-glob.sh | 136 +++
 3 files changed, 145 insertions(+), 5 deletions(-)
 create mode 100755 t/t9168-git-svn-prefixed-glob.sh

diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index 0c0f60b..529cffe 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -1034,6 +1034,7 @@ listed below are allowed:
url = http://server.org/svn
fetch = trunk/project-a:refs/remotes/project-a/trunk
branches = branches/*/project-a:refs/remotes/project-a/branches/*
+   branches = branches/release_*:refs/remotes/project-a/branches/release_*
tags = tags/*/project-a:refs/remotes/project-a/tags/*
 
 
@@ -1044,6 +1045,10 @@ independent path component (surrounded by '/' or EOL).   
This
 type of configuration is not automatically created by 'init' and
 should be manually entered with a text-editor or using 'git config'.
 
+Also note that prefixed globs (e.g. 'release_*') match everything after prefix
+but do not match exact prefix. For example:
+'release_*' will match 'release_1' or 'release_v1' but will not match 
'release_'.
+
 It is also possible to fetch a subset of branches or tags by using a
 comma-separated list of names within braces. For example:
 
diff --git a/perl/Git/SVN/GlobSpec.pm b/perl/Git/SVN/GlobSpec.pm
index c95f5d7..a136090 100644
--- a/perl/Git/SVN/GlobSpec.pm
+++ b/perl/Git/SVN/GlobSpec.pm
@@ -11,16 +11,15 @@ sub new {
my $die_msg = "Only one set of wildcard directories " .
"(e.g. '*' or '*/*/*') is supported: '$glob'\n";
for my $part (split(m|/|, $glob)) {
-   if ($part =~ /\*/ && $part ne "*") {
-   die "Invalid pattern in '$glob': $part\n";
-   } elsif ($pattern_ok && $part =~ /[{}]/ &&
+   if ($pattern_ok && $part =~ /[{}]/ &&
 $part !~ /^\{[^{}]+\}/) {
die "Invalid pattern in '$glob': $part\n";
}
-   if ($part eq "*") {
+   if ($part =~ /(\w*)\*/) {
die $die_msg if $state eq "right";
$state = "pattern";
-   push(@patterns, "[^/]*");
+   my $pat = $1 ? "${1}[^/]+" : "[^/]*";
+   push(@patterns, $pat);
} elsif ($pattern_ok && $part =~ /^\{(.*)\}$/) {
die $die_msg if $state eq "right";
$state = "pattern";
diff --git a/t/t9168-git-svn-prefixed-glob.sh b/t/t9168-git-svn-prefixed-glob.sh
new file mode 100755
index 000..a5a3227
--- /dev/null
+++ b/t/t9168-git-svn-prefixed-glob.sh
@@ -0,0 +1,136 @@
+#!/bin/sh
+test_description='git svn globbing refspecs with prefixed globs'
+. ./lib-git-svn.sh
+
+cat >expect.end trunk/src/b/readme &&
+   svn_cmd import -m "initial" trunk "$svnrepo"/trunk &&
+   svn_cmd co "$svnrepo" tmp &&
+   (
+   cd tmp &&
+   mkdir branches tags &&
+   svn_cmd add branches tags &&
+   svn_cmd cp trunk branches/b_start &&
+   svn_cmd commit -m "start a new branch" &&
+   svn_cmd up &&
+   echo "hi" >>branches/b_start/src/b/readme &&
+   poke branches/b_start/src/b/readme &&
+   echo "hey" >>branches/b_start/src/a/readme &&
+   poke branches/b_start/src/a/readme &&
+   svn_cmd commit -m "hi" &&
+   svn_cmd up &&
+   svn_cmd cp branches/b_start tags/t_end &&
+   echo "bye" >>tags/t_end/src/b/readme &&
+   poke tags/t_end/src/b/readme &&
+   echo "aye" >>tags/t_end/src/a/readme &&
+   poke tags/t_end/src/a/readme &&
+   svn_cmd commit -m "the end" &&
+   echo "byebye" >>tags/t_end/src/b/readme &&
+   poke tags/t_end/src/b/readme &&
+   svn_cmd commit -m "nothing to see here"
+   ) &&
+   git config --add svn-remote.svn.url "$svnrepo" &&
+   git config --add svn-remote.svn.fetch \
+"trunk/src/a:refs/remotes/trunk" &&
+   git config --add svn-remote.svn.branches \
+"branches/b_*/src/a:refs/remotes/branches/b_*" &&
+   git config --add svn-remote.svn.tags\
+ 

RefTree: Alternate ref backend

2015-12-17 Thread Shawn Pearce
I started playing around with the idea of storing references directly
in Git. Exploiting the GITLINK tree entry, we can associate a name to
any SHA-1.

By storing all references in a single tree, atomic transactions are
possible. Its a simple compare-and-swap of a single 40 byte SHA-1.
This of course leads to a bootstrapping problem, where do we store the
40 byte SHA-1? For this example its just $GIT_DIR/refs/txn/committed
as a classical loose reference.


I posted code for this to JGit (sorry):

   https://git.eclipse.org/r/62970


Configuration:

  [core]
repositoryformatversion = 1
  [extensions]
refsBackendType = RefTree

For example, recent git.git has a structure like this:

  $ git ls-tree -r refs/txn/committed
  12 blob 22e42fc826b437033ca444e09368f53a0b169322 ..HEAD
  16 commit 1ff88560c8d22bcdb528a6629239d638f927cb96 heads/maint
  16 commit f3adf457e046f92f039353762a78dcb3afb2cb13 heads/master
  16 commit 5ee9e94ccfede68f0c386c497dd85c017efa22d6 heads/next
  16 commit d3835d54cffb16c4362979a5be3ba9958eab4116 heads/pu
  16 commit 68a0f56b615b61afdbd86be01a3ca63dca70edc0 heads/todo
  ...
  16 commit 17f9f635c101aef03874e1de1d8d0322187494b3 tags/v2.6.0
  16 commit 5bebb9057df8287684c763c59c67f25f16884ef6 tags/v2.6.0-rc0
  16 commit 16ffa6443e279a9b3b63d7a2bebeb07833506010 tags/v2.6.0-rc0^{}
  16 commit bbdca2a7bd942e1d3ce517b48e6229b99f7d7b2b tags/v2.6.0-rc1
  16 commit 689efb737a7b46351850eefdfa57d2ce232011fb tags/v2.6.0-rc1^{}
  16 commit 7b269a793392ee3d71ecddac88a8ad63497cbc4d tags/v2.6.0-rc2
  16 commit 45733fa93f287fbc04d6a6a3f5a39cc852c5cf50 tags/v2.6.0-rc2^{}
  16 commit 27df6e2585060add45b32bbd46f6e92ef79d069b tags/v2.6.0-rc3
  16 commit 8d530c4d64ffcc853889f7b385f554d53db375ed tags/v2.6.0-rc3^{}
  16 commit be08dee9738eaaa0423885ed189c2b6ad8368cf0 tags/v2.6.0^{}

Tags are stored twice, to cache the peel information for network advertisements.

Packing the tree by itself is smaller than packed-refs, which is uncompressed:

  -rw-r- 1 shawn me  60K Dec 17 12:43 packed-refs
  -r--r- 1 shawn me 1.2K Dec 17 12:56 R-5533*.idx
  -r--r- 1 shawn me  28K Dec 17 12:56 R-5533*.pack


By exploiting Git to store Git, we get a reflog for free:

  $ git log -p refs/txn/committed -1
  commit f7ec5ceeba6ca87fa112b3af70d8ac17364045f7
  Author: anonymous 
  Date:   Thu Dec 17 12:53:39 2015 -0800

  push

  diff --git a/heads/tmp2 b/heads/tmp2
  deleted file mode 16
  index f3adf45..000
  --- a/heads/tmp2
  +++ /dev/null
  @@ -1 +0,0 @@
  -Subproject commit f3adf457e046f92f039353762a78dcb3afb2cb13

:)
--
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: [PATCHv2 2/7] xread: poll on non blocking fds

2015-12-17 Thread Stefan Beller
On Thu, Dec 17, 2015 at 12:42 PM, Torsten Bögershausen  wrote:
> On 17.12.15 21:22, Stefan Beller wrote:
>> On Thu, Dec 17, 2015 at 12:12 PM, Torsten Bögershausen  wrote:
>>> On 16.12.15 01:04, Stefan Beller wrote:
 The man page of read(2) says:

   EAGAIN The file descriptor fd refers to a file other than a socket
and has been marked nonblocking (O_NONBLOCK), and the read
would block.

   EAGAIN or EWOULDBLOCK
The file descriptor fd refers to a socket and has been marked
nonblocking (O_NONBLOCK), and the read would block.  POSIX.1-2001
allows either error to be returned for this case, and does not
require these constants to have the same value, so a portable
application should check for both possibilities.

 If we get an EAGAIN or EWOULDBLOCK the fd must have set O_NONBLOCK.
 As the intent of xread is to read as much as possible either until the
 fd is EOF or an actual error occurs, we can ease the feeder of the fd
 by not spinning the whole time, but rather wait for it politely by not
 busy waiting.

 We should not care if the call to poll failed, as we're in an infinite
 loop and can only get out with the correct read().
>>> I'm not sure if this is valid under all circumstances:
>>> This is what "man poll" says under Linux:
>>> []
>>>  ENOMEM There was no space to allocate file descriptor tables.
>>> []
>>> And this is from Mac OS, ("BSD System Calls Manual")
>>> ERRORS
>>>  Poll() will fail if:
>>>
>>>  [EAGAIN]   Allocation of internal data structures fails.  A 
>>> sub-
>>> sequent request may succeed.
>>> And this is opengroup:
>>> http://pubs.opengroup.org/onlinepubs/9699919799//functions/poll.html:
>>> [EAGAIN]
>>> The allocation of internal data structures failed but a subsequent 
>>> request may succeed.
>>>
>>> read() may return EAGAIN, but poll() may fail to allocate memory, and fail.
>>> Is it always guaranteed that the loop is terminated?
>>
>> In case poll fails (assume a no op for it), the logic should not have
>> changed by this patch?
>>
>> Looking closely:
>>
   while (1) {
   nr = read(fd, buf, len);
 - if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
 - continue;
 + if (nr < 0) {
 + if (errno == EINTR)
 + continue;
 + if (errno == EAGAIN || errno == EWOULDBLOCK) {
 + struct pollfd pfd;
 + pfd.events = POLLIN;
 + pfd.fd = fd;
 + /*
 +  * it is OK if this poll() failed; we
 +  * want to leave this infinite loop
 +  * only when read() returns with
 +  * success, or an expected failure,
 +  * which would be checked by the next
 +  * call to read(2).
 +  */
 + poll(&pfd, 1, -1);
>>
>> Or do you mean to insert another continue in here?
> I was thinking that we run into similar loop as before:
> read() returns -1; errno = EAGAIN  /* No data to read */

which is expected for non blocking fds,

> poll() returns -1; errno = EAGAIN /* poll failed. If the fd was OK, the 
> failure may be temporaly,
> as much as poll() can see.
> But most probably we run out ouf memory */

Before this patch we would not have asked poll, but had just a continue here,
so I think we need to have it here again no matter of the return code
of the poll.

If poll determines it is low on memory, this should not make this function fail,
we can still do as good as we did before by just asking read
repeatedly again, though?

So I'd be convinced now we'd want to have:

poll(&pfd, 1, -1); /* this is only buying time
for the fd to deliver data, in case it fails
we don't care but just fall back to old
behavior before this patch with busy spinning*/
continue;


>
> So the code would look like this:
>
>if (!poll(&pfd, 1, -1))
>   return -1;
>
>
>>
>
 + }
 + }
   return nr;
   }
  }

>>>
>> --
>> 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
>>
>
--
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 15/16] refs: add LMDB refs backend

2015-12-17 Thread Jonathan Nieder
David Turner wrote:
> On Wed, 2015-12-16 at 17:00 -0800, Jonathan Nieder wrote:
>> David Turner wrote:

>>> +core.refsBackendType::
>>> +   Type of refs backend. Default is to use the original files
>>> +   based backend. Set to 'lmdb' to activate the lmdb database
>>> +   backend.  If you use the lmdb backend,
>>> +   core.repositoryFormatVersion must be set to 1, and
>>> +   extensions.refBackend must be set to 'lmdb'.
>>
>> If core.refsBackendType names one backend and extensions.refBackend
>> names another, which wins?
>
> I've simplified this to just use extensions.refsBackendType for
> everything.  Will re-roll once I finish getting comments on the rest of
> this series.

Perfect.  Thanks for the quick reply.

Jonathan
--
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: [PATCHv2 2/7] xread: poll on non blocking fds

2015-12-17 Thread Torsten Bögershausen
On 17.12.15 21:22, Stefan Beller wrote:
> On Thu, Dec 17, 2015 at 12:12 PM, Torsten Bögershausen  wrote:
>> On 16.12.15 01:04, Stefan Beller wrote:
>>> The man page of read(2) says:
>>>
>>>   EAGAIN The file descriptor fd refers to a file other than a socket
>>>and has been marked nonblocking (O_NONBLOCK), and the read
>>>would block.
>>>
>>>   EAGAIN or EWOULDBLOCK
>>>The file descriptor fd refers to a socket and has been marked
>>>nonblocking (O_NONBLOCK), and the read would block.  POSIX.1-2001
>>>allows either error to be returned for this case, and does not
>>>require these constants to have the same value, so a portable
>>>application should check for both possibilities.
>>>
>>> If we get an EAGAIN or EWOULDBLOCK the fd must have set O_NONBLOCK.
>>> As the intent of xread is to read as much as possible either until the
>>> fd is EOF or an actual error occurs, we can ease the feeder of the fd
>>> by not spinning the whole time, but rather wait for it politely by not
>>> busy waiting.
>>>
>>> We should not care if the call to poll failed, as we're in an infinite
>>> loop and can only get out with the correct read().
>> I'm not sure if this is valid under all circumstances:
>> This is what "man poll" says under Linux:
>> []
>>  ENOMEM There was no space to allocate file descriptor tables.
>> []
>> And this is from Mac OS, ("BSD System Calls Manual")
>> ERRORS
>>  Poll() will fail if:
>>
>>  [EAGAIN]   Allocation of internal data structures fails.  A sub-
>> sequent request may succeed.
>> And this is opengroup:
>> http://pubs.opengroup.org/onlinepubs/9699919799//functions/poll.html:
>> [EAGAIN]
>> The allocation of internal data structures failed but a subsequent 
>> request may succeed.
>>
>> read() may return EAGAIN, but poll() may fail to allocate memory, and fail.
>> Is it always guaranteed that the loop is terminated?
> 
> In case poll fails (assume a no op for it), the logic should not have
> changed by this patch?
> 
> Looking closely:
> 
>>>   while (1) {
>>>   nr = read(fd, buf, len);
>>> - if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
>>> - continue;
>>> + if (nr < 0) {
>>> + if (errno == EINTR)
>>> + continue;
>>> + if (errno == EAGAIN || errno == EWOULDBLOCK) {
>>> + struct pollfd pfd;
>>> + pfd.events = POLLIN;
>>> + pfd.fd = fd;
>>> + /*
>>> +  * it is OK if this poll() failed; we
>>> +  * want to leave this infinite loop
>>> +  * only when read() returns with
>>> +  * success, or an expected failure,
>>> +  * which would be checked by the next
>>> +  * call to read(2).
>>> +  */
>>> + poll(&pfd, 1, -1);
> 
> Or do you mean to insert another continue in here?
I was thinking that we run into similar loop as before:
read() returns -1; errno = EAGAIN  /* No data to read */
poll() returns -1; errno = EAGAIN /* poll failed. If the fd was OK, the failure 
may be temporaly,
as much as poll() can see.
But most probably we run out ouf memory */

So the code would look like this:

   if (!poll(&pfd, 1, -1))
  return -1;


> 

>>> + }
>>> + }
>>>   return nr;
>>>   }
>>>  }
>>>
>>
> --
> 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
> 

--
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] revision.c: propagate tag names from pending array

2015-12-17 Thread Junio C Hamano
Jeff King  writes:

> When we unwrap a tag to find its commit for a traversal, we
> do not propagate the "name" field of the tag in the pending
> array (i.e., the ref name the user gave us in the first
> place) to the commit (instead, we use an empty string). This
> means that "git log --source" will never show the tag-name
> for commits we reach through it.
>
> This was broken in 2073949 (traverse_commit_list: support
> pending blobs/trees with paths, 2014-10-15). That commit
> tried to be careful and avoid propagating the path
> information for a tag (which would be nonsensical) to trees
> and blobs. But it should not have cut off the "name" field,
> which should carry forward to children.
> ...
> This was reported several weeks ago, but I needed to take the time to
> convince myself this wasn't regressing any cases. I'm pretty sure it's
> the right thing to do.
>
> The regression is in v2.2.0, so this is not urgent to make it into v2.7
> before release, but it is definitely maint-worthy.

Makes sense, and I agree.

By the way, a totally unrelated niggle I have with 2073949 is this.

$ git describe --contains 2073949
v2.3.1~3^2~4

while as you said, this dates back to at least v2.2.0-rc0

$ git tag --contains 2073949
v2.2.0
v2.2.0-rc0
...
v2.7.0-rc1

That "describe --contains" output comes from "name-rev --tags", and
I need to force it to use v2.2.0-rc0 as the source of naming, i.e.

$ git name-rev --refs=refs/tags/v2.2.0-rc0 2073949
2073949 tags/v2.2.0-rc0~13^2~9

to get what I would expect to be more useful.

I know "name-rev --contains" wants to describe a commit based on an
anchor point that is topologically closest, and even though I do not
offhand think of any, I am sure there are valid use cases that want
to see the current behaviour.  But from time to time, I wish it did
its naming taking the topological age of the anchor points into
account.  If a commit is contained in v2.2.0-rc0 and onward, even
though v2.0.0-rc0~13^2~9 describes a longer path from v2.0.0-rc0
than v2.3.1~3^2~4 is from v2.3.1, I often want to see the name based
on the "oldest" tag (if such a thing exists, and for older commits
in this project, it always is the case, I think).


--
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: [PATCHv2 2/7] xread: poll on non blocking fds

2015-12-17 Thread Stefan Beller
On Thu, Dec 17, 2015 at 12:12 PM, Torsten Bögershausen  wrote:
> On 16.12.15 01:04, Stefan Beller wrote:
>> The man page of read(2) says:
>>
>>   EAGAIN The file descriptor fd refers to a file other than a socket
>>and has been marked nonblocking (O_NONBLOCK), and the read
>>would block.
>>
>>   EAGAIN or EWOULDBLOCK
>>The file descriptor fd refers to a socket and has been marked
>>nonblocking (O_NONBLOCK), and the read would block.  POSIX.1-2001
>>allows either error to be returned for this case, and does not
>>require these constants to have the same value, so a portable
>>application should check for both possibilities.
>>
>> If we get an EAGAIN or EWOULDBLOCK the fd must have set O_NONBLOCK.
>> As the intent of xread is to read as much as possible either until the
>> fd is EOF or an actual error occurs, we can ease the feeder of the fd
>> by not spinning the whole time, but rather wait for it politely by not
>> busy waiting.
>>
>> We should not care if the call to poll failed, as we're in an infinite
>> loop and can only get out with the correct read().
> I'm not sure if this is valid under all circumstances:
> This is what "man poll" says under Linux:
> []
>  ENOMEM There was no space to allocate file descriptor tables.
> []
> And this is from Mac OS, ("BSD System Calls Manual")
> ERRORS
>  Poll() will fail if:
>
>  [EAGAIN]   Allocation of internal data structures fails.  A sub-
> sequent request may succeed.
> And this is opengroup:
> http://pubs.opengroup.org/onlinepubs/9699919799//functions/poll.html:
> [EAGAIN]
> The allocation of internal data structures failed but a subsequent 
> request may succeed.
>
> read() may return EAGAIN, but poll() may fail to allocate memory, and fail.
> Is it always guaranteed that the loop is terminated?

In case poll fails (assume a no op for it), the logic should not have
changed by this patch?

Looking closely:

>>   while (1) {
>>   nr = read(fd, buf, len);
>> - if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
>> - continue;
>> + if (nr < 0) {
>> + if (errno == EINTR)
>> + continue;
>> + if (errno == EAGAIN || errno == EWOULDBLOCK) {
>> + struct pollfd pfd;
>> + pfd.events = POLLIN;
>> + pfd.fd = fd;
>> + /*
>> +  * it is OK if this poll() failed; we
>> +  * want to leave this infinite loop
>> +  * only when read() returns with
>> +  * success, or an expected failure,
>> +  * which would be checked by the next
>> +  * call to read(2).
>> +  */
>> + poll(&pfd, 1, -1);

Or do you mean to insert another continue in here?

>> + }
>> + }
>>   return nr;
>>   }
>>  }
>>
>
--
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: [PATCHv2 2/7] xread: poll on non blocking fds

2015-12-17 Thread Torsten Bögershausen
On 16.12.15 01:04, Stefan Beller wrote:
> The man page of read(2) says:
> 
>   EAGAIN The file descriptor fd refers to a file other than a socket
>and has been marked nonblocking (O_NONBLOCK), and the read
>would block.
> 
>   EAGAIN or EWOULDBLOCK
>The file descriptor fd refers to a socket and has been marked
>nonblocking (O_NONBLOCK), and the read would block.  POSIX.1-2001
>allows either error to be returned for this case, and does not
>require these constants to have the same value, so a portable
>application should check for both possibilities.
> 
> If we get an EAGAIN or EWOULDBLOCK the fd must have set O_NONBLOCK.
> As the intent of xread is to read as much as possible either until the
> fd is EOF or an actual error occurs, we can ease the feeder of the fd
> by not spinning the whole time, but rather wait for it politely by not
> busy waiting.
> 
> We should not care if the call to poll failed, as we're in an infinite
> loop and can only get out with the correct read().
I'm not sure if this is valid under all circumstances:
This is what "man poll" says under Linux: 
[]
 ENOMEM There was no space to allocate file descriptor tables.
[]
And this is from Mac OS, ("BSD System Calls Manual")
ERRORS
 Poll() will fail if:

 [EAGAIN]   Allocation of internal data structures fails.  A sub-
sequent request may succeed.
And this is opengroup:
http://pubs.opengroup.org/onlinepubs/9699919799//functions/poll.html:
[EAGAIN]
The allocation of internal data structures failed but a subsequent request 
may succeed.

read() may return EAGAIN, but poll() may fail to allocate memory, and fail.
Is it always guaranteed that the loop is terminated?



> 
> Signed-off-by: Stefan Beller 
> Acked-by: Johannes Sixt 
> Signed-off-by: Junio C Hamano 
> ---
>  wrapper.c | 20 ++--
>  1 file changed, 18 insertions(+), 2 deletions(-)
> 
> diff --git a/wrapper.c b/wrapper.c
> index 6fcaa4d..1770efa 100644
> --- a/wrapper.c
> +++ b/wrapper.c
> @@ -236,8 +236,24 @@ ssize_t xread(int fd, void *buf, size_t len)
>   len = MAX_IO_SIZE;
>   while (1) {
>   nr = read(fd, buf, len);
> - if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
> - continue;
> + if (nr < 0) {
> + if (errno == EINTR)
> + continue;
> + if (errno == EAGAIN || errno == EWOULDBLOCK) {
> + struct pollfd pfd;
> + pfd.events = POLLIN;
> + pfd.fd = fd;
> + /*
> +  * it is OK if this poll() failed; we
> +  * want to leave this infinite loop
> +  * only when read() returns with
> +  * success, or an expected failure,
> +  * which would be checked by the next
> +  * call to read(2).
> +  */
> + poll(&pfd, 1, -1);
> + }
> + }
>   return nr;
>   }
>  }
> 

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


Re: [PATCH v2 4/4] git gui: allow for a long recentrepo list

2015-12-17 Thread Philip Oakley

From: "Junio C Hamano" , December 17, 2015 7:32 PM

Philip Oakley  writes:


The gui.recentrepo list may be longer than the maxrecent setting.
Allow extra space to show any extra entries.

In an ideal world, the git gui would limit the number of entries
to the maxrecent setting, however the recentrepo config list may
have been extended outside of the gui, or the maxrecent setting changed
to a reduced value. Further, when testing the gui's recentrepo
logic it is useful to show these extra, but valid, entries.


I do not have a strong objection either way, but the magic number 5
smells like an indication that this is solving a wrong problem or
solving a problem in a wrong approach.  What happens to the entries
beyond $maxrecent-th in the recent list with the current code?  The
list effectively truncated and not shown?  Wouldn't the same thing
happen to the entries beyond ($maxrecent+5)-th in the recent list
with your patch?


True, it was a magic number selected as being a moderate overspill 
allowance.
I tried 3 and 5 as possible values, and 5 didn't look ungainly, even on my 
small netbook, and covered all my test hacking cases.


The issue was that the prior code assumed that the fault could never happen 
and limited the display, which is sorted, to the max value, so in a fault 
condition the most recent repo could fall off the bottom.


As a bit of 'monkey patching' I wasn't sure how the dialog creation could 
know in advance how long the list would be, so I simply added on a small 
margin.




Truncating the list at $maxrecent-th to match the display
(i.e. declare that "$maxrecent" is really the max number of entries
we would keep track of), or allowing the UI to scroll so that
entries beyond $maxrecent-th one can be shown, perhaps?


This would certainly be a reasonable approach, but I don't know enough of 
the tcl to know how to make it happen. If anyone has suggestions...






Signed-off-by: Philip Oakley 
---
word usage corrected.
Eric's comments $gmane/282432
---
 git-gui/lib/choose_repository.tcl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/git-gui/lib/choose_repository.tcl 
b/git-gui/lib/choose_repository.tcl

index ad7a888..a08ed4f 100644
--- a/git-gui/lib/choose_repository.tcl
+++ b/git-gui/lib/choose_repository.tcl
@@ -153,7 +153,7 @@ constructor pick {} {
 -background [get_bg_color $w_body.recentlabel] \
 -wrap none \
 -width 50 \
- -height $maxrecent
+ -height [expr {$maxrecent + 5}]
 $w_recentlist tag conf link \
 -foreground blue \
 -underline 1

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



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


Re: [PATCH v2 4/4] git gui: allow for a long recentrepo list

2015-12-17 Thread Junio C Hamano
Philip Oakley  writes:

> The gui.recentrepo list may be longer than the maxrecent setting.
> Allow extra space to show any extra entries.
>
> In an ideal world, the git gui would limit the number of entries
> to the maxrecent setting, however the recentrepo config list may
> have been extended outside of the gui, or the maxrecent setting changed
> to a reduced value. Further, when testing the gui's recentrepo
> logic it is useful to show these extra, but valid, entries.

I do not have a strong objection either way, but the magic number 5
smells like an indication that this is solving a wrong problem or
solving a problem in a wrong approach.  What happens to the entries
beyond $maxrecent-th in the recent list with the current code?  The
list effectively truncated and not shown?  Wouldn't the same thing
happen to the entries beyond ($maxrecent+5)-th in the recent list
with your patch?

Truncating the list at $maxrecent-th to match the display
(i.e. declare that "$maxrecent" is really the max number of entries
we would keep track of), or allowing the UI to scroll so that
entries beyond $maxrecent-th one can be shown, perhaps?

>
> Signed-off-by: Philip Oakley 
> ---
> word usage corrected.
> Eric's comments $gmane/282432
> ---
>  git-gui/lib/choose_repository.tcl | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/git-gui/lib/choose_repository.tcl 
> b/git-gui/lib/choose_repository.tcl
> index ad7a888..a08ed4f 100644
> --- a/git-gui/lib/choose_repository.tcl
> +++ b/git-gui/lib/choose_repository.tcl
> @@ -153,7 +153,7 @@ constructor pick {} {
>   -background [get_bg_color $w_body.recentlabel] \
>   -wrap none \
>   -width 50 \
> - -height $maxrecent
> + -height [expr {$maxrecent + 5}]
>   $w_recentlist tag conf link \
>   -foreground blue \
>   -underline 1
--
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] mingw: emulate write(2) that fails with a EPIPE

2015-12-17 Thread Junio C Hamano
Johannes Schindelin  writes:

> On Windows, when writing to a pipe fails, errno is always
> EINVAL. However, Git expects it to be EPIPE.
>
> According to the documentation, there are two cases in which write()
> triggers EINVAL: the buffer is NULL, or the length is odd but the mode
> is 16-bit Unicode (the broken pipe is not mentioned as possible cause).
> Git never sets the file mode to anything but binary, therefore we know
> that errno should actually be EPIPE if it is EINVAL and the buffer is
> not NULL.
>
> See https://msdn.microsoft.com/en-us/library/1570wh78.aspx for more
> details.
>
> This works around t5571.11 failing with v2.6.4 on Windows.
>
> Signed-off-by: Johannes Schindelin 
> ---
>  compat/mingw.c | 17 +
>  compat/mingw.h |  3 +++
>  2 files changed, 20 insertions(+)
>
> diff --git a/compat/mingw.c b/compat/mingw.c
> index 90bdb1e..5edea29 100644
> --- a/compat/mingw.c
> +++ b/compat/mingw.c
> @@ -394,6 +394,23 @@ int mingw_fflush(FILE *stream)
>   return ret;
>  }
>  
> +#undef write
> +ssize_t mingw_write(int fd, const void *buf, size_t len)
> +{
> + ssize_t result = write(fd, buf, len);
> +
> + if (result < 0 && errno == EINVAL && buf) {
> + /* check if fd is a pipe */
> + HANDLE h = (HANDLE) _get_osfhandle(fd);
> + if (GetFileType(h) == FILE_TYPE_PIPE)
> + errno = EPIPE;
> + else
> + errno = EINVAL;
> + }
> +
> + return result;
> +}
> +
>  int mingw_access(const char *filename, int mode)
>  {
>   wchar_t wfilename[MAX_PATH];
> diff --git a/compat/mingw.h b/compat/mingw.h
> index 738865c..57ca477 100644
> --- a/compat/mingw.h
> +++ b/compat/mingw.h
> @@ -210,6 +210,9 @@ FILE *mingw_freopen (const char *filename, const char 
> *otype, FILE *stream);
>  int mingw_fflush(FILE *stream);
>  #define fflush mingw_fflush
>  
> +ssize_t mingw_write(int fd, const void *buf, size_t len);
> +#define write mingw_write
> +
>  int mingw_access(const char *filename, int mode);
>  #undef access
>  #define access mingw_access


PLEASE DON'T DO THE BELOW TO THE SAME MESSAGE AS THE PATCH ITSELF.
"git apply" would not read and understand the next line as a natural
language sentence for obvious reasons.

> Interdiff vs v1:
>
> diff --git a/compat/mingw.c b/compat/mingw.c
> index 90bdb1e..5edea29 100644
> --- a/compat/mingw.c
> +++ b/compat/mingw.c
> @@ -394,6 +394,23 @@ int mingw_fflush(FILE *stream)
>   return ret;
>  }
>  
> +#undef write
> +ssize_t mingw_write(int fd, const void *buf, size_t len)
> +{
> + ssize_t result = write(fd, buf, len);
> +
> + if (result < 0 && errno == EINVAL && buf) {
> + /* check if fd is a pipe */
> + HANDLE h = (HANDLE) _get_osfhandle(fd);
> + if (GetFileType(h) == FILE_TYPE_PIPE)
> + errno = EPIPE;
> + else
> + errno = EINVAL;
> + }
> +
> + return result;
> +}
> +
>  int mingw_access(const char *filename, int mode)
>  {
>   wchar_t wfilename[MAX_PATH];
> diff --git a/compat/mingw.h b/compat/mingw.h
> index 2aca347..57ca477 100644
> --- a/compat/mingw.h
> +++ b/compat/mingw.h
> @@ -210,22 +210,7 @@ FILE *mingw_freopen (const char *filename, const char 
> *otype, FILE *stream);
>  int mingw_fflush(FILE *stream);
>  #define fflush mingw_fflush
>  
> -static inline ssize_t mingw_write(int fd, const void *buf, size_t len)
> -{
> - ssize_t result = write(fd, buf, len);
> -
> - if (result < 0 && errno == EINVAL && buf) {
> - /* check if fd is a pipe */
> - HANDLE h = (HANDLE) _get_osfhandle(fd);
> - if (GetFileType(h) == FILE_TYPE_PIPE)
> - errno = EPIPE;
> - else
> - errno = EINVAL;
> - }
> -
> - return result;
> -}
> -
> +ssize_t mingw_write(int fd, const void *buf, size_t len);
>  #define write mingw_write
>  
>  int mingw_access(const char *filename, int mode);
--
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: [PATCHv2] submodule: Port resolve_relative_url from shell to C

2015-12-17 Thread Johannes Sixt

Am 17.12.2015 um 19:55 schrieb Johannes Sixt:

As to the implementation, find a patch below that removes the ifdefs
and a few other suggestions.


The word "offers" is missing in this last half-sentence ;)

--
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: [PATCHv2] submodule: Port resolve_relative_url from shell to C

2015-12-17 Thread Johannes Sixt
Am 17.12.2015 um 01:26 schrieb Stefan Beller:
> This reimplements the helper function `resolve_relative_url` in shell
> in C. This functionality is needed in C for introducing the groups
> feature later on. When using groups, the user should not need to run
> `git submodule init`, but it should be implicit at all appropriate places,
> which are all in C code. As the we would not just call out to `git
> submodule init`, but do a more fine grained structure there, we actually
> need all the init functionality in C before attempting the groups
> feature. To get the init functionality in C, rewriting the
> resolve_relative_url subfunction is a major step.
>
> This also improves the performance:
> (Best out of 3) time ./t7400-submodule-basic.sh
> Before:
> real  0m9.575s
> user  0m2.683s
> sys   0m6.773s
> After:
> real  0m9.293s
> user  0m2.691s
> sys   0m6.549s
>
> That's about 3%.

I appreciate this effort as it should help us on Windows. Although the
numbers (and my own timings) suggest that this is only a small step
forward. That's not surprising as the patch removes only two forks.

As to the implementation, find a patch below that removes the ifdefs
and a few other suggestions. It is a mechanical conversion without
understanding what relative_url() does. I have the gut feeling that the
two strbuf_addf towards the end of the function can be contracted and
the temporarily allocate copy in 'out' can be removed.

If there were a few examples in the comment above the function, it
would be much simpler to understand.

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index b925bed..8ec0975 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -11,6 +11,7 @@
 #include "run-command.h"
 #include "remote.h"
 #include "refs.h"
+#include "connect.h"
 
 static const char *get_default_remote(void)
 {
@@ -31,34 +32,23 @@ static const char *get_default_remote(void)
return xstrdup(dest);
 }
 
-static int has_same_dir_prefix(const char *str, const char **out)
+static int starts_with_dot_slash(const char *str)
 {
-#ifdef GIT_WINDOWS_NATIVE
-   return skip_prefix(str, "./", out)
-   || skip_prefix(str, ".\\", out);
-#else
-   return skip_prefix(str, "./", out);
-#endif
+   return str[0] == '.' && is_dir_sep(str[1]);
 }
 
-static int has_upper_dir_prefix(const char *str, const char **out)
+static int starts_with_dot_dot_slash(const char *str)
 {
-#ifdef GIT_WINDOWS_NATIVE
-   return skip_prefix(str, "../", out)
-   || skip_prefix(str, "..\\", out);
-#else
-   return skip_prefix(str, "../", out);
-#endif
+   return str[0] == '.' && str[1] == '.' && is_dir_sep(str[2]);
 }
 
-static char *last_dir_separator(const char *str)
+static char *last_dir_separator(char *str)
 {
-#ifdef GIT_WINDOWS_NATIVE
-   return strrchr(str, "/")
-   || strrchr(str, "\\");
-#else
-   return strrchr(str, '/');
-#endif
+   char* p = str + strlen(str);
+   while (p-- != str)
+   if (is_dir_sep(*p))
+   return p;
+   return NULL;
 }
 
 /*
@@ -85,9 +75,10 @@ static const char *relative_url(const char *url, const char 
*up_path)
size_t len;
char *remoteurl = NULL;
char *sep = "/";
-   const char *out;
+   char *out;
struct strbuf sb = STRBUF_INIT;
const char *remote = get_default_remote();
+
strbuf_addf(&sb, "remote.%s.url", remote);
 
if (git_config_get_string(sb.buf, &remoteurl))
@@ -98,22 +89,23 @@ static const char *relative_url(const char *url, const char 
*up_path)
if (is_dir_sep(remoteurl[len]))
remoteurl[len] = '\0';
 
-   if (strchr(remoteurl, ':') || is_dir_sep(*remoteurl))
+   if (!url_is_local_not_ssh(remoteurl) || is_absolute_path(remoteurl))
is_relative = 0;
-   else if (has_same_dir_prefix(remoteurl, &out) ||
-   has_upper_dir_prefix(remoteurl, &out))
+   else if (starts_with_dot_slash(remoteurl) ||
+   starts_with_dot_dot_slash(remoteurl))
is_relative = 1;
else {
is_relative = 1;
strbuf_reset(&sb);
strbuf_addf(&sb, "./%s", remoteurl);
+   free(remoteurl);
remoteurl = strbuf_detach(&sb, NULL);
}
 
while (url) {
-   if (has_upper_dir_prefix(url, &out)) {
+   if (starts_with_dot_dot_slash(url)) {
char *rfind;
-   url = out;
+   url += 3;
 
rfind = last_dir_separator(remoteurl);
if (rfind)
@@ -130,22 +122,23 @@ static const char *relative_url(const char *url, const 
char *up_path)
remoteurl = ".";
}
}
-   } else if (has_same_dir_prefix(url, &out))
-   

Re: [PATCH v2 10/10] dir: do not use untracked cache ident anymore

2015-12-17 Thread Junio C Hamano
Christian Couder  writes:

> In the "git worktree" documentation there is:
>
> "If you move a linked working tree to another file system, or within a
> file system that does not support hard links, you need to run at least
> one git command inside the linked working tree (e.g. git status) in
> order to update its administrative files in the repository so that
> they do not get automatically pruned."
>
> It looks like git can detect when a worktree created with "git
> worktree" has been moved and I wonder if it would be possible to
> detect if the main worktree pointed to by GIT_WORK_TREE as moved.

As I personally do not find "moving a working tree" a very
compelling use case, I'd be fine if cached information is not used
when the actual worktree and the root of the cached untracked paths
are different.

If you are going to change the in-index data of untracked cache
anyway (like you attempted with 10/10 patch), I think a lot more
sensible simplification may be to make the mechanism _always_ keep
track of the worktree that is rooted one level above the index, and
not use the cache in all other cases.  That way, if you move the
working tree in its entirety (i.e. $foo/{Makefile,.git/,untracked}
all move to $bar/. at the same time), the untracked cache data that
was in $foo/.git/index, which knew about $foo/untracked, will now
know about $bar/untracked when the index is moved to $bar/.git/index
automatically.

--
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: Git issue report : issue with capital letter in folder name

2015-12-17 Thread Stefan Beller
On Thu, Dec 17, 2015 at 7:45 AM, PFDuc
 wrote:
> Hello,
>
> first of all thank you for developping git !
>
> I had an issue with a capital block in the folder name inside my git repo.
> The folder in my local was named "Display" and the one at origin was named
> "display" resulting in error when importing python code from this folder for
> users who got the repo from origin.

By any chance, were different operating systems or file systems
involved in creation of
this problem?

There are file systems which care about the capitalization, and others don't.
So if you have a file system which doesn't care about capitalization
of the folder/file name,
you can use a different capitalization and it still works. If you take
the code to
another system then, which is a bit more careful there are problems of course.

The main question which remains, is how is Git involved? i.e. would it
also happen
if you just transfer a tarball? Did Git itself break anything?

>
> I tried to change the folder name on bitbucket.org but I was unable to (or
> wasn't smart enough to find how to).
>
> I fixed the issue by deleting the file from my local, then commit, then
> push, put the same folder in my local, then commit then push.
>
> I am therefore only writing to tell you that story which is not so
> important, but I had the thought that because it is not so important maybe
> nobody reports that and the bug (if any) cannot be fixed.
>
> Have a good day and happy end of year season!
>
> Regards,
>
> Pierre-François Duc
> PhD candidate Physics McGill university
> --
> 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
--
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] rebase: add --verify-signatures

2015-12-17 Thread Junio C Hamano
Alexander 'z33ky' Hirsch <1ze...@gmail.com> writes:

> As I understand it, this is the same reason for the existence of
> --verify-signatures for git-merge. Otherwise the same argument could be
> made for git-merge 

I suspect that you are missing the bigger workflow issues, if you
think this and merge are the same.

git-merge will check the other history on the side branch that you
are merging _into_ the trunk, to give you an opportunity to reject
what does not pass and keep the trunk sane without doing anything
else.  How you (or others who asked you to pull) clean up the side
branch is outside the scope of its verification.

Your change to "git pull --rebase" checks the other way---the
history, which is already the trunk, onto which your work will be
rebased.  There is nothing you can do without messing with the trunk
if the validation did not pass, be it with a rewind-and-rebuild or a
sealing empty commit which is pointless.
--
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


Git issue report : issue with capital letter in folder name

2015-12-17 Thread PFDuc

Hello,

first of all thank you for developping git !

I had an issue with a capital block in the folder name inside my git 
repo. The folder in my local was named "Display" and the one at origin 
was named "display" resulting in error when importing python code from 
this folder for users who got the repo from origin.


I tried to change the folder name on bitbucket.org but I was unable to 
(or wasn't smart enough to find how to).


I fixed the issue by deleting the file from my local, then commit, then 
push, put the same folder in my local, then commit then push.


I am therefore only writing to tell you that story which is not so 
important, but I had the thought that because it is not so important 
maybe nobody reports that and the bug (if any) cannot be fixed.


Have a good day and happy end of year season!

Regards,

Pierre-François Duc
PhD candidate Physics McGill university
--
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 02/10] update-index: add --test-untracked-cache

2015-12-17 Thread David Turner
On Tue, 2015-12-15 at 17:28 +0100, Christian Couder wrote: 
> +--test-untracked-cache::
> + Only perform tests on the working directory to make sure
> + untracked cache can be used. You have to manually enable
> + untracked cache using `--force-untracked-cache` (or
> + `--untracked-cache` but this will run the tests again)
> + afterwards if you really want to use it.

It would be nice if this said how the result would be reported (by exit
code, it appears).
--
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] mingw: emulate write(2) that fails with a EPIPE

2015-12-17 Thread Johannes Schindelin
Hi Junio,

On Thu, 17 Dec 2015, Junio C Hamano wrote:

> Johannes Schindelin  writes:
> 
> > My intuition (which I honestly did not verify using performance tests) was
> > that write() is called *much* more often than, say, open(),...
> 
> My gut feeling agrees with yours, but I do not think the frequency
> at which write() is called should be the primary factor when you
> decide to make its wrapper inlined.  Once you call write(2), you
> will hit either the disk or the network doing I/O, and at that point
> I'd expect that the cost of making an extra layer of wrapper call
> would be lost in the noise.  I'd worry a lot more about from how
> many callsites write() is called---by inlining the extra code that
> is run only when the underlying write(2) returns an error to many
> callsites, we would make the program as a whole bigger, and as the
> result other code needs to be evicted out of the instruction cache,
> which also would hurt performance.

That argument convinced me. v2 coming shortly.

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


[PATCH v2] mingw: emulate write(2) that fails with a EPIPE

2015-12-17 Thread Johannes Schindelin
On Windows, when writing to a pipe fails, errno is always
EINVAL. However, Git expects it to be EPIPE.

According to the documentation, there are two cases in which write()
triggers EINVAL: the buffer is NULL, or the length is odd but the mode
is 16-bit Unicode (the broken pipe is not mentioned as possible cause).
Git never sets the file mode to anything but binary, therefore we know
that errno should actually be EPIPE if it is EINVAL and the buffer is
not NULL.

See https://msdn.microsoft.com/en-us/library/1570wh78.aspx for more
details.

This works around t5571.11 failing with v2.6.4 on Windows.

Signed-off-by: Johannes Schindelin 
---
 compat/mingw.c | 17 +
 compat/mingw.h |  3 +++
 2 files changed, 20 insertions(+)

diff --git a/compat/mingw.c b/compat/mingw.c
index 90bdb1e..5edea29 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -394,6 +394,23 @@ int mingw_fflush(FILE *stream)
return ret;
 }
 
+#undef write
+ssize_t mingw_write(int fd, const void *buf, size_t len)
+{
+   ssize_t result = write(fd, buf, len);
+
+   if (result < 0 && errno == EINVAL && buf) {
+   /* check if fd is a pipe */
+   HANDLE h = (HANDLE) _get_osfhandle(fd);
+   if (GetFileType(h) == FILE_TYPE_PIPE)
+   errno = EPIPE;
+   else
+   errno = EINVAL;
+   }
+
+   return result;
+}
+
 int mingw_access(const char *filename, int mode)
 {
wchar_t wfilename[MAX_PATH];
diff --git a/compat/mingw.h b/compat/mingw.h
index 738865c..57ca477 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -210,6 +210,9 @@ FILE *mingw_freopen (const char *filename, const char 
*otype, FILE *stream);
 int mingw_fflush(FILE *stream);
 #define fflush mingw_fflush
 
+ssize_t mingw_write(int fd, const void *buf, size_t len);
+#define write mingw_write
+
 int mingw_access(const char *filename, int mode);
 #undef access
 #define access mingw_access
Interdiff vs v1:

diff --git a/compat/mingw.c b/compat/mingw.c
index 90bdb1e..5edea29 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -394,6 +394,23 @@ int mingw_fflush(FILE *stream)
return ret;
 }
 
+#undef write
+ssize_t mingw_write(int fd, const void *buf, size_t len)
+{
+   ssize_t result = write(fd, buf, len);
+
+   if (result < 0 && errno == EINVAL && buf) {
+   /* check if fd is a pipe */
+   HANDLE h = (HANDLE) _get_osfhandle(fd);
+   if (GetFileType(h) == FILE_TYPE_PIPE)
+   errno = EPIPE;
+   else
+   errno = EINVAL;
+   }
+
+   return result;
+}
+
 int mingw_access(const char *filename, int mode)
 {
wchar_t wfilename[MAX_PATH];
diff --git a/compat/mingw.h b/compat/mingw.h
index 2aca347..57ca477 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -210,22 +210,7 @@ FILE *mingw_freopen (const char *filename, const char 
*otype, FILE *stream);
 int mingw_fflush(FILE *stream);
 #define fflush mingw_fflush
 
-static inline ssize_t mingw_write(int fd, const void *buf, size_t len)
-{
-   ssize_t result = write(fd, buf, len);
-
-   if (result < 0 && errno == EINVAL && buf) {
-   /* check if fd is a pipe */
-   HANDLE h = (HANDLE) _get_osfhandle(fd);
-   if (GetFileType(h) == FILE_TYPE_PIPE)
-   errno = EPIPE;
-   else
-   errno = EINVAL;
-   }
-
-   return result;
-}
-
+ssize_t mingw_write(int fd, const void *buf, size_t len);
 #define write mingw_write
 
 int mingw_access(const char *filename, int mode);

-- 
2.6.3.windows.1.300.g1c25e49
--
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 10/10] dir: do not use untracked cache ident anymore

2015-12-17 Thread Christian Couder
On Tue, Dec 15, 2015 at 8:49 PM, Junio C Hamano  wrote:
> Christian Couder  writes:
>
>> +/*
>> + * We used to save the location of the work tree and the kernel version,
>> + * but it was not a good idea, so we now just save an empty string.
>> + */
>
> I do agree that storing the kernel version (or hostname or whatever
> specific to the machine) was not a good idea.  I however suspect
> that you must save and check the location of the working tree,
> though, for correctness.  If you use one GIT_DIR and GIT_WORK_TREE
> to do "git add" or whatever, and then use the same GIT_DIR but a
> different GIT_WORK_TREE, you should be able to notice that a
> directory D in the old GIT_WORK_TREE whose modification time you
> recorded is different from the directory D with the same name but in
> the new GIT_WORK_TREE, no?

Yeah, if people use many worktrees made using "git worktree", the code
above should be fine because there is one index per worktree, but if
they just use one GIT_DIR with many GIT_WORK_TREE then there will be
only one index used.

I am wondering about the case when the worktree is moved and then
GIT_WORK_TREE is changed to reflect the new path were the worktree has
been moved.

In the "git worktree" documentation there is:

"If you move a linked working tree to another file system, or within a
file system that does not support hard links, you need to run at least
one git command inside the linked working tree (e.g. git status) in
order to update its administrative files in the repository so that
they do not get automatically pruned."

It looks like git can detect when a worktree created with "git
worktree" has been moved and I wonder if it would be possible to
detect if the main worktree pointed to by GIT_WORK_TREE as moved.
--
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] push: Fully test --recurse-submodules on command line overrides config

2015-12-17 Thread Junio C Hamano
Stefan Beller  writes:

>>> This looks good to me.
>>>
>> Thanks.  Does "This" refer to 1/2 alone or the whole series?
>
> Yes. :)
>
> "This" is applicable to both patches. We had the discussion on 2/2 about me
> misreading a line a few days earlier, but apart from that it looked good, too.

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


Re: [PATCH] mingw: emulate write(2) that fails with a EPIPE

2015-12-17 Thread Junio C Hamano
Johannes Schindelin  writes:

> My intuition (which I honestly did not verify using performance tests) was
> that write() is called *much* more often than, say, open(),...

My gut feeling agrees with yours, but I do not think the frequency
at which write() is called should be the primary factor when you
decide to make its wrapper inlined.  Once you call write(2), you
will hit either the disk or the network doing I/O, and at that point
I'd expect that the cost of making an extra layer of wrapper call
would be lost in the noise.  I'd worry a lot more about from how
many callsites write() is called---by inlining the extra code that
is run only when the underlying write(2) returns an error to many
callsites, we would make the program as a whole bigger, and as the
result other code needs to be evicted out of the instruction cache,
which also would hurt performance.


--
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 v2] git-svn: add support for prefixed globs in config

2015-12-17 Thread Victor Leschuk
Introduce prefixed globs for branches and tags in git-svn.
Globs like 'release_*' allow users to avoid long lines in config like:

branches = branches/{release_20,release_21,release_22,...}

Signed-off-by: Victor Leschuk 
---
Changes from v1:
* Joined implementation and test in one patch
* Fixed test code style according to current coding style guide

 Documentation/git-svn.txt|   5 ++
 perl/Git/SVN/GlobSpec.pm |   9 ++-
 t/t9168-git-svn-prefixed-glob.sh | 136 +++
 3 files changed, 145 insertions(+), 5 deletions(-)
 create mode 100755 t/t9168-git-svn-prefixed-glob.sh

diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index 0c0f60b..529cffe 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -1034,6 +1034,7 @@ listed below are allowed:
url = http://server.org/svn
fetch = trunk/project-a:refs/remotes/project-a/trunk
branches = branches/*/project-a:refs/remotes/project-a/branches/*
+   branches = branches/release_*:refs/remotes/project-a/branches/release_*
tags = tags/*/project-a:refs/remotes/project-a/tags/*
 
 
@@ -1044,6 +1045,10 @@ independent path component (surrounded by '/' or EOL).   
This
 type of configuration is not automatically created by 'init' and
 should be manually entered with a text-editor or using 'git config'.
 
+Also note that prefixed globs (e.g. 'release_*') match everything after prefix
+but do not match exact prefix. For example:
+'release_*' will match 'release_1' or 'release_v1' but will not match 
'release_'.
+
 It is also possible to fetch a subset of branches or tags by using a
 comma-separated list of names within braces. For example:
 
diff --git a/perl/Git/SVN/GlobSpec.pm b/perl/Git/SVN/GlobSpec.pm
index c95f5d7..a136090 100644
--- a/perl/Git/SVN/GlobSpec.pm
+++ b/perl/Git/SVN/GlobSpec.pm
@@ -11,16 +11,15 @@ sub new {
my $die_msg = "Only one set of wildcard directories " .
"(e.g. '*' or '*/*/*') is supported: '$glob'\n";
for my $part (split(m|/|, $glob)) {
-   if ($part =~ /\*/ && $part ne "*") {
-   die "Invalid pattern in '$glob': $part\n";
-   } elsif ($pattern_ok && $part =~ /[{}]/ &&
+   if ($pattern_ok && $part =~ /[{}]/ &&
 $part !~ /^\{[^{}]+\}/) {
die "Invalid pattern in '$glob': $part\n";
}
-   if ($part eq "*") {
+   if ($part =~ /(\w*)\*/) {
die $die_msg if $state eq "right";
$state = "pattern";
-   push(@patterns, "[^/]*");
+   my $pat = $1 ? "${1}[^/]+" : "[^/]*";
+   push(@patterns, $pat);
} elsif ($pattern_ok && $part =~ /^\{(.*)\}$/) {
die $die_msg if $state eq "right";
$state = "pattern";
diff --git a/t/t9168-git-svn-prefixed-glob.sh b/t/t9168-git-svn-prefixed-glob.sh
new file mode 100755
index 000..b8a059b
--- /dev/null
+++ b/t/t9168-git-svn-prefixed-glob.sh
@@ -0,0 +1,136 @@
+#!/bin/sh
+test_description='git svn globbing refspecs with prefixed globs'
+. ./lib-git-svn.sh
+
+cat >expect.end trunk/src/b/readme &&
+   svn_cmd import -m "initial" trunk "$svnrepo"/trunk &&
+   svn_cmd co "$svnrepo" tmp &&
+   (
+   cd tmp &&
+   mkdir branches tags &&
+   svn_cmd add branches tags &&
+   svn_cmd cp trunk branches/b_start &&
+   svn_cmd commit -m "start a new branch" &&
+   svn_cmd up &&
+   echo "hi" >>branches/b_start/src/b/readme &&
+   poke branches/b_start/src/b/readme &&
+   echo "hey" >>branches/b_start/src/a/readme &&
+   poke branches/b_start/src/a/readme &&
+   svn_cmd commit -m "hi" &&
+   svn_cmd up &&
+   svn_cmd cp branches/b_start tags/t_end &&
+   echo "bye" >>tags/t_end/src/b/readme &&
+   poke tags/t_end/src/b/readme &&
+   echo "aye" >>tags/t_end/src/a/readme &&
+   poke tags/t_end/src/a/readme &&
+   svn_cmd commit -m "the end" &&
+   echo "byebye" >>tags/t_end/src/b/readme &&
+   poke tags/t_end/src/b/readme &&
+   svn_cmd commit -m "nothing to see here"
+   ) &&
+   git config --add svn-remote.svn.url "$svnrepo" &&
+   git config --add svn-remote.svn.fetch \
+"trunk/src/a:refs/remotes/trunk" &&
+   git config --add svn-remote.svn.branches \
+"branches/b_*/src/a:refs/remotes/branches/b_*" &&
+   git config --add svn-remote.svn.tags\
+"tags/t_*/src/a:refs/remotes/tags/t_

RE: CruiseControl.NET hangs on git-submodule bad file descriptor

2015-12-17 Thread Alexander Skrinnik
OK, no problem 
I have workaround :)

Thanks a lot for your help

Best wishes
--
Alexander Skrinnik


-Original Message-
From: Johannes Schindelin [mailto:johannes.schinde...@gmx.de] 
Sent: Thursday, December 17, 2015 3:55 PM
To: Alexander Skrinnik
Cc: git@vger.kernel.org
Subject: RE: CruiseControl.NET hangs on git-submodule bad file descriptor

Hi Alexander,

you might want to refrain from top-posting on this list in the future.
Just sayin' ;-)

On Thu, 17 Dec 2015, Alexander Skrinnik wrote:

> I found workaround, CC.NET invokes bat-file with command:
> git submodule foreach git checkout "myBranch"  
> It works fine. But looks like the issue is in git. Not in CC.NET :) If 
> you have a chance, could you look into it, please?

Unfortunately, this is one of those problems where the bug reporter expects me 
not only to fix the problem, but also to come up with an easy way to reproduce 
the issue.

And even more unfortunate is the fact that I am really pressed on some other, 
more critical issues.

Is there really no chance for you to have a crack at resolving this issue?

Ciao,
Johannes
--
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: CruiseControl.NET hangs on git-submodule bad file descriptor

2015-12-17 Thread Johannes Schindelin
Hi Alexander,

you might want to refrain from top-posting on this list in the future.
Just sayin' ;-)

On Thu, 17 Dec 2015, Alexander Skrinnik wrote:

> I found workaround, CC.NET invokes bat-file with command:
> git submodule foreach git checkout "myBranch"  
> It works fine. But looks like the issue is in git. Not in CC.NET :)
> If you have a chance, could you look into it, please?

Unfortunately, this is one of those problems where the bug reporter
expects me not only to fix the problem, but also to come up with an easy
way to reproduce the issue.

And even more unfortunate is the fact that I am really pressed on some
other, more critical issues.

Is there really no chance for you to have a crack at resolving this issue?

Ciao,
Johannes
--
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 7/8] config: add core.untrackedCache

2015-12-17 Thread Duy Nguyen
On Wed, Dec 16, 2015 at 4:53 AM, Ævar Arnfjörð Bjarmason
 wrote:
> On Tue, Dec 15, 2015 at 8:40 PM, Junio C Hamano  wrote:
>> Ævar Arnfjörð Bjarmason  writes:
>> I still have a problem with the approach from "design cleanliness"
>> point of view[...]
>>
>> In any case I think we already have agreed to disagree on this
>> point, so there is no use discussing it any longer from my side.  I
>> am not closing the door to this series, but I am not convinced,
>> either.  At least not yet.
>
> In general the fantastic thing about the git configuration facility is
> that it provides both systems administrators and normal users with
> what they want. It's possible to configure things system-wide and
> override those on a user or repository basis.
>
> Of course hindsight is 20/20, but I think that given what's been
> covered in this thread it's been established that it's categorically
> better that if we introduce features like these that they be
> configured through the normal configuration facility rather than the
> configuration being sticky to the index.

A minor note for implementers. We need to check that config is loaded
first. read-cache.c, being part of the core, does not bother itself
with config loading. And I think so far it has not used any config
vars. If a command forgets (*) to load the config, the cache may be
deleted (if we do it the safe way).

(*) is there any command deliberately avoid loading config? git-clone
and git-init are special, but for this particular case it's probably
fine.
-- 
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: CruiseControl.NET hangs on git-submodule bad file descriptor

2015-12-17 Thread Alexander Skrinnik
Hi Johannes,

Thank you for your answer.
Yes, this is the same issue. I found workaround, CC.NET invokes bat-file with 
command:
git submodule foreach git checkout "myBranch" mailto:johannes.schinde...@gmx.de] 
Sent: Thursday, December 17, 2015 11:46 AM
To: Alexander Skrinnik
Cc: git@vger.kernel.org
Subject: Re: CruiseControl.NET hangs on git-submodule bad file descriptor

Hi Alexander,

On Thu, 17 Dec 2015, Alexander Skrinnik wrote:

> I had installed CruiseControl.NET 1.8.5 and Git-1.9.5-preview20150319 
> CC.NET invokes bat-file which invokes git submodule foreach git 
> checkout "myBranch"
> 
> It worked good.
> Today I upgraded git to 2.6.4 and CC.NET fails on this command with
> error: C:\Program Files
> (x86)\Git\mingw32/libexec/git-core\git-submodule: line 544: 0: Bad 
> file descriptor

This sounds very similar (maybe identical) to this bug report:

https://github.com/git-for-windows/git/issues/181

Ciao,
Johannes
--
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 7/8] config: add core.untrackedCache

2015-12-17 Thread Duy Nguyen
On Thu, Dec 17, 2015 at 2:44 PM, Jeff King  wrote:
> I think we may actually be thinking of the same thing. Naively, I would
> expect:
>
> ..
>   - if there is cache data in the index but that config flag is not set,
> presumably we would not update it (we could even explicitly drop it,
> but my understanding is that is not necessary for correctness, but
> only as a possible optimization).

No, if somebody adds or removes something from the index, we either
update or drop it, or it's stale. There's the invalidate_untracked()
or something in dir.c that we can hook in, check config var and do
that. And because config is cached recently, it should be a cheap
operation.

Apart from that the idea is fine.

> You could have a config option for "if there is a cache there, pretend
> it isn't and ignore it", but I don't see much point.
-- 
Duy
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 01/10] update-index: use enum for untracked cache options

2015-12-17 Thread Torsten Bögershausen
On 15.12.15 17:28, Christian Couder wrote:
> Signed-off-by: Christian Couder 
> ---
>  builtin/update-index.c | 18 +-
>  1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/builtin/update-index.c b/builtin/update-index.c
> index 7431938..2430a68 100644
> --- a/builtin/update-index.c
> +++ b/builtin/update-index.c
> @@ -35,6 +35,14 @@ static int mark_skip_worktree_only;
>  #define UNMARK_FLAG 2
>  static struct strbuf mtime_dir = STRBUF_INIT;
>  
> +/* Untracked cache mode */
> +enum uc_mode {
> + UC_UNSPECIFIED = -1,
> + UC_DISABLE = 0,
> + UC_ENABLE,
> + UC_FORCE
> +};
> +
>  __attribute__((format (printf, 1, 2)))
>  static void report(const char *fmt, ...)
>  {
> @@ -902,7 +910,7 @@ static int reupdate_callback(struct parse_opt_ctx_t *ctx,
>  int cmd_update_index(int argc, const char **argv, const char *prefix)
>  {
>   int newfd, entries, has_errors = 0, line_termination = '\n';
> - int untracked_cache = -1;
> + enum uc_mode untracked_cache = UC_UNSPECIFIED;
>   int read_from_stdin = 0;
>   int prefix_length = prefix ? strlen(prefix) : 0;
>   int preferred_index_format = 0;
> @@ -997,7 +1005,7 @@ int cmd_update_index(int argc, const char **argv, const 
> char *prefix)
>   OPT_BOOL(0, "untracked-cache", &untracked_cache,
>   N_("enable/disable untracked cache")),
>   OPT_SET_INT(0, "force-untracked-cache", &untracked_cache,
> - N_("enable untracked cache without testing the 
> filesystem"), 2),
> + N_("enable untracked cache without testing the 
> filesystem"), UC_FORCE),
>   OPT_END()
>   };
>  
> @@ -1104,10 +1112,10 @@ int cmd_update_index(int argc, const char **argv, 
> const char *prefix)
>   the_index.split_index = NULL;
>   the_index.cache_changed |= SOMETHING_CHANGED;
>   }
> - if (untracked_cache > 0) {
> + if (untracked_cache > UC_DISABLE) {
I think the "correct way" for a comparison between an enum and an int is to 
cast the enum
into an int.
But, if we have an enum, these kind of comparision should go away, and replaced
with a switch-case (or if) statemant.
>   struct untracked_cache *uc;
>  
> - if (untracked_cache < 2) {
> + if (untracked_cache < UC_FORCE) {

Same here

--
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: No auto CRLF conversion in Commit Message comments

2015-12-17 Thread Andrew Harfoot

Hi Johannes,

On 16/12/2015 16:45, Johannes Schindelin wrote:

However, if you have `core.editor = notepad`, it should Just Work because
there is a `notepad` helper that performs the LF<->CR/LF translation
transparently.


The problem in my case was that I had

`core.editor = notepad.exe`

This wasn't triggering the helper, I've changed it, dropping the '.exe' 
and it now works nicely.


Thanks for your help,

Andy

--
Andy Harfoot

GeoData Institute
University of Southampton
Southampton
SO17 1BJ

Tel:  +44 (0)23 8059 2719
Fax:  +44 (0)23 8059 2849

www.geodata.soton.ac.uk

--
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: CruiseControl.NET hangs on git-submodule bad file descriptor

2015-12-17 Thread Johannes Schindelin
Hi Alexander,

On Thu, 17 Dec 2015, Alexander Skrinnik wrote:

> I had installed CruiseControl.NET 1.8.5 and Git-1.9.5-preview20150319
> CC.NET invokes bat-file which invokes 
> git submodule foreach git checkout "myBranch"
> 
> It worked good.
> Today I upgraded git to 2.6.4 and CC.NET fails on this command with
> error: C:\Program Files
> (x86)\Git\mingw32/libexec/git-core\git-submodule: line 544: 0: Bad file
> descriptor

This sounds very similar (maybe identical) to this bug report:

https://github.com/git-for-windows/git/issues/181

Ciao,
Johannes
--
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 10/11] ref-filter: introduce contents_atom_parser()

2015-12-17 Thread Eric Sunshine
On Wed, Dec 16, 2015 at 10:30 AM, Karthik Nayak  wrote:
> Introduce contents_atom_parser() which will parse the '%(contents)'
> atom and store information into the 'used_atom' structure based on the
> modifiers used along with the atom.
>
> Helped-by: Ramsay Jones 
> Signed-off-by: Karthik Nayak 
> ---
> diff --git a/ref-filter.c b/ref-filter.c
> @@ -39,6 +39,10 @@ static struct used_atom {
> struct align align;
> enum { RR_SHORTEN, RR_TRACK, RR_TRACKSHORT, RR_NORMAL }
> remote_ref;
> +   struct {
> +   enum { C_BARE, C_BODY, C_BODY_DEP, C_LINES, C_SIG, 
> C_SUB } option;
> +   unsigned int no_lines;

'no_lines' sounds like "no lines!". How about 'nlines' instead?

> +   } contents;
> } u;
>  } *used_atom;
>  static int used_atom_cnt, need_tagged, need_symref;
> @@ -90,6 +94,36 @@ static void remote_ref_atom_parser(struct used_atom *atom)
> +static void contents_atom_parser(struct used_atom *atom)
> +{
> +   const char * buf;
> +
> +   if (match_atom_name(atom->str, "contents", &buf))
> +   atom->u.contents.option = C_BARE;
> +   else if (match_atom_name(atom->str, "subject", &buf)) {

The original code used strcmp() and matched only "subject", however
the new code will incorrectly match both "subject" and
"subject:whatever". Therefore, you should be using strcmp() here
rather than match_atom_name().

Ditto for "body".

> +   atom->u.contents.option = C_SUB;
> +   return;
> +   } else if (match_atom_name(atom->str, "body", &buf)) {
> +   atom->u.contents.option = C_BODY_DEP;
> +   return;
> +   }
> +   if (!buf)
> +   return;

It's not easy to see that this 'if (!buf)' check relates to the
"contents" check at the very top of the if/else if/ chain since there
are entirely unrelated checks in between. Reorganizing it can improve
clarity:

if (!strcmp("subject")) {
...
return;
} else if (!strcmp("body")) {
...
return;
} else if (!match_atom_name(...,"contents", &buf))
die("BUG: expected 'contents' or 'contents:'");

if (!buf) {
atom->u.contents.option = C_BARE;
return;
}

> +   if (!strcmp(buf, "body"))
> +   atom->u.contents.option = C_BODY;
> +   else if (!strcmp(buf, "signature"))
> +   atom->u.contents.option = C_SIG;
> +   else if (!strcmp(buf, "subject"))
> +   atom->u.contents.option = C_SUB;
> +   else if (skip_prefix(buf, "lines=", &buf)) {
> +   atom->u.contents.option = C_LINES;
> +   if (strtoul_ui(buf, 10, &atom->u.contents.no_lines))
> +   die(_("positive value expected contents:lines=%s"), 
> buf);
> +   } else
> +   die(_("unrecognized %%(contents) argument: %s"), buf);
> +}
> @@ -777,28 +801,23 @@ static void grab_sub_body_contents(struct atom_value 
> *val, int deref, struct obj
> &bodypos, &bodylen, &nonsiglen,
> &sigpos, &siglen);
>
> -   if (!strcmp(name, "subject"))
> +   if (atom->u.contents.option == C_SUB)
> v->s = copy_subject(subpos, sublen);
> -   else if (!strcmp(name, "contents:subject"))
> -   v->s = copy_subject(subpos, sublen);
> -   else if (!strcmp(name, "body"))
> +   else if (atom->u.contents.option == C_BODY_DEP)
> v->s = xmemdupz(bodypos, bodylen);
> -   else if (!strcmp(name, "contents:body"))
> +   else if (atom->u.contents.option == C_BODY)
> v->s = xmemdupz(bodypos, nonsiglen);
> -   else if (!strcmp(name, "contents:signature"))
> +   else if (atom->u.contents.option == C_SIG)
> v->s = xmemdupz(sigpos, siglen);
> -   else if (!strcmp(name, "contents"))
> -   v->s = xstrdup(subpos);
> -   else if (skip_prefix(name, "contents:lines=", &valp)) {
> +   else if (atom->u.contents.option == C_LINES) {
> struct strbuf s = STRBUF_INIT;
> const char *contents_end = bodylen + bodypos - siglen;
>
> -   if (strtoul_ui(valp, 10, &v->u.contents.lines))
> -   die(_("positive value expected 
> contents:lines=%s"), valp);
> /*  Size is the length of the message after removing 
> the signature */
> -   append_lines(&s, subpos, contents_end - subpos, 
> v->u.contents.lines);
> +   append_lines(&s, subpos, contents_end - subpos, 
> atom->u.contents.no_lines);
> v->s = strbuf_detach(&s, NULL);
> -   }
> +   } else if (atom->u.contents.

Re: [PATCH] mingw: emulate write(2) that fails with a EPIPE

2015-12-17 Thread Johannes Schindelin
Hi Junio,

On Wed, 16 Dec 2015, Junio C Hamano wrote:

> Johannes Schindelin  writes:
> 
> >  int mingw_fflush(FILE *stream);
> >  #define fflush mingw_fflush
> >  
> > +static inline ssize_t mingw_write(int fd, const void *buf, size_t len)
> > +{
> > +   ssize_t result = write(fd, buf, len);
> > +
> > +   if (result < 0 && errno == EINVAL && buf) {
> > +   /* check if fd is a pipe */
> > +   HANDLE h = (HANDLE) _get_osfhandle(fd);
> > +   if (GetFileType(h) == FILE_TYPE_PIPE)
> > +   errno = EPIPE;
> > +   else
> > +   errno = EINVAL;
> > +   }
> > +
> > +   return result;
> > +}
> > +
> > +#define write mingw_write
> > +
> 
> It strikes me a bit strange to see this inlined compared to what
> appears in the context.  Shouldn't the implementation be done in
> compat/mingw.c like all others?

My intuition (which I honestly did not verify using performance tests) was
that write() is called *much* more often than, say, open(), and therefore
I wanted to interfere as little as possible with the performance penalty.
Hence the choice of an inlined function as opposed to a non-optimizable
increment of the call chain.

If it bothers you a lot I will set aside time to perform performance
tests.

Ciao,
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] mingw: emulate write(2) that fails with a EPIPE

2015-12-17 Thread Johannes Schindelin
Hi Eric,

On Wed, 16 Dec 2015, Eric Sunshine wrote:

> On Wednesday, December 16, 2015, Johannes Schindelin
>  wrote:
> > diff --git a/compat/mingw.h b/compat/mingw.h
> > @@ -210,6 +210,24 @@ FILE *mingw_freopen (const char *filename, const char 
> > *otype, FILE *stream);
> > +static inline ssize_t mingw_write(int fd, const void *buf, size_t len)
> > +{
> > +   ssize_t result = write(fd, buf, len);
> > +
> > +   if (result < 0 && errno == EINVAL && buf) {
> 
> Here, errno is EINVAL...
> 
> > +   /* check if fd is a pipe */
> > +   HANDLE h = (HANDLE) _get_osfhandle(fd);
> > +   if (GetFileType(h) == FILE_TYPE_PIPE)
> > +   errno = EPIPE;
> > +   else
> > +   errno = EINVAL;
> 
> Does any of the code between the outer 'if' and this point clobber
> errno, or are you merely assigning EINVAL for robustness against
> future changes?

Yes, it is proofing the code against future changes. And TBH I did not
even bother to check whether _get_osfhandle() or GetFileType() can modify
the errno value, since I *really* wanted to make sure that errno is either
EPIPE or EINVAL in this execution path.

Ciao,
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 v2 09/11] ref-filter: introduce remote_ref_atom_parser()

2015-12-17 Thread Eric Sunshine
On Wed, Dec 16, 2015 at 10:30 AM, Karthik Nayak  wrote:
> Introduce remote_ref_atom_parser() which will parse the '%(upstream)'
> and '%(push)' atoms and store information into the 'used_atom'
> structure based on the modifiers used along with the corresponding
> atom.
>
> Helped-by: Ramsay Jones 
> Signed-off-by: Karthik Nayak 
> ---
> diff --git a/ref-filter.c b/ref-filter.c
> @@ -37,6 +37,8 @@ static struct used_atom {
> union {
> const char *color;
> struct align align;
> +   enum { RR_SHORTEN, RR_TRACK, RR_TRACKSHORT, RR_NORMAL }

Nit: I'd have expected to see the normal/plain case first rather than
last (but not itself worth a re-roll).

> +   remote_ref;
> } u;
>  } *used_atom;
>  static int used_atom_cnt, need_tagged, need_symref;
> @@ -69,6 +71,25 @@ static void color_atom_parser(struct used_atom *atom)
> +static void remote_ref_atom_parser(struct used_atom *atom)
> +{
> +   const char *buf;
> +
> +   buf = strchr(atom->str, ':');
> +   atom->u.remote_ref = RR_NORMAL;
> +   if (!buf)
> +   return;

This code is not as clear as it could be due to the way the 'buf'
assignment and check for NULL are split apart. It can be made clearer
either by doing this:

atom->u.remote_ref = RR_NORMAL;
buf = strchr(...);
if (!buf)
return;

or (even better) this:

buf = strchr(...);
if (!buf) {
atom->u.remote_ref = RR_NORMAL;
return;
}

> +   buf++;
> +   if (!strcmp(buf, "short"))
> +   atom->u.remote_ref = RR_SHORTEN;
> +   else if (!strcmp(buf, "track"))
> +   atom->u.remote_ref = RR_TRACK;
> +   else if (!strcmp(buf, "trackshort"))
> +   atom->u.remote_ref = RR_TRACKSHORT;
> +   else
> +   die(_("unrecognized format: %%(%s)"), atom->str);
> +}
> +
> @@ -835,6 +856,42 @@ static inline char *copy_advance(char *dst, const char 
> *src)
> +static void fill_remote_ref_details(struct used_atom *atom, const char 
> *refname,
> +   struct branch *branch, const char **s)
> +{
> +   int num_ours, num_theirs;
> +   if (atom->u.remote_ref == RR_SHORTEN)
> +   *s = shorten_unambiguous_ref(refname, warn_ambiguous_refs);
> +   else if (atom->u.remote_ref == RR_TRACK) {
> +   if (stat_tracking_info(branch, &num_ours,
> +  &num_theirs, NULL))
> +   return;

The RR_TRACKSHORT branch below has a blank line following the
'return', but this branch lacks it, which is inconsistent.

> +   if (!num_ours && !num_theirs)
> +   *s = "";
> +   else if (!num_ours)
> +   *s = xstrfmt("[behind %d]", num_theirs);
> +   else if (!num_theirs)
> +   *s = xstrfmt("[ahead %d]", num_ours);
> +   else
> +   *s = xstrfmt("[ahead %d, behind %d]",
> +num_ours, num_theirs);
> +   } else if (atom->u.remote_ref == RR_TRACKSHORT) {
> +   if (stat_tracking_info(branch, &num_ours,
> +  &num_theirs, NULL))

What happened to the assert(branch) which was in the original code
from which this was derived (below)? Is it no longer needed?

> +   return;
> +
> +   if (!num_ours && !num_theirs)
> +   *s = "=";
> +   else if (!num_ours)
> +   *s = "<";
> +   else if (!num_theirs)
> +   *s = ">";
> +   else
> +   *s = "<>";
> +   } else if (atom->u.remote_ref == RR_NORMAL)
> +   *s = refname;
> +}
> +
>  /*
>   * Parse the object referred by ref, and grab needed value.
>   */
> @@ -889,6 +946,8 @@ static void populate_value(struct ref_array_item *ref)
> refname = branch_get_upstream(branch, NULL);
> if (!refname)
> continue;
> +   fill_remote_ref_details(atom, refname, branch, &v->s);
> +   continue;
> } else if (starts_with(name, "push")) {
> const char *branch_name;
> if (!skip_prefix(ref->refname, "refs/heads/",
> @@ -899,6 +958,8 @@ static void populate_value(struct ref_array_item *ref)
> refname = branch_get_push(branch, NULL);
> if (!refname)
> continue;
> +   fill_remote_ref_details(atom, refname, branch, &v->s);
> +   continue;
> } else if (starts_with(name, "color:")) {
> char color[COLOR_MAXLEN] = "";
>
> @@ -944,49 +1005,11 @@ static void populate_value(struct ref_array_item *ref)
>
> format

Re: [PATCH v2 08/11] ref-filter: introduce prefixes for the align atom

2015-12-17 Thread Eric Sunshine
On Wed, Dec 16, 2015 at 10:29 AM, Karthik Nayak  wrote:
> ref-filter: introduce prefixes for the align atom

The prefixes are actually for the arguments to the 'align' atom, not
for the atom itself. However, it might be better to describe this at a
bit higher level. Perhaps:

ref-filter: align: introduce long-form syntax

or something.

> Introduce optional prefixes "width=" and "position=" for the align atom
> so that the atom can be used as "%(align:width=,position=)".
>
> Add Documetation and tests for the same.
>
> Signed-off-by: Karthik Nayak 
> ---
> diff --git a/ref-filter.c b/ref-filter.c
> @@ -96,10 +96,19 @@ static void align_atom_parser(struct used_atom *atom)
>
> while (*s) {
> int position;
> +   buf = s[0]->buf;

It probably would be better to do this assignment in the previous
patch (7/11) since its presence here introduces unwanted noise
(textual replacement of "s[0]->buf" with "buf") in several locations
below which slightly obscure the real changes of this patch.

> -   if (!strtoul_ui(s[0]->buf, 10, (unsigned int *)&width))
> +   if (skip_prefix(buf, "position=", &buf)) {
> +   position = parse_align_position(buf);
> +   if (position == -1)

It may be more idiomatic in this codebase to detect errors via '< 0'
rather than explicit '== -1'. Ditto below.

> +   die(_("unrecognized position:%s"), buf);
> +   align->position = position;
> +   } else if (skip_prefix(buf, "width=", &buf)) {
> +   if (strtoul_ui(buf, 10, (unsigned int *)&width))
> +   die(_("unrecognized width:%s"), buf);
> +   } else if (!strtoul_ui(buf, 10, (unsigned int *)&width))
> ;
> -   else if ((position = parse_align_position(s[0]->buf)) > 0)
> +   else if ((position = parse_align_position(buf)) != -1)
> align->position = position;
> else
> die(_("unrecognized %%(align) argument: %s"), 
> s[0]->buf);

s/s[0]->//

More below...

> diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh
> @@ -133,6 +133,168 @@ test_expect_success 'right alignment' '
> test_cmp expect actual
>  '
>
> +test_expect_success 'alignment with "position" prefix' '
> +   cat >expect <<-\EOF &&
> +   |  refname is refs/heads/master|refs/heads/master
> +   |refname is refs/heads/side|refs/heads/side
> +   |  refname is refs/odd/spot|refs/odd/spot
> +   |refname is refs/tags/double-tag|refs/tags/double-tag
> +   | refname is refs/tags/four|refs/tags/four
> +   |  refname is refs/tags/one|refs/tags/one
> +   |refname is refs/tags/signed-tag|refs/tags/signed-tag
> +   |refname is refs/tags/three|refs/tags/three
> +   |  refname is refs/tags/two|refs/tags/two
> +   EOF
> +   git for-each-ref --format="|%(align:30,position=right)refname is 
> %(refname)%(end)|%(refname)" >actual &&
> +   test_cmp expect actual
> +'
> +
> +test_expect_success 'alignment with "position" prefix' '
> +   cat >expect <<-\EOF &&
> +   |  refname is refs/heads/master|refs/heads/master
> +   |refname is refs/heads/side|refs/heads/side
> +   |  refname is refs/odd/spot|refs/odd/spot
> +   |refname is refs/tags/double-tag|refs/tags/double-tag
> +   | refname is refs/tags/four|refs/tags/four
> +   |  refname is refs/tags/one|refs/tags/one
> +   |refname is refs/tags/signed-tag|refs/tags/signed-tag
> +   |refname is refs/tags/three|refs/tags/three
> +   |  refname is refs/tags/two|refs/tags/two
> +   EOF
> +   git for-each-ref --format="|%(align:position=right,30)refname is 
> %(refname)%(end)|%(refname)" >actual &&
> +   test_cmp expect actual
> +'

This (and below) is a lot of copy/paste code which makes it difficult
to read the tests and maintain (change) them. Since 'expect' doesn't
appear to change from test to test, one way to eliminate some of this
noisiness would be to create 'expect' once outside of the tests.

However, even better, especially from a comprehension,
maintainability, and extensibility standpoints would be to make this
all table-driven. In particular, I'd expect to see a table with
exactly the list of test inputs mentioned in my earlier review[1], and
have that table passed to a shell function which performs the test for
each element of the table. For instance, something like:

test_align_permutations <<-\EOF
middle,42
42,middle
position=middle,42
42,position=middle
middle,width=42
width=42,middle
position=middle,width=42
width=42,position=middle
EOF

where test_align_permutations is the name of the shell function which
reads each line of it stdin and performs the "git for-each-

Re: [PATCH v2 01/11] strbuf: introduce strbuf_split_str_without_term()

2015-12-17 Thread Karthik Nayak
On Thu, Dec 17, 2015 at 2:05 AM, Eric Sunshine  wrote:
> On Wed, Dec 16, 2015 at 10:29 AM, Karthik Nayak  wrote:
>> strbuf: introduce strbuf_split_str_without_term()
>
> s/without/omit/
>
>> The current implementation of 'strbuf_split_buf()' includes the
>> terminator at the end of each strbuf post splitting. Add an option
>> wherein we can drop the terminator if desired. In this context
>> introduce a wrapper function 'strbuf_split_str_without_term()' which
>
> s/without/omit/
>

Oops! will change that,

>> splits a given string into strbufs without including the terminator.
>>
>> Signed-off-by: Karthik Nayak 
>> ---
>> diff --git a/strbuf.c b/strbuf.c
>> @@ -115,7 +115,7 @@ void strbuf_tolower(struct strbuf *sb)
>>  struct strbuf **strbuf_split_buf(const char *str, size_t slen,
>> -int terminator, int max)
>> +int terminator, int max, int omit_term)
>>  {
>> struct strbuf **ret = NULL;
>> size_t nr = 0, alloc = 0;
>> @@ -123,14 +123,15 @@ struct strbuf **strbuf_split_buf(const char *str, 
>> size_t slen,
>>
>> while (slen) {
>> int len = slen;
>> +   const char *end = NULL;
>> if (max <= 0 || nr + 1 < max) {
>> -   const char *end = memchr(str, terminator, slen);
>> +   end = memchr(str, terminator, slen);
>> if (end)
>> len = end - str + 1;
>> }
>> t = xmalloc(sizeof(struct strbuf));
>> strbuf_init(t, len);
>> -   strbuf_add(t, str, len);
>> +   strbuf_add(t, str, len - !!end * !!omit_term);
>
> This version of the patch with its minimal[1] change is much easier to
> review for correctness than the original attempt[2].
>
> [1]: http://article.gmane.org/gmane.comp.version-control.git/281882
> [2]: http://article.gmane.org/gmane.comp.version-control.git/281189
>
>> ALLOC_GROW(ret, nr + 2, alloc);
>> ret[nr++] = t;
>> str += len;
>> diff --git a/strbuf.h b/strbuf.h
>> index 6ae7a72..a865a74 100644
>> --- a/strbuf.h
>> +++ b/strbuf.h
>> @@ -450,11 +450,12 @@ static inline int strbuf_strip_suffix(struct strbuf 
>> *sb, const char *suffix)
>>  /**
>>   * Split str (of length slen) at the specified terminator character.
>>   * Return a null-terminated array of pointers to strbuf objects
>> - * holding the substrings.  The substrings include the terminator,
>> - * except for the last substring, which might be unterminated if the
>> - * original string did not end with a terminator.  If max is positive,
>> - * then split the string into at most max substrings (with the last
>> - * substring containing everything following the (max-1)th terminator
>> + * holding the substrings.  The substrings include the terminator if
>> + * the value of omit_term is '0' else the terminator is excluded.  The
>
> Perhaps just say "if omit_term is false" rather than "if the value of ... is 
> 0".
>
>> + * last substring, might be unterminated if the original string did
>> + * not end with a terminator.  If max is positive, then split the
>
> This bit about the last substring is perhaps too disconnected from the
> previous sentence. What if you re-word the entire thing something like
> this:
>
> If omit_term is true, the terminator will be stripped from all
> substrings. Otherwise, substrings will include the terminator,
> except for the final substring, if the original string lacked a
> terminator.
>

Im quite bad at this, thanks :)

>>
>> This version of the patch with its minimal[1] change is much easier to
>> review for correctness than the original attempt[2].
>
> Perhaps worthy of a Helped-by:?

Definitely! Sorry for not including that, slipped off my mind.

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


CruiseControl.NET hangs on git-submodule bad file descriptor

2015-12-17 Thread Alexander Skrinnik
Hi guys,

I had installed CruiseControl.NET 1.8.5 and Git-1.9.5-preview20150319
CC.NET invokes bat-file which invokes 
git submodule foreach git checkout "myBranch"

It worked good.
Today I upgraded git to 2.6.4 and CC.NET fails on this command with error:
C:\Program Files (x86)\Git\mingw32/libexec/git-core\git-submodule: line 544: 0: 
Bad file descriptor

When I run the same command from cmd window all works without error
For now I have to return to 1.9.5 version.

Could you, please, help to fix the issue?

Thank you in advance
--
Alexander Skrinnik

--
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: [PATCHv2] submodule: Port resolve_relative_url from shell to C

2015-12-17 Thread Eric Sunshine
A rather superficial review...

On Wed, Dec 16, 2015 at 7:26 PM, Stefan Beller  wrote:
> This reimplements the helper function `resolve_relative_url` in shell

s/This reimplements/Reimplement/

> in C. This functionality is needed in C for introducing the groups
> feature later on. When using groups, the user should not need to run
> `git submodule init`, but it should be implicit at all appropriate places,
> which are all in C code. As the we would not just call out to `git

I guess you mean "As then we..." or something?

> submodule init`, but do a more fine grained structure there, we actually
> need all the init functionality in C before attempting the groups
> feature. To get the init functionality in C, rewriting the
> resolve_relative_url subfunction is a major step.
>
> Signed-off-by: Stefan Beller 
> ---
> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
> @@ -9,6 +9,156 @@
> +static const char *get_default_remote(void)
> +{
> +   char *dest = NULL;
> +   unsigned char sha1[20];
> +   int flag;
> +   struct strbuf sb = STRBUF_INIT;
> +   const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, &flag);
> +
> +   if (!refname)
> +   die("No such ref: HEAD");
> +
> +   refname = shorten_unambiguous_ref(refname, 0);
> +   strbuf_addf(&sb, "branch.%s.remote", refname);
> +   if (git_config_get_string(sb.buf, &dest))
> +   return "origin";
> +   else
> +   return xstrdup(dest);

Leaking the strbuf at both returns.

And, leaking the strdup'd dest (in the caller), but I suppose that's
intentional?

> +}
> +
> +static int has_same_dir_prefix(const char *str, const char **out)
> +{
> +#ifdef GIT_WINDOWS_NATIVE
> +   return skip_prefix(str, "./", out)
> +   || skip_prefix(str, ".\\", out);
> +#else
> +   return skip_prefix(str, "./", out);
> +#endif
> +}
> +
> +static int has_upper_dir_prefix(const char *str, const char **out)
> +{
> +#ifdef GIT_WINDOWS_NATIVE
> +   return skip_prefix(str, "../", out)
> +   || skip_prefix(str, "..\\", out);
> +#else
> +   return skip_prefix(str, "../", out);
> +#endif
> +}
> +
> +static char *last_dir_separator(const char *str)
> +{
> +#ifdef GIT_WINDOWS_NATIVE
> +   return strrchr(str, "/")
> +   || strrchr(str, "\\");
> +#else
> +   return strrchr(str, '/');
> +#endif
> +}

Cleaner would be to move the #if's outside the functions:

#ifdef GIT_WINDOWS_NATIVE

/* Windows implementations */
static int has_same_dir_prefix(...) {...}
static int has_upper_dir_prefix(...) {...}
static char *last_dir_separator(...) {...}

#else

/* POSIX implementations */
static int has_same_dir_prefix(...) {...}
static int has_upper_dir_prefix(...) {...}
static char *last_dir_separator(...) {...}

#endif

> +static const char *relative_url(const char *url, const char *up_path)
> +{
> +   int is_relative = 0;
> +   size_t len;
> +   char *remoteurl = NULL;
> +   char *sep = "/";

'sep' only ever holds a single character, so why not declare it 'char'
rather than 'char *'? (And, adjust the format string of strbuf_addf(),
of course.)

> +   const char *out;
> +   [...]
> +   while (url) {
> +   if (has_upper_dir_prefix(url, &out)) {
> +   [...]
> +   if (rfind)
> +   *rfind = '\0';
> +   else {
> +   rfind = strrchr(remoteurl, ':');
> +   if (rfind) {
> +   *rfind = '\0';
> +   sep = ":";
> +   } else {
> +   [...]
> +   }
> +   }
> +   } else if (has_same_dir_prefix(url, &out))
> +   url = out;
> +   else
> +   break;
> +   }
> +   strbuf_reset(&sb);
> +   strbuf_addf(&sb, "%s%s%s", remoteurl, sep, url);
> +
> +   if (!has_same_dir_prefix(sb.buf, &out))
> +   out = sb.buf;
> +   out = xstrdup(out);
> +
> +   strbuf_reset(&sb);
> +   strbuf_addf(&sb, "%s%s", is_relative && up_path ? up_path : "", out);
> +
> +   free((char*)out);

Why declare 'out' const if you know you will be freeing it?

> +   return strbuf_detach(&sb, NULL);
> +}
> +
> +static int resolve_relative_url(int argc, const char **argv, const char 
> *prefix)
> +{
> +   if (argc == 2)
> +   printf("%s\n", relative_url(argv[1], NULL));
> +   else if (argc == 3)
> +   printf("%s\n", relative_url(argv[1], argv[2]));
> +   else
> +   die("BUG: resolve_relative_url only accepts one or two 
> arguments");
> +   return 0;
> +}
>
>  struct module_list {
> const struct cache_entry **entries;
> @@ -264,6 +414,7 @@ st