Re: Globbing for ignored branches?

2014-01-25 Thread Markus Trippelsdorf
On 2014.01.24 at 20:34 -0500, Jeff King wrote:
 On Fri, Jan 24, 2014 at 01:08:42PM -0800, Junio C Hamano wrote:
 
  Not really.  You do not have to view it as 'not refs/heads/foo' is
  affecting the previous '+refs/heads/*:refs/remotes/origin/*'.
  
  You can think of two refspecs refs/heads/foo refs/heads/bar are
  both affecting the end result; so far we only had a single way for
  multiple refspecs to affect the end result and that was a union.
  Introducing subtract as another mode of combining is not too bad,
  I would think, at the conceptual level.
 
  I tend to agree that refs/heads/foo: is being too cute and may be
  confusing, at least if it will be the only way to express this in
  the end-user-facing UI.  Even some people were confused enough on a
  very sensible push nothing to ref means deletion to make us add
  another explicit way, push --delete, to ask for the same thing.
 
 Agreed. I went with ^refs/heads/master in the patch below, but I am
 open to other suggestions.

Many thanks for the patch. It seems to work as advertised, but only if
the negative refspec appears on a separate line. For example:

[remote origin]
url = git://gcc.gnu.org/git/gcc.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = ^refs/remotes/hjl

works fine, but:

