548 newenv = dict(s.split(b'=', 1) for s in l) |
548 newenv = dict(s.split(b'=', 1) for s in l) |
549 except ValueError: |
549 except ValueError: |
550 raise ValueError(b'unexpected value in setenv request') |
550 raise ValueError(b'unexpected value in setenv request') |
551 self.ui.log(b'chgserver', b'setenv: %r\n', sorted(newenv.keys())) |
551 self.ui.log(b'chgserver', b'setenv: %r\n', sorted(newenv.keys())) |
552 |
552 |
553 # Python3 has some logic to "coerce" the C locale to a UTF-8 capable |
|
554 # one, and it sets LC_CTYPE in the environment to C.UTF-8 if none of |
|
555 # 'LC_CTYPE', 'LC_ALL' or 'LANG' are set (to any value). This can be |
|
556 # disabled with PYTHONCOERCECLOCALE=0 in the environment. |
|
557 # |
|
558 # When fromui is called via _inithashstate, python has already set |
|
559 # this, so that's in the environment right when we start up the hg |
|
560 # process. Then chg will call us and tell us to set the environment to |
|
561 # the one it has; this might NOT have LC_CTYPE, so we'll need to |
|
562 # carry-forward the LC_CTYPE that was coerced in these situations. |
|
563 # |
|
564 # If this is not handled, we will fail config+env validation and fail |
|
565 # to start chg. If this is just ignored instead of carried forward, we |
|
566 # may have different behavior between chg and non-chg. |
|
567 if pycompat.ispy3: |
|
568 # Rename for wordwrapping purposes |
|
569 oldenv = encoding.environ |
|
570 if not any( |
|
571 e.get(b'PYTHONCOERCECLOCALE') == b'0' for e in [oldenv, newenv] |
|
572 ): |
|
573 keys = [b'LC_CTYPE', b'LC_ALL', b'LANG'] |
|
574 old_keys = [k for k, v in oldenv.items() if k in keys and v] |
|
575 new_keys = [k for k, v in newenv.items() if k in keys and v] |
|
576 # If the user's environment (from chg) doesn't have ANY of the |
|
577 # keys that python looks for, and the environment (from |
|
578 # initialization) has ONLY LC_CTYPE and it's set to C.UTF-8, |
|
579 # carry it forward. |
|
580 if ( |
|
581 not new_keys |
|
582 and old_keys == [b'LC_CTYPE'] |
|
583 and oldenv[b'LC_CTYPE'] == b'C.UTF-8' |
|
584 ): |
|
585 newenv[b'LC_CTYPE'] = oldenv[b'LC_CTYPE'] |
|
586 |
|
587 encoding.environ.clear() |
553 encoding.environ.clear() |
588 encoding.environ.update(newenv) |
554 encoding.environ.update(newenv) |
589 |
555 |
590 capabilities = commandserver.server.capabilities.copy() |
556 capabilities = commandserver.server.capabilities.copy() |
591 capabilities.update( |
557 capabilities.update( |
728 # demandimport or detecting chg client started by chg client. When executed |
694 # demandimport or detecting chg client started by chg client. When executed |
729 # here, CHGINTERNALMARK is no longer useful and hence dropped to make |
695 # here, CHGINTERNALMARK is no longer useful and hence dropped to make |
730 # environ cleaner. |
696 # environ cleaner. |
731 if b'CHGINTERNALMARK' in encoding.environ: |
697 if b'CHGINTERNALMARK' in encoding.environ: |
732 del encoding.environ[b'CHGINTERNALMARK'] |
698 del encoding.environ[b'CHGINTERNALMARK'] |
|
699 # Python3.7+ "coerces" the LC_CTYPE environment variable to a UTF-8 one if |
|
700 # it thinks the current value is "C". This breaks the hash computation and |
|
701 # causes chg to restart loop. |
|
702 if b'CHGORIG_LC_CTYPE' in encoding.environ: |
|
703 encoding.environ[b'LC_CTYPE'] = encoding.environ[b'CHGORIG_LC_CTYPE'] |
|
704 del encoding.environ[b'CHGORIG_LC_CTYPE'] |
|
705 elif b'CHG_CLEAR_LC_CTYPE' in encoding.environ: |
|
706 if b'LC_CTYPE' in encoding.environ: |
|
707 del encoding.environ[b'LC_CTYPE'] |
|
708 del encoding.environ[b'CHG_CLEAR_LC_CTYPE'] |
733 |
709 |
734 if repo: |
710 if repo: |
735 # one chgserver can serve multiple repos. drop repo information |
711 # one chgserver can serve multiple repos. drop repo information |
736 ui.setconfig(b'bundle', b'mainreporoot', b'', b'repo') |
712 ui.setconfig(b'bundle', b'mainreporoot', b'', b'repo') |
737 h = chgunixservicehandler(ui) |
713 h = chgunixservicehandler(ui) |