]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'js/neuter-sideband' into seen
authorJunio C Hamano <gitster@pobox.com>
Sat, 17 Jan 2026 18:37:36 +0000 (10:37 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sat, 17 Jan 2026 18:37:36 +0000 (10:37 -0800)
Invalidate control characters in sideband messages, to avoid
terminal state getting messed up.

* js/neuter-sideband:
  sideband: offer to configure sanitizing on a per-URL basis
  sideband: add options to allow more control sequences to be passed through
  sideband: do allow ANSI color sequences by default
  sideband: introduce an "escape hatch" to allow control characters
  sideband: mask control characters

1  2 
Documentation/config.adoc
Documentation/config/sideband.adoc
sideband.c
t/t5409-colorize-remote-messages.sh
transport.c

index 62eebe7c54501c5bfc9c408f5fcddef13612d29f,48870bb588eb95c76d59c46fe6a1fdea65132edb..dcea3c0c15e2a93d271adf4d1322763257bcc4f9
@@@ -373,188 -372,188 +373,190 @@@ inventing new variables for use in you
  names do not conflict with those that are used by Git itself and
  other popular tools, and describe them in your documentation.
  
 -include::config/add.txt[]
 +include::config/add.adoc[]
 +
 +include::config/advice.adoc[]
  
 -include::config/advice.txt[]
 +include::config/alias.adoc[]
  
 -include::config/alias.txt[]
 +include::config/am.adoc[]
  
 -include::config/am.txt[]
 +include::config/apply.adoc[]
  
 -include::config/apply.txt[]
 +include::config/attr.adoc[]
  
 -include::config/attr.txt[]
 +include::config/bitmap-pseudo-merge.adoc[]
  
 -include::config/bitmap-pseudo-merge.txt[]
 +include::config/blame.adoc[]
  
 -include::config/blame.txt[]
 +include::config/branch.adoc[]
  
 -include::config/branch.txt[]
 +include::config/browser.adoc[]
  
 -include::config/browser.txt[]
 +include::config/bundle.adoc[]
  
 -include::config/bundle.txt[]
 +include::config/checkout.adoc[]
  
 -include::config/checkout.txt[]
 +include::config/clean.adoc[]
  
 -include::config/clean.txt[]
 +include::config/clone.adoc[]
  
 -include::config/clone.txt[]
 +include::config/color.adoc[]
  
 -include::config/color.txt[]
 +include::config/column.adoc[]
  
 -include::config/column.txt[]
 +include::config/commit.adoc[]
  
 -include::config/commit.txt[]
 +include::config/commitgraph.adoc[]
  
 -include::config/commitgraph.txt[]
 +include::config/completion.adoc[]
  
 -include::config/completion.txt[]
 +include::config/core.adoc[]
  
 -include::config/core.txt[]
 +include::config/credential.adoc[]
  
 -include::config/credential.txt[]
 +include::config/diff.adoc[]
  
 -include::config/diff.txt[]
 +include::config/difftool.adoc[]
  
 -include::config/difftool.txt[]
 +include::config/extensions.adoc[]
  
 -include::config/extensions.txt[]
 +include::config/fastimport.adoc[]
  
 -include::config/fastimport.txt[]
 +include::config/feature.adoc[]
  
 -include::config/feature.txt[]
 +include::config/fetch.adoc[]
  
 -include::config/fetch.txt[]
 +include::config/filter.adoc[]
  
 -include::config/filter.txt[]
 +include::config/format.adoc[]
  
 -include::config/format.txt[]
 +include::config/fsck.adoc[]
  
 -include::config/fsck.txt[]
 +include::config/fsmonitor--daemon.adoc[]
  
 -include::config/fsmonitor--daemon.txt[]
 +include::config/gc.adoc[]
  
 -include::config/gc.txt[]
 +include::config/gitcvs.adoc[]
  
 -include::config/gitcvs.txt[]
 +include::config/gitweb.adoc[]
  
 -include::config/gitweb.txt[]
 +include::config/gpg.adoc[]
  
 -include::config/gpg.txt[]
 +include::config/grep.adoc[]
  
 -include::config/grep.txt[]
 +include::config/gui.adoc[]
  
 -include::config/gui.txt[]
 +include::config/guitool.adoc[]
  
 -include::config/guitool.txt[]
 +include::config/help.adoc[]
  
 -include::config/help.txt[]
 +include::config/http.adoc[]
  
 -include::config/http.txt[]
 +include::config/i18n.adoc[]
  
 -include::config/i18n.txt[]
 +include::config/imap.adoc[]
  
 -include::config/imap.txt[]
 +include::config/includeif.adoc[]
  
 -include::config/includeif.txt[]
 +include::config/index.adoc[]
  
 -include::config/index.txt[]
 +include::config/init.adoc[]
  
 -include::config/init.txt[]
 +include::config/instaweb.adoc[]
  
 -include::config/instaweb.txt[]
 +include::config/interactive.adoc[]
  
 -include::config/interactive.txt[]
 +include::config/log.adoc[]
  
 -include::config/log.txt[]
 +include::config/lsrefs.adoc[]
  
 -include::config/lsrefs.txt[]
 +include::config/mailinfo.adoc[]
  
 -include::config/mailinfo.txt[]
 +include::config/mailmap.adoc[]
  
 -include::config/mailmap.txt[]
 +include::config/maintenance.adoc[]
  
 -include::config/maintenance.txt[]
 +include::config/man.adoc[]
  
 -include::config/man.txt[]
 +include::config/merge.adoc[]
  
 -include::config/merge.txt[]
 +include::config/mergetool.adoc[]
  
 -include::config/mergetool.txt[]
 +include::config/notes.adoc[]
  
 -include::config/notes.txt[]
 +include::config/pack.adoc[]
  
 -include::config/pack.txt[]
 +include::config/pager.adoc[]
  
 -include::config/pager.txt[]
 +include::config/pretty.adoc[]
  
 -include::config/pretty.txt[]
 +include::config/promisor.adoc[]
  
 -include::config/promisor.txt[]
 +include::config/protocol.adoc[]
  
 -include::config/protocol.txt[]
 +include::config/pull.adoc[]
  
 -include::config/pull.txt[]
 +include::config/push.adoc[]
  
 -include::config/push.txt[]
 +include::config/rebase.adoc[]
  
 -include::config/rebase.txt[]
 +include::config/receive.adoc[]
  
 -include::config/receive.txt[]
 +include::config/reftable.adoc[]
  
 -include::config/reftable.txt[]
 +include::config/remote.adoc[]
  
 -include::config/remote.txt[]
 +include::config/remotes.adoc[]
  
 -include::config/remotes.txt[]
 +include::config/repack.adoc[]
  
 -include::config/repack.txt[]
 +include::config/rerere.adoc[]
  
 -include::config/rerere.txt[]
 +include::config/revert.adoc[]
  
 -include::config/revert.txt[]
 +include::config/safe.adoc[]
  
 -include::config/safe.txt[]
 +include::config/sendemail.adoc[]
  
 -include::config/sendemail.txt[]
 +include::config/sequencer.adoc[]
  
 -include::config/sequencer.txt[]
 +include::config/showbranch.adoc[]
  
 -include::config/showbranch.txt[]
++include::config/sideband.adoc[]
 -include::config/sideband.txt[]
 +include::config/sparse.adoc[]
  
 -include::config/sparse.txt[]
 +include::config/splitindex.adoc[]
  
 -include::config/splitindex.txt[]
 +include::config/ssh.adoc[]
  
 -include::config/ssh.txt[]
 +include::config/stash.adoc[]
  
 -include::config/stash.txt[]
 +include::config/status.adoc[]
  
 -include::config/status.txt[]
 +include::config/submodule.adoc[]
  
 -include::config/submodule.txt[]
 +include::config/tag.adoc[]
  
 -include::config/tag.txt[]
 +include::config/tar.adoc[]
  
 -include::config/tar.txt[]
 +include::config/trace2.adoc[]
  
 -include::config/trace2.txt[]
 +include::config/trailer.adoc[]
  
 -include::config/transfer.txt[]
 +include::config/transfer.adoc[]
  
 -include::config/uploadarchive.txt[]
 +include::config/uploadarchive.adoc[]
  
 -include::config/uploadpack.txt[]
 +include::config/uploadpack.adoc[]
  
 -include::config/url.txt[]
 +include::config/url.adoc[]
  
 -include::config/user.txt[]
 +include::config/user.adoc[]
  
 -include::config/versionsort.txt[]
 +include::config/versionsort.adoc[]
  
 -include::config/web.txt[]
 +include::config/web.adoc[]
  
 -include::config/worktree.txt[]
 +include::config/worktree.adoc[]
index 0000000000000000000000000000000000000000,32088bbf2f0a40e2a6b926e07df2e748067c1082..32088bbf2f0a40e2a6b926e07df2e748067c1082
mode 000000,100644..100644
--- /dev/null
diff --cc sideband.c
index ea7c25211ef7e1c8a80cb60475ee43457c8c13f1,a8cd142cd745d57f4013f43bbf5524a307af2239..67e12eb21a80967fa3c4f6b741abcb7f21f49a8f
@@@ -26,22 -26,111 +27,113 @@@ static struct keyword_entry keywords[] 
        { "error",      GIT_COLOR_BOLD_RED },
  };
  
 -      git_config(urlmatch_config_entry, &config);
