Re: URL rewrite in local config unable to override global config rule
Thanks a lot Peff. This cleared a lot of things. Would it be okay if I cite some parts of this conversation on my personal blog? On Fri, Jun 17, 2016 at 8:31 PM, Jeff Kingwrote: > On Fri, Jun 17, 2016 at 08:05:47PM +0530, Saksham Saxena wrote: > >> > ..even if I have an existing "url.git://.insteadOf=https://;. But I >> > could believe that having other config confuses things. The >> > url-rewriting is not "last one wins", but rather that we try all of >> > >> > > them, and the longest match wins. >> >> Longest? Could you elaborate please? > > The one that matches the longest number of characters. So > "https://example.com; is a preferred match over "https://;. > > I don't think that's what's going on here, though. > >> Here you go >> (https://gist.github.com/sakshamsaxena/a1cee9c39ddc127ae659e92d02d58f0b). >> The commands are run in that sequence. > > OK, so you have: > > url.git://.insteadof=https:// > > in your initial config, to convert https URLs to git. > > Later you add: > > url.https://.insteadof=git:// > > to do the opposite. > > The URL in your config uses http: > > remote.origin.url=https://github.com/sakshamsaxena/sails-hook-jbvcs.wiki.git > > And when you push, this gets converted to "git://". > > I think this is the expected behavior, due to the first insteadOf, which > converts https to git. Both rules are "active", in the sense that the > later one does not replace the former; together they make a list of > rules to try applying. > > Git doesn't recursively apply insteadOf transformations. So the "convert > https to git" rule triggers, and we stop. The "convert git to https" one > doesn't trigger initially (because we are already https). And if we were > to apply rules recursively in this case, it would loop infinitely. > > So I this is all operating as intended. And what you really want is a > way to say "erase any earlier rewrite rules; I do not want them applied > in this repository". There's currently not any way to do that. > > For other "multi-valued configs" like this one (i.e., ones that form a > list rather than overriding earlier values), we have started using the > convention that assigning the empty value resets the list. But this > particular config key has not learned that trick yet, so it would > require a patch to git. > >> > You should be able to clone, fetch, or push wiki repositories using any >> > of the normal protocols. So: >> > >> > g...@github.com:username/repo.wiki.git >> > >> > should work. Likewise, git:// will work if the repository is public, but >> > >> > > you cannot push over it. >> >> True. Can't push over git:// and that's why I'm limited to https:// > > You can over ssh, though (which I thought you said earlier was your > preferred protocol). > > -Peff Thanks and Regards Saksham Saxena -- To unsubscribe from this list: send the line "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 (Jun 2016, #05; Thu, 16)
On 06/17/2016 05:20 AM, Junio C Hamano wrote: > [...] > * mh/ref-iterators (2016-06-03) 13 commits > (merged to 'next' on 2016-06-06 at c8e79dc) > + for_each_reflog(): reimplement using iterators > + dir_iterator: new API for iterating over a directory tree > + for_each_reflog(): don't abort for bad references > + do_for_each_ref(): reimplement using reference iteration > + refs: introduce an iterator interface > + ref_resolves_to_object(): new function > + entry_resolves_to_object(): rename function from ref_resolves_to_object() > + get_ref_cache(): only create an instance if there is a submodule > + remote rm: handle symbolic refs correctly > + delete_refs(): add a flags argument > + refs: use name "prefix" consistently > + do_for_each_ref(): move docstring to the header file > + refs: remove unnecessary "extern" keywords > (this branch is used by mh/ref-store; uses mh/split-under-lock; is tangled > with mh/update-ref-errors.) > > The API to iterate over all the refs (i.e. for_each_ref(), etc.) > has been revamped. > > Will merge to 'master'. It would be preferable (though not critical) to use the promised v3, which I just sent [1]. This includes some minor improvements, described here [2]. This is also available from my GitHub fork [3] as branch "ref-iterators". > * mh/split-under-lock (2016-05-13) 33 commits > (merged to 'next' on 2016-06-03 at 2e71330) > + lock_ref_sha1_basic(): only handle REF_NODEREF mode > + commit_ref_update(): remove the flags parameter > + lock_ref_for_update(): don't resolve symrefs > + lock_ref_for_update(): don't re-read non-symbolic references > + refs: resolve symbolic refs first > + ref_transaction_update(): check refname_is_safe() at a minimum > + unlock_ref(): move definition higher in the file > + lock_ref_for_update(): new function > + add_update(): initialize the whole ref_update > + verify_refname_available(): adjust constness in declaration > + refs: don't dereference on rename > + refs: allow log-only updates > + delete_branches(): use resolve_refdup() > + ref_transaction_commit(): correctly report close_ref() failure > + ref_transaction_create(): disallow recursive pruning > + refs: make error messages more consistent > + lock_ref_sha1_basic(): remove unneeded local variable > + read_raw_ref(): move docstring to header file > + read_raw_ref(): improve docstring > + read_raw_ref(): rename symref argument to referent > + read_raw_ref(): clear *type at start of function > + read_raw_ref(): rename flags argument to type > + ref_transaction_commit(): remove local variable n > + rename_ref(): remove unneeded local variable > + commit_ref_update(): write error message to *err, not stderr > + refname_is_safe(): insist that the refname already be normalized > + refname_is_safe(): don't allow the empty string > + refname_is_safe(): use skip_prefix() > + remove_dir_recursively(): add docstring > + safe_create_leading_directories(): improve docstring > + read_raw_ref(): don't get confused by an empty directory > + commit_ref(): if there is an empty dir in the way, delete it > + t1404: demonstrate a bug resolving references > (this branch is used by mh/ref-iterators, mh/ref-store and > mh/update-ref-errors.) > > Further preparatory work on the refs API before the pluggable > backend series can land. > > Will merge to 'master'. Please make sure to pick up the important bugfix discussed here [4], which is integrated into branch "split-under-lock" on my GitHub fork [3]. Michael [1] http://thread.gmane.org/gmane.comp.version-control.git/297625 [2] http://thread.gmane.org/gmane.comp.version-control.git/296322/focus=296883 [3] https://github.com/mhagger/git [4] http://article.gmane.org/gmane.comp.version-control.git/297174 -- To unsubscribe from this list: send the line "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 06/13] get_ref_cache(): only create an instance if there is a submodule
If there is not a nonbare repository where a submodule is supposedly located, then don't instantiate a ref_cache for it. The analogous check can be removed from resolve_gitlink_ref(). Signed-off-by: Michael Haggerty--- refs/files-backend.c | 33 ++--- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/refs/files-backend.c b/refs/files-backend.c index e15f7ae..b563a7e 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -954,15 +954,26 @@ static struct ref_cache *lookup_ref_cache(const char *submodule) /* * Return a pointer to a ref_cache for the specified submodule. For - * the main repository, use submodule==NULL. The returned structure - * will be allocated and initialized but not necessarily populated; it - * should not be freed. + * the main repository, use submodule==NULL; such a call cannot fail. + * For a submodule, the submodule must exist and be a nonbare + * repository, otherwise return NULL. + * + * The returned structure will be allocated and initialized but not + * necessarily populated; it should not be freed. */ static struct ref_cache *get_ref_cache(const char *submodule) { struct ref_cache *refs = lookup_ref_cache(submodule); - if (!refs) - refs = create_ref_cache(submodule); + + if (!refs) { + struct strbuf submodule_sb = STRBUF_INIT; + + strbuf_addstr(_sb, submodule); + if (is_nonbare_repository_dir(_sb)) + refs = create_ref_cache(submodule); + strbuf_release(_sb); + } + return refs; } @@ -1341,13 +1352,10 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh return -1; strbuf_add(, path, len); - refs = lookup_ref_cache(submodule.buf); + refs = get_ref_cache(submodule.buf); if (!refs) { - if (!is_nonbare_repository_dir()) { - strbuf_release(); - return -1; - } - refs = create_ref_cache(submodule.buf); + strbuf_release(); + return -1; } strbuf_release(); @@ -1885,6 +1893,9 @@ int do_for_each_ref(const char *submodule, const char *prefix, struct ref_cache *refs; refs = get_ref_cache(submodule); + if (!refs) + return 0; + data.prefix = prefix; data.trim = trim; data.flags = flags; -- 2.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 v3 13/13] for_each_reflog(): reimplement using iterators
Allow references with reflogs to be iterated over using a ref_iterator. The latter is implemented as a files_reflog_iterator, which in turn uses dir_iterator to read the "logs" directory. Note that reflog iteration doesn't correctly handle per-worktree reflogs (either before or after this patch). Signed-off-by: Ramsay JonesSigned-off-by: Michael Haggerty --- refs/files-backend.c | 113 --- refs/refs-internal.h | 7 2 files changed, 78 insertions(+), 42 deletions(-) diff --git a/refs/files-backend.c b/refs/files-backend.c index ab40db3..a9ca003 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2,6 +2,7 @@ #include "../refs.h" #include "refs-internal.h" #include "../iterator.h" +#include "../dir-iterator.h" #include "../lockfile.h" #include "../object.h" #include "../dir.h" @@ -3291,60 +3292,88 @@ int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_dat strbuf_release(); return ret; } -/* - * Call fn for each reflog in the namespace indicated by name. name - * must be empty or end with '/'. Name will be used as a scratch - * space, but its contents will be restored before return. - */ -static int do_for_each_reflog(struct strbuf *name, each_ref_fn fn, void *cb_data) + +struct files_reflog_iterator { + struct ref_iterator base; + + struct dir_iterator *dir_iterator; + struct object_id oid; +}; + +static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator) { - DIR *d = opendir(git_path("logs/%s", name->buf)); - int retval = 0; - struct dirent *de; - int oldlen = name->len; + struct files_reflog_iterator *iter = + (struct files_reflog_iterator *)ref_iterator; + struct dir_iterator *diter = iter->dir_iterator; + int ok; - if (!d) - return name->len ? errno : 0; + while ((ok = dir_iterator_advance(diter)) == ITER_OK) { + int flags; - while ((de = readdir(d)) != NULL) { - struct stat st; - - if (de->d_name[0] == '.') + if (!S_ISREG(diter->st.st_mode)) + continue; + if (diter->basename[0] == '.') continue; - if (ends_with(de->d_name, ".lock")) + if (ends_with(diter->basename, ".lock")) continue; - strbuf_addstr(name, de->d_name); - if (stat(git_path("logs/%s", name->buf), ) < 0) { - ; /* silently ignore */ - } else { - if (S_ISDIR(st.st_mode)) { - strbuf_addch(name, '/'); - retval = do_for_each_reflog(name, fn, cb_data); - } else { - struct object_id oid; - if (read_ref_full(name->buf, 0, oid.hash, NULL)) - error("bad ref for %s", name->buf); - else - retval = fn(name->buf, , 0, cb_data); - } - if (retval) - break; + if (read_ref_full(diter->relative_path, 0, + iter->oid.hash, )) { + error("bad ref for %s", diter->path.buf); + continue; } - strbuf_setlen(name, oldlen); + + iter->base.refname = diter->relative_path; + iter->base.oid = >oid; + iter->base.flags = flags; + return ITER_OK; } - closedir(d); - return retval; + + iter->dir_iterator = NULL; + if (ref_iterator_abort(ref_iterator) == ITER_ERROR) + ok = ITER_ERROR; + return ok; +} + +static int files_reflog_iterator_peel(struct ref_iterator *ref_iterator, + struct object_id *peeled) +{ + die("BUG: ref_iterator_peel() called for reflog_iterator"); +} + +static int files_reflog_iterator_abort(struct ref_iterator *ref_iterator) +{ + struct files_reflog_iterator *iter = + (struct files_reflog_iterator *)ref_iterator; + int ok = ITER_DONE; + + if (iter->dir_iterator) + ok = dir_iterator_abort(iter->dir_iterator); + + base_ref_iterator_free(ref_iterator); + return ok; +} + +static struct ref_iterator_vtable files_reflog_iterator_vtable = { + files_reflog_iterator_advance, + files_reflog_iterator_peel, + files_reflog_iterator_abort +}; + +struct ref_iterator *files_reflog_iterator_begin(void) +{ + struct files_reflog_iterator *iter = xcalloc(1, sizeof(*iter)); + struct ref_iterator *ref_iterator = >base; + + base_ref_iterator_init(ref_iterator,
[PATCH v3 10/13] do_for_each_ref(): reimplement using reference iteration
Use the reference iterator interface to implement do_for_each_ref(). Delete a bunch of code supporting the old for_each_ref() implementation. And now that do_for_each_ref() is generic code (it is no longer tied to the files backend), move it to refs.c. The implementation is via a new function, do_for_each_ref_iterator(), which takes a reference iterator as argument and calls a callback function for each of the references in the iterator. This change requires the current_ref performance hack for peel_ref() to be implemented via ref_iterator_peel() rather than peel_entry() because we don't have a ref_entry handy (it is hidden under three layers: file_ref_iterator, merge_ref_iterator, and cache_ref_iterator). So: * do_for_each_ref_iterator() records the active iterator in current_ref_iter while it is running. * peel_ref() checks whether current_ref_iter is pointing at the requested reference. If so, it asks the iterator to peel the reference (which it can do efficiently via its "peel" virtual function). For extra safety, we do the optimization only if the refname *addresses* are the same, not only if the refname *strings* are the same, to forestall possible mixups between refnames that come from different ref_iterators. Please note that this optimization of peel_ref() is only available when iterating via do_for_each_ref_iterator() (including all of the for_each_ref() functions, which call it indirectly). It would be complicated to implement a similar optimization when iterating directly using a reference iterator, because multiple reference iterators can be in use at the same time, with interleaved calls to ref_iterator_advance(). (In fact we do exactly that in merge_ref_iterator.) But that is not necessary. peel_ref() is only called while iterating over references. Callers who iterate using the for_each_ref() functions benefit from the optimization described above. Callers who iterate using reference iterators directly have access to the ref_iterator, so they can call ref_iterator_peel() themselves to get an analogous optimization in a more straightforward manner. If we rewrite all callers to use the reference iteration API, then we can remove the current_ref_iter hack permanently. Signed-off-by: Michael Haggerty--- refs.c | 20 + refs/files-backend.c | 206 ++- refs/iterator.c | 29 refs/refs-internal.h | 33 ++--- 4 files changed, 76 insertions(+), 212 deletions(-) diff --git a/refs.c b/refs.c index 842c5c7..814cad3 100644 --- a/refs.c +++ b/refs.c @@ -1120,6 +1120,26 @@ int head_ref(each_ref_fn fn, void *cb_data) return head_ref_submodule(NULL, fn, cb_data); } +/* + * Call fn for each reference in the specified submodule for which the + * refname begins with prefix. If trim is non-zero, then trim that + * many characters off the beginning of each refname before passing + * the refname to fn. flags can be DO_FOR_EACH_INCLUDE_BROKEN to + * include broken references in the iteration. If fn ever returns a + * non-zero value, stop the iteration and return that value; + * otherwise, return 0. + */ +static int do_for_each_ref(const char *submodule, const char *prefix, + each_ref_fn fn, int trim, int flags, void *cb_data) +{ + struct ref_iterator *iter; + + iter = files_ref_iterator_begin(submodule, prefix, flags); + iter = prefix_ref_iterator_begin(iter, prefix, trim); + + return do_for_each_ref_iterator(iter, fn, cb_data); +} + int for_each_ref(each_ref_fn fn, void *cb_data) { return do_for_each_ref(NULL, "", fn, 0, 0, cb_data); diff --git a/refs/files-backend.c b/refs/files-backend.c index 395056b..4232da8 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -542,53 +542,8 @@ static int entry_resolves_to_object(struct ref_entry *entry) >u.value.oid, entry->flag); } -/* - * current_ref is a performance hack: when iterating over references - * using the for_each_ref*() functions, current_ref is set to the - * current reference's entry before calling the callback function. If - * the callback function calls peel_ref(), then peel_ref() first - * checks whether the reference to be peeled is the current reference - * (it usually is) and if so, returns that reference's peeled version - * if it is available. This avoids a refname lookup in a common case. - */ -static struct ref_entry *current_ref; - typedef int each_ref_entry_fn(struct ref_entry *entry, void *cb_data); -struct ref_entry_cb { - const char *prefix; - int trim; - int flags; - each_ref_fn *fn; - void *cb_data; -}; - -/* - * Handle one reference in a do_for_each_ref*()-style iteration, - * calling an each_ref_fn for each entry. - */ -static int do_one_ref(struct ref_entry *entry, void *cb_data) -{ - struct ref_entry_cb *data = cb_data; - struct ref_entry
[PATCH v3 08/13] ref_resolves_to_object(): new function
Extract new function ref_resolves_to_object() from entry_resolves_to_object(). It can be used even if there is no ref_entry at hand. Signed-off-by: Michael Haggerty--- refs/files-backend.c | 33 +++-- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/refs/files-backend.c b/refs/files-backend.c index c24a78e..62280b5 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -513,19 +513,32 @@ static void sort_ref_dir(struct ref_dir *dir) } /* - * Return true iff the reference described by entry can be resolved to - * an object in the database. Emit a warning if the referred-to - * object does not exist. + * Return true if refname, which has the specified oid and flags, can + * be resolved to an object in the database. If the referred-to object + * does not exist, emit a warning and return false. + */ +static int ref_resolves_to_object(const char *refname, + const struct object_id *oid, + unsigned int flags) +{ + if (flags & REF_ISBROKEN) + return 0; + if (!has_sha1_file(oid->hash)) { + error("%s does not point to a valid object!", refname); + return 0; + } + return 1; +} + +/* + * Return true if the reference described by entry can be resolved to + * an object in the database; otherwise, emit a warning and return + * false. */ static int entry_resolves_to_object(struct ref_entry *entry) { - if (entry->flag & REF_ISBROKEN) - return 0; - if (!has_sha1_file(entry->u.value.oid.hash)) { - error("%s does not point to a valid object!", entry->name); - return 0; - } - return 1; + return ref_resolves_to_object(entry->name, + >u.value.oid, entry->flag); } /* -- 2.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 v3 12/13] dir_iterator: new API for iterating over a directory tree
The iterator interface is modeled on that for references, though no vtable is necessary because there is (so far?) only one type of dir_iterator. There are obviously a lot of features that could easily be added to this class: * Skip/include directory paths in the iteration * Shallow/deep iteration * Letting the caller decide which subdirectories to recurse into (e.g., via a dir_iterator_advance_into() function) * Option to iterate in sorted order * Option to iterate over directory paths before vs. after their contents But these are not needed for the current patch series, so I refrain. Signed-off-by: Michael Haggerty--- Makefile | 1 + dir-iterator.c | 202 + dir-iterator.h | 87 + 3 files changed, 290 insertions(+) create mode 100644 dir-iterator.c create mode 100644 dir-iterator.h diff --git a/Makefile b/Makefile index ac8f365..b4ffc11 100644 --- a/Makefile +++ b/Makefile @@ -722,6 +722,7 @@ LIB_OBJS += diff-lib.o LIB_OBJS += diff-no-index.o LIB_OBJS += diff.o LIB_OBJS += dir.o +LIB_OBJS += dir-iterator.o LIB_OBJS += editor.o LIB_OBJS += entry.o LIB_OBJS += environment.o diff --git a/dir-iterator.c b/dir-iterator.c new file mode 100644 index 000..34182a9 --- /dev/null +++ b/dir-iterator.c @@ -0,0 +1,202 @@ +#include "cache.h" +#include "dir.h" +#include "iterator.h" +#include "dir-iterator.h" + +struct dir_iterator_level { + int initialized; + + DIR *dir; + + /* +* The length of the directory part of path at this level +* (including a trailing '/'): +*/ + size_t prefix_len; + + /* +* The last action that has been taken with the current entry +* (needed for directories, which have to be included in the +* iteration and also iterated into): +*/ + enum { + DIR_STATE_ITER, + DIR_STATE_RECURSE + } dir_state; +}; + +/* + * The full data structure used to manage the internal directory + * iteration state. It includes members that are not part of the + * public interface. + */ +struct dir_iterator_int { + struct dir_iterator base; + + /* +* The number of levels currently on the stack. This is always +* at least 1, because when it becomes zero the iteration is +* ended and this struct is freed. +*/ + size_t levels_nr; + + /* The number of levels that have been allocated on the stack */ + size_t levels_alloc; + + /* +* A stack of levels. levels[0] is the uppermost directory +* that will be included in this iteration. +*/ + struct dir_iterator_level *levels; +}; + +int dir_iterator_advance(struct dir_iterator *dir_iterator) +{ + struct dir_iterator_int *iter = + (struct dir_iterator_int *)dir_iterator; + + while (1) { + struct dir_iterator_level *level = + >levels[iter->levels_nr - 1]; + struct dirent *de; + + if (!level->initialized) { + /* +* Note: dir_iterator_begin() ensures that +* path is not the empty string. +*/ + if (!is_dir_sep(iter->base.path.buf[iter->base.path.len - 1])) + strbuf_addch(>base.path, '/'); + level->prefix_len = iter->base.path.len; + + level->dir = opendir(iter->base.path.buf); + if (!level->dir && errno != ENOENT) { + warning("error opening directory %s: %s", + iter->base.path.buf, strerror(errno)); + /* Popping the level is handled below */ + } + + level->initialized = 1; + } else if (S_ISDIR(iter->base.st.st_mode)) { + if (level->dir_state == DIR_STATE_ITER) { + /* +* The directory was just iterated +* over; now prepare to iterate into +* it. +*/ + level->dir_state = DIR_STATE_RECURSE; + ALLOC_GROW(iter->levels, iter->levels_nr + 1, + iter->levels_alloc); + level = >levels[iter->levels_nr++]; + level->initialized = 0; + continue; + } else { + /* +* The directory has already been +* iterated over and iterated into; +* we're done with it. +*/ +
[PATCH v3 11/13] for_each_reflog(): don't abort for bad references
If there is a file under "$GIT_DIR/logs" with no corresponding reference, the old code was emitting an error message, aborting the reflog iteration, and returning -1. But * None of the callers was checking the exit value * The callers all want to find all legitimate reflogs (sometimes for the purpose of determining object reachability!) and wouldn't benefit from a truncated iteration anyway. So instead, emit an error message and skip the "broken" reflog, but continue with the iteration. Signed-off-by: Michael Haggerty--- refs/files-backend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/refs/files-backend.c b/refs/files-backend.c index 4232da8..ab40db3 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3324,7 +3324,7 @@ static int do_for_each_reflog(struct strbuf *name, each_ref_fn fn, void *cb_data struct object_id oid; if (read_ref_full(name->buf, 0, oid.hash, NULL)) - retval = error("bad ref for %s", name->buf); + error("bad ref for %s", name->buf); else retval = fn(name->buf, , 0, cb_data); } -- 2.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 v3 05/13] remote rm: handle symbolic refs correctly
In the modern world of reference backends, it is not OK to delete a symref by unlink()ing the file directly. This must be done via the refs API. We do so by adding the symref to the list of references to delete along with the non-symbolic references, then calling delete_refs() with the new flags option set to REF_NODEREF. Signed-off-by: Michael Haggerty--- builtin/remote.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/builtin/remote.c b/builtin/remote.c index 1bbf9b4..c4b4d67 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -539,10 +539,6 @@ static int add_branch_for_removal(const char *refname, return 0; } - /* make sure that symrefs are deleted */ - if (flags & REF_ISSYMREF) - return unlink(git_path("%s", refname)); - string_list_append(branches->branches, refname); return 0; @@ -788,7 +784,7 @@ static int rm(int argc, const char **argv) strbuf_release(); if (!result) - result = delete_refs(, 0); + result = delete_refs(, REF_NODEREF); string_list_clear(, 0); if (skipped.nr) { -- 2.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 v3 02/13] do_for_each_ref(): move docstring to the header file
Signed-off-by: Michael Haggerty--- refs/files-backend.c | 9 - refs/refs-internal.h | 10 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/refs/files-backend.c b/refs/files-backend.c index bbf96ad..8fa897b 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1878,15 +1878,6 @@ static int do_for_each_entry(struct ref_cache *refs, const char *base, return retval; } -/* - * Call fn for each reference in the specified ref_cache for which the - * refname begins with base. If trim is non-zero, then trim that many - * characters off the beginning of each refname before passing the - * refname to fn. flags can be DO_FOR_EACH_INCLUDE_BROKEN to include - * broken references in the iteration. If fn ever returns a non-zero - * value, stop the iteration and return that value; otherwise, return - * 0. - */ int do_for_each_ref(const char *submodule, const char *base, each_ref_fn fn, int trim, int flags, void *cb_data) { diff --git a/refs/refs-internal.h b/refs/refs-internal.h index 1bb3d87..b4dd545 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -249,7 +249,15 @@ int rename_ref_available(const char *oldname, const char *newname); #define DO_FOR_EACH_INCLUDE_BROKEN 0x01 /* - * The common backend for the for_each_*ref* functions + * Call fn for each reference in the specified submodule for which the + * refname begins with base. If trim is non-zero, then trim that many + * characters off the beginning of each refname before passing the + * refname to fn. flags can be DO_FOR_EACH_INCLUDE_BROKEN to include + * broken references in the iteration. If fn ever returns a non-zero + * value, stop the iteration and return that value; otherwise, return + * 0. + * + * This is the common backend for the for_each_*ref* functions. */ int do_for_each_ref(const char *submodule, const char *base, each_ref_fn fn, int trim, int flags, void *cb_data); -- 2.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 v3 09/13] refs: introduce an iterator interface
Currently, the API for iterating over references is via a family of for_each_ref()-type functions that invoke a callback function for each selected reference. All of these eventually call do_for_each_ref(), which knows how to do one thing: iterate in parallel through two ref_caches, one for loose and one for packed refs, giving loose references precedence over packed refs. This is rather complicated code, and is quite specialized to the files backend. It also requires callers to encapsulate their work into a callback function, which often means that they have to define and use a "cb_data" struct to manage their context. The current design is already bursting at the seams, and will become even more awkward in the upcoming world of multiple reference storage backends: * Per-worktree vs. shared references are currently handled via a kludge in git_path() rather than iterating over each part of the reference namespace separately and merging the results. This kludge will cease to work when we have multiple reference storage backends. * The current scheme is inflexible. What if we sometimes want to bypass the ref_cache, or use it only for packed or only for loose refs? What if we want to store symbolic refs in one type of storage backend and non-symbolic ones in another? In the future, each reference backend will need to define its own way of iterating over references. The crux of the problem with the current design is that it is impossible to compose for_each_ref()-style iterations, because the flow of control is owned by the for_each_ref() function. There is nothing that a caller can do but iterate through all references in a single burst, so there is no way for it to interleave references from multiple backends and present the result to the rest of the world as a single compound backend. This commit introduces a new iteration primitive for references: a ref_iterator. A ref_iterator is a polymorphic object that a reference storage backend can be asked to instantiate. There are three functions that can be applied to a ref_iterator: * ref_iterator_advance(): move to the next reference in the iteration * ref_iterator_abort(): end the iteration before it is exhausted * ref_iterator_peel(): peel the reference currently being looked at Iterating using a ref_iterator leaves the flow of control in the hands of the caller, which means that ref_iterators from multiple sources (e.g., loose and packed refs) can be composed and presented to the world as a single compound ref_iterator. It also means that the backend code for implementing reference iteration will sometimes be more complicated. For example, the cache_ref_iterator (which iterates over a ref_cache) can't use the C stack to recurse; instead, it must manage its own stack internally as explicit data structures. There is also a lot of boilerplate connected with object-oriented programming in C. Eventually, end-user callers will be able to be written in a more natural way—managing their own flow of control rather than having to work via callbacks. Since there will only be a few reference backends but there are many consumers of this API, this is a good tradeoff. More importantly, we gain composability, and especially the possibility of writing interchangeable parts that can work with any ref_iterator. For example, merge_ref_iterator implements a generic way of merging the contents of any two ref_iterators. It is used to merge loose + packed refs as part of the implementation of the files_ref_iterator. But it will also be possible to use it to merge other pairs of reference sources (e.g., per-worktree vs. shared refs). Another example is prefix_ref_iterator, which can be used to trim a prefix off the front of reference names before presenting them to the caller (e.g., "refs/heads/master" -> "master"). In this patch, we introduce the iterator abstraction and many utilities, and implement a reference iterator for the files ref storage backend. (I've written several other obvious utilities, for example a generic way to filter references being iterated over. These will probably be useful in the future. But they are not needed for this patch series, so I am not including them at this time.) In a moment we will rewrite do_for_each_ref() to work via reference iterators (allowing some special-purpose code to be discarded), and do something similar for reflogs. In future patch series, we will expose the ref_iterator abstraction in the public refs API so that callers can use it directly. Implementation note: I tried abstracting this a layer further to allow generic iterators (over arbitrary types of objects) and generic utilities like a generic merge_iterator. But the implementation in C was very cumbersome, involving (in my opinion) too much boilerplate and too much unsafe casting, some of which would have had to be done on the caller side. However, I did put a few iterator-related constants in a top-level header file, iterator.h, as they will be
[PATCH v3 07/13] entry_resolves_to_object(): rename function from ref_resolves_to_object()
Free up the old name for a more general purpose. Signed-off-by: Michael Haggerty--- refs/files-backend.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/refs/files-backend.c b/refs/files-backend.c index b563a7e..c24a78e 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -517,7 +517,7 @@ static void sort_ref_dir(struct ref_dir *dir) * an object in the database. Emit a warning if the referred-to * object does not exist. */ -static int ref_resolves_to_object(struct ref_entry *entry) +static int entry_resolves_to_object(struct ref_entry *entry) { if (entry->flag & REF_ISBROKEN) return 0; @@ -563,7 +563,7 @@ static int do_one_ref(struct ref_entry *entry, void *cb_data) return 0; if (!(data->flags & DO_FOR_EACH_INCLUDE_BROKEN) && - !ref_resolves_to_object(entry)) + !entry_resolves_to_object(entry)) return 0; /* Store the old value, in case this is a recursive call: */ @@ -2228,7 +2228,7 @@ static int pack_if_possible_fn(struct ref_entry *entry, void *cb_data) return 0; /* Do not pack symbolic or broken refs: */ - if ((entry->flag & REF_ISSYMREF) || !ref_resolves_to_object(entry)) + if ((entry->flag & REF_ISSYMREF) || !entry_resolves_to_object(entry)) return 0; /* Add a packed ref cache entry equivalent to the loose entry. */ -- 2.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 v3 01/13] refs: remove unnecessary "extern" keywords
There's continuing work in this area, so clean up unneeded "extern" keywords rather than schlepping them around. Also split up some overlong lines and add parameter names in a couple of places. Signed-off-by: Michael Haggerty--- refs.h | 132 +++-- 1 file changed, 72 insertions(+), 60 deletions(-) diff --git a/refs.h b/refs.h index 9230d47..21874f0 100644 --- a/refs.h +++ b/refs.h @@ -52,19 +52,19 @@ #define RESOLVE_REF_NO_RECURSE 0x02 #define RESOLVE_REF_ALLOW_BAD_NAME 0x04 -extern const char *resolve_ref_unsafe(const char *refname, int resolve_flags, - unsigned char *sha1, int *flags); +const char *resolve_ref_unsafe(const char *refname, int resolve_flags, + unsigned char *sha1, int *flags); -extern char *resolve_refdup(const char *refname, int resolve_flags, - unsigned char *sha1, int *flags); +char *resolve_refdup(const char *refname, int resolve_flags, +unsigned char *sha1, int *flags); -extern int read_ref_full(const char *refname, int resolve_flags, -unsigned char *sha1, int *flags); -extern int read_ref(const char *refname, unsigned char *sha1); +int read_ref_full(const char *refname, int resolve_flags, + unsigned char *sha1, int *flags); +int read_ref(const char *refname, unsigned char *sha1); -extern int ref_exists(const char *refname); +int ref_exists(const char *refname); -extern int is_branch(const char *refname); +int is_branch(const char *refname); /* * If refname is a non-symbolic reference that refers to a tag object, @@ -74,24 +74,25 @@ extern int is_branch(const char *refname); * Symbolic references are considered unpeelable, even if they * ultimately resolve to a peelable tag. */ -extern int peel_ref(const char *refname, unsigned char *sha1); +int peel_ref(const char *refname, unsigned char *sha1); /** * Resolve refname in the nested "gitlink" repository that is located * at path. If the resolution is successful, return 0 and set sha1 to * the name of the object; otherwise, return a non-zero value. */ -extern int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1); +int resolve_gitlink_ref(const char *path, const char *refname, + unsigned char *sha1); /* * Return true iff abbrev_name is a possible abbreviation for * full_name according to the rules defined by ref_rev_parse_rules in * refs.c. */ -extern int refname_match(const char *abbrev_name, const char *full_name); +int refname_match(const char *abbrev_name, const char *full_name); -extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref); -extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref); +int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref); +int dwim_log(const char *str, int len, unsigned char *sha1, char **ref); /* * A ref_transaction represents a collection of ref updates @@ -182,38 +183,45 @@ typedef int each_ref_fn(const char *refname, * modifies the reference also returns a nonzero value to immediately * stop the iteration. */ -extern int head_ref(each_ref_fn fn, void *cb_data); -extern int for_each_ref(each_ref_fn fn, void *cb_data); -extern int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data); -extern int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsigned int broken); -extern int for_each_tag_ref(each_ref_fn fn, void *cb_data); -extern int for_each_branch_ref(each_ref_fn fn, void *cb_data); -extern int for_each_remote_ref(each_ref_fn fn, void *cb_data); -extern int for_each_replace_ref(each_ref_fn fn, void *cb_data); -extern int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data); -extern int for_each_glob_ref_in(each_ref_fn fn, const char *pattern, const char *prefix, void *cb_data); +int head_ref(each_ref_fn fn, void *cb_data); +int for_each_ref(each_ref_fn fn, void *cb_data); +int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data); +int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, + unsigned int broken); +int for_each_tag_ref(each_ref_fn fn, void *cb_data); +int for_each_branch_ref(each_ref_fn fn, void *cb_data); +int for_each_remote_ref(each_ref_fn fn, void *cb_data); +int for_each_replace_ref(each_ref_fn fn, void *cb_data); +int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data); +int for_each_glob_ref_in(each_ref_fn fn, const char *pattern, +const char *prefix, void *cb_data); -extern int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data); -extern int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data); -extern int for_each_ref_in_submodule(const char *submodule, const char *prefix,
[PATCH v3 00/13] Reference iterators
This is the reroll of branch mh/ref-iterators promised and discussed earlier [1]. There are no showstoppers here, but it would be preferable to merge this version rather than v2. This version squashes in Ramsay's patch [2], addresses Eric's comments, and incorporates the whitespace fix that you made when incorporating v2. List of changes relative to v2: * In "refs: introduce an iterator interface": * Make two vtables private. * Add a whitespace fix from Junio's mh/ref-iterators. * In "dir_iterator: new API for iterating over a directory tree": * Add and improve some comments and docstrings. * Fix some formatting problems. * Use a for rather than a while loop in `dir_iterator_abort()` to improve the clarity. * Warn on failures of `opendir()`, `readdir()`, and `closedir()` that can't be explained as a simple race. * In "for_each_reflog(): reimplement using iterators", make the vtable private. These changes are also available from my GitHub fork [3] as branch "ref-iterators". Michael [1] http://article.gmane.org/gmane.comp.version-control.git/296883 [2] http://thread.gmane.org/gmane.comp.version-control.git/296801 [3] https://github.com/mhagger/git Michael Haggerty (13): refs: remove unnecessary "extern" keywords do_for_each_ref(): move docstring to the header file refs: use name "prefix" consistently delete_refs(): add a flags argument remote rm: handle symbolic refs correctly get_ref_cache(): only create an instance if there is a submodule entry_resolves_to_object(): rename function from ref_resolves_to_object() ref_resolves_to_object(): new function refs: introduce an iterator interface do_for_each_ref(): reimplement using reference iteration for_each_reflog(): don't abort for bad references dir_iterator: new API for iterating over a directory tree for_each_reflog(): reimplement using iterators Makefile | 2 + builtin/fetch.c | 2 +- builtin/remote.c | 8 +- dir-iterator.c | 202 + dir-iterator.h | 87 +++ iterator.h | 81 +++ refs.c | 20 ++ refs.h | 139 +++- refs/files-backend.c | 629 +++ refs/iterator.c | 384 +++ refs/refs-internal.h | 226 +- 11 files changed, 1458 insertions(+), 322 deletions(-) create mode 100644 dir-iterator.c create mode 100644 dir-iterator.h create mode 100644 iterator.h create mode 100644 refs/iterator.c -- 2.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: Migrating away from SHA-1?
Leo Gaspardwrote: > First, sorry for not having this message threaded: I'm not subscribed to > the list and haven't found a way to get a Message-Id from gmane. Appending "/raw" to the gmane URL will get you the raw message with full headers: article.gmane.org/gmane.comp.version-control.git/$NUMBER/raw you can also use that article $NUMBER via NNTP on news.gmane.org > So, my questions to the git team: It is customary to Cc: all relevant parties involved with that thread since they may not all be subscribed, either. > * Is there a consensus, that git should migrate away from SHA-1 before > it gets a collision attack, because it would mean chosen-prefix > collision isn't far away and people wouldn't have the time to upgrade? > * Is there a consensus, that Peter Anvin's amended transition plan is > the way to go? > * If the two conditions above are fulfilled, has work started on it > yet? (I guess as Brian Carlson had started his work 9 weeks ago and he > was speaking about working on it on the week-end he should have finished > it now, so excluding this) AFAIK, brian is still working on it. Last series on the matter begins here: http://mid.gmane.org/20160607005716.69222-2-sand...@crustytoothpaste.net I'm just on the sidelines observing :) > * If the two first conditions are fulfilled, is there anything I could > do to help this transition? (including helping Brian if his work hasn't > actually ended yet) -- To unsubscribe from this list: send the line "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: Migrating away from SHA-1?
First, sorry for not having this message threaded: I'm not subscribed to the list and haven't found a way to get a Message-Id from gmane. I just wanted to ask, as an end-user highly relying on commit signatures, a few questions as to the migration away from SHA-1. SHA-1 already suffers from a freestart collision attack. Based on what I understand of the object model of git, a chosen-prefix collision attack (perhaps somewhat improved) is enough to make reviewers accept a patch, sign it, and then swap the innocuous-looking patch for an evil-doing one -- which *will be signed*. As for the issue about code checking being an easier entrypoint (Theodore Ts'o, 2016-04-14 22:40:51 GMT), in a use case of mine there is a repo with my dotfiles on an untrusted server. Yet I download them and am able to execute them without fear because each commit is PGP-signed with my key. The point being that code checking is not even a possible entrypoint in some cases, so SHA-1 seems to be(come) the weakest link. So, I don't think it is possible to disagree with Jeff King when he wrote his 2016-04-12 23:15:19 GMT email. Peter Anvin (2016-04-14 17:28:50 GMT) gets a point in that there is no need to hurry (chosen-prefix collisions may be still quite a long way, even though there is no guesswork in these matters), and quality is important. Yet Jeff King's proposal (2016-04-12 23:42:52 GMT), amended by Junio Hamano (2016-04-13 01:03:02 GMT) and himself (2016-04-13 01:36:32 GMT) seem to have met no opposition. So, my questions to the git team: * Is there a consensus, that git should migrate away from SHA-1 before it gets a collision attack, because it would mean chosen-prefix collision isn't far away and people wouldn't have the time to upgrade? * Is there a consensus, that Peter Anvin's amended transition plan is the way to go? * If the two conditions above are fulfilled, has work started on it yet? (I guess as Brian Carlson had started his work 9 weeks ago and he was speaking about working on it on the week-end he should have finished it now, so excluding this) * If the two first conditions are fulfilled, is there anything I could do to help this transition? (including helping Brian if his work hasn't actually ended yet) Sorry for bringing up again a subject that seems to be quite recurrent, and for this long block of text, Leo Gaspard signature.asc Description: OpenPGP digital signature
Re: [PATCH] archive-tar: add UL type suffix to unsigned long constant
On 18/06/16 00:40, Jeff King wrote: > On Fri, Jun 17, 2016 at 10:06:14PM +0100, Ramsay Jones wrote: > >> If you need to re-roll your 'jk/big-and-old-archive-tar' branch, could >> you please squash this into the relevant patch (commit 8035a1e3, >> "archive-tar: write extended headers for far-future mtime", 16-06-2016). >> >> Thanks! >> >> ATB, >> Ramsay Jones >> >> archive-tar.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/archive-tar.c b/archive-tar.c >> index 749722f..c7b85fd 100644 >> --- a/archive-tar.c >> +++ b/archive-tar.c >> @@ -187,7 +187,7 @@ static inline unsigned long ustar_size(uintmax_t size) >> >> static inline unsigned long ustar_mtime(time_t mtime) >> { >> -if (mtime < 0777) >> +if (mtime < 0777UL) > > Whoops. I even got it right in the similar line above. :-/ > > This did make me wonder how the whole thing fares on a system where > "unsigned long" is 32-bit (AIUI, Git for Windows is such a system). > > The sizes passed around (here and all through git) are "unsigned long", > so I don't think we're making anything _worse_. Heh, I had exactly the same thought! ;-) I have a TODO item that reads: check odb code for object size limitations imposed by using 'unsigned long'. This is a known problem on Git for Windows. [Not for cygwin, however, since long is 64bit (just like linux). The win32api headers on cygwin have been written in terms of a __LONG32 #define to allow them to be used on LLP64 and LP64 systems.] However, since I don't have GFW installed, I couldn't actually test it, so ... ATB, Ramsay Jones -- To unsubscribe from this list: send the line "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] run-command: mark file-local symbols static
On 18/06/16 00:33, Jeff King wrote: > On Fri, Jun 17, 2016 at 10:01:24PM +0100, Ramsay Jones wrote: > >> If you need to re-roll your 'jk/gpg-interface-cleanup' branch, could >> you please squash this into the relevant patch (commit 74287e34, >> "run-command: add pipe_command helper", 16-06-2016). > > Thanks, yes. > >> BTW, also on that branch, commit 6fec0a89 ("verify_signed_buffer: use >> tempfile object", 16-06-2016) removes the last use of the git_mkstemp() >> function. Should it be removed? > > I think so. We still have git_mkstemp_mode and friends, so in that sense > this is part of a family of commands that somebody might use again. But: > > 1. Unlike the others in the family, where we implement mkstemp > ourselves, this one uses the system mkstemp. Which probably behaves > in totally the same way, but it's kind of weird and oddball. > > 2. I think we should be steering people towards tempfile.c anyway, for > its auto-cleanup properties. > > Want to do a patch on top? OK, will do. (tomorrow, it is 2am here ...) ATB, Ramsay Jones -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 00/11] Fix icase grep on non-ascii
On Sat, Jun 18, 2016 at 6:17 AM, Junio C Hamanowrote: > Nguyễn Thái Ngọc Duy writes: > >> v6 fixes comments from Ramsay and Eric. Interdiff below. > > Another thing I noticed with this is that the non-ascii test breaks > when run under dash (but passes under bash). You need to have is_IS > locale on the system to see the breakage, it seems (which is why I > didn't see it so far). Is it a special version, maybe from debian? It works for me on gentoo. > ~/w/git/temp/t $ equery --quiet list dash app-shells/dash-0.5.8.2 > ~/w/git/temp/t $ dash ./t7812-grep-icase-non-ascii.sh # lib-gettext: Found 'is_IS.utf8' as an is_IS UTF-8 locale # lib-gettext: Found 'is_IS.iso88591' as an is_IS ISO-8859-1 locale ok 1 - setup ok 2 - grep literal string, no -F ok 3 - grep pcre utf-8 icase ok 4 - grep pcre utf-8 string with "+" ok 5 - grep literal string, with -F ok 6 - grep string with regex, with -F ok 7 - pickaxe -i on non-ascii # passed all 7 test(s) 1..7 -- Duy -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 01/11] grep: allow -F -i combination
On Sat, Jun 18, 2016 at 4:54 AM, Junio C Hamanowrote: > Nguyễn Thái Ngọc Duy writes: > >> -F means "no regex", not "case sensitive" so it should not override -i > > That logic is flawed, isn't it? > > "-F" means "no regex", so it should not touch opt.regflags at all. > >> Signed-off-by: Nguyễn Thái Ngọc Duy >> --- >> builtin/grep.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/builtin/grep.c b/builtin/grep.c >> index 5526fd7..4be0df5 100644 >> --- a/builtin/grep.c >> +++ b/builtin/grep.c >> @@ -809,7 +809,7 @@ int cmd_grep(int argc, const char **argv, const char >> *prefix) >> >> if (!opt.pattern_list) >> die(_("no pattern given.")); >> - if (!opt.fixed && opt.ignore_case) >> + if (opt.ignore_case) >> opt.regflags |= REG_ICASE; >> >> compile_grep_patterns(); > > In grep.c, we do this: > > static void compile_regexp(struct grep_pat *p, struct grep_opt *opt) > { > int err; > > p->word_regexp = opt->word_regexp; > p->ignore_case = opt->ignore_case; > > if (opt->fixed || is_fixed(p->pattern, p->patternlen)) > p->fixed = 1; > else > p->fixed = 0; > > if (p->fixed) { > if (opt->regflags & REG_ICASE || p->ignore_case) > p->kws = kwsalloc(tolower_trans_tbl); > else > > It is possible that your later changes _depend_ on having REG_ICASE > set in opt->regflags, but if that is why this commit is needed, then > you are going in a wrong direction. Yeah.. some commits down the line, we need to avoid kws (because it can't deal with non-ascii) and fall back to regex after all special chars are quoted. Will fix. -- Duy -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] archive-tar: add UL type suffix to unsigned long constant
On Fri, Jun 17, 2016 at 10:06:14PM +0100, Ramsay Jones wrote: > If you need to re-roll your 'jk/big-and-old-archive-tar' branch, could > you please squash this into the relevant patch (commit 8035a1e3, > "archive-tar: write extended headers for far-future mtime", 16-06-2016). > > Thanks! > > ATB, > Ramsay Jones > > archive-tar.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/archive-tar.c b/archive-tar.c > index 749722f..c7b85fd 100644 > --- a/archive-tar.c > +++ b/archive-tar.c > @@ -187,7 +187,7 @@ static inline unsigned long ustar_size(uintmax_t size) > > static inline unsigned long ustar_mtime(time_t mtime) > { > - if (mtime < 0777) > + if (mtime < 0777UL) Whoops. I even got it right in the similar line above. :-/ This did make me wonder how the whole thing fares on a system where "unsigned long" is 32-bit (AIUI, Git for Windows is such a system). The sizes passed around (here and all through git) are "unsigned long", so I don't think we're making anything _worse_. -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 v2 3/7] verify_signed_buffer: use tempfile object
We use git_mkstemp to create a temporary file, and try to clean it up in all exit paths from the function. But that misses any cases where we die by signal, or by calling die() in a sub-function. In addition, we missed one of the exit paths. Let's convert to using a tempfile object, which handles the hard cases for us, and add the missing cleanup call. Note that we would not simply want to rely on program exit to catch our missed cleanup, as this function may be called many times in a single program (for the same reason, we use a static tempfile instead of heap-allocating a new one; that gives an upper bound on our memory usage). Signed-off-by: Jeff King--- gpg-interface.c | 21 + 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/gpg-interface.c b/gpg-interface.c index 216cad8..854c1e5 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -3,6 +3,7 @@ #include "strbuf.h" #include "gpg-interface.h" #include "sigchain.h" +#include "tempfile.h" static char *configured_signing_key; static const char *gpg_program = "gpg"; @@ -208,28 +209,32 @@ int verify_signed_buffer(const char *payload, size_t payload_size, struct strbuf *gpg_output, struct strbuf *gpg_status) { struct child_process gpg = CHILD_PROCESS_INIT; - char path[PATH_MAX]; + static struct tempfile temp; int fd, ret; struct strbuf buf = STRBUF_INIT; - fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXX"); + fd = mks_tempfile_t(, ".git_vtag_tmpXX"); if (fd < 0) - return error_errno(_("could not create temporary file '%s'"), path); - if (write_in_full(fd, signature, signature_size) < 0) - return error_errno(_("failed writing detached signature to '%s'"), path); + return error_errno(_("could not create temporary file")); + if (write_in_full(fd, signature, signature_size) < 0) { + error_errno(_("failed writing detached signature to '%s'"), + temp.filename.buf); + delete_tempfile(); + return -1; + } close(fd); argv_array_pushl(, gpg_program, "--status-fd=1", -"--verify", path, "-", +"--verify", temp.filename.buf, "-", NULL); gpg.in = -1; gpg.out = -1; if (gpg_output) gpg.err = -1; if (start_command()) { - unlink(path); + delete_tempfile(); return error(_("could not run gpg.")); } @@ -249,7 +254,7 @@ int verify_signed_buffer(const char *payload, size_t payload_size, ret = finish_command(); sigchain_pop(SIGPIPE); - unlink_or_warn(path); + delete_tempfile(); ret |= !strstr(gpg_status->buf, "\n[GNUPG:] GOODSIG "); strbuf_release(); /* no matter it was used or not */ -- 2.9.0.165.g4aacdc3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 6/7] sign_buffer: use pipe_command
Similar to the prior commit for verify_signed_buffer, the motivation here is both to make the code simpler, and to avoid any possible deadlocks with gpg. In this case we have the same "write to stdin, then read from stdout" that the verify case had. This is unlikely to be a problem in practice, since stdout has the detached signature, which it cannot compute until it has read all of stdin (if it were a non-detached signature, that would be a problem, though). We don't read from stderr at all currently. However, we will want to in a future patch, so this also prepares us there (and in that case gpg _does_ write before reading all of the input, though again, it is unlikely that a key uid will fill up a pipe buffer). Signed-off-by: Jeff King--- gpg-interface.c | 24 +--- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/gpg-interface.c b/gpg-interface.c index c98035d..74f08a2 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -151,40 +151,26 @@ const char *get_signing_key(void) int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key) { struct child_process gpg = CHILD_PROCESS_INIT; - ssize_t len; + int ret; size_t i, j, bottom; - gpg.in = -1; - gpg.out = -1; argv_array_pushl(, gpg_program, "-bsau", signing_key, NULL); - if (start_command()) - return error(_("could not run gpg.")); + bottom = signature->len; /* * When the username signingkey is bad, program could be terminated * because gpg exits without reading and then write gets SIGPIPE. */ sigchain_push(SIGPIPE, SIG_IGN); - - if (write_in_full(gpg.in, buffer->buf, buffer->len) != buffer->len) { - close(gpg.in); - close(gpg.out); - finish_command(); - return error(_("gpg did not accept the data")); - } - close(gpg.in); - - bottom = signature->len; - len = strbuf_read(signature, gpg.out, 1024); - close(gpg.out); - + ret = pipe_command(, buffer->buf, buffer->len, + signature, 1024, NULL, 0); sigchain_pop(SIGPIPE); - if (finish_command() || !len || len < 0) + if (ret || signature->len == bottom) return error(_("gpg failed to sign the data")); /* Strip CR from the line endings, in case we are on Windows. */ -- 2.9.0.165.g4aacdc3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 5/7] verify_signed_buffer: use pipe_command
This is shorter and should make the function easier to follow. But more importantly, it removes the possibility of any deadlocks based on reading or writing to gpg. It's not clear if such a deadlock is possible in practice. We do write the whole payload before reading anything, so we could deadlock there. However, in practice gpg will need to read our whole input to verify the signature, so it will drain our payload first. It could write an error to stderr before reading, but it's unlikely that such an error wouldn't be followed by it immediately exiting, or that the error would actually be larger than a pipe buffer. On the writing side, we drain stderr (with the human-readable output) in its entirety before reading stdout (with the status-fd data). Running strace on "gpg --verify" does show interleaved output on the two descriptors: write(2, "gpg: ", 5)= 5 write(2, "Signature made Thu 16 Jun 2016 0"..., 73) = 73 write(1, "[GNUPG:] SIG_ID tQw8KGcs9rBfLvAj"..., 66) = 66 write(1, "[GNUPG:] GOODSIG 69808639F9430ED"..., 60) = 60 write(2, "gpg: ", 5)= 5 write(2, "Good signature from \"Jeff King <"..., 47) = 47 write(2, "\n", 1) = 1 write(2, "gpg: ", 5)= 5 write(2, "aka \"Jeff King <"..., 49) = 49 write(2, "\n", 1) = 1 write(1, "[GNUPG:] VALIDSIG C49CE24156AF08"..., 135) = 135 write(1, "[GNUPG:] TRUST_ULTIMATE\n", 24) = 24 The second line written to stdout there contains the signer's UID, which can be arbitrarily long. If it fills the pipe buffer, then gpg would block writing to its stdout, while we are blocked trying to read its stderr. In practice, GPG seems to limit UIDs to 2048 bytes, so unless your pipe buffer size is quite small, or unless gpg does not enforce the limit under some conditions, this seems unlikely in practice. Still, it is not hard for us to be cautious and just use pipe_command. Signed-off-by: Jeff King--- gpg-interface.c | 22 +++--- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/gpg-interface.c b/gpg-interface.c index 854c1e5..c98035d 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -229,29 +229,13 @@ int verify_signed_buffer(const char *payload, size_t payload_size, "--status-fd=1", "--verify", temp.filename.buf, "-", NULL); - gpg.in = -1; - gpg.out = -1; - if (gpg_output) - gpg.err = -1; - if (start_command()) { - delete_tempfile(); - return error(_("could not run gpg.")); - } - sigchain_push(SIGPIPE, SIG_IGN); - write_in_full(gpg.in, payload, payload_size); - close(gpg.in); - - if (gpg_output) { - strbuf_read(gpg_output, gpg.err, 0); - close(gpg.err); - } if (!gpg_status) gpg_status = - strbuf_read(gpg_status, gpg.out, 0); - close(gpg.out); - ret = finish_command(); + sigchain_push(SIGPIPE, SIG_IGN); + ret = pipe_command(, payload, payload_size, + gpg_status, 0, gpg_output, 0); sigchain_pop(SIGPIPE); delete_tempfile(); -- 2.9.0.165.g4aacdc3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 4/7] run-command: add pipe_command helper
We already have capture_command(), which captures the stdout of a command in a way that avoids deadlocks. But sometimes we need to do more I/O, like capturing stderr as well, or sending data to stdin. It's easy to write code that deadlocks racily in these situations depending on how fast the command reads its input, or in which order it writes its output. Let's give callers an easy interface for doing this the right way, similar to what capture_command() did for the simple case. The whole thing is backed by a generic poll() loop that can feed an arbitrary number of buffers to descriptors, and fill an arbitrary number of strbufs from other descriptors. This seems like overkill, but the resulting code is actually a bit cleaner than just handling the three descriptors (because the output code for stdout/stderr is effectively duplicated, so being able to loop is a benefit). Signed-off-by: Jeff King--- run-command.c | 152 -- run-command.h | 31 +--- 2 files changed, 171 insertions(+), 12 deletions(-) diff --git a/run-command.c b/run-command.c index af0c8a1..33bc63a 100644 --- a/run-command.c +++ b/run-command.c @@ -864,19 +864,161 @@ int run_hook_le(const char *const *env, const char *name, ...) return ret; } -int capture_command(struct child_process *cmd, struct strbuf *buf, size_t hint) +struct io_pump { + /* initialized by caller */ + int fd; + int type; /* POLLOUT or POLLIN */ + union { + struct { + const char *buf; + size_t len; + } out; + struct { + struct strbuf *buf; + size_t hint; + } in; + } u; + + /* returned by pump_io */ + int error; /* 0 for success, otherwise errno */ + + /* internal use */ + struct pollfd *pfd; +}; + +static int pump_io_round(struct io_pump *slots, int nr, struct pollfd *pfd) +{ + int pollsize = 0; + int i; + + for (i = 0; i < nr; i++) { + struct io_pump *io = [i]; + if (io->fd < 0) + continue; + pfd[pollsize].fd = io->fd; + pfd[pollsize].events = io->type; + io->pfd = [pollsize++]; + } + + if (!pollsize) + return 0; + + if (poll(pfd, pollsize, -1) < 0) { + if (errno == EINTR) + return 1; + die_errno("poll failed"); + } + + for (i = 0; i < nr; i++) { + struct io_pump *io = [i]; + + if (io->fd < 0) + continue; + + if (!(io->pfd->revents & (POLLOUT|POLLIN|POLLHUP|POLLERR|POLLNVAL))) + continue; + + if (io->type == POLLOUT) { + ssize_t len = xwrite(io->fd, +io->u.out.buf, io->u.out.len); + if (len < 0) { + io->error = errno; + close(io->fd); + io->fd = -1; + } else { + io->u.out.buf += len; + io->u.out.len -= len; + if (!io->u.out.len) { + close(io->fd); + io->fd = -1; + } + } + } + + if (io->type == POLLIN) { + ssize_t len = strbuf_read_once(io->u.in.buf, + io->fd, io->u.in.hint); + if (len < 0) + io->error = errno; + if (len <= 0) { + close(io->fd); + io->fd = -1; + } + } + } + + return 1; +} + +static int pump_io(struct io_pump *slots, int nr) +{ + struct pollfd *pfd; + int i; + + for (i = 0; i < nr; i++) + slots[i].error = 0; + + ALLOC_ARRAY(pfd, nr); + while (pump_io_round(slots, nr, pfd)) + ; /* nothing */ + free(pfd); + + /* There may be multiple errno values, so just pick the first. */ + for (i = 0; i < nr; i++) { + if (slots[i].error) { + errno = slots[i].error; + return -1; + } + } + return 0; +} + + +int pipe_command(struct child_process *cmd, +const char *in, size_t in_len, +struct strbuf *out, size_t out_hint, +struct strbuf *err, size_t err_hint) { - cmd->out = -1; + struct io_pump io[3]; + int nr = 0; + + if (in) + cmd->in = -1; + if
[PATCH v2 7/7] gpg-interface: check gpg signature creation status
From: Michael J GruberWhen we create a signature, it may happen that gpg returns with "success" but not with an actual detached signature on stdout. Check for the correct signature creation status to catch these cases better. Really, --status-fd parsing is the only way to check gpg status reliably. We do the same for verify already. Signed-off-by: Michael J Gruber Signed-off-by: Jeff King --- gpg-interface.c | 8 ++-- t/t7004-tag.sh | 9 - 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/gpg-interface.c b/gpg-interface.c index 74f08a2..08356f9 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -153,9 +153,11 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *sig struct child_process gpg = CHILD_PROCESS_INIT; int ret; size_t i, j, bottom; + struct strbuf gpg_status = STRBUF_INIT; argv_array_pushl(, gpg_program, +"--status-fd=2", "-bsau", signing_key, NULL); @@ -167,10 +169,12 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *sig */ sigchain_push(SIGPIPE, SIG_IGN); ret = pipe_command(, buffer->buf, buffer->len, - signature, 1024, NULL, 0); + signature, 1024, _status, 0); sigchain_pop(SIGPIPE); - if (ret || signature->len == bottom) + ret |= !strstr(gpg_status.buf, "\n[GNUPG:] SIG_CREATED "); + strbuf_release(_status); + if (ret) return error(_("gpg failed to sign the data")); /* Strip CR from the line endings, in case we are on Windows. */ diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index f9b7d79..8b0f71a 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1202,10 +1202,17 @@ test_expect_success GPG,RFC1991 \ # try to sign with bad user.signingkey git config user.signingkey BobTheMouse test_expect_success GPG \ - 'git tag -s fails if gpg is misconfigured' \ + 'git tag -s fails if gpg is misconfigured (bad key)' \ 'test_must_fail git tag -s -m tail tag-gpg-failure' git config --unset user.signingkey +# try to produce invalid signature +test_expect_success GPG \ + 'git tag -s fails if gpg is misconfigured (bad signature format)' \ + 'test_config gpg.program echo && +test_must_fail git tag -s -m tail tag-gpg-failure' + + # try to verify without gpg: rm -rf gpghome -- 2.9.0.165.g4aacdc3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/7] verify_signed_buffer: drop pbuf variable
If our caller gave us a non-NULL gpg_status parameter, we write the gpg status into their strbuf. If they didn't, then we write it to a temporary local strbuf (since we still need to look at it). The variable "pbuf" adds an extra layer of indirection so that the rest of the function can just access whichever is appropriate. However, the name "pbuf" isn't very descriptive, and it's easy to get confused about what is supposed to be in it (especially because we are reading both "status" and "output" from gpg). Rather than give it a more descriptive name, we can just use gpg_status as our indirection pointer. Either it points to the caller's input, or we can point it directly to our temporary buffer. Signed-off-by: Jeff King--- gpg-interface.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/gpg-interface.c b/gpg-interface.c index 0ed9fa7..216cad8 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -211,7 +211,6 @@ int verify_signed_buffer(const char *payload, size_t payload_size, char path[PATH_MAX]; int fd, ret; struct strbuf buf = STRBUF_INIT; - struct strbuf *pbuf = fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXX"); if (fd < 0) @@ -242,9 +241,9 @@ int verify_signed_buffer(const char *payload, size_t payload_size, strbuf_read(gpg_output, gpg.err, 0); close(gpg.err); } - if (gpg_status) - pbuf = gpg_status; - strbuf_read(pbuf, gpg.out, 0); + if (!gpg_status) + gpg_status = + strbuf_read(gpg_status, gpg.out, 0); close(gpg.out); ret = finish_command(); @@ -252,7 +251,7 @@ int verify_signed_buffer(const char *payload, size_t payload_size, unlink_or_warn(path); - ret |= !strstr(pbuf->buf, "\n[GNUPG:] GOODSIG "); + ret |= !strstr(gpg_status->buf, "\n[GNUPG:] GOODSIG "); strbuf_release(); /* no matter it was used or not */ return ret; -- 2.9.0.165.g4aacdc3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/7] gpg-interface: use child_process.args
Our argv allocations are relatively straightforward, but this avoids us having to manually keep the count up to date (or create new to-be-replaced slots in the declaration) when we add new arguments. Signed-off-by: Jeff King--- gpg-interface.c | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/gpg-interface.c b/gpg-interface.c index c4b1e8c..0ed9fa7 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -150,17 +150,15 @@ const char *get_signing_key(void) int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key) { struct child_process gpg = CHILD_PROCESS_INIT; - const char *args[4]; ssize_t len; size_t i, j, bottom; - gpg.argv = args; gpg.in = -1; gpg.out = -1; - args[0] = gpg_program; - args[1] = "-bsau"; - args[2] = signing_key; - args[3] = NULL; + argv_array_pushl(, +gpg_program, +"-bsau", signing_key, +NULL); if (start_command()) return error(_("could not run gpg.")); @@ -210,13 +208,11 @@ int verify_signed_buffer(const char *payload, size_t payload_size, struct strbuf *gpg_output, struct strbuf *gpg_status) { struct child_process gpg = CHILD_PROCESS_INIT; - const char *args_gpg[] = {NULL, "--status-fd=1", "--verify", "FILE", "-", NULL}; char path[PATH_MAX]; int fd, ret; struct strbuf buf = STRBUF_INIT; struct strbuf *pbuf = - args_gpg[0] = gpg_program; fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXX"); if (fd < 0) return error_errno(_("could not create temporary file '%s'"), path); @@ -224,12 +220,15 @@ int verify_signed_buffer(const char *payload, size_t payload_size, return error_errno(_("failed writing detached signature to '%s'"), path); close(fd); - gpg.argv = args_gpg; + argv_array_pushl(, +gpg_program, +"--status-fd=1", +"--verify", path, "-", +NULL); gpg.in = -1; gpg.out = -1; if (gpg_output) gpg.err = -1; - args_gpg[3] = path; if (start_command()) { unlink(path); return error(_("could not run gpg.")); -- 2.9.0.165.g4aacdc3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 0/7] gpg-interface cleanups
On Thu, Jun 16, 2016 at 05:32:48AM -0400, Jeff King wrote: > [1/7]: gpg-interface: use child_process.args > [2/7]: verify_signed_buffer: drop pbuf variable > [3/7]: verify_signed_buffer: use tempfile object > [4/7]: run-command: add pipe_command helper > [5/7]: verify_signed_buffer: use pipe_command > [6/7]: sign_buffer: use pipe_command > [7/7]: gpg-interface: check gpg signature creation status Here's a re-roll, fixing a few things in 4/7: - s/capture/pipe/ in the pipe_command docstring, from Eric - make internal pump_io functions static, from Ramsay and more importantly: - I screwed up the in-body "From:" in the final patch; Michael should be the author -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] run-command: mark file-local symbols static
On Fri, Jun 17, 2016 at 10:01:24PM +0100, Ramsay Jones wrote: > If you need to re-roll your 'jk/gpg-interface-cleanup' branch, could > you please squash this into the relevant patch (commit 74287e34, > "run-command: add pipe_command helper", 16-06-2016). Thanks, yes. > BTW, also on that branch, commit 6fec0a89 ("verify_signed_buffer: use > tempfile object", 16-06-2016) removes the last use of the git_mkstemp() > function. Should it be removed? I think so. We still have git_mkstemp_mode and friends, so in that sense this is part of a family of commands that somebody might use again. But: 1. Unlike the others in the family, where we implement mkstemp ourselves, this one uses the system mkstemp. Which probably behaves in totally the same way, but it's kind of weird and oddball. 2. I think we should be steering people towards tempfile.c anyway, for its auto-cleanup properties. Want to do a patch on top? -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 4/7] run-command: add pipe_command helper
On Fri, Jun 17, 2016 at 7:28 PM, Jeff Kingwrote: > On Fri, Jun 17, 2016 at 04:03:18PM -0400, Eric Sunshine wrote: >> > diff --git a/run-command.h b/run-command.h >> > @@ -79,17 +79,34 @@ int run_command_v_opt(const char **argv, int opt); >> > /** >> > - * Execute the given command, capturing its stdout in the given strbuf. >> > + * Execute the given command, sending "in" to its stdin, and capturing its >> > + * stdout and stderr in the "out" and "err" strbufs. Any of the three may >> > + * be NULL to skip processing. >> > + * >> > * Returns -1 if starting the command fails or reading fails, and >> > otherwise >> > - * returns the exit code of the command. The output collected in the >> > - * buffer is kept even if the command returns a non-zero exit. The hint >> > field >> > - * gives a starting size for the strbuf allocation. >> > + * returns the exit code of the command. Any output collected in the >> >> Did you mean s/returns/Returns/ ? > > I don't think so. This is a continuatino of "...and otherwise" from the > context line above. Indeed. I somehow imagined a leading '-' on the line containing "...and otherwise". -- To unsubscribe from this list: send the line "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 4/7] run-command: add pipe_command helper
On Fri, Jun 17, 2016 at 04:03:18PM -0400, Eric Sunshine wrote: > > diff --git a/run-command.h b/run-command.h > > @@ -79,17 +79,34 @@ int run_command_v_opt(const char **argv, int opt); > > /** > > - * Execute the given command, capturing its stdout in the given strbuf. > > + * Execute the given command, sending "in" to its stdin, and capturing its > > + * stdout and stderr in the "out" and "err" strbufs. Any of the three may > > + * be NULL to skip processing. > > + * > > * Returns -1 if starting the command fails or reading fails, and otherwise > > - * returns the exit code of the command. The output collected in the > > - * buffer is kept even if the command returns a non-zero exit. The hint > > field > > - * gives a starting size for the strbuf allocation. > > + * returns the exit code of the command. Any output collected in the > > Did you mean s/returns/Returns/ ? I don't think so. This is a continuatino of "...and otherwise" from the context line above. > > + * buffers is kept even if the command returns a non-zero exit. The hint > > fields > > + * gives starting sizes for the strbuf allocations. > > * > > * The fields of "cmd" should be set up as they would for a normal > > run_command > > - * invocation. But note that there is no need to set cmd->out; the function > > - * sets it up for the caller. > > + * invocation. But note that there is no need to set the in, out, or err > > + * fields; capture_command handles that automatically. > > s/capture_command/pipe_command/ Whoops, yes. -Peff -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 00/11] Fix icase grep on non-ascii
Nguyễn Thái Ngọc Duywrites: > v6 fixes comments from Ramsay and Eric. Interdiff below. Another thing I noticed with this is that the non-ascii test breaks when run under dash (but passes under bash). You need to have is_IS locale on the system to see the breakage, it seems (which is why I didn't see it so far). -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 0/4] clarify %f documentation
It's natural to expect %f to be an actual file on disk; help avoid that mistake. Signed-off-by: Joey Hess--- This patch series was meant to contain 5 patches; here's the missing one. This patch will apply cleanly on top of v2.9.0. Documentation/gitattributes.txt | 5 + 1 file changed, 5 insertions(+) diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index e3b1de8..145dd10 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -374,6 +374,11 @@ substitution. For example: smudge = git-p4-filter --smudge %f +Note that "%f" is the name of the path that is being worked on. Depending +on the version that is being filtered, the corresponding file on disk may +not exist, or may have different contents. So, smudge and clean commands +should not try to access the file on disk, but only act as filters on the +content provided to them on standard input. Interaction between checkin/checkout attributes ^^^ -- 2.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
Fwd: Re: [PATCH] hooks--pre-commit.sample: check for chars, that are not allowed for a windows file name
Am 15.06.2016 um 19:54 schrieb Junio C Hamano: > > dexteritaswrites: >> >> After the ASCII-check, test the windows compatibility of file names. >> Can be disabled by: git config hooks.allownonwindowschars true --- > > Missing sign off. Will be there next time. >> >> templates/hooks--pre-commit.sample | 22 ++ 1 file >> changed, 22 insertions(+) diff --git >> a/templates/hooks--pre-commit.sample >> b/templates/hooks--pre-commit.sample index 68d62d5..120daf1 100755 >> --- a/templates/hooks--pre-commit.sample +++ >> b/templates/hooks--pre-commit.sample @@ -17,6 +17,7 @@ fi # If you >> want to allow non-ASCII filenames set this variable to true. >> allownonascii=$(git config --bool hooks.allownonascii) >> +allownonwindowschars=$(git config --bool hooks.allownonwindowschars) >> # Redirect output to stderr. exec 1>&2 @@ -43,6 +44,27 @@ If you know >> what you are doing you can disable this check using: git config >> hooks.allownonascii true EOF exit 1 +elif [ "$allownonwindowschars" >> != "true" ] && > > This line is doubly irritating because (1) the double negation is > somewhat hard to grok, and (2) [] is not part of our CodingStyle. > Because you inherited this from the existing "allow-non-ascii" one, > however, I do not want to see you change this line, if you need to > reroll. ok >> >> + # If you work with linux and windows, there is a problem, if you >> use + # chars like \ / : * ? " < > | > > There is no reason to single out Linux, is there? This new check is > only about Windows and because people on other platforms, not limited > to Linux, may not be aware of some characters that are not usable on > Windows, you are trying to help them, no? You're right. Linux is just an example. > > >> >> + # Check if there are used only windows compatible chars + test >> $(git diff --cached --name-only --diff-filter=A -z $against | + >> LC_ALL=C tr -d '[0-9A-Za-z\[\]\{\}_ -)+-.]\0' | wc -c) != 0 > > Because this is in "elif", we know we are allowing non-ascii > characters when we come here. So you need to do a quite similar check > from scratch, which is sensible. I do not offhand know if this covers > all the characters that Windows users cannot use, though. Actually the first if checks: "$allownonascii" != "true" ] && test $(git diff --cached --name-only --diff-filter=A -z $against | LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 If we come to the elif, we either allow non-ascii characters or we don't allow them and they don't occur. Well, it covers the characters, but some reserved names and files with trailing period or space are missing, as Thomas Braun wrote before. >> >> +then + cat <<\EOF +Error: Attempt to add a chars that are not >> allowed for a windows file name. + +This can cause problems if you >> want to work with people on other platforms. + +To be portable it is >> advisable to rename the file. + +Check your filenames for: \ / : * ? >> " < > | + +If you know what you are doing you can disable this check >> using: + + git config hooks.allownonwindowschars true +EOF + exit 2 > > Why 2? Should be 1. >> >> fi # If there are whitespace errors, print the offending file names >> and fail. > > When the user says [hooks] allownonascii = false allownonwindowschars > = false what happens? The user's intention clearly is that the project > wants to be usable on Windows and also wants to exclude characters > from codepages that are not ASCII. I however suspect that the hook > with your patch will allow people to create a "path>like?this.txt" > happily. That would throw an error (on the check for nonwindowschars), because ">" and "?" are not inlcuded in the expression '[0-9A-Za-z\[\]\{\}_ -)+-.]\0'. This one also checks, if there are only ascii chars, because if allownonwindowschars = false, non-ascii should be excluded no matter what "allownonascii" was set to. It may follow a reroll sometime. -- To unsubscribe from this list: send the line "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 00/38] i18n and test updates
Junio C Hamanowrites: > Vasco Almeida writes: > >> Interdiff included below. >> >> Vasco Almeida (38): >> i18n: builtin/remote.c: fix mark for translation >> i18n: advice: mark string about detached head for translation >> i18n: advice: internationalize message for conflicts >> i18n: transport: mark strings for translation >> i18n: sequencer: mark entire sentences for translation >> i18n: sequencer: mark string for translation >> i18n: merge-octopus: mark messages for translation >> merge-octupus: use die shell function from git-sh-setup.sh > > octopus. > The last 5 patches seem to have been lost... > >> i18n: init-db: join message pieces >> i18n: submodule: join strings marked for translation >> i18n: submodule: escape shell variables inside eval_gettext >> i18n: unmark die messages for translation >> i18n: branch: mark comment when editing branch description for >> translation Now we see them ;-) Thanks. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] hooks--pre-commit.sample: check for chars, that are not allowed for a windows file name
Am 15.06.2016 um 13:15 schrieb Thomas Braun: > Am 15.06.2016 um 10:02 schrieb dexteritas: >> After the ASCII-check, test the windows compatibility of file names. >> Can be disabled by: >> git config hooks.allownonwindowschars true >> --- >> templates/hooks--pre-commit.sample | 22 ++ >> 1 file changed, 22 insertions(+) >> >> diff --git a/templates/hooks--pre-commit.sample >> b/templates/hooks--pre-commit.sample >> index 68d62d5..120daf1 100755 >> --- a/templates/hooks--pre-commit.sample >> +++ b/templates/hooks--pre-commit.sample >> @@ -17,6 +17,7 @@ fi >> >> # If you want to allow non-ASCII filenames set this variable to true. >> allownonascii=$(git config --bool hooks.allownonascii) >> +allownonwindowschars=$(git config --bool hooks.allownonwindowschars) >> >> # Redirect output to stderr. >> exec 1>&2 >> @@ -43,6 +44,27 @@ If you know what you are doing you can disable this check >> using: >>git config hooks.allownonascii true >> EOF >> exit 1 >> +elif [ "$allownonwindowschars" != "true" ] && >> +# If you work with linux and windows, there is a problem, if you use >> +# chars like \ / : * ? " < > | >> +# Check if there are used only windows compatible chars >> +test $(git diff --cached --name-only --diff-filter=A -z $against | >> + LC_ALL=C tr -d '[0-9A-Za-z\[\]\{\}_ -)+-.]\0' | wc -c) != 0 >> +then >> +cat <<\EOF >> +Error: Attempt to add a chars that are not allowed for a windows file name. >> + >> +This can cause problems if you want to work with people on other platforms. >> + >> +To be portable it is advisable to rename the file. >> + >> +Check your filenames for: \ / : * ? " < > | >> + >> +If you know what you are doing you can disable this check using: >> + >> + git config hooks.allownonwindowschars true >> +EOF >> +exit 2 >> fi >> >> # If there are whitespace errors, print the offending file names and fail. > There are some cases of illegal file names missing. E.g. reserved names, > trailing period and space. My trial with a precommit hook for avoiding > illegal filenames on windows can be found at [1]. Feel free to loot my > version for a reroll. > > [1]: > https://github.com/t-b/git-pre-commit-hook-windows-filenames/blob/master/pre-commit > You're right. Thanks for the example. -- To unsubscribe from this list: send the line "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 (Jun 2016, #05; Thu, 16)
Lars Schneiderwrites: >> On 17 Jun 2016, at 05:20, Junio C Hamano wrote: >> >> ... >> >> * mh/split-under-lock (2016-05-13) 33 commits >> (merged to 'next' on 2016-06-03 at 2e71330) >> + lock_ref_sha1_basic(): only handle REF_NODEREF mode >> + ... >> + t1404: demonstrate a bug resolving references >> (this branch is used by mh/ref-iterators, mh/ref-store and >> mh/update-ref-errors.) >> >> Further preparatory work on the refs API before the pluggable >> backend series can land. >> >> Will merge to 'master'. > > This topic seems break two git-p4 tests (t9801 and t9803) on next: > https://travis-ci.org/git/git/jobs/137333785 > > According to git bisect the commit "ref_transaction_update(): > check refname_is_safe() at a minimum" (3da1f3) introduces the problem: > https://s3.amazonaws.com/archive.travis-ci.org/jobs/138457628/log.txt > (scroll all the way down to see the bisecting) Thanks. Let's hold it and all of its dependents to see what is going on. -- To unsubscribe from this list: send the line "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 (Jun 2016, #05; Thu, 16)
> On 17 Jun 2016, at 05:20, Junio C Hamanowrote: > > ... > > * mh/split-under-lock (2016-05-13) 33 commits > (merged to 'next' on 2016-06-03 at 2e71330) > + lock_ref_sha1_basic(): only handle REF_NODEREF mode > + commit_ref_update(): remove the flags parameter > + lock_ref_for_update(): don't resolve symrefs > + lock_ref_for_update(): don't re-read non-symbolic references > + refs: resolve symbolic refs first > + ref_transaction_update(): check refname_is_safe() at a minimum > + unlock_ref(): move definition higher in the file > + lock_ref_for_update(): new function > + add_update(): initialize the whole ref_update > + verify_refname_available(): adjust constness in declaration > + refs: don't dereference on rename > + refs: allow log-only updates > + delete_branches(): use resolve_refdup() > + ref_transaction_commit(): correctly report close_ref() failure > + ref_transaction_create(): disallow recursive pruning > + refs: make error messages more consistent > + lock_ref_sha1_basic(): remove unneeded local variable > + read_raw_ref(): move docstring to header file > + read_raw_ref(): improve docstring > + read_raw_ref(): rename symref argument to referent > + read_raw_ref(): clear *type at start of function > + read_raw_ref(): rename flags argument to type > + ref_transaction_commit(): remove local variable n > + rename_ref(): remove unneeded local variable > + commit_ref_update(): write error message to *err, not stderr > + refname_is_safe(): insist that the refname already be normalized > + refname_is_safe(): don't allow the empty string > + refname_is_safe(): use skip_prefix() > + remove_dir_recursively(): add docstring > + safe_create_leading_directories(): improve docstring > + read_raw_ref(): don't get confused by an empty directory > + commit_ref(): if there is an empty dir in the way, delete it > + t1404: demonstrate a bug resolving references > (this branch is used by mh/ref-iterators, mh/ref-store and > mh/update-ref-errors.) > > Further preparatory work on the refs API before the pluggable > backend series can land. > > Will merge to 'master'. This topic seems break two git-p4 tests (t9801 and t9803) on next: https://travis-ci.org/git/git/jobs/137333785 According to git bisect the commit "ref_transaction_update(): check refname_is_safe() at a minimum" (3da1f3) introduces the problem: https://s3.amazonaws.com/archive.travis-ci.org/jobs/138457628/log.txt (scroll all the way down to see the bisecting) - Lars-- To unsubscribe from this list: send the line "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 v5 38/38] i18n: branch: mark comment when editing branch description for translation
When one issues git branch --edit-description branch_name, a edit with that message commented out is opened. Mark that message for translation in to order to be localized. Signed-off-by: Vasco Almeida--- builtin/branch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/builtin/branch.c b/builtin/branch.c index 2ecde53..12203fd 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -614,9 +614,9 @@ static int edit_branch_description(const char *branch_name) if (!buf.len || buf.buf[buf.len-1] != '\n') strbuf_addch(, '\n'); strbuf_commented_addf(, - "Please edit the description for the branch\n" - " %s\n" - "Lines starting with '%c' will be stripped.\n", + _("Please edit the description for the branch\n" + " %s\n" + "Lines starting with '%c' will be stripped.\n"), branch_name, comment_line_char); if (write_file_gently(git_path(edit_description), "%s", buf.buf)) { strbuf_release(); -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 34/38] i18n: init-db: join message pieces
Join message displayed during repository initialization in one entire sentence. That would improve translations since it's easier translate an entire sentence than translating each piece. Update Icelandic translation to reflect the changes. The Icelandic translation of these messages is used with test t0204-gettext-reencode-sanity.sh and not updating the translation would fail the test. Signed-off-by: Vasco Almeida--- builtin/init-db.c | 17 ++--- po/is.po | 46 -- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/builtin/init-db.c b/builtin/init-db.c index b2d8d40..3a45f0b 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -397,13 +397,16 @@ int init_db(const char *template_dir, unsigned int flags) if (!(flags & INIT_DB_QUIET)) { int len = strlen(git_dir); - /* TRANSLATORS: The first '%s' is either "Reinitialized - existing" or "Initialized empty", the second " shared" or - "", and the last '%s%s' is the verbatim directory name. */ - printf(_("%s%s Git repository in %s%s\n"), - reinit ? _("Reinitialized existing") : _("Initialized empty"), - get_shared_repository() ? _(" shared") : "", - git_dir, len && git_dir[len-1] != '/' ? "/" : ""); + if (reinit) + printf(get_shared_repository() + ? _("Reinitialized existing shared Git repository in %s%s\n") + : _("Reinitialized existing Git repository in %s%s\n"), + git_dir, len && git_dir[len-1] != '/' ? "/" : ""); + else + printf(get_shared_repository() + ? _("Initialized empty shared Git repository in %s%s\n") + : _("Initialized empty Git repository in %s%s\n"), + git_dir, len && git_dir[len-1] != '/' ? "/" : ""); } return 0; diff --git a/po/is.po b/po/is.po index 8692a8b..b8b34fd 100644 --- a/po/is.po +++ b/po/is.po @@ -7,14 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List \n" -"POT-Creation-Date: 2010-09-20 14:44+\n" -"PO-Revision-Date: 2010-06-05 19:06 +\n" -"Last-Translator: Ævar Arnfjörð Bjarmason \n" +"POT-Creation-Date: 2016-06-17 18:55+\n" +"PO-Revision-Date: 2016-06-17 19:17+\n" +"Last-Translator: Vasco Almeida \n" "Language-Team: Git Mailing List \n" "Language: is\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.5\n" #. TRANSLATORS: This is a test. You don't need to translate it. #: t/t0200/test.c:5 @@ -72,22 +73,31 @@ msgstr "TILRAUN: Perl tilraunastrengur" msgid "TEST: A Perl test variable %s" msgstr "TILRAUN: Perl tilraunastrengur með breytunni %s" -#. TRANSLATORS: The first '%s' is either "Reinitialized -#. existing" or "Initialized empty", the second " shared" or -#. "", and the last '%s%s' is the verbatim directory name. -#: builtin/init-db.c:355 +#: builtin/init-db.c:402 #, c-format -msgid "%s%s Git repository in %s%s\n" -msgstr "%s%s Git lind í %s%s\n" +msgid "Reinitialized existing shared Git repository in %s%s\n" +msgstr "Endurgerði Git lind í %s%s\n" -#: builtin/init-db.c:356 -msgid "Reinitialized existing" -msgstr "Endurgerði" +#: builtin/init-db.c:403 +#, c-format +msgid "Reinitialized existing Git repository in %s%s\n" +msgstr "Endurgerði Git lind í %s%s\n" + +#: builtin/init-db.c:407 +#, c-format +msgid "Initialized empty shared Git repository in %s%s\n" +msgstr "Bjó til tóma sameiginlega Git lind í %s%s\n" + +#: builtin/init-db.c:408 +#, c-format +msgid "Initialized empty Git repository in %s%s\n" +msgstr "Bjó til tóma Git lind í %s%s\n" + +#~ msgid "Reinitialized existing" +#~ msgstr "Endurgerði" -#: builtin/init-db.c:356 -msgid "Initialized empty" -msgstr "Bjó til tóma" +#~ msgid "Initialized empty" +#~ msgstr "Bjó til tóma" -#: builtin/init-db.c:357 -msgid " shared" -msgstr " sameiginlega" +#~ msgid " shared" +#~ msgstr " sameiginlega" -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 36/38] i18n: submodule: escape shell variables inside eval_gettext
According to the gettext manual [1], references to shell variables inside eval_gettext call must be escaped so that eval_gettext receives the translatable string before the variable values are substituted into it. [1] http://www.gnu.org/software/gettext/manual/html_node/Preparing-Shell-Scripts.html Signed-off-by: Vasco Almeida--- git-submodule.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/git-submodule.sh b/git-submodule.sh index f72b237..1ff2f3a 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -618,7 +618,7 @@ cmd_update() remote_name=$(sanitize_submodule_env; cd "$sm_path" && get_default_remote) sha1=$(sanitize_submodule_env; cd "$sm_path" && git rev-parse --verify "${remote_name}/${branch}") || - die "$(eval_gettext "Unable to find current ${remote_name}/${branch} revision in submodule path '\$sm_path'")" + die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")" fi if test "$subsha1" != "$sha1" || test -n "$force" @@ -642,7 +642,7 @@ cmd_update() # not be reachable from any of the refs is_tip_reachable "$sm_path" "$sha1" || fetch_in_submodule "$sm_path" "$sha1" || - die "$(eval_gettext "Fetched in submodule path '\$displaypath', but it did not contain $sha1. Direct fetching of that commit failed.")" + die "$(eval_gettext "Fetched in submodule path '\$displaypath', but it did not contain \$sha1. Direct fetching of that commit failed.")" fi must_die_on_failure= -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 37/38] i18n: unmark die messages for translation
These messages are relevant for the programmer only, not for the end user. Thus, they can be unmarked for translation, saving translator some work. Signed-off-by: Vasco Almeida--- git-bisect.sh | 2 +- wt-status.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/git-bisect.sh b/git-bisect.sh index 30d01bb..ae3cb01 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -274,7 +274,7 @@ bisect_state() { check_and_set_terms $state case "$#,$state" in 0,*) - die "$(gettext "Please call 'bisect_state' with at least one argument.")" ;; + die "Please call 'bisect_state' with at least one argument." ;; 1,"$TERM_BAD"|1,"$TERM_GOOD"|1,skip) bisected_head=$(bisect_head) rev=$(git rev-parse --verify "$bisected_head") || diff --git a/wt-status.c b/wt-status.c index 4f27bd6..5a91279 100644 --- a/wt-status.c +++ b/wt-status.c @@ -263,7 +263,7 @@ static const char *wt_status_unmerged_status_string(int stagemask) case 7: return _("both modified:"); default: - die(_("bug: unhandled unmerged status %x"), stagemask); + die("bug: unhandled unmerged status %x", stagemask); } } @@ -388,7 +388,7 @@ static void wt_status_print_change_data(struct wt_status *s, status_printf(s, color(WT_STATUS_HEADER, s), "\t"); what = wt_status_diff_status_string(status); if (!what) - die(_("bug: unhandled diff status %c"), status); + die("bug: unhandled diff status %c", status); len = label_width - utf8_strwidth(what); assert(len >= 0); if (status == DIFF_STATUS_COPIED || status == DIFF_STATUS_RENAMED) -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 35/38] i18n: submodule: join strings marked for translation
Join strings marked for translation since that would facilitate and improve translations result. Signed-off-by: Vasco Almeida--- git-submodule.sh | 18 ++ 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/git-submodule.sh b/git-submodule.sh index 5b9674a..f72b237 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -239,14 +239,15 @@ Use -f if you really want to add it." >&2 then if test -z "$force" then - echo >&2 "$(eval_gettext "A git directory for '\$sm_name' is found locally with remote(s):")" + eval_gettextln >&2 "A git directory for '\$sm_name' is found locally with remote(s):" GIT_DIR=".git/modules/$sm_name" GIT_WORK_TREE=. git remote -v | grep '(fetch)' | sed -e s,^," ", -e s,' (fetch)',, >&2 - echo >&2 "$(eval_gettext "If you want to reuse this local git directory instead of cloning again from")" - echo >&2 " $realrepo" - echo >&2 "$(eval_gettext "use the '--force' option. If the local git directory is not the correct repo")" - die "$(eval_gettext "or you are unsure what this means choose another name with the '--name' option.")" + die "$(eval_gettextln "\ +If you want to reuse this local git directory instead of cloning again from + \$realrepo +use the '--force' option. If the local git directory is not the correct repo +or you are unsure what this means choose another name with the '--name' option.")" else - echo "$(eval_gettext "Reactivating local git directory for submodule '\$sm_name'.")" + eval_gettextln "Reactivating local git directory for submodule '\$sm_name'." fi fi git submodule--helper clone ${GIT_QUIET:+--quiet} --prefix "$wt_prefix" --path "$sm_path" --name "$sm_name" --url "$realrepo" ${reference:+"$reference"} ${depth:+"$depth"} || exit @@ -437,8 +438,9 @@ cmd_deinit() # Protect submodules containing a .git directory if test -d "$sm_path/.git" then - echo >&2 "$(eval_gettext "Submodule work tree '\$displaypath' contains a .git directory")" - die "$(eval_gettext "(use 'rm -rf' if you really want to remove it including all of its history)")" + die "$(eval_gettext "\ +Submodule work tree '\$displaypath' contains a .git directory +(use 'rm -rf' if you really want to remove it including all of its history)")" fi if test -z "$force" -- 2.6.6 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 01/11] grep: allow -F -i combination
Nguyễn Thái Ngọc Duywrites: > -F means "no regex", not "case sensitive" so it should not override -i That logic is flawed, isn't it? "-F" means "no regex", so it should not touch opt.regflags at all. > Signed-off-by: Nguyễn Thái Ngọc Duy > --- > builtin/grep.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/builtin/grep.c b/builtin/grep.c > index 5526fd7..4be0df5 100644 > --- a/builtin/grep.c > +++ b/builtin/grep.c > @@ -809,7 +809,7 @@ int cmd_grep(int argc, const char **argv, const char > *prefix) > > if (!opt.pattern_list) > die(_("no pattern given.")); > - if (!opt.fixed && opt.ignore_case) > + if (opt.ignore_case) > opt.regflags |= REG_ICASE; > > compile_grep_patterns(); In grep.c, we do this: static void compile_regexp(struct grep_pat *p, struct grep_opt *opt) { int err; p->word_regexp = opt->word_regexp; p->ignore_case = opt->ignore_case; if (opt->fixed || is_fixed(p->pattern, p->patternlen)) p->fixed = 1; else p->fixed = 0; if (p->fixed) { if (opt->regflags & REG_ICASE || p->ignore_case) p->kws = kwsalloc(tolower_trans_tbl); else It is possible that your later changes _depend_ on having REG_ICASE set in opt->regflags, but if that is why this commit is needed, then you are going in a wrong direction. I liked the overall objective of making "-i" work better on non-ASCII, and I wanted to like this whole series, but at least this change needs to be dropped (and the remainder of the series fixed if they depend on this change). Thanks. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v12 11/20] index-helper: use watchman to avoid refreshing index with lstat()
> > - if (really && cache_errno == EINVAL) { > > + if (really || cache_errno == EINVAL) { > > /* If we are doing --really-refresh that > > * means the index is not valid anymore. > > */ > > This looks really odd. I don't see why we would need this. It seems > first appeared in your "do not apply" patch [1]. Maybe leftover? > > I found this while re-reading the series and I have not put much time > in studying this code yet. So I may be wrong. I'll post again if I > find that it's true after some more staring. I don't remember the exact details here, but I think we needed this so that we would ever refresh a file that watchman told us had been modified. We definitely were missing some invalidation if we didn't have it. P.S. Please CC nova...@novalis.org on these emails as I don't always check the git mailing list. P.P.S. I am testing out using emacs to send this message, so if it ends up screwed up, I apologize. Date: Fri, 17 Jun 2016 17:38:03 -0400 Message-ID: <874m8r1op0@novalis.org> -- To unsubscribe from this list: send the line "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 00/38] i18n and test updates
Vasco Almeidawrites: > Interdiff included below. > > Vasco Almeida (38): > i18n: builtin/remote.c: fix mark for translation > i18n: advice: mark string about detached head for translation > i18n: advice: internationalize message for conflicts > i18n: transport: mark strings for translation > i18n: sequencer: mark entire sentences for translation > i18n: sequencer: mark string for translation > i18n: merge-octopus: mark messages for translation > merge-octupus: use die shell function from git-sh-setup.sh octopus. > i18n: rebase: fix marked string to use eval_gettext variant > i18n: rebase: mark placeholder for translation > i18n: bisect: simplify error message for i18n > t6030: update to use test_i18ncmp > i18n: git-sh-setup.sh: mark strings for translation > i18n: rebase-interactive: mark strings for translation > i18n: rebase-interactive: mark here-doc strings for translation > i18n: rebase-interactive: mark comments of squash for translation > i18n: setup: mark strings for translation > tests: use test_i18n* functions to suppress false positives > tests: unpack-trees: update to use test_i18n* functions > t9003: become resilient to GETTEXT_POISON > t4153: fix negated test_i18ngrep call > t5523: use test_i18ngrep for negation > i18n: bisect: mark strings for translation > i18n: transport-helper.c: change N_() call to _() > i18n: notes: mark strings for translation > i18n: notes: mark options for translation > i18n: config: unfold error messages marked for translation > i18n: merge: mark messages for translation > i18n: merge: change command option help to lowercase > i18n: sequencer: add period to error message > i18n: standardise messages > i18n: remote: mark URL fallback text for translation > i18n: remote: allow translations to reorder message The last 5 patches seem to have been lost... > i18n: init-db: join message pieces > i18n: submodule: join strings marked for translation > i18n: submodule: escape shell variables inside eval_gettext > i18n: unmark die messages for translation > i18n: branch: mark comment when editing branch description for > translation > > Makefile | 5 +- > advice.c | 23 ++- > bisect.c | 56 --- > builtin/apply.c | 6 +- > builtin/branch.c | 6 +- > builtin/checkout.c| 6 +- > builtin/init-db.c | 17 +- > builtin/merge.c | 12 +- > builtin/notes.c | 24 +-- > builtin/pull.c| 2 +- > builtin/remote.c | 19 ++- > builtin/repack.c | 2 +- > cache.h | 9 +- > config.c | 101 ++-- > git-bisect.sh | 8 +- > git-merge-octopus.sh | 23 ++- > git-rebase--interactive.sh| 290 > -- > git-rebase.sh | 5 +- > git-sh-i18n.sh| 18 +++ > git-sh-setup.sh | 63 ++-- > git-stash.sh | 1 - > git-submodule.sh | 23 +-- > po/is.po | 46 +++--- > sequencer.c | 15 +- > setup.c | 16 +- > submodule-config.c| 2 +- > t/lib-rebase.sh | 1 + > t/t0008-ignores.sh| 4 +- > t/t1011-read-tree-sparse-checkout.sh | 2 +- > t/t1300-repo-config.sh| 8 +- > t/t1307-config-blob.sh| 5 +- > t/t1308-config-set.sh | 4 +- > t/t1400-update-ref.sh | 2 +- > t/t1506-rev-parse-diagnosis.sh| 2 +- > t/t2010-checkout-ambiguous.sh | 2 +- > t/t2018-checkout-branch.sh| 2 +- > t/t3200-branch.sh | 6 +- > t/t3201-branch-contains.sh| 2 +- > t/t3310-notes-merge-manual-resolve.sh | 8 +- > t/t3320-notes-merge-worktrees.sh | 4 +- > t/t3400-rebase.sh | 4 +- > t/t3404-rebase-interactive.sh | 18 +-- > t/t4153-am-resume-override-opts.sh| 2 +- > t/t4208-log-magic-pathspec.sh | 4 +- > t/t5505-remote.sh | 2 +- > t/t5510-fetch.sh | 2 +- > t/t5520-pull.sh | 2 +- > t/t5523-push-upstream.sh | 12 +- > t/t5536-fetch-conflicts.sh| 4 +- > t/t6030-bisect-porcelain.sh | 26 +-- > t/t6301-for-each-ref-errors.sh| 10 +- > t/t7063-status-untracked-cache.sh | 2 +- > t/t7102-reset.sh | 4 +- > t/t7201-co.sh | 2 +- >
Re: [PATCH v2 0/4] extend smudge/clean filters with direct file access
Joey Hesswrites: > Reroll of this patch set with changes: ... where is this 4-patch series designed to apply? The first one already fails... Applying: add smudgeToFile and cleanFromFile filter configs .git/rebase-apply/patch:28: trailing whitespace. Similar to filter..clean but the specified command .git/rebase-apply/patch:30: trailing whitespace. receiving the file content from standard input. .git/rebase-apply/patch:129: indent with spaces. struct strbuf *dst, const char *cmd) fatal: sha1 information is lacking or useless (Documentation/gitattributes.txt). error: could not build fake ancestor Patch failed at 0001 add smudgeToFile and cleanFromFile filter configs The copy of the patch that failed is found in: .git/rebase-apply/patch When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort". > > * Renamed the new filter drivers for consistency with other configs. > * Improved documentation with feedback from Junio and others. > * Eliminated %p and instead append the filename to the commands > (separated by a space). > * Fixed an FD leak and a space leak. > * Only use smudgeToFile with regular files, not symlinks. > * After running the smudgeToFile command, double-check that the > expected file is present, in case the command was buggy and deleted it. > * Added a warning message when the new filter commands are configured > but the old ones are not, so that the user knows it's refusing to use > their configuration. > > There's been good and helpful documentation and interface review, > but some more code review would be good! Also, git-annex has a > improved-smudge-filters branch now that demonstrates this interface. > > Joey Hess (4): > add smudgeToFile and cleanFromFile filter configs > use cleanFromFile in git add > use smudgeToFile in git checkout etc > warn on unusable smudgeToFile/cleanFromFile config > > Documentation/config.txt| 18 +- > Documentation/gitattributes.txt | 37 > convert.c | 126 > +++- > convert.h | 10 > entry.c | 37 +--- > sha1_file.c | 42 -- > t/t0021-conversion.sh | 64 > 7 files changed, 304 insertions(+), 30 deletions(-) -- To unsubscribe from this list: send the line "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] archive-tar: add UL type suffix to unsigned long constant
Signed-off-by: Ramsay Jones--- Hi Jeff, If you need to re-roll your 'jk/big-and-old-archive-tar' branch, could you please squash this into the relevant patch (commit 8035a1e3, "archive-tar: write extended headers for far-future mtime", 16-06-2016). Thanks! ATB, Ramsay Jones archive-tar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archive-tar.c b/archive-tar.c index 749722f..c7b85fd 100644 --- a/archive-tar.c +++ b/archive-tar.c @@ -187,7 +187,7 @@ static inline unsigned long ustar_size(uintmax_t size) static inline unsigned long ustar_mtime(time_t mtime) { - if (mtime < 0777) + if (mtime < 0777UL) return mtime; else return 0; -- 2.9.0 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 0/4] extend smudge/clean filters with direct file access
Doing a quick benchmark of this new interface and git-annex's use of it, git checkout of a 1 gigabyte file with git-annex providing the smudge filter took: 19 seconds using the smudge interface 11 seconds using smudgeToFile 0.1 seconds with smudgeToFile and annex.thin set (while also saving 1 gb of disk space!) So around 2x speed improvement due to not needing to pipe the file content through the filter, even without git-annex's annex.thin tricks. -- see shy jo signature.asc Description: PGP signature
[PATCH] run-command: mark file-local symbols static
Signed-off-by: Ramsay Jones--- Hi Jeff, If you need to re-roll your 'jk/gpg-interface-cleanup' branch, could you please squash this into the relevant patch (commit 74287e34, "run-command: add pipe_command helper", 16-06-2016). BTW, also on that branch, commit 6fec0a89 ("verify_signed_buffer: use tempfile object", 16-06-2016) removes the last use of the git_mkstemp() function. Should it be removed? Thanks! ATB, Ramsay Jones run-command.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/run-command.c b/run-command.c index 609fa4c..33bc63a 100644 --- a/run-command.c +++ b/run-command.c @@ -886,7 +886,7 @@ struct io_pump { struct pollfd *pfd; }; -int pump_io_round(struct io_pump *slots, int nr, struct pollfd *pfd) +static int pump_io_round(struct io_pump *slots, int nr, struct pollfd *pfd) { int pollsize = 0; int i; @@ -950,7 +950,7 @@ int pump_io_round(struct io_pump *slots, int nr, struct pollfd *pfd) return 1; } -int pump_io(struct io_pump *slots, int nr) +static int pump_io(struct io_pump *slots, int nr) { struct pollfd *pfd; int i; -- 2.9.0 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/4] use smudgeToFile in git checkout etc
This makes git checkout, git reset, etc use smudgeToFile. Includes test cases. (There's a call to convert_to_working_tree in merge-recursive.c that could also be made to use smudgeToFile as well.) Signed-off-by: Joey Hess--- entry.c | 37 + t/t0021-conversion.sh | 38 +- 2 files changed, 62 insertions(+), 13 deletions(-) diff --git a/entry.c b/entry.c index 519e042..97975e5 100644 --- a/entry.c +++ b/entry.c @@ -175,8 +175,13 @@ static int write_entry(struct cache_entry *ce, /* * Convert from git internal format to working tree format +* unless the smudgeToFile filter can write to the +* file directly. */ - if (ce_mode_s_ifmt == S_IFREG && + int regular_file = ce_mode_s_ifmt == S_IFREG; + int smudge_to_file = regular_file + && can_smudge_to_file(ce->name); + if (regular_file && ! smudge_to_file && convert_to_working_tree(ce->name, new, size, )) { free(new); new = strbuf_detach(, ); @@ -189,13 +194,29 @@ static int write_entry(struct cache_entry *ce, return error_errno("unable to create file %s", path); } - wrote = write_in_full(fd, new, size); - if (!to_tempfile) - fstat_done = fstat_output(fd, state, ); - close(fd); - free(new); - if (wrote != size) - return error("unable to write file %s", path); + if (! smudge_to_file) { + wrote = write_in_full(fd, new, size); + if (!to_tempfile) + fstat_done = fstat_output(fd, state, ); + close(fd); + free(new); + if (wrote != size) + return error("unable to write file %s", path); + } + else { + close(fd); + convert_to_working_tree_filter_to_file(ce->name, path, new, size); + free(new); + /* The smudgeToFile filter may have replaced the +* file; open it to make sure that the file +* exists. */ + fd = open(path, O_RDONLY); + if (fd < 0) + return error_errno("unable to create file %s", path); + if (!to_tempfile) + fstat_done = fstat_output(fd, state, ); + close(fd); + } break; case S_IFGITLINK: if (to_tempfile) diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh index 399f92b..a8042d1 100755 --- a/t/t0021-conversion.sh +++ b/t/t0021-conversion.sh @@ -14,12 +14,20 @@ chmod +x rot13.sh cat "\$destfile" +EOF +chmod +x rot13-to-file.sh + test_expect_success setup ' git config filter.rot13.smudge ./rot13.sh && git config filter.rot13.clean ./rot13.sh && @@ -291,6 +299,17 @@ test_expect_success 'cleanFromFile filter is used when adding a file' ' cmp test.t fstest.t ' +test_expect_success 'smudgeToFile filter is used when checking out a file' ' + test_config filter.rot13.smudgeToFile ./rot13-to-file.sh && + + rm -f fstest.t && + git checkout -- fstest.t && + cmp test.t fstest.t && + + test -e rot13-to-file.ran && + rm -f rot13-to-file.ran +' + test_expect_success 'cleanFromFile filter is not used when clean filter is not configured' ' test_config filter.noclean.smudge ./rot13.sh && test_config filter.noclean.cleanFromFile ./rot13-from-file.sh && @@ -299,9 +318,18 @@ test_expect_success 'cleanFromFile filter is not used when clean filter is not c cat test.t >test.no && git add test.no && - test ! -e rot13-from-file.ran && - git cat-file blob :test.no >actual && - cmp test.t actual + test ! -e rot13-from-file.ran +' + +test_expect_success 'smudgeToFile filter is not used when smudge filter is not configured' ' + test_config filter.nosmudge.clean ./rot13.sh && + test_config filter.nosmudge.smudgeToFile ./rot13-to-file.sh && + + echo "*.no filter=nosmudge" >.gitattributes && + + rm -f fstest.t && + git checkout -- fstest.t && + test ! -e rot13-to-file.ran ' test_done -- 2.8.1 -- To unsubscribe from this
[PATCH v2 1/4] add smudgeToFile and cleanFromFile filter configs
This adds new smudgeToFile and cleanFromFile filter commands, which are similar to smudge and clean but allow direct access to files on disk. This interface can be much more efficient when operating on large files, because the whole file content does not need to be streamed through the filter. It even allows for things like cleanFromFile commands that avoid reading the whole content of the file, and for smudgeToFile commands that populate a work tree file using an efficient Copy On Write operation. The new filter commands will not be used for all filtering. They are efficient to use when git add is adding a file, or when the work tree is being updated, but not a good fit when git is internally filtering blob objects in memory for eg, a diff. So, a user who wants to use smudgeToFile should also provide a smudge command to be used in cases where smudgeToFile is not used. And ditto with cleanFromFile and clean. To avoid foot-shooting configurations, the new commands are not used unless the old commands are also configured. That also ensures that a filter driver configuration that includes these new commands will work, although less efficiently, when used with an older version of git that does not support them. Signed-off-by: Joey Hess--- Documentation/config.txt| 18 ++- Documentation/gitattributes.txt | 37 ++ convert.c | 108 ++-- convert.h | 10 4 files changed, 157 insertions(+), 16 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 2e1b2e4..38f54c1 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1299,15 +1299,29 @@ format.useAutoBase:: format-patch by default. filter..clean:: - The command which is used to convert the content of a worktree + The command which is used as a filter to convert the content of a worktree file to a blob upon checkin. See linkgit:gitattributes[5] for details. filter..smudge:: - The command which is used to convert the content of a blob + The command which is used as a filter to convert the content of a blob object to a worktree file upon checkout. See linkgit:gitattributes[5] for details. +filter..cleanFromFile:: + Similar to filter..clean but the specified command + directly accesses a worktree file on disk, rather than + receiving the file content from standard input. + Only used when filter..clean is also configured. + See linkgit:gitattributes[5] for details. + +filter..smudgeToFile:: + Similar to filter..smudge but the specified command + writes the content of a blob directly to a worktree file, + rather than to standard output. + Only used when filter..smudge is also configured. + See linkgit:gitattributes[5] for details. + fsck.:: Allows overriding the message type (error, warn or ignore) of a specific message ID such as `missingEmail`. diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index 145dd10..5ae0783 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -380,6 +380,43 @@ not exist, or may have different contents. So, smudge and clean commands should not try to access the file on disk, but only act as filters on the content provided to them on standard input. +There are two extra commands "cleanFromFile" and "smudgeToFile", which +can optionally be set in a filter driver. These are similar to the "clean" +and "smudge" commands, but avoid needing to pipe the contents of files +through the filters, and instead read/write files in the filesystem. +This can be more efficient when using filters with large files that are not +directly stored in the repository. + +Both "cleanFromFile" and "smudgeToFile" are provided a path as an +added parameter after the configured command line. + +The "cleanFromFile" command is provided the path to the file that +it should clean. Like the "clean" command, it should output the cleaned +version to standard output. + +The "smudgeToFile" command is provided a path to the file that it +should write to. (This file will already exist, as an empty file that can +be written to or replaced.) Like the "smudge" command, "smudgeToFile" +is fed the blob object from its standard input. + +Some git operations that need to apply filters cannot use "cleanFromFile" +and "smudgeToFile", since the files are not present to disk. So, to avoid +inconsistent behavior, "cleanFromFile" will only be used if "clean" is +also configured, and "smudgeToFile" will only be used if "smudge" is also +configured. + +An example large file storage filter driver using cleanFromFile and +smudgeToFile follows: + + +[filter "bigfiles"] + clean = store-bigfile --from-stdin + cleanFromFile = store-bigfile --from-file + smudge =
[PATCH v2 4/4] warn on unusable smudgeToFile/cleanFromFile config
Let the user know when they have a smudgeToFile/cleanFromFile config that cannot be used because the corresponding smudge/clean config is missing. The warning is only displayed a maximum of once per git invocation, and only when doing an operation that would use the filter. Signed-off-by: Joey Hess--- convert.c | 34 ++ 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/convert.c b/convert.c index bf63ba0..84f6bc5 100644 --- a/convert.c +++ b/convert.c @@ -847,32 +847,50 @@ int would_convert_to_git_filter_fd(const char *path) return apply_filter(path, NULL, NULL, 0, -1, NULL, ca.drv->clean); } +static int can_filter_file(const char *filefilter, const char *filefiltername, + const char *stdiofilter, const char *stdiofiltername, + const struct conv_attrs *ca, + int *warncount) +{ + if (! filefilter) + return 0; + + if (stdiofilter) + return 1; + + if (*warncount == 0) + warning("Not running your configured filter.%s.%s command, because filter.%s.%s is not configured", + ca->drv->name, filefiltername, + ca->drv->name, stdiofiltername); + *warncount=*warncount+1; + + return 0; +} + int can_clean_from_file(const char *path) { struct conv_attrs ca; + static int warncount = 0; convert_attrs(, path); if (!ca.drv) return 0; - /* Only use the cleanFromFile filter when the clean filter is also -* configured. -*/ - return (ca.drv->clean_from_file && ca.drv->clean); + return can_filter_file(ca.drv->clean_from_file, "cleanFromFile", + ca.drv->clean, "clean", , ); } int can_smudge_to_file(const char *path) { struct conv_attrs ca; + static int warncount = 0; convert_attrs(, path); if (!ca.drv) return 0; - /* Only use the smudgeToFile filter when the smudge filter is also -* configured. -*/ - return (ca.drv->smudge_to_file && ca.drv->smudge); + return can_filter_file(ca.drv->smudge_to_file, "smudgeToFile", + ca.drv->smudge, "smudge", , ); } const char *get_convert_attr_ascii(const char *path) -- 2.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 v2 2/4] use cleanFromFile in git add
Includes test cases. Signed-off-by: Joey Hess--- sha1_file.c | 42 -- t/t0021-conversion.sh | 36 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index d5e1121..8df86a0 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -3329,6 +3329,29 @@ static int index_stream_convert_blob(unsigned char *sha1, int fd, return ret; } +static int index_from_file_convert_blob(unsigned char *sha1, + const char *path, unsigned flags) +{ + int ret; + const int write_object = flags & HASH_WRITE_OBJECT; + struct strbuf sbuf = STRBUF_INIT; + + assert(path); + assert(can_clean_from_file(path)); + + convert_to_git_filter_from_file(path, , +write_object ? safe_crlf : SAFE_CRLF_FALSE); + + if (write_object) + ret = write_sha1_file(sbuf.buf, sbuf.len, typename(OBJ_BLOB), + sha1); + else + ret = hash_sha1_file(sbuf.buf, sbuf.len, typename(OBJ_BLOB), +sha1); + strbuf_release(); + return ret; +} + static int index_pipe(unsigned char *sha1, int fd, enum object_type type, const char *path, unsigned flags) { @@ -3421,12 +3444,19 @@ int index_path(unsigned char *sha1, const char *path, struct stat *st, unsigned switch (st->st_mode & S_IFMT) { case S_IFREG: - fd = open(path, O_RDONLY); - if (fd < 0) - return error_errno("open(\"%s\")", path); - if (index_fd(sha1, fd, st, OBJ_BLOB, path, flags) < 0) - return error("%s: failed to insert into database", -path); + if (can_clean_from_file(path)) { + if (index_from_file_convert_blob(sha1, path, flags) < 0) + return error("%s: failed to insert into database", +path); + } + else { + fd = open(path, O_RDONLY); + if (fd < 0) + return error_errno("open(\"%s\")", path); + if (index_fd(sha1, fd, st, OBJ_BLOB, path, flags) < 0) + return error("%s: failed to insert into database", +path); + } break; case S_IFLNK: if (strbuf_readlink(, path, st->st_size)) diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh index 7bac2bc..399f92b 100755 --- a/t/t0021-conversion.sh +++ b/t/t0021-conversion.sh @@ -12,6 +12,14 @@ tr \ EOF chmod +x rot13.sh +cat .gitattributes && + + cat test.t >fstest.t && + git add fstest.t && + test -e rot13-from-file.ran && + rm -f rot13-from-file.ran && + + rm -f fstest.t && + git checkout -- fstest.t && + cmp test.t fstest.t +' + +test_expect_success 'cleanFromFile filter is not used when clean filter is not configured' ' + test_config filter.noclean.smudge ./rot13.sh && + test_config filter.noclean.cleanFromFile ./rot13-from-file.sh && + + echo "*.no filter=noclean" >.gitattributes && + + cat test.t >test.no && + git add test.no && + test ! -e rot13-from-file.ran && + git cat-file blob :test.no >actual && + cmp test.t actual +' + test_done -- 2.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 v2 0/4] extend smudge/clean filters with direct file access
Reroll of this patch set with changes: * Renamed the new filter drivers for consistency with other configs. * Improved documentation with feedback from Junio and others. * Eliminated %p and instead append the filename to the commands (separated by a space). * Fixed an FD leak and a space leak. * Only use smudgeToFile with regular files, not symlinks. * After running the smudgeToFile command, double-check that the expected file is present, in case the command was buggy and deleted it. * Added a warning message when the new filter commands are configured but the old ones are not, so that the user knows it's refusing to use their configuration. There's been good and helpful documentation and interface review, but some more code review would be good! Also, git-annex has a improved-smudge-filters branch now that demonstrates this interface. Joey Hess (4): add smudgeToFile and cleanFromFile filter configs use cleanFromFile in git add use smudgeToFile in git checkout etc warn on unusable smudgeToFile/cleanFromFile config Documentation/config.txt| 18 +- Documentation/gitattributes.txt | 37 convert.c | 126 +++- convert.h | 10 entry.c | 37 +--- sha1_file.c | 42 -- t/t0021-conversion.sh | 64 7 files changed, 304 insertions(+), 30 deletions(-) -- 2.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 v5 32/38] i18n: remote: mark URL fallback text for translation
Marks fallback text for translation that may be displayed in git remote show output. Signed-off-by: Vasco Almeida--- builtin/remote.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/builtin/remote.c b/builtin/remote.c index ae74da6..9f934cb 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -1158,11 +1158,11 @@ static int show(int argc, const char **argv) the one in " Fetch URL: %s" translation */ printf_ln(_(" Push URL: %s"), url[i]); if (!i) - printf_ln(_(" Push URL: %s"), "(no URL)"); + printf_ln(_(" Push URL: %s"), _("(no URL)")); if (no_query) - printf_ln(_(" HEAD branch: %s"), "(not queried)"); + printf_ln(_(" HEAD branch: %s"), _("(not queried)")); else if (!states.heads.nr) - printf_ln(_(" HEAD branch: %s"), "(unknown)"); + printf_ln(_(" HEAD branch: %s"), _("(unknown)")); else if (states.heads.nr == 1) printf_ln(_(" HEAD branch: %s"), states.heads.items[0].string); else { -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 27/38] i18n: config: unfold error messages marked for translation
Introduced in 473166b ("config: add 'origin_type' to config_source struct", 2016-02-19), Git can inform the user about the origin of a config error, but the implementation does not allow translators to translate the keywords 'file', 'blob, 'standard input', and 'submodule-blob'. Moreover, for the second message, a reason for the error is appended to the message, not allowing translators to translate that reason either. Unfold the message into several templates for each known origin_type. That would result in better translation at the expense of code verbosity. Add enum git_config_oringin_type to ease management of the various configuration origin types (blob, file, etc). For the first instance, use xstrfmt() function to prepare the message string, instead of doing something like it's done for the second one, because intelligibility and code conciseness are improved for that instance. Signed-off-by: Vasco Almeida--- cache.h| 9 - config.c | 101 - submodule-config.c | 2 +- 3 files changed, 94 insertions(+), 18 deletions(-) diff --git a/cache.h b/cache.h index 6049f86..4bded9a 100644 --- a/cache.h +++ b/cache.h @@ -1559,10 +1559,17 @@ struct git_config_source { const char *blob; }; +enum git_config_origin_type { + CFG_BLOB, + CFG_FILE, + CFG_STDIN, + CFG_SUBMODULE_BLOB +}; + typedef int (*config_fn_t)(const char *, const char *, void *); extern int git_default_config(const char *, const char *, void *); extern int git_config_from_file(config_fn_t fn, const char *, void *); -extern int git_config_from_mem(config_fn_t fn, const char *origin_type, +extern int git_config_from_mem(config_fn_t fn, const enum git_config_origin_type, const char *name, const char *buf, size_t len, void *data); extern void git_config_push_parameter(const char *text); extern int git_config_from_parameters(config_fn_t fn, void *data); diff --git a/config.c b/config.c index f51c56b..e86f0aa 100644 --- a/config.c +++ b/config.c @@ -24,7 +24,7 @@ struct config_source { size_t pos; } buf; } u; - const char *origin_type; + enum git_config_origin_type origin_type; const char *name; const char *path; int die_on_error; @@ -417,6 +417,8 @@ static int git_parse_source(config_fn_t fn, void *data) int comment = 0; int baselen = 0; struct strbuf *var = >var; + int error_return = 0; + char *error_msg = NULL; /* U+FEFF Byte Order Mark in UTF8 */ const char *bomptr = utf8_bom; @@ -471,10 +473,36 @@ static int git_parse_source(config_fn_t fn, void *data) if (get_value(fn, data, var) < 0) break; } + + switch (cf->origin_type) { + case CFG_BLOB: + error_msg = xstrfmt(_("bad config line %d in blob %s"), + cf->linenr, cf->name); + break; + case CFG_FILE: + error_msg = xstrfmt(_("bad config line %d in file %s"), + cf->linenr, cf->name); + break; + case CFG_STDIN: + error_msg = xstrfmt(_("bad config line %d in standard input"), + cf->linenr); + break; + case CFG_SUBMODULE_BLOB: + error_msg = xstrfmt(_("bad config line %d in submodule-blob %s"), + cf->linenr, cf->name); + break; + default: + error_msg = xstrfmt(_("bad config line %d in %s"), + cf->linenr, cf->name); + } + if (cf->die_on_error) - die(_("bad config line %d in %s %s"), cf->linenr, cf->origin_type, cf->name); + die(error_msg); else - return error(_("bad config line %d in %s %s"), cf->linenr, cf->origin_type, cf->name); + error_return = error(error_msg); + + free(error_msg); + return error_return; } static int parse_unit_factor(const char *end, uintmax_t *val) @@ -583,16 +611,42 @@ int git_parse_ulong(const char *value, unsigned long *ret) NORETURN static void die_bad_number(const char *name, const char *value) { - const char *reason = errno == ERANGE ? -"out of range" : -"invalid unit"; if (!value) value = ""; - if (cf && cf->origin_type && cf->name) - die(_("bad numeric config value '%s' for '%s' in %s %s: %s"), - value, name, cf->origin_type, cf->name, reason); - die(_("bad numeric config value '%s' for '%s': %s"), value, name, reason); + if (!(cf && cf->name)) + die(errno == ERANGE + ? _("bad numeric config value
[PATCH v5 10/38] i18n: rebase: mark placeholder for translation
Mark placeholder "" in git-rebase.sh for translation. The string containing the named placeholder is passed to shell function error_on_missing_default_upstream in git-parse-remote.sh which uses it to display a command hint for the user. Signed-off-by: Vasco Almeida--- git-rebase.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-rebase.sh b/git-rebase.sh index 1fadc04..9ba21ab 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -449,7 +449,7 @@ then then . git-parse-remote error_on_missing_default_upstream "rebase" "rebase" \ - "against" "git rebase " + "against" "git rebase $(gettext '')" fi test "$fork_point" = auto && fork_point=t -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 07/38] i18n: merge-octopus: mark messages for translation
Mark messages in git-merge-octopus.sh for translation. Signed-off-by: Vasco Almeida--- git-merge-octopus.sh | 18 ++ 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/git-merge-octopus.sh b/git-merge-octopus.sh index dc2fd1b..89e967a 100755 --- a/git-merge-octopus.sh +++ b/git-merge-octopus.sh @@ -5,6 +5,8 @@ # Resolve two or more trees. # +. git-sh-i18n + LF=' ' @@ -46,7 +48,7 @@ esac if ! git diff-index --quiet --cached HEAD -- then -echo "Error: Your local changes to the following files would be overwritten by merge" +gettextln "Error: Your local changes to the following files would be overwritten by merge" git diff-index --cached --name-only HEAD -- | sed -e 's/^//' exit 2 fi @@ -61,8 +63,8 @@ do # We allow only last one to have a hand-resolvable # conflicts. Last round failed and we still had # a head to merge. - echo "Automated merge did not work." - echo "Should not be doing an Octopus." + gettextln "Automated merge did not work." + gettextln "Should not be doing an Octopus." exit 2 esac @@ -73,11 +75,11 @@ do eval pretty_name=\${GITHEAD_$SHA1_UP:-$pretty_name} fi common=$(git merge-base --all $SHA1 $MRC) || - die "Unable to find common commit with $pretty_name" + die "$(eval_gettext "Unable to find common commit with \$pretty_name")" case "$LF$common$LF" in *"$LF$SHA1$LF"*) - echo "Already up-to-date with $pretty_name" + eval_gettextln "Already up-to-date with \$pretty_name" continue ;; esac @@ -89,7 +91,7 @@ do # tree as the intermediate result of the merge. # We still need to count this as part of the parent set. - echo "Fast-forwarding to: $pretty_name" + eval_gettextln "Fast-forwarding to: \$pretty_name" git read-tree -u -m $head $SHA1 || exit MRC=$SHA1 MRT=$(git write-tree) continue @@ -97,12 +99,12 @@ do NON_FF_MERGE=1 - echo "Trying simple merge with $pretty_name" + eval_gettextln "Trying simple merge with \$pretty_name" git read-tree -u -m --aggressive $common $MRT $SHA1 || exit 2 next=$(git write-tree 2>/dev/null) if test $? -ne 0 then - echo "Simple merge did not work, trying automatic merge." + gettextln "Simple merge did not work, trying automatic merge." git-merge-index -o git-merge-one-file -a || OCTOPUS_FAILURE=1 next=$(git write-tree 2>/dev/null) -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 21/38] t4153: fix negated test_i18ngrep call
The function test_i18ngrep fakes success when run under GETTEXT_POISON. Hence, running in the following manner will always fail under gettext poison: ! test_i18ngrep expected actual Use correct syntax: test_i18ngrep ! expected actual For other instance of this issue see 41ca19b ("tests: fix negated test_i18ngrep calls", 2014-08-13). Signed-off-by: Vasco Almeida--- t/t4153-am-resume-override-opts.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/t4153-am-resume-override-opts.sh b/t/t4153-am-resume-override-opts.sh index 7c013d8..8ea22d1 100755 --- a/t/t4153-am-resume-override-opts.sh +++ b/t/t4153-am-resume-override-opts.sh @@ -53,7 +53,7 @@ test_expect_success '--no-quiet overrides --quiet' ' # Applying side1 will be quiet. test_must_fail git am --quiet side[123].eml >out && test_path_is_dir .git/rebase-apply && - ! test_i18ngrep "^Applying: " out && + test_i18ngrep ! "^Applying: " out && echo side1 >file && git add file && -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 13/38] i18n: git-sh-setup.sh: mark strings for translation
Positional arguments, such as $0, $1, etc, need to be stored on shell variables for use in translatable strings, according to gettext manual [1]. Add git-sh-setup.sh to LOCALIZED_SH variable in Makefile to enable extraction of string marked for translation by xgettext. Source git-sh-i18n in git-sh-setup.sh for gettext support. git-sh-setup.sh is a shell library to be sourced by other shell scripts. In order to avoid other scripts from sourcing git-sh-i18n twice, remove line that sources it from them. Not sourcing git-sh-i18n in any script that uses gettext would lead to failure due to, for instance, gettextln not being found. [1] http://www.gnu.org/software/gettext/manual/html_node/Preparing-Shell-Scripts.html Signed-off-by: Vasco Almeida--- Makefile | 4 +++- git-bisect.sh| 1 - git-merge-octopus.sh | 1 - git-rebase.sh| 1 - git-sh-setup.sh | 63 +++- git-stash.sh | 1 - git-submodule.sh | 1 - 7 files changed, 50 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index de5a030..6169389 100644 --- a/Makefile +++ b/Makefile @@ -2063,7 +2063,9 @@ XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell \ --keyword=gettextln --keyword=eval_gettextln XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --keyword=__ --language=Perl LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H) -LOCALIZED_SH = $(SCRIPT_SH) git-parse-remote.sh +LOCALIZED_SH = $(SCRIPT_SH) +LOCALIZED_SH += git-parse-remote.sh +LOCALIZED_SH += git-sh-setup.sh LOCALIZED_PERL = $(SCRIPT_PERL) ifdef XGETTEXT_INCLUDE_TESTS diff --git a/git-bisect.sh b/git-bisect.sh index 737bf05..30d01bb 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -33,7 +33,6 @@ Please use "git help bisect" to get the full man page.' OPTIONS_SPEC= . git-sh-setup -. git-sh-i18n _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" diff --git a/git-merge-octopus.sh b/git-merge-octopus.sh index d79fc84..308eafd 100755 --- a/git-merge-octopus.sh +++ b/git-merge-octopus.sh @@ -6,7 +6,6 @@ # . git-sh-setup -. git-sh-i18n LF=' ' diff --git a/git-rebase.sh b/git-rebase.sh index 9ba21ab..04f6e44 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -45,7 +45,6 @@ skip! skip current patch and continue edit-todo! edit the todo list during an interactive rebase " . git-sh-setup -. git-sh-i18n set_reflog_action rebase require_work_tree_exists cd_to_toplevel diff --git a/git-sh-setup.sh b/git-sh-setup.sh index c48139a..2eda134 100644 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -2,6 +2,9 @@ # to set up some variables pointing at the normal git directories and # a few helper shell functions. +# Source git-sh-i18n for gettext support. +. git-sh-i18n + # Having this variable in your environment would break scripts because # you would cause "cd" to be taken to unexpected places. If you # like CDPATH, define it for your interactive shell sessions without @@ -83,16 +86,16 @@ if test -n "$OPTIONS_SPEC"; then else dashless=$(basename -- "$0" | sed -e 's/-/ /') usage() { - die "usage: $dashless $USAGE" + die "$(eval_gettext "usage: \$dashless \$USAGE")" } if [ -z "$LONG_USAGE" ] then - LONG_USAGE="usage: $dashless $USAGE" + LONG_USAGE="$(eval_gettext "usage: \$dashless \$USAGE")" else - LONG_USAGE="usage: $dashless $USAGE + LONG_USAGE="$(eval_gettext "usage: \$dashless \$USAGE -$LONG_USAGE" +$LONG_USAGE")" fi case "$1" in @@ -182,7 +185,7 @@ is_bare_repository () { cd_to_toplevel () { cdup=$(git rev-parse --show-toplevel) && cd "$cdup" || { - echo >&2 "Cannot chdir to $cdup, the toplevel of the working tree" + gettextln "Cannot chdir to \$cdup, the toplevel of the working tree" >&2 exit 1 } } @@ -190,13 +193,16 @@ cd_to_toplevel () { require_work_tree_exists () { if test "z$(git rev-parse --is-bare-repository)" != zfalse then - die "fatal: $0 cannot be used without a working tree." + program_name=$0 + die "$(gettext "fatal: \$program_name cannot be used without a working tree.")" fi } require_work_tree () { - test "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = true || - die "fatal: $0 cannot be used without a working tree." + test "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = true || { + program_name=$0 + die "$(gettext "fatal: \$program_name cannot be used without a working tree.")" + } } require_clean_work_tree () { @@ -206,24 +212,49 @@ require_clean_work_tree () { if ! git diff-files --quiet --ignore-submodules then - echo >&2 "Cannot $1: You have unstaged
[PATCH v5 16/38] i18n: rebase-interactive: mark comments of squash for translation
Mark comment messages of squash/fixup file ($squash_msg) for translation. Helper functions this_nth_commit_message and skip_nth_commit_message replace the previous method of making the comment messages (such as "This is the 2nd commit message:") aided by nth_string helper function. This step was taken as a workaround to enabled translation of entire sentences. However, doesn't change any text seen in English by the user, except for string "The first commit's message is:" which was changed to match the style of other instances. The test t3404-rebase-interactive.sh resorts to set_fake_editor which didn't account for GETTEXT_POISON. Fix it by assuming success when we find dummy gettext poison output where was supposed to find the first comment line "This is a combination of $count commits.". For that same message, use plural aware eval_ngettext instead of eval_gettext, since other languages have more complex plural forms. Signed-off-by: Vasco Almeida--- git-rebase--interactive.sh | 69 +- t/lib-rebase.sh| 1 + 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index a16ce3a..0446efd 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -401,12 +401,52 @@ pick_one_preserving_merges () { esac } -nth_string () { - case "$1" in - *1[0-9]|*[04-9]) echo "$1"th;; - *1) echo "$1"st;; - *2) echo "$1"nd;; - *3) echo "$1"rd;; +this_nth_commit_message () { + n=$1 + case "$n" in + 1) gettext "This is the 1st commit message:";; + 2) gettext "This is the 2nd commit message:";; + 3) gettext "This is the 3rd commit message:";; + 4) gettext "This is the 4th commit message:";; + 5) gettext "This is the 5th commit message:";; + 6) gettext "This is the 6th commit message:";; + 7) gettext "This is the 7th commit message:";; + 8) gettext "This is the 8th commit message:";; + 9) gettext "This is the 9th commit message:";; + 10) gettext "This is the 10th commit message:";; + # TRANSLATORS: if the language you are translating into + # doesn't allow you to compose a sentence in this fashion, + # consider translating as if this and the following few strings + # were "This is the commit message ${n}:" + *1[0-9]|*[04-9]) eval_gettext "This is the \${n}th commit message:";; + *1) eval_gettext "This is the \${n}st commit message:";; + *2) eval_gettext "This is the \${n}nd commit message:";; + *3) eval_gettext "This is the \${n}rd commit message:";; + *) eval_gettext "This is the commit message \${n}:";; + esac +} +skip_nth_commit_message () { + n=$1 + case "$n" in + 1) gettext "The 1st commit message will be skipped:";; + 2) gettext "The 2nd commit message will be skipped:";; + 3) gettext "The 3rd commit message will be skipped:";; + 4) gettext "The 4th commit message will be skipped:";; + 5) gettext "The 5th commit message will be skipped:";; + 6) gettext "The 6th commit message will be skipped:";; + 7) gettext "The 7th commit message will be skipped:";; + 8) gettext "The 8th commit message will be skipped:";; + 9) gettext "The 9th commit message will be skipped:";; + 10) gettext "The 10th commit message will be skipped:";; + # TRANSLATORS: if the language you are translating into + # doesn't allow you to compose a sentence in this fashion, + # consider translating as if this and the following few strings + # were "The commit message ${n} will be skipped:" + *1[0-9]|*[04-9]) eval_gettext "The \${n}th commit message will be skipped:";; + *1) eval_gettext "The \${n}st commit message will be skipped:";; + *2) eval_gettext "The \${n}nd commit message will be skipped:";; + *3) eval_gettext "The \${n}rd commit message will be skipped:";; + *) eval_gettext "The commit message \${n} will be skipped:";; esac } @@ -414,20 +454,23 @@ update_squash_messages () { if test -f "$squash_msg"; then mv "$squash_msg" "$squash_msg".bak || exit count=$(($(sed -n \ - -e "1s/^. This is a combination of \(.*\) commits\./\1/p" \ + -e "1s/^$comment_char.*\([0-9][0-9]*\).*/\1/p" \ -e "q" < "$squash_msg".bak)+1)) { - printf '%s\n' "$comment_char This is a combination of $count commits." + printf '%s\n' "$comment_char $(eval_ngettext \ + "This is a combination of \$count commit." \ + "This is a combination of \$count commits." \ + $count)" sed -e 1d -e '2,/^./{ /^$/d
[PATCH v5 15/38] i18n: rebase-interactive: mark here-doc strings for translation
Use pipe to send gettext output to git stripspace instead of the original method of using shell here-document, because command substitution '$(...)' would not take place inside the here-documents. The exception is the case of the last here-document redirecting to cat, in which commands substitution works and, thus, is preserved in this commit. t3404: adapt test to the strings newly marked for translation Test t3404-rebase-interactive.sh would fail under GETTEXT_POISON unless using test_i18ngrep. Add eval_ngettext fallback functions to be called when running, for instance, under GETTEXT_POISON. Otherwise, tests would fail under GETTEXT_POISON, or other build that doesn't support the GNU gettext, because that function could not be found. Signed-off-by: Vasco Almeida--- git-rebase--interactive.sh| 30 +++--- git-sh-i18n.sh| 18 ++ t/t3404-rebase-interactive.sh | 14 +++--- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 2b8a845..a16ce3a 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -144,29 +144,28 @@ reschedule_last_action () { } append_todo_help () { - git stripspace --comment-lines >>"$todo" <<\EOF - + gettext " Commands: p, pick = use commit r, reword = use commit, but edit the commit message e, edit = use commit, but stop for amending s, squash = use commit, but meld into previous commit - f, fixup = like "squash", but discard this commit's log message + f, fixup = like \"squash\", but discard this commit's log message x, exec = run command (the rest of the line) using shell d, drop = remove commit These lines can be re-ordered; they are executed from top to bottom. +" | git stripspace --comment-lines >>"$todo" -EOF if test $(get_missing_commit_check_level) = error then - git stripspace --comment-lines >>"$todo" <<\EOF + gettext " Do not remove any line. Use 'drop' explicitly to remove a commit. -EOF +" | git stripspace --comment-lines >>"$todo" else - git stripspace --comment-lines >>"$todo" <<\EOF + gettext " If you remove a line here THAT COMMIT WILL BE LOST. -EOF +" | git stripspace --comment-lines >>"$todo" fi } @@ -1122,13 +1121,12 @@ edit-todo) mv -f "$todo".new "$todo" collapse_todo_ids append_todo_help - git stripspace --comment-lines >>"$todo" <<\EOF - + gettext " You are editing the todo file of an ongoing interactive rebase. To continue rebase after editing, run: git rebase --continue -EOF +" | git stripspace --comment-lines >>"$todo" git_sequence_editor "$todo" || die "$(gettext "Could not execute editor")" @@ -1269,14 +1267,16 @@ todocount=${todocount##* } cat >>"$todo" <>"$todo" <<\EOF - +gettext " However, if you remove everything, the rebase will be aborted. -EOF +" | git stripspace --comment-lines >>"$todo" if test -z "$keep_empty" then diff --git a/git-sh-i18n.sh b/git-sh-i18n.sh index e6c3116..1ef1889 100644 --- a/git-sh-i18n.sh +++ b/git-sh-i18n.sh @@ -53,6 +53,13 @@ gettext_without_eval_gettext) git sh-i18n--envsubst "$1" ) } + + eval_ngettext () { + ngettext "$1" "$2" "$3" | ( + export PATH $(git sh-i18n--envsubst --variables "$2"); + git sh-i18n--envsubst "$2" + ) + } ;; poison) # Emit garbage so that tests that incorrectly rely on translatable @@ -64,6 +71,10 @@ poison) eval_gettext () { printf "%s" "# GETTEXT POISON #" } + + eval_ngettext () { + printf "%s" "# GETTEXT POISON #" + } ;; *) gettext () { @@ -76,6 +87,13 @@ poison) git sh-i18n--envsubst "$1" ) } + + eval_ngettext () { + (test "$3" = 1 && printf "%s" "$1" || printf "%s" "$2") | ( + export PATH $(git sh-i18n--envsubst --variables "$2"); + git sh-i18n--envsubst "$2" + ) + } ;; esac diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 66348f1..f4ccd10 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -540,7 +540,7 @@ test_expect_success 'clean error after failed "exec"' ' echo "edited again" > file7 && git add file7 && test_must_fail git rebase --continue 2>error && - grep "You have staged changes in your working tree." error + test_i18ngrep "You have staged changes in your working tree." error ' test_expect_success 'rebase a detached HEAD' ' @@ -1060,7 +1060,7 @@ test_expect_success 'todo count' ' EOF test_set_editor "$(pwd)/dump-raw.sh" &&
[PATCH v5 19/38] tests: unpack-trees: update to use test_i18n* functions
Use functions test_i18ncmp and test_i18ngrep to successfully pass tests running under GETTEXT_POISON. The output strings compared to in these test were marked for translation in ed47fdf ("i18n: unpack-trees: mark strings for translation", 2016-04-09) and later improved in 2e3926b ("i18n: unpack-trees: avoid substituting only a verb in sentences", 2016-05-12). Signed-off-by: Vasco Almeida--- t/t1011-read-tree-sparse-checkout.sh | 2 +- t/t3400-rebase.sh| 4 ++-- t/t3404-rebase-interactive.sh| 4 ++-- t/t7607-merge-overwrite.sh | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh index 0c74bee..3583105 100755 --- a/t/t1011-read-tree-sparse-checkout.sh +++ b/t/t1011-read-tree-sparse-checkout.sh @@ -247,7 +247,7 @@ error: The following untracked working tree files would be overwritten by checko Please move or remove them before you can switch branches. Aborting EOF - test_cmp expected actual + test_i18ncmp expected actual ' test_expect_success 'checkout without --ignore-skip-worktree-bits' ' diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index 47b5682..f5fd15e 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -136,8 +136,8 @@ test_expect_success 'setup: recover' ' test_expect_success 'Show verbose error when HEAD could not be detached' ' >B && test_must_fail git rebase topic 2>output.err >output.out && - grep "The following untracked working tree files would be overwritten by checkout:" output.err && - grep B output.err + test_i18ngrep "The following untracked working tree files would be overwritten by checkout:" output.err && + test_i18ngrep B output.err ' rm -f B diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index f4ccd10..8ac1868 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -219,9 +219,9 @@ test_expect_success 'abort with error when new base cannot be checked out' ' git commit -m "remove file in base" && set_fake_editor && test_must_fail git rebase -i master > output 2>&1 && - grep "The following untracked working tree files would be overwritten by checkout:" \ + test_i18ngrep "The following untracked working tree files would be overwritten by checkout:" \ output && - grep "file1" output && + test_i18ngrep "file1" output && test_path_is_missing .git/rebase-merge && git reset --hard HEAD^ ' diff --git a/t/t7607-merge-overwrite.sh b/t/t7607-merge-overwrite.sh index 758a623..e8ec54c 100755 --- a/t/t7607-merge-overwrite.sh +++ b/t/t7607-merge-overwrite.sh @@ -125,7 +125,7 @@ test_expect_success 'will not overwrite untracked file in leading path' ' cp important sub && cp important sub2 && test_must_fail git merge sub 2>out && - test_cmp out expect && + test_i18ncmp out expect && test_path_is_missing .git/MERGE_HEAD && test_cmp important sub && test_cmp important sub2 && -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 28/38] i18n: merge: mark messages for translation
Mark messages shown to the user for translation. Signed-off-by: Vasco Almeida--- builtin/merge.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/builtin/merge.c b/builtin/merge.c index b555a1b..961def5 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -1014,7 +1014,7 @@ static int default_edit_option(void) if (e) { int v = git_config_maybe_bool(name, e); if (v < 0) - die("Bad value '%s' in environment '%s'", e, name); + die(_("Bad value '%s' in environment '%s'"), e, name); return v; } @@ -1115,7 +1115,7 @@ static void handle_fetch_head(struct commit_list **remotes, struct strbuf *merge if (!commit) { if (ptr) *ptr = '\0'; - die("not something we can merge in %s: %s", + die(_("not something we can merge in %s: %s"), filename, merge_names->buf + pos); } remotes = _list_insert(commit, remotes)->next; @@ -1149,7 +1149,7 @@ static struct commit_list *collect_parents(struct commit *head_commit, struct commit *commit = get_merge_parent(argv[i]); if (!commit) help_unknown_ref(argv[i], "merge", -"not something we can merge"); +_("not something we can merge")); remotes = _list_insert(commit, remotes)->next; } remoteheads = reduce_parents(head_commit, head_subsumed, remoteheads); @@ -1421,7 +1421,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) * If head can reach all the merge then we are up to date. * but first the most common case of merging one remote. */ - finish_up_to_date("Already up-to-date."); + finish_up_to_date(_("Already up-to-date.")); goto done; } else if (fast_forward != FF_NO && !remoteheads->next && !common->next && @@ -1506,7 +1506,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) } } if (up_to_date) { - finish_up_to_date("Already up-to-date. Yeeah!"); + finish_up_to_date(_("Already up-to-date. Yeeah!")); goto done; } } -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 17/38] i18n: setup: mark strings for translation
Update tests that compare the strings newly marked for translation to succeed when running under GETTEXT_POISON. Signed-off-by: Vasco Almeida--- setup.c| 16 t/t1506-rev-parse-diagnosis.sh | 2 +- t/t4208-log-magic-pathspec.sh | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/setup.c b/setup.c index c86bf5c..6d0e0c9 100644 --- a/setup.c +++ b/setup.c @@ -157,8 +157,8 @@ static void NORETURN die_verify_filename(const char *prefix, int diagnose_misspelt_rev) { if (!diagnose_misspelt_rev) - die("%s: no such path in the working tree.\n" - "Use 'git -- ...' to specify paths that do not exist locally.", + die(_("%s: no such path in the working tree.\n" + "Use 'git -- ...' to specify paths that do not exist locally."), arg); /* * Saying "'(icase)foo' does not exist in the index" when the @@ -170,9 +170,9 @@ static void NORETURN die_verify_filename(const char *prefix, maybe_die_on_misspelt_object_name(arg, prefix); /* ... or fall back the most general message. */ - die("ambiguous argument '%s': unknown revision or path not in the working tree.\n" - "Use '--' to separate paths from revisions, like this:\n" - "'git [...] -- [...]'", arg); + die(_("ambiguous argument '%s': unknown revision or path not in the working tree.\n" + "Use '--' to separate paths from revisions, like this:\n" + "'git [...] -- [...]'"), arg); } @@ -220,9 +220,9 @@ void verify_non_filename(const char *prefix, const char *arg) return; /* flag */ if (!check_filename(prefix, arg)) return; - die("ambiguous argument '%s': both revision and filename\n" - "Use '--' to separate paths from revisions, like this:\n" - "'git [...] -- [...]'", arg); + die(_("ambiguous argument '%s': both revision and filename\n" + "Use '--' to separate paths from revisions, like this:\n" + "'git [...] -- [...]'"), arg); } int get_common_dir(struct strbuf *sb, const char *gitdir) diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh index 86c2ff2..79a0251 100755 --- a/t/t1506-rev-parse-diagnosis.sh +++ b/t/t1506-rev-parse-diagnosis.sh @@ -106,7 +106,7 @@ test_expect_success 'incorrect revision id' ' test_must_fail git rev-parse foobar:file.txt 2>error && grep "Invalid object name '"'"'foobar'"'"'." error && test_must_fail git rev-parse foobar 2> error && - grep "unknown revision or path not in the working tree." error + test_i18ngrep "unknown revision or path not in the working tree." error ' test_expect_success 'incorrect file in sha1:path' ' diff --git a/t/t4208-log-magic-pathspec.sh b/t/t4208-log-magic-pathspec.sh index d8f23f4..001343e 100755 --- a/t/t4208-log-magic-pathspec.sh +++ b/t/t4208-log-magic-pathspec.sh @@ -18,7 +18,7 @@ test_expect_success '"git log :/" should not be ambiguous' ' test_expect_success '"git log :/a" should be ambiguous (applied both rev and worktree)' ' : >a && test_must_fail git log :/a 2>error && - grep ambiguous error + test_i18ngrep ambiguous error ' test_expect_success '"git log :/a -- " should not be ambiguous' ' @@ -31,7 +31,7 @@ test_expect_success '"git log -- :/a" should not be ambiguous' ' test_expect_success '"git log :" should be ambiguous' ' test_must_fail git log : 2>error && - grep ambiguous error + test_i18ngrep ambiguous error ' test_expect_success 'git log -- :' ' -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 14/38] i18n: rebase-interactive: mark strings for translation
Mark strings in git-rebase--interactive.sh for translation. There is no need to source git-sh-i18n since git-rebase.sh already does so. Add git-rebase--interactive.sh to LOCALIZED_SH in Makefile in order to enable extracting strings marked for translation by xgettext. Signed-off-by: Vasco Almeida--- Makefile | 1 + git-rebase--interactive.sh | 191 - 2 files changed, 102 insertions(+), 90 deletions(-) diff --git a/Makefile b/Makefile index 6169389..3cb1d60 100644 --- a/Makefile +++ b/Makefile @@ -2065,6 +2065,7 @@ XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --keyword=__ --language=Perl LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H) LOCALIZED_SH = $(SCRIPT_SH) LOCALIZED_SH += git-parse-remote.sh +LOCALIZED_SH += git-rebase--interactive.sh LOCALIZED_SH += git-sh-setup.sh LOCALIZED_PERL = $(SCRIPT_PERL) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 6e96abc..2b8a845 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -128,7 +128,7 @@ mark_action_done () { if test "$last_count" != "$new_count" then last_count=$new_count - printf "Rebasing (%d/%d)\r" $new_count $total + eval_gettext "Rebasing (\$new_count/\$total)"; printf "\r" test -z "$verbose" || echo fi } @@ -200,13 +200,14 @@ exit_with_patch () { make_patch $1 git rev-parse --verify HEAD > "$amend" gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} - warn "You can amend the commit now, with" - warn - warn " git commit --amend $gpg_sign_opt_quoted" - warn - warn "Once you are satisfied with your changes, run" - warn - warn " git rebase --continue" + warn "$(eval_gettext "\ +You can amend the commit now, with + + git commit --amend \$gpg_sign_opt_quoted + +Once you are satisfied with your changes, run + + git rebase --continue")" warn exit $2 } @@ -221,10 +222,12 @@ has_action () { } is_empty_commit() { - tree=$(git rev-parse -q --verify "$1"^{tree} 2>/dev/null || - die "$1: not a commit that can be picked") - ptree=$(git rev-parse -q --verify "$1"^^{tree} 2>/dev/null || - ptree=4b825dc642cb6eb9a060e54bf8d69288fbee4904) + tree=$(git rev-parse -q --verify "$1"^{tree} 2>/dev/null) || { + sha1=$1 + die "$(eval_gettext "\$sha1: not a commit that can be picked")" + } + ptree=$(git rev-parse -q --verify "$1"^^{tree} 2>/dev/null) || + ptree=4b825dc642cb6eb9a060e54bf8d69288fbee4904 test "$tree" = "$ptree" } @@ -260,7 +263,7 @@ pick_one () { case "$1" in -n) sha1=$2; ff= ;; *) sha1=$1 ;; esac case "$force_rebase" in '') ;; ?*) ff= ;; esac - output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1" + output git rev-parse --verify $sha1 || die "$(eval_gettext "Invalid commit name: \$sha1")" if is_empty_commit "$sha1" then @@ -302,7 +305,7 @@ pick_one_preserving_merges () { git rev-parse HEAD > "$rewritten"/$current_commit done <"$state_dir"/current-commit rm "$state_dir"/current-commit || - die "Cannot write current commit's replacement sha1" + die "$(gettext "Cannot write current commit's replacement sha1")" fi fi @@ -354,9 +357,9 @@ pick_one_preserving_merges () { done case $fast_forward in t) - output warn "Fast-forward to $sha1" + output warn "$(eval_gettext "Fast-forward to \$sha1")" output git reset --hard $sha1 || - die "Cannot fast-forward to $sha1" + die "$(eval_gettext "Cannot fast-forward to \$sha1")" ;; f) first_parent=$(expr "$new_parents" : ' \([^ ]*\)') @@ -365,12 +368,12 @@ pick_one_preserving_merges () { then # detach HEAD to current parent output git checkout $first_parent 2> /dev/null || - die "Cannot move HEAD to $first_parent" + die "$(eval_gettext "Cannot move HEAD to \$first_parent")" fi case "$new_parents" in ' '*' '*) - test "a$1" = a-n && die "Refusing to squash a merge: $sha1" + test "a$1" = a-n && die "$(eval_gettext "Refusing to squash a merge: \$sha1")" # redo merge author_script_content=$(get_author_ident_from_commit $sha1) @@ -384,7 +387,7 @@ pick_one_preserving_merges () { $merge_args
[PATCH v5 31/38] i18n: standardise messages
Standardise messages in order to save translators some work. Nuances fixed in this commit: "failed to read %s" "read of %s failed" "detach the HEAD at named commit" "detach HEAD at named commit" "removing '%s' failed" "failed to remove '%s'" "index file corrupt" "corrupt index file" "failed to read %s" "read of %s failed" "detach the HEAD at named commit" "detach HEAD at named commit" Signed-off-by: Vasco Almeida--- builtin/apply.c| 6 +++--- builtin/checkout.c | 6 +++--- builtin/repack.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/builtin/apply.c b/builtin/apply.c index c770d7d..a741274 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -3226,7 +3226,7 @@ static int load_patch_target(struct strbuf *buf, { if (cached || check_index) { if (read_file_or_gitlink(ce, buf)) - return error(_("read of %s failed"), name); + return error(_("failed to read %s"), name); } else if (name) { if (S_ISGITLINK(expected_mode)) { if (ce) @@ -3237,7 +3237,7 @@ static int load_patch_target(struct strbuf *buf, return error(_("reading from '%s' beyond a symbolic link"), name); } else { if (read_old_data(st, name, buf)) - return error(_("read of %s failed"), name); + return error(_("failed to read %s"), name); } } return 0; @@ -3282,7 +3282,7 @@ static int load_preimage(struct image *image, free_fragment_list(patch->fragments); patch->fragments = NULL; } else if (status) { - return error(_("read of %s failed"), patch->old_name); + return error(_("failed to read %s"), patch->old_name); } } diff --git a/builtin/checkout.c b/builtin/checkout.c index 3398c61..05c7b71 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -276,7 +276,7 @@ static int checkout_paths(const struct checkout_opts *opts, hold_locked_index(lock_file, 1); if (read_cache_preload(>pathspec) < 0) - return error(_("corrupt index file")); + return error(_("index file corrupt")); if (opts->source_tree) read_tree_some(opts->source_tree, >pathspec); @@ -470,7 +470,7 @@ static int merge_working_tree(const struct checkout_opts *opts, hold_locked_index(lock_file, 1); if (read_cache_preload(NULL) < 0) - return error(_("corrupt index file")); + return error(_("index file corrupt")); resolve_undo_clear(); if (opts->force) { @@ -1138,7 +1138,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) OPT_STRING('B', NULL, _branch_force, N_("branch"), N_("create/reset and checkout a branch")), OPT_BOOL('l', NULL, _branch_log, N_("create reflog for new branch")), - OPT_BOOL(0, "detach", _detach, N_("detach the HEAD at named commit")), + OPT_BOOL(0, "detach", _detach, N_("detach HEAD at named commit")), OPT_SET_INT('t', "track", , N_("set upstream info for new branch"), BRANCH_TRACK_EXPLICIT), OPT_STRING(0, "orphan", _orphan_branch, N_("new-branch"), N_("new unparented branch")), diff --git a/builtin/repack.c b/builtin/repack.c index 858db38..0108819 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -378,7 +378,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix) item->string, exts[ext].name); if (remove_path(fname)) - warning(_("removing '%s' failed"), fname); + warning(_("failed to remove '%s'"), fname); free(fname); } } -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 29/38] i18n: merge: change command option help to lowercase
Change command option description to lowercase, matching pull counterpart option. Translators would have to translate such message only once. Signed-off-by: Vasco Almeida--- builtin/merge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/merge.c b/builtin/merge.c index 961def5..d82f6c1 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -211,7 +211,7 @@ static struct option builtin_merge_options[] = { PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, FF_ONLY }, OPT_RERERE_AUTOUPDATE(_rerere_auto), OPT_BOOL(0, "verify-signatures", _signatures, - N_("Verify that the named commit has a valid GPG signature")), + N_("verify that the named commit has a valid GPG signature")), OPT_CALLBACK('s', "strategy", _strategies, N_("strategy"), N_("merge strategy to use"), option_parse_strategy), OPT_CALLBACK('X', "strategy-option", , N_("option=value"), -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 18/38] tests: use test_i18n* functions to suppress false positives
The test functions test_i18ncmp and test_i18ngrep pretend success if run under GETTEXT_POISON. By using those functions to test output which is correctly marked as translatable, enables one to detect if the strings newly marked for translation are from plumbing output. If they are indeed from plumbing, the test would fail, and the string should be unmarked, since it is not seen by users. Thus, it is productive to not have false positives when running the test under GETTEXT_POISON. This commit replaces normal test functions by their i18n aware variants in use-cases know to be correctly marked for translation, suppressing false positives. Signed-off-by: Vasco Almeida--- t/t0008-ignores.sh| 4 ++-- t/t1300-repo-config.sh| 8 t/t1307-config-blob.sh| 5 + t/t1308-config-set.sh | 4 ++-- t/t1400-update-ref.sh | 2 +- t/t2010-checkout-ambiguous.sh | 2 +- t/t2018-checkout-branch.sh| 2 +- t/t3200-branch.sh | 6 +++--- t/t3201-branch-contains.sh| 2 +- t/t3320-notes-merge-worktrees.sh | 2 +- t/t5505-remote.sh | 2 +- t/t5510-fetch.sh | 2 +- t/t5523-push-upstream.sh | 4 ++-- t/t5536-fetch-conflicts.sh| 4 ++-- t/t6301-for-each-ref-errors.sh| 10 +- t/t7063-status-untracked-cache.sh | 2 +- t/t7102-reset.sh | 4 ++-- t/t7400-submodule-basic.sh| 2 +- t/t7403-submodule-sync.sh | 4 ++-- t/t7406-submodule-update.sh | 10 +- t/t7508-status.sh | 4 ++-- 21 files changed, 41 insertions(+), 44 deletions(-) diff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh index b425f3a..d27f438 100755 --- a/t/t0008-ignores.sh +++ b/t/t0008-ignores.sh @@ -34,7 +34,7 @@ expect_from_stdin () { test_stderr () { expected="$1" expect_in stderr "$1" && - test_cmp "$HOME/expected-stderr" "$HOME/stderr" + test_i18ncmp "$HOME/expected-stderr" "$HOME/stderr" } broken_c_unquote () { @@ -47,7 +47,7 @@ broken_c_unquote_verbose () { stderr_contains () { regexp="$1" - if grep "$regexp" "$HOME/stderr" + if test_i18ngrep "$regexp" "$HOME/stderr" then return 0 else diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index d934a24..923bfc5 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -886,7 +886,7 @@ test_expect_success !MINGW 'get --path copes with unset $HOME' ' git config --get --path path.normal >>result && git config --get --path path.trailingtilde >>result ) && - grep "[Ff]ailed to expand.*~/" msg && + test_i18ngrep "[Ff]ailed to expand.*~/" msg && test_cmp expect result ' @@ -1126,7 +1126,7 @@ test_expect_success 'barf on syntax error' ' key garbage EOF test_must_fail git config --get section.key >actual 2>error && - grep " line 3 " error + test_i18ngrep " line 3 " error ' test_expect_success 'barf on incomplete section header' ' @@ -1136,7 +1136,7 @@ test_expect_success 'barf on incomplete section header' ' key = value EOF test_must_fail git config --get section.key >actual 2>error && - grep " line 2 " error + test_i18ngrep " line 2 " error ' test_expect_success 'barf on incomplete string' ' @@ -1146,7 +1146,7 @@ test_expect_success 'barf on incomplete string' ' key = "value string EOF test_must_fail git config --get section.key >actual 2>error && - grep " line 3 " error + test_i18ngrep " line 3 " error ' test_expect_success 'urlmatch' ' diff --git a/t/t1307-config-blob.sh b/t/t1307-config-blob.sh index 3c6791e..eed31ff 100755 --- a/t/t1307-config-blob.sh +++ b/t/t1307-config-blob.sh @@ -61,10 +61,7 @@ test_expect_success 'parse errors in blobs are properly attributed' ' git commit -m broken && test_must_fail git config --blob=HEAD:config some.value 2>err && - - # just grep for our token as the exact error message is likely to - # change or be internationalized - grep "HEAD:config" err + test_i18ngrep "HEAD:config" err ' test_expect_success 'can parse blob ending with CR' ' diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh index 005d66d..cd62063 100755 --- a/t/t1308-config-set.sh +++ b/t/t1308-config-set.sh @@ -197,14 +197,14 @@ test_expect_success 'proper error on error in default config files' ' echo "[" >>.git/config && echo "fatal: bad config line 34 in file .git/config" >expect && test_expect_code 128 test-config get_value foo.bar 2>actual && - test_cmp expect actual + test_i18ncmp expect actual ' test_expect_success 'proper error on error in custom config files' ' echo "[" >>syntax-error && echo "fatal: bad config line 1 in file syntax-error"
[PATCH v5 25/38] i18n: notes: mark strings for translation
Mark strings of messages for the user as translatable. Update tests t3310-notes-merge-manual-resolve.sh and t3320-notes-merge-worktrees.sh to reflect new translatable messages. Tests that grep for .git/NOTES_MERGE_WORKTREE reflect the translatable string "Automatic notes merge failed. Fix conflicts in %s and [...]". Signed-off-by: Vasco Almeida--- builtin/notes.c | 20 ++-- t/t3310-notes-merge-manual-resolve.sh | 8 t/t3320-notes-merge-worktrees.sh | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/builtin/notes.c b/builtin/notes.c index c65b59a..d11e6eb 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -749,7 +749,7 @@ static int git_config_get_notes_strategy(const char *key, if (git_config_get_string(key, )) return 1; if (parse_notes_merge_strategy(value, strategy)) - git_die_config(key, "unknown notes merge strategy %s", value); + git_die_config(key, _("unknown notes merge strategy %s"), value); free(value); return 0; @@ -788,15 +788,15 @@ static int merge(int argc, const char **argv, const char *prefix) if (strategy || do_commit + do_abort == 0) do_merge = 1; if (do_merge + do_commit + do_abort != 1) { - error("cannot mix --commit, --abort or -s/--strategy"); + error(_("cannot mix --commit, --abort or -s/--strategy")); usage_with_options(git_notes_merge_usage, options); } if (do_merge && argc != 1) { - error("Must specify a notes ref to merge"); + error(_("Must specify a notes ref to merge")); usage_with_options(git_notes_merge_usage, options); } else if (!do_merge && argc) { - error("too many parameters"); + error(_("too many parameters")); usage_with_options(git_notes_merge_usage, options); } @@ -817,7 +817,7 @@ static int merge(int argc, const char **argv, const char *prefix) if (strategy) { if (parse_notes_merge_strategy(strategy, )) { - error("Unknown -s/--strategy: %s", strategy); + error(_("Unknown -s/--strategy: %s"), strategy); usage_with_options(git_notes_merge_usage, options); } } else { @@ -857,11 +857,11 @@ static int merge(int argc, const char **argv, const char *prefix) die(_("A notes merge into %s is already in-progress at %s"), default_notes_ref(), wt->path); if (create_symref("NOTES_MERGE_REF", default_notes_ref(), NULL)) - die("Failed to store link to current notes ref (%s)", + die(_("Failed to store link to current notes ref (%s)"), default_notes_ref()); - printf("Automatic notes merge failed. Fix conflicts in %s and " - "commit the result with 'git notes merge --commit', or " - "abort the merge with 'git notes merge --abort'.\n", + printf(_("Automatic notes merge failed. Fix conflicts in %s and " +"commit the result with 'git notes merge --commit', or " +"abort the merge with 'git notes merge --abort'.\n"), git_path(NOTES_MERGE_WORKTREE)); } @@ -964,7 +964,7 @@ static int get_ref(int argc, const char **argv, const char *prefix) git_notes_get_ref_usage, 0); if (argc) { - error("too many parameters"); + error(_("too many parameters")); usage_with_options(git_notes_get_ref_usage, options); } diff --git a/t/t3310-notes-merge-manual-resolve.sh b/t/t3310-notes-merge-manual-resolve.sh index d557212..6967436 100755 --- a/t/t3310-notes-merge-manual-resolve.sh +++ b/t/t3310-notes-merge-manual-resolve.sh @@ -178,7 +178,7 @@ test_expect_success 'merge z into m (== y) with default ("manual") resolver => C git config core.notesRef refs/notes/m && test_must_fail git notes merge z >output && # Output should point to where to resolve conflicts - grep -q "\\.git/NOTES_MERGE_WORKTREE" output && + test_i18ngrep "\\.git/NOTES_MERGE_WORKTREE" output && # Inspect merge conflicts ls .git/NOTES_MERGE_WORKTREE >output_conflicts && test_cmp expect_conflicts output_conflicts && @@ -381,7 +381,7 @@ test_expect_success 'redo merge of z into m (== y) with default ("manual") resol git config core.notesRef refs/notes/m && test_must_fail git notes merge z >output && # Output should point to where to resolve conflicts - grep -q "\\.git/NOTES_MERGE_WORKTREE" output && + test_i18ngrep "\\.git/NOTES_MERGE_WORKTREE" output && #
[PATCH v5 33/38] i18n: remote: allow translations to reorder message
Before this patch, translations couldn't place the branch name where it was better fit in the message "and with remote ". Allow translations that, instead of forcing the branch name to display right of the message. Signed-off-by: Vasco Almeida--- builtin/remote.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/builtin/remote.c b/builtin/remote.c index 9f934cb..7f0f78b 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -952,7 +952,7 @@ static int show_local_info_item(struct string_list_item *item, void *cb_data) struct show_info *show_info = cb_data; struct branch_info *branch_info = item->util; struct string_list *merge = _info->merge; - const char *also; + int width = show_info->width + 4; int i; if (branch_info->rebase && branch_info->merge.nr > 1) { @@ -969,13 +969,12 @@ static int show_local_info_item(struct string_list_item *item, void *cb_data) return 0; } else if (show_info->any_rebase) { printf_ln(_(" merges with remote %s"), merge->items[0].string); - also = _("and with remote"); + width++; } else { printf_ln(_("merges with remote %s"), merge->items[0].string); - also = _(" and with remote"); } for (i = 1; i < merge->nr; i++) - printf("%-*s %s %s\n", show_info->width, "", also, + printf(_("%-*sand with remote %s\n"), width, "", merge->items[i].string); return 0; -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 12/38] t6030: update to use test_i18ncmp
Since the git bisect output tested here is subject to translation, the helper function test_i18ncmp should be used over test_cmp. Signed-off-by: Vasco Almeida--- t/t6030-bisect-porcelain.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index e74662b..7012011 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -803,7 +803,7 @@ test_expect_success 'bisect terms needs 0 or 1 argument' ' test_must_fail git bisect terms 1 2 && test_must_fail git bisect terms 2>actual && echo "no terms defined" >expected && - test_cmp expected actual + test_i18ncmp expected actual ' test_expect_success 'bisect terms shows good/bad after start' ' @@ -875,7 +875,7 @@ test_expect_success 'bisect start --term-* does store terms' ' Your current terms are two for the old state and one for the new state. EOF - test_cmp expected actual && + test_i18ncmp expected actual && git bisect terms --term-bad >actual && echo one >expected && test_cmp expected actual && -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 26/38] i18n: notes: mark options for translation
Mark options description of git prune for translation. Signed-off-by: Vasco Almeida--- builtin/notes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builtin/notes.c b/builtin/notes.c index d11e6eb..0572051 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -934,8 +934,8 @@ static int prune(int argc, const char **argv, const char *prefix) struct notes_tree *t; int show_only = 0, verbose = 0; struct option options[] = { - OPT__DRY_RUN(_only, "do not remove, show only"), - OPT__VERBOSE(, "report pruned notes"), + OPT__DRY_RUN(_only, N_("do not remove, show only")), + OPT__VERBOSE(, N_("report pruned notes")), OPT_END() }; -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 30/38] i18n: sequencer: add period to error message
Add a period to error message so it matches others instances in sequencer.c. Now translator would have to translate such message only once. Signed-off-by: Vasco Almeida--- sequencer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sequencer.c b/sequencer.c index 57b3671..e916387 100644 --- a/sequencer.c +++ b/sequencer.c @@ -190,7 +190,7 @@ static void write_message(struct strbuf *msgbuf, const char *filename) die_errno(_("Could not write to %s"), filename); strbuf_release(msgbuf); if (commit_lock_file(_file) < 0) - die(_("Error wrapping up %s"), filename); + die(_("Error wrapping up %s."), filename); } static struct tree *empty_tree(void) -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 24/38] i18n: transport-helper.c: change N_() call to _()
The N_() no-op call currently marks the string to be extracted by xgettext but doesn't trigger the retrieval of the translation at run time, whereas _() does both. Meaning that, in spite of having translations available, they were never retrieved to make use of them. Signed-off-by: Vasco Almeida--- transport-helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transport-helper.c b/transport-helper.c index bd666b2..4208743 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -1038,7 +1038,7 @@ static struct ref *get_refs_list(struct transport *transport, int for_push) (*tail)->status |= REF_STATUS_UPTODATE; if (read_ref((*tail)->name, (*tail)->old_oid.hash) < 0) - die(N_("Could not read ref %s"), + die(_("Could not read ref %s"), (*tail)->name); } } -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 11/38] i18n: bisect: simplify error message for i18n
The message was not being extracted by xgettext, although it was marked for translation, seemingly because it contained a command substitution. Moreover, eval_gettext should be used instead of gettext for strings with substitution. See step 4. of section 15.5.2.1 Preparing Shell Scripts for Internationalization from gettext manual [1]: "Simplify translatable strings so that they don't contain command substitution ("`...`" or "$(...)") [...]" [1] http://www.gnu.org/software/gettext/manual/html_node/Preparing-Shell-Scripts.html Signed-off-by: Vasco Almeida--- git-bisect.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/git-bisect.sh b/git-bisect.sh index 5d1cb00..737bf05 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -277,8 +277,9 @@ bisect_state() { 0,*) die "$(gettext "Please call 'bisect_state' with at least one argument.")" ;; 1,"$TERM_BAD"|1,"$TERM_GOOD"|1,skip) - rev=$(git rev-parse --verify $(bisect_head)) || - die "$(gettext "Bad rev input: $(bisect_head)")" + bisected_head=$(bisect_head) + rev=$(git rev-parse --verify "$bisected_head") || + die "$(eval_gettext "Bad rev input: \$bisected_head")" bisect_write "$state" "$rev" check_expected_revs "$rev" ;; 2,"$TERM_BAD"|*,"$TERM_GOOD"|*,skip) -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 20/38] t9003: become resilient to GETTEXT_POISON
The test t9003-help-autocorrect.sh fails when run under GETTEXT_POISON, because it's expecting to filter out the original output. Accommodate gettext poison case by also filtering out the default simulated output. Signed-off-by: Vasco Almeida--- t/t9003-help-autocorrect.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/t/t9003-help-autocorrect.sh b/t/t9003-help-autocorrect.sh index dfe95c9..b1c7919 100755 --- a/t/t9003-help-autocorrect.sh +++ b/t/t9003-help-autocorrect.sh @@ -31,10 +31,10 @@ test_expect_success 'autocorrect showing candidates' ' git config help.autocorrect 0 && test_must_fail git lfg 2>actual && - sed -e "1,/^Did you mean this/d" actual | grep lgf && + grep "^ lgf" actual && test_must_fail git distimdist 2>actual && - sed -e "1,/^Did you mean this/d" actual | grep distimdistim + grep "^ distimdistim" actual ' test_expect_success 'autocorrect running commands' ' -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 23/38] i18n: bisect: mark strings for translation
In the last message, involving Q_(), try to mark the message in such way that is suited for RTL (Right to Left) languages. Update test t6030-bisect-porcelain.sh to reflect the changes. Signed-off-by: Vasco Almeida--- bisect.c| 56 + t/t6030-bisect-porcelain.sh | 22 +- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/bisect.c b/bisect.c index 6d93edb..a8713a8 100644 --- a/bisect.c +++ b/bisect.c @@ -438,12 +438,12 @@ static void read_bisect_paths(struct argv_array *array) FILE *fp = fopen(filename, "r"); if (!fp) - die_errno("Could not open file '%s'", filename); + die_errno(_("Could not open file '%s'"), filename); while (strbuf_getline_lf(, fp) != EOF) { strbuf_trim(); if (sq_dequote_to_argv_array(str.buf, array)) - die("Badly quoted content in file '%s': %s", + die(_("Badly quoted content in file '%s': %s"), filename, str.buf); } @@ -649,7 +649,7 @@ static void exit_if_skipped_commits(struct commit_list *tried, print_commit_list(tried, "%s\n", "%s\n"); if (bad) printf("%s\n", oid_to_hex(bad)); - printf("We cannot bisect more!\n"); + printf(_("We cannot bisect more!\n")); exit(2); } @@ -702,7 +702,7 @@ static struct commit *get_commit_reference(const unsigned char *sha1) { struct commit *r = lookup_commit_reference(sha1); if (!r) - die("Not a valid commit name %s", sha1_to_hex(sha1)); + die(_("Not a valid commit name %s"), sha1_to_hex(sha1)); return r; } @@ -726,27 +726,27 @@ static void handle_bad_merge_base(void) char *bad_hex = oid_to_hex(current_bad_oid); char *good_hex = join_sha1_array_hex(_revs, ' '); if (!strcmp(term_bad, "bad") && !strcmp(term_good, "good")) { - fprintf(stderr, "The merge base %s is bad.\n" + fprintf(stderr, _("The merge base %s is bad.\n" "This means the bug has been fixed " - "between %s and [%s].\n", + "between %s and [%s].\n"), bad_hex, bad_hex, good_hex); } else if (!strcmp(term_bad, "new") && !strcmp(term_good, "old")) { - fprintf(stderr, "The merge base %s is new.\n" + fprintf(stderr, _("The merge base %s is new.\n" "The property has changed " - "between %s and [%s].\n", + "between %s and [%s].\n"), bad_hex, bad_hex, good_hex); } else { - fprintf(stderr, "The merge base %s is %s.\n" + fprintf(stderr, _("The merge base %s is %s.\n" "This means the first '%s' commit is " - "between %s and [%s].\n", + "between %s and [%s].\n"), bad_hex, term_bad, term_good, bad_hex, good_hex); } exit(3); } - fprintf(stderr, "Some %s revs are not ancestor of the %s rev.\n" + fprintf(stderr, _("Some %s revs are not ancestor of the %s rev.\n" "git bisect cannot work properly in this case.\n" - "Maybe you mistook %s and %s revs?\n", + "Maybe you mistook %s and %s revs?\n"), term_good, term_bad, term_good, term_bad); exit(1); } @@ -757,11 +757,11 @@ static void handle_skipped_merge_base(const unsigned char *mb) char *bad_hex = sha1_to_hex(current_bad_oid->hash); char *good_hex = join_sha1_array_hex(_revs, ' '); - warning("the merge base between %s and [%s] " + warning(_("the merge base between %s and [%s] " "must be skipped.\n" "So we cannot be sure the first %s commit is " "between %s and %s.\n" - "We continue anyway.", + "We continue anyway."), bad_hex, good_hex, term_bad, mb_hex, bad_hex); free(good_hex); } @@ -792,7 +792,7 @@ static void check_merge_bases(int no_checkout) } else if (0 <= sha1_array_lookup(_revs, mb)) { handle_skipped_merge_base(mb); } else { - printf("Bisecting: a merge base must be tested\n"); + printf(_("Bisecting: a merge base must be tested\n")); exit(bisect_checkout(mb, no_checkout)); } } @@ -843,7 +843,7 @@ static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout) int
[PATCH v5 22/38] t5523: use test_i18ngrep for negation
Replace the first form with the second one: ! grep expected actual test_i18ngrep ! expected actual The latter syntax is supported by test_i18ngrep defined in t/test-lib.sh. Although the test already passes whether GETTEXT_POSION is enabled, use the i18n grep variant for the sake of consistency and also to make obvious that those strings are subject to i18n. Signed-off-by: Vasco Almeida--- t/t5523-push-upstream.sh | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh index 4a7b98b..d6981ba 100755 --- a/t/t5523-push-upstream.sh +++ b/t/t5523-push-upstream.sh @@ -83,7 +83,7 @@ test_expect_success 'progress messages do not go to non-tty' ' # skip progress messages, since stderr is non-tty git push -u upstream master >out 2>err && - ! grep "Writing objects" err + test_i18ngrep ! "Writing objects" err ' test_expect_success 'progress messages go to non-tty (forced)' ' @@ -98,15 +98,15 @@ test_expect_success TTY 'push -q suppresses progress' ' ensure_fresh_upstream && test_terminal git push -u -q upstream master >out 2>err && - ! grep "Writing objects" err + test_i18ngrep ! "Writing objects" err ' test_expect_success TTY 'push --no-progress suppresses progress' ' ensure_fresh_upstream && test_terminal git push -u --no-progress upstream master >out 2>err && - ! grep "Unpacking objects" err && - ! grep "Writing objects" err + test_i18ngrep ! "Unpacking objects" err && + test_i18ngrep ! "Writing objects" err ' test_expect_success TTY 'quiet push' ' -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 06/38] i18n: sequencer: mark string for translation
Mark informative string ": fast-forward" for translation. Signed-off-by: Vasco Almeida--- sequencer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sequencer.c b/sequencer.c index 88a7c78..57b3671 100644 --- a/sequencer.c +++ b/sequencer.c @@ -225,7 +225,7 @@ static int fast_forward_to(const unsigned char *to, const unsigned char *from, if (checkout_fast_forward(from, to, 1)) exit(128); /* the callee should have complained already */ - strbuf_addf(, "%s: fast-forward", action_name(opts)); + strbuf_addf(, _("%s: fast-forward"), action_name(opts)); transaction = ref_transaction_begin(); if (!transaction || -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 04/38] i18n: transport: mark strings for translation
Mark one printf string and one error string for translation. Signed-off-by: Vasco Almeida--- transport.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/transport.c b/transport.c index 095e61f..59b911e 100644 --- a/transport.c +++ b/transport.c @@ -59,7 +59,7 @@ static void set_upstreams(struct transport *transport, struct ref *refs, localname + 11, transport->remote->name, remotename); else - printf("Would set upstream of '%s' to '%s' of '%s'\n", + printf(_("Would set upstream of '%s' to '%s' of '%s'\n"), localname + 11, remotename + 11, transport->remote->name); } @@ -148,7 +148,7 @@ static int set_git_option(struct git_transport_options *opts, char *end; opts->depth = strtol(value, , 0); if (*end) - die("transport: invalid depth option '%s'", value); + die(_("transport: invalid depth option '%s'"), value); } return 0; } @@ -767,19 +767,19 @@ static void die_with_unpushed_submodules(struct string_list *needs_pushing) { int i; - fprintf(stderr, "The following submodule paths contain changes that can\n" - "not be found on any remote:\n"); + fprintf(stderr, _("The following submodule paths contain changes that can\n" + "not be found on any remote:\n")); for (i = 0; i < needs_pushing->nr; i++) printf(" %s\n", needs_pushing->items[i].string); - fprintf(stderr, "\nPlease try\n\n" - " git push --recurse-submodules=on-demand\n\n" - "or cd to the path and use\n\n" - " git push\n\n" - "to push them to a remote.\n\n"); + fprintf(stderr, _("\nPlease try\n\n" + " git push --recurse-submodules=on-demand\n\n" + "or cd to the path and use\n\n" + " git push\n\n" + "to push them to a remote.\n\n")); string_list_clear(needs_pushing, 0); - die("Aborting."); + die(_("Aborting.")); } static int run_pre_push_hook(struct transport *transport, -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 09/38] i18n: rebase: fix marked string to use eval_gettext variant
The string message marked for translation should use eval_gettext variant instead of the gettext one, since we want to dollar-substitute $head_name in the result. Signed-off-by: Vasco Almeida--- git-rebase.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-rebase.sh b/git-rebase.sh index 44ede36..1fadc04 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -154,7 +154,7 @@ move_to_original_branch () { git symbolic-ref \ -m "rebase finished: returning to $head_name" \ HEAD $head_name || - die "$(gettext "Could not move back to $head_name")" + die "$(eval_gettext "Could not move back to \$head_name")" ;; esac } -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 02/38] i18n: advice: mark string about detached head for translation
Mark string with advice seen by the user when in detached head. Update test t7201-co.sh to pass under GETTEXT_POISON build. Pretend success if the number of lines of "git checkout renamer^" output is not greater than 1 and test are running under GETTEXT_POISON. Signed-off-by: Vasco Almeida--- advice.c | 6 +++--- t/t7201-co.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/advice.c b/advice.c index 4dc5cf1..cb445a7 100644 --- a/advice.c +++ b/advice.c @@ -106,14 +106,14 @@ void NORETURN die_conclude_merge(void) void detach_advice(const char *new_name) { - const char fmt[] = - "Note: checking out '%s'.\n\n" + const char *fmt = + _("Note: checking out '%s'.\n\n" "You are in 'detached HEAD' state. You can look around, make experimental\n" "changes and commit them, and you can discard any commits you make in this\n" "state without impacting any branches by performing another checkout.\n\n" "If you want to create a new branch to retain commits you create, you may\n" "do so (now or later) by using -b with the checkout command again. Example:\n\n" - " git checkout -b \n\n"; + " git checkout -b \n\n"); fprintf(stderr, fmt, new_name); } diff --git a/t/t7201-co.sh b/t/t7201-co.sh index 8859236..d4b217b 100755 --- a/t/t7201-co.sh +++ b/t/t7201-co.sh @@ -257,7 +257,7 @@ test_expect_success 'checkout to detach HEAD' ' git checkout -f renamer && git clean -f && git checkout renamer^ 2>messages && test_i18ngrep "HEAD is now at 7329388" messages && - test_line_count -gt 1 messages && + (test_line_count -gt 1 messages || test -n "$GETTEXT_POISON") && H=$(git rev-parse --verify HEAD) && M=$(git show-ref -s --verify refs/heads/master) && test "z$H" = "z$M" && -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 05/38] i18n: sequencer: mark entire sentences for translation
Mark entire sentences of error message rather than assembling one using placeholders (e.g. "Cannot %s during a %s"). That would facilitate translation work because it is easier to translate a entire sentence than translating pieces. We would have better translations at the expense of source code verbosity. Moreover, translators can now 1) translate the terms "revert" and "cherry-pick" if they please 2) have more leeway to adapt their translations. Signed-off-by: Vasco Almeida--- sequencer.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sequencer.c b/sequencer.c index 4687ad4..88a7c78 100644 --- a/sequencer.c +++ b/sequencer.c @@ -697,9 +697,14 @@ static struct commit *parse_insn_line(char *bol, char *eol, struct replay_opts * * opts; we don't support arbitrary instructions */ if (action != opts->action) { - const char *action_str; - action_str = action == REPLAY_REVERT ? "revert" : "cherry-pick"; - error(_("Cannot %s during a %s"), action_str, action_name(opts)); + if (action == REPLAY_REVERT) + error((opts->action == REPLAY_REVERT) + ? _("Cannot revert during a another revert.") + : _("Cannot revert during a cherry-pick.")); + else + error((opts->action == REPLAY_REVERT) + ? _("Cannot cherry-pick during a revert.") + : _("Cannot cherry-pick during another cherry-pick.")); return NULL; } -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 00/38] i18n and test updates
Marks several messages for translation and updates tests to pass under GETTEXT_POISON. Some tests were updated to fit previous i18n marks, others were updated to fit marks made by these patches. Patches that only touch test file refer to marks done in commits previous to these ones. "[PATCH v5 34/38] i18n: init-db: join message pieces" now updates Icelandic translation to pass test t0204-gettext-reencode-sanity.sh. That failure went unnoticed because my system did not have the Icelandic locale installed at that time. I have only tested with UTF-8 but expect to also pass the ISO-8859-1 locale since the translated strings are the same. In order to pass the tests, this series depended upon commit fe17fc0 ("t2300: run git-sh-setup in an environment that better mimics the real life", 2016-06-01) which was previously on 'next' branch, but now it has graduated to 'master'. Interdiff included below. Vasco Almeida (38): i18n: builtin/remote.c: fix mark for translation i18n: advice: mark string about detached head for translation i18n: advice: internationalize message for conflicts i18n: transport: mark strings for translation i18n: sequencer: mark entire sentences for translation i18n: sequencer: mark string for translation i18n: merge-octopus: mark messages for translation merge-octupus: use die shell function from git-sh-setup.sh i18n: rebase: fix marked string to use eval_gettext variant i18n: rebase: mark placeholder for translation i18n: bisect: simplify error message for i18n t6030: update to use test_i18ncmp i18n: git-sh-setup.sh: mark strings for translation i18n: rebase-interactive: mark strings for translation i18n: rebase-interactive: mark here-doc strings for translation i18n: rebase-interactive: mark comments of squash for translation i18n: setup: mark strings for translation tests: use test_i18n* functions to suppress false positives tests: unpack-trees: update to use test_i18n* functions t9003: become resilient to GETTEXT_POISON t4153: fix negated test_i18ngrep call t5523: use test_i18ngrep for negation i18n: bisect: mark strings for translation i18n: transport-helper.c: change N_() call to _() i18n: notes: mark strings for translation i18n: notes: mark options for translation i18n: config: unfold error messages marked for translation i18n: merge: mark messages for translation i18n: merge: change command option help to lowercase i18n: sequencer: add period to error message i18n: standardise messages i18n: remote: mark URL fallback text for translation i18n: remote: allow translations to reorder message i18n: init-db: join message pieces i18n: submodule: join strings marked for translation i18n: submodule: escape shell variables inside eval_gettext i18n: unmark die messages for translation i18n: branch: mark comment when editing branch description for translation Makefile | 5 +- advice.c | 23 ++- bisect.c | 56 --- builtin/apply.c | 6 +- builtin/branch.c | 6 +- builtin/checkout.c| 6 +- builtin/init-db.c | 17 +- builtin/merge.c | 12 +- builtin/notes.c | 24 +-- builtin/pull.c| 2 +- builtin/remote.c | 19 ++- builtin/repack.c | 2 +- cache.h | 9 +- config.c | 101 ++-- git-bisect.sh | 8 +- git-merge-octopus.sh | 23 ++- git-rebase--interactive.sh| 290 -- git-rebase.sh | 5 +- git-sh-i18n.sh| 18 +++ git-sh-setup.sh | 63 ++-- git-stash.sh | 1 - git-submodule.sh | 23 +-- po/is.po | 46 +++--- sequencer.c | 15 +- setup.c | 16 +- submodule-config.c| 2 +- t/lib-rebase.sh | 1 + t/t0008-ignores.sh| 4 +- t/t1011-read-tree-sparse-checkout.sh | 2 +- t/t1300-repo-config.sh| 8 +- t/t1307-config-blob.sh| 5 +- t/t1308-config-set.sh | 4 +- t/t1400-update-ref.sh | 2 +- t/t1506-rev-parse-diagnosis.sh| 2 +- t/t2010-checkout-ambiguous.sh | 2 +- t/t2018-checkout-branch.sh| 2 +- t/t3200-branch.sh | 6 +- t/t3201-branch-contains.sh| 2 +- t/t3310-notes-merge-manual-resolve.sh | 8 +- t/t3320-notes-merge-worktrees.sh | 4 +- t/t3400-rebase.sh | 4 +- t/t3404-rebase-interactive.sh | 18 +--
[PATCH v5 01/38] i18n: builtin/remote.c: fix mark for translation
The second string inside _() was not being extracted for translation by xgettext, meaning that, although the string was passed to gettext, there was no translation available. Mark each individual string instead of marking the result of ternary if. Signed-off-by: Vasco Almeida--- builtin/remote.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/builtin/remote.c b/builtin/remote.c index d33766b..ae74da6 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -963,9 +963,9 @@ static int show_local_info_item(struct string_list_item *item, void *cb_data) printf("%-*s ", show_info->width, item->string); if (branch_info->rebase) { - printf_ln(_(branch_info->rebase == INTERACTIVE_REBASE ? - "rebases interactively onto remote %s" : - "rebases onto remote %s"), merge->items[0].string); + printf_ln(branch_info->rebase == INTERACTIVE_REBASE + ? _("rebases interactively onto remote %s") + : _("rebases onto remote %s"), merge->items[0].string); return 0; } else if (show_info->any_rebase) { printf_ln(_(" merges with remote %s"), merge->items[0].string); -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 03/38] i18n: advice: internationalize message for conflicts
Mark message for translation telling the user she has conflicts to resolve. Expose each particular use case, in order to enable translating entire sentences which would facilitate translating into other languages. Change "Pull" to lowercase to match other instances. Update test t5520-pull.sh, that relied on the old error message, to use the new one. Although we loose in source code conciseness, we would gain better translations because translators can 1) translate the entire sentence, including those terms concerning Git (committing, merging, etc) 2) have leeway to adapt to their languages. Signed-off-by: Vasco Almeida--- advice.c| 17 +++-- builtin/pull.c | 2 +- t/t5520-pull.sh | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/advice.c b/advice.c index cb445a7..b84ae49 100644 --- a/advice.c +++ b/advice.c @@ -79,7 +79,20 @@ int git_default_advice_config(const char *var, const char *value) int error_resolve_conflict(const char *me) { - error("%s is not possible because you have unmerged files.", me); + if (!strcmp(me, "cherry-pick")) + error(_("Cherry-picking is not possible because you have unmerged files.")); + else if (!strcmp(me, "commit")) + error(_("Committing is not possible because you have unmerged files.")); + else if (!strcmp(me, "merge")) + error(_("Merging is not possible because you have unmerged files.")); + else if (!strcmp(me, "pull")) + error(_("Pulling is not possible because you have unmerged files.")); + else if (!strcmp(me, "revert")) + error(_("Reverting is not possible because you have unmerged files.")); + else + error(_("It is not possible to %s because you have unmerged files."), + me); + if (advice_resolve_conflict) /* * Message used both when 'git commit' fails and when @@ -93,7 +106,7 @@ int error_resolve_conflict(const char *me) void NORETURN die_resolve_conflict(const char *me) { error_resolve_conflict(me); - die("Exiting because of an unresolved conflict."); + die(_("Exiting because of an unresolved conflict.")); } void NORETURN die_conclude_merge(void) diff --git a/builtin/pull.c b/builtin/pull.c index 1d7333c..a980dcf 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -852,7 +852,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix) git_config(git_pull_config, NULL); if (read_cache_unmerged()) - die_resolve_conflict("Pull"); + die_resolve_conflict("pull"); if (file_exists(git_path("MERGE_HEAD"))) die_conclude_merge(); diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 739c089..45e44ca 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -211,7 +211,7 @@ test_expect_success 'fail if the index has unresolved entries' ' test -n "$(git ls-files -u)" && cp file expected && test_must_fail git pull . second 2>err && - test_i18ngrep "Pull is not possible because you have unmerged files" err && + test_i18ngrep "Pulling is not possible because you have unmerged files." err && test_cmp expected file && git add file && test -z "$(git ls-files -u)" && -- 2.6.6 -- To unsubscribe from this list: send the line "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 v5 08/38] merge-octupus: use die shell function from git-sh-setup.sh
Source git-sh-setup in order to use die shell function from git-sh-setup.sh library instead of using the one defined in git-merge-octopus.sh. Remove the former die function. Signed-off-by: Vasco Almeida--- git-merge-octopus.sh | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/git-merge-octopus.sh b/git-merge-octopus.sh index 89e967a..d79fc84 100755 --- a/git-merge-octopus.sh +++ b/git-merge-octopus.sh @@ -5,16 +5,12 @@ # Resolve two or more trees. # +. git-sh-setup . git-sh-i18n LF=' ' -die () { -echo >&2 "$*" -exit 1 -} - # The first parameters up to -- are merge bases; the rest are heads. bases= head= remotes= sep_seen= for arg -- 2.6.6 -- To unsubscribe from this list: send the line "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 4/7] run-command: add pipe_command helper
On Thu, Jun 16, 2016 at 5:37 AM, Jeff Kingwrote: > We already have capture_command(), which captures the stdout > of a command in a way that avoids deadlocks. But sometimes > we need to do more I/O, like capturing stderr as well, or > sending data to stdin. It's easy to write code that > deadlocks racily in these situations depending on how fast > the command reads its input, or in which order it writes its > output. > > Let's give callers an easy interface for doing this the > right way, similar to what capture_command() did for the > simple case. > > The whole thing is backed by a generic poll() loop that can > feed an arbitrary number of buffers to descriptors, and fill > an arbitrary number of strbufs from other descriptors. This > seems like overkill, but the resulting code is actually a > bit cleaner than just handling the three descriptors > (because the output code for stdout/stderr is effectively > duplicated, so being able to loop is a benefit). > > Signed-off-by: Jeff King > --- > diff --git a/run-command.h b/run-command.h > @@ -79,17 +79,34 @@ int run_command_v_opt(const char **argv, int opt); > /** > - * Execute the given command, capturing its stdout in the given strbuf. > + * Execute the given command, sending "in" to its stdin, and capturing its > + * stdout and stderr in the "out" and "err" strbufs. Any of the three may > + * be NULL to skip processing. > + * > * Returns -1 if starting the command fails or reading fails, and otherwise > - * returns the exit code of the command. The output collected in the > - * buffer is kept even if the command returns a non-zero exit. The hint field > - * gives a starting size for the strbuf allocation. > + * returns the exit code of the command. Any output collected in the Did you mean s/returns/Returns/ ? > + * buffers is kept even if the command returns a non-zero exit. The hint > fields > + * gives starting sizes for the strbuf allocations. > * > * The fields of "cmd" should be set up as they would for a normal > run_command > - * invocation. But note that there is no need to set cmd->out; the function > - * sets it up for the caller. > + * invocation. But note that there is no need to set the in, out, or err > + * fields; capture_command handles that automatically. s/capture_command/pipe_command/ > + */ > +int pipe_command(struct child_process *cmd, > +const char *in, size_t in_len, > +struct strbuf *out, size_t out_hint, > +struct strbuf *err, size_t err_hint); > + -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCHv2] Documentation/technical: push certificate format
Michael J Gruberwrites: > Signed-off-by: Michael J Gruber > --- > This is the version describing the current state, not assuming any new > verify command for blobs. > > Documentation/technical/signature-format.txt | 51 > > 1 file changed, 51 insertions(+) > > diff --git a/Documentation/technical/signature-format.txt > b/Documentation/technical/signature-format.txt > index 7afd403..1c21379 100644 > --- a/Documentation/technical/signature-format.txt > +++ b/Documentation/technical/signature-format.txt > @@ -184,3 +184,54 @@ Date: Wed Jun 15 09:13:29 2016 + > # gpg: There is no indication that the signature belongs to the > owner. > # Primary key fingerprint: D4BE 2231 1AD3 131E 5EDA 29A4 6109 2E85 B722 > 7189 > > + > +== Push certificates > + > +- created by: `git push --signed` > +- payload: a push certificate header followed by the push transcript > + (see pack-protocol.txt and below) > +- embedding: append the signature to the push transcript and pass it to > receive hooks > + via the environment (see below) > +- example: push of commit `dd1416f` updating `master` on `.` from `d36de3d`, > + resulting in push certificate object `d4169b9`: > + > + > +certificate version 0.1 > +pusher C O Mitter 1465983405 + > +pushee . > +nonce 1465983405-07421dc1515c6f4d76d4 > + > +d36de3db9b6a83076477254a3186b721a7bfaab7 > dd1416f2cd1ec85957a9520a33e9053a133a775d refs/heads/master > +-BEGIN PGP SIGNATURE- > +Version: GnuPG v1 > + > +iEYEABECAAYFAldhIa0ACgkQE7b1Hs3eQw2pGwCgmJs98xETSDZb6rooh/X7af3V > +zWgAn08ctVNga27jRkIdhFNetJy3x8De > +=WH0m > +-END PGP SIGNATURE- > + > + > +- verify with: `gpg --verify <(git cat-file -p pushcert | sed -n > '/-BEGIN PGP/,$p') <(git cat-file -p pushcert | sed '/-BEGIN PGP/Q')` > + (assuming the push certificate is stored in the blob tagged `pushcert`) And assuming your sed is GNU, assuming your shell is bash. Let's have a version of this without "verify with", finish that "generalized way to verify the 'payload followed by detached signature'" patch, and add a description to use that command here when it is done. > + > + > +gpg: Signature made Wed Jun 15 11:36:45 2016 CEST using DSA key ID CDDE430D > +gpg: Good signature from "C O Mitter " > + > + > +- pre- and post-receive hook input: > + > + > +d36de3db9b6a83076477254a3186b721a7bfaab7 > dd1416f2cd1ec85957a9520a33e9053a133a775d refs/heads/master > + > + > +- pre- and post-receive hook environment: > + > + > +GIT_PUSH_CERT_NONCE_STATUS=OK > +GIT_PUSH_CERT_KEY=13B6F51ECDDE430D > +GIT_PUSH_CERT=d4169b9a3c2674458f9656796132c145bbc5ba74 > +GIT_PUSH_CERT_STATUS=G > +GIT_PUSH_CERT_SIGNER=C O Mitter > +GIT_PUSH_CERT_NONCE=1465983405-07421dc1515c6f4d76d4 > + -- To unsubscribe from this list: send the line "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/4] add smudge-to-file and clean-from-file filter configuration
Joey Hesswrites: > Here's a revised version of the documentation that I think takes the other > suggestions onboard. I emphasise that clean and smudge operate as filters, > to contrast better with cleanFromFile and smudgeToFile not operating as > regular stdio filters. > ... > This could be extended more, but I think this should describe the config > settings concisely and point to the more involved discussion of filter drivers > in gitattributes. Yup. This version I can agree with. Thanks. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4] add smudge-to-file and clean-from-file filter configuration
Joey Hesswrites: > Or we could pick one of the two methods of appending the file > (I prefer not including a space before it as more flexible), and > anything using this interface would need to design its command line > parsing with this interface in mind, and would probably choose to use > --to-file=foo rather than --to-file foo. When I gave the example in the message you are responding to, I chose to assume that we will always have a space there, and this was to to avoid a problem that will become common if we did otherwise, namely: [filter "foo"] cleanFromFile = command which must be spelled as [filter "foo"] cleanFromFile = "command " to separate the command name with it argument if we didn't add the space there. I tend to agree with what you said in the other response, i.e. "Probably anything using this interface is gonna be implemented with the interface in mind from the beginning", so they will not have an issue if the interface always added a space there, and there is the "sh -c" thing if they really want to do something unusual. -- To unsubscribe from this list: send the line "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/4] add smudge-to-file and clean-from-file filter configuration
Junio C Hamano wrote: > Would an interface that always appends the pathname at the end of > the command line string work? One problem with this is that "appends" is subtly unclear in this case. With the example of smugeToFile = cmd --to-file it seems that a space should be added by git before the filename. On the other handle, consider smugeToFile = cmd --to-file= here a space is not wanted before the filename. So, either a space is automatically included before the filename and the second example breaks, or no space is included, and to make the first example work would need careful inclusion of the trailing space with quoting to prevent it being elided eg, smugeToFile = "cmd --to-file " %p does avoid this ambiguity. But as Junio noted, %p is mandatory in the command for it to possibly work. Git could refuse to use smugeToFile = cmd as not containing a %p and so not possibly being able to work. Or we could pick one of the two methods of appending the file (I prefer not including a space before it as more flexible), and anything using this interface would need to design its command line parsing with this interface in mind, and would probably choose to use --to-file=foo rather than --to-file foo. -- see shy jo signature.asc Description: PGP signature
Re: What's cooking in git.git (Jun 2016, #05; Thu, 16)
Junio C Hamano pobox.com> writes: > * va/i18n-even-more (2016-06-07) 38 commits > - i18n: branch: mark comment when editing branch description for translation > - i18n: unmark die messages for translation > - i18n: submodule: escape shell variables inside eval_gettext > - i18n: submodule: join strings marked for translation > - i18n: init-db: join message pieces [snip] > - i18n: builtin/remote.c: fix mark for translation > - Merge branch 'jc/t2300-setup' into HEAD Patch "i18n: init-db: join message pieces" breaks test t0204-gettext-reencode-sanity.sh because it changes message id used in Icelandic translation used on that test. Please, don't merge this series, I'm going to send a re-roll (v5). Discussion: http://mid.gmane.org/1562644.BnkjqA6nsN@linux-omuo -- To unsubscribe from this list: send the line "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 v4 34/38] i18n: init-db: join message pieces
A Terça, 7 de Junho de 2016 12:55:37 Vasco Almeida escreveu: > Join message displayed during repository initialization in one entire > sentence. That would improve translations since it's easier translate an > entire sentence than translating each piece. > > Signed-off-by: Vasco Almeida> --- > builtin/init-db.c | 17 ++--- > 1 file changed, 10 insertions(+), 7 deletions(-) > > diff --git a/builtin/init-db.c b/builtin/init-db.c > index b2d8d40..3a45f0b 100644 > --- a/builtin/init-db.c > +++ b/builtin/init-db.c > @@ -397,13 +397,16 @@ int init_db(const char *template_dir, unsigned int > flags) if (!(flags & INIT_DB_QUIET)) { > int len = strlen(git_dir); > > - /* TRANSLATORS: The first '%s' is either "Reinitialized > -existing" or "Initialized empty", the second " shared" or > -"", and the last '%s%s' is the verbatim directory name. */ > - printf(_("%s%s Git repository in %s%s\n"), > -reinit ? _("Reinitialized existing") : _("Initialized > empty"), > -get_shared_repository() ? _(" shared") : "", > -git_dir, len && git_dir[len-1] != '/' ? "/" : ""); > + if (reinit) > + printf(get_shared_repository() > +? _("Reinitialized existing shared Git > repository in %s%s\n") > +: _("Reinitialized existing Git repository in > %s%s\n"), > +git_dir, len && git_dir[len-1] != '/' ? "/" : > ""); > + else > + printf(get_shared_repository() > +? _("Initialized empty shared Git repository in > %s%s\n") > +: _("Initialized empty Git repository in > %s%s\n"), > +git_dir, len && git_dir[len-1] != '/' ? "/" : > ""); > } > > return 0; This patch breaks test t0204-gettext-reencode-sanity.sh because those strings are used in Icelandic translation for checking gettext. Since the message id has changed, git outputs in English instead of Icelandic. I must have forgot to check normal build (without GETTEXT_POISON enabled). I'm going to send a re-roll updating the Icelandic translation best I can or Ævar Arnfjörð Bjarmason could do it for me. -- To unsubscribe from this list: send the line "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/5] Documentation/technical: describe signature formats
Michael J Gruberwrites: > - We don't support verifying push certificates, although they fit in with > git verify-tag. Patch has been submitted, and this series documents the > result already (git verify-tag --blob). > > - We don' support verifying signed merge tags other than by using log/show, > which is not quite fit for scripting. Both true and are good things to tackle, I would think. It would be ideal if we can unify the latter with verification of signed commits. > - We have signature parsing code all over the place, including places that > should probably abstract more, such as tag.c and log-tree.c. Looking forward to see the result of that new abstraction. > - We may want to give more support for deciding about the trustworthiness > of signatures, the same way we export information to receive hooks > in the presence of push certificates. (Give information, don't decide.) Again, true. Thanks for starting this. > Michael J Gruber (5): > Documentation/technical: describe signature formats > Documentation/technical: signed tag format > Documentation/technical: signed commit format > Documentation/technical: signed merge tag format > Documentation/technical: push certificate format > > Documentation/Makefile | 1 + > Documentation/technical/signature-format.txt | 242 > +++ > 2 files changed, 243 insertions(+) > create mode 100644 Documentation/technical/signature-format.txt -- To unsubscribe from this list: send the line "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/4] add smudge-to-file and clean-from-file filter configuration
Junio C Hamano wrote: > Would an interface that always appends the pathname at the end of > the command line string work? I'm ok with this, and like getting rid of %p as it's not distinguishable from %f without reading the documentation. The sh -c trick can of course be used if some other ordering of parameters is needed. Probably anything using this interface is gonna be implemented with the interface in mind from the beginning and won't need such a trick. -- see shy jo signature.asc Description: PGP signature
Re: [PATCH 0/2] Log pretty format alignment improvements
Junio C Hamano wrote, on 16.6.2016 20:25: > "as long as >(N) can be used as Duy claims as a workaround to > get the original behaviour, it is good to allow using >|(N) > for this new output format; I didn't check if >(N) does behave > that way, though" Yes, it can be used in such way. Example: $ git log --format='%<(10)%t%<(20)%h.' -n 1 004419a 9ca73ba . $ git log --format='%<(10)%t%<|(30)%h.' -n 1 004419a 9ca73ba . Notice that dot is at exactly same column, because 10 + 20 == 30. The difference is when using --graph, because width of the graph is not known in advance. After the patch the graph width is included in %<(N). Original behavior is to not count with the graph width. signature.asc Description: OpenPGP digital signature