Re: [PATCH] tests: turn on test-lint-shell-syntax by default

2013-01-13 Thread Torsten Bögershausen
On 12.01.13 07:00, Junio C Hamano wrote:
 Torsten Bögershausen tbo...@web.de writes:
 
 The test Makefile has a default set of lint tests which are run
 as part of make test.

 The macro TEST_LINT defaults to test-lint-duplicates test-lint-executable.

 Add test-lint-shell-syntax here, to detect non-portable shell syntax early.

 Signed-off-by: Torsten Bögershausen tbo...@web.de
 ---
 
 As I said already, I do not want to do this yet without further
 reduction of false positives.
Which reinds me that the expression fishing for which is really poor.

How about something like the following:

-- 8 --
Subject: [PATCH] Reduce false positive in check-non-portable-shell.pl

check-non-portable-shell.pl is using simple regular expressions to
find illegal shell syntax.
Improve the expressions and reduce the chance for false positves:

sed -i must be followed by 1..n whitespace and 1 non whitespace
declare must be followed by 1..n whitespace and 1 non whitespace
echo -n must be followed by 1..n whitespace and 1 non whitespace
which must be followed by 1..n whitespace, a string, end of line



diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl
index 8b5a71d..7151dd6 100755
--- a/t/check-non-portable-shell.pl
+++ b/t/check-non-portable-shell.pl
@@ -16,10 +16,10 @@ sub err {
 
 while () {
chomp;
-   /^\s*sed\s+-i/ and err 'sed -i is not portable';
-   /^\s*echo\s+-n/ and err 'echo -n is not portable (please use printf)';
-   /^\s*declare\s+/ and err 'arrays/declare not portable';
-   /^\s*[^#]\s*which\s/ and err 'which is not portable (please use type)';
+   /^\s*sed\s+-i\s+\S/ and err 'sed -i is not portable';
+   /^\s*echo\s+-n\s+\S/ and err 'echo -n is not portable (please use 
printf)';
+   /^\s*declare\s+\S/ and err 'arrays/declare not portable';
+   /^\s*[^#]\s*which\s+[-a-zA-Z0-9]+$/ and err 'which is not portable 
(please use type)';
/test\s+[^=]*==/ and err 'test a == b is not portable (please use =)';
# this resets our $. for each file
close ARGV if eof;

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


git list files

2013-01-13 Thread Стойчо Слепцов
Hi,

I was searching for some git- command to provide me a list of files
(in a git directory), same as ls,
but showing information from the last commit of the file instead.

lets, say the equivalent of the $ls -d b* within git.git root directory
would look like:


98746061 jrnieder 2010-08-12 17:11 Standardize-do-.-while-0-style   base85.c
c43cb386 pclouds  2012-10-26 22:53 Move-estimate_bisect_steps-to-li bisect.c
efc7df45 pclouds  2012-10-26 22:53 Move-print_commit_list-to-libgit bisect.h
837d395a barkalow 2010-01-18 13:06 Replace-parse_blob-with-an-expla blob.c
837d395a barkalow 2010-01-18 13:06 Replace-parse_blob-with-an-expla blob.h
ebcfa444 gitster  2012-07-23 20:56 Merge-branch-jn-block-sha1   block-sha1
d53a3503 pclouds  2012-06-07 19:05 Remove-i18n-legos-in-notifying-n branch.c
f9a482e6 peff 2012-03-26 19:51 checkout-suppress-tracking-messa branch.h
c566ea13 gitster  2013-01-11 18:34 Merge-branch-jc-merge-blobs  builtin
cf6c52fc gitster  2013-01-10 13:46 Merge-branch-jc-maint-fmt-merge- builtin.h
568508e7 gitster  2011-10-28 14:48 bulk-checkin-replace-fast-import
bulk-checkin.c
568508e7 gitster  2011-10-28 14:48 bulk-checkin-replace-fast-import
bulk-checkin.h
8c3710fd gitster  2012-06-04 11:51 tweak-bundle-verify-of-a-complet bundle.c
b76c561a gitster  2011-10-21 16:04 Merge-branch-jc-unseekable-bundl bundle.h


(pretty the same idea as what we see in github when reviewing a
repository under the Files tab.)

Unfortunately I couldn't find any suitable.

As suggested at http://git-scm.com/community I asked my question at
the Git user mailing list on Google Groups which is a nice place for
beginners to ask about anything,
and one of the valuable answers was:

Also I wouldn't hesitate to ask this question on the main Git list as
this question appears to be hard-core enough to warrant assisting of
someone knowledgeable about Git internals.

So here I am...

So is there such a command, or I have to build my own script, starting
from, lets say git-rev-list in addition with some diff?

At the beginning I was hoping that $git rev-list HEAD --no-walk
--all-match -- paths + some git status --porcelain could do the job
for me,
but seems git rev-list, same as git log stops at the first found
matching commit, without to take care that there are still more files
unsatisfied in the list...

isn't it supposed to satisfy all the files in the list when
--all-match -- paths are given?

Thank you in advance,
Blind.
--
To unsubscribe from this list: send the line 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: missing objects -- prevention

2013-01-13 Thread Jeff King
On Sun, Jan 13, 2013 at 06:26:53AM +0530, Sitaram Chamarty wrote:

  Right, I meant if you have receive.fsckObjects on. It won't help this
  situation at all, as we already do a connectivity check separate from
  the fsck. But I do recommend it in general, just because it helps catch
  bad objects before they gets disseminated to a wider audience (at which
  point it is often infeasible to rewind history). And it has found git
  bugs (e.g., null sha1s in tree entries).
 
 I will add this.  Any idea if there's a significant performance hit?

Not usually; we are already resolving all of the sent deltas as a
precaution, anyway. I do notice after a push to GitHub there is
sometimes a second or two of pause from the server before the push
status is shown. But I haven't narrowed it down to fsck (versus
connectivity check, versus our post-receive hook).

So you may want to keep an eye on the effects (and if you have numbers,
please share :) ).

 That's always the hard part.  System admins (at the Unix level) insist
 there's nothing wrong and no disk errors and so on...  that is why I
 was interested in network errors causing problems and so on.

Yeah, I feel bad saying well, this repo is totally corrupted, but it
couldn't possibly be git's fault, because that's not what its failure
modes look like. But luckily our Ops people are very understanding, and
most of the problems I have seen have turned out to be fs corruption
after all (the pack-refs things is the big exception).

 Thanks once again for your patient replies!

No problem. There aren't many people dealing with large-scale
server-side issues, so it's something that doesn't come up much on the
list. I'm happy to talk about it.

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


Re: [PATCH 0/8] Initial support for Python 3

2013-01-13 Thread John Keeping
On Sun, Jan 13, 2013 at 12:41:30AM +, John Keeping wrote:
 On Sat, Jan 12, 2013 at 06:43:04PM -0500, Pete Wyckoff wrote:
 Can you give me some hints about the byte/unicode string issues
 in git-p4.py?  There's really only one place that does:
 
 p4 = subprocess.Popen(p4 -G ...)
 marshal.load(p4.stdout)
 
 If that's the only issue, this might not be too paniful.
 
 The problem is that what gets loaded there is a dictionary (encoded by
 p4) that maps byte strings to byte strings, so all of the accesses to
 that dictionary need to either:
 
1) explicitly call encode() on a string constant
 or 2) use a byte string constant with a b prefix
 
 Or we could re-write the dictionary once, which handles the keys... but
 some of the values are also used as strings and we can't handle that as
 a one-off conversion since in other places we really do want the byte
 string (think content of binary files).
 
 Basically a thorough audit of all access to variables that come from p4
 would be needed, with explicit decode()s for authors, dates, etc.

Having thought about this a bit more, another possibility would be to
apply this transformation once using something like this (completely
untested, I haven't looked up the keys of interest):

-- 8 --

def _noop(s):
return s

def _decode(s):
return s.decode('utf-8')

CONVERSION_MAP = {
'user': _decode,
'data': _decode
}

d = marshal.load(p4.stdout)
retval = {}
for k, v in d.items():
key = k.decode('utf-8')
retval[key] = CONVERSION_MAP.get(key, _noop)(v)
return retval

-- 8 --

Obviously this isn't ideal but without p4 gaining a Python 3 output mode
I suspect this would be the best we could do.


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


[PATCH v3 00/31] nd/parse-pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy
Changes from v2 (it's hard to keep track of after the rebase, so I may
be missing something here):

 - rebased on top of recent master, incorporate changes in
   init_pathspec from jk/pathspec-literal and nd/pathspec-wildcard to
   parse_pathspec

 - kill strip_trailing_slash_from_submodules and treat_gitlinks
   (pretty sure it'll cause conflicts with as/check-ignore)

 - kill init_pathspec, match_pathspec, diff_tree_setup_paths and
   diff_tree_release_paths
 
 - check points for future pathspec development

As far as I understand the pathspec unification, I'd say we are
there, with a few exceptions like mv, external commands.. But those
are pretty much isolated.

I'll send another WIP series implementing :(icase) and :(glob), mainly
to show (me) how future pathspec feature development looks like after
this.

Nguyễn Thái Ngọc Duy (31):
  clean: remove unused variable seen
  Add copy_pathspec
  Add parse_pathspec() that converts cmdline args to struct pathspec
  parse_pathspec: save original pathspec for reporting
  Export parse_pathspec() and convert some get_pathspec() calls
  Guard against new pathspec magic in pathspec matching code
  clean: convert to use parse_pathspec
  parse_pathspec: add PATHSPEC_EMPTY_MATCH_ALL
  commit: convert to use parse_pathspec
  status: convert to use parse_pathspec
  rerere: convert to use parse_pathspec
  checkout: convert to use parse_pathspec
  rm: convert to use parse_pathspec
  parse_pathspec: support stripping submodule trailing slashes
  ls-files: convert to use parse_pathspec
  archive: convert to use parse_pathspec
  parse_pathspec: support stripping/checking submodule paths
  add: convert to use parse_pathspec
  Convert read_cache_preload() to take struct pathspec
  Convert unmerge_cache to take struct pathspec
  checkout: convert read_tree_some to take struct pathspec
  Convert report_path_error to take struct pathspec
  Convert refresh_index to take struct pathspec
  Convert {read,fill}_directory to take struct pathspec
  Convert add_files_to_cache to take struct pathspec
  Convert common_prefix() to use struct pathspec
  Remove diff_tree_{setup,release}_paths
  Remove init_pathspec() in favor of parse_pathspec()
  Remove match_pathspec() in favor of match_pathspec_depth()
  tree-diff: remove the use of pathspec's raw[] in follow-rename codepath
  Rename field raw to _raw in struct pathspec

 archive.c  |  18 +++--
 archive.h  |   2 +-
 builtin/add.c  | 155 +++--
 builtin/blame.c|  12 +--
 builtin/checkout.c |  44 ++-
 builtin/clean.c|  21 ++---
 builtin/commit.c   |  37 +
 builtin/diff-files.c   |   2 +-
 builtin/diff-index.c   |   2 +-
 builtin/diff.c |   6 +-
 builtin/grep.c |   6 +-
 builtin/log.c  |   2 +-
 builtin/ls-files.c |  72 +++---
 builtin/ls-tree.c  |  10 ++-
 builtin/mv.c   |  13 ++--
 builtin/rerere.c   |   6 +-
 builtin/reset.c|   4 +-
 builtin/rm.c   |  23 +++---
 builtin/update-index.c |   3 +-
 cache.h|  36 +++--
 diff-lib.c |   2 +-
 diff.h |   2 -
 dir.c  | 202 -
 dir.h  |   9 ++-
 merge-recursive.c  |   2 +-
 notes-merge.c  |   4 +-
 preload-index.c|  20 ++---
 read-cache.c   |   5 +-
 rerere.c   |   6 +-
 rerere.h   |   4 +-
 resolve-undo.c |   4 +-
 resolve-undo.h |   2 +-
 revision.c |  11 +--
 setup.c| 149 ++--
 tree-diff.c|  47 +++-
 tree-walk.c|   2 +
 tree.c |   4 +-
 tree.h |   2 +-
 wt-status.c|  17 ++---
 wt-status.h|   2 +-
 40 files changed, 460 insertions(+), 510 deletions(-)

-- 
1.8.0.rc2.23.g1fb49df

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


[PATCH v3 01/31] clean: remove unused variable seen

2013-01-13 Thread Nguyễn Thái Ngọc Duy

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

diff --git a/builtin/clean.c b/builtin/clean.c
index 69c1cda..4cdabe0 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -46,7 +46,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
struct strbuf buf = STRBUF_INIT;
struct string_list exclude_list = STRING_LIST_INIT_NODUP;
const char *qname;
-   char *seen = NULL;
struct option options[] = {
OPT__QUIET(quiet, N_(do not print names of files removed)),
OPT__DRY_RUN(show_only, N_(dry run)),
@@ -105,9 +104,6 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
 
fill_directory(dir, pathspec);
 
-   if (pathspec)
-   seen = xmalloc(argc  0 ? argc : 1);
-
for (i = 0; i  dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
int len, pos;
@@ -141,11 +137,9 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
if (lstat(ent-name, st))
continue;
 
-   if (pathspec) {
-   memset(seen, 0, argc  0 ? argc : 1);
+   if (pathspec)
matches = match_pathspec(pathspec, ent-name, len,
-0, seen);
-   }
+0, NULL);
 
if (S_ISDIR(st.st_mode)) {
strbuf_addstr(directory, ent-name);
@@ -184,7 +178,6 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
}
}
}
-   free(seen);
 
strbuf_release(directory);
string_list_clear(exclude_list, 0);
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line 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 02/31] Add copy_pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/mv.c | 13 +++--
 cache.h  |  1 +
 dir.c|  8 
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/builtin/mv.c b/builtin/mv.c
index 034fec9..16ce99b 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -15,8 +15,9 @@ static const char * const builtin_mv_usage[] = {
NULL
 };
 