[remote origin]
url = git://gcc.gnu.org/git/gcc.git
fetch = +refs/heads/*:refs/remotes/origin/* ^refs/remotes/hjl 

doesn't. (I think this happens because bad_ref_char in refs.c checks for '^'.)

-- 
Markus
--
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: Globbing for ignored branches?

2014-01-25 Thread Markus Trippelsdorf
On 2014.01.25 at 15:15 +0100, Markus Trippelsdorf wrote:
 On 2014.01.24 at 20:34 -0500, Jeff King wrote:
  On Fri, Jan 24, 2014 at 01:08:42PM -0800, Junio C Hamano wrote:
  
   Not really.  You do not have to view it as 'not refs/heads/foo' is
   affecting the previous '+refs/heads/*:refs/remotes/origin/*'.
   
   You can think of two refspecs refs/heads/foo refs/heads/bar are
   both affecting the end result; so far we only had a single way for
   multiple refspecs to affect the end result and that was a union.
   Introducing subtract as another mode of combining is not too bad,
   I would think, at the conceptual level.
  
   I tend to agree that refs/heads/foo: is being too cute and may be
   confusing, at least if it will be the only way to express this in
   the end-user-facing UI.  Even some people were confused enough on a
   very sensible push nothing to ref means deletion to make us add
   another explicit way, push --delete, to ask for the same thing.
  
  Agreed. I went with ^refs/heads/master in the patch below, but I am
  open to other suggestions.
 
 Many thanks for the patch. It seems to work as advertised, but only if
 the negative refspec appears on a separate line. For example:

I've posted a wrong negative refspec. Sorry. Correction below.

 [remote origin]
 url = git://gcc.gnu.org/git/gcc.git
 fetch = +refs/heads/*:refs/remotes/origin/*
 fetch = ^refs/remotes/hjl
  fetch = ^refs/remotes/origin/hjl

 works fine, but:
 
 [remote origin]
 url = git://gcc.gnu.org/git/gcc.git
 fetch = +refs/heads/*:refs/remotes/origin/* ^refs/remotes/hjl 
  fetch = +refs/heads/*:refs/remotes/origin/* ^refs/remotes/origin/hjl

 doesn't. (I think this happens because bad_ref_char in refs.c checks for '^'.)

-- 
Markus
--
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: Globbing for ignored branches?

2014-01-25 Thread Jeff King
On Sat, Jan 25, 2014 at 03:15:42PM +0100, Markus Trippelsdorf wrote:

 Many thanks for the patch. It seems to work as advertised, but only if
 the negative refspec appears on a separate line. For example:
 
 [remote origin]
 url = git://gcc.gnu.org/git/gcc.git
 fetch = +refs/heads/*:refs/remotes/origin/*
 fetch = ^refs/remotes/hjl
 
 works fine, but:
 
 [remote origin]
 url = git://gcc.gnu.org/git/gcc.git
 fetch = +refs/heads/*:refs/remotes/origin/* ^refs/remotes/hjl 

That does not have anything to do with the negative refspec. The config
format is one refspec per fetch key, but you may have as many keys as
you like. Doing:

  [remote origin]
  fetch = refs/heads/a:refs/heads/a refs/heads/b:refs/heads/b

is similarly wrong. You need to do:

  [remote origin]
  fetch = refs/heads/a:refs/heads/a
  fetch = refs/heads/b:refs/heads/b

instead.  I believe that since space is forbidden in refnames, it should
also be forbidden in refspecs, which means that we could interpret the
first one as you expected without losing backwards compatibility. But I
do not think there is any real advantage to doing so, aside from being
more forgiving. I suspect the documentation in that area could be
improved, though.

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


Globbing for ignored branches?

2014-01-24 Thread Markus Trippelsdorf
I would like to ignore branches that match a certain pattern, e.g.:

markus@x4 gcc % git branch -a
  gcc-4.8
* master
  remotes/origin/HEAD - origin/master
  remotes/origin/aldyh/cilk-in-gomp
...
  remotes/origin/hjl/arch
  remotes/origin/hjl/asan
...
  remotes/origin/hjl/x86/m16
  remotes/origin/ifunc
  remotes/origin/jason/4.6-cxx0x
  remotes/origin/jason/alias-decl
  remotes/origin/jason/comdat-debug
  remotes/origin/lw-ipo
  remotes/origin/master
...

Is it possible to ignore all branches that match hjl?

-- 
Markus
--
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: Globbing for ignored branches?

2014-01-24 Thread Jim Garrison
 -Original Message-
 Behalf Of Markus Trippelsdorf
 Sent: Friday, January 24, 2014 1:01 AM
 Subject: Globbing for ignored branches?
 
 I would like to ignore branches that match a certain pattern, e.g.:
[snip]
 
 Is it possible to ignore all branches that match hjl?
 

If you mean ignore them when you do git branch -a, then

git branch -a |grep -v hjl

If you mean ignore in some other scenario you need to be more specific about 
what you want.

--
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: Globbing for ignored branches?

2014-01-24 Thread Markus Trippelsdorf
On 2014.01.24 at 18:07 +0100, Markus Trippelsdorf wrote:
 On 2014.01.24 at 16:37 +, Jim Garrison wrote:
   -Original Message-
   Behalf Of Markus Trippelsdorf
   Sent: Friday, January 24, 2014 1:01 AM
   Subject: Globbing for ignored branches?
   
   I would like to ignore branches that match a certain pattern, e.g.:
  [snip]
   
   Is it possible to ignore all branches that match hjl?
   
  
  If you mean ignore them when you do git branch -a, then
  
  git branch -a |grep -v hjl
  
  If you mean ignore in some other scenario you need to be more
  specific about what you want.
 
 I want to them when I run git pull.
   ignore
-- 
Markus
--
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: Globbing for ignored branches?

2014-01-24 Thread Markus Trippelsdorf
On 2014.01.24 at 16:37 +, Jim Garrison wrote:
  -Original Message-
  Behalf Of Markus Trippelsdorf
  Sent: Friday, January 24, 2014 1:01 AM
  Subject: Globbing for ignored branches?
  
  I would like to ignore branches that match a certain pattern, e.g.:
 [snip]
  
  Is it possible to ignore all branches that match hjl?
  
 
 If you mean ignore them when you do git branch -a, then
 
 git branch -a |grep -v hjl
 
 If you mean ignore in some other scenario you need to be more
 specific about what you want.

I want to them when I run git pull.

-- 
Markus
--
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: Globbing for ignored branches?

2014-01-24 Thread Jeff King
On Fri, Jan 24, 2014 at 06:09:09PM +0100, Markus Trippelsdorf wrote:

   If you mean ignore in some other scenario you need to be more
   specific about what you want.
  
  I want to them when I run git pull.
ignore

I assume you mean that you do not want to fetch them at all, not that
you want to avoid merging them. The set of branches that git fetches is
configured by the fetch refspec in your config file. It usually looks
like this:

  $ git config remote.origin.fetch
  +refs/heads/*:refs/remotes/origin/*

But you can specify a specific list of branches you want to fetch
instead:

  $ git config --unset remote.origin.fetch
  $ for i in master other-branch; do
  git config --add remote.origin.fetch \
   +refs/heads/$i:refs/remotes/origin/$i
done

However, you do have to specify each branch individually. You probably
want to say all branches except X, and you cannot currently specify
a negative refspec like that.

-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: Globbing for ignored branches?

2014-01-24 Thread Markus Trippelsdorf
On 2014.01.24 at 13:23 -0500, Jeff King wrote:
 On Fri, Jan 24, 2014 at 06:09:09PM +0100, Markus Trippelsdorf wrote:
 
If you mean ignore in some other scenario you need to be more
specific about what you want.
   
   I want to them when I run git pull.
 ignore
 
 I assume you mean that you do not want to fetch them at all, not that
 you want to avoid merging them. The set of branches that git fetches is
 configured by the fetch refspec in your config file. It usually looks
 like this:
 
   $ git config remote.origin.fetch
   +refs/heads/*:refs/remotes/origin/*
 
 But you can specify a specific list of branches you want to fetch
 instead:
 
   $ git config --unset remote.origin.fetch
   $ for i in master other-branch; do
   git config --add remote.origin.fetch \
+refs/heads/$i:refs/remotes/origin/$i
 done
 
 However, you do have to specify each branch individually. You probably
 want to say all branches except X, and you cannot currently specify
 a negative refspec like that.

Thanks.
Yes, that was the question I wanted to ask (, sorry for not formulating
it more clearly). 
Is this negative refspec for branches a feature that is planned for
the future?

-- 
Markus
--
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: Globbing for ignored branches?

2014-01-24 Thread Jeff King
On Fri, Jan 24, 2014 at 07:32:22PM +0100, Markus Trippelsdorf wrote:

  However, you do have to specify each branch individually. You probably
  want to say all branches except X, and you cannot currently specify
  a negative refspec like that.
 
 Yes, that was the question I wanted to ask (, sorry for not formulating
 it more clearly). 
 Is this negative refspec for branches a feature that is planned for
 the future?

It is something that has been talked about before, but I do not think
anybody is actively working on. It would probably not be too hard a
feature if you are interested in getting your feet wet in git
development. :)

-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: Globbing for ignored branches?

2014-01-24 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 On Fri, Jan 24, 2014 at 07:32:22PM +0100, Markus Trippelsdorf wrote:

  However, you do have to specify each branch individually. You probably
  want to say all branches except X, and you cannot currently specify
  a negative refspec like that.
 
 Yes, that was the question I wanted to ask (, sorry for not formulating
 it more clearly). 
 Is this negative refspec for branches a feature that is planned for
 the future?

 It is something that has been talked about before, but I do not think
 anybody is actively working on. It would probably not be too hard a
 feature if you are interested in getting your feet wet in git
 development. :)

The end result might be not so hard in the mechanical sense, but
designing the interface would be hard.  I do not offhand think of a
good way to do this.
--
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: Globbing for ignored branches?

2014-01-24 Thread Markus Trippelsdorf
On 2014.01.24 at 12:00 -0800, Junio C Hamano wrote:
 Jeff King p...@peff.net writes:
 
  On Fri, Jan 24, 2014 at 07:32:22PM +0100, Markus Trippelsdorf wrote:
 
   However, you do have to specify each branch individually. You probably
   want to say all branches except X, and you cannot currently specify
   a negative refspec like that.
  
  Yes, that was the question I wanted to ask (, sorry for not formulating
  it more clearly). 
  Is this negative refspec for branches a feature that is planned for
  the future?
 
  It is something that has been talked about before, but I do not think
  anybody is actively working on. It would probably not be too hard a
  feature if you are interested in getting your feet wet in git
  development. :)
 
 The end result might be not so hard in the mechanical sense, but
 designing the interface would be hard.  I do not offhand think of a
 good way to do this.

I don't know if the in-tree regex engine supports negative lookaheads.
If it does, then something like the following should work (to use my
hjl example):

^(.(?!hjl))*

-- 
Markus
--
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: Globbing for ignored branches?

2014-01-24 Thread Junio C Hamano
Markus Trippelsdorf mar...@trippelsdorf.de writes:

 On 2014.01.24 at 12:00 -0800, Junio C Hamano wrote:
 Jeff King p...@peff.net writes:
 
  On Fri, Jan 24, 2014 at 07:32:22PM +0100, Markus Trippelsdorf wrote:
 
   However, you do have to specify each branch individually. You probably
   want to say all branches except X, and you cannot currently specify
   a negative refspec like that.
  
  Yes, that was the question I wanted to ask (, sorry for not formulating
  it more clearly). 
  Is this negative refspec for branches a feature that is planned for
  the future?
 
  It is something that has been talked about before, but I do not think
  anybody is actively working on. It would probably not be too hard a
  feature if you are interested in getting your feet wet in git
  development. :)
 
 The end result might be not so hard in the mechanical sense, but
 designing the interface would be hard.  I do not offhand think of a
 good way to do this.

 I don't know if the in-tree regex engine supports negative lookaheads.
 If it does, then something like the following should work (to use my
 hjl example):

 ^(.(?!hjl))*

refspec wildcards are *NOT* regular expressions.
--
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: Globbing for ignored branches?

2014-01-24 Thread Jeff King
On Fri, Jan 24, 2014 at 12:00:16PM -0800, Junio C Hamano wrote:

 Jeff King p...@peff.net writes:
 
  On Fri, Jan 24, 2014 at 07:32:22PM +0100, Markus Trippelsdorf wrote:
 
   However, you do have to specify each branch individually. You probably
   want to say all branches except X, and you cannot currently specify
   a negative refspec like that.
 [...]
 The end result might be not so hard in the mechanical sense, but
 designing the interface would be hard.  I do not offhand think of a
 good way to do this.

I had imagined a not token at the front of the refspec, like:

  git fetch origin +refs/heads/*:refs/remotes/origin/* ^refs/heads/foo

In this case, a colon in the refspec would be an error. An alternative
would be:

  git fetch origin +refs/heads/*:refs/remotes/origin/* refs/heads/foo:

I.e., to say put foo to nowhere. But generally refspecs do not affect
each other. So refs/heads/foo:refs/heads/bar would generally work _in
addition_ to the other refspec. Making the null destination work
differently might be confusing.

I dunno. I have not thought very hard on the topic, so maybe there are
some subtle cases I am missing.

-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: Globbing for ignored branches?

2014-01-24 Thread Markus Trippelsdorf
On 2014.01.24 at 12:44 -0800, Junio C Hamano wrote:
 Markus Trippelsdorf mar...@trippelsdorf.de writes:
 
  On 2014.01.24 at 12:00 -0800, Junio C Hamano wrote:
  Jeff King p...@peff.net writes:
  
   On Fri, Jan 24, 2014 at 07:32:22PM +0100, Markus Trippelsdorf wrote:
  
However, you do have to specify each branch individually. You probably
want to say all branches except X, and you cannot currently specify
a negative refspec like that.
   
   Yes, that was the question I wanted to ask (, sorry for not formulating
   it more clearly). 
   Is this negative refspec for branches a feature that is planned for
   the future?
  
   It is something that has been talked about before, but I do not think
   anybody is actively working on. It would probably not be too hard a
   feature if you are interested in getting your feet wet in git
   development. :)
  
  The end result might be not so hard in the mechanical sense, but
  designing the interface would be hard.  I do not offhand think of a
  good way to do this.
 
  I don't know if the in-tree regex engine supports negative lookaheads.
  If it does, then something like the following should work (to use my
  hjl example):
 
  ^(.(?!hjl))*
 
 refspec wildcards are *NOT* regular expressions.

Yes, but that's the point. If they were, the negative refspec
interface issue would be solved.

-- 
Markus
--
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: Globbing for ignored branches?

2014-01-24 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 I had imagined a not token at the front of the refspec, like:

   git fetch origin +refs/heads/*:refs/remotes/origin/* ^refs/heads/foo

 In this case, a colon in the refspec would be an error. An alternative
 would be:

   git fetch origin +refs/heads/*:refs/remotes/origin/* refs/heads/foo:

 I.e., to say put foo to nowhere. But generally refspecs do not affect
 each other.

Not really.  You do not have to view it as 'not refs/heads/foo' is
affecting the previous '+refs/heads/*:refs/remotes/origin/*'.

You can think of two refspecs refs/heads/foo refs/heads/bar are
both affecting the end result; so far we only had a single way for
multiple refspecs to affect the end result and that was a union.
Introducing subtract as another mode of combining is not too bad,
I would think, at the conceptual level.

 ... Making the null destination work
 differently might be confusing.

I tend to agree that refs/heads/foo: is being too cute and may be
confusing, at least if it will be the only way to express this in
the end-user-facing UI.  Even some people were confused enough on a
very sensible push nothing to ref means deletion to make us add
another explicit way, push --delete, to ask for the same thing.
--
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: Globbing for ignored branches?

2014-01-24 Thread Jeff King
On Fri, Jan 24, 2014 at 01:08:42PM -0800, Junio C Hamano wrote:

 Not really.  You do not have to view it as 'not refs/heads/foo' is
 affecting the previous '+refs/heads/*:refs/remotes/origin/*'.
 
 You can think of two refspecs refs/heads/foo refs/heads/bar are
 both affecting the end result; so far we only had a single way for
 multiple refspecs to affect the end result and that was a union.
 Introducing subtract as another mode of combining is not too bad,
 I would think, at the conceptual level.

OK, I buy that line of reasoning. I assume that ordering should not
matter (that is, we would apply all positive refspecs, and then subtract
all negative refspecs).

I took a quick look at the refspec code, and how bad it would be to
implement this feature. It's rather a bit of a mess. It looks like there
are three separate code paths to apply refspecs:

  - fetch uses get_ref_map, which calls get_fetch_map for each refspec;
each refspec than expands into 0, 1, or multiple refs (if it's a
pattern). You can mention a ref multiple times on the LHS of a
refspec, and it may be fetched multiple times. After we have the
whole list, we detect duplicate destinations, and either drop the
duplicates (if all sources are the same) or complain (if there are
different sources).

  - push uses match_push_refs, which calls get_ref_match for each ref
(not refspec). So the loop is inside-out from fetch, and it looks
like we do weird things with multiple matches. We seem to handle
multiple explicit matches like:

  $ git push --dry-run tmp master:foo master:bar
  To tmp
   * [new branch]  master - foo
   * [new branch]  master - bar

but we don't seem to do the same for pattern matches:

  $ git push --dry-run tmp refs/heads/*:refs/foo/* \
   refs/heads/*:refs/bar/*
  To tmp
   * [new branch]  master - refs/foo/master

we just take the first match, even though the two did not conflict.
I doubt this comes up that much, but I do not see any reason this
should not be doing the same as fetch: apply all refspecs to come up
with a complete list, then cull duplicates.

  - @{upstream} uses apply_refspecs to convert a single name. This is
also used by transport-helper's fetch_with_import and
push_with_import. Which makes me think they do not handle
overlapping refspecs at all, unlike the builtin counterparts.

There is also query_refspecs, which underlies apply_refspecs. I'm
not even sure I understand all of the uses there.

The patch below implements negative refspecs for fetch, but does nothing
for push and apply_refspecs (in fact, it probably makes them worse,
because they've learned to parse negative refspecs, but not handle them
properly).

The helpers in the patch could probably be used to build support for the
other code paths, but it really seems like there could stand to be some
refactoring. I'm not sure if I have the time/stomach for it at the
moment. But I'll post this here anyway in case somebody else is
interested.

 I tend to agree that refs/heads/foo: is being too cute and may be
 confusing, at least if it will be the only way to express this in
 the end-user-facing UI.  Even some people were confused enough on a
 very sensible push nothing to ref means deletion to make us add
 another explicit way, push --delete, to ask for the same thing.

Agreed. I went with ^refs/heads/master in the patch below, but I am
open to other suggestions.

---
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 025bc3e..47f25e9 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -363,6 +363,8 @@ static struct ref *get_ref_map(struct transport *transport,
tail = rm-next;
}
 
+   ref_map = apply_negative_refspecs(ref_map, refspecs, refspec_count);
+
return ref_remove_duplicates(ref_map);
 }
 
diff --git a/remote.c b/remote.c
index a89efab..b7b20de 100644
--- a/remote.c
+++ b/remote.c
@@ -16,6 +16,7 @@ static struct refspec s_tag_refspec = {
1,
0,
0,
+   0,
refs/tags/*,
refs/tags/*
 };
@@ -533,8 +534,14 @@ static struct refspec *parse_refspec_internal(int 
nr_refspec, const char **refsp
rs[i].force = 1;
lhs++;
}
+   else if (*lhs == '^') {
+   rs[i].negative = 1;
+   lhs++;
+   }
 
rhs = strrchr(lhs, ':');
+   if (rs[i].negative  rhs)
+   goto invalid;
 
/*
 * Before going on, special case : (or +:) as a refspec
@@ -1663,6 +1670,9 @@ int get_fetch_map(const struct ref *remote_refs,
 {
struct ref *ref_map, **rmp;
 
+   if (refspec-negative)
+   return 0;
+
if (refspec-pattern) {
ref_map = get_expanded_map(remote_refs, refspec);
} else {
@@ -1705,6 +1715,48 @@ int