+ static enum {
+       ALLOW_CONTROL_SEQUENCES_UNSET = -1,
+       ALLOW_NO_CONTROL_CHARACTERS   = 0,
+       ALLOW_ANSI_COLOR_SEQUENCES    = 1<<0,
+       ALLOW_ANSI_CURSOR_MOVEMENTS   = 1<<1,
+       ALLOW_ANSI_ERASE              = 1<<2,
+       ALLOW_DEFAULT_ANSI_SEQUENCES  = ALLOW_ANSI_COLOR_SEQUENCES,
+       ALLOW_ALL_CONTROL_CHARACTERS  = 1<<3,
+ } allow_control_characters = ALLOW_CONTROL_SEQUENCES_UNSET;
+ static inline int skip_prefix_in_csv(const char *value, const char *prefix,
+                                    const char **out)
+ {
+       if (!skip_prefix(value, prefix, &value) ||
+           (*value && *value != ','))
+               return 0;
+       *out = value + !!*value;
+       return 1;
+ }
+ int sideband_allow_control_characters_config(const char *var, const char *value)
+ {
+       switch (git_parse_maybe_bool(value)) {
+       case 0:
+               allow_control_characters = ALLOW_NO_CONTROL_CHARACTERS;
+               return 0;
+       case 1:
+               allow_control_characters = ALLOW_ALL_CONTROL_CHARACTERS;
+               return 0;
+       default:
+               break;
+       }
+       allow_control_characters = ALLOW_NO_CONTROL_CHARACTERS;
+       while (*value) {
+               if (skip_prefix_in_csv(value, "default", &value))
+                       allow_control_characters |= ALLOW_DEFAULT_ANSI_SEQUENCES;
+               else if (skip_prefix_in_csv(value, "color", &value))
+                       allow_control_characters |= ALLOW_ANSI_COLOR_SEQUENCES;
+               else if (skip_prefix_in_csv(value, "cursor", &value))
+                       allow_control_characters |= ALLOW_ANSI_CURSOR_MOVEMENTS;
+               else if (skip_prefix_in_csv(value, "erase", &value))
+                       allow_control_characters |= ALLOW_ANSI_ERASE;
+               else if (skip_prefix_in_csv(value, "true", &value))
+                       allow_control_characters = ALLOW_ALL_CONTROL_CHARACTERS;
+               else if (skip_prefix_in_csv(value, "false", &value))
+                       allow_control_characters = ALLOW_NO_CONTROL_CHARACTERS;
+               else
+                       warning(_("unrecognized value for '%s': '%s'"), var, value);
+       }
+       return 0;
+ }
+ static int sideband_config_callback(const char *var, const char *value,
+                                   const struct config_context *ctx UNUSED,
+                                   void *data UNUSED)
+ {
+       if (!strcmp(var, "sideband.allowcontrolcharacters"))
+               return sideband_allow_control_characters_config(var, value);
+       return 0;
+ }
+ void sideband_apply_url_config(const char *url)
+ {
+       struct urlmatch_config config = URLMATCH_CONFIG_INIT;
+       char *normalized_url;
+       if (!url)
+               BUG("must not call sideband_apply_url_config(NULL)");
+       config.section = "sideband";
+       config.collect_fn = sideband_config_callback;
+       normalized_url = url_normalize(url, &config.url);
++      repo_config(the_repository, urlmatch_config_entry, &config);
+       free(normalized_url);
+       string_list_clear(&config.vars, 1);
+       urlmatch_config_release(&config);
+ }
  /* Returns a color setting (GIT_COLOR_NEVER, etc). */
 -static int use_sideband_colors(void)
 +static enum git_colorbool use_sideband_colors(void)
  {
 -      static int use_sideband_colors_cached = -1;
 +      static enum git_colorbool use_sideband_colors_cached = GIT_COLOR_UNKNOWN;
  
        const char *key = "color.remote";
        struct strbuf sb = STRBUF_INIT;
        const char *value;
        int i;
  
 -      if (use_sideband_colors_cached >= 0)
 +      if (use_sideband_colors_cached != GIT_COLOR_UNKNOWN)
                return use_sideband_colors_cached;
  
 -              if (!git_config_get_value("sideband.allowcontrolcharacters", &value))
 -                      sideband_allow_control_characters_config("sideband.allowcontrolcharacters", value);
+       if (allow_control_characters == ALLOW_CONTROL_SEQUENCES_UNSET) {
 -      if (!git_config_get_string_tmp(key, &value))
++              if (!repo_config_get_value(the_repository,
++                                         "sideband.allowcontrolcharacters", &value))
++                      sideband_allow_control_characters_config(
++                              "sideband.allowcontrolcharacters", value);
+               if (allow_control_characters == ALLOW_CONTROL_SEQUENCES_UNSET)
+                       allow_control_characters = ALLOW_DEFAULT_ANSI_SEQUENCES;
+       }
 +      if (!repo_config_get_string_tmp(the_repository, key, &value))
                use_sideband_colors_cached = git_config_colorbool(key, value);
 -      else if (!git_config_get_string_tmp("color.ui", &value))
 +      else if (!repo_config_get_string_tmp(the_repository, "color.ui", &value))
                use_sideband_colors_cached = git_config_colorbool("color.ui", value);
        else
                use_sideband_colors_cached = GIT_COLOR_AUTO;
Simple merge
diff --cc transport.c
index c5830e2b3723cc5a794ebd821fbebb7fefc906fb,e19536c9c6b7eca6ae14629ac8ff76c015329055..df3bd23de49a4313e4dbe3deeb4e2cb10bf1d36f
@@@ -29,8 -28,9 +29,9 @@@
  #include "object-name.h"
  #include "color.h"
  #include "bundle-uri.h"
+ #include "sideband.h"
  
 -static int transport_use_color = -1;
 +static enum git_colorbool transport_use_color = GIT_COLOR_UNKNOWN;
  static char transport_colors[][COLOR_MAXLEN] = {
        GIT_COLOR_RESET,
        GIT_COLOR_RED           /* REJECTED */
@@@ -1244,8 -1209,10 +1245,10 @@@ struct transport *transport_get(struct 
                        ret->smart_options->receivepack = remote->receivepack;
        }
  
 -      ret->hash_algo = &hash_algos[GIT_HASH_SHA1];
 +      ret->hash_algo = &hash_algos[GIT_HASH_SHA1_LEGACY];
  
+       sideband_apply_url_config(ret->url);
        return ret;
  }