-static const char **copy_pathspec(const char *prefix, const char **pathspec,
- int count, int base_name)
+static const char **internal_copy_pathspec(const char *prefix,
+  const char **pathspec,
+  int count, int base_name)
 {
int i;
const char **result = xmalloc((count + 1) * sizeof(const char *));
@@ -81,17 +82,17 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
if (read_cache()  0)
die(_(index file corrupt));
 
-   source = copy_pathspec(prefix, argv, argc, 0);
+   source = internal_copy_pathspec(prefix, argv, argc, 0);
modes = xcalloc(argc, sizeof(enum update_mode));
-   dest_path = copy_pathspec(prefix, argv + argc, 1, 0);
+   dest_path = internal_copy_pathspec(prefix, argv + argc, 1, 0);
 
if (dest_path[0][0] == '\0')
/* special case: . was normalized to  */
-   destination = copy_pathspec(dest_path[0], argv, argc, 1);
+   destination = internal_copy_pathspec(dest_path[0], argv, argc, 
1);
else if (!lstat(dest_path[0], st) 
S_ISDIR(st.st_mode)) {
dest_path[0] = add_slash(dest_path[0]);
-   destination = copy_pathspec(dest_path[0], argv, argc, 1);
+   destination = internal_copy_pathspec(dest_path[0], argv, argc, 
1);
} else {
if (argc != 1)
die(destination '%s' is not a directory, 
dest_path[0]);
diff --git a/cache.h b/cache.h
index c257953..72675a1 100644
--- a/cache.h
+++ b/cache.h
@@ -491,6 +491,7 @@ struct pathspec {
 };
 
 extern int init_pathspec(struct pathspec *, const char **);
+extern void copy_pathspec(struct pathspec *dst, const struct pathspec *src);
 extern void free_pathspec(struct pathspec *);
 extern int ce_path_match(const struct cache_entry *ce, const struct pathspec 
*pathspec);
 
diff --git a/dir.c b/dir.c
index e883a91..12a76d7 100644
--- a/dir.c
+++ b/dir.c
@@ -1559,6 +1559,14 @@ int init_pathspec(struct pathspec *pathspec, const char 
**paths)
return 0;
 }
 
+void copy_pathspec(struct pathspec *dst, const struct pathspec *src)
+{
+   *dst = *src;
+   dst-items = xmalloc(sizeof(struct pathspec_item) * dst-nr);
+   memcpy(dst-items, src-items,
+  sizeof(struct pathspec_item) * dst-nr);
+}
+
 void free_pathspec(struct pathspec *pathspec)
 {
free(pathspec-items);
-- 
1.8.0.rc2.23.g1fb49df

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


[PATCH v3 03/31] Add parse_pathspec() that converts cmdline args to struct pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy
Currently to fill a struct pathspec, we do:

   const char **paths;
   paths = get_pathspec(prefix, argv);
   ...
   init_pathspec(pathspec, paths);

paths can only carry bare strings, which loses information from
command line arguments such as pathspec magic or the prefix part's
length for each argument.

parse_pathspec() is introduced to combine the two calls into one. The
plan is gradually replace all get_pathspec() and init_pathspec() with
parse_pathspec(). get_pathspec() now becomes a thin wrapper of
parse_pathspec().

parse_pathspec() allows the caller to reject the pathspec magics that
it does not support. When a new pathspec magic is introduced, we can
enable it per command after making sure that all underlying code has no
problem with the new magic.

flags parameter is currently unused. But it would allow callers to
pass certain instructions to parse_pathspec, for example forcing
literal pathspec when no magic is used.

With the introduction of parse_pathspec, there are now two functions
that can initialize struct pathspec: init_pathspec and
parse_pathspec. Any semantic changes in struct pathspec must be
reflected in both functions. init_pathspec() will be phased out in
favor of parse_pathspec().

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 cache.h |   2 ++
 dir.c   |   4 +--
 dir.h   |   2 ++
 setup.c | 108 +---
 4 files changed, 90 insertions(+), 26 deletions(-)

diff --git a/cache.h b/cache.h
index 72675a1..759c62a 100644
--- a/cache.h
+++ b/cache.h
@@ -481,9 +481,11 @@ struct pathspec {
int nr;
unsigned int has_wildcard:1;
unsigned int recursive:1;
+   unsigned magic;
int max_depth;
struct pathspec_item {
const char *match;
+   unsigned magic;
int len;
int nowildcard_len;
int flags;
diff --git a/dir.c b/dir.c
index 12a76d7..8454c13 100644
--- a/dir.c
+++ b/dir.c
@@ -323,7 +323,7 @@ int match_pathspec_depth(const struct pathspec *ps,
 /*
  * Return the length of the simple part of a path match limiter.
  */
-static int simple_length(const char *match)
+int simple_length(const char *match)
 {
int len = -1;
 
@@ -335,7 +335,7 @@ static int simple_length(const char *match)
}
 }
 
-static int no_wildcard(const char *string)
+int no_wildcard(const char *string)
 {
return string[simple_length(string)] == '\0';
 }
diff --git a/dir.h b/dir.h
index ae1bc46..0cf5ccf 100644
--- a/dir.h
+++ b/dir.h
@@ -88,6 +88,8 @@ struct dir_struct {
 #define MATCHED_RECURSIVELY 1
 #define MATCHED_FNMATCH 2
 #define MATCHED_EXACTLY 3
+extern int simple_length(const char *match);
+extern int no_wildcard(const char *string);
 extern char *common_prefix(const char **pathspec);
 extern int match_pathspec(const char **pathspec, const char *name, int 
namelen, int prefix, char *seen);
 extern int match_pathspec_depth(const struct pathspec *pathspec,
diff --git a/setup.c b/setup.c
index f108c4b..92adefc 100644
--- a/setup.c
+++ b/setup.c
@@ -174,7 +174,7 @@ static struct pathspec_magic {
 
 /*
  * Take an element of a pathspec and check for magic signatures.
- * Append the result to the prefix.
+ * Append the result to the prefix. Return the magic bitmap.
  *
  * For now, we only parse the syntax and throw out anything other than
  * top magic.
@@ -185,10 +185,14 @@ static struct pathspec_magic {
  * the prefix part must always match literally, and a single stupid
  * string cannot express such a case.
  */
-static const char *prefix_pathspec(const char *prefix, int prefixlen, const 
char *elt)
+static unsigned prefix_pathspec(struct pathspec_item *item,
+   const char **raw, unsigned flags,
+   const char *prefix, int prefixlen,
+   const char *elt)
 {
unsigned magic = 0;
const char *copyfrom = elt;
+   char *match;
int i;
 
if (elt[0] != ':') {
@@ -241,39 +245,95 @@ static const char *prefix_pathspec(const char *prefix, 
int prefixlen, const char
}
 
if (magic  PATHSPEC_FROMTOP)
-   return xstrdup(copyfrom);
+   match = xstrdup(copyfrom);
else
-   return prefix_path(prefix, prefixlen, copyfrom);
+   match = prefix_path(prefix, prefixlen, copyfrom);
+   *raw = item-match = match;
+   item-len = strlen(item-match);
+   item-flags = 0;
+   if (limit_pathspec_to_literal())
+   item-nowildcard_len = item-len;
+   else
+   item-nowildcard_len = simple_length(item-match);
+   if (item-nowildcard_len  item-len 
+   item-match[item-nowildcard_len] == '*' 
+   no_wildcard(item-match + item-nowildcard_len + 1))
+   item-flags |= PATHSPEC_ONESTAR;
+   return magic;
 }
 
-const char **get_pathspec(const char *prefix, const char **pathspec)
+static int 

[PATCH v3 04/31] parse_pathspec: save original pathspec for reporting

2013-01-13 Thread Nguyễn Thái Ngọc Duy
We usually use pathspec_item's match field for pathspec error
reporting. However match (or raw) does not show the magic part,
which will play more important role later on. Preserve exact user
input for reporting.

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

diff --git a/cache.h b/cache.h
index 759c62a..136e4c7 100644
--- a/cache.h
+++ b/cache.h
@@ -485,6 +485,7 @@ struct pathspec {
int max_depth;
struct pathspec_item {
const char *match;
+   const char *original;
unsigned magic;
int len;
int nowildcard_len;
diff --git a/dir.c b/dir.c
index 8454c13..beb7532 100644
--- a/dir.c
+++ b/dir.c
@@ -1538,6 +1538,7 @@ int init_pathspec(struct pathspec *pathspec, const char 
**paths)
const char *path = paths[i];
 
item-match = path;
+   item-original = path;
item-len = strlen(path);
item-flags = 0;
if (limit_pathspec_to_literal()) {
diff --git a/setup.c b/setup.c
index 92adefc..a1ad012 100644
--- a/setup.c
+++ b/setup.c
@@ -249,6 +249,7 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
else
match = prefix_path(prefix, prefixlen, copyfrom);
*raw = item-match = match;
+   item-original = elt;
item-len = strlen(item-match);
item-flags = 0;
if (limit_pathspec_to_literal())
@@ -295,6 +296,7 @@ static void parse_pathspec(struct pathspec *pathspec,
 
pathspec-items = item = xmalloc(sizeof(*item));
item-match = prefix;
+   item-original = prefix;
item-nowildcard_len = item-len = strlen(prefix);
raw[0] = prefix;
raw[1] = NULL;
-- 
1.8.0.rc2.23.g1fb49df

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


[PATCH v3 05/31] Export parse_pathspec() and convert some get_pathspec() calls

2013-01-13 Thread Nguyễn Thái Ngọc Duy
These call sites follow the pattern:

   paths = get_pathspec(prefix, argv);
   init_pathspec(pathspec, paths);

which can be converted into a single parse_pathspec() call.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/grep.c | 4 +---
 builtin/ls-tree.c  | 8 +++-
 builtin/update-index.c | 3 +--
 cache.h| 6 ++
 revision.c | 4 ++--
 setup.c| 7 +++
 6 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/builtin/grep.c b/builtin/grep.c
index 0e1b6c8..705f9ff 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -630,7 +630,6 @@ int cmd_grep(int argc, const char **argv, const char 
*prefix)
const char *show_in_pager = NULL, *default_pager = dummy;
struct grep_opt opt;
struct object_array list = OBJECT_ARRAY_INIT;
-   const char **paths = NULL;
struct pathspec pathspec;
struct string_list path_list = STRING_LIST_INIT_NODUP;
int i;
@@ -857,8 +856,7 @@ int cmd_grep(int argc, const char **argv, const char 
*prefix)
verify_filename(prefix, argv[j], j == i);
}
 
-   paths = get_pathspec(prefix, argv + i);
-   init_pathspec(pathspec, paths);
+   parse_pathspec(pathspec, PATHSPEC_FROMTOP, 0, prefix, argv + i);
pathspec.max_depth = opt.max_depth;
pathspec.recursive = 1;
 
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index fb76e38..e03aaaf 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -166,7 +166,13 @@ int cmd_ls_tree(int argc, const char **argv, const char 
*prefix)
if (get_sha1(argv[0], sha1))
die(Not a valid object name %s, argv[0]);
 
-   init_pathspec(pathspec, get_pathspec(prefix, argv + 1));
+   /*
+* show_recursive() rolls its own matching code and is
+* generally ignorant of 'struct pathspec'. The magic mask
+* cannot be lifted until it is converted to use
+* match_pathspec_depth() or tree_entry_interesting()
+*/
+   parse_pathspec(pathspec, PATHSPEC_FROMTOP, 0, prefix, argv + 1);
for (i = 0; i  pathspec.nr; i++)
pathspec.items[i].nowildcard_len = pathspec.items[i].len;
pathspec.has_wildcard = 0;
diff --git a/builtin/update-index.c b/builtin/update-index.c
index ada1dff..6728e59 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -546,10 +546,9 @@ static int do_reupdate(int ac, const char **av,
 */
int pos;
int has_head = 1;
-   const char **paths = get_pathspec(prefix, av + 1);
struct pathspec pathspec;
 
-   init_pathspec(pathspec, paths);
+   parse_pathspec(pathspec, PATHSPEC_FROMTOP, 0, prefix, av + 1);
 
if (read_ref(HEAD, head_sha1))
/* If there is no HEAD, that means it is an initial
diff --git a/cache.h b/cache.h
index 136e4c7..858c7e4 100644
--- a/cache.h
+++ b/cache.h
@@ -474,6 +474,9 @@ extern int index_name_is_other(const struct index_state *, 
const char *, int);
 extern int ie_match_stat(const struct index_state *, struct cache_entry *, 
struct stat *, unsigned int);
 extern int ie_modified(const struct index_state *, struct cache_entry *, 
struct stat *, unsigned int);
 
+/* Pathspec magic */
+#define PATHSPEC_FROMTOP(10)
+
 #define PATHSPEC_ONESTAR 1 /* the pathspec pattern sastisfies GFNM_ONESTAR 
*/
 
 struct pathspec {
@@ -494,6 +497,9 @@ struct pathspec {
 };
 
 extern int init_pathspec(struct pathspec *, const char **);
+extern void parse_pathspec(struct pathspec *pathspec, unsigned magic_mask,
+  unsigned flags, const char *prefix,
+  const char **args);
 extern void copy_pathspec(struct pathspec *dst, const struct pathspec *src);
 extern void free_pathspec(struct pathspec *);
 extern int ce_path_match(const struct cache_entry *ce, const struct pathspec 
*pathspec);
diff --git a/revision.c b/revision.c
index 95d21e6..a044242 100644
--- a/revision.c
+++ b/revision.c
@@ -1851,8 +1851,8 @@ int setup_revisions(int argc, const char **argv, struct 
rev_info *revs, struct s
 */
ALLOC_GROW(prune_data.path, prune_data.nr+1, prune_data.alloc);
prune_data.path[prune_data.nr++] = NULL;
-   init_pathspec(revs-prune_data,
- get_pathspec(revs-prefix, prune_data.path));
+   parse_pathspec(revs-prune_data, PATHSPEC_FROMTOP, 0,
+  revs-prefix, prune_data.path);
}
 
if (revs-def == NULL)
diff --git a/setup.c b/setup.c
index a1ad012..0c9fc75 100644
--- a/setup.c
+++ b/setup.c
@@ -162,7 +162,6 @@ void verify_non_filename(const char *prefix, const char 
*arg)
  * { PATHSPEC_REGEXP, '\0', regexp },
  *
  */
-#define PATHSPEC_FROMTOP(10)
 
 static struct pathspec_magic {
unsigned bit;
@@ -276,9 +275,9 @@ static int pathspec_item_cmp(const void *a_, const void *b_)
  * Given command line 

[PATCH v3 06/31] Guard against new pathspec magic in pathspec matching code

2013-01-13 Thread Nguyễn Thái Ngọc Duy
GUARD_PATHSPEC() marks pathspec-sensitive code (basically anything in
'struct pathspec' except fields nr and original). GUARD_PATHSPEC()
is not supposed to fail. The steps for a new pathspec magic or
optimization would be:

 - update parse_pathspec, add extra information to struct pathspec

 - grep GUARD_PATHSPEC() and update all relevant code (or note those
   that won't work with your new stuff). Update GUARD_PATHSPEC mask
   accordingly.

 - update parse_pathspec calls to allow new magic. Make sure
   parse_pathspec() catches unsupported syntax early, not until
   GUARD_PATHSPEC catches it.

 - add tests to verify supported/unsupported commands both work as
   expected.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/diff.c |  2 ++
 cache.h|  7 +++
 dir.c  |  2 ++
 tree-diff.c| 19 +++
 tree-walk.c|  2 ++
 5 files changed, 32 insertions(+)

diff --git a/builtin/diff.c b/builtin/diff.c
index 8c2af6c..d237e0a 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -371,6 +371,8 @@ int cmd_diff(int argc, const char **argv, const char 
*prefix)
die(_(unhandled object '%s' given.), name);
}
if (rev.prune_data.nr) {
+   /* builtin_diff_b_f() */
+   GUARD_PATHSPEC(rev.prune_data, PATHSPEC_FROMTOP);
if (!path)
path = rev.prune_data.items[0].match;
paths += rev.prune_data.nr;
diff --git a/cache.h b/cache.h
index 858c7e4..1f51423 100644
--- a/cache.h
+++ b/cache.h
@@ -496,6 +496,13 @@ struct pathspec {
} *items;
 };
 
+#define GUARD_PATHSPEC(ps, mask) \
+   do { \
+   if ((ps)-magic  ~(mask)) \
+   die(BUG:%s:%d: unsupported magic %x,  \
+   __FILE__, __LINE__, (ps)-magic  ~(mask)); \
+   } while (0)
+
 extern int init_pathspec(struct pathspec *, const char **);
 extern void parse_pathspec(struct pathspec *pathspec, unsigned magic_mask,
   unsigned flags, const char *prefix,
diff --git a/dir.c b/dir.c
index beb7532..37280c8 100644
--- a/dir.c
+++ b/dir.c
@@ -282,6 +282,8 @@ int match_pathspec_depth(const struct pathspec *ps,
 {
int i, retval = 0;
 
+   GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP);
+
if (!ps-nr) {
if (!ps-recursive || ps-max_depth == -1)
return MATCHED_RECURSIVELY;
diff --git a/tree-diff.c b/tree-diff.c
index ba01563..68a9e7c 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -199,6 +199,25 @@ static void try_to_follow_renames(struct tree_desc *t1, 
struct tree_desc *t2, co
const char *paths[1];
int i;
 
+   /*
+* follow-rename code is very specific, we need exactly one
+* path. Magic that matches more than one path is not
+* supported.
+*/
+   GUARD_PATHSPEC(opt-pathspec, PATHSPEC_FROMTOP);
+#if 0
+   /*
+* We should reject wildcards as well. Unfortunately we
+* haven't got a reliable way to detect that 'foo\*bar' in
+* fact has no wildcards. nowildcard_len is merely a hint for
+* optimization. Let it slip for now until wildmatch is taught
+* about dry-run mode and returns wildcard info.
+*/
+   if (opt-pathspec.has_wildcard)
+   die(BUG:%s:%d: wildcards are not supported,
+   __FILE__, __LINE__);
+#endif
+
/* Remove the file creation entry from the diff queue, and remember it 
*/
choice = q-queue[0];
q-nr = 0;
diff --git a/tree-walk.c b/tree-walk.c
index 6e30ef9..dd03750 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -635,6 +635,8 @@ enum interesting tree_entry_interesting(const struct 
name_entry *entry,
enum interesting never_interesting = ps-has_wildcard ?
entry_not_interesting : all_entries_not_interesting;
 
+   GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP);
+
if (!ps-nr) {
if (!ps-recursive || ps-max_depth == -1)
return all_entries_interesting;
-- 
1.8.0.rc2.23.g1fb49df

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


[PATCH v3 07/31] clean: convert to use parse_pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/clean.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/builtin/clean.c b/builtin/clean.c
index 4cdabe0..fb0fe9a 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -42,7 +42,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
int rm_flags = REMOVE_DIR_KEEP_NESTED_GIT;
struct strbuf directory = STRBUF_INIT;
struct dir_struct dir;
-   static const char **pathspec;
+   struct pathspec pathspec;
struct strbuf buf = STRBUF_INIT;
struct string_list exclude_list = STRING_LIST_INIT_NODUP;
const char *qname;
@@ -100,9 +100,9 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
add_exclude(exclude_list.items[i].string, , 0,
dir.exclude_list[EXC_CMDL]);
 
-   pathspec = get_pathspec(prefix, argv);
+   parse_pathspec(pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
 
-   fill_directory(dir, pathspec);
+   fill_directory(dir, pathspec.raw);
 
for (i = 0; i  dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
@@ -137,9 +137,9 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
if (lstat(ent-name, st))
continue;
 
-   if (pathspec)
-   matches = match_pathspec(pathspec, ent-name, len,
-0, NULL);
+   if (pathspec.nr)
+   matches = match_pathspec_depth(pathspec, ent-name,
+  len, 0, NULL);
 
if (S_ISDIR(st.st_mode)) {
strbuf_addstr(directory, ent-name);
@@ -163,7 +163,7 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
}
strbuf_reset(directory);
} else {
-   if (pathspec  !matches)
+   if (pathspec.nr  !matches)
continue;
qname = quote_path_relative(ent-name, -1, buf, 
prefix);
if (show_only) {
-- 
1.8.0.rc2.23.g1fb49df

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


[PATCH v3 08/31] parse_pathspec: add PATHSPEC_EMPTY_MATCH_ALL

2013-01-13 Thread Nguyễn Thái Ngọc Duy
We have two ways of dealing with empty pathspec:

1. limit it to current prefix
2. match the entire working directory

Some commands go with #1, some with #2. get_pathspec() and
parse_pathspec() only supports #1. Make it support #2 too via
PATHSPEC_EMPTY_MATCH_ALL flag.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 cache.h | 3 +++
 setup.c | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/cache.h b/cache.h
index 1f51423..32231d8 100644
--- a/cache.h
+++ b/cache.h
@@ -503,6 +503,9 @@ struct pathspec {
__FILE__, __LINE__, (ps)-magic  ~(mask)); \
} while (0)
 
+/* parse_pathspec flags */
+#define PATHSPEC_EMPTY_MATCH_ALL (10) /* No args means match everything */
+
 extern int init_pathspec(struct pathspec *, const char **);
 extern void parse_pathspec(struct pathspec *pathspec, unsigned magic_mask,
   unsigned flags, const char *prefix,
diff --git a/setup.c b/setup.c
index 0c9fc75..d0b1d1f 100644
--- a/setup.c
+++ b/setup.c
@@ -289,6 +289,9 @@ void parse_pathspec(struct pathspec *pathspec,
if (!entry  !prefix)
return;
 
+   if (!*argv  (flags  PATHSPEC_EMPTY_MATCH_ALL))
+   return;
+
/* No arguments with prefix - prefix pathspec */
if (!entry) {
static const char *raw[2];
-- 
1.8.0.rc2.23.g1fb49df

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


[PATCH v3 09/31] commit: convert to use parse_pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy

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

diff --git a/builtin/commit.c b/builtin/commit.c
index d6dd3df..444ae1d 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -277,17 +277,17 @@ static char *prepare_index(int argc, const char **argv, 
const char *prefix,
 {
int fd;
struct string_list partial;
-   const char **pathspec = NULL;
+   struct pathspec pathspec;
char *old_index_env = NULL;
int refresh_flags = REFRESH_QUIET;
 
if (is_status)
refresh_flags |= REFRESH_UNMERGED;
+   parse_pathspec(pathspec, PATHSPEC_FROMTOP,
+  PATHSPEC_EMPTY_MATCH_ALL,
+  prefix, argv);
 
-   if (*argv)
-   pathspec = get_pathspec(prefix, argv);
-
-   if (read_cache_preload(pathspec)  0)
+   if (read_cache_preload(pathspec.raw)  0)
die(_(index file corrupt));
 
if (interactive) {
@@ -329,9 +329,9 @@ static char *prepare_index(int argc, const char **argv, 
const char *prefix,
 * (A) if all goes well, commit the real index;
 * (B) on failure, rollback the real index.
 */
-   if (all || (also  pathspec  *pathspec)) {
+   if (all || (also  pathspec.nr)) {
fd = hold_locked_index(index_lock, 1);
-   add_files_to_cache(also ? prefix : NULL, pathspec, 0);
+   add_files_to_cache(also ? prefix : NULL, pathspec.raw, 0);
refresh_cache_or_die(refresh_flags);
update_main_cache_tree(WRITE_TREE_SILENT);
if (write_cache(fd, active_cache, active_nr) ||
@@ -350,7 +350,7 @@ static char *prepare_index(int argc, const char **argv, 
const char *prefix,
 * and create commit from the_index.
 * We still need to refresh the index here.
 */
-   if (!only  (!pathspec || !*pathspec)) {
+   if (!only  !pathspec.nr) {
fd = hold_locked_index(index_lock, 1);
refresh_cache_or_die(refresh_flags);
if (active_cache_changed) {
@@ -395,7 +395,7 @@ static char *prepare_index(int argc, const char **argv, 
const char *prefix,
 
memset(partial, 0, sizeof(partial));
partial.strdup_strings = 1;
-   if (list_paths(partial, !current_head ? NULL : HEAD, prefix, 
pathspec))
+   if (list_paths(partial, !current_head ? NULL : HEAD, prefix, 
pathspec.raw))
exit(1);
 
discard_cache();
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line 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 10/31] status: convert to use parse_pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/commit.c |  9 +
 wt-status.c  | 17 +++--
 wt-status.h  |  2 +-
 3 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index 444ae1d..196dfab 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1205,11 +1205,12 @@ int cmd_status(int argc, const char **argv, const char 
*prefix)
handle_untracked_files_arg(s);
if (show_ignored_in_status)
s.show_ignored_files = 1;
-   if (*argv)
-   s.pathspec = get_pathspec(prefix, argv);
+   parse_pathspec(s.pathspec, PATHSPEC_FROMTOP,
+  PATHSPEC_EMPTY_MATCH_ALL,
+  prefix, argv);
 
-   read_cache_preload(s.pathspec);
-   refresh_index(the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, 
NULL, NULL);
+   read_cache_preload(s.pathspec.raw);
+   refresh_index(the_index, REFRESH_QUIET|REFRESH_UNMERGED, 
s.pathspec.raw, NULL, NULL);
 
fd = hold_locked_index(index_lock, 0);
if (0 = fd)
diff --git a/wt-status.c b/wt-status.c
index 2a9658b..76edadc 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -434,7 +434,7 @@ static void wt_status_collect_changes_worktree(struct 
wt_status *s)
}
rev.diffopt.format_callback = wt_status_collect_changed_cb;
rev.diffopt.format_callback_data = s;
-   init_pathspec(rev.prune_data, s-pathspec);
+   copy_pathspec(rev.prune_data, s-pathspec);
run_diff_files(rev, 0);
 }
 
@@ -459,22 +459,20 @@ static void wt_status_collect_changes_index(struct 
wt_status *s)
rev.diffopt.detect_rename = 1;
rev.diffopt.rename_limit = 200;
rev.diffopt.break_opt = 0;
-   init_pathspec(rev.prune_data, s-pathspec);
+   copy_pathspec(rev.prune_data, s-pathspec);
run_diff_index(rev, 1);
 }
 
 static void wt_status_collect_changes_initial(struct wt_status *s)
 {
-   struct pathspec pathspec;
int i;
 
-   init_pathspec(pathspec, s-pathspec);
for (i = 0; i  active_nr; i++) {
struct string_list_item *it;
struct wt_status_change_data *d;
struct cache_entry *ce = active_cache[i];
 
-   if (!ce_path_match(ce, pathspec))
+   if (!ce_path_match(ce, s-pathspec))
continue;
it = string_list_insert(s-change, ce-name);
d = it-util;
@@ -489,7 +487,6 @@ static void wt_status_collect_changes_initial(struct 
wt_status *s)
else
d-index_status = DIFF_STATUS_ADDED;
}
-   free_pathspec(pathspec);
 }
 
 static void wt_status_collect_untracked(struct wt_status *s)
@@ -505,11 +502,11 @@ static void wt_status_collect_untracked(struct wt_status 
*s)
DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;
setup_standard_excludes(dir);
 
-   fill_directory(dir, s-pathspec);
+   fill_directory(dir, s-pathspec.raw);
for (i = 0; i  dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
if (cache_name_is_other(ent-name, ent-len) 
-   match_pathspec(s-pathspec, ent-name, ent-len, 0, NULL))
+   match_pathspec_depth(s-pathspec, ent-name, ent-len, 0, 
NULL))
string_list_insert(s-untracked, ent-name);
free(ent);
}
@@ -517,11 +514,11 @@ static void wt_status_collect_untracked(struct wt_status 
*s)
if (s-show_ignored_files) {
dir.nr = 0;
dir.flags = DIR_SHOW_IGNORED | DIR_SHOW_OTHER_DIRECTORIES;
-   fill_directory(dir, s-pathspec);
+   fill_directory(dir, s-pathspec.raw);
for (i = 0; i  dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
if (cache_name_is_other(ent-name, ent-len) 
-   match_pathspec(s-pathspec, ent-name, ent-len, 0, 
NULL))
+   match_pathspec_depth(s-pathspec, ent-name, 
ent-len, 0, NULL))
string_list_insert(s-ignored, ent-name);
free(ent);
}
diff --git a/wt-status.h b/wt-status.h
index 236b41f..dd8df41 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -44,7 +44,7 @@ struct wt_status {
int is_initial;
char *branch;
const char *reference;
-   const char **pathspec;
+   struct pathspec pathspec;
int verbose;
int amend;
enum commit_whence whence;
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line 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 11/31] rerere: convert to use parse_pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/rerere.c | 6 +++---
 rerere.c | 8 
 rerere.h | 4 +++-
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/builtin/rerere.c b/builtin/rerere.c
index dc1708e..a573c4a 100644
--- a/builtin/rerere.c
+++ b/builtin/rerere.c
@@ -68,11 +68,11 @@ int cmd_rerere(int argc, const char **argv, const char 
*prefix)
return rerere(flags);
 
if (!strcmp(argv[0], forget)) {
-   const char **pathspec;
+   struct pathspec pathspec;
if (argc  2)
warning('git rerere forget' without paths is 
deprecated);
-   pathspec = get_pathspec(prefix, argv + 1);
-   return rerere_forget(pathspec);
+   parse_pathspec(pathspec, PATHSPEC_FROMTOP, 0, prefix, argv + 
1);
+   return rerere_forget(pathspec);
}
 
fd = setup_rerere(merge_rr, flags);
diff --git a/rerere.c b/rerere.c
index a6a5cd5..f8ddf85 100644
--- a/rerere.c
+++ b/rerere.c
@@ -655,7 +655,7 @@ static int rerere_forget_one_path(const char *path, struct 
string_list *rr)
return 0;
 }
 
-int rerere_forget(const char **pathspec)
+int rerere_forget(struct pathspec *pathspec)
 {
int i, fd;
struct string_list conflict = STRING_LIST_INIT_DUP;
@@ -666,12 +666,12 @@ int rerere_forget(const char **pathspec)
 
fd = setup_rerere(merge_rr, RERERE_NOAUTOUPDATE);
 
-   unmerge_cache(pathspec);
+   unmerge_cache(pathspec-raw);
find_conflict(conflict);
for (i = 0; i  conflict.nr; i++) {
struct string_list_item *it = conflict.items[i];
-   if (!match_pathspec(pathspec, it-string, strlen(it-string),
-   0, NULL))
+   if (!match_pathspec_depth(pathspec, it-string, 
strlen(it-string),
+ 0, NULL))
continue;
rerere_forget_one_path(it-string, merge_rr);
}
diff --git a/rerere.h b/rerere.h
index 156d2aa..4aa06c9 100644
--- a/rerere.h
+++ b/rerere.h
@@ -3,6 +3,8 @@
 
 #include string-list.h
 
+struct pathspec;
+
 #define RERERE_AUTOUPDATE   01
 #define RERERE_NOAUTOUPDATE 02
 
@@ -16,7 +18,7 @@ extern void *RERERE_RESOLVED;
 extern int setup_rerere(struct string_list *, int);
 extern int rerere(int);
 extern const char *rerere_path(const char *hex, const char *file);
-extern int rerere_forget(const char **);
+extern int rerere_forget(struct pathspec *);
 extern int rerere_remaining(struct string_list *);
 extern void rerere_clear(struct string_list *);
 extern void rerere_gc(struct string_list *);
-- 
1.8.0.rc2.23.g1fb49df

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


[PATCH v3 12/31] checkout: convert to use parse_pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy
This commit introduces a subtle bug:

- when match_pathspec() returns seen[], it follows the order of the
  input const char **pathspec, which is now pathspec.raw[]

- when match_pathspec() returns seen[], it follows the order of
  pathspec.items[]

- due to 86e4ca6 (tree_entry_interesting(): fix depth limit with
  overlapping pathspecs - 2010-12-15), pathspec.items[] is sorted, but
  pathspec.raw[] is NOT.

by converting from match_pathspec() to match_pathspec_depth(), we also
have to switch the original path array. Unfortunately we can't because
this array is processed by report_path_error() and it's also used by
builtin/ls-files.c, which still uses the old indexing.

The bug causes wrong error messages (e.g. if the first pathspec is
faulty, it may report the second..) The bug will be dealt with after
ls-files is converted.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/checkout.c | 37 +
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index a9c1b5a..3e60f2e 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -45,7 +45,7 @@ struct checkout_opts {
 
int branch_exists;
const char *prefix;
-   const char **pathspec;
+   struct pathspec pathspec;
struct tree *source_tree;
 };
 
@@ -256,39 +256,37 @@ static int checkout_paths(const struct checkout_opts 
*opts,
 
if (opts-patch_mode)
return run_add_interactive(revision, --patch=checkout,
-  opts-pathspec);
+  opts-pathspec.raw);
 
lock_file = xcalloc(1, sizeof(struct lock_file));
 
newfd = hold_locked_index(lock_file, 1);
-   if (read_cache_preload(opts-pathspec)  0)
+   if (read_cache_preload(opts-pathspec.raw)  0)
return error(_(corrupt index file));
 
if (opts-source_tree)
-   read_tree_some(opts-source_tree, opts-pathspec);
+   read_tree_some(opts-source_tree, opts-pathspec.raw);
 
-   for (pos = 0; opts-pathspec[pos]; pos++)
-   ;
-   ps_matched = xcalloc(1, pos);
+   ps_matched = xcalloc(1, opts-pathspec.nr);
 
for (pos = 0; pos  active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
if (opts-source_tree  !(ce-ce_flags  CE_UPDATE))
continue;
-   match_pathspec(opts-pathspec, ce-name, ce_namelen(ce), 0, 
ps_matched);
+   match_pathspec_depth(opts-pathspec, ce-name, ce_namelen(ce), 
0, ps_matched);
}
 
-   if (report_path_error(ps_matched, opts-pathspec, opts-prefix))
+   if (report_path_error(ps_matched, opts-pathspec.raw, opts-prefix))
return 1;
 
/* checkout -m path to recreate conflicted state */
if (opts-merge)
-   unmerge_cache(opts-pathspec);
+   unmerge_cache(opts-pathspec.raw);
 
/* Any unmerged paths? */
for (pos = 0; pos  active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
-   if (match_pathspec(opts-pathspec, ce-name, ce_namelen(ce), 0, 
NULL)) {
+   if (match_pathspec_depth(opts-pathspec, ce-name, 
ce_namelen(ce), 0, NULL)) {
if (!ce_stage(ce))
continue;
if (opts-force) {
@@ -315,7 +313,7 @@ static int checkout_paths(const struct checkout_opts *opts,
struct cache_entry *ce = active_cache[pos];
if (opts-source_tree  !(ce-ce_flags  CE_UPDATE))
continue;
-   if (match_pathspec(opts-pathspec, ce-name, ce_namelen(ce), 0, 
NULL)) {
+   if (match_pathspec_depth(opts-pathspec, ce-name, 
ce_namelen(ce), 0, NULL)) {
if (!ce_stage(ce)) {
errs |= checkout_entry(ce, state, NULL);
continue;
@@ -960,7 +958,7 @@ static int switch_unborn_to_new_branch(const struct 
checkout_opts *opts)
 static int checkout_branch(struct checkout_opts *opts,
   struct branch_info *new)
 {
-   if (opts-pathspec)
+   if (opts-pathspec.nr)
die(_(paths cannot be used with switching branches));
 
if (opts-patch_mode)
@@ -1110,9 +1108,16 @@ int cmd_checkout(int argc, const char **argv, const char 
*prefix)
}
 
if (argc) {
-   opts.pathspec = get_pathspec(prefix, argv);
+   /*
+* In patch mode (opts.patch_mode != 0), we pass the
+* pathspec to an external program, git-add--interactive.
+* Do not accept any kind of magic that that program
+* cannot handle. Magic mask is pretty safe to be
+* lifted for new magic when opts.patch_mode == 0.
+*/
+   

[PATCH v3 13/31] rm: convert to use parse_pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/rm.c | 23 +++
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/builtin/rm.c b/builtin/rm.c
index dabfcf6..1a2c932 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -216,7 +216,7 @@ static struct option builtin_rm_options[] = {
 int cmd_rm(int argc, const char **argv, const char *prefix)
 {
int i, newfd;
-   const char **pathspec;
+   struct pathspec pathspec;
char *seen;
 
git_config(git_default_config, NULL);
@@ -249,31 +249,30 @@ int cmd_rm(int argc, const char **argv, const char 
*prefix)
}
}
 
-   pathspec = get_pathspec(prefix, argv);
-   refresh_index(the_index, REFRESH_QUIET, pathspec, NULL, NULL);
+   parse_pathspec(pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
+   refresh_index(the_index, REFRESH_QUIET, pathspec.raw, NULL, NULL);
 
seen = NULL;
-   for (i = 0; pathspec[i] ; i++)
-   /* nothing */;
-   seen = xcalloc(i, 1);
+   seen = xcalloc(pathspec.nr, 1);
 
for (i = 0; i  active_nr; i++) {
struct cache_entry *ce = active_cache[i];
-   if (!match_pathspec(pathspec, ce-name, ce_namelen(ce), 0, 
seen))
+   if (!match_pathspec_depth(pathspec, ce-name, ce_namelen(ce), 
0, seen))
continue;
ALLOC_GROW(list.entry, list.nr + 1, list.alloc);
list.entry[list.nr].name = ce-name;
list.entry[list.nr++].is_submodule = S_ISGITLINK(ce-ce_mode);
}
 
-   if (pathspec) {
-   const char *match;
+   if (pathspec.nr) {
+   const char *original;
int seen_any = 0;
-   for (i = 0; (match = pathspec[i]) != NULL ; i++) {
+   for (i = 0; i  pathspec.nr; i++) {
+   original = pathspec.items[i].original;
if (!seen[i]) {
if (!ignore_unmatch) {
die(_(pathspec '%s' did not match any 
files),
-   match);
+   original);
}
}
else {
@@ -281,7 +280,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
}
if (!recursive  seen[i] == MATCHED_RECURSIVELY)
die(_(not removing '%s' recursively without 
-r),
-   *match ? match : .);
+   *original ? original : .);
}
 
if (! seen_any)
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line 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 14/31] parse_pathspec: support stripping submodule trailing slashes

2013-01-13 Thread Nguyễn Thái Ngọc Duy
This flag is equivalent to builtin/ls-files.c:strip_trailing_slashes()
and is intended to replace that function when ls-files is converted to
use parse_pathspec.

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

diff --git a/cache.h b/cache.h
index 32231d8..611a410 100644
--- a/cache.h
+++ b/cache.h
@@ -505,6 +505,7 @@ struct pathspec {
 
 /* parse_pathspec flags */
 #define PATHSPEC_EMPTY_MATCH_ALL (10) /* No args means match everything */
+#define PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP (11)
 
 extern int init_pathspec(struct pathspec *, const char **);
 extern void parse_pathspec(struct pathspec *pathspec, unsigned magic_mask,
diff --git a/setup.c b/setup.c
index d0b1d1f..a1aabc2 100644
--- a/setup.c
+++ b/setup.c
@@ -250,6 +250,15 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
*raw = item-match = match;
item-original = elt;
item-len = strlen(item-match);
+
+   if ((flags  PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP) 
+   (item-len = 1  item-match[item-len - 1] == '/') 
+   (i = cache_name_pos(item-match, item-len - 1)) = 0 
+   S_ISGITLINK(active_cache[i]-ce_mode)) {
+   item-len--;
+   match[item-len] = '\0';
+   }
+
item-flags = 0;
if (limit_pathspec_to_literal())
item-nowildcard_len = item-len;
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line 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 16/31] archive: convert to use parse_pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy

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

diff --git a/archive.c b/archive.c
index 93e00bb..f1a28c9 100644
--- a/archive.c
+++ b/archive.c
@@ -151,7 +151,6 @@ int write_archive_entries(struct archiver_args *args,
struct archiver_context context;
struct unpack_trees_options opts;
struct tree_desc t;
-   struct pathspec pathspec;
int err;
 
if (args-baselen  0  args-base[args-baselen - 1] == '/') {
@@ -186,10 +185,8 @@ int write_archive_entries(struct archiver_args *args,
git_attr_set_direction(GIT_ATTR_INDEX, the_index);
}
 
-   init_pathspec(pathspec, args-pathspec);
-   err = read_tree_recursive(args-tree, , 0, 0, pathspec,
+   err = read_tree_recursive(args-tree, , 0, 0, args-pathspec,
  write_archive_entry, context);
-   free_pathspec(pathspec);
if (err == READ_TREE_RECURSIVE)
err = 0;
return err;
@@ -231,8 +228,15 @@ static int path_exists(struct tree *tree, const char *path)
 static void parse_pathspec_arg(const char **pathspec,
struct archiver_args *ar_args)
 {
-   ar_args-pathspec = pathspec = get_pathspec(, pathspec);
-   if (pathspec) {
+   /*
+* raw[] is used to check for unused pathspec. This is
+* tree_entry_interesting's limitation because it does not
+* mark used pathspec. The magic mask cannot be lifted until
+* it does.
+*/
+   parse_pathspec(ar_args-pathspec, PATHSPEC_FROMTOP, 0, , pathspec);
+   if (ar_args-pathspec.nr) {
+   pathspec = ar_args-pathspec.raw;
while (*pathspec) {
if (!path_exists(ar_args-tree, *pathspec))
die(path not found: %s, *pathspec);
diff --git a/archive.h b/archive.h
index 895afcd..a98c49e 100644
--- a/archive.h
+++ b/archive.h
@@ -8,7 +8,7 @@ struct archiver_args {
const unsigned char *commit_sha1;
const struct commit *commit;
time_t time;
-   const char **pathspec;
+   struct pathspec pathspec;
unsigned int verbose : 1;
unsigned int worktree_attributes : 1;
unsigned int convert : 1;
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line 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 18/31] add: convert to use parse_pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/add.c | 106 +-
 1 file changed, 39 insertions(+), 67 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index 075312a..22076ff 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -153,33 +153,6 @@ static char *prune_directory(struct dir_struct *dir, const 
char **pathspec, int
return seen;
 }
 
-static void treat_gitlinks(const char **pathspec)
-{
-   int i;
-
-   if (!pathspec || !*pathspec)
-   return;
-
-   for (i = 0; i  active_nr; i++) {
-   struct cache_entry *ce = active_cache[i];
-   if (S_ISGITLINK(ce-ce_mode)) {
-   int len = ce_namelen(ce), j;
-   for (j = 0; pathspec[j]; j++) {
-   int len2 = strlen(pathspec[j]);
-   if (len2 = len || pathspec[j][len] != '/' ||
-   memcmp(ce-name, pathspec[j], len))
-   continue;
-   if (len2 == len + 1)
-   /* strip trailing slash */
-   pathspec[j] = xstrndup(ce-name, len);
-   else
-   die (_(Path '%s' is in submodule 
'%.*s'),
-   pathspec[j], len, ce-name);
-   }
-   }
-   }
-}
-
 static void refresh(int verbose, const char **pathspec)
 {
char *seen;
@@ -197,23 +170,6 @@ static void refresh(int verbose, const char **pathspec)
 free(seen);
 }
 
-static const char **validate_pathspec(int argc, const char **argv, const char 
*prefix)
-{
-   const char **pathspec = get_pathspec(prefix, argv);
-
-   if (pathspec) {
-   const char **p;
-   for (p = pathspec; *p; p++) {
-   if (has_symlink_leading_path(*p, strlen(*p))) {
-   int len = prefix ? strlen(prefix) : 0;
-   die(_('%s' is beyond a symbolic link), *p + 
len);
-   }
-   }
-   }
-
-   return pathspec;
-}
-
 int run_add_interactive(const char *revision, const char *patch_mode,
const char **pathspec)
 {
@@ -245,17 +201,20 @@ int run_add_interactive(const char *revision, const char 
*patch_mode,
 
 int interactive_add(int argc, const char **argv, const char *prefix, int patch)
 {
-   const char **pathspec = NULL;
+   struct pathspec pathspec;
 
-   if (argc) {
-   pathspec = validate_pathspec(argc, argv, prefix);
-   if (!pathspec)
-   return -1;
-   }
+   /*
+* Do not enable fancy magic here.  git-add--interactive may
+* not be able to handle it.
+*/
+   parse_pathspec(pathspec, PATHSPEC_FROMTOP,
+  PATHSPEC_EMPTY_MATCH_ALL |
+  PATHSPEC_SYMLINK_LEADING_PATH,
+  prefix, argv);
 
return run_add_interactive(NULL,
   patch ? --patch : NULL,
-  pathspec);
+  pathspec.raw);
 }
 
 static int edit_patch(int argc, const char **argv, const char *prefix)
@@ -367,7 +326,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 {
int exit_status = 0;
int newfd;
-   const char **pathspec;
+   struct pathspec pathspec;
struct dir_struct dir;
int flags;
int add_new_files;
@@ -415,11 +374,18 @@ int cmd_add(int argc, const char **argv, const char 
*prefix)
fprintf(stderr, _(Maybe you wanted to say 'git add .'?\n));
return 0;
}
-   pathspec = validate_pathspec(argc, argv, prefix);
 
if (read_cache()  0)
die(_(index file corrupt));
-   treat_gitlinks(pathspec);
+
+   /*
+* Check the pathspec '%s' did not match any files block
+* below before enabling new magic.
+*/
+   parse_pathspec(pathspec, PATHSPEC_FROMTOP,
+  PATHSPEC_SYMLINK_LEADING_PATH |
+  PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE,
+  prefix, argv);
 
if (add_new_files) {
int baselen;
@@ -432,33 +398,39 @@ int cmd_add(int argc, const char **argv, const char 
*prefix)
}
 
/* This picks up the paths that are not tracked */
-   baselen = fill_directory(dir, pathspec);
-   if (pathspec)
-   seen = prune_directory(dir, pathspec, baselen);
+   baselen = fill_directory(dir, pathspec.raw);
+   if (pathspec.nr)
+   seen = prune_directory(dir, pathspec.raw, baselen);
}
 
if (refresh_only) 

[PATCH v3 19/31] Convert read_cache_preload() to take struct pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/checkout.c   |  2 +-
 builtin/commit.c |  4 ++--
 builtin/diff-files.c |  2 +-
 builtin/diff-index.c |  2 +-
 builtin/diff.c   |  4 ++--
 cache.h  |  4 +++-
 preload-index.c  | 20 +++-
 7 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 3e60f2e..7ec5472 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -261,7 +261,7 @@ static int checkout_paths(const struct checkout_opts *opts,
lock_file = xcalloc(1, sizeof(struct lock_file));
 
newfd = hold_locked_index(lock_file, 1);
-   if (read_cache_preload(opts-pathspec.raw)  0)
+   if (read_cache_preload(opts-pathspec)  0)
return error(_(corrupt index file));
 
if (opts-source_tree)
diff --git a/builtin/commit.c b/builtin/commit.c
index 196dfab..069d853 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -287,7 +287,7 @@ static char *prepare_index(int argc, const char **argv, 
const char *prefix,
   PATHSPEC_EMPTY_MATCH_ALL,
   prefix, argv);
 
-   if (read_cache_preload(pathspec.raw)  0)
+   if (read_cache_preload(pathspec)  0)
die(_(index file corrupt));
 
if (interactive) {
@@ -1209,7 +1209,7 @@ int cmd_status(int argc, const char **argv, const char 
*prefix)
   PATHSPEC_EMPTY_MATCH_ALL,
   prefix, argv);
 
-   read_cache_preload(s.pathspec.raw);
+   read_cache_preload(s.pathspec);
refresh_index(the_index, REFRESH_QUIET|REFRESH_UNMERGED, 
s.pathspec.raw, NULL, NULL);
 
fd = hold_locked_index(index_lock, 0);
diff --git a/builtin/diff-files.c b/builtin/diff-files.c
index 46085f8..9200069 100644
--- a/builtin/diff-files.c
+++ b/builtin/diff-files.c
@@ -61,7 +61,7 @@ int cmd_diff_files(int argc, const char **argv, const char 
*prefix)
(rev.diffopt.output_format  DIFF_FORMAT_PATCH))
rev.combine_merges = rev.dense_combined_merges = 1;
 
-   if (read_cache_preload(rev.diffopt.pathspec.raw)  0) {
+   if (read_cache_preload(rev.diffopt.pathspec)  0) {
perror(read_cache_preload);
return -1;
}
diff --git a/builtin/diff-index.c b/builtin/diff-index.c
index 1c737f7..ce15b23 100644
--- a/builtin/diff-index.c
+++ b/builtin/diff-index.c
@@ -43,7 +43,7 @@ int cmd_diff_index(int argc, const char **argv, const char 
*prefix)
usage(diff_cache_usage);
if (!cached) {
setup_work_tree();
-   if (read_cache_preload(rev.diffopt.pathspec.raw)  0) {
+   if (read_cache_preload(rev.diffopt.pathspec)  0) {
perror(read_cache_preload);
return -1;
}
diff --git a/builtin/diff.c b/builtin/diff.c
index d237e0a..6b4e3f9 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -140,7 +140,7 @@ static int builtin_diff_index(struct rev_info *revs,
usage(builtin_diff_usage);
if (!cached) {
setup_work_tree();
-   if (read_cache_preload(revs-diffopt.pathspec.raw)  0) {
+   if (read_cache_preload(revs-diffopt.pathspec)  0) {
perror(read_cache_preload);
return -1;
}
@@ -240,7 +240,7 @@ static int builtin_diff_files(struct rev_info *revs, int 
argc, const char **argv
revs-combine_merges = revs-dense_combined_merges = 1;
 
setup_work_tree();
-   if (read_cache_preload(revs-diffopt.pathspec.raw)  0) {
+   if (read_cache_preload(revs-diffopt.pathspec)  0) {
perror(read_cache_preload);
return -1;
}
diff --git a/cache.h b/cache.h
index a49496e..fb8a1f7 100644
--- a/cache.h
+++ b/cache.h
@@ -182,6 +182,8 @@ struct cache_entry {
 #error CE_EXTENDED_FLAGS out of range
 #endif
 
+struct pathspec;
+
 /*
  * Copy the sha1 and stat state of a cache entry from one to
  * another. But we never change the name, or the hash state!
@@ -434,7 +436,7 @@ extern int init_db(const char *template_dir, unsigned int 
flags);
 
 /* Initialize and use the cache information */
 extern int read_index(struct index_state *);
-extern int read_index_preload(struct index_state *, const char **pathspec);
+extern int read_index_preload(struct index_state *, const struct pathspec 
*pathspec);
 extern int read_index_from(struct index_state *, const char *path);
 extern int is_index_unborn(struct index_state *);
 extern int read_index_unmerged(struct index_state *);
diff --git a/preload-index.c b/preload-index.c
index 49cb08d..dea9021 100644
--- a/preload-index.c
+++ b/preload-index.c
@@ -4,7 +4,8 @@
 #include cache.h
 
 #ifdef NO_PTHREADS
-static void preload_index(struct index_state *index, const char **pathspec)
+static void preload_index(struct index_state *index,
+ 

[PATCH v3 20/31] Convert unmerge_cache to take struct pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/checkout.c | 2 +-
 rerere.c   | 2 +-
 resolve-undo.c | 4 ++--
 resolve-undo.h | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 7ec5472..92b11ea 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -281,7 +281,7 @@ static int checkout_paths(const struct checkout_opts *opts,
 
/* checkout -m path to recreate conflicted state */
if (opts-merge)
-   unmerge_cache(opts-pathspec.raw);
+   unmerge_cache(opts-pathspec);
 
/* Any unmerged paths? */
for (pos = 0; pos  active_nr; pos++) {
diff --git a/rerere.c b/rerere.c
index f8ddf85..9d149fa 100644
--- a/rerere.c
+++ b/rerere.c
@@ -666,7 +666,7 @@ int rerere_forget(struct pathspec *pathspec)
 
fd = setup_rerere(merge_rr, RERERE_NOAUTOUPDATE);
 
-   unmerge_cache(pathspec-raw);
+   unmerge_cache(pathspec);
find_conflict(conflict);
for (i = 0; i  conflict.nr; i++) {
struct string_list_item *it = conflict.items[i];
diff --git a/resolve-undo.c b/resolve-undo.c
index 72b4612..1bfece2 100644
--- a/resolve-undo.c
+++ b/resolve-undo.c
@@ -156,7 +156,7 @@ int unmerge_index_entry_at(struct index_state *istate, int 
pos)
return unmerge_index_entry_at(istate, pos);
 }
 
-void unmerge_index(struct index_state *istate, const char **pathspec)
+void unmerge_index(struct index_state *istate, const struct pathspec *pathspec)
 {
int i;
 
@@ -165,7 +165,7 @@ void unmerge_index(struct index_state *istate, const char 
**pathspec)
 
for (i = 0; i  istate-cache_nr; i++) {
struct cache_entry *ce = istate-cache[i];
-   if (!match_pathspec(pathspec, ce-name, ce_namelen(ce), 0, 
NULL))
+   if (!match_pathspec_depth(pathspec, ce-name, ce_namelen(ce), 
0, NULL))
continue;
i = unmerge_index_entry_at(istate, i);
}
diff --git a/resolve-undo.h b/resolve-undo.h
index 8458769..81e8803 100644
--- a/resolve-undo.h
+++ b/resolve-undo.h
@@ -11,6 +11,6 @@ extern void resolve_undo_write(struct strbuf *, struct 
string_list *);
 extern struct string_list *resolve_undo_read(const char *, unsigned long);
 extern void resolve_undo_clear_index(struct index_state *);
 extern int unmerge_index_entry_at(struct index_state *, int);
-extern void unmerge_index(struct index_state *, const char **);
+extern void unmerge_index(struct index_state *, const struct pathspec *);
 
 #endif
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line 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 21/31] checkout: convert read_tree_some to take struct pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/checkout.c | 9 +++--
 tree.c | 4 ++--
 tree.h | 2 +-
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 92b11ea..97ea496 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -82,12 +82,9 @@ static int update_some(const unsigned char *sha1, const char 
*base, int baselen,
return 0;
 }
 
-static int read_tree_some(struct tree *tree, const char **pathspec)
+static int read_tree_some(struct tree *tree, const struct pathspec *pathspec)
 {
-   struct pathspec ps;
-   init_pathspec(ps, pathspec);
-   read_tree_recursive(tree, , 0, 0, ps, update_some, NULL);
-   free_pathspec(ps);
+   read_tree_recursive(tree, , 0, 0, pathspec, update_some, NULL);
 
/* update the index with the given tree's info
 * for all args, expanding wildcards, and exit
@@ -265,7 +262,7 @@ static int checkout_paths(const struct checkout_opts *opts,
return error(_(corrupt index file));
 
if (opts-source_tree)
-   read_tree_some(opts-source_tree, opts-pathspec.raw);
+   read_tree_some(opts-source_tree, opts-pathspec);
 
ps_matched = xcalloc(1, opts-pathspec.nr);
 
diff --git a/tree.c b/tree.c
index 62fed63..ff72f67 100644
--- a/tree.c
+++ b/tree.c
@@ -47,7 +47,7 @@ static int read_one_entry_quick(const unsigned char *sha1, 
const char *base, int
 }
 
 static int read_tree_1(struct tree *tree, struct strbuf *base,
-  int stage, struct pathspec *pathspec,
+  int stage, const struct pathspec *pathspec,
   read_tree_fn_t fn, void *context)
 {
struct tree_desc desc;
@@ -116,7 +116,7 @@ static int read_tree_1(struct tree *tree, struct strbuf 
*base,
 
 int read_tree_recursive(struct tree *tree,
const char *base, int baselen,
-   int stage, struct pathspec *pathspec,
+   int stage, const struct pathspec *pathspec,
read_tree_fn_t fn, void *context)
 {
struct strbuf sb = STRBUF_INIT;
diff --git a/tree.h b/tree.h
index 69bcb5e..9dc90ba 100644
--- a/tree.h
+++ b/tree.h
@@ -25,7 +25,7 @@ typedef int (*read_tree_fn_t)(const unsigned char *, const 
char *, int, const ch
 
 extern int read_tree_recursive(struct tree *tree,
   const char *base, int baselen,
-  int stage, struct pathspec *pathspec,
+  int stage, const struct pathspec *pathspec,
   read_tree_fn_t fn, void *context);
 
 extern int read_tree(struct tree *tree, int stage, struct pathspec *pathspec);
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line 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 22/31] Convert report_path_error to take struct pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy
This commit fixes a subtle bug in ls-files and commit:

- when match_pathspec() returns seen[], it follows the order of the
  input const char **pathspec, which is now pathspec.raw[]

- when match_pathspec() returns seen[], it follows the order of
  pathspec.items[]

- due to 86e4ca6 (tree_entry_interesting(): fix depth limit with
  overlapping pathspecs - 2010-12-15), pathspec.items[] is sorted, but
  pathspec.raw[] is NOT.

by converting from match_pathspec() to match_pathspec_depth(), we also
have to switch the original path array. We haven't done so because
there are other call sites of report_path_error() that relies on old
order. We now follow pathspec.items[] order.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/checkout.c |  2 +-
 builtin/commit.c   | 14 ++
 builtin/ls-files.c | 19 +++
 cache.h|  2 +-
 4 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 97ea496..d2fc996 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -273,7 +273,7 @@ static int checkout_paths(const struct checkout_opts *opts,
match_pathspec_depth(opts-pathspec, ce-name, ce_namelen(ce), 
0, ps_matched);
}
 
-   if (report_path_error(ps_matched, opts-pathspec.raw, opts-prefix))
+   if (report_path_error(ps_matched, opts-pathspec, opts-prefix))
return 1;
 
/* checkout -m path to recreate conflicted state */
diff --git a/builtin/commit.c b/builtin/commit.c
index 069d853..8777c19 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -181,20 +181,18 @@ static int commit_index_files(void)
  * and return the paths that match the given pattern in list.
  */
 static int list_paths(struct string_list *list, const char *with_tree,
- const char *prefix, const char **pattern)
+ const char *prefix, const struct pathspec *pattern)
 {
int i;
char *m;
 
-   if (!pattern)
+   if (!pattern-nr)
return 0;
 
-   for (i = 0; pattern[i]; i++)
-   ;
-   m = xcalloc(1, i);
+   m = xcalloc(1, pattern-nr);
 
if (with_tree) {
-   char *max_prefix = common_prefix(pattern);
+   char *max_prefix = common_prefix(pattern-raw);
overlay_tree_on_cache(with_tree, max_prefix ? max_prefix : 
prefix);
free(max_prefix);
}
@@ -205,7 +203,7 @@ static int list_paths(struct string_list *list, const char 
*with_tree,
 
if (ce-ce_flags  CE_UPDATE)
continue;
-   if (!match_pathspec(pattern, ce-name, ce_namelen(ce), 0, m))
+   if (!match_pathspec_depth(pattern, ce-name, ce_namelen(ce), 0, 
m))
continue;
item = string_list_insert(list, ce-name);
if (ce_skip_worktree(ce))
@@ -395,7 +393,7 @@ static char *prepare_index(int argc, const char **argv, 
const char *prefix,
 
memset(partial, 0, sizeof(partial));
partial.strdup_strings = 1;
-   if (list_paths(partial, !current_head ? NULL : HEAD, prefix, 
pathspec.raw))
+   if (list_paths(partial, !current_head ? NULL : HEAD, prefix, 
pathspec))
exit(1);
 
discard_cache();
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 8905bd3..4bf3238 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -349,15 +349,16 @@ void overlay_tree_on_cache(const char *tree_name, const 
char *prefix)
}
 }
 
-int report_path_error(const char *ps_matched, const char **pathspec, const 
char *prefix)
+int report_path_error(const char *ps_matched,
+ const struct pathspec *pathspec,
+ const char *prefix)
 {
/*
 * Make sure all pathspec matched; otherwise it is an error.
 */
struct strbuf sb = STRBUF_INIT;
-   const char *name;
int num, errors = 0;
-   for (num = 0; pathspec[num]; num++) {
+   for (num = 0; num  pathspec-nr; num++) {
int other, found_dup;
 
if (ps_matched[num])
@@ -365,13 +366,16 @@ int report_path_error(const char *ps_matched, const char 
**pathspec, const char
/*
 * The caller might have fed identical pathspec
 * twice.  Do not barf on such a mistake.
+* FIXME: parse_pathspec should have eliminated
+* duplicate pathspec.
 */
for (found_dup = other = 0;
-!found_dup  pathspec[other];
+!found_dup  other  pathspec-nr;
 other++) {
if (other == num || !ps_matched[other])
continue;
-   if (!strcmp(pathspec[other], pathspec[num]))
+   if (!strcmp(pathspec-items[other].original,
+   

[PATCH v3 24/31] Convert {read,fill}_directory to take struct pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/add.c  |  2 +-
 builtin/clean.c|  2 +-
 builtin/grep.c |  2 +-
 builtin/ls-files.c |  2 +-
 dir.c  | 16 +++-
 dir.h  |  4 ++--
 wt-status.c|  4 ++--
 7 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index 7069b77..dcea98f 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -397,7 +397,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
}
 
/* This picks up the paths that are not tracked */
-   baselen = fill_directory(dir, pathspec.raw);
+   baselen = fill_directory(dir, pathspec);
if (pathspec.nr)
seen = prune_directory(dir, pathspec.raw, baselen);
}
diff --git a/builtin/clean.c b/builtin/clean.c
index fb0fe9a..1d8ff5f 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -102,7 +102,7 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
 
parse_pathspec(pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
 
-   fill_directory(dir, pathspec.raw);
+   fill_directory(dir, pathspec);
 
for (i = 0; i  dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
diff --git a/builtin/grep.c b/builtin/grep.c
index 705f9ff..f370bad 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -522,7 +522,7 @@ static int grep_directory(struct grep_opt *opt, const 
struct pathspec *pathspec,
if (exc_std)
setup_standard_excludes(dir);
 
-   fill_directory(dir, pathspec-raw);
+   fill_directory(dir, pathspec);
for (i = 0; i  dir.nr; i++) {
const char *name = dir.entries[i]-name;
int namelen = strlen(name);
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 4bf3238..9655cc5 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -216,7 +216,7 @@ static void show_files(struct dir_struct *dir)
 
/* For cached/deleted files we don't need to even do the readdir */
if (show_others || show_killed) {
-   fill_directory(dir, pathspec.raw);
+   fill_directory(dir, pathspec);
if (show_others)
show_other_files(dir);
if (show_killed)
diff --git a/dir.c b/dir.c
index 37280c8..6657b02 100644
--- a/dir.c
+++ b/dir.c
@@ -98,7 +98,7 @@ char *common_prefix(const char **pathspec)
return len ? xmemdupz(*pathspec, len) : NULL;
 }
 
-int fill_directory(struct dir_struct *dir, const char **pathspec)
+int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec)
 {
size_t len;
 
@@ -106,10 +106,10 @@ int fill_directory(struct dir_struct *dir, const char 
**pathspec)
 * Calculate common prefix for the pathspec, and
 * use that to optimize the directory walk
 */
-   len = common_prefix_len(pathspec);
+   len = common_prefix_len(pathspec-raw);
 
/* Read the directory and prune it */
-   read_directory(dir, pathspec ? *pathspec : , len, pathspec);
+   read_directory(dir, pathspec-nr ? pathspec-raw[0] : , len, 
pathspec);
return len;
 }
 
@@ -1323,14 +1323,20 @@ static int treat_leading_path(struct dir_struct *dir,
return rc;
 }
 
-int read_directory(struct dir_struct *dir, const char *path, int len, const 
char **pathspec)
+int read_directory(struct dir_struct *dir, const char *path, int len, const 
struct pathspec *pathspec)
 {
struct path_simplify *simplify;
 
+   /*
+* Check out create_simplify()
+*/
+   if (pathspec)
+   GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP);
+
if (has_symlink_leading_path(path, len))
return dir-nr;
 
-   simplify = create_simplify(pathspec);
+   simplify = create_simplify(pathspec ? pathspec-raw : NULL);
if (!len || treat_leading_path(dir, path, len, simplify))
read_directory_recursive(dir, path, len, 0, simplify);
free_simplify(simplify);
diff --git a/dir.h b/dir.h
index 0cf5ccf..36bb4dd 100644
--- a/dir.h
+++ b/dir.h
@@ -97,8 +97,8 @@ extern int match_pathspec_depth(const struct pathspec 
*pathspec,
int prefix, char *seen);
 extern int within_depth(const char *name, int namelen, int depth, int 
max_depth);
 
-extern int fill_directory(struct dir_struct *dir, const char **pathspec);
-extern int read_directory(struct dir_struct *, const char *path, int len, 
const char **pathspec);
+extern int fill_directory(struct dir_struct *dir, const struct pathspec 
*pathspec);
+extern int read_directory(struct dir_struct *, const char *path, int len, 
const struct pathspec *pathspec);
 
 extern int is_excluded_from_list(const char *pathname, int pathlen, const char 
*basename,
 int *dtype, struct exclude_list *el);
diff --git a/wt-status.c b/wt-status.c
index 76edadc..c5b979e 

[PATCH v3 25/31] Convert add_files_to_cache to take struct pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/add.c| 8 +---
 builtin/commit.c | 2 +-
 cache.h  | 2 +-
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index dcea98f..89ae67d 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -80,13 +80,15 @@ static void update_callback(struct diff_queue_struct *q,
}
 }
 
-int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
+int add_files_to_cache(const char *prefix,
+  const struct pathspec *pathspec, int flags)
 {
struct update_callback_data data;
struct rev_info rev;
init_revisions(rev, prefix);
setup_revisions(0, NULL, rev, NULL);
-   init_pathspec(rev.prune_data, pathspec);
+   if (pathspec)
+   copy_pathspec(rev.prune_data, pathspec);
rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
rev.diffopt.format_callback = update_callback;
data.flags = flags;
@@ -438,7 +440,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 
plug_bulk_checkin();
 
-   exit_status |= add_files_to_cache(prefix, pathspec.raw, flags);
+   exit_status |= add_files_to_cache(prefix, pathspec, flags);
 
if (add_new_files)
exit_status |= add_files(dir, flags);
diff --git a/builtin/commit.c b/builtin/commit.c
index 2fe6054..d79613d 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -329,7 +329,7 @@ static char *prepare_index(int argc, const char **argv, 
const char *prefix,
 */
if (all || (also  pathspec.nr)) {
fd = hold_locked_index(index_lock, 1);
-   add_files_to_cache(also ? prefix : NULL, pathspec.raw, 0);
+   add_files_to_cache(also ? prefix : NULL, pathspec, 0);
refresh_cache_or_die(refresh_flags);
update_main_cache_tree(WRITE_TREE_SILENT);
if (write_cache(fd, active_cache, active_nr) ||
diff --git a/cache.h b/cache.h
index 803cfeb..f7afb19 100644
--- a/cache.h
+++ b/cache.h
@@ -1255,7 +1255,7 @@ void packet_trace_identity(const char *prog);
  * return 0 if success, 1 - if addition of a file failed and
  * ADD_FILES_IGNORE_ERRORS was specified in flags
  */
-int add_files_to_cache(const char *prefix, const char **pathspec, int flags);
+int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, 
int flags);
 
 /* diff.c */
 extern int diff_auto_refresh_index;
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line 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 27/31] Remove diff_tree_{setup,release}_paths

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/blame.c | 12 ++--
 builtin/reset.c |  4 ++--
 diff.h  |  2 --
 notes-merge.c   |  4 ++--
 revision.c  |  5 +++--
 tree-diff.c | 18 --
 6 files changed, 17 insertions(+), 28 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index cfae569..5317d23 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -406,7 +406,7 @@ static struct origin *find_origin(struct scoreboard *sb,
paths[0] = origin-path;
paths[1] = NULL;
 
-   diff_tree_setup_paths(paths, diff_opts);
+   init_pathspec(diff_opts.pathspec, paths);
diff_setup_done(diff_opts);
 
if (is_null_sha1(origin-commit-object.sha1))
@@ -456,7 +456,7 @@ static struct origin *find_origin(struct scoreboard *sb,
}
}
diff_flush(diff_opts);
-   diff_tree_release_paths(diff_opts);
+   free_pathspec(diff_opts.pathspec);
if (porigin) {
/*
 * Create a freestanding copy that is not part of
@@ -492,7 +492,7 @@ static struct origin *find_rename(struct scoreboard *sb,
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_opts.single_follow = origin-path;
paths[0] = NULL;
-   diff_tree_setup_paths(paths, diff_opts);
+   init_pathspec(diff_opts.pathspec, paths);
diff_setup_done(diff_opts);
 
if (is_null_sha1(origin-commit-object.sha1))
@@ -514,7 +514,7 @@ static struct origin *find_rename(struct scoreboard *sb,
}
}
diff_flush(diff_opts);
-   diff_tree_release_paths(diff_opts);
+   free_pathspec(diff_opts.pathspec);
return porigin;
 }
 
@@ -1072,7 +1072,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
 
paths[0] = NULL;
-   diff_tree_setup_paths(paths, diff_opts);
+   init_pathspec(diff_opts.pathspec, paths);
diff_setup_done(diff_opts);
 
/* Try find copies harder on new path if requested;
@@ -1155,7 +1155,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
}
reset_scanned_flag(sb);
diff_flush(diff_opts);
-   diff_tree_release_paths(diff_opts);
+   free_pathspec(diff_opts.pathspec);
return retval;
 }
 
diff --git a/builtin/reset.c b/builtin/reset.c
index 915cc9f..0185bb0 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -183,7 +183,7 @@ static int read_from_tree(const char *prefix, const char 
**argv,
struct diff_options opt;
 
memset(opt, 0, sizeof(opt));
-   diff_tree_setup_paths(get_pathspec(prefix, (const char **)argv), opt);
+   parse_pathspec(opt.pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
opt.output_format = DIFF_FORMAT_CALLBACK;
opt.format_callback = update_index_from_diff;
opt.format_callback_data = index_was_discarded;
@@ -195,7 +195,7 @@ static int read_from_tree(const char *prefix, const char 
**argv,
return 1;
diffcore_std(opt);
diff_flush(opt);
-   diff_tree_release_paths(opt);
+   free_pathspec(opt.pathspec);
 
if (!index_was_discarded)
/* The index is still clobbered from do_diff_cache() */
diff --git a/diff.h b/diff.h
index a47bae4..dd2a022 100644
--- a/diff.h
+++ b/diff.h
@@ -176,8 +176,6 @@ const char *diff_get_color(int diff_use_color, enum 
color_diff ix);
 
 extern const char mime_boundary_leader[];
 
-extern void diff_tree_setup_paths(const char **paths, struct diff_options *);
-extern void diff_tree_release_paths(struct diff_options *);
 extern int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
 const char *base, struct diff_options *opt);
 extern int diff_tree_sha1(const unsigned char *old, const unsigned char *new,
diff --git a/notes-merge.c b/notes-merge.c
index 0f67bd3..f1a3b39 100644
--- a/notes-merge.c
+++ b/notes-merge.c
@@ -169,7 +169,7 @@ static struct notes_merge_pair *diff_tree_remote(struct 
notes_merge_options *o,
   sha1_to_hex(mp-remote));
}
diff_flush(opt);
-   diff_tree_release_paths(opt);
+   free_pathspec(opt.pathspec);
 
*num_changes = len;
return changes;
@@ -255,7 +255,7 @@ static void diff_tree_local(struct notes_merge_options *o,
   sha1_to_hex(mp-local));
}
diff_flush(opt);
-   diff_tree_release_paths(opt);
+   free_pathspec(opt.pathspec);
 }
 
 static void check_notes_merge_worktree(struct notes_merge_options *o)
diff --git a/revision.c b/revision.c
index a044242..451b223 100644
--- a/revision.c
+++ b/revision.c
@@ -1885,12 +1885,13 @@ int setup_revisions(int argc, const char **argv, struct 
rev_info *revs, struct s
revs-limited = 1;
 
if (revs-prune_data.nr) {
-   diff_tree_setup_paths(revs-prune_data.raw, revs-pruning);
+   copy_pathspec(revs-pruning.pathspec, 

[PATCH v3 28/31] Remove init_pathspec() in favor of parse_pathspec()

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 archive.c  |  2 +-
 builtin/blame.c|  6 +++---
 builtin/log.c  |  2 +-
 builtin/ls-files.c | 10 --
 cache.h|  1 -
 diff-lib.c |  2 +-
 dir.c  | 52 
 merge-recursive.c  |  2 +-
 revision.c |  2 +-
 tree-diff.c| 10 +-
 10 files changed, 17 insertions(+), 72 deletions(-)

diff --git a/archive.c b/archive.c
index f1a28c9..ef50d49 100644
--- a/archive.c
+++ b/archive.c
@@ -219,7 +219,7 @@ static int path_exists(struct tree *tree, const char *path)
struct pathspec pathspec;
int ret;
 
-   init_pathspec(pathspec, paths);
+   parse_pathspec(pathspec, 0, 0, , paths);
ret = read_tree_recursive(tree, , 0, 0, pathspec, reject_entry, 
NULL);
free_pathspec(pathspec);
return ret != 0;
diff --git a/builtin/blame.c b/builtin/blame.c
index 5317d23..fdba756 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -406,7 +406,7 @@ static struct origin *find_origin(struct scoreboard *sb,
paths[0] = origin-path;
paths[1] = NULL;
 
-   init_pathspec(diff_opts.pathspec, paths);
+   parse_pathspec(diff_opts.pathspec, 0, 0, , paths);
diff_setup_done(diff_opts);
 
if (is_null_sha1(origin-commit-object.sha1))
@@ -492,7 +492,7 @@ static struct origin *find_rename(struct scoreboard *sb,
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_opts.single_follow = origin-path;
paths[0] = NULL;
-   init_pathspec(diff_opts.pathspec, paths);
+   parse_pathspec(diff_opts.pathspec, 0, 0, , paths);
diff_setup_done(diff_opts);
 
if (is_null_sha1(origin-commit-object.sha1))
@@ -1072,7 +1072,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
 
paths[0] = NULL;
-   init_pathspec(diff_opts.pathspec, paths);
+   parse_pathspec(diff_opts.pathspec, 0, 0, , paths);
diff_setup_done(diff_opts);
 
/* Try find copies harder on new path if requested;
diff --git a/builtin/log.c b/builtin/log.c
index 3899b1d..e8f5514 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -455,7 +455,7 @@ int cmd_show(int argc, const char **argv, const char 
*prefix)
init_grep_defaults();
git_config(git_log_config, NULL);
 
-   init_pathspec(match_all, NULL);
+   memset(match_all, 0, sizeof(match_all));
init_revisions(rev, prefix);
rev.diff = 1;
rev.always_show_header = 1;
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 6c4ee40..e3ccf50 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -318,13 +318,11 @@ void overlay_tree_on_cache(const char *tree_name, const 
char *prefix)
}
 
if (prefix) {
-   static const char *(matchbuf[2]);
-   matchbuf[0] = prefix;
-   matchbuf[1] = NULL;
-   init_pathspec(pathspec, matchbuf);
-   pathspec.items[0].nowildcard_len = pathspec.items[0].len;
+   static const char *(matchbuf[1]);
+   matchbuf[0] = NULL;
+   parse_pathspec(pathspec, 0, 0, prefix, matchbuf);
} else
-   init_pathspec(pathspec, NULL);
+   memset(pathspec, 0, sizeof(pathspec));
if (read_tree(tree, 1, pathspec))
die(unable to read tree entries %s, tree_name);
 
diff --git a/cache.h b/cache.h
index f7afb19..13cc217 100644
--- a/cache.h
+++ b/cache.h
@@ -511,7 +511,6 @@ struct pathspec {
 #define PATHSPEC_SYMLINK_LEADING_PATH (12) /* has_symlink_leading_path */
 #define PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE (13)
 
-extern int init_pathspec(struct pathspec *, const char **);
 extern void parse_pathspec(struct pathspec *pathspec, unsigned magic_mask,
   unsigned flags, const char *prefix,
   const char **args);
diff --git a/diff-lib.c b/diff-lib.c
index f35de0f..e5236ab 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -500,7 +500,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct 
diff_options *opt)
struct rev_info revs;
 
init_revisions(revs, NULL);
-   init_pathspec(revs.prune_data, opt-pathspec.raw);
+   copy_pathspec(revs.prune_data, opt-pathspec);
revs.diffopt = *opt;
 
if (diff_cache(revs, tree_sha1, NULL, 1))
diff --git a/dir.c b/dir.c
index 5d257fb..76b267e 100644
--- a/dir.c
+++ b/dir.c
@@ -1515,58 +1515,6 @@ int remove_path(const char *name)
return 0;
 }
 
-static int pathspec_item_cmp(const void *a_, const void *b_)
-{
-   struct pathspec_item *a, *b;
-
-   a = (struct pathspec_item *)a_;
-   b = (struct pathspec_item *)b_;
-   return strcmp(a-match, b-match);
-}
-
-int init_pathspec(struct pathspec *pathspec, const char **paths)
-{
-   const char **p = paths;
-   int i;
-
-   memset(pathspec, 0, 

[PATCH v3 29/31] Remove match_pathspec() in favor of match_pathspec_depth()

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/add.c |  46 ---
 dir.c | 100 --
 dir.h |   1 -
 3 files changed, 20 insertions(+), 127 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index 89ae67d..9edab95 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -99,7 +99,7 @@ int add_files_to_cache(const char *prefix,
return !!data.add_errors;
 }
 
-static void fill_pathspec_matches(const char **pathspec, char *seen, int specs)
+static void fill_pathspec_matches(struct pathspec *pathspec, char *seen)
 {
int num_unmatched = 0, i;
 
@@ -109,49 +109,43 @@ static void fill_pathspec_matches(const char **pathspec, 
char *seen, int specs)
 * mistakenly think that the user gave a pathspec that did not match
 * anything.
 */
-   for (i = 0; i  specs; i++)
+   for (i = 0; i  pathspec-nr; i++)
if (!seen[i])
num_unmatched++;
if (!num_unmatched)
return;
for (i = 0; i  active_nr; i++) {
struct cache_entry *ce = active_cache[i];
-   match_pathspec(pathspec, ce-name, ce_namelen(ce), 0, seen);
+   match_pathspec_depth(pathspec, ce-name, ce_namelen(ce), 0, 
seen);
}
 }
 
-static char *find_used_pathspec(const char **pathspec)
+static char *find_used_pathspec(struct pathspec *pathspec)
 {
char *seen;
-   int i;
-
-   for (i = 0; pathspec[i];  i++)
-   ; /* just counting */
-   seen = xcalloc(i, 1);
-   fill_pathspec_matches(pathspec, seen, i);
+   seen = xcalloc(pathspec-nr, 1);
+   fill_pathspec_matches(pathspec, seen);
return seen;
 }
 
-static char *prune_directory(struct dir_struct *dir, const char **pathspec, 
int prefix)
+static char *prune_directory(struct dir_struct *dir, struct pathspec 
*pathspec, int prefix)
 {
char *seen;
-   int i, specs;
+   int i;
struct dir_entry **src, **dst;
 
-   for (specs = 0; pathspec[specs];  specs++)
-   /* nothing */;
-   seen = xcalloc(specs, 1);
+   seen = xcalloc(pathspec-nr, 1);
 
src = dst = dir-entries;
i = dir-nr;
while (--i = 0) {
struct dir_entry *entry = *src++;
-   if (match_pathspec(pathspec, entry-name, entry-len,
-  prefix, seen))
+   if (match_pathspec_depth(pathspec, entry-name, entry-len,
+prefix, seen))
*dst++ = entry;
}
dir-nr = dst - dir-entries;
-   fill_pathspec_matches(pathspec, seen, specs);
+   fill_pathspec_matches(pathspec, seen);
return seen;
 }
 
@@ -401,7 +395,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
/* This picks up the paths that are not tracked */
baselen = fill_directory(dir, pathspec);
if (pathspec.nr)
-   seen = prune_directory(dir, pathspec.raw, baselen);
+   seen = prune_directory(dir, pathspec, baselen);
}
 
if (refresh_only) {
@@ -415,23 +409,23 @@ int cmd_add(int argc, const char **argv, const char 
*prefix)
 
path_exclude_check_init(check, dir);
if (!seen)
-   seen = find_used_pathspec(pathspec.raw);
+   seen = find_used_pathspec(pathspec);
 
/*
 * file_exists() assumes exact match
 */
GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP);
 
-   for (i = 0; pathspec.raw[i]; i++) {
-   if (!seen[i]  pathspec.raw[i][0]
-!file_exists(pathspec.raw[i])) {
+   for (i = 0; i  pathspec.nr; i++) {
+   const char *path = pathspec.items[i].match;
+   if (!seen[i]  !file_exists(path)) {
if (ignore_missing) {
int dtype = DT_UNKNOWN;
-   if (is_path_excluded(check, 
pathspec.raw[i], -1, dtype))
-   dir_add_ignored(dir, 
pathspec.raw[i], strlen(pathspec.raw[i]));
+   if (is_path_excluded(check, path, -1, 
dtype))
+   dir_add_ignored(dir, path, 
pathspec.items[i].len);
} else
die(_(pathspec '%s' did not match any 
files),
-   pathspec.raw[i]);
+   pathspec.items[i].original);
}
}
free(seen);
diff --git a/dir.c b/dir.c
index 76b267e..2a1bcb8 100644
--- a/dir.c
+++ b/dir.c
@@ -139,106 +139,6 @@ int 

[PATCH v3 30/31] tree-diff: remove the use of pathspec's raw[] in follow-rename codepath

2013-01-13 Thread Nguyễn Thái Ngọc Duy
Put a checkpoint to guard unsupported pathspec features in future.

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

diff --git a/tree-diff.c b/tree-diff.c
index aba6df7..718f938 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -225,7 +225,7 @@ static void try_to_follow_renames(struct tree_desc *t1, 
struct tree_desc *t2, co
DIFF_OPT_SET(diff_opts, RECURSIVE);
DIFF_OPT_SET(diff_opts, FIND_COPIES_HARDER);
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
-   diff_opts.single_follow = opt-pathspec.raw[0];
+   diff_opts.single_follow = opt-pathspec.items[0].match;
diff_opts.break_opt = opt-break_opt;
diff_opts.rename_score = opt-rename_score;
diff_setup_done(diff_opts);
@@ -244,7 +244,7 @@ static void try_to_follow_renames(struct tree_desc *t1, 
struct tree_desc *t2, co
 * the future!
 */
if ((p-status == 'R' || p-status == 'C') 
-   !strcmp(p-two-path, opt-pathspec.raw[0])) {
+   !strcmp(p-two-path, opt-pathspec.items[0].match)) {
const char *path[2];
 
/* Switch the file-pairs around */
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line 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 31/31] Rename field raw to _raw in struct pathspec

2013-01-13 Thread Nguyễn Thái Ngọc Duy
This patch is essentially no-op. It helps catching new use of this
field though. This field is introduced as an intermediate step for the
pathspec conversion and will be removed eventually. At this stage no
more access sites should be introduced.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 archive.c  | 2 +-
 builtin/add.c  | 2 +-
 builtin/checkout.c | 2 +-
 builtin/ls-tree.c  | 2 +-
 cache.h| 2 +-
 dir.c  | 4 ++--
 setup.c| 6 +++---
 7 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/archive.c b/archive.c
index ef50d49..d9da58b 100644
--- a/archive.c
+++ b/archive.c
@@ -236,7 +236,7 @@ static void parse_pathspec_arg(const char **pathspec,
 */
parse_pathspec(ar_args-pathspec, PATHSPEC_FROMTOP, 0, , pathspec);
if (ar_args-pathspec.nr) {
-   pathspec = ar_args-pathspec.raw;
+   pathspec = ar_args-pathspec._raw;
while (*pathspec) {
if (!path_exists(ar_args-tree, *pathspec))
die(path not found: %s, *pathspec);
diff --git a/builtin/add.c b/builtin/add.c
index 9edab95..a7840c8 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -209,7 +209,7 @@ int interactive_add(int argc, const char **argv, const char 
*prefix, int patch)
 
return run_add_interactive(NULL,
   patch ? --patch : NULL,
-  pathspec.raw);
+  pathspec._raw);
 }
 
 static int edit_patch(int argc, const char **argv, const char *prefix)
diff --git a/builtin/checkout.c b/builtin/checkout.c
index d2fc996..1b413e2 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -253,7 +253,7 @@ static int checkout_paths(const struct checkout_opts *opts,
 
if (opts-patch_mode)
return run_add_interactive(revision, --patch=checkout,
-  opts-pathspec.raw);
+  opts-pathspec._raw);
 
lock_file = xcalloc(1, sizeof(struct lock_file));
 
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index e03aaaf..58899a5 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -35,7 +35,7 @@ static int show_recursive(const char *base, int baselen, 
const char *pathname)
if (ls_options  LS_RECURSIVE)
return 1;
 
-   s = pathspec.raw;
+   s = pathspec._raw;
if (!s)
return 0;
 
diff --git a/cache.h b/cache.h
index 13cc217..c7a8d28 100644
--- a/cache.h
+++ b/cache.h
@@ -482,7 +482,7 @@ extern int ie_modified(const struct index_state *, struct 
cache_entry *, struct
 #define PATHSPEC_ONESTAR 1 /* the pathspec pattern sastisfies GFNM_ONESTAR 
*/
 
 struct pathspec {
-   const char **raw; /* get_pathspec() result, not freed by 
free_pathspec() */
+   const char **_raw; /* get_pathspec() result, not freed by 
free_pathspec() */
int nr;
unsigned int has_wildcard:1;
unsigned int recursive:1;
diff --git a/dir.c b/dir.c
index 2a1bcb8..efc676c 100644
--- a/dir.c
+++ b/dir.c
@@ -108,7 +108,7 @@ int fill_directory(struct dir_struct *dir, const struct 
pathspec *pathspec)
len = common_prefix_len(pathspec);
 
/* Read the directory and prune it */
-   read_directory(dir, pathspec-nr ? pathspec-raw[0] : , len, 
pathspec);
+   read_directory(dir, pathspec-nr ? pathspec-_raw[0] : , len, 
pathspec);
return len;
 }
 
@@ -1235,7 +1235,7 @@ int read_directory(struct dir_struct *dir, const char 
*path, int len, const stru
if (has_symlink_leading_path(path, len))
return dir-nr;
 
-   simplify = create_simplify(pathspec ? pathspec-raw : NULL);
+   simplify = create_simplify(pathspec ? pathspec-_raw : NULL);
if (!len || treat_leading_path(dir, path, len, simplify))
read_directory_recursive(dir, path, len, 0, simplify);
free_simplify(simplify);
diff --git a/setup.c b/setup.c
index b6f419d..69ca047 100644
--- a/setup.c
+++ b/setup.c
@@ -332,7 +332,7 @@ void parse_pathspec(struct pathspec *pathspec,
raw[0] = prefix;
raw[1] = NULL;
pathspec-nr = 1;
-   pathspec-raw = raw;
+   pathspec-_raw = raw;
return;
}
 
@@ -342,7 +342,7 @@ void parse_pathspec(struct pathspec *pathspec,
 
pathspec-nr = n;
pathspec-items = item = xmalloc(sizeof(*item) * n);
-   pathspec-raw = argv;
+   pathspec-_raw = argv;
prefixlen = prefix ? strlen(prefix) : 0;
 
for (i = 0; i  n; i++) {
@@ -372,7 +372,7 @@ const char **get_pathspec(const char *prefix, const char 
**pathspec)
 {
struct pathspec ps;
parse_pathspec(ps, PATHSPEC_FROMTOP, 0, prefix, pathspec);
-   return ps.raw;
+   return ps._raw;
 }
 
 /*
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line unsubscribe git 

[PATCH/WIP 00/10] Fancy pathspec stuff

2013-01-13 Thread Nguyễn Thái Ngọc Duy
I wanted to see how new pathspec feature can be implemented after
nd/parse-pathspec, mainly to see if nd/parse-pathspec needs fixing.
It's nowhere near 'pu' quality but may be interesting for some people.

It does:

- introduce :q/.../ syntax in addition to :(...), which always
  requires quoting in bash

- separate prefix part from the rest of pathspec, allowing it to be
  treated differently (e.g. prefix is matched exactly regardless
  pathspec magic)

- implement :(glob) using wildmatch (i.e. incompatible with the
  wildcards that current pathspec uses)

- implement :(icase) -- with bugs

- implement :(literal), similar to --literal-pathspecs

That's all my spam for today.

Nguyễn Thái Ngọc Duy (10):
  pathspec: allow to use alternate char for quoting long magic mnemonic
  parse_pathspec: make sure the prefix part is wildcard-free
  pathspec: support :(literal) syntax for noglob pathspec
  parse_pathspec: save prefix information
  pathspec: prepare for :(glob)path syntax
  Enable :(glob)path syntax for a lot of commands
  parse_pathspec: accept :(icase)path syntax
  common_prefix/read_directory: treat PATHSPEC_ICASE like wildcards
  pathspec: support icase in match_pathspec_depth and
tree_entry_interesting
  Enable ls-files and ls-tree for testing PATHSPEC_ICASE

 archive.c  |  4 ++-
 builtin/add.c  | 19 +++---
 builtin/checkout.c |  6 -
 builtin/clean.c|  6 -
 builtin/commit.c   | 10 +--
 builtin/diff.c |  2 +-
 builtin/grep.c |  6 -
 builtin/ls-files.c |  6 -
 builtin/ls-tree.c  |  7 -
 builtin/rerere.c   |  6 -
 builtin/reset.c|  6 -
 builtin/rm.c   |  6 -
 builtin/update-index.c |  6 -
 cache.h| 23 +++-
 dir.c  | 60 --
 dir.h  |  8 +++---
 path.c | 15 ++-
 revision.c |  7 +++--
 setup.c| 65 +-
 t/t6130-pathspec-noglob.sh | 18 +
 t/t6131-pathspec-prefix.sh | 47 +
 tree-diff.c|  2 +-
 tree-walk.c| 39 +---
 23 files changed, 295 insertions(+), 79 deletions(-)
 create mode 100755 t/t6131-pathspec-prefix.sh

-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line 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/WIP 01/10] pathspec: allow to use alternate char for quoting long magic mnemonic

2013-01-13 Thread Nguyễn Thái Ngọc Duy
Currently use parentheses, e.g. :(icase,literal)path, but they do
not play well with unix shells because they have special meaning and
we need to quote them. Allow an alternate syntax :q/icase,literal/path.

Similar to ed's s/// syntax, '/' can be replaced with anything. If the
opening quote has a closing counterpart, e.g. () []  {}, then it'll
be quoted as such.

It may even be a good thing to kill ':(...)' syntax, which can easily
be replaced with ':q(...)'. It's unlikely that anybody is used to it
yet.

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

diff --git a/setup.c b/setup.c
index 69ca047..9db6093 100644
--- a/setup.c
+++ b/setup.c
@@ -196,14 +196,32 @@ static unsigned prefix_pathspec(struct pathspec_item 
*item,
 
if (elt[0] != ':') {
; /* nothing to do */
-   } else if (elt[1] == '(') {
+   } else if (elt[1] == '(' || elt[1] == 'q') {
/* longhand */
const char *nextat;
-   for (copyfrom = elt + 2;
-*copyfrom  *copyfrom != ')';
+   char close = ')';
+   char sep[3] = ,);
+   if (elt[1] == '(')
+   copyfrom = elt + 2;
+   else {
+   copyfrom = elt + 3;
+   switch (elt[2]) {
+   case '(': close = ')'; break;
+   case '[': close = ']'; break;
+   case '{': close = '}'; break;
+   case '': close = ''; break;
+   case '\0':
+   die(Invalid pathspec '%s', elt);
+   default:
+   close = elt[2];
+   }
+   sep[1] = close;
+   }
+   for (;
+*copyfrom  *copyfrom != close;
 copyfrom = nextat) {
-   size_t len = strcspn(copyfrom, ,));
-   if (copyfrom[len] == ')')
+   size_t len = strcspn(copyfrom, sep);
+   if (copyfrom[len] == close)
nextat = copyfrom + len;
else
nextat = copyfrom + len + 1;
@@ -219,7 +237,7 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
die(Invalid pathspec magic '%.*s' in '%s',
(int) len, copyfrom, elt);
}
-   if (*copyfrom == ')')
+   if (*copyfrom == close)
copyfrom++;
} else {
/* shorthand */
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line 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/WIP 02/10] parse_pathspec: make sure the prefix part is wildcard-free

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 cache.h|  1 +
 path.c | 15 ++-
 setup.c| 24 +++
 t/t6131-pathspec-prefix.sh | 47 ++
 4 files changed, 78 insertions(+), 9 deletions(-)
 create mode 100755 t/t6131-pathspec-prefix.sh

diff --git a/cache.h b/cache.h
index c7a8d28..f3de28d 100644
--- a/cache.h
+++ b/cache.h
@@ -747,6 +747,7 @@ const char *real_path(const char *path);
 const char *real_path_if_valid(const char *path);
 const char *absolute_path(const char *path);
 const char *relative_path(const char *abs, const char *base);
+int normalize_path_copy_len(char *dst, const char *src, int *prefix_len);
 int normalize_path_copy(char *dst, const char *src);
 int longest_ancestor_length(const char *path, struct string_list *prefixes);
 char *strip_path_suffix(const char *path, const char *suffix);
diff --git a/path.c b/path.c
index d3d3f8b..7baf334 100644
--- a/path.c
+++ b/path.c
@@ -487,8 +487,14 @@ const char *relative_path(const char *abs, const char 
*base)
  *
  * Note that this function is purely textual.  It does not follow symlinks,
  * verify the existence of the path, or make any system calls.
+ *
+ * prefix_len != NULL is for a specific case of prefix_pathspec():
+ * assume that src == dst and src[0..prefix_len-1] is already
+ * normalized, any time ../ eats up to the prefix_len part,
+ * prefix_len is reduced. In the end prefix_len is the remaining
+ * prefix that has not been overridden by user pathspec.
  */
-int normalize_path_copy(char *dst, const char *src)
+int normalize_path_copy_len(char *dst, const char *src, int *prefix_len)
 {
char *dst0;
 
@@ -563,11 +569,18 @@ int normalize_path_copy(char *dst, const char *src)
/* Windows: dst[-1] cannot be backslash anymore */
while (dst0  dst  dst[-1] != '/')
dst--;
+   if (prefix_len  *prefix_len  dst - dst0)
+   *prefix_len = dst - dst0;
}
*dst = '\0';
return 0;
 }
 
+int normalize_path_copy(char *dst, const char *src)
+{
+   return normalize_path_copy_len(dst, src, NULL);
+}
+
 /*
  * path = Canonical absolute path
  * prefixes = string_list containing normalized, absolute paths without
diff --git a/setup.c b/setup.c
index 9db6093..c5e97c9 100644
--- a/setup.c
+++ b/setup.c
@@ -5,10 +5,11 @@
 static int inside_git_dir = -1;
 static int inside_work_tree = -1;
 
-static char *prefix_path_gently(const char *prefix, int len, const char *path)
+static char *prefix_path_gently(const char *prefix, int *p_len, const char 
*path)
 {
const char *orig = path;
char *sanitized;
+   int len = *p_len;
if (is_absolute_path(orig)) {
const char *temp = real_path(path);
sanitized = xmalloc(len + strlen(temp) + 1);
@@ -19,7 +20,7 @@ static char *prefix_path_gently(const char *prefix, int len, 
const char *path)
memcpy(sanitized, prefix, len);
strcpy(sanitized + len, path);
}
-   if (normalize_path_copy(sanitized, sanitized))
+   if (normalize_path_copy_len(sanitized, sanitized, p_len))
goto error_out;
if (is_absolute_path(orig)) {
size_t root_len, len, total;
@@ -44,7 +45,7 @@ static char *prefix_path_gently(const char *prefix, int len, 
const char *path)
 
 char *prefix_path(const char *prefix, int len, const char *path)
 {
-   char *r = prefix_path_gently(prefix, len, path);
+   char *r = prefix_path_gently(prefix, len, path);
if (!r)
die('%s' is outside repository, path);
return r;
@@ -53,7 +54,7 @@ char *prefix_path(const char *prefix, int len, const char 
*path)
 int path_inside_repo(const char *prefix, const char *path)
 {
int len = prefix ? strlen(prefix) : 0;
-   char *r = prefix_path_gently(prefix, len, path);
+   char *r = prefix_path_gently(prefix, len, path);
if (r) {
free(r);
return 1;
@@ -261,10 +262,14 @@ static unsigned prefix_pathspec(struct pathspec_item 
*item,
copyfrom++;
}
 
-   if (magic  PATHSPEC_FROMTOP)
+   if (magic  PATHSPEC_FROMTOP) {
match = xstrdup(copyfrom);
-   else
-   match = prefix_path(prefix, prefixlen, copyfrom);
+   prefixlen = 0;
+   } else {
+   match = prefix_path_gently(prefix, prefixlen, copyfrom);
+   if (!match)
+   die(%s: '%s' is outside repository, elt, copyfrom);
+   }
*raw = item-match = match;
item-original = elt;
item-len = strlen(item-match);
@@ -300,8 +305,11 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
item-flags = 0;
if (limit_pathspec_to_literal())
item-nowildcard_len = item-len;
- 

[PATCH/WIP 04/10] parse_pathspec: save prefix information

2013-01-13 Thread Nguyễn Thái Ngọc Duy

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

diff --git a/cache.h b/cache.h
index 900b81a..fb54876 100644
--- a/cache.h
+++ b/cache.h
@@ -493,7 +493,7 @@ struct pathspec {
const char *match;
const char *original;
unsigned magic;
-   int len;
+   int len, prefix;
int nowildcard_len;
int flags;
} *items;
diff --git a/setup.c b/setup.c
index 6b48f1b..c4af05e 100644
--- a/setup.c
+++ b/setup.c
@@ -310,6 +310,7 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
if (item-nowildcard_len  prefixlen)
item-nowildcard_len = prefixlen;
}
+   item-prefix = prefixlen;
if (item-nowildcard_len  item-len 
item-match[item-nowildcard_len] == '*' 
no_wildcard(item-match + item-nowildcard_len + 1))
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line 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/WIP 05/10] pathspec: prepare for :(glob)path syntax

2013-01-13 Thread Nguyễn Thái Ngọc Duy
:(glob)path differs from path that it uses wildmatch with
FNM_PATHNAME while plain path uses fnmatch without FNM_PATHNAME.

git_fnmatch() was probably ill-designed. It was intended to cover
other use of fnmatch besides pathspec. But so far it's only used by
pathspec code.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/add.c |  9 +++--
 cache.h   |  1 +
 dir.c | 34 ++
 dir.h |  8 +++-
 setup.c   |  1 +
 tree-walk.c   | 11 ++-
 6 files changed, 40 insertions(+), 24 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index d09a07a..1b99e2b 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -416,11 +416,16 @@ int cmd_add(int argc, const char **argv, const char 
*prefix)
/*
 * file_exists() assumes exact match
 */
-   GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
+   GUARD_PATHSPEC(pathspec,
+  PATHSPEC_FROMTOP |
+  PATHSPEC_LITERAL |
+  PATHSPEC_GLOB);
 
for (i = 0; i  pathspec.nr; i++) {
const char *path = pathspec.items[i].match;
-   if (!seen[i]  !file_exists(path)) {
+   if (!seen[i] 
+   ((pathspec.items[i].magic  PATHSPEC_GLOB) ||
+!file_exists(path))) {
if (ignore_missing) {
int dtype = DT_UNKNOWN;
if (is_path_excluded(check, path, -1, 
dtype))
diff --git a/cache.h b/cache.h
index fb54876..9c27f18 100644
--- a/cache.h
+++ b/cache.h
@@ -479,6 +479,7 @@ extern int ie_modified(const struct index_state *, struct 
cache_entry *, struct
 /* Pathspec magic */
 #define PATHSPEC_FROMTOP(10)
 #define PATHSPEC_LITERAL(11)
+#define PATHSPEC_GLOB   (12)
 
 #define PATHSPEC_ONESTAR 1 /* the pathspec pattern sastisfies GFNM_ONESTAR 
*/
 
diff --git a/dir.c b/dir.c
index 63d07cd..760b776 100644
--- a/dir.c
+++ b/dir.c
@@ -37,26 +37,28 @@ int fnmatch_icase(const char *pattern, const char *string, 
int flags)
return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 
0));
 }
 
-inline int git_fnmatch(const char *pattern, const char *string,
-  int flags, int prefix)
+inline int git_fnmatch(const struct pathspec_item *item,
+  const char *pattern, const char *string,
+  int prefix)
 {
-   int fnm_flags = 0;
-   if (flags  GFNM_PATHNAME)
-   fnm_flags |= FNM_PATHNAME;
if (prefix  0) {
if (strncmp(pattern, string, prefix))
return FNM_NOMATCH;
pattern += prefix;
string += prefix;
}
-   if (flags  GFNM_ONESTAR) {
+   if (item-flags  PATHSPEC_ONESTAR) {
int pattern_len = strlen(++pattern);
int string_len = strlen(string);
return string_len  pattern_len ||
   strcmp(pattern,
  string + string_len - pattern_len);
}
-   return fnmatch(pattern, string, fnm_flags);
+   if (item-magic  PATHSPEC_GLOB)
+   return wildmatch(pattern, string, 0);
+   else
+   /* wildmatch has not learned no FNM_PATHNAME mode yet */
+   return fnmatch(pattern, string, 0);
 }
 
 static size_t common_prefix_len(const struct pathspec *pathspec)
@@ -64,7 +66,10 @@ static size_t common_prefix_len(const struct pathspec 
*pathspec)
int n;
size_t max = 0;
 
-   GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
+   GUARD_PATHSPEC(pathspec,
+  PATHSPEC_FROMTOP |
+  PATHSPEC_LITERAL |
+  PATHSPEC_GLOB);
 
for (n = 0; n  pathspec-nr; n++) {
size_t i = 0, len = 0;
@@ -159,8 +164,7 @@ static int match_pathspec_item(const struct pathspec_item 
*item, int prefix,
}
 
if (item-nowildcard_len  item-len 
-   !git_fnmatch(match, name,
-item-flags  PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0,
+   !git_fnmatch(item, match, name,
 item-nowildcard_len - prefix))
return MATCHED_FNMATCH;
 
@@ -181,7 +185,10 @@ int match_pathspec_depth(const struct pathspec *ps,
 {
int i, retval = 0;
 
-   GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
+   GUARD_PATHSPEC(ps,
+  PATHSPEC_FROMTOP |
+  PATHSPEC_LITERAL |
+  PATHSPEC_GLOB);
 
if (!ps-nr) {
if (!ps-recursive || ps-max_depth == -1)
@@ -1230,7 +1237,10 @@ int read_directory(struct dir_struct *dir, const char 
*path, int len, const stru
 * Check out 

[PATCH/WIP 06/10] Enable :(glob)path syntax for a lot of commands

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/add.c  | 4 +++-
 builtin/checkout.c | 4 +++-
 builtin/clean.c| 4 +++-
 builtin/commit.c   | 8 ++--
 builtin/grep.c | 4 +++-
 builtin/ls-files.c | 4 +++-
 builtin/ls-tree.c  | 4 +++-
 builtin/rerere.c   | 4 +++-
 builtin/reset.c| 4 +++-
 builtin/rm.c   | 4 +++-
 builtin/update-index.c | 4 +++-
 revision.c | 4 +++-
 12 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index 1b99e2b..a3ffa9d 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -379,7 +379,9 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 * below before enabling new magic.
 */
parse_pathspec(pathspec,
-  PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+  PATHSPEC_FROMTOP |
+  PATHSPEC_LITERAL |
+  PATHSPEC_GLOB,
   PATHSPEC_SYMLINK_LEADING_PATH |
   PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE,
   prefix, argv);
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 90f4a01..cb5d548 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -1113,7 +1113,9 @@ int cmd_checkout(int argc, const char **argv, const char 
*prefix)
 * lifted for new magic when opts.patch_mode == 0.
 */
parse_pathspec(opts.pathspec,
-  PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+  PATHSPEC_FROMTOP |
+  PATHSPEC_LITERAL |
+  (opts.patch_mode ? PATHSPEC_GLOB : 0),
   0, prefix, argv);
 
if (!opts.pathspec.nr)
diff --git a/builtin/clean.c b/builtin/clean.c
index b4ffa2b..f675d5a 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -101,7 +101,9 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
dir.exclude_list[EXC_CMDL]);
 
parse_pathspec(pathspec,
-  PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+  PATHSPEC_FROMTOP |
+  PATHSPEC_LITERAL |
+  PATHSPEC_GLOB,
   0, prefix, argv);
 
fill_directory(dir, pathspec);
diff --git a/builtin/commit.c b/builtin/commit.c
index 433fdb9..743a3ea 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -282,7 +282,9 @@ static char *prepare_index(int argc, const char **argv, 
const char *prefix,
if (is_status)
refresh_flags |= REFRESH_UNMERGED;
parse_pathspec(pathspec,
-  PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+  PATHSPEC_FROMTOP |
+  PATHSPEC_LITERAL |
+  PATHSPEC_GLOB,
   PATHSPEC_EMPTY_MATCH_ALL,
   prefix, argv);
 
@@ -1205,7 +1207,9 @@ int cmd_status(int argc, const char **argv, const char 
*prefix)
if (show_ignored_in_status)
s.show_ignored_files = 1;
parse_pathspec(s.pathspec,
-  PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+  PATHSPEC_FROMTOP |
+  PATHSPEC_LITERAL |
+  PATHSPEC_GLOB,
   PATHSPEC_EMPTY_MATCH_ALL,
   prefix, argv);
 
diff --git a/builtin/grep.c b/builtin/grep.c
index 4d8e82c..9f1b029 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -857,7 +857,9 @@ int cmd_grep(int argc, const char **argv, const char 
*prefix)
}
 
parse_pathspec(pathspec,
-  PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+  PATHSPEC_FROMTOP |
+  PATHSPEC_LITERAL |
+  PATHSPEC_GLOB,
   0, prefix, argv + i);
pathspec.max_depth = opt.max_depth;
pathspec.recursive = 1;
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 1cbd211..feb4220 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -536,7 +536,9 @@ int cmd_ls_files(int argc, const char **argv, const char 
*cmd_prefix)
setup_work_tree();
 
parse_pathspec(pathspec,
-  PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+  PATHSPEC_FROMTOP |
+  PATHSPEC_LITERAL |
+  PATHSPEC_GLOB,
   PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP,
   prefix, argv);
 
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index 4764683..25d0590 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -173,7 +173,9 @@ int cmd_ls_tree(int argc, const char **argv, const char 
*prefix)
 * match_pathspec_depth() or tree_entry_interesting()
 */
parse_pathspec(pathspec,
-  PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+  PATHSPEC_FROMTOP 

[PATCH/WIP 07/10] parse_pathspec: accept :(icase)path syntax

2013-01-13 Thread Nguyễn Thái Ngọc Duy

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

diff --git a/cache.h b/cache.h
index 9c27f18..c3b5585 100644
--- a/cache.h
+++ b/cache.h
@@ -480,6 +480,7 @@ extern int ie_modified(const struct index_state *, struct 
cache_entry *, struct
 #define PATHSPEC_FROMTOP(10)
 #define PATHSPEC_LITERAL(11)
 #define PATHSPEC_GLOB   (12)
+#define PATHSPEC_ICASE  (13)
 
 #define PATHSPEC_ONESTAR 1 /* the pathspec pattern sastisfies GFNM_ONESTAR 
*/
 
diff --git a/setup.c b/setup.c
index b3e146d..e22abf1 100644
--- a/setup.c
+++ b/setup.c
@@ -157,7 +157,6 @@ void verify_non_filename(const char *prefix, const char 
*arg)
  *
  * Possible future magic semantics include stuff like:
  *
- * { PATHSPEC_ICASE, '\0', icase },
  * { PATHSPEC_RECURSIVE, '*', recursive },
  * { PATHSPEC_REGEXP, '\0', regexp },
  *
@@ -171,6 +170,7 @@ static struct pathspec_magic {
{ PATHSPEC_FROMTOP, '/', top },
{ PATHSPEC_LITERAL,   0, literal },
{ PATHSPEC_GLOB,   '\0', glob },
+   { PATHSPEC_ICASE,  '\0', icase },
 };
 
 /*
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line 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/WIP 08/10] common_prefix/read_directory: treat PATHSPEC_ICASE like wildcards

2013-01-13 Thread Nguyễn Thái Ngọc Duy

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

diff --git a/dir.c b/dir.c
index 760b776..d0e7ca8 100644
--- a/dir.c
+++ b/dir.c
@@ -66,15 +66,22 @@ static size_t common_prefix_len(const struct pathspec 
*pathspec)
int n;
size_t max = 0;
 
+   /*
+* :(icase)path is treated as a pathspec full of wildcard
+*/
GUARD_PATHSPEC(pathspec,
   PATHSPEC_FROMTOP |
   PATHSPEC_LITERAL |
-  PATHSPEC_GLOB);
+  PATHSPEC_GLOB |
+  PATHSPEC_ICASE);
 
for (n = 0; n  pathspec-nr; n++) {
-   size_t i = 0, len = 0;
-   while (i  pathspec-items[n].nowildcard_len 
-  (n == 0 || i  max)) {
+   size_t i = 0, len = 0, item_len;
+   if (pathspec-items[n].magic  PATHSPEC_ICASE)
+   item_len = pathspec-items[n].prefix;
+   else
+   item_len = pathspec-items[n].nowildcard_len;
+   while (i  item_len  (n == 0 || i  max)) {
char c = pathspec-items[n].match[i];
if (c != pathspec-items[0].match[i])
break;
@@ -1240,7 +1247,8 @@ int read_directory(struct dir_struct *dir, const char 
*path, int len, const stru
GUARD_PATHSPEC(pathspec,
   PATHSPEC_FROMTOP |
   PATHSPEC_LITERAL |
-  PATHSPEC_GLOB);
+  PATHSPEC_GLOB |
+  PATHSPEC_ICASE);
 
if (has_symlink_leading_path(path, len))
return dir-nr;
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line 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/WIP 09/10] pathspec: support icase in match_pathspec_depth and tree_entry_interesting

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 cache.h | 17 +
 dir.c   | 18 +++---
 tree-walk.c | 30 +++---
 3 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/cache.h b/cache.h
index c3b5585..216f87c 100644
--- a/cache.h
+++ b/cache.h
@@ -522,6 +522,23 @@ extern void free_pathspec(struct pathspec *);
 extern int ce_path_match(const struct cache_entry *ce, const struct pathspec 
*pathspec);
 
 extern int limit_pathspec_to_literal(void);
+static inline int ps_strncmp(const struct pathspec_item *item,
+const char *s1, const char *s2, size_t n)
+{
+   if (item-magic  PATHSPEC_ICASE)
+   return strncasecmp(s1, s2, n);
+   else
+   return strncmp(s1, s2, n);
+}
+
+static inline int ps_strcmp(const struct pathspec_item *item,
+   const char *s1, const char *s2)
+{
+   if (item-magic  PATHSPEC_ICASE)
+   return strcasecmp(s1, s2);
+   else
+   return strcmp(s1, s2);
+}
 
 #define HASH_WRITE_OBJECT 1
 #define HASH_FORMAT_CHECK 2
diff --git a/dir.c b/dir.c
index d0e7ca8..e9edb65 100644
--- a/dir.c
+++ b/dir.c
@@ -42,7 +42,7 @@ inline int git_fnmatch(const struct pathspec_item *item,
   int prefix)
 {
if (prefix  0) {
-   if (strncmp(pattern, string, prefix))
+   if (ps_strncmp(item, pattern, string, prefix))
return FNM_NOMATCH;
pattern += prefix;
string += prefix;
@@ -51,14 +51,16 @@ inline int git_fnmatch(const struct pathspec_item *item,
int pattern_len = strlen(++pattern);
int string_len = strlen(string);
return string_len  pattern_len ||
-  strcmp(pattern,
- string + string_len - pattern_len);
+   ps_strcmp(item, pattern,
+ string + string_len - pattern_len);
}
if (item-magic  PATHSPEC_GLOB)
-   return wildmatch(pattern, string, 0);
+   return wildmatch(pattern, string,
+item-magic  PATHSPEC_ICASE ? FNM_CASEFOLD : 
0);
else
/* wildmatch has not learned no FNM_PATHNAME mode yet */
-   return fnmatch(pattern, string, 0);
+   return fnmatch(pattern, string,
+  item-magic  PATHSPEC_ICASE ? FNM_CASEFOLD : 0);
 }
 
 static size_t common_prefix_len(const struct pathspec *pathspec)
@@ -162,7 +164,7 @@ static int match_pathspec_item(const struct pathspec_item 
*item, int prefix,
if (!*match)
return MATCHED_RECURSIVELY;
 
-   if (matchlen = namelen  !strncmp(match, name, matchlen)) {
+   if (matchlen = namelen  !ps_strncmp(item, match, name, matchlen)) {
if (matchlen == namelen)
return MATCHED_EXACTLY;
 
@@ -192,10 +194,12 @@ int match_pathspec_depth(const struct pathspec *ps,
 {
int i, retval = 0;
 
+   /* BUG: we should not match icase on the prefix part */
GUARD_PATHSPEC(ps,
   PATHSPEC_FROMTOP |
   PATHSPEC_LITERAL |
-  PATHSPEC_GLOB);
+  PATHSPEC_GLOB |
+  PATHSPEC_ICASE);
 
if (!ps-nr) {
if (!ps-recursive || ps-max_depth == -1)
diff --git a/tree-walk.c b/tree-walk.c
index 1679ce7..3d9c2ba 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -488,7 +488,8 @@ int get_tree_entry(const unsigned char *tree_sha1, const 
char *name, unsigned ch
return retval;
 }
 
-static int match_entry(const struct name_entry *entry, int pathlen,
+static int match_entry(const struct pathspec_item *item,
+  const struct name_entry *entry, int pathlen,
   const char *match, int matchlen,
   enum interesting *never_interesting)
 {
@@ -504,8 +505,8 @@ static int match_entry(const struct name_entry *entry, int 
pathlen,
 * Does match sort strictly earlier than path
 * with their common parts?
 */
-   m = strncmp(match, entry-path,
-   (matchlen  pathlen) ? matchlen : pathlen);
+   m = ps_strncmp(item, match, entry-path,
+  (matchlen  pathlen) ? matchlen : pathlen);
if (m  0)
return 0;
 
@@ -540,7 +541,7 @@ static int match_entry(const struct name_entry *entry, int 
pathlen,
 * we cheated and did not do strncmp(), so we do
 * that here.
 */
-   m = strncmp(match, entry-path, pathlen);
+   m = ps_strncmp(item, match, entry-path, pathlen);
 
/*
 * If common part matched earlier then it is a hit,
@@ -553,10 +554,11 @@ static int 

[PATCH/WIP 10/10] Enable ls-files and ls-tree for testing PATHSPEC_ICASE

2013-01-13 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/add.c  | 6 --
 builtin/ls-files.c | 3 ++-
 builtin/ls-tree.c  | 3 ++-
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index a3ffa9d..b9a5432 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -421,12 +421,14 @@ int cmd_add(int argc, const char **argv, const char 
*prefix)
GUARD_PATHSPEC(pathspec,
   PATHSPEC_FROMTOP |
   PATHSPEC_LITERAL |
-  PATHSPEC_GLOB);
+  PATHSPEC_GLOB |
+  PATHSPEC_ICASE);
 
for (i = 0; i  pathspec.nr; i++) {
const char *path = pathspec.items[i].match;
if (!seen[i] 
-   ((pathspec.items[i].magic  PATHSPEC_GLOB) ||
+   ((pathspec.items[i].magic 
+ (PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
 !file_exists(path))) {
if (ignore_missing) {
int dtype = DT_UNKNOWN;
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index feb4220..53b222d 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -538,7 +538,8 @@ int cmd_ls_files(int argc, const char **argv, const char 
*cmd_prefix)
parse_pathspec(pathspec,
   PATHSPEC_FROMTOP |
   PATHSPEC_LITERAL |
-  PATHSPEC_GLOB,
+  PATHSPEC_GLOB |
+  PATHSPEC_ICASE,
   PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP,
   prefix, argv);
 
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index 25d0590..cf943dd 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -175,7 +175,8 @@ int cmd_ls_tree(int argc, const char **argv, const char 
*prefix)
parse_pathspec(pathspec,
   PATHSPEC_FROMTOP |
   PATHSPEC_LITERAL |
-  PATHSPEC_GLOB,
+  PATHSPEC_GLOB |
+  PATHSPEC_ICASE,
   0, prefix, argv + 1);
for (i = 0; i  pathspec.nr; i++)
pathspec.items[i].nowildcard_len = pathspec.items[i].len;
-- 
1.8.0.rc2.23.g1fb49df

--
To unsubscribe from this list: send the line 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/8] git_remote_helpers: fix input when running under Python 3

2013-01-13 Thread John Keeping
On Sun, Jan 13, 2013 at 04:26:39AM +0100, Michael Haggerty wrote:
 On 01/12/2013 08:23 PM, John Keeping wrote:
 Although 2to3 will fix most issues in Python 2 code to make it run under
 Python 3, it does not handle the new strict separation between byte
 strings and unicode strings.  There is one instance in
 git_remote_helpers where we are caught by this.
 
 Fix it by explicitly decoding the incoming byte string into a unicode
 string.  In this instance, use the locale under which the application is
 running.
 
 Signed-off-by: John Keeping j...@keeping.me.uk
 ---
  git_remote_helpers/git/importer.py | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/git_remote_helpers/git/importer.py 
 b/git_remote_helpers/git/importer.py
 index e28cc8f..6814003 100644
 --- a/git_remote_helpers/git/importer.py
 +++ b/git_remote_helpers/git/importer.py
 @@ -20,7 +20,7 @@ class GitImporter(object):
  Returns a dictionary with refs.
  
  args = [git, --git-dir= + gitdir, for-each-ref, refs/heads]
 -lines = check_output(args).strip().split('\n')
 +lines = check_output(args).decode().strip().split('\n')
  refs = {}
  for line in lines:
  value, name = line.split(' ')
 
 
 Won't this change cause an exception if the branch names are not all
 valid strings in the current locale's encoding?  I don't see how this
 assumption is justified (e.g., see git-check-ref-format(1) for the rules
 governing reference names).

Yes it will.  The problem is that for Python 3 we need to decode the
byte string into a unicode string, which means we need to know what
encoding it is.

I don't think we can just say git-for-each-ref will print refs in
UTF-8 since AFAIK git doesn't care what encoding the refs are in - I
suspect that's determined by the filesystem which in the end probably
maps to whatever bytes the shell fed git when the ref was created.

That's why I chose the current locale in this case.  I'm hoping someone
here will correct me if we can do better, but I don't see any way of
avoiding choosing some encoding here if we want to support Python 3
(which I think we will, even if we don't right now).


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


Re: [PATCH 3/8] git_remote_helpers: Force rebuild if python version changes

2013-01-13 Thread John Keeping
On Sat, Jan 12, 2013 at 06:30:44PM -0500, Pete Wyckoff wrote:
 j...@keeping.me.uk wrote on Sat, 12 Jan 2013 19:23 +:
 When different version of python are used to build via distutils, the
 behaviour can change.  Detect changes in version and pass --force in
 this case.
[..]
 diff --git a/git_remote_helpers/Makefile b/git_remote_helpers/Makefile
[..]
 +py_version=$(shell $(PYTHON_PATH) -c \
 +'import sys; print(%i.%i % sys.version_info[:2])')
 +
  all: $(pysetupfile)
 -$(QUIET)$(PYTHON_PATH) $(pysetupfile) $(QUIETSETUP) build
 +$(QUIET)test $$(cat GIT-PYTHON_VERSION 2/dev/null) = $(py_version) 
 || \
 +flags=--force; \
 +$(PYTHON_PATH) $(pysetupfile) $(QUIETSETUP) build $$flags
 +$(QUIET)echo $(py_version) GIT-PYTHON_VERSION
 
 Can you depend on ../GIT-PYTHON-VARS instead?  It comes from
 96a4647 (Makefile: detect when PYTHON_PATH changes, 2012-12-18).
 It doesn't check version, just path, but hopefully that's good
 enough.  I'm imagining a rule that would do clean if
 ../GIT-PYTHON-VARS changed, then build without --force.

I was trying to keep the git_remote_helpers directory self contained.  I
can't see how to depend on ../GIT-PYTHON-VARS in a way that is as simple
as this and keeps make -C git_remote_helpers working in a clean tree.

Am I missing something obvious here?


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


Re: [PATCH 0/8] Initial support for Python 3

2013-01-13 Thread Pete Wyckoff
j...@keeping.me.uk wrote on Sun, 13 Jan 2013 00:41 +:
 On Sat, Jan 12, 2013 at 06:43:04PM -0500, Pete Wyckoff wrote:
  Can you give me some hints about the byte/unicode string issues
  in git-p4.py?  There's really only one place that does:
  
  p4 = subprocess.Popen(p4 -G ...)
  marshal.load(p4.stdout)
  
  If that's the only issue, this might not be too paniful.
 
 The problem is that what gets loaded there is a dictionary (encoded by
 p4) that maps byte strings to byte strings, so all of the accesses to
 that dictionary need to either:
 
1) explicitly call encode() on a string constant
 or 2) use a byte string constant with a b prefix
 
 Or we could re-write the dictionary once, which handles the keys... but
 some of the values are also used as strings and we can't handle that as
 a one-off conversion since in other places we really do want the byte
 string (think content of binary files).
 
 Basically a thorough audit of all access to variables that come from p4
 would be needed, with explicit decode()s for authors, dates, etc.

Your auto-conversion snippet in the follow-up mail would work
fine for most keys and values.  A few perforce docs and some
playing around convince me that it is mostly utf-8, except for
file data for particular types.

I'd still rather handle each command separately, and think about
the conversions, to do it right in the long run.

  I hesitated to take Sebastian's changes due to the huge number of
  print() lines, but maybe a 2to3 approach would make that aspect
  of python3 support not too onerous.
 
 I think we'd want to change to print() eventually and having a single
 codebase for 2 and 3 would be nicer for development, but I think we need
 to be able to say no one is using Python 2.5 or earlier before we can
 do that and I'm not sure we're there yet.  From where we are at the
 moment I think 2to3 is a good answer, particularly where we're already
 using distutils to generate a release image.

Agreed.  The 2to3 diff is large but straightforward.  But these
p4 -G interface errors require a lot of thought and work.  I'm
not too eager to work on this yet.

Thanks.

-- Pete
--
To unsubscribe from this list: send the line 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] tests: turn on test-lint-shell-syntax by default

2013-01-13 Thread Matt Kraai
On Sun, Jan 13, 2013 at 11:25:57AM +0100, Torsten Bögershausen wrote:
 @@ -16,10 +16,10 @@ sub err {
  
  while () {
   chomp;
 - /^\s*sed\s+-i/ and err 'sed -i is not portable';
 - /^\s*echo\s+-n/ and err 'echo -n is not portable (please use printf)';
 - /^\s*declare\s+/ and err 'arrays/declare not portable';
 - /^\s*[^#]\s*which\s/ and err 'which is not portable (please use type)';
 + /^\s*sed\s+-i\s+\S/ and err 'sed -i is not portable';
 + /^\s*echo\s+-n\s+\S/ and err 'echo -n is not portable (please use 
 printf)';
 + /^\s*declare\s+\S/ and err 'arrays/declare not portable';
 + /^\s*[^#]\s*which\s+[-a-zA-Z0-9]+$/ and err 'which is not portable 
 (please use type)';

The [^#] appears to ensure that there's at least one character
before the which and that it's not a pound sign.  Why is this done?
Why isn't it done for the other commands?
--
To unsubscribe from this list: send the line 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] t/lib-cvs: cvsimport no longer works without Python = 2.7

2013-01-13 Thread John Keeping
On Sat, Jan 12, 2013 at 04:27:36PM +0100, Michael Haggerty wrote:
  Even if we were to rip out the fallback code that uses the 2.7-only
  subprocess.check_output() on cvsps -V, the function is also used
  for doing the real work interacting with cvsps-3.x, so I think this
  patch will be necessary.  Unless new cvsimport is tweaked not to
  use the method, that is.
 
  A suggestion for a better alternative is of course very much
  appreciated.
 
 If the only reason to require Python 2.7 is subprocess.check_output(),
 it would be easy to reimplement it (it is only 12 lines of
 straightforward code, plus a few lines to define the exception type
 CalledProcessError).  According to [1], the Python license is
 GPL-compatible; therefore these lines could even be copied into
 git-cvsimport.

Note that this has already be done in git_remote_helpers.util.  Is there
any reason not to just reference that?


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


Re: [PATCH 0/8] Initial support for Python 3

2013-01-13 Thread John Keeping
On Sun, Jan 13, 2013 at 11:40:45AM -0500, Pete Wyckoff wrote:
 j...@keeping.me.uk wrote on Sun, 13 Jan 2013 00:41 +:
 On Sat, Jan 12, 2013 at 06:43:04PM -0500, Pete Wyckoff wrote:
  Can you give me some hints about the byte/unicode string issues
  in git-p4.py?  There's really only one place that does:
  
  p4 = subprocess.Popen(p4 -G ...)
  marshal.load(p4.stdout)
  
  If that's the only issue, this might not be too paniful.
 
 The problem is that what gets loaded there is a dictionary (encoded by
 p4) that maps byte strings to byte strings, so all of the accesses to
 that dictionary need to either:
 
1) explicitly call encode() on a string constant
 or 2) use a byte string constant with a b prefix
 
 Or we could re-write the dictionary once, which handles the keys... but
 some of the values are also used as strings and we can't handle that as
 a one-off conversion since in other places we really do want the byte
 string (think content of binary files).
 
 Basically a thorough audit of all access to variables that come from p4
 would be needed, with explicit decode()s for authors, dates, etc.
 
 Your auto-conversion snippet in the follow-up mail would work
 fine for most keys and values.  A few perforce docs and some
 playing around convince me that it is mostly utf-8, except for
 file data for particular types.
 
 I'd still rather handle each command separately, and think about
 the conversions, to do it right in the long run.

I sent that on the assumption that the same key would have similar
semantics wherever its used, but I don't use git-p4 or know much about
perforce.

It would be interesting to know whether there is any likelihood of p4
gaining a Python 3 output mode (since the documentation currently say
not to use p4 -G with Python 3).  If it does then I would assume that
it will make a sensible choice about unicode/bytes such that the
existing git-p4 would Just Work with only a small change to the
invocation of p4 to add the new argument.

  I hesitated to take Sebastian's changes due to the huge number of
  print() lines, but maybe a 2to3 approach would make that aspect
  of python3 support not too onerous.
 
 I think we'd want to change to print() eventually and having a single
 codebase for 2 and 3 would be nicer for development, but I think we need
 to be able to say no one is using Python 2.5 or earlier before we can
 do that and I'm not sure we're there yet.  From where we are at the
 moment I think 2to3 is a good answer, particularly where we're already
 using distutils to generate a release image.
 
 Agreed.  The 2to3 diff is large but straightforward.  But these
 p4 -G interface errors require a lot of thought and work.  I'm
 not too eager to work on this yet.

Fair enough.  As I don't use git-p4, it's not something I intend to
tackle either (given the scale of the changes involved).

Given the minimal scope of the changes needed for everything else, I
sent this series wondering whether it's sensible to move forward on the
basis of Python scripts except git-p4 work with Python 3.  You must use
Python 2 if you want to use git-p4.


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


Re: [PATCH 3/8] git_remote_helpers: Force rebuild if python version changes

2013-01-13 Thread John Keeping
On Sun, Jan 13, 2013 at 12:14:02PM -0500, Pete Wyckoff wrote:
 j...@keeping.me.uk wrote on Sun, 13 Jan 2013 16:26 +:
 On Sat, Jan 12, 2013 at 06:30:44PM -0500, Pete Wyckoff wrote:
  j...@keeping.me.uk wrote on Sat, 12 Jan 2013 19:23 +:
  When different version of python are used to build via distutils, the
  behaviour can change.  Detect changes in version and pass --force in
  this case.
 [..]
  diff --git a/git_remote_helpers/Makefile b/git_remote_helpers/Makefile
 [..]
  +py_version=$(shell $(PYTHON_PATH) -c \
  + 'import sys; print(%i.%i % sys.version_info[:2])')
  +
   all: $(pysetupfile)
  - $(QUIET)$(PYTHON_PATH) $(pysetupfile) $(QUIETSETUP) build
  + $(QUIET)test $$(cat GIT-PYTHON_VERSION 2/dev/null) = $(py_version) 
  || \
  + flags=--force; \
  + $(PYTHON_PATH) $(pysetupfile) $(QUIETSETUP) build $$flags
  + $(QUIET)echo $(py_version) GIT-PYTHON_VERSION
  
  Can you depend on ../GIT-PYTHON-VARS instead?  It comes from
  96a4647 (Makefile: detect when PYTHON_PATH changes, 2012-12-18).
  It doesn't check version, just path, but hopefully that's good
  enough.  I'm imagining a rule that would do clean if
  ../GIT-PYTHON-VARS changed, then build without --force.
 
 I was trying to keep the git_remote_helpers directory self contained.  I
 can't see how to depend on ../GIT-PYTHON-VARS in a way that is as simple
 as this and keeps make -C git_remote_helpers working in a clean tree.
 
 Am I missing something obvious here?
 
 Not if it wants to stay self-contained; you're right.
 
 I'm not thrilled with how git_remote_helpers/Makefile always
 runs setup.py, and always generates PYLIBDIR, and now always
 invokes python a third time to see if its version changed.

I don't think PYLIBDIR will be calculated unless it's used ('=' not
':=' means its a deferred variable).

I wonder if the version check should move into setup.py - it would be
just as easy to check the file there and massage sys.args, although
possibly not as neat.


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


Re: git list files

2013-01-13 Thread Jonathan Nieder
Hi,

Стойчо Слепцов wrote:

 lets, say the equivalent of the $ls -d b* within git.git root directory
 would look like:

 
 98746061 jrnieder 2010-08-12 17:11 Standardize-do-.-while-0-style   base85.c
 c43cb386 pclouds  2012-10-26 22:53 Move-estimate_bisect_steps-to-li bisect.c
 efc7df45 pclouds  2012-10-26 22:53 Move-print_commit_list-to-libgit bisect.h
 837d395a barkalow 2010-01-18 13:06 Replace-parse_blob-with-an-expla blob.c
 837d395a barkalow 2010-01-18 13:06 Replace-parse_blob-with-an-expla blob.h
 ebcfa444 gitster  2012-07-23 20:56 Merge-branch-jn-block-sha1   block-sha1

You might like Peff's or Jakub's tree blame script.  The newest version
I can find is

 http://thread.gmane.org/gmane.comp.version-control.git/168323

If you use it, let us know how it goes.

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


Re: git list files

2013-01-13 Thread Стойчо Слепцов
not really,
ls-tree provides the hash of blobs and trees,
what I am searching for isthe last commitwho introduced the blob or tree.

but, hey, thanks for the answer!
Blind

2013/1/13 Matthieu Moy matthieu@grenoble-inp.fr:
 Стойчо Слепцов stoycho.slept...@gmail.com writes:

 Hi,

 I was searching for some git- command to provide me a list of files
 (in a git directory), same as ls,
 but showing information from the last commit of the file instead.

 lets, say the equivalent of the $ls -d b* within git.git root directory
 would look like:

 git ls-tree HEAD

 ?

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


Re: git list files

2013-01-13 Thread Стойчо Слепцов
thanks alot, Jonathan,
I'll try to search through those scripts.

Blind.

2013/1/13 Jonathan Nieder jrnie...@gmail.com:
 Hi,

 Стойчо Слепцов wrote:

 lets, say the equivalent of the $ls -d b* within git.git root directory
 would look like:

 
 98746061 jrnieder 2010-08-12 17:11 Standardize-do-.-while-0-style   base85.c
 c43cb386 pclouds  2012-10-26 22:53 Move-estimate_bisect_steps-to-li bisect.c
 efc7df45 pclouds  2012-10-26 22:53 Move-print_commit_list-to-libgit bisect.h
 837d395a barkalow 2010-01-18 13:06 Replace-parse_blob-with-an-expla blob.c
 837d395a barkalow 2010-01-18 13:06 Replace-parse_blob-with-an-expla blob.h
 ebcfa444 gitster  2012-07-23 20:56 Merge-branch-jn-block-sha1   
 block-sha1

 You might like Peff's or Jakub's tree blame script.  The newest version
 I can find is

  http://thread.gmane.org/gmane.comp.version-control.git/168323

 If you use it, let us know how it goes.

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


Re: [PATCH] archive-tar: fix sanity check in config parsing

2013-01-13 Thread Jeff King
On Sun, Jan 13, 2013 at 06:42:01PM +0100, René Scharfe wrote:

 When parsing these config variable names, we currently check that
 the second dot is found nine characters into the name, disallowing
 filter names with a length of five characters.  Additionally,
 git archive crashes when the second dot is omitted:
 
   $ ./git -c tar.foo=bar archive HEAD /dev/null
   fatal: Data too large to fit into virtual memory space.
 
 Instead we should check if the second dot exists at all, or if
 we only found the first one.

Eek. Thanks for finding it. Your fix is obviously correct.

 --- a/archive-tar.c
 +++ b/archive-tar.c
 @@ -335,7 +335,7 @@ static int tar_filter_config(const char *var, const char 
 *value, void *data)
   if (prefixcmp(var, tar.))
   return 0;
   dot = strrchr(var, '.');
 - if (dot == var + 9)
 + if (dot == var + 3)
   return 0;

For the curious, the original version of the patch[1] read:

+   if (prefixcmp(var, tarfilter.))
+   return 0;
+   dot = strrchr(var, '.');
+   if (dot == var + 9)
+   return 0;

and when I shortened the config section to tar in a re-roll of the
series, I missed the corresponding change to the offset.

-Peff

[1] http://thread.gmane.org/gmane.comp.version-control.git/175785/focus=175858
--
To unsubscribe from this list: send the line 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 list files

2013-01-13 Thread Jeff King
On Sun, Jan 13, 2013 at 09:56:02AM -0800, Jonathan Nieder wrote:

  lets, say the equivalent of the $ls -d b* within git.git root directory
  would look like:
 
  
  98746061 jrnieder 2010-08-12 17:11 Standardize-do-.-while-0-style   base85.c
  c43cb386 pclouds  2012-10-26 22:53 Move-estimate_bisect_steps-to-li bisect.c
  efc7df45 pclouds  2012-10-26 22:53 Move-print_commit_list-to-libgit bisect.h
  837d395a barkalow 2010-01-18 13:06 Replace-parse_blob-with-an-expla blob.c
  837d395a barkalow 2010-01-18 13:06 Replace-parse_blob-with-an-expla blob.h
  ebcfa444 gitster  2012-07-23 20:56 Merge-branch-jn-block-sha1   
  block-sha1
 
 You might like Peff's or Jakub's tree blame script.  The newest version
 I can find is
 
  http://thread.gmane.org/gmane.comp.version-control.git/168323

As far as I recall, that script works. However, I have a pure-C
blame-tree implementation that is much faster, which may also be of
interest. I need to clean up and put a few finishing touches on it to
send it to the list, but it has been in production at GitHub for a few
months. You can find it here:

  git://github.com/peff/git jk/blame-tree

It's built on the regular diff traversal, just like the perl script you
linked, but doing it all in-process makes things fast.  I also added a
--max-depth parameter for diff, so you can do:

  git blame-tree --max-depth=1 -- Documentation

to recurse into the Documentation subdir, but not go into its
subdirectories. One of the things I need to clean up is that my counting
of --max-depth is different from that used by git grep, and we would
probably want reconcile that.

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


[PATCH] t0050: mark TC merge (case change) as success

2013-01-13 Thread Torsten Bögershausen
The test merge (case change) passes on a case ignoring file system

Use test_expect_success to remove the known breakage vanished

Signed-off-by: Torsten Bögershausen tbo...@web.de
---
 t/t0050-filesystem.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh
index 78816d9..ccd685d 100755
--- a/t/t0050-filesystem.sh
+++ b/t/t0050-filesystem.sh
@@ -77,7 +77,7 @@ $test_case 'rename (case change)' '
 
 '
 
-$test_case 'merge (case change)' '
+test_expect_success 'merge (case change)' '
 
rm -f CamelCase 
rm -f camelcase 
-- 
1.8.0.197.g5a90748

--
To unsubscribe from this list: send the line 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] t0050: mark TC merge (case change) as success

2013-01-13 Thread Torsten Bögershausen
The test merge (case change) passes on a case ignoring file system

Use test_expect_success to remove the known breakage vanished

Signed-off-by: Torsten Bögershausen tbo...@web.de
---
 t/t0050-filesystem.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh
index 78816d9..ccd685d 100755
--- a/t/t0050-filesystem.sh
+++ b/t/t0050-filesystem.sh
@@ -77,7 +77,7 @@ $test_case 'rename (case change)' '
 
 '
 
-$test_case 'merge (case change)' '
+test_expect_success 'merge (case change)' '
 
rm -f CamelCase 
rm -f camelcase 
-- 
1.8.0.197.g5a90748

--
To unsubscribe from this list: send the line 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] git-completion.bash: add support for path completion

2013-01-13 Thread Junio C Hamano
Manlio Perillo manlio.peri...@gmail.com writes:

 +# Skip git (first argument)
 +for ((i=1; i  ${#words[@]}; i++)); do
 +word=${words[i]}
 +
 +case $word in
 +--)

 Sorry, I have incorrectly (again) indented the case labels.
 I have now configured my editor to correctly indent this.

Yeah, thanks for spotting.

I wouldn't worry *too* much about the style in this script at this
point, though.  It uses a style on its own that is totally different
from the rest of the system (e.g. [ instead of test, semicolon
in if ...; then, etc.) and it probably is better to emulate the
surrounding code, and leave the style fixes to a separate topic,
if we want to (as a contrib/ material that is not POSIX but bash
specific, I do not know if that is even worth it).

 +# Good; we can assume that the following are 
 only non
 +# option arguments.
 +((c = 0))
 +;;

 Here I was thinking to do something like this (not tested):

   -*)
   if [ -n ${2-} ]; then
   # Assume specified git command only
 # accepts simple options
   # (without arguments)
   ((c = 0))

 Since git mv only accepts simple options, this will make the use of '--'
 not required.

Unless you have a file whose name begins with a dash, perhaps?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: What's cooking in git.git (Jan 2013, #05; Fri, 11)

2013-01-13 Thread Junio C Hamano
Duy Nguyen pclo...@gmail.com writes:

 On Sat, Jan 12, 2013 at 6:56 AM, Junio C Hamano gits...@pobox.com wrote:
 * nd/parse-pathspec (2013-01-11) 20 commits

  Uses the parsed pathspec structure in more places where we used to
  use the raw array of strings pathspec.

  Unfortunately, this conflicts a couple of topics in flight. I tried
  to be careful while resolving conflicts, though.

 parse_pathspec has not picked up init_pathspec changes from
 jk/pathspec-literal and nd/pathspec-wildcard (already in master) so
 --literal-pathspecs is probably broken in 'pu' after a lot of
 init_pathspec - parse_pathspec conversion.

I guess it may be a better way forward to hold the series off, and
instead help polishing the other topics that are depended on so that
they can graduate sooner, given multiple topics in flight wants to
touch pathspecs (either change the way they are handled, or adds new
places that use them).
--
To unsubscribe from this list: send the line 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-completion.bash should not add a space after a ref

2013-01-13 Thread Junio C Hamano
Manlio Perillo manlio.peri...@gmail.com writes:

 This is not really a bug, but a small usability problem.

 When completing a reference, Bash will add a space after the reference name.

 As an example in:

 $git show masterTAB

 The problem is that an user may want to show a tree or blog object from
 master:

 $git show master:git.c

Or the user may want to see only changes to the documentation, e.g.

$ git show master Documentation/

so removing a SP is a regression in the other way around.

Given that refer to an object in a tree is a much less often used
operation, I have a feeling that the current behaviour happens to
make a good trade-off between these two conflicting purposes that
cannot be satisfied both at the same time.

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


Re: [PATCH v3 00/31] nd/parse-pathspec

2013-01-13 Thread Junio C Hamano
Nguyễn Thái Ngọc Duy  pclo...@gmail.com writes:

 Changes from v2 (it's hard to keep track of after the rebase, so I may
 be missing something here):

  - rebased on top of recent master, incorporate changes in
init_pathspec from jk/pathspec-literal and nd/pathspec-wildcard to
parse_pathspec

  - kill strip_trailing_slash_from_submodules and treat_gitlinks
(pretty sure it'll cause conflicts with as/check-ignore)

  - kill init_pathspec, match_pathspec, diff_tree_setup_paths and
diff_tree_release_paths
  
  - check points for future pathspec development

 As far as I understand the pathspec unification, I'd say we are
 there, with a few exceptions like mv, external commands.. But those
 are pretty much isolated.

 I'll send another WIP series implementing :(icase) and :(glob), mainly
 to show (me) how future pathspec feature development looks like after
 this.

;-)

Thanks; looking forward to reading 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] t0050: mark TC merge (case change) as success

2013-01-13 Thread Junio C Hamano
Torsten Bögershausen tbo...@web.de writes:

 The test merge (case change) passes on a case ignoring file system

 Use test_expect_success to remove the known breakage vanished

 Signed-off-by: Torsten Bögershausen tbo...@web.de
 ---

Interesting.  When did this change?  Do you happen to have a
bisection?  Or did the test pass from the very beginning?

  t/t0050-filesystem.sh | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

 diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh
 index 78816d9..ccd685d 100755
 --- a/t/t0050-filesystem.sh
 +++ b/t/t0050-filesystem.sh
 @@ -77,7 +77,7 @@ $test_case 'rename (case change)' '
  
  '
  
 -$test_case 'merge (case change)' '
 +test_expect_success 'merge (case change)' '
  
   rm -f CamelCase 
   rm -f camelcase 
--
To unsubscribe from this list: send the line 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] cvsimport: rewrite to use cvsps 3.x to fix major bugs

2013-01-13 Thread Junio C Hamano
Junio C Hamano gits...@pobox.com writes:

 Jonathan Nieder jrnie...@gmail.com writes:

 Michael Haggerty wrote:

 Regarding your claim that within a few months the Perl git-cvsimport is
 going to cease even pretending to work: It might be that the old
 git-cvsimport will stop working *for people who upgrade to cvsps 3.x*.
 But it is not realistic to expect people to synchronize their git and
 cvsps version upgrades.  It is even quite possible that this or that
 Linux distribution will package incompatible versions of the two packages.

 Moreover, I feel an obligation to point the following out:

 In a hypothetical world where cvsps 3.x simply breaks git cvsimport
 it is likely that some distributions would just stick to the existing
 cvsps and not upgrade to 3.x.  Maybe that's a wrong choice, but that's
 a choice some would make.  An even more likely outcome in that
 hypothetical world is that they would ship it renamed to something
 like cvsps3 alongside the existing cvsps.  Or they could rename the
 old version to cvsps2.  If we were the last holdout, we could even
 bundle it as compat/cvsps.

 So please do not act as though the cvsps upgrade is a crisis that we
 need to break ourselves for at threat of no longer working at all.
 The threat doesn't hold water.

 Luckily you have already written patches to make git cvsimport work
 with cvsps 3.x, and through your work you are making a better
 argument: The new cvsimport + cvsps will work better, at least for
 some users, than the old tool.

 Just don't pretend you have the power to force a change for a less
 sensible reason than that!

 After a quick survey of various distros, I think it is very unlikely
 that we will see distros move on to newer cvsps, leaving cvsimport
 broken situation. If anything, it is more like distros decide to
 ignore the new cvsps, until it is made to work with cvsimport [*1*].

 I think it is probably sensible to rename the current cvsimport to
 cvsimport-2, write a small wrapper git-cvsimport.sh which is
 something like this:

 - 8 -
 #!/bin/sh

 if test -z $GIT_CVSPS_VERSION
 then
   case $(cvsps -h 21 | grep 'cvsps version') in
 2.*)
   GIT_CVSPS_VERSION=2
 ;;
   3.*)
   GIT_CVSPS_VERSION=3
 ;;
   esac
 fi

 if test -z $GIT_CVSPS_VERSION 
 then
   echo 2 No supported cvsps available
   exit 1
 fi

 exec git cvsimport-$GIT_CVSPS_VERSION $@
 - 8 -

 and put Eric's one as git-cvsimport-3 (after ripping out the code to
 fallback to the old cvsimport).  The longer term trend will be to
 move away from cvsimport-2, as it is unlikely cvsps-2.x will gain
 improvements, if any; keeping fallback code outside cvsimport-3 will
 be a better first step in the healthier long term code evolution.

 We will keep the current t96xx series of tests, and have them export
 GIT_CVSPS_VERSION=2 at the beginning, protect them with test prereq
 that requires presence of cvsps 2.x; this will still make sure that
 the current cvsimport users will not see any regressions.

 Eric's one should be polished enough to produce good results on the

s/should be polished enough/should be in a polished enough state/
that is.  Also if not right now may better convey what I meant if
written if not already.

 simpler sample CVS histories t96xx deal with soonish if not right
 now, so we can use a method similar to how we shared tests between
 blame and annotate while both were _different_ implementations to
 make sure the newer blame did not inroduce regression by running the
 same set of tests.  Where the result _ought_ to differ, we should
 also add tests that work only with the new cvsimport, of course.

 I could help getting the ball rolling on this, if everybody agrees
 that the above is a sensible direction to go, given the real world
 constraints of distro inertia.

 Agreed?


 [References]

 *1* Fedora, Debian and Ubuntu do not even have cvsps 3.x in their
 bleeding edges, OpenBSD and NetBSD do not seem to have it either,
 and Gentoo and ArchLinux have the cvsps 3.x blocked due to
 incompatiblity.

 http://pkgs.fedoraproject.org/cgit/cvsps.git/
 http://packages.debian.org/search?keywords=cvsps
 http://packages.ubuntu.com/search?keywords=cvsps

 http://packages.gentoo.org/package/dev-vcs/cvsps
 https://bugs.gentoo.org/show_bug.cgi?id=450424

 https://bugs.archlinux.org/task/33363?project=1cat%5B0%5D=2string=cvsps
--
To unsubscribe from this list: send the line 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 03/31] Add parse_pathspec() that converts cmdline args to struct pathspec

2013-01-13 Thread Martin von Zweigbergk
On Sun, Jan 13, 2013 at 4:35 AM, Nguyễn Thái Ngọc Duy pclo...@gmail.com wrote:
 +static void parse_pathspec(struct pathspec *pathspec,
 +  unsigned magic_mask, unsigned flags,
 +  const char *prefix, const char **argv)
 +{
 +   struct pathspec_item *item;
 +   const char *entry = *argv;
 ...
 +   for (i = 0; i  n; i++) {
 +   const char *arg = argv[i];

Nit: *argv was assigned to entry above. Reassign that variable instead?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


cvs-fast-export release announcement

2013-01-13 Thread Eric S. Raymond
Version 0.2 of the code formerly known as parsecvs has just shipped as
cvs-fast-export.  Project page, with links to documentation and the
public repository, is at http://www.catb.org/esr/cvs-fast-export/.

I have some cvsps and reposurgeon patches to merge before I can get
back to the script wrapper.
-- 
a href=http://www.catb.org/~esr/;Eric S. Raymond/a

The most foolish mistake we could possibly make would be to permit 
the conquered Eastern peoples to have arms.  History teaches that all 
conquerors who have allowed their subject races to carry arms have 
prepared their own downfall by doing so.
-- Adolph Hitler, April 11 1942.
--
To unsubscribe from this list: send the line 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 03/31] Add parse_pathspec() that converts cmdline args to struct pathspec

2013-01-13 Thread Duy Nguyen
On Mon, Jan 14, 2013 at 7:05 AM, Martin von Zweigbergk
martinv...@gmail.com wrote:
 On Sun, Jan 13, 2013 at 4:35 AM, Nguyễn Thái Ngọc Duy pclo...@gmail.com 
 wrote:
 +static void parse_pathspec(struct pathspec *pathspec,
 +  unsigned magic_mask, unsigned flags,
 +  const char *prefix, const char **argv)
 +{
 +   struct pathspec_item *item;
 +   const char *entry = *argv;
 ...
 +   for (i = 0; i  n; i++) {
 +   const char *arg = argv[i];

 Nit: *argv was assigned to entry above. Reassign that variable instead?

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


Re: What's cooking in git.git (Jan 2013, #05; Fri, 11)

2013-01-13 Thread Duy Nguyen
On Mon, Jan 14, 2013 at 6:02 AM, Junio C Hamano gits...@pobox.com wrote:
 Duy Nguyen pclo...@gmail.com writes:

 On Sat, Jan 12, 2013 at 6:56 AM, Junio C Hamano gits...@pobox.com wrote:
 * nd/parse-pathspec (2013-01-11) 20 commits

  Uses the parsed pathspec structure in more places where we used to
  use the raw array of strings pathspec.

  Unfortunately, this conflicts a couple of topics in flight. I tried
  to be careful while resolving conflicts, though.

 parse_pathspec has not picked up init_pathspec changes from
 jk/pathspec-literal and nd/pathspec-wildcard (already in master) so
 --literal-pathspecs is probably broken in 'pu' after a lot of
 init_pathspec - parse_pathspec conversion.

 I guess it may be a better way forward to hold the series off, and
 instead help polishing the other topics that are depended on so that
 they can graduate sooner, given multiple topics in flight wants to
 touch pathspecs (either change the way they are handled, or adds new
 places that use them).

No problem. Just tell me when you want me to flood git@vger again.
-- 
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/3] A smoother transition plan for cvsimport

2013-01-13 Thread Junio C Hamano
So here is a start of how such a transition plan outlined in the
previous message may look like.

The first two are preparatory step to allow the current code to
still work even when cvsps2 and cvsps3 are both available on the
system.

The last patch is mostly for illustration purposes; the cvsimport-3.py
script it adds was taken from the patch Eric sent earlier and I relayed
to the list, and does not have later improvements in Eric's tree or
any of Chris's patches.

Junio C Hamano (3):
  cvsimport: allow setting a custom cvsps (2.x) program name
  cvsimport: introduce a version-switch wrapper
  cvsimport: start adding cvsps 3.x support

 .gitignore   |1 +
 Makefile |   28 +-
 git-cvsimport-2.perl | 1179 ++
 git-cvsimport-3.py   |  344 +++
 git-cvsimport.perl   | 1177 -
 git-cvsimport.sh |5 +
 t/lib-cvs.sh |4 +-
 7 files changed, 1553 insertions(+), 1185 deletions(-)
 create mode 100755 git-cvsimport-2.perl
 create mode 100755 git-cvsimport-3.py
 delete mode 100755 git-cvsimport.perl
 create mode 100755 git-cvsimport.sh

-- 
1.8.1.421.g6236851

--
To unsubscribe from this list: send the line 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/3] cvsimport: allow setting a custom cvsps (2.x) program name

2013-01-13 Thread Junio C Hamano
Distros may ship old cvsps under a different name, or the user may
install it outside the normal $PATH.  Allow setting CVSPS2_PATH from
the build environment.

Signed-off-by: Junio C Hamano gits...@pobox.com
---
 Makefile   | 9 +++--
 git-cvsimport.perl | 4 +++-
 t/lib-cvs.sh   | 4 +++-
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index 1b30d7b..8cb4a1b 100644
--- a/Makefile
+++ b/Makefile
@@ -571,9 +571,11 @@ endif
 ifndef PYTHON_PATH
PYTHON_PATH = /usr/bin/python
 endif
+ifndef CVSPS2_PATH
+   CVSPS2_PATH = cvsps
+endif
 
-export PERL_PATH
-export PYTHON_PATH
+export PERL_PATH PYTHON_PATH CVSPS2_PATH
 
 LIB_FILE = libgit.a
 XDIFF_LIB = xdiff/lib.a
@@ -1511,6 +1513,7 @@ SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
 PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
 PYTHON_PATH_SQ = $(subst ','\'',$(PYTHON_PATH))
 TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
+CVSPS2_PATH_SQ = $(subst ','\'',$(CVSPS2_PATH))
 DIFF_SQ = $(subst ','\'',$(DIFF))
 
 LIBS = $(GITLIBS) $(EXTLIBS)
@@ -1724,6 +1727,7 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl 
GIT-VERSION-FILE
-e 'H' \
-e 'x' \
-e '}' \
+   -e 's|@@CVSPS2_PATH@@|$(CVSPS2_PATH_SQ)|g' \
-e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
$@.perl $@+  \
chmod +x $@+  \
@@ -2102,6 +2106,7 @@ GIT-LDFLAGS: FORCE
 GIT-BUILD-OPTIONS: FORCE
@echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' $@
@echo PERL_PATH=\''$(subst ','\'',$(PERL_PATH_SQ))'\' $@
+   @echo CVSPS2_PATH=\''$(subst ','\'',$(CVSPS2_PATH_SQ))'\' $@
@echo DIFF=\''$(subst ','\'',$(subst ','\'',$(DIFF)))'\' $@
@echo PYTHON_PATH=\''$(subst ','\'',$(PYTHON_PATH_SQ))'\' $@
@echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' $@
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index 0a31ebd..ad460a5 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -33,6 +33,8 @@
 our 
($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, 
$opt_s,$opt_m,@opt_M,$opt_A,$opt_S,$opt_L, $opt_a, $opt_r, $opt_R);
 my (%conv_author_name, %conv_author_email, %conv_author_tz);
 
+my $cvsps2 = @@CVSPS2_PATH@@;
+
 sub usage(;$) {
my $msg = shift;
print(STDERR Error: $msg\n) if $msg;
@@ -751,7 +753,7 @@ sub munge_user_filename {
unless (defined($opt_p)  $opt_p =~ m/--no-cvs-direct/) {
push @opt, '--cvs-direct';
}
-   exec(cvsps,--norc,@opt,-u,-A,'--root',$opt_d,$cvs_tree);
+   exec($cvsps2,--norc,@opt,-u,-A,'--root',$opt_d,$cvs_tree);
die Could not start cvsps: $!\n;
}
($cvspsfh, $cvspsfile) = tempfile('gitXX', SUFFIX = '.cvsps',
diff --git a/t/lib-cvs.sh b/t/lib-cvs.sh
index 44263ad..bdab63c 100644
--- a/t/lib-cvs.sh
+++ b/t/lib-cvs.sh
@@ -13,7 +13,9 @@ fi
 CVS=cvs -f
 export CVS
 
-cvsps_version=`cvsps -h 21 | sed -ne 's/cvsps version //p'`
+CVSPS=$CVSPS2_PATH
+
+cvsps_version=`$CVSPS -h 21 | sed -ne 's/cvsps version //p'`
 case $cvsps_version in
 2.1 | 2.2*)
;;
-- 
1.8.1.421.g6236851

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


[PATCH 3/3] cvsimport: start adding cvsps 3.x support

2013-01-13 Thread Junio C Hamano
The new cvsps 3.x series lacks support of some options cvsps 2.x
series had and used by cvsimport-2; add a replacement program from
the author of cvsps 3.x and allow users to choose it by setting the
GIT_CVSPS_VERSION environment variable to 3.  We would later add
support to auto-detect the version of installed cvsps to this code
when the environment variable is not set.

Note that in this step, cvsimport-3 that relies on cvsps 3.x does
not have any test coverage.  As cvsimport-3 supports most of the
command line options cvsimport-2, we should be able to tweak some of
t96xx tests and run them with GIT_CVSPS_VERSION set to both 2 and 3,
but that is a topic of later patches that should come on top.

Signed-off-by: Junio C Hamano gits...@pobox.com
---
 Makefile   |  18 ++-
 git-cvsimport-3.py | 344 +
 git-cvsimport.sh   |   4 +-
 3 files changed, 359 insertions(+), 7 deletions(-)
 create mode 100755 git-cvsimport-3.py

diff --git a/Makefile b/Makefile
index b022db2..060cdc2 100644
--- a/Makefile
+++ b/Makefile
@@ -470,8 +470,9 @@ SCRIPT_PERL += git-relink.perl
 SCRIPT_PERL += git-send-email.perl
 SCRIPT_PERL += git-svn.perl
 
-SCRIPT_PYTHON += git-remote-testpy.py
+SCRIPT_PYTHON += git-cvsimport-3.py
 SCRIPT_PYTHON += git-p4.py
+SCRIPT_PYTHON += git-remote-testpy.py
 
 SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
  $(patsubst %.perl,%,$(SCRIPT_PERL)) \
@@ -575,8 +576,11 @@ endif
 ifndef CVSPS2_PATH
CVSPS2_PATH = cvsps
 endif
+ifndef CVSPS3_PATH
+   CVSPS3_PATH = cvsps
+endif
 
-export PERL_PATH PYTHON_PATH CVSPS2_PATH
+export PERL_PATH PYTHON_PATH CVSPS2_PATH CVSPS3_PATH
 
 LIB_FILE = libgit.a
 XDIFF_LIB = xdiff/lib.a
@@ -1515,6 +1519,7 @@ PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
 PYTHON_PATH_SQ = $(subst ','\'',$(PYTHON_PATH))
 TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
 CVSPS2_PATH_SQ = $(subst ','\'',$(CVSPS2_PATH))
+CVSPS3_PATH_SQ = $(subst ','\'',$(CVSPS3_PATH))
 DIFF_SQ = $(subst ','\'',$(DIFF))
 
 LIBS = $(GITLIBS) $(EXTLIBS)
@@ -1757,12 +1762,15 @@ ifndef NO_PYTHON
 $(patsubst %.py,%,$(SCRIPT_PYTHON)): GIT-CFLAGS GIT-PREFIX GIT-PYTHON-VARS
 $(patsubst %.py,%,$(SCRIPT_PYTHON)): % : %.py
$(QUIET_GEN)$(RM) $@ $@+  \
-   INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C git_remote_helpers -s \
+   INSTLIBDIR_SQ=`MAKEFLAGS= $(MAKE) -C git_remote_helpers -s \
--no-print-directory prefix='$(prefix_SQ)' 
DESTDIR='$(DESTDIR_SQ)' \
-   instlibdir`  \
+   instlibdir | \
+   sed -e s/'/'\''/g`  \
+   echo InstLibDir is $$INSTLIBDIR_SQ  \
sed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \
-e 's|\(os\.getenv(GITPYTHONLIB\)[^)]*)|\1,@@INSTLIBDIR@@)|' \
-   -e 's|@@INSTLIBDIR@@|'$$INSTLIBDIR'|g' \
+   -e 's|@@CVSPS3_PATH@@|$(CVSPS3_PATH_SQ)|g' \
+   -e 's|@@INSTLIBDIR@@|'$$INSTLIBDIR_SQ'|g' \
$@.py $@+  \
chmod +x $@+  \
mv $@+ $@
diff --git a/git-cvsimport-3.py b/git-cvsimport-3.py
new file mode 100755
index 000..57f13b7
--- /dev/null
+++ b/git-cvsimport-3.py
@@ -0,0 +1,344 @@
+#!/usr/bin/env python
+#
+# Import CVS history into git
+#
+# Intended to be a near-workalike of Matthias Urlichs's Perl implementation.
+#
+# By Eric S. Raymond e...@thyrsus.com, December 2012
+# May be redistributed under the license of the git project.
+
+import sys
+
+if sys.hexversion  0x0206:
+sys.stderr.write(git cvsimport: requires Python 2.6 or later.\n)
+sys.exit(1)
+
+import os, getopt, subprocess, tempfile, shutil
+
+DEBUG_COMMANDS = 1
+
+class Fatal(Exception):
+Unrecoverable error.
+def __init__(self, msg):
+Exception.__init__(self)
+self.msg = msg
+
+def do_or_die(dcmd, legend=):
+Either execute a command or raise a fatal exception.
+if legend:
+legend =+ legend
+if verbose = DEBUG_COMMANDS:
+sys.stdout.write(git cvsimport: executing '%s'%s\n % (dcmd, legend))
+try:
+retcode = subprocess.call(dcmd, shell=True)
+if retcode  0:
+raise Fatal(git cvsimport: child was terminated by signal %d. % 
-retcode)
+elif retcode != 0:
+raise Fatal(git cvsimport: child returned %d. % retcode)
+except (OSError, IOError) as e:
+raise Fatal(git cvsimport: execution of %s%s failed: %s % (dcmd, 
legend, e))
+
+def capture_or_die(dcmd, legend=):
+Either execute a command and capture its output or die.
+if legend:
+legend =+ legend
+if verbose = DEBUG_COMMANDS:
+sys.stdout.write(git cvsimport: executing '%s'%s\n % (dcmd, legend))
+try:
+return subprocess.check_output(dcmd, shell=True)
+except subprocess.CalledProcessError as e:
+if e.returncode  0:
+sys.stderr.write(git cvsimport: child was terminated by signal 
%d. % -e.returncode)
+elif e.returncode != 0:
+sys.stderr.write(git cvsimport: child returned %d. % 
e.returncode)

Re: [PATCH 2/3] cvsimport: introduce a version-switch wrapper

2013-01-13 Thread Junio C Hamano
Junio C Hamano gits...@pobox.com writes:

 In preparation to have both old and new cvsimport during the
 transition period, rename the cvsimport script to cvsimport-2
 and introduce a small wrapper that we can later change it to
 allow users to run either frontend (with their corresponding
 cvsps backends).

 Signed-off-by: Junio C Hamano gits...@pobox.com
 ---
  .gitignore   |1 +
  Makefile |3 +-
  git-cvsimport-2.perl | 1179 
 ++
  git-cvsimport.perl   | 1179 
 --

Sorry, I should have done format-patch -M for this one.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH/RFC 4/7] contrib/subtree: Code cleaning and refactoring

2013-01-13 Thread Techlive Zheng
2013/1/13 Techlive Zheng techlivezh...@gmail.com:
 Mostly prepare for the later tests refactoring.

 Signed-off-by: Techlive Zheng techlivezh...@gmail.com

I am personally a SP-indenting guy, I did not aware of Git's indenting
policy until now, so it is bad that I replaced all the lines initially
indent using HT with SP in the test file of this commit. I will submit
another set of patches with the right indenting.
--
To unsubscribe from this list: send the line 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/RFC v2 0/8] contrib/subtree: Reroll to follow Git's whitespace policy

2013-01-13 Thread Techlive Zheng
David A. Greene (1):
  contrib/subtree: Remove test number comments

Techlive Zheng (7):
  contrib/subtree: Fix whitespaces
  contrib/subtree: Add vim modeline
  contrib/subtree: Ignore testing directory
  contrib/subtree: Code cleaning and refactoring
  contrib/subtree: Make each test self-contained
  contrib/subtree: Use %B for the split commit message
  contrib/subtree: Handle '--prefix' argument with a slash appended

 contrib/subtree/.gitignore |5 +-
 contrib/subtree/git-subtree.sh |   85 +--
 contrib/subtree/git-subtree.txt|   55 +-
 contrib/subtree/t/t7900-subtree.sh | 1255 +++-
 4 files changed, 905 insertions(+), 495 deletions(-)

-- 
1.8.1

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


[PATCH/RFC v2 1/8] contrib/subtree: Fix whitespaces

2013-01-13 Thread Techlive Zheng
Previous code does not fulfill Git's whitespace policy.

Signed-off-by: Techlive Zheng techlivezh...@gmail.com
---
 contrib/subtree/git-subtree.sh |  68 
 contrib/subtree/git-subtree.txt|  42 ++---
 contrib/subtree/t/t7900-subtree.sh | 314 ++---
 3 files changed, 212 insertions(+), 212 deletions(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 920c664..70f86ea 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -5,7 +5,7 @@
 # Copyright (C) 2009 Avery Pennarun apenw...@gmail.com
 #
 if [ $# -eq 0 ]; then
-set -- -h
+   set -- -h
 fi
 OPTS_SPEC=\
 git subtree add   --prefix=prefix commit
@@ -110,9 +110,9 @@ if [ -z $prefix ]; then
 fi
 
 case $command in
-   add) [ -e $prefix ]  
+   add) [ -e $prefix ] 
die prefix '$prefix' already exists. ;;
-   *)   [ -e $prefix ] || 
+   *)   [ -e $prefix ] ||
die '$prefix' does not exist; use 'git subtree add' ;;
 esac
 
@@ -181,8 +181,8 @@ cache_set()
oldrev=$1
newrev=$2
if [ $oldrev != latest_old \
--a $oldrev != latest_new \
--a -e $cachedir/$oldrev ]; then
+   -a $oldrev != latest_new \
+   -a -e $cachedir/$oldrev ]; then
die cache for $oldrev already exists!
fi
echo $newrev $cachedir/$oldrev
@@ -304,7 +304,7 @@ copy_commit()
read GIT_COMMITTER_NAME
read GIT_COMMITTER_EMAIL
read GIT_COMMITTER_DATE
-   export  GIT_AUTHOR_NAME \
+   export GIT_AUTHOR_NAME \
GIT_AUTHOR_EMAIL \
GIT_AUTHOR_DATE \
GIT_COMMITTER_NAME \
@@ -327,7 +327,7 @@ add_msg()
fi
cat -EOF
$commit_message
-   
+
git-subtree-dir: $dir
git-subtree-mainline: $latest_old
git-subtree-split: $latest_new
@@ -355,7 +355,7 @@ rejoin_msg()
fi
cat -EOF
$commit_message
-   
+
git-subtree-dir: $dir
git-subtree-mainline: $latest_old
git-subtree-split: $latest_new
@@ -368,7 +368,7 @@ squash_msg()
oldsub=$2
newsub=$3
newsub_short=$(git rev-parse --short $newsub)
-   
+
if [ -n $oldsub ]; then
oldsub_short=$(git rev-parse --short $oldsub)
echo Squashed '$dir/' changes from 
$oldsub_short..$newsub_short
@@ -378,7 +378,7 @@ squash_msg()
else
echo Squashed '$dir/' content from commit $newsub_short
fi
-   
+
echo
echo git-subtree-dir: $dir
echo git-subtree-split: $newsub
@@ -427,7 +427,7 @@ new_squash_commit()
newsub=$3
tree=$(toptree_for_commit $newsub) || exit $?
if [ -n $old ]; then
-   squash_msg $dir $oldsub $newsub | 
+   squash_msg $dir $oldsub $newsub |
git commit-tree $tree -p $old || exit $?
else
squash_msg $dir  $newsub |
@@ -455,7 +455,7 @@ copy_or_skip()
else
nonidentical=$parent
fi
-   
+
# sometimes both old parents map to the same newparent;
# eliminate duplicates
is_new=1
@@ -470,7 +470,7 @@ copy_or_skip()
p=$p -p $parent
fi
done
-   
+
if [ -n $identical ]; then
echo $identical
else
@@ -495,14 +495,14 @@ cmd_add()
fi
 
ensure_clean
-   
+
if [ $# -eq 1 ]; then
cmd_add_commit $@
elif [ $# -eq 2 ]; then
cmd_add_repository $@
else
-   say error: parameters were '$@'
-   die Provide either a refspec or a repository and refspec.
+   say error: parameters were '$@'
+   die Provide either a refspec or a repository and refspec.
fi
 }
 
@@ -522,19 +522,19 @@ cmd_add_commit()
revs=$(git rev-parse $default --revs-only $@) || exit $?
set -- $revs
rev=$1
-   
+
debug Adding $dir as '$rev'...
git read-tree --prefix=$dir $rev || exit $?
git checkout -- $dir || exit $?
tree=$(git write-tree) || exit $?
-   
+
headrev=$(git rev-parse HEAD) || exit $?
if [ -n $headrev -a $headrev != $rev ]; then
headp=-p $headrev
else
headp=
fi
-   
+
if [ -n $squash ]; then
rev=$(new_squash_commit   $rev) || exit $?
commit=$(add_squashed_msg $rev $dir |
@@ -544,7 +544,7 @@ cmd_add_commit()
 git commit-tree $tree $headp -p $rev) || exit $?
fi
git reset $commit || exit $?
-   
+
say 

[PATCH/RFC v2 2/8] contrib/subtree: Add vim modeline

2013-01-13 Thread Techlive Zheng
Signed-off-by: Techlive Zheng techlivezh...@gmail.com
---
 contrib/subtree/git-subtree.sh | 2 ++
 contrib/subtree/t/t7900-subtree.sh | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 70f86ea..88903c0 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -710,3 +710,5 @@ cmd_push()
 }
 
 cmd_$command $@
+
+# vim: set ts=4 sw=4 noet
diff --git a/contrib/subtree/t/t7900-subtree.sh 
b/contrib/subtree/t/t7900-subtree.sh
index b98f7d0..e32d31a 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -506,3 +506,5 @@ test_expect_success 'verify one file change per commit' '
 '
 
 test_done
+
+# vim: set ts=4 sw=4 noet
-- 
1.8.1

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


[PATCH/RFC v2 3/8] contrib/subtree: Ignore testing directory

2013-01-13 Thread Techlive Zheng
Signed-off-by: Techlive Zheng techlivezh...@gmail.com
---
 contrib/subtree/.gitignore | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/contrib/subtree/.gitignore b/contrib/subtree/.gitignore
index 91360a3..59aeeb4 100644
--- a/contrib/subtree/.gitignore
+++ b/contrib/subtree/.gitignore
@@ -1,6 +1,5 @@
 *~
 git-subtree
-git-subtree.xml
 git-subtree.1
-mainline
-subproj
+git-subtree.xml
+t/trash\ directory.*
-- 
1.8.1

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


[PATCH/RFC v2 4/8] contrib/subtree: Remove test number comments

2013-01-13 Thread Techlive Zheng
From: David A. Greene gree...@obbligato.org

Delete the comments indicating test numbers as it causes maintenance
headaches.  t*.sh -i will help us find any broken tests.

Signed-off-by: David A. Greene gree...@obbligato.org
Signed-off-by: Techlive Zheng techlivezh...@gmail.com
---
 contrib/subtree/t/t7900-subtree.sh | 55 --
 1 file changed, 55 deletions(-)

diff --git a/contrib/subtree/t/t7900-subtree.sh 
b/contrib/subtree/t/t7900-subtree.sh
index e32d31a..851d00c 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -60,7 +60,6 @@ last_commit_message()
git log --pretty=format:%s -1
 }
 
-# 1
 test_expect_success 'init subproj' '
test_create_repo subproj
 '
@@ -68,7 +67,6 @@ test_expect_success 'init subproj' '
 # To the subproject!
 cd subproj
 
-# 2
 test_expect_success 'add sub1' '
create sub1 
git commit -m sub1 
@@ -76,14 +74,12 @@ test_expect_success 'add sub1' '
git branch -m master subproj
 '
 
-# 3
 test_expect_success 'add sub2' '
create sub2 
git commit -m sub2 
git branch sub2
 '
 
-# 4
 test_expect_success 'add sub3' '
create sub3 
git commit -m sub3 
@@ -93,7 +89,6 @@ test_expect_success 'add sub3' '
 # Back to mainline
 cd ..
 
-# 5
 test_expect_success 'add main4' '
create main4 
git commit -m main4 
@@ -101,101 +96,85 @@ test_expect_success 'add main4' '
git branch subdir
 '
 
-# 6
 test_expect_success 'fetch subproj history' '
git fetch ./subproj sub1 
git branch sub1 FETCH_HEAD
 '
 
-# 7
 test_expect_success 'no subtree exists in main tree' '
test_must_fail git subtree merge --prefix=subdir sub1
 '
 
-# 8
 test_expect_success 'no pull from non-existant subtree' '
test_must_fail git subtree pull --prefix=subdir ./subproj sub1
 '
 
-# 9
 test_expect_success 'check if --message works for add' '
git subtree add --prefix=subdir --message=Added subproject 
sub1 
check_equal ''$(last_commit_message)'' Added subproject 
undo
 '
 
-# 10
 test_expect_success 'check if --message works as -m and --prefix as -P' '
git subtree add -P subdir -m Added subproject using git 
subtree sub1 
check_equal ''$(last_commit_message)'' Added subproject 
using git subtree 
undo
 '
 
-# 11
 test_expect_success 'check if --message works with squash too' '
git subtree add -P subdir -m Added subproject with squash 
--squash sub1 
check_equal ''$(last_commit_message)'' Added subproject with 
squash 
undo
 '
 
-# 12
 test_expect_success 'add subproj to mainline' '
git subtree add --prefix=subdir/ FETCH_HEAD 
check_equal ''$(last_commit_message)'' Add ''subdir/'' 
from commit '$(git rev-parse sub1)'
 '
 
-# 13
 # this shouldn't actually do anything, since FETCH_HEAD is already a parent
 test_expect_success 'merge fetched subproj' '
git merge -m merge -s -ours -s ours FETCH_HEAD
 '
 
-# 14
 test_expect_success 'add main-sub5' '
create subdir/main-sub5 
git commit -m main-sub5
 '
 
-# 15
 test_expect_success 'add main6' '
create main6 
git commit -m main6 boring
 '
 
-# 16
 test_expect_success 'add main-sub7' '
create subdir/main-sub7 
git commit -m main-sub7
 '
 
-# 17
 test_expect_success 'fetch new subproj history' '
git fetch ./subproj sub2 
git branch sub2 FETCH_HEAD
 '
 
-# 18
 test_expect_success 'check if --message works for merge' '
git subtree merge --prefix=subdir -m Merged changes from 
subproject sub2 
check_equal ''$(last_commit_message)'' Merged changes from 
subproject 
undo
 '
 
-# 19
 test_expect_success 'check if --message for merge works with squash too' '
git subtree merge --prefix subdir -m Merged changes from 
subproject using squash --squash sub2 
check_equal ''$(last_commit_message)'' Merged changes from 
subproject using squash 
undo
 '
 
-# 20
 test_expect_success 'merge new subproj history into subdir' '
git subtree merge --prefix=subdir FETCH_HEAD 
git branch pre-split 
check_equal ''$(last_commit_message)'' Merge commit 
'''$(git rev-parse sub2)''' into mainline
 '
 
-# 21
 test_expect_success 'Check that prefix argument is required for split' '
echo You must provide the --prefix option.  expected 
test_must_fail git subtree split  actual 21 
@@ -207,7 +186,6 @@ test_expect_success 'Check that prefix argument is required 
for split' '
rm -f expected 

[PATCH/RFC v2 5/8] contrib/subtree: Code cleaning and refactoring

2013-01-13 Thread Techlive Zheng
Mostly prepare for the later tests refactoring.

Signed-off-by: Techlive Zheng techlivezh...@gmail.com
---
 contrib/subtree/t/t7900-subtree.sh | 251 +++--
 1 file changed, 130 insertions(+), 121 deletions(-)

diff --git a/contrib/subtree/t/t7900-subtree.sh 
b/contrib/subtree/t/t7900-subtree.sh
index 851d00c..69bd41c 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -4,7 +4,7 @@
 #
 test_description='Basic porcelain support for subtrees
 
-This test verifies the basic operation of the merge, pull, add
+This test verifies the basic operation of the add, pull, merge
 and split subcommands of git subtree.
 '
 
@@ -18,19 +18,6 @@ create()
git add $1
 }
 
-
-check_equal()
-{
-   test_debug 'echo'
-   test_debug echo \check a:\ \{$1}\
-   test_debug echo \  b:\ \{$2}\
-   if [ $1 = $2 ]; then
-   return 0
-   else
-   return 1
-   fi
-}
-
 fixnl()
 {
t=
@@ -55,6 +42,42 @@ undo()
git reset --hard HEAD~
 }
 
+test_equal()
+{
+   test_debug 'echo'
+   test_debug echo \check a:\ \{$1}\
+   test_debug echo \  b:\ \{$2}\
+   if [ $1 = $2 ]; then
+   return 0
+   else
+   return 1
+   fi
+}
+
+# Make sure no patch changes more than one file.
+# The original set of commits changed only one file each.
+# A multi-file change would imply that we pruned commits
+# too aggressively.
+join_commits()
+{
+   commit=
+   all=
+   while read x y; do
+   if [ -z $x ]; then
+   continue
+   elif [ $x = commit: ]; then
+   if [ -n $commit ]; then
+   echo $commit $all
+   all=
+   fi
+   commit=$y
+   else
+   all=$all $y
+   fi
+   done
+   echo $commit $all
+}
+
 last_commit_message()
 {
git log --pretty=format:%s -1
@@ -93,7 +116,7 @@ test_expect_success 'add main4' '
create main4 
git commit -m main4 
git branch -m master mainline 
-   git branch subdir
+   git branch init
 '
 
 test_expect_success 'fetch subproj history' '
@@ -101,40 +124,43 @@ test_expect_success 'fetch subproj history' '
git branch sub1 FETCH_HEAD
 '
 
-test_expect_success 'no subtree exists in main tree' '
-   test_must_fail git subtree merge --prefix=subdir sub1
-'
-
 test_expect_success 'no pull from non-existant subtree' '
test_must_fail git subtree pull --prefix=subdir ./subproj sub1
 '
 
-test_expect_success 'check if --message works for add' '
-   git subtree add --prefix=subdir --message=Added subproject 
sub1 
-   check_equal ''$(last_commit_message)'' Added subproject 
+test_expect_success 'no merge from non-existant subtree' '
+   test_must_fail git subtree merge --prefix=subdir FETCH_HEAD
+'
+
+test_expect_success 'add subproj as subtree into subdir/ with --prefix' '
+   git subtree add --prefix=subdir FETCH_HEAD 
+   test_equal $(last_commit_message) Add '\''subdir/'\'' from 
commit '\''$(git rev-parse FETCH_HEAD)'\'' 
undo
 '
 
-test_expect_success 'check if --message works as -m and --prefix as -P' '
-   git subtree add -P subdir -m Added subproject using git 
subtree sub1 
-   check_equal ''$(last_commit_message)'' Added subproject 
using git subtree 
+test_expect_success 'add subproj as subtree into subdir/ with --prefix and 
--message' '
+   git subtree add --prefix=subdir --message=Added subproject 
FETCH_HEAD 
+   test_equal $(last_commit_message) Added subproject 
undo
 '
 
-test_expect_success 'check if --message works with squash too' '
-   git subtree add -P subdir -m Added subproject with squash 
--squash sub1 
-   check_equal ''$(last_commit_message)'' Added subproject with 
squash 
+test_expect_success 'add subproj as subtree into subdir/ with --prefix as -P 
and --message as -m' '
+   git subtree add -P subdir -m Added subproject FETCH_HEAD 
+   test_equal $(last_commit_message) Added subproject 
undo
 '
 
-test_expect_success 'add subproj to mainline' '
-   git subtree add --prefix=subdir/ FETCH_HEAD 
-   check_equal ''$(last_commit_message)'' Add ''subdir/'' 
from commit '$(git rev-parse sub1)'
+test_expect_success 'add subproj as subtree into subdir/ with --squash and 
--prefix and --message' '
+   git subtree add --prefix=subdir --message=Added subproject 
with squash --squash FETCH_HEAD 
+   test_equal $(last_commit_message) Added subproject with 
squash 
+   undo
 '
 
-# this shouldn't actually do 

[PATCH/RFC v2 6/8] contrib/subtree: Make each test self-contained

2013-01-13 Thread Techlive Zheng
Signed-off-by: Techlive Zheng techlivezh...@gmail.com
---
 contrib/subtree/t/t7900-subtree.sh | 865 ++---
 1 file changed, 614 insertions(+), 251 deletions(-)

diff --git a/contrib/subtree/t/t7900-subtree.sh 
b/contrib/subtree/t/t7900-subtree.sh
index 69bd41c..ef83f31 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -12,12 +12,6 @@ export TEST_DIRECTORY=$(pwd)/../../../t
 
 . ../../../t/test-lib.sh
 
-create()
-{
-   echo $1 $1
-   git add $1
-}
-
 fixnl()
 {
t=
@@ -37,11 +31,6 @@ multiline()
done
 }
 
-undo()
-{
-   git reset --hard HEAD~
-}
-
 test_equal()
 {
test_debug 'echo'
@@ -78,373 +67,746 @@ join_commits()
echo $commit $all
 }
 
+test_create_commit() (
+   repo=$1
+   commit=$2
+   cd $repo
+   mkdir -p $(dirname $commit)
+   echo $commit  $commit
+   git add $commit
+   git commit -m $commit
+)
+
 last_commit_message()
 {
git log --pretty=format:%s -1
 }
 
-test_expect_success 'init subproj' '
-   test_create_repo subproj
-'
-
-# To the subproject!
-cd subproj
-
-test_expect_success 'add sub1' '
-   create sub1 
-   git commit -m sub1 
-   git branch sub1 
-   git branch -m master subproj
-'
-
-test_expect_success 'add sub2' '
-   create sub2 
-   git commit -m sub2 
-   git branch sub2
-'
-
-test_expect_success 'add sub3' '
-   create sub3 
-   git commit -m sub3 
-   git branch sub3
-'
-
-# Back to mainline
-cd ..
-
-test_expect_success 'add main4' '
-   create main4 
-   git commit -m main4 
-   git branch -m master mainline 
-   git branch init
-'
-
-test_expect_success 'fetch subproj history' '
-   git fetch ./subproj sub1 
-   git branch sub1 FETCH_HEAD
-'
+#
+# Tests for 'git subtree add'
+#
 
 test_expect_success 'no pull from non-existant subtree' '
-   test_must_fail git subtree pull --prefix=subdir ./subproj sub1
+   test_create_repo $test_count 
+   test_create_repo $test_count/subproj 
+   test_create_commit $test_count main1 
+   test_create_commit $test_count/subproj sub1 
+   (
+   cd $test_count 
+   git fetch ./subproj master 
+   test_must_fail git subtree pull --prefix=subdir ./subproj master
+   )
 '
 
 test_expect_success 'no merge from non-existant subtree' '
+   test_create_repo $test_count 
+   test_create_repo $test_count/subproj 
+   test_create_commit $test_count main1 
+   test_create_commit $test_count/subproj sub1 
+   (
+   cd $test_count 
+   git fetch ./subproj master 
test_must_fail git subtree merge --prefix=subdir FETCH_HEAD
+   )
 '
 
 test_expect_success 'add subproj as subtree into subdir/ with --prefix' '
+   test_create_repo $test_count 
+   test_create_repo $test_count/subproj 
+   test_create_commit $test_count main1 
+   test_create_commit $test_count/subproj sub1 
+   (
+   cd $test_count 
+   git fetch ./subproj master 
git subtree add --prefix=subdir FETCH_HEAD 
-   test_equal $(last_commit_message) Add '\''subdir/'\'' from 
commit '\''$(git rev-parse FETCH_HEAD)'\'' 
-   undo
+   test_equal $(last_commit_message) Add '\''subdir/'\'' from 
commit '\''$(git rev-parse FETCH_HEAD)'\''
+   )
 '
 
 test_expect_success 'add subproj as subtree into subdir/ with --prefix and 
--message' '
+   test_create_repo $test_count 
+   test_create_repo $test_count/subproj 
+   test_create_commit $test_count main1 
+   test_create_commit $test_count/subproj sub1 
+   (
+   cd $test_count 
+   git fetch ./subproj master 
git subtree add --prefix=subdir --message=Added subproject 
FETCH_HEAD 
-   test_equal $(last_commit_message) Added subproject 
-   undo
+   test_equal $(last_commit_message) Added subproject
+   )
 '
 
 test_expect_success 'add subproj as subtree into subdir/ with --prefix as -P 
and --message as -m' '
+   test_create_repo $test_count 
+   test_create_repo $test_count/subproj 
+   test_create_commit $test_count main1 
+   test_create_commit $test_count/subproj sub1 
+   (
+   cd $test_count 
+   git fetch ./subproj master 
git subtree add -P subdir -m Added subproject FETCH_HEAD 
-   test_equal $(last_commit_message) Added subproject 
-   undo
+   test_equal $(last_commit_message) Added subproject
+   )
 '
 
 test_expect_success 'add subproj as subtree into subdir/ with --squash and 
--prefix and --message' '
+   test_create_repo $test_count 
+   test_create_repo 

[PATCH/RFC v2 7/8] contrib/subtree: Use %B for the split commit message

2013-01-13 Thread Techlive Zheng
Use %B rather than %s%n%n%b to handle the special case of a commit that
only has a subject line.  We don't want to introduce a newline after the
subject, causing generation of a new hash.

After this commit, the newly split branch might differ from the previous
one. If this is the case, --fallback option could help.

Signed-off-by: Techlive Zheng techlivezh...@gmail.com
Signed-off-by: David A. Greene gree...@obbligato.org
---
 contrib/subtree/git-subtree.sh | 13 ++-
 contrib/subtree/git-subtree.txt| 13 +++
 contrib/subtree/t/t7900-subtree.sh | 47 ++
 3 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 88903c0..d529a76 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -25,6 +25,7 @@ b,branch= create a new branch from the split subtree
 ignore-joins  ignore prior --rejoin commits
 onto= try connecting new tree to an existing one
 rejoinmerge the new branch back into HEAD
+fallback  fallback to the obsolete commit generating mechanism
  options for 'add', 'merge', 'pull' and 'push'
 squashmerge subtree changes as a single commit
 
@@ -45,6 +46,7 @@ ignore_joins=
 annotate=
 squash=
 message=
+fallback=
 
 debug()
 {
@@ -92,6 +94,8 @@ while [ $# -gt 0 ]; do
--no-ignore-joins) ignore_joins= ;;
--squash) squash=1 ;;
--no-squash) squash= ;;
+   --fallback) fallback=1 ;;
+   --no-fallback) fallback= ;;
--) break ;;
*) die Unexpected option: $opt ;;
esac
@@ -296,7 +300,14 @@ copy_commit()
# We're going to set some environment vars here, so
# do it in a subshell to get rid of them safely later
debug copy_commit {$1} {$2} {$3}
-   git log -1 --pretty=format:'%an%n%ae%n%ad%n%cn%n%ce%n%cd%n%s%n%n%b' 
$1 |
+
+   if [ -z $fallback ]; then
+   log_format='%an%n%ae%n%ad%n%cn%n%ce%n%cd%n%B'
+   else
+   log_format='%an%n%ae%n%ad%n%cn%n%ce%n%cd%n%s%n%n%b'
+   fi
+
+   git log -1 --pretty=format:$log_format $1 |
(
read GIT_AUTHOR_NAME
read GIT_AUTHOR_EMAIL
diff --git a/contrib/subtree/git-subtree.txt b/contrib/subtree/git-subtree.txt
index 72be8e4..55d0575 100644
--- a/contrib/subtree/git-subtree.txt
+++ b/contrib/subtree/git-subtree.txt
@@ -254,6 +254,19 @@ OPTIONS FOR split
'--rejoin' when you split, because you don't want the
subproject's history to be part of your project anyway.
 
+--fallback::
+   Previously, git subtree would introduce an extra new line for
+   the commits whose commit message contains only one line.
+   This behavior has been correct. Unfortunately, for those whose
+   current split branch contains these kind of commits, git subtree
+   will generate a new split branch which differs from the existing
+   split branch in these commits. It is better to use this new
+   split branch, because its commits stay intact within the mainline.
+
+   Otherwise, the previous fault behavior could still be used with
+   this option. This option is only for a compatible purpose, newly
+   split branch should never use this option.
+
 
 EXAMPLE 1. Add command
 --
diff --git a/contrib/subtree/t/t7900-subtree.sh 
b/contrib/subtree/t/t7900-subtree.sh
index ef83f31..232ed89 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -399,6 +399,53 @@ test_expect_success 'split subdir/ with --branch for an 
incompatible branch' '
)
 '
 
+test_expect_success 'make sure commits with one line message stay intact after 
split' '
+   test_create_repo $test_count 
+   test_create_repo $test_count/subproj 
+   test_create_commit $test_count main1 
+   test_create_commit $test_count/subproj sub1 
+   (
+   cd $test_count 
+   git fetch ./subproj master 
+   ori_hash=$(git rev-parse FETCH_HEAD) 
+   git branch subori FETCH_HEAD 
+   git filter-branch --index-filter '\''git ls-files -s | sed 
s-\t-subdir/- | GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index 
--index-info  mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE'\'' subori
+   git merge -m Merge B project as our subdirectory subori 
+   git subtree split --prefix subdir --branch splitbr1 
+   new_hash_1=$(git rev-parse splitbr1) 
+   test_equal $ori_hash $new_hash_1 
+   git subtree split --prefix subdir --branch splitbr2 --fallback 

+   new_hash_2=$(git rev-parse splitbr2) 
+   test_must_fail test_equal $ori_hash $new_hash_2
+   )
+'
+
+test_expect_success 'make sure --fallback option works correctly for the 
existing split branch' '
+   test_create_repo $test_count 
+   

[PATCH/RFC v2 8/8] contrib/subtree: Handle '--prefix' argument with a slash appended

2013-01-13 Thread Techlive Zheng
'git subtree merge' will fail if the argument of '--prefix' has a slash
appended.

Signed-off-by: Techlive Zheng techlivezh...@gmail.com
---
 contrib/subtree/git-subtree.sh |  2 +-
 contrib/subtree/t/t7900-subtree.sh | 19 +++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index d529a76..40100e5 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -83,7 +83,7 @@ while [ $# -gt 0 ]; do
--annotate) annotate=$1; shift ;;
--no-annotate) annotate= ;;
-b) branch=$1; shift ;;
-   -P) prefix=$1; shift ;;
+   -P) prefix=${1%/}; shift ;;
-m) message=$1; shift ;;
--no-prefix) prefix= ;;
--onto) onto=$1; shift ;;
diff --git a/contrib/subtree/t/t7900-subtree.sh 
b/contrib/subtree/t/t7900-subtree.sh
index 232ed89..297dac4 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -238,6 +238,25 @@ test_expect_success 'merge new subproj history into 
subdir/ with --squash and --
)
 '
 
+test_expect_success 'merge new subproj history into subdir/ with a slash 
appended to the argument of --prefix' '
+   test_create_repo $test_count 
+   test_create_repo $test_count/subproj 
+   test_create_commit $test_count main1 
+   test_create_commit $test_count/subproj sub1 
+   (
+   cd $test_count 
+   git fetch ./subproj master 
+   git subtree add --prefix=subdir/ FETCH_HEAD
+   ) 
+   test_create_commit $test_count/subproj sub2 
+   (
+   cd $test_count 
+   git fetch ./subproj master 
+   git subtree merge --prefix=subdir/ FETCH_HEAD 
+   test_equal $(last_commit_message) Merge commit '\''$(git 
rev-parse FETCH_HEAD)'\''
+   )
+'
+
 #
 # Tests for 'git subtree split'
 #
-- 
1.8.1

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


Re: [PATCH 2/8] git_remote_helpers: fix input when running under Python 3

2013-01-13 Thread Michael Haggerty
On 01/13/2013 05:17 PM, John Keeping wrote:
 On Sun, Jan 13, 2013 at 04:26:39AM +0100, Michael Haggerty wrote:
 On 01/12/2013 08:23 PM, John Keeping wrote:
 Although 2to3 will fix most issues in Python 2 code to make it run under
 Python 3, it does not handle the new strict separation between byte
 strings and unicode strings.  There is one instance in
 git_remote_helpers where we are caught by this.

 Fix it by explicitly decoding the incoming byte string into a unicode
 string.  In this instance, use the locale under which the application is
 running.

 Signed-off-by: John Keeping j...@keeping.me.uk
 ---
  git_remote_helpers/git/importer.py | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

 diff --git a/git_remote_helpers/git/importer.py 
 b/git_remote_helpers/git/importer.py
 index e28cc8f..6814003 100644
 --- a/git_remote_helpers/git/importer.py
 +++ b/git_remote_helpers/git/importer.py
 @@ -20,7 +20,7 @@ class GitImporter(object):
  Returns a dictionary with refs.
  
  args = [git, --git-dir= + gitdir, for-each-ref, refs/heads]
 -lines = check_output(args).strip().split('\n')
 +lines = check_output(args).decode().strip().split('\n')
  refs = {}
  for line in lines:
  value, name = line.split(' ')


 Won't this change cause an exception if the branch names are not all
 valid strings in the current locale's encoding?  I don't see how this
 assumption is justified (e.g., see git-check-ref-format(1) for the rules
 governing reference names).
 
 Yes it will.  The problem is that for Python 3 we need to decode the
 byte string into a unicode string, which means we need to know what
 encoding it is.
 
 I don't think we can just say git-for-each-ref will print refs in
 UTF-8 since AFAIK git doesn't care what encoding the refs are in - I
 suspect that's determined by the filesystem which in the end probably
 maps to whatever bytes the shell fed git when the ref was created.
 
 That's why I chose the current locale in this case.  I'm hoping someone
 here will correct me if we can do better, but I don't see any way of
 avoiding choosing some encoding here if we want to support Python 3
 (which I think we will, even if we don't right now).

I'm not just trying to be a nuisance here; I'm struggling myself to
understand how a program that cares about strings-vs-bytes (e.g., a
Python3 script) should coexist with a program that doesn't (e.g., git
[1]).  I think this will become a big issue if my Python version of the
commit email script ever gets integrated and then made compatible with
Python3.

You claim for Python 3 we need to decode the byte string into a unicode
string.  I understand that Python 3 strings are Unicode, but why/when
is it necessary to decode data into a Unicode string as opposed to
leaving it as a byte sequence?

In this particular case (from a cursory look over the code) it seems to
me that (1) decoding to Unicode will sometimes fail for data that git
considers valid and (2) there is no obvious reason that the data cannot
be processed as byte sequences.

Michael

[1] And it doesn't just seem that git doesn't care about Unicode
*yet*.  It seems more likely that git will adamantly refuse to deal
with Unicode.  For example, Linus is quite clearly in favor of treating
data as byte sequences in most situations:
https://plus.google.com/111049168280159033135/posts/f3fngVm174f

-- 
Michael Haggerty
mhag...@alum.mit.edu
http://softwareswirl.blogspot.com/
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] cvsimport: rewrite to use cvsps 3.x to fix major bugs

2013-01-13 Thread Michael Haggerty
On 01/13/2013 11:20 PM, Junio C Hamano wrote:
 After a quick survey of various distros, I think it is very unlikely
 that we will see distros move on to newer cvsps, leaving cvsimport
 broken situation. If anything, it is more like distros decide to
 ignore the new cvsps, until it is made to work with cvsimport [*1*].

A better predictor of the distros' decisions is probably which other
packages depend on cvsps.  As one data point: on Debian squeeze and on
Ubuntu precise, only two packages depend on cvsps (git-cvs and
bzr-cvsps-import) and one suggests it (chora2, a code repository
viewing component for horde framework).  So also by this standard they
are unlikely to feel a lot of pressure to update quickly to cvsps3.

 I think it is probably sensible to [...]
 
 Agreed?

Yes, I agree that what you propose is a good strategy.

Michael

-- 
Michael Haggerty
mhag...@alum.mit.edu
http://softwareswirl.blogspot.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


[PATCH 02/14] imap-send.c: remove struct msg_data

2013-01-13 Thread Michael Haggerty
Now that its flags member has been deleted, all that is left is a
strbuf.  So use a strbuf directly.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 imap-send.c | 18 +++---
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/imap-send.c b/imap-send.c
index 451d502..a8cb66a 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -68,10 +68,6 @@ struct store {
int recent; /* # of recent messages - don't trust this beyond the 
initial read */
 };
 
-struct msg_data {
-   struct strbuf data;
-};
-
 static const char imap_send_usage[] = git imap-send  mbox;
 
 #undef DRV_OK
@@ -1279,7 +1275,7 @@ static void lf_to_crlf(struct strbuf *msg)
  * Store msg to IMAP.  Also detach and free the data from msg-data,
  * leaving msg-data empty.
  */
-static int imap_store_msg(struct store *gctx, struct msg_data *msg)
+static int imap_store_msg(struct store *gctx, struct strbuf *msg)
 {
struct imap_store *ctx = (struct imap_store *)gctx;
struct imap *imap = ctx-imap;
@@ -1287,11 +1283,11 @@ static int imap_store_msg(struct store *gctx, struct 
msg_data *msg)
const char *prefix, *box;
int ret;
 
-   lf_to_crlf(msg-data);
+   lf_to_crlf(msg);
memset(cb, 0, sizeof(cb));
 
-   cb.dlen = msg-data.len;
-   cb.data = strbuf_detach(msg-data, NULL);
+   cb.dlen = msg-len;
+   cb.data = strbuf_detach(msg, NULL);
 
box = gctx-name;
prefix = !strcmp(box, INBOX) ?  : ctx-prefix;
@@ -1449,7 +1445,7 @@ static int git_imap_config(const char *key, const char 
*val, void *cb)
 int main(int argc, char **argv)
 {
struct strbuf all_msgs = STRBUF_INIT;
-   struct msg_data msg = {STRBUF_INIT};
+   struct strbuf msg = STRBUF_INIT;
struct store *ctx = NULL;
int ofs = 0;
int r;
@@ -1511,10 +1507,10 @@ int main(int argc, char **argv)
unsigned percent = n * 100 / total;
 
fprintf(stderr, %4u%% (%d/%d) done\r, percent, n, total);
-   if (!split_msg(all_msgs, msg.data, ofs))
+   if (!split_msg(all_msgs, msg, ofs))
break;
if (server.use_html)
-   wrap_in_html(msg.data);
+   wrap_in_html(msg);
r = imap_store_msg(ctx, msg);
if (r != DRV_OK)
break;
-- 
1.8.0.3

--
To unsubscribe from this list: send the line 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 04/14] imap-send.c: remove struct store_conf

2013-01-13 Thread Michael Haggerty
It was never used.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 imap-send.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/imap-send.c b/imap-send.c
index d675e70..3177361 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -33,15 +33,6 @@ typedef void *SSL;
 #include openssl/hmac.h
 #endif
 
-struct store_conf {
-   char *name;
-   const char *path; /* should this be here? its interpretation is 
driver-specific */
-   char *map_inbox;
-   char *trash;
-   unsigned max_size; /* off_t is overkill */
-   unsigned trash_remote_new:1, trash_only_new:1;
-};
-
 /* For message-status */
 #define M_RECENT   (10) /* unsyncable flag; maildir_* depend on this 
being 10 */
 #define M_DEAD (11) /* expunged */
@@ -55,8 +46,6 @@ struct message {
 };
 
 struct store {
-   struct store_conf *conf; /* foreign */
-
/* currently open mailbox */
const char *name; /* foreign! maybe preset? */
char *path; /* own */
-- 
1.8.0.3

--
To unsubscribe from this list: send the line 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 05/14] imap-send.c: remove struct message

2013-01-13 Thread Michael Haggerty
It was never used.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 imap-send.c | 26 --
 1 file changed, 26 deletions(-)

diff --git a/imap-send.c b/imap-send.c
index 3177361..a47008b 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -33,23 +33,10 @@ typedef void *SSL;
 #include openssl/hmac.h
 #endif
 
-/* For message-status */
-#define M_RECENT   (10) /* unsyncable flag; maildir_* depend on this 
being 10 */
-#define M_DEAD (11) /* expunged */
-#define M_FLAGS(12) /* flags fetched */
-
-struct message {
-   struct message *next;
-   size_t size; /* zero implies not fetched */
-   int uid;
-   unsigned char flags, status;
-};
-
 struct store {
/* currently open mailbox */
const char *name; /* foreign! maybe preset? */
char *path; /* own */
-   struct message *msgs; /* own */
int uidvalidity;
unsigned char opts; /* maybe preset? */
/* note that the following do _not_ reflect stats from msgs, but 
mailbox totals */
@@ -74,8 +61,6 @@ static void imap_warn(const char *, ...);
 
 static char *next_arg(char **);
 
-static void free_generic_messages(struct message *);
-
 __attribute__((format (printf, 3, 4)))
 static int nfsnprintf(char *buf, int blen, const char *fmt, ...);
 
@@ -447,16 +432,6 @@ static char *next_arg(char **s)
return ret;
 }
 
-static void free_generic_messages(struct message *msgs)
-{
-   struct message *tmsg;
-
-   for (; msgs; msgs = tmsg) {
-   tmsg = msgs-next;
-   free(msgs);
-   }
-}
-
 static int nfsnprintf(char *buf, int blen, const char *fmt, ...)
 {
int ret;
@@ -914,7 +889,6 @@ static void imap_close_server(struct imap_store *ictx)
 static void imap_close_store(struct store *ctx)
 {
imap_close_server((struct imap_store *)ctx);
-   free_generic_messages(ctx-msgs);
free(ctx);
 }
 
-- 
1.8.0.3

--
To unsubscribe from this list: send the line 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 06/14] imap-send.c: remove some unused fields from struct store

2013-01-13 Thread Michael Haggerty

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 imap-send.c | 15 +++
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/imap-send.c b/imap-send.c
index a47008b..fe2bfab 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -36,12 +36,7 @@ typedef void *SSL;
 struct store {
/* currently open mailbox */
const char *name; /* foreign! maybe preset? */
-   char *path; /* own */
int uidvalidity;
-   unsigned char opts; /* maybe preset? */
-   /* note that the following do _not_ reflect stats from msgs, but 
mailbox totals */
-   int count; /* # of messages */
-   int recent; /* # of recent messages - don't trust this beyond the 
initial read */
 };
 
 static const char imap_send_usage[] = git imap-send  mbox;
@@ -772,13 +767,10 @@ static int get_cmd_result(struct imap_store *ctx, struct 
imap_cmd *tcmd)
   !strcmp(NO, arg) || !strcmp(BYE, arg)) {
if ((resp = parse_response_code(ctx, NULL, 
cmd)) != RESP_OK)
return resp;
-   } else if (!strcmp(CAPABILITY, arg))
+   } else if (!strcmp(CAPABILITY, arg)) {
parse_capability(imap, cmd);
-   else if ((arg1 = next_arg(cmd))) {
-   if (!strcmp(EXISTS, arg1))
-   ctx-gen.count = atoi(arg);
-   else if (!strcmp(RECENT, arg1))
-   ctx-gen.recent = atoi(arg);
+   } else if ((arg1 = next_arg(cmd))) {
+   /* unused */
} else {
fprintf(stderr, IMAP error: unable to parse 
untagged response\n);
return RESP_BAD;
@@ -1254,7 +1246,6 @@ static int imap_store_msg(struct store *gctx, struct 
strbuf *msg)
imap-caps = imap-rcaps;
if (ret != DRV_OK)
return ret;
-   gctx-count++;
 
return DRV_OK;
 }
-- 
1.8.0.3

--
To unsubscribe from this list: send the line 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 08/14] imap-send.c: remove struct imap argument to parse_imap_list_l()

2013-01-13 Thread Michael Haggerty
It was always set to NULL.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 imap-send.c | 39 +++
 1 file changed, 3 insertions(+), 36 deletions(-)

diff --git a/imap-send.c b/imap-send.c
index 452e73e..5238c74 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -578,11 +578,10 @@ static void free_list(struct imap_list *list)
}
 }
 
-static int parse_imap_list_l(struct imap *imap, char **sp, struct imap_list 
**curp, int level)
+static int parse_imap_list_l(char **sp, struct imap_list **curp, int level)
 {
struct imap_list *cur;
char *s = *sp, *p;
-   int n, bytes;
 
for (;;) {
while (isspace((unsigned char)*s))
@@ -598,39 +597,7 @@ static int parse_imap_list_l(struct imap *imap, char **sp, 
struct imap_list **cu
/* sublist */
s++;
cur-val = LIST;
-   if (parse_imap_list_l(imap, s, cur-child, level + 1))
-   goto bail;
-   } else if (imap  *s == '{') {
-   /* literal */
-   bytes = cur-len = strtol(s + 1, s, 10);
-   if (*s != '}')
-   goto bail;
-
-   s = cur-val = xmalloc(cur-len);
-
-   /* dump whats left over in the input buffer */
-   n = imap-buf.bytes - imap-buf.offset;
-
-   if (n  bytes)
-   /* the entire message fit in the buffer */
-   n = bytes;
-
-   memcpy(s, imap-buf.buf + imap-buf.offset, n);
-   s += n;
-   bytes -= n;
-
-   /* mark that we used part of the buffer */
-   imap-buf.offset += n;
-
-   /* now read the rest of the message */
-   while (bytes  0) {
-   if ((n = socket_read(imap-buf.sock, s, 
bytes)) = 0)
-   goto bail;
-   s += n;
-   bytes -= n;
-   }
-
-   if (buffer_gets(imap-buf, s))
+   if (parse_imap_list_l(s, cur-child, level + 1))
goto bail;
} else if (*s == '') {
/* quoted string */
@@ -673,7 +640,7 @@ static struct imap_list *parse_list(char **sp)
 {
struct imap_list *head;
 
-   if (!parse_imap_list_l(NULL, sp, head, 0))
+   if (!parse_imap_list_l(sp, head, 0))
return head;
free_list(head);
return NULL;
-- 
1.8.0.3

--
To unsubscribe from this list: send the line 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 10/14] imap-send.c: remove unused field imap_store::trashnc

2013-01-13 Thread Michael Haggerty

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 imap-send.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/imap-send.c b/imap-send.c
index 9616e80..70abe9b 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -127,7 +127,6 @@ struct imap_store {
int uidvalidity;
struct imap *imap;
const char *prefix;
-   unsigned /*currentnc:1,*/ trashnc:1;
 };
 
 struct imap_cmd_cb {
@@ -1079,7 +1078,6 @@ static struct store *imap_open_store(struct 
imap_server_conf *srvc)
} /* !preauth */
 
ctx-prefix = ;
-   ctx-trashnc = 1;
return (struct store *)ctx;
 
 bail:
-- 
1.8.0.3

--
To unsubscribe from this list: send the line 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 13/14] imap-send.c: remove unused field imap_store::uidvalidity

2013-01-13 Thread Michael Haggerty
I suspect that the existence of both imap_store::uidvalidity and
store::uidvalidity was an accident.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 imap-send.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/imap-send.c b/imap-send.c
index 31fdbf3..4d24faf 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -124,7 +124,6 @@ struct imap {
 
 struct imap_store {
struct store gen;
-   int uidvalidity;
struct imap *imap;
const char *prefix;
 };
-- 
1.8.0.3

--
To unsubscribe from this list: send the line 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 14/14] imap-send.c: fold struct store into struct imap_store

2013-01-13 Thread Michael Haggerty

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 imap-send.c | 18 +++---
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/imap-send.c b/imap-send.c
index 4d24faf..1b665bb 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -33,12 +33,6 @@ typedef void *SSL;
 #include openssl/hmac.h
 #endif
 
-struct store {
-   /* currently open mailbox */
-   const char *name; /* foreign! maybe preset? */
-   int uidvalidity;
-};
-
 static const char imap_send_usage[] = git imap-send  mbox;
 
 #undef DRV_OK
@@ -123,7 +117,9 @@ struct imap {
 };
 
 struct imap_store {
-   struct store gen;
+   /* currently open mailbox */
+   const char *name; /* foreign! maybe preset? */
+   int uidvalidity;
struct imap *imap;
const char *prefix;
 };
@@ -618,7 +614,7 @@ static int parse_response_code(struct imap_store *ctx, 
struct imap_cmd_cb *cb,
*p++ = 0;
arg = next_arg(s);
if (!strcmp(UIDVALIDITY, arg)) {
-   if (!(arg = next_arg(s)) || !(ctx-gen.uidvalidity = 
atoi(arg))) {
+   if (!(arg = next_arg(s)) || !(ctx-uidvalidity = atoi(arg))) {
fprintf(stderr, IMAP error: malformed UIDVALIDITY 
status\n);
return RESP_BAD;
}
@@ -636,7 +632,7 @@ static int parse_response_code(struct imap_store *ctx, 
struct imap_cmd_cb *cb,
for (; isspace((unsigned char)*p); p++);
fprintf(stderr, *** IMAP ALERT *** %s\n, p);
} else if (cb  cb-ctx  !strcmp(APPENDUID, arg)) {
-   if (!(arg = next_arg(s)) || !(ctx-gen.uidvalidity = 
atoi(arg)) ||
+   if (!(arg = next_arg(s)) || !(ctx-uidvalidity = atoi(arg)) ||
!(arg = next_arg(s)) || !(*(int *)cb-ctx = atoi(arg))) {
fprintf(stderr, IMAP error: malformed APPENDUID 
status\n);
return RESP_BAD;
@@ -1124,7 +1120,7 @@ static int imap_store_msg(struct imap_store *ctx, struct 
strbuf *msg)
cb.dlen = msg-len;
cb.data = strbuf_detach(msg, NULL);
 
-   box = ctx-gen.name;
+   box = ctx-name;
prefix = !strcmp(box, INBOX) ?  : ctx-prefix;
cb.create = 0;
ret = imap_exec_m(ctx, cb, APPEND \%s%s\, prefix, box);
@@ -1336,7 +1332,7 @@ int main(int argc, char **argv)
}
 
fprintf(stderr, sending %d message%s\n, total, (total != 1) ? s : 
);
-   ctx-gen.name = imap_folder;
+   ctx-name = imap_folder;
while (1) {
unsigned percent = n * 100 / total;
 
-- 
1.8.0.3

--
To unsubscribe from this list: send the line 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 01/14] imap-send.c: remove msg_data::flags, which was always zero

2013-01-13 Thread Michael Haggerty
This removes the need for function imap_make_flags(), so delete it,
too.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 imap-send.c | 40 +++-
 1 file changed, 3 insertions(+), 37 deletions(-)

diff --git a/imap-send.c b/imap-send.c
index e521e2f..451d502 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -70,7 +70,6 @@ struct store {
 
 struct msg_data {
struct strbuf data;
-   unsigned char flags;
 };
 
 static const char imap_send_usage[] = git imap-send  mbox;
@@ -225,14 +224,6 @@ static const char *cap_list[] = {
 static int get_cmd_result(struct imap_store *ctx, struct imap_cmd *tcmd);
 
 
-static const char *Flags[] = {
-   Draft,
-   Flagged,
-   Answered,
-   Seen,
-   Deleted,
-};
-
 #ifndef NO_OPENSSL
 static void ssl_socket_perror(const char *func)
 {
@@ -1246,23 +1237,6 @@ bail:
return NULL;
 }
 
-static int imap_make_flags(int flags, char *buf)
-{
-   const char *s;
-   unsigned i, d;
-
-   for (i = d = 0; i  ARRAY_SIZE(Flags); i++)
-   if (flags  (1  i)) {
-   buf[d++] = ' ';
-   buf[d++] = '\\';
-   for (s = Flags[i]; *s; s++)
-   buf[d++] = *s;
-   }
-   buf[0] = '(';
-   buf[d++] = ')';
-   return d;
-}
-
 static void lf_to_crlf(struct strbuf *msg)
 {
size_t new_len;
@@ -1311,8 +1285,7 @@ static int imap_store_msg(struct store *gctx, struct 
msg_data *msg)
struct imap *imap = ctx-imap;
struct imap_cmd_cb cb;
const char *prefix, *box;
-   int ret, d;
-   char flagstr[128];
+   int ret;
 
lf_to_crlf(msg-data);
memset(cb, 0, sizeof(cb));
@@ -1320,17 +1293,10 @@ static int imap_store_msg(struct store *gctx, struct 
msg_data *msg)
cb.dlen = msg-data.len;
cb.data = strbuf_detach(msg-data, NULL);
 
-   d = 0;
-   if (msg-flags) {
-   d = imap_make_flags(msg-flags, flagstr);
-   flagstr[d++] = ' ';
-   }
-   flagstr[d] = 0;
-
box = gctx-name;
prefix = !strcmp(box, INBOX) ?  : ctx-prefix;
cb.create = 0;
-   ret = imap_exec_m(ctx, cb, APPEND \%s%s\ %s, prefix, box, flagstr);
+   ret = imap_exec_m(ctx, cb, APPEND \%s%s\, prefix, box);
imap-caps = imap-rcaps;
if (ret != DRV_OK)
return ret;
@@ -1483,7 +1449,7 @@ static int git_imap_config(const char *key, const char 
*val, void *cb)
 int main(int argc, char **argv)
 {
struct strbuf all_msgs = STRBUF_INIT;
-   struct msg_data msg = {STRBUF_INIT, 0};
+   struct msg_data msg = {STRBUF_INIT};
struct store *ctx = NULL;
int ofs = 0;
int r;
-- 
1.8.0.3

--
To unsubscribe from this list: send the line 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 03/14] iamp-send.c: remove unused struct imap_store_conf

2013-01-13 Thread Michael Haggerty

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 imap-send.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/imap-send.c b/imap-send.c
index a8cb66a..d675e70 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -130,11 +130,6 @@ static struct imap_server_conf server = {
NULL,   /* auth_method */
 };
 
-struct imap_store_conf {
-   struct store_conf gen;
-   struct imap_server_conf *server;
-};
-
 #define NIL(void *)0x1
 #define LIST   (void *)0x2
 
-- 
1.8.0.3

--
To unsubscribe from this list: send the line 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 07/14] imap-send.c: inline imap_parse_list() in imap_list()

2013-01-13 Thread Michael Haggerty
The function is only called from here.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 imap-send.c | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/imap-send.c b/imap-send.c
index fe2bfab..452e73e 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -669,21 +669,16 @@ bail:
return -1;
 }
 
-static struct imap_list *parse_imap_list(struct imap *imap, char **sp)
+static struct imap_list *parse_list(char **sp)
 {
struct imap_list *head;
 
-   if (!parse_imap_list_l(imap, sp, head, 0))
+   if (!parse_imap_list_l(NULL, sp, head, 0))
return head;
free_list(head);
return NULL;
 }
 
-static struct imap_list *parse_list(char **sp)
-{
-   return parse_imap_list(NULL, sp);
-}
-
 static void parse_capability(struct imap *imap, char *cmd)
 {
char *arg;
-- 
1.8.0.3

--
To unsubscribe from this list: send the line 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 12/14] imap-send.c: use struct imap_store instead of struct store

2013-01-13 Thread Michael Haggerty
In fact, all struct store instances are upcasts of struct imap_store
anyway, so stop making the distinction.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 imap-send.c | 19 +--
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/imap-send.c b/imap-send.c
index 3167dcc..31fdbf3 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -781,9 +781,9 @@ static void imap_close_server(struct imap_store *ictx)
free(imap);
 }
 
-static void imap_close_store(struct store *ctx)
+static void imap_close_store(struct imap_store *ctx)
 {
-   imap_close_server((struct imap_store *)ctx);
+   imap_close_server(ctx);
free(ctx);
 }
 
@@ -868,7 +868,7 @@ static int auth_cram_md5(struct imap_store *ctx, struct 
imap_cmd *cmd, const cha
return 0;
 }
 
-static struct store *imap_open_store(struct imap_server_conf *srvc)
+static struct imap_store *imap_open_store(struct imap_server_conf *srvc)
 {
struct imap_store *ctx;
struct imap *imap;
@@ -1078,10 +1078,10 @@ static struct store *imap_open_store(struct 
imap_server_conf *srvc)
} /* !preauth */
 
ctx-prefix = ;
-   return (struct store *)ctx;
+   return ctx;
 
 bail:
-   imap_close_store(ctx-gen);
+   imap_close_store(ctx);
return NULL;
 }
 
@@ -1112,9 +1112,8 @@ static void lf_to_crlf(struct strbuf *msg)
  * Store msg to IMAP.  Also detach and free the data from msg-data,
  * leaving msg-data empty.
  */
-static int imap_store_msg(struct store *gctx, struct strbuf *msg)
+static int imap_store_msg(struct imap_store *ctx, struct strbuf *msg)
 {
-   struct imap_store *ctx = (struct imap_store *)gctx;
struct imap *imap = ctx-imap;
struct imap_cmd_cb cb;
const char *prefix, *box;
@@ -1126,7 +1125,7 @@ static int imap_store_msg(struct store *gctx, struct 
strbuf *msg)
cb.dlen = msg-len;
cb.data = strbuf_detach(msg, NULL);
 
-   box = gctx-name;
+   box = ctx-gen.name;
prefix = !strcmp(box, INBOX) ?  : ctx-prefix;
cb.create = 0;
ret = imap_exec_m(ctx, cb, APPEND \%s%s\, prefix, box);
@@ -1282,7 +1281,7 @@ int main(int argc, char **argv)
 {
struct strbuf all_msgs = STRBUF_INIT;
struct strbuf msg = STRBUF_INIT;
-   struct store *ctx = NULL;
+   struct imap_store *ctx = NULL;
int ofs = 0;
int r;
int total, n = 0;
@@ -1338,7 +1337,7 @@ int main(int argc, char **argv)
}
 
fprintf(stderr, sending %d message%s\n, total, (total != 1) ? s : 
);
-   ctx-name = imap_folder;
+   ctx-gen.name = imap_folder;
while (1) {
unsigned percent = n * 100 / total;
 
-- 
1.8.0.3

--
To unsubscribe from this list: send the line 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 09/14] imap-send.c: remove namespace fields from struct imap

2013-01-13 Thread Michael Haggerty
They are unused, and their removal means that a bunch of list-related
infrastructure can be disposed of.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 imap-send.c | 74 +++--
 1 file changed, 8 insertions(+), 66 deletions(-)

diff --git a/imap-send.c b/imap-send.c
index 5238c74..9616e80 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -99,15 +99,6 @@ static struct imap_server_conf server = {
NULL,   /* auth_method */
 };
 
-#define NIL(void *)0x1
-#define LIST   (void *)0x2
-
-struct imap_list {
-   struct imap_list *next, *child;
-   char *val;
-   int len;
-};
-
 struct imap_socket {
int fd[2];
SSL *ssl;
@@ -124,7 +115,6 @@ struct imap_cmd;
 
 struct imap {
int uidnext; /* from SELECT responses */
-   struct imap_list *ns_personal, *ns_other, *ns_shared; /* NAMESPACE info 
*/
unsigned caps, rcaps; /* CAPABILITY results */
/* command queue */
int nexttag, num_in_progress, literal_pending;
@@ -554,34 +544,9 @@ static int imap_exec_m(struct imap_store *ctx, struct 
imap_cmd_cb *cb,
}
 }
 
-static int is_atom(struct imap_list *list)
-{
-   return list  list-val  list-val != NIL  list-val != LIST;
-}
-
-static int is_list(struct imap_list *list)
-{
-   return list  list-val == LIST;
-}
-
-static void free_list(struct imap_list *list)
-{
-   struct imap_list *tmp;
-
-   for (; list; list = tmp) {
-   tmp = list-next;
-   if (is_list(list))
-   free_list(list-child);
-   else if (is_atom(list))
-   free(list-val);
-   free(list);
-   }
-}
-
-static int parse_imap_list_l(char **sp, struct imap_list **curp, int level)
+static int skip_imap_list_l(char **sp, int level)
 {
-   struct imap_list *cur;
-   char *s = *sp, *p;
+   char *s = *sp;
 
for (;;) {
while (isspace((unsigned char)*s))
@@ -590,36 +555,23 @@ static int parse_imap_list_l(char **sp, struct imap_list 
**curp, int level)
s++;
break;
}
-   *curp = cur = xmalloc(sizeof(*cur));
-   curp = cur-next;
-   cur-val = NULL; /* for clean bail */
if (*s == '(') {
/* sublist */
s++;
-   cur-val = LIST;
-   if (parse_imap_list_l(s, cur-child, level + 1))
+   if (skip_imap_list_l(s, level + 1))
goto bail;
} else if (*s == '') {
/* quoted string */
s++;
-   p = s;
for (; *s != ''; s++)
if (!*s)
goto bail;
-   cur-len = s - p;
s++;
-   cur-val = xmemdupz(p, cur-len);
} else {
/* atom */
-   p = s;
for (; *s  !isspace((unsigned char)*s); s++)
if (level  *s == ')')
break;
-   cur-len = s - p;
-   if (cur-len == 3  !memcmp(NIL, p, 3))
-   cur-val = NIL;
-   else
-   cur-val = xmemdupz(p, cur-len);
}
 
if (!level)
@@ -628,22 +580,15 @@ static int parse_imap_list_l(char **sp, struct imap_list 
**curp, int level)
goto bail;
}
*sp = s;
-   *curp = NULL;
return 0;
 
 bail:
-   *curp = NULL;
return -1;
 }
 
-static struct imap_list *parse_list(char **sp)
+static void skip_list(char **sp)
 {
-   struct imap_list *head;
-
-   if (!parse_imap_list_l(sp, head, 0))
-   return head;
-   free_list(head);
-   return NULL;
+   skip_imap_list_l(sp, 0);
 }
 
 static void parse_capability(struct imap *imap, char *cmd)
@@ -722,9 +667,9 @@ static int get_cmd_result(struct imap_store *ctx, struct 
imap_cmd *tcmd)
}
 
if (!strcmp(NAMESPACE, arg)) {
-   imap-ns_personal = parse_list(cmd);
-   imap-ns_other = parse_list(cmd);
-   imap-ns_shared = parse_list(cmd);
+   skip_list(cmd);
+   skip_list(cmd);
+   skip_list(cmd);
} else if (!strcmp(OK, arg) || !strcmp(BAD, arg) ||
   !strcmp(NO, arg) || !strcmp(BYE, arg)) {
if ((resp = parse_response_code(ctx, NULL, 
cmd)) != RESP_OK)
@@ -834,9 +779,6 @@ static void 

[PATCH 11/14] imap-send.c: simplify logic in lf_to_crlf()

2013-01-13 Thread Michael Haggerty

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
 imap-send.c | 31 ---
 1 file changed, 8 insertions(+), 23 deletions(-)

diff --git a/imap-send.c b/imap-send.c
index 70abe9b..3167dcc 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -1089,36 +1089,21 @@ static void lf_to_crlf(struct strbuf *msg)
 {
size_t new_len;
char *new;
-   int i, j, lfnum = 0;
+   int i, j = 0, lfnum = 0;
+   char lastc;
 
-   if (msg-buf[0] == '\n')
-   lfnum++;
-   for (i = 1; i  msg-len; i++) {
-   if (msg-buf[i - 1] != '\r'  msg-buf[i] == '\n')
+   for (i = 0, lastc = '\0'; i  msg-len; i++) {
+   if (msg-buf[i] == '\n'  lastc != '\r')
lfnum++;
+   lastc = msg-buf[i];
}
 
new_len = msg-len + lfnum;
new = xmalloc(new_len + 1);
-   if (msg-buf[0] == '\n') {
-   new[0] = '\r';
-   new[1] = '\n';
-   i = 1;
-   j = 2;
-   } else {
-   new[0] = msg-buf[0];
-   i = 1;
-   j = 1;
-   }
-   for ( ; i  msg-len; i++) {
-   if (msg-buf[i] != '\n') {
-   new[j++] = msg-buf[i];
-   continue;
-   }
-   if (msg-buf[i - 1] != '\r')
+   for (i = 0, lastc = '\0'; i  msg-len; i++) {
+   if (msg-buf[i] == '\n'  lastc != '\r')
new[j++] = '\r';
-   /* otherwise it already had CR before */
-   new[j++] = '\n';
+   lastc = new[j++] = msg-buf[i];
}
strbuf_attach(msg, new, new_len, new_len + 1);
 }
-- 
1.8.0.3

--
To unsubscribe from this list: send the line 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 01/14] imap-send.c: remove msg_data::flags, which was always zero

2013-01-13 Thread Jonathan Nieder
Hi,

Michael Haggerty wrote:

 This removes the need for function imap_make_flags(), so delete it,
 too.
[...]
 --- a/imap-send.c
 +++ b/imap-send.c
[...]
   box = gctx-name;
   prefix = !strcmp(box, INBOX) ?  : ctx-prefix;
   cb.create = 0;
 - ret = imap_exec_m(ctx, cb, APPEND \%s%s\ %s, prefix, box, flagstr);
 + ret = imap_exec_m(ctx, cb, APPEND \%s%s\, prefix, box);

Before this change, the command is

APPEND SP mailbox SP { msglen } CRLF

.  After this change, it leaves out the space before the brace.  If I
understand RFC3501 correctly, the space is required.  Intentional?

With the below squashed in,
Reviewed-by: Jonathan Nieder jrnie...@gmail.com

diff --git i/imap-send.c w/imap-send.c
index 451d5027..f1c8f5a5 100644
--- i/imap-send.c
+++ w/imap-send.c
@@ -1296,7 +1296,7 @@ static int imap_store_msg(struct store *gctx, struct 
msg_data *msg)
box = gctx-name;
prefix = !strcmp(box, INBOX) ?  : ctx-prefix;
cb.create = 0;
-   ret = imap_exec_m(ctx, cb, APPEND \%s%s\, prefix, box);
+   ret = imap_exec_m(ctx, cb, APPEND \%s%s\ , prefix, box);
imap-caps = imap-rcaps;
if (ret != DRV_OK)
return ret;
--
To unsubscribe from this list: send the line 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 00/14] Remove unused code from imap-send.c

2013-01-13 Thread Jeff King
On Mon, Jan 14, 2013 at 06:32:32AM +0100, Michael Haggerty wrote:

 As discussed before [1], imap-send.c was copied from isync, including
 a lot of code that is not used within the git project.  This patch
 series rips a bunch of it out.

Thanks, this looks like a good direction.

I did not notice any problems reading through the patches, but my brain
is frazzled from a day of flying. I missed the problem Jonathan noticed.
:)

Some of the things you are removing are for advanced IMAP features that
imap-send does not need. In theory, somebody might extend it to use them
in the future. But since it has not seen any active feature development
in years, and since anybody could resurrect the code by reverting your
commits, I don't think it is a big risk.

I suspect you could go even further in ripping things out (e.g., I do
not think a server will generate an untagged namespace response at all
if we do not ask for it by issuing a namespace command). But you've
certainly grabbed the low-hanging fruit that can mostly be verified by
the compiler, and I don't know if it's worth the effort to go much
further, as it would require a lot of manual verification (and
understanding of IMAP, which will rot your brain).

-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


Announcing git-reparent

2013-01-13 Thread Mark Lodato
I threw together a small utility called git-reparent, available on GitHub at:

https://github.com/MarkLodato/git-reparent

I welcome any comments or suggestions.  To make discussion easier,
I've copied the README and code below.

--- 8 ---

NAME


git-reparent - Recommit HEAD with a new set of parents.


SYNOPSIS


``git reparent [OPTIONS] ((-p parent)... | --no-parent)``


DESCRIPTION
===

Create a new commit object that has the same tree and commit message as HEAD
but with a different set of parents.  If ``--no-reset`` is given, the full
object id of this commit is printed and the program exits; otherwise, ``git
reset`` is used to update HEAD and the current branch to this new commit.

This command can be used to manually shape the history of a repository.
Whereas ``git rebase`` moves around *diffs*, ``git reparent`` moves around
*snapshots*.  See EXAMPLES for a reason why you might want to use this
command.


OPTIONS
===

-h, --helpshow the help
-e, --editedit the commit message in an editor first
-m, --message message   use the given message instead of that of HEAD
-p, --parent commit new parent to use; may be given multiple times
--no-parent   create a parentless commit
-q, --quiet   be quiet; only report errors
--no-resetprint the new object id instead of updating HEAD


INSTALLATION


Make executable and place somewhere in your $PATH.


EXAMPLES


Reparenting the tip of a branch
---

Suppose we create some commit *B* and then accidentally pass the ``--amend``
flag when creating new commit *C*, resulting in the following history::

B
   /
...---A---C (HEAD)

What we really wanted was one linear history, ``...---A--B--C``.  If we
were to use ``git rebase`` or ``git cherry-pick`` to reconstruct the history,
this would try to apply the *diff* of *A..C* onto *B*, which might fail.
Instead, what we really want to do is use the exact message and tree from *C*
but with parent *B* instead of *A*.  To do this, we run ::

$ git reparent -p B

where the name *B* can be found by running ``git reflog`` and looking for the
first commit (amend).  The resulting history is now just what we wanted::

C
   /
...---A---B---C' (HEAD)


Reparenting an inner commit
---

We can also update the parents of a commit other than the most recent.
Suppose that we want to perform a rebase-like operation, moving *master* onto
*origin/master*, but we want to completely ignore any changes made in the
remote branch.  That is, our history currently looks like this::

B---C (master, HEAD)
   /
...---A---D---E (origin/master)

and we want to make it look like this::

B---C   (origin/master)
   /   /
...---A---D---E---B'---C' (master, HEAD)

We can accomplish this by using ``git rebase --interactive`` along with ``git
reparent``::

$ git rebase -i A
# select the edit command for commit B
# git rebase will dump us out at commit B
$ git reparent -p origin/master
$ git rebase --continue

Now the history will look as desired, and the trees, commit messages, and
authors of *B'* and *C'* will be identical to those of *B* and *C*,
respectively.


SEE ALSO


git-filter-branch(1) combined with either git grafts or git-replace(1) can be
used to achieve the same effect

git-rebase(1) can be used to re-apply the *diffs* of the current branch to
another


AUTHOR
==

Mark Lodato loda...@gmail.com

--- 8 ---

#!/bin/sh
# Copyright (c) Mark Lodato, 2013

OPTIONS_SPEC=\
git reparent [OPTIONS] ((-p parent)... | --no-parent)

Recommit HEAD with a new set of parents.
--
h,help  show the help
e,edit  edit the commit message in an editor first
m,message=  use the given message instead of that of HEAD
p,parent=!  new parent to use; may be given multiple times
no-parent!  create a parentless commit
q,quiet be quiet; only report errors
reset*  default behavior
no-reset!   print the new object id instead of updating HEAD

SUBDIRECTORY_OK=Yes
. $(git --exec-path)/git-sh-setup || exit $?
require_clean_work_tree reparent Please commit or stash them first.

# Location of the temporary message.
msg_file=$GIT_DIR/reparent-msg

die_with_usage() {
echo error: $1 2
usage
}

edit=
message=
no_parent=
no_reset=
parent_flags=
quiet=
while [ $# -gt 0 ]; do
case $1 in
-p)
[ $# -eq 0 ]  die_with_usage -p requires an argument
shift
parent_flags=$parent_flags$(git rev-parse --sq-quote -p $1)
;;
--no-parent) no_parent=1 ;;
-e)  edit=1 ;;
--no-edit)   edit= ;;
-m)  message=$2; shift ;;
--no-message)message= ;;

Re: [PATCH 06/14] imap-send.c: remove some unused fields from struct store

2013-01-13 Thread Jonathan Nieder
Michael Haggerty wrote:

 --- a/imap-send.c
 +++ b/imap-send.c
[...]
 @@ -772,13 +767,10 @@ static int get_cmd_result(struct imap_store *ctx, 
 struct imap_cmd *tcmd)
  !strcmp(NO, arg) || !strcmp(BYE, arg)) {
   if ((resp = parse_response_code(ctx, NULL, 
 cmd)) != RESP_OK)
   return resp;
 - } else if (!strcmp(CAPABILITY, arg))
 + } else if (!strcmp(CAPABILITY, arg)) {
   parse_capability(imap, cmd);
 - else if ((arg1 = next_arg(cmd))) {
 - if (!strcmp(EXISTS, arg1))
 - ctx-gen.count = atoi(arg);
 - else if (!strcmp(RECENT, arg1))
 - ctx-gen.recent = atoi(arg);
 + } else if ((arg1 = next_arg(cmd))) {
 + /* unused */

Neat.  Let me try to understand what was going on here:

When opening a mailbox with the SELECT command, an IMAP server
responds with tagged data indicating how many messages exist and how
many are marked Recent.  But git imap-send never reads mailboxes and
in particular never uses the SELECT command, so there is no need for
us to parse or record such responses.

Out of paranoia we are keeping the parsing for now, but the parsed
response is unused, hence the comment above.

If I've understood correctly so far (a big assumption), I still am not
sure what it would mean if we hit this ((arg1 = next_arg(cmd))) case.
Does it mean:

 A. The server has gone haywire and given a tagged response where
one is not allowed, but let's tolerate it because we always have
done so?  Or

 B. This is a perfectly normal response to some of the commands we
send, and we have always been deliberately ignoring it because it
is not important for what imap-send does?

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


  1   2   >