diff options
37 files changed, 434 insertions, 167 deletions
diff --git a/Documentation/Makefile b/Documentation/Makefile index 9c67c3a1c5..a6ba5bd460 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -191,14 +191,6 @@ MAN_BASE_URL = file://$(htmldir)/ endif XMLTO_EXTRA += -m manpage-base-url.xsl -# If your target system uses GNU groff, it may try to render -# apostrophes as a "pretty" apostrophe using unicode. This breaks -# cut&paste, so you should set GNU_ROFF to force them to be ASCII -# apostrophes. Unfortunately does not work with non-GNU roff. -ifdef GNU_ROFF -XMLTO_EXTRA += -m manpage-quote-apos.xsl -endif - ifdef USE_ASCIIDOCTOR ASCIIDOC = asciidoctor ASCIIDOC_CONF = diff --git a/Documentation/RelNotes/2.41.0.txt b/Documentation/RelNotes/2.41.0.txt index 5db6f1b0ef..05b755ac39 100644 --- a/Documentation/RelNotes/2.41.0.txt +++ b/Documentation/RelNotes/2.41.0.txt @@ -35,6 +35,9 @@ UI, Workflows & Features This is a backward compatibility breaking change. + * Lift the limitation that colored prompts can only be used with + PROMPT_COMMAND mode. + Performance, Internal Implementation, Development Support etc. @@ -49,6 +52,13 @@ Performance, Internal Implementation, Development Support etc. configuration variables, make the subsystem lazily initialize itself. + * Remove workaround for ancient versions of DocBook to make it work + correctly with groff, which has not been necessary since docbook + 1.76 from 2010. + + * Code clean-up to include and/or uninclude parse-options.h file as + needed. + Fixes since v2.40 ----------------- @@ -101,6 +111,31 @@ Fixes since v2.40 corrected. (merge c55c30669c ps/receive-pack-unlock-before-die later to maint). + * "git rev-parse --quiet foo@{u}", or anything that asks @{u} to be + parsed with GET_OID_QUIETLY option, did not quietly fail, which has + been corrected. + (merge dfbfdc521d fc/oid-quietly-parse-upstream later to maint). + + * Transports that do not support protocol v2 did not correctly fall + back to protocol v0 under certain conditions, which has been + corrected. + (merge eaa0fd6584 jk/fix-proto-downgrade-to-v0 later to maint). + + * time(2) on glib 2.31+, especially on Linux, goes out of sync with + higher resolution timers used for gettimeofday(2) and by the + filesystem. Replace all calls to it with a git_time() wrapper and + (merge 370ddcbc89 pe/time-use-gettimeofday later to maint). + + * Code clean-up to use designated initializers in parse-options API. + (merge 353e6d4554 sg/parse-options-h-initializers later to maint). + + * A recent-ish change to allow unicode character classes to be used + with "grep -P" triggered a JIT bug in older pcre2 libraries. + The problematic change in Git built with these older libraries has + been disabled to work around the bug. + (merge 14b9a04479 mk/workaround-pcre-jit-ucp-bug later to maint). + * Other code cleanup, docfix, build fix, etc. (merge f7111175df as/doc-markup-fix later to maint). (merge 90ff7c9898 fc/test-aggregation-clean-up later to maint). + (merge 9b0c7f308a jc/am-doc-refer-to-format-patch later to maint). diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt index 0c1dfb3c98..900be198b1 100644 --- a/Documentation/git-am.txt +++ b/Documentation/git-am.txt @@ -24,7 +24,9 @@ DESCRIPTION ----------- Splits mail messages in a mailbox into commit log message, authorship information and patches, and applies them to the -current branch. +current branch. You could think of it as a reverse operation +of linkgit:git-format-patch[1] run on a branch with a straight +history without merges. OPTIONS ------- @@ -273,7 +275,8 @@ include::config/am.txt[] SEE ALSO -------- -linkgit:git-apply[1]. +linkgit:git-apply[1], +linkgit:git-format-patch[1]. GIT --- diff --git a/Documentation/manpage-quote-apos.xsl b/Documentation/manpage-quote-apos.xsl deleted file mode 100644 index aeb8839f33..0000000000 --- a/Documentation/manpage-quote-apos.xsl +++ /dev/null @@ -1,16 +0,0 @@ -<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - version="1.0"> - -<!-- work around newer groff/man setups using a prettier apostrophe - that unfortunately does not quote anything when cut&pasting - examples to the shell --> -<xsl:template name="escape.apostrophe"> - <xsl:param name="content"/> - <xsl:call-template name="string.subst"> - <xsl:with-param name="string" select="$content"/> - <xsl:with-param name="target">'</xsl:with-param> - <xsl:with-param name="replacement">\(aq</xsl:with-param> - </xsl:call-template> -</xsl:template> - -</xsl:stylesheet> @@ -207,10 +207,6 @@ include shared.mak # Define NO_ST_BLOCKS_IN_STRUCT_STAT if your platform does not have st_blocks # field that counts the on-disk footprint in 512-byte blocks. # -# Define GNU_ROFF if your target system uses GNU groff. This forces -# apostrophes to be ASCII so that cut&pasting examples to the shell -# will work. -# # Define USE_ASCIIDOCTOR to use Asciidoctor instead of AsciiDoc to build the # documentation. # diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c index 702c9a3397..d1a4306da3 100644 --- a/builtin/fetch-pack.c +++ b/builtin/fetch-pack.c @@ -213,8 +213,8 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) int flags = args.verbose ? CONNECT_VERBOSE : 0; if (args.diag_url) flags |= CONNECT_DIAG_URL; - conn = git_connect(fd, dest, args.uploadpack, - flags); + conn = git_connect(fd, dest, "git-upload-pack", + args.uploadpack, flags); if (!conn) return args.diag_url ? 0 : 1; } diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c index 2dfbd8ed9b..a9de0575ce 100644 --- a/builtin/ls-remote.c +++ b/builtin/ls-remote.c @@ -5,6 +5,7 @@ #include "ref-filter.h" #include "remote.h" #include "refs.h" +#include "parse-options.h" static const char * const ls_remote_usage[] = { N_("git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n" diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 545b8bddc8..7e9e20172a 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -39,6 +39,7 @@ #include "shallow.h" #include "promisor-remote.h" #include "pack-mtimes.h" +#include "parse-options.h" /* * Objects we are going to pack are collected in the `to_pack` structure. diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index cccdb73807..554cda269d 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -31,6 +31,7 @@ #include "commit-reach.h" #include "worktree.h" #include "shallow.h" +#include "parse-options.h" static const char * const receive_pack_usage[] = { N_("git receive-pack <git-dir>"), diff --git a/builtin/reflog.c b/builtin/reflog.c index 270681dcdf..9b000bb6bc 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -4,6 +4,7 @@ #include "reachable.h" #include "worktree.h" #include "reflog.h" +#include "parse-options.h" #define BUILTIN_REFLOG_SHOW_USAGE \ N_("git reflog [show] [<log-options>] [<ref>]") diff --git a/builtin/send-pack.c b/builtin/send-pack.c index fb5b2bad2c..640125fe95 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -16,6 +16,7 @@ #include "gpg-interface.h" #include "gettext.h" #include "protocol.h" +#include "parse-options.h" static const char * const send_pack_usage[] = { N_("git send-pack [--mirror] [--dry-run] [--force]\n" @@ -274,7 +275,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) fd[0] = 0; fd[1] = 1; } else { - conn = git_connect(fd, dest, receivepack, + conn = git_connect(fd, dest, "git-receive-pack", receivepack, args.verbose ? CONNECT_VERBOSE : 0); } @@ -1408,6 +1408,7 @@ static void fill_ssh_args(struct child_process *conn, const char *ssh_host, * the connection failed). */ struct child_process *git_connect(int fd[2], const char *url, + const char *name, const char *prog, int flags) { char *hostandport, *path; @@ -1417,10 +1418,11 @@ struct child_process *git_connect(int fd[2], const char *url, /* * NEEDSWORK: If we are trying to use protocol v2 and we are planning - * to perform a push, then fallback to v0 since the client doesn't know - * how to push yet using v2. + * to perform any operation that doesn't involve upload-pack (i.e., a + * fetch, ls-remote, etc), then fallback to v0 since we don't know how + * to do anything else (like push or remote archive) via v2. */ - if (version == protocol_v2 && !strcmp("git-receive-pack", prog)) + if (version == protocol_v2 && strcmp("git-upload-pack", name)) version = protocol_v0; /* Without this we cannot rely on waitpid() to tell @@ -7,7 +7,7 @@ #define CONNECT_DIAG_URL (1u << 1) #define CONNECT_IPV4 (1u << 2) #define CONNECT_IPV6 (1u << 3) -struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags); +struct child_process *git_connect(int fd[2], const char *url, const char *name, const char *prog, int flags); int finish_connect(struct child_process *conn); int git_connection_is_socket(struct child_process *conn); int server_supports(const char *feature); diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 57972c2845..76ee4ab1e5 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -100,9 +100,7 @@ # # If you would like a colored hint about the current dirty state, set # GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on -# the colored output of "git status -sb" and are available only when -# using __git_ps1 for PROMPT_COMMAND or precmd in Bash, -# but always available in Zsh. +# the colored output of "git status -sb". # # If you would like __git_ps1 to do nothing in the case when the current # directory is set up to be ignored by git, then set @@ -259,12 +257,12 @@ __git_ps1_colorize_gitstring () local c_lblue='%F{blue}' local c_clear='%f' else - # Using \[ and \] around colors is necessary to prevent + # Using \001 and \002 around colors is necessary to prevent # issues with command line editing/browsing/completion! - local c_red='\[\e[31m\]' - local c_green='\[\e[32m\]' - local c_lblue='\[\e[1;34m\]' - local c_clear='\[\e[0m\]' + local c_red=$'\001\e[31m\002' + local c_green=$'\001\e[32m\002' + local c_lblue=$'\001\e[1;34m\002' + local c_clear=$'\001\e[0m\002' fi local bad_color=$c_red local ok_color=$c_green @@ -574,11 +572,8 @@ __git_ps1 () b="\${__git_ps1_branch_name}" fi - # NO color option unless in PROMPT_COMMAND mode or it's Zsh if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then - if [ $pcmode = yes ] || [ -n "${ZSH_VERSION-}" ]; then - __git_ps1_colorize_gitstring - fi + __git_ps1_colorize_gitstring fi local f="$h$w$i$s$u$p" diff --git a/diagnose.c b/diagnose.c index 5b398f0cff..998f517c48 100644 --- a/diagnose.c +++ b/diagnose.c @@ -8,6 +8,7 @@ #include "strvec.h" #include "object-store.h" #include "packfile.h" +#include "parse-options.h" struct archive_dir { const char *path; diff --git a/diagnose.h b/diagnose.h index 7a4951a786..f525219ab0 100644 --- a/diagnose.h +++ b/diagnose.h @@ -2,7 +2,8 @@ #define DIAGNOSE_H #include "strbuf.h" -#include "parse-options.h" + +struct option; enum diagnose_mode { DIAGNOSE_NONE, diff --git a/git-compat-util.h b/git-compat-util.h index 1e6592624d..4a200a9fb4 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -339,6 +339,25 @@ static inline const char *precompose_string_if_needed(const char *in) int compat_mkdir_wo_trailing_slash(const char*, mode_t); #endif +#ifdef time +#undef time +#endif +static inline time_t git_time(time_t *tloc) +{ + struct timeval tv; + + /* + * Avoid time(NULL), which can disagree with gettimeofday(2) + * and filesystem timestamps. + */ + gettimeofday(&tv, NULL); + + if (tloc) + *tloc = tv.tv_sec; + return tv.tv_sec; +} +#define time git_time + #ifdef NO_STRUCT_ITIMERVAL struct itimerval { struct timeval it_interval; @@ -321,6 +321,15 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt if (!opt->ignore_locale && is_utf8_locale() && !literal) options |= (PCRE2_UTF | PCRE2_UCP | PCRE2_MATCH_INVALID_UTF); +#ifndef GIT_PCRE2_VERSION_10_35_OR_HIGHER + /* + * Work around a JIT bug related to invalid Unicode character handling + * fixed in 10.35: + * https://github.com/PCRE2Project/pcre2/commit/c21bd977547d + */ + options &= ~PCRE2_UCP; +#endif + #ifndef GIT_PCRE2_VERSION_10_36_OR_HIGHER /* Work around https://bugs.exim.org/show_bug.cgi?id=2642 fixed in 10.36 */ if (PCRE2_MATCH_INVALID_UTF && options & (PCRE2_UTF | PCRE2_CASELESS)) @@ -7,6 +7,9 @@ #if (PCRE2_MAJOR >= 10 && PCRE2_MINOR >= 36) || PCRE2_MAJOR >= 11 #define GIT_PCRE2_VERSION_10_36_OR_HIGHER #endif +#if (PCRE2_MAJOR >= 10 && PCRE2_MINOR >= 35) || PCRE2_MAJOR >= 11 +#define GIT_PCRE2_VERSION_10_35_OR_HIGHER +#endif #if (PCRE2_MAJOR >= 10 && PCRE2_MINOR >= 34) || PCRE2_MAJOR >= 11 #define GIT_PCRE2_VERSION_10_34_OR_HIGHER #endif diff --git a/list-objects-filter-options.c b/list-objects-filter-options.c index 1d25a5737d..72aeb089cc 100644 --- a/list-objects-filter-options.c +++ b/list-objects-filter-options.c @@ -11,6 +11,7 @@ #include "promisor-remote.h" #include "trace.h" #include "url.h" +#include "parse-options.h" static int parse_combine_filter( struct list_objects_filter_options *filter_options, diff --git a/list-objects-filter-options.h b/list-objects-filter-options.h index ef03b45132..727c986122 100644 --- a/list-objects-filter-options.h +++ b/list-objects-filter-options.h @@ -2,10 +2,11 @@ #define LIST_OBJECTS_FILTER_OPTIONS_H #include "object.h" -#include "parse-options.h" #include "string-list.h" #include "strbuf.h" +struct option; + /* * The list of defined filters for list-objects. */ diff --git a/object-name.c b/object-name.c index 69db1ec498..61e8540f2e 100644 --- a/object-name.c +++ b/object-name.c @@ -899,6 +899,7 @@ static int get_oid_basic(struct repository *r, const char *str, int len, char *real_ref = NULL; int refs_found = 0; int at, reflog_len, nth_prior = 0; + int fatal = !(flags & GET_OID_QUIETLY); if (len == r->hash_algo->hexsz && !get_oid_hex(str, oid)) { if (warn_ambiguous_refs && warn_on_object_refname_ambiguity) { @@ -953,11 +954,11 @@ static int get_oid_basic(struct repository *r, const char *str, int len, if (!len && reflog_len) /* allow "@{...}" to mean the current branch reflog */ - refs_found = repo_dwim_ref(r, "HEAD", 4, oid, &real_ref, 0); + refs_found = repo_dwim_ref(r, "HEAD", 4, oid, &real_ref, !fatal); else if (reflog_len) refs_found = repo_dwim_log(r, str, len, oid, &real_ref); else - refs_found = repo_dwim_ref(r, str, len, oid, &real_ref, 0); + refs_found = repo_dwim_ref(r, str, len, oid, &real_ref, !fatal); if (!refs_found) return -1; diff --git a/parse-options.h b/parse-options.h index 50d852f299..26f19384e5 100644 --- a/parse-options.h +++ b/parse-options.h @@ -158,71 +158,202 @@ struct option { parse_opt_subcommand_fn *subcommand_fn; }; -#define OPT_BIT_F(s, l, v, h, b, f) { OPTION_BIT, (s), (l), (v), NULL, (h), \ - PARSE_OPT_NOARG|(f), NULL, (b) } -#define OPT_COUNTUP_F(s, l, v, h, f) { OPTION_COUNTUP, (s), (l), (v), NULL, \ - (h), PARSE_OPT_NOARG|(f) } -#define OPT_SET_INT_F(s, l, v, h, i, f) { OPTION_SET_INT, (s), (l), (v), NULL, \ - (h), PARSE_OPT_NOARG | (f), NULL, (i) } +#define OPT_BIT_F(s, l, v, h, b, f) { \ + .type = OPTION_BIT, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .help = (h), \ + .flags = PARSE_OPT_NOARG|(f), \ + .callback = NULL, \ + .defval = (b), \ +} +#define OPT_COUNTUP_F(s, l, v, h, f) { \ + .type = OPTION_COUNTUP, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .help = (h), \ + .flags = PARSE_OPT_NOARG|(f), \ +} +#define OPT_SET_INT_F(s, l, v, h, i, f) { \ + .type = OPTION_SET_INT, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .help = (h), \ + .flags = PARSE_OPT_NOARG | (f), \ + .defval = (i), \ +} #define OPT_BOOL_F(s, l, v, h, f) OPT_SET_INT_F(s, l, v, h, 1, f) -#define OPT_CALLBACK_F(s, l, v, a, h, f, cb) \ - { OPTION_CALLBACK, (s), (l), (v), (a), (h), (f), (cb) } -#define OPT_STRING_F(s, l, v, a, h, f) { OPTION_STRING, (s), (l), (v), (a), (h), (f) } -#define OPT_INTEGER_F(s, l, v, h, f) { OPTION_INTEGER, (s), (l), (v), N_("n"), (h), (f) } +#define OPT_CALLBACK_F(s, l, v, a, h, f, cb) { \ + .type = OPTION_CALLBACK, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .argh = (a), \ + .help = (h), \ + .flags = (f), \ + .callback = (cb), \ +} +#define OPT_STRING_F(s, l, v, a, h, f) { \ + .type = OPTION_STRING, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .argh = (a), \ + .help = (h), \ + .flags = (f), \ +} +#define OPT_INTEGER_F(s, l, v, h, f) { \ + .type = OPTION_INTEGER, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .argh = N_("n"), \ + .help = (h), \ + .flags = (f), \ +} -#define OPT_END() { OPTION_END } -#define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) } +#define OPT_END() { \ + .type = OPTION_END, \ +} +#define OPT_GROUP(h) { \ + .type = OPTION_GROUP, \ + .help = (h), \ +} #define OPT_BIT(s, l, v, h, b) OPT_BIT_F(s, l, v, h, b, 0) -#define OPT_BITOP(s, l, v, h, set, clear) { OPTION_BITOP, (s), (l), (v), NULL, (h), \ - PARSE_OPT_NOARG|PARSE_OPT_NONEG, NULL, \ - (set), NULL, (clear) } -#define OPT_NEGBIT(s, l, v, h, b) { OPTION_NEGBIT, (s), (l), (v), NULL, \ - (h), PARSE_OPT_NOARG, NULL, (b) } +#define OPT_BITOP(s, l, v, h, set, clear) { \ + .type = OPTION_BITOP, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .help = (h), \ + .flags = PARSE_OPT_NOARG|PARSE_OPT_NONEG, \ + .defval = (set), \ + .extra = (clear), \ +} +#define OPT_NEGBIT(s, l, v, h, b) { \ + .type = OPTION_NEGBIT, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .help = (h), \ + .flags = PARSE_OPT_NOARG, \ + .defval = (b), \ +} #define OPT_COUNTUP(s, l, v, h) OPT_COUNTUP_F(s, l, v, h, 0) #define OPT_SET_INT(s, l, v, h, i) OPT_SET_INT_F(s, l, v, h, i, 0) #define OPT_BOOL(s, l, v, h) OPT_BOOL_F(s, l, v, h, 0) -#define OPT_HIDDEN_BOOL(s, l, v, h) { OPTION_SET_INT, (s), (l), (v), NULL, \ - (h), PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1} -#define OPT_CMDMODE_F(s, l, v, h, i, f) { OPTION_SET_INT, (s), (l), (v), NULL, \ - (h), PARSE_OPT_CMDMODE|PARSE_OPT_NOARG|PARSE_OPT_NONEG | (f), NULL, (i) } +#define OPT_HIDDEN_BOOL(s, l, v, h) { \ + .type = OPTION_SET_INT, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .help = (h), \ + .flags = PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, \ + .defval = 1, \ +} +#define OPT_CMDMODE_F(s, l, v, h, i, f) { \ + .type = OPTION_SET_INT, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .help = (h), \ + .flags = PARSE_OPT_CMDMODE|PARSE_OPT_NOARG|PARSE_OPT_NONEG | (f), \ + .defval = (i), \ +} #define OPT_CMDMODE(s, l, v, h, i) OPT_CMDMODE_F(s, l, v, h, i, 0) #define OPT_INTEGER(s, l, v, h) OPT_INTEGER_F(s, l, v, h, 0) -#define OPT_MAGNITUDE(s, l, v, h) { OPTION_MAGNITUDE, (s), (l), (v), \ - N_("n"), (h), PARSE_OPT_NONEG } +#define OPT_MAGNITUDE(s, l, v, h) { \ + .type = OPTION_MAGNITUDE, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .argh = N_("n"), \ + .help = (h), \ + .flags = PARSE_OPT_NONEG, \ +} #define OPT_STRING(s, l, v, a, h) OPT_STRING_F(s, l, v, a, h, 0) -#define OPT_STRING_LIST(s, l, v, a, h) \ - { OPTION_CALLBACK, (s), (l), (v), (a), \ - (h), 0, &parse_opt_string_list } -#define OPT_UYN(s, l, v, h) { OPTION_CALLBACK, (s), (l), (v), NULL, \ - (h), PARSE_OPT_NOARG, &parse_opt_tertiary } -#define OPT_EXPIRY_DATE(s, l, v, h) \ - { OPTION_CALLBACK, (s), (l), (v), N_("expiry-date"),(h), 0, \ - parse_opt_expiry_date_cb } -#define OPT_CALLBACK(s, l, v, a, h, f) OPT_CALLBACK_F(s, l, v, a, h, 0, f) -#define OPT_NUMBER_CALLBACK(v, h, f) \ - { OPTION_NUMBER, 0, NULL, (v), NULL, (h), \ - PARSE_OPT_NOARG | PARSE_OPT_NONEG, (f) } -#define OPT_FILENAME(s, l, v, h) { OPTION_FILENAME, (s), (l), (v), \ - N_("file"), (h) } -#define OPT_COLOR_FLAG(s, l, v, h) \ - { OPTION_CALLBACK, (s), (l), (v), N_("when"), (h), PARSE_OPT_OPTARG, \ - parse_opt_color_flag_cb, (intptr_t)"always" } - -#define OPT_NOOP_NOARG(s, l) \ - { OPTION_CALLBACK, (s), (l), NULL, NULL, \ - N_("no-op (backward compatibility)"), \ - PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, parse_opt_noop_cb } - -#define OPT_ALIAS(s, l, source_long_name) \ - { OPTION_ALIAS, (s), (l), (source_long_name) } +#define OPT_STRING_LIST(s, l, v, a, h) { \ + .type = OPTION_CALLBACK, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .argh = (a), \ + .help = (h), \ + .callback = &parse_opt_string_list, \ +} +#define OPT_UYN(s, l, v, h) { \ + .type = OPTION_CALLBACK, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .help = (h), \ + .flags = PARSE_OPT_NOARG, \ + .callback = &parse_opt_tertiary, \ +} +#define OPT_EXPIRY_DATE(s, l, v, h) { \ + .type = OPTION_CALLBACK, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .argh = N_("expiry-date"), \ + .help = (h), \ + .callback = parse_opt_expiry_date_cb, \ +} +#define OPT_CALLBACK(s, l, v, a, h, cb) OPT_CALLBACK_F(s, l, v, a, h, 0, cb) +#define OPT_NUMBER_CALLBACK(v, h, cb) { \ + .type = OPTION_NUMBER, \ + .value = (v), \ + .help = (h), \ + .flags = PARSE_OPT_NOARG | PARSE_OPT_NONEG, \ + .callback = (cb), \ +} +#define OPT_FILENAME(s, l, v, h) { \ + .type = OPTION_FILENAME, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .argh = N_("file"), \ + .help = (h), \ +} +#define OPT_COLOR_FLAG(s, l, v, h) { \ + .type = OPTION_CALLBACK, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .argh = N_("when"), \ + .help = (h), \ + .flags = PARSE_OPT_OPTARG, \ + .callback = parse_opt_color_flag_cb, \ + .defval = (intptr_t)"always", \ +} + +#define OPT_NOOP_NOARG(s, l) { \ + .type = OPTION_CALLBACK, \ + .short_name = (s), \ + .long_name = (l), \ + .help = N_("no-op (backward compatibility)"), \ + .flags = PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, \ + .callback = parse_opt_noop_cb, \ +} + +#define OPT_ALIAS(s, l, source_long_name) { \ + .type = OPTION_ALIAS, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (source_long_name), \ +} #define OPT_SUBCOMMAND_F(l, v, fn, f) { \ .type = OPTION_SUBCOMMAND, \ .long_name = (l), \ .value = (v), \ .flags = (f), \ - .subcommand_fn = (fn) } + .subcommand_fn = (fn), \ +} #define OPT_SUBCOMMAND(l, v, fn) OPT_SUBCOMMAND_F((l), (v), (fn), 0) /* @@ -358,34 +489,80 @@ int parse_opt_tracking_mode(const struct option *, const char *, int); #define OPT__VERBOSE(var, h) OPT_COUNTUP('v', "verbose", (var), (h)) #define OPT__QUIET(var, h) OPT_COUNTUP('q', "quiet", (var), (h)) -#define OPT__VERBOSITY(var) \ - { OPTION_CALLBACK, 'v', "verbose", (var), NULL, N_("be more verbose"), \ - PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }, \ - { OPTION_CALLBACK, 'q', "quiet", (var), NULL, N_("be more quiet"), \ - PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 } +#define OPT__VERBOSITY(var) { \ + .type = OPTION_CALLBACK, \ + .short_name = 'v', \ + .long_name = "verbose", \ + .value = (var), \ + .help = N_("be more verbose"), \ + .flags = PARSE_OPT_NOARG, \ + .callback = &parse_opt_verbosity_cb, \ +}, { \ + .type = OPTION_CALLBACK, \ + .short_name = 'q', \ + .long_name = "quiet", \ + .value = (var), \ + .help = N_("be more quiet"), \ + .flags = PARSE_OPT_NOARG, \ + .callback = &parse_opt_verbosity_cb, \ +} #define OPT__DRY_RUN(var, h) OPT_BOOL('n', "dry-run", (var), (h)) #define OPT__FORCE(var, h, f) OPT_COUNTUP_F('f', "force", (var), (h), (f)) -#define OPT__ABBREV(var) \ - { OPTION_CALLBACK, 0, "abbrev", (var), N_("n"), \ - N_("use <n> digits to display object names"), \ - PARSE_OPT_OPTARG, &parse_opt_abbrev_cb, 0 } +#define OPT__ABBREV(var) { \ + .type = OPTION_CALLBACK, \ + .long_name = "abbrev", \ + .value = (var), \ + .argh = N_("n"), \ + .help = N_("use <n> digits to display object names"), \ + .flags = PARSE_OPT_OPTARG, \ + .callback = &parse_opt_abbrev_cb, \ +} #define OPT__SUPER_PREFIX(var) \ OPT_STRING_F(0, "super-prefix", (var), N_("prefix"), \ N_("prefixed path to initial superproject"), PARSE_OPT_HIDDEN) #define OPT__COLOR(var, h) \ OPT_COLOR_FLAG(0, "color", (var), (h)) -#define OPT_COLUMN(s, l, v, h) \ - { OPTION_CALLBACK, (s), (l), (v), N_("style"), (h), PARSE_OPT_OPTARG, parseopt_column_callback } -#define OPT_PASSTHRU(s, l, v, a, h, f) \ - { OPTION_CALLBACK, (s), (l), (v), (a), (h), (f), parse_opt_passthru } -#define OPT_PASSTHRU_ARGV(s, l, v, a, h, f) \ - { OPTION_CALLBACK, (s), (l), (v), (a), (h), (f), parse_opt_passthru_argv } -#define _OPT_CONTAINS_OR_WITH(name, variable, help, flag) \ - { OPTION_CALLBACK, 0, name, (variable), N_("commit"), (help), \ - PARSE_OPT_LASTARG_DEFAULT | flag, \ - parse_opt_commits, (intptr_t) "HEAD" \ - } +#define OPT_COLUMN(s, l, v, h) { \ + .type = OPTION_CALLBACK, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .argh = N_("style"), \ + .help = (h), \ + .flags = PARSE_OPT_OPTARG, \ + .callback = parseopt_column_callback, \ +} +#define OPT_PASSTHRU(s, l, v, a, h, f) { \ + .type = OPTION_CALLBACK, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .argh = (a), \ + .help = (h), \ + .flags = (f), \ + .callback = parse_opt_passthru, \ +} +#define OPT_PASSTHRU_ARGV(s, l, v, a, h, f) { \ + .type = OPTION_CALLBACK, \ + .short_name = (s), \ + .long_name = (l), \ + .value = (v), \ + .argh = (a), \ + .help = (h), \ + .flags = (f), \ + .callback = parse_opt_passthru_argv, \ +} +#define _OPT_CONTAINS_OR_WITH(l, v, h, f) { \ + .type = OPTION_CALLBACK, \ + .long_name = (l), \ + .value = (v), \ + .argh = N_("commit"), \ + .help = (h), \ + .flags = PARSE_OPT_LASTARG_DEFAULT | (f), \ + .callback = parse_opt_commits, \ + .defval = (intptr_t) "HEAD", \ +} #define OPT_CONTAINS(v, h) _OPT_CONTAINS_OR_WITH("contains", v, h, PARSE_OPT_NONEG) #define OPT_NO_CONTAINS(v, h) _OPT_CONTAINS_OR_WITH("no-contains", v, h, PARSE_OPT_NONEG) #define OPT_WITH(v, h) _OPT_CONTAINS_OR_WITH("with", v, h, PARSE_OPT_HIDDEN | PARSE_OPT_NONEG) diff --git a/ref-filter.h b/ref-filter.h index aa0eea4ecf..daa6d02017 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -4,7 +4,6 @@ #include "oid-array.h" #include "refs.h" #include "commit.h" -#include "parse-options.h" /* Quoting styles */ #define QUOTE_NONE 0 @@ -24,6 +23,7 @@ struct atom_value; struct ref_sorting; +struct option; enum ref_sorting_order { REF_SORTING_REVERSE = 1<<0, diff --git a/remote-curl.c b/remote-curl.c index ed7e3a043a..bf5a0b186f 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -474,10 +474,11 @@ static struct discovery *discover_refs(const char *service, int for_push) /* * NEEDSWORK: If we are trying to use protocol v2 and we are planning - * to perform a push, then fallback to v0 since the client doesn't know - * how to push yet using v2. + * to perform any operation that doesn't involve upload-pack (i.e., a + * fetch, ls-remote, etc), then fallback to v0 since we don't know how + * to do anything else (like push or remote archive) via v2. */ - if (version == protocol_v2 && !strcmp("git-receive-pack", service)) + if (version == protocol_v2 && strcmp("git-upload-pack", service)) version = protocol_v0; /* Add the extra Git-Protocol header */ @@ -17,6 +17,7 @@ #include "commit-reach.h" #include "advice.h" #include "connect.h" +#include "parse-options.h" enum map_direction { FROM_SRC, FROM_DST }; @@ -1,10 +1,10 @@ #ifndef REMOTE_H #define REMOTE_H -#include "parse-options.h" #include "hashmap.h" #include "refspec.h" +struct option; struct transport_ls_refs_options; /** diff --git a/revision.c b/revision.c index e4c066e90b..8b1ecf07fc 100644 --- a/revision.c +++ b/revision.c @@ -37,6 +37,7 @@ #include "json-writer.h" #include "list-objects-filter-options.h" #include "resolve-undo.h" +#include "parse-options.h" volatile show_early_output_fn_t show_early_output; diff --git a/revision.h b/revision.h index ab71443696..649f817f39 100644 --- a/revision.h +++ b/revision.h @@ -2,7 +2,6 @@ #define REVISION_H #include "commit.h" -#include "parse-options.h" #include "grep.h" #include "notes.h" #include "pretty.h" @@ -62,6 +61,8 @@ struct string_list; struct saved_parents; struct bloom_key; struct bloom_filter_settings; +struct option; +struct parse_opt_ctx_t; define_shared_commit_slab(revision_sources, char *); struct rev_cmdline_info { diff --git a/send-pack.c b/send-pack.c index 423a5cfe22..0d05191162 100644 --- a/send-pack.c +++ b/send-pack.c @@ -17,6 +17,7 @@ #include "gpg-interface.h" #include "cache.h" #include "shallow.h" +#include "parse-options.h" int option_parse_push_signed(const struct option *opt, const char *arg, int unset) diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh index c34714ffe3..549eb315a9 100755 --- a/t/t1507-rev-parse-upstream.sh +++ b/t/t1507-rev-parse-upstream.sh @@ -183,6 +183,11 @@ test_expect_success '@{u} error message when no upstream' ' test_cmp expect actual ' +test_expect_success '@{u} silent error when no upstream' ' + test_must_fail git rev-parse --verify --quiet @{u} 2>actual && + test_must_be_empty actual +' + test_expect_success 'branch@{u} error message with misspelt branch' ' cat >expect <<-EOF && fatal: no such branch: ${SQ}no-such-branch${SQ} diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index b8aaece860..3982b6b49d 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -7,12 +7,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh -if test_have_prereq !PERL -then - skip_all='skipping add -i (scripted) tests, perl not available' - test_done -fi - diff_cmp () { for x do diff --git a/t/t5563-simple-http-auth.sh b/t/t5563-simple-http-auth.sh index ccf7e54b07..f45a43b4b5 100755 --- a/t/t5563-simple-http-auth.sh +++ b/t/t5563-simple-http-auth.sh @@ -252,15 +252,14 @@ test_expect_success 'access using basic auth with wwwauth header empty continuat # Note that leading and trailing whitespace is important to correctly # simulate a continuation/folded header. - printf "">$CHALLENGE && - printf "WWW-Authenticate: FooBar param1=\"value1\"\r\n" >$CHALLENGE && - printf " \r\n" >>$CHALLENGE && - printf " param2=\"value2\"\r\n" >>$CHALLENGE && - printf "WWW-Authenticate: Bearer authorize_uri=\"id.example.com\"\r\n" >>$CHALLENGE && - printf " p=1\r\n" >>$CHALLENGE && - printf " \r\n" >>$CHALLENGE && - printf " q=0\r\n" >>$CHALLENGE && - printf "WWW-Authenticate: Basic realm=\"example.com\"\r\n" >>$CHALLENGE && + printf "WWW-Authenticate: FooBar param1=\"value1\"\r\n" >"$CHALLENGE" && + printf " \r\n" >>"$CHALLENGE" && + printf " param2=\"value2\"\r\n" >>"$CHALLENGE" && + printf "WWW-Authenticate: Bearer authorize_uri=\"id.example.com\"\r\n" >>"$CHALLENGE" && + printf " p=1\r\n" >>"$CHALLENGE" && + printf " \r\n" >>"$CHALLENGE" && + printf " q=0\r\n" >>"$CHALLENGE" && + printf "WWW-Authenticate: Basic realm=\"example.com\"\r\n" >>"$CHALLENGE" && test_config_global credential.helper test-helper && git ls-remote "$HTTPD_URL/custom_auth/repo.git" && @@ -298,11 +297,10 @@ test_expect_success 'access using basic auth with wwwauth header mixed line-endi # Note that leading and trailing whitespace is important to correctly # simulate a continuation/folded header. - printf "">$CHALLENGE && - printf "WWW-Authenticate: FooBar param1=\"value1\"\r\n" >$CHALLENGE && - printf " \r\n" >>$CHALLENGE && - printf "\tparam2=\"value2\"\r\n" >>$CHALLENGE && - printf "WWW-Authenticate: Basic realm=\"example.com\"" >>$CHALLENGE && + printf "WWW-Authenticate: FooBar param1=\"value1\"\r\n" >"$CHALLENGE" && + printf " \r\n" >>"$CHALLENGE" && + printf "\tparam2=\"value2\"\r\n" >>"$CHALLENGE" && + printf "WWW-Authenticate: Basic realm=\"example.com\"" >>"$CHALLENGE" && test_config_global credential.helper test-helper && git ls-remote "$HTTPD_URL/custom_auth/repo.git" && diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index e4db7513f4..71aabe30b7 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -728,6 +728,33 @@ test_expect_success 'file:// --negotiate-only with protocol v0' ' test_i18ngrep "negotiate-only requires protocol v2" err ' +test_expect_success 'push with custom path does not request v2' ' + rm -f env.trace && + git -C client push \ + --receive-pack="env >../env.trace; git-receive-pack" \ + origin HEAD:refs/heads/custom-push-test && + test_path_is_file env.trace && + ! grep ^GIT_PROTOCOL env.trace +' + +test_expect_success 'fetch with custom path does request v2' ' + rm -f env.trace && + git -C client fetch \ + --upload-pack="env >../env.trace; git-upload-pack" \ + origin HEAD && + grep ^GIT_PROTOCOL=version=2 env.trace +' + +test_expect_success 'archive with custom path does not request v2' ' + rm -f env.trace && + git -C client archive \ + --exec="env >../env.trace; git-upload-archive" \ + --remote=origin \ + HEAD >/dev/null && + test_path_is_file env.trace && + ! grep ^GIT_PROTOCOL env.trace +' + # Test protocol v2 with 'http://' transport # . "$TEST_DIRECTORY"/lib-httpd.sh diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh index d459fae655..d667dda654 100755 --- a/t/t9903-bash-prompt.sh +++ b/t/t9903-bash-prompt.sh @@ -13,10 +13,10 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME . "$GIT_BUILD_DIR/contrib/completion/git-prompt.sh" actual="$TRASH_DIRECTORY/actual" -c_red='\\[\\e[31m\\]' -c_green='\\[\\e[32m\\]' -c_lblue='\\[\\e[1;34m\\]' -c_clear='\\[\\e[0m\\]' +c_red='\001\e[31m\002' +c_green='\001\e[32m\002' +c_lblue='\001\e[1;34m\002' +c_clear='\001\e[0m\002' test_expect_success 'setup for prompt tests' ' git init otherrepo && diff --git a/transport.c b/transport.c index 906dbad5a0..fa9bc3be08 100644 --- a/transport.c +++ b/transport.c @@ -279,8 +279,12 @@ static int connect_setup(struct transport *transport, int for_push) } data->conn = git_connect(data->fd, transport->url, - for_push ? data->options.receivepack : - data->options.uploadpack, + for_push ? + "git-receive-pack" : + "git-upload-pack", + for_push ? + data->options.receivepack : + data->options.uploadpack, flags); return 0; @@ -914,7 +918,7 @@ static int connect_git(struct transport *transport, const char *name, { struct git_transport_data *data = transport->data; data->conn = git_connect(data->fd, transport->url, - executable, 0); + name, executable, 0); fd[0] = data->fd[0]; fd[1] = data->fd[1]; return 0; diff --git a/unicode-width.h b/unicode-width.h index 97c851b27d..e15fb0455b 100644 --- a/unicode-width.h +++ b/unicode-width.h @@ -94,7 +94,7 @@ static const struct interval zero_width[] = { { 0x0E47, 0x0E4E }, { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EBC }, -{ 0x0EC8, 0x0ECD }, +{ 0x0EC8, 0x0ECE }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, { 0x0F37, 0x0F37 }, @@ -228,6 +228,7 @@ static const struct interval zero_width[] = { { 0x10AE5, 0x10AE6 }, { 0x10D24, 0x10D27 }, { 0x10EAB, 0x10EAC }, +{ 0x10EFD, 0x10EFF }, { 0x10F46, 0x10F50 }, { 0x10F82, 0x10F85 }, { 0x11001, 0x11001 }, @@ -252,6 +253,7 @@ static const struct interval zero_width[] = { { 0x11234, 0x11234 }, { 0x11236, 0x11237 }, { 0x1123E, 0x1123E }, +{ 0x11241, 0x11241 }, { 0x112DF, 0x112DF }, { 0x112E3, 0x112EA }, { 0x11300, 0x11301 }, @@ -313,7 +315,12 @@ static const struct interval zero_width[] = { { 0x11D95, 0x11D95 }, { 0x11D97, 0x11D97 }, { 0x11EF3, 0x11EF4 }, -{ 0x13430, 0x13438 }, +{ 0x11F00, 0x11F01 }, +{ 0x11F36, 0x11F3A }, +{ 0x11F40, 0x11F40 }, +{ 0x11F42, 0x11F42 }, +{ 0x13430, 0x13440 }, +{ 0x13447, 0x13455 }, { 0x16AF0, 0x16AF4 }, { 0x16B30, 0x16B36 }, { 0x16F4F, 0x16F4F }, @@ -339,9 +346,11 @@ static const struct interval zero_width[] = { { 0x1E01B, 0x1E021 }, { 0x1E023, 0x1E024 }, { 0x1E026, 0x1E02A }, +{ 0x1E08F, 0x1E08F }, { 0x1E130, 0x1E136 }, { 0x1E2AE, 0x1E2AE }, { 0x1E2EC, 0x1E2EF }, +{ 0x1E4EC, 0x1E4EF }, { 0x1E8D0, 0x1E8D6 }, { 0x1E944, 0x1E94A }, { 0xE0001, 0xE0001 }, @@ -417,7 +426,9 @@ static const struct interval double_width[] = { { 0x1AFF5, 0x1AFFB }, { 0x1AFFD, 0x1AFFE }, { 0x1B000, 0x1B122 }, +{ 0x1B132, 0x1B132 }, { 0x1B150, 0x1B152 }, +{ 0x1B155, 0x1B155 }, { 0x1B164, 0x1B167 }, { 0x1B170, 0x1B2FB }, { 0x1F004, 0x1F004 }, @@ -451,7 +462,7 @@ static const struct interval double_width[] = { { 0x1F6CC, 0x1F6CC }, { 0x1F6D0, 0x1F6D2 }, { 0x1F6D5, 0x1F6D7 }, -{ 0x1F6DD, 0x1F6DF }, +{ 0x1F6DC, 0x1F6DF }, { 0x1F6EB, 0x1F6EC }, { 0x1F6F4, 0x1F6FC }, { 0x1F7E0, 0x1F7EB }, @@ -459,15 +470,13 @@ static const struct interval double_width[] = { { 0x1F90C, 0x1F93A }, { 0x1F93C, 0x1F945 }, { 0x1F947, 0x1F9FF }, -{ 0x1FA70, 0x1FA74 }, -{ 0x1FA78, 0x1FA7C }, -{ 0x1FA80, 0x1FA86 }, -{ 0x1FA90, 0x1FAAC }, -{ 0x1FAB0, 0x1FABA }, -{ 0x1FAC0, 0x1FAC5 }, -{ 0x1FAD0, 0x1FAD9 }, -{ 0x1FAE0, 0x1FAE7 }, -{ 0x1FAF0, 0x1FAF6 }, +{ 0x1FA70, 0x1FA7C }, +{ 0x1FA80, 0x1FA88 }, +{ 0x1FA90, 0x1FABD }, +{ 0x1FABF, 0x1FAC5 }, +{ 0x1FACE, 0x1FADB }, +{ 0x1FAE0, 0x1FAE8 }, +{ 0x1FAF0, 0x1FAF8 }, { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD } }; |
