Re: [PATCH] tests: turn on test-lint-shell-syntax by default
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
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()
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
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
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
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
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
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
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
:(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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
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
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
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
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
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
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
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
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)
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
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
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
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
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/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
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
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
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
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
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
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
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
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
'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
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
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
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
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
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
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()
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
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
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
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
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
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()
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
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
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()
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
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
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
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
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