Re: [PATCH v6 1/3] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL

2016-05-16 Thread Eric Sunshine
On Thu, May 12, 2016 at 1:32 AM, Pranit Bauva  wrote:
> `--next-all` is meant to be used as a subcommand to support multiple
> "operation mode" though the current implementation does not contain any
> other subcommand along side with `--next-all` but further commits will
> include some more subcommands.
>
> Signed-off-by: Pranit Bauva 
> ---
> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
> @@ -23,9 +23,14 @@ int cmd_bisect__helper(int argc, const char **argv, const 
> char *prefix)
> -   if (!next_all)
> +   if (!cmdmode)
> usage_with_options(git_bisect_helper_usage, options);
>
> -   /* next-all */
> -   return bisect_next_all(prefix, no_checkout);
> +   switch (cmdmode) {
> +   case NEXT_ALL:
> +   return bisect_next_all(prefix, no_checkout);
> +   default:
> +   die("BUG: unknown subcommand '%d'", cmdmode);
> +   }
> +   return 0;

What happens if you remove this useless 'return 0'? Does the (or some)
compiler incorrectly complain about it falling off the end of the
function without returning a value?

>  }
--
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 v6 3/3] bisect--helper: `write_terms` shell function in C

2016-05-16 Thread Eric Sunshine
On Thu, May 12, 2016 at 1:32 AM, Pranit Bauva  wrote:
> Reimplement the `write_terms` shell function in C and add a `write-terms`
> subcommand to `git bisect--helper` to call it from git-bisect.sh . Also
> remove the subcommand `--check-term-format` as it can now be called from
> inside the function write_terms() C implementation.
>
> Using `--write-terms` subcommand is a temporary measure to port shell
> function to C so as to use the existing test suite. As more functions
> are ported, this subcommand will be retired and will be called by some
> other method.
>
> Signed-off-by: Pranit Bauva 
> ---
> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
> @@ -56,18 +56,41 @@ static int check_term_format(const char *term, const char 
> *orig_term)
> +int write_terms(const char *bad, const char *good)

s/^/static/

> +{
> +   struct strbuf content = STRBUF_INIT;
> +   FILE *fp;
> +   int res;
> +
> +   if (!strcmp(bad, good))
> +   return error(_("please use two different terms"));
> +
> +   if (check_term_format(bad, "bad") || check_term_format(good, "good"))
> +   return -1;
> +
> +   strbuf_addf(&content, "%s\n%s\n", bad, good);

What's the point of the strbuf when you could more easily emit this
same content directly to the file via:

fprintf(fp, "%s\n%s\n", bad, good);

> +   fp = fopen(".git/BISECT_TERMS", "w");

Hardcoding ".git/" is wrong for a variety of reasons: It won't be
correct with linked worktrees, or when GIT_DIR is pointing elsewhere,
or when ".git" is a symbolic link, etc. Check out the get_git_dir(),
get_git_common_dir(), etc. functions in cache.h instead.

> +   if (!fp){

Style: space before '{'

> +   strbuf_release(&content);
> +   die_errno(_("could not open the file to read terms"));

"read terms"? I thought this was writing.

Is dying here correct? I thought we established previously that you
should be reporting failure via normal -1 return value rather than
dying. Indeed, you're doing so below when strbuf_write() fails.

> +   }
> +   res = strbuf_write(&content, fp);
> +   fclose(fp);
> +   strbuf_release(&content);
> +   return (res < 0) ? -1 : 0;
> +}
>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)

Style: insert blank line between functions
--
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] bisect--helper: `bisect_log` shell function in C

2016-05-16 Thread Eric Sunshine
On Fri, May 13, 2016 at 4:02 PM, Pranit Bauva  wrote:
> bisect--helper: `bisect_log` shell function in C

Do you need to insert "rewrite" or "reimplement" in the subject?

> Reimplement the `bisect_log` shell function in C and add a
> `--bisect-log` subcommand to `git bisect--helper` to call it from
> git-bisect.sh .
>
> Using `--bisect-log` subcommand is a temporary measure to port shell
> function to C so as to use the existing test suite. As more functions
> are ported, this subcommand will be retired and will be called by some
> other method.
>
> Signed-off-by: Pranit Bauva 
> ---
> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
> @@ -79,11 +80,26 @@ int write_terms(const char *bad, const char *good)
> +int bisect_log(void)

s/^/static/

> +{
> +   struct strbuf buf = STRBUF_INIT;
> +
> +   if (strbuf_read_file(&buf, ".git/BISECT_LOG", 256) < 0)

As mentioned in my review of the "write-terms" rewrite, hardcoding
".git/" here is wrong for a variety of reasons. See get_git_dir(),
get_git_common_dir(), etc. in cache.h instead.

> +   return error(_("We are not bisecting."));
> +
> +   printf("%s", buf.buf);
> +   strbuf_release(&buf);
> +
> +   return 0;
> +}
> +
>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
>  {
> @@ -109,6 +127,8 @@ int cmd_bisect__helper(int argc, const char **argv, const 
> char *prefix)
> if (argc != 2)
> die(_("--write-terms requires two arguments"));
> return write_terms(argv[0], argv[1]);
> +   case BISECT_LOG:

Shouldn't you be die()ing here with an appropriate error message if
argc is not 0?

> +   return bisect_log();
> default:
> die("BUG: unknown subcommand '%d'", cmdmode);
> }
--
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 2/2] bisect--helper: `bisect_voc` shell function in C

2016-05-16 Thread Matthieu Moy
Pranit Bauva  writes:

> +int bisect_voc(const char *term)
> +{
> + if (!strcmp(term, "bad"))
> + printf("bad|new\n");
> + if (!strcmp(term, "good"))
> + printf("good|old\n");

If you meant to use this as a helper command, then the implementation is
right, but you're not doing that.

If you write the function because one day you'll be calling it from C,
then:

1) First, I'd wait for this "one day" to happen. In general, write code
   when you need it, don't write it ahead of time. Currently, you have
   dead and untested code (I know, *you* have tested it, but it's still
   "untested" as far as git.git is concerned). Dead code may bother
   people reading the code (one would not understand why it's there),
   and untested code means it may break later without anyone noticing.

2) Second, you'd need to return the string, not print it. You'll
   typically use it like this:

 printf(_("You need to give me at least one %s and one %s"),
bisect_voc(BISECT_BAD), bisect_voc(BISECT_GOOD));

   which gives one more argument for 1): once you have a use-case, you
   can design the API properly, and not blindly guess that you're going
   to need printf. Actually, writting these 2 example lines, I also
   noticed that the parameters could/should be an enum type rather than
   a string, it makes the code both more efficient and clearer.

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


Ensimag students contribution

2016-05-16 Thread Antoine Queru
Hello everyone,

 We are a team of 4 students from Ensimag (french computer science engineering 
school) tutored by Matthieu Moy, doing a full-time Git project, planning to 
work on few features during the next month.

We would like to start with microproject first,  "Add more builtin patterns for 
userdiff" and "Make upload-pack and receive-pack use the parse-options api" as 
a warm up. Then, we would like to work on features from the SmallProjectsIdeas 
Page on the wiki. We don't know yet what we can implement though, we will 
choose after contributing on our first project, to have a better understanding 
on the project as a whole.

If you have any suggestion for us, please feel free to warn us.

Best regards,

Beutin François, Duclot William
Queru Antoine, Rabourg simon
--
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 push --quiet option does not seem to work

2016-05-16 Thread Chris B
PS H:\test-ps\myrepo> "hi" >> whatever

PS H:\test-ps\myrepo> git add .

PS H:\test-ps\myrepo> git commit -m 'boo'
[test1 3cde450] boo
 Committer: 
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly. Run the
following command and follow the instructions in your editor to edit
your configuration file:

git config --global --edit

After doing this, you may fix the identity used for this commit with:

git commit --amend --reset-author

 1 file changed, 0 insertions(+), 0 deletions(-)

PS H:\test-ps\myrepo> git push --quiet
git : remote:
At line:1 char:1
+ git push --quiet
+ ~~
+ CategoryInfo  : NotSpecified: (remote: :String) [],
RemoteException
+ FullyQualifiedErrorId : NativeCommandError

remote: Analyzing objects... (3/3) (119 ms)
remote: Storing packfile... done (113 ms)
remote: Storing index... done (29 ms)
--
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 v6 3/3] bisect--helper: `write_terms` shell function in C

2016-05-16 Thread Johannes Schindelin
Hi,

On Mon, 16 May 2016, Eric Sunshine wrote:

> On Thu, May 12, 2016 at 1:32 AM, Pranit Bauva  wrote:
> 
> > +   fp = fopen(".git/BISECT_TERMS", "w");
> 
> Hardcoding ".git/" is wrong for a variety of reasons: It won't be correct
> with linked worktrees, or when GIT_DIR is pointing elsewhere, or when ".git"
> is a symbolic link, etc. Check out the get_git_dir(), get_git_common_dir(),
> etc. functions in cache.h instead.

Maybe in this case, `git_path("BISECT_TERMS")` would be a good idea. Or even
better: follow the example of bisect.c and use
`GIT_PATH_FUNC(bisect_terms_path, "BISECT_TERMS")`.

> > +   strbuf_release(&content);
> > +   die_errno(_("could not open the file to read terms"));
> 
> "read terms"? I thought this was writing.
> 
> Is dying here correct? I thought we established previously that you
> should be reporting failure via normal -1 return value rather than
> dying. Indeed, you're doing so below when strbuf_write() fails.

The rule of thumb seems to be that die()ing is okay in builtin/*.c, but not
in *.c. So technically, it would be okay here, too. However, I think that
this code should be written with libification in mind, so I would also
prefer it to error() and return, to give the caller a chance to do other
things after an error occurred.

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: git push --quiet option does not seem to work

2016-05-16 Thread Johannes Schindelin
Hi Chris,

could you please quote just the parts of the mail you are replying to, and
*not* top-post? It would be appreciated.

On Mon, 16 May 2016, Chris B wrote:

> PS H:\test-ps\myrepo> git push --quiet
> git : remote:
> At line:1 char:1
> + git push --quiet
> + ~~
> + CategoryInfo  : NotSpecified: (remote: :String) [],
> RemoteException
> + FullyQualifiedErrorId : NativeCommandError
> 
> remote: Analyzing objects... (3/3) (119 ms)
> remote: Storing packfile... done (113 ms)
> remote: Storing index... done (29 ms)

So it actually works, eh?

Could you please verify that this is a PowerShell-only problem by
performing a similar push in Git CMD and in Git Bash?

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


mail-patch-series.sh, was Re: [PATCH v7 0/3] Add support for sending additional HTTP headers (part 2)

2016-05-16 Thread Johannes Schindelin
Hi Lars,

On Tue, 10 May 2016, Lars Schneider wrote:

> > On 09 May 2016, at 08:18, Johannes Schindelin
> >  wrote:
> > 
> > [...]
> > 
> > Published-As: 
> > https://github.com/dscho/git/releases/tag/extra-http-headers-v7
> > Interdiff vs v6:
> 
> Published-As and Interdiff are really neat. I assume you have some kind
> of script to create all this? If yes, are you willing to share it?

Thanks for prodding me. I had planned to clean up my script and make it
public for a long time already, as I think that submitting code to the Git
project is quite a little bit too tedious, even for old timers like me, in
particular when compared to the ease of opening Pull Requests a la GitHub.

So now I cleaned up my script a bit and published it here:

https://github.com/dscho/mail-patch-series

Ironically, I welcome Pull Requests for this script ;-)

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: git push --quiet option does not seem to work

2016-05-16 Thread Jeff King
On Mon, May 16, 2016 at 03:28:30PM +0200, Johannes Schindelin wrote:

> > PS H:\test-ps\myrepo> git push --quiet
> > git : remote:
> > At line:1 char:1
> > + git push --quiet
> > + ~~
> > + CategoryInfo  : NotSpecified: (remote: :String) [],
> > RemoteException
> > + FullyQualifiedErrorId : NativeCommandError
> > 
> > remote: Analyzing objects... (3/3) (119 ms)
> > remote: Storing packfile... done (113 ms)
> > remote: Storing index... done (29 ms)
> 
> So it actually works, eh?
> 
> Could you please verify that this is a PowerShell-only problem by
> performing a similar push in Git CMD and in Git Bash?

I don't know much about PowerShell, but presumably it is responsible for
the first few lines.

But there is something else going on, too, which is those "remote:"
lines. Those are being relayed from the server by the git client. I
don't think it would be correct for the client to suppress them, even
with "--quiet", because the client side has no idea if they are progress
junk or critical error messages.

The client _does_ pass along the "quiet" flag to the server via the git
protocol, so it should be the server's responsibility to drop progress
output when it is present. The server side here is clearly not stock
git, from the content of those progress messages (some googling shows it
looks like whatever visualstudio.com is running, but I don't know what
that is). So either the server implementation doesn't support the
"quiet" protocol extension, or it is ignoring it. It might be worth
filing a bug with them.

-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: git push --quiet option does not seem to work

2016-05-16 Thread Chris B
Once I included the whole email in my reply, but otherwise I deleted it all.

Anyway, it is not a Powershell thing. I tested on another repo on
GitHub and it worked as expected. So I guess indeed the problem lies
with Microsoft's implementation.
--
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 push --quiet option does not seem to work

2016-05-16 Thread Johannes Schindelin
Hi Chris,

On Mon, 16 May 2016, Chris B wrote:

> Once I included the whole email in my reply, but otherwise I deleted it
> all.

Both are bad practice. If you are considerate with the reader's time, this
consideration is typically reprocicated. So it is a good idea to save the
reader time by giving them the precise context they need.

> Anyway, it is not a Powershell thing. I tested on another repo on
> GitHub and it worked as expected. So I guess indeed the problem lies
> with Microsoft's implementation.

This is *really* unclear.

What "Microsoft's implementation"??? Do you refer to VSTS, or do you refer
to Git for Windows, or PowerShell?

Please. To make it really simple for everybody involved, try to repeat as
closely as possible the same push from PowerShell, Git CMD and Git Bash.
We want to compare oranges to oranges.

FWIW You can repeat the same push by force-pushing the previous state
between re-runs. E.g.

git push myremote HEAD^:my-branch
git push myremote my-branch

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: git push --quiet option does not seem to work

2016-05-16 Thread Jeff King
On Mon, May 16, 2016 at 05:04:34PM +0200, Johannes Schindelin wrote:

> > Anyway, it is not a Powershell thing. I tested on another repo on
> > GitHub and it worked as expected. So I guess indeed the problem lies
> > with Microsoft's implementation.
> 
> This is *really* unclear.
> 
> What "Microsoft's implementation"??? Do you refer to VSTS, or do you refer
> to Git for Windows, or PowerShell?
> 
> Please. To make it really simple for everybody involved, try to repeat as
> closely as possible the same push from PowerShell, Git CMD and Git Bash.
> We want to compare oranges to oranges.

I don't think there is much to debug there. According to

  
http://superuser.com/questions/213848/using-powershell-call-native-command-line-app-and-capture-stderr/462362#462362

and other sources, it looks like PowerShell is very picky about calling
programs which produce any output on stderr, and may in an error object.
So I think both Powershell and Git are working as advertised, it's just
that their behaviors are incompatible.

The "bug" is that the server is asking the client to write non-error
output to stderr, even though the client should have asked the server to
be quiet (though it would not hurt to check that it is doing so by
looking at the output of GIT_TRACE_PACKET).

-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 v6 3/3] bisect--helper: `write_terms` shell function in C

2016-05-16 Thread Eric Sunshine
On Mon, May 16, 2016 at 9:16 AM, Johannes Schindelin
 wrote:
> On Mon, 16 May 2016, Eric Sunshine wrote:
>> On Thu, May 12, 2016 at 1:32 AM, Pranit Bauva  wrote:
>> > +   fp = fopen(".git/BISECT_TERMS", "w");
>>
>> Hardcoding ".git/" is wrong for a variety of reasons: It won't be correct
>> with linked worktrees, or when GIT_DIR is pointing elsewhere, or when ".git"
>> is a symbolic link, etc. Check out the get_git_dir(), get_git_common_dir(),
>> etc. functions in cache.h instead.
>
> Maybe in this case, `git_path("BISECT_TERMS")` would be a good idea. Or even
> better: follow the example of bisect.c and use
> `GIT_PATH_FUNC(bisect_terms_path, "BISECT_TERMS")`.

Thanks for pointing this out. My review time is severely limited these
days so I didn't go the distance of re-studying and re-digesting which
function was the correct one to use.

>> > +   strbuf_release(&content);
>> > +   die_errno(_("could not open the file to read terms"));
>>
>> Is dying here correct? I thought we established previously that you
>> should be reporting failure via normal -1 return value rather than
>> dying. Indeed, you're doing so below when strbuf_write() fails.
>
> The rule of thumb seems to be that die()ing is okay in builtin/*.c, but not
> in *.c. So technically, it would be okay here, too. However, I think that
> this code should be written with libification in mind, so I would also
> prefer it to error() and return, to give the caller a chance to do other
> things after an error occurred.

Agreed. Specific to the "established previously" I wrote above, I was
referring to [1] from just a few days ago which explained why 'return
-1' was preferable to die() in a similar case that had an odd mix of
'return -1' and die() in the same function.

[1]: http://thread.gmane.org/gmane.comp.version-control.git/289476/focus=293556
--
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] Ignore dirty submodule states during stash

2016-05-16 Thread Vasily Titskiy
Hi Stefan,

On Sun, May 15, 2016 at 11:37:20PM -0700, Stefan Beller wrote:
> On Sun, May 15, 2016 at 7:07 PM, Vasily Titskiy  wrote:
> > Do not save states of submodules as stash should ignore it.
> 
> Can you explain why this is a good idea?
> (It is not obvious to me either way.)
Actually, submodules are already ignored by stash, but not fully (it was 
introduced in commit 6848d58).
Current behavior is counter-intuitive, for example (if one has a project with a 
submodule):
 $ cd sub1
 $ edit .. commit .. edit .. commit. Alternatively, just checkout some other 
commit
 $ cd .. # back to main project
 $ git stash save
   No local changes to save
 $ # so, stash declares there are no changes
 $ edit main.cpp
 $ # For example, I need to update my working tree to latest master
 $ git stash save # save local changes of 'main.cpp'...
 $ git pull --recurse-submodules && git submodule update --recursive # update 
to latest
 $ git stash pop # I expect to get stashed changes for 'main.cpp', but...
   warning: Failed to merge submodule sub1 (commits don't follow merge-base)
   Auto-merging sub1
   CONFLICT (submodule): Merge conflict in sub1

So, this is the issue. Instead of getting my local changes, I got a conflict 
(and stash is not 
poped out). The root cause is the 'stash' command does not know how to deal 
with submodules,
but currently it tries to save the state of submodules, and even tries to 
re-apply the state
(and it fails of course). The proposed solution fixes this behaviour.

All internal tests work fine with the change.


> 
> Do we need a test/documentation updates for this?
I don't think so, 'stash' have never claimed submodule support.

> 
> >
> > Signed-off-by: Vasily Titskiy 
> > ---
> >  git-stash.sh | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/git-stash.sh b/git-stash.sh
> > index c7c65e2..b500c44 100755
> > --- a/git-stash.sh
> > +++ b/git-stash.sh
> > @@ -116,7 +116,7 @@ create_stash () {
> > git read-tree --index-output="$TMPindex" -m $i_tree 
> > &&
> > GIT_INDEX_FILE="$TMPindex" &&
> > export GIT_INDEX_FILE &&
> > -   git diff --name-only -z HEAD -- >"$TMP-stagenames" 
> > &&
> > +   git diff --name-only --ignore-submodules -z HEAD -- 
> > >"$TMP-stagenames" &&
> > git update-index -z --add --remove --stdin 
> > <"$TMP-stagenames" &&
> > git write-tree &&
> > rm -f "$TMPindex"
> > --
> > 2.1.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
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 1/1] convert: ce_compare_data() checks for a sha1 of a path

2016-05-16 Thread tboegi
From: Torsten Bögershausen 

To compare a file in working tree with the index, convert_to_git() is used,
the the result is hashed and the hash value compared with ce->sha1.

Deep down would_convert_crlf_at_commit() is invoked, to check if CRLF
are converted or not: When a CRLF had been in the index before, CRLF in
the working tree are not converted.

While in a merge, a file name in the working tree has different blobs
in the index with different hash values.
Forwarding ce->sha1 from ce_compare_data() into crlf_to_git() makes sure
the would_convert_crlf_at_commit() looks at the appropriate blob.

Signed-off-by: Torsten Bögershausen 
---
 cache.h  |  1 +
 convert.c| 35 +--
 convert.h| 23 +++
 read-cache.c |  4 +++-
 sha1_file.c  | 17 +
 5 files changed, 57 insertions(+), 23 deletions(-)

diff --git a/cache.h b/cache.h
index 160f8e3..5b25462 100644
--- a/cache.h
+++ b/cache.h
@@ -604,6 +604,7 @@ extern int ie_modified(const struct index_state *, const 
struct cache_entry *, s
 
 #define HASH_WRITE_OBJECT 1
 #define HASH_FORMAT_CHECK 2
+#define HASH_CE_HAS_SHA1  4
 extern int index_fd(unsigned char *sha1, int fd, struct stat *st, enum 
object_type type, const char *path, unsigned flags);
 extern int index_path(unsigned char *sha1, const char *path, struct stat *st, 
unsigned flags);
 
diff --git a/convert.c b/convert.c
index f524b8d..dc86899 100644
--- a/convert.c
+++ b/convert.c
@@ -217,21 +217,25 @@ static void check_safe_crlf(const char *path, enum 
crlf_action crlf_action,
}
 }
 
-static int has_cr_in_index(const char *path)
+static int has_cr_in_index(const char *path, const unsigned char *sha1)
 {
unsigned long sz;
void *data;
-   int has_cr;
-
-   data = read_blob_data_from_cache(path, &sz);
-   if (!data)
-   return 0;
-   has_cr = memchr(data, '\r', sz) != NULL;
+   int has_cr = 0;
+   enum object_type type = OBJ_BLOB;
+   if (sha1)
+   data = read_sha1_file(sha1, &type, &sz);
+   else
+   data = read_blob_data_from_cache(path, &sz);
+
+   if (data)
+   has_cr = memchr(data, '\r', sz) != NULL;
free(data);
return has_cr;
 }
 
-static int crlf_to_git(const char *path, const char *src, size_t len,
+static int crlf_to_git(const char *path, const unsigned char *sha1,
+  const char *src, size_t len,
   struct strbuf *buf,
   enum crlf_action crlf_action, enum safe_crlf checksafe)
 {
@@ -260,7 +264,7 @@ static int crlf_to_git(const char *path, const char *src, 
size_t len,
 * If the file in the index has any CR in it, do not 
convert.
 * This is the new safer autocrlf handling.
 */
-   if (has_cr_in_index(path))
+   if (has_cr_in_index(path, sha1))
return 0;
}
}
@@ -852,8 +856,9 @@ const char *get_convert_attr_ascii(const char *path)
return "";
 }
 
-int convert_to_git(const char *path, const char *src, size_t len,
-   struct strbuf *dst, enum safe_crlf checksafe)
+int convert_to_git_ce_sha1(const char *path, const unsigned char *sha1,
+  const char *src, size_t len,
+  struct strbuf *dst, enum safe_crlf checksafe)
 {
int ret = 0;
const char *filter = NULL;
@@ -874,7 +879,7 @@ int convert_to_git(const char *path, const char *src, 
size_t len,
src = dst->buf;
len = dst->len;
}
-   ret |= crlf_to_git(path, src, len, dst, ca.crlf_action, checksafe);
+   ret |= crlf_to_git(path, sha1, src, len, dst, ca.crlf_action, 
checksafe);
if (ret && dst) {
src = dst->buf;
len = dst->len;
@@ -882,7 +887,9 @@ int convert_to_git(const char *path, const char *src, 
size_t len,
return ret | ident_to_git(path, src, len, dst, ca.ident);
 }
 
-void convert_to_git_filter_fd(const char *path, int fd, struct strbuf *dst,
+void convert_to_git_filter_fd(const char *path,
+ const unsigned char *sha1,
+ int fd, struct strbuf *dst,
  enum safe_crlf checksafe)
 {
struct conv_attrs ca;
@@ -894,7 +901,7 @@ void convert_to_git_filter_fd(const char *path, int fd, 
struct strbuf *dst,
if (!apply_filter(path, NULL, 0, fd, dst, ca.drv->clean))
die("%s: clean filter '%s' failed", path, ca.drv->name);
 
-   crlf_to_git(path, dst->buf, dst->len, dst, ca.crlf_action, checksafe);
+   crlf_to_git(path, sha1, dst->buf, dst->len, dst, ca.crlf_action, 
checksafe);
ident_to_git(path, dst->buf, dst->len, dst, ca.ident);
 }
 
diff --git a/convert.h b/convert.h
index ccf436b..1634d37 100644
--- a/convert.h
+++ b/convert.h
@@

[PATCH v3 0/1] CRLF-Handling: bug fix around ce_compare_data()

2016-05-16 Thread tboegi
From: Torsten Bögershausen 

Changes since v2:

- Only 1 patch, the t6038 needs to go as a separate "series"

has_cr_in_index() uses either
data = read_sha1_file(sha1, &type, &sz);
or
data = read_blob_data_from_cache(path, &sz);

(I like v2 better, since there is a single code to get a sha object
into memory, which later will be replaced by a streaming object)
But in any case, here is v3

Torsten Bögershausen (1):
  convert: ce_compare_data() checks for a sha1 of a path

 cache.h|  1 +
 convert.c  | 35 +--
 convert.h  | 23 +++
 read-cache.c   |  4 +++-
 sha1_file.c| 17 +

-- 
2.0.0.rc1.6318.g0c2c796

--
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] commit.c: use strchrnul() to scan for one line

2016-05-16 Thread Junio C Hamano
Johannes Schindelin  writes:

> On Sun, 15 May 2016, Junio C Hamano wrote:
>
>> diff --git a/commit.c b/commit.c
>> index 3f4f371..1f9ee8a 100644
>> --- a/commit.c
>> +++ b/commit.c
>> @@ -415,8 +415,7 @@ int find_commit_subject(const char *commit_buffer, const 
>> char **subject)
>>  p++;
>>  if (*p) {
>>  p += 2;
>> -for (eol = p; *eol && *eol != '\n'; eol++)
>> -; /* do nothing */
>> +eol = strchrnul(p, '\n');
>>  } else
>>  eol = p;
>
> ACK. This was my fault, when I introduced the code in 9509af68 (Make
> git-revert & git-cherry-pick a builtin, 2007-03-01). To be fair,
> strchrnul() was introduced only later, in 659c69c (Add strchrnul(),
> 2007-11-09).

Oh, there is no fault.

I was reading through attr.c to see how bad a work to revamp
attribute lookup would look like, found a hand-rolled strchrnul()
that predates the widespread use of the function, and looked for
similar patterns while I was updating it.  As there were many false
positives (i.e. "Yes, this loop is looking for the end of line, but
it does something else to the characters on the line while doing so,
so it cannot become strchrnul()") that I needed eyeballing in order
to reject and avoid incorrect conversion, it is very much appreciated
that you double-checked this one that I spotted.

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 v2 56/94] apply: move 'struct apply_state' to apply.h

2016-05-16 Thread Junio C Hamano
Eric Sunshine  writes:

> On Wed, May 11, 2016 at 9:17 AM, Christian Couder
>  wrote:
>> To libify `git apply` functionality we must make 'struct apply_state'
>> usable outside "builtin/apply.c".
>
> Why is this patch plopped right in the middle of a bunch of other
> patches which are making functions return -1 rather than die()ing?
> Seems out of place.

Two possible places that would make more sense are (1) when it is
introduced very early in the series, or (2) when it absorbed all the
file-scope-static global states in the middle of the series.  I think
either is fine.

That would be a good place to end the first batch of the topic.
Then the second batch would be "turn die() into error status that is
propagated upwards".
--
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


[no subject]

2016-05-16 Thread Nathan Wendt
Recently I have run into an issue with the git-completion.tcsh script
where an error would occur upon sourcing the file on login. The error
that would occur was:

__git_tcsh_completion_version: Subscript out of range.

In taking a look at the script, I noticed that when the script parses
the tcsh version that I am running it does not put the output into an
array. Thus, when it attempts to access subscript 2 of
__git_tcsh_completion_version it throws the above error. To correct
this, I changed

set __git_tcsh_completion_version =  ` \echo ${tcsh} | \sed 's/\./ /g'`

to

set __git_tcsh_completion_version =  `( \echo ${tcsh} | \sed 's/\./ /g' )`

and the script runs correctly. I could not find others having issues
with this in the forums so I am not sure if this is unique to my
system or not. Thought I would pass it along.

For reference, I am running tcsh 6.17.00 on RHEL 6.8

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 v3 0/1] CRLF-Handling: bug fix around ce_compare_data()

2016-05-16 Thread Junio C Hamano
tbo...@web.de writes:

> From: Torsten Bögershausen 
>
> Changes since v2:
>
> - Only 1 patch, the t6038 needs to go as a separate "series"
>
> has_cr_in_index() uses either
>   data = read_sha1_file(sha1, &type, &sz);
> or
>   data = read_blob_data_from_cache(path, &sz);
>
> (I like v2 better, since there is a single code to get a sha object
> into memory, which later will be replaced by a streaming object)

Wait a minute, please.  I only asked the reason why you did it that
way and mentioned that the end result seemed equivalent.  "The end
result seems equivalent" does not automatically mean "therefore you
must avoid changing the code."

If you still prefer the original code, and your preference is backed
by a solid reasoning, don't change the code to a less preferrable
version.  You may have to explain what you wrote in () above clearly
in an updated log message to save other readers from asking the same
question as I asked, though.

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


Re: [PATCH] attr.c: simplify macroexpand_one()

2016-05-16 Thread Stefan Beller
On Sun, May 15, 2016 at 9:41 PM, Junio C Hamano  wrote:
> On Sun, May 15, 2016 at 8:31 PM, Eric Sunshine  
> wrote:
>> On Sun, May 15, 2016 at 6:57 PM, Junio C Hamano  wrote:
>>> The double-loop wants to do an early return immediately when one
>>> matching macro is found.  Eliminate the extra variable 'a' used for
>>> that purpose and rewrite the "assign found itme to 'a' to make it
>>
>> What's "itme"?
>
> item.

The code looks good.

Thanks,
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] Ignore dirty submodule states during stash

2016-05-16 Thread Stefan Beller
On Mon, May 16, 2016 at 8:46 AM, Vasily Titskiy  wrote:
> Hi Stefan,
>
> On Sun, May 15, 2016 at 11:37:20PM -0700, Stefan Beller wrote:
>> On Sun, May 15, 2016 at 7:07 PM, Vasily Titskiy  wrote:
>> > Do not save states of submodules as stash should ignore it.
>>
>> Can you explain why this is a good idea?
>> (It is not obvious to me either way.)
> Actually, submodules are already ignored by stash, but not fully (it was 
> introduced in commit 6848d58).
> Current behavior is counter-intuitive, for example (if one has a project with 
> a submodule):
>  $ cd sub1
>  $ edit .. commit .. edit .. commit. Alternatively, just checkout some other 
> commit
>  $ cd .. # back to main project
>  $ git stash save
>No local changes to save
>  $ # so, stash declares there are no changes
>  $ edit main.cpp
>  $ # For example, I need to update my working tree to latest master
>  $ git stash save # save local changes of 'main.cpp'...
>  $ git pull --recurse-submodules && git submodule update --recursive # update 
> to latest
>  $ git stash pop # I expect to get stashed changes for 'main.cpp', but...
>warning: Failed to merge submodule sub1 (commits don't follow merge-base)
>Auto-merging sub1
>CONFLICT (submodule): Merge conflict in sub1
>
> So, this is the issue. Instead of getting my local changes, I got a conflict 
> (and stash is not
> poped out). The root cause is the 'stash' command does not know how to deal 
> with submodules,
> but currently it tries to save the state of submodules, and even tries to 
> re-apply the state
> (and it fails of course). The proposed solution fixes this behaviour.
>
> All internal tests work fine with the change.

I think you could take the example as above and make it into a test?
Showing that this change actually fixes a bug.

Looking for a good place, I would have expected t/t3906-stash-submodule.sh
would be a good place to put your code, but I am not sure how to
properly integrate that test there.

Maybe we can put the test in t3903 instead?

>
>
>>
>> Do we need a test/documentation updates for this?
> I don't think so, 'stash' have never claimed submodule support.

But it also never explicitly claimed it doesn't support it.

Maybe we want to squash in something like
(with better wording):

diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt
index 92df596..b2649eb 100644
--- a/Documentation/git-stash.txt
+++ b/Documentation/git-stash.txt
@@ -41,6 +41,8 @@ the usual reflog syntax (e.g. `stash@{0}` is the most recently
 created stash, `stash@{1}` is the one before it, `stash@{2.hours.ago}`
 is also possible).

+Stashing ignores submodule operations completely.
+
 OPTIONS
 ---


Thanks,
Stefan



>
>>
>> >
>> > Signed-off-by: Vasily Titskiy 
>> > ---
>> >  git-stash.sh | 2 +-
>> >  1 file changed, 1 insertion(+), 1 deletion(-)
>> >
>> > diff --git a/git-stash.sh b/git-stash.sh
>> > index c7c65e2..b500c44 100755
>> > --- a/git-stash.sh
>> > +++ b/git-stash.sh
>> > @@ -116,7 +116,7 @@ create_stash () {
>> > git read-tree --index-output="$TMPindex" -m 
>> > $i_tree &&
>> > GIT_INDEX_FILE="$TMPindex" &&
>> > export GIT_INDEX_FILE &&
>> > -   git diff --name-only -z HEAD -- >"$TMP-stagenames" 
>> > &&
>> > +   git diff --name-only --ignore-submodules -z HEAD 
>> > -- >"$TMP-stagenames" &&
>> > git update-index -z --add --remove --stdin 
>> > <"$TMP-stagenames" &&
>> > git write-tree &&
>> > rm -f "$TMPindex"
>> > --
>> > 2.1.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
--
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] Ignore dirty submodule states during stash

2016-05-16 Thread Johannes Schindelin
Hi Vasily,

On Mon, 16 May 2016, Vasily Titskiy wrote:

> On Sun, May 15, 2016 at 11:37:20PM -0700, Stefan Beller wrote:
> > On Sun, May 15, 2016 at 7:07 PM, Vasily Titskiy  wrote:
> > > Do not save states of submodules as stash should ignore it.
> > 
> > Can you explain why this is a good idea?
> > (It is not obvious to me either way.)
> Actually, submodules are already ignored by stash, but not fully (it was
> introduced in commit 6848d58).
> Current behavior is counter-intuitive, for example (if one has a project
> with a submodule):
>  [...]
> 
> So, this is the issue. Instead of getting my local changes, I got a
> conflict (and stash is not poped out). The root cause is the 'stash'
> command does not know how to deal with submodules, but currently it
> tries to save the state of submodules, and even tries to re-apply the
> state (and it fails of course). The proposed solution fixes this
> behaviour.

Please make it a habit to put such information into the commit message. I
have to admit that I was as puzzled as Stefan by the proposed patch. Such
problems, and tedious back-and-forth discussion, can be easily avoided by
providing additional background in the commit message. We even ask in our
Documentation/SubmittingPatches explicitly to do that:

> The body should provide a meaningful commit message, which:
>
>   . explains the problem the change tries to solve, iow, what is wrong
> with the current code without the change.
>
>   . justifies the way the change solves the problem, iow, why the
> result with the change is better.
>
>   . alternate solutions considered but discarded, if any.

BTW this is not something we ask to make contributors' lives harder. In
fact it helps everybody, including the contributors themselves. Just
imagine what kind of kick-ass commit message you would want to read in six
months when you stumble over your very own commit and want to know what
the heck it was about.

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 v6 3/3] bisect--helper: `write_terms` shell function in C

2016-05-16 Thread Johannes Schindelin
Hi Eric,

On Mon, 16 May 2016, Eric Sunshine wrote:

> On Mon, May 16, 2016 at 9:16 AM, Johannes Schindelin
>  wrote:
> > On Mon, 16 May 2016, Eric Sunshine wrote:
> >> On Thu, May 12, 2016 at 1:32 AM, Pranit Bauva  
> >> wrote:
> >> > +   fp = fopen(".git/BISECT_TERMS", "w");
> >>
> >> Hardcoding ".git/" is wrong for a variety of reasons: It won't be correct
> >> with linked worktrees, or when GIT_DIR is pointing elsewhere, or when 
> >> ".git"
> >> is a symbolic link, etc. Check out the get_git_dir(), get_git_common_dir(),
> >> etc. functions in cache.h instead.
> >
> > Maybe in this case, `git_path("BISECT_TERMS")` would be a good idea. Or even
> > better: follow the example of bisect.c and use
> > `GIT_PATH_FUNC(bisect_terms_path, "BISECT_TERMS")`.
> 
> Thanks for pointing this out. My review time is severely limited these
> days so I didn't go the distance of re-studying and re-digesting which
> function was the correct one to use.

I am constantly amazed how much you manage to review, and how helpful your
comments are. I am glad if I could contribute a little.

> >> > +   strbuf_release(&content);
> >> > +   die_errno(_("could not open the file to read terms"));
> >>
> >> Is dying here correct? I thought we established previously that you
> >> should be reporting failure via normal -1 return value rather than
> >> dying. Indeed, you're doing so below when strbuf_write() fails.
> >
> > The rule of thumb seems to be that die()ing is okay in builtin/*.c, but not
> > in *.c. So technically, it would be okay here, too. However, I think that
> > this code should be written with libification in mind, so I would also
> > prefer it to error() and return, to give the caller a chance to do other
> > things after an error occurred.
> 
> Agreed. Specific to the "established previously" I wrote above, I was
> referring to [1] from just a few days ago which explained why 'return
> -1' was preferable to die() in a similar case that had an odd mix of
> 'return -1' and die() in the same function.
> 
> [1]: 
> http://thread.gmane.org/gmane.comp.version-control.git/289476/focus=293556

Yes, this is an excellent link. Maybe we would want something like this,
too?

-- snipsnap --
(From: Eric Sunshine )
CodingGuidelines: mention that die() is for fatal errors only

Let's formalize the rule when to use die() and when to use error().

diff --git a/Documentation/CodingGuidelines
b/Documentation/CodingGuidelines
index 0ddd368..5d2d65f 100644
--- a/Documentation/CodingGuidelines
+++ b/Documentation/CodingGuidelines
@@ -333,6 +333,10 @@ For C programs:
 
  - When you come up with an API, document it.
 
+ - Use die() only to signal an exceptional conditions which should
+   abort the program. All other error conditions should instead
+   return e.g. using "return error(...)".
+
  - The first #include in C files, except in platform specific compat/
implementations, must be either "git-compat-util.h", "cache.h" or
"builtin.h".  You do not have to include more than one of these.

--
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 v6 3/3] bisect--helper: `write_terms` shell function in C

2016-05-16 Thread Eric Sunshine
On Mon, May 16, 2016 at 12:45 PM, Johannes Schindelin
 wrote:
> On Mon, 16 May 2016, Eric Sunshine wrote:
>> On Mon, May 16, 2016 at 9:16 AM, Johannes Schindelin
>>  wrote:
>> > On Mon, 16 May 2016, Eric Sunshine wrote:
>> Agreed. Specific to the "established previously" I wrote above, I was
>> referring to [1] from just a few days ago which explained why 'return
>> -1' was preferable to die() in a similar case that had an odd mix of
>> 'return -1' and die() in the same function.
>>
>> [1]: 
>> http://thread.gmane.org/gmane.comp.version-control.git/289476/focus=293556
>
> Yes, this is an excellent link. Maybe we would want something like this,
> too?
>
> -- snipsnap --
> diff --git a/Documentation/CodingGuidelines
> @@ -333,6 +333,10 @@ For C programs:
> + - Use die() only to signal an exceptional conditions which should
> +   abort the program. All other error conditions should instead
> +   return e.g. using "return error(...)".

Hmm, the bit you said earlier about "library" code vs. end-user code
would be important, too, I'd think. Also, I'd expect that this sort of
thing is implicitly understood by most programmers, and as this is
only the first time (in recent memory) that it has needed explanation
on the mailing list, I'm not sure that it deserves explicit mention in
CodingGuidelines (but perhaps I'm not a good judge of these things).
--
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 v5 0/2] bisect--helper: rewrite of check-term-format()

2016-05-16 Thread Christian Couder
On Mon, May 16, 2016 at 2:35 AM, Eric Sunshine  wrote:
> On Sun, May 8, 2016 at 9:34 AM, Pranit Bauva  wrote:
>> On Sun, May 8, 2016 at 11:53 AM, Pranit Bauva  wrote:
>>> On Sun, May 8, 2016 at 7:55 AM, Junio C Hamano  wrote:
 Pranit Bauva  writes:
> I completely missed your point and you want me to go the Eric Sunshine's 
> way?

 I am neutral.

 When I read your response to Eric's "top down" suggestion, I didn't
 quite get much more than "I started going this way, and I do not
 want to change to the other direction.", which was what I had the
 most trouble with.  If your justification for the approach to start
 from building a tiny bottom layer that will need to be dismantled
 soon and repeat that (which sounds somewhat wasteful) were more
 convincing, I may have felt differently.
>>>
>>> Sorry if it seemed that "I have done quite some work and I don't want
>>> to scrape it off and redo everything". This isn't a case for me. I
>>> think of this as just a small part in the process of learning and my
>>> efforts would be completely wasted as I can still reuse the methods I
>>
>> efforts would **not** be completely wasted
>>
>>> wrote. This is still open for a "philosophical" discussion. I am
>>> assuming 1e1ea69fa4e is how Eric is suggesting.
>
> Speaking of 1e1ea69 (pull: implement skeletal builtin pull,
> 2015-06-14), one of the (numerous) things Paul Tan did which impressed
> me was to formally measure test suite coverage of the commands he was
> converting to C, and then improve coverage where it was lacking. That
> approach increases confidence in the conversion far more than fallible
> human reviews do.
>
> Setting aside the top-down vs. bottom-up discussion, as a reviewer
> (and user) I'd be far more interested in seeing you spend a good
> initial chunk of your project emulating Paul's approach to measuring
> and improving test coverage (though I don't know how your GSoC mentors
> feel about that).

If we could test each `git bisect-helper` subcommand that has been
converted to C separately, then I think it would be quite easy and a
good idea. And maybe Paul's approach is really great and easy to use,
but I haven't followed his GSoC, so I cannot tell.

As we take the approach of testing the whole thing, which is made of a
number of different source files (shell code in git-bisect.sh, C code
in `git bisect-helper` subcommands and in bisect.{c,h}), I am worried
that Pranit would spend too much time initially not only to measure
test coverage but especially to find ways to improve it.

The good thing with converting code incrementally to C is that one
does not need to understand everything first. While if one wants to
increase test coverage initially, it might be needed to understand
many things.

What I started asking though is to take advantage of bugs that are
found, and were not covered by the test suite, to improve test
coverage.

Also starting to convert functions right away can make the student
feel productive early and in turn make everyone else happy to see some
progress.
--
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 5/5] pathspec: record labels

2016-05-16 Thread Stefan Beller
On Sat, May 14, 2016 at 12:23 PM, Junio C Hamano  wrote:
> Stefan Beller  writes:
>
>> Labels were originally designed to manage large amount of
>> submodules, the discussion steered this in a more general
>> direction, such that other files can be labeled as well.
>
> s/other files/any path/.
>
>> Labels are meant to describe arbitrary set of files, which
>> is not described via the tree layout.
>
> Let's avoid "are meant to", which is merely to give you an excuse to
> say "it was meant to ... but the implementation did not quite achieve
> that goal".
>
> The "label" attribute can be attached to paths, and the pathspec
> mechanism is extended via the new ":(label=X)pattern/to/match"

I wasn't sure about whether we want to have '=' or ':' as the separator
of "label" and its values. The prefix which is passed around uses
a colon instead of equal sign, so I thought consistency would be neat
there. But as that is only internal, we can be inconsistent to a new
public feature, so '=' seems better for the labeling system.

> syntax to filter paths so that it requires paths to not just
> match the given pattern but also have the specified labels
> attached for them to be chosen.
>
> or something?
>
>> +Attaching labels to path
>> +
>> +
>> +`label`
>> +^^
>> +By the value of this attribute you can specify a list of arbitrary strings
>> +to be attached to a path as labels. These labels can be used for
>> +easier paths matching using pathspecs (linkgit:gitglossary[1]).
>> +It is recommended to use only alphanumeric characters, dashes and
>> +underscores for the labels.
>
> Make this recomendation stronger to requirement.  It is always
> possible to loosen it later, but once we allow random things even
> with a warning, it gets impossible to take them back. Users will say
> "Even though we got a warning, it used to correctly filter; now Git
> is broken and my setup does not work."

I'll change the text here with s/recommended/required/ and error out
for that.

But still we do not enforce it early enough. Some crazy upstream may
add some labels which do not follow the requirements and then
tell downstream to run a command like `git foo "(label=!@#$)".
and then downstream curses at upstream as well as Git.

>
> s/habe/have/

done

>
>> + if (ATTR_TRUE(check.value))
>> + ret = 1; /* has all the labels */
>
> So this is "pretend that I have all the labels under the sun".
>
>> + else if (ATTR_FALSE(check.value))
>> + ret = 0; /* has no labels */
>
> I do not see a value in this.  What difference does it have compared
> to having a "label=" that explicitly says "I do not have one"?  What
> is your answer to an end-user question "When should I say 'label='
> and when should I say '!label'?"
>
> Just forbid it for now; we may find a better use for it later.

I don't think we want to die in that code as it is in the data already.
If we were to die in that case, you cannot query any path with
labels any more if asking for any kind of label.

>
>> + else if (ATTR_UNSET(check.value))
>> + /*
>> +  * If no label was specified this matches, otherwise
>> +  * there is a missing label.
>> +  */
>> + ret = (required_labels->nr > 0) ? 0 : 1;
>
> Hmm, I can see that this is making things more complicated to
> explain and understand, but I cannot see what the expected use case
> is.
>
> Unless there is any compelling use case, I'd say we should forbid it
> for now.

We need to allow the UNSET case, as otherwise you'd need to label
any path if using labels? In the next iteration I'll go with

if (ATTR_TRUE(check.value))
ret = 1; /* has all the labels */
else if (ATTR_FALSE(check.value))
die(_("Label attributes must not be unset"));
else if (ATTR_UNSET(check.value))
ret = 0; /* has no labels */
else {
...
>
>> + else {
>> + struct string_list_item *si;
>> + struct string_list attr_labels = STRING_LIST_INIT_DUP;
>> + string_list_split(&attr_labels, check.value, ',', -1);
>> + string_list_sort(&attr_labels);
>
> Filter out a non-compliant label values here, so that they are
> ignored from day one.  That way you would not have to deal with "I
> know I got the warning, but it used to work and you broke it" later.

So you're saying we should not die(...) but just ignore those labels?

>
>> + ret = 1;
>> + for_each_string_list_item(si, required_labels) {
>> + if (!string_list_has_string(&attr_labels, si->string)) 
>> {
>> + ret = 0;
>> + break;
>> + }
>> + }
>> + string_list_clear(&attr_labels, 0);
>> + }
>> +
>> + return ret;
>> +}
>
>> +static void validate_label_name(const char *label)
>> +{
>> + 

Re: [PATCH v2 52/94] builtin/apply: read_patch_file() return -1 instead of die()ing

2016-05-16 Thread Christian Couder
On Mon, May 16, 2016 at 3:56 AM, Eric Sunshine  wrote:
> On Wed, May 11, 2016 at 9:17 AM, Christian Couder
>  wrote:
>> To libify `git apply` functionality we have to signal errors to the
>> caller instead of die()ing. Let's do that by using error() instead
>> of die()ing in read_patch_file().
>>
>> Signed-off-by: Christian Couder 
>> ---
>> diff --git a/builtin/apply.c b/builtin/apply.c
>> @@ -445,10 +445,10 @@ static void say_patch_name(FILE *output, const char 
>> *fmt, struct patch *patch)
>> -static void read_patch_file(struct strbuf *sb, int fd)
>> +static int read_patch_file(struct strbuf *sb, int fd)
>>  {
>> if (strbuf_read(sb, fd, 0) < 0)
>> -   die_errno("git apply: failed to read");
>> +   return error("git apply: failed to read: %s", 
>> strerror(errno));
>
> When Duy's nd/error-errno series, which is in 'next', gets promoted to
> 'master', then this could become:
>
> return error_errno(...);

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


Re: [RFC PATCH 0/4] pathspec labels [WAS: submodule groups]

2016-05-16 Thread Stefan Beller
On Sun, May 15, 2016 at 3:06 AM, Duy Nguyen  wrote:
> Instead of putting everything in under the same attribute name
> "label", make one attribute per label? Would this work?
>
> *.[ch] c-group code-group
>
> And the pathspec magic name can be simply "attr", any git attribute
> can be used with it, e.g. :(attr:c-group)

So you want to be able to query something like:

git ls-files ":(crlf=auto)"

as well?
--
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 5/5] pathspec: record labels

2016-05-16 Thread Junio C Hamano
Stefan Beller  writes:

>> Let's avoid "are meant to", which is merely to give you an excuse to
>> say "it was meant to ... but the implementation did not quite achieve
>> that goal".
>>
>> The "label" attribute can be attached to paths, and the pathspec
>> mechanism is extended via the new ":(label=X)pattern/to/match"
>
> I wasn't sure about whether we want to have '=' or ':' as the separator
> of "label" and its values. ...

Oh, sorry, the above wasn't a suggestion to change : to = at all.  I
was merely being sloppy in the details that is irrelevant to my main
point (which is, it is better spend the bits you spent for "meant
to" instead for saying clearly what it does).

> ... But as that is only internal, we can be inconsistent to a new
> public feature, so '=' seems better for the labeling system.

I can buy that, too.  Good that my sloppy wording helped you think
about it further ;-).

> But still we do not enforce it early enough. Some crazy upstream may
> add some labels which do not follow the requirements and then
> tell downstream to run a command like `git foo "(label=!@#$)".
> and then downstream curses at upstream as well as Git.

That is why it is "warn and ignore", not "die".

>>> + if (ATTR_TRUE(check.value))
>>> + ret = 1; /* has all the labels */
>>
>> So this is "pretend that I have all the labels under the sun".
>>
>>> + else if (ATTR_FALSE(check.value))
>>> + ret = 0; /* has no labels */
>>
>> I do not see a value in this.  What difference does it have compared
>> to having a "label=" that explicitly says "I do not have one"?  What
>> is your answer to an end-user question "When should I say 'label='
>> and when should I say '!label'?"
>>
>> Just forbid it for now; we may find a better use for it later.
>
> I don't think we want to die in that code as it is in the data already.

Is it?  I think this is coming from the command line pathspec magic,
not from .gitattributes file recorded in the tree.

> We need to allow the UNSET case, as otherwise you'd need to label
> any path if using labels?

You do need UNSET (roughly, "no label is mentioned for the path").

If I want to say "Everything under Documentation/ and also things
with label=doc", I'd say

git cmd "Documentation/" ":(label=doc)"

and no path in Documentation/ need any label, i.e. for them, the
labels are unset.  They will not be caught with ":(label=doc)"
because they are not set, but that is OK.

FALSE is different from UNSET.  It needs an explicit mention, i.e.

*.doc   doc
false.doc   -doc

What's the difference between saying "-doc" and not saying anything?
If you really want to explicitly say "doc attribute is unset for
this path (perhaps because you may have other patterns that set the
doc elsewhere), you would say "!doc", and you already have code for
that.

> if (ATTR_TRUE(check.value))
> ret = 1; /* has all the labels */
> else if (ATTR_FALSE(check.value))
> die(_("Label attributes must not be unset"));

The message is wrong.  You are dying because the user explicitly set
it to false, not because the user made it unset.

> else if (ATTR_UNSET(check.value))
> ret = 0; /* has no labels */

>>> + struct string_list_item *si;
>>> + struct string_list attr_labels = STRING_LIST_INIT_DUP;
>>> + string_list_split(&attr_labels, check.value, ',', -1);
>>> + string_list_sort(&attr_labels);
>>
>> Filter out a non-compliant label values here, so that they are
>> ignored from day one.  That way you would not have to deal with "I
>> know I got the warning, but it used to work and you broke it" later.
>
> So you're saying we should not die(...) but just ignore those labels?

Do not die() but warn-and-ignore when you see funnies in
.gitattributes; do die() if you see funnies in pathspec magic.

>> I am NOT suggesting to make this enhancement in the prototype to
>> allow us experiment with submodule selection use case, but this is
>> an obvious place to allow
>>
>> :(label=A B):(label=C D)
>>
>> to mean ((A & B) | (C & D)) by making item->labels an array of set
>> of labels.
>>
>> And no, I do not think arbitrary boolean expression is too complex

s/do not/do/

>> to understand to the end-users, especially if we have to stay within
>> the pathspec magic syntax.  And my gut feeling is that it is not
>> worth it to support anything more complex than "OR of these ANDed
>> ones".
>
> That makes sense.

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: [RFC PATCH 0/4] pathspec labels [WAS: submodule groups]

2016-05-16 Thread Junio C Hamano
Stefan Beller  writes:

> On Sun, May 15, 2016 at 3:06 AM, Duy Nguyen  wrote:
>> Instead of putting everything in under the same attribute name
>> "label", make one attribute per label? Would this work?
>>
>> *.[ch] c-group code-group
>>
>> And the pathspec magic name can be simply "attr", any git attribute
>> can be used with it, e.g. :(attr:c-group)
>
> So you want to be able to query something like:
>
> git ls-files ":(crlf=auto)"
>
> as well?

It would be more like

git ls-files ":(attr:crlf=auto)"

It certainly sounds tempting, even though I do not want to keep what
this initial chunk of the series needs to do to the minimum.
--
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 0/6] modernize t1500

2016-05-16 Thread Eric Sunshine
On Tue, May 10, 2016 at 2:26 PM, Junio C Hamano  wrote:
> Junio C Hamano  writes:
>> Junio C Hamano  writes:
>> Subject: [PATCH 7/6] t1500: finish preparation upfront
>>
>> The earlier tests do not attempt to modify the contents of .git (by
>> creating objects or refs, for example), which means that even if
>> some earlier tests before "cp -R" fail, the tests in repo.git will
>> run in an environment that we can expect them to succeed in.
>>
>> Make it clear that tests in repo.git will be independent from the
>> results of earlier tests done in .git by moving its initialization
>> "cp -R .git repo.git" much higher in the test sequence.
>>
>> Signed-off-by: Junio C Hamano 
>> ---
>
> I think the same logic applies to other preparatory things like
> creation of sub/dir in the working tree etc.

Hmm, so are you suggesting a single 'setup' test at the start of
script which does the 'cp -R' and creates those other directories
needed by later tests?
--
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 5/5] pathspec: record labels

2016-05-16 Thread Stefan Beller
On Mon, May 16, 2016 at 10:38 AM, Junio C Hamano  wrote:
> Stefan Beller  writes:
>
>>> Let's avoid "are meant to", which is merely to give you an excuse to
>>> say "it was meant to ... but the implementation did not quite achieve
>>> that goal".
>>>
>>> The "label" attribute can be attached to paths, and the pathspec
>>> mechanism is extended via the new ":(label=X)pattern/to/match"
>>
>> I wasn't sure about whether we want to have '=' or ':' as the separator
>> of "label" and its values. ...
>
> Oh, sorry, the above wasn't a suggestion to change : to = at all.  I
> was merely being sloppy in the details that is irrelevant to my main
> point (which is, it is better spend the bits you spent for "meant
> to" instead for saying clearly what it does).
>
>> ... But as that is only internal, we can be inconsistent to a new
>> public feature, so '=' seems better for the labeling system.
>
> I can buy that, too.  Good that my sloppy wording helped you think
> about it further ;-).
>
>> But still we do not enforce it early enough. Some crazy upstream may
>> add some labels which do not follow the requirements and then
>> tell downstream to run a command like `git foo "(label=!@#$)".
>> and then downstream curses at upstream as well as Git.
>
> That is why it is "warn and ignore", not "die".

So "warn and ignore" for data from .gitattributes and die for
commandline arguments? That makes sense.

>
 + if (ATTR_TRUE(check.value))
 + ret = 1; /* has all the labels */
>>>
>>> So this is "pretend that I have all the labels under the sun".
>>>
 + else if (ATTR_FALSE(check.value))
 + ret = 0; /* has no labels */
>>>
>>> I do not see a value in this.  What difference does it have compared
>>> to having a "label=" that explicitly says "I do not have one"?  What
>>> is your answer to an end-user question "When should I say 'label='
>>> and when should I say '!label'?"
>>>
>>> Just forbid it for now; we may find a better use for it later.
>>
>> I don't think we want to die in that code as it is in the data already.
>
> Is it?  I think this is coming from the command line pathspec magic,
> not from .gitattributes file recorded in the tree.

The 'check.value' is coming from the .gitattributes.

The 'required_labels' string list comes from the command line.
("The command line requires these labels")

>
>> We need to allow the UNSET case, as otherwise you'd need to label
>> any path if using labels?
>
> You do need UNSET (roughly, "no label is mentioned for the path").
>
> If I want to say "Everything under Documentation/ and also things
> with label=doc", I'd say
>
> git cmd "Documentation/" ":(label=doc)"
>
> and no path in Documentation/ need any label, i.e. for them, the
> labels are unset.  They will not be caught with ":(label=doc)"
> because they are not set, but that is OK.

right. that is what the end user should be able to do. That also means,
we need to handle files with UNSET labels (all under Documentation/)

>
> FALSE is different from UNSET.  It needs an explicit mention, i.e.
>
> *.doc   doc
> false.doc   -doc

and this is in the .gitattribues, so warn-and-ignore and by ignore
we mean treat it as UNSET?

>
> What's the difference between saying "-doc" and not saying anything?
> If you really want to explicitly say "doc attribute is unset for
> this path (perhaps because you may have other patterns that set the
> doc elsewhere), you would say "!doc", and you already have code for
> that.
>
>> if (ATTR_TRUE(check.value))
>> ret = 1; /* has all the labels */
>> else if (ATTR_FALSE(check.value))
>> die(_("Label attributes must not be unset"));
>
> The message is wrong.  You are dying because the user explicitly set
> it to false, not because the user made it unset.

Ok, so here is the warn-and-ignore code:


if (ATTR_TRUE(check.value))
ret = 1; /* has all the labels */
else if (ATTR_FALSE(check.value)) {
warning(_("Path '%s': Label must not be false. Treat
as if no label was set"), path);
ret = 0;
else if (ATTR_UNSET(check.value))
ret = 0; /* has no labels */
else {

Thanks,
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: [RFC PATCH 0/4] pathspec labels [WAS: submodule groups]

2016-05-16 Thread Stefan Beller
On Mon, May 16, 2016 at 10:39 AM, Junio C Hamano  wrote:
> Stefan Beller  writes:
>
>> On Sun, May 15, 2016 at 3:06 AM, Duy Nguyen  wrote:
>>> Instead of putting everything in under the same attribute name
>>> "label", make one attribute per label? Would this work?
>>>
>>> *.[ch] c-group code-group
>>>
>>> And the pathspec magic name can be simply "attr", any git attribute
>>> can be used with it, e.g. :(attr:c-group)
>>
>> So you want to be able to query something like:
>>
>> git ls-files ":(crlf=auto)"
>>
>> as well?
>
> It would be more like
>
> git ls-files ":(attr:crlf=auto)"
>
> It certainly sounds tempting, even though I do not want to keep what
> this initial chunk of the series needs to do to the minimum.

This is another case for using ':' instead of '='.
So I think ':' is better for this future enhancement.

Also this future enhancement may ask for

  git ls-files ":(attr:label=foo)"

or

  git ls-files ":(attr:-label)"

so the user can circumvent the warn and ignore strategy. :(
--
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 5/5] pathspec: record labels

2016-05-16 Thread Stefan Beller
> I am NOT suggesting to make this enhancement in the prototype to
> allow us experiment with submodule selection use case, but this is
> an obvious place to allow
>
> :(label=A B):(label=C D)
>
> to mean ((A & B) | (C & D)) by making item->labels an array of set
> of labels.

This is what already works with the series. Or rather:

":(label=A B)" ":(label=C D)"

works as you would expect for (A&B) | (C&D).

So I am a bit hesitant to replace the string list by an array
of stringlists or such, as the future enhancement can also do that?

The enhancement may bring in more expressions into the label string,
so it may even parse that string into a tree for Lexicographical order
instead of just using an array of lists.

>
> And no, I do not think arbitrary boolean expression is too complex
> to understand to the end-users, especially if we have to stay within
> the pathspec magic syntax.  And my gut feeling is that it is not
> worth it to support anything more complex than "OR of these ANDed
> ones".
>
>> + string_list_split(item->labels, sb.buf, ' ', -1);
>> + string_list_remove_empty_items(item->labels, 0);
>> + strbuf_release(&sb);
>> + continue;
>
> The data structure to record the "required labels" is shared
> knowledge between this function and the has_all_labels() and nobody
> else knows it is done with string_list, so I think this is a good
> balance between expediency and future optimization possibilities (I
> am anticipating that linear search of string list would be found as
> performance bottleneck).
>
--
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 v10 20/20] untracked-cache: config option

2016-05-16 Thread David Turner
On Sun, 2016-05-15 at 16:43 +0700, Duy Nguyen wrote:
> On Fri, May 13, 2016 at 3:20 AM, David Turner <
> dtur...@twopensource.com> wrote:
> > Add a config option to populate the untracked cache.
> > 
> > For installations that have centrally-managed configuration, it's
> > easier to set a config once than to run update-index on every
> > repository.
> 
> This sounds like the job for core.untrackedCache. It populates after
> reading the index though (in post_read_index_from) not writing, but I
> think it accomplishes the same thing.

OK, I'll drop this one.

> > Signed-off-by: David Turner 
> > ---
> >  Documentation/config.txt | 4 
> >  read-cache.c | 7 ++-
> >  2 files changed, 10 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Documentation/config.txt b/Documentation/config.txt
> > index 385ea66..c7b76ef 100644
> > --- a/Documentation/config.txt
> > +++ b/Documentation/config.txt
> > @@ -1848,6 +1848,10 @@ imap::
> > The configuration variables in the 'imap' section are
> > described
> > in linkgit:git-imap-send[1].
> > 
> > +index.adduntrackedcache::
> > +   Automatically populate the untracked cache whenever the
> > index
> > +   is written.
> > +
> >  index.addwatchmanextension::
> > Automatically add the watchman extension to the index
> > whenever
> > it is written.
> > diff --git a/read-cache.c b/read-cache.c
> > index 22c64d0..4a1cccf 100644
> > --- a/read-cache.c
> > +++ b/read-cache.c
> > @@ -2472,7 +2472,7 @@ static int do_write_index(struct index_state
> > *istate, int newfd,
> > int entries = istate->cache_nr;
> > struct stat st;
> > struct strbuf previous_name_buf = STRBUF_INIT,
> > *previous_name;
> > -   int watchman = 0;
> > +   int watchman = 0, untracked = 0;
> > uint64_t start = getnanotime();
> > 
> > for (i = removed = extended = 0; i < entries; i++) {
> > @@ -2502,6 +2502,11 @@ static int do_write_index(struct index_state
> > *istate, int newfd,
> > !the_index.last_update)
> > the_index.last_update = xstrdup("");
> > 
> > +   if (!git_config_get_bool("index.adduntrackedcache",
> > &untracked) &&
> > +   untracked &&
> > +   !istate->untracked)
> > +   add_untracked_cache(&the_index);
> > +
> > hdr_version = istate->version;
> > 
> > hdr.hdr_signature = htonl(CACHE_SIGNATURE);
> > --
> > 2.4.2.767.g62658d5-twtrsrc
> > 
> 
> 
> 
--
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


[PATCHv4 3/5] pathspec: move long magic parsing out of prefix_pathspec

2016-05-16 Thread Stefan Beller
`prefix_pathspec` is quite a lengthy function and we plan on adding more.
Split it up for better readability. As we want to add code into the
inner loop of the long magic parsing, we also benefit from lower
indentation.

Signed-off-by: Stefan Beller 
---
 pathspec.c | 84 +++---
 1 file changed, 47 insertions(+), 37 deletions(-)

diff --git a/pathspec.c b/pathspec.c
index c9e9b6c..eba37c2 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -88,6 +88,52 @@ static void prefix_short_magic(struct strbuf *sb, int 
prefixlen,
strbuf_addf(sb, ",prefix:%d)", prefixlen);
 }
 
+static void eat_long_magic(struct pathspec_item *item, const char *elt,
+   unsigned *magic, int *pathspec_prefix,
+   const char **copyfrom_, const char **long_magic_end)
+{
+   int i;
+   const char *copyfrom = *copyfrom_;
+   /* longhand */
+   const char *nextat;
+   for (copyfrom = elt + 2;
+*copyfrom && *copyfrom != ')';
+copyfrom = nextat) {
+   size_t len = strcspn(copyfrom, ",)");
+   if (copyfrom[len] == ',')
+   nextat = copyfrom + len + 1;
+   else
+   /* handle ')' and '\0' */
+   nextat = copyfrom + len;
+   if (!len)
+   continue;
+   for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++) {
+   if (strlen(pathspec_magic[i].name) == len &&
+   !strncmp(pathspec_magic[i].name, copyfrom, len)) {
+   *magic |= pathspec_magic[i].bit;
+   break;
+   }
+   if (starts_with(copyfrom, "prefix:")) {
+   char *endptr;
+   *pathspec_prefix = strtol(copyfrom + 7,
+ &endptr, 10);
+   if (endptr - copyfrom != len)
+   die(_("invalid parameter for pathspec 
magic 'prefix'"));
+   /* "i" would be wrong, but it does not matter */
+   break;
+   }
+   }
+   if (ARRAY_SIZE(pathspec_magic) <= i)
+   die(_("Invalid pathspec magic '%.*s' in '%s'"),
+   (int) len, copyfrom, elt);
+   }
+   if (*copyfrom != ')')
+   die(_("Missing ')' at the end of pathspec magic in '%s'"), elt);
+   *long_magic_end = copyfrom;
+   copyfrom++;
+   *copyfrom_ = copyfrom;
+}
+
 /*
  * Take an element of a pathspec and check for magic signatures.
  * Append the result to the prefix. Return the magic bitmap.
@@ -150,43 +196,7 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
(flags & PATHSPEC_LITERAL_PATH)) {
; /* nothing to do */
} else if (elt[1] == '(') {
-   /* longhand */
-   const char *nextat;
-   for (copyfrom = elt + 2;
-*copyfrom && *copyfrom != ')';
-copyfrom = nextat) {
-   size_t len = strcspn(copyfrom, ",)");
-   if (copyfrom[len] == ',')
-   nextat = copyfrom + len + 1;
-   else
-   /* handle ')' and '\0' */
-   nextat = copyfrom + len;
-   if (!len)
-   continue;
-   for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++) {
-   if (strlen(pathspec_magic[i].name) == len &&
-   !strncmp(pathspec_magic[i].name, copyfrom, 
len)) {
-   magic |= pathspec_magic[i].bit;
-   break;
-   }
-   if (starts_with(copyfrom, "prefix:")) {
-   char *endptr;
-   pathspec_prefix = strtol(copyfrom + 7,
-&endptr, 10);
-   if (endptr - copyfrom != len)
-   die(_("invalid parameter for 
pathspec magic 'prefix'"));
-   /* "i" would be wrong, but it does not 
matter */
-   break;
-   }
-   }
-   if (ARRAY_SIZE(pathspec_magic) <= i)
-   die(_("Invalid pathspec magic '%.*s' in '%s'"),
-   (int) len, copyfrom, elt);
-   }
-   if (*copyfrom != ')')
-   die(_("Missing ')' at the end of pathspec 

[PATCHv4 0/5] pathspec labels

2016-05-16 Thread Stefan Beller
Thanks Junio for the review!
Thanks Duy for suggestions to think about in the not-submodule case :)

* when invalid labels are found
  -> in the .gitattributes "warn and ignore"
  -> in command line args die(..)
* treat labels set to false as unset.
* fixes in documentation/ reworded the commit message

Thanks,
Stefan

diff to current origin/sb/pathspec-label (v2 of the series, so a lot):

diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index af2c682..b846848 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -906,6 +906,18 @@ If this attribute is not set or has an invalid value, the 
value of the
 (See linkgit:git-config[1]).
 
 
+Attaching labels to path
+
+
+`label`
+^^^
+By the value of this attribute you can specify a list of arbitrary strings
+to be attached to a path as labels. These labels can be used for
+easier paths matching using pathspecs (linkgit:gitglossary[1]).
+It is required to use only alphanumeric characters, dashes and
+underscores for the labels.
+
+
 USING MACRO ATTRIBUTES
 --
 
diff --git a/Documentation/glossary-content.txt 
b/Documentation/glossary-content.txt
index a1fc9e0..e264a58 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -362,11 +362,6 @@ glob;;
For example, "Documentation/{asterisk}.html" matches
"Documentation/git.html" but not "Documentation/ppc/ppc.html"
or "tools/perf/Documentation/perf.html".
-
-label:;;
-   Labels can be assigned to pathspecs in the .gitattributes file.
-   By specifying a list of labels the pattern will match only
-   files which have all of the listed labels.
 +
 Two consecutive asterisks ("`**`") in patterns matched against
 full pathname may have special meaning:
@@ -389,6 +384,10 @@ full pathname may have special meaning:
 +
 Glob magic is incompatible with literal magic.
 
+label=;;
+   Additionally to matching the pathspec, the path must have a 'label'
+   attribute having set all labels listed here.
+
 exclude;;
After a path matches any non-exclude pathspec, it will be run
through all exclude pathspec (magic signature: `!`). If it
diff --git a/attr.h b/attr.h
index f6fc7c3..8b08d33 100644
--- a/attr.h
+++ b/attr.h
@@ -18,7 +18,6 @@ extern const char git_attr__false[];
 #define ATTR_TRUE(v) ((v) == git_attr__true)
 #define ATTR_FALSE(v) ((v) == git_attr__false)
 #define ATTR_UNSET(v) ((v) == NULL)
-#define ATTR_CUSTOM(v) (!(ATTR_UNSET(v) || ATTR_FALSE(v) || ATTR_TRUE(v)))
 
 /*
  * Send one or more git_attr_check to git_check_attr(), and
diff --git a/dir.c b/dir.c
index 51d5965..fd39f92 100644
--- a/dir.c
+++ b/dir.c
@@ -209,25 +209,56 @@ int within_depth(const char *name, int namelen,
return 1;
 }
 
-void load_labels(const char *name, int namelen, struct string_list *list)
+static int has_all_labels(const char *name, int namelen,
+  const struct string_list *required_labels)
 {
static struct git_attr *attr;
+
struct git_attr_check check;
-   char *path = xmemdupz(name, namelen);
+   char *path;
+   int ret;
 
if (!attr)
attr = git_attr("label");
check.attr = attr;
 
+   path = xmemdupz(name, namelen);
if (git_check_attr(path, 1, &check))
-   die("git_check_attr died");
-
-   if (ATTR_CUSTOM(check.value)) {
-   string_list_split(list, check.value, ',', -1);
-   string_list_sort(list);
+   die("internal bug: git_check_attr died.");
+
+   if (ATTR_TRUE(check.value))
+   ret = 1; /* has all the labels */
+   else if (ATTR_FALSE(check.value)) {
+   warning(_("Path '%s': Label must not be false. Treat as if no 
label was set."), path);
+   ret = 0;
+   } else if (ATTR_UNSET(check.value))
+   ret = 0; /* has no labels */
+   else {
+   struct string_list_item *si;
+   struct string_list attr_labels = STRING_LIST_INIT_DUP;
+   string_list_split(&attr_labels, check.value, ',', -1);
+   for_each_string_list_item(si, &attr_labels) {
+   if (validate_label_name(si->string)) {
+   warning(_("Ignoring label '%s'"), si->string);
+   free(si->string);
+   si->string = "";
+   }
+   }
+   string_list_remove_empty_items(&attr_labels, 0);
+   string_list_sort(&attr_labels);
+   ret = 1;
+   for_each_string_list_item(si, required_labels) {
+   if (!string_list_has_string(&attr_labels, si->string)) {
+   ret = 0;
+   break;
+   }
+   }
+   string_list_clear(&attr_labels, 0);
}
 

[PATCHv4 2/5] Documentation: correct typo in example for querying attributes

2016-05-16 Thread Stefan Beller
The introductory text of the example has a typo in the
specification which makes it harder to follow that example.

Signed-off-by: Stefan Beller 
---
 Documentation/technical/api-gitattributes.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/technical/api-gitattributes.txt 
b/Documentation/technical/api-gitattributes.txt
index 2602668..36fc9af 100644
--- a/Documentation/technical/api-gitattributes.txt
+++ b/Documentation/technical/api-gitattributes.txt
@@ -61,7 +61,7 @@ Querying Specific Attributes
 Example
 ---
 
-To see how attributes "crlf" and "indent" are set for different paths.
+To see how attributes "crlf" and "ident" are set for different paths.
 
 . Prepare an array of `struct git_attr_check` with two elements (because
   we are checking two attributes).  Initialize their `attr` member with
-- 
2.8.2.401.gb49ffe6.dirty

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


[PATCH 1/2] difftool: initialize variables for readability

2016-05-16 Thread David Aguilar
The code always goes into one of the two conditional blocks but make it
clear that not doing so is an error condition by setting $ok to 0.

Signed-off-by: David Aguilar 
---
 git-difftool.perl | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/git-difftool.perl b/git-difftool.perl
index 488d14b..8cf0040 100755
--- a/git-difftool.perl
+++ b/git-difftool.perl
@@ -273,7 +273,7 @@ EOF
# temporary file to both the left and right directories to show the
# change in the recorded SHA1 for the submodule.
for my $path (keys %submodule) {
-   my $ok;
+   my $ok = 0;
if (defined($submodule{$path}{left})) {
$ok = write_to_file("$ldir/$path",
"Subproject commit $submodule{$path}{left}");
@@ -289,7 +289,7 @@ EOF
# shows only the link itself, not the contents of the link target.
# This loop replicates that behavior.
for my $path (keys %symlink) {
-   my $ok;
+   my $ok = 0;
if (defined($symlink{$path}{left})) {
$ok = write_to_file("$ldir/$path",
$symlink{$path}{left});
-- 
2.8.2.404.gdfc6a507

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


[PATCHv4 1/5] Documentation: fix a typo

2016-05-16 Thread Stefan Beller
Signed-off-by: Stefan Beller 
---
 Documentation/gitattributes.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index e3b1de8..af2c682 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -86,7 +86,7 @@ is either not set or empty, $HOME/.config/git/attributes is 
used instead.
 Attributes for all users on a system should be placed in the
 `$(prefix)/etc/gitattributes` file.
 
-Sometimes you would need to override an setting of an attribute
+Sometimes you would need to override a setting of an attribute
 for a path to `Unspecified` state.  This can be done by listing
 the name of the attribute prefixed with an exclamation point `!`.
 
-- 
2.8.2.401.gb49ffe6.dirty

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


[PATCHv4 4/5] pathspec: move prefix check out of the inner loop

2016-05-16 Thread Stefan Beller
The prefix check is not related the check of pathspec magic; also there
is no code that is relevant after we'd break the loop on a match for
"prefix:". So move the check before the loop and shortcircuit the outer
loop.

Signed-off-by: Stefan Beller 
---
 pathspec.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/pathspec.c b/pathspec.c
index eba37c2..4dff252 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -107,21 +107,22 @@ static void eat_long_magic(struct pathspec_item *item, 
const char *elt,
nextat = copyfrom + len;
if (!len)
continue;
+
+   if (starts_with(copyfrom, "prefix:")) {
+   char *endptr;
+   *pathspec_prefix = strtol(copyfrom + 7,
+ &endptr, 10);
+   if (endptr - copyfrom != len)
+   die(_("invalid parameter for pathspec magic 
'prefix'"));
+   continue;
+   }
+
for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++) {
if (strlen(pathspec_magic[i].name) == len &&
!strncmp(pathspec_magic[i].name, copyfrom, len)) {
*magic |= pathspec_magic[i].bit;
break;
}
-   if (starts_with(copyfrom, "prefix:")) {
-   char *endptr;
-   *pathspec_prefix = strtol(copyfrom + 7,
- &endptr, 10);
-   if (endptr - copyfrom != len)
-   die(_("invalid parameter for pathspec 
magic 'prefix'"));
-   /* "i" would be wrong, but it does not matter */
-   break;
-   }
}
if (ARRAY_SIZE(pathspec_magic) <= i)
die(_("Invalid pathspec magic '%.*s' in '%s'"),
-- 
2.8.2.401.gb49ffe6.dirty

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


[PATCHv4 5/5] pathspec: record labels

2016-05-16 Thread Stefan Beller
The "label" attribute can be attached to paths, and the pathspec
mechanism is extended via the new ":(label=X)pattern/to/match"
syntax to filter paths so that it requires paths to not just
match the given pattern but also have the specified labels
attached for them to be chosen.

Labels are meant to describe arbitrary set of files, which
is not described via the tree layout.

Signed-off-by: Stefan Beller 
---
 Documentation/gitattributes.txt|  12 +++
 Documentation/glossary-content.txt |   4 +
 dir.c  |  56 +
 pathspec.c |  65 ++-
 pathspec.h |   2 +
 t/t6134-pathspec-with-labels.sh| 158 +
 6 files changed, 293 insertions(+), 4 deletions(-)
 create mode 100755 t/t6134-pathspec-with-labels.sh

diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index af2c682..b846848 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -906,6 +906,18 @@ If this attribute is not set or has an invalid value, the 
value of the
 (See linkgit:git-config[1]).
 
 
+Attaching labels to path
+
+
+`label`
+^^^
+By the value of this attribute you can specify a list of arbitrary strings
+to be attached to a path as labels. These labels can be used for
+easier paths matching using pathspecs (linkgit:gitglossary[1]).
+It is required to use only alphanumeric characters, dashes and
+underscores for the labels.
+
+
 USING MACRO ATTRIBUTES
 --
 
diff --git a/Documentation/glossary-content.txt 
b/Documentation/glossary-content.txt
index 8ad29e6..e264a58 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -384,6 +384,10 @@ full pathname may have special meaning:
 +
 Glob magic is incompatible with literal magic.
 
+label=;;
+   Additionally to matching the pathspec, the path must have a 'label'
+   attribute having set all labels listed here.
+
 exclude;;
After a path matches any non-exclude pathspec, it will be run
through all exclude pathspec (magic signature: `!`). If it
diff --git a/dir.c b/dir.c
index 656f272..fd39f92 100644
--- a/dir.c
+++ b/dir.c
@@ -9,6 +9,7 @@
  */
 #include "cache.h"
 #include "dir.h"
+#include "attr.h"
 #include "refs.h"
 #include "wildmatch.h"
 #include "pathspec.h"
@@ -208,6 +209,58 @@ int within_depth(const char *name, int namelen,
return 1;
 }
 
+static int has_all_labels(const char *name, int namelen,
+  const struct string_list *required_labels)
+{
+   static struct git_attr *attr;
+
+   struct git_attr_check check;
+   char *path;
+   int ret;
+
+   if (!attr)
+   attr = git_attr("label");
+   check.attr = attr;
+
+   path = xmemdupz(name, namelen);
+   if (git_check_attr(path, 1, &check))
+   die("internal bug: git_check_attr died.");
+
+   if (ATTR_TRUE(check.value))
+   ret = 1; /* has all the labels */
+   else if (ATTR_FALSE(check.value)) {
+   warning(_("Path '%s': Label must not be false. Treat as if no 
label was set."), path);
+   ret = 0;
+   } else if (ATTR_UNSET(check.value))
+   ret = 0; /* has no labels */
+   else {
+   struct string_list_item *si;
+   struct string_list attr_labels = STRING_LIST_INIT_DUP;
+   string_list_split(&attr_labels, check.value, ',', -1);
+   for_each_string_list_item(si, &attr_labels) {
+   if (validate_label_name(si->string)) {
+   warning(_("Ignoring label '%s'"), si->string);
+   free(si->string);
+   si->string = "";
+   }
+   }
+   string_list_remove_empty_items(&attr_labels, 0);
+   string_list_sort(&attr_labels);
+   ret = 1;
+   for_each_string_list_item(si, required_labels) {
+   if (!string_list_has_string(&attr_labels, si->string)) {
+   ret = 0;
+   break;
+   }
+   }
+   string_list_clear(&attr_labels, 0);
+   }
+
+   free(path);
+
+   return ret;
+}
+
 #define DO_MATCH_EXCLUDE   1
 #define DO_MATCH_DIRECTORY 2
 
@@ -263,6 +316,9 @@ static int match_pathspec_item(const struct pathspec_item 
*item, int prefix,
strncmp(item->match, name - prefix, item->prefix))
return 0;
 
+   if (item->labels && !has_all_labels(name, namelen, item->labels))
+   return 0;
+
/* If the match was just the prefix, we matched */
if (!*match)
return MATCHED_RECURSIVELY;
diff --git a/pathspec.c b/pathspec.c
index 4dff252..2f053fb 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -88,12 +88,42 @@ 

[PATCH 2/2] difftool: handle unmerged files in dir-diff mode

2016-05-16 Thread David Aguilar
When files are unmerged they can show up as both unmerged and
modified in the output of `git diff --raw`.  This causes
difftool's dir-diff to create filesystem entries for the same
path twice, which fails when it encounters a duplicate path.

Ensure that each worktree path is only processed once.
Add a test to demonstrate the breakage.

Reported-by: Jan Smets 
Signed-off-by: David Aguilar 
---
 git-difftool.perl   |  5 +
 t/t7800-difftool.sh | 23 +++
 2 files changed, 28 insertions(+)

diff --git a/git-difftool.perl b/git-difftool.perl
index 8cf0040..ebd13ba 100755
--- a/git-difftool.perl
+++ b/git-difftool.perl
@@ -138,6 +138,7 @@ sub setup_dir_diff
my %submodule;
my %symlink;
my @working_tree = ();
+   my %working_tree_dups = ();
my @rawdiff = split('\0', $diffrtn);
 
my $i = 0;
@@ -188,6 +189,10 @@ EOF
}
 
if ($rmode ne $null_mode) {
+   # Avoid duplicate working_tree entries
+   if ($working_tree_dups{$dst_path}++) {
+   next;
+   }
my ($use, $wt_sha1) = use_wt_file($repo, $workdir,
  $dst_path, $rsha1);
if ($use) {
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index ff7a9e9..7ce4cd7 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -419,6 +419,29 @@ run_dir_diff_test 'difftool --dir-diff when worktree file 
is missing' '
grep file2 output
 '
 
+run_dir_diff_test 'difftool --dir-diff with unmerged files' '
+   test_when_finished git reset --hard &&
+   test_config difftool.echo.cmd "echo ok" &&
+   git checkout -B conflict-a &&
+   git checkout -B conflict-b &&
+   git checkout conflict-a &&
+   echo a >>file &&
+   git add file &&
+   git commit -m conflict-a &&
+   git checkout conflict-b &&
+   echo b >>file &&
+   git add file &&
+   git commit -m conflict-b &&
+   git checkout master &&
+   git merge conflict-a &&
+   test_must_fail git merge conflict-b &&
+   cat >expect <<-EOF &&
+   ok
+   EOF
+   git difftool --dir-diff $symlinks -t echo >actual &&
+   test_cmp expect actual
+'
+
 write_script .git/CHECK_SYMLINKS <<\EOF
 for f in file file2 sub/sub
 do
-- 
2.8.2.404.gdfc6a507

--
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 54/94] builtin/apply: make parse_chunk() return a negative integer on error

2016-05-16 Thread Christian Couder
On Mon, May 16, 2016 at 5:04 AM, Eric Sunshine  wrote:
> On Wed, May 11, 2016 at 9:17 AM, Christian Couder
>  wrote:
>> To libify `git apply` functionality we have to signal errors to the
>> caller instead of die()ing or exit()ing.
>>
>> To do that in a compatible manner with the rest of the error handling
>> in builtin/apply.c, find_header() should return -1 instead of calling
>> die() or exit().
>
> Why is this talking about making find_header() return -1? Didn't that
> happen in the previous patch?
>
>> As parse_chunk() is called only by apply_patch() which already
>> returns -1 when an error happened, let's make apply_patch() return -1
>> when parse_chunk() returns -1.
>>
>> If find_header() returns -2 because no patch header has been found, it
>> is ok for parse_chunk() to also return -2. If find_header() returns -1
>> because an error happened, it is ok for parse_chunk() to do the same.
>>
>> Helped-by: Eric Sunshine 
>> Signed-off-by: Christian Couder 
>> ---
>> diff --git a/builtin/apply.c b/builtin/apply.c
>> @@ -2176,8 +2176,9 @@ static int parse_chunk(struct apply_state *state, char 
>> *buffer, unsigned long si
>>  * empty to us here.
>>  */
>> if ((state->apply || state->check) &&
>> -   (!patch->is_binary && !metadata_changes(patch)))
>> -   die(_("patch with only garbage at line %d"), 
>> state->linenr);
>> +   (!patch->is_binary && !metadata_changes(patch))) {
>> +   return error(_("patch with only garbage at line 
>> %d"), state->linenr);
>> +   }
>
> Unnecessary braces.

Ok, will remove.
--
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 5/5] pathspec: record labels

2016-05-16 Thread Junio C Hamano
Stefan Beller  writes:

>> I am NOT suggesting to make this enhancement in the prototype to
>> allow us experiment with submodule selection use case, but this is
>> an obvious place to allow
>>
>> :(label=A B):(label=C D)
>>
>> to mean ((A & B) | (C & D)) by making item->labels an array of set
>> of labels.
>
> This is what already works with the series. Or rather:
>
> ":(label=A B)" ":(label=C D)"
>
> works as you would expect for (A&B) | (C&D).

That is "duplicationg path".  I was envisioning a single

":(label=A B):(label=C D)tediously/long/path/because/java/"

a shorter and sweeter way to say your two pathspec variant, i.e.

":(label=A B)tediously/long/path/because/java/" \
":(label=C D)tediously/long/path/because/java/"

--
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 5/5] pathspec: record labels

2016-05-16 Thread Junio C Hamano
Stefan Beller  writes:

> So "warn and ignore" for data from .gitattributes and die for
> commandline arguments? That makes sense.

Yes.

On the "command line" front, because we may want to give different
meanings to these two entries in the future:

:(label=-doc)Documentation/
:(label=!doc)Documentation/

we should diagnose -doc (FALSE) as an error, not treating it as the
same as !doc (UNSET).  And we should warn and ignore -doc (FALSE) in
.gitattributes.  Yes, ignoring it would be more or less equivalent
to treating it as UNSET, but because we may use -doc (FALSE) for a
better purpose later, we should still warn.

> Ok, so here is the warn-and-ignore code:
>
>
> if (ATTR_TRUE(check.value))
> ret = 1; /* has all the labels */
> else if (ATTR_FALSE(check.value)) {
> warning(_("Path '%s': Label must not be false. Treat
> as if no label was set"), path);
> ret = 0;

s/Treat as if .../The -label may be used differently in future
versions of Git, so do not use it/;

But if we are going in the direction of :(attr:crlf=auto), all this
discussion is moot, isn't it?  I haven't formed a firm opinion on
this, but it sure does sound tempting, doesn't it?

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


Re: [PATCH 0/6] modernize t1500

2016-05-16 Thread Junio C Hamano
Eric Sunshine  writes:

> On Tue, May 10, 2016 at 2:26 PM, Junio C Hamano  wrote:
>> Junio C Hamano  writes:
>>> Junio C Hamano  writes:
>>> Subject: [PATCH 7/6] t1500: finish preparation upfront
>>>
>>> The earlier tests do not attempt to modify the contents of .git (by
>>> creating objects or refs, for example), which means that even if
>>> some earlier tests before "cp -R" fail, the tests in repo.git will
>>> run in an environment that we can expect them to succeed in.
>>>
>>> Make it clear that tests in repo.git will be independent from the
>>> results of earlier tests done in .git by moving its initialization
>>> "cp -R .git repo.git" much higher in the test sequence.
>>>
>>> Signed-off-by: Junio C Hamano 
>>> ---
>>
>> I think the same logic applies to other preparatory things like
>> creation of sub/dir in the working tree etc.
>
> Hmm, so are you suggesting a single 'setup' test at the start of
> script which does the 'cp -R' and creates those other directories
> needed by later tests?

Exactly.
--
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 5/5] pathspec: record labels

2016-05-16 Thread Stefan Beller
On Mon, May 16, 2016 at 11:52 AM, Junio C Hamano  wrote:
> Stefan Beller  writes:
>
>> So "warn and ignore" for data from .gitattributes and die for
>> commandline arguments? That makes sense.
>
> Yes.
>
> On the "command line" front, because we may want to give different
> meanings to these two entries in the future:
>
> :(label=-doc)Documentation/
> :(label=!doc)Documentation/

Yes but both of these already errors out with:

Label -doc': Label names must start with an
alphabetic character and use only alphanumeric
characters, dashes and underscores.
fatal: Labels in the wrong syntax are prohibited.

The command line arguments are not parsed via the attr system.
Only data from .gitattributes are parsed via the attr system.

I can add tests for those to fail though.

>
> we should diagnose -doc (FALSE) as an error, not treating it as the
> same as !doc (UNSET).  And we should warn and ignore -doc (FALSE) in
> .gitattributes.  Yes, ignoring it would be more or less equivalent
> to treating it as UNSET, but because we may use -doc (FALSE) for a
> better purpose later, we should still warn.
>
>> Ok, so here is the warn-and-ignore code:
>>
>>
>> if (ATTR_TRUE(check.value))
>> ret = 1; /* has all the labels */
>> else if (ATTR_FALSE(check.value)) {
>> warning(_("Path '%s': Label must not be false. Treat
>> as if no label was set"), path);
>> ret = 0;
>
> s/Treat as if .../The -label may be used differently in future
> versions of Git, so do not use it/;

"... but for now Git treats it as if it is not set at all" is a valuable
information to the user, still?

That code path is only used for data coming from .gitattributes,
so we can bike shed the best warning message.

>
> But if we are going in the direction of :(attr:crlf=auto), all this
> discussion is moot, isn't it?  I haven't formed a firm opinion on
> this, but it sure does sound tempting, doesn't it?
>

That direction sounds scary as people may use any sort of labels, so
we can no longer add labels later on sanely.

:(attr:random-attr=foo)

should also fall into the "warn and ignore" space. We only want to allow

:(attr:known-attr)
:(attr:label=..)

instead of label= we may want to allow a little bit more, such as
abbreviated  'l='
or 'group=', but not any sort of labeling.
--
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 5/5] pathspec: record labels

2016-05-16 Thread Junio C Hamano
Stefan Beller  writes:

> "... but for now Git treats it as if it is not set at all" is a valuable
> information to the user, still?

Not at all.  "What you are using is wrong and there is no guarantee
what behaviour you would get" is the message we need to convey.
--
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 5/5] pathspec: record labels

2016-05-16 Thread Stefan Beller
On Mon, May 16, 2016 at 12:08 PM, Junio C Hamano  wrote:
> Stefan Beller  writes:
>
>> "... but for now Git treats it as if it is not set at all" is a valuable
>> information to the user, still?
>
> Not at all.  "What you are using is wrong and there is no guarantee
> what behaviour you would get" is the message we need to convey.

"Path '%s': Ignoring label set to false; This may behave
differently in future versions of Git."

Maybe even with s/may/will/

I think that conveys both the message about the future as well as
"what happened just now in that command"
--
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


Best Practices with code/build fixes post-merge?

2016-05-16 Thread Robert Dailey
Sometimes, I merge 2 branches that have deviated quite a bit. A
worst-case example would be some API change. The topic branch
(long-lived) may start using the old API. However, once I merge the
topic back to master, that API no longer exists. As such, every place
that introduces a usage of the old API will fail to build (but won't
necessarily cause a conflict during a merge).

Concerning best practices, which of the following is better?

1. Make the fixes (which may be vast), smoke test, get a general feel
that everything is working on master again. Amend the changes to the
previous merge commit.

2. Make the fixes as in step 1, but instead of amending to the merge
commit, create a new descendant commit representing the changes.

Concerns I see with either choice:

1. Pros: Changes are atomic. Cons: merge commits are typically very
difficult to view, especially from logs. For example, `git log
--name-status` does nothing for merge commits, so it makes it
less-intuitive to get a good overview of changes.

2. Opposite of #1: Changes are not atomic (con), but it makes it very
clear that these changes were made "on top of" the merge (pro)

Is there a best practice here? What do each of you do as a personal
preference or policy? Thanks in advance.
--
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 5/5] pathspec: record labels

2016-05-16 Thread Junio C Hamano
Stefan Beller  writes:

> "Path '%s': Ignoring label set to false; This may behave
> differently in future versions of Git."

I agree that mentioning "ignoring" is good enough.  I think our
recent messages begin with lowercase, though.

--
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: Best Practices with code/build fixes post-merge?

2016-05-16 Thread Junio C Hamano
Robert Dailey  writes:

> Sometimes, I merge 2 branches that have deviated quite a bit. A
> worst-case example would be some API change. The topic branch
> (long-lived) may start using the old API. However, once I merge the
> topic back to master, that API no longer exists. As such, every place
> that introduces a usage of the old API will fail to build (but won't
> necessarily cause a conflict during a merge).
> ...
> Is there a best practice here? What do each of you do as a personal
> preference or policy? Thanks in advance.

I think the best practice is to make sure your "some API change" is
done in a way competent people do.  Namely, have a thin wrapper to
emulate the old API so that such a long-lived topic that adds new
caller of old API would still be syntactically and semantically
correct after getting textually merged.

Your developers however are not perfect (nobody is), so the next
best is to arrange that a build fails (which seems to be what you
have), so that you can notice at the merge time.

If the adjustment of an application that uses the old API to use the
new one is simple enough, amending the merge would be my preference,
as a merge commit should be "a single atomic change" as any other
commit.  But at the same time, you do not have to be too worried
about such a "mismerge".  A merge commit is a change that can
introduce a bug as any other commit.  After all, we are dealing with
human endeavours.  So "I did this merge as a single atomic change,
merging the work done in the topic while adjusting the way the topic
did certain things using old API to use new API, to the best of my
ability, but I may have introduced a bug" is perfectly fine.  You do
a commit to ensure it is correct to the best of your ability, and
because everybody knows you are not perfect (nobody is), nobody
expects your commit is always correct.  If you find a bug later, you
just fix up with a follow-up commit.  A merge commit is no special.

My personal preference, if adjustment from old API to new API is
more involved, is to have a new topic branch that is forked from the
trunk and merge the topic with new call sites of old API into it.
I'd fix as much breakage in that merge commit, and then fix things
up as necessary in follow up commits on that new topic branch as
necessary.  After that, merging the result to the trunk.
--
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 02/12] attr.c: use strchrnul() to scan for one line

2016-05-16 Thread Junio C Hamano
Signed-off-by: Junio C Hamano 
---
 attr.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/attr.c b/attr.c
index eec5d7d..45aec1b 100644
--- a/attr.c
+++ b/attr.c
@@ -402,8 +402,8 @@ static struct attr_stack *read_attr_from_index(const char 
*path, int macro_ok)
for (sp = buf; *sp; ) {
char *ep;
int more;
-   for (ep = sp; *ep && *ep != '\n'; ep++)
-   ;
+
+   ep = strchrnul(sp, '\n');
more = (*ep == '\n');
*ep = '\0';
handle_attr_line(res, sp, path, ++lineno, macro_ok);
-- 
2.8.2-748-gfb85f76

--
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 00/12] revamping git_check_attr() API

2016-05-16 Thread Junio C Hamano
A common pattern to check N attributes for many paths is to

 (1) prepare an array A of N git_attr_check_elem items;
 (2) call git_attr() to intern the N attribute names and fill A;
 (3) repeatedly call git_check_attrs() for path with N and A;

A look-up for these N attributes for a single path P scans the
entire attr_stack, starting from the .git/info/attributes file and
then .gitattributes file in the directory the path P is in, going
upwards to find .gitattributes file found in parent directories.

An earlier commit 06a604e6 (attr: avoid heavy work when we know the
specified attr is not defined, 2014-12-28) tried to optimize out
this scanning for one trivial special case: when the attribute being
sought is known not to exist, we do not have to scan for it.  While
this may be a cheap and effective heuristic, it would not work well
when N is (much) more than 1.

What we would want is a more customized way to skip irrelevant
entries in the attribute stack, and the definition of irrelevance
is tied to the set of attributes passed to git_check_attrs() call,
i.e. the set of attributes being sought.  The data necessary for
this optimization needs to live alongside the set of attributes, but
a simple array of git_attr_check_elem simply does not have any place
for that.

Introduce "struct git_attr_check" that contains N, the number of
attributes being sought, and A, the array that holds N
git_attr_check_elem items, and a function git_check_attr() that
takes a path P and this structure as its parameters.  This structure
can later be extended to hold extra data necessary for optimization.

Side Note: While in this series, I am not interested in
specifying the exact optimization, it would help readers to give
what is envisioned.  Even when the caller is interested in only
a few attributes (say, "diff", "text" and "group-doc"), we'd walk
the attribute entries in various .gitattributes files, perform
the pattern match and collect attributes for the path.  An
earlier commit 06a604e6 (attr: avoid heavy work when we know the
specified attr is not defined, 2014-12-28) tried to optimize out
this scanning for one trivial special case: where an asked-for
attribute does not appear anywhere in these files, we know we do
not have to scan at all.

We can do much better.  We can scan these attribute entries that
came from .gitattributes files once and mark the ones that affect
one or more of the attributes we know the caller is interested
in.  Then we only go through the marked entries.  E.g. if the
caller is interested in "diff", "text" and "group-doc"
attributes, we can mark entries that talks about any of "diff",
"text", "group-doc" and "binary" attributes.  The last one is
because it is an attribute macro that expands to affect "diff"
and "text" (these attribute are unset by having "binary").

The way git_attr_check() API is structured expects that the
caller expresses the set of attributes it is interested in
upfront, and reuses to ask the same question about many paths,
and it is already optimized for the case where it does so in
in-order recursive descent of a tree hierarchy by having an
attr_stack that reads, pre-parses and caches contents of the
.gitattributes files found in each directory hierarchy.  The
cached optimization data that sits in "struct git_attr_check"
would be effective for this expected access pattern.

The optimization data cannot be file-scope static to attr.c,
even though that might be easier to implement, in anticipation
of having more than one "struct git_attr_check" working
alternatingly, e.g. having more than one pathspec with
":(attr=X)" pathspec magic, i.e.

git cmd ":(attr=X)dir/" ":(attr=Y)dir/ectory/"

Each pathspec element is expected to keep its own "struct
git_attr_check" in the custom data to support pathspec magic
to match with attributes, and the optimization data kept there
would survive repeated calls to git_check_attr() for the same
path with different set of attributes.


The patches in the earliest part of the series have been sent to the
list already; there is no substantial change (I think I made a
typofix in the commit log message found by Eric).

  commit.c: use strchrnul() to scan for one line
  attr.c: use strchrnul() to scan for one line
  attr.c: update a stale comment on "struct match_attr"
  attr.c: explain the lack of attr-name syntax check in parse_attr()
  attr.c: complete a sentence in a comment
  attr.c: mark where #if DEBUG ends more clearly
  attr.c: simplify macroexpand_one()

Step 8 is to make sure I can catch all the existing callers and
update the API incrementally.

  attr: rename function and struct related to checking attributes

Step 9 is the most important one.  By updating the API to allow the
callers hold piece of information more than just a simple array of
 pair, it paves the way to add data

[PATCH v2 01/12] commit.c: use strchrnul() to scan for one line

2016-05-16 Thread Junio C Hamano
Signed-off-by: Junio C Hamano 
---
 commit.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/commit.c b/commit.c
index 3f4f371..1f9ee8a 100644
--- a/commit.c
+++ b/commit.c
@@ -415,8 +415,7 @@ int find_commit_subject(const char *commit_buffer, const 
char **subject)
p++;
if (*p) {
p += 2;
-   for (eol = p; *eol && *eol != '\n'; eol++)
-   ; /* do nothing */
+   eol = strchrnul(p, '\n');
} else
eol = p;
 
-- 
2.8.2-748-gfb85f76

--
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 03/12] attr.c: update a stale comment on "struct match_attr"

2016-05-16 Thread Junio C Hamano
When 82dce998 (attr: more matching optimizations from .gitignore,
2012-10-15) changed a pointer to a string "*pattern" into an
embedded "struct pattern" in struct match_attr, it forgot to update
the comment that describes the structure.

Signed-off-by: Junio C Hamano 
---
 attr.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/attr.c b/attr.c
index 45aec1b..4ae7801 100644
--- a/attr.c
+++ b/attr.c
@@ -131,9 +131,8 @@ struct pattern {
  * If is_macro is true, then u.attr is a pointer to the git_attr being
  * defined.
  *
- * If is_macro is false, then u.pattern points at the filename pattern
- * to which the rule applies.  (The memory pointed to is part of the
- * memory block allocated for the match_attr instance.)
+ * If is_macro is false, then u.pat is the filename pattern to which the
+ * rule applies.
  *
  * In either case, num_attr is the number of attributes affected by
  * this rule, and state is an array listing them.  The attributes are
-- 
2.8.2-748-gfb85f76

--
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 05/12] attr.c: complete a sentence in a comment

2016-05-16 Thread Junio C Hamano
Signed-off-by: Junio C Hamano 
---
 attr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/attr.c b/attr.c
index 05db667..a7f2c3f 100644
--- a/attr.c
+++ b/attr.c
@@ -300,7 +300,7 @@ static struct match_attr *parse_attr_line(const char *line, 
const char *src,
  * directory (again, reading the file from top to bottom) down to the
  * current directory, and then scan the list backwards to find the first match.
  * This is exactly the same as what is_excluded() does in dir.c to deal with
- * .gitignore
+ * .gitignore file and info/excludes file as a fallback.
  */
 
 static struct attr_stack {
-- 
2.8.2-748-gfb85f76

--
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 04/12] attr.c: explain the lack of attr-name syntax check in parse_attr()

2016-05-16 Thread Junio C Hamano
Signed-off-by: Junio C Hamano 
---
 attr.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/attr.c b/attr.c
index 4ae7801..05db667 100644
--- a/attr.c
+++ b/attr.c
@@ -183,6 +183,12 @@ static const char *parse_attr(const char *src, int lineno, 
const char *cp,
return NULL;
}
} else {
+   /*
+* As this function is always called twice, once with
+* e == NULL in the first pass and then e != NULL in
+* the second pass, no need for invalid_attr_name()
+* check here.
+*/
if (*cp == '-' || *cp == '!') {
e->setto = (*cp == '-') ? ATTR__FALSE : ATTR__UNSET;
cp++;
-- 
2.8.2-748-gfb85f76

--
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 09/12] attr: (re)introduce git_check_attr() and struct git_attr_check

2016-05-16 Thread Junio C Hamano
A common pattern to check N attributes for many paths is to

 (1) prepare an array A of N git_attr_check_elem items;
 (2) call git_attr() to intern the N attribute names and fill A;
 (3) repeatedly call git_check_attrs() for path with N and A;

A look-up for these N attributes for a single path P scans the
entire attr_stack, starting from the .git/info/attributes file and
then .gitattributes file in the directory the path P is in, going
upwards to find .gitattributes file found in parent directories.

An earlier commit 06a604e6 (attr: avoid heavy work when we know the
specified attr is not defined, 2014-12-28) tried to optimize out
this scanning for one trivial special case: when the attribute being
sought is known not to exist, we do not have to scan for it.  While
this may be a cheap and effective heuristic, it would not work well
when N is (much) more than 1.

What we would want is a more customized way to skip irrelevant
entries in the attribute stack, and the definition of irrelevance
is tied to the set of attributes passed to git_check_attrs() call,
i.e. the set of attributes being sought.  The data necessary for
this optimization needs to live alongside the set of attributes, but
a simple array of git_attr_check_elem simply does not have any place
for that.

Introduce "struct git_attr_check" that contains N, the number of
attributes being sought, and A, the array that holds N
git_attr_check_elem items, and a function git_check_attr() that
takes a path P and this structure as its parameters.  This structure
can later be extended to hold extra data necessary for optimization.

Also, to make it easier to write the first two steps in common
cases, introduce git_attr_check_initl() helper function, which takes
a NULL-terminated list of attribute names and initialize this
structure.

As an illustration of this new API, convert archive.c that asks for
export-subst and export-ignore attributes for each paths.

Signed-off-by: Junio C Hamano 
---
 archive.c | 24 ++--
 attr.c| 34 ++
 attr.h|  9 +
 3 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/archive.c b/archive.c
index 0f6acc5..7779af1 100644
--- a/archive.c
+++ b/archive.c
@@ -87,19 +87,6 @@ void *sha1_file_to_archive(const struct archiver_args *args,
return buffer;
 }
 
-static void setup_archive_check(struct git_attr_check_elem *check)
-{
-   static struct git_attr *attr_export_ignore;
-   static struct git_attr *attr_export_subst;
-
-   if (!attr_export_ignore) {
-   attr_export_ignore = git_attr("export-ignore");
-   attr_export_subst = git_attr("export-subst");
-   }
-   check[0].attr = attr_export_ignore;
-   check[1].attr = attr_export_subst;
-}
-
 struct directory {
struct directory *up;
struct object_id oid;
@@ -123,7 +110,7 @@ static int write_archive_entry(const unsigned char *sha1, 
const char *base,
struct archiver_context *c = context;
struct archiver_args *args = c->args;
write_archive_entry_fn_t write_entry = c->write_entry;
-   struct git_attr_check_elem check[2];
+   static struct git_attr_check *check;
const char *path_without_prefix;
int err;
 
@@ -137,11 +124,12 @@ static int write_archive_entry(const unsigned char *sha1, 
const char *base,
strbuf_addch(&path, '/');
path_without_prefix = path.buf + args->baselen;
 
-   setup_archive_check(check);
-   if (!git_check_attrs(path_without_prefix, ARRAY_SIZE(check), check)) {
-   if (ATTR_TRUE(check[0].value))
+   if (!check)
+   check = git_attr_check_initl("export-ignore", "export-subst", 
NULL);
+   if (!git_check_attr(path_without_prefix, check)) {
+   if (ATTR_TRUE(check->check[0].value))
return 0;
-   args->convert = ATTR_TRUE(check[1].value);
+   args->convert = ATTR_TRUE(check->check[1].value);
}
 
if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
diff --git a/attr.c b/attr.c
index 8aa346c..285fc58 100644
--- a/attr.c
+++ b/attr.c
@@ -825,3 +825,37 @@ void git_attr_set_direction(enum git_attr_direction new, 
struct index_state *ist
drop_attr_stack();
use_index = istate;
 }
+
+int git_check_attr(const char *path, struct git_attr_check *check)
+{
+   return git_check_attrs(path, check->check_nr, check->check);
+}
+
+struct git_attr_check *git_attr_check_initl(const char *one, ...)
+{
+   struct git_attr_check *check;
+   int cnt;
+   va_list params;
+   const char *param;
+
+   va_start(params, one);
+   for (cnt = 1; (param = va_arg(params, const char *)) != NULL; cnt++)
+   ;
+   va_end(params);
+   check = xcalloc(1,
+   sizeof(*check) + cnt * sizeof(*(check->check)));
+   check->check_nr = cnt;
+   check->check = (struct git_attr_check_elem *)(check + 1)

[PATCH v2 07/12] attr.c: simplify macroexpand_one()

2016-05-16 Thread Junio C Hamano
The double-loop wants to do an early return immediately when one
matching macro is found.  Eliminate the extra variable 'a' used for
that purpose and rewrite the "assign the found item to 'a' to make
it non-NULL and force the loop(s) to terminate" with a direct return
from there.

Signed-off-by: Junio C Hamano 
---
 attr.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/attr.c b/attr.c
index 95416d3..7bfeef3 100644
--- a/attr.c
+++ b/attr.c
@@ -701,24 +701,21 @@ static int fill(const char *path, int pathlen, int 
basename_offset,
 static int macroexpand_one(int nr, int rem)
 {
struct attr_stack *stk;
-   struct match_attr *a = NULL;
int i;
 
if (check_all_attr[nr].value != ATTR__TRUE ||
!check_all_attr[nr].attr->maybe_macro)
return rem;
 
-   for (stk = attr_stack; !a && stk; stk = stk->prev)
-   for (i = stk->num_matches - 1; !a && 0 <= i; i--) {
+   for (stk = attr_stack; stk; stk = stk->prev) {
+   for (i = stk->num_matches - 1; 0 <= i; i--) {
struct match_attr *ma = stk->attrs[i];
if (!ma->is_macro)
continue;
if (ma->u.attr->attr_nr == nr)
-   a = ma;
+   return fill_one("expand", ma, rem);
}
-
-   if (a)
-   rem = fill_one("expand", a, rem);
+   }
 
return rem;
 }
-- 
2.8.2-748-gfb85f76

--
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 08/12] attr: rename function and struct related to checking attributes

2016-05-16 Thread Junio C Hamano
The traditional API to check attributes is to prepare an N-element
array of "struct git_attr_check" and pass N and the array to the
function "git_check_attr()" as arguments.

In preparation to revamp the API to pass a single structure, in
which these N elements are held, rename the type used for these
individual array elements to "struct git_attr_check_elem" and rename
the function to "git_check_attrs()".

Signed-off-by: Junio C Hamano 
---
 archive.c  |  6 +++---
 attr.c | 12 ++--
 attr.h |  8 
 builtin/check-attr.c   | 19 ++-
 builtin/pack-objects.c |  6 +++---
 convert.c  | 12 ++--
 ll-merge.c | 10 +-
 userdiff.c |  4 ++--
 ws.c   |  6 +++---
 9 files changed, 42 insertions(+), 41 deletions(-)

diff --git a/archive.c b/archive.c
index 5d735ae..0f6acc5 100644
--- a/archive.c
+++ b/archive.c
@@ -87,7 +87,7 @@ void *sha1_file_to_archive(const struct archiver_args *args,
return buffer;
 }
 
-static void setup_archive_check(struct git_attr_check *check)
+static void setup_archive_check(struct git_attr_check_elem *check)
 {
static struct git_attr *attr_export_ignore;
static struct git_attr *attr_export_subst;
@@ -123,7 +123,7 @@ static int write_archive_entry(const unsigned char *sha1, 
const char *base,
struct archiver_context *c = context;
struct archiver_args *args = c->args;
write_archive_entry_fn_t write_entry = c->write_entry;
-   struct git_attr_check check[2];
+   struct git_attr_check_elem check[2];
const char *path_without_prefix;
int err;
 
@@ -138,7 +138,7 @@ static int write_archive_entry(const unsigned char *sha1, 
const char *base,
path_without_prefix = path.buf + args->baselen;
 
setup_archive_check(check);
-   if (!git_check_attr(path_without_prefix, ARRAY_SIZE(check), check)) {
+   if (!git_check_attrs(path_without_prefix, ARRAY_SIZE(check), check)) {
if (ATTR_TRUE(check[0].value))
return 0;
args->convert = ATTR_TRUE(check[1].value);
diff --git a/attr.c b/attr.c
index 7bfeef3..8aa346c 100644
--- a/attr.c
+++ b/attr.c
@@ -40,7 +40,7 @@ struct git_attr {
 static int attr_nr;
 static int cannot_trust_maybe_real;
 
-static struct git_attr_check *check_all_attr;
+static struct git_attr_check_elem *check_all_attr;
 static struct git_attr *(git_attr_hash[HASHSIZE]);
 
 char *git_attr_name(struct git_attr *attr)
@@ -661,7 +661,7 @@ static int macroexpand_one(int attr_nr, int rem);
 
 static int fill_one(const char *what, struct match_attr *a, int rem)
 {
-   struct git_attr_check *check = check_all_attr;
+   struct git_attr_check_elem *check = check_all_attr;
int i;
 
for (i = a->num_attr - 1; 0 < rem && 0 <= i; i--) {
@@ -726,7 +726,7 @@ static int macroexpand_one(int nr, int rem)
  * collected. Otherwise all attributes are collected.
  */
 static void collect_some_attrs(const char *path, int num,
-  struct git_attr_check *check)
+  struct git_attr_check_elem *check)
 
 {
struct attr_stack *stk;
@@ -754,7 +754,7 @@ static void collect_some_attrs(const char *path, int num,
rem = 0;
for (i = 0; i < num; i++) {
if (!check[i].attr->maybe_real) {
-   struct git_attr_check *c;
+   struct git_attr_check_elem *c;
c = check_all_attr + check[i].attr->attr_nr;
c->value = ATTR__UNSET;
rem++;
@@ -769,7 +769,7 @@ static void collect_some_attrs(const char *path, int num,
rem = fill(path, pathlen, basename_offset, stk, rem);
 }
 
-int git_check_attr(const char *path, int num, struct git_attr_check *check)
+int git_check_attrs(const char *path, int num, struct git_attr_check_elem 
*check)
 {
int i;
 
@@ -785,7 +785,7 @@ int git_check_attr(const char *path, int num, struct 
git_attr_check *check)
return 0;
 }
 
-int git_all_attrs(const char *path, int *num, struct git_attr_check **check)
+int git_all_attrs(const char *path, int *num, struct git_attr_check_elem 
**check)
 {
int i, count, j;
 
diff --git a/attr.h b/attr.h
index 8b08d33..cab82ec 100644
--- a/attr.h
+++ b/attr.h
@@ -20,11 +20,11 @@ extern const char git_attr__false[];
 #define ATTR_UNSET(v) ((v) == NULL)
 
 /*
- * Send one or more git_attr_check to git_check_attr(), and
+ * Send one or more git_attr_check to git_check_attrs(), and
  * each 'value' member tells what its value is.
  * Unset one is returned as NULL.
  */
-struct git_attr_check {
+struct git_attr_check_elem {
struct git_attr *attr;
const char *value;
 };
@@ -36,7 +36,7 @@ struct git_attr_check {
  */
 char *git_attr_name(struct git_attr *);
 
-int git_che

[PATCH v2 06/12] attr.c: mark where #if DEBUG ends more clearly

2016-05-16 Thread Junio C Hamano
Signed-off-by: Junio C Hamano 
---
 attr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/attr.c b/attr.c
index a7f2c3f..95416d3 100644
--- a/attr.c
+++ b/attr.c
@@ -469,7 +469,7 @@ static void debug_set(const char *what, const char *match, 
struct git_attr *attr
 #define debug_push(a) do { ; } while (0)
 #define debug_pop(a) do { ; } while (0)
 #define debug_set(a,b,c,d) do { ; } while (0)
-#endif
+#endif /* DEBUG_ATTR */
 
 static void drop_attr_stack(void)
 {
-- 
2.8.2-748-gfb85f76

--
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 10/12] attr: convert git_all_attrs() to use "struct git_attr_check"

2016-05-16 Thread Junio C Hamano
This updates the other two ways the attribute check is done via an
array of "struct git_attr_check_elem" elements.  These two niches
appear only in "git check-attr".

 * The caller does not know offhand what attributes it wants to ask
   about and cannot use git_attr_check_initl() to prepare the
   git_attr_check structure.

 * The caller may not know what attributes it wants to ask at all,
   and instead wants to learn everything that the given path has.

Such a caller can call git_attr_check_alloc() to allocate an empty
git_attr_check, and then call git_attr_check_append() to add
attribute names one by one.  A new attribute can be appended until
git_attr_check structure is "finalized", which happens when it is
used to ask for attributes for any path by calling git_check_attr()
or git_all_attrs().  A git_attr_check structure that is initialized
by git_attr_check_initl() is already finalized when it is returned.

I am not at all happy with the way git_all_attrs() API turned out to
be, but it is only to support one niche caller ("check-attr --all"),
so I'll stop here for now.

Signed-off-by: Junio C Hamano 
---
 attr.c   | 70 +---
 attr.h   | 16 +++-
 builtin/check-attr.c | 54 ++--
 3 files changed, 84 insertions(+), 56 deletions(-)

diff --git a/attr.c b/attr.c
index 285fc58..9c187bc 100644
--- a/attr.c
+++ b/attr.c
@@ -785,32 +785,21 @@ int git_check_attrs(const char *path, int num, struct 
git_attr_check_elem *check
return 0;
 }
 
-int git_all_attrs(const char *path, int *num, struct git_attr_check_elem 
**check)
+void git_all_attrs(const char *path, struct git_attr_check *check)
 {
-   int i, count, j;
+   int i;
 
+   git_attr_check_clear(check);
collect_some_attrs(path, 0, NULL);
 
-   /* Count the number of attributes that are set. */
-   count = 0;
-   for (i = 0; i < attr_nr; i++) {
-   const char *value = check_all_attr[i].value;
-   if (value != ATTR__UNSET && value != ATTR__UNKNOWN)
-   ++count;
-   }
-   *num = count;
-   ALLOC_ARRAY(*check, count);
-   j = 0;
for (i = 0; i < attr_nr; i++) {
+   const char *name = check_all_attr[i].attr->name;
const char *value = check_all_attr[i].value;
-   if (value != ATTR__UNSET && value != ATTR__UNKNOWN) {
-   (*check)[j].attr = check_all_attr[i].attr;
-   (*check)[j].value = value;
-   ++j;
-   }
+   if (value == ATTR__UNSET || value == ATTR__UNKNOWN)
+   continue;
+   git_attr_check_append(check, name);
+   check->check[check->check_nr - 1].value = value;
}
-
-   return 0;
 }
 
 void git_attr_set_direction(enum git_attr_direction new, struct index_state 
*istate)
@@ -828,6 +817,7 @@ void git_attr_set_direction(enum git_attr_direction new, 
struct index_state *ist
 
 int git_check_attr(const char *path, struct git_attr_check *check)
 {
+   check->finalized = 1;
return git_check_attrs(path, check->check_nr, check->check);
 }
 
@@ -845,17 +835,57 @@ struct git_attr_check *git_attr_check_initl(const char 
*one, ...)
check = xcalloc(1,
sizeof(*check) + cnt * sizeof(*(check->check)));
check->check_nr = cnt;
+   check->finalized = 1;
check->check = (struct git_attr_check_elem *)(check + 1);
 
check->check[0].attr = git_attr(one);
va_start(params, one);
for (cnt = 1; cnt < check->check_nr; cnt++) {
+   struct git_attr *attr;
param = va_arg(params, const char *);
if (!param)
die("BUG: counted %d != ended at %d",
check->check_nr, cnt);
-   check->check[cnt].attr = git_attr(param);
+   attr = git_attr(param);
+   if (!attr)
+   die("BUG: %s: not a valid attribute name", param);
+   check->check[cnt].attr = attr;
}
va_end(params);
return check;
 }
+
+struct git_attr_check *git_attr_check_alloc(void)
+{
+   return xcalloc(1, sizeof(struct git_attr_check));
+}
+
+void git_attr_check_append(struct git_attr_check *check, const char *name)
+{
+   struct git_attr *attr;
+
+   if (check->finalized)
+   die("BUG: append after git_attr_check structure is finalized");
+
+   attr = git_attr(name);
+   if (!attr)
+   die("%s: not a valid attribute name", name);
+   ALLOC_GROW(check->check, check->check_nr + 1, check->check_alloc);
+   check->check[check->check_nr++].attr = attr;
+}
+
+void git_attr_check_clear(struct git_attr_check *check)
+{
+   if ((void *)(check->check) == (void *)(check + 1))
+   die("BUG: clearing a statically initialized 

[PATCH v2 12/12] attr: retire git_check_attrs() API

2016-05-16 Thread Junio C Hamano
Since nobody uses the old API, make it file-scope static, and update
the documentation to describe the new API.

Signed-off-by: Junio C Hamano 
---
 Documentation/technical/api-gitattributes.txt | 62 +++
 attr.c|  3 +-
 attr.h|  2 -
 3 files changed, 36 insertions(+), 31 deletions(-)

diff --git a/Documentation/technical/api-gitattributes.txt 
b/Documentation/technical/api-gitattributes.txt
index 2602668..6f13f94 100644
--- a/Documentation/technical/api-gitattributes.txt
+++ b/Documentation/technical/api-gitattributes.txt
@@ -16,10 +16,15 @@ Data Structure
of no interest to the calling programs.  The name of the
attribute can be retrieved by calling `git_attr_name()`.
 
+`struct git_attr_check_elem`::
+
+   This structure represents one attribute and its value.
+
 `struct git_attr_check`::
 
-   This structure represents a set of attributes to check in a call
-   to `git_check_attr()` function, and receives the results.
+   This structure represents a collection of `git_attr_check_elem`.
+   It is passed to `git_check_attr()` function, specifying the
+   attributes to check, and receives their values.
 
 
 Attribute Values
@@ -48,49 +53,47 @@ value of the attribute for the path.
 Querying Specific Attributes
 
 
-* Prepare an array of `struct git_attr_check` to define the list of
-  attributes you would want to check.  To populate this array, you would
-  need to define necessary attributes by calling `git_attr()` function.
+* Prepare `struct git_attr_check` using git_attr_check_initl()
+  function, enumerating the names of attributes whose values you are
+  interested in, terminated with a NULL pointer.
 
 * Call `git_check_attr()` to check the attributes for the path.
 
-* Inspect `git_attr_check` structure to see how each of the attribute in
-  the array is defined for the path.
+* Inspect `git_attr_check` structure to see how each of the
+  attribute in the array is defined for the path.
 
 
 Example
 ---
 
-To see how attributes "crlf" and "indent" are set for different paths.
+To see how attributes "crlf" and "ident" are set for different paths.
 
-. Prepare an array of `struct git_attr_check` with two elements (because
-  we are checking two attributes).  Initialize their `attr` member with
-  pointers to `struct git_attr` obtained by calling `git_attr()`:
+. Prepare a `struct git_attr_check` with two elements (because
+  we are checking two attributes):
 
 
-static struct git_attr_check check[2];
+static struct git_attr_check *check;
 static void setup_check(void)
 {
-   if (check[0].attr)
+   if (check)
return; /* already done */
-   check[0].attr = git_attr("crlf");
-   check[1].attr = git_attr("ident");
+   check = git_attr_check_initl("crlf", "ident", NULL);
 }
 
 
-. Call `git_check_attr()` with the prepared array of `struct git_attr_check`:
+. Call `git_check_attr()` with the prepared `struct git_attr_check`:
 
 
const char *path;
 
setup_check();
-   git_check_attr(path, ARRAY_SIZE(check), check);
+   git_check_attr(path, check);
 
 
-. Act on `.value` member of the result, left in `check[]`:
+. Act on `.value` member of the result, left in `check->check[]`:
 
 
-   const char *value = check[0].value;
+   const char *value = check->check[0].value;
 
if (ATTR_TRUE(value)) {
The attribute is Set, by listing only the name of the
@@ -115,14 +118,17 @@ Querying All Attributes
 
 To get the values of all attributes associated with a file:
 
-* Call `git_all_attrs()`, which returns an array of `git_attr_check`
-  structures.
+* Prepare an empty `git_attr_check` structure by calling
+  `git_attr_check_alloc()`.
+
+* Call `git_all_attrs()`, which populates the `git_attr_check`
+  with the attributes attached to the path.
 
-* Iterate over the `git_attr_check` array to examine the attribute
-  names and values.  The name of the attribute described by a
-  `git_attr_check` object can be retrieved via
-  `git_attr_name(check[i].attr)`.  (Please note that no items will be
-  returned for unset attributes, so `ATTR_UNSET()` will return false
-  for all returned `git_array_check` objects.)
+* Iterate over the `git_attr_check.check[]` array to examine
+  the attribute names and values.  The name of the attribute
+  described by a  `git_attr_check.check[]` object can be retrieved via
+  `git_attr_name(check->check[i].attr)`.  (Please note that no items
+  will be returned for unset attributes, so `ATTR_UNSET()` will return
+  false for all returned `git_array_check` objects.)
 
-* Free the `git_array_check` array.
+* Free the `git_array_check` by calling `git_attr_check_free()`.
diff --git a/attr.c b/attr.c
index 9c187bc..c3295a9 100644
--- a/attr.c
+++ b/attr.c
@@ -769,7 +769,8 @@ stat

[PATCH v2 11/12] attr: convert git_check_attrs() callers to use the new API

2016-05-16 Thread Junio C Hamano
The remaining callers are all simple "I have N attributes I am
interested in.  I'll ask about them with various paths one by one".

After this step, no caller to git_check_attrs() remains.  After
removing it, we can extend "struct git_attr_check" struct with data
that can be used in optimizing the query for the specific N
attributes it contains.

Signed-off-by: Junio C Hamano 
---
 builtin/pack-objects.c | 19 +--
 convert.c  | 18 +++---
 ll-merge.c | 33 ++---
 userdiff.c | 19 ---
 ws.c   | 19 ++-
 5 files changed, 40 insertions(+), 68 deletions(-)

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 167c301..c6c2a69 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -886,24 +886,15 @@ static void write_pack_file(void)
written, nr_result);
 }
 
-static void setup_delta_attr_check(struct git_attr_check_elem *check)
-{
-   static struct git_attr *attr_delta;
-
-   if (!attr_delta)
-   attr_delta = git_attr("delta");
-
-   check[0].attr = attr_delta;
-}
-
 static int no_try_delta(const char *path)
 {
-   struct git_attr_check_elem check[1];
+   static struct git_attr_check *check;
 
-   setup_delta_attr_check(check);
-   if (git_check_attrs(path, ARRAY_SIZE(check), check))
+   if (!check)
+   check = git_attr_check_initl("delta", NULL);
+   if (git_check_attr(path, check))
return 0;
-   if (ATTR_FALSE(check->value))
+   if (ATTR_FALSE(check->check[0].value))
return 1;
return 0;
 }
diff --git a/convert.c b/convert.c
index 058da86..510d1b9 100644
--- a/convert.c
+++ b/convert.c
@@ -760,24 +760,20 @@ struct conv_attrs {
int ident;
 };
 
-static const char *conv_attr_name[] = {
-   "crlf", "ident", "filter", "eol", "text",
-};
-#define NUM_CONV_ATTRS ARRAY_SIZE(conv_attr_name)
-
 static void convert_attrs(struct conv_attrs *ca, const char *path)
 {
-   int i;
-   static struct git_attr_check_elem ccheck[NUM_CONV_ATTRS];
+   static struct git_attr_check *check;
 
-   if (!ccheck[0].attr) {
-   for (i = 0; i < NUM_CONV_ATTRS; i++)
-   ccheck[i].attr = git_attr(conv_attr_name[i]);
+   if (!check) {
+   check = git_attr_check_initl("crlf", "ident",
+"filter", "eol", "text",
+NULL);
user_convert_tail = &user_convert;
git_config(read_convert_config, NULL);
}
 
-   if (!git_check_attrs(path, NUM_CONV_ATTRS, ccheck)) {
+   if (!git_check_attr(path, check)) {
+   struct git_attr_check_elem *ccheck = check->check;
ca->crlf_action = git_path_check_crlf(ccheck + 4);
if (ca->crlf_action == CRLF_UNDEFINED)
ca->crlf_action = git_path_check_crlf(ccheck + 0);
diff --git a/ll-merge.c b/ll-merge.c
index 772b14e..d4380c4 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -334,15 +334,6 @@ static const struct ll_merge_driver 
*find_ll_merge_driver(const char *merge_attr
return &ll_merge_drv[LL_TEXT_MERGE];
 }
 
-static int git_path_check_merge(const char *path, struct git_attr_check_elem 
check[2])
-{
-   if (!check[0].attr) {
-   check[0].attr = git_attr("merge");
-   check[1].attr = git_attr("conflict-marker-size");
-   }
-   return git_check_attrs(path, 2, check);
-}
-
 static void normalize_file(mmfile_t *mm, const char *path)
 {
struct strbuf strbuf = STRBUF_INIT;
@@ -360,7 +351,7 @@ int ll_merge(mmbuffer_t *result_buf,
 mmfile_t *theirs, const char *their_label,
 const struct ll_merge_options *opts)
 {
-   static struct git_attr_check_elem check[2];
+   static struct git_attr_check *check;
static const struct ll_merge_options default_opts;
const char *ll_driver_name = NULL;
int marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
@@ -374,10 +365,14 @@ int ll_merge(mmbuffer_t *result_buf,
normalize_file(ours, path);
normalize_file(theirs, path);
}
-   if (!git_path_check_merge(path, check)) {
-   ll_driver_name = check[0].value;
-   if (check[1].value) {
-   marker_size = atoi(check[1].value);
+
+   if (!check)
+   check = git_attr_check_initl("merge", "conflict-marker-size", 
NULL);
+
+   if (!git_check_attr(path, check)) {
+   ll_driver_name = check->check[0].value;
+   if (check->check[1].value) {
+   marker_size = atoi(check->check[1].value);
if (marker_size <= 0)
marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
}
@@ -392,13 +387,13 @@ int ll_merge

Re: [RFC PATCH 0/4] pathspec labels [WAS: submodule groups]

2016-05-16 Thread Junio C Hamano
Stefan Beller  writes:

> This is another case for using ':' instead of '='.
> So I think ':' is better for this future enhancement.
>
> Also this future enhancement may ask for
>
>   git ls-files ":(attr:label=foo)"
>
> or
>
>   git ls-files ":(attr:-label)"
>
> so the user can circumvent the warn and ignore strategy. :(

That is exactly what we want, I would say, if we want to accept
"arbitrary set of attributes with their states".

The "warn and ignore" comes only from "with '(:label=X Y Z)', we
inspect attributes X, Y and Z and insist them to be set to true; it
is a configuration error to set the label to anything but a string",
and accepting "arbitrary set of attributes with their states" makes
it moot (as I said earlier in $gmane/294776).

So are we leaning towards ":(attr:)", where  is one of

var=value
var
-var
!var

now?  It makes the pathspec magic parser a bit more complex (and I
am not sure if we have to worry too much about quoting "value" part
to allow arbitrary sequence of bytes), though.

--
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: bug: autostash is lost after aborted rebase

2016-05-16 Thread Eugene Yarmash
The bug still persists when you abort the rebase by using :cq in Vim (exit
with an error code).
See also http://stackoverflow.com/q/37252108/244297



--
View this message in context: 
http://git.661346.n2.nabble.com/bug-autostash-is-lost-after-aborted-rebase-tp7611141p7656556.html
Sent from the git mailing list archive at Nabble.com.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 0/4] pathspec labels [WAS: submodule groups]

2016-05-16 Thread Stefan Beller
On Mon, May 16, 2016 at 2:18 PM, Junio C Hamano  wrote:
> Stefan Beller  writes:
>
>> This is another case for using ':' instead of '='.
>> So I think ':' is better for this future enhancement.
>>
>> Also this future enhancement may ask for
>>
>>   git ls-files ":(attr:label=foo)"
>>
>> or
>>
>>   git ls-files ":(attr:-label)"
>>
>> so the user can circumvent the warn and ignore strategy. :(
>
> That is exactly what we want, I would say, if we want to accept
> "arbitrary set of attributes with their states".
>
> The "warn and ignore" comes only from "with '(:label=X Y Z)', we
> inspect attributes X, Y and Z and insist them to be set to true; it
> is a configuration error to set the label to anything but a string",
> and accepting "arbitrary set of attributes with their states" makes
> it moot (as I said earlier in $gmane/294776).
>
> So are we leaning towards ":(attr:)", where  is one of
>
> var=value
> var
> -var
> !var
>
> now?  It makes the pathspec magic parser a bit more complex (and I
> am not sure if we have to worry too much about quoting "value" part
> to allow arbitrary sequence of bytes), though.

And we want to have both "label=A B C" and attr:label=A B C" or *just* the
attr query?

We should not allow the user to add arbitrary attributes (i.e. labels).
Instead each of the "attr for labeling purposes" needs to follow a clear scheme
that allows us to add attributes later on that are outside of that scheme.

In a very first implementation we could require the attribute to start with
"label=". ;)
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 0/4] pathspec labels [WAS: submodule groups]

2016-05-16 Thread Junio C Hamano
Stefan Beller  writes:

> And we want to have both "label=A B C" and attr:label=A B C" or *just* the
> attr query?

I think the choice at this point is between supporting just "label=A
B C" or supporting just "attr:eol=crlf text=auto !diff".

I think "attr:label=A" is merely a degenerated case of the latter.

> We should not allow the user to add arbitrary attributes (i.e. labels).

Hmph, why not?

> Instead each of the "attr for labeling purposes" needs to follow a clear 
> scheme
> that allows us to add attributes later on that are outside of that scheme.

That was my initial reaction when I saw Duy's "attr:crlf=auto" (by
the way, there is no such setting; crlf should be one of TRUE, UNSET
or set to string "input") idea.  But I do not think of a good
argument to justify that arbitrary attributes are not allowed.
--
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 2/2] difftool: handle unmerged files in dir-diff mode

2016-05-16 Thread Junio C Hamano
Thanks, will queue.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 0/4] pathspec labels [WAS: submodule groups]

2016-05-16 Thread Stefan Beller
On Mon, May 16, 2016 at 2:50 PM, Junio C Hamano  wrote:
> Stefan Beller  writes:
>
>> And we want to have both "label=A B C" and attr:label=A B C" or *just* the
>> attr query?
>
> I think the choice at this point is between supporting just "label=A
> B C" or supporting just "attr:eol=crlf text=auto !diff".
>
> I think "attr:label=A" is merely a degenerated case of the latter.
>
>> We should not allow the user to add arbitrary attributes (i.e. labels).

Because we cannot extend our attributes any further from that?

Consider a user starts using attr  for their labeling purposes.
Later (in 2 years) we decide that  is an attribute we want to
use to mark files as foo-ish. so we add meaning to that attribute
(just like eol.crlf does an arbitrary thing, foo would do another arbitrary
thing).

Then the user picks up the new version of Git and expects  to
still be a "I use it for labeling purposes only" thing. They would not
expect to all files labeled as  to start behaving  ?

> Hmph, why not?

We need a namespace for which
* we can guarantee that it is for labeling purposes only (even in the future)
* is obvious to the user to be a labeling name space

Starting with "label" offers both?

>
>> Instead each of the "attr for labeling purposes" needs to follow a clear 
>> scheme
>> that allows us to add attributes later on that are outside of that scheme.
>
> That was my initial reaction when I saw Duy's "attr:crlf=auto" (by
> the way, there is no such setting; crlf should be one of TRUE, UNSET
> or set to string "input") idea.  But I do not think of a good
> argument to justify that arbitrary attributes are not allowed.

I agree that querying for attr:eol or attr:diff is a good idea.

I do however want to point out that all labels for "labeling purposes"
MUST be a clear from the beginning, otherwise we'll have the maintenance
problem down the road?
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 0/4] pathspec labels [WAS: submodule groups]

2016-05-16 Thread Junio C Hamano
Stefan Beller  writes:

>> Hmph, why not?
>
> We need a namespace for which
> * we can guarantee that it is for labeling purposes only (even in the future)
> * is obvious to the user to be a labeling name space
>
> Starting with "label" offers both?

Ah, of course.  I thought that you were trying to limit ":(attr:)"
magic only to attributes that begin with "label-", which is where my
"why not?" comes from.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 0/4] pathspec labels [WAS: submodule groups]

2016-05-16 Thread Stefan Beller
On Mon, May 16, 2016 at 3:02 PM, Junio C Hamano  wrote:
> Stefan Beller  writes:
>
>>> Hmph, why not?
>>
>> We need a namespace for which
>> * we can guarantee that it is for labeling purposes only (even in the future)
>> * is obvious to the user to be a labeling name space
>>
>> Starting with "label" offers both?
>
> Ah, of course.  I thought that you were trying to limit ":(attr:)"
> magic only to attributes that begin with "label-", which is where my
> "why not?" comes from.

And going by the logic you presented before, we would
need to error out for the given pathspec ":()" if

* either the string is not well known (e.g. diif, eol )
* or is outside of the labeling namespace.

So we don't want to see users complaining about
"bug attr:foo worked as a label, now it is a feature; you broke my code"

We would need to ignore data from .gitattributes as it may be crafted from
a newer version of Git, but the command line argument still needs to die
for unknown arguments?

So asking for :(foo) would yield a

fatal: attr 'foo' is not known to Git, nor is it in the labeling name space

I guess what I am asking is if there is a nice way to query "do we know
this attribute?"

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 v6 00/17] Port branch.c to use ref-filter's printing options

2016-05-16 Thread Junio C Hamano
Karthik Nayak  writes:

> This is part of unification of the commands 'git tag -l, git branch -l
> and git for-each-ref'. This ports over branch.c to use ref-filter's
> printing options.
>
> Initially posted here: $(gmane/279226). It was decided that this series
> would follow up after refactoring ref-filter parsing mechanism, which
> is now merged into master (9606218b32344c5c756f7c29349d3845ef60b80c).

9606218b?

> Changes in this version:
>
> 1. Rebased on top of f307218 (t6302: simplify non-gpg cases).

Huh?

  $ git checkout f307218
  $ git am 0001-ref-filter-implement-if.txt
  Applying: ref-filter: implement %(if), %(then), and %(else) atoms
  error: patch failed: Documentation/git-for-each-ref.txt:181
  error: Documentation/git-for-each-ref.txt: patch does not apply
  Patch failed at 0001 ref-filter: implement %(if), %(then), and %(else) atoms
  The copy of the patch that failed is found in: .git/rebase-apply/patch
  When you have resolved this problem, run "git am --continue".
  If you prefer to skip this patch, run "git am --skip" instead.
  To restore the original branch and stop patching, run "git am --abort".
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 0/4] pathspec labels [WAS: submodule groups]

2016-05-16 Thread Junio C Hamano
Stefan Beller  writes:

>> Ah, of course.  I thought that you were trying to limit ":(attr:)"
>> magic only to attributes that begin with "label-", which is where my
>> "why not?" comes from.
>
> And going by the logic you presented before, we would
> need to error out for the given pathspec ":()" if
>
> * either the string is not well known (e.g. diif, eol )
> * or is outside of the labeling namespace.

I do not think that follows _my_ line of thought.  What is "well
known"?  Doesn't that change over time?

If we are to do the "attribute match", there is no useful
enforcement point.  An arbitrary version of Git cannot differentiate
a random cruft users will write in their .gitattributes from a
legitimate attribute that will be introduced in the future, so both
"data in .gitattributes" and "pathspec magic that referes to attribute"
cannot be limited by us.

So if we are going to take the arbitrary ":(attr:)"
route, "label-" prefix would be limitation on the "core Git" side
and does not limit what end-user does.  We will promise that we
won't use names that begin with the prefix ourselves and leave them
up to the projects.  If the end user uses an attribute "foo", which
does not begin with "label-", the end user is risking to be broken
by future versions of Git.

If you want to compile an authoritative list of attributes used by
core Git and maintain it forever, you are welcome to add warning,
but I wouldn't bother if I were doing this series, at least at the
beginning.

--
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 v5 2/9] connect: only match the host with core.gitProxy

2016-05-16 Thread Junio C Hamano
Mike Hommey  writes:

> Currently, core.gitProxy doesn't actually match purely on domain names
> as documented: it also matches ports.
> ...
> This per-port behavior seems like an oversight rather than a deliberate
> choice, so, make git://kernel.org:port/path call the gitProxy script in

Hmph.  The fact that hostandport, not just host after stripping
possible ":port" part, is passed to the function smells like a
deliberate design to allow people to use different proxy for
different port, so I am not sure everybody agrees with your "seems
like an oversight".

Don't existing users depend on the behaviour?  Isn't the change
robbing Peter to pay Paul?

--
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 v5 2/9] connect: only match the host with core.gitProxy

2016-05-16 Thread Mike Hommey
On Mon, May 16, 2016 at 03:30:01PM -0700, Junio C Hamano wrote:
> Mike Hommey  writes:
> 
> > Currently, core.gitProxy doesn't actually match purely on domain names
> > as documented: it also matches ports.
> > ...
> > This per-port behavior seems like an oversight rather than a deliberate
> > choice, so, make git://kernel.org:port/path call the gitProxy script in
> 
> Hmph.  The fact that hostandport, not just host after stripping
> possible ":port" part, is passed to the function smells like a
> deliberate design to allow people to use different proxy for
> different port, so I am not sure everybody agrees with your "seems
> like an oversight".
> 
> Don't existing users depend on the behaviour?  Isn't the change
> robbing Peter to pay Paul?

The gitProxy script gets the port passed. Why would you need different
scripts for different ports if the port is passed as an argument? Also,
if it's deliberate, it's widely undocumented.

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


Re: [PATCH v5 4/9] connect: make parse_connect_url() return separated host and port

2016-05-16 Thread Junio C Hamano
Mike Hommey  writes:

> + get_host_and_port(&host, &port);
> +
> + if (*host && !port) {
> + /* The host might contain a user:password string, ignore it
> +  * when searching for the port again */
> + char *end_user = strrchr(host, '@');
> + port = get_port(end_user ? end_user : host);

Scanning from the right because host part would never have '@', but
there could be an invalid URL with an unquoted '@' in userinfo part?
Then this makes sense.

> diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
> index 91a69fc..9acba2b 100755
> --- a/t/t5500-fetch-pack.sh
> +++ b/t/t5500-fetch-pack.sh
> @@ -553,7 +553,7 @@ check_prot_path () {
>   Diag: protocol=$2
>   Diag: path=$3
>   EOF
> - git fetch-pack --diag-url "$1" | grep -v hostandport= >actual &&
> + git fetch-pack --diag-url "$1" | grep -v host= | grep -v port= >actual 
> &&

A single process:

... | grep -v -e '^host=' -e '^port='

perhaps?

> @@ -562,22 +562,17 @@ check_prot_host_port_path () {
>   case "$2" in
>   *ssh*)
>   pp=ssh
> - uah=userandhost
> - ehost=$(echo $3 | tr -d "[]")
> - diagport="Diag: port=$4"
>   ;;
>   *)
> - pp=$p
> - uah=hostandport
> - ehost=$(echo $3$4 | sed -e "s/22$/:22/" -e "s/NONE//")
> - diagport=""
> + pp=$2
>   ;;
>   esac
> + ehost=$(echo $3 | tr -d "[]")
>   cat >exp <<-EOF &&
>   Diag: url=$1
>   Diag: protocol=$pp
> - Diag: $uah=$ehost
> - $diagport
> + Diag: userandhost=$ehost
> + Diag: port=$4
>   Diag: path=$5
>   EOF

This makes the diag output simpler and allows the caller to expect
the same set of variables, which is good.
--
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 v5 8/9] connect: actively reject git:// urls with a user part

2016-05-16 Thread Junio C Hamano
Mike Hommey  writes:

> Currently, urls of the for git://user@host don't work because user@host
> is not resolving at the DNS level, but we shouldn't be relying on it
> being an invalid host name, and actively reject it for containing a
> username in the first place.

Makes sense.  Connecting to host by stripping user@ would probably
give us a better behaviour, but this is a good first step even if we
are aiming for that endgame state.

>
> Signed-off-by: Mike Hommey 
> ---
>  connect.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/connect.c b/connect.c
> index df15ff3..fdd40b0 100644
> --- a/connect.c
> +++ b/connect.c
> @@ -716,6 +716,9 @@ struct child_process *git_connect(int fd[2], const char 
> *url,
>*/
>   struct strbuf target_host = STRBUF_INIT;
>   char *override_vhost = getenv("GIT_OVERRIDE_VIRTUAL_HOST");
> + if (user)
> + die("user@host is not allowed in git:// urls");
> +
>   if (override_vhost)
>   strbuf_addstr(&target_host, override_vhost);
>   else {
--
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 v5 4/9] connect: make parse_connect_url() return separated host and port

2016-05-16 Thread Mike Hommey
On Mon, May 16, 2016 at 03:39:08PM -0700, Junio C Hamano wrote:
> Mike Hommey  writes:
> 
> > +   get_host_and_port(&host, &port);
> > +
> > +   if (*host && !port) {
> > +   /* The host might contain a user:password string, ignore it
> > +* when searching for the port again */
> > +   char *end_user = strrchr(host, '@');
> > +   port = get_port(end_user ? end_user : host);
> 
> Scanning from the right because host part would never have '@', but
> there could be an invalid URL with an unquoted '@' in userinfo part?
> Then this makes sense.

Indeed, I forgot to update the comment after the discussion on this
list.

> > diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
> > index 91a69fc..9acba2b 100755
> > --- a/t/t5500-fetch-pack.sh
> > +++ b/t/t5500-fetch-pack.sh
> > @@ -553,7 +553,7 @@ check_prot_path () {
> > Diag: protocol=$2
> > Diag: path=$3
> > EOF
> > -   git fetch-pack --diag-url "$1" | grep -v hostandport= >actual &&
> > +   git fetch-pack --diag-url "$1" | grep -v host= | grep -v port= >actual 
> > &&
> 
> A single process:
> 
>   ... | grep -v -e '^host=' -e '^port='

heh, I'm actually replacing it with a single egrep in a subsequent
patch, following feedback from previous round, but missed that there was
this intermediate step with multiple greps still. Do you want an update
anyways, or does only the final result really matter? I guess I can
update it in any case, since I'll have to update the patch for the
comment above anyways.

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


Re: [PATCH v5 2/9] connect: only match the host with core.gitProxy

2016-05-16 Thread Junio C Hamano
Mike Hommey  writes:

> The gitProxy script gets the port passed. Why would you need different
> scripts for different ports if the port is passed as an argument? Also,
> if it's deliberate, it's widely undocumented.

Fair enough.

A user who has been working around thsi "oversight", would have
relied on her proxy configured with 'script for myhost.xz:9111' to
be called for git://myhost.xz:9111/path, right?  We'd need to
somehow let her know that her configuration will be broken, but as
long as we can find a way to do so to ease the transition, I think
the updated "if you want to use a different behaviour depending on
port, use the port parameter" is a lot more sensible behaviour than
what we had traditionally.


--
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/12] commit.c: use strchrnul() to scan for one line

2016-05-16 Thread Stefan Beller
On Mon, May 16, 2016 at 2:05 PM, Junio C Hamano  wrote:
> Signed-off-by: Junio C Hamano 
> ---
>  commit.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/commit.c b/commit.c
> index 3f4f371..1f9ee8a 100644
> --- a/commit.c
> +++ b/commit.c
> @@ -415,8 +415,7 @@ int find_commit_subject(const char *commit_buffer, const 
> char **subject)
> p++;
> if (*p) {
> p += 2;
> -   for (eol = p; *eol && *eol != '\n'; eol++)
> -   ; /* do nothing */
> +   eol = strchrnul(p, '\n');

Nit:
You could include the +2 into the arg of  strchrnul,
such that you can drop the braces.

> } else
> eol = p;
>
> --
> 2.8.2-748-gfb85f76
>
> --
> 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 02/12] attr.c: use strchrnul() to scan for one line

2016-05-16 Thread Stefan Beller
On Mon, May 16, 2016 at 2:05 PM, Junio C Hamano  wrote:
> Signed-off-by: Junio C Hamano 
> ---
>  attr.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/attr.c b/attr.c
> index eec5d7d..45aec1b 100644
> --- a/attr.c
> +++ b/attr.c
> @@ -402,8 +402,8 @@ static struct attr_stack *read_attr_from_index(const char 
> *path, int macro_ok)
> for (sp = buf; *sp; ) {
> char *ep;
> int more;
> -   for (ep = sp; *ep && *ep != '\n'; ep++)
> -   ;
> +
> +   ep = strchrnul(sp, '\n');

(Even lesser nit as in patch 1)
You could directly assign ep and more when declaring them.

> more = (*ep == '\n');
> *ep = '\0';
> handle_attr_line(res, sp, path, ++lineno, macro_ok);
> --
> 2.8.2-748-gfb85f76
>
> --
> 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 03/12] attr.c: update a stale comment on "struct match_attr"

2016-05-16 Thread Stefan Beller
On Mon, May 16, 2016 at 2:05 PM, Junio C Hamano  wrote:
> When 82dce998 (attr: more matching optimizations from .gitignore,
> 2012-10-15) changed a pointer to a string "*pattern" into an
> embedded "struct pattern" in struct match_attr, it forgot to update
> the comment that describes the structure.
>
> Signed-off-by: Junio C Hamano 
> ---
>  attr.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/attr.c b/attr.c
> index 45aec1b..4ae7801 100644
> --- a/attr.c
> +++ b/attr.c
> @@ -131,9 +131,8 @@ struct pattern {
>   * If is_macro is true, then u.attr is a pointer to the git_attr being
>   * defined.
>   *
> - * If is_macro is false, then u.pattern points at the filename pattern
> - * to which the rule applies.  (The memory pointed to is part of the
> - * memory block allocated for the match_attr instance.)
> + * If is_macro is false, then u.pat is the filename pattern to which the
> + * rule applies.

and we don't need to talk about memory ownership here as that
is clear for 'struct pattern' documented elsewhere?

>   *
>   * In either case, num_attr is the number of attributes affected by
>   * this rule, and state is an array listing them.  The attributes are
> --
> 2.8.2-748-gfb85f76
>
> --
> 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 03/12] attr.c: update a stale comment on "struct match_attr"

2016-05-16 Thread Junio C Hamano
On Mon, May 16, 2016 at 4:34 PM, Stefan Beller  wrote:
>> - * If is_macro is false, then u.pattern points at the filename pattern
>> - * to which the rule applies.  (The memory pointed to is part of the
>> - * memory block allocated for the match_attr instance.)
>> + * If is_macro is false, then u.pat is the filename pattern to which the
>> + * rule applies.
>
> and we don't need to talk about memory ownership here as that
> is clear for 'struct pattern' documented elsewhere?

It is embedded in the structure which you cannot lose independently, no?
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Bug] git-log prints wrong unixtime with --date=format:%s

2016-05-16 Thread Michael Heerdegen
Hello,

the command

   git log --pretty=format:%ad --date=format:%s

displays wrong unixtime values; apparently how much the printed value
differs from the expected value depends on the system's time zone and
whether daylight savings time is enabled or not.

Here is a reproducible recipe compiled by Yuri Khan who helped me
localizing the problem and whom I CC'd:

0. Versions

$ git --version
git version 2.8.2

$ dpkg -l tzdata | tail -1
ii  tzdata  2016d-0ubuntu0.16.04 all  time zone and
daylight-saving time data

1. Initialize an empty Git repository:

$ git init test
$ cd test

2. Make a commit, using the Europe/Berlin time zone:

$ TZ=Europe/Berlin git commit -m 'test' --allow-empty

3. Examine the timestamp recorded in the commit object:

$ git cat-file -p HEAD | grep author
author Yuri Khan  1463260938 +0200

4. Check that it corresponds to the current time:

$ date +%s
1463260977

5. Try to get the commit date in the unixtime format:

$ TZ=Europe/Berlin git log --pretty=format:%ad --date=format:%s -1

Expected result: 1463260938 (same as recorded in the commit object).
Observed result: 1463264538 (3600s = one hour ahead).

For lulz, use another time zone:

$ TZ=Asia/Novosibirsk git log --pretty=format:%ad --date=format:%s -1

Expected result: 1463260938 (unixtime is always UTC and should not
depend on TZ).
Observed result: 1463246538 (-14400s = 4 hours behind).

Not even specifying the UTC time zone helps:

$ TZ=UTC git log --pretty=format:%ad --date=format:%s -1

Expected result: still 1463260938.
Observed result: 1463268138 (7200s = 2 hours ahead).


FWIW, personally I have not bound the TZ environment variable, my time
zone is constantly that of Berlin, currently CEST.

Many thanks in advance,


Michael.

--
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/12] commit.c: use strchrnul() to scan for one line

2016-05-16 Thread Junio C Hamano
On Mon, May 16, 2016 at 4:19 PM, Stefan Beller  wrote:
>> if (*p) {
>> p += 2;
>> -   for (eol = p; *eol && *eol != '\n'; eol++)
>> -   ; /* do nothing */
>> +   eol = strchrnul(p, '\n');
>
> Nit:
> You could include the +2 into the arg of  strchrnul,
> such that you can drop the braces.

You're right. With or without braces,

  eol = strchrnul(p + 2, '\n');

would be easier to understand (I do not know offhand if the value of p
matters after this part, as I am responding from GMail Web UI without
access to the wider context in the source, though).
--
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/12] attr.c: use strchrnul() to scan for one line

2016-05-16 Thread Junio C Hamano
On Mon, May 16, 2016 at 4:28 PM, Stefan Beller  wrote:
>> for (sp = buf; *sp; ) {
>> char *ep;
>> int more;
>> -   for (ep = sp; *ep && *ep != '\n'; ep++)
>> -   ;
>> +
>> +   ep = strchrnul(sp, '\n');
>
> (Even lesser nit as in patch 1)
> You could directly assign ep and more when declaring them.

I'd prefer not to.

"A declaration block, blank and statement" pattern allows you
to have the declaration of variables to group related things
together and in an order that makes it easier to explain.
If you throw in initialization there, you cannot do that anymore
(e.g. ep must be initialized before you can compute more).
--
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/12] commit.c: use strchrnul() to scan for one line

2016-05-16 Thread Stefan Beller
On Mon, May 16, 2016 at 4:41 PM, Junio C Hamano  wrote:
> On Mon, May 16, 2016 at 4:19 PM, Stefan Beller  wrote:
>>> if (*p) {
>>> p += 2;
>>> -   for (eol = p; *eol && *eol != '\n'; eol++)
>>> -   ; /* do nothing */
>>> +   eol = strchrnul(p, '\n');
>>
>> Nit:
>> You could include the +2 into the arg of  strchrnul,
>> such that you can drop the braces.
>
> You're right. With or without braces,
>
>   eol = strchrnul(p + 2, '\n');
>
> would be easier to understand (I do not know offhand if the value of p
> matters after this part, as I am responding from GMail Web UI without
> access to the wider context in the source, though).

Heh, good point, I did not think it through apparently. `p` matters.
--
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 push --quiet option does not seem to work

2016-05-16 Thread Chris B
>> Once I included the whole email in my reply, but otherwise I deleted it
>> all.

> Both are bad practice. If you are considerate with the reader's time, this
> consideration is typically reprocicated. So it is a good idea to save the
> reader time by giving them the precise context they need.

This is among a few reasons I don't understand why in 2016 we use mail
lists for this kind of stuff. First time I've had to deal with this
since the 1990's so I forgot how it works.

On Mon, May 16, 2016 at 11:17 AM, Jeff King  wrote:
> On Mon, May 16, 2016 at 05:04:34PM +0200, Johannes Schindelin wrote:
>
>> > Anyway, it is not a Powershell thing. I tested on another repo on
>> > GitHub and it worked as expected. So I guess indeed the problem lies
>> > with Microsoft's implementation.
>>
>> This is *really* unclear.
>>
>> What "Microsoft's implementation"??? Do you refer to VSTS, or do you refer
>> to Git for Windows, or PowerShell?
>>
>> Please. To make it really simple for everybody involved, try to repeat as
>> closely as possible the same push from PowerShell, Git CMD and Git Bash.
>> We want to compare oranges to oranges.

As I was mentioning GitHub I assumed "Microsoft implementation" would
indicate their hosted Git service "Visual Studio Team Services".

I really didn't think there was anything else to provide. The feedback
lead me to test with Github and with that I verified that when the
remote was for Github it worked, but when the remote was VSTS it was
not.. and "not working" means not paying attention to "--quiet"
setting only with git push, while it does work for other commands such
as clone. (though I think I have to re-test with pull.)

The problem is not with Powershell (though how it handles seeing
output in STDERR is not anything I agree with). I was merely trying to
point out that 'git push --quiet' was not working until we realized it
was with VSTS.

This "ticket" if it exists as such in a maillist can be closed.

I think this accurately sums it up:

> The "bug" is that the server is asking the client to write non-error
> output to stderr, even though the client should have asked the server to
> be quiet (though it would not hurt to check that it is doing so by
> looking at the output of GIT_TRACE_PACKET).
>
> -Peff
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v6 0/9] connect: various cleanups

2016-05-16 Thread Mike Hommey
The main difference here is patch 2/9 now throwing an error in user's face
when they have a core.gitProxy configuration with a port number. There might
be some bikeshedding to do on the content of the error message.

Mike Hommey (9):
  connect: call get_host_and_port() earlier
  connect: only match the host with core.gitProxy
  connect: fill the host header in the git protocol with the host and
port variables
  connect: make parse_connect_url() return separated host and port
  connect: group CONNECT_DIAG_URL handling code
  connect: make parse_connect_url() return the user part of the url as a
separate value
  connect: change the --diag-url output to separate user and host
  connect: actively reject git:// urls with a user part
  connect: move ssh command line preparation to a separate function

 connect.c  | 243 +
 t/t5500-fetch-pack.sh  |  42 ++---
 t/t5532-fetch-proxy.sh |   8 +-
 3 files changed, 183 insertions(+), 110 deletions(-)

-- 
2.8.2.411.ga570dec.dirty

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


[PATCH v6 5/9] connect: group CONNECT_DIAG_URL handling code

2016-05-16 Thread Mike Hommey
Previous changes made both branches handling CONNECT_DIAG_URL identical.
We can now remove one of those branches and have CONNECT_DIAG_URL be
handled in one place.

Signed-off-by: Mike Hommey 
---
 connect.c | 16 +---
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/connect.c b/connect.c
index 4ce83f7..3a77b2f 100644
--- a/connect.c
+++ b/connect.c
@@ -708,7 +708,7 @@ struct child_process *git_connect(int fd[2], const char 
*url,
signal(SIGCHLD, SIG_DFL);
 
protocol = parse_connect_url(url, &host, &port, &path);
-   if ((flags & CONNECT_DIAG_URL) && (protocol != PROTO_SSH)) {
+   if (flags & CONNECT_DIAG_URL) {
printf("Diag: url=%s\n", url ? url : "NULL");
printf("Diag: protocol=%s\n", prot_name(protocol));
printf("Diag: userandhost=%s\n", host ? host : "NULL");
@@ -778,20 +778,6 @@ struct child_process *git_connect(int fd[2], const char 
*url,
int putty = 0, tortoiseplink = 0;
transport_check_allowed("ssh");
 
-   if (flags & CONNECT_DIAG_URL) {
-   printf("Diag: url=%s\n", url ? url : "NULL");
-   printf("Diag: protocol=%s\n", 
prot_name(protocol));
-   printf("Diag: userandhost=%s\n", host ? host : 
"NULL");
-   printf("Diag: port=%s\n", port ? port : "NONE");
-   printf("Diag: path=%s\n", path ? path : "NULL");
-
-   free(host);
-   free(port);
-   free(path);
-   free(conn);
-   return NULL;
-   }
-
ssh = getenv("GIT_SSH_COMMAND");
if (!ssh) {
const char *base;
-- 
2.8.2.411.ga570dec.dirty

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


[PATCH v6 8/9] connect: actively reject git:// urls with a user part

2016-05-16 Thread Mike Hommey
Currently, urls of the for git://user@host don't work because user@host
is not resolving at the DNS level, but we shouldn't be relying on it
being an invalid host name, and actively reject it for containing a
username in the first place.

Signed-off-by: Mike Hommey 
---
 connect.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/connect.c b/connect.c
index dcaf32f..7360d57 100644
--- a/connect.c
+++ b/connect.c
@@ -733,6 +733,9 @@ struct child_process *git_connect(int fd[2], const char 
*url,
 */
struct strbuf target_host = STRBUF_INIT;
char *override_vhost = getenv("GIT_OVERRIDE_VIRTUAL_HOST");
+   if (user)
+   die("user@host is not allowed in git:// urls");
+
if (override_vhost)
strbuf_addstr(&target_host, override_vhost);
else {
-- 
2.8.2.411.ga570dec.dirty

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


[PATCH v6 2/9] connect: only match the host with core.gitProxy

2016-05-16 Thread Mike Hommey
Currently, core.gitProxy doesn't actually match purely on domain names
as documented: it also matches ports.

So a core.gitProxy value like "script for kernel.org" doesn't make the
script called for an url like git://kernel.org:port/path, while it is
called for git://kernel.org/path.

This per-port behavior seems like an oversight rather than a deliberate
choice, so, make git://kernel.org:port/path call the gitProxy script in
the case described above.

However, if people have been relying on this behavior, git now fails
with an error message inviting for a configuration change.

Signed-off-by: Mike Hommey 
---
 connect.c  | 20 +---
 t/t5532-fetch-proxy.sh |  8 +++-
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/connect.c b/connect.c
index d3448c2..0f48cde 100644
--- a/connect.c
+++ b/connect.c
@@ -490,6 +490,8 @@ static void git_tcp_connect(int fd[2], const char *host, 
const char *port,
 }
 
 
+static char *get_port(char *host);
+
 static char *git_proxy_command;
 
 static int git_proxy_command_options(const char *var, const char *value,
@@ -517,10 +519,14 @@ static int git_proxy_command_options(const char *var, 
const char *value,
/* matches everybody */
matchlen = strlen(value);
else {
-   hostlen = strlen(for_pos + 5);
+   struct strbuf host = STRBUF_INIT;
+   char *port;
+   strbuf_addstr(&host, for_pos + 5);
+   port = get_port(host.buf);
+   hostlen = strlen(host.buf);
if (rhost_len < hostlen)
matchlen = -1;
-   else if (!strncmp(for_pos + 5,
+   else if (!strncmp(host.buf,
  rhost_name + rhost_len - hostlen,
  hostlen) &&
 ((rhost_len == hostlen) ||
@@ -528,6 +534,14 @@ static int git_proxy_command_options(const char *var, 
const char *value,
matchlen = for_pos - value;
else
matchlen = -1;
+   if (matchlen > 0 && port)
+   die("core.gitProxy only supports \"for "
+   "host/domain\", not \"for host:port\".\n"
+   "Please change your configuration "
+   "accordingly.\nPlease note that the port "
+   "is given as second argument to the proxy "
+   "script.\n");
+   strbuf_release(&host);
}
if (0 <= matchlen) {
/* core.gitproxy = none for kernel.org */
@@ -706,7 +720,7 @@ struct child_process *git_connect(int fd[2], const char 
*url,
/* These underlying connection commands die() if they
 * cannot connect.
 */
-   if (git_use_proxy(hostandport))
+   if (git_use_proxy(host))
conn = git_proxy_connect(fd, host, port);
else
git_tcp_connect(fd, host, port, flags);
diff --git a/t/t5532-fetch-proxy.sh b/t/t5532-fetch-proxy.sh
index 51c9669..efa80f8 100755
--- a/t/t5532-fetch-proxy.sh
+++ b/t/t5532-fetch-proxy.sh
@@ -33,7 +33,9 @@ test_expect_success 'setup proxy script' '
 
 test_expect_success 'setup local repo' '
git remote add fake git://example.com/remote &&
-   git config core.gitproxy ./proxy
+   git remote add fake_b git://example.org/remote &&
+   git config core.gitproxy "./proxy for example.com" &&
+   git config --add core.gitproxy "./proxy for example.org:9418"
 '
 
 test_expect_success 'fetch through proxy works' '
@@ -43,4 +45,8 @@ test_expect_success 'fetch through proxy works' '
test_cmp expect actual
 '
 
+test_expect_success 'core.gitProxy with port fails' '
+   test_must_fail git fetch fake_b
+'
+
 test_done
-- 
2.8.2.411.ga570dec.dirty

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


[PATCH v6 1/9] connect: call get_host_and_port() earlier

2016-05-16 Thread Mike Hommey
Currently, get_host_and_port() is called in git_connect() for the ssh
protocol, and in git_tcp_connect_sock() for the git protocol. Instead
of doing this, just call it from a single place, right after
parse_connect_url(), and pass the host and port separately to
git_*_connect() functions.

We however preserve hostandport, at least for now.

Note that in git_tcp_connect_sock, the port was set to "" in a
case that never can happen, so that code path was removed.

Signed-off-by: Mike Hommey 
---
 connect.c | 47 +++
 1 file changed, 23 insertions(+), 24 deletions(-)

diff --git a/connect.c b/connect.c
index c53f3f1..d3448c2 100644
--- a/connect.c
+++ b/connect.c
@@ -343,18 +343,16 @@ static const char *ai_name(const struct addrinfo *ai)
 /*
  * Returns a connected socket() fd, or else die()s.
  */
-static int git_tcp_connect_sock(char *host, int flags)
+static int git_tcp_connect_sock(const char *host, const char *port, int flags)
 {
struct strbuf error_message = STRBUF_INIT;
int sockfd = -1;
-   const char *port = STR(DEFAULT_GIT_PORT);
struct addrinfo hints, *ai0, *ai;
int gai;
int cnt = 0;
 
-   get_host_and_port(&host, &port);
-   if (!*port)
-   port = "";
+   if (!port)
+   port = STR(DEFAULT_GIT_PORT);
 
memset(&hints, 0, sizeof(hints));
if (flags & CONNECT_IPV4)
@@ -411,11 +409,10 @@ static int git_tcp_connect_sock(char *host, int flags)
 /*
  * Returns a connected socket() fd, or else die()s.
  */
-static int git_tcp_connect_sock(char *host, int flags)
+static int git_tcp_connect_sock(const char *host, const char *port, int flags)
 {
struct strbuf error_message = STRBUF_INIT;
int sockfd = -1;
-   const char *port = STR(DEFAULT_GIT_PORT);
char *ep;
struct hostent *he;
struct sockaddr_in sa;
@@ -423,7 +420,8 @@ static int git_tcp_connect_sock(char *host, int flags)
unsigned int nport;
int cnt;
 
-   get_host_and_port(&host, &port);
+   if (!port)
+   port = STR(DEFAULT_GIT_PORT);
 
if (flags & CONNECT_VERBOSE)
fprintf(stderr, "Looking up %s ... ", host);
@@ -482,9 +480,10 @@ static int git_tcp_connect_sock(char *host, int flags)
 #endif /* NO_IPV6 */
 
 
-static void git_tcp_connect(int fd[2], char *host, int flags)
+static void git_tcp_connect(int fd[2], const char *host, const char *port,
+   int flags)
 {
-   int sockfd = git_tcp_connect_sock(host, flags);
+   int sockfd = git_tcp_connect_sock(host, port, flags);
 
fd[0] = sockfd;
fd[1] = dup(sockfd);
@@ -550,18 +549,16 @@ static int git_use_proxy(const char *host)
return (git_proxy_command && *git_proxy_command);
 }
 
-static struct child_process *git_proxy_connect(int fd[2], char *host)
+static struct child_process *git_proxy_connect(int fd[2], const char *host,
+  const char *port)
 {
-   const char *port = STR(DEFAULT_GIT_PORT);
struct child_process *proxy;
 
-   get_host_and_port(&host, &port);
-
proxy = xmalloc(sizeof(*proxy));
child_process_init(proxy);
argv_array_push(&proxy->args, git_proxy_command);
argv_array_push(&proxy->args, host);
-   argv_array_push(&proxy->args, port);
+   argv_array_push(&proxy->args, port ? port : STR(DEFAULT_GIT_PORT));
proxy->in = -1;
proxy->out = -1;
if (start_command(proxy))
@@ -672,7 +669,8 @@ static struct child_process no_fork = CHILD_PROCESS_INIT;
 struct child_process *git_connect(int fd[2], const char *url,
  const char *prog, int flags)
 {
-   char *hostandport, *path;
+   char *hostandport, *path, *host;
+   const char *port = NULL;
struct child_process *conn = &no_fork;
enum protocol protocol;
struct strbuf cmd = STRBUF_INIT;
@@ -683,6 +681,8 @@ struct child_process *git_connect(int fd[2], const char 
*url,
signal(SIGCHLD, SIG_DFL);
 
protocol = parse_connect_url(url, &hostandport, &path);
+   host = xstrdup(hostandport);
+   get_host_and_port(&host, &port);
if ((flags & CONNECT_DIAG_URL) && (protocol != PROTO_SSH)) {
printf("Diag: url=%s\n", url ? url : "NULL");
printf("Diag: protocol=%s\n", prot_name(protocol));
@@ -707,9 +707,9 @@ struct child_process *git_connect(int fd[2], const char 
*url,
 * cannot connect.
 */
if (git_use_proxy(hostandport))
-   conn = git_proxy_connect(fd, hostandport);
+   conn = git_proxy_connect(fd, host, port);
else
-   git_tcp_connect(fd, hostandport, flags);
+   git_tcp_connect(fd, host, port, flags);
/*
 * Separate original protocol components prog and

[PATCH v6 3/9] connect: fill the host header in the git protocol with the host and port variables

2016-05-16 Thread Mike Hommey
The last use of the hostandport variable, besides being strdup'ed before
being split into host and port, is to fill the host header in the git
protocol.

Instead of relying on parse_connect_url() to return a host:port string
that makes sense there, construct one from the host and port variables.

Signed-off-by: Mike Hommey 
---
 connect.c | 27 ---
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/connect.c b/connect.c
index 0f48cde..0676ee0 100644
--- a/connect.c
+++ b/connect.c
@@ -709,11 +709,24 @@ struct child_process *git_connect(int fd[2], const char 
*url,
 * connect, unless the user has overridden us in
 * the environment.
 */
-   char *target_host = getenv("GIT_OVERRIDE_VIRTUAL_HOST");
-   if (target_host)
-   target_host = xstrdup(target_host);
-   else
-   target_host = xstrdup(hostandport);
+   struct strbuf target_host = STRBUF_INIT;
+   char *override_vhost = getenv("GIT_OVERRIDE_VIRTUAL_HOST");
+   if (override_vhost)
+   strbuf_addstr(&target_host, override_vhost);
+   else {
+   /* If the host contains a colon (ipv6 address), it
+* needs to be enclosed with square brackets. */
+   const char *colon = strchr(host, ':');
+   if (colon)
+   strbuf_addch(&target_host, '[');
+   strbuf_addstr(&target_host, host);
+   if (colon)
+   strbuf_addch(&target_host, ']');
+   if (port) {
+   strbuf_addch(&target_host, ':');
+   strbuf_addstr(&target_host, port);
+   }
+   }
 
transport_check_allowed("git");
 
@@ -734,8 +747,8 @@ struct child_process *git_connect(int fd[2], const char 
*url,
packet_write(fd[1],
 "%s %s%chost=%s%c",
 prog, path, 0,
-target_host, 0);
-   free(target_host);
+target_host.buf, 0);
+   strbuf_release(&target_host);
} else {
conn = xmalloc(sizeof(*conn));
child_process_init(conn);
-- 
2.8.2.411.ga570dec.dirty

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


[PATCH v6 7/9] connect: change the --diag-url output to separate user and host

2016-05-16 Thread Mike Hommey
Signed-off-by: Mike Hommey 
---
 connect.c |  6 ++
 t/t5500-fetch-pack.sh | 14 --
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/connect.c b/connect.c
index 2659b40..dcaf32f 100644
--- a/connect.c
+++ b/connect.c
@@ -720,10 +720,8 @@ struct child_process *git_connect(int fd[2], const char 
*url,
if (flags & CONNECT_DIAG_URL) {
printf("Diag: url=%s\n", url ? url : "NULL");
printf("Diag: protocol=%s\n", prot_name(protocol));
-   if (user)
-   printf("Diag: userandhost=%s@%s\n", user, host);
-   else
-   printf("Diag: userandhost=%s\n", host ? host : "NULL");
+   printf("Diag: user=%s\n", user ? user : "NULL");
+   printf("Diag: host=%s\n", host ? host : "NULL");
printf("Diag: port=%s\n", port ? port : "NONE");
printf("Diag: path=%s\n", path ? path : "NULL");
conn = NULL;
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 739c6b1..2d9c4be 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -553,7 +553,7 @@ check_prot_path () {
Diag: protocol=$2
Diag: path=$3
EOF
-   git fetch-pack --diag-url "$1" | egrep -v '(host|port)=' >actual &&
+   git fetch-pack --diag-url "$1" | egrep -v "(user|host|port)=" >actual &&
test_cmp expected actual
 }
 
@@ -568,10 +568,20 @@ check_prot_host_port_path () {
;;
esac
ehost=$(echo $3 | tr -d "[]")
+   case "$ehost" in
+   *@*)
+   user=${ehost%@*}
+   ehost=${ehost#$user@}
+   ;;
+   *)
+   user=NULL
+   ;;
+   esac
cat >exp <<-EOF &&
Diag: url=$1
Diag: protocol=$pp
-   Diag: userandhost=$ehost
+   Diag: user=$user
+   Diag: host=$ehost
Diag: port=$4
Diag: path=$5
EOF
-- 
2.8.2.411.ga570dec.dirty

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


  1   2   >