##// END OF EJS Templates
branching: merge stable into default
Raphaël Gomès -
r51356:f57f5ab0 merge default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,245 +1,246 b''
1 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0 iD8DBQBEYmO2ywK+sNU5EO8RAnaYAKCO7x15xUn5mnhqWNXqk/ehlhRt2QCfRDfY0LrUq2q4oK/KypuJYPHgq1A=
1 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0 iD8DBQBEYmO2ywK+sNU5EO8RAnaYAKCO7x15xUn5mnhqWNXqk/ehlhRt2QCfRDfY0LrUq2q4oK/KypuJYPHgq1A=
2 2be3001847cb18a23c403439d9e7d0ace30804e9 0 iD8DBQBExUbjywK+sNU5EO8RAhzxAKCtyHAQUzcTSZTqlfJ0by6vhREwWQCghaQFHfkfN0l9/40EowNhuMOKnJk=
2 2be3001847cb18a23c403439d9e7d0ace30804e9 0 iD8DBQBExUbjywK+sNU5EO8RAhzxAKCtyHAQUzcTSZTqlfJ0by6vhREwWQCghaQFHfkfN0l9/40EowNhuMOKnJk=
3 36a957364b1b89c150f2d0e60a99befe0ee08bd3 0 iD8DBQBFfL2QywK+sNU5EO8RAjYFAKCoGlaWRTeMsjdmxAjUYx6diZxOBwCfY6IpBYsKvPTwB3oktnPt5Rmrlys=
3 36a957364b1b89c150f2d0e60a99befe0ee08bd3 0 iD8DBQBFfL2QywK+sNU5EO8RAjYFAKCoGlaWRTeMsjdmxAjUYx6diZxOBwCfY6IpBYsKvPTwB3oktnPt5Rmrlys=
4 27230c29bfec36d5540fbe1c976810aefecfd1d2 0 iD8DBQBFheweywK+sNU5EO8RAt7VAKCrqJQWT2/uo2RWf0ZI4bLp6v82jACgjrMdsaTbxRsypcmEsdPhlG6/8F4=
4 27230c29bfec36d5540fbe1c976810aefecfd1d2 0 iD8DBQBFheweywK+sNU5EO8RAt7VAKCrqJQWT2/uo2RWf0ZI4bLp6v82jACgjrMdsaTbxRsypcmEsdPhlG6/8F4=
5 fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0 iD8DBQBGgHicywK+sNU5EO8RAgNxAJ0VG8ixAaeudx4sZbhngI1syu49HQCeNUJQfWBgA8bkJ2pvsFpNxwYaX3I=
5 fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0 iD8DBQBGgHicywK+sNU5EO8RAgNxAJ0VG8ixAaeudx4sZbhngI1syu49HQCeNUJQfWBgA8bkJ2pvsFpNxwYaX3I=
6 23889160905a1b09fffe1c07378e9fc1827606eb 0 iD8DBQBHGTzoywK+sNU5EO8RAr/UAJ0Y8s4jQtzgS+G9vM8z6CWBThZ8fwCcCT5XDj2XwxKkz/0s6UELwjsO3LU=
6 23889160905a1b09fffe1c07378e9fc1827606eb 0 iD8DBQBHGTzoywK+sNU5EO8RAr/UAJ0Y8s4jQtzgS+G9vM8z6CWBThZ8fwCcCT5XDj2XwxKkz/0s6UELwjsO3LU=
7 bae2e9c838e90a393bae3973a7850280413e091a 0 iD8DBQBH6DO5ywK+sNU5EO8RAsfrAJ0e4r9c9GF/MJsM7Xjd3NesLRC3+ACffj6+6HXdZf8cswAoFPO+DY00oD0=
7 bae2e9c838e90a393bae3973a7850280413e091a 0 iD8DBQBH6DO5ywK+sNU5EO8RAsfrAJ0e4r9c9GF/MJsM7Xjd3NesLRC3+ACffj6+6HXdZf8cswAoFPO+DY00oD0=
8 d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 0 iD8DBQBINdwsywK+sNU5EO8RAjIUAKCPmlFJSpsPAAUKF+iNHAwVnwmzeQCdEXrL27CWclXuUKdbQC8De7LICtE=
8 d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 0 iD8DBQBINdwsywK+sNU5EO8RAjIUAKCPmlFJSpsPAAUKF+iNHAwVnwmzeQCdEXrL27CWclXuUKdbQC8De7LICtE=
9 d2375bbee6d47e62ba8e415c86e83a465dc4dce9 0 iD8DBQBIo1wpywK+sNU5EO8RAmRNAJ94x3OFt6blbqu/yBoypm/AJ44fuACfUaldXcV5z9tht97hSp22DVTEPGc=
9 d2375bbee6d47e62ba8e415c86e83a465dc4dce9 0 iD8DBQBIo1wpywK+sNU5EO8RAmRNAJ94x3OFt6blbqu/yBoypm/AJ44fuACfUaldXcV5z9tht97hSp22DVTEPGc=
10 2a67430f92f15ea5159c26b09ec4839a0c549a26 0 iEYEABECAAYFAkk1hykACgkQywK+sNU5EO85QACeNJNUanjc2tl4wUoPHNuv+lSj0ZMAoIm93wSTc/feyYnO2YCaQ1iyd9Nu
10 2a67430f92f15ea5159c26b09ec4839a0c549a26 0 iEYEABECAAYFAkk1hykACgkQywK+sNU5EO85QACeNJNUanjc2tl4wUoPHNuv+lSj0ZMAoIm93wSTc/feyYnO2YCaQ1iyd9Nu
11 3773e510d433969e277b1863c317b674cbee2065 0 iEYEABECAAYFAklNbbAACgkQywK+sNU5EO8o+gCfeb2/lfIJZMvyDA1m+G1CsBAxfFsAoIa6iAMG8SBY7hW1Q85Yf/LXEvaE
11 3773e510d433969e277b1863c317b674cbee2065 0 iEYEABECAAYFAklNbbAACgkQywK+sNU5EO8o+gCfeb2/lfIJZMvyDA1m+G1CsBAxfFsAoIa6iAMG8SBY7hW1Q85Yf/LXEvaE
12 11a4eb81fb4f4742451591489e2797dc47903277 0 iEYEABECAAYFAklcAnsACgkQywK+sNU5EO+uXwCbBVHNNsLy1g7BlAyQJwadYVyHOXoAoKvtAVO71+bv7EbVoukwTzT+P4Sx
12 11a4eb81fb4f4742451591489e2797dc47903277 0 iEYEABECAAYFAklcAnsACgkQywK+sNU5EO+uXwCbBVHNNsLy1g7BlAyQJwadYVyHOXoAoKvtAVO71+bv7EbVoukwTzT+P4Sx
13 11efa41037e280d08cfb07c09ad485df30fb0ea8 0 iEYEABECAAYFAkmvJRQACgkQywK+sNU5EO9XZwCeLMgDgPSMWMm6vgjL4lDs2pEc5+0AnRxfiFbpbBfuEFTqKz9nbzeyoBlx
13 11efa41037e280d08cfb07c09ad485df30fb0ea8 0 iEYEABECAAYFAkmvJRQACgkQywK+sNU5EO9XZwCeLMgDgPSMWMm6vgjL4lDs2pEc5+0AnRxfiFbpbBfuEFTqKz9nbzeyoBlx
14 02981000012e3adf40c4849bd7b3d5618f9ce82d 0 iEYEABECAAYFAknEH3wACgkQywK+sNU5EO+uXwCeI+LbLMmhjU1lKSfU3UWJHjjUC7oAoIZLvYDGOL/tNZFUuatc3RnZ2eje
14 02981000012e3adf40c4849bd7b3d5618f9ce82d 0 iEYEABECAAYFAknEH3wACgkQywK+sNU5EO+uXwCeI+LbLMmhjU1lKSfU3UWJHjjUC7oAoIZLvYDGOL/tNZFUuatc3RnZ2eje
15 196d40e7c885fa6e95f89134809b3ec7bdbca34b 0 iEYEABECAAYFAkpL2X4ACgkQywK+sNU5EO9FOwCfXJycjyKJXsvQqKkHrglwOQhEKS4An36GfKzptfN8b1qNc3+ya/5c2WOM
15 196d40e7c885fa6e95f89134809b3ec7bdbca34b 0 iEYEABECAAYFAkpL2X4ACgkQywK+sNU5EO9FOwCfXJycjyKJXsvQqKkHrglwOQhEKS4An36GfKzptfN8b1qNc3+ya/5c2WOM
16 3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 0 iEYEABECAAYFAkpopLIACgkQywK+sNU5EO8QSgCfZ0ztsd071rOa2lhmp9Fyue/WoI0AoLTei80/xrhRlB8L/rZEf2KBl8dA
16 3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 0 iEYEABECAAYFAkpopLIACgkQywK+sNU5EO8QSgCfZ0ztsd071rOa2lhmp9Fyue/WoI0AoLTei80/xrhRlB8L/rZEf2KBl8dA
17 31ec469f9b556f11819937cf68ee53f2be927ebf 0 iEYEABECAAYFAksBuxAACgkQywK+sNU5EO+mBwCfagB+A0txzWZ6dRpug3LEoK7Z1QsAoKpbk8vsLjv6/oRDicSk/qBu33+m
17 31ec469f9b556f11819937cf68ee53f2be927ebf 0 iEYEABECAAYFAksBuxAACgkQywK+sNU5EO+mBwCfagB+A0txzWZ6dRpug3LEoK7Z1QsAoKpbk8vsLjv6/oRDicSk/qBu33+m
18 439d7ea6fe3aa4ab9ec274a68846779153789de9 0 iEYEABECAAYFAksVw0kACgkQywK+sNU5EO/oZwCfdfBEkgp38xq6wN2F4nj+SzofrJIAnjmxt04vaJSeOOeHylHvk6lzuQsw
18 439d7ea6fe3aa4ab9ec274a68846779153789de9 0 iEYEABECAAYFAksVw0kACgkQywK+sNU5EO/oZwCfdfBEkgp38xq6wN2F4nj+SzofrJIAnjmxt04vaJSeOOeHylHvk6lzuQsw
19 296a0b14a68621f6990c54fdba0083f6f20935bf 0 iEYEABECAAYFAks+jCoACgkQywK+sNU5EO9J8wCeMUGF9E/gS2UBsqIz56WS4HMPRPUAoI5J95mwEIK8Clrl7qFRidNI6APq
19 296a0b14a68621f6990c54fdba0083f6f20935bf 0 iEYEABECAAYFAks+jCoACgkQywK+sNU5EO9J8wCeMUGF9E/gS2UBsqIz56WS4HMPRPUAoI5J95mwEIK8Clrl7qFRidNI6APq
20 4aa619c4c2c09907034d9824ebb1dd0e878206eb 0 iEYEABECAAYFAktm9IsACgkQywK+sNU5EO9XGgCgk4HclRQhexEtooPE5GcUCdB6M8EAn2ptOhMVbIoO+JncA+tNACPFXh0O
20 4aa619c4c2c09907034d9824ebb1dd0e878206eb 0 iEYEABECAAYFAktm9IsACgkQywK+sNU5EO9XGgCgk4HclRQhexEtooPE5GcUCdB6M8EAn2ptOhMVbIoO+JncA+tNACPFXh0O
21 ff2704a8ded37fbebd8b6eb5ec733731d725da8a 0 iEYEABECAAYFAkuRoSQACgkQywK+sNU5EO//3QCeJDc5r2uFyFCtAlpSA27DEE5rrxAAn2FSwTy9fhrB3QAdDQlwkEZcQzDh
21 ff2704a8ded37fbebd8b6eb5ec733731d725da8a 0 iEYEABECAAYFAkuRoSQACgkQywK+sNU5EO//3QCeJDc5r2uFyFCtAlpSA27DEE5rrxAAn2FSwTy9fhrB3QAdDQlwkEZcQzDh
22 2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 0 iEYEABECAAYFAku1IwIACgkQywK+sNU5EO9MjgCdHLVwkTZlNHxhcznZKBL1rjN+J7cAoLLWi9LTL6f/TgBaPSKOy1ublbaW
22 2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 0 iEYEABECAAYFAku1IwIACgkQywK+sNU5EO9MjgCdHLVwkTZlNHxhcznZKBL1rjN+J7cAoLLWi9LTL6f/TgBaPSKOy1ublbaW
23 39f725929f0c48c5fb3b90c071fc3066012456ca 0 iEYEABECAAYFAkvclvsACgkQywK+sNU5EO9FSwCeL9i5x8ALW/LE5+lCX6MFEAe4MhwAn1ev5o6SX6GrNdDfKweiemfO2VBk
23 39f725929f0c48c5fb3b90c071fc3066012456ca 0 iEYEABECAAYFAkvclvsACgkQywK+sNU5EO9FSwCeL9i5x8ALW/LE5+lCX6MFEAe4MhwAn1ev5o6SX6GrNdDfKweiemfO2VBk
24 fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 0 iEYEABECAAYFAkvsKTkACgkQywK+sNU5EO9qEACgiSiRGvTG2vXGJ65tUSOIYihTuFAAnRzRIqEVSw8M8/RGeUXRps0IzaCO
24 fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 0 iEYEABECAAYFAkvsKTkACgkQywK+sNU5EO9qEACgiSiRGvTG2vXGJ65tUSOIYihTuFAAnRzRIqEVSw8M8/RGeUXRps0IzaCO
25 24fe2629c6fd0c74c90bd066e77387c2b02e8437 0 iEYEABECAAYFAkwFLRsACgkQywK+sNU5EO+pJACgp13tPI+pbwKZV+LeMjcQ4H6tCZYAoJebzhd6a8yYx6qiwpJxA9BXZNXy
25 24fe2629c6fd0c74c90bd066e77387c2b02e8437 0 iEYEABECAAYFAkwFLRsACgkQywK+sNU5EO+pJACgp13tPI+pbwKZV+LeMjcQ4H6tCZYAoJebzhd6a8yYx6qiwpJxA9BXZNXy
26 f786fc4b8764cd2a5526d259cf2f94d8a66924d9 0 iEYEABECAAYFAkwsyxcACgkQywK+sNU5EO+crACfUpNAF57PmClkSri9nJcBjb2goN4AniPCNaKvnki7TnUsi1u2oxltpKKL
26 f786fc4b8764cd2a5526d259cf2f94d8a66924d9 0 iEYEABECAAYFAkwsyxcACgkQywK+sNU5EO+crACfUpNAF57PmClkSri9nJcBjb2goN4AniPCNaKvnki7TnUsi1u2oxltpKKL
27 bf1774d95bde614af3956d92b20e2a0c68c5fec7 0 iEYEABECAAYFAkxVwccACgkQywK+sNU5EO+oFQCeJzwZ+we1fIIyBGCddHceOUAN++cAnjvT6A8ZWW0zV21NXIFF1qQmjxJd
27 bf1774d95bde614af3956d92b20e2a0c68c5fec7 0 iEYEABECAAYFAkxVwccACgkQywK+sNU5EO+oFQCeJzwZ+we1fIIyBGCddHceOUAN++cAnjvT6A8ZWW0zV21NXIFF1qQmjxJd
28 c00f03a4982e467fb6b6bd45908767db6df4771d 0 iEYEABECAAYFAkxXDqsACgkQywK+sNU5EO/GJACfT9Rz4hZOxPQEs91JwtmfjevO84gAmwSmtfo5mmWSm8gtTUebCcdTv0Kf
28 c00f03a4982e467fb6b6bd45908767db6df4771d 0 iEYEABECAAYFAkxXDqsACgkQywK+sNU5EO/GJACfT9Rz4hZOxPQEs91JwtmfjevO84gAmwSmtfo5mmWSm8gtTUebCcdTv0Kf
29 ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 0 iD8DBQBMdo+qywK+sNU5EO8RAqQpAJ975BL2CCAiWMz9SXthNQ9xG181IwCgp4O+KViHPkufZVFn2aTKMNvcr1A=
29 ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 0 iD8DBQBMdo+qywK+sNU5EO8RAqQpAJ975BL2CCAiWMz9SXthNQ9xG181IwCgp4O+KViHPkufZVFn2aTKMNvcr1A=
30 93d8bff78c96fe7e33237b257558ee97290048a4 0 iD8DBQBMpfvdywK+sNU5EO8RAsxVAJ0UaL1XB51C76JUBhafc9GBefuMxwCdEWkTOzwvE0SarJBe9i008jhbqW4=
30 93d8bff78c96fe7e33237b257558ee97290048a4 0 iD8DBQBMpfvdywK+sNU5EO8RAsxVAJ0UaL1XB51C76JUBhafc9GBefuMxwCdEWkTOzwvE0SarJBe9i008jhbqW4=
31 333421b9e0f96c7bc788e5667c146a58a9440a55 0 iD8DBQBMz0HOywK+sNU5EO8RAlsEAJ0USh6yOG7OrWkADGunVt9QimBQnwCbBqeMnKgSbwEw8jZwE3Iz1mdrYlo=
31 333421b9e0f96c7bc788e5667c146a58a9440a55 0 iD8DBQBMz0HOywK+sNU5EO8RAlsEAJ0USh6yOG7OrWkADGunVt9QimBQnwCbBqeMnKgSbwEw8jZwE3Iz1mdrYlo=
32 4438875ec01bd0fc32be92b0872eb6daeed4d44f 0 iD8DBQBM4WYUywK+sNU5EO8RAhCVAJ0dJswachwFAHALmk1x0RJehxzqPQCbBNskP9n/X689jB+btNTZTyKU/fw=
32 4438875ec01bd0fc32be92b0872eb6daeed4d44f 0 iD8DBQBM4WYUywK+sNU5EO8RAhCVAJ0dJswachwFAHALmk1x0RJehxzqPQCbBNskP9n/X689jB+btNTZTyKU/fw=
33 6aff4f144ad356311318b0011df0bb21f2c97429 0 iD8DBQBM9uxXywK+sNU5EO8RAv+4AKCDj4qKP16GdPaq1tP6BUwpM/M1OACfRyzLPp/qiiN8xJTWoWYSe/XjJug=
33 6aff4f144ad356311318b0011df0bb21f2c97429 0 iD8DBQBM9uxXywK+sNU5EO8RAv+4AKCDj4qKP16GdPaq1tP6BUwpM/M1OACfRyzLPp/qiiN8xJTWoWYSe/XjJug=
34 e3bf16703e2601de99e563cdb3a5d50b64e6d320 0 iD8DBQBNH8WqywK+sNU5EO8RAiQTAJ9sBO+TeiGro4si77VVaQaA6jcRUgCfSA28dBbjj0oFoQwvPoZjANiZBH8=
34 e3bf16703e2601de99e563cdb3a5d50b64e6d320 0 iD8DBQBNH8WqywK+sNU5EO8RAiQTAJ9sBO+TeiGro4si77VVaQaA6jcRUgCfSA28dBbjj0oFoQwvPoZjANiZBH8=
35 a6c855c32ea081da3c3b8ff628f1847ff271482f 0 iD8DBQBNSJJ+ywK+sNU5EO8RAoJaAKCweDEF70fu+r1Zn7pYDXdlk5RuSgCeO9gK/eit8Lin/1n3pO7aYguFLok=
35 a6c855c32ea081da3c3b8ff628f1847ff271482f 0 iD8DBQBNSJJ+ywK+sNU5EO8RAoJaAKCweDEF70fu+r1Zn7pYDXdlk5RuSgCeO9gK/eit8Lin/1n3pO7aYguFLok=
36 2b2155623ee2559caf288fd333f30475966c4525 0 iD8DBQBNSJeBywK+sNU5EO8RAm1KAJ4hW9Cm9nHaaGJguchBaPLlAr+O3wCgqgmMok8bdAS06N6PL60PSTM//Gg=
36 2b2155623ee2559caf288fd333f30475966c4525 0 iD8DBQBNSJeBywK+sNU5EO8RAm1KAJ4hW9Cm9nHaaGJguchBaPLlAr+O3wCgqgmMok8bdAS06N6PL60PSTM//Gg=
37 2616325766e3504c8ae7c84bd15ee610901fe91d 0 iD8DBQBNbWy9ywK+sNU5EO8RAlWCAJ4mW8HbzjJj9GpK98muX7k+7EvEHwCfaTLbC/DH3QEsZBhEP+M8tzL6RU4=
37 2616325766e3504c8ae7c84bd15ee610901fe91d 0 iD8DBQBNbWy9ywK+sNU5EO8RAlWCAJ4mW8HbzjJj9GpK98muX7k+7EvEHwCfaTLbC/DH3QEsZBhEP+M8tzL6RU4=
38 aa1f3be38ab127280761889d2dca906ca465b5f4 0 iD8DBQBNeQq7ywK+sNU5EO8RAlEOAJ4tlEDdetE9lKfjGgjbkcR8PrC3egCfXCfF3qNVvU/2YYjpgvRwevjvDy0=
38 aa1f3be38ab127280761889d2dca906ca465b5f4 0 iD8DBQBNeQq7ywK+sNU5EO8RAlEOAJ4tlEDdetE9lKfjGgjbkcR8PrC3egCfXCfF3qNVvU/2YYjpgvRwevjvDy0=
39 b032bec2c0a651ca0ddecb65714bfe6770f67d70 0 iD8DBQBNlg5kywK+sNU5EO8RAnGEAJ9gmEx6MfaR4XcG2m/93vwtfyzs3gCgltzx8/YdHPwqDwRX/WbpYgi33is=
39 b032bec2c0a651ca0ddecb65714bfe6770f67d70 0 iD8DBQBNlg5kywK+sNU5EO8RAnGEAJ9gmEx6MfaR4XcG2m/93vwtfyzs3gCgltzx8/YdHPwqDwRX/WbpYgi33is=
40 3cb1e95676ad089596bd81d0937cad37d6e3b7fb 0 iD8DBQBNvTy4ywK+sNU5EO8RAmp8AJ9QnxK4jTJ7G722MyeBxf0UXEdGwACgtlM7BKtNQfbEH/fOW5y+45W88VI=
40 3cb1e95676ad089596bd81d0937cad37d6e3b7fb 0 iD8DBQBNvTy4ywK+sNU5EO8RAmp8AJ9QnxK4jTJ7G722MyeBxf0UXEdGwACgtlM7BKtNQfbEH/fOW5y+45W88VI=
41 733af5d9f6b22387913e1d11350fb8cb7c1487dd 0 iD8DBQBN5q/8ywK+sNU5EO8RArRGAKCNGT94GKIYtSuwZ57z1sQbcw6uLACfffpbMV4NAPMl8womAwg+7ZPKnIU=
41 733af5d9f6b22387913e1d11350fb8cb7c1487dd 0 iD8DBQBN5q/8ywK+sNU5EO8RArRGAKCNGT94GKIYtSuwZ57z1sQbcw6uLACfffpbMV4NAPMl8womAwg+7ZPKnIU=
42 de9eb6b1da4fc522b1cab16d86ca166204c24f25 0 iD8DBQBODhfhywK+sNU5EO8RAr2+AJ4ugbAj8ae8/K0bYZzx3sascIAg1QCeK3b+zbbVVqd3b7CDpwFnaX8kTd4=
42 de9eb6b1da4fc522b1cab16d86ca166204c24f25 0 iD8DBQBODhfhywK+sNU5EO8RAr2+AJ4ugbAj8ae8/K0bYZzx3sascIAg1QCeK3b+zbbVVqd3b7CDpwFnaX8kTd4=
43 4a43e23b8c55b4566b8200bf69fe2158485a2634 0 iD8DBQBONzIMywK+sNU5EO8RAj5SAJ0aPS3+JHnyI6bHB2Fl0LImbDmagwCdGbDLp1S7TFobxXudOH49bX45Iik=
43 4a43e23b8c55b4566b8200bf69fe2158485a2634 0 iD8DBQBONzIMywK+sNU5EO8RAj5SAJ0aPS3+JHnyI6bHB2Fl0LImbDmagwCdGbDLp1S7TFobxXudOH49bX45Iik=
44 d629f1e89021103f1753addcef6b310e4435b184 0 iD8DBQBOWAsBywK+sNU5EO8RAht4AJwJl9oNFopuGkj5m8aKuf7bqPkoAQCeNrEm7UhFsZKYT5iUOjnMV7s2LaM=
44 d629f1e89021103f1753addcef6b310e4435b184 0 iD8DBQBOWAsBywK+sNU5EO8RAht4AJwJl9oNFopuGkj5m8aKuf7bqPkoAQCeNrEm7UhFsZKYT5iUOjnMV7s2LaM=
45 351a9292e430e35766c552066ed3e87c557b803b 0 iD8DBQBOh3zUywK+sNU5EO8RApFMAKCD3Y/u3avDFndznwqfG5UeTHMlvACfUivPIVQZyDZnhZMq0UhC6zhCEQg=
45 351a9292e430e35766c552066ed3e87c557b803b 0 iD8DBQBOh3zUywK+sNU5EO8RApFMAKCD3Y/u3avDFndznwqfG5UeTHMlvACfUivPIVQZyDZnhZMq0UhC6zhCEQg=
46 384082750f2c51dc917d85a7145748330fa6ef4d 0 iD8DBQBOmd+OywK+sNU5EO8RAgDgAJ9V/X+G7VLwhTpHrZNiOHabzSyzYQCdE2kKfIevJUYB9QLAWCWP6DPwrwI=
46 384082750f2c51dc917d85a7145748330fa6ef4d 0 iD8DBQBOmd+OywK+sNU5EO8RAgDgAJ9V/X+G7VLwhTpHrZNiOHabzSyzYQCdE2kKfIevJUYB9QLAWCWP6DPwrwI=
47 41453d55b481ddfcc1dacb445179649e24ca861d 0 iD8DBQBOsFhpywK+sNU5EO8RAqM6AKCyfxUae3/zLuiLdQz+JR78690eMACfQ6JTBQib4AbE+rUDdkeFYg9K/+4=
47 41453d55b481ddfcc1dacb445179649e24ca861d 0 iD8DBQBOsFhpywK+sNU5EO8RAqM6AKCyfxUae3/zLuiLdQz+JR78690eMACfQ6JTBQib4AbE+rUDdkeFYg9K/+4=
48 195dbd1cef0c2f9f8bcf4ea303238105f716bda3 0 iD8DBQBO1/fWywK+sNU5EO8RAmoPAKCR5lpv1D6JLURHD8KVLSV4GRVEBgCgnd0Sy78ligNfqAMafmACRDvj7vo=
48 195dbd1cef0c2f9f8bcf4ea303238105f716bda3 0 iD8DBQBO1/fWywK+sNU5EO8RAmoPAKCR5lpv1D6JLURHD8KVLSV4GRVEBgCgnd0Sy78ligNfqAMafmACRDvj7vo=
49 6344043924497cd06d781d9014c66802285072e4 0 iD8DBQBPALgmywK+sNU5EO8RAlfhAJ9nYOdWnhfVDHYtDTJAyJtXBAQS9wCgnefoSQt7QABkbGxM+Q85UYEBuD0=
49 6344043924497cd06d781d9014c66802285072e4 0 iD8DBQBPALgmywK+sNU5EO8RAlfhAJ9nYOdWnhfVDHYtDTJAyJtXBAQS9wCgnefoSQt7QABkbGxM+Q85UYEBuD0=
50 db33555eafeaf9df1e18950e29439eaa706d399b 0 iD8DBQBPGdzxywK+sNU5EO8RAppkAJ9jOXhUVE/97CPgiMA0pMGiIYnesQCfengAszcBiSiKGugiI8Okc9ghU+Y=
50 db33555eafeaf9df1e18950e29439eaa706d399b 0 iD8DBQBPGdzxywK+sNU5EO8RAppkAJ9jOXhUVE/97CPgiMA0pMGiIYnesQCfengAszcBiSiKGugiI8Okc9ghU+Y=
51 2aa5b51f310fb3befd26bed99c02267f5c12c734 0 iD8DBQBPKZ9bywK+sNU5EO8RAt1TAJ45r1eJ0YqSkInzrrayg4TVCh0SnQCgm0GA/Ua74jnnDwVQ60lAwROuz1Q=
51 2aa5b51f310fb3befd26bed99c02267f5c12c734 0 iD8DBQBPKZ9bywK+sNU5EO8RAt1TAJ45r1eJ0YqSkInzrrayg4TVCh0SnQCgm0GA/Ua74jnnDwVQ60lAwROuz1Q=
52 53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 0 iD8DBQBPT/fvywK+sNU5EO8RAnfYAKCn7d0vwqIb100YfWm1F7nFD5B+FACeM02YHpQLSNsztrBCObtqcnfod7Q=
52 53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 0 iD8DBQBPT/fvywK+sNU5EO8RAnfYAKCn7d0vwqIb100YfWm1F7nFD5B+FACeM02YHpQLSNsztrBCObtqcnfod7Q=
53 b9bd95e61b49c221c4cca24e6da7c946fc02f992 0 iD8DBQBPeLsIywK+sNU5EO8RAvpNAKCtKe2gitz8dYn52IRF0hFOPCR7AQCfRJL/RWCFweu2T1vH/mUOCf8SXXc=
53 b9bd95e61b49c221c4cca24e6da7c946fc02f992 0 iD8DBQBPeLsIywK+sNU5EO8RAvpNAKCtKe2gitz8dYn52IRF0hFOPCR7AQCfRJL/RWCFweu2T1vH/mUOCf8SXXc=
54 d9e2f09d5488c395ae9ddbb320ceacd24757e055 0 iD8DBQBPju/dywK+sNU5EO8RArBYAJ9xtifdbk+hCOJO8OZa4JfHX8OYZQCeKPMBaBWiT8N/WHoOm1XU0q+iono=
54 d9e2f09d5488c395ae9ddbb320ceacd24757e055 0 iD8DBQBPju/dywK+sNU5EO8RArBYAJ9xtifdbk+hCOJO8OZa4JfHX8OYZQCeKPMBaBWiT8N/WHoOm1XU0q+iono=
55 00182b3d087909e3c3ae44761efecdde8f319ef3 0 iD8DBQBPoFhIywK+sNU5EO8RAhzhAKCBj1n2jxPTkZNJJ5pSp3soa+XHIgCgsZZpAQxOpXwCp0eCdNGe0+pmxmg=
55 00182b3d087909e3c3ae44761efecdde8f319ef3 0 iD8DBQBPoFhIywK+sNU5EO8RAhzhAKCBj1n2jxPTkZNJJ5pSp3soa+XHIgCgsZZpAQxOpXwCp0eCdNGe0+pmxmg=
56 5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 0 iD8DBQBPovNWywK+sNU5EO8RAhgiAJ980T91FdPTRMmVONDhpkMsZwVIMACgg3bKvoWSeuCW28llUhAJtUjrMv0=
56 5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 0 iD8DBQBPovNWywK+sNU5EO8RAhgiAJ980T91FdPTRMmVONDhpkMsZwVIMACgg3bKvoWSeuCW28llUhAJtUjrMv0=
57 85a358df5bbbe404ca25730c9c459b34263441dc 0 iD8DBQBPyZsWywK+sNU5EO8RAnpLAJ48qrGDJRT+pteS0mSQ11haqHstPwCdG4ccGbk+0JHb7aNy8/NRGAOqn9w=
57 85a358df5bbbe404ca25730c9c459b34263441dc 0 iD8DBQBPyZsWywK+sNU5EO8RAnpLAJ48qrGDJRT+pteS0mSQ11haqHstPwCdG4ccGbk+0JHb7aNy8/NRGAOqn9w=
58 b013baa3898e117959984fc64c29d8c784d2f28b 0 iD8DBQBP8QOPywK+sNU5EO8RAqimAKCFRSx0lvG6y8vne2IhNG062Hn0dACeMLI5/zhpWpHBIVeAAquYfx2XFeA=
58 b013baa3898e117959984fc64c29d8c784d2f28b 0 iD8DBQBP8QOPywK+sNU5EO8RAqimAKCFRSx0lvG6y8vne2IhNG062Hn0dACeMLI5/zhpWpHBIVeAAquYfx2XFeA=
59 7f5094bb3f423fc799e471aac2aee81a7ce57a0b 0 iD8DBQBQGiL8ywK+sNU5EO8RAq5oAJ4rMMCPx6O+OuzNXVOexogedWz/QgCeIiIxLd76I4pXO48tdXhr0hQcBuM=
59 7f5094bb3f423fc799e471aac2aee81a7ce57a0b 0 iD8DBQBQGiL8ywK+sNU5EO8RAq5oAJ4rMMCPx6O+OuzNXVOexogedWz/QgCeIiIxLd76I4pXO48tdXhr0hQcBuM=
60 072209ae4ddb654eb2d5fd35bff358c738414432 0 iD8DBQBQQkq0ywK+sNU5EO8RArDTAJ9nk5CySnNAjAXYvqvx4uWCw9ThZwCgqmFRehH/l+oTwj3f8nw8u8qTCdc=
60 072209ae4ddb654eb2d5fd35bff358c738414432 0 iD8DBQBQQkq0ywK+sNU5EO8RArDTAJ9nk5CySnNAjAXYvqvx4uWCw9ThZwCgqmFRehH/l+oTwj3f8nw8u8qTCdc=
61 b3f0f9a39c4e1d0250048cd803ab03542d6f140a 0 iD8DBQBQamltywK+sNU5EO8RAlsqAJ4qF/m6aFu4mJCOKTiAP5RvZFK02ACfawYShUZO6OXEFfveU0aAxDR0M1k=
61 b3f0f9a39c4e1d0250048cd803ab03542d6f140a 0 iD8DBQBQamltywK+sNU5EO8RAlsqAJ4qF/m6aFu4mJCOKTiAP5RvZFK02ACfawYShUZO6OXEFfveU0aAxDR0M1k=
62 d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 0 iD8DBQBQgPV5ywK+sNU5EO8RArylAJ0abcx5NlDjyv3ZDWpAfRIHyRsJtQCgn4TMuEayqgxzrvadQZHdTEU2g38=
62 d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 0 iD8DBQBQgPV5ywK+sNU5EO8RArylAJ0abcx5NlDjyv3ZDWpAfRIHyRsJtQCgn4TMuEayqgxzrvadQZHdTEU2g38=
63 195ad823b5d58c68903a6153a25e3fb4ed25239d 0 iD8DBQBQkuT9ywK+sNU5EO8RAhB4AKCeerItoK2Jipm2cVf4euGofAa/WACeJj3TVd4pFILpb+ogj7ebweFLJi0=
63 195ad823b5d58c68903a6153a25e3fb4ed25239d 0 iD8DBQBQkuT9ywK+sNU5EO8RAhB4AKCeerItoK2Jipm2cVf4euGofAa/WACeJj3TVd4pFILpb+ogj7ebweFLJi0=
64 0c10cf8191469e7c3c8844922e17e71a176cb7cb 0 iD8DBQBQvQWoywK+sNU5EO8RAnq3AJoCn98u4geFx5YaQaeh99gFhCd7bQCgjoBwBSUyOvGd0yBy60E3Vv3VZhM=
64 0c10cf8191469e7c3c8844922e17e71a176cb7cb 0 iD8DBQBQvQWoywK+sNU5EO8RAnq3AJoCn98u4geFx5YaQaeh99gFhCd7bQCgjoBwBSUyOvGd0yBy60E3Vv3VZhM=
65 a4765077b65e6ae29ba42bab7834717b5072d5ba 0 iD8DBQBQ486sywK+sNU5EO8RAhmJAJ90aLfLKZhmcZN7kqphigQJxiFOQACeJ5IUZxjGKH4xzi3MrgIcx9n+dB0=
65 a4765077b65e6ae29ba42bab7834717b5072d5ba 0 iD8DBQBQ486sywK+sNU5EO8RAhmJAJ90aLfLKZhmcZN7kqphigQJxiFOQACeJ5IUZxjGKH4xzi3MrgIcx9n+dB0=
66 f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 0 iD8DBQBQ+yuYywK+sNU5EO8RAm9JAJoD/UciWvpGeKBcpGtZJBFJVcL/HACghDXSgQ+xQDjB+6uGrdgAQsRR1Lg=
66 f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 0 iD8DBQBQ+yuYywK+sNU5EO8RAm9JAJoD/UciWvpGeKBcpGtZJBFJVcL/HACghDXSgQ+xQDjB+6uGrdgAQsRR1Lg=
67 a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 0 iD8DBQBRDDROywK+sNU5EO8RAh75AJ9uJCGoCWnP0Lv/+XuYs4hvUl+sAgCcD36QgAnuw8IQXrvv684BAXAnHcA=
67 a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 0 iD8DBQBRDDROywK+sNU5EO8RAh75AJ9uJCGoCWnP0Lv/+XuYs4hvUl+sAgCcD36QgAnuw8IQXrvv684BAXAnHcA=
68 7511d4df752e61fe7ae4f3682e0a0008573b0402 0 iD8DBQBRFYaoywK+sNU5EO8RAuErAJoDyhXn+lptU3+AevVdwAIeNFyR2gCdHzPHyWd+JDeWCUR+pSOBi8O2ppM=
68 7511d4df752e61fe7ae4f3682e0a0008573b0402 0 iD8DBQBRFYaoywK+sNU5EO8RAuErAJoDyhXn+lptU3+AevVdwAIeNFyR2gCdHzPHyWd+JDeWCUR+pSOBi8O2ppM=
69 5b7175377babacce80a6c1e12366d8032a6d4340 0 iD8DBQBRMCYgywK+sNU5EO8RAq1/AKCWKlt9ysibyQgYwoxxIOZv5J8rpwCcDSHQaaf1fFZUTnQsOePwcM2Y/Sg=
69 5b7175377babacce80a6c1e12366d8032a6d4340 0 iD8DBQBRMCYgywK+sNU5EO8RAq1/AKCWKlt9ysibyQgYwoxxIOZv5J8rpwCcDSHQaaf1fFZUTnQsOePwcM2Y/Sg=
70 50c922c1b5145dab8baefefb0437d363b6a6c21c 0 iD8DBQBRWnUnywK+sNU5EO8RAuQRAJwM42cJqJPeqJ0jVNdMqKMDqr4dSACeP0cRVGz1gitMuV0x8f3mrZrqc7I=
70 50c922c1b5145dab8baefefb0437d363b6a6c21c 0 iD8DBQBRWnUnywK+sNU5EO8RAuQRAJwM42cJqJPeqJ0jVNdMqKMDqr4dSACeP0cRVGz1gitMuV0x8f3mrZrqc7I=
71 8a7bd2dccd44ed571afe7424cd7f95594f27c092 0 iD8DBQBRXfBvywK+sNU5EO8RAn+LAKCsMmflbuXjYRxlzFwId5ptm8TZcwCdGkyLbZcASBOkzQUm/WW1qfknJHU=
71 8a7bd2dccd44ed571afe7424cd7f95594f27c092 0 iD8DBQBRXfBvywK+sNU5EO8RAn+LAKCsMmflbuXjYRxlzFwId5ptm8TZcwCdGkyLbZcASBOkzQUm/WW1qfknJHU=
72 292cd385856d98bacb2c3086f8897bc660c2beea 0 iD8DBQBRcM0BywK+sNU5EO8RAjp4AKCJBykQbvXhKuvLSMxKx3a2TBiXcACfbr/kLg5GlZTF/XDPmY+PyHgI/GM=
72 292cd385856d98bacb2c3086f8897bc660c2beea 0 iD8DBQBRcM0BywK+sNU5EO8RAjp4AKCJBykQbvXhKuvLSMxKx3a2TBiXcACfbr/kLg5GlZTF/XDPmY+PyHgI/GM=
73 23f785b38af38d2fca6b8f3db56b8007a84cd73a 0 iD8DBQBRgZwNywK+sNU5EO8RAmO4AJ4u2ILGuimRP6MJgE2t65LZ5dAdkACgiENEstIdrlFC80p+sWKD81kKIYI=
73 23f785b38af38d2fca6b8f3db56b8007a84cd73a 0 iD8DBQBRgZwNywK+sNU5EO8RAmO4AJ4u2ILGuimRP6MJgE2t65LZ5dAdkACgiENEstIdrlFC80p+sWKD81kKIYI=
74 ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 0 iD8DBQBRkswvywK+sNU5EO8RAiYYAJsHTHyHbJeAgmGvBTmDrfcKu4doUgCeLm7eGBjx7yAPUvEtxef8rAkQmXI=
74 ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 0 iD8DBQBRkswvywK+sNU5EO8RAiYYAJsHTHyHbJeAgmGvBTmDrfcKu4doUgCeLm7eGBjx7yAPUvEtxef8rAkQmXI=
75 cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 0 iD8DBQBRqnFLywK+sNU5EO8RAsWNAJ9RR6t+y1DLFc2HeH0eN9VfZAKF9gCeJ8ezvhtKq/LMs0/nvcgKQc/d5jk=
75 cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 0 iD8DBQBRqnFLywK+sNU5EO8RAsWNAJ9RR6t+y1DLFc2HeH0eN9VfZAKF9gCeJ8ezvhtKq/LMs0/nvcgKQc/d5jk=
76 009794acc6e37a650f0fae37872e733382ac1c0c 0 iD8DBQBR0guxywK+sNU5EO8RArNkAKCq9pMihVzP8Os5kCmgbWpe5C37wgCgqzuPZTHvAsXF5wTyaSTMVa9Ccq4=
76 009794acc6e37a650f0fae37872e733382ac1c0c 0 iD8DBQBR0guxywK+sNU5EO8RArNkAKCq9pMihVzP8Os5kCmgbWpe5C37wgCgqzuPZTHvAsXF5wTyaSTMVa9Ccq4=
77 f0d7721d7322dcfb5af33599c2543f27335334bb 0 iD8DBQBR8taaywK+sNU5EO8RAqeEAJ4idDhhDuEsgsUjeQgWNj498matHACfT67gSF5w0ylsrBx1Hb52HkGXDm0=
77 f0d7721d7322dcfb5af33599c2543f27335334bb 0 iD8DBQBR8taaywK+sNU5EO8RAqeEAJ4idDhhDuEsgsUjeQgWNj498matHACfT67gSF5w0ylsrBx1Hb52HkGXDm0=
78 f37b5a17e6a0ee17afde2cdde5393dd74715fb58 0 iD8DBQBR+ymFywK+sNU5EO8RAuSdAJkBMcd9DAZ3rWE9WGKPm2YZ8LBoXACfXn/wbEsVy7ZgJoUwiWmHSnQaWCI=
78 f37b5a17e6a0ee17afde2cdde5393dd74715fb58 0 iD8DBQBR+ymFywK+sNU5EO8RAuSdAJkBMcd9DAZ3rWE9WGKPm2YZ8LBoXACfXn/wbEsVy7ZgJoUwiWmHSnQaWCI=
79 335a558f81dc73afeab4d7be63617392b130117f 0 iQIVAwUAUiZrIyBXgaxoKi1yAQK2iw//cquNqqSkc8Re5/TZT9I6NH+lh6DbOKjJP0Xl1Wqq0K+KSIUgZG4G32ovaEb2l5X0uY+3unRPiZ0ebl0YSw4Fb2ZiPIADXLBTOYRrY2Wwd3tpJeGI6wEgZt3SfcITV/g7NJrCjT3FlYoSOIayrExM80InSdcEM0Q3Rx6HKzY2acyxzgZeAtAW5ohFvHilSvY6p5Gcm4+QptMxvw45GPdreUmjeXZxNXNXZ8P+MjMz/QJbai/N7PjmK8lqnhkBsT48Ng/KhhmOkGntNJ2/ImBWLFGcWngSvJ7sfWwnyhndvGhe0Hq1NcCf7I8TjNDxU5TR+m+uW7xjXdLoDbUjBdX4sKXnh8ZjbYiODKBOrrDq25cf8nA/tnpKyE/qsVy60kOk6loY4XKiYmn1V49Ta0emmDx0hqo3HgxHHsHX0NDnGdWGol7cPRET0RzVobKq1A0jnrhPooWidvLh9bPzLonrWDo+ib+DuySoRkuYUK4pgZJ2mbg6daFOBEZygkSyRB8bo1UQUP7EgQDrWe4khb/5GHEfDkrQz3qu/sXvc0Ir1mOUWBFPHC2DjjCn/oMJuUkG1SwM8l2Bfv7h67ssES6YQ2+RjOix4yid7EXS/Ogl45PzCIPSI5+BbNs10JhE0w5uErBHlF53EDTe/TSLc+GU6DB6PP6dH912Njdr3jpNSUQ=
79 335a558f81dc73afeab4d7be63617392b130117f 0 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
@@ -1,261 +1,262 b''
1 d40cc5aacc31ed673d9b5b24f98bee78c283062c 0.4f
1 d40cc5aacc31ed673d9b5b24f98bee78c283062c 0.4f
2 1c590d34bf61e2ea12c71738e5a746cd74586157 0.4e
2 1c590d34bf61e2ea12c71738e5a746cd74586157 0.4e
3 7eca4cfa8aad5fce9a04f7d8acadcd0452e2f34e 0.4d
3 7eca4cfa8aad5fce9a04f7d8acadcd0452e2f34e 0.4d
4 b4d0c3786ad3e47beacf8412157326a32b6d25a4 0.4c
4 b4d0c3786ad3e47beacf8412157326a32b6d25a4 0.4c
5 f40273b0ad7b3a6d3012fd37736d0611f41ecf54 0.5
5 f40273b0ad7b3a6d3012fd37736d0611f41ecf54 0.5
6 0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 0.5b
6 0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 0.5b
7 12e0fdbc57a0be78f0e817fd1d170a3615cd35da 0.6
7 12e0fdbc57a0be78f0e817fd1d170a3615cd35da 0.6
8 4ccf3de52989b14c3d84e1097f59e39a992e00bd 0.6b
8 4ccf3de52989b14c3d84e1097f59e39a992e00bd 0.6b
9 eac9c8efcd9bd8244e72fb6821f769f450457a32 0.6c
9 eac9c8efcd9bd8244e72fb6821f769f450457a32 0.6c
10 979c049974485125e1f9357f6bbe9c1b548a64c3 0.7
10 979c049974485125e1f9357f6bbe9c1b548a64c3 0.7
11 3a56574f329a368d645853e0f9e09472aee62349 0.8
11 3a56574f329a368d645853e0f9e09472aee62349 0.8
12 6a03cff2b0f5d30281e6addefe96b993582f2eac 0.8.1
12 6a03cff2b0f5d30281e6addefe96b993582f2eac 0.8.1
13 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0.9
13 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0.9
14 2be3001847cb18a23c403439d9e7d0ace30804e9 0.9.1
14 2be3001847cb18a23c403439d9e7d0ace30804e9 0.9.1
15 36a957364b1b89c150f2d0e60a99befe0ee08bd3 0.9.2
15 36a957364b1b89c150f2d0e60a99befe0ee08bd3 0.9.2
16 27230c29bfec36d5540fbe1c976810aefecfd1d2 0.9.3
16 27230c29bfec36d5540fbe1c976810aefecfd1d2 0.9.3
17 fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0.9.4
17 fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0.9.4
18 23889160905a1b09fffe1c07378e9fc1827606eb 0.9.5
18 23889160905a1b09fffe1c07378e9fc1827606eb 0.9.5
19 bae2e9c838e90a393bae3973a7850280413e091a 1.0
19 bae2e9c838e90a393bae3973a7850280413e091a 1.0
20 d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 1.0.1
20 d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 1.0.1
21 d2375bbee6d47e62ba8e415c86e83a465dc4dce9 1.0.2
21 d2375bbee6d47e62ba8e415c86e83a465dc4dce9 1.0.2
22 2a67430f92f15ea5159c26b09ec4839a0c549a26 1.1
22 2a67430f92f15ea5159c26b09ec4839a0c549a26 1.1
23 3773e510d433969e277b1863c317b674cbee2065 1.1.1
23 3773e510d433969e277b1863c317b674cbee2065 1.1.1
24 11a4eb81fb4f4742451591489e2797dc47903277 1.1.2
24 11a4eb81fb4f4742451591489e2797dc47903277 1.1.2
25 11efa41037e280d08cfb07c09ad485df30fb0ea8 1.2
25 11efa41037e280d08cfb07c09ad485df30fb0ea8 1.2
26 02981000012e3adf40c4849bd7b3d5618f9ce82d 1.2.1
26 02981000012e3adf40c4849bd7b3d5618f9ce82d 1.2.1
27 196d40e7c885fa6e95f89134809b3ec7bdbca34b 1.3
27 196d40e7c885fa6e95f89134809b3ec7bdbca34b 1.3
28 3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 1.3.1
28 3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 1.3.1
29 31ec469f9b556f11819937cf68ee53f2be927ebf 1.4
29 31ec469f9b556f11819937cf68ee53f2be927ebf 1.4
30 439d7ea6fe3aa4ab9ec274a68846779153789de9 1.4.1
30 439d7ea6fe3aa4ab9ec274a68846779153789de9 1.4.1
31 296a0b14a68621f6990c54fdba0083f6f20935bf 1.4.2
31 296a0b14a68621f6990c54fdba0083f6f20935bf 1.4.2
32 4aa619c4c2c09907034d9824ebb1dd0e878206eb 1.4.3
32 4aa619c4c2c09907034d9824ebb1dd0e878206eb 1.4.3
33 ff2704a8ded37fbebd8b6eb5ec733731d725da8a 1.5
33 ff2704a8ded37fbebd8b6eb5ec733731d725da8a 1.5
34 2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 1.5.1
34 2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 1.5.1
35 39f725929f0c48c5fb3b90c071fc3066012456ca 1.5.2
35 39f725929f0c48c5fb3b90c071fc3066012456ca 1.5.2
36 fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 1.5.3
36 fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 1.5.3
37 24fe2629c6fd0c74c90bd066e77387c2b02e8437 1.5.4
37 24fe2629c6fd0c74c90bd066e77387c2b02e8437 1.5.4
38 f786fc4b8764cd2a5526d259cf2f94d8a66924d9 1.6
38 f786fc4b8764cd2a5526d259cf2f94d8a66924d9 1.6
39 bf1774d95bde614af3956d92b20e2a0c68c5fec7 1.6.1
39 bf1774d95bde614af3956d92b20e2a0c68c5fec7 1.6.1
40 c00f03a4982e467fb6b6bd45908767db6df4771d 1.6.2
40 c00f03a4982e467fb6b6bd45908767db6df4771d 1.6.2
41 ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 1.6.3
41 ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 1.6.3
42 93d8bff78c96fe7e33237b257558ee97290048a4 1.6.4
42 93d8bff78c96fe7e33237b257558ee97290048a4 1.6.4
43 333421b9e0f96c7bc788e5667c146a58a9440a55 1.7
43 333421b9e0f96c7bc788e5667c146a58a9440a55 1.7
44 4438875ec01bd0fc32be92b0872eb6daeed4d44f 1.7.1
44 4438875ec01bd0fc32be92b0872eb6daeed4d44f 1.7.1
45 6aff4f144ad356311318b0011df0bb21f2c97429 1.7.2
45 6aff4f144ad356311318b0011df0bb21f2c97429 1.7.2
46 e3bf16703e2601de99e563cdb3a5d50b64e6d320 1.7.3
46 e3bf16703e2601de99e563cdb3a5d50b64e6d320 1.7.3
47 a6c855c32ea081da3c3b8ff628f1847ff271482f 1.7.4
47 a6c855c32ea081da3c3b8ff628f1847ff271482f 1.7.4
48 2b2155623ee2559caf288fd333f30475966c4525 1.7.5
48 2b2155623ee2559caf288fd333f30475966c4525 1.7.5
49 2616325766e3504c8ae7c84bd15ee610901fe91d 1.8
49 2616325766e3504c8ae7c84bd15ee610901fe91d 1.8
50 aa1f3be38ab127280761889d2dca906ca465b5f4 1.8.1
50 aa1f3be38ab127280761889d2dca906ca465b5f4 1.8.1
51 b032bec2c0a651ca0ddecb65714bfe6770f67d70 1.8.2
51 b032bec2c0a651ca0ddecb65714bfe6770f67d70 1.8.2
52 3cb1e95676ad089596bd81d0937cad37d6e3b7fb 1.8.3
52 3cb1e95676ad089596bd81d0937cad37d6e3b7fb 1.8.3
53 733af5d9f6b22387913e1d11350fb8cb7c1487dd 1.8.4
53 733af5d9f6b22387913e1d11350fb8cb7c1487dd 1.8.4
54 de9eb6b1da4fc522b1cab16d86ca166204c24f25 1.9
54 de9eb6b1da4fc522b1cab16d86ca166204c24f25 1.9
55 4a43e23b8c55b4566b8200bf69fe2158485a2634 1.9.1
55 4a43e23b8c55b4566b8200bf69fe2158485a2634 1.9.1
56 d629f1e89021103f1753addcef6b310e4435b184 1.9.2
56 d629f1e89021103f1753addcef6b310e4435b184 1.9.2
57 351a9292e430e35766c552066ed3e87c557b803b 1.9.3
57 351a9292e430e35766c552066ed3e87c557b803b 1.9.3
58 384082750f2c51dc917d85a7145748330fa6ef4d 2.0-rc
58 384082750f2c51dc917d85a7145748330fa6ef4d 2.0-rc
59 41453d55b481ddfcc1dacb445179649e24ca861d 2.0
59 41453d55b481ddfcc1dacb445179649e24ca861d 2.0
60 195dbd1cef0c2f9f8bcf4ea303238105f716bda3 2.0.1
60 195dbd1cef0c2f9f8bcf4ea303238105f716bda3 2.0.1
61 6344043924497cd06d781d9014c66802285072e4 2.0.2
61 6344043924497cd06d781d9014c66802285072e4 2.0.2
62 db33555eafeaf9df1e18950e29439eaa706d399b 2.1-rc
62 db33555eafeaf9df1e18950e29439eaa706d399b 2.1-rc
63 2aa5b51f310fb3befd26bed99c02267f5c12c734 2.1
63 2aa5b51f310fb3befd26bed99c02267f5c12c734 2.1
64 53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 2.1.1
64 53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 2.1.1
65 b9bd95e61b49c221c4cca24e6da7c946fc02f992 2.1.2
65 b9bd95e61b49c221c4cca24e6da7c946fc02f992 2.1.2
66 d9e2f09d5488c395ae9ddbb320ceacd24757e055 2.2-rc
66 d9e2f09d5488c395ae9ddbb320ceacd24757e055 2.2-rc
67 00182b3d087909e3c3ae44761efecdde8f319ef3 2.2
67 00182b3d087909e3c3ae44761efecdde8f319ef3 2.2
68 5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 2.2.1
68 5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 2.2.1
69 85a358df5bbbe404ca25730c9c459b34263441dc 2.2.2
69 85a358df5bbbe404ca25730c9c459b34263441dc 2.2.2
70 b013baa3898e117959984fc64c29d8c784d2f28b 2.2.3
70 b013baa3898e117959984fc64c29d8c784d2f28b 2.2.3
71 a06e2681dd1786e2354d84a5fa9c1c88dd4fa3e0 2.3-rc
71 a06e2681dd1786e2354d84a5fa9c1c88dd4fa3e0 2.3-rc
72 7f5094bb3f423fc799e471aac2aee81a7ce57a0b 2.3
72 7f5094bb3f423fc799e471aac2aee81a7ce57a0b 2.3
73 072209ae4ddb654eb2d5fd35bff358c738414432 2.3.1
73 072209ae4ddb654eb2d5fd35bff358c738414432 2.3.1
74 b3f0f9a39c4e1d0250048cd803ab03542d6f140a 2.3.2
74 b3f0f9a39c4e1d0250048cd803ab03542d6f140a 2.3.2
75 d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 2.4-rc
75 d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 2.4-rc
76 195ad823b5d58c68903a6153a25e3fb4ed25239d 2.4
76 195ad823b5d58c68903a6153a25e3fb4ed25239d 2.4
77 0c10cf8191469e7c3c8844922e17e71a176cb7cb 2.4.1
77 0c10cf8191469e7c3c8844922e17e71a176cb7cb 2.4.1
78 a4765077b65e6ae29ba42bab7834717b5072d5ba 2.4.2
78 a4765077b65e6ae29ba42bab7834717b5072d5ba 2.4.2
79 f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 2.5-rc
79 f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 2.5-rc
80 a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 2.5
80 a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 2.5
81 7511d4df752e61fe7ae4f3682e0a0008573b0402 2.5.1
81 7511d4df752e61fe7ae4f3682e0a0008573b0402 2.5.1
82 5b7175377babacce80a6c1e12366d8032a6d4340 2.5.2
82 5b7175377babacce80a6c1e12366d8032a6d4340 2.5.2
83 50c922c1b5145dab8baefefb0437d363b6a6c21c 2.5.3
83 50c922c1b5145dab8baefefb0437d363b6a6c21c 2.5.3
84 8a7bd2dccd44ed571afe7424cd7f95594f27c092 2.5.4
84 8a7bd2dccd44ed571afe7424cd7f95594f27c092 2.5.4
85 292cd385856d98bacb2c3086f8897bc660c2beea 2.6-rc
85 292cd385856d98bacb2c3086f8897bc660c2beea 2.6-rc
86 23f785b38af38d2fca6b8f3db56b8007a84cd73a 2.6
86 23f785b38af38d2fca6b8f3db56b8007a84cd73a 2.6
87 ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 2.6.1
87 ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 2.6.1
88 cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 2.6.2
88 cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 2.6.2
89 009794acc6e37a650f0fae37872e733382ac1c0c 2.6.3
89 009794acc6e37a650f0fae37872e733382ac1c0c 2.6.3
90 f0d7721d7322dcfb5af33599c2543f27335334bb 2.7-rc
90 f0d7721d7322dcfb5af33599c2543f27335334bb 2.7-rc
91 f37b5a17e6a0ee17afde2cdde5393dd74715fb58 2.7
91 f37b5a17e6a0ee17afde2cdde5393dd74715fb58 2.7
92 335a558f81dc73afeab4d7be63617392b130117f 2.7.1
92 335a558f81dc73afeab4d7be63617392b130117f 2.7.1
93 e7fa36d2ad3a7944a52dca126458d6f482db3524 2.7.2
93 e7fa36d2ad3a7944a52dca126458d6f482db3524 2.7.2
94 1596f2d8f2421314b1ddead8f7d0c91009358994 2.8-rc
94 1596f2d8f2421314b1ddead8f7d0c91009358994 2.8-rc
95 d825e4025e39d1c39db943cdc89818abd0a87c27 2.8
95 d825e4025e39d1c39db943cdc89818abd0a87c27 2.8
96 209e04a06467e2969c0cc6501335be0406d46ef0 2.8.1
96 209e04a06467e2969c0cc6501335be0406d46ef0 2.8.1
97 ca387377df7a3a67dbb90b6336b781cdadc3ef41 2.8.2
97 ca387377df7a3a67dbb90b6336b781cdadc3ef41 2.8.2
98 8862469e16f9236208581b20de5f96bd13cc039d 2.9-rc
98 8862469e16f9236208581b20de5f96bd13cc039d 2.9-rc
99 3cec5134e9c4bceab6a00c60f52a4f80677a78f2 2.9
99 3cec5134e9c4bceab6a00c60f52a4f80677a78f2 2.9
100 b96cb15ec9e04d8ac5ee08b34fcbbe4200588965 2.9.1
100 b96cb15ec9e04d8ac5ee08b34fcbbe4200588965 2.9.1
101 3f83fc5cfe715d292069ee8417c83804f6c6c1e4 2.9.2
101 3f83fc5cfe715d292069ee8417c83804f6c6c1e4 2.9.2
102 564f55b251224f16508dd1311452db7780dafe2b 3.0-rc
102 564f55b251224f16508dd1311452db7780dafe2b 3.0-rc
103 2195ac506c6ababe86985b932f4948837c0891b5 3.0
103 2195ac506c6ababe86985b932f4948837c0891b5 3.0
104 269c80ee5b3cb3684fa8edc61501b3506d02eb10 3.0.1
104 269c80ee5b3cb3684fa8edc61501b3506d02eb10 3.0.1
105 2d8cd3d0e83c7336c0cb45a9f88638363f993848 3.0.2
105 2d8cd3d0e83c7336c0cb45a9f88638363f993848 3.0.2
106 6c36dc6cd61a0e1b563f1d51e55bdf4dacf12162 3.1-rc
106 6c36dc6cd61a0e1b563f1d51e55bdf4dacf12162 3.1-rc
107 3178e49892020336491cdc6945885c4de26ffa8b 3.1
107 3178e49892020336491cdc6945885c4de26ffa8b 3.1
108 5dc91146f35369949ea56b40172308158b59063a 3.1.1
108 5dc91146f35369949ea56b40172308158b59063a 3.1.1
109 f768c888aaa68d12dd7f509dcc7f01c9584357d0 3.1.2
109 f768c888aaa68d12dd7f509dcc7f01c9584357d0 3.1.2
110 7f8d16af8cae246fa5a48e723d48d58b015aed94 3.2-rc
110 7f8d16af8cae246fa5a48e723d48d58b015aed94 3.2-rc
111 ced632394371a36953ce4d394f86278ae51a2aae 3.2
111 ced632394371a36953ce4d394f86278ae51a2aae 3.2
112 643c58303fb0ec020907af28b9e486be299ba043 3.2.1
112 643c58303fb0ec020907af28b9e486be299ba043 3.2.1
113 902554884335e5ca3661d63be9978eb4aec3f68a 3.2.2
113 902554884335e5ca3661d63be9978eb4aec3f68a 3.2.2
114 6dad422ecc5adb63d9fa649eeb8e05a5f9bc4900 3.2.3
114 6dad422ecc5adb63d9fa649eeb8e05a5f9bc4900 3.2.3
115 1265a3a71d75396f5d4cf6935ae7d9ba5407a547 3.2.4
115 1265a3a71d75396f5d4cf6935ae7d9ba5407a547 3.2.4
116 db8e3f7948b1fdeb9ad12d448fc3525759908b9f 3.3-rc
116 db8e3f7948b1fdeb9ad12d448fc3525759908b9f 3.3-rc
117 fbdd5195528fae4f41feebc1838215c110b25d6a 3.3
117 fbdd5195528fae4f41feebc1838215c110b25d6a 3.3
118 5b4ed033390bf6e2879c8f5c28c84e1ee3b87231 3.3.1
118 5b4ed033390bf6e2879c8f5c28c84e1ee3b87231 3.3.1
119 07a92bbd02e5e3a625e0820389b47786b02b2cea 3.3.2
119 07a92bbd02e5e3a625e0820389b47786b02b2cea 3.3.2
120 2e2e9a0750f91a6fe0ad88e4de34f8efefdcab08 3.3.3
120 2e2e9a0750f91a6fe0ad88e4de34f8efefdcab08 3.3.3
121 e89f909edffad558b56f4affa8239e4832f88de0 3.4-rc
121 e89f909edffad558b56f4affa8239e4832f88de0 3.4-rc
122 8cc6036bca532e06681c5a8fa37efaa812de67b5 3.4
122 8cc6036bca532e06681c5a8fa37efaa812de67b5 3.4
123 ed18f4acf435a2824c6f49fba40f42b9df5da7ad 3.4.1
123 ed18f4acf435a2824c6f49fba40f42b9df5da7ad 3.4.1
124 540cd0ddac49c1125b2e013aa2ff18ecbd4dd954 3.4.2
124 540cd0ddac49c1125b2e013aa2ff18ecbd4dd954 3.4.2
125 96a38d44ba093bd1d1ecfd34119e94056030278b 3.5-rc
125 96a38d44ba093bd1d1ecfd34119e94056030278b 3.5-rc
126 21aa1c313b05b1a85f8ffa1120d51579ddf6bf24 3.5
126 21aa1c313b05b1a85f8ffa1120d51579ddf6bf24 3.5
127 1a45e49a6bed023deb229102a8903234d18054d3 3.5.1
127 1a45e49a6bed023deb229102a8903234d18054d3 3.5.1
128 9a466b9f9792e3ad7ae3fc6c43c3ff2e136b718d 3.5.2
128 9a466b9f9792e3ad7ae3fc6c43c3ff2e136b718d 3.5.2
129 b66e3ca0b90c3095ea28dfd39aa24247bebf5c20 3.6-rc
129 b66e3ca0b90c3095ea28dfd39aa24247bebf5c20 3.6-rc
130 47dd34f2e7272be9e3b2a5a83cd0d20be44293f4 3.6
130 47dd34f2e7272be9e3b2a5a83cd0d20be44293f4 3.6
131 1aa5083cbebbe7575c88f3402ab377539b484897 3.6.1
131 1aa5083cbebbe7575c88f3402ab377539b484897 3.6.1
132 2d437a0f3355834a9485bbbeb30a52a052c98f19 3.6.2
132 2d437a0f3355834a9485bbbeb30a52a052c98f19 3.6.2
133 ea389970c08449440587712117f178d33bab3f1e 3.6.3
133 ea389970c08449440587712117f178d33bab3f1e 3.6.3
134 158bdc8965720ca4061f8f8d806563cfc7cdb62e 3.7-rc
134 158bdc8965720ca4061f8f8d806563cfc7cdb62e 3.7-rc
135 2408645de650d8a29a6ce9e7dce601d8dd0d1474 3.7
135 2408645de650d8a29a6ce9e7dce601d8dd0d1474 3.7
136 b698abf971e7377d9b7ec7fc8c52df45255b0329 3.7.1
136 b698abf971e7377d9b7ec7fc8c52df45255b0329 3.7.1
137 d493d64757eb45ada99fcb3693e479a51b7782da 3.7.2
137 d493d64757eb45ada99fcb3693e479a51b7782da 3.7.2
138 ae279d4a19e9683214cbd1fe8298cf0b50571432 3.7.3
138 ae279d4a19e9683214cbd1fe8298cf0b50571432 3.7.3
139 740156eedf2c450aee58b1a90b0e826f47c5da64 3.8-rc
139 740156eedf2c450aee58b1a90b0e826f47c5da64 3.8-rc
140 f85de28eae32e7d3064b1a1321309071bbaaa069 3.8
140 f85de28eae32e7d3064b1a1321309071bbaaa069 3.8
141 a56296f55a5e1038ea5016dace2076b693c28a56 3.8.1
141 a56296f55a5e1038ea5016dace2076b693c28a56 3.8.1
142 aaabed77791a75968a12b8c43ad263631a23ee81 3.8.2
142 aaabed77791a75968a12b8c43ad263631a23ee81 3.8.2
143 a9764ab80e11bcf6a37255db7dd079011f767c6c 3.8.3
143 a9764ab80e11bcf6a37255db7dd079011f767c6c 3.8.3
144 26a5d605b8683a292bb89aea11f37a81b06ac016 3.8.4
144 26a5d605b8683a292bb89aea11f37a81b06ac016 3.8.4
145 519bb4f9d3a47a6e83c2b414d58811ed38f503c2 3.9-rc
145 519bb4f9d3a47a6e83c2b414d58811ed38f503c2 3.9-rc
146 299546f84e68dbb9bd026f0f3a974ce4bdb93686 3.9
146 299546f84e68dbb9bd026f0f3a974ce4bdb93686 3.9
147 ccd436f7db6d5d7b9af89715179b911d031d44f1 3.9.1
147 ccd436f7db6d5d7b9af89715179b911d031d44f1 3.9.1
148 149433e68974eb5c63ccb03f794d8b57339a80c4 3.9.2
148 149433e68974eb5c63ccb03f794d8b57339a80c4 3.9.2
149 438173c415874f6ac653efc1099dec9c9150e90f 4.0-rc
149 438173c415874f6ac653efc1099dec9c9150e90f 4.0-rc
150 eab27446995210c334c3d06f1a659e3b9b5da769 4.0
150 eab27446995210c334c3d06f1a659e3b9b5da769 4.0
151 b3b1ae98f6a0e14c1e1ba806a6c18e193b6dae5c 4.0.1
151 b3b1ae98f6a0e14c1e1ba806a6c18e193b6dae5c 4.0.1
152 e69874dc1f4e142746ff3df91e678a09c6fc208c 4.0.2
152 e69874dc1f4e142746ff3df91e678a09c6fc208c 4.0.2
153 a1dd2c0c479e0550040542e392e87bc91262517e 4.1-rc
153 a1dd2c0c479e0550040542e392e87bc91262517e 4.1-rc
154 e1526da1e6d84e03146151c9b6e6950fe9a83d7d 4.1
154 e1526da1e6d84e03146151c9b6e6950fe9a83d7d 4.1
155 25703b624d27e3917d978af56d6ad59331e0464a 4.1.1
155 25703b624d27e3917d978af56d6ad59331e0464a 4.1.1
156 ed5b25874d998ababb181a939dd37a16ea644435 4.1.2
156 ed5b25874d998ababb181a939dd37a16ea644435 4.1.2
157 77eaf9539499a1b8be259ffe7ada787d07857f80 4.1.3
157 77eaf9539499a1b8be259ffe7ada787d07857f80 4.1.3
158 616e788321cc4ae9975b7f0c54c849f36d82182b 4.2-rc
158 616e788321cc4ae9975b7f0c54c849f36d82182b 4.2-rc
159 bb96d4a497432722623ae60d9bc734a1e360179e 4.2
159 bb96d4a497432722623ae60d9bc734a1e360179e 4.2
160 c850f0ed54c1d42f9aa079ad528f8127e5775217 4.2.1
160 c850f0ed54c1d42f9aa079ad528f8127e5775217 4.2.1
161 26c49ed51a698ec016d2b4c6b44ca3c3f73cc788 4.2.2
161 26c49ed51a698ec016d2b4c6b44ca3c3f73cc788 4.2.2
162 857876ebaed4e315f63157bd157d6ce553c7ab73 4.3-rc
162 857876ebaed4e315f63157bd157d6ce553c7ab73 4.3-rc
163 5544af8622863796a0027566f6b646e10d522c4c 4.3
163 5544af8622863796a0027566f6b646e10d522c4c 4.3
164 943c91326b23954e6e1c6960d0239511f9530258 4.2.3
164 943c91326b23954e6e1c6960d0239511f9530258 4.2.3
165 3fee7f7d2da04226914c2258cc2884dc27384fd7 4.3.1
165 3fee7f7d2da04226914c2258cc2884dc27384fd7 4.3.1
166 920977f72c7b70acfdaf56ab35360584d7845827 4.3.2
166 920977f72c7b70acfdaf56ab35360584d7845827 4.3.2
167 2f427b57bf9019c6dc3750baa539dc22c1be50f6 4.3.3
167 2f427b57bf9019c6dc3750baa539dc22c1be50f6 4.3.3
168 1e2454b60e5936f5e77498cab2648db469504487 4.4-rc
168 1e2454b60e5936f5e77498cab2648db469504487 4.4-rc
169 0ccb43d4cf01d013ae05917ec4f305509f851b2d 4.4
169 0ccb43d4cf01d013ae05917ec4f305509f851b2d 4.4
170 cabc840ffdee8a72f3689fb77dd74d04fdc2bc04 4.4.1
170 cabc840ffdee8a72f3689fb77dd74d04fdc2bc04 4.4.1
171 a92b9f8e11ba330614cdfd6af0e03b15c1ff3797 4.4.2
171 a92b9f8e11ba330614cdfd6af0e03b15c1ff3797 4.4.2
172 27b6df1b5adbdf647cf5c6675b40575e1b197c60 4.5-rc
172 27b6df1b5adbdf647cf5c6675b40575e1b197c60 4.5-rc
173 d334afc585e29577f271c5eda03378736a16ca6b 4.5
173 d334afc585e29577f271c5eda03378736a16ca6b 4.5
174 369aadf7a3264b03c8b09efce715bc41e6ab4a9b 4.5.1
174 369aadf7a3264b03c8b09efce715bc41e6ab4a9b 4.5.1
175 8bba684efde7f45add05f737952093bb2aa07155 4.5.2
175 8bba684efde7f45add05f737952093bb2aa07155 4.5.2
176 7de7bd407251af2bc98e5b809c8598ee95830daf 4.5.3
176 7de7bd407251af2bc98e5b809c8598ee95830daf 4.5.3
177 ed5448edcbfa747b9154099e18630e49024fd47b 4.6rc0
177 ed5448edcbfa747b9154099e18630e49024fd47b 4.6rc0
178 1ec874717d8a93b19e0d50628443e0ee5efab3a9 4.6rc1
178 1ec874717d8a93b19e0d50628443e0ee5efab3a9 4.6rc1
179 6614cac550aea66d19c601e45efd1b7bd08d7c40 4.6
179 6614cac550aea66d19c601e45efd1b7bd08d7c40 4.6
180 9c5ced5276d6e7d54f7c3dadf5247b7ee98ec79c 4.6.1
180 9c5ced5276d6e7d54f7c3dadf5247b7ee98ec79c 4.6.1
181 0b63a6743010dfdbf8a8154186e119949bdaa1cc 4.6.2
181 0b63a6743010dfdbf8a8154186e119949bdaa1cc 4.6.2
182 e90130af47ce8dd53a3109aed9d15876b3e7dee8 4.7rc0
182 e90130af47ce8dd53a3109aed9d15876b3e7dee8 4.7rc0
183 33ac6a72308a215e6086fbced347ec10aa963b0a 4.7
183 33ac6a72308a215e6086fbced347ec10aa963b0a 4.7
184 ede3bf31fe63677fdf5bd8db687977d4e3d792ed 4.7.1
184 ede3bf31fe63677fdf5bd8db687977d4e3d792ed 4.7.1
185 5405cb1a79010ac50c58cd84e6f50c4556bf2a4c 4.7.2
185 5405cb1a79010ac50c58cd84e6f50c4556bf2a4c 4.7.2
186 956ec6f1320df26f3133ec40f3de866ea0695fd7 4.8rc0
186 956ec6f1320df26f3133ec40f3de866ea0695fd7 4.8rc0
187 a91a2837150bdcb27ae76b3646e6c93cd6a15904 4.8
187 a91a2837150bdcb27ae76b3646e6c93cd6a15904 4.8
188 1c8c54cf97256f4468da2eb4dbee24f7f3888e71 4.8.1
188 1c8c54cf97256f4468da2eb4dbee24f7f3888e71 4.8.1
189 197f092b2cd9691e2a55d198f717b231af9be6f9 4.8.2
189 197f092b2cd9691e2a55d198f717b231af9be6f9 4.8.2
190 593718ff5844cad7a27ee3eb5adad89ac8550949 4.9rc0
190 593718ff5844cad7a27ee3eb5adad89ac8550949 4.9rc0
191 83377b4b4ae0e9a6b8e579f7b0a693b8cf5c3b10 4.9
191 83377b4b4ae0e9a6b8e579f7b0a693b8cf5c3b10 4.9
192 4ea21df312ec7159c5b3633096b6ecf68750b0dd 4.9.1
192 4ea21df312ec7159c5b3633096b6ecf68750b0dd 4.9.1
193 4a8d9ed864754837a185a642170cde24392f9abf 5.0rc0
193 4a8d9ed864754837a185a642170cde24392f9abf 5.0rc0
194 07e479ef7c9639be0029f00e6a722b96dcc05fee 5.0
194 07e479ef7c9639be0029f00e6a722b96dcc05fee 5.0
195 c3484ddbdb9621256d597ed86b90d229c59c2af9 5.0.1
195 c3484ddbdb9621256d597ed86b90d229c59c2af9 5.0.1
196 97ada9b8d51bef24c5cb4cdca4243f0db694ab6e 5.0.2
196 97ada9b8d51bef24c5cb4cdca4243f0db694ab6e 5.0.2
197 e386b5f4f8360dbb43a576dd9b1368e386fefa5b 5.1rc0
197 e386b5f4f8360dbb43a576dd9b1368e386fefa5b 5.1rc0
198 e91930d712e8507d1bc1b2dffd96c83edc4cbed3 5.1
198 e91930d712e8507d1bc1b2dffd96c83edc4cbed3 5.1
199 a4e32fd539ab41489a51b2aa88bda9a73b839562 5.1.1
199 a4e32fd539ab41489a51b2aa88bda9a73b839562 5.1.1
200 181e52f2b62f4768aa0d988936c929dc7c4a41a0 5.1.2
200 181e52f2b62f4768aa0d988936c929dc7c4a41a0 5.1.2
201 59338f9561099de77c684c00f76507f11e46ebe8 5.2rc0
201 59338f9561099de77c684c00f76507f11e46ebe8 5.2rc0
202 ca3dca416f8d5863ca6f5a4a6a6bb835dcd5feeb 5.2
202 ca3dca416f8d5863ca6f5a4a6a6bb835dcd5feeb 5.2
203 a50fecefa691c9b72a99e49aa6fe9dd13943c2bf 5.2.1
203 a50fecefa691c9b72a99e49aa6fe9dd13943c2bf 5.2.1
204 b4c82b70418022e67cc0e69b1aa3c3aa43aa1d29 5.2.2
204 b4c82b70418022e67cc0e69b1aa3c3aa43aa1d29 5.2.2
205 84a0102c05c7852c8215ef6cf21d809927586b69 5.3rc0
205 84a0102c05c7852c8215ef6cf21d809927586b69 5.3rc0
206 e4344e463c0c888a2f437b78b5982ecdf3f6650a 5.3rc1
206 e4344e463c0c888a2f437b78b5982ecdf3f6650a 5.3rc1
207 7f5410dfc8a64bb587d19637deb95d378fd1eb5c 5.3
207 7f5410dfc8a64bb587d19637deb95d378fd1eb5c 5.3
208 6d121acbb82e65fe4dd3c2318a1b61981b958492 5.3.1
208 6d121acbb82e65fe4dd3c2318a1b61981b958492 5.3.1
209 8fca7e8449a847e3cf1054f2c07b51237699fad3 5.3.2
209 8fca7e8449a847e3cf1054f2c07b51237699fad3 5.3.2
210 26ce8e7515036d3431a03aaeb7bc72dd96cb1112 5.4rc0
210 26ce8e7515036d3431a03aaeb7bc72dd96cb1112 5.4rc0
211 cf3e07d7648a4371ce584d15dd692e7a6845792f 5.4
211 cf3e07d7648a4371ce584d15dd692e7a6845792f 5.4
212 065704cbdbdbb05dcd6bb814eb9bbdd982211b28 5.4.1
212 065704cbdbdbb05dcd6bb814eb9bbdd982211b28 5.4.1
213 0ea9c86fac8974cd74dc12ea681c8986eb6da6c4 5.4.2
213 0ea9c86fac8974cd74dc12ea681c8986eb6da6c4 5.4.2
214 28163c5de797e5416f9b588940f4608269b4d50a 5.5rc0
214 28163c5de797e5416f9b588940f4608269b4d50a 5.5rc0
215 7fc3c5fbc65f6fe85d70ea63923b8767dda4f2e0 5.5
215 7fc3c5fbc65f6fe85d70ea63923b8767dda4f2e0 5.5
216 f62bb5d07848ca598aa860a517394130b61bf2ee 5.5.1
216 f62bb5d07848ca598aa860a517394130b61bf2ee 5.5.1
217 07731064ac41dacdf0ec869ebd05c2e848c14fbf 5.5.2
217 07731064ac41dacdf0ec869ebd05c2e848c14fbf 5.5.2
218 0e06a7ab9e0d5c65af4e511aee1e0342998799df 5.6rc0
218 0e06a7ab9e0d5c65af4e511aee1e0342998799df 5.6rc0
219 18c17d63fdabd009e70bf994e5efb7db422f4f7f 5.6
219 18c17d63fdabd009e70bf994e5efb7db422f4f7f 5.6
220 1d5189a57405ceca5aa244052c9f948977f4699b 5.6.1
220 1d5189a57405ceca5aa244052c9f948977f4699b 5.6.1
221 9da65e3cf3706ff41e08b311381c588440c27baf 5.7rc0
221 9da65e3cf3706ff41e08b311381c588440c27baf 5.7rc0
222 0e2e7300f4302b02412b0b734717697049494c4c 5.7
222 0e2e7300f4302b02412b0b734717697049494c4c 5.7
223 d5d9177c0045d206db575bae6daa98e2cb2fe5bc 5.7.1
223 d5d9177c0045d206db575bae6daa98e2cb2fe5bc 5.7.1
224 f67b8946bb1b6cfa8328dbf8d6a9128b69ccdcb4 5.8rc0
224 f67b8946bb1b6cfa8328dbf8d6a9128b69ccdcb4 5.8rc0
225 8d2b62d716b095507effaa8d56f87cd27ba659ab 5.8rc1
225 8d2b62d716b095507effaa8d56f87cd27ba659ab 5.8rc1
226 067f2c53fb24506c9e9fb4639871b13b19a85f8a 5.8
226 067f2c53fb24506c9e9fb4639871b13b19a85f8a 5.8
227 411dc27fd9fd076d6a031a08fcaace659afe2fe3 5.8.1
227 411dc27fd9fd076d6a031a08fcaace659afe2fe3 5.8.1
228 d7515d29761d5ada7d9c765f517db67db75dea9a 5.9rc0
228 d7515d29761d5ada7d9c765f517db67db75dea9a 5.9rc0
229 2813d406b03607cdb8c06cb04c44efcc9a79d9a2 5.9rc1
229 2813d406b03607cdb8c06cb04c44efcc9a79d9a2 5.9rc1
230 53221078e0de65d1a821ce5311dec45a7a978301 5.9
230 53221078e0de65d1a821ce5311dec45a7a978301 5.9
231 86a60679cf619e14cee9442f865fcf31b142cb9f 5.9.1
231 86a60679cf619e14cee9442f865fcf31b142cb9f 5.9.1
232 750920b18aaaddd654756be40dec59d90f2643be 5.9.2
232 750920b18aaaddd654756be40dec59d90f2643be 5.9.2
233 6ee0244fc1cf889ae543d2ce0ec45201ae0be6e1 5.9.3
233 6ee0244fc1cf889ae543d2ce0ec45201ae0be6e1 5.9.3
234 a44bb185f6bdbecc754996d8386722e2f0123b0a 6.0rc0
234 a44bb185f6bdbecc754996d8386722e2f0123b0a 6.0rc0
235 5d08b289e2e526259d7d5ea32b70fe76d5b327d7 6.0
235 5d08b289e2e526259d7d5ea32b70fe76d5b327d7 6.0
236 799fdf4cca80cb9ae40537a90995e6bd163ebc0b 6.0.1
236 799fdf4cca80cb9ae40537a90995e6bd163ebc0b 6.0.1
237 75676122c2bf7594ac732b7388db4c74c648b365 6.0.2
237 75676122c2bf7594ac732b7388db4c74c648b365 6.0.2
238 dcec16e799ddb6d33fcd11b04af530250a417a58 6.0.3
238 dcec16e799ddb6d33fcd11b04af530250a417a58 6.0.3
239 c00d3ce4e94bb0ee8d809e25e1dcb2a5fab84e2c 6.1rc0
239 c00d3ce4e94bb0ee8d809e25e1dcb2a5fab84e2c 6.1rc0
240 d4486810a1795fba9521449b8885ced034f3a6dd 6.1
240 d4486810a1795fba9521449b8885ced034f3a6dd 6.1
241 5bd6bcd31dd1ebb63b8914b00064f96297267af7 6.1.1
241 5bd6bcd31dd1ebb63b8914b00064f96297267af7 6.1.1
242 0ddd5e1f5f67438af85d12e4ce6c39021dde9916 6.1.2
242 0ddd5e1f5f67438af85d12e4ce6c39021dde9916 6.1.2
243 6b10151b962108f65bfa12b3918b1021ca334f73 6.1.3
243 6b10151b962108f65bfa12b3918b1021ca334f73 6.1.3
244 0cc5f74ff7f0f4ac2427096bddbe102dbc2453ae 6.1.4
244 0cc5f74ff7f0f4ac2427096bddbe102dbc2453ae 6.1.4
245 288de6f5d724bba7bf1669e2838f196962bb7528 6.2rc0
245 288de6f5d724bba7bf1669e2838f196962bb7528 6.2rc0
246 094a5fa3cf52f936e0de3f1e507c818bee5ece6b 6.2
246 094a5fa3cf52f936e0de3f1e507c818bee5ece6b 6.2
247 f69bffd00abe3a1b94d1032eb2c92e611d16a192 6.2.1
247 f69bffd00abe3a1b94d1032eb2c92e611d16a192 6.2.1
248 b5c8524827d20fe2e0ca8fb1234a0fe35a1a36c7 6.2.2
248 b5c8524827d20fe2e0ca8fb1234a0fe35a1a36c7 6.2.2
249 dbdee8ac3e3fcdda1fa55b90c0a235125b7f8e6f 6.2.3
249 dbdee8ac3e3fcdda1fa55b90c0a235125b7f8e6f 6.2.3
250 a3356ab610fc50000cf0ba55c424a4d96da11db7 6.3rc0
250 a3356ab610fc50000cf0ba55c424a4d96da11db7 6.3rc0
251 04f1dba53c961dfdb875c8469adc96fa999cfbed 6.3.0
251 04f1dba53c961dfdb875c8469adc96fa999cfbed 6.3.0
252 04f1dba53c961dfdb875c8469adc96fa999cfbed 6.3
252 04f1dba53c961dfdb875c8469adc96fa999cfbed 6.3
253 04f1dba53c961dfdb875c8469adc96fa999cfbed 6.3.0
253 04f1dba53c961dfdb875c8469adc96fa999cfbed 6.3.0
254 0000000000000000000000000000000000000000 6.3.0
254 0000000000000000000000000000000000000000 6.3.0
255 c890d8b8bc59b18e5febf60caada629df5356ee2 6.3.1
255 c890d8b8bc59b18e5febf60caada629df5356ee2 6.3.1
256 59466b13a3ae0e29a5d4f485393e516cfbb057d0 6.3.2
256 59466b13a3ae0e29a5d4f485393e516cfbb057d0 6.3.2
257 8830004967ad865ead89c28a410405a6e71e0796 6.3.3
257 8830004967ad865ead89c28a410405a6e71e0796 6.3.3
258 05de4896508e8ec387b33eb30d8aab78d1c8e9e4 6.4rc0
258 05de4896508e8ec387b33eb30d8aab78d1c8e9e4 6.4rc0
259 f14864fffdcab725d9eac6d4f4c07be05a35f59a 6.4
259 f14864fffdcab725d9eac6d4f4c07be05a35f59a 6.4
260 83ea6ce48b4fd09fb79c4e34cc5750c805699a53 6.4.1
260 83ea6ce48b4fd09fb79c4e34cc5750c805699a53 6.4.1
261 f952be90b0514a576dcc8bbe758ce3847faba9bb 6.4.2
261 f952be90b0514a576dcc8bbe758ce3847faba9bb 6.4.2
262 fc445f8abcf90b33db7c463816a1b3560681767f 6.4.3
@@ -1,559 +1,560 b''
1 /*
1 /*
2 * A fast client for Mercurial command server
2 * A fast client for Mercurial command server
3 *
3 *
4 * Copyright (c) 2011 Yuya Nishihara <yuya@tcha.org>
4 * Copyright (c) 2011 Yuya Nishihara <yuya@tcha.org>
5 *
5 *
6 * This software may be used and distributed according to the terms of the
6 * This software may be used and distributed according to the terms of the
7 * GNU General Public License version 2 or any later version.
7 * GNU General Public License version 2 or any later version.
8 */
8 */
9
9
10 #include <assert.h>
10 #include <assert.h>
11 #include <dirent.h>
11 #include <dirent.h>
12 #include <errno.h>
12 #include <errno.h>
13 #include <fcntl.h>
13 #include <fcntl.h>
14 #include <signal.h>
14 #include <signal.h>
15 #include <stdio.h>
15 #include <stdio.h>
16 #include <stdlib.h>
16 #include <stdlib.h>
17 #include <string.h>
17 #include <string.h>
18 #include <sys/file.h>
18 #include <sys/file.h>
19 #include <sys/stat.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
20 #include <sys/types.h>
21 #include <sys/un.h>
21 #include <sys/un.h>
22 #include <sys/wait.h>
22 #include <sys/wait.h>
23 #include <time.h>
23 #include <time.h>
24 #include <unistd.h>
24 #include <unistd.h>
25
25
26 #include "hgclient.h"
26 #include "hgclient.h"
27 #include "procutil.h"
27 #include "procutil.h"
28 #include "util.h"
28 #include "util.h"
29
29
30 #ifndef PATH_MAX
30 #ifndef PATH_MAX
31 #define PATH_MAX 4096
31 #define PATH_MAX 4096
32 #endif
32 #endif
33
33
34 extern char **environ;
35
34 struct cmdserveropts {
36 struct cmdserveropts {
35 char sockname[PATH_MAX];
37 char sockname[PATH_MAX];
36 char initsockname[PATH_MAX];
38 char initsockname[PATH_MAX];
37 char redirectsockname[PATH_MAX];
39 char redirectsockname[PATH_MAX];
38 size_t argsize;
40 size_t argsize;
39 const char **args;
41 const char **args;
40 };
42 };
41
43
42 static void initcmdserveropts(struct cmdserveropts *opts)
44 static void initcmdserveropts(struct cmdserveropts *opts)
43 {
45 {
44 memset(opts, 0, sizeof(struct cmdserveropts));
46 memset(opts, 0, sizeof(struct cmdserveropts));
45 }
47 }
46
48
47 static void freecmdserveropts(struct cmdserveropts *opts)
49 static void freecmdserveropts(struct cmdserveropts *opts)
48 {
50 {
49 free(opts->args);
51 free(opts->args);
50 opts->args = NULL;
52 opts->args = NULL;
51 opts->argsize = 0;
53 opts->argsize = 0;
52 }
54 }
53
55
54 /*
56 /*
55 * Test if an argument is a sensitive flag that should be passed to the server.
57 * Test if an argument is a sensitive flag that should be passed to the server.
56 * Return 0 if not, otherwise the number of arguments starting from the current
58 * Return 0 if not, otherwise the number of arguments starting from the current
57 * one that should be passed to the server.
59 * one that should be passed to the server.
58 */
60 */
59 static size_t testsensitiveflag(const char *arg)
61 static size_t testsensitiveflag(const char *arg)
60 {
62 {
61 static const struct {
63 static const struct {
62 const char *name;
64 const char *name;
63 size_t narg;
65 size_t narg;
64 } flags[] = {
66 } flags[] = {
65 {"--config", 1}, {"--cwd", 1}, {"--repo", 1},
67 {"--config", 1}, {"--cwd", 1}, {"--repo", 1},
66 {"--repository", 1}, {"--traceback", 0}, {"-R", 1},
68 {"--repository", 1}, {"--traceback", 0}, {"-R", 1},
67 };
69 };
68 size_t i;
70 size_t i;
69 for (i = 0; i < sizeof(flags) / sizeof(flags[0]); ++i) {
71 for (i = 0; i < sizeof(flags) / sizeof(flags[0]); ++i) {
70 size_t len = strlen(flags[i].name);
72 size_t len = strlen(flags[i].name);
71 size_t narg = flags[i].narg;
73 size_t narg = flags[i].narg;
72 if (memcmp(arg, flags[i].name, len) == 0) {
74 if (memcmp(arg, flags[i].name, len) == 0) {
73 if (arg[len] == '\0') {
75 if (arg[len] == '\0') {
74 /* --flag (value) */
76 /* --flag (value) */
75 return narg + 1;
77 return narg + 1;
76 } else if (arg[len] == '=' && narg > 0) {
78 } else if (arg[len] == '=' && narg > 0) {
77 /* --flag=value */
79 /* --flag=value */
78 return 1;
80 return 1;
79 } else if (flags[i].name[1] != '-') {
81 } else if (flags[i].name[1] != '-') {
80 /* short flag */
82 /* short flag */
81 return 1;
83 return 1;
82 }
84 }
83 }
85 }
84 }
86 }
85 return 0;
87 return 0;
86 }
88 }
87
89
88 /*
90 /*
89 * Parse argv[] and put sensitive flags to opts->args
91 * Parse argv[] and put sensitive flags to opts->args
90 */
92 */
91 static void setcmdserverargs(struct cmdserveropts *opts, int argc,
93 static void setcmdserverargs(struct cmdserveropts *opts, int argc,
92 const char *argv[])
94 const char *argv[])
93 {
95 {
94 size_t i, step;
96 size_t i, step;
95 opts->argsize = 0;
97 opts->argsize = 0;
96 for (i = 0, step = 1; i < (size_t)argc; i += step, step = 1) {
98 for (i = 0, step = 1; i < (size_t)argc; i += step, step = 1) {
97 if (!argv[i])
99 if (!argv[i])
98 continue; /* pass clang-analyse */
100 continue; /* pass clang-analyse */
99 if (strcmp(argv[i], "--") == 0)
101 if (strcmp(argv[i], "--") == 0)
100 break;
102 break;
101 size_t n = testsensitiveflag(argv[i]);
103 size_t n = testsensitiveflag(argv[i]);
102 if (n == 0 || i + n > (size_t)argc)
104 if (n == 0 || i + n > (size_t)argc)
103 continue;
105 continue;
104 opts->args =
106 opts->args =
105 reallocx(opts->args, (n + opts->argsize) * sizeof(char *));
107 reallocx(opts->args, (n + opts->argsize) * sizeof(char *));
106 memcpy(opts->args + opts->argsize, argv + i,
108 memcpy(opts->args + opts->argsize, argv + i,
107 sizeof(char *) * n);
109 sizeof(char *) * n);
108 opts->argsize += n;
110 opts->argsize += n;
109 step = n;
111 step = n;
110 }
112 }
111 }
113 }
112
114
113 static void preparesockdir(const char *sockdir)
115 static void preparesockdir(const char *sockdir)
114 {
116 {
115 int r;
117 int r;
116 r = mkdir(sockdir, 0700);
118 r = mkdir(sockdir, 0700);
117 if (r < 0 && errno != EEXIST)
119 if (r < 0 && errno != EEXIST)
118 abortmsgerrno("cannot create sockdir %s", sockdir);
120 abortmsgerrno("cannot create sockdir %s", sockdir);
119
121
120 struct stat st;
122 struct stat st;
121 r = lstat(sockdir, &st);
123 r = lstat(sockdir, &st);
122 if (r < 0)
124 if (r < 0)
123 abortmsgerrno("cannot stat %s", sockdir);
125 abortmsgerrno("cannot stat %s", sockdir);
124 if (!S_ISDIR(st.st_mode))
126 if (!S_ISDIR(st.st_mode))
125 abortmsg("cannot create sockdir %s (file exists)", sockdir);
127 abortmsg("cannot create sockdir %s (file exists)", sockdir);
126 if (st.st_uid != geteuid() || st.st_mode & 0077)
128 if (st.st_uid != geteuid() || st.st_mode & 0077)
127 abortmsg("insecure sockdir %s", sockdir);
129 abortmsg("insecure sockdir %s", sockdir);
128 }
130 }
129
131
130 /*
132 /*
131 * Check if a socket directory exists and is only owned by the current user.
133 * Check if a socket directory exists and is only owned by the current user.
132 * Return 1 if so, 0 if not. This is used to check if XDG_RUNTIME_DIR can be
134 * Return 1 if so, 0 if not. This is used to check if XDG_RUNTIME_DIR can be
133 * used or not. According to the specification [1], XDG_RUNTIME_DIR should be
135 * used or not. According to the specification [1], XDG_RUNTIME_DIR should be
134 * ignored if the directory is not owned by the user with mode 0700.
136 * ignored if the directory is not owned by the user with mode 0700.
135 * [1]: https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
137 * [1]: https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
136 */
138 */
137 static int checkruntimedir(const char *sockdir)
139 static int checkruntimedir(const char *sockdir)
138 {
140 {
139 struct stat st;
141 struct stat st;
140 int r = lstat(sockdir, &st);
142 int r = lstat(sockdir, &st);
141 if (r < 0) /* ex. does not exist */
143 if (r < 0) /* ex. does not exist */
142 return 0;
144 return 0;
143 if (!S_ISDIR(st.st_mode)) /* ex. is a file, not a directory */
145 if (!S_ISDIR(st.st_mode)) /* ex. is a file, not a directory */
144 return 0;
146 return 0;
145 return st.st_uid == geteuid() && (st.st_mode & 0777) == 0700;
147 return st.st_uid == geteuid() && (st.st_mode & 0777) == 0700;
146 }
148 }
147
149
148 static void getdefaultsockdir(char sockdir[], size_t size)
150 static void getdefaultsockdir(char sockdir[], size_t size)
149 {
151 {
150 /* by default, put socket file in secure directory
152 /* by default, put socket file in secure directory
151 * (${XDG_RUNTIME_DIR}/chg, or /${TMPDIR:-tmp}/chg$UID)
153 * (${XDG_RUNTIME_DIR}/chg, or /${TMPDIR:-tmp}/chg$UID)
152 * (permission of socket file may be ignored on some Unices) */
154 * (permission of socket file may be ignored on some Unices) */
153 const char *runtimedir = getenv("XDG_RUNTIME_DIR");
155 const char *runtimedir = getenv("XDG_RUNTIME_DIR");
154 int r;
156 int r;
155 if (runtimedir && checkruntimedir(runtimedir)) {
157 if (runtimedir && checkruntimedir(runtimedir)) {
156 r = snprintf(sockdir, size, "%s/chg", runtimedir);
158 r = snprintf(sockdir, size, "%s/chg", runtimedir);
157 } else {
159 } else {
158 const char *tmpdir = getenv("TMPDIR");
160 const char *tmpdir = getenv("TMPDIR");
159 if (!tmpdir)
161 if (!tmpdir)
160 tmpdir = "/tmp";
162 tmpdir = "/tmp";
161 r = snprintf(sockdir, size, "%s/chg%d", tmpdir, geteuid());
163 r = snprintf(sockdir, size, "%s/chg%d", tmpdir, geteuid());
162 }
164 }
163 if (r < 0 || (size_t)r >= size)
165 if (r < 0 || (size_t)r >= size)
164 abortmsg("too long TMPDIR (r = %d)", r);
166 abortmsg("too long TMPDIR (r = %d)", r);
165 }
167 }
166
168
167 static void setcmdserveropts(struct cmdserveropts *opts)
169 static void setcmdserveropts(struct cmdserveropts *opts)
168 {
170 {
169 int r;
171 int r;
170 char sockdir[PATH_MAX];
172 char sockdir[PATH_MAX];
171 const char *envsockname = getenv("CHGSOCKNAME");
173 const char *envsockname = getenv("CHGSOCKNAME");
172 if (!envsockname) {
174 if (!envsockname) {
173 getdefaultsockdir(sockdir, sizeof(sockdir));
175 getdefaultsockdir(sockdir, sizeof(sockdir));
174 preparesockdir(sockdir);
176 preparesockdir(sockdir);
175 }
177 }
176
178
177 const char *basename = (envsockname) ? envsockname : sockdir;
179 const char *basename = (envsockname) ? envsockname : sockdir;
178 const char *sockfmt = (envsockname) ? "%s" : "%s/server";
180 const char *sockfmt = (envsockname) ? "%s" : "%s/server";
179 r = snprintf(opts->sockname, sizeof(opts->sockname), sockfmt, basename);
181 r = snprintf(opts->sockname, sizeof(opts->sockname), sockfmt, basename);
180 if (r < 0 || (size_t)r >= sizeof(opts->sockname))
182 if (r < 0 || (size_t)r >= sizeof(opts->sockname))
181 abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r);
183 abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r);
182 r = snprintf(opts->initsockname, sizeof(opts->initsockname), "%s.%u",
184 r = snprintf(opts->initsockname, sizeof(opts->initsockname), "%s.%u",
183 opts->sockname, (unsigned)getpid());
185 opts->sockname, (unsigned)getpid());
184 if (r < 0 || (size_t)r >= sizeof(opts->initsockname))
186 if (r < 0 || (size_t)r >= sizeof(opts->initsockname))
185 abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r);
187 abortmsg("too long TMPDIR or CHGSOCKNAME (r = %d)", r);
186 }
188 }
187
189
188 /* If the current program is, say, /a/b/c/chg, returns /a/b/c/hg. */
190 /* If the current program is, say, /a/b/c/chg, returns /a/b/c/hg. */
189 static char *getrelhgcmd(void)
191 static char *getrelhgcmd(void)
190 {
192 {
191 ssize_t n;
193 ssize_t n;
192 char *res, *slash;
194 char *res, *slash;
193 int maxsize = 4096;
195 int maxsize = 4096;
194 res = malloc(maxsize);
196 res = malloc(maxsize);
195 if (res == NULL)
197 if (res == NULL)
196 goto cleanup;
198 goto cleanup;
197 n = readlink("/proc/self/exe", res, maxsize);
199 n = readlink("/proc/self/exe", res, maxsize);
198 if (n < 0 || n >= maxsize)
200 if (n < 0 || n >= maxsize)
199 goto cleanup;
201 goto cleanup;
200 res[n] = '\0';
202 res[n] = '\0';
201 slash = strrchr(res, '/');
203 slash = strrchr(res, '/');
202 if (slash == NULL)
204 if (slash == NULL)
203 goto cleanup;
205 goto cleanup;
204 /* 4 is strlen("/hg") + nul byte */
206 /* 4 is strlen("/hg") + nul byte */
205 if (slash + 4 >= res + maxsize)
207 if (slash + 4 >= res + maxsize)
206 goto cleanup;
208 goto cleanup;
207 memcpy(slash, "/hg", 4);
209 memcpy(slash, "/hg", 4);
208 return res;
210 return res;
209 cleanup:
211 cleanup:
210 free(res);
212 free(res);
211 return NULL;
213 return NULL;
212 }
214 }
213
215
214 static const char *gethgcmd(void)
216 static const char *gethgcmd(void)
215 {
217 {
216 static const char *hgcmd = NULL;
218 static const char *hgcmd = NULL;
217 #ifdef HGPATHREL
219 #ifdef HGPATHREL
218 int tryrelhgcmd = 1;
220 int tryrelhgcmd = 1;
219 #else
221 #else
220 int tryrelhgcmd = 0;
222 int tryrelhgcmd = 0;
221 #endif
223 #endif
222 if (!hgcmd) {
224 if (!hgcmd) {
223 hgcmd = getenv("CHGHG");
225 hgcmd = getenv("CHGHG");
224 if (!hgcmd || hgcmd[0] == '\0')
226 if (!hgcmd || hgcmd[0] == '\0')
225 hgcmd = getenv("HG");
227 hgcmd = getenv("HG");
226 if (tryrelhgcmd && (!hgcmd || hgcmd[0] == '\0'))
228 if (tryrelhgcmd && (!hgcmd || hgcmd[0] == '\0'))
227 hgcmd = getrelhgcmd();
229 hgcmd = getrelhgcmd();
228 if (!hgcmd || hgcmd[0] == '\0')
230 if (!hgcmd || hgcmd[0] == '\0')
229 #ifdef HGPATH
231 #ifdef HGPATH
230 hgcmd = (HGPATH);
232 hgcmd = (HGPATH);
231 #else
233 #else
232 hgcmd = "hg";
234 hgcmd = "hg";
233 #endif
235 #endif
234 }
236 }
235 /* Set $CHGHG to the path to the seleted hg executable if it wasn't
236 * already set. This has the effect of ensuring that a new command
237 * server will be spawned if the existing command server is running from
238 * an executable at a different path. */
239 if (setenv("CHGHG", hgcmd, 1) != 0)
240 abortmsgerrno("failed to setenv");
241 return hgcmd;
237 return hgcmd;
242 }
238 }
243
239
244 static void execcmdserver(const char *hgcmd, const struct cmdserveropts *opts)
240 static void execcmdserver(const struct cmdserveropts *opts)
245 {
241 {
246
242 const char *hgcmd = gethgcmd();
247 const char *baseargv[] = {
243 const char *baseargv[] = {
248 hgcmd, "serve", "--no-profile", "--cmdserver",
244 hgcmd, "serve", "--no-profile", "--cmdserver",
249 "chgunix", "--address", opts->initsockname, "--daemon-postexec",
245 "chgunix", "--address", opts->initsockname, "--daemon-postexec",
250 "chdir:/",
246 "chdir:/",
251 };
247 };
252 size_t baseargvsize = sizeof(baseargv) / sizeof(baseargv[0]);
248 size_t baseargvsize = sizeof(baseargv) / sizeof(baseargv[0]);
253 size_t argsize = baseargvsize + opts->argsize + 1;
249 size_t argsize = baseargvsize + opts->argsize + 1;
254
250
255 const char **argv = mallocx(sizeof(char *) * argsize);
251 const char **argv = mallocx(sizeof(char *) * argsize);
256 memcpy(argv, baseargv, sizeof(baseargv));
252 memcpy(argv, baseargv, sizeof(baseargv));
257 if (opts->args) {
253 if (opts->args) {
258 size_t size = sizeof(char *) * opts->argsize;
254 size_t size = sizeof(char *) * opts->argsize;
259 memcpy(argv + baseargvsize, opts->args, size);
255 memcpy(argv + baseargvsize, opts->args, size);
260 }
256 }
261 argv[argsize - 1] = NULL;
257 argv[argsize - 1] = NULL;
262
258
263 const char *lc_ctype_env = getenv("LC_CTYPE");
259 const char *lc_ctype_env = getenv("LC_CTYPE");
264 if (lc_ctype_env == NULL) {
260 if (lc_ctype_env == NULL) {
265 if (putenv("CHG_CLEAR_LC_CTYPE=") != 0)
261 if (putenv("CHG_CLEAR_LC_CTYPE=") != 0)
266 abortmsgerrno("failed to putenv CHG_CLEAR_LC_CTYPE");
262 abortmsgerrno("failed to putenv CHG_CLEAR_LC_CTYPE");
267 } else {
263 } else {
268 if (setenv("CHGORIG_LC_CTYPE", lc_ctype_env, 1) != 0) {
264 if (setenv("CHGORIG_LC_CTYPE", lc_ctype_env, 1) != 0) {
269 abortmsgerrno("failed to setenv CHGORIG_LC_CTYPE");
265 abortmsgerrno("failed to setenv CHGORIG_LC_CTYPE");
270 }
266 }
271 }
267 }
272
268
273 /* close any open files to avoid hanging locks */
269 /* close any open files to avoid hanging locks */
274 DIR *dp = opendir("/proc/self/fd");
270 DIR *dp = opendir("/proc/self/fd");
275 if (dp != NULL) {
271 if (dp != NULL) {
276 debugmsg("closing files based on /proc contents");
272 debugmsg("closing files based on /proc contents");
277 struct dirent *de;
273 struct dirent *de;
278 while ((de = readdir(dp))) {
274 while ((de = readdir(dp))) {
279 errno = 0;
275 errno = 0;
280 char *end;
276 char *end;
281 long fd_value = strtol(de->d_name, &end, 10);
277 long fd_value = strtol(de->d_name, &end, 10);
282 if (end == de->d_name) {
278 if (end == de->d_name) {
283 /* unable to convert to int (. or ..) */
279 /* unable to convert to int (. or ..) */
284 continue;
280 continue;
285 }
281 }
286 if (errno == ERANGE) {
282 if (errno == ERANGE) {
287 debugmsg("tried to parse %s, but range error "
283 debugmsg("tried to parse %s, but range error "
288 "occurred",
284 "occurred",
289 de->d_name);
285 de->d_name);
290 continue;
286 continue;
291 }
287 }
292 if (fd_value > STDERR_FILENO && fd_value != dirfd(dp)) {
288 if (fd_value > STDERR_FILENO && fd_value != dirfd(dp)) {
293 debugmsg("closing fd %ld", fd_value);
289 debugmsg("closing fd %ld", fd_value);
294 int res = close(fd_value);
290 int res = close(fd_value);
295 if (res) {
291 if (res) {
296 debugmsg("tried to close fd %ld: %d "
292 debugmsg("tried to close fd %ld: %d "
297 "(errno: %d)",
293 "(errno: %d)",
298 fd_value, res, errno);
294 fd_value, res, errno);
299 }
295 }
300 }
296 }
301 }
297 }
302 closedir(dp);
298 closedir(dp);
303 }
299 }
304
300
305 if (putenv("CHGINTERNALMARK=") != 0)
301 if (putenv("CHGINTERNALMARK=") != 0)
306 abortmsgerrno("failed to putenv");
302 abortmsgerrno("failed to putenv");
307 if (execvp(hgcmd, (char **)argv) < 0)
303 if (execvp(hgcmd, (char **)argv) < 0)
308 abortmsgerrno("failed to exec cmdserver");
304 abortmsgerrno("failed to exec cmdserver");
309 free(argv);
305 free(argv);
310 }
306 }
311
307
312 /* Retry until we can connect to the server. Give up after some time. */
308 /* Retry until we can connect to the server. Give up after some time. */
313 static hgclient_t *retryconnectcmdserver(struct cmdserveropts *opts, pid_t pid)
309 static hgclient_t *retryconnectcmdserver(struct cmdserveropts *opts, pid_t pid)
314 {
310 {
315 static const struct timespec sleepreq = {0, 10 * 1000000};
311 static const struct timespec sleepreq = {0, 10 * 1000000};
316 int pst = 0;
312 int pst = 0;
317
313
318 debugmsg("try connect to %s repeatedly", opts->initsockname);
314 debugmsg("try connect to %s repeatedly", opts->initsockname);
319
315
320 unsigned int timeoutsec = 60; /* default: 60 seconds */
316 unsigned int timeoutsec = 60; /* default: 60 seconds */
321 const char *timeoutenv = getenv("CHGTIMEOUT");
317 const char *timeoutenv = getenv("CHGTIMEOUT");
322 if (timeoutenv)
318 if (timeoutenv)
323 sscanf(timeoutenv, "%u", &timeoutsec);
319 sscanf(timeoutenv, "%u", &timeoutsec);
324
320
325 for (unsigned int i = 0; !timeoutsec || i < timeoutsec * 100; i++) {
321 for (unsigned int i = 0; !timeoutsec || i < timeoutsec * 100; i++) {
326 hgclient_t *hgc = hgc_open(opts->initsockname);
322 hgclient_t *hgc = hgc_open(opts->initsockname);
327 if (hgc) {
323 if (hgc) {
328 debugmsg("rename %s to %s", opts->initsockname,
324 debugmsg("rename %s to %s", opts->initsockname,
329 opts->sockname);
325 opts->sockname);
330 int r = rename(opts->initsockname, opts->sockname);
326 int r = rename(opts->initsockname, opts->sockname);
331 if (r != 0)
327 if (r != 0)
332 abortmsgerrno("cannot rename");
328 abortmsgerrno("cannot rename");
333 return hgc;
329 return hgc;
334 }
330 }
335
331
336 if (pid > 0) {
332 if (pid > 0) {
337 /* collect zombie if child process fails to start */
333 /* collect zombie if child process fails to start */
338 int r = waitpid(pid, &pst, WNOHANG);
334 int r = waitpid(pid, &pst, WNOHANG);
339 if (r != 0)
335 if (r != 0)
340 goto cleanup;
336 goto cleanup;
341 }
337 }
342
338
343 nanosleep(&sleepreq, NULL);
339 nanosleep(&sleepreq, NULL);
344 }
340 }
345
341
346 abortmsg("timed out waiting for cmdserver %s", opts->initsockname);
342 abortmsg("timed out waiting for cmdserver %s", opts->initsockname);
347 return NULL;
343 return NULL;
348
344
349 cleanup:
345 cleanup:
350 if (WIFEXITED(pst)) {
346 if (WIFEXITED(pst)) {
351 if (WEXITSTATUS(pst) == 0)
347 if (WEXITSTATUS(pst) == 0)
352 abortmsg("could not connect to cmdserver "
348 abortmsg("could not connect to cmdserver "
353 "(exited with status 0)");
349 "(exited with status 0)");
354 debugmsg("cmdserver exited with status %d", WEXITSTATUS(pst));
350 debugmsg("cmdserver exited with status %d", WEXITSTATUS(pst));
355 exit(WEXITSTATUS(pst));
351 exit(WEXITSTATUS(pst));
356 } else if (WIFSIGNALED(pst)) {
352 } else if (WIFSIGNALED(pst)) {
357 abortmsg("cmdserver killed by signal %d", WTERMSIG(pst));
353 abortmsg("cmdserver killed by signal %d", WTERMSIG(pst));
358 } else {
354 } else {
359 abortmsg("error while waiting for cmdserver");
355 abortmsg("error while waiting for cmdserver");
360 }
356 }
361 return NULL;
357 return NULL;
362 }
358 }
363
359
364 /* Connect to a cmdserver. Will start a new server on demand. */
360 /* Connect to a cmdserver. Will start a new server on demand. */
365 static hgclient_t *connectcmdserver(struct cmdserveropts *opts)
361 static hgclient_t *connectcmdserver(struct cmdserveropts *opts)
366 {
362 {
367 const char *sockname =
363 const char *sockname =
368 opts->redirectsockname[0] ? opts->redirectsockname : opts->sockname;
364 opts->redirectsockname[0] ? opts->redirectsockname : opts->sockname;
369 debugmsg("try connect to %s", sockname);
365 debugmsg("try connect to %s", sockname);
370 hgclient_t *hgc = hgc_open(sockname);
366 hgclient_t *hgc = hgc_open(sockname);
371 if (hgc)
367 if (hgc)
372 return hgc;
368 return hgc;
373
369
374 /* prevent us from being connected to an outdated server: we were
370 /* prevent us from being connected to an outdated server: we were
375 * told by a server to redirect to opts->redirectsockname and that
371 * told by a server to redirect to opts->redirectsockname and that
376 * address does not work. we do not want to connect to the server
372 * address does not work. we do not want to connect to the server
377 * again because it will probably tell us the same thing. */
373 * again because it will probably tell us the same thing. */
378 if (sockname == opts->redirectsockname)
374 if (sockname == opts->redirectsockname)
379 unlink(opts->sockname);
375 unlink(opts->sockname);
380
376
381 debugmsg("start cmdserver at %s", opts->initsockname);
377 debugmsg("start cmdserver at %s", opts->initsockname);
382
378
383 /* Get the path to the hg executable before we fork because this
384 * function might update the environment, and we want this to be
385 * reflected in both the parent and child processes. */
386 const char *hgcmd = gethgcmd();
387
388 pid_t pid = fork();
379 pid_t pid = fork();
389 if (pid < 0)
380 if (pid < 0)
390 abortmsg("failed to fork cmdserver process");
381 abortmsg("failed to fork cmdserver process");
391 if (pid == 0) {
382 if (pid == 0) {
392 execcmdserver(hgcmd, opts);
383 execcmdserver(opts);
393 } else {
384 } else {
394 hgc = retryconnectcmdserver(opts, pid);
385 hgc = retryconnectcmdserver(opts, pid);
395 }
386 }
396
387
397 return hgc;
388 return hgc;
398 }
389 }
399
390
400 static void killcmdserver(const struct cmdserveropts *opts)
391 static void killcmdserver(const struct cmdserveropts *opts)
401 {
392 {
402 /* resolve config hash */
393 /* resolve config hash */
403 char *resolvedpath = realpath(opts->sockname, NULL);
394 char *resolvedpath = realpath(opts->sockname, NULL);
404 if (resolvedpath) {
395 if (resolvedpath) {
405 unlink(resolvedpath);
396 unlink(resolvedpath);
406 free(resolvedpath);
397 free(resolvedpath);
407 }
398 }
408 }
399 }
409
400
410 /* Run instructions sent from the server like unlink and set redirect path
401 /* Run instructions sent from the server like unlink and set redirect path
411 * Return 1 if reconnect is needed, otherwise 0 */
402 * Return 1 if reconnect is needed, otherwise 0 */
412 static int runinstructions(struct cmdserveropts *opts, const char **insts)
403 static int runinstructions(struct cmdserveropts *opts, const char **insts)
413 {
404 {
414 int needreconnect = 0;
405 int needreconnect = 0;
415 if (!insts)
406 if (!insts)
416 return needreconnect;
407 return needreconnect;
417
408
418 assert(insts);
409 assert(insts);
419 opts->redirectsockname[0] = '\0';
410 opts->redirectsockname[0] = '\0';
420 const char **pinst;
411 const char **pinst;
421 for (pinst = insts; *pinst; pinst++) {
412 for (pinst = insts; *pinst; pinst++) {
422 debugmsg("instruction: %s", *pinst);
413 debugmsg("instruction: %s", *pinst);
423 if (strncmp(*pinst, "unlink ", 7) == 0) {
414 if (strncmp(*pinst, "unlink ", 7) == 0) {
424 unlink(*pinst + 7);
415 unlink(*pinst + 7);
425 } else if (strncmp(*pinst, "redirect ", 9) == 0) {
416 } else if (strncmp(*pinst, "redirect ", 9) == 0) {
426 int r = snprintf(opts->redirectsockname,
417 int r = snprintf(opts->redirectsockname,
427 sizeof(opts->redirectsockname), "%s",
418 sizeof(opts->redirectsockname), "%s",
428 *pinst + 9);
419 *pinst + 9);
429 if (r < 0 || r >= (int)sizeof(opts->redirectsockname))
420 if (r < 0 || r >= (int)sizeof(opts->redirectsockname))
430 abortmsg("redirect path is too long (%d)", r);
421 abortmsg("redirect path is too long (%d)", r);
431 needreconnect = 1;
422 needreconnect = 1;
432 } else if (strncmp(*pinst, "exit ", 5) == 0) {
423 } else if (strncmp(*pinst, "exit ", 5) == 0) {
433 int n = 0;
424 int n = 0;
434 if (sscanf(*pinst + 5, "%d", &n) != 1)
425 if (sscanf(*pinst + 5, "%d", &n) != 1)
435 abortmsg("cannot read the exit code");
426 abortmsg("cannot read the exit code");
436 exit(n);
427 exit(n);
437 } else if (strcmp(*pinst, "reconnect") == 0) {
428 } else if (strcmp(*pinst, "reconnect") == 0) {
438 needreconnect = 1;
429 needreconnect = 1;
439 } else {
430 } else {
440 abortmsg("unknown instruction: %s", *pinst);
431 abortmsg("unknown instruction: %s", *pinst);
441 }
432 }
442 }
433 }
443 return needreconnect;
434 return needreconnect;
444 }
435 }
445
436
446 /*
437 /*
447 * Test whether the command and the environment is unsupported or not.
438 * Test whether the command and the environment is unsupported or not.
448 *
439 *
449 * If any of the stdio file descriptors are not present (rare, but some tools
440 * If any of the stdio file descriptors are not present (rare, but some tools
450 * might spawn new processes without stdio instead of redirecting them to the
441 * might spawn new processes without stdio instead of redirecting them to the
451 * null device), then mark it as not supported because attachio won't work
442 * null device), then mark it as not supported because attachio won't work
452 * correctly.
443 * correctly.
453 *
444 *
454 * The command list is not designed to cover all cases. But it's fast, and does
445 * The command list is not designed to cover all cases. But it's fast, and does
455 * not depend on the server.
446 * not depend on the server.
456 */
447 */
457 static int isunsupported(int argc, const char *argv[])
448 static int isunsupported(int argc, const char *argv[])
458 {
449 {
459 enum {
450 enum {
460 SERVE = 1,
451 SERVE = 1,
461 DAEMON = 2,
452 DAEMON = 2,
462 SERVEDAEMON = SERVE | DAEMON,
453 SERVEDAEMON = SERVE | DAEMON,
463 };
454 };
464 unsigned int state = 0;
455 unsigned int state = 0;
465 int i;
456 int i;
466 /* use fcntl to test missing stdio fds */
457 /* use fcntl to test missing stdio fds */
467 if (fcntl(STDIN_FILENO, F_GETFD) == -1 ||
458 if (fcntl(STDIN_FILENO, F_GETFD) == -1 ||
468 fcntl(STDOUT_FILENO, F_GETFD) == -1 ||
459 fcntl(STDOUT_FILENO, F_GETFD) == -1 ||
469 fcntl(STDERR_FILENO, F_GETFD) == -1) {
460 fcntl(STDERR_FILENO, F_GETFD) == -1) {
470 debugmsg("stdio fds are missing");
461 debugmsg("stdio fds are missing");
471 return 1;
462 return 1;
472 }
463 }
473 for (i = 0; i < argc; ++i) {
464 for (i = 0; i < argc; ++i) {
474 if (strcmp(argv[i], "--") == 0)
465 if (strcmp(argv[i], "--") == 0)
475 break;
466 break;
476 /*
467 /*
477 * there can be false positives but no false negative
468 * there can be false positives but no false negative
478 * we cannot assume `serve` will always be first argument
469 * we cannot assume `serve` will always be first argument
479 * because global options can be passed before the command name
470 * because global options can be passed before the command name
480 */
471 */
481 if (strcmp("serve", argv[i]) == 0)
472 if (strcmp("serve", argv[i]) == 0)
482 state |= SERVE;
473 state |= SERVE;
483 else if (strcmp("-d", argv[i]) == 0 ||
474 else if (strcmp("-d", argv[i]) == 0 ||
484 strcmp("--daemon", argv[i]) == 0)
475 strcmp("--daemon", argv[i]) == 0)
485 state |= DAEMON;
476 state |= DAEMON;
486 }
477 }
487 return (state & SERVEDAEMON) == SERVEDAEMON;
478 return (state & SERVEDAEMON) == SERVEDAEMON;
488 }
479 }
489
480
490 static void execoriginalhg(const char *argv[])
481 static void execoriginalhg(const char *argv[])
491 {
482 {
492 debugmsg("execute original hg");
483 debugmsg("execute original hg");
493 if (execvp(gethgcmd(), (char **)argv) < 0)
484 if (execvp(gethgcmd(), (char **)argv) < 0)
494 abortmsgerrno("failed to exec original hg");
485 abortmsgerrno("failed to exec original hg");
495 }
486 }
496
487
497 int main(int argc, const char *argv[])
488 int main(int argc, const char *argv[])
498 {
489 {
499 if (getenv("CHGDEBUG"))
490 if (getenv("CHGDEBUG"))
500 enabledebugmsg();
491 enabledebugmsg();
501
492
502 if (!getenv("HGPLAIN") && isatty(fileno(stderr)))
493 if (!getenv("HGPLAIN") && isatty(fileno(stderr)))
503 enablecolor();
494 enablecolor();
504
495
505 if (getenv("CHGINTERNALMARK"))
496 if (getenv("CHGINTERNALMARK"))
506 abortmsg("chg started by chg detected.\n"
497 abortmsg("chg started by chg detected.\n"
507 "Please make sure ${HG:-hg} is not a symlink or "
498 "Please make sure ${HG:-hg} is not a symlink or "
508 "wrapper to chg. Alternatively, set $CHGHG to the "
499 "wrapper to chg. Alternatively, set $CHGHG to the "
509 "path of real hg.");
500 "path of real hg.");
510
501
511 if (isunsupported(argc - 1, argv + 1))
502 if (isunsupported(argc - 1, argv + 1))
512 execoriginalhg(argv);
503 execoriginalhg(argv);
513
504
514 struct cmdserveropts opts;
505 struct cmdserveropts opts;
515 initcmdserveropts(&opts);
506 initcmdserveropts(&opts);
516 setcmdserveropts(&opts);
507 setcmdserveropts(&opts);
517 setcmdserverargs(&opts, argc, argv);
508 setcmdserverargs(&opts, argc, argv);
518
509
519 if (argc == 2) {
510 if (argc == 2) {
520 if (strcmp(argv[1], "--kill-chg-daemon") == 0) {
511 if (strcmp(argv[1], "--kill-chg-daemon") == 0) {
521 killcmdserver(&opts);
512 killcmdserver(&opts);
522 return 0;
513 return 0;
523 }
514 }
524 }
515 }
525
516
517 /* Set $CHGHG to the path of the hg executable we intend to use. This
518 * is a no-op if $CHGHG was expliclty specified, but otherwise this
519 * ensures that we will spawn a new command server if we connect to an
520 * existing one running from a different executable. This should only
521 * only be needed when chg is built with HGPATHREL since otherwise the
522 * hg executable used when CHGHG is absent should be deterministic.
523 * */
524 if (setenv("CHGHG", gethgcmd(), 1) != 0)
525 abortmsgerrno("failed to setenv");
526
526 hgclient_t *hgc;
527 hgclient_t *hgc;
527 size_t retry = 0;
528 size_t retry = 0;
528 while (1) {
529 while (1) {
529 hgc = connectcmdserver(&opts);
530 hgc = connectcmdserver(&opts);
530 if (!hgc)
531 if (!hgc)
531 abortmsg("cannot open hg client");
532 abortmsg("cannot open hg client");
532 /* Use `environ(7)` instead of the optional `envp` argument to
533 /* Use `environ(7)` instead of the optional `envp` argument to
533 * `main` because `envp` does not update when the environment
534 * `main` because `envp` does not update when the environment
534 * changes, but `environ` does. */
535 * changes, but `environ` does. */
535 hgc_setenv(hgc, (const char *const *)environ);
536 hgc_setenv(hgc, (const char *const *)environ);
536 const char **insts = hgc_validate(hgc, argv + 1, argc - 1);
537 const char **insts = hgc_validate(hgc, argv + 1, argc - 1);
537 int needreconnect = runinstructions(&opts, insts);
538 int needreconnect = runinstructions(&opts, insts);
538 free(insts);
539 free(insts);
539 if (!needreconnect)
540 if (!needreconnect)
540 break;
541 break;
541 hgc_close(hgc);
542 hgc_close(hgc);
542 if (++retry > 10)
543 if (++retry > 10)
543 abortmsg("too many redirections.\n"
544 abortmsg("too many redirections.\n"
544 "Please make sure %s is not a wrapper which "
545 "Please make sure %s is not a wrapper which "
545 "changes sensitive environment variables "
546 "changes sensitive environment variables "
546 "before executing hg. If you have to use a "
547 "before executing hg. If you have to use a "
547 "wrapper, wrap chg instead of hg.",
548 "wrapper, wrap chg instead of hg.",
548 gethgcmd());
549 gethgcmd());
549 }
550 }
550
551
551 setupsignalhandler(hgc_peerpid(hgc), hgc_peerpgid(hgc));
552 setupsignalhandler(hgc_peerpid(hgc), hgc_peerpgid(hgc));
552 atexit(waitpager);
553 atexit(waitpager);
553 int exitcode = hgc_runcommand(hgc, argv + 1, argc - 1);
554 int exitcode = hgc_runcommand(hgc, argv + 1, argc - 1);
554 restoresignalhandler();
555 restoresignalhandler();
555 hgc_close(hgc);
556 hgc_close(hgc);
556 freecmdserveropts(&opts);
557 freecmdserveropts(&opts);
557
558
558 return exitcode;
559 return exitcode;
559 }
560 }
@@ -1,958 +1,959 b''
1 # fix - rewrite file content in changesets and working copy
1 # fix - rewrite file content in changesets and working copy
2 #
2 #
3 # Copyright 2018 Google LLC.
3 # Copyright 2018 Google LLC.
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7 """rewrite file content in changesets or working copy (EXPERIMENTAL)
7 """rewrite file content in changesets or working copy (EXPERIMENTAL)
8
8
9 Provides a command that runs configured tools on the contents of modified files,
9 Provides a command that runs configured tools on the contents of modified files,
10 writing back any fixes to the working copy or replacing changesets.
10 writing back any fixes to the working copy or replacing changesets.
11
11
12 Fixer tools are run in the repository's root directory. This allows them to read
13 configuration files from the working copy, or even write to the working copy.
14 The working copy is not updated to match the revision being fixed. In fact,
15 several revisions may be fixed in parallel. Writes to the working copy are not
16 amended into the revision being fixed; fixer tools MUST always read content to
17 be fixed from stdin, and write fixed file content back to stdout.
18
12 Here is an example configuration that causes :hg:`fix` to apply automatic
19 Here is an example configuration that causes :hg:`fix` to apply automatic
13 formatting fixes to modified lines in C++ code::
20 formatting fixes to modified lines in C++ code::
14
21
15 [fix]
22 [fix]
16 clang-format:command=clang-format --assume-filename={rootpath}
23 clang-format:command=clang-format --assume-filename={rootpath}
17 clang-format:linerange=--lines={first}:{last}
24 clang-format:linerange=--lines={first}:{last}
18 clang-format:pattern=set:**.cpp or **.hpp
25 clang-format:pattern=set:**.cpp or **.hpp
19
26
20 The :command suboption forms the first part of the shell command that will be
27 The :command suboption forms the first part of the shell command that will be
21 used to fix a file. The content of the file is passed on standard input, and the
28 used to fix a file. The content of the file is passed on standard input, and the
22 fixed file content is expected on standard output. Any output on standard error
29 fixed file content is expected on standard output. Any output on standard error
23 will be displayed as a warning. If the exit status is not zero, the file will
30 will be displayed as a warning. If the exit status is not zero, the file will
24 not be affected. A placeholder warning is displayed if there is a non-zero exit
31 not be affected. A placeholder warning is displayed if there is a non-zero exit
25 status but no standard error output. Some values may be substituted into the
32 status but no standard error output. Some values may be substituted into the
26 command::
33 command::
27
34
28 {rootpath} The path of the file being fixed, relative to the repo root
35 {rootpath} The path of the file being fixed, relative to the repo root
29 {basename} The name of the file being fixed, without the directory path
36 {basename} The name of the file being fixed, without the directory path
30
37
31 If the :linerange suboption is set, the tool will only be run if there are
38 If the :linerange suboption is set, the tool will only be run if there are
32 changed lines in a file. The value of this suboption is appended to the shell
39 changed lines in a file. The value of this suboption is appended to the shell
33 command once for every range of changed lines in the file. Some values may be
40 command once for every range of changed lines in the file. Some values may be
34 substituted into the command::
41 substituted into the command::
35
42
36 {first} The 1-based line number of the first line in the modified range
43 {first} The 1-based line number of the first line in the modified range
37 {last} The 1-based line number of the last line in the modified range
44 {last} The 1-based line number of the last line in the modified range
38
45
39 Deleted sections of a file will be ignored by :linerange, because there is no
46 Deleted sections of a file will be ignored by :linerange, because there is no
40 corresponding line range in the version being fixed.
47 corresponding line range in the version being fixed.
41
48
42 By default, tools that set :linerange will only be executed if there is at least
49 By default, tools that set :linerange will only be executed if there is at least
43 one changed line range. This is meant to prevent accidents like running a code
50 one changed line range. This is meant to prevent accidents like running a code
44 formatter in such a way that it unexpectedly reformats the whole file. If such a
51 formatter in such a way that it unexpectedly reformats the whole file. If such a
45 tool needs to operate on unchanged files, it should set the :skipclean suboption
52 tool needs to operate on unchanged files, it should set the :skipclean suboption
46 to false.
53 to false.
47
54
48 The :pattern suboption determines which files will be passed through each
55 The :pattern suboption determines which files will be passed through each
49 configured tool. See :hg:`help patterns` for possible values. However, all
56 configured tool. See :hg:`help patterns` for possible values. However, all
50 patterns are relative to the repo root, even if that text says they are relative
57 patterns are relative to the repo root, even if that text says they are relative
51 to the current working directory. If there are file arguments to :hg:`fix`, the
58 to the current working directory. If there are file arguments to :hg:`fix`, the
52 intersection of these patterns is used.
59 intersection of these patterns is used.
53
60
54 There is also a configurable limit for the maximum size of file that will be
61 There is also a configurable limit for the maximum size of file that will be
55 processed by :hg:`fix`::
62 processed by :hg:`fix`::
56
63
57 [fix]
64 [fix]
58 maxfilesize = 2MB
65 maxfilesize = 2MB
59
66
60 Normally, execution of configured tools will continue after a failure (indicated
67 Normally, execution of configured tools will continue after a failure (indicated
61 by a non-zero exit status). It can also be configured to abort after the first
68 by a non-zero exit status). It can also be configured to abort after the first
62 such failure, so that no files will be affected if any tool fails. This abort
69 such failure, so that no files will be affected if any tool fails. This abort
63 will also cause :hg:`fix` to exit with a non-zero status::
70 will also cause :hg:`fix` to exit with a non-zero status::
64
71
65 [fix]
72 [fix]
66 failure = abort
73 failure = abort
67
74
68 When multiple tools are configured to affect a file, they execute in an order
75 When multiple tools are configured to affect a file, they execute in an order
69 defined by the :priority suboption. The priority suboption has a default value
76 defined by the :priority suboption. The priority suboption has a default value
70 of zero for each tool. Tools are executed in order of descending priority. The
77 of zero for each tool. Tools are executed in order of descending priority. The
71 execution order of tools with equal priority is unspecified. For example, you
78 execution order of tools with equal priority is unspecified. For example, you
72 could use the 'sort' and 'head' utilities to keep only the 10 smallest numbers
79 could use the 'sort' and 'head' utilities to keep only the 10 smallest numbers
73 in a text file by ensuring that 'sort' runs before 'head'::
80 in a text file by ensuring that 'sort' runs before 'head'::
74
81
75 [fix]
82 [fix]
76 sort:command = sort -n
83 sort:command = sort -n
77 head:command = head -n 10
84 head:command = head -n 10
78 sort:pattern = numbers.txt
85 sort:pattern = numbers.txt
79 head:pattern = numbers.txt
86 head:pattern = numbers.txt
80 sort:priority = 2
87 sort:priority = 2
81 head:priority = 1
88 head:priority = 1
82
89
83 To account for changes made by each tool, the line numbers used for incremental
90 To account for changes made by each tool, the line numbers used for incremental
84 formatting are recomputed before executing the next tool. So, each tool may see
91 formatting are recomputed before executing the next tool. So, each tool may see
85 different values for the arguments added by the :linerange suboption.
92 different values for the arguments added by the :linerange suboption.
86
93
87 Each fixer tool is allowed to return some metadata in addition to the fixed file
94 Each fixer tool is allowed to return some metadata in addition to the fixed file
88 content. The metadata must be placed before the file content on stdout,
95 content. The metadata must be placed before the file content on stdout,
89 separated from the file content by a zero byte. The metadata is parsed as a JSON
96 separated from the file content by a zero byte. The metadata is parsed as a JSON
90 value (so, it should be UTF-8 encoded and contain no zero bytes). A fixer tool
97 value (so, it should be UTF-8 encoded and contain no zero bytes). A fixer tool
91 is expected to produce this metadata encoding if and only if the :metadata
98 is expected to produce this metadata encoding if and only if the :metadata
92 suboption is true::
99 suboption is true::
93
100
94 [fix]
101 [fix]
95 tool:command = tool --prepend-json-metadata
102 tool:command = tool --prepend-json-metadata
96 tool:metadata = true
103 tool:metadata = true
97
104
98 The metadata values are passed to hooks, which can be used to print summaries or
105 The metadata values are passed to hooks, which can be used to print summaries or
99 perform other post-fixing work. The supported hooks are::
106 perform other post-fixing work. The supported hooks are::
100
107
101 "postfixfile"
108 "postfixfile"
102 Run once for each file in each revision where any fixer tools made changes
109 Run once for each file in each revision where any fixer tools made changes
103 to the file content. Provides "$HG_REV" and "$HG_PATH" to identify the file,
110 to the file content. Provides "$HG_REV" and "$HG_PATH" to identify the file,
104 and "$HG_METADATA" with a map of fixer names to metadata values from fixer
111 and "$HG_METADATA" with a map of fixer names to metadata values from fixer
105 tools that affected the file. Fixer tools that didn't affect the file have a
112 tools that affected the file. Fixer tools that didn't affect the file have a
106 value of None. Only fixer tools that executed are present in the metadata.
113 value of None. Only fixer tools that executed are present in the metadata.
107
114
108 "postfix"
115 "postfix"
109 Run once after all files and revisions have been handled. Provides
116 Run once after all files and revisions have been handled. Provides
110 "$HG_REPLACEMENTS" with information about what revisions were created and
117 "$HG_REPLACEMENTS" with information about what revisions were created and
111 made obsolete. Provides a boolean "$HG_WDIRWRITTEN" to indicate whether any
118 made obsolete. Provides a boolean "$HG_WDIRWRITTEN" to indicate whether any
112 files in the working copy were updated. Provides a list "$HG_METADATA"
119 files in the working copy were updated. Provides a list "$HG_METADATA"
113 mapping fixer tool names to lists of metadata values returned from
120 mapping fixer tool names to lists of metadata values returned from
114 executions that modified a file. This aggregates the same metadata
121 executions that modified a file. This aggregates the same metadata
115 previously passed to the "postfixfile" hook.
122 previously passed to the "postfixfile" hook.
116
117 Fixer tools are run in the repository's root directory. This allows them to read
118 configuration files from the working copy, or even write to the working copy.
119 The working copy is not updated to match the revision being fixed. In fact,
120 several revisions may be fixed in parallel. Writes to the working copy are not
121 amended into the revision being fixed; fixer tools should always write fixed
122 file content back to stdout as documented above.
123 """
123 """
124
124
125
125
126 import collections
126 import collections
127 import itertools
127 import itertools
128 import os
128 import os
129 import re
129 import re
130 import subprocess
130 import subprocess
131
131
132 from mercurial.i18n import _
132 from mercurial.i18n import _
133 from mercurial.node import (
133 from mercurial.node import (
134 nullid,
134 nullid,
135 nullrev,
135 nullrev,
136 wdirrev,
136 wdirrev,
137 )
137 )
138
138
139 from mercurial.utils import procutil
139 from mercurial.utils import procutil
140
140
141 from mercurial import (
141 from mercurial import (
142 cmdutil,
142 cmdutil,
143 context,
143 context,
144 copies,
144 copies,
145 error,
145 error,
146 logcmdutil,
146 logcmdutil,
147 match as matchmod,
147 match as matchmod,
148 mdiff,
148 mdiff,
149 merge,
149 merge,
150 mergestate as mergestatemod,
150 mergestate as mergestatemod,
151 pycompat,
151 pycompat,
152 registrar,
152 registrar,
153 rewriteutil,
153 rewriteutil,
154 scmutil,
154 scmutil,
155 util,
155 util,
156 worker,
156 worker,
157 )
157 )
158
158
159 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
159 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
160 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
160 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
161 # be specifying the version(s) of Mercurial they are tested with, or
161 # be specifying the version(s) of Mercurial they are tested with, or
162 # leave the attribute unspecified.
162 # leave the attribute unspecified.
163 testedwith = b'ships-with-hg-core'
163 testedwith = b'ships-with-hg-core'
164
164
165 cmdtable = {}
165 cmdtable = {}
166 command = registrar.command(cmdtable)
166 command = registrar.command(cmdtable)
167
167
168 configtable = {}
168 configtable = {}
169 configitem = registrar.configitem(configtable)
169 configitem = registrar.configitem(configtable)
170
170
171 # Register the suboptions allowed for each configured fixer, and default values.
171 # Register the suboptions allowed for each configured fixer, and default values.
172 FIXER_ATTRS = {
172 FIXER_ATTRS = {
173 b'command': None,
173 b'command': None,
174 b'linerange': None,
174 b'linerange': None,
175 b'pattern': None,
175 b'pattern': None,
176 b'priority': 0,
176 b'priority': 0,
177 b'metadata': False,
177 b'metadata': False,
178 b'skipclean': True,
178 b'skipclean': True,
179 b'enabled': True,
179 b'enabled': True,
180 }
180 }
181
181
182 for key, default in FIXER_ATTRS.items():
182 for key, default in FIXER_ATTRS.items():
183 configitem(b'fix', b'.*:%s$' % key, default=default, generic=True)
183 configitem(b'fix', b'.*:%s$' % key, default=default, generic=True)
184
184
185 # A good default size allows most source code files to be fixed, but avoids
185 # A good default size allows most source code files to be fixed, but avoids
186 # letting fixer tools choke on huge inputs, which could be surprising to the
186 # letting fixer tools choke on huge inputs, which could be surprising to the
187 # user.
187 # user.
188 configitem(b'fix', b'maxfilesize', default=b'2MB')
188 configitem(b'fix', b'maxfilesize', default=b'2MB')
189
189
190 # Allow fix commands to exit non-zero if an executed fixer tool exits non-zero.
190 # Allow fix commands to exit non-zero if an executed fixer tool exits non-zero.
191 # This helps users do shell scripts that stop when a fixer tool signals a
191 # This helps users do shell scripts that stop when a fixer tool signals a
192 # problem.
192 # problem.
193 configitem(b'fix', b'failure', default=b'continue')
193 configitem(b'fix', b'failure', default=b'continue')
194
194
195
195
196 def checktoolfailureaction(ui, message, hint=None):
196 def checktoolfailureaction(ui, message, hint=None):
197 """Abort with 'message' if fix.failure=abort"""
197 """Abort with 'message' if fix.failure=abort"""
198 action = ui.config(b'fix', b'failure')
198 action = ui.config(b'fix', b'failure')
199 if action not in (b'continue', b'abort'):
199 if action not in (b'continue', b'abort'):
200 raise error.Abort(
200 raise error.Abort(
201 _(b'unknown fix.failure action: %s') % (action,),
201 _(b'unknown fix.failure action: %s') % (action,),
202 hint=_(b'use "continue" or "abort"'),
202 hint=_(b'use "continue" or "abort"'),
203 )
203 )
204 if action == b'abort':
204 if action == b'abort':
205 raise error.Abort(message, hint=hint)
205 raise error.Abort(message, hint=hint)
206
206
207
207
208 allopt = (b'', b'all', False, _(b'fix all non-public non-obsolete revisions'))
208 allopt = (b'', b'all', False, _(b'fix all non-public non-obsolete revisions'))
209 baseopt = (
209 baseopt = (
210 b'',
210 b'',
211 b'base',
211 b'base',
212 [],
212 [],
213 _(
213 _(
214 b'revisions to diff against (overrides automatic '
214 b'revisions to diff against (overrides automatic '
215 b'selection, and applies to every revision being '
215 b'selection, and applies to every revision being '
216 b'fixed)'
216 b'fixed)'
217 ),
217 ),
218 _(b'REV'),
218 _(b'REV'),
219 )
219 )
220 revopt = (b'r', b'rev', [], _(b'revisions to fix (ADVANCED)'), _(b'REV'))
220 revopt = (b'r', b'rev', [], _(b'revisions to fix (ADVANCED)'), _(b'REV'))
221 sourceopt = (
221 sourceopt = (
222 b's',
222 b's',
223 b'source',
223 b'source',
224 [],
224 [],
225 _(b'fix the specified revisions and their descendants'),
225 _(b'fix the specified revisions and their descendants'),
226 _(b'REV'),
226 _(b'REV'),
227 )
227 )
228 wdiropt = (b'w', b'working-dir', False, _(b'fix the working directory'))
228 wdiropt = (b'w', b'working-dir', False, _(b'fix the working directory'))
229 wholeopt = (b'', b'whole', False, _(b'always fix every line of a file'))
229 wholeopt = (b'', b'whole', False, _(b'always fix every line of a file'))
230 usage = _(b'[OPTION]... [FILE]...')
230 usage = _(b'[OPTION]... [FILE]...')
231
231
232
232
233 @command(
233 @command(
234 b'fix',
234 b'fix',
235 [allopt, baseopt, revopt, sourceopt, wdiropt, wholeopt],
235 [allopt, baseopt, revopt, sourceopt, wdiropt, wholeopt],
236 usage,
236 usage,
237 helpcategory=command.CATEGORY_FILE_CONTENTS,
237 helpcategory=command.CATEGORY_FILE_CONTENTS,
238 )
238 )
239 def fix(ui, repo, *pats, **opts):
239 def fix(ui, repo, *pats, **opts):
240 """rewrite file content in changesets or working directory
240 """rewrite file content in changesets or working directory
241
241
242 Runs any configured tools to fix the content of files. Only affects files
242 Runs any configured tools to fix the content of files. (See
243 :hg:`help -e fix` for details about configuring tools.) Only affects files
243 with changes, unless file arguments are provided. Only affects changed lines
244 with changes, unless file arguments are provided. Only affects changed lines
244 of files, unless the --whole flag is used. Some tools may always affect the
245 of files, unless the --whole flag is used. Some tools may always affect the
245 whole file regardless of --whole.
246 whole file regardless of --whole.
246
247
247 If --working-dir is used, files with uncommitted changes in the working copy
248 If --working-dir is used, files with uncommitted changes in the working copy
248 will be fixed. Note that no backup are made.
249 will be fixed. Note that no backup are made.
249
250
250 If revisions are specified with --source, those revisions and their
251 If revisions are specified with --source, those revisions and their
251 descendants will be checked, and they may be replaced with new revisions
252 descendants will be checked, and they may be replaced with new revisions
252 that have fixed file content. By automatically including the descendants,
253 that have fixed file content. By automatically including the descendants,
253 no merging, rebasing, or evolution will be required. If an ancestor of the
254 no merging, rebasing, or evolution will be required. If an ancestor of the
254 working copy is included, then the working copy itself will also be fixed,
255 working copy is included, then the working copy itself will also be fixed,
255 and the working copy will be updated to the fixed parent.
256 and the working copy will be updated to the fixed parent.
256
257
257 When determining what lines of each file to fix at each revision, the whole
258 When determining what lines of each file to fix at each revision, the whole
258 set of revisions being fixed is considered, so that fixes to earlier
259 set of revisions being fixed is considered, so that fixes to earlier
259 revisions are not forgotten in later ones. The --base flag can be used to
260 revisions are not forgotten in later ones. The --base flag can be used to
260 override this default behavior, though it is not usually desirable to do so.
261 override this default behavior, though it is not usually desirable to do so.
261 """
262 """
262 opts = pycompat.byteskwargs(opts)
263 opts = pycompat.byteskwargs(opts)
263 cmdutil.check_at_most_one_arg(opts, b'all', b'source', b'rev')
264 cmdutil.check_at_most_one_arg(opts, b'all', b'source', b'rev')
264 cmdutil.check_incompatible_arguments(
265 cmdutil.check_incompatible_arguments(
265 opts, b'working_dir', [b'all', b'source']
266 opts, b'working_dir', [b'all', b'source']
266 )
267 )
267
268
268 with repo.wlock(), repo.lock(), repo.transaction(b'fix'):
269 with repo.wlock(), repo.lock(), repo.transaction(b'fix'):
269 revstofix = getrevstofix(ui, repo, opts)
270 revstofix = getrevstofix(ui, repo, opts)
270 basectxs = getbasectxs(repo, opts, revstofix)
271 basectxs = getbasectxs(repo, opts, revstofix)
271 workqueue, numitems = getworkqueue(
272 workqueue, numitems = getworkqueue(
272 ui, repo, pats, opts, revstofix, basectxs
273 ui, repo, pats, opts, revstofix, basectxs
273 )
274 )
274 basepaths = getbasepaths(repo, opts, workqueue, basectxs)
275 basepaths = getbasepaths(repo, opts, workqueue, basectxs)
275 fixers = getfixers(ui)
276 fixers = getfixers(ui)
276
277
277 # Rather than letting each worker independently fetch the files
278 # Rather than letting each worker independently fetch the files
278 # (which also would add complications for shared/keepalive
279 # (which also would add complications for shared/keepalive
279 # connections), prefetch them all first.
280 # connections), prefetch them all first.
280 _prefetchfiles(repo, workqueue, basepaths)
281 _prefetchfiles(repo, workqueue, basepaths)
281
282
282 # There are no data dependencies between the workers fixing each file
283 # There are no data dependencies between the workers fixing each file
283 # revision, so we can use all available parallelism.
284 # revision, so we can use all available parallelism.
284 def getfixes(items):
285 def getfixes(items):
285 for srcrev, path, dstrevs in items:
286 for srcrev, path, dstrevs in items:
286 ctx = repo[srcrev]
287 ctx = repo[srcrev]
287 olddata = ctx[path].data()
288 olddata = ctx[path].data()
288 metadata, newdata = fixfile(
289 metadata, newdata = fixfile(
289 ui,
290 ui,
290 repo,
291 repo,
291 opts,
292 opts,
292 fixers,
293 fixers,
293 ctx,
294 ctx,
294 path,
295 path,
295 basepaths,
296 basepaths,
296 basectxs[srcrev],
297 basectxs[srcrev],
297 )
298 )
298 # We ungroup the work items now, because the code that consumes
299 # We ungroup the work items now, because the code that consumes
299 # these results has to handle each dstrev separately, and in
300 # these results has to handle each dstrev separately, and in
300 # topological order. Because these are handled in topological
301 # topological order. Because these are handled in topological
301 # order, it's important that we pass around references to
302 # order, it's important that we pass around references to
302 # "newdata" instead of copying it. Otherwise, we would be
303 # "newdata" instead of copying it. Otherwise, we would be
303 # keeping more copies of file content in memory at a time than
304 # keeping more copies of file content in memory at a time than
304 # if we hadn't bothered to group/deduplicate the work items.
305 # if we hadn't bothered to group/deduplicate the work items.
305 data = newdata if newdata != olddata else None
306 data = newdata if newdata != olddata else None
306 for dstrev in dstrevs:
307 for dstrev in dstrevs:
307 yield (dstrev, path, metadata, data)
308 yield (dstrev, path, metadata, data)
308
309
309 results = worker.worker(
310 results = worker.worker(
310 ui, 1.0, getfixes, tuple(), workqueue, threadsafe=False
311 ui, 1.0, getfixes, tuple(), workqueue, threadsafe=False
311 )
312 )
312
313
313 # We have to hold on to the data for each successor revision in memory
314 # We have to hold on to the data for each successor revision in memory
314 # until all its parents are committed. We ensure this by committing and
315 # until all its parents are committed. We ensure this by committing and
315 # freeing memory for the revisions in some topological order. This
316 # freeing memory for the revisions in some topological order. This
316 # leaves a little bit of memory efficiency on the table, but also makes
317 # leaves a little bit of memory efficiency on the table, but also makes
317 # the tests deterministic. It might also be considered a feature since
318 # the tests deterministic. It might also be considered a feature since
318 # it makes the results more easily reproducible.
319 # it makes the results more easily reproducible.
319 filedata = collections.defaultdict(dict)
320 filedata = collections.defaultdict(dict)
320 aggregatemetadata = collections.defaultdict(list)
321 aggregatemetadata = collections.defaultdict(list)
321 replacements = {}
322 replacements = {}
322 wdirwritten = False
323 wdirwritten = False
323 commitorder = sorted(revstofix, reverse=True)
324 commitorder = sorted(revstofix, reverse=True)
324 with ui.makeprogress(
325 with ui.makeprogress(
325 topic=_(b'fixing'), unit=_(b'files'), total=sum(numitems.values())
326 topic=_(b'fixing'), unit=_(b'files'), total=sum(numitems.values())
326 ) as progress:
327 ) as progress:
327 for rev, path, filerevmetadata, newdata in results:
328 for rev, path, filerevmetadata, newdata in results:
328 progress.increment(item=path)
329 progress.increment(item=path)
329 for fixername, fixermetadata in filerevmetadata.items():
330 for fixername, fixermetadata in filerevmetadata.items():
330 aggregatemetadata[fixername].append(fixermetadata)
331 aggregatemetadata[fixername].append(fixermetadata)
331 if newdata is not None:
332 if newdata is not None:
332 filedata[rev][path] = newdata
333 filedata[rev][path] = newdata
333 hookargs = {
334 hookargs = {
334 b'rev': rev,
335 b'rev': rev,
335 b'path': path,
336 b'path': path,
336 b'metadata': filerevmetadata,
337 b'metadata': filerevmetadata,
337 }
338 }
338 repo.hook(
339 repo.hook(
339 b'postfixfile',
340 b'postfixfile',
340 throw=False,
341 throw=False,
341 **pycompat.strkwargs(hookargs)
342 **pycompat.strkwargs(hookargs)
342 )
343 )
343 numitems[rev] -= 1
344 numitems[rev] -= 1
344 # Apply the fixes for this and any other revisions that are
345 # Apply the fixes for this and any other revisions that are
345 # ready and sitting at the front of the queue. Using a loop here
346 # ready and sitting at the front of the queue. Using a loop here
346 # prevents the queue from being blocked by the first revision to
347 # prevents the queue from being blocked by the first revision to
347 # be ready out of order.
348 # be ready out of order.
348 while commitorder and not numitems[commitorder[-1]]:
349 while commitorder and not numitems[commitorder[-1]]:
349 rev = commitorder.pop()
350 rev = commitorder.pop()
350 ctx = repo[rev]
351 ctx = repo[rev]
351 if rev == wdirrev:
352 if rev == wdirrev:
352 writeworkingdir(repo, ctx, filedata[rev], replacements)
353 writeworkingdir(repo, ctx, filedata[rev], replacements)
353 wdirwritten = bool(filedata[rev])
354 wdirwritten = bool(filedata[rev])
354 else:
355 else:
355 replacerev(ui, repo, ctx, filedata[rev], replacements)
356 replacerev(ui, repo, ctx, filedata[rev], replacements)
356 del filedata[rev]
357 del filedata[rev]
357
358
358 cleanup(repo, replacements, wdirwritten)
359 cleanup(repo, replacements, wdirwritten)
359 hookargs = {
360 hookargs = {
360 b'replacements': replacements,
361 b'replacements': replacements,
361 b'wdirwritten': wdirwritten,
362 b'wdirwritten': wdirwritten,
362 b'metadata': aggregatemetadata,
363 b'metadata': aggregatemetadata,
363 }
364 }
364 repo.hook(b'postfix', throw=True, **pycompat.strkwargs(hookargs))
365 repo.hook(b'postfix', throw=True, **pycompat.strkwargs(hookargs))
365
366
366
367
367 def cleanup(repo, replacements, wdirwritten):
368 def cleanup(repo, replacements, wdirwritten):
368 """Calls scmutil.cleanupnodes() with the given replacements.
369 """Calls scmutil.cleanupnodes() with the given replacements.
369
370
370 "replacements" is a dict from nodeid to nodeid, with one key and one value
371 "replacements" is a dict from nodeid to nodeid, with one key and one value
371 for every revision that was affected by fixing. This is slightly different
372 for every revision that was affected by fixing. This is slightly different
372 from cleanupnodes().
373 from cleanupnodes().
373
374
374 "wdirwritten" is a bool which tells whether the working copy was affected by
375 "wdirwritten" is a bool which tells whether the working copy was affected by
375 fixing, since it has no entry in "replacements".
376 fixing, since it has no entry in "replacements".
376
377
377 Useful as a hook point for extending "hg fix" with output summarizing the
378 Useful as a hook point for extending "hg fix" with output summarizing the
378 effects of the command, though we choose not to output anything here.
379 effects of the command, though we choose not to output anything here.
379 """
380 """
380 replacements = {prec: [succ] for prec, succ in replacements.items()}
381 replacements = {prec: [succ] for prec, succ in replacements.items()}
381 scmutil.cleanupnodes(repo, replacements, b'fix', fixphase=True)
382 scmutil.cleanupnodes(repo, replacements, b'fix', fixphase=True)
382
383
383
384
384 def getworkqueue(ui, repo, pats, opts, revstofix, basectxs):
385 def getworkqueue(ui, repo, pats, opts, revstofix, basectxs):
385 """Constructs a list of files to fix and which revisions each fix applies to
386 """Constructs a list of files to fix and which revisions each fix applies to
386
387
387 To avoid duplicating work, there is usually only one work item for each file
388 To avoid duplicating work, there is usually only one work item for each file
388 revision that might need to be fixed. There can be multiple work items per
389 revision that might need to be fixed. There can be multiple work items per
389 file revision if the same file needs to be fixed in multiple changesets with
390 file revision if the same file needs to be fixed in multiple changesets with
390 different baserevs. Each work item also contains a list of changesets where
391 different baserevs. Each work item also contains a list of changesets where
391 the file's data should be replaced with the fixed data. The work items for
392 the file's data should be replaced with the fixed data. The work items for
392 earlier changesets come earlier in the work queue, to improve pipelining by
393 earlier changesets come earlier in the work queue, to improve pipelining by
393 allowing the first changeset to be replaced while fixes are still being
394 allowing the first changeset to be replaced while fixes are still being
394 computed for later changesets.
395 computed for later changesets.
395
396
396 Also returned is a map from changesets to the count of work items that might
397 Also returned is a map from changesets to the count of work items that might
397 affect each changeset. This is used later to count when all of a changeset's
398 affect each changeset. This is used later to count when all of a changeset's
398 work items have been finished, without having to inspect the remaining work
399 work items have been finished, without having to inspect the remaining work
399 queue in each worker subprocess.
400 queue in each worker subprocess.
400
401
401 The example work item (1, "foo/bar.txt", (1, 2, 3)) means that the data of
402 The example work item (1, "foo/bar.txt", (1, 2, 3)) means that the data of
402 bar.txt should be read from revision 1, then fixed, and written back to
403 bar.txt should be read from revision 1, then fixed, and written back to
403 revisions 1, 2 and 3. Revision 1 is called the "srcrev" and the list of
404 revisions 1, 2 and 3. Revision 1 is called the "srcrev" and the list of
404 revisions is called the "dstrevs". In practice the srcrev is always one of
405 revisions is called the "dstrevs". In practice the srcrev is always one of
405 the dstrevs, and we make that choice when constructing the work item so that
406 the dstrevs, and we make that choice when constructing the work item so that
406 the choice can't be made inconsistently later on. The dstrevs should all
407 the choice can't be made inconsistently later on. The dstrevs should all
407 have the same file revision for the given path, so the choice of srcrev is
408 have the same file revision for the given path, so the choice of srcrev is
408 arbitrary. The wdirrev can be a dstrev and a srcrev.
409 arbitrary. The wdirrev can be a dstrev and a srcrev.
409 """
410 """
410 dstrevmap = collections.defaultdict(list)
411 dstrevmap = collections.defaultdict(list)
411 numitems = collections.defaultdict(int)
412 numitems = collections.defaultdict(int)
412 maxfilesize = ui.configbytes(b'fix', b'maxfilesize')
413 maxfilesize = ui.configbytes(b'fix', b'maxfilesize')
413 for rev in sorted(revstofix):
414 for rev in sorted(revstofix):
414 fixctx = repo[rev]
415 fixctx = repo[rev]
415 match = scmutil.match(fixctx, pats, opts)
416 match = scmutil.match(fixctx, pats, opts)
416 for path in sorted(
417 for path in sorted(
417 pathstofix(ui, repo, pats, opts, match, basectxs[rev], fixctx)
418 pathstofix(ui, repo, pats, opts, match, basectxs[rev], fixctx)
418 ):
419 ):
419 fctx = fixctx[path]
420 fctx = fixctx[path]
420 if fctx.islink():
421 if fctx.islink():
421 continue
422 continue
422 if fctx.size() > maxfilesize:
423 if fctx.size() > maxfilesize:
423 ui.warn(
424 ui.warn(
424 _(b'ignoring file larger than %s: %s\n')
425 _(b'ignoring file larger than %s: %s\n')
425 % (util.bytecount(maxfilesize), path)
426 % (util.bytecount(maxfilesize), path)
426 )
427 )
427 continue
428 continue
428 baserevs = tuple(ctx.rev() for ctx in basectxs[rev])
429 baserevs = tuple(ctx.rev() for ctx in basectxs[rev])
429 dstrevmap[(fctx.filerev(), baserevs, path)].append(rev)
430 dstrevmap[(fctx.filerev(), baserevs, path)].append(rev)
430 numitems[rev] += 1
431 numitems[rev] += 1
431 workqueue = [
432 workqueue = [
432 (min(dstrevs), path, dstrevs)
433 (min(dstrevs), path, dstrevs)
433 for (_filerev, _baserevs, path), dstrevs in dstrevmap.items()
434 for (_filerev, _baserevs, path), dstrevs in dstrevmap.items()
434 ]
435 ]
435 # Move work items for earlier changesets to the front of the queue, so we
436 # Move work items for earlier changesets to the front of the queue, so we
436 # might be able to replace those changesets (in topological order) while
437 # might be able to replace those changesets (in topological order) while
437 # we're still processing later work items. Note the min() in the previous
438 # we're still processing later work items. Note the min() in the previous
438 # expression, which means we don't need a custom comparator here. The path
439 # expression, which means we don't need a custom comparator here. The path
439 # is also important in the sort order to make the output order stable. There
440 # is also important in the sort order to make the output order stable. There
440 # are some situations where this doesn't help much, but some situations
441 # are some situations where this doesn't help much, but some situations
441 # where it lets us buffer O(1) files instead of O(n) files.
442 # where it lets us buffer O(1) files instead of O(n) files.
442 workqueue.sort()
443 workqueue.sort()
443 return workqueue, numitems
444 return workqueue, numitems
444
445
445
446
446 def getrevstofix(ui, repo, opts):
447 def getrevstofix(ui, repo, opts):
447 """Returns the set of revision numbers that should be fixed"""
448 """Returns the set of revision numbers that should be fixed"""
448 if opts[b'all']:
449 if opts[b'all']:
449 revs = repo.revs(b'(not public() and not obsolete()) or wdir()')
450 revs = repo.revs(b'(not public() and not obsolete()) or wdir()')
450 elif opts[b'source']:
451 elif opts[b'source']:
451 source_revs = logcmdutil.revrange(repo, opts[b'source'])
452 source_revs = logcmdutil.revrange(repo, opts[b'source'])
452 revs = set(repo.revs(b'(%ld::) - obsolete()', source_revs))
453 revs = set(repo.revs(b'(%ld::) - obsolete()', source_revs))
453 if wdirrev in source_revs:
454 if wdirrev in source_revs:
454 # `wdir()::` is currently empty, so manually add wdir
455 # `wdir()::` is currently empty, so manually add wdir
455 revs.add(wdirrev)
456 revs.add(wdirrev)
456 if repo[b'.'].rev() in revs:
457 if repo[b'.'].rev() in revs:
457 revs.add(wdirrev)
458 revs.add(wdirrev)
458 else:
459 else:
459 revs = set(logcmdutil.revrange(repo, opts[b'rev']))
460 revs = set(logcmdutil.revrange(repo, opts[b'rev']))
460 if opts.get(b'working_dir'):
461 if opts.get(b'working_dir'):
461 revs.add(wdirrev)
462 revs.add(wdirrev)
462 # Allow fixing only wdir() even if there's an unfinished operation
463 # Allow fixing only wdir() even if there's an unfinished operation
463 if not (len(revs) == 1 and wdirrev in revs):
464 if not (len(revs) == 1 and wdirrev in revs):
464 cmdutil.checkunfinished(repo)
465 cmdutil.checkunfinished(repo)
465 rewriteutil.precheck(repo, revs, b'fix')
466 rewriteutil.precheck(repo, revs, b'fix')
466 if (
467 if (
467 wdirrev in revs
468 wdirrev in revs
468 and mergestatemod.mergestate.read(repo).unresolvedcount()
469 and mergestatemod.mergestate.read(repo).unresolvedcount()
469 ):
470 ):
470 raise error.Abort(b'unresolved conflicts', hint=b"use 'hg resolve'")
471 raise error.Abort(b'unresolved conflicts', hint=b"use 'hg resolve'")
471 if not revs:
472 if not revs:
472 raise error.Abort(
473 raise error.Abort(
473 b'no changesets specified', hint=b'use --source or --working-dir'
474 b'no changesets specified', hint=b'use --source or --working-dir'
474 )
475 )
475 return revs
476 return revs
476
477
477
478
478 def pathstofix(ui, repo, pats, opts, match, basectxs, fixctx):
479 def pathstofix(ui, repo, pats, opts, match, basectxs, fixctx):
479 """Returns the set of files that should be fixed in a context
480 """Returns the set of files that should be fixed in a context
480
481
481 The result depends on the base contexts; we include any file that has
482 The result depends on the base contexts; we include any file that has
482 changed relative to any of the base contexts. Base contexts should be
483 changed relative to any of the base contexts. Base contexts should be
483 ancestors of the context being fixed.
484 ancestors of the context being fixed.
484 """
485 """
485 files = set()
486 files = set()
486 for basectx in basectxs:
487 for basectx in basectxs:
487 stat = basectx.status(
488 stat = basectx.status(
488 fixctx, match=match, listclean=bool(pats), listunknown=bool(pats)
489 fixctx, match=match, listclean=bool(pats), listunknown=bool(pats)
489 )
490 )
490 files.update(
491 files.update(
491 set(
492 set(
492 itertools.chain(
493 itertools.chain(
493 stat.added, stat.modified, stat.clean, stat.unknown
494 stat.added, stat.modified, stat.clean, stat.unknown
494 )
495 )
495 )
496 )
496 )
497 )
497 return files
498 return files
498
499
499
500
500 def lineranges(opts, path, basepaths, basectxs, fixctx, content2):
501 def lineranges(opts, path, basepaths, basectxs, fixctx, content2):
501 """Returns the set of line ranges that should be fixed in a file
502 """Returns the set of line ranges that should be fixed in a file
502
503
503 Of the form [(10, 20), (30, 40)].
504 Of the form [(10, 20), (30, 40)].
504
505
505 This depends on the given base contexts; we must consider lines that have
506 This depends on the given base contexts; we must consider lines that have
506 changed versus any of the base contexts, and whether the file has been
507 changed versus any of the base contexts, and whether the file has been
507 renamed versus any of them.
508 renamed versus any of them.
508
509
509 Another way to understand this is that we exclude line ranges that are
510 Another way to understand this is that we exclude line ranges that are
510 common to the file in all base contexts.
511 common to the file in all base contexts.
511 """
512 """
512 if opts.get(b'whole'):
513 if opts.get(b'whole'):
513 # Return a range containing all lines. Rely on the diff implementation's
514 # Return a range containing all lines. Rely on the diff implementation's
514 # idea of how many lines are in the file, instead of reimplementing it.
515 # idea of how many lines are in the file, instead of reimplementing it.
515 return difflineranges(b'', content2)
516 return difflineranges(b'', content2)
516
517
517 rangeslist = []
518 rangeslist = []
518 for basectx in basectxs:
519 for basectx in basectxs:
519 basepath = basepaths.get((basectx.rev(), fixctx.rev(), path), path)
520 basepath = basepaths.get((basectx.rev(), fixctx.rev(), path), path)
520
521
521 if basepath in basectx:
522 if basepath in basectx:
522 content1 = basectx[basepath].data()
523 content1 = basectx[basepath].data()
523 else:
524 else:
524 content1 = b''
525 content1 = b''
525 rangeslist.extend(difflineranges(content1, content2))
526 rangeslist.extend(difflineranges(content1, content2))
526 return unionranges(rangeslist)
527 return unionranges(rangeslist)
527
528
528
529
529 def getbasepaths(repo, opts, workqueue, basectxs):
530 def getbasepaths(repo, opts, workqueue, basectxs):
530 if opts.get(b'whole'):
531 if opts.get(b'whole'):
531 # Base paths will never be fetched for line range determination.
532 # Base paths will never be fetched for line range determination.
532 return {}
533 return {}
533
534
534 basepaths = {}
535 basepaths = {}
535 for srcrev, path, _dstrevs in workqueue:
536 for srcrev, path, _dstrevs in workqueue:
536 fixctx = repo[srcrev]
537 fixctx = repo[srcrev]
537 for basectx in basectxs[srcrev]:
538 for basectx in basectxs[srcrev]:
538 basepath = copies.pathcopies(basectx, fixctx).get(path, path)
539 basepath = copies.pathcopies(basectx, fixctx).get(path, path)
539 if basepath in basectx:
540 if basepath in basectx:
540 basepaths[(basectx.rev(), fixctx.rev(), path)] = basepath
541 basepaths[(basectx.rev(), fixctx.rev(), path)] = basepath
541 return basepaths
542 return basepaths
542
543
543
544
544 def unionranges(rangeslist):
545 def unionranges(rangeslist):
545 """Return the union of some closed intervals
546 """Return the union of some closed intervals
546
547
547 >>> unionranges([])
548 >>> unionranges([])
548 []
549 []
549 >>> unionranges([(1, 100)])
550 >>> unionranges([(1, 100)])
550 [(1, 100)]
551 [(1, 100)]
551 >>> unionranges([(1, 100), (1, 100)])
552 >>> unionranges([(1, 100), (1, 100)])
552 [(1, 100)]
553 [(1, 100)]
553 >>> unionranges([(1, 100), (2, 100)])
554 >>> unionranges([(1, 100), (2, 100)])
554 [(1, 100)]
555 [(1, 100)]
555 >>> unionranges([(1, 99), (1, 100)])
556 >>> unionranges([(1, 99), (1, 100)])
556 [(1, 100)]
557 [(1, 100)]
557 >>> unionranges([(1, 100), (40, 60)])
558 >>> unionranges([(1, 100), (40, 60)])
558 [(1, 100)]
559 [(1, 100)]
559 >>> unionranges([(1, 49), (50, 100)])
560 >>> unionranges([(1, 49), (50, 100)])
560 [(1, 100)]
561 [(1, 100)]
561 >>> unionranges([(1, 48), (50, 100)])
562 >>> unionranges([(1, 48), (50, 100)])
562 [(1, 48), (50, 100)]
563 [(1, 48), (50, 100)]
563 >>> unionranges([(1, 2), (3, 4), (5, 6)])
564 >>> unionranges([(1, 2), (3, 4), (5, 6)])
564 [(1, 6)]
565 [(1, 6)]
565 """
566 """
566 rangeslist = sorted(set(rangeslist))
567 rangeslist = sorted(set(rangeslist))
567 unioned = []
568 unioned = []
568 if rangeslist:
569 if rangeslist:
569 unioned, rangeslist = [rangeslist[0]], rangeslist[1:]
570 unioned, rangeslist = [rangeslist[0]], rangeslist[1:]
570 for a, b in rangeslist:
571 for a, b in rangeslist:
571 c, d = unioned[-1]
572 c, d = unioned[-1]
572 if a > d + 1:
573 if a > d + 1:
573 unioned.append((a, b))
574 unioned.append((a, b))
574 else:
575 else:
575 unioned[-1] = (c, max(b, d))
576 unioned[-1] = (c, max(b, d))
576 return unioned
577 return unioned
577
578
578
579
579 def difflineranges(content1, content2):
580 def difflineranges(content1, content2):
580 """Return list of line number ranges in content2 that differ from content1.
581 """Return list of line number ranges in content2 that differ from content1.
581
582
582 Line numbers are 1-based. The numbers are the first and last line contained
583 Line numbers are 1-based. The numbers are the first and last line contained
583 in the range. Single-line ranges have the same line number for the first and
584 in the range. Single-line ranges have the same line number for the first and
584 last line. Excludes any empty ranges that result from lines that are only
585 last line. Excludes any empty ranges that result from lines that are only
585 present in content1. Relies on mdiff's idea of where the line endings are in
586 present in content1. Relies on mdiff's idea of where the line endings are in
586 the string.
587 the string.
587
588
588 >>> from mercurial import pycompat
589 >>> from mercurial import pycompat
589 >>> lines = lambda s: b'\\n'.join([c for c in pycompat.iterbytestr(s)])
590 >>> lines = lambda s: b'\\n'.join([c for c in pycompat.iterbytestr(s)])
590 >>> difflineranges2 = lambda a, b: difflineranges(lines(a), lines(b))
591 >>> difflineranges2 = lambda a, b: difflineranges(lines(a), lines(b))
591 >>> difflineranges2(b'', b'')
592 >>> difflineranges2(b'', b'')
592 []
593 []
593 >>> difflineranges2(b'a', b'')
594 >>> difflineranges2(b'a', b'')
594 []
595 []
595 >>> difflineranges2(b'', b'A')
596 >>> difflineranges2(b'', b'A')
596 [(1, 1)]
597 [(1, 1)]
597 >>> difflineranges2(b'a', b'a')
598 >>> difflineranges2(b'a', b'a')
598 []
599 []
599 >>> difflineranges2(b'a', b'A')
600 >>> difflineranges2(b'a', b'A')
600 [(1, 1)]
601 [(1, 1)]
601 >>> difflineranges2(b'ab', b'')
602 >>> difflineranges2(b'ab', b'')
602 []
603 []
603 >>> difflineranges2(b'', b'AB')
604 >>> difflineranges2(b'', b'AB')
604 [(1, 2)]
605 [(1, 2)]
605 >>> difflineranges2(b'abc', b'ac')
606 >>> difflineranges2(b'abc', b'ac')
606 []
607 []
607 >>> difflineranges2(b'ab', b'aCb')
608 >>> difflineranges2(b'ab', b'aCb')
608 [(2, 2)]
609 [(2, 2)]
609 >>> difflineranges2(b'abc', b'aBc')
610 >>> difflineranges2(b'abc', b'aBc')
610 [(2, 2)]
611 [(2, 2)]
611 >>> difflineranges2(b'ab', b'AB')
612 >>> difflineranges2(b'ab', b'AB')
612 [(1, 2)]
613 [(1, 2)]
613 >>> difflineranges2(b'abcde', b'aBcDe')
614 >>> difflineranges2(b'abcde', b'aBcDe')
614 [(2, 2), (4, 4)]
615 [(2, 2), (4, 4)]
615 >>> difflineranges2(b'abcde', b'aBCDe')
616 >>> difflineranges2(b'abcde', b'aBCDe')
616 [(2, 4)]
617 [(2, 4)]
617 """
618 """
618 ranges = []
619 ranges = []
619 for lines, kind in mdiff.allblocks(content1, content2):
620 for lines, kind in mdiff.allblocks(content1, content2):
620 firstline, lastline = lines[2:4]
621 firstline, lastline = lines[2:4]
621 if kind == b'!' and firstline != lastline:
622 if kind == b'!' and firstline != lastline:
622 ranges.append((firstline + 1, lastline))
623 ranges.append((firstline + 1, lastline))
623 return ranges
624 return ranges
624
625
625
626
626 def getbasectxs(repo, opts, revstofix):
627 def getbasectxs(repo, opts, revstofix):
627 """Returns a map of the base contexts for each revision
628 """Returns a map of the base contexts for each revision
628
629
629 The base contexts determine which lines are considered modified when we
630 The base contexts determine which lines are considered modified when we
630 attempt to fix just the modified lines in a file. It also determines which
631 attempt to fix just the modified lines in a file. It also determines which
631 files we attempt to fix, so it is important to compute this even when
632 files we attempt to fix, so it is important to compute this even when
632 --whole is used.
633 --whole is used.
633 """
634 """
634 # The --base flag overrides the usual logic, and we give every revision
635 # The --base flag overrides the usual logic, and we give every revision
635 # exactly the set of baserevs that the user specified.
636 # exactly the set of baserevs that the user specified.
636 if opts.get(b'base'):
637 if opts.get(b'base'):
637 baserevs = set(logcmdutil.revrange(repo, opts.get(b'base')))
638 baserevs = set(logcmdutil.revrange(repo, opts.get(b'base')))
638 if not baserevs:
639 if not baserevs:
639 baserevs = {nullrev}
640 baserevs = {nullrev}
640 basectxs = {repo[rev] for rev in baserevs}
641 basectxs = {repo[rev] for rev in baserevs}
641 return {rev: basectxs for rev in revstofix}
642 return {rev: basectxs for rev in revstofix}
642
643
643 # Proceed in topological order so that we can easily determine each
644 # Proceed in topological order so that we can easily determine each
644 # revision's baserevs by looking at its parents and their baserevs.
645 # revision's baserevs by looking at its parents and their baserevs.
645 basectxs = collections.defaultdict(set)
646 basectxs = collections.defaultdict(set)
646 for rev in sorted(revstofix):
647 for rev in sorted(revstofix):
647 ctx = repo[rev]
648 ctx = repo[rev]
648 for pctx in ctx.parents():
649 for pctx in ctx.parents():
649 if pctx.rev() in basectxs:
650 if pctx.rev() in basectxs:
650 basectxs[rev].update(basectxs[pctx.rev()])
651 basectxs[rev].update(basectxs[pctx.rev()])
651 else:
652 else:
652 basectxs[rev].add(pctx)
653 basectxs[rev].add(pctx)
653 return basectxs
654 return basectxs
654
655
655
656
656 def _prefetchfiles(repo, workqueue, basepaths):
657 def _prefetchfiles(repo, workqueue, basepaths):
657 toprefetch = set()
658 toprefetch = set()
658
659
659 # Prefetch the files that will be fixed.
660 # Prefetch the files that will be fixed.
660 for srcrev, path, _dstrevs in workqueue:
661 for srcrev, path, _dstrevs in workqueue:
661 if srcrev == wdirrev:
662 if srcrev == wdirrev:
662 continue
663 continue
663 toprefetch.add((srcrev, path))
664 toprefetch.add((srcrev, path))
664
665
665 # Prefetch the base contents for lineranges().
666 # Prefetch the base contents for lineranges().
666 for (baserev, fixrev, path), basepath in basepaths.items():
667 for (baserev, fixrev, path), basepath in basepaths.items():
667 toprefetch.add((baserev, basepath))
668 toprefetch.add((baserev, basepath))
668
669
669 if toprefetch:
670 if toprefetch:
670 scmutil.prefetchfiles(
671 scmutil.prefetchfiles(
671 repo,
672 repo,
672 [
673 [
673 (rev, scmutil.matchfiles(repo, [path]))
674 (rev, scmutil.matchfiles(repo, [path]))
674 for rev, path in toprefetch
675 for rev, path in toprefetch
675 ],
676 ],
676 )
677 )
677
678
678
679
679 def fixfile(ui, repo, opts, fixers, fixctx, path, basepaths, basectxs):
680 def fixfile(ui, repo, opts, fixers, fixctx, path, basepaths, basectxs):
680 """Run any configured fixers that should affect the file in this context
681 """Run any configured fixers that should affect the file in this context
681
682
682 Returns the file content that results from applying the fixers in some order
683 Returns the file content that results from applying the fixers in some order
683 starting with the file's content in the fixctx. Fixers that support line
684 starting with the file's content in the fixctx. Fixers that support line
684 ranges will affect lines that have changed relative to any of the basectxs
685 ranges will affect lines that have changed relative to any of the basectxs
685 (i.e. they will only avoid lines that are common to all basectxs).
686 (i.e. they will only avoid lines that are common to all basectxs).
686
687
687 A fixer tool's stdout will become the file's new content if and only if it
688 A fixer tool's stdout will become the file's new content if and only if it
688 exits with code zero. The fixer tool's working directory is the repository's
689 exits with code zero. The fixer tool's working directory is the repository's
689 root.
690 root.
690 """
691 """
691 metadata = {}
692 metadata = {}
692 newdata = fixctx[path].data()
693 newdata = fixctx[path].data()
693 for fixername, fixer in fixers.items():
694 for fixername, fixer in fixers.items():
694 if fixer.affects(opts, fixctx, path):
695 if fixer.affects(opts, fixctx, path):
695 ranges = lineranges(
696 ranges = lineranges(
696 opts, path, basepaths, basectxs, fixctx, newdata
697 opts, path, basepaths, basectxs, fixctx, newdata
697 )
698 )
698 command = fixer.command(ui, path, ranges)
699 command = fixer.command(ui, path, ranges)
699 if command is None:
700 if command is None:
700 continue
701 continue
701 msg = b'fixing: %s - %s - %s\n'
702 msg = b'fixing: %s - %s - %s\n'
702 msg %= (fixctx, fixername, path)
703 msg %= (fixctx, fixername, path)
703 ui.debug(msg)
704 ui.debug(msg)
704 ui.debug(b'subprocess: %s\n' % (command,))
705 ui.debug(b'subprocess: %s\n' % (command,))
705 proc = subprocess.Popen(
706 proc = subprocess.Popen(
706 procutil.tonativestr(command),
707 procutil.tonativestr(command),
707 shell=True,
708 shell=True,
708 cwd=procutil.tonativestr(repo.root),
709 cwd=procutil.tonativestr(repo.root),
709 stdin=subprocess.PIPE,
710 stdin=subprocess.PIPE,
710 stdout=subprocess.PIPE,
711 stdout=subprocess.PIPE,
711 stderr=subprocess.PIPE,
712 stderr=subprocess.PIPE,
712 )
713 )
713 stdout, stderr = proc.communicate(newdata)
714 stdout, stderr = proc.communicate(newdata)
714 if stderr:
715 if stderr:
715 showstderr(ui, fixctx.rev(), fixername, stderr)
716 showstderr(ui, fixctx.rev(), fixername, stderr)
716 newerdata = stdout
717 newerdata = stdout
717 if fixer.shouldoutputmetadata():
718 if fixer.shouldoutputmetadata():
718 try:
719 try:
719 metadatajson, newerdata = stdout.split(b'\0', 1)
720 metadatajson, newerdata = stdout.split(b'\0', 1)
720 metadata[fixername] = pycompat.json_loads(metadatajson)
721 metadata[fixername] = pycompat.json_loads(metadatajson)
721 except ValueError:
722 except ValueError:
722 ui.warn(
723 ui.warn(
723 _(b'ignored invalid output from fixer tool: %s\n')
724 _(b'ignored invalid output from fixer tool: %s\n')
724 % (fixername,)
725 % (fixername,)
725 )
726 )
726 continue
727 continue
727 else:
728 else:
728 metadata[fixername] = None
729 metadata[fixername] = None
729 if proc.returncode == 0:
730 if proc.returncode == 0:
730 newdata = newerdata
731 newdata = newerdata
731 else:
732 else:
732 if not stderr:
733 if not stderr:
733 message = _(b'exited with status %d\n') % (proc.returncode,)
734 message = _(b'exited with status %d\n') % (proc.returncode,)
734 showstderr(ui, fixctx.rev(), fixername, message)
735 showstderr(ui, fixctx.rev(), fixername, message)
735 checktoolfailureaction(
736 checktoolfailureaction(
736 ui,
737 ui,
737 _(b'no fixes will be applied'),
738 _(b'no fixes will be applied'),
738 hint=_(
739 hint=_(
739 b'use --config fix.failure=continue to apply any '
740 b'use --config fix.failure=continue to apply any '
740 b'successful fixes anyway'
741 b'successful fixes anyway'
741 ),
742 ),
742 )
743 )
743 return metadata, newdata
744 return metadata, newdata
744
745
745
746
746 def showstderr(ui, rev, fixername, stderr):
747 def showstderr(ui, rev, fixername, stderr):
747 """Writes the lines of the stderr string as warnings on the ui
748 """Writes the lines of the stderr string as warnings on the ui
748
749
749 Uses the revision number and fixername to give more context to each line of
750 Uses the revision number and fixername to give more context to each line of
750 the error message. Doesn't include file names, since those take up a lot of
751 the error message. Doesn't include file names, since those take up a lot of
751 space and would tend to be included in the error message if they were
752 space and would tend to be included in the error message if they were
752 relevant.
753 relevant.
753 """
754 """
754 for line in re.split(b'[\r\n]+', stderr):
755 for line in re.split(b'[\r\n]+', stderr):
755 if line:
756 if line:
756 ui.warn(b'[')
757 ui.warn(b'[')
757 if rev is None:
758 if rev is None:
758 ui.warn(_(b'wdir'), label=b'evolve.rev')
759 ui.warn(_(b'wdir'), label=b'evolve.rev')
759 else:
760 else:
760 ui.warn(b'%d' % rev, label=b'evolve.rev')
761 ui.warn(b'%d' % rev, label=b'evolve.rev')
761 ui.warn(b'] %s: %s\n' % (fixername, line))
762 ui.warn(b'] %s: %s\n' % (fixername, line))
762
763
763
764
764 def writeworkingdir(repo, ctx, filedata, replacements):
765 def writeworkingdir(repo, ctx, filedata, replacements):
765 """Write new content to the working copy and check out the new p1 if any
766 """Write new content to the working copy and check out the new p1 if any
766
767
767 We check out a new revision if and only if we fixed something in both the
768 We check out a new revision if and only if we fixed something in both the
768 working directory and its parent revision. This avoids the need for a full
769 working directory and its parent revision. This avoids the need for a full
769 update/merge, and means that the working directory simply isn't affected
770 update/merge, and means that the working directory simply isn't affected
770 unless the --working-dir flag is given.
771 unless the --working-dir flag is given.
771
772
772 Directly updates the dirstate for the affected files.
773 Directly updates the dirstate for the affected files.
773 """
774 """
774 for path, data in filedata.items():
775 for path, data in filedata.items():
775 fctx = ctx[path]
776 fctx = ctx[path]
776 fctx.write(data, fctx.flags())
777 fctx.write(data, fctx.flags())
777
778
778 oldp1 = repo.dirstate.p1()
779 oldp1 = repo.dirstate.p1()
779 newp1 = replacements.get(oldp1, oldp1)
780 newp1 = replacements.get(oldp1, oldp1)
780 if newp1 != oldp1:
781 if newp1 != oldp1:
781 assert repo.dirstate.p2() == nullid
782 assert repo.dirstate.p2() == nullid
782 with repo.dirstate.changing_parents(repo):
783 with repo.dirstate.changing_parents(repo):
783 scmutil.movedirstate(repo, repo[newp1])
784 scmutil.movedirstate(repo, repo[newp1])
784
785
785
786
786 def replacerev(ui, repo, ctx, filedata, replacements):
787 def replacerev(ui, repo, ctx, filedata, replacements):
787 """Commit a new revision like the given one, but with file content changes
788 """Commit a new revision like the given one, but with file content changes
788
789
789 "ctx" is the original revision to be replaced by a modified one.
790 "ctx" is the original revision to be replaced by a modified one.
790
791
791 "filedata" is a dict that maps paths to their new file content. All other
792 "filedata" is a dict that maps paths to their new file content. All other
792 paths will be recreated from the original revision without changes.
793 paths will be recreated from the original revision without changes.
793 "filedata" may contain paths that didn't exist in the original revision;
794 "filedata" may contain paths that didn't exist in the original revision;
794 they will be added.
795 they will be added.
795
796
796 "replacements" is a dict that maps a single node to a single node, and it is
797 "replacements" is a dict that maps a single node to a single node, and it is
797 updated to indicate the original revision is replaced by the newly created
798 updated to indicate the original revision is replaced by the newly created
798 one. No entry is added if the replacement's node already exists.
799 one. No entry is added if the replacement's node already exists.
799
800
800 The new revision has the same parents as the old one, unless those parents
801 The new revision has the same parents as the old one, unless those parents
801 have already been replaced, in which case those replacements are the parents
802 have already been replaced, in which case those replacements are the parents
802 of this new revision. Thus, if revisions are replaced in topological order,
803 of this new revision. Thus, if revisions are replaced in topological order,
803 there is no need to rebase them into the original topology later.
804 there is no need to rebase them into the original topology later.
804 """
805 """
805
806
806 p1rev, p2rev = repo.changelog.parentrevs(ctx.rev())
807 p1rev, p2rev = repo.changelog.parentrevs(ctx.rev())
807 p1ctx, p2ctx = repo[p1rev], repo[p2rev]
808 p1ctx, p2ctx = repo[p1rev], repo[p2rev]
808 newp1node = replacements.get(p1ctx.node(), p1ctx.node())
809 newp1node = replacements.get(p1ctx.node(), p1ctx.node())
809 newp2node = replacements.get(p2ctx.node(), p2ctx.node())
810 newp2node = replacements.get(p2ctx.node(), p2ctx.node())
810
811
811 # We don't want to create a revision that has no changes from the original,
812 # We don't want to create a revision that has no changes from the original,
812 # but we should if the original revision's parent has been replaced.
813 # but we should if the original revision's parent has been replaced.
813 # Otherwise, we would produce an orphan that needs no actual human
814 # Otherwise, we would produce an orphan that needs no actual human
814 # intervention to evolve. We can't rely on commit() to avoid creating the
815 # intervention to evolve. We can't rely on commit() to avoid creating the
815 # un-needed revision because the extra field added below produces a new hash
816 # un-needed revision because the extra field added below produces a new hash
816 # regardless of file content changes.
817 # regardless of file content changes.
817 if (
818 if (
818 not filedata
819 not filedata
819 and p1ctx.node() not in replacements
820 and p1ctx.node() not in replacements
820 and p2ctx.node() not in replacements
821 and p2ctx.node() not in replacements
821 ):
822 ):
822 return
823 return
823
824
824 extra = ctx.extra().copy()
825 extra = ctx.extra().copy()
825 extra[b'fix_source'] = ctx.hex()
826 extra[b'fix_source'] = ctx.hex()
826
827
827 wctx = context.overlayworkingctx(repo)
828 wctx = context.overlayworkingctx(repo)
828 wctx.setbase(repo[newp1node])
829 wctx.setbase(repo[newp1node])
829 merge.revert_to(ctx, wc=wctx)
830 merge.revert_to(ctx, wc=wctx)
830 copies.graftcopies(wctx, ctx, ctx.p1())
831 copies.graftcopies(wctx, ctx, ctx.p1())
831
832
832 for path in filedata.keys():
833 for path in filedata.keys():
833 fctx = ctx[path]
834 fctx = ctx[path]
834 copysource = fctx.copysource()
835 copysource = fctx.copysource()
835 wctx.write(path, filedata[path], flags=fctx.flags())
836 wctx.write(path, filedata[path], flags=fctx.flags())
836 if copysource:
837 if copysource:
837 wctx.markcopied(path, copysource)
838 wctx.markcopied(path, copysource)
838
839
839 desc = rewriteutil.update_hash_refs(
840 desc = rewriteutil.update_hash_refs(
840 repo,
841 repo,
841 ctx.description(),
842 ctx.description(),
842 {oldnode: [newnode] for oldnode, newnode in replacements.items()},
843 {oldnode: [newnode] for oldnode, newnode in replacements.items()},
843 )
844 )
844
845
845 memctx = wctx.tomemctx(
846 memctx = wctx.tomemctx(
846 text=desc,
847 text=desc,
847 branch=ctx.branch(),
848 branch=ctx.branch(),
848 extra=extra,
849 extra=extra,
849 date=ctx.date(),
850 date=ctx.date(),
850 parents=(newp1node, newp2node),
851 parents=(newp1node, newp2node),
851 user=ctx.user(),
852 user=ctx.user(),
852 )
853 )
853
854
854 sucnode = memctx.commit()
855 sucnode = memctx.commit()
855 prenode = ctx.node()
856 prenode = ctx.node()
856 if prenode == sucnode:
857 if prenode == sucnode:
857 ui.debug(b'node %s already existed\n' % (ctx.hex()))
858 ui.debug(b'node %s already existed\n' % (ctx.hex()))
858 else:
859 else:
859 replacements[ctx.node()] = sucnode
860 replacements[ctx.node()] = sucnode
860
861
861
862
862 def getfixers(ui):
863 def getfixers(ui):
863 """Returns a map of configured fixer tools indexed by their names
864 """Returns a map of configured fixer tools indexed by their names
864
865
865 Each value is a Fixer object with methods that implement the behavior of the
866 Each value is a Fixer object with methods that implement the behavior of the
866 fixer's config suboptions. Does not validate the config values.
867 fixer's config suboptions. Does not validate the config values.
867 """
868 """
868 fixers = {}
869 fixers = {}
869 for name in fixernames(ui):
870 for name in fixernames(ui):
870 enabled = ui.configbool(b'fix', name + b':enabled')
871 enabled = ui.configbool(b'fix', name + b':enabled')
871 command = ui.config(b'fix', name + b':command')
872 command = ui.config(b'fix', name + b':command')
872 pattern = ui.config(b'fix', name + b':pattern')
873 pattern = ui.config(b'fix', name + b':pattern')
873 linerange = ui.config(b'fix', name + b':linerange')
874 linerange = ui.config(b'fix', name + b':linerange')
874 priority = ui.configint(b'fix', name + b':priority')
875 priority = ui.configint(b'fix', name + b':priority')
875 metadata = ui.configbool(b'fix', name + b':metadata')
876 metadata = ui.configbool(b'fix', name + b':metadata')
876 skipclean = ui.configbool(b'fix', name + b':skipclean')
877 skipclean = ui.configbool(b'fix', name + b':skipclean')
877 # Don't use a fixer if it has no pattern configured. It would be
878 # Don't use a fixer if it has no pattern configured. It would be
878 # dangerous to let it affect all files. It would be pointless to let it
879 # dangerous to let it affect all files. It would be pointless to let it
879 # affect no files. There is no reasonable subset of files to use as the
880 # affect no files. There is no reasonable subset of files to use as the
880 # default.
881 # default.
881 if command is None:
882 if command is None:
882 ui.warn(
883 ui.warn(
883 _(b'fixer tool has no command configuration: %s\n') % (name,)
884 _(b'fixer tool has no command configuration: %s\n') % (name,)
884 )
885 )
885 elif pattern is None:
886 elif pattern is None:
886 ui.warn(
887 ui.warn(
887 _(b'fixer tool has no pattern configuration: %s\n') % (name,)
888 _(b'fixer tool has no pattern configuration: %s\n') % (name,)
888 )
889 )
889 elif not enabled:
890 elif not enabled:
890 ui.debug(b'ignoring disabled fixer tool: %s\n' % (name,))
891 ui.debug(b'ignoring disabled fixer tool: %s\n' % (name,))
891 else:
892 else:
892 fixers[name] = Fixer(
893 fixers[name] = Fixer(
893 command, pattern, linerange, priority, metadata, skipclean
894 command, pattern, linerange, priority, metadata, skipclean
894 )
895 )
895 return collections.OrderedDict(
896 return collections.OrderedDict(
896 sorted(fixers.items(), key=lambda item: item[1]._priority, reverse=True)
897 sorted(fixers.items(), key=lambda item: item[1]._priority, reverse=True)
897 )
898 )
898
899
899
900
900 def fixernames(ui):
901 def fixernames(ui):
901 """Returns the names of [fix] config options that have suboptions"""
902 """Returns the names of [fix] config options that have suboptions"""
902 names = set()
903 names = set()
903 for k, v in ui.configitems(b'fix'):
904 for k, v in ui.configitems(b'fix'):
904 if b':' in k:
905 if b':' in k:
905 names.add(k.split(b':', 1)[0])
906 names.add(k.split(b':', 1)[0])
906 return names
907 return names
907
908
908
909
909 class Fixer:
910 class Fixer:
910 """Wraps the raw config values for a fixer with methods"""
911 """Wraps the raw config values for a fixer with methods"""
911
912
912 def __init__(
913 def __init__(
913 self, command, pattern, linerange, priority, metadata, skipclean
914 self, command, pattern, linerange, priority, metadata, skipclean
914 ):
915 ):
915 self._command = command
916 self._command = command
916 self._pattern = pattern
917 self._pattern = pattern
917 self._linerange = linerange
918 self._linerange = linerange
918 self._priority = priority
919 self._priority = priority
919 self._metadata = metadata
920 self._metadata = metadata
920 self._skipclean = skipclean
921 self._skipclean = skipclean
921
922
922 def affects(self, opts, fixctx, path):
923 def affects(self, opts, fixctx, path):
923 """Should this fixer run on the file at the given path and context?"""
924 """Should this fixer run on the file at the given path and context?"""
924 repo = fixctx.repo()
925 repo = fixctx.repo()
925 matcher = matchmod.match(
926 matcher = matchmod.match(
926 repo.root, repo.root, [self._pattern], ctx=fixctx
927 repo.root, repo.root, [self._pattern], ctx=fixctx
927 )
928 )
928 return matcher(path)
929 return matcher(path)
929
930
930 def shouldoutputmetadata(self):
931 def shouldoutputmetadata(self):
931 """Should the stdout of this fixer start with JSON and a null byte?"""
932 """Should the stdout of this fixer start with JSON and a null byte?"""
932 return self._metadata
933 return self._metadata
933
934
934 def command(self, ui, path, ranges):
935 def command(self, ui, path, ranges):
935 """A shell command to use to invoke this fixer on the given file/lines
936 """A shell command to use to invoke this fixer on the given file/lines
936
937
937 May return None if there is no appropriate command to run for the given
938 May return None if there is no appropriate command to run for the given
938 parameters.
939 parameters.
939 """
940 """
940 expand = cmdutil.rendercommandtemplate
941 expand = cmdutil.rendercommandtemplate
941 parts = [
942 parts = [
942 expand(
943 expand(
943 ui,
944 ui,
944 self._command,
945 self._command,
945 {b'rootpath': path, b'basename': os.path.basename(path)},
946 {b'rootpath': path, b'basename': os.path.basename(path)},
946 )
947 )
947 ]
948 ]
948 if self._linerange:
949 if self._linerange:
949 if self._skipclean and not ranges:
950 if self._skipclean and not ranges:
950 # No line ranges to fix, so don't run the fixer.
951 # No line ranges to fix, so don't run the fixer.
951 return None
952 return None
952 for first, last in ranges:
953 for first, last in ranges:
953 parts.append(
954 parts.append(
954 expand(
955 expand(
955 ui, self._linerange, {b'first': first, b'last': last}
956 ui, self._linerange, {b'first': first, b'last': last}
956 )
957 )
957 )
958 )
958 return b' '.join(parts)
959 return b' '.join(parts)
@@ -1,2975 +1,2979 b''
1 # configitems.py - centralized declaration of configuration option
1 # configitems.py - centralized declaration of configuration option
2 #
2 #
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8
8
9 import functools
9 import functools
10 import re
10 import re
11
11
12 from . import (
12 from . import (
13 encoding,
13 encoding,
14 error,
14 error,
15 )
15 )
16
16
17
17
18 def loadconfigtable(ui, extname, configtable):
18 def loadconfigtable(ui, extname, configtable):
19 """update config item known to the ui with the extension ones"""
19 """update config item known to the ui with the extension ones"""
20 for section, items in sorted(configtable.items()):
20 for section, items in sorted(configtable.items()):
21 knownitems = ui._knownconfig.setdefault(section, itemregister())
21 knownitems = ui._knownconfig.setdefault(section, itemregister())
22 knownkeys = set(knownitems)
22 knownkeys = set(knownitems)
23 newkeys = set(items)
23 newkeys = set(items)
24 for key in sorted(knownkeys & newkeys):
24 for key in sorted(knownkeys & newkeys):
25 msg = b"extension '%s' overwrite config item '%s.%s'"
25 msg = b"extension '%s' overwrite config item '%s.%s'"
26 msg %= (extname, section, key)
26 msg %= (extname, section, key)
27 ui.develwarn(msg, config=b'warn-config')
27 ui.develwarn(msg, config=b'warn-config')
28
28
29 knownitems.update(items)
29 knownitems.update(items)
30
30
31
31
32 class configitem:
32 class configitem:
33 """represent a known config item
33 """represent a known config item
34
34
35 :section: the official config section where to find this item,
35 :section: the official config section where to find this item,
36 :name: the official name within the section,
36 :name: the official name within the section,
37 :default: default value for this item,
37 :default: default value for this item,
38 :alias: optional list of tuples as alternatives,
38 :alias: optional list of tuples as alternatives,
39 :generic: this is a generic definition, match name using regular expression.
39 :generic: this is a generic definition, match name using regular expression.
40 """
40 """
41
41
42 def __init__(
42 def __init__(
43 self,
43 self,
44 section,
44 section,
45 name,
45 name,
46 default=None,
46 default=None,
47 alias=(),
47 alias=(),
48 generic=False,
48 generic=False,
49 priority=0,
49 priority=0,
50 experimental=False,
50 experimental=False,
51 ):
51 ):
52 self.section = section
52 self.section = section
53 self.name = name
53 self.name = name
54 self.default = default
54 self.default = default
55 self.alias = list(alias)
55 self.alias = list(alias)
56 self.generic = generic
56 self.generic = generic
57 self.priority = priority
57 self.priority = priority
58 self.experimental = experimental
58 self.experimental = experimental
59 self._re = None
59 self._re = None
60 if generic:
60 if generic:
61 self._re = re.compile(self.name)
61 self._re = re.compile(self.name)
62
62
63
63
64 class itemregister(dict):
64 class itemregister(dict):
65 """A specialized dictionary that can handle wild-card selection"""
65 """A specialized dictionary that can handle wild-card selection"""
66
66
67 def __init__(self):
67 def __init__(self):
68 super(itemregister, self).__init__()
68 super(itemregister, self).__init__()
69 self._generics = set()
69 self._generics = set()
70
70
71 def update(self, other):
71 def update(self, other):
72 super(itemregister, self).update(other)
72 super(itemregister, self).update(other)
73 self._generics.update(other._generics)
73 self._generics.update(other._generics)
74
74
75 def __setitem__(self, key, item):
75 def __setitem__(self, key, item):
76 super(itemregister, self).__setitem__(key, item)
76 super(itemregister, self).__setitem__(key, item)
77 if item.generic:
77 if item.generic:
78 self._generics.add(item)
78 self._generics.add(item)
79
79
80 def get(self, key):
80 def get(self, key):
81 baseitem = super(itemregister, self).get(key)
81 baseitem = super(itemregister, self).get(key)
82 if baseitem is not None and not baseitem.generic:
82 if baseitem is not None and not baseitem.generic:
83 return baseitem
83 return baseitem
84
84
85 # search for a matching generic item
85 # search for a matching generic item
86 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
86 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
87 for item in generics:
87 for item in generics:
88 # we use 'match' instead of 'search' to make the matching simpler
88 # we use 'match' instead of 'search' to make the matching simpler
89 # for people unfamiliar with regular expression. Having the match
89 # for people unfamiliar with regular expression. Having the match
90 # rooted to the start of the string will produce less surprising
90 # rooted to the start of the string will produce less surprising
91 # result for user writing simple regex for sub-attribute.
91 # result for user writing simple regex for sub-attribute.
92 #
92 #
93 # For example using "color\..*" match produces an unsurprising
93 # For example using "color\..*" match produces an unsurprising
94 # result, while using search could suddenly match apparently
94 # result, while using search could suddenly match apparently
95 # unrelated configuration that happens to contains "color."
95 # unrelated configuration that happens to contains "color."
96 # anywhere. This is a tradeoff where we favor requiring ".*" on
96 # anywhere. This is a tradeoff where we favor requiring ".*" on
97 # some match to avoid the need to prefix most pattern with "^".
97 # some match to avoid the need to prefix most pattern with "^".
98 # The "^" seems more error prone.
98 # The "^" seems more error prone.
99 if item._re.match(key):
99 if item._re.match(key):
100 return item
100 return item
101
101
102 return None
102 return None
103
103
104
104
105 coreitems = {}
105 coreitems = {}
106
106
107
107
108 def _register(configtable, *args, **kwargs):
108 def _register(configtable, *args, **kwargs):
109 item = configitem(*args, **kwargs)
109 item = configitem(*args, **kwargs)
110 section = configtable.setdefault(item.section, itemregister())
110 section = configtable.setdefault(item.section, itemregister())
111 if item.name in section:
111 if item.name in section:
112 msg = b"duplicated config item registration for '%s.%s'"
112 msg = b"duplicated config item registration for '%s.%s'"
113 raise error.ProgrammingError(msg % (item.section, item.name))
113 raise error.ProgrammingError(msg % (item.section, item.name))
114 section[item.name] = item
114 section[item.name] = item
115
115
116
116
117 # special value for case where the default is derived from other values
117 # special value for case where the default is derived from other values
118 dynamicdefault = object()
118 dynamicdefault = object()
119
119
120 # Registering actual config items
120 # Registering actual config items
121
121
122
122
123 def getitemregister(configtable):
123 def getitemregister(configtable):
124 f = functools.partial(_register, configtable)
124 f = functools.partial(_register, configtable)
125 # export pseudo enum as configitem.*
125 # export pseudo enum as configitem.*
126 f.dynamicdefault = dynamicdefault
126 f.dynamicdefault = dynamicdefault
127 return f
127 return f
128
128
129
129
130 coreconfigitem = getitemregister(coreitems)
130 coreconfigitem = getitemregister(coreitems)
131
131
132
132
133 def _registerdiffopts(section, configprefix=b''):
133 def _registerdiffopts(section, configprefix=b''):
134 coreconfigitem(
134 coreconfigitem(
135 section,
135 section,
136 configprefix + b'nodates',
136 configprefix + b'nodates',
137 default=False,
137 default=False,
138 )
138 )
139 coreconfigitem(
139 coreconfigitem(
140 section,
140 section,
141 configprefix + b'showfunc',
141 configprefix + b'showfunc',
142 default=False,
142 default=False,
143 )
143 )
144 coreconfigitem(
144 coreconfigitem(
145 section,
145 section,
146 configprefix + b'unified',
146 configprefix + b'unified',
147 default=None,
147 default=None,
148 )
148 )
149 coreconfigitem(
149 coreconfigitem(
150 section,
150 section,
151 configprefix + b'git',
151 configprefix + b'git',
152 default=False,
152 default=False,
153 )
153 )
154 coreconfigitem(
154 coreconfigitem(
155 section,
155 section,
156 configprefix + b'ignorews',
156 configprefix + b'ignorews',
157 default=False,
157 default=False,
158 )
158 )
159 coreconfigitem(
159 coreconfigitem(
160 section,
160 section,
161 configprefix + b'ignorewsamount',
161 configprefix + b'ignorewsamount',
162 default=False,
162 default=False,
163 )
163 )
164 coreconfigitem(
164 coreconfigitem(
165 section,
165 section,
166 configprefix + b'ignoreblanklines',
166 configprefix + b'ignoreblanklines',
167 default=False,
167 default=False,
168 )
168 )
169 coreconfigitem(
169 coreconfigitem(
170 section,
170 section,
171 configprefix + b'ignorewseol',
171 configprefix + b'ignorewseol',
172 default=False,
172 default=False,
173 )
173 )
174 coreconfigitem(
174 coreconfigitem(
175 section,
175 section,
176 configprefix + b'nobinary',
176 configprefix + b'nobinary',
177 default=False,
177 default=False,
178 )
178 )
179 coreconfigitem(
179 coreconfigitem(
180 section,
180 section,
181 configprefix + b'noprefix',
181 configprefix + b'noprefix',
182 default=False,
182 default=False,
183 )
183 )
184 coreconfigitem(
184 coreconfigitem(
185 section,
185 section,
186 configprefix + b'word-diff',
186 configprefix + b'word-diff',
187 default=False,
187 default=False,
188 )
188 )
189
189
190
190
191 coreconfigitem(
191 coreconfigitem(
192 b'alias',
192 b'alias',
193 b'.*',
193 b'.*',
194 default=dynamicdefault,
194 default=dynamicdefault,
195 generic=True,
195 generic=True,
196 )
196 )
197 coreconfigitem(
197 coreconfigitem(
198 b'auth',
198 b'auth',
199 b'cookiefile',
199 b'cookiefile',
200 default=None,
200 default=None,
201 )
201 )
202 _registerdiffopts(section=b'annotate')
202 _registerdiffopts(section=b'annotate')
203 # bookmarks.pushing: internal hack for discovery
203 # bookmarks.pushing: internal hack for discovery
204 coreconfigitem(
204 coreconfigitem(
205 b'bookmarks',
205 b'bookmarks',
206 b'pushing',
206 b'pushing',
207 default=list,
207 default=list,
208 )
208 )
209 # bundle.mainreporoot: internal hack for bundlerepo
209 # bundle.mainreporoot: internal hack for bundlerepo
210 coreconfigitem(
210 coreconfigitem(
211 b'bundle',
211 b'bundle',
212 b'mainreporoot',
212 b'mainreporoot',
213 default=b'',
213 default=b'',
214 )
214 )
215 coreconfigitem(
215 coreconfigitem(
216 b'censor',
216 b'censor',
217 b'policy',
217 b'policy',
218 default=b'abort',
218 default=b'abort',
219 experimental=True,
219 experimental=True,
220 )
220 )
221 coreconfigitem(
221 coreconfigitem(
222 b'chgserver',
222 b'chgserver',
223 b'idletimeout',
223 b'idletimeout',
224 default=3600,
224 default=3600,
225 )
225 )
226 coreconfigitem(
226 coreconfigitem(
227 b'chgserver',
227 b'chgserver',
228 b'skiphash',
228 b'skiphash',
229 default=False,
229 default=False,
230 )
230 )
231 coreconfigitem(
231 coreconfigitem(
232 b'cmdserver',
232 b'cmdserver',
233 b'log',
233 b'log',
234 default=None,
234 default=None,
235 )
235 )
236 coreconfigitem(
236 coreconfigitem(
237 b'cmdserver',
237 b'cmdserver',
238 b'max-log-files',
238 b'max-log-files',
239 default=7,
239 default=7,
240 )
240 )
241 coreconfigitem(
241 coreconfigitem(
242 b'cmdserver',
242 b'cmdserver',
243 b'max-log-size',
243 b'max-log-size',
244 default=b'1 MB',
244 default=b'1 MB',
245 )
245 )
246 coreconfigitem(
246 coreconfigitem(
247 b'cmdserver',
247 b'cmdserver',
248 b'max-repo-cache',
248 b'max-repo-cache',
249 default=0,
249 default=0,
250 experimental=True,
250 experimental=True,
251 )
251 )
252 coreconfigitem(
252 coreconfigitem(
253 b'cmdserver',
253 b'cmdserver',
254 b'message-encodings',
254 b'message-encodings',
255 default=list,
255 default=list,
256 )
256 )
257 coreconfigitem(
257 coreconfigitem(
258 b'cmdserver',
258 b'cmdserver',
259 b'track-log',
259 b'track-log',
260 default=lambda: [b'chgserver', b'cmdserver', b'repocache'],
260 default=lambda: [b'chgserver', b'cmdserver', b'repocache'],
261 )
261 )
262 coreconfigitem(
262 coreconfigitem(
263 b'cmdserver',
263 b'cmdserver',
264 b'shutdown-on-interrupt',
264 b'shutdown-on-interrupt',
265 default=True,
265 default=True,
266 )
266 )
267 coreconfigitem(
267 coreconfigitem(
268 b'color',
268 b'color',
269 b'.*',
269 b'.*',
270 default=None,
270 default=None,
271 generic=True,
271 generic=True,
272 )
272 )
273 coreconfigitem(
273 coreconfigitem(
274 b'color',
274 b'color',
275 b'mode',
275 b'mode',
276 default=b'auto',
276 default=b'auto',
277 )
277 )
278 coreconfigitem(
278 coreconfigitem(
279 b'color',
279 b'color',
280 b'pagermode',
280 b'pagermode',
281 default=dynamicdefault,
281 default=dynamicdefault,
282 )
282 )
283 coreconfigitem(
283 coreconfigitem(
284 b'command-templates',
284 b'command-templates',
285 b'graphnode',
285 b'graphnode',
286 default=None,
286 default=None,
287 alias=[(b'ui', b'graphnodetemplate')],
287 alias=[(b'ui', b'graphnodetemplate')],
288 )
288 )
289 coreconfigitem(
289 coreconfigitem(
290 b'command-templates',
290 b'command-templates',
291 b'log',
291 b'log',
292 default=None,
292 default=None,
293 alias=[(b'ui', b'logtemplate')],
293 alias=[(b'ui', b'logtemplate')],
294 )
294 )
295 coreconfigitem(
295 coreconfigitem(
296 b'command-templates',
296 b'command-templates',
297 b'mergemarker',
297 b'mergemarker',
298 default=(
298 default=(
299 b'{node|short} '
299 b'{node|short} '
300 b'{ifeq(tags, "tip", "", '
300 b'{ifeq(tags, "tip", "", '
301 b'ifeq(tags, "", "", "{tags} "))}'
301 b'ifeq(tags, "", "", "{tags} "))}'
302 b'{if(bookmarks, "{bookmarks} ")}'
302 b'{if(bookmarks, "{bookmarks} ")}'
303 b'{ifeq(branch, "default", "", "{branch} ")}'
303 b'{ifeq(branch, "default", "", "{branch} ")}'
304 b'- {author|user}: {desc|firstline}'
304 b'- {author|user}: {desc|firstline}'
305 ),
305 ),
306 alias=[(b'ui', b'mergemarkertemplate')],
306 alias=[(b'ui', b'mergemarkertemplate')],
307 )
307 )
308 coreconfigitem(
308 coreconfigitem(
309 b'command-templates',
309 b'command-templates',
310 b'pre-merge-tool-output',
310 b'pre-merge-tool-output',
311 default=None,
311 default=None,
312 alias=[(b'ui', b'pre-merge-tool-output-template')],
312 alias=[(b'ui', b'pre-merge-tool-output-template')],
313 )
313 )
314 coreconfigitem(
314 coreconfigitem(
315 b'command-templates',
315 b'command-templates',
316 b'oneline-summary',
316 b'oneline-summary',
317 default=None,
317 default=None,
318 )
318 )
319 coreconfigitem(
319 coreconfigitem(
320 b'command-templates',
320 b'command-templates',
321 b'oneline-summary.*',
321 b'oneline-summary.*',
322 default=dynamicdefault,
322 default=dynamicdefault,
323 generic=True,
323 generic=True,
324 )
324 )
325 _registerdiffopts(section=b'commands', configprefix=b'commit.interactive.')
325 _registerdiffopts(section=b'commands', configprefix=b'commit.interactive.')
326 coreconfigitem(
326 coreconfigitem(
327 b'commands',
327 b'commands',
328 b'commit.post-status',
328 b'commit.post-status',
329 default=False,
329 default=False,
330 )
330 )
331 coreconfigitem(
331 coreconfigitem(
332 b'commands',
332 b'commands',
333 b'grep.all-files',
333 b'grep.all-files',
334 default=False,
334 default=False,
335 experimental=True,
335 experimental=True,
336 )
336 )
337 coreconfigitem(
337 coreconfigitem(
338 b'commands',
338 b'commands',
339 b'merge.require-rev',
339 b'merge.require-rev',
340 default=False,
340 default=False,
341 )
341 )
342 coreconfigitem(
342 coreconfigitem(
343 b'commands',
343 b'commands',
344 b'push.require-revs',
344 b'push.require-revs',
345 default=False,
345 default=False,
346 )
346 )
347 coreconfigitem(
347 coreconfigitem(
348 b'commands',
348 b'commands',
349 b'resolve.confirm',
349 b'resolve.confirm',
350 default=False,
350 default=False,
351 )
351 )
352 coreconfigitem(
352 coreconfigitem(
353 b'commands',
353 b'commands',
354 b'resolve.explicit-re-merge',
354 b'resolve.explicit-re-merge',
355 default=False,
355 default=False,
356 )
356 )
357 coreconfigitem(
357 coreconfigitem(
358 b'commands',
358 b'commands',
359 b'resolve.mark-check',
359 b'resolve.mark-check',
360 default=b'none',
360 default=b'none',
361 )
361 )
362 _registerdiffopts(section=b'commands', configprefix=b'revert.interactive.')
362 _registerdiffopts(section=b'commands', configprefix=b'revert.interactive.')
363 coreconfigitem(
363 coreconfigitem(
364 b'commands',
364 b'commands',
365 b'show.aliasprefix',
365 b'show.aliasprefix',
366 default=list,
366 default=list,
367 )
367 )
368 coreconfigitem(
368 coreconfigitem(
369 b'commands',
369 b'commands',
370 b'status.relative',
370 b'status.relative',
371 default=False,
371 default=False,
372 )
372 )
373 coreconfigitem(
373 coreconfigitem(
374 b'commands',
374 b'commands',
375 b'status.skipstates',
375 b'status.skipstates',
376 default=[],
376 default=[],
377 experimental=True,
377 experimental=True,
378 )
378 )
379 coreconfigitem(
379 coreconfigitem(
380 b'commands',
380 b'commands',
381 b'status.terse',
381 b'status.terse',
382 default=b'',
382 default=b'',
383 )
383 )
384 coreconfigitem(
384 coreconfigitem(
385 b'commands',
385 b'commands',
386 b'status.verbose',
386 b'status.verbose',
387 default=False,
387 default=False,
388 )
388 )
389 coreconfigitem(
389 coreconfigitem(
390 b'commands',
390 b'commands',
391 b'update.check',
391 b'update.check',
392 default=None,
392 default=None,
393 )
393 )
394 coreconfigitem(
394 coreconfigitem(
395 b'commands',
395 b'commands',
396 b'update.requiredest',
396 b'update.requiredest',
397 default=False,
397 default=False,
398 )
398 )
399 coreconfigitem(
399 coreconfigitem(
400 b'committemplate',
400 b'committemplate',
401 b'.*',
401 b'.*',
402 default=None,
402 default=None,
403 generic=True,
403 generic=True,
404 )
404 )
405 coreconfigitem(
405 coreconfigitem(
406 b'convert',
406 b'convert',
407 b'bzr.saverev',
407 b'bzr.saverev',
408 default=True,
408 default=True,
409 )
409 )
410 coreconfigitem(
410 coreconfigitem(
411 b'convert',
411 b'convert',
412 b'cvsps.cache',
412 b'cvsps.cache',
413 default=True,
413 default=True,
414 )
414 )
415 coreconfigitem(
415 coreconfigitem(
416 b'convert',
416 b'convert',
417 b'cvsps.fuzz',
417 b'cvsps.fuzz',
418 default=60,
418 default=60,
419 )
419 )
420 coreconfigitem(
420 coreconfigitem(
421 b'convert',
421 b'convert',
422 b'cvsps.logencoding',
422 b'cvsps.logencoding',
423 default=None,
423 default=None,
424 )
424 )
425 coreconfigitem(
425 coreconfigitem(
426 b'convert',
426 b'convert',
427 b'cvsps.mergefrom',
427 b'cvsps.mergefrom',
428 default=None,
428 default=None,
429 )
429 )
430 coreconfigitem(
430 coreconfigitem(
431 b'convert',
431 b'convert',
432 b'cvsps.mergeto',
432 b'cvsps.mergeto',
433 default=None,
433 default=None,
434 )
434 )
435 coreconfigitem(
435 coreconfigitem(
436 b'convert',
436 b'convert',
437 b'git.committeractions',
437 b'git.committeractions',
438 default=lambda: [b'messagedifferent'],
438 default=lambda: [b'messagedifferent'],
439 )
439 )
440 coreconfigitem(
440 coreconfigitem(
441 b'convert',
441 b'convert',
442 b'git.extrakeys',
442 b'git.extrakeys',
443 default=list,
443 default=list,
444 )
444 )
445 coreconfigitem(
445 coreconfigitem(
446 b'convert',
446 b'convert',
447 b'git.findcopiesharder',
447 b'git.findcopiesharder',
448 default=False,
448 default=False,
449 )
449 )
450 coreconfigitem(
450 coreconfigitem(
451 b'convert',
451 b'convert',
452 b'git.remoteprefix',
452 b'git.remoteprefix',
453 default=b'remote',
453 default=b'remote',
454 )
454 )
455 coreconfigitem(
455 coreconfigitem(
456 b'convert',
456 b'convert',
457 b'git.renamelimit',
457 b'git.renamelimit',
458 default=400,
458 default=400,
459 )
459 )
460 coreconfigitem(
460 coreconfigitem(
461 b'convert',
461 b'convert',
462 b'git.saverev',
462 b'git.saverev',
463 default=True,
463 default=True,
464 )
464 )
465 coreconfigitem(
465 coreconfigitem(
466 b'convert',
466 b'convert',
467 b'git.similarity',
467 b'git.similarity',
468 default=50,
468 default=50,
469 )
469 )
470 coreconfigitem(
470 coreconfigitem(
471 b'convert',
471 b'convert',
472 b'git.skipsubmodules',
472 b'git.skipsubmodules',
473 default=False,
473 default=False,
474 )
474 )
475 coreconfigitem(
475 coreconfigitem(
476 b'convert',
476 b'convert',
477 b'hg.clonebranches',
477 b'hg.clonebranches',
478 default=False,
478 default=False,
479 )
479 )
480 coreconfigitem(
480 coreconfigitem(
481 b'convert',
481 b'convert',
482 b'hg.ignoreerrors',
482 b'hg.ignoreerrors',
483 default=False,
483 default=False,
484 )
484 )
485 coreconfigitem(
485 coreconfigitem(
486 b'convert',
486 b'convert',
487 b'hg.preserve-hash',
487 b'hg.preserve-hash',
488 default=False,
488 default=False,
489 )
489 )
490 coreconfigitem(
490 coreconfigitem(
491 b'convert',
491 b'convert',
492 b'hg.revs',
492 b'hg.revs',
493 default=None,
493 default=None,
494 )
494 )
495 coreconfigitem(
495 coreconfigitem(
496 b'convert',
496 b'convert',
497 b'hg.saverev',
497 b'hg.saverev',
498 default=False,
498 default=False,
499 )
499 )
500 coreconfigitem(
500 coreconfigitem(
501 b'convert',
501 b'convert',
502 b'hg.sourcename',
502 b'hg.sourcename',
503 default=None,
503 default=None,
504 )
504 )
505 coreconfigitem(
505 coreconfigitem(
506 b'convert',
506 b'convert',
507 b'hg.startrev',
507 b'hg.startrev',
508 default=None,
508 default=None,
509 )
509 )
510 coreconfigitem(
510 coreconfigitem(
511 b'convert',
511 b'convert',
512 b'hg.tagsbranch',
512 b'hg.tagsbranch',
513 default=b'default',
513 default=b'default',
514 )
514 )
515 coreconfigitem(
515 coreconfigitem(
516 b'convert',
516 b'convert',
517 b'hg.usebranchnames',
517 b'hg.usebranchnames',
518 default=True,
518 default=True,
519 )
519 )
520 coreconfigitem(
520 coreconfigitem(
521 b'convert',
521 b'convert',
522 b'ignoreancestorcheck',
522 b'ignoreancestorcheck',
523 default=False,
523 default=False,
524 experimental=True,
524 experimental=True,
525 )
525 )
526 coreconfigitem(
526 coreconfigitem(
527 b'convert',
527 b'convert',
528 b'localtimezone',
528 b'localtimezone',
529 default=False,
529 default=False,
530 )
530 )
531 coreconfigitem(
531 coreconfigitem(
532 b'convert',
532 b'convert',
533 b'p4.encoding',
533 b'p4.encoding',
534 default=dynamicdefault,
534 default=dynamicdefault,
535 )
535 )
536 coreconfigitem(
536 coreconfigitem(
537 b'convert',
537 b'convert',
538 b'p4.startrev',
538 b'p4.startrev',
539 default=0,
539 default=0,
540 )
540 )
541 coreconfigitem(
541 coreconfigitem(
542 b'convert',
542 b'convert',
543 b'skiptags',
543 b'skiptags',
544 default=False,
544 default=False,
545 )
545 )
546 coreconfigitem(
546 coreconfigitem(
547 b'convert',
547 b'convert',
548 b'svn.debugsvnlog',
548 b'svn.debugsvnlog',
549 default=True,
549 default=True,
550 )
550 )
551 coreconfigitem(
551 coreconfigitem(
552 b'convert',
552 b'convert',
553 b'svn.trunk',
553 b'svn.trunk',
554 default=None,
554 default=None,
555 )
555 )
556 coreconfigitem(
556 coreconfigitem(
557 b'convert',
557 b'convert',
558 b'svn.tags',
558 b'svn.tags',
559 default=None,
559 default=None,
560 )
560 )
561 coreconfigitem(
561 coreconfigitem(
562 b'convert',
562 b'convert',
563 b'svn.branches',
563 b'svn.branches',
564 default=None,
564 default=None,
565 )
565 )
566 coreconfigitem(
566 coreconfigitem(
567 b'convert',
567 b'convert',
568 b'svn.startrev',
568 b'svn.startrev',
569 default=0,
569 default=0,
570 )
570 )
571 coreconfigitem(
571 coreconfigitem(
572 b'convert',
572 b'convert',
573 b'svn.dangerous-set-commit-dates',
573 b'svn.dangerous-set-commit-dates',
574 default=False,
574 default=False,
575 )
575 )
576 coreconfigitem(
576 coreconfigitem(
577 b'debug',
577 b'debug',
578 b'dirstate.delaywrite',
578 b'dirstate.delaywrite',
579 default=0,
579 default=0,
580 )
580 )
581 coreconfigitem(
581 coreconfigitem(
582 b'debug',
582 b'debug',
583 b'revlog.verifyposition.changelog',
583 b'revlog.verifyposition.changelog',
584 default=b'',
584 default=b'',
585 )
585 )
586 coreconfigitem(
586 coreconfigitem(
587 b'debug',
587 b'debug',
588 b'revlog.debug-delta',
588 b'revlog.debug-delta',
589 default=False,
589 default=False,
590 )
590 )
591 # display extra information about the bundling process
591 # display extra information about the bundling process
592 coreconfigitem(
592 coreconfigitem(
593 b'debug',
593 b'debug',
594 b'bundling-stats',
594 b'bundling-stats',
595 default=False,
595 default=False,
596 )
596 )
597 # display extra information about the unbundling process
597 # display extra information about the unbundling process
598 coreconfigitem(
598 coreconfigitem(
599 b'debug',
599 b'debug',
600 b'unbundling-stats',
600 b'unbundling-stats',
601 default=False,
601 default=False,
602 )
602 )
603 coreconfigitem(
603 coreconfigitem(
604 b'defaults',
604 b'defaults',
605 b'.*',
605 b'.*',
606 default=None,
606 default=None,
607 generic=True,
607 generic=True,
608 )
608 )
609 coreconfigitem(
609 coreconfigitem(
610 b'devel',
610 b'devel',
611 b'all-warnings',
611 b'all-warnings',
612 default=False,
612 default=False,
613 )
613 )
614 coreconfigitem(
614 coreconfigitem(
615 b'devel',
615 b'devel',
616 b'bundle2.debug',
616 b'bundle2.debug',
617 default=False,
617 default=False,
618 )
618 )
619 # which kind of delta to put in the bundled changegroup. Possible value
620 # - '': use default behavior
621 # - p1: force to always use delta against p1
622 # - full: force to always use full content
619 coreconfigitem(
623 coreconfigitem(
620 b'devel',
624 b'devel',
621 b'bundle.delta',
625 b'bundle.delta',
622 default=b'',
626 default=b'',
623 )
627 )
624 coreconfigitem(
628 coreconfigitem(
625 b'devel',
629 b'devel',
626 b'cache-vfs',
630 b'cache-vfs',
627 default=None,
631 default=None,
628 )
632 )
629 coreconfigitem(
633 coreconfigitem(
630 b'devel',
634 b'devel',
631 b'check-locks',
635 b'check-locks',
632 default=False,
636 default=False,
633 )
637 )
634 coreconfigitem(
638 coreconfigitem(
635 b'devel',
639 b'devel',
636 b'check-relroot',
640 b'check-relroot',
637 default=False,
641 default=False,
638 )
642 )
639 # Track copy information for all file, not just "added" one (very slow)
643 # Track copy information for all file, not just "added" one (very slow)
640 coreconfigitem(
644 coreconfigitem(
641 b'devel',
645 b'devel',
642 b'copy-tracing.trace-all-files',
646 b'copy-tracing.trace-all-files',
643 default=False,
647 default=False,
644 )
648 )
645 coreconfigitem(
649 coreconfigitem(
646 b'devel',
650 b'devel',
647 b'default-date',
651 b'default-date',
648 default=None,
652 default=None,
649 )
653 )
650 coreconfigitem(
654 coreconfigitem(
651 b'devel',
655 b'devel',
652 b'deprec-warn',
656 b'deprec-warn',
653 default=False,
657 default=False,
654 )
658 )
655 # possible values:
659 # possible values:
656 # - auto (the default)
660 # - auto (the default)
657 # - force-append
661 # - force-append
658 # - force-new
662 # - force-new
659 coreconfigitem(
663 coreconfigitem(
660 b'devel',
664 b'devel',
661 b'dirstate.v2.data_update_mode',
665 b'dirstate.v2.data_update_mode',
662 default="auto",
666 default="auto",
663 )
667 )
664 coreconfigitem(
668 coreconfigitem(
665 b'devel',
669 b'devel',
666 b'disableloaddefaultcerts',
670 b'disableloaddefaultcerts',
667 default=False,
671 default=False,
668 )
672 )
669 coreconfigitem(
673 coreconfigitem(
670 b'devel',
674 b'devel',
671 b'warn-empty-changegroup',
675 b'warn-empty-changegroup',
672 default=False,
676 default=False,
673 )
677 )
674 coreconfigitem(
678 coreconfigitem(
675 b'devel',
679 b'devel',
676 b'legacy.exchange',
680 b'legacy.exchange',
677 default=list,
681 default=list,
678 )
682 )
679 # When True, revlogs use a special reference version of the nodemap, that is not
683 # When True, revlogs use a special reference version of the nodemap, that is not
680 # performant but is "known" to behave properly.
684 # performant but is "known" to behave properly.
681 coreconfigitem(
685 coreconfigitem(
682 b'devel',
686 b'devel',
683 b'persistent-nodemap',
687 b'persistent-nodemap',
684 default=False,
688 default=False,
685 )
689 )
686 coreconfigitem(
690 coreconfigitem(
687 b'devel',
691 b'devel',
688 b'servercafile',
692 b'servercafile',
689 default=b'',
693 default=b'',
690 )
694 )
691 # This config option is intended for use in tests only. It is a giant
695 # This config option is intended for use in tests only. It is a giant
692 # footgun to kill security. Don't define it.
696 # footgun to kill security. Don't define it.
693 coreconfigitem(
697 coreconfigitem(
694 b'devel',
698 b'devel',
695 b'server-insecure-exact-protocol',
699 b'server-insecure-exact-protocol',
696 default=b'',
700 default=b'',
697 )
701 )
698 coreconfigitem(
702 coreconfigitem(
699 b'devel',
703 b'devel',
700 b'serverrequirecert',
704 b'serverrequirecert',
701 default=False,
705 default=False,
702 )
706 )
703 # Makes the status algorithm wait for the existence of this file
707 # Makes the status algorithm wait for the existence of this file
704 # (or until a timeout of `devel.sync.status.pre-dirstate-write-file-timeout`
708 # (or until a timeout of `devel.sync.status.pre-dirstate-write-file-timeout`
705 # seconds) before taking the lock and writing the dirstate.
709 # seconds) before taking the lock and writing the dirstate.
706 # Status signals that it's ready to wait by creating a file
710 # Status signals that it's ready to wait by creating a file
707 # with the same name + `.waiting`.
711 # with the same name + `.waiting`.
708 # Useful when testing race conditions.
712 # Useful when testing race conditions.
709 coreconfigitem(
713 coreconfigitem(
710 b'devel',
714 b'devel',
711 b'sync.status.pre-dirstate-write-file',
715 b'sync.status.pre-dirstate-write-file',
712 default=None,
716 default=None,
713 )
717 )
714 coreconfigitem(
718 coreconfigitem(
715 b'devel',
719 b'devel',
716 b'sync.status.pre-dirstate-write-file-timeout',
720 b'sync.status.pre-dirstate-write-file-timeout',
717 default=2,
721 default=2,
718 )
722 )
719 coreconfigitem(
723 coreconfigitem(
720 b'devel',
724 b'devel',
721 b'sync.dirstate.post-docket-read-file',
725 b'sync.dirstate.post-docket-read-file',
722 default=None,
726 default=None,
723 )
727 )
724 coreconfigitem(
728 coreconfigitem(
725 b'devel',
729 b'devel',
726 b'sync.dirstate.post-docket-read-file-timeout',
730 b'sync.dirstate.post-docket-read-file-timeout',
727 default=2,
731 default=2,
728 )
732 )
729 coreconfigitem(
733 coreconfigitem(
730 b'devel',
734 b'devel',
731 b'sync.dirstate.pre-read-file',
735 b'sync.dirstate.pre-read-file',
732 default=None,
736 default=None,
733 )
737 )
734 coreconfigitem(
738 coreconfigitem(
735 b'devel',
739 b'devel',
736 b'sync.dirstate.pre-read-file-timeout',
740 b'sync.dirstate.pre-read-file-timeout',
737 default=2,
741 default=2,
738 )
742 )
739 coreconfigitem(
743 coreconfigitem(
740 b'devel',
744 b'devel',
741 b'strip-obsmarkers',
745 b'strip-obsmarkers',
742 default=True,
746 default=True,
743 )
747 )
744 coreconfigitem(
748 coreconfigitem(
745 b'devel',
749 b'devel',
746 b'warn-config',
750 b'warn-config',
747 default=None,
751 default=None,
748 )
752 )
749 coreconfigitem(
753 coreconfigitem(
750 b'devel',
754 b'devel',
751 b'warn-config-default',
755 b'warn-config-default',
752 default=None,
756 default=None,
753 )
757 )
754 coreconfigitem(
758 coreconfigitem(
755 b'devel',
759 b'devel',
756 b'user.obsmarker',
760 b'user.obsmarker',
757 default=None,
761 default=None,
758 )
762 )
759 coreconfigitem(
763 coreconfigitem(
760 b'devel',
764 b'devel',
761 b'warn-config-unknown',
765 b'warn-config-unknown',
762 default=None,
766 default=None,
763 )
767 )
764 coreconfigitem(
768 coreconfigitem(
765 b'devel',
769 b'devel',
766 b'debug.copies',
770 b'debug.copies',
767 default=False,
771 default=False,
768 )
772 )
769 coreconfigitem(
773 coreconfigitem(
770 b'devel',
774 b'devel',
771 b'copy-tracing.multi-thread',
775 b'copy-tracing.multi-thread',
772 default=True,
776 default=True,
773 )
777 )
774 coreconfigitem(
778 coreconfigitem(
775 b'devel',
779 b'devel',
776 b'debug.extensions',
780 b'debug.extensions',
777 default=False,
781 default=False,
778 )
782 )
779 coreconfigitem(
783 coreconfigitem(
780 b'devel',
784 b'devel',
781 b'debug.repo-filters',
785 b'debug.repo-filters',
782 default=False,
786 default=False,
783 )
787 )
784 coreconfigitem(
788 coreconfigitem(
785 b'devel',
789 b'devel',
786 b'debug.peer-request',
790 b'debug.peer-request',
787 default=False,
791 default=False,
788 )
792 )
789 # If discovery.exchange-heads is False, the discovery will not start with
793 # If discovery.exchange-heads is False, the discovery will not start with
790 # remote head fetching and local head querying.
794 # remote head fetching and local head querying.
791 coreconfigitem(
795 coreconfigitem(
792 b'devel',
796 b'devel',
793 b'discovery.exchange-heads',
797 b'discovery.exchange-heads',
794 default=True,
798 default=True,
795 )
799 )
796 # If devel.debug.abort-update is True, then any merge with the working copy,
800 # If devel.debug.abort-update is True, then any merge with the working copy,
797 # e.g. [hg update], will be aborted after figuring out what needs to be done,
801 # e.g. [hg update], will be aborted after figuring out what needs to be done,
798 # but before spawning the parallel worker
802 # but before spawning the parallel worker
799 coreconfigitem(
803 coreconfigitem(
800 b'devel',
804 b'devel',
801 b'debug.abort-update',
805 b'debug.abort-update',
802 default=False,
806 default=False,
803 )
807 )
804 # If discovery.grow-sample is False, the sample size used in set discovery will
808 # If discovery.grow-sample is False, the sample size used in set discovery will
805 # not be increased through the process
809 # not be increased through the process
806 coreconfigitem(
810 coreconfigitem(
807 b'devel',
811 b'devel',
808 b'discovery.grow-sample',
812 b'discovery.grow-sample',
809 default=True,
813 default=True,
810 )
814 )
811 # When discovery.grow-sample.dynamic is True, the default, the sample size is
815 # When discovery.grow-sample.dynamic is True, the default, the sample size is
812 # adapted to the shape of the undecided set (it is set to the max of:
816 # adapted to the shape of the undecided set (it is set to the max of:
813 # <target-size>, len(roots(undecided)), len(heads(undecided)
817 # <target-size>, len(roots(undecided)), len(heads(undecided)
814 coreconfigitem(
818 coreconfigitem(
815 b'devel',
819 b'devel',
816 b'discovery.grow-sample.dynamic',
820 b'discovery.grow-sample.dynamic',
817 default=True,
821 default=True,
818 )
822 )
819 # discovery.grow-sample.rate control the rate at which the sample grow
823 # discovery.grow-sample.rate control the rate at which the sample grow
820 coreconfigitem(
824 coreconfigitem(
821 b'devel',
825 b'devel',
822 b'discovery.grow-sample.rate',
826 b'discovery.grow-sample.rate',
823 default=1.05,
827 default=1.05,
824 )
828 )
825 # If discovery.randomize is False, random sampling during discovery are
829 # If discovery.randomize is False, random sampling during discovery are
826 # deterministic. It is meant for integration tests.
830 # deterministic. It is meant for integration tests.
827 coreconfigitem(
831 coreconfigitem(
828 b'devel',
832 b'devel',
829 b'discovery.randomize',
833 b'discovery.randomize',
830 default=True,
834 default=True,
831 )
835 )
832 # Control the initial size of the discovery sample
836 # Control the initial size of the discovery sample
833 coreconfigitem(
837 coreconfigitem(
834 b'devel',
838 b'devel',
835 b'discovery.sample-size',
839 b'discovery.sample-size',
836 default=200,
840 default=200,
837 )
841 )
838 # Control the initial size of the discovery for initial change
842 # Control the initial size of the discovery for initial change
839 coreconfigitem(
843 coreconfigitem(
840 b'devel',
844 b'devel',
841 b'discovery.sample-size.initial',
845 b'discovery.sample-size.initial',
842 default=100,
846 default=100,
843 )
847 )
844 _registerdiffopts(section=b'diff')
848 _registerdiffopts(section=b'diff')
845 coreconfigitem(
849 coreconfigitem(
846 b'diff',
850 b'diff',
847 b'merge',
851 b'merge',
848 default=False,
852 default=False,
849 experimental=True,
853 experimental=True,
850 )
854 )
851 coreconfigitem(
855 coreconfigitem(
852 b'email',
856 b'email',
853 b'bcc',
857 b'bcc',
854 default=None,
858 default=None,
855 )
859 )
856 coreconfigitem(
860 coreconfigitem(
857 b'email',
861 b'email',
858 b'cc',
862 b'cc',
859 default=None,
863 default=None,
860 )
864 )
861 coreconfigitem(
865 coreconfigitem(
862 b'email',
866 b'email',
863 b'charsets',
867 b'charsets',
864 default=list,
868 default=list,
865 )
869 )
866 coreconfigitem(
870 coreconfigitem(
867 b'email',
871 b'email',
868 b'from',
872 b'from',
869 default=None,
873 default=None,
870 )
874 )
871 coreconfigitem(
875 coreconfigitem(
872 b'email',
876 b'email',
873 b'method',
877 b'method',
874 default=b'smtp',
878 default=b'smtp',
875 )
879 )
876 coreconfigitem(
880 coreconfigitem(
877 b'email',
881 b'email',
878 b'reply-to',
882 b'reply-to',
879 default=None,
883 default=None,
880 )
884 )
881 coreconfigitem(
885 coreconfigitem(
882 b'email',
886 b'email',
883 b'to',
887 b'to',
884 default=None,
888 default=None,
885 )
889 )
886 coreconfigitem(
890 coreconfigitem(
887 b'experimental',
891 b'experimental',
888 b'archivemetatemplate',
892 b'archivemetatemplate',
889 default=dynamicdefault,
893 default=dynamicdefault,
890 )
894 )
891 coreconfigitem(
895 coreconfigitem(
892 b'experimental',
896 b'experimental',
893 b'auto-publish',
897 b'auto-publish',
894 default=b'publish',
898 default=b'publish',
895 )
899 )
896 coreconfigitem(
900 coreconfigitem(
897 b'experimental',
901 b'experimental',
898 b'bundle-phases',
902 b'bundle-phases',
899 default=False,
903 default=False,
900 )
904 )
901 coreconfigitem(
905 coreconfigitem(
902 b'experimental',
906 b'experimental',
903 b'bundle2-advertise',
907 b'bundle2-advertise',
904 default=True,
908 default=True,
905 )
909 )
906 coreconfigitem(
910 coreconfigitem(
907 b'experimental',
911 b'experimental',
908 b'bundle2-output-capture',
912 b'bundle2-output-capture',
909 default=False,
913 default=False,
910 )
914 )
911 coreconfigitem(
915 coreconfigitem(
912 b'experimental',
916 b'experimental',
913 b'bundle2.pushback',
917 b'bundle2.pushback',
914 default=False,
918 default=False,
915 )
919 )
916 coreconfigitem(
920 coreconfigitem(
917 b'experimental',
921 b'experimental',
918 b'bundle2lazylocking',
922 b'bundle2lazylocking',
919 default=False,
923 default=False,
920 )
924 )
921 coreconfigitem(
925 coreconfigitem(
922 b'experimental',
926 b'experimental',
923 b'bundlecomplevel',
927 b'bundlecomplevel',
924 default=None,
928 default=None,
925 )
929 )
926 coreconfigitem(
930 coreconfigitem(
927 b'experimental',
931 b'experimental',
928 b'bundlecomplevel.bzip2',
932 b'bundlecomplevel.bzip2',
929 default=None,
933 default=None,
930 )
934 )
931 coreconfigitem(
935 coreconfigitem(
932 b'experimental',
936 b'experimental',
933 b'bundlecomplevel.gzip',
937 b'bundlecomplevel.gzip',
934 default=None,
938 default=None,
935 )
939 )
936 coreconfigitem(
940 coreconfigitem(
937 b'experimental',
941 b'experimental',
938 b'bundlecomplevel.none',
942 b'bundlecomplevel.none',
939 default=None,
943 default=None,
940 )
944 )
941 coreconfigitem(
945 coreconfigitem(
942 b'experimental',
946 b'experimental',
943 b'bundlecomplevel.zstd',
947 b'bundlecomplevel.zstd',
944 default=None,
948 default=None,
945 )
949 )
946 coreconfigitem(
950 coreconfigitem(
947 b'experimental',
951 b'experimental',
948 b'bundlecompthreads',
952 b'bundlecompthreads',
949 default=None,
953 default=None,
950 )
954 )
951 coreconfigitem(
955 coreconfigitem(
952 b'experimental',
956 b'experimental',
953 b'bundlecompthreads.bzip2',
957 b'bundlecompthreads.bzip2',
954 default=None,
958 default=None,
955 )
959 )
956 coreconfigitem(
960 coreconfigitem(
957 b'experimental',
961 b'experimental',
958 b'bundlecompthreads.gzip',
962 b'bundlecompthreads.gzip',
959 default=None,
963 default=None,
960 )
964 )
961 coreconfigitem(
965 coreconfigitem(
962 b'experimental',
966 b'experimental',
963 b'bundlecompthreads.none',
967 b'bundlecompthreads.none',
964 default=None,
968 default=None,
965 )
969 )
966 coreconfigitem(
970 coreconfigitem(
967 b'experimental',
971 b'experimental',
968 b'bundlecompthreads.zstd',
972 b'bundlecompthreads.zstd',
969 default=None,
973 default=None,
970 )
974 )
971 coreconfigitem(
975 coreconfigitem(
972 b'experimental',
976 b'experimental',
973 b'changegroup3',
977 b'changegroup3',
974 default=True,
978 default=True,
975 )
979 )
976 coreconfigitem(
980 coreconfigitem(
977 b'experimental',
981 b'experimental',
978 b'changegroup4',
982 b'changegroup4',
979 default=False,
983 default=False,
980 )
984 )
981
985
982 # might remove rank configuration once the computation has no impact
986 # might remove rank configuration once the computation has no impact
983 coreconfigitem(
987 coreconfigitem(
984 b'experimental',
988 b'experimental',
985 b'changelog-v2.compute-rank',
989 b'changelog-v2.compute-rank',
986 default=True,
990 default=True,
987 )
991 )
988 coreconfigitem(
992 coreconfigitem(
989 b'experimental',
993 b'experimental',
990 b'cleanup-as-archived',
994 b'cleanup-as-archived',
991 default=False,
995 default=False,
992 )
996 )
993 coreconfigitem(
997 coreconfigitem(
994 b'experimental',
998 b'experimental',
995 b'clientcompressionengines',
999 b'clientcompressionengines',
996 default=list,
1000 default=list,
997 )
1001 )
998 coreconfigitem(
1002 coreconfigitem(
999 b'experimental',
1003 b'experimental',
1000 b'copytrace',
1004 b'copytrace',
1001 default=b'on',
1005 default=b'on',
1002 )
1006 )
1003 coreconfigitem(
1007 coreconfigitem(
1004 b'experimental',
1008 b'experimental',
1005 b'copytrace.movecandidateslimit',
1009 b'copytrace.movecandidateslimit',
1006 default=100,
1010 default=100,
1007 )
1011 )
1008 coreconfigitem(
1012 coreconfigitem(
1009 b'experimental',
1013 b'experimental',
1010 b'copytrace.sourcecommitlimit',
1014 b'copytrace.sourcecommitlimit',
1011 default=100,
1015 default=100,
1012 )
1016 )
1013 coreconfigitem(
1017 coreconfigitem(
1014 b'experimental',
1018 b'experimental',
1015 b'copies.read-from',
1019 b'copies.read-from',
1016 default=b"filelog-only",
1020 default=b"filelog-only",
1017 )
1021 )
1018 coreconfigitem(
1022 coreconfigitem(
1019 b'experimental',
1023 b'experimental',
1020 b'copies.write-to',
1024 b'copies.write-to',
1021 default=b'filelog-only',
1025 default=b'filelog-only',
1022 )
1026 )
1023 coreconfigitem(
1027 coreconfigitem(
1024 b'experimental',
1028 b'experimental',
1025 b'crecordtest',
1029 b'crecordtest',
1026 default=None,
1030 default=None,
1027 )
1031 )
1028 coreconfigitem(
1032 coreconfigitem(
1029 b'experimental',
1033 b'experimental',
1030 b'directaccess',
1034 b'directaccess',
1031 default=False,
1035 default=False,
1032 )
1036 )
1033 coreconfigitem(
1037 coreconfigitem(
1034 b'experimental',
1038 b'experimental',
1035 b'directaccess.revnums',
1039 b'directaccess.revnums',
1036 default=False,
1040 default=False,
1037 )
1041 )
1038 coreconfigitem(
1042 coreconfigitem(
1039 b'experimental',
1043 b'experimental',
1040 b'editortmpinhg',
1044 b'editortmpinhg',
1041 default=False,
1045 default=False,
1042 )
1046 )
1043 coreconfigitem(
1047 coreconfigitem(
1044 b'experimental',
1048 b'experimental',
1045 b'evolution',
1049 b'evolution',
1046 default=list,
1050 default=list,
1047 )
1051 )
1048 coreconfigitem(
1052 coreconfigitem(
1049 b'experimental',
1053 b'experimental',
1050 b'evolution.allowdivergence',
1054 b'evolution.allowdivergence',
1051 default=False,
1055 default=False,
1052 alias=[(b'experimental', b'allowdivergence')],
1056 alias=[(b'experimental', b'allowdivergence')],
1053 )
1057 )
1054 coreconfigitem(
1058 coreconfigitem(
1055 b'experimental',
1059 b'experimental',
1056 b'evolution.allowunstable',
1060 b'evolution.allowunstable',
1057 default=None,
1061 default=None,
1058 )
1062 )
1059 coreconfigitem(
1063 coreconfigitem(
1060 b'experimental',
1064 b'experimental',
1061 b'evolution.createmarkers',
1065 b'evolution.createmarkers',
1062 default=None,
1066 default=None,
1063 )
1067 )
1064 coreconfigitem(
1068 coreconfigitem(
1065 b'experimental',
1069 b'experimental',
1066 b'evolution.effect-flags',
1070 b'evolution.effect-flags',
1067 default=True,
1071 default=True,
1068 alias=[(b'experimental', b'effect-flags')],
1072 alias=[(b'experimental', b'effect-flags')],
1069 )
1073 )
1070 coreconfigitem(
1074 coreconfigitem(
1071 b'experimental',
1075 b'experimental',
1072 b'evolution.exchange',
1076 b'evolution.exchange',
1073 default=None,
1077 default=None,
1074 )
1078 )
1075 coreconfigitem(
1079 coreconfigitem(
1076 b'experimental',
1080 b'experimental',
1077 b'evolution.bundle-obsmarker',
1081 b'evolution.bundle-obsmarker',
1078 default=False,
1082 default=False,
1079 )
1083 )
1080 coreconfigitem(
1084 coreconfigitem(
1081 b'experimental',
1085 b'experimental',
1082 b'evolution.bundle-obsmarker:mandatory',
1086 b'evolution.bundle-obsmarker:mandatory',
1083 default=True,
1087 default=True,
1084 )
1088 )
1085 coreconfigitem(
1089 coreconfigitem(
1086 b'experimental',
1090 b'experimental',
1087 b'log.topo',
1091 b'log.topo',
1088 default=False,
1092 default=False,
1089 )
1093 )
1090 coreconfigitem(
1094 coreconfigitem(
1091 b'experimental',
1095 b'experimental',
1092 b'evolution.report-instabilities',
1096 b'evolution.report-instabilities',
1093 default=True,
1097 default=True,
1094 )
1098 )
1095 coreconfigitem(
1099 coreconfigitem(
1096 b'experimental',
1100 b'experimental',
1097 b'evolution.track-operation',
1101 b'evolution.track-operation',
1098 default=True,
1102 default=True,
1099 )
1103 )
1100 # repo-level config to exclude a revset visibility
1104 # repo-level config to exclude a revset visibility
1101 #
1105 #
1102 # The target use case is to use `share` to expose different subset of the same
1106 # The target use case is to use `share` to expose different subset of the same
1103 # repository, especially server side. See also `server.view`.
1107 # repository, especially server side. See also `server.view`.
1104 coreconfigitem(
1108 coreconfigitem(
1105 b'experimental',
1109 b'experimental',
1106 b'extra-filter-revs',
1110 b'extra-filter-revs',
1107 default=None,
1111 default=None,
1108 )
1112 )
1109 coreconfigitem(
1113 coreconfigitem(
1110 b'experimental',
1114 b'experimental',
1111 b'maxdeltachainspan',
1115 b'maxdeltachainspan',
1112 default=-1,
1116 default=-1,
1113 )
1117 )
1114 # tracks files which were undeleted (merge might delete them but we explicitly
1118 # tracks files which were undeleted (merge might delete them but we explicitly
1115 # kept/undeleted them) and creates new filenodes for them
1119 # kept/undeleted them) and creates new filenodes for them
1116 coreconfigitem(
1120 coreconfigitem(
1117 b'experimental',
1121 b'experimental',
1118 b'merge-track-salvaged',
1122 b'merge-track-salvaged',
1119 default=False,
1123 default=False,
1120 )
1124 )
1121 coreconfigitem(
1125 coreconfigitem(
1122 b'experimental',
1126 b'experimental',
1123 b'mmapindexthreshold',
1127 b'mmapindexthreshold',
1124 default=None,
1128 default=None,
1125 )
1129 )
1126 coreconfigitem(
1130 coreconfigitem(
1127 b'experimental',
1131 b'experimental',
1128 b'narrow',
1132 b'narrow',
1129 default=False,
1133 default=False,
1130 )
1134 )
1131 coreconfigitem(
1135 coreconfigitem(
1132 b'experimental',
1136 b'experimental',
1133 b'nonnormalparanoidcheck',
1137 b'nonnormalparanoidcheck',
1134 default=False,
1138 default=False,
1135 )
1139 )
1136 coreconfigitem(
1140 coreconfigitem(
1137 b'experimental',
1141 b'experimental',
1138 b'exportableenviron',
1142 b'exportableenviron',
1139 default=list,
1143 default=list,
1140 )
1144 )
1141 coreconfigitem(
1145 coreconfigitem(
1142 b'experimental',
1146 b'experimental',
1143 b'extendedheader.index',
1147 b'extendedheader.index',
1144 default=None,
1148 default=None,
1145 )
1149 )
1146 coreconfigitem(
1150 coreconfigitem(
1147 b'experimental',
1151 b'experimental',
1148 b'extendedheader.similarity',
1152 b'extendedheader.similarity',
1149 default=False,
1153 default=False,
1150 )
1154 )
1151 coreconfigitem(
1155 coreconfigitem(
1152 b'experimental',
1156 b'experimental',
1153 b'graphshorten',
1157 b'graphshorten',
1154 default=False,
1158 default=False,
1155 )
1159 )
1156 coreconfigitem(
1160 coreconfigitem(
1157 b'experimental',
1161 b'experimental',
1158 b'graphstyle.parent',
1162 b'graphstyle.parent',
1159 default=dynamicdefault,
1163 default=dynamicdefault,
1160 )
1164 )
1161 coreconfigitem(
1165 coreconfigitem(
1162 b'experimental',
1166 b'experimental',
1163 b'graphstyle.missing',
1167 b'graphstyle.missing',
1164 default=dynamicdefault,
1168 default=dynamicdefault,
1165 )
1169 )
1166 coreconfigitem(
1170 coreconfigitem(
1167 b'experimental',
1171 b'experimental',
1168 b'graphstyle.grandparent',
1172 b'graphstyle.grandparent',
1169 default=dynamicdefault,
1173 default=dynamicdefault,
1170 )
1174 )
1171 coreconfigitem(
1175 coreconfigitem(
1172 b'experimental',
1176 b'experimental',
1173 b'hook-track-tags',
1177 b'hook-track-tags',
1174 default=False,
1178 default=False,
1175 )
1179 )
1176 coreconfigitem(
1180 coreconfigitem(
1177 b'experimental',
1181 b'experimental',
1178 b'httppostargs',
1182 b'httppostargs',
1179 default=False,
1183 default=False,
1180 )
1184 )
1181 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1185 coreconfigitem(b'experimental', b'nointerrupt', default=False)
1182 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1186 coreconfigitem(b'experimental', b'nointerrupt-interactiveonly', default=True)
1183
1187
1184 coreconfigitem(
1188 coreconfigitem(
1185 b'experimental',
1189 b'experimental',
1186 b'obsmarkers-exchange-debug',
1190 b'obsmarkers-exchange-debug',
1187 default=False,
1191 default=False,
1188 )
1192 )
1189 coreconfigitem(
1193 coreconfigitem(
1190 b'experimental',
1194 b'experimental',
1191 b'remotenames',
1195 b'remotenames',
1192 default=False,
1196 default=False,
1193 )
1197 )
1194 coreconfigitem(
1198 coreconfigitem(
1195 b'experimental',
1199 b'experimental',
1196 b'removeemptydirs',
1200 b'removeemptydirs',
1197 default=True,
1201 default=True,
1198 )
1202 )
1199 coreconfigitem(
1203 coreconfigitem(
1200 b'experimental',
1204 b'experimental',
1201 b'revert.interactive.select-to-keep',
1205 b'revert.interactive.select-to-keep',
1202 default=False,
1206 default=False,
1203 )
1207 )
1204 coreconfigitem(
1208 coreconfigitem(
1205 b'experimental',
1209 b'experimental',
1206 b'revisions.prefixhexnode',
1210 b'revisions.prefixhexnode',
1207 default=False,
1211 default=False,
1208 )
1212 )
1209 # "out of experimental" todo list.
1213 # "out of experimental" todo list.
1210 #
1214 #
1211 # * include management of a persistent nodemap in the main docket
1215 # * include management of a persistent nodemap in the main docket
1212 # * enforce a "no-truncate" policy for mmap safety
1216 # * enforce a "no-truncate" policy for mmap safety
1213 # - for censoring operation
1217 # - for censoring operation
1214 # - for stripping operation
1218 # - for stripping operation
1215 # - for rollback operation
1219 # - for rollback operation
1216 # * proper streaming (race free) of the docket file
1220 # * proper streaming (race free) of the docket file
1217 # * track garbage data to evemtually allow rewriting -existing- sidedata.
1221 # * track garbage data to evemtually allow rewriting -existing- sidedata.
1218 # * Exchange-wise, we will also need to do something more efficient than
1222 # * Exchange-wise, we will also need to do something more efficient than
1219 # keeping references to the affected revlogs, especially memory-wise when
1223 # keeping references to the affected revlogs, especially memory-wise when
1220 # rewriting sidedata.
1224 # rewriting sidedata.
1221 # * introduce a proper solution to reduce the number of filelog related files.
1225 # * introduce a proper solution to reduce the number of filelog related files.
1222 # * use caching for reading sidedata (similar to what we do for data).
1226 # * use caching for reading sidedata (similar to what we do for data).
1223 # * no longer set offset=0 if sidedata_size=0 (simplify cutoff computation).
1227 # * no longer set offset=0 if sidedata_size=0 (simplify cutoff computation).
1224 # * Improvement to consider
1228 # * Improvement to consider
1225 # - avoid compression header in chunk using the default compression?
1229 # - avoid compression header in chunk using the default compression?
1226 # - forbid "inline" compression mode entirely?
1230 # - forbid "inline" compression mode entirely?
1227 # - split the data offset and flag field (the 2 bytes save are mostly trouble)
1231 # - split the data offset and flag field (the 2 bytes save are mostly trouble)
1228 # - keep track of uncompressed -chunk- size (to preallocate memory better)
1232 # - keep track of uncompressed -chunk- size (to preallocate memory better)
1229 # - keep track of chain base or size (probably not that useful anymore)
1233 # - keep track of chain base or size (probably not that useful anymore)
1230 coreconfigitem(
1234 coreconfigitem(
1231 b'experimental',
1235 b'experimental',
1232 b'revlogv2',
1236 b'revlogv2',
1233 default=None,
1237 default=None,
1234 )
1238 )
1235 coreconfigitem(
1239 coreconfigitem(
1236 b'experimental',
1240 b'experimental',
1237 b'revisions.disambiguatewithin',
1241 b'revisions.disambiguatewithin',
1238 default=None,
1242 default=None,
1239 )
1243 )
1240 coreconfigitem(
1244 coreconfigitem(
1241 b'experimental',
1245 b'experimental',
1242 b'rust.index',
1246 b'rust.index',
1243 default=False,
1247 default=False,
1244 )
1248 )
1245 coreconfigitem(
1249 coreconfigitem(
1246 b'experimental',
1250 b'experimental',
1247 b'server.allow-hidden-access',
1251 b'server.allow-hidden-access',
1248 default=list,
1252 default=list,
1249 )
1253 )
1250 coreconfigitem(
1254 coreconfigitem(
1251 b'experimental',
1255 b'experimental',
1252 b'server.filesdata.recommended-batch-size',
1256 b'server.filesdata.recommended-batch-size',
1253 default=50000,
1257 default=50000,
1254 )
1258 )
1255 coreconfigitem(
1259 coreconfigitem(
1256 b'experimental',
1260 b'experimental',
1257 b'server.manifestdata.recommended-batch-size',
1261 b'server.manifestdata.recommended-batch-size',
1258 default=100000,
1262 default=100000,
1259 )
1263 )
1260 coreconfigitem(
1264 coreconfigitem(
1261 b'experimental',
1265 b'experimental',
1262 b'server.stream-narrow-clones',
1266 b'server.stream-narrow-clones',
1263 default=False,
1267 default=False,
1264 )
1268 )
1265 coreconfigitem(
1269 coreconfigitem(
1266 b'experimental',
1270 b'experimental',
1267 b'single-head-per-branch',
1271 b'single-head-per-branch',
1268 default=False,
1272 default=False,
1269 )
1273 )
1270 coreconfigitem(
1274 coreconfigitem(
1271 b'experimental',
1275 b'experimental',
1272 b'single-head-per-branch:account-closed-heads',
1276 b'single-head-per-branch:account-closed-heads',
1273 default=False,
1277 default=False,
1274 )
1278 )
1275 coreconfigitem(
1279 coreconfigitem(
1276 b'experimental',
1280 b'experimental',
1277 b'single-head-per-branch:public-changes-only',
1281 b'single-head-per-branch:public-changes-only',
1278 default=False,
1282 default=False,
1279 )
1283 )
1280 coreconfigitem(
1284 coreconfigitem(
1281 b'experimental',
1285 b'experimental',
1282 b'sparse-read',
1286 b'sparse-read',
1283 default=False,
1287 default=False,
1284 )
1288 )
1285 coreconfigitem(
1289 coreconfigitem(
1286 b'experimental',
1290 b'experimental',
1287 b'sparse-read.density-threshold',
1291 b'sparse-read.density-threshold',
1288 default=0.50,
1292 default=0.50,
1289 )
1293 )
1290 coreconfigitem(
1294 coreconfigitem(
1291 b'experimental',
1295 b'experimental',
1292 b'sparse-read.min-gap-size',
1296 b'sparse-read.min-gap-size',
1293 default=b'65K',
1297 default=b'65K',
1294 )
1298 )
1295 coreconfigitem(
1299 coreconfigitem(
1296 b'experimental',
1300 b'experimental',
1297 b'treemanifest',
1301 b'treemanifest',
1298 default=False,
1302 default=False,
1299 )
1303 )
1300 coreconfigitem(
1304 coreconfigitem(
1301 b'experimental',
1305 b'experimental',
1302 b'update.atomic-file',
1306 b'update.atomic-file',
1303 default=False,
1307 default=False,
1304 )
1308 )
1305 coreconfigitem(
1309 coreconfigitem(
1306 b'experimental',
1310 b'experimental',
1307 b'web.full-garbage-collection-rate',
1311 b'web.full-garbage-collection-rate',
1308 default=1, # still forcing a full collection on each request
1312 default=1, # still forcing a full collection on each request
1309 )
1313 )
1310 coreconfigitem(
1314 coreconfigitem(
1311 b'experimental',
1315 b'experimental',
1312 b'worker.wdir-get-thread-safe',
1316 b'worker.wdir-get-thread-safe',
1313 default=False,
1317 default=False,
1314 )
1318 )
1315 coreconfigitem(
1319 coreconfigitem(
1316 b'experimental',
1320 b'experimental',
1317 b'worker.repository-upgrade',
1321 b'worker.repository-upgrade',
1318 default=False,
1322 default=False,
1319 )
1323 )
1320 coreconfigitem(
1324 coreconfigitem(
1321 b'experimental',
1325 b'experimental',
1322 b'xdiff',
1326 b'xdiff',
1323 default=False,
1327 default=False,
1324 )
1328 )
1325 coreconfigitem(
1329 coreconfigitem(
1326 b'extensions',
1330 b'extensions',
1327 b'[^:]*',
1331 b'[^:]*',
1328 default=None,
1332 default=None,
1329 generic=True,
1333 generic=True,
1330 )
1334 )
1331 coreconfigitem(
1335 coreconfigitem(
1332 b'extensions',
1336 b'extensions',
1333 b'[^:]*:required',
1337 b'[^:]*:required',
1334 default=False,
1338 default=False,
1335 generic=True,
1339 generic=True,
1336 )
1340 )
1337 coreconfigitem(
1341 coreconfigitem(
1338 b'extdata',
1342 b'extdata',
1339 b'.*',
1343 b'.*',
1340 default=None,
1344 default=None,
1341 generic=True,
1345 generic=True,
1342 )
1346 )
1343 coreconfigitem(
1347 coreconfigitem(
1344 b'format',
1348 b'format',
1345 b'bookmarks-in-store',
1349 b'bookmarks-in-store',
1346 default=False,
1350 default=False,
1347 )
1351 )
1348 coreconfigitem(
1352 coreconfigitem(
1349 b'format',
1353 b'format',
1350 b'chunkcachesize',
1354 b'chunkcachesize',
1351 default=None,
1355 default=None,
1352 experimental=True,
1356 experimental=True,
1353 )
1357 )
1354 coreconfigitem(
1358 coreconfigitem(
1355 # Enable this dirstate format *when creating a new repository*.
1359 # Enable this dirstate format *when creating a new repository*.
1356 # Which format to use for existing repos is controlled by .hg/requires
1360 # Which format to use for existing repos is controlled by .hg/requires
1357 b'format',
1361 b'format',
1358 b'use-dirstate-v2',
1362 b'use-dirstate-v2',
1359 default=False,
1363 default=False,
1360 experimental=True,
1364 experimental=True,
1361 alias=[(b'format', b'exp-rc-dirstate-v2')],
1365 alias=[(b'format', b'exp-rc-dirstate-v2')],
1362 )
1366 )
1363 coreconfigitem(
1367 coreconfigitem(
1364 b'format',
1368 b'format',
1365 b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories',
1369 b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories',
1366 default=False,
1370 default=False,
1367 experimental=True,
1371 experimental=True,
1368 )
1372 )
1369 coreconfigitem(
1373 coreconfigitem(
1370 b'format',
1374 b'format',
1371 b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet',
1375 b'use-dirstate-v2.automatic-upgrade-of-mismatching-repositories:quiet',
1372 default=False,
1376 default=False,
1373 experimental=True,
1377 experimental=True,
1374 )
1378 )
1375 coreconfigitem(
1379 coreconfigitem(
1376 b'format',
1380 b'format',
1377 b'use-dirstate-tracked-hint',
1381 b'use-dirstate-tracked-hint',
1378 default=False,
1382 default=False,
1379 experimental=True,
1383 experimental=True,
1380 )
1384 )
1381 coreconfigitem(
1385 coreconfigitem(
1382 b'format',
1386 b'format',
1383 b'use-dirstate-tracked-hint.version',
1387 b'use-dirstate-tracked-hint.version',
1384 default=1,
1388 default=1,
1385 experimental=True,
1389 experimental=True,
1386 )
1390 )
1387 coreconfigitem(
1391 coreconfigitem(
1388 b'format',
1392 b'format',
1389 b'use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories',
1393 b'use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories',
1390 default=False,
1394 default=False,
1391 experimental=True,
1395 experimental=True,
1392 )
1396 )
1393 coreconfigitem(
1397 coreconfigitem(
1394 b'format',
1398 b'format',
1395 b'use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet',
1399 b'use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories:quiet',
1396 default=False,
1400 default=False,
1397 experimental=True,
1401 experimental=True,
1398 )
1402 )
1399 coreconfigitem(
1403 coreconfigitem(
1400 b'format',
1404 b'format',
1401 b'dotencode',
1405 b'dotencode',
1402 default=True,
1406 default=True,
1403 )
1407 )
1404 coreconfigitem(
1408 coreconfigitem(
1405 b'format',
1409 b'format',
1406 b'generaldelta',
1410 b'generaldelta',
1407 default=False,
1411 default=False,
1408 experimental=True,
1412 experimental=True,
1409 )
1413 )
1410 coreconfigitem(
1414 coreconfigitem(
1411 b'format',
1415 b'format',
1412 b'manifestcachesize',
1416 b'manifestcachesize',
1413 default=None,
1417 default=None,
1414 experimental=True,
1418 experimental=True,
1415 )
1419 )
1416 coreconfigitem(
1420 coreconfigitem(
1417 b'format',
1421 b'format',
1418 b'maxchainlen',
1422 b'maxchainlen',
1419 default=dynamicdefault,
1423 default=dynamicdefault,
1420 experimental=True,
1424 experimental=True,
1421 )
1425 )
1422 coreconfigitem(
1426 coreconfigitem(
1423 b'format',
1427 b'format',
1424 b'obsstore-version',
1428 b'obsstore-version',
1425 default=None,
1429 default=None,
1426 )
1430 )
1427 coreconfigitem(
1431 coreconfigitem(
1428 b'format',
1432 b'format',
1429 b'sparse-revlog',
1433 b'sparse-revlog',
1430 default=True,
1434 default=True,
1431 )
1435 )
1432 coreconfigitem(
1436 coreconfigitem(
1433 b'format',
1437 b'format',
1434 b'revlog-compression',
1438 b'revlog-compression',
1435 default=lambda: [b'zstd', b'zlib'],
1439 default=lambda: [b'zstd', b'zlib'],
1436 alias=[(b'experimental', b'format.compression')],
1440 alias=[(b'experimental', b'format.compression')],
1437 )
1441 )
1438 # Experimental TODOs:
1442 # Experimental TODOs:
1439 #
1443 #
1440 # * Same as for revlogv2 (but for the reduction of the number of files)
1444 # * Same as for revlogv2 (but for the reduction of the number of files)
1441 # * Actually computing the rank of changesets
1445 # * Actually computing the rank of changesets
1442 # * Improvement to investigate
1446 # * Improvement to investigate
1443 # - storing .hgtags fnode
1447 # - storing .hgtags fnode
1444 # - storing branch related identifier
1448 # - storing branch related identifier
1445
1449
1446 coreconfigitem(
1450 coreconfigitem(
1447 b'format',
1451 b'format',
1448 b'exp-use-changelog-v2',
1452 b'exp-use-changelog-v2',
1449 default=None,
1453 default=None,
1450 experimental=True,
1454 experimental=True,
1451 )
1455 )
1452 coreconfigitem(
1456 coreconfigitem(
1453 b'format',
1457 b'format',
1454 b'usefncache',
1458 b'usefncache',
1455 default=True,
1459 default=True,
1456 )
1460 )
1457 coreconfigitem(
1461 coreconfigitem(
1458 b'format',
1462 b'format',
1459 b'usegeneraldelta',
1463 b'usegeneraldelta',
1460 default=True,
1464 default=True,
1461 )
1465 )
1462 coreconfigitem(
1466 coreconfigitem(
1463 b'format',
1467 b'format',
1464 b'usestore',
1468 b'usestore',
1465 default=True,
1469 default=True,
1466 )
1470 )
1467
1471
1468
1472
1469 def _persistent_nodemap_default():
1473 def _persistent_nodemap_default():
1470 """compute `use-persistent-nodemap` default value
1474 """compute `use-persistent-nodemap` default value
1471
1475
1472 The feature is disabled unless a fast implementation is available.
1476 The feature is disabled unless a fast implementation is available.
1473 """
1477 """
1474 from . import policy
1478 from . import policy
1475
1479
1476 return policy.importrust('revlog') is not None
1480 return policy.importrust('revlog') is not None
1477
1481
1478
1482
1479 coreconfigitem(
1483 coreconfigitem(
1480 b'format',
1484 b'format',
1481 b'use-persistent-nodemap',
1485 b'use-persistent-nodemap',
1482 default=_persistent_nodemap_default,
1486 default=_persistent_nodemap_default,
1483 )
1487 )
1484 coreconfigitem(
1488 coreconfigitem(
1485 b'format',
1489 b'format',
1486 b'exp-use-copies-side-data-changeset',
1490 b'exp-use-copies-side-data-changeset',
1487 default=False,
1491 default=False,
1488 experimental=True,
1492 experimental=True,
1489 )
1493 )
1490 coreconfigitem(
1494 coreconfigitem(
1491 b'format',
1495 b'format',
1492 b'use-share-safe',
1496 b'use-share-safe',
1493 default=True,
1497 default=True,
1494 )
1498 )
1495 coreconfigitem(
1499 coreconfigitem(
1496 b'format',
1500 b'format',
1497 b'use-share-safe.automatic-upgrade-of-mismatching-repositories',
1501 b'use-share-safe.automatic-upgrade-of-mismatching-repositories',
1498 default=False,
1502 default=False,
1499 experimental=True,
1503 experimental=True,
1500 )
1504 )
1501 coreconfigitem(
1505 coreconfigitem(
1502 b'format',
1506 b'format',
1503 b'use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet',
1507 b'use-share-safe.automatic-upgrade-of-mismatching-repositories:quiet',
1504 default=False,
1508 default=False,
1505 experimental=True,
1509 experimental=True,
1506 )
1510 )
1507
1511
1508 # Moving this on by default means we are confident about the scaling of phases.
1512 # Moving this on by default means we are confident about the scaling of phases.
1509 # This is not garanteed to be the case at the time this message is written.
1513 # This is not garanteed to be the case at the time this message is written.
1510 coreconfigitem(
1514 coreconfigitem(
1511 b'format',
1515 b'format',
1512 b'use-internal-phase',
1516 b'use-internal-phase',
1513 default=False,
1517 default=False,
1514 experimental=True,
1518 experimental=True,
1515 )
1519 )
1516 # The interaction between the archived phase and obsolescence markers needs to
1520 # The interaction between the archived phase and obsolescence markers needs to
1517 # be sorted out before wider usage of this are to be considered.
1521 # be sorted out before wider usage of this are to be considered.
1518 #
1522 #
1519 # At the time this message is written, behavior when archiving obsolete
1523 # At the time this message is written, behavior when archiving obsolete
1520 # changeset differ significantly from stripping. As part of stripping, we also
1524 # changeset differ significantly from stripping. As part of stripping, we also
1521 # remove the obsolescence marker associated to the stripped changesets,
1525 # remove the obsolescence marker associated to the stripped changesets,
1522 # revealing the precedecessors changesets when applicable. When archiving, we
1526 # revealing the precedecessors changesets when applicable. When archiving, we
1523 # don't touch the obsolescence markers, keeping everything hidden. This can
1527 # don't touch the obsolescence markers, keeping everything hidden. This can
1524 # result in quite confusing situation for people combining exchanging draft
1528 # result in quite confusing situation for people combining exchanging draft
1525 # with the archived phases. As some markers needed by others may be skipped
1529 # with the archived phases. As some markers needed by others may be skipped
1526 # during exchange.
1530 # during exchange.
1527 coreconfigitem(
1531 coreconfigitem(
1528 b'format',
1532 b'format',
1529 b'exp-archived-phase',
1533 b'exp-archived-phase',
1530 default=False,
1534 default=False,
1531 experimental=True,
1535 experimental=True,
1532 )
1536 )
1533 coreconfigitem(
1537 coreconfigitem(
1534 b'shelve',
1538 b'shelve',
1535 b'store',
1539 b'store',
1536 default=b'internal',
1540 default=b'internal',
1537 experimental=True,
1541 experimental=True,
1538 )
1542 )
1539 coreconfigitem(
1543 coreconfigitem(
1540 b'fsmonitor',
1544 b'fsmonitor',
1541 b'warn_when_unused',
1545 b'warn_when_unused',
1542 default=True,
1546 default=True,
1543 )
1547 )
1544 coreconfigitem(
1548 coreconfigitem(
1545 b'fsmonitor',
1549 b'fsmonitor',
1546 b'warn_update_file_count',
1550 b'warn_update_file_count',
1547 default=50000,
1551 default=50000,
1548 )
1552 )
1549 coreconfigitem(
1553 coreconfigitem(
1550 b'fsmonitor',
1554 b'fsmonitor',
1551 b'warn_update_file_count_rust',
1555 b'warn_update_file_count_rust',
1552 default=400000,
1556 default=400000,
1553 )
1557 )
1554 coreconfigitem(
1558 coreconfigitem(
1555 b'help',
1559 b'help',
1556 br'hidden-command\..*',
1560 br'hidden-command\..*',
1557 default=False,
1561 default=False,
1558 generic=True,
1562 generic=True,
1559 )
1563 )
1560 coreconfigitem(
1564 coreconfigitem(
1561 b'help',
1565 b'help',
1562 br'hidden-topic\..*',
1566 br'hidden-topic\..*',
1563 default=False,
1567 default=False,
1564 generic=True,
1568 generic=True,
1565 )
1569 )
1566 coreconfigitem(
1570 coreconfigitem(
1567 b'hooks',
1571 b'hooks',
1568 b'[^:]*',
1572 b'[^:]*',
1569 default=dynamicdefault,
1573 default=dynamicdefault,
1570 generic=True,
1574 generic=True,
1571 )
1575 )
1572 coreconfigitem(
1576 coreconfigitem(
1573 b'hooks',
1577 b'hooks',
1574 b'.*:run-with-plain',
1578 b'.*:run-with-plain',
1575 default=True,
1579 default=True,
1576 generic=True,
1580 generic=True,
1577 )
1581 )
1578 coreconfigitem(
1582 coreconfigitem(
1579 b'hgweb-paths',
1583 b'hgweb-paths',
1580 b'.*',
1584 b'.*',
1581 default=list,
1585 default=list,
1582 generic=True,
1586 generic=True,
1583 )
1587 )
1584 coreconfigitem(
1588 coreconfigitem(
1585 b'hostfingerprints',
1589 b'hostfingerprints',
1586 b'.*',
1590 b'.*',
1587 default=list,
1591 default=list,
1588 generic=True,
1592 generic=True,
1589 )
1593 )
1590 coreconfigitem(
1594 coreconfigitem(
1591 b'hostsecurity',
1595 b'hostsecurity',
1592 b'ciphers',
1596 b'ciphers',
1593 default=None,
1597 default=None,
1594 )
1598 )
1595 coreconfigitem(
1599 coreconfigitem(
1596 b'hostsecurity',
1600 b'hostsecurity',
1597 b'minimumprotocol',
1601 b'minimumprotocol',
1598 default=dynamicdefault,
1602 default=dynamicdefault,
1599 )
1603 )
1600 coreconfigitem(
1604 coreconfigitem(
1601 b'hostsecurity',
1605 b'hostsecurity',
1602 b'.*:minimumprotocol$',
1606 b'.*:minimumprotocol$',
1603 default=dynamicdefault,
1607 default=dynamicdefault,
1604 generic=True,
1608 generic=True,
1605 )
1609 )
1606 coreconfigitem(
1610 coreconfigitem(
1607 b'hostsecurity',
1611 b'hostsecurity',
1608 b'.*:ciphers$',
1612 b'.*:ciphers$',
1609 default=dynamicdefault,
1613 default=dynamicdefault,
1610 generic=True,
1614 generic=True,
1611 )
1615 )
1612 coreconfigitem(
1616 coreconfigitem(
1613 b'hostsecurity',
1617 b'hostsecurity',
1614 b'.*:fingerprints$',
1618 b'.*:fingerprints$',
1615 default=list,
1619 default=list,
1616 generic=True,
1620 generic=True,
1617 )
1621 )
1618 coreconfigitem(
1622 coreconfigitem(
1619 b'hostsecurity',
1623 b'hostsecurity',
1620 b'.*:verifycertsfile$',
1624 b'.*:verifycertsfile$',
1621 default=None,
1625 default=None,
1622 generic=True,
1626 generic=True,
1623 )
1627 )
1624
1628
1625 coreconfigitem(
1629 coreconfigitem(
1626 b'http_proxy',
1630 b'http_proxy',
1627 b'always',
1631 b'always',
1628 default=False,
1632 default=False,
1629 )
1633 )
1630 coreconfigitem(
1634 coreconfigitem(
1631 b'http_proxy',
1635 b'http_proxy',
1632 b'host',
1636 b'host',
1633 default=None,
1637 default=None,
1634 )
1638 )
1635 coreconfigitem(
1639 coreconfigitem(
1636 b'http_proxy',
1640 b'http_proxy',
1637 b'no',
1641 b'no',
1638 default=list,
1642 default=list,
1639 )
1643 )
1640 coreconfigitem(
1644 coreconfigitem(
1641 b'http_proxy',
1645 b'http_proxy',
1642 b'passwd',
1646 b'passwd',
1643 default=None,
1647 default=None,
1644 )
1648 )
1645 coreconfigitem(
1649 coreconfigitem(
1646 b'http_proxy',
1650 b'http_proxy',
1647 b'user',
1651 b'user',
1648 default=None,
1652 default=None,
1649 )
1653 )
1650
1654
1651 coreconfigitem(
1655 coreconfigitem(
1652 b'http',
1656 b'http',
1653 b'timeout',
1657 b'timeout',
1654 default=None,
1658 default=None,
1655 )
1659 )
1656
1660
1657 coreconfigitem(
1661 coreconfigitem(
1658 b'logtoprocess',
1662 b'logtoprocess',
1659 b'commandexception',
1663 b'commandexception',
1660 default=None,
1664 default=None,
1661 )
1665 )
1662 coreconfigitem(
1666 coreconfigitem(
1663 b'logtoprocess',
1667 b'logtoprocess',
1664 b'commandfinish',
1668 b'commandfinish',
1665 default=None,
1669 default=None,
1666 )
1670 )
1667 coreconfigitem(
1671 coreconfigitem(
1668 b'logtoprocess',
1672 b'logtoprocess',
1669 b'command',
1673 b'command',
1670 default=None,
1674 default=None,
1671 )
1675 )
1672 coreconfigitem(
1676 coreconfigitem(
1673 b'logtoprocess',
1677 b'logtoprocess',
1674 b'develwarn',
1678 b'develwarn',
1675 default=None,
1679 default=None,
1676 )
1680 )
1677 coreconfigitem(
1681 coreconfigitem(
1678 b'logtoprocess',
1682 b'logtoprocess',
1679 b'uiblocked',
1683 b'uiblocked',
1680 default=None,
1684 default=None,
1681 )
1685 )
1682 coreconfigitem(
1686 coreconfigitem(
1683 b'merge',
1687 b'merge',
1684 b'checkunknown',
1688 b'checkunknown',
1685 default=b'abort',
1689 default=b'abort',
1686 )
1690 )
1687 coreconfigitem(
1691 coreconfigitem(
1688 b'merge',
1692 b'merge',
1689 b'checkignored',
1693 b'checkignored',
1690 default=b'abort',
1694 default=b'abort',
1691 )
1695 )
1692 coreconfigitem(
1696 coreconfigitem(
1693 b'experimental',
1697 b'experimental',
1694 b'merge.checkpathconflicts',
1698 b'merge.checkpathconflicts',
1695 default=False,
1699 default=False,
1696 )
1700 )
1697 coreconfigitem(
1701 coreconfigitem(
1698 b'merge',
1702 b'merge',
1699 b'followcopies',
1703 b'followcopies',
1700 default=True,
1704 default=True,
1701 )
1705 )
1702 coreconfigitem(
1706 coreconfigitem(
1703 b'merge',
1707 b'merge',
1704 b'on-failure',
1708 b'on-failure',
1705 default=b'continue',
1709 default=b'continue',
1706 )
1710 )
1707 coreconfigitem(
1711 coreconfigitem(
1708 b'merge',
1712 b'merge',
1709 b'preferancestor',
1713 b'preferancestor',
1710 default=lambda: [b'*'],
1714 default=lambda: [b'*'],
1711 experimental=True,
1715 experimental=True,
1712 )
1716 )
1713 coreconfigitem(
1717 coreconfigitem(
1714 b'merge',
1718 b'merge',
1715 b'strict-capability-check',
1719 b'strict-capability-check',
1716 default=False,
1720 default=False,
1717 )
1721 )
1718 coreconfigitem(
1722 coreconfigitem(
1719 b'merge',
1723 b'merge',
1720 b'disable-partial-tools',
1724 b'disable-partial-tools',
1721 default=False,
1725 default=False,
1722 experimental=True,
1726 experimental=True,
1723 )
1727 )
1724 coreconfigitem(
1728 coreconfigitem(
1725 b'partial-merge-tools',
1729 b'partial-merge-tools',
1726 b'.*',
1730 b'.*',
1727 default=None,
1731 default=None,
1728 generic=True,
1732 generic=True,
1729 experimental=True,
1733 experimental=True,
1730 )
1734 )
1731 coreconfigitem(
1735 coreconfigitem(
1732 b'partial-merge-tools',
1736 b'partial-merge-tools',
1733 br'.*\.patterns',
1737 br'.*\.patterns',
1734 default=dynamicdefault,
1738 default=dynamicdefault,
1735 generic=True,
1739 generic=True,
1736 priority=-1,
1740 priority=-1,
1737 experimental=True,
1741 experimental=True,
1738 )
1742 )
1739 coreconfigitem(
1743 coreconfigitem(
1740 b'partial-merge-tools',
1744 b'partial-merge-tools',
1741 br'.*\.executable$',
1745 br'.*\.executable$',
1742 default=dynamicdefault,
1746 default=dynamicdefault,
1743 generic=True,
1747 generic=True,
1744 priority=-1,
1748 priority=-1,
1745 experimental=True,
1749 experimental=True,
1746 )
1750 )
1747 coreconfigitem(
1751 coreconfigitem(
1748 b'partial-merge-tools',
1752 b'partial-merge-tools',
1749 br'.*\.order',
1753 br'.*\.order',
1750 default=0,
1754 default=0,
1751 generic=True,
1755 generic=True,
1752 priority=-1,
1756 priority=-1,
1753 experimental=True,
1757 experimental=True,
1754 )
1758 )
1755 coreconfigitem(
1759 coreconfigitem(
1756 b'partial-merge-tools',
1760 b'partial-merge-tools',
1757 br'.*\.args',
1761 br'.*\.args',
1758 default=b"$local $base $other",
1762 default=b"$local $base $other",
1759 generic=True,
1763 generic=True,
1760 priority=-1,
1764 priority=-1,
1761 experimental=True,
1765 experimental=True,
1762 )
1766 )
1763 coreconfigitem(
1767 coreconfigitem(
1764 b'partial-merge-tools',
1768 b'partial-merge-tools',
1765 br'.*\.disable',
1769 br'.*\.disable',
1766 default=False,
1770 default=False,
1767 generic=True,
1771 generic=True,
1768 priority=-1,
1772 priority=-1,
1769 experimental=True,
1773 experimental=True,
1770 )
1774 )
1771 coreconfigitem(
1775 coreconfigitem(
1772 b'merge-tools',
1776 b'merge-tools',
1773 b'.*',
1777 b'.*',
1774 default=None,
1778 default=None,
1775 generic=True,
1779 generic=True,
1776 )
1780 )
1777 coreconfigitem(
1781 coreconfigitem(
1778 b'merge-tools',
1782 b'merge-tools',
1779 br'.*\.args$',
1783 br'.*\.args$',
1780 default=b"$local $base $other",
1784 default=b"$local $base $other",
1781 generic=True,
1785 generic=True,
1782 priority=-1,
1786 priority=-1,
1783 )
1787 )
1784 coreconfigitem(
1788 coreconfigitem(
1785 b'merge-tools',
1789 b'merge-tools',
1786 br'.*\.binary$',
1790 br'.*\.binary$',
1787 default=False,
1791 default=False,
1788 generic=True,
1792 generic=True,
1789 priority=-1,
1793 priority=-1,
1790 )
1794 )
1791 coreconfigitem(
1795 coreconfigitem(
1792 b'merge-tools',
1796 b'merge-tools',
1793 br'.*\.check$',
1797 br'.*\.check$',
1794 default=list,
1798 default=list,
1795 generic=True,
1799 generic=True,
1796 priority=-1,
1800 priority=-1,
1797 )
1801 )
1798 coreconfigitem(
1802 coreconfigitem(
1799 b'merge-tools',
1803 b'merge-tools',
1800 br'.*\.checkchanged$',
1804 br'.*\.checkchanged$',
1801 default=False,
1805 default=False,
1802 generic=True,
1806 generic=True,
1803 priority=-1,
1807 priority=-1,
1804 )
1808 )
1805 coreconfigitem(
1809 coreconfigitem(
1806 b'merge-tools',
1810 b'merge-tools',
1807 br'.*\.executable$',
1811 br'.*\.executable$',
1808 default=dynamicdefault,
1812 default=dynamicdefault,
1809 generic=True,
1813 generic=True,
1810 priority=-1,
1814 priority=-1,
1811 )
1815 )
1812 coreconfigitem(
1816 coreconfigitem(
1813 b'merge-tools',
1817 b'merge-tools',
1814 br'.*\.fixeol$',
1818 br'.*\.fixeol$',
1815 default=False,
1819 default=False,
1816 generic=True,
1820 generic=True,
1817 priority=-1,
1821 priority=-1,
1818 )
1822 )
1819 coreconfigitem(
1823 coreconfigitem(
1820 b'merge-tools',
1824 b'merge-tools',
1821 br'.*\.gui$',
1825 br'.*\.gui$',
1822 default=False,
1826 default=False,
1823 generic=True,
1827 generic=True,
1824 priority=-1,
1828 priority=-1,
1825 )
1829 )
1826 coreconfigitem(
1830 coreconfigitem(
1827 b'merge-tools',
1831 b'merge-tools',
1828 br'.*\.mergemarkers$',
1832 br'.*\.mergemarkers$',
1829 default=b'basic',
1833 default=b'basic',
1830 generic=True,
1834 generic=True,
1831 priority=-1,
1835 priority=-1,
1832 )
1836 )
1833 coreconfigitem(
1837 coreconfigitem(
1834 b'merge-tools',
1838 b'merge-tools',
1835 br'.*\.mergemarkertemplate$',
1839 br'.*\.mergemarkertemplate$',
1836 default=dynamicdefault, # take from command-templates.mergemarker
1840 default=dynamicdefault, # take from command-templates.mergemarker
1837 generic=True,
1841 generic=True,
1838 priority=-1,
1842 priority=-1,
1839 )
1843 )
1840 coreconfigitem(
1844 coreconfigitem(
1841 b'merge-tools',
1845 b'merge-tools',
1842 br'.*\.priority$',
1846 br'.*\.priority$',
1843 default=0,
1847 default=0,
1844 generic=True,
1848 generic=True,
1845 priority=-1,
1849 priority=-1,
1846 )
1850 )
1847 coreconfigitem(
1851 coreconfigitem(
1848 b'merge-tools',
1852 b'merge-tools',
1849 br'.*\.premerge$',
1853 br'.*\.premerge$',
1850 default=dynamicdefault,
1854 default=dynamicdefault,
1851 generic=True,
1855 generic=True,
1852 priority=-1,
1856 priority=-1,
1853 )
1857 )
1854 coreconfigitem(
1858 coreconfigitem(
1855 b'merge-tools',
1859 b'merge-tools',
1856 br'.*\.regappend$',
1860 br'.*\.regappend$',
1857 default=b"",
1861 default=b"",
1858 generic=True,
1862 generic=True,
1859 priority=-1,
1863 priority=-1,
1860 )
1864 )
1861 coreconfigitem(
1865 coreconfigitem(
1862 b'merge-tools',
1866 b'merge-tools',
1863 br'.*\.symlink$',
1867 br'.*\.symlink$',
1864 default=False,
1868 default=False,
1865 generic=True,
1869 generic=True,
1866 priority=-1,
1870 priority=-1,
1867 )
1871 )
1868 coreconfigitem(
1872 coreconfigitem(
1869 b'pager',
1873 b'pager',
1870 b'attend-.*',
1874 b'attend-.*',
1871 default=dynamicdefault,
1875 default=dynamicdefault,
1872 generic=True,
1876 generic=True,
1873 )
1877 )
1874 coreconfigitem(
1878 coreconfigitem(
1875 b'pager',
1879 b'pager',
1876 b'ignore',
1880 b'ignore',
1877 default=list,
1881 default=list,
1878 )
1882 )
1879 coreconfigitem(
1883 coreconfigitem(
1880 b'pager',
1884 b'pager',
1881 b'pager',
1885 b'pager',
1882 default=dynamicdefault,
1886 default=dynamicdefault,
1883 )
1887 )
1884 coreconfigitem(
1888 coreconfigitem(
1885 b'patch',
1889 b'patch',
1886 b'eol',
1890 b'eol',
1887 default=b'strict',
1891 default=b'strict',
1888 )
1892 )
1889 coreconfigitem(
1893 coreconfigitem(
1890 b'patch',
1894 b'patch',
1891 b'fuzz',
1895 b'fuzz',
1892 default=2,
1896 default=2,
1893 )
1897 )
1894 coreconfigitem(
1898 coreconfigitem(
1895 b'paths',
1899 b'paths',
1896 b'default',
1900 b'default',
1897 default=None,
1901 default=None,
1898 )
1902 )
1899 coreconfigitem(
1903 coreconfigitem(
1900 b'paths',
1904 b'paths',
1901 b'default-push',
1905 b'default-push',
1902 default=None,
1906 default=None,
1903 )
1907 )
1904 coreconfigitem(
1908 coreconfigitem(
1905 b'paths',
1909 b'paths',
1906 b'[^:]*',
1910 b'[^:]*',
1907 default=None,
1911 default=None,
1908 generic=True,
1912 generic=True,
1909 )
1913 )
1910 coreconfigitem(
1914 coreconfigitem(
1911 b'paths',
1915 b'paths',
1912 b'.*:bookmarks.mode',
1916 b'.*:bookmarks.mode',
1913 default='default',
1917 default='default',
1914 generic=True,
1918 generic=True,
1915 )
1919 )
1916 coreconfigitem(
1920 coreconfigitem(
1917 b'paths',
1921 b'paths',
1918 b'.*:multi-urls',
1922 b'.*:multi-urls',
1919 default=False,
1923 default=False,
1920 generic=True,
1924 generic=True,
1921 )
1925 )
1922 coreconfigitem(
1926 coreconfigitem(
1923 b'paths',
1927 b'paths',
1924 b'.*:pushrev',
1928 b'.*:pushrev',
1925 default=None,
1929 default=None,
1926 generic=True,
1930 generic=True,
1927 )
1931 )
1928 coreconfigitem(
1932 coreconfigitem(
1929 b'paths',
1933 b'paths',
1930 b'.*:pushurl',
1934 b'.*:pushurl',
1931 default=None,
1935 default=None,
1932 generic=True,
1936 generic=True,
1933 )
1937 )
1934 coreconfigitem(
1938 coreconfigitem(
1935 b'paths',
1939 b'paths',
1936 b'.*:pulled-delta-reuse-policy',
1940 b'.*:pulled-delta-reuse-policy',
1937 default=None,
1941 default=None,
1938 generic=True,
1942 generic=True,
1939 )
1943 )
1940 coreconfigitem(
1944 coreconfigitem(
1941 b'phases',
1945 b'phases',
1942 b'checksubrepos',
1946 b'checksubrepos',
1943 default=b'follow',
1947 default=b'follow',
1944 )
1948 )
1945 coreconfigitem(
1949 coreconfigitem(
1946 b'phases',
1950 b'phases',
1947 b'new-commit',
1951 b'new-commit',
1948 default=b'draft',
1952 default=b'draft',
1949 )
1953 )
1950 coreconfigitem(
1954 coreconfigitem(
1951 b'phases',
1955 b'phases',
1952 b'publish',
1956 b'publish',
1953 default=True,
1957 default=True,
1954 )
1958 )
1955 coreconfigitem(
1959 coreconfigitem(
1956 b'profiling',
1960 b'profiling',
1957 b'enabled',
1961 b'enabled',
1958 default=False,
1962 default=False,
1959 )
1963 )
1960 coreconfigitem(
1964 coreconfigitem(
1961 b'profiling',
1965 b'profiling',
1962 b'format',
1966 b'format',
1963 default=b'text',
1967 default=b'text',
1964 )
1968 )
1965 coreconfigitem(
1969 coreconfigitem(
1966 b'profiling',
1970 b'profiling',
1967 b'freq',
1971 b'freq',
1968 default=1000,
1972 default=1000,
1969 )
1973 )
1970 coreconfigitem(
1974 coreconfigitem(
1971 b'profiling',
1975 b'profiling',
1972 b'limit',
1976 b'limit',
1973 default=30,
1977 default=30,
1974 )
1978 )
1975 coreconfigitem(
1979 coreconfigitem(
1976 b'profiling',
1980 b'profiling',
1977 b'nested',
1981 b'nested',
1978 default=0,
1982 default=0,
1979 )
1983 )
1980 coreconfigitem(
1984 coreconfigitem(
1981 b'profiling',
1985 b'profiling',
1982 b'output',
1986 b'output',
1983 default=None,
1987 default=None,
1984 )
1988 )
1985 coreconfigitem(
1989 coreconfigitem(
1986 b'profiling',
1990 b'profiling',
1987 b'showmax',
1991 b'showmax',
1988 default=0.999,
1992 default=0.999,
1989 )
1993 )
1990 coreconfigitem(
1994 coreconfigitem(
1991 b'profiling',
1995 b'profiling',
1992 b'showmin',
1996 b'showmin',
1993 default=dynamicdefault,
1997 default=dynamicdefault,
1994 )
1998 )
1995 coreconfigitem(
1999 coreconfigitem(
1996 b'profiling',
2000 b'profiling',
1997 b'showtime',
2001 b'showtime',
1998 default=True,
2002 default=True,
1999 )
2003 )
2000 coreconfigitem(
2004 coreconfigitem(
2001 b'profiling',
2005 b'profiling',
2002 b'sort',
2006 b'sort',
2003 default=b'inlinetime',
2007 default=b'inlinetime',
2004 )
2008 )
2005 coreconfigitem(
2009 coreconfigitem(
2006 b'profiling',
2010 b'profiling',
2007 b'statformat',
2011 b'statformat',
2008 default=b'hotpath',
2012 default=b'hotpath',
2009 )
2013 )
2010 coreconfigitem(
2014 coreconfigitem(
2011 b'profiling',
2015 b'profiling',
2012 b'time-track',
2016 b'time-track',
2013 default=dynamicdefault,
2017 default=dynamicdefault,
2014 )
2018 )
2015 coreconfigitem(
2019 coreconfigitem(
2016 b'profiling',
2020 b'profiling',
2017 b'type',
2021 b'type',
2018 default=b'stat',
2022 default=b'stat',
2019 )
2023 )
2020 coreconfigitem(
2024 coreconfigitem(
2021 b'progress',
2025 b'progress',
2022 b'assume-tty',
2026 b'assume-tty',
2023 default=False,
2027 default=False,
2024 )
2028 )
2025 coreconfigitem(
2029 coreconfigitem(
2026 b'progress',
2030 b'progress',
2027 b'changedelay',
2031 b'changedelay',
2028 default=1,
2032 default=1,
2029 )
2033 )
2030 coreconfigitem(
2034 coreconfigitem(
2031 b'progress',
2035 b'progress',
2032 b'clear-complete',
2036 b'clear-complete',
2033 default=True,
2037 default=True,
2034 )
2038 )
2035 coreconfigitem(
2039 coreconfigitem(
2036 b'progress',
2040 b'progress',
2037 b'debug',
2041 b'debug',
2038 default=False,
2042 default=False,
2039 )
2043 )
2040 coreconfigitem(
2044 coreconfigitem(
2041 b'progress',
2045 b'progress',
2042 b'delay',
2046 b'delay',
2043 default=3,
2047 default=3,
2044 )
2048 )
2045 coreconfigitem(
2049 coreconfigitem(
2046 b'progress',
2050 b'progress',
2047 b'disable',
2051 b'disable',
2048 default=False,
2052 default=False,
2049 )
2053 )
2050 coreconfigitem(
2054 coreconfigitem(
2051 b'progress',
2055 b'progress',
2052 b'estimateinterval',
2056 b'estimateinterval',
2053 default=60.0,
2057 default=60.0,
2054 )
2058 )
2055 coreconfigitem(
2059 coreconfigitem(
2056 b'progress',
2060 b'progress',
2057 b'format',
2061 b'format',
2058 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
2062 default=lambda: [b'topic', b'bar', b'number', b'estimate'],
2059 )
2063 )
2060 coreconfigitem(
2064 coreconfigitem(
2061 b'progress',
2065 b'progress',
2062 b'refresh',
2066 b'refresh',
2063 default=0.1,
2067 default=0.1,
2064 )
2068 )
2065 coreconfigitem(
2069 coreconfigitem(
2066 b'progress',
2070 b'progress',
2067 b'width',
2071 b'width',
2068 default=dynamicdefault,
2072 default=dynamicdefault,
2069 )
2073 )
2070 coreconfigitem(
2074 coreconfigitem(
2071 b'pull',
2075 b'pull',
2072 b'confirm',
2076 b'confirm',
2073 default=False,
2077 default=False,
2074 )
2078 )
2075 coreconfigitem(
2079 coreconfigitem(
2076 b'push',
2080 b'push',
2077 b'pushvars.server',
2081 b'pushvars.server',
2078 default=False,
2082 default=False,
2079 )
2083 )
2080 coreconfigitem(
2084 coreconfigitem(
2081 b'rewrite',
2085 b'rewrite',
2082 b'backup-bundle',
2086 b'backup-bundle',
2083 default=True,
2087 default=True,
2084 alias=[(b'ui', b'history-editing-backup')],
2088 alias=[(b'ui', b'history-editing-backup')],
2085 )
2089 )
2086 coreconfigitem(
2090 coreconfigitem(
2087 b'rewrite',
2091 b'rewrite',
2088 b'update-timestamp',
2092 b'update-timestamp',
2089 default=False,
2093 default=False,
2090 )
2094 )
2091 coreconfigitem(
2095 coreconfigitem(
2092 b'rewrite',
2096 b'rewrite',
2093 b'empty-successor',
2097 b'empty-successor',
2094 default=b'skip',
2098 default=b'skip',
2095 experimental=True,
2099 experimental=True,
2096 )
2100 )
2097 # experimental as long as format.use-dirstate-v2 is.
2101 # experimental as long as format.use-dirstate-v2 is.
2098 coreconfigitem(
2102 coreconfigitem(
2099 b'storage',
2103 b'storage',
2100 b'dirstate-v2.slow-path',
2104 b'dirstate-v2.slow-path',
2101 default=b"abort",
2105 default=b"abort",
2102 experimental=True,
2106 experimental=True,
2103 )
2107 )
2104 coreconfigitem(
2108 coreconfigitem(
2105 b'storage',
2109 b'storage',
2106 b'new-repo-backend',
2110 b'new-repo-backend',
2107 default=b'revlogv1',
2111 default=b'revlogv1',
2108 experimental=True,
2112 experimental=True,
2109 )
2113 )
2110 coreconfigitem(
2114 coreconfigitem(
2111 b'storage',
2115 b'storage',
2112 b'revlog.optimize-delta-parent-choice',
2116 b'revlog.optimize-delta-parent-choice',
2113 default=True,
2117 default=True,
2114 alias=[(b'format', b'aggressivemergedeltas')],
2118 alias=[(b'format', b'aggressivemergedeltas')],
2115 )
2119 )
2116 coreconfigitem(
2120 coreconfigitem(
2117 b'storage',
2121 b'storage',
2118 b'revlog.delta-parent-search.candidate-group-chunk-size',
2122 b'revlog.delta-parent-search.candidate-group-chunk-size',
2119 default=20,
2123 default=20,
2120 )
2124 )
2121 coreconfigitem(
2125 coreconfigitem(
2122 b'storage',
2126 b'storage',
2123 b'revlog.issue6528.fix-incoming',
2127 b'revlog.issue6528.fix-incoming',
2124 default=True,
2128 default=True,
2125 )
2129 )
2126 # experimental as long as rust is experimental (or a C version is implemented)
2130 # experimental as long as rust is experimental (or a C version is implemented)
2127 coreconfigitem(
2131 coreconfigitem(
2128 b'storage',
2132 b'storage',
2129 b'revlog.persistent-nodemap.mmap',
2133 b'revlog.persistent-nodemap.mmap',
2130 default=True,
2134 default=True,
2131 )
2135 )
2132 # experimental as long as format.use-persistent-nodemap is.
2136 # experimental as long as format.use-persistent-nodemap is.
2133 coreconfigitem(
2137 coreconfigitem(
2134 b'storage',
2138 b'storage',
2135 b'revlog.persistent-nodemap.slow-path',
2139 b'revlog.persistent-nodemap.slow-path',
2136 default=b"abort",
2140 default=b"abort",
2137 )
2141 )
2138
2142
2139 coreconfigitem(
2143 coreconfigitem(
2140 b'storage',
2144 b'storage',
2141 b'revlog.reuse-external-delta',
2145 b'revlog.reuse-external-delta',
2142 default=True,
2146 default=True,
2143 )
2147 )
2144 # This option is True unless `format.generaldelta` is set.
2148 # This option is True unless `format.generaldelta` is set.
2145 coreconfigitem(
2149 coreconfigitem(
2146 b'storage',
2150 b'storage',
2147 b'revlog.reuse-external-delta-parent',
2151 b'revlog.reuse-external-delta-parent',
2148 default=None,
2152 default=None,
2149 )
2153 )
2150 coreconfigitem(
2154 coreconfigitem(
2151 b'storage',
2155 b'storage',
2152 b'revlog.zlib.level',
2156 b'revlog.zlib.level',
2153 default=None,
2157 default=None,
2154 )
2158 )
2155 coreconfigitem(
2159 coreconfigitem(
2156 b'storage',
2160 b'storage',
2157 b'revlog.zstd.level',
2161 b'revlog.zstd.level',
2158 default=None,
2162 default=None,
2159 )
2163 )
2160 coreconfigitem(
2164 coreconfigitem(
2161 b'server',
2165 b'server',
2162 b'bookmarks-pushkey-compat',
2166 b'bookmarks-pushkey-compat',
2163 default=True,
2167 default=True,
2164 )
2168 )
2165 coreconfigitem(
2169 coreconfigitem(
2166 b'server',
2170 b'server',
2167 b'bundle1',
2171 b'bundle1',
2168 default=True,
2172 default=True,
2169 )
2173 )
2170 coreconfigitem(
2174 coreconfigitem(
2171 b'server',
2175 b'server',
2172 b'bundle1gd',
2176 b'bundle1gd',
2173 default=None,
2177 default=None,
2174 )
2178 )
2175 coreconfigitem(
2179 coreconfigitem(
2176 b'server',
2180 b'server',
2177 b'bundle1.pull',
2181 b'bundle1.pull',
2178 default=None,
2182 default=None,
2179 )
2183 )
2180 coreconfigitem(
2184 coreconfigitem(
2181 b'server',
2185 b'server',
2182 b'bundle1gd.pull',
2186 b'bundle1gd.pull',
2183 default=None,
2187 default=None,
2184 )
2188 )
2185 coreconfigitem(
2189 coreconfigitem(
2186 b'server',
2190 b'server',
2187 b'bundle1.push',
2191 b'bundle1.push',
2188 default=None,
2192 default=None,
2189 )
2193 )
2190 coreconfigitem(
2194 coreconfigitem(
2191 b'server',
2195 b'server',
2192 b'bundle1gd.push',
2196 b'bundle1gd.push',
2193 default=None,
2197 default=None,
2194 )
2198 )
2195 coreconfigitem(
2199 coreconfigitem(
2196 b'server',
2200 b'server',
2197 b'bundle2.stream',
2201 b'bundle2.stream',
2198 default=True,
2202 default=True,
2199 alias=[(b'experimental', b'bundle2.stream')],
2203 alias=[(b'experimental', b'bundle2.stream')],
2200 )
2204 )
2201 coreconfigitem(
2205 coreconfigitem(
2202 b'server',
2206 b'server',
2203 b'compressionengines',
2207 b'compressionengines',
2204 default=list,
2208 default=list,
2205 )
2209 )
2206 coreconfigitem(
2210 coreconfigitem(
2207 b'server',
2211 b'server',
2208 b'concurrent-push-mode',
2212 b'concurrent-push-mode',
2209 default=b'check-related',
2213 default=b'check-related',
2210 )
2214 )
2211 coreconfigitem(
2215 coreconfigitem(
2212 b'server',
2216 b'server',
2213 b'disablefullbundle',
2217 b'disablefullbundle',
2214 default=False,
2218 default=False,
2215 )
2219 )
2216 coreconfigitem(
2220 coreconfigitem(
2217 b'server',
2221 b'server',
2218 b'maxhttpheaderlen',
2222 b'maxhttpheaderlen',
2219 default=1024,
2223 default=1024,
2220 )
2224 )
2221 coreconfigitem(
2225 coreconfigitem(
2222 b'server',
2226 b'server',
2223 b'pullbundle',
2227 b'pullbundle',
2224 default=True,
2228 default=True,
2225 )
2229 )
2226 coreconfigitem(
2230 coreconfigitem(
2227 b'server',
2231 b'server',
2228 b'preferuncompressed',
2232 b'preferuncompressed',
2229 default=False,
2233 default=False,
2230 )
2234 )
2231 coreconfigitem(
2235 coreconfigitem(
2232 b'server',
2236 b'server',
2233 b'streamunbundle',
2237 b'streamunbundle',
2234 default=False,
2238 default=False,
2235 )
2239 )
2236 coreconfigitem(
2240 coreconfigitem(
2237 b'server',
2241 b'server',
2238 b'uncompressed',
2242 b'uncompressed',
2239 default=True,
2243 default=True,
2240 )
2244 )
2241 coreconfigitem(
2245 coreconfigitem(
2242 b'server',
2246 b'server',
2243 b'uncompressedallowsecret',
2247 b'uncompressedallowsecret',
2244 default=False,
2248 default=False,
2245 )
2249 )
2246 coreconfigitem(
2250 coreconfigitem(
2247 b'server',
2251 b'server',
2248 b'view',
2252 b'view',
2249 default=b'served',
2253 default=b'served',
2250 )
2254 )
2251 coreconfigitem(
2255 coreconfigitem(
2252 b'server',
2256 b'server',
2253 b'validate',
2257 b'validate',
2254 default=False,
2258 default=False,
2255 )
2259 )
2256 coreconfigitem(
2260 coreconfigitem(
2257 b'server',
2261 b'server',
2258 b'zliblevel',
2262 b'zliblevel',
2259 default=-1,
2263 default=-1,
2260 )
2264 )
2261 coreconfigitem(
2265 coreconfigitem(
2262 b'server',
2266 b'server',
2263 b'zstdlevel',
2267 b'zstdlevel',
2264 default=3,
2268 default=3,
2265 )
2269 )
2266 coreconfigitem(
2270 coreconfigitem(
2267 b'share',
2271 b'share',
2268 b'pool',
2272 b'pool',
2269 default=None,
2273 default=None,
2270 )
2274 )
2271 coreconfigitem(
2275 coreconfigitem(
2272 b'share',
2276 b'share',
2273 b'poolnaming',
2277 b'poolnaming',
2274 default=b'identity',
2278 default=b'identity',
2275 )
2279 )
2276 coreconfigitem(
2280 coreconfigitem(
2277 b'share',
2281 b'share',
2278 b'safe-mismatch.source-not-safe',
2282 b'safe-mismatch.source-not-safe',
2279 default=b'abort',
2283 default=b'abort',
2280 )
2284 )
2281 coreconfigitem(
2285 coreconfigitem(
2282 b'share',
2286 b'share',
2283 b'safe-mismatch.source-safe',
2287 b'safe-mismatch.source-safe',
2284 default=b'abort',
2288 default=b'abort',
2285 )
2289 )
2286 coreconfigitem(
2290 coreconfigitem(
2287 b'share',
2291 b'share',
2288 b'safe-mismatch.source-not-safe.warn',
2292 b'safe-mismatch.source-not-safe.warn',
2289 default=True,
2293 default=True,
2290 )
2294 )
2291 coreconfigitem(
2295 coreconfigitem(
2292 b'share',
2296 b'share',
2293 b'safe-mismatch.source-safe.warn',
2297 b'safe-mismatch.source-safe.warn',
2294 default=True,
2298 default=True,
2295 )
2299 )
2296 coreconfigitem(
2300 coreconfigitem(
2297 b'share',
2301 b'share',
2298 b'safe-mismatch.source-not-safe:verbose-upgrade',
2302 b'safe-mismatch.source-not-safe:verbose-upgrade',
2299 default=True,
2303 default=True,
2300 )
2304 )
2301 coreconfigitem(
2305 coreconfigitem(
2302 b'share',
2306 b'share',
2303 b'safe-mismatch.source-safe:verbose-upgrade',
2307 b'safe-mismatch.source-safe:verbose-upgrade',
2304 default=True,
2308 default=True,
2305 )
2309 )
2306 coreconfigitem(
2310 coreconfigitem(
2307 b'shelve',
2311 b'shelve',
2308 b'maxbackups',
2312 b'maxbackups',
2309 default=10,
2313 default=10,
2310 )
2314 )
2311 coreconfigitem(
2315 coreconfigitem(
2312 b'smtp',
2316 b'smtp',
2313 b'host',
2317 b'host',
2314 default=None,
2318 default=None,
2315 )
2319 )
2316 coreconfigitem(
2320 coreconfigitem(
2317 b'smtp',
2321 b'smtp',
2318 b'local_hostname',
2322 b'local_hostname',
2319 default=None,
2323 default=None,
2320 )
2324 )
2321 coreconfigitem(
2325 coreconfigitem(
2322 b'smtp',
2326 b'smtp',
2323 b'password',
2327 b'password',
2324 default=None,
2328 default=None,
2325 )
2329 )
2326 coreconfigitem(
2330 coreconfigitem(
2327 b'smtp',
2331 b'smtp',
2328 b'port',
2332 b'port',
2329 default=dynamicdefault,
2333 default=dynamicdefault,
2330 )
2334 )
2331 coreconfigitem(
2335 coreconfigitem(
2332 b'smtp',
2336 b'smtp',
2333 b'tls',
2337 b'tls',
2334 default=b'none',
2338 default=b'none',
2335 )
2339 )
2336 coreconfigitem(
2340 coreconfigitem(
2337 b'smtp',
2341 b'smtp',
2338 b'username',
2342 b'username',
2339 default=None,
2343 default=None,
2340 )
2344 )
2341 coreconfigitem(
2345 coreconfigitem(
2342 b'sparse',
2346 b'sparse',
2343 b'missingwarning',
2347 b'missingwarning',
2344 default=True,
2348 default=True,
2345 experimental=True,
2349 experimental=True,
2346 )
2350 )
2347 coreconfigitem(
2351 coreconfigitem(
2348 b'subrepos',
2352 b'subrepos',
2349 b'allowed',
2353 b'allowed',
2350 default=dynamicdefault, # to make backporting simpler
2354 default=dynamicdefault, # to make backporting simpler
2351 )
2355 )
2352 coreconfigitem(
2356 coreconfigitem(
2353 b'subrepos',
2357 b'subrepos',
2354 b'hg:allowed',
2358 b'hg:allowed',
2355 default=dynamicdefault,
2359 default=dynamicdefault,
2356 )
2360 )
2357 coreconfigitem(
2361 coreconfigitem(
2358 b'subrepos',
2362 b'subrepos',
2359 b'git:allowed',
2363 b'git:allowed',
2360 default=dynamicdefault,
2364 default=dynamicdefault,
2361 )
2365 )
2362 coreconfigitem(
2366 coreconfigitem(
2363 b'subrepos',
2367 b'subrepos',
2364 b'svn:allowed',
2368 b'svn:allowed',
2365 default=dynamicdefault,
2369 default=dynamicdefault,
2366 )
2370 )
2367 coreconfigitem(
2371 coreconfigitem(
2368 b'templates',
2372 b'templates',
2369 b'.*',
2373 b'.*',
2370 default=None,
2374 default=None,
2371 generic=True,
2375 generic=True,
2372 )
2376 )
2373 coreconfigitem(
2377 coreconfigitem(
2374 b'templateconfig',
2378 b'templateconfig',
2375 b'.*',
2379 b'.*',
2376 default=dynamicdefault,
2380 default=dynamicdefault,
2377 generic=True,
2381 generic=True,
2378 )
2382 )
2379 coreconfigitem(
2383 coreconfigitem(
2380 b'trusted',
2384 b'trusted',
2381 b'groups',
2385 b'groups',
2382 default=list,
2386 default=list,
2383 )
2387 )
2384 coreconfigitem(
2388 coreconfigitem(
2385 b'trusted',
2389 b'trusted',
2386 b'users',
2390 b'users',
2387 default=list,
2391 default=list,
2388 )
2392 )
2389 coreconfigitem(
2393 coreconfigitem(
2390 b'ui',
2394 b'ui',
2391 b'_usedassubrepo',
2395 b'_usedassubrepo',
2392 default=False,
2396 default=False,
2393 )
2397 )
2394 coreconfigitem(
2398 coreconfigitem(
2395 b'ui',
2399 b'ui',
2396 b'allowemptycommit',
2400 b'allowemptycommit',
2397 default=False,
2401 default=False,
2398 )
2402 )
2399 coreconfigitem(
2403 coreconfigitem(
2400 b'ui',
2404 b'ui',
2401 b'archivemeta',
2405 b'archivemeta',
2402 default=True,
2406 default=True,
2403 )
2407 )
2404 coreconfigitem(
2408 coreconfigitem(
2405 b'ui',
2409 b'ui',
2406 b'askusername',
2410 b'askusername',
2407 default=False,
2411 default=False,
2408 )
2412 )
2409 coreconfigitem(
2413 coreconfigitem(
2410 b'ui',
2414 b'ui',
2411 b'available-memory',
2415 b'available-memory',
2412 default=None,
2416 default=None,
2413 )
2417 )
2414
2418
2415 coreconfigitem(
2419 coreconfigitem(
2416 b'ui',
2420 b'ui',
2417 b'clonebundlefallback',
2421 b'clonebundlefallback',
2418 default=False,
2422 default=False,
2419 )
2423 )
2420 coreconfigitem(
2424 coreconfigitem(
2421 b'ui',
2425 b'ui',
2422 b'clonebundleprefers',
2426 b'clonebundleprefers',
2423 default=list,
2427 default=list,
2424 )
2428 )
2425 coreconfigitem(
2429 coreconfigitem(
2426 b'ui',
2430 b'ui',
2427 b'clonebundles',
2431 b'clonebundles',
2428 default=True,
2432 default=True,
2429 )
2433 )
2430 coreconfigitem(
2434 coreconfigitem(
2431 b'ui',
2435 b'ui',
2432 b'color',
2436 b'color',
2433 default=b'auto',
2437 default=b'auto',
2434 )
2438 )
2435 coreconfigitem(
2439 coreconfigitem(
2436 b'ui',
2440 b'ui',
2437 b'commitsubrepos',
2441 b'commitsubrepos',
2438 default=False,
2442 default=False,
2439 )
2443 )
2440 coreconfigitem(
2444 coreconfigitem(
2441 b'ui',
2445 b'ui',
2442 b'debug',
2446 b'debug',
2443 default=False,
2447 default=False,
2444 )
2448 )
2445 coreconfigitem(
2449 coreconfigitem(
2446 b'ui',
2450 b'ui',
2447 b'debugger',
2451 b'debugger',
2448 default=None,
2452 default=None,
2449 )
2453 )
2450 coreconfigitem(
2454 coreconfigitem(
2451 b'ui',
2455 b'ui',
2452 b'editor',
2456 b'editor',
2453 default=dynamicdefault,
2457 default=dynamicdefault,
2454 )
2458 )
2455 coreconfigitem(
2459 coreconfigitem(
2456 b'ui',
2460 b'ui',
2457 b'detailed-exit-code',
2461 b'detailed-exit-code',
2458 default=False,
2462 default=False,
2459 experimental=True,
2463 experimental=True,
2460 )
2464 )
2461 coreconfigitem(
2465 coreconfigitem(
2462 b'ui',
2466 b'ui',
2463 b'fallbackencoding',
2467 b'fallbackencoding',
2464 default=None,
2468 default=None,
2465 )
2469 )
2466 coreconfigitem(
2470 coreconfigitem(
2467 b'ui',
2471 b'ui',
2468 b'forcecwd',
2472 b'forcecwd',
2469 default=None,
2473 default=None,
2470 )
2474 )
2471 coreconfigitem(
2475 coreconfigitem(
2472 b'ui',
2476 b'ui',
2473 b'forcemerge',
2477 b'forcemerge',
2474 default=None,
2478 default=None,
2475 )
2479 )
2476 coreconfigitem(
2480 coreconfigitem(
2477 b'ui',
2481 b'ui',
2478 b'formatdebug',
2482 b'formatdebug',
2479 default=False,
2483 default=False,
2480 )
2484 )
2481 coreconfigitem(
2485 coreconfigitem(
2482 b'ui',
2486 b'ui',
2483 b'formatjson',
2487 b'formatjson',
2484 default=False,
2488 default=False,
2485 )
2489 )
2486 coreconfigitem(
2490 coreconfigitem(
2487 b'ui',
2491 b'ui',
2488 b'formatted',
2492 b'formatted',
2489 default=None,
2493 default=None,
2490 )
2494 )
2491 coreconfigitem(
2495 coreconfigitem(
2492 b'ui',
2496 b'ui',
2493 b'interactive',
2497 b'interactive',
2494 default=None,
2498 default=None,
2495 )
2499 )
2496 coreconfigitem(
2500 coreconfigitem(
2497 b'ui',
2501 b'ui',
2498 b'interface',
2502 b'interface',
2499 default=None,
2503 default=None,
2500 )
2504 )
2501 coreconfigitem(
2505 coreconfigitem(
2502 b'ui',
2506 b'ui',
2503 b'interface.chunkselector',
2507 b'interface.chunkselector',
2504 default=None,
2508 default=None,
2505 )
2509 )
2506 coreconfigitem(
2510 coreconfigitem(
2507 b'ui',
2511 b'ui',
2508 b'large-file-limit',
2512 b'large-file-limit',
2509 default=10 * (2 ** 20),
2513 default=10 * (2 ** 20),
2510 )
2514 )
2511 coreconfigitem(
2515 coreconfigitem(
2512 b'ui',
2516 b'ui',
2513 b'logblockedtimes',
2517 b'logblockedtimes',
2514 default=False,
2518 default=False,
2515 )
2519 )
2516 coreconfigitem(
2520 coreconfigitem(
2517 b'ui',
2521 b'ui',
2518 b'merge',
2522 b'merge',
2519 default=None,
2523 default=None,
2520 )
2524 )
2521 coreconfigitem(
2525 coreconfigitem(
2522 b'ui',
2526 b'ui',
2523 b'mergemarkers',
2527 b'mergemarkers',
2524 default=b'basic',
2528 default=b'basic',
2525 )
2529 )
2526 coreconfigitem(
2530 coreconfigitem(
2527 b'ui',
2531 b'ui',
2528 b'message-output',
2532 b'message-output',
2529 default=b'stdio',
2533 default=b'stdio',
2530 )
2534 )
2531 coreconfigitem(
2535 coreconfigitem(
2532 b'ui',
2536 b'ui',
2533 b'nontty',
2537 b'nontty',
2534 default=False,
2538 default=False,
2535 )
2539 )
2536 coreconfigitem(
2540 coreconfigitem(
2537 b'ui',
2541 b'ui',
2538 b'origbackuppath',
2542 b'origbackuppath',
2539 default=None,
2543 default=None,
2540 )
2544 )
2541 coreconfigitem(
2545 coreconfigitem(
2542 b'ui',
2546 b'ui',
2543 b'paginate',
2547 b'paginate',
2544 default=True,
2548 default=True,
2545 )
2549 )
2546 coreconfigitem(
2550 coreconfigitem(
2547 b'ui',
2551 b'ui',
2548 b'patch',
2552 b'patch',
2549 default=None,
2553 default=None,
2550 )
2554 )
2551 coreconfigitem(
2555 coreconfigitem(
2552 b'ui',
2556 b'ui',
2553 b'portablefilenames',
2557 b'portablefilenames',
2554 default=b'warn',
2558 default=b'warn',
2555 )
2559 )
2556 coreconfigitem(
2560 coreconfigitem(
2557 b'ui',
2561 b'ui',
2558 b'promptecho',
2562 b'promptecho',
2559 default=False,
2563 default=False,
2560 )
2564 )
2561 coreconfigitem(
2565 coreconfigitem(
2562 b'ui',
2566 b'ui',
2563 b'quiet',
2567 b'quiet',
2564 default=False,
2568 default=False,
2565 )
2569 )
2566 coreconfigitem(
2570 coreconfigitem(
2567 b'ui',
2571 b'ui',
2568 b'quietbookmarkmove',
2572 b'quietbookmarkmove',
2569 default=False,
2573 default=False,
2570 )
2574 )
2571 coreconfigitem(
2575 coreconfigitem(
2572 b'ui',
2576 b'ui',
2573 b'relative-paths',
2577 b'relative-paths',
2574 default=b'legacy',
2578 default=b'legacy',
2575 )
2579 )
2576 coreconfigitem(
2580 coreconfigitem(
2577 b'ui',
2581 b'ui',
2578 b'remotecmd',
2582 b'remotecmd',
2579 default=b'hg',
2583 default=b'hg',
2580 )
2584 )
2581 coreconfigitem(
2585 coreconfigitem(
2582 b'ui',
2586 b'ui',
2583 b'report_untrusted',
2587 b'report_untrusted',
2584 default=True,
2588 default=True,
2585 )
2589 )
2586 coreconfigitem(
2590 coreconfigitem(
2587 b'ui',
2591 b'ui',
2588 b'rollback',
2592 b'rollback',
2589 default=True,
2593 default=True,
2590 )
2594 )
2591 coreconfigitem(
2595 coreconfigitem(
2592 b'ui',
2596 b'ui',
2593 b'signal-safe-lock',
2597 b'signal-safe-lock',
2594 default=True,
2598 default=True,
2595 )
2599 )
2596 coreconfigitem(
2600 coreconfigitem(
2597 b'ui',
2601 b'ui',
2598 b'slash',
2602 b'slash',
2599 default=False,
2603 default=False,
2600 )
2604 )
2601 coreconfigitem(
2605 coreconfigitem(
2602 b'ui',
2606 b'ui',
2603 b'ssh',
2607 b'ssh',
2604 default=b'ssh',
2608 default=b'ssh',
2605 )
2609 )
2606 coreconfigitem(
2610 coreconfigitem(
2607 b'ui',
2611 b'ui',
2608 b'ssherrorhint',
2612 b'ssherrorhint',
2609 default=None,
2613 default=None,
2610 )
2614 )
2611 coreconfigitem(
2615 coreconfigitem(
2612 b'ui',
2616 b'ui',
2613 b'statuscopies',
2617 b'statuscopies',
2614 default=False,
2618 default=False,
2615 )
2619 )
2616 coreconfigitem(
2620 coreconfigitem(
2617 b'ui',
2621 b'ui',
2618 b'strict',
2622 b'strict',
2619 default=False,
2623 default=False,
2620 )
2624 )
2621 coreconfigitem(
2625 coreconfigitem(
2622 b'ui',
2626 b'ui',
2623 b'style',
2627 b'style',
2624 default=b'',
2628 default=b'',
2625 )
2629 )
2626 coreconfigitem(
2630 coreconfigitem(
2627 b'ui',
2631 b'ui',
2628 b'supportcontact',
2632 b'supportcontact',
2629 default=None,
2633 default=None,
2630 )
2634 )
2631 coreconfigitem(
2635 coreconfigitem(
2632 b'ui',
2636 b'ui',
2633 b'textwidth',
2637 b'textwidth',
2634 default=78,
2638 default=78,
2635 )
2639 )
2636 coreconfigitem(
2640 coreconfigitem(
2637 b'ui',
2641 b'ui',
2638 b'timeout',
2642 b'timeout',
2639 default=b'600',
2643 default=b'600',
2640 )
2644 )
2641 coreconfigitem(
2645 coreconfigitem(
2642 b'ui',
2646 b'ui',
2643 b'timeout.warn',
2647 b'timeout.warn',
2644 default=0,
2648 default=0,
2645 )
2649 )
2646 coreconfigitem(
2650 coreconfigitem(
2647 b'ui',
2651 b'ui',
2648 b'timestamp-output',
2652 b'timestamp-output',
2649 default=False,
2653 default=False,
2650 )
2654 )
2651 coreconfigitem(
2655 coreconfigitem(
2652 b'ui',
2656 b'ui',
2653 b'traceback',
2657 b'traceback',
2654 default=False,
2658 default=False,
2655 )
2659 )
2656 coreconfigitem(
2660 coreconfigitem(
2657 b'ui',
2661 b'ui',
2658 b'tweakdefaults',
2662 b'tweakdefaults',
2659 default=False,
2663 default=False,
2660 )
2664 )
2661 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2665 coreconfigitem(b'ui', b'username', alias=[(b'ui', b'user')])
2662 coreconfigitem(
2666 coreconfigitem(
2663 b'ui',
2667 b'ui',
2664 b'verbose',
2668 b'verbose',
2665 default=False,
2669 default=False,
2666 )
2670 )
2667 coreconfigitem(
2671 coreconfigitem(
2668 b'verify',
2672 b'verify',
2669 b'skipflags',
2673 b'skipflags',
2670 default=0,
2674 default=0,
2671 )
2675 )
2672 coreconfigitem(
2676 coreconfigitem(
2673 b'web',
2677 b'web',
2674 b'allowbz2',
2678 b'allowbz2',
2675 default=False,
2679 default=False,
2676 )
2680 )
2677 coreconfigitem(
2681 coreconfigitem(
2678 b'web',
2682 b'web',
2679 b'allowgz',
2683 b'allowgz',
2680 default=False,
2684 default=False,
2681 )
2685 )
2682 coreconfigitem(
2686 coreconfigitem(
2683 b'web',
2687 b'web',
2684 b'allow-pull',
2688 b'allow-pull',
2685 alias=[(b'web', b'allowpull')],
2689 alias=[(b'web', b'allowpull')],
2686 default=True,
2690 default=True,
2687 )
2691 )
2688 coreconfigitem(
2692 coreconfigitem(
2689 b'web',
2693 b'web',
2690 b'allow-push',
2694 b'allow-push',
2691 alias=[(b'web', b'allow_push')],
2695 alias=[(b'web', b'allow_push')],
2692 default=list,
2696 default=list,
2693 )
2697 )
2694 coreconfigitem(
2698 coreconfigitem(
2695 b'web',
2699 b'web',
2696 b'allowzip',
2700 b'allowzip',
2697 default=False,
2701 default=False,
2698 )
2702 )
2699 coreconfigitem(
2703 coreconfigitem(
2700 b'web',
2704 b'web',
2701 b'archivesubrepos',
2705 b'archivesubrepos',
2702 default=False,
2706 default=False,
2703 )
2707 )
2704 coreconfigitem(
2708 coreconfigitem(
2705 b'web',
2709 b'web',
2706 b'cache',
2710 b'cache',
2707 default=True,
2711 default=True,
2708 )
2712 )
2709 coreconfigitem(
2713 coreconfigitem(
2710 b'web',
2714 b'web',
2711 b'comparisoncontext',
2715 b'comparisoncontext',
2712 default=5,
2716 default=5,
2713 )
2717 )
2714 coreconfigitem(
2718 coreconfigitem(
2715 b'web',
2719 b'web',
2716 b'contact',
2720 b'contact',
2717 default=None,
2721 default=None,
2718 )
2722 )
2719 coreconfigitem(
2723 coreconfigitem(
2720 b'web',
2724 b'web',
2721 b'deny_push',
2725 b'deny_push',
2722 default=list,
2726 default=list,
2723 )
2727 )
2724 coreconfigitem(
2728 coreconfigitem(
2725 b'web',
2729 b'web',
2726 b'guessmime',
2730 b'guessmime',
2727 default=False,
2731 default=False,
2728 )
2732 )
2729 coreconfigitem(
2733 coreconfigitem(
2730 b'web',
2734 b'web',
2731 b'hidden',
2735 b'hidden',
2732 default=False,
2736 default=False,
2733 )
2737 )
2734 coreconfigitem(
2738 coreconfigitem(
2735 b'web',
2739 b'web',
2736 b'labels',
2740 b'labels',
2737 default=list,
2741 default=list,
2738 )
2742 )
2739 coreconfigitem(
2743 coreconfigitem(
2740 b'web',
2744 b'web',
2741 b'logoimg',
2745 b'logoimg',
2742 default=b'hglogo.png',
2746 default=b'hglogo.png',
2743 )
2747 )
2744 coreconfigitem(
2748 coreconfigitem(
2745 b'web',
2749 b'web',
2746 b'logourl',
2750 b'logourl',
2747 default=b'https://mercurial-scm.org/',
2751 default=b'https://mercurial-scm.org/',
2748 )
2752 )
2749 coreconfigitem(
2753 coreconfigitem(
2750 b'web',
2754 b'web',
2751 b'accesslog',
2755 b'accesslog',
2752 default=b'-',
2756 default=b'-',
2753 )
2757 )
2754 coreconfigitem(
2758 coreconfigitem(
2755 b'web',
2759 b'web',
2756 b'address',
2760 b'address',
2757 default=b'',
2761 default=b'',
2758 )
2762 )
2759 coreconfigitem(
2763 coreconfigitem(
2760 b'web',
2764 b'web',
2761 b'allow-archive',
2765 b'allow-archive',
2762 alias=[(b'web', b'allow_archive')],
2766 alias=[(b'web', b'allow_archive')],
2763 default=list,
2767 default=list,
2764 )
2768 )
2765 coreconfigitem(
2769 coreconfigitem(
2766 b'web',
2770 b'web',
2767 b'allow_read',
2771 b'allow_read',
2768 default=list,
2772 default=list,
2769 )
2773 )
2770 coreconfigitem(
2774 coreconfigitem(
2771 b'web',
2775 b'web',
2772 b'baseurl',
2776 b'baseurl',
2773 default=None,
2777 default=None,
2774 )
2778 )
2775 coreconfigitem(
2779 coreconfigitem(
2776 b'web',
2780 b'web',
2777 b'cacerts',
2781 b'cacerts',
2778 default=None,
2782 default=None,
2779 )
2783 )
2780 coreconfigitem(
2784 coreconfigitem(
2781 b'web',
2785 b'web',
2782 b'certificate',
2786 b'certificate',
2783 default=None,
2787 default=None,
2784 )
2788 )
2785 coreconfigitem(
2789 coreconfigitem(
2786 b'web',
2790 b'web',
2787 b'collapse',
2791 b'collapse',
2788 default=False,
2792 default=False,
2789 )
2793 )
2790 coreconfigitem(
2794 coreconfigitem(
2791 b'web',
2795 b'web',
2792 b'csp',
2796 b'csp',
2793 default=None,
2797 default=None,
2794 )
2798 )
2795 coreconfigitem(
2799 coreconfigitem(
2796 b'web',
2800 b'web',
2797 b'deny_read',
2801 b'deny_read',
2798 default=list,
2802 default=list,
2799 )
2803 )
2800 coreconfigitem(
2804 coreconfigitem(
2801 b'web',
2805 b'web',
2802 b'descend',
2806 b'descend',
2803 default=True,
2807 default=True,
2804 )
2808 )
2805 coreconfigitem(
2809 coreconfigitem(
2806 b'web',
2810 b'web',
2807 b'description',
2811 b'description',
2808 default=b"",
2812 default=b"",
2809 )
2813 )
2810 coreconfigitem(
2814 coreconfigitem(
2811 b'web',
2815 b'web',
2812 b'encoding',
2816 b'encoding',
2813 default=lambda: encoding.encoding,
2817 default=lambda: encoding.encoding,
2814 )
2818 )
2815 coreconfigitem(
2819 coreconfigitem(
2816 b'web',
2820 b'web',
2817 b'errorlog',
2821 b'errorlog',
2818 default=b'-',
2822 default=b'-',
2819 )
2823 )
2820 coreconfigitem(
2824 coreconfigitem(
2821 b'web',
2825 b'web',
2822 b'ipv6',
2826 b'ipv6',
2823 default=False,
2827 default=False,
2824 )
2828 )
2825 coreconfigitem(
2829 coreconfigitem(
2826 b'web',
2830 b'web',
2827 b'maxchanges',
2831 b'maxchanges',
2828 default=10,
2832 default=10,
2829 )
2833 )
2830 coreconfigitem(
2834 coreconfigitem(
2831 b'web',
2835 b'web',
2832 b'maxfiles',
2836 b'maxfiles',
2833 default=10,
2837 default=10,
2834 )
2838 )
2835 coreconfigitem(
2839 coreconfigitem(
2836 b'web',
2840 b'web',
2837 b'maxshortchanges',
2841 b'maxshortchanges',
2838 default=60,
2842 default=60,
2839 )
2843 )
2840 coreconfigitem(
2844 coreconfigitem(
2841 b'web',
2845 b'web',
2842 b'motd',
2846 b'motd',
2843 default=b'',
2847 default=b'',
2844 )
2848 )
2845 coreconfigitem(
2849 coreconfigitem(
2846 b'web',
2850 b'web',
2847 b'name',
2851 b'name',
2848 default=dynamicdefault,
2852 default=dynamicdefault,
2849 )
2853 )
2850 coreconfigitem(
2854 coreconfigitem(
2851 b'web',
2855 b'web',
2852 b'port',
2856 b'port',
2853 default=8000,
2857 default=8000,
2854 )
2858 )
2855 coreconfigitem(
2859 coreconfigitem(
2856 b'web',
2860 b'web',
2857 b'prefix',
2861 b'prefix',
2858 default=b'',
2862 default=b'',
2859 )
2863 )
2860 coreconfigitem(
2864 coreconfigitem(
2861 b'web',
2865 b'web',
2862 b'push_ssl',
2866 b'push_ssl',
2863 default=True,
2867 default=True,
2864 )
2868 )
2865 coreconfigitem(
2869 coreconfigitem(
2866 b'web',
2870 b'web',
2867 b'refreshinterval',
2871 b'refreshinterval',
2868 default=20,
2872 default=20,
2869 )
2873 )
2870 coreconfigitem(
2874 coreconfigitem(
2871 b'web',
2875 b'web',
2872 b'server-header',
2876 b'server-header',
2873 default=None,
2877 default=None,
2874 )
2878 )
2875 coreconfigitem(
2879 coreconfigitem(
2876 b'web',
2880 b'web',
2877 b'static',
2881 b'static',
2878 default=None,
2882 default=None,
2879 )
2883 )
2880 coreconfigitem(
2884 coreconfigitem(
2881 b'web',
2885 b'web',
2882 b'staticurl',
2886 b'staticurl',
2883 default=None,
2887 default=None,
2884 )
2888 )
2885 coreconfigitem(
2889 coreconfigitem(
2886 b'web',
2890 b'web',
2887 b'stripes',
2891 b'stripes',
2888 default=1,
2892 default=1,
2889 )
2893 )
2890 coreconfigitem(
2894 coreconfigitem(
2891 b'web',
2895 b'web',
2892 b'style',
2896 b'style',
2893 default=b'paper',
2897 default=b'paper',
2894 )
2898 )
2895 coreconfigitem(
2899 coreconfigitem(
2896 b'web',
2900 b'web',
2897 b'templates',
2901 b'templates',
2898 default=None,
2902 default=None,
2899 )
2903 )
2900 coreconfigitem(
2904 coreconfigitem(
2901 b'web',
2905 b'web',
2902 b'view',
2906 b'view',
2903 default=b'served',
2907 default=b'served',
2904 experimental=True,
2908 experimental=True,
2905 )
2909 )
2906 coreconfigitem(
2910 coreconfigitem(
2907 b'worker',
2911 b'worker',
2908 b'backgroundclose',
2912 b'backgroundclose',
2909 default=dynamicdefault,
2913 default=dynamicdefault,
2910 )
2914 )
2911 # Windows defaults to a limit of 512 open files. A buffer of 128
2915 # Windows defaults to a limit of 512 open files. A buffer of 128
2912 # should give us enough headway.
2916 # should give us enough headway.
2913 coreconfigitem(
2917 coreconfigitem(
2914 b'worker',
2918 b'worker',
2915 b'backgroundclosemaxqueue',
2919 b'backgroundclosemaxqueue',
2916 default=384,
2920 default=384,
2917 )
2921 )
2918 coreconfigitem(
2922 coreconfigitem(
2919 b'worker',
2923 b'worker',
2920 b'backgroundcloseminfilecount',
2924 b'backgroundcloseminfilecount',
2921 default=2048,
2925 default=2048,
2922 )
2926 )
2923 coreconfigitem(
2927 coreconfigitem(
2924 b'worker',
2928 b'worker',
2925 b'backgroundclosethreadcount',
2929 b'backgroundclosethreadcount',
2926 default=4,
2930 default=4,
2927 )
2931 )
2928 coreconfigitem(
2932 coreconfigitem(
2929 b'worker',
2933 b'worker',
2930 b'enabled',
2934 b'enabled',
2931 default=True,
2935 default=True,
2932 )
2936 )
2933 coreconfigitem(
2937 coreconfigitem(
2934 b'worker',
2938 b'worker',
2935 b'numcpus',
2939 b'numcpus',
2936 default=None,
2940 default=None,
2937 )
2941 )
2938
2942
2939 # Rebase related configuration moved to core because other extension are doing
2943 # Rebase related configuration moved to core because other extension are doing
2940 # strange things. For example, shelve import the extensions to reuse some bit
2944 # strange things. For example, shelve import the extensions to reuse some bit
2941 # without formally loading it.
2945 # without formally loading it.
2942 coreconfigitem(
2946 coreconfigitem(
2943 b'commands',
2947 b'commands',
2944 b'rebase.requiredest',
2948 b'rebase.requiredest',
2945 default=False,
2949 default=False,
2946 )
2950 )
2947 coreconfigitem(
2951 coreconfigitem(
2948 b'experimental',
2952 b'experimental',
2949 b'rebaseskipobsolete',
2953 b'rebaseskipobsolete',
2950 default=True,
2954 default=True,
2951 )
2955 )
2952 coreconfigitem(
2956 coreconfigitem(
2953 b'rebase',
2957 b'rebase',
2954 b'singletransaction',
2958 b'singletransaction',
2955 default=False,
2959 default=False,
2956 )
2960 )
2957 coreconfigitem(
2961 coreconfigitem(
2958 b'rebase',
2962 b'rebase',
2959 b'experimental.inmemory',
2963 b'experimental.inmemory',
2960 default=False,
2964 default=False,
2961 )
2965 )
2962
2966
2963 # This setting controls creation of a rebase_source extra field
2967 # This setting controls creation of a rebase_source extra field
2964 # during rebase. When False, no such field is created. This is
2968 # during rebase. When False, no such field is created. This is
2965 # useful eg for incrementally converting changesets and then
2969 # useful eg for incrementally converting changesets and then
2966 # rebasing them onto an existing repo.
2970 # rebasing them onto an existing repo.
2967 # WARNING: this is an advanced setting reserved for people who know
2971 # WARNING: this is an advanced setting reserved for people who know
2968 # exactly what they are doing. Misuse of this setting can easily
2972 # exactly what they are doing. Misuse of this setting can easily
2969 # result in obsmarker cycles and a vivid headache.
2973 # result in obsmarker cycles and a vivid headache.
2970 coreconfigitem(
2974 coreconfigitem(
2971 b'rebase',
2975 b'rebase',
2972 b'store-source',
2976 b'store-source',
2973 default=True,
2977 default=True,
2974 experimental=True,
2978 experimental=True,
2975 )
2979 )
@@ -1,1511 +1,1530 b''
1 # revlogdeltas.py - Logic around delta computation for revlog
1 # revlogdeltas.py - Logic around delta computation for revlog
2 #
2 #
3 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
3 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
4 # Copyright 2018 Octobus <contact@octobus.net>
4 # Copyright 2018 Octobus <contact@octobus.net>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8 """Helper class to compute deltas stored inside revlogs"""
8 """Helper class to compute deltas stored inside revlogs"""
9
9
10
10
11 import collections
11 import collections
12 import struct
12 import struct
13
13
14 # import stuff from node for others to import from revlog
14 # import stuff from node for others to import from revlog
15 from ..node import nullrev
15 from ..node import nullrev
16 from ..i18n import _
16 from ..i18n import _
17 from ..pycompat import getattr
17 from ..pycompat import getattr
18
18
19 from .constants import (
19 from .constants import (
20 COMP_MODE_DEFAULT,
20 COMP_MODE_DEFAULT,
21 COMP_MODE_INLINE,
21 COMP_MODE_INLINE,
22 COMP_MODE_PLAIN,
22 COMP_MODE_PLAIN,
23 DELTA_BASE_REUSE_FORCE,
23 DELTA_BASE_REUSE_FORCE,
24 DELTA_BASE_REUSE_NO,
24 DELTA_BASE_REUSE_NO,
25 KIND_CHANGELOG,
25 KIND_CHANGELOG,
26 KIND_FILELOG,
26 KIND_FILELOG,
27 KIND_MANIFESTLOG,
27 KIND_MANIFESTLOG,
28 REVIDX_ISCENSORED,
28 REVIDX_ISCENSORED,
29 REVIDX_RAWTEXT_CHANGING_FLAGS,
29 REVIDX_RAWTEXT_CHANGING_FLAGS,
30 )
30 )
31
31
32 from ..thirdparty import attr
32 from ..thirdparty import attr
33
33
34 from .. import (
34 from .. import (
35 error,
35 error,
36 mdiff,
36 mdiff,
37 util,
37 util,
38 )
38 )
39
39
40 from . import flagutil
40 from . import flagutil
41
41
42 # maximum <delta-chain-data>/<revision-text-length> ratio
42 # maximum <delta-chain-data>/<revision-text-length> ratio
43 LIMIT_DELTA2TEXT = 2
43 LIMIT_DELTA2TEXT = 2
44
44
45
45
46 class _testrevlog:
46 class _testrevlog:
47 """minimalist fake revlog to use in doctests"""
47 """minimalist fake revlog to use in doctests"""
48
48
49 def __init__(self, data, density=0.5, mingap=0, snapshot=()):
49 def __init__(self, data, density=0.5, mingap=0, snapshot=()):
50 """data is an list of revision payload boundaries"""
50 """data is an list of revision payload boundaries"""
51 self._data = data
51 self._data = data
52 self._srdensitythreshold = density
52 self._srdensitythreshold = density
53 self._srmingapsize = mingap
53 self._srmingapsize = mingap
54 self._snapshot = set(snapshot)
54 self._snapshot = set(snapshot)
55 self.index = None
55 self.index = None
56
56
57 def start(self, rev):
57 def start(self, rev):
58 if rev == nullrev:
58 if rev == nullrev:
59 return 0
59 return 0
60 if rev == 0:
60 if rev == 0:
61 return 0
61 return 0
62 return self._data[rev - 1]
62 return self._data[rev - 1]
63
63
64 def end(self, rev):
64 def end(self, rev):
65 if rev == nullrev:
65 if rev == nullrev:
66 return 0
66 return 0
67 return self._data[rev]
67 return self._data[rev]
68
68
69 def length(self, rev):
69 def length(self, rev):
70 return self.end(rev) - self.start(rev)
70 return self.end(rev) - self.start(rev)
71
71
72 def __len__(self):
72 def __len__(self):
73 return len(self._data)
73 return len(self._data)
74
74
75 def issnapshot(self, rev):
75 def issnapshot(self, rev):
76 if rev == nullrev:
76 if rev == nullrev:
77 return True
77 return True
78 return rev in self._snapshot
78 return rev in self._snapshot
79
79
80
80
81 def slicechunk(revlog, revs, targetsize=None):
81 def slicechunk(revlog, revs, targetsize=None):
82 """slice revs to reduce the amount of unrelated data to be read from disk.
82 """slice revs to reduce the amount of unrelated data to be read from disk.
83
83
84 ``revs`` is sliced into groups that should be read in one time.
84 ``revs`` is sliced into groups that should be read in one time.
85 Assume that revs are sorted.
85 Assume that revs are sorted.
86
86
87 The initial chunk is sliced until the overall density (payload/chunks-span
87 The initial chunk is sliced until the overall density (payload/chunks-span
88 ratio) is above `revlog._srdensitythreshold`. No gap smaller than
88 ratio) is above `revlog._srdensitythreshold`. No gap smaller than
89 `revlog._srmingapsize` is skipped.
89 `revlog._srmingapsize` is skipped.
90
90
91 If `targetsize` is set, no chunk larger than `targetsize` will be yield.
91 If `targetsize` is set, no chunk larger than `targetsize` will be yield.
92 For consistency with other slicing choice, this limit won't go lower than
92 For consistency with other slicing choice, this limit won't go lower than
93 `revlog._srmingapsize`.
93 `revlog._srmingapsize`.
94
94
95 If individual revisions chunk are larger than this limit, they will still
95 If individual revisions chunk are larger than this limit, they will still
96 be raised individually.
96 be raised individually.
97
97
98 >>> data = [
98 >>> data = [
99 ... 5, #00 (5)
99 ... 5, #00 (5)
100 ... 10, #01 (5)
100 ... 10, #01 (5)
101 ... 12, #02 (2)
101 ... 12, #02 (2)
102 ... 12, #03 (empty)
102 ... 12, #03 (empty)
103 ... 27, #04 (15)
103 ... 27, #04 (15)
104 ... 31, #05 (4)
104 ... 31, #05 (4)
105 ... 31, #06 (empty)
105 ... 31, #06 (empty)
106 ... 42, #07 (11)
106 ... 42, #07 (11)
107 ... 47, #08 (5)
107 ... 47, #08 (5)
108 ... 47, #09 (empty)
108 ... 47, #09 (empty)
109 ... 48, #10 (1)
109 ... 48, #10 (1)
110 ... 51, #11 (3)
110 ... 51, #11 (3)
111 ... 74, #12 (23)
111 ... 74, #12 (23)
112 ... 85, #13 (11)
112 ... 85, #13 (11)
113 ... 86, #14 (1)
113 ... 86, #14 (1)
114 ... 91, #15 (5)
114 ... 91, #15 (5)
115 ... ]
115 ... ]
116 >>> revlog = _testrevlog(data, snapshot=range(16))
116 >>> revlog = _testrevlog(data, snapshot=range(16))
117
117
118 >>> list(slicechunk(revlog, list(range(16))))
118 >>> list(slicechunk(revlog, list(range(16))))
119 [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]]
119 [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]]
120 >>> list(slicechunk(revlog, [0, 15]))
120 >>> list(slicechunk(revlog, [0, 15]))
121 [[0], [15]]
121 [[0], [15]]
122 >>> list(slicechunk(revlog, [0, 11, 15]))
122 >>> list(slicechunk(revlog, [0, 11, 15]))
123 [[0], [11], [15]]
123 [[0], [11], [15]]
124 >>> list(slicechunk(revlog, [0, 11, 13, 15]))
124 >>> list(slicechunk(revlog, [0, 11, 13, 15]))
125 [[0], [11, 13, 15]]
125 [[0], [11, 13, 15]]
126 >>> list(slicechunk(revlog, [1, 2, 3, 5, 8, 10, 11, 14]))
126 >>> list(slicechunk(revlog, [1, 2, 3, 5, 8, 10, 11, 14]))
127 [[1, 2], [5, 8, 10, 11], [14]]
127 [[1, 2], [5, 8, 10, 11], [14]]
128
128
129 Slicing with a maximum chunk size
129 Slicing with a maximum chunk size
130 >>> list(slicechunk(revlog, [0, 11, 13, 15], targetsize=15))
130 >>> list(slicechunk(revlog, [0, 11, 13, 15], targetsize=15))
131 [[0], [11], [13], [15]]
131 [[0], [11], [13], [15]]
132 >>> list(slicechunk(revlog, [0, 11, 13, 15], targetsize=20))
132 >>> list(slicechunk(revlog, [0, 11, 13, 15], targetsize=20))
133 [[0], [11], [13, 15]]
133 [[0], [11], [13, 15]]
134
134
135 Slicing involving nullrev
135 Slicing involving nullrev
136 >>> list(slicechunk(revlog, [-1, 0, 11, 13, 15], targetsize=20))
136 >>> list(slicechunk(revlog, [-1, 0, 11, 13, 15], targetsize=20))
137 [[-1, 0], [11], [13, 15]]
137 [[-1, 0], [11], [13, 15]]
138 >>> list(slicechunk(revlog, [-1, 13, 15], targetsize=5))
138 >>> list(slicechunk(revlog, [-1, 13, 15], targetsize=5))
139 [[-1], [13], [15]]
139 [[-1], [13], [15]]
140 """
140 """
141 if targetsize is not None:
141 if targetsize is not None:
142 targetsize = max(targetsize, revlog._srmingapsize)
142 targetsize = max(targetsize, revlog._srmingapsize)
143 # targetsize should not be specified when evaluating delta candidates:
143 # targetsize should not be specified when evaluating delta candidates:
144 # * targetsize is used to ensure we stay within specification when reading,
144 # * targetsize is used to ensure we stay within specification when reading,
145 densityslicing = getattr(revlog.index, 'slicechunktodensity', None)
145 densityslicing = getattr(revlog.index, 'slicechunktodensity', None)
146 if densityslicing is None:
146 if densityslicing is None:
147 densityslicing = lambda x, y, z: _slicechunktodensity(revlog, x, y, z)
147 densityslicing = lambda x, y, z: _slicechunktodensity(revlog, x, y, z)
148 for chunk in densityslicing(
148 for chunk in densityslicing(
149 revs, revlog._srdensitythreshold, revlog._srmingapsize
149 revs, revlog._srdensitythreshold, revlog._srmingapsize
150 ):
150 ):
151 for subchunk in _slicechunktosize(revlog, chunk, targetsize):
151 for subchunk in _slicechunktosize(revlog, chunk, targetsize):
152 yield subchunk
152 yield subchunk
153
153
154
154
155 def _slicechunktosize(revlog, revs, targetsize=None):
155 def _slicechunktosize(revlog, revs, targetsize=None):
156 """slice revs to match the target size
156 """slice revs to match the target size
157
157
158 This is intended to be used on chunk that density slicing selected by that
158 This is intended to be used on chunk that density slicing selected by that
159 are still too large compared to the read garantee of revlog. This might
159 are still too large compared to the read garantee of revlog. This might
160 happens when "minimal gap size" interrupted the slicing or when chain are
160 happens when "minimal gap size" interrupted the slicing or when chain are
161 built in a way that create large blocks next to each other.
161 built in a way that create large blocks next to each other.
162
162
163 >>> data = [
163 >>> data = [
164 ... 3, #0 (3)
164 ... 3, #0 (3)
165 ... 5, #1 (2)
165 ... 5, #1 (2)
166 ... 6, #2 (1)
166 ... 6, #2 (1)
167 ... 8, #3 (2)
167 ... 8, #3 (2)
168 ... 8, #4 (empty)
168 ... 8, #4 (empty)
169 ... 11, #5 (3)
169 ... 11, #5 (3)
170 ... 12, #6 (1)
170 ... 12, #6 (1)
171 ... 13, #7 (1)
171 ... 13, #7 (1)
172 ... 14, #8 (1)
172 ... 14, #8 (1)
173 ... ]
173 ... ]
174
174
175 == All snapshots cases ==
175 == All snapshots cases ==
176 >>> revlog = _testrevlog(data, snapshot=range(9))
176 >>> revlog = _testrevlog(data, snapshot=range(9))
177
177
178 Cases where chunk is already small enough
178 Cases where chunk is already small enough
179 >>> list(_slicechunktosize(revlog, [0], 3))
179 >>> list(_slicechunktosize(revlog, [0], 3))
180 [[0]]
180 [[0]]
181 >>> list(_slicechunktosize(revlog, [6, 7], 3))
181 >>> list(_slicechunktosize(revlog, [6, 7], 3))
182 [[6, 7]]
182 [[6, 7]]
183 >>> list(_slicechunktosize(revlog, [0], None))
183 >>> list(_slicechunktosize(revlog, [0], None))
184 [[0]]
184 [[0]]
185 >>> list(_slicechunktosize(revlog, [6, 7], None))
185 >>> list(_slicechunktosize(revlog, [6, 7], None))
186 [[6, 7]]
186 [[6, 7]]
187
187
188 cases where we need actual slicing
188 cases where we need actual slicing
189 >>> list(_slicechunktosize(revlog, [0, 1], 3))
189 >>> list(_slicechunktosize(revlog, [0, 1], 3))
190 [[0], [1]]
190 [[0], [1]]
191 >>> list(_slicechunktosize(revlog, [1, 3], 3))
191 >>> list(_slicechunktosize(revlog, [1, 3], 3))
192 [[1], [3]]
192 [[1], [3]]
193 >>> list(_slicechunktosize(revlog, [1, 2, 3], 3))
193 >>> list(_slicechunktosize(revlog, [1, 2, 3], 3))
194 [[1, 2], [3]]
194 [[1, 2], [3]]
195 >>> list(_slicechunktosize(revlog, [3, 5], 3))
195 >>> list(_slicechunktosize(revlog, [3, 5], 3))
196 [[3], [5]]
196 [[3], [5]]
197 >>> list(_slicechunktosize(revlog, [3, 4, 5], 3))
197 >>> list(_slicechunktosize(revlog, [3, 4, 5], 3))
198 [[3], [5]]
198 [[3], [5]]
199 >>> list(_slicechunktosize(revlog, [5, 6, 7, 8], 3))
199 >>> list(_slicechunktosize(revlog, [5, 6, 7, 8], 3))
200 [[5], [6, 7, 8]]
200 [[5], [6, 7, 8]]
201 >>> list(_slicechunktosize(revlog, [0, 1, 2, 3, 4, 5, 6, 7, 8], 3))
201 >>> list(_slicechunktosize(revlog, [0, 1, 2, 3, 4, 5, 6, 7, 8], 3))
202 [[0], [1, 2], [3], [5], [6, 7, 8]]
202 [[0], [1, 2], [3], [5], [6, 7, 8]]
203
203
204 Case with too large individual chunk (must return valid chunk)
204 Case with too large individual chunk (must return valid chunk)
205 >>> list(_slicechunktosize(revlog, [0, 1], 2))
205 >>> list(_slicechunktosize(revlog, [0, 1], 2))
206 [[0], [1]]
206 [[0], [1]]
207 >>> list(_slicechunktosize(revlog, [1, 3], 1))
207 >>> list(_slicechunktosize(revlog, [1, 3], 1))
208 [[1], [3]]
208 [[1], [3]]
209 >>> list(_slicechunktosize(revlog, [3, 4, 5], 2))
209 >>> list(_slicechunktosize(revlog, [3, 4, 5], 2))
210 [[3], [5]]
210 [[3], [5]]
211
211
212 == No Snapshot cases ==
212 == No Snapshot cases ==
213 >>> revlog = _testrevlog(data)
213 >>> revlog = _testrevlog(data)
214
214
215 Cases where chunk is already small enough
215 Cases where chunk is already small enough
216 >>> list(_slicechunktosize(revlog, [0], 3))
216 >>> list(_slicechunktosize(revlog, [0], 3))
217 [[0]]
217 [[0]]
218 >>> list(_slicechunktosize(revlog, [6, 7], 3))
218 >>> list(_slicechunktosize(revlog, [6, 7], 3))
219 [[6, 7]]
219 [[6, 7]]
220 >>> list(_slicechunktosize(revlog, [0], None))
220 >>> list(_slicechunktosize(revlog, [0], None))
221 [[0]]
221 [[0]]
222 >>> list(_slicechunktosize(revlog, [6, 7], None))
222 >>> list(_slicechunktosize(revlog, [6, 7], None))
223 [[6, 7]]
223 [[6, 7]]
224
224
225 cases where we need actual slicing
225 cases where we need actual slicing
226 >>> list(_slicechunktosize(revlog, [0, 1], 3))
226 >>> list(_slicechunktosize(revlog, [0, 1], 3))
227 [[0], [1]]
227 [[0], [1]]
228 >>> list(_slicechunktosize(revlog, [1, 3], 3))
228 >>> list(_slicechunktosize(revlog, [1, 3], 3))
229 [[1], [3]]
229 [[1], [3]]
230 >>> list(_slicechunktosize(revlog, [1, 2, 3], 3))
230 >>> list(_slicechunktosize(revlog, [1, 2, 3], 3))
231 [[1], [2, 3]]
231 [[1], [2, 3]]
232 >>> list(_slicechunktosize(revlog, [3, 5], 3))
232 >>> list(_slicechunktosize(revlog, [3, 5], 3))
233 [[3], [5]]
233 [[3], [5]]
234 >>> list(_slicechunktosize(revlog, [3, 4, 5], 3))
234 >>> list(_slicechunktosize(revlog, [3, 4, 5], 3))
235 [[3], [4, 5]]
235 [[3], [4, 5]]
236 >>> list(_slicechunktosize(revlog, [5, 6, 7, 8], 3))
236 >>> list(_slicechunktosize(revlog, [5, 6, 7, 8], 3))
237 [[5], [6, 7, 8]]
237 [[5], [6, 7, 8]]
238 >>> list(_slicechunktosize(revlog, [0, 1, 2, 3, 4, 5, 6, 7, 8], 3))
238 >>> list(_slicechunktosize(revlog, [0, 1, 2, 3, 4, 5, 6, 7, 8], 3))
239 [[0], [1, 2], [3], [5], [6, 7, 8]]
239 [[0], [1, 2], [3], [5], [6, 7, 8]]
240
240
241 Case with too large individual chunk (must return valid chunk)
241 Case with too large individual chunk (must return valid chunk)
242 >>> list(_slicechunktosize(revlog, [0, 1], 2))
242 >>> list(_slicechunktosize(revlog, [0, 1], 2))
243 [[0], [1]]
243 [[0], [1]]
244 >>> list(_slicechunktosize(revlog, [1, 3], 1))
244 >>> list(_slicechunktosize(revlog, [1, 3], 1))
245 [[1], [3]]
245 [[1], [3]]
246 >>> list(_slicechunktosize(revlog, [3, 4, 5], 2))
246 >>> list(_slicechunktosize(revlog, [3, 4, 5], 2))
247 [[3], [5]]
247 [[3], [5]]
248
248
249 == mixed case ==
249 == mixed case ==
250 >>> revlog = _testrevlog(data, snapshot=[0, 1, 2])
250 >>> revlog = _testrevlog(data, snapshot=[0, 1, 2])
251 >>> list(_slicechunktosize(revlog, list(range(9)), 5))
251 >>> list(_slicechunktosize(revlog, list(range(9)), 5))
252 [[0, 1], [2], [3, 4, 5], [6, 7, 8]]
252 [[0, 1], [2], [3, 4, 5], [6, 7, 8]]
253 """
253 """
254 assert targetsize is None or 0 <= targetsize
254 assert targetsize is None or 0 <= targetsize
255 startdata = revlog.start(revs[0])
255 startdata = revlog.start(revs[0])
256 enddata = revlog.end(revs[-1])
256 enddata = revlog.end(revs[-1])
257 fullspan = enddata - startdata
257 fullspan = enddata - startdata
258 if targetsize is None or fullspan <= targetsize:
258 if targetsize is None or fullspan <= targetsize:
259 yield revs
259 yield revs
260 return
260 return
261
261
262 startrevidx = 0
262 startrevidx = 0
263 endrevidx = 1
263 endrevidx = 1
264 iterrevs = enumerate(revs)
264 iterrevs = enumerate(revs)
265 next(iterrevs) # skip first rev.
265 next(iterrevs) # skip first rev.
266 # first step: get snapshots out of the way
266 # first step: get snapshots out of the way
267 for idx, r in iterrevs:
267 for idx, r in iterrevs:
268 span = revlog.end(r) - startdata
268 span = revlog.end(r) - startdata
269 snapshot = revlog.issnapshot(r)
269 snapshot = revlog.issnapshot(r)
270 if span <= targetsize and snapshot:
270 if span <= targetsize and snapshot:
271 endrevidx = idx + 1
271 endrevidx = idx + 1
272 else:
272 else:
273 chunk = _trimchunk(revlog, revs, startrevidx, endrevidx)
273 chunk = _trimchunk(revlog, revs, startrevidx, endrevidx)
274 if chunk:
274 if chunk:
275 yield chunk
275 yield chunk
276 startrevidx = idx
276 startrevidx = idx
277 startdata = revlog.start(r)
277 startdata = revlog.start(r)
278 endrevidx = idx + 1
278 endrevidx = idx + 1
279 if not snapshot:
279 if not snapshot:
280 break
280 break
281
281
282 # for the others, we use binary slicing to quickly converge toward valid
282 # for the others, we use binary slicing to quickly converge toward valid
283 # chunks (otherwise, we might end up looking for start/end of many
283 # chunks (otherwise, we might end up looking for start/end of many
284 # revisions). This logic is not looking for the perfect slicing point, it
284 # revisions). This logic is not looking for the perfect slicing point, it
285 # focuses on quickly converging toward valid chunks.
285 # focuses on quickly converging toward valid chunks.
286 nbitem = len(revs)
286 nbitem = len(revs)
287 while (enddata - startdata) > targetsize:
287 while (enddata - startdata) > targetsize:
288 endrevidx = nbitem
288 endrevidx = nbitem
289 if nbitem - startrevidx <= 1:
289 if nbitem - startrevidx <= 1:
290 break # protect against individual chunk larger than limit
290 break # protect against individual chunk larger than limit
291 localenddata = revlog.end(revs[endrevidx - 1])
291 localenddata = revlog.end(revs[endrevidx - 1])
292 span = localenddata - startdata
292 span = localenddata - startdata
293 while span > targetsize:
293 while span > targetsize:
294 if endrevidx - startrevidx <= 1:
294 if endrevidx - startrevidx <= 1:
295 break # protect against individual chunk larger than limit
295 break # protect against individual chunk larger than limit
296 endrevidx -= (endrevidx - startrevidx) // 2
296 endrevidx -= (endrevidx - startrevidx) // 2
297 localenddata = revlog.end(revs[endrevidx - 1])
297 localenddata = revlog.end(revs[endrevidx - 1])
298 span = localenddata - startdata
298 span = localenddata - startdata
299 chunk = _trimchunk(revlog, revs, startrevidx, endrevidx)
299 chunk = _trimchunk(revlog, revs, startrevidx, endrevidx)
300 if chunk:
300 if chunk:
301 yield chunk
301 yield chunk
302 startrevidx = endrevidx
302 startrevidx = endrevidx
303 startdata = revlog.start(revs[startrevidx])
303 startdata = revlog.start(revs[startrevidx])
304
304
305 chunk = _trimchunk(revlog, revs, startrevidx)
305 chunk = _trimchunk(revlog, revs, startrevidx)
306 if chunk:
306 if chunk:
307 yield chunk
307 yield chunk
308
308
309
309
310 def _slicechunktodensity(revlog, revs, targetdensity=0.5, mingapsize=0):
310 def _slicechunktodensity(revlog, revs, targetdensity=0.5, mingapsize=0):
311 """slice revs to reduce the amount of unrelated data to be read from disk.
311 """slice revs to reduce the amount of unrelated data to be read from disk.
312
312
313 ``revs`` is sliced into groups that should be read in one time.
313 ``revs`` is sliced into groups that should be read in one time.
314 Assume that revs are sorted.
314 Assume that revs are sorted.
315
315
316 The initial chunk is sliced until the overall density (payload/chunks-span
316 The initial chunk is sliced until the overall density (payload/chunks-span
317 ratio) is above `targetdensity`. No gap smaller than `mingapsize` is
317 ratio) is above `targetdensity`. No gap smaller than `mingapsize` is
318 skipped.
318 skipped.
319
319
320 >>> revlog = _testrevlog([
320 >>> revlog = _testrevlog([
321 ... 5, #00 (5)
321 ... 5, #00 (5)
322 ... 10, #01 (5)
322 ... 10, #01 (5)
323 ... 12, #02 (2)
323 ... 12, #02 (2)
324 ... 12, #03 (empty)
324 ... 12, #03 (empty)
325 ... 27, #04 (15)
325 ... 27, #04 (15)
326 ... 31, #05 (4)
326 ... 31, #05 (4)
327 ... 31, #06 (empty)
327 ... 31, #06 (empty)
328 ... 42, #07 (11)
328 ... 42, #07 (11)
329 ... 47, #08 (5)
329 ... 47, #08 (5)
330 ... 47, #09 (empty)
330 ... 47, #09 (empty)
331 ... 48, #10 (1)
331 ... 48, #10 (1)
332 ... 51, #11 (3)
332 ... 51, #11 (3)
333 ... 74, #12 (23)
333 ... 74, #12 (23)
334 ... 85, #13 (11)
334 ... 85, #13 (11)
335 ... 86, #14 (1)
335 ... 86, #14 (1)
336 ... 91, #15 (5)
336 ... 91, #15 (5)
337 ... ])
337 ... ])
338
338
339 >>> list(_slicechunktodensity(revlog, list(range(16))))
339 >>> list(_slicechunktodensity(revlog, list(range(16))))
340 [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]]
340 [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]]
341 >>> list(_slicechunktodensity(revlog, [0, 15]))
341 >>> list(_slicechunktodensity(revlog, [0, 15]))
342 [[0], [15]]
342 [[0], [15]]
343 >>> list(_slicechunktodensity(revlog, [0, 11, 15]))
343 >>> list(_slicechunktodensity(revlog, [0, 11, 15]))
344 [[0], [11], [15]]
344 [[0], [11], [15]]
345 >>> list(_slicechunktodensity(revlog, [0, 11, 13, 15]))
345 >>> list(_slicechunktodensity(revlog, [0, 11, 13, 15]))
346 [[0], [11, 13, 15]]
346 [[0], [11, 13, 15]]
347 >>> list(_slicechunktodensity(revlog, [1, 2, 3, 5, 8, 10, 11, 14]))
347 >>> list(_slicechunktodensity(revlog, [1, 2, 3, 5, 8, 10, 11, 14]))
348 [[1, 2], [5, 8, 10, 11], [14]]
348 [[1, 2], [5, 8, 10, 11], [14]]
349 >>> list(_slicechunktodensity(revlog, [1, 2, 3, 5, 8, 10, 11, 14],
349 >>> list(_slicechunktodensity(revlog, [1, 2, 3, 5, 8, 10, 11, 14],
350 ... mingapsize=20))
350 ... mingapsize=20))
351 [[1, 2, 3, 5, 8, 10, 11], [14]]
351 [[1, 2, 3, 5, 8, 10, 11], [14]]
352 >>> list(_slicechunktodensity(revlog, [1, 2, 3, 5, 8, 10, 11, 14],
352 >>> list(_slicechunktodensity(revlog, [1, 2, 3, 5, 8, 10, 11, 14],
353 ... targetdensity=0.95))
353 ... targetdensity=0.95))
354 [[1, 2], [5], [8, 10, 11], [14]]
354 [[1, 2], [5], [8, 10, 11], [14]]
355 >>> list(_slicechunktodensity(revlog, [1, 2, 3, 5, 8, 10, 11, 14],
355 >>> list(_slicechunktodensity(revlog, [1, 2, 3, 5, 8, 10, 11, 14],
356 ... targetdensity=0.95, mingapsize=12))
356 ... targetdensity=0.95, mingapsize=12))
357 [[1, 2], [5, 8, 10, 11], [14]]
357 [[1, 2], [5, 8, 10, 11], [14]]
358 """
358 """
359 start = revlog.start
359 start = revlog.start
360 length = revlog.length
360 length = revlog.length
361
361
362 if len(revs) <= 1:
362 if len(revs) <= 1:
363 yield revs
363 yield revs
364 return
364 return
365
365
366 deltachainspan = segmentspan(revlog, revs)
366 deltachainspan = segmentspan(revlog, revs)
367
367
368 if deltachainspan < mingapsize:
368 if deltachainspan < mingapsize:
369 yield revs
369 yield revs
370 return
370 return
371
371
372 readdata = deltachainspan
372 readdata = deltachainspan
373 chainpayload = sum(length(r) for r in revs)
373 chainpayload = sum(length(r) for r in revs)
374
374
375 if deltachainspan:
375 if deltachainspan:
376 density = chainpayload / float(deltachainspan)
376 density = chainpayload / float(deltachainspan)
377 else:
377 else:
378 density = 1.0
378 density = 1.0
379
379
380 if density >= targetdensity:
380 if density >= targetdensity:
381 yield revs
381 yield revs
382 return
382 return
383
383
384 # Store the gaps in a heap to have them sorted by decreasing size
384 # Store the gaps in a heap to have them sorted by decreasing size
385 gaps = []
385 gaps = []
386 prevend = None
386 prevend = None
387 for i, rev in enumerate(revs):
387 for i, rev in enumerate(revs):
388 revstart = start(rev)
388 revstart = start(rev)
389 revlen = length(rev)
389 revlen = length(rev)
390
390
391 # Skip empty revisions to form larger holes
391 # Skip empty revisions to form larger holes
392 if revlen == 0:
392 if revlen == 0:
393 continue
393 continue
394
394
395 if prevend is not None:
395 if prevend is not None:
396 gapsize = revstart - prevend
396 gapsize = revstart - prevend
397 # only consider holes that are large enough
397 # only consider holes that are large enough
398 if gapsize > mingapsize:
398 if gapsize > mingapsize:
399 gaps.append((gapsize, i))
399 gaps.append((gapsize, i))
400
400
401 prevend = revstart + revlen
401 prevend = revstart + revlen
402 # sort the gaps to pop them from largest to small
402 # sort the gaps to pop them from largest to small
403 gaps.sort()
403 gaps.sort()
404
404
405 # Collect the indices of the largest holes until the density is acceptable
405 # Collect the indices of the largest holes until the density is acceptable
406 selected = []
406 selected = []
407 while gaps and density < targetdensity:
407 while gaps and density < targetdensity:
408 gapsize, gapidx = gaps.pop()
408 gapsize, gapidx = gaps.pop()
409
409
410 selected.append(gapidx)
410 selected.append(gapidx)
411
411
412 # the gap sizes are stored as negatives to be sorted decreasingly
412 # the gap sizes are stored as negatives to be sorted decreasingly
413 # by the heap
413 # by the heap
414 readdata -= gapsize
414 readdata -= gapsize
415 if readdata > 0:
415 if readdata > 0:
416 density = chainpayload / float(readdata)
416 density = chainpayload / float(readdata)
417 else:
417 else:
418 density = 1.0
418 density = 1.0
419 selected.sort()
419 selected.sort()
420
420
421 # Cut the revs at collected indices
421 # Cut the revs at collected indices
422 previdx = 0
422 previdx = 0
423 for idx in selected:
423 for idx in selected:
424
424
425 chunk = _trimchunk(revlog, revs, previdx, idx)
425 chunk = _trimchunk(revlog, revs, previdx, idx)
426 if chunk:
426 if chunk:
427 yield chunk
427 yield chunk
428
428
429 previdx = idx
429 previdx = idx
430
430
431 chunk = _trimchunk(revlog, revs, previdx)
431 chunk = _trimchunk(revlog, revs, previdx)
432 if chunk:
432 if chunk:
433 yield chunk
433 yield chunk
434
434
435
435
436 def _trimchunk(revlog, revs, startidx, endidx=None):
436 def _trimchunk(revlog, revs, startidx, endidx=None):
437 """returns revs[startidx:endidx] without empty trailing revs
437 """returns revs[startidx:endidx] without empty trailing revs
438
438
439 Doctest Setup
439 Doctest Setup
440 >>> revlog = _testrevlog([
440 >>> revlog = _testrevlog([
441 ... 5, #0
441 ... 5, #0
442 ... 10, #1
442 ... 10, #1
443 ... 12, #2
443 ... 12, #2
444 ... 12, #3 (empty)
444 ... 12, #3 (empty)
445 ... 17, #4
445 ... 17, #4
446 ... 21, #5
446 ... 21, #5
447 ... 21, #6 (empty)
447 ... 21, #6 (empty)
448 ... ])
448 ... ])
449
449
450 Contiguous cases:
450 Contiguous cases:
451 >>> _trimchunk(revlog, [0, 1, 2, 3, 4, 5, 6], 0)
451 >>> _trimchunk(revlog, [0, 1, 2, 3, 4, 5, 6], 0)
452 [0, 1, 2, 3, 4, 5]
452 [0, 1, 2, 3, 4, 5]
453 >>> _trimchunk(revlog, [0, 1, 2, 3, 4, 5, 6], 0, 5)
453 >>> _trimchunk(revlog, [0, 1, 2, 3, 4, 5, 6], 0, 5)
454 [0, 1, 2, 3, 4]
454 [0, 1, 2, 3, 4]
455 >>> _trimchunk(revlog, [0, 1, 2, 3, 4, 5, 6], 0, 4)
455 >>> _trimchunk(revlog, [0, 1, 2, 3, 4, 5, 6], 0, 4)
456 [0, 1, 2]
456 [0, 1, 2]
457 >>> _trimchunk(revlog, [0, 1, 2, 3, 4, 5, 6], 2, 4)
457 >>> _trimchunk(revlog, [0, 1, 2, 3, 4, 5, 6], 2, 4)
458 [2]
458 [2]
459 >>> _trimchunk(revlog, [0, 1, 2, 3, 4, 5, 6], 3)
459 >>> _trimchunk(revlog, [0, 1, 2, 3, 4, 5, 6], 3)
460 [3, 4, 5]
460 [3, 4, 5]
461 >>> _trimchunk(revlog, [0, 1, 2, 3, 4, 5, 6], 3, 5)
461 >>> _trimchunk(revlog, [0, 1, 2, 3, 4, 5, 6], 3, 5)
462 [3, 4]
462 [3, 4]
463
463
464 Discontiguous cases:
464 Discontiguous cases:
465 >>> _trimchunk(revlog, [1, 3, 5, 6], 0)
465 >>> _trimchunk(revlog, [1, 3, 5, 6], 0)
466 [1, 3, 5]
466 [1, 3, 5]
467 >>> _trimchunk(revlog, [1, 3, 5, 6], 0, 2)
467 >>> _trimchunk(revlog, [1, 3, 5, 6], 0, 2)
468 [1]
468 [1]
469 >>> _trimchunk(revlog, [1, 3, 5, 6], 1, 3)
469 >>> _trimchunk(revlog, [1, 3, 5, 6], 1, 3)
470 [3, 5]
470 [3, 5]
471 >>> _trimchunk(revlog, [1, 3, 5, 6], 1)
471 >>> _trimchunk(revlog, [1, 3, 5, 6], 1)
472 [3, 5]
472 [3, 5]
473 """
473 """
474 length = revlog.length
474 length = revlog.length
475
475
476 if endidx is None:
476 if endidx is None:
477 endidx = len(revs)
477 endidx = len(revs)
478
478
479 # If we have a non-emtpy delta candidate, there are nothing to trim
479 # If we have a non-emtpy delta candidate, there are nothing to trim
480 if revs[endidx - 1] < len(revlog):
480 if revs[endidx - 1] < len(revlog):
481 # Trim empty revs at the end, except the very first revision of a chain
481 # Trim empty revs at the end, except the very first revision of a chain
482 while (
482 while (
483 endidx > 1 and endidx > startidx and length(revs[endidx - 1]) == 0
483 endidx > 1 and endidx > startidx and length(revs[endidx - 1]) == 0
484 ):
484 ):
485 endidx -= 1
485 endidx -= 1
486
486
487 return revs[startidx:endidx]
487 return revs[startidx:endidx]
488
488
489
489
490 def segmentspan(revlog, revs):
490 def segmentspan(revlog, revs):
491 """Get the byte span of a segment of revisions
491 """Get the byte span of a segment of revisions
492
492
493 revs is a sorted array of revision numbers
493 revs is a sorted array of revision numbers
494
494
495 >>> revlog = _testrevlog([
495 >>> revlog = _testrevlog([
496 ... 5, #0
496 ... 5, #0
497 ... 10, #1
497 ... 10, #1
498 ... 12, #2
498 ... 12, #2
499 ... 12, #3 (empty)
499 ... 12, #3 (empty)
500 ... 17, #4
500 ... 17, #4
501 ... ])
501 ... ])
502
502
503 >>> segmentspan(revlog, [0, 1, 2, 3, 4])
503 >>> segmentspan(revlog, [0, 1, 2, 3, 4])
504 17
504 17
505 >>> segmentspan(revlog, [0, 4])
505 >>> segmentspan(revlog, [0, 4])
506 17
506 17
507 >>> segmentspan(revlog, [3, 4])
507 >>> segmentspan(revlog, [3, 4])
508 5
508 5
509 >>> segmentspan(revlog, [1, 2, 3,])
509 >>> segmentspan(revlog, [1, 2, 3,])
510 7
510 7
511 >>> segmentspan(revlog, [1, 3])
511 >>> segmentspan(revlog, [1, 3])
512 7
512 7
513 """
513 """
514 if not revs:
514 if not revs:
515 return 0
515 return 0
516 end = revlog.end(revs[-1])
516 end = revlog.end(revs[-1])
517 return end - revlog.start(revs[0])
517 return end - revlog.start(revs[0])
518
518
519
519
520 def _textfromdelta(fh, revlog, baserev, delta, p1, p2, flags, expectednode):
520 def _textfromdelta(fh, revlog, baserev, delta, p1, p2, flags, expectednode):
521 """build full text from a (base, delta) pair and other metadata"""
521 """build full text from a (base, delta) pair and other metadata"""
522 # special case deltas which replace entire base; no need to decode
522 # special case deltas which replace entire base; no need to decode
523 # base revision. this neatly avoids censored bases, which throw when
523 # base revision. this neatly avoids censored bases, which throw when
524 # they're decoded.
524 # they're decoded.
525 hlen = struct.calcsize(b">lll")
525 hlen = struct.calcsize(b">lll")
526 if delta[:hlen] == mdiff.replacediffheader(
526 if delta[:hlen] == mdiff.replacediffheader(
527 revlog.rawsize(baserev), len(delta) - hlen
527 revlog.rawsize(baserev), len(delta) - hlen
528 ):
528 ):
529 fulltext = delta[hlen:]
529 fulltext = delta[hlen:]
530 else:
530 else:
531 # deltabase is rawtext before changed by flag processors, which is
531 # deltabase is rawtext before changed by flag processors, which is
532 # equivalent to non-raw text
532 # equivalent to non-raw text
533 basetext = revlog.revision(baserev, _df=fh)
533 basetext = revlog.revision(baserev, _df=fh)
534 fulltext = mdiff.patch(basetext, delta)
534 fulltext = mdiff.patch(basetext, delta)
535
535
536 try:
536 try:
537 validatehash = flagutil.processflagsraw(revlog, fulltext, flags)
537 validatehash = flagutil.processflagsraw(revlog, fulltext, flags)
538 if validatehash:
538 if validatehash:
539 revlog.checkhash(fulltext, expectednode, p1=p1, p2=p2)
539 revlog.checkhash(fulltext, expectednode, p1=p1, p2=p2)
540 if flags & REVIDX_ISCENSORED:
540 if flags & REVIDX_ISCENSORED:
541 raise error.StorageError(
541 raise error.StorageError(
542 _(b'node %s is not censored') % expectednode
542 _(b'node %s is not censored') % expectednode
543 )
543 )
544 except error.CensoredNodeError:
544 except error.CensoredNodeError:
545 # must pass the censored index flag to add censored revisions
545 # must pass the censored index flag to add censored revisions
546 if not flags & REVIDX_ISCENSORED:
546 if not flags & REVIDX_ISCENSORED:
547 raise
547 raise
548 return fulltext
548 return fulltext
549
549
550
550
551 @attr.s(slots=True, frozen=True)
551 @attr.s(slots=True, frozen=True)
552 class _deltainfo:
552 class _deltainfo:
553 distance = attr.ib()
553 distance = attr.ib()
554 deltalen = attr.ib()
554 deltalen = attr.ib()
555 data = attr.ib()
555 data = attr.ib()
556 base = attr.ib()
556 base = attr.ib()
557 chainbase = attr.ib()
557 chainbase = attr.ib()
558 chainlen = attr.ib()
558 chainlen = attr.ib()
559 compresseddeltalen = attr.ib()
559 compresseddeltalen = attr.ib()
560 snapshotdepth = attr.ib()
560 snapshotdepth = attr.ib()
561
561
562
562
563 def drop_u_compression(delta):
563 def drop_u_compression(delta):
564 """turn into a "u" (no-compression) into no-compression without header
564 """turn into a "u" (no-compression) into no-compression without header
565
565
566 This is useful for revlog format that has better compression method.
566 This is useful for revlog format that has better compression method.
567 """
567 """
568 assert delta.data[0] == b'u', delta.data[0]
568 assert delta.data[0] == b'u', delta.data[0]
569 return _deltainfo(
569 return _deltainfo(
570 delta.distance,
570 delta.distance,
571 delta.deltalen - 1,
571 delta.deltalen - 1,
572 (b'', delta.data[1]),
572 (b'', delta.data[1]),
573 delta.base,
573 delta.base,
574 delta.chainbase,
574 delta.chainbase,
575 delta.chainlen,
575 delta.chainlen,
576 delta.compresseddeltalen,
576 delta.compresseddeltalen,
577 delta.snapshotdepth,
577 delta.snapshotdepth,
578 )
578 )
579
579
580
580
581 def is_good_delta_info(revlog, deltainfo, revinfo):
581 def is_good_delta_info(revlog, deltainfo, revinfo):
582 """Returns True if the given delta is good. Good means that it is within
582 """Returns True if the given delta is good. Good means that it is within
583 the disk span, disk size, and chain length bounds that we know to be
583 the disk span, disk size, and chain length bounds that we know to be
584 performant."""
584 performant."""
585 if deltainfo is None:
585 if deltainfo is None:
586 return False
586 return False
587
587
588 if (
588 if (
589 revinfo.cachedelta is not None
589 revinfo.cachedelta is not None
590 and deltainfo.base == revinfo.cachedelta[0]
590 and deltainfo.base == revinfo.cachedelta[0]
591 and revinfo.cachedelta[2] == DELTA_BASE_REUSE_FORCE
591 and revinfo.cachedelta[2] == DELTA_BASE_REUSE_FORCE
592 ):
592 ):
593 return True
593 return True
594
594
595 # - 'deltainfo.distance' is the distance from the base revision --
595 # - 'deltainfo.distance' is the distance from the base revision --
596 # bounding it limits the amount of I/O we need to do.
596 # bounding it limits the amount of I/O we need to do.
597 # - 'deltainfo.compresseddeltalen' is the sum of the total size of
597 # - 'deltainfo.compresseddeltalen' is the sum of the total size of
598 # deltas we need to apply -- bounding it limits the amount of CPU
598 # deltas we need to apply -- bounding it limits the amount of CPU
599 # we consume.
599 # we consume.
600
600
601 textlen = revinfo.textlen
601 textlen = revinfo.textlen
602 defaultmax = textlen * 4
602 defaultmax = textlen * 4
603 maxdist = revlog._maxdeltachainspan
603 maxdist = revlog._maxdeltachainspan
604 if not maxdist:
604 if not maxdist:
605 maxdist = deltainfo.distance # ensure the conditional pass
605 maxdist = deltainfo.distance # ensure the conditional pass
606 maxdist = max(maxdist, defaultmax)
606 maxdist = max(maxdist, defaultmax)
607
607
608 # Bad delta from read span:
608 # Bad delta from read span:
609 #
609 #
610 # If the span of data read is larger than the maximum allowed.
610 # If the span of data read is larger than the maximum allowed.
611 #
611 #
612 # In the sparse-revlog case, we rely on the associated "sparse reading"
612 # In the sparse-revlog case, we rely on the associated "sparse reading"
613 # to avoid issue related to the span of data. In theory, it would be
613 # to avoid issue related to the span of data. In theory, it would be
614 # possible to build pathological revlog where delta pattern would lead
614 # possible to build pathological revlog where delta pattern would lead
615 # to too many reads. However, they do not happen in practice at all. So
615 # to too many reads. However, they do not happen in practice at all. So
616 # we skip the span check entirely.
616 # we skip the span check entirely.
617 if not revlog._sparserevlog and maxdist < deltainfo.distance:
617 if not revlog._sparserevlog and maxdist < deltainfo.distance:
618 return False
618 return False
619
619
620 # Bad delta from new delta size:
620 # Bad delta from new delta size:
621 #
621 #
622 # If the delta size is larger than the target text, storing the
622 # If the delta size is larger than the target text, storing the
623 # delta will be inefficient.
623 # delta will be inefficient.
624 if textlen < deltainfo.deltalen:
624 if textlen < deltainfo.deltalen:
625 return False
625 return False
626
626
627 # Bad delta from cumulated payload size:
627 # Bad delta from cumulated payload size:
628 #
628 #
629 # If the sum of delta get larger than K * target text length.
629 # If the sum of delta get larger than K * target text length.
630 if textlen * LIMIT_DELTA2TEXT < deltainfo.compresseddeltalen:
630 if textlen * LIMIT_DELTA2TEXT < deltainfo.compresseddeltalen:
631 return False
631 return False
632
632
633 # Bad delta from chain length:
633 # Bad delta from chain length:
634 #
634 #
635 # If the number of delta in the chain gets too high.
635 # If the number of delta in the chain gets too high.
636 if revlog._maxchainlen and revlog._maxchainlen < deltainfo.chainlen:
636 if revlog._maxchainlen and revlog._maxchainlen < deltainfo.chainlen:
637 return False
637 return False
638
638
639 # bad delta from intermediate snapshot size limit
639 # bad delta from intermediate snapshot size limit
640 #
640 #
641 # If an intermediate snapshot size is higher than the limit. The
641 # If an intermediate snapshot size is higher than the limit. The
642 # limit exist to prevent endless chain of intermediate delta to be
642 # limit exist to prevent endless chain of intermediate delta to be
643 # created.
643 # created.
644 if (
644 if (
645 deltainfo.snapshotdepth is not None
645 deltainfo.snapshotdepth is not None
646 and (textlen >> deltainfo.snapshotdepth) < deltainfo.deltalen
646 and (textlen >> deltainfo.snapshotdepth) < deltainfo.deltalen
647 ):
647 ):
648 return False
648 return False
649
649
650 # bad delta if new intermediate snapshot is larger than the previous
650 # bad delta if new intermediate snapshot is larger than the previous
651 # snapshot
651 # snapshot
652 if (
652 if (
653 deltainfo.snapshotdepth
653 deltainfo.snapshotdepth
654 and revlog.length(deltainfo.base) < deltainfo.deltalen
654 and revlog.length(deltainfo.base) < deltainfo.deltalen
655 ):
655 ):
656 return False
656 return False
657
657
658 return True
658 return True
659
659
660
660
661 # If a revision's full text is that much bigger than a base candidate full
661 # If a revision's full text is that much bigger than a base candidate full
662 # text's, it is very unlikely that it will produce a valid delta. We no longer
662 # text's, it is very unlikely that it will produce a valid delta. We no longer
663 # consider these candidates.
663 # consider these candidates.
664 LIMIT_BASE2TEXT = 500
664 LIMIT_BASE2TEXT = 500
665
665
666
666
667 def _candidategroups(
667 def _candidategroups(
668 revlog,
668 revlog,
669 textlen,
669 textlen,
670 p1,
670 p1,
671 p2,
671 p2,
672 cachedelta,
672 cachedelta,
673 excluded_bases=None,
673 excluded_bases=None,
674 target_rev=None,
674 target_rev=None,
675 snapshot_cache=None,
675 snapshot_cache=None,
676 ):
676 ):
677 """Provides group of revision to be tested as delta base
677 """Provides group of revision to be tested as delta base
678
678
679 This top level function focus on emitting groups with unique and worthwhile
679 This top level function focus on emitting groups with unique and worthwhile
680 content. See _raw_candidate_groups for details about the group order.
680 content. See _raw_candidate_groups for details about the group order.
681 """
681 """
682 # should we try to build a delta?
682 # should we try to build a delta?
683 if not (len(revlog) and revlog._storedeltachains):
683 if not (len(revlog) and revlog._storedeltachains):
684 yield None
684 yield None
685 return
685 return
686
686
687 if target_rev is None:
688 target_rev = len(revlog)
689
690 if not revlog._generaldelta:
691 # before general delta, there is only one possible delta base
692 yield (target_rev - 1,)
693 yield None
694 return
695
687 if (
696 if (
688 cachedelta is not None
697 cachedelta is not None
689 and nullrev == cachedelta[0]
698 and nullrev == cachedelta[0]
690 and cachedelta[2] == DELTA_BASE_REUSE_FORCE
699 and cachedelta[2] == DELTA_BASE_REUSE_FORCE
691 ):
700 ):
692 # instruction are to forcibly do a full snapshot
701 # instruction are to forcibly do a full snapshot
693 yield None
702 yield None
694 return
703 return
695
704
696 deltalength = revlog.length
705 deltalength = revlog.length
697 deltaparent = revlog.deltaparent
706 deltaparent = revlog.deltaparent
698 sparse = revlog._sparserevlog
707 sparse = revlog._sparserevlog
699 good = None
708 good = None
700
709
701 deltas_limit = textlen * LIMIT_DELTA2TEXT
710 deltas_limit = textlen * LIMIT_DELTA2TEXT
702 group_chunk_size = revlog._candidate_group_chunk_size
711 group_chunk_size = revlog._candidate_group_chunk_size
703
712
704 tested = {nullrev}
713 tested = {nullrev}
705 candidates = _refinedgroups(
714 candidates = _refinedgroups(
706 revlog,
715 revlog,
707 p1,
716 p1,
708 p2,
717 p2,
709 cachedelta,
718 cachedelta,
710 snapshot_cache=snapshot_cache,
719 snapshot_cache=snapshot_cache,
711 )
720 )
712 while True:
721 while True:
713 temptative = candidates.send(good)
722 temptative = candidates.send(good)
714 if temptative is None:
723 if temptative is None:
715 break
724 break
716 group = []
725 group = []
717 for rev in temptative:
726 for rev in temptative:
718 # skip over empty delta (no need to include them in a chain)
727 # skip over empty delta (no need to include them in a chain)
719 while revlog._generaldelta and not (
728 while not (rev == nullrev or rev in tested or deltalength(rev)):
720 rev == nullrev or rev in tested or deltalength(rev)
721 ):
722 tested.add(rev)
729 tested.add(rev)
723 rev = deltaparent(rev)
730 rev = deltaparent(rev)
724 # no need to try a delta against nullrev, this will be done as a
731 # no need to try a delta against nullrev, this will be done as a
725 # last resort.
732 # last resort.
726 if rev == nullrev:
733 if rev == nullrev:
727 continue
734 continue
728 # filter out revision we tested already
735 # filter out revision we tested already
729 if rev in tested:
736 if rev in tested:
730 continue
737 continue
731
738
732 if (
739 if (
733 cachedelta is not None
740 cachedelta is not None
734 and rev == cachedelta[0]
741 and rev == cachedelta[0]
735 and cachedelta[2] == DELTA_BASE_REUSE_FORCE
742 and cachedelta[2] == DELTA_BASE_REUSE_FORCE
736 ):
743 ):
737 # instructions are to forcibly consider/use this delta base
744 # instructions are to forcibly consider/use this delta base
738 group.append(rev)
745 group.append(rev)
739 continue
746 continue
740
747
741 # an higher authority deamed the base unworthy (e.g. censored)
748 # an higher authority deamed the base unworthy (e.g. censored)
742 if excluded_bases is not None and rev in excluded_bases:
749 if excluded_bases is not None and rev in excluded_bases:
743 tested.add(rev)
750 tested.add(rev)
744 continue
751 continue
745 # We are in some recomputation cases and that rev is too high in
752 # We are in some recomputation cases and that rev is too high in
746 # the revlog
753 # the revlog
747 if target_rev is not None and rev >= target_rev:
754 if target_rev is not None and rev >= target_rev:
748 tested.add(rev)
755 tested.add(rev)
749 continue
756 continue
750 # filter out delta base that will never produce good delta
757 # filter out delta base that will never produce good delta
751 if deltas_limit < revlog.length(rev):
758 if deltas_limit < revlog.length(rev):
752 tested.add(rev)
759 tested.add(rev)
753 continue
760 continue
754 if sparse and revlog.rawsize(rev) < (textlen // LIMIT_BASE2TEXT):
761 if sparse and revlog.rawsize(rev) < (textlen // LIMIT_BASE2TEXT):
755 tested.add(rev)
762 tested.add(rev)
756 continue
763 continue
757 # no delta for rawtext-changing revs (see "candelta" for why)
764 # no delta for rawtext-changing revs (see "candelta" for why)
758 if revlog.flags(rev) & REVIDX_RAWTEXT_CHANGING_FLAGS:
765 if revlog.flags(rev) & REVIDX_RAWTEXT_CHANGING_FLAGS:
759 tested.add(rev)
766 tested.add(rev)
760 continue
767 continue
761
768
762 # If we reach here, we are about to build and test a delta.
769 # If we reach here, we are about to build and test a delta.
763 # The delta building process will compute the chaininfo in all
770 # The delta building process will compute the chaininfo in all
764 # case, since that computation is cached, it is fine to access it
771 # case, since that computation is cached, it is fine to access it
765 # here too.
772 # here too.
766 chainlen, chainsize = revlog._chaininfo(rev)
773 chainlen, chainsize = revlog._chaininfo(rev)
767 # if chain will be too long, skip base
774 # if chain will be too long, skip base
768 if revlog._maxchainlen and chainlen >= revlog._maxchainlen:
775 if revlog._maxchainlen and chainlen >= revlog._maxchainlen:
769 tested.add(rev)
776 tested.add(rev)
770 continue
777 continue
771 # if chain already have too much data, skip base
778 # if chain already have too much data, skip base
772 if deltas_limit < chainsize:
779 if deltas_limit < chainsize:
773 tested.add(rev)
780 tested.add(rev)
774 continue
781 continue
775 if sparse and revlog.upperboundcomp is not None:
782 if sparse and revlog.upperboundcomp is not None:
776 maxcomp = revlog.upperboundcomp
783 maxcomp = revlog.upperboundcomp
777 basenotsnap = (p1, p2, nullrev)
784 basenotsnap = (p1, p2, nullrev)
778 if rev not in basenotsnap and revlog.issnapshot(rev):
785 if rev not in basenotsnap and revlog.issnapshot(rev):
779 snapshotdepth = revlog.snapshotdepth(rev)
786 snapshotdepth = revlog.snapshotdepth(rev)
780 # If text is significantly larger than the base, we can
787 # If text is significantly larger than the base, we can
781 # expect the resulting delta to be proportional to the size
788 # expect the resulting delta to be proportional to the size
782 # difference
789 # difference
783 revsize = revlog.rawsize(rev)
790 revsize = revlog.rawsize(rev)
784 rawsizedistance = max(textlen - revsize, 0)
791 rawsizedistance = max(textlen - revsize, 0)
785 # use an estimate of the compression upper bound.
792 # use an estimate of the compression upper bound.
786 lowestrealisticdeltalen = rawsizedistance // maxcomp
793 lowestrealisticdeltalen = rawsizedistance // maxcomp
787
794
788 # check the absolute constraint on the delta size
795 # check the absolute constraint on the delta size
789 snapshotlimit = textlen >> snapshotdepth
796 snapshotlimit = textlen >> snapshotdepth
790 if snapshotlimit < lowestrealisticdeltalen:
797 if snapshotlimit < lowestrealisticdeltalen:
791 # delta lower bound is larger than accepted upper bound
798 # delta lower bound is larger than accepted upper bound
792 tested.add(rev)
799 tested.add(rev)
793 continue
800 continue
794
801
795 # check the relative constraint on the delta size
802 # check the relative constraint on the delta size
796 revlength = revlog.length(rev)
803 revlength = revlog.length(rev)
797 if revlength < lowestrealisticdeltalen:
804 if revlength < lowestrealisticdeltalen:
798 # delta probable lower bound is larger than target base
805 # delta probable lower bound is larger than target base
799 tested.add(rev)
806 tested.add(rev)
800 continue
807 continue
801
808
802 group.append(rev)
809 group.append(rev)
803 if group:
810 if group:
804 # When the size of the candidate group is big, it can result in a
811 # When the size of the candidate group is big, it can result in a
805 # quite significant performance impact. To reduce this, we can send
812 # quite significant performance impact. To reduce this, we can send
806 # them in smaller batches until the new batch does not provide any
813 # them in smaller batches until the new batch does not provide any
807 # improvements.
814 # improvements.
808 #
815 #
809 # This might reduce the overall efficiency of the compression in
816 # This might reduce the overall efficiency of the compression in
810 # some corner cases, but that should also prevent very pathological
817 # some corner cases, but that should also prevent very pathological
811 # cases from being an issue. (eg. 20 000 candidates).
818 # cases from being an issue. (eg. 20 000 candidates).
812 #
819 #
813 # XXX note that the ordering of the group becomes important as it
820 # XXX note that the ordering of the group becomes important as it
814 # now impacts the final result. The current order is unprocessed
821 # now impacts the final result. The current order is unprocessed
815 # and can be improved.
822 # and can be improved.
816 if group_chunk_size == 0:
823 if group_chunk_size == 0:
817 tested.update(group)
824 tested.update(group)
818 good = yield tuple(group)
825 good = yield tuple(group)
819 else:
826 else:
820 prev_good = good
827 prev_good = good
821 for start in range(0, len(group), group_chunk_size):
828 for start in range(0, len(group), group_chunk_size):
822 sub_group = group[start : start + group_chunk_size]
829 sub_group = group[start : start + group_chunk_size]
823 tested.update(sub_group)
830 tested.update(sub_group)
824 good = yield tuple(sub_group)
831 good = yield tuple(sub_group)
825 if prev_good == good:
832 if prev_good == good:
826 break
833 break
827
834
828 yield None
835 yield None
829
836
830
837
831 def _refinedgroups(revlog, p1, p2, cachedelta, snapshot_cache=None):
838 def _refinedgroups(revlog, p1, p2, cachedelta, snapshot_cache=None):
832 good = None
839 good = None
833 # First we try to reuse a the delta contained in the bundle.
840 # First we try to reuse a the delta contained in the bundle.
834 # (or from the source revlog)
841 # (or from the source revlog)
835 #
842 #
836 # This logic only applies to general delta repositories and can be disabled
843 # This logic only applies to general delta repositories and can be disabled
837 # through configuration. Disabling reuse source delta is useful when
844 # through configuration. Disabling reuse source delta is useful when
838 # we want to make sure we recomputed "optimal" deltas.
845 # we want to make sure we recomputed "optimal" deltas.
839 debug_info = None
846 debug_info = None
840 if cachedelta is not None and cachedelta[2] > DELTA_BASE_REUSE_NO:
847 if cachedelta is not None and cachedelta[2] > DELTA_BASE_REUSE_NO:
841 # Assume what we received from the server is a good choice
848 # Assume what we received from the server is a good choice
842 # build delta will reuse the cache
849 # build delta will reuse the cache
843 if debug_info is not None:
850 if debug_info is not None:
844 debug_info['cached-delta.tested'] += 1
851 debug_info['cached-delta.tested'] += 1
845 good = yield (cachedelta[0],)
852 good = yield (cachedelta[0],)
846 if good is not None:
853 if good is not None:
847 if debug_info is not None:
854 if debug_info is not None:
848 debug_info['cached-delta.accepted'] += 1
855 debug_info['cached-delta.accepted'] += 1
849 yield None
856 yield None
850 return
857 return
851 if snapshot_cache is None:
858 if snapshot_cache is None:
852 snapshot_cache = SnapshotCache()
859 snapshot_cache = SnapshotCache()
853 groups = _rawgroups(
860 groups = _rawgroups(
854 revlog,
861 revlog,
855 p1,
862 p1,
856 p2,
863 p2,
857 cachedelta,
864 cachedelta,
858 snapshot_cache,
865 snapshot_cache,
859 )
866 )
860 for candidates in groups:
867 for candidates in groups:
861 good = yield candidates
868 good = yield candidates
862 if good is not None:
869 if good is not None:
863 break
870 break
864
871
865 # If sparse revlog is enabled, we can try to refine the available deltas
872 # If sparse revlog is enabled, we can try to refine the available deltas
866 if not revlog._sparserevlog:
873 if not revlog._sparserevlog:
867 yield None
874 yield None
868 return
875 return
869
876
870 # if we have a refinable value, try to refine it
877 # if we have a refinable value, try to refine it
871 if good is not None and good not in (p1, p2) and revlog.issnapshot(good):
878 if good is not None and good not in (p1, p2) and revlog.issnapshot(good):
872 # refine snapshot down
879 # refine snapshot down
873 previous = None
880 previous = None
874 while previous != good:
881 while previous != good:
875 previous = good
882 previous = good
876 base = revlog.deltaparent(good)
883 base = revlog.deltaparent(good)
877 if base == nullrev:
884 if base == nullrev:
878 break
885 break
879 good = yield (base,)
886 good = yield (base,)
880 # refine snapshot up
887 # refine snapshot up
881 if not snapshot_cache.snapshots:
888 if not snapshot_cache.snapshots:
882 snapshot_cache.update(revlog, good + 1)
889 snapshot_cache.update(revlog, good + 1)
883 previous = None
890 previous = None
884 while good != previous:
891 while good != previous:
885 previous = good
892 previous = good
886 children = tuple(sorted(c for c in snapshot_cache.snapshots[good]))
893 children = tuple(sorted(c for c in snapshot_cache.snapshots[good]))
887 good = yield children
894 good = yield children
888
895
889 if debug_info is not None:
896 if debug_info is not None:
890 if good is None:
897 if good is None:
891 debug_info['no-solution'] += 1
898 debug_info['no-solution'] += 1
892
899
893 yield None
900 yield None
894
901
895
902
896 def _rawgroups(revlog, p1, p2, cachedelta, snapshot_cache=None):
903 def _rawgroups(revlog, p1, p2, cachedelta, snapshot_cache=None):
897 """Provides group of revision to be tested as delta base
904 """Provides group of revision to be tested as delta base
898
905
899 This lower level function focus on emitting delta theorically interresting
906 This lower level function focus on emitting delta theorically interresting
900 without looking it any practical details.
907 without looking it any practical details.
901
908
902 The group order aims at providing fast or small candidates first.
909 The group order aims at providing fast or small candidates first.
903 """
910 """
904 gdelta = revlog._generaldelta
911 # Why search for delta base if we cannot use a delta base ?
905 # gate sparse behind general-delta because of issue6056
912 assert revlog._generaldelta
906 sparse = gdelta and revlog._sparserevlog
913 # also see issue6056
914 sparse = revlog._sparserevlog
907 curr = len(revlog)
915 curr = len(revlog)
908 prev = curr - 1
916 prev = curr - 1
909 deltachain = lambda rev: revlog._deltachain(rev)[0]
917 deltachain = lambda rev: revlog._deltachain(rev)[0]
910
918
911 if gdelta:
919 # exclude already lazy tested base if any
912 # exclude already lazy tested base if any
920 parents = [p for p in (p1, p2) if p != nullrev]
913 parents = [p for p in (p1, p2) if p != nullrev]
914
921
915 if not revlog._deltabothparents and len(parents) == 2:
922 if not revlog._deltabothparents and len(parents) == 2:
916 parents.sort()
923 parents.sort()
917 # To minimize the chance of having to build a fulltext,
924 # To minimize the chance of having to build a fulltext,
918 # pick first whichever parent is closest to us (max rev)
925 # pick first whichever parent is closest to us (max rev)
919 yield (parents[1],)
926 yield (parents[1],)
920 # then the other one (min rev) if the first did not fit
927 # then the other one (min rev) if the first did not fit
921 yield (parents[0],)
928 yield (parents[0],)
922 elif len(parents) > 0:
929 elif len(parents) > 0:
923 # Test all parents (1 or 2), and keep the best candidate
930 # Test all parents (1 or 2), and keep the best candidate
924 yield parents
931 yield parents
925
932
926 if sparse and parents:
933 if sparse and parents:
927 if snapshot_cache is None:
934 if snapshot_cache is None:
928 # map: base-rev: [snapshot-revs]
935 # map: base-rev: [snapshot-revs]
929 snapshot_cache = SnapshotCache()
936 snapshot_cache = SnapshotCache()
930 # See if we can use an existing snapshot in the parent chains to use as
937 # See if we can use an existing snapshot in the parent chains to use as
931 # a base for a new intermediate-snapshot
938 # a base for a new intermediate-snapshot
932 #
939 #
933 # search for snapshot in parents delta chain
940 # search for snapshot in parents delta chain
934 # map: snapshot-level: snapshot-rev
941 # map: snapshot-level: snapshot-rev
935 parents_snaps = collections.defaultdict(set)
942 parents_snaps = collections.defaultdict(set)
936 candidate_chains = [deltachain(p) for p in parents]
943 candidate_chains = [deltachain(p) for p in parents]
937 for chain in candidate_chains:
944 for chain in candidate_chains:
938 for idx, s in enumerate(chain):
945 for idx, s in enumerate(chain):
939 if not revlog.issnapshot(s):
946 if not revlog.issnapshot(s):
940 break
947 break
941 parents_snaps[idx].add(s)
948 parents_snaps[idx].add(s)
942 snapfloor = min(parents_snaps[0]) + 1
949 snapfloor = min(parents_snaps[0]) + 1
943 snapshot_cache.update(revlog, snapfloor)
950 snapshot_cache.update(revlog, snapfloor)
944 # search for the highest "unrelated" revision
951 # search for the highest "unrelated" revision
945 #
952 #
946 # Adding snapshots used by "unrelated" revision increase the odd we
953 # Adding snapshots used by "unrelated" revision increase the odd we
947 # reuse an independant, yet better snapshot chain.
954 # reuse an independant, yet better snapshot chain.
948 #
955 #
949 # XXX instead of building a set of revisions, we could lazily enumerate
956 # XXX instead of building a set of revisions, we could lazily enumerate
950 # over the chains. That would be more efficient, however we stick to
957 # over the chains. That would be more efficient, however we stick to
951 # simple code for now.
958 # simple code for now.
952 all_revs = set()
959 all_revs = set()
953 for chain in candidate_chains:
960 for chain in candidate_chains:
954 all_revs.update(chain)
961 all_revs.update(chain)
955 other = None
962 other = None
956 for r in revlog.revs(prev, snapfloor):
963 for r in revlog.revs(prev, snapfloor):
957 if r not in all_revs:
964 if r not in all_revs:
958 other = r
965 other = r
959 break
966 break
960 if other is not None:
967 if other is not None:
961 # To avoid unfair competition, we won't use unrelated intermediate
968 # To avoid unfair competition, we won't use unrelated intermediate
962 # snapshot that are deeper than the ones from the parent delta
969 # snapshot that are deeper than the ones from the parent delta
963 # chain.
970 # chain.
964 max_depth = max(parents_snaps.keys())
971 max_depth = max(parents_snaps.keys())
965 chain = deltachain(other)
972 chain = deltachain(other)
966 for depth, s in enumerate(chain):
973 for depth, s in enumerate(chain):
967 if s < snapfloor:
974 if s < snapfloor:
968 continue
975 continue
969 if max_depth < depth:
976 if max_depth < depth:
970 break
977 break
971 if not revlog.issnapshot(s):
978 if not revlog.issnapshot(s):
972 break
979 break
973 parents_snaps[depth].add(s)
980 parents_snaps[depth].add(s)
974 # Test them as possible intermediate snapshot base
981 # Test them as possible intermediate snapshot base
975 # We test them from highest to lowest level. High level one are more
982 # We test them from highest to lowest level. High level one are more
976 # likely to result in small delta
983 # likely to result in small delta
977 floor = None
984 floor = None
978 for idx, snaps in sorted(parents_snaps.items(), reverse=True):
985 for idx, snaps in sorted(parents_snaps.items(), reverse=True):
979 siblings = set()
986 siblings = set()
980 for s in snaps:
987 for s in snaps:
981 siblings.update(snapshot_cache.snapshots[s])
988 siblings.update(snapshot_cache.snapshots[s])
982 # Before considering making a new intermediate snapshot, we check
989 # Before considering making a new intermediate snapshot, we check
983 # if an existing snapshot, children of base we consider, would be
990 # if an existing snapshot, children of base we consider, would be
984 # suitable.
991 # suitable.
985 #
992 #
986 # It give a change to reuse a delta chain "unrelated" to the
993 # It give a change to reuse a delta chain "unrelated" to the
987 # current revision instead of starting our own. Without such
994 # current revision instead of starting our own. Without such
988 # re-use, topological branches would keep reopening new chains.
995 # re-use, topological branches would keep reopening new chains.
989 # Creating more and more snapshot as the repository grow.
996 # Creating more and more snapshot as the repository grow.
990
997
991 if floor is not None:
998 if floor is not None:
992 # We only do this for siblings created after the one in our
999 # We only do this for siblings created after the one in our
993 # parent's delta chain. Those created before has less chances
1000 # parent's delta chain. Those created before has less chances
994 # to be valid base since our ancestors had to create a new
1001 # to be valid base since our ancestors had to create a new
995 # snapshot.
1002 # snapshot.
996 siblings = [r for r in siblings if floor < r]
1003 siblings = [r for r in siblings if floor < r]
997 yield tuple(sorted(siblings))
1004 yield tuple(sorted(siblings))
998 # then test the base from our parent's delta chain.
1005 # then test the base from our parent's delta chain.
999 yield tuple(sorted(snaps))
1006 yield tuple(sorted(snaps))
1000 floor = min(snaps)
1007 floor = min(snaps)
1001 # No suitable base found in the parent chain, search if any full
1008 # No suitable base found in the parent chain, search if any full
1002 # snapshots emitted since parent's base would be a suitable base for an
1009 # snapshots emitted since parent's base would be a suitable base for an
1003 # intermediate snapshot.
1010 # intermediate snapshot.
1004 #
1011 #
1005 # It give a chance to reuse a delta chain unrelated to the current
1012 # It give a chance to reuse a delta chain unrelated to the current
1006 # revisions instead of starting our own. Without such re-use,
1013 # revisions instead of starting our own. Without such re-use,
1007 # topological branches would keep reopening new full chains. Creating
1014 # topological branches would keep reopening new full chains. Creating
1008 # more and more snapshot as the repository grow.
1015 # more and more snapshot as the repository grow.
1009 full = [r for r in snapshot_cache.snapshots[nullrev] if snapfloor <= r]
1016 full = [r for r in snapshot_cache.snapshots[nullrev] if snapfloor <= r]
1010 yield tuple(sorted(full))
1017 yield tuple(sorted(full))
1011
1018
1012 if not sparse:
1019 if not sparse:
1013 # other approach failed try against prev to hopefully save us a
1020 # other approach failed try against prev to hopefully save us a
1014 # fulltext.
1021 # fulltext.
1015 yield (prev,)
1022 yield (prev,)
1016
1023
1017
1024
1018 class SnapshotCache:
1025 class SnapshotCache:
1019 __slots__ = ('snapshots', '_start_rev', '_end_rev')
1026 __slots__ = ('snapshots', '_start_rev', '_end_rev')
1020
1027
1021 def __init__(self):
1028 def __init__(self):
1022 self.snapshots = collections.defaultdict(set)
1029 self.snapshots = collections.defaultdict(set)
1023 self._start_rev = None
1030 self._start_rev = None
1024 self._end_rev = None
1031 self._end_rev = None
1025
1032
1026 def update(self, revlog, start_rev=0):
1033 def update(self, revlog, start_rev=0):
1027 """find snapshots from start_rev to tip"""
1034 """find snapshots from start_rev to tip"""
1028 nb_revs = len(revlog)
1035 nb_revs = len(revlog)
1029 end_rev = nb_revs - 1
1036 end_rev = nb_revs - 1
1030 if start_rev > end_rev:
1037 if start_rev > end_rev:
1031 return # range is empty
1038 return # range is empty
1032
1039
1033 if self._start_rev is None:
1040 if self._start_rev is None:
1034 assert self._end_rev is None
1041 assert self._end_rev is None
1035 self._update(revlog, start_rev, end_rev)
1042 self._update(revlog, start_rev, end_rev)
1036 elif not (self._start_rev <= start_rev and end_rev <= self._end_rev):
1043 elif not (self._start_rev <= start_rev and end_rev <= self._end_rev):
1037 if start_rev < self._start_rev:
1044 if start_rev < self._start_rev:
1038 self._update(revlog, start_rev, self._start_rev - 1)
1045 self._update(revlog, start_rev, self._start_rev - 1)
1039 if self._end_rev < end_rev:
1046 if self._end_rev < end_rev:
1040 self._update(revlog, self._end_rev + 1, end_rev)
1047 self._update(revlog, self._end_rev + 1, end_rev)
1041
1048
1042 if self._start_rev is None:
1049 if self._start_rev is None:
1043 assert self._end_rev is None
1050 assert self._end_rev is None
1044 self._end_rev = end_rev
1051 self._end_rev = end_rev
1045 self._start_rev = start_rev
1052 self._start_rev = start_rev
1046 else:
1053 else:
1047 self._start_rev = min(self._start_rev, start_rev)
1054 self._start_rev = min(self._start_rev, start_rev)
1048 self._end_rev = max(self._end_rev, end_rev)
1055 self._end_rev = max(self._end_rev, end_rev)
1049 assert self._start_rev <= self._end_rev, (
1056 assert self._start_rev <= self._end_rev, (
1050 self._start_rev,
1057 self._start_rev,
1051 self._end_rev,
1058 self._end_rev,
1052 )
1059 )
1053
1060
1054 def _update(self, revlog, start_rev, end_rev):
1061 def _update(self, revlog, start_rev, end_rev):
1055 """internal method that actually do update content"""
1062 """internal method that actually do update content"""
1056 assert self._start_rev is None or (
1063 assert self._start_rev is None or (
1057 start_rev < self._start_rev or start_rev > self._end_rev
1064 start_rev < self._start_rev or start_rev > self._end_rev
1058 ), (self._start_rev, self._end_rev, start_rev, end_rev)
1065 ), (self._start_rev, self._end_rev, start_rev, end_rev)
1059 assert self._start_rev is None or (
1066 assert self._start_rev is None or (
1060 end_rev < self._start_rev or end_rev > self._end_rev
1067 end_rev < self._start_rev or end_rev > self._end_rev
1061 ), (self._start_rev, self._end_rev, start_rev, end_rev)
1068 ), (self._start_rev, self._end_rev, start_rev, end_rev)
1062 cache = self.snapshots
1069 cache = self.snapshots
1063 if util.safehasattr(revlog.index, b'findsnapshots'):
1070 if util.safehasattr(revlog.index, b'findsnapshots'):
1064 revlog.index.findsnapshots(cache, start_rev, end_rev)
1071 revlog.index.findsnapshots(cache, start_rev, end_rev)
1065 else:
1072 else:
1066 deltaparent = revlog.deltaparent
1073 deltaparent = revlog.deltaparent
1067 issnapshot = revlog.issnapshot
1074 issnapshot = revlog.issnapshot
1068 for rev in revlog.revs(start_rev, end_rev):
1075 for rev in revlog.revs(start_rev, end_rev):
1069 if issnapshot(rev):
1076 if issnapshot(rev):
1070 cache[deltaparent(rev)].add(rev)
1077 cache[deltaparent(rev)].add(rev)
1071
1078
1072
1079
1073 class deltacomputer:
1080 class deltacomputer:
1074 def __init__(
1081 def __init__(
1075 self,
1082 self,
1076 revlog,
1083 revlog,
1077 write_debug=None,
1084 write_debug=None,
1078 debug_search=False,
1085 debug_search=False,
1079 debug_info=None,
1086 debug_info=None,
1080 ):
1087 ):
1081 self.revlog = revlog
1088 self.revlog = revlog
1082 self._write_debug = write_debug
1089 self._write_debug = write_debug
1083 self._debug_search = debug_search
1090 self._debug_search = debug_search
1084 self._debug_info = debug_info
1091 self._debug_info = debug_info
1085 self._snapshot_cache = SnapshotCache()
1092 self._snapshot_cache = SnapshotCache()
1086
1093
1087 def buildtext(self, revinfo, fh):
1094 def buildtext(self, revinfo, fh):
1088 """Builds a fulltext version of a revision
1095 """Builds a fulltext version of a revision
1089
1096
1090 revinfo: revisioninfo instance that contains all needed info
1097 revinfo: revisioninfo instance that contains all needed info
1091 fh: file handle to either the .i or the .d revlog file,
1098 fh: file handle to either the .i or the .d revlog file,
1092 depending on whether it is inlined or not
1099 depending on whether it is inlined or not
1093 """
1100 """
1094 btext = revinfo.btext
1101 btext = revinfo.btext
1095 if btext[0] is not None:
1102 if btext[0] is not None:
1096 return btext[0]
1103 return btext[0]
1097
1104
1098 revlog = self.revlog
1105 revlog = self.revlog
1099 cachedelta = revinfo.cachedelta
1106 cachedelta = revinfo.cachedelta
1100 baserev = cachedelta[0]
1107 baserev = cachedelta[0]
1101 delta = cachedelta[1]
1108 delta = cachedelta[1]
1102
1109
1103 fulltext = btext[0] = _textfromdelta(
1110 fulltext = btext[0] = _textfromdelta(
1104 fh,
1111 fh,
1105 revlog,
1112 revlog,
1106 baserev,
1113 baserev,
1107 delta,
1114 delta,
1108 revinfo.p1,
1115 revinfo.p1,
1109 revinfo.p2,
1116 revinfo.p2,
1110 revinfo.flags,
1117 revinfo.flags,
1111 revinfo.node,
1118 revinfo.node,
1112 )
1119 )
1113 return fulltext
1120 return fulltext
1114
1121
1115 def _builddeltadiff(self, base, revinfo, fh):
1122 def _builddeltadiff(self, base, revinfo, fh):
1116 revlog = self.revlog
1123 revlog = self.revlog
1117 t = self.buildtext(revinfo, fh)
1124 t = self.buildtext(revinfo, fh)
1118 if revlog.iscensored(base):
1125 if revlog.iscensored(base):
1119 # deltas based on a censored revision must replace the
1126 # deltas based on a censored revision must replace the
1120 # full content in one patch, so delta works everywhere
1127 # full content in one patch, so delta works everywhere
1121 header = mdiff.replacediffheader(revlog.rawsize(base), len(t))
1128 header = mdiff.replacediffheader(revlog.rawsize(base), len(t))
1122 delta = header + t
1129 delta = header + t
1123 else:
1130 else:
1124 ptext = revlog.rawdata(base, _df=fh)
1131 ptext = revlog.rawdata(base, _df=fh)
1125 delta = mdiff.textdiff(ptext, t)
1132 delta = mdiff.textdiff(ptext, t)
1126
1133
1127 return delta
1134 return delta
1128
1135
1129 def _builddeltainfo(self, revinfo, base, fh):
1136 def _builddeltainfo(self, revinfo, base, fh, target_rev=None):
1130 # can we use the cached delta?
1137 # can we use the cached delta?
1131 revlog = self.revlog
1138 revlog = self.revlog
1132 debug_search = self._write_debug is not None and self._debug_search
1139 debug_search = self._write_debug is not None and self._debug_search
1133 chainbase = revlog.chainbase(base)
1140 chainbase = revlog.chainbase(base)
1134 if revlog._generaldelta:
1141 if revlog._generaldelta:
1135 deltabase = base
1142 deltabase = base
1136 else:
1143 else:
1144 if target_rev is not None and base != target_rev - 1:
1145 msg = (
1146 b'general delta cannot use delta for something else '
1147 b'than `prev`: %d<-%d'
1148 )
1149 msg %= (base, target_rev)
1150 raise error.ProgrammingError(msg)
1137 deltabase = chainbase
1151 deltabase = chainbase
1138 snapshotdepth = None
1152 snapshotdepth = None
1139 if revlog._sparserevlog and deltabase == nullrev:
1153 if revlog._sparserevlog and deltabase == nullrev:
1140 snapshotdepth = 0
1154 snapshotdepth = 0
1141 elif revlog._sparserevlog and revlog.issnapshot(deltabase):
1155 elif revlog._sparserevlog and revlog.issnapshot(deltabase):
1142 # A delta chain should always be one full snapshot,
1156 # A delta chain should always be one full snapshot,
1143 # zero or more semi-snapshots, and zero or more deltas
1157 # zero or more semi-snapshots, and zero or more deltas
1144 p1, p2 = revlog.rev(revinfo.p1), revlog.rev(revinfo.p2)
1158 p1, p2 = revlog.rev(revinfo.p1), revlog.rev(revinfo.p2)
1145 if deltabase not in (p1, p2) and revlog.issnapshot(deltabase):
1159 if deltabase not in (p1, p2) and revlog.issnapshot(deltabase):
1146 snapshotdepth = len(revlog._deltachain(deltabase)[0])
1160 snapshotdepth = len(revlog._deltachain(deltabase)[0])
1147 delta = None
1161 delta = None
1148 if revinfo.cachedelta:
1162 if revinfo.cachedelta:
1149 cachebase = revinfo.cachedelta[0]
1163 cachebase = revinfo.cachedelta[0]
1150 # check if the diff still apply
1164 # check if the diff still apply
1151 currentbase = cachebase
1165 currentbase = cachebase
1152 while (
1166 while (
1153 currentbase != nullrev
1167 currentbase != nullrev
1154 and currentbase != base
1168 and currentbase != base
1155 and self.revlog.length(currentbase) == 0
1169 and self.revlog.length(currentbase) == 0
1156 ):
1170 ):
1157 currentbase = self.revlog.deltaparent(currentbase)
1171 currentbase = self.revlog.deltaparent(currentbase)
1158 if self.revlog._lazydelta and currentbase == base:
1172 if self.revlog._lazydelta and currentbase == base:
1159 delta = revinfo.cachedelta[1]
1173 delta = revinfo.cachedelta[1]
1160 if delta is None:
1174 if delta is None:
1161 delta = self._builddeltadiff(base, revinfo, fh)
1175 delta = self._builddeltadiff(base, revinfo, fh)
1162 if debug_search:
1176 if debug_search:
1163 msg = b"DBG-DELTAS-SEARCH: uncompressed-delta-size=%d\n"
1177 msg = b"DBG-DELTAS-SEARCH: uncompressed-delta-size=%d\n"
1164 msg %= len(delta)
1178 msg %= len(delta)
1165 self._write_debug(msg)
1179 self._write_debug(msg)
1166 # snapshotdept need to be neither None nor 0 level snapshot
1180 # snapshotdept need to be neither None nor 0 level snapshot
1167 if revlog.upperboundcomp is not None and snapshotdepth:
1181 if revlog.upperboundcomp is not None and snapshotdepth:
1168 lowestrealisticdeltalen = len(delta) // revlog.upperboundcomp
1182 lowestrealisticdeltalen = len(delta) // revlog.upperboundcomp
1169 snapshotlimit = revinfo.textlen >> snapshotdepth
1183 snapshotlimit = revinfo.textlen >> snapshotdepth
1170 if debug_search:
1184 if debug_search:
1171 msg = b"DBG-DELTAS-SEARCH: projected-lower-size=%d\n"
1185 msg = b"DBG-DELTAS-SEARCH: projected-lower-size=%d\n"
1172 msg %= lowestrealisticdeltalen
1186 msg %= lowestrealisticdeltalen
1173 self._write_debug(msg)
1187 self._write_debug(msg)
1174 if snapshotlimit < lowestrealisticdeltalen:
1188 if snapshotlimit < lowestrealisticdeltalen:
1175 if debug_search:
1189 if debug_search:
1176 msg = b"DBG-DELTAS-SEARCH: DISCARDED (snapshot limit)\n"
1190 msg = b"DBG-DELTAS-SEARCH: DISCARDED (snapshot limit)\n"
1177 self._write_debug(msg)
1191 self._write_debug(msg)
1178 return None
1192 return None
1179 if revlog.length(base) < lowestrealisticdeltalen:
1193 if revlog.length(base) < lowestrealisticdeltalen:
1180 if debug_search:
1194 if debug_search:
1181 msg = b"DBG-DELTAS-SEARCH: DISCARDED (prev size)\n"
1195 msg = b"DBG-DELTAS-SEARCH: DISCARDED (prev size)\n"
1182 self._write_debug(msg)
1196 self._write_debug(msg)
1183 return None
1197 return None
1184 header, data = revlog.compress(delta)
1198 header, data = revlog.compress(delta)
1185 deltalen = len(header) + len(data)
1199 deltalen = len(header) + len(data)
1186 offset = revlog.end(len(revlog) - 1)
1200 offset = revlog.end(len(revlog) - 1)
1187 dist = deltalen + offset - revlog.start(chainbase)
1201 dist = deltalen + offset - revlog.start(chainbase)
1188 chainlen, compresseddeltalen = revlog._chaininfo(base)
1202 chainlen, compresseddeltalen = revlog._chaininfo(base)
1189 chainlen += 1
1203 chainlen += 1
1190 compresseddeltalen += deltalen
1204 compresseddeltalen += deltalen
1191
1205
1192 return _deltainfo(
1206 return _deltainfo(
1193 dist,
1207 dist,
1194 deltalen,
1208 deltalen,
1195 (header, data),
1209 (header, data),
1196 deltabase,
1210 deltabase,
1197 chainbase,
1211 chainbase,
1198 chainlen,
1212 chainlen,
1199 compresseddeltalen,
1213 compresseddeltalen,
1200 snapshotdepth,
1214 snapshotdepth,
1201 )
1215 )
1202
1216
1203 def _fullsnapshotinfo(self, fh, revinfo, curr):
1217 def _fullsnapshotinfo(self, fh, revinfo, curr):
1204 rawtext = self.buildtext(revinfo, fh)
1218 rawtext = self.buildtext(revinfo, fh)
1205 data = self.revlog.compress(rawtext)
1219 data = self.revlog.compress(rawtext)
1206 compresseddeltalen = deltalen = dist = len(data[1]) + len(data[0])
1220 compresseddeltalen = deltalen = dist = len(data[1]) + len(data[0])
1207 deltabase = chainbase = curr
1221 deltabase = chainbase = curr
1208 snapshotdepth = 0
1222 snapshotdepth = 0
1209 chainlen = 1
1223 chainlen = 1
1210
1224
1211 return _deltainfo(
1225 return _deltainfo(
1212 dist,
1226 dist,
1213 deltalen,
1227 deltalen,
1214 data,
1228 data,
1215 deltabase,
1229 deltabase,
1216 chainbase,
1230 chainbase,
1217 chainlen,
1231 chainlen,
1218 compresseddeltalen,
1232 compresseddeltalen,
1219 snapshotdepth,
1233 snapshotdepth,
1220 )
1234 )
1221
1235
1222 def finddeltainfo(self, revinfo, fh, excluded_bases=None, target_rev=None):
1236 def finddeltainfo(self, revinfo, fh, excluded_bases=None, target_rev=None):
1223 """Find an acceptable delta against a candidate revision
1237 """Find an acceptable delta against a candidate revision
1224
1238
1225 revinfo: information about the revision (instance of _revisioninfo)
1239 revinfo: information about the revision (instance of _revisioninfo)
1226 fh: file handle to either the .i or the .d revlog file,
1240 fh: file handle to either the .i or the .d revlog file,
1227 depending on whether it is inlined or not
1241 depending on whether it is inlined or not
1228
1242
1229 Returns the first acceptable candidate revision, as ordered by
1243 Returns the first acceptable candidate revision, as ordered by
1230 _candidategroups
1244 _candidategroups
1231
1245
1232 If no suitable deltabase is found, we return delta info for a full
1246 If no suitable deltabase is found, we return delta info for a full
1233 snapshot.
1247 snapshot.
1234
1248
1235 `excluded_bases` is an optional set of revision that cannot be used as
1249 `excluded_bases` is an optional set of revision that cannot be used as
1236 a delta base. Use this to recompute delta suitable in censor or strip
1250 a delta base. Use this to recompute delta suitable in censor or strip
1237 context.
1251 context.
1238 """
1252 """
1239 if target_rev is None:
1253 if target_rev is None:
1240 target_rev = len(self.revlog)
1254 target_rev = len(self.revlog)
1241
1255
1242 if not revinfo.textlen:
1256 if not revinfo.textlen:
1243 return self._fullsnapshotinfo(fh, revinfo, target_rev)
1257 return self._fullsnapshotinfo(fh, revinfo, target_rev)
1244
1258
1245 if excluded_bases is None:
1259 if excluded_bases is None:
1246 excluded_bases = set()
1260 excluded_bases = set()
1247
1261
1248 # no delta for flag processor revision (see "candelta" for why)
1262 # no delta for flag processor revision (see "candelta" for why)
1249 # not calling candelta since only one revision needs test, also to
1263 # not calling candelta since only one revision needs test, also to
1250 # avoid overhead fetching flags again.
1264 # avoid overhead fetching flags again.
1251 if revinfo.flags & REVIDX_RAWTEXT_CHANGING_FLAGS:
1265 if revinfo.flags & REVIDX_RAWTEXT_CHANGING_FLAGS:
1252 return self._fullsnapshotinfo(fh, revinfo, target_rev)
1266 return self._fullsnapshotinfo(fh, revinfo, target_rev)
1253
1267
1254 gather_debug = (
1268 gather_debug = (
1255 self._write_debug is not None or self._debug_info is not None
1269 self._write_debug is not None or self._debug_info is not None
1256 )
1270 )
1257 debug_search = self._write_debug is not None and self._debug_search
1271 debug_search = self._write_debug is not None and self._debug_search
1258
1272
1259 if gather_debug:
1273 if gather_debug:
1260 start = util.timer()
1274 start = util.timer()
1261
1275
1262 # count the number of different delta we tried (for debug purpose)
1276 # count the number of different delta we tried (for debug purpose)
1263 dbg_try_count = 0
1277 dbg_try_count = 0
1264 # count the number of "search round" we did. (for debug purpose)
1278 # count the number of "search round" we did. (for debug purpose)
1265 dbg_try_rounds = 0
1279 dbg_try_rounds = 0
1266 dbg_type = b'unknown'
1280 dbg_type = b'unknown'
1267
1281
1268 cachedelta = revinfo.cachedelta
1282 cachedelta = revinfo.cachedelta
1269 p1 = revinfo.p1
1283 p1 = revinfo.p1
1270 p2 = revinfo.p2
1284 p2 = revinfo.p2
1271 revlog = self.revlog
1285 revlog = self.revlog
1272
1286
1273 deltainfo = None
1287 deltainfo = None
1274 p1r, p2r = revlog.rev(p1), revlog.rev(p2)
1288 p1r, p2r = revlog.rev(p1), revlog.rev(p2)
1275
1289
1276 if gather_debug:
1290 if gather_debug:
1277 if p1r != nullrev:
1291 if p1r != nullrev:
1278 p1_chain_len = revlog._chaininfo(p1r)[0]
1292 p1_chain_len = revlog._chaininfo(p1r)[0]
1279 else:
1293 else:
1280 p1_chain_len = -1
1294 p1_chain_len = -1
1281 if p2r != nullrev:
1295 if p2r != nullrev:
1282 p2_chain_len = revlog._chaininfo(p2r)[0]
1296 p2_chain_len = revlog._chaininfo(p2r)[0]
1283 else:
1297 else:
1284 p2_chain_len = -1
1298 p2_chain_len = -1
1285 if debug_search:
1299 if debug_search:
1286 msg = b"DBG-DELTAS-SEARCH: SEARCH rev=%d\n"
1300 msg = b"DBG-DELTAS-SEARCH: SEARCH rev=%d\n"
1287 msg %= target_rev
1301 msg %= target_rev
1288 self._write_debug(msg)
1302 self._write_debug(msg)
1289
1303
1290 groups = _candidategroups(
1304 groups = _candidategroups(
1291 self.revlog,
1305 self.revlog,
1292 revinfo.textlen,
1306 revinfo.textlen,
1293 p1r,
1307 p1r,
1294 p2r,
1308 p2r,
1295 cachedelta,
1309 cachedelta,
1296 excluded_bases,
1310 excluded_bases,
1297 target_rev,
1311 target_rev,
1298 snapshot_cache=self._snapshot_cache,
1312 snapshot_cache=self._snapshot_cache,
1299 )
1313 )
1300 candidaterevs = next(groups)
1314 candidaterevs = next(groups)
1301 while candidaterevs is not None:
1315 while candidaterevs is not None:
1302 dbg_try_rounds += 1
1316 dbg_try_rounds += 1
1303 if debug_search:
1317 if debug_search:
1304 prev = None
1318 prev = None
1305 if deltainfo is not None:
1319 if deltainfo is not None:
1306 prev = deltainfo.base
1320 prev = deltainfo.base
1307
1321
1308 if (
1322 if (
1309 cachedelta is not None
1323 cachedelta is not None
1310 and len(candidaterevs) == 1
1324 and len(candidaterevs) == 1
1311 and cachedelta[0] in candidaterevs
1325 and cachedelta[0] in candidaterevs
1312 ):
1326 ):
1313 round_type = b"cached-delta"
1327 round_type = b"cached-delta"
1314 elif p1 in candidaterevs or p2 in candidaterevs:
1328 elif p1 in candidaterevs or p2 in candidaterevs:
1315 round_type = b"parents"
1329 round_type = b"parents"
1316 elif prev is not None and all(c < prev for c in candidaterevs):
1330 elif prev is not None and all(c < prev for c in candidaterevs):
1317 round_type = b"refine-down"
1331 round_type = b"refine-down"
1318 elif prev is not None and all(c > prev for c in candidaterevs):
1332 elif prev is not None and all(c > prev for c in candidaterevs):
1319 round_type = b"refine-up"
1333 round_type = b"refine-up"
1320 else:
1334 else:
1321 round_type = b"search-down"
1335 round_type = b"search-down"
1322 msg = b"DBG-DELTAS-SEARCH: ROUND #%d - %d candidates - %s\n"
1336 msg = b"DBG-DELTAS-SEARCH: ROUND #%d - %d candidates - %s\n"
1323 msg %= (dbg_try_rounds, len(candidaterevs), round_type)
1337 msg %= (dbg_try_rounds, len(candidaterevs), round_type)
1324 self._write_debug(msg)
1338 self._write_debug(msg)
1325 nominateddeltas = []
1339 nominateddeltas = []
1326 if deltainfo is not None:
1340 if deltainfo is not None:
1327 if debug_search:
1341 if debug_search:
1328 msg = (
1342 msg = (
1329 b"DBG-DELTAS-SEARCH: CONTENDER: rev=%d - length=%d\n"
1343 b"DBG-DELTAS-SEARCH: CONTENDER: rev=%d - length=%d\n"
1330 )
1344 )
1331 msg %= (deltainfo.base, deltainfo.deltalen)
1345 msg %= (deltainfo.base, deltainfo.deltalen)
1332 self._write_debug(msg)
1346 self._write_debug(msg)
1333 # if we already found a good delta,
1347 # if we already found a good delta,
1334 # challenge it against refined candidates
1348 # challenge it against refined candidates
1335 nominateddeltas.append(deltainfo)
1349 nominateddeltas.append(deltainfo)
1336 for candidaterev in candidaterevs:
1350 for candidaterev in candidaterevs:
1337 if debug_search:
1351 if debug_search:
1338 msg = b"DBG-DELTAS-SEARCH: CANDIDATE: rev=%d\n"
1352 msg = b"DBG-DELTAS-SEARCH: CANDIDATE: rev=%d\n"
1339 msg %= candidaterev
1353 msg %= candidaterev
1340 self._write_debug(msg)
1354 self._write_debug(msg)
1341 candidate_type = None
1355 candidate_type = None
1342 if candidaterev == p1:
1356 if candidaterev == p1:
1343 candidate_type = b"p1"
1357 candidate_type = b"p1"
1344 elif candidaterev == p2:
1358 elif candidaterev == p2:
1345 candidate_type = b"p2"
1359 candidate_type = b"p2"
1346 elif self.revlog.issnapshot(candidaterev):
1360 elif self.revlog.issnapshot(candidaterev):
1347 candidate_type = b"snapshot-%d"
1361 candidate_type = b"snapshot-%d"
1348 candidate_type %= self.revlog.snapshotdepth(
1362 candidate_type %= self.revlog.snapshotdepth(
1349 candidaterev
1363 candidaterev
1350 )
1364 )
1351
1365
1352 if candidate_type is not None:
1366 if candidate_type is not None:
1353 msg = b"DBG-DELTAS-SEARCH: type=%s\n"
1367 msg = b"DBG-DELTAS-SEARCH: type=%s\n"
1354 msg %= candidate_type
1368 msg %= candidate_type
1355 self._write_debug(msg)
1369 self._write_debug(msg)
1356 msg = b"DBG-DELTAS-SEARCH: size=%d\n"
1370 msg = b"DBG-DELTAS-SEARCH: size=%d\n"
1357 msg %= self.revlog.length(candidaterev)
1371 msg %= self.revlog.length(candidaterev)
1358 self._write_debug(msg)
1372 self._write_debug(msg)
1359 msg = b"DBG-DELTAS-SEARCH: base=%d\n"
1373 msg = b"DBG-DELTAS-SEARCH: base=%d\n"
1360 msg %= self.revlog.deltaparent(candidaterev)
1374 msg %= self.revlog.deltaparent(candidaterev)
1361 self._write_debug(msg)
1375 self._write_debug(msg)
1362
1376
1363 dbg_try_count += 1
1377 dbg_try_count += 1
1364
1378
1365 if debug_search:
1379 if debug_search:
1366 delta_start = util.timer()
1380 delta_start = util.timer()
1367 candidatedelta = self._builddeltainfo(revinfo, candidaterev, fh)
1381 candidatedelta = self._builddeltainfo(
1382 revinfo,
1383 candidaterev,
1384 fh,
1385 target_rev=target_rev,
1386 )
1368 if debug_search:
1387 if debug_search:
1369 delta_end = util.timer()
1388 delta_end = util.timer()
1370 msg = b"DBG-DELTAS-SEARCH: delta-search-time=%f\n"
1389 msg = b"DBG-DELTAS-SEARCH: delta-search-time=%f\n"
1371 msg %= delta_end - delta_start
1390 msg %= delta_end - delta_start
1372 self._write_debug(msg)
1391 self._write_debug(msg)
1373 if candidatedelta is not None:
1392 if candidatedelta is not None:
1374 if is_good_delta_info(self.revlog, candidatedelta, revinfo):
1393 if is_good_delta_info(self.revlog, candidatedelta, revinfo):
1375 if debug_search:
1394 if debug_search:
1376 msg = b"DBG-DELTAS-SEARCH: DELTA: length=%d (GOOD)\n"
1395 msg = b"DBG-DELTAS-SEARCH: DELTA: length=%d (GOOD)\n"
1377 msg %= candidatedelta.deltalen
1396 msg %= candidatedelta.deltalen
1378 self._write_debug(msg)
1397 self._write_debug(msg)
1379 nominateddeltas.append(candidatedelta)
1398 nominateddeltas.append(candidatedelta)
1380 elif debug_search:
1399 elif debug_search:
1381 msg = b"DBG-DELTAS-SEARCH: DELTA: length=%d (BAD)\n"
1400 msg = b"DBG-DELTAS-SEARCH: DELTA: length=%d (BAD)\n"
1382 msg %= candidatedelta.deltalen
1401 msg %= candidatedelta.deltalen
1383 self._write_debug(msg)
1402 self._write_debug(msg)
1384 elif debug_search:
1403 elif debug_search:
1385 msg = b"DBG-DELTAS-SEARCH: NO-DELTA\n"
1404 msg = b"DBG-DELTAS-SEARCH: NO-DELTA\n"
1386 self._write_debug(msg)
1405 self._write_debug(msg)
1387 if nominateddeltas:
1406 if nominateddeltas:
1388 deltainfo = min(nominateddeltas, key=lambda x: x.deltalen)
1407 deltainfo = min(nominateddeltas, key=lambda x: x.deltalen)
1389 if deltainfo is not None:
1408 if deltainfo is not None:
1390 candidaterevs = groups.send(deltainfo.base)
1409 candidaterevs = groups.send(deltainfo.base)
1391 else:
1410 else:
1392 candidaterevs = next(groups)
1411 candidaterevs = next(groups)
1393
1412
1394 if deltainfo is None:
1413 if deltainfo is None:
1395 dbg_type = b"full"
1414 dbg_type = b"full"
1396 deltainfo = self._fullsnapshotinfo(fh, revinfo, target_rev)
1415 deltainfo = self._fullsnapshotinfo(fh, revinfo, target_rev)
1397 elif deltainfo.snapshotdepth: # pytype: disable=attribute-error
1416 elif deltainfo.snapshotdepth: # pytype: disable=attribute-error
1398 dbg_type = b"snapshot"
1417 dbg_type = b"snapshot"
1399 else:
1418 else:
1400 dbg_type = b"delta"
1419 dbg_type = b"delta"
1401
1420
1402 if gather_debug:
1421 if gather_debug:
1403 end = util.timer()
1422 end = util.timer()
1404 if dbg_type == b'full':
1423 if dbg_type == b'full':
1405 used_cached = (
1424 used_cached = (
1406 cachedelta is not None
1425 cachedelta is not None
1407 and dbg_try_rounds == 0
1426 and dbg_try_rounds == 0
1408 and dbg_try_count == 0
1427 and dbg_try_count == 0
1409 and cachedelta[0] == nullrev
1428 and cachedelta[0] == nullrev
1410 )
1429 )
1411 else:
1430 else:
1412 used_cached = (
1431 used_cached = (
1413 cachedelta is not None
1432 cachedelta is not None
1414 and dbg_try_rounds == 1
1433 and dbg_try_rounds == 1
1415 and dbg_try_count == 1
1434 and dbg_try_count == 1
1416 and deltainfo.base == cachedelta[0]
1435 and deltainfo.base == cachedelta[0]
1417 )
1436 )
1418 dbg = {
1437 dbg = {
1419 'duration': end - start,
1438 'duration': end - start,
1420 'revision': target_rev,
1439 'revision': target_rev,
1421 'delta-base': deltainfo.base, # pytype: disable=attribute-error
1440 'delta-base': deltainfo.base, # pytype: disable=attribute-error
1422 'search_round_count': dbg_try_rounds,
1441 'search_round_count': dbg_try_rounds,
1423 'using-cached-base': used_cached,
1442 'using-cached-base': used_cached,
1424 'delta_try_count': dbg_try_count,
1443 'delta_try_count': dbg_try_count,
1425 'type': dbg_type,
1444 'type': dbg_type,
1426 'p1-chain-len': p1_chain_len,
1445 'p1-chain-len': p1_chain_len,
1427 'p2-chain-len': p2_chain_len,
1446 'p2-chain-len': p2_chain_len,
1428 }
1447 }
1429 if (
1448 if (
1430 deltainfo.snapshotdepth # pytype: disable=attribute-error
1449 deltainfo.snapshotdepth # pytype: disable=attribute-error
1431 is not None
1450 is not None
1432 ):
1451 ):
1433 dbg[
1452 dbg[
1434 'snapshot-depth'
1453 'snapshot-depth'
1435 ] = deltainfo.snapshotdepth # pytype: disable=attribute-error
1454 ] = deltainfo.snapshotdepth # pytype: disable=attribute-error
1436 else:
1455 else:
1437 dbg['snapshot-depth'] = 0
1456 dbg['snapshot-depth'] = 0
1438 target_revlog = b"UNKNOWN"
1457 target_revlog = b"UNKNOWN"
1439 target_type = self.revlog.target[0]
1458 target_type = self.revlog.target[0]
1440 target_key = self.revlog.target[1]
1459 target_key = self.revlog.target[1]
1441 if target_type == KIND_CHANGELOG:
1460 if target_type == KIND_CHANGELOG:
1442 target_revlog = b'CHANGELOG:'
1461 target_revlog = b'CHANGELOG:'
1443 elif target_type == KIND_MANIFESTLOG:
1462 elif target_type == KIND_MANIFESTLOG:
1444 target_revlog = b'MANIFESTLOG:'
1463 target_revlog = b'MANIFESTLOG:'
1445 if target_key:
1464 if target_key:
1446 target_revlog += b'%s:' % target_key
1465 target_revlog += b'%s:' % target_key
1447 elif target_type == KIND_FILELOG:
1466 elif target_type == KIND_FILELOG:
1448 target_revlog = b'FILELOG:'
1467 target_revlog = b'FILELOG:'
1449 if target_key:
1468 if target_key:
1450 target_revlog += b'%s:' % target_key
1469 target_revlog += b'%s:' % target_key
1451 dbg['target-revlog'] = target_revlog
1470 dbg['target-revlog'] = target_revlog
1452
1471
1453 if self._debug_info is not None:
1472 if self._debug_info is not None:
1454 self._debug_info.append(dbg)
1473 self._debug_info.append(dbg)
1455
1474
1456 if self._write_debug is not None:
1475 if self._write_debug is not None:
1457 msg = (
1476 msg = (
1458 b"DBG-DELTAS:"
1477 b"DBG-DELTAS:"
1459 b" %-12s"
1478 b" %-12s"
1460 b" rev=%d:"
1479 b" rev=%d:"
1461 b" delta-base=%d"
1480 b" delta-base=%d"
1462 b" is-cached=%d"
1481 b" is-cached=%d"
1463 b" - search-rounds=%d"
1482 b" - search-rounds=%d"
1464 b" try-count=%d"
1483 b" try-count=%d"
1465 b" - delta-type=%-6s"
1484 b" - delta-type=%-6s"
1466 b" snap-depth=%d"
1485 b" snap-depth=%d"
1467 b" - p1-chain-length=%d"
1486 b" - p1-chain-length=%d"
1468 b" p2-chain-length=%d"
1487 b" p2-chain-length=%d"
1469 b" - duration=%f"
1488 b" - duration=%f"
1470 b"\n"
1489 b"\n"
1471 )
1490 )
1472 msg %= (
1491 msg %= (
1473 dbg["target-revlog"],
1492 dbg["target-revlog"],
1474 dbg["revision"],
1493 dbg["revision"],
1475 dbg["delta-base"],
1494 dbg["delta-base"],
1476 dbg["using-cached-base"],
1495 dbg["using-cached-base"],
1477 dbg["search_round_count"],
1496 dbg["search_round_count"],
1478 dbg["delta_try_count"],
1497 dbg["delta_try_count"],
1479 dbg["type"],
1498 dbg["type"],
1480 dbg["snapshot-depth"],
1499 dbg["snapshot-depth"],
1481 dbg["p1-chain-len"],
1500 dbg["p1-chain-len"],
1482 dbg["p2-chain-len"],
1501 dbg["p2-chain-len"],
1483 dbg["duration"],
1502 dbg["duration"],
1484 )
1503 )
1485 self._write_debug(msg)
1504 self._write_debug(msg)
1486 return deltainfo
1505 return deltainfo
1487
1506
1488
1507
1489 def delta_compression(default_compression_header, deltainfo):
1508 def delta_compression(default_compression_header, deltainfo):
1490 """return (COMPRESSION_MODE, deltainfo)
1509 """return (COMPRESSION_MODE, deltainfo)
1491
1510
1492 used by revlog v2+ format to dispatch between PLAIN and DEFAULT
1511 used by revlog v2+ format to dispatch between PLAIN and DEFAULT
1493 compression.
1512 compression.
1494 """
1513 """
1495 h, d = deltainfo.data
1514 h, d = deltainfo.data
1496 compression_mode = COMP_MODE_INLINE
1515 compression_mode = COMP_MODE_INLINE
1497 if not h and not d:
1516 if not h and not d:
1498 # not data to store at all... declare them uncompressed
1517 # not data to store at all... declare them uncompressed
1499 compression_mode = COMP_MODE_PLAIN
1518 compression_mode = COMP_MODE_PLAIN
1500 elif not h:
1519 elif not h:
1501 t = d[0:1]
1520 t = d[0:1]
1502 if t == b'\0':
1521 if t == b'\0':
1503 compression_mode = COMP_MODE_PLAIN
1522 compression_mode = COMP_MODE_PLAIN
1504 elif t == default_compression_header:
1523 elif t == default_compression_header:
1505 compression_mode = COMP_MODE_DEFAULT
1524 compression_mode = COMP_MODE_DEFAULT
1506 elif h == b'u':
1525 elif h == b'u':
1507 # we have a more efficient way to declare uncompressed
1526 # we have a more efficient way to declare uncompressed
1508 h = b''
1527 h = b''
1509 compression_mode = COMP_MODE_PLAIN
1528 compression_mode = COMP_MODE_PLAIN
1510 deltainfo = drop_u_compression(deltainfo)
1529 deltainfo = drop_u_compression(deltainfo)
1511 return compression_mode, deltainfo
1530 return compression_mode, deltainfo
@@ -1,955 +1,960 b''
1 # transaction.py - simple journaling scheme for mercurial
1 # transaction.py - simple journaling scheme for mercurial
2 #
2 #
3 # This transaction scheme is intended to gracefully handle program
3 # This transaction scheme is intended to gracefully handle program
4 # errors and interruptions. More serious failures like system crashes
4 # errors and interruptions. More serious failures like system crashes
5 # can be recovered with an fsck-like tool. As the whole repository is
5 # can be recovered with an fsck-like tool. As the whole repository is
6 # effectively log-structured, this should amount to simply truncating
6 # effectively log-structured, this should amount to simply truncating
7 # anything that isn't referenced in the changelog.
7 # anything that isn't referenced in the changelog.
8 #
8 #
9 # Copyright 2005, 2006 Olivia Mackall <olivia@selenic.com>
9 # Copyright 2005, 2006 Olivia Mackall <olivia@selenic.com>
10 #
10 #
11 # This software may be used and distributed according to the terms of the
11 # This software may be used and distributed according to the terms of the
12 # GNU General Public License version 2 or any later version.
12 # GNU General Public License version 2 or any later version.
13
13
14 import errno
14 import errno
15 import os
15 import os
16
16
17 from .i18n import _
17 from .i18n import _
18 from . import (
18 from . import (
19 error,
19 error,
20 pycompat,
20 pycompat,
21 util,
21 util,
22 )
22 )
23 from .utils import stringutil
23 from .utils import stringutil
24
24
25 version = 2
25 version = 2
26
26
27 GEN_GROUP_ALL = b'all'
27 GEN_GROUP_ALL = b'all'
28 GEN_GROUP_PRE_FINALIZE = b'prefinalize'
28 GEN_GROUP_PRE_FINALIZE = b'prefinalize'
29 GEN_GROUP_POST_FINALIZE = b'postfinalize'
29 GEN_GROUP_POST_FINALIZE = b'postfinalize'
30
30
31
31
32 def active(func):
32 def active(func):
33 def _active(self, *args, **kwds):
33 def _active(self, *args, **kwds):
34 if self._count == 0:
34 if self._count == 0:
35 raise error.ProgrammingError(
35 raise error.ProgrammingError(
36 b'cannot use transaction when it is already committed/aborted'
36 b'cannot use transaction when it is already committed/aborted'
37 )
37 )
38 return func(self, *args, **kwds)
38 return func(self, *args, **kwds)
39
39
40 return _active
40 return _active
41
41
42
42
43 UNDO_BACKUP = b'%s.backupfiles'
43 UNDO_BACKUP = b'%s.backupfiles'
44
44
45 UNDO_FILES_MAY_NEED_CLEANUP = [
45 UNDO_FILES_MAY_NEED_CLEANUP = [
46 # legacy entries that might exists on disk from previous version:
46 # legacy entries that might exists on disk from previous version:
47 (b'store', b'%s.narrowspec'),
47 (b'store', b'%s.narrowspec'),
48 (b'plain', b'%s.narrowspec.dirstate'),
48 (b'plain', b'%s.narrowspec.dirstate'),
49 (b'plain', b'%s.branch'),
49 (b'plain', b'%s.branch'),
50 (b'plain', b'%s.bookmarks'),
50 (b'plain', b'%s.bookmarks'),
51 (b'store', b'%s.phaseroots'),
51 (b'store', b'%s.phaseroots'),
52 (b'plain', b'%s.dirstate'),
52 (b'plain', b'%s.dirstate'),
53 # files actually in uses today:
53 # files actually in uses today:
54 (b'plain', b'%s.desc'),
54 (b'plain', b'%s.desc'),
55 # Always delete undo last to make sure we detect that a clean up is needed if
55 # Always delete undo last to make sure we detect that a clean up is needed if
56 # the process is interrupted.
56 # the process is interrupted.
57 (b'store', b'%s'),
57 (b'store', b'%s'),
58 ]
58 ]
59
59
60
60
61 def cleanup_undo_files(report, vfsmap, undo_prefix=b'undo'):
61 def cleanup_undo_files(report, vfsmap, undo_prefix=b'undo'):
62 """remove "undo" files used by the rollback logic
62 """remove "undo" files used by the rollback logic
63
63
64 This is useful to prevent rollback running in situation were it does not
64 This is useful to prevent rollback running in situation were it does not
65 make sense. For example after a strip.
65 make sense. For example after a strip.
66 """
66 """
67 backup_listing = UNDO_BACKUP % undo_prefix
67 backup_listing = UNDO_BACKUP % undo_prefix
68
68
69 backup_entries = []
69 backup_entries = []
70 undo_files = []
70 undo_files = []
71 svfs = vfsmap[b'store']
71 svfs = vfsmap[b'store']
72 try:
72 try:
73 with svfs(backup_listing) as f:
73 with svfs(backup_listing) as f:
74 backup_entries = read_backup_files(report, f)
74 backup_entries = read_backup_files(report, f)
75 except OSError as e:
75 except OSError as e:
76 if e.errno != errno.ENOENT:
76 if e.errno != errno.ENOENT:
77 msg = _(b'could not read %s: %s\n')
77 msg = _(b'could not read %s: %s\n')
78 msg %= (svfs.join(backup_listing), stringutil.forcebytestr(e))
78 msg %= (svfs.join(backup_listing), stringutil.forcebytestr(e))
79 report(msg)
79 report(msg)
80
80
81 for location, f, backup_path, c in backup_entries:
81 for location, f, backup_path, c in backup_entries:
82 if location in vfsmap and backup_path:
82 if location in vfsmap and backup_path:
83 undo_files.append((vfsmap[location], backup_path))
83 undo_files.append((vfsmap[location], backup_path))
84
84
85 undo_files.append((svfs, backup_listing))
85 undo_files.append((svfs, backup_listing))
86 for location, undo_path in UNDO_FILES_MAY_NEED_CLEANUP:
86 for location, undo_path in UNDO_FILES_MAY_NEED_CLEANUP:
87 undo_files.append((vfsmap[location], undo_path % undo_prefix))
87 undo_files.append((vfsmap[location], undo_path % undo_prefix))
88 for undovfs, undofile in undo_files:
88 for undovfs, undofile in undo_files:
89 try:
89 try:
90 undovfs.unlink(undofile)
90 undovfs.unlink(undofile)
91 except OSError as e:
91 except OSError as e:
92 if e.errno != errno.ENOENT:
92 if e.errno != errno.ENOENT:
93 msg = _(b'error removing %s: %s\n')
93 msg = _(b'error removing %s: %s\n')
94 msg %= (undovfs.join(undofile), stringutil.forcebytestr(e))
94 msg %= (undovfs.join(undofile), stringutil.forcebytestr(e))
95 report(msg)
95 report(msg)
96
96
97
97
98 def _playback(
98 def _playback(
99 journal,
99 journal,
100 report,
100 report,
101 opener,
101 opener,
102 vfsmap,
102 vfsmap,
103 entries,
103 entries,
104 backupentries,
104 backupentries,
105 unlink=True,
105 unlink=True,
106 checkambigfiles=None,
106 checkambigfiles=None,
107 ):
107 ):
108 """rollback a transaction :
108 """rollback a transaction :
109 - truncate files that have been appended to
109 - truncate files that have been appended to
110 - restore file backups
110 - restore file backups
111 - delete temporary files
111 - delete temporary files
112 """
112 """
113 backupfiles = []
113 backupfiles = []
114
114
115 def restore_one_backup(vfs, f, b, checkambig):
115 def restore_one_backup(vfs, f, b, checkambig):
116 filepath = vfs.join(f)
116 filepath = vfs.join(f)
117 backuppath = vfs.join(b)
117 backuppath = vfs.join(b)
118 try:
118 try:
119 util.copyfile(backuppath, filepath, checkambig=checkambig)
119 util.copyfile(backuppath, filepath, checkambig=checkambig)
120 backupfiles.append((vfs, b))
120 backupfiles.append((vfs, b))
121 except IOError as exc:
121 except IOError as exc:
122 e_msg = stringutil.forcebytestr(exc)
122 e_msg = stringutil.forcebytestr(exc)
123 report(_(b"failed to recover %s (%s)\n") % (f, e_msg))
123 report(_(b"failed to recover %s (%s)\n") % (f, e_msg))
124 raise
124 raise
125
125
126 # gather all backup files that impact the store
126 # gather all backup files that impact the store
127 # (we need this to detect files that are both backed up and truncated)
127 # (we need this to detect files that are both backed up and truncated)
128 store_backup = {}
128 store_backup = {}
129 for entry in backupentries:
129 for entry in backupentries:
130 location, file_path, backup_path, cache = entry
130 location, file_path, backup_path, cache = entry
131 vfs = vfsmap[location]
131 vfs = vfsmap[location]
132 is_store = vfs.join(b'') == opener.join(b'')
132 is_store = vfs.join(b'') == opener.join(b'')
133 if is_store and file_path and backup_path:
133 if is_store and file_path and backup_path:
134 store_backup[file_path] = entry
134 store_backup[file_path] = entry
135 copy_done = set()
135 copy_done = set()
136
136
137 # truncate all file `f` to offset `o`
137 # truncate all file `f` to offset `o`
138 for f, o in sorted(dict(entries).items()):
138 for f, o in sorted(dict(entries).items()):
139 # if we have a backup for `f`, we should restore it first and truncate
139 # if we have a backup for `f`, we should restore it first and truncate
140 # the restored file
140 # the restored file
141 bck_entry = store_backup.get(f)
141 bck_entry = store_backup.get(f)
142 if bck_entry is not None:
142 if bck_entry is not None:
143 location, file_path, backup_path, cache = bck_entry
143 location, file_path, backup_path, cache = bck_entry
144 checkambig = False
144 checkambig = False
145 if checkambigfiles:
145 if checkambigfiles:
146 checkambig = (file_path, location) in checkambigfiles
146 checkambig = (file_path, location) in checkambigfiles
147 restore_one_backup(opener, file_path, backup_path, checkambig)
147 restore_one_backup(opener, file_path, backup_path, checkambig)
148 copy_done.add(bck_entry)
148 copy_done.add(bck_entry)
149 # truncate the file to its pre-transaction size
149 # truncate the file to its pre-transaction size
150 if o or not unlink:
150 if o or not unlink:
151 checkambig = checkambigfiles and (f, b'') in checkambigfiles
151 checkambig = checkambigfiles and (f, b'') in checkambigfiles
152 try:
152 try:
153 fp = opener(f, b'a', checkambig=checkambig)
153 fp = opener(f, b'a', checkambig=checkambig)
154 if fp.tell() < o:
154 if fp.tell() < o:
155 raise error.Abort(
155 raise error.Abort(
156 _(
156 _(
157 b"attempted to truncate %s to %d bytes, but it was "
157 b"attempted to truncate %s to %d bytes, but it was "
158 b"already %d bytes\n"
158 b"already %d bytes\n"
159 )
159 )
160 % (f, o, fp.tell())
160 % (f, o, fp.tell())
161 )
161 )
162 fp.truncate(o)
162 fp.truncate(o)
163 fp.close()
163 fp.close()
164 except IOError:
164 except IOError:
165 report(_(b"failed to truncate %s\n") % f)
165 report(_(b"failed to truncate %s\n") % f)
166 raise
166 raise
167 else:
167 else:
168 # delete empty file
168 # delete empty file
169 try:
169 try:
170 opener.unlink(f)
170 opener.unlink(f)
171 except FileNotFoundError:
171 except FileNotFoundError:
172 pass
172 pass
173 # restore backed up files and clean up temporary files
173 # restore backed up files and clean up temporary files
174 for entry in backupentries:
174 for entry in backupentries:
175 if entry in copy_done:
175 if entry in copy_done:
176 continue
176 continue
177 l, f, b, c = entry
177 l, f, b, c = entry
178 if l not in vfsmap and c:
178 if l not in vfsmap and c:
179 report(b"couldn't handle %s: unknown cache location %s\n" % (b, l))
179 report(b"couldn't handle %s: unknown cache location %s\n" % (b, l))
180 vfs = vfsmap[l]
180 vfs = vfsmap[l]
181 try:
181 try:
182 checkambig = checkambigfiles and (f, l) in checkambigfiles
182 checkambig = checkambigfiles and (f, l) in checkambigfiles
183 if f and b:
183 if f and b:
184 restore_one_backup(vfs, f, b, checkambig)
184 restore_one_backup(vfs, f, b, checkambig)
185 else:
185 else:
186 target = f or b
186 target = f or b
187 try:
187 try:
188 vfs.unlink(target)
188 vfs.unlink(target)
189 except FileNotFoundError:
189 except FileNotFoundError:
190 # This is fine because
190 # This is fine because
191 #
191 #
192 # either we are trying to delete the main file, and it is
192 # either we are trying to delete the main file, and it is
193 # already deleted.
193 # already deleted.
194 #
194 #
195 # or we are trying to delete a temporary file and it is
195 # or we are trying to delete a temporary file and it is
196 # already deleted.
196 # already deleted.
197 #
197 #
198 # in both case, our target result (delete the file) is
198 # in both case, our target result (delete the file) is
199 # already achieved.
199 # already achieved.
200 pass
200 pass
201 except (IOError, OSError, error.Abort):
201 except (IOError, OSError, error.Abort):
202 if not c:
202 if not c:
203 raise
203 raise
204
204
205 # cleanup transaction state file and the backups file
205 # cleanup transaction state file and the backups file
206 backuppath = b"%s.backupfiles" % journal
206 backuppath = b"%s.backupfiles" % journal
207 if opener.exists(backuppath):
207 if opener.exists(backuppath):
208 opener.unlink(backuppath)
208 opener.unlink(backuppath)
209 opener.unlink(journal)
209 opener.unlink(journal)
210 try:
210 try:
211 for vfs, f in backupfiles:
211 for vfs, f in backupfiles:
212 if vfs.exists(f):
212 if vfs.exists(f):
213 vfs.unlink(f)
213 vfs.unlink(f)
214 except (IOError, OSError, error.Abort):
214 except (IOError, OSError, error.Abort):
215 # only pure backup file remains, it is sage to ignore any error
215 # only pure backup file remains, it is sage to ignore any error
216 pass
216 pass
217
217
218
218
219 class transaction(util.transactional):
219 class transaction(util.transactional):
220 def __init__(
220 def __init__(
221 self,
221 self,
222 report,
222 report,
223 opener,
223 opener,
224 vfsmap,
224 vfsmap,
225 journalname,
225 journalname,
226 undoname=None,
226 undoname=None,
227 after=None,
227 after=None,
228 createmode=None,
228 createmode=None,
229 validator=None,
229 validator=None,
230 releasefn=None,
230 releasefn=None,
231 checkambigfiles=None,
231 checkambigfiles=None,
232 name='<unnamed>',
232 name='<unnamed>',
233 ):
233 ):
234 """Begin a new transaction
234 """Begin a new transaction
235
235
236 Begins a new transaction that allows rolling back writes in the event of
236 Begins a new transaction that allows rolling back writes in the event of
237 an exception.
237 an exception.
238
238
239 * `after`: called after the transaction has been committed
239 * `after`: called after the transaction has been committed
240 * `createmode`: the mode of the journal file that will be created
240 * `createmode`: the mode of the journal file that will be created
241 * `releasefn`: called after releasing (with transaction and result)
241 * `releasefn`: called after releasing (with transaction and result)
242
242
243 `checkambigfiles` is a set of (path, vfs-location) tuples,
243 `checkambigfiles` is a set of (path, vfs-location) tuples,
244 which determine whether file stat ambiguity should be avoided
244 which determine whether file stat ambiguity should be avoided
245 for corresponded files.
245 for corresponded files.
246 """
246 """
247 self._count = 1
247 self._count = 1
248 self._usages = 1
248 self._usages = 1
249 self._report = report
249 self._report = report
250 # a vfs to the store content
250 # a vfs to the store content
251 self._opener = opener
251 self._opener = opener
252 # a map to access file in various {location -> vfs}
252 # a map to access file in various {location -> vfs}
253 vfsmap = vfsmap.copy()
253 vfsmap = vfsmap.copy()
254 vfsmap[b''] = opener # set default value
254 vfsmap[b''] = opener # set default value
255 self._vfsmap = vfsmap
255 self._vfsmap = vfsmap
256 self._after = after
256 self._after = after
257 self._offsetmap = {}
257 self._offsetmap = {}
258 self._newfiles = set()
258 self._newfiles = set()
259 self._journal = journalname
259 self._journal = journalname
260 self._journal_files = []
260 self._journal_files = []
261 self._undoname = undoname
261 self._undoname = undoname
262 self._queue = []
262 self._queue = []
263 # A callback to do something just after releasing transaction.
263 # A callback to do something just after releasing transaction.
264 if releasefn is None:
264 if releasefn is None:
265 releasefn = lambda tr, success: None
265 releasefn = lambda tr, success: None
266 self._releasefn = releasefn
266 self._releasefn = releasefn
267
267
268 self._checkambigfiles = set()
268 self._checkambigfiles = set()
269 if checkambigfiles:
269 if checkambigfiles:
270 self._checkambigfiles.update(checkambigfiles)
270 self._checkambigfiles.update(checkambigfiles)
271
271
272 self._names = [name]
272 self._names = [name]
273
273
274 # A dict dedicated to precisely tracking the changes introduced in the
274 # A dict dedicated to precisely tracking the changes introduced in the
275 # transaction.
275 # transaction.
276 self.changes = {}
276 self.changes = {}
277
277
278 # a dict of arguments to be passed to hooks
278 # a dict of arguments to be passed to hooks
279 self.hookargs = {}
279 self.hookargs = {}
280 self._file = opener.open(self._journal, b"w+")
280 self._file = opener.open(self._journal, b"w+")
281
281
282 # a list of ('location', 'path', 'backuppath', cache) entries.
282 # a list of ('location', 'path', 'backuppath', cache) entries.
283 # - if 'backuppath' is empty, no file existed at backup time
283 # - if 'backuppath' is empty, no file existed at backup time
284 # - if 'path' is empty, this is a temporary transaction file
284 # - if 'path' is empty, this is a temporary transaction file
285 # - if 'location' is not empty, the path is outside main opener reach.
285 # - if 'location' is not empty, the path is outside main opener reach.
286 # use 'location' value as a key in a vfsmap to find the right 'vfs'
286 # use 'location' value as a key in a vfsmap to find the right 'vfs'
287 # (cache is currently unused)
287 # (cache is currently unused)
288 self._backupentries = []
288 self._backupentries = []
289 self._backupmap = {}
289 self._backupmap = {}
290 self._backupjournal = b"%s.backupfiles" % self._journal
290 self._backupjournal = b"%s.backupfiles" % self._journal
291 self._backupsfile = opener.open(self._backupjournal, b'w')
291 self._backupsfile = opener.open(self._backupjournal, b'w')
292 self._backupsfile.write(b'%d\n' % version)
292 self._backupsfile.write(b'%d\n' % version)
293
293
294 if createmode is not None:
294 if createmode is not None:
295 opener.chmod(self._journal, createmode & 0o666)
295 opener.chmod(self._journal, createmode & 0o666)
296 opener.chmod(self._backupjournal, createmode & 0o666)
296 opener.chmod(self._backupjournal, createmode & 0o666)
297
297
298 # hold file generations to be performed on commit
298 # hold file generations to be performed on commit
299 self._filegenerators = {}
299 self._filegenerators = {}
300 # hold callback to write pending data for hooks
300 # hold callback to write pending data for hooks
301 self._pendingcallback = {}
301 self._pendingcallback = {}
302 # True is any pending data have been written ever
302 # True is any pending data have been written ever
303 self._anypending = False
303 self._anypending = False
304 # holds callback to call when writing the transaction
304 # holds callback to call when writing the transaction
305 self._finalizecallback = {}
305 self._finalizecallback = {}
306 # holds callback to call when validating the transaction
306 # holds callback to call when validating the transaction
307 # should raise exception if anything is wrong
307 # should raise exception if anything is wrong
308 self._validatecallback = {}
308 self._validatecallback = {}
309 if validator is not None:
309 if validator is not None:
310 self._validatecallback[b'001-userhooks'] = validator
310 self._validatecallback[b'001-userhooks'] = validator
311 # hold callback for post transaction close
311 # hold callback for post transaction close
312 self._postclosecallback = {}
312 self._postclosecallback = {}
313 # holds callbacks to call during abort
313 # holds callbacks to call during abort
314 self._abortcallback = {}
314 self._abortcallback = {}
315
315
316 def __repr__(self):
316 def __repr__(self):
317 name = b'/'.join(self._names)
317 name = b'/'.join(self._names)
318 return '<transaction name=%s, count=%d, usages=%d>' % (
318 return '<transaction name=%s, count=%d, usages=%d>' % (
319 name,
319 name,
320 self._count,
320 self._count,
321 self._usages,
321 self._usages,
322 )
322 )
323
323
324 def __del__(self):
324 def __del__(self):
325 if self._journal:
325 if self._journal:
326 self._abort()
326 self._abort()
327
327
328 @property
328 @property
329 def finalized(self):
329 def finalized(self):
330 return self._finalizecallback is None
330 return self._finalizecallback is None
331
331
332 @active
332 @active
333 def startgroup(self):
333 def startgroup(self):
334 """delay registration of file entry
334 """delay registration of file entry
335
335
336 This is used by strip to delay vision of strip offset. The transaction
336 This is used by strip to delay vision of strip offset. The transaction
337 sees either none or all of the strip actions to be done."""
337 sees either none or all of the strip actions to be done."""
338 self._queue.append([])
338 self._queue.append([])
339
339
340 @active
340 @active
341 def endgroup(self):
341 def endgroup(self):
342 """apply delayed registration of file entry.
342 """apply delayed registration of file entry.
343
343
344 This is used by strip to delay vision of strip offset. The transaction
344 This is used by strip to delay vision of strip offset. The transaction
345 sees either none or all of the strip actions to be done."""
345 sees either none or all of the strip actions to be done."""
346 q = self._queue.pop()
346 q = self._queue.pop()
347 for f, o in q:
347 for f, o in q:
348 self._addentry(f, o)
348 self._addentry(f, o)
349
349
350 @active
350 @active
351 def add(self, file, offset):
351 def add(self, file, offset):
352 """record the state of an append-only file before update"""
352 """record the state of an append-only file before update"""
353 if (
353 if (
354 file in self._newfiles
354 file in self._newfiles
355 or file in self._offsetmap
355 or file in self._offsetmap
356 or file in self._backupmap
356 or file in self._backupmap
357 ):
357 ):
358 return
358 return
359 if self._queue:
359 if self._queue:
360 self._queue[-1].append((file, offset))
360 self._queue[-1].append((file, offset))
361 return
361 return
362
362
363 self._addentry(file, offset)
363 self._addentry(file, offset)
364
364
365 def _addentry(self, file, offset):
365 def _addentry(self, file, offset):
366 """add a append-only entry to memory and on-disk state"""
366 """add a append-only entry to memory and on-disk state"""
367 if (
367 if (
368 file in self._newfiles
368 file in self._newfiles
369 or file in self._offsetmap
369 or file in self._offsetmap
370 or file in self._backupmap
370 or file in self._backupmap
371 ):
371 ):
372 return
372 return
373 if offset:
373 if offset:
374 self._offsetmap[file] = offset
374 self._offsetmap[file] = offset
375 else:
375 else:
376 self._newfiles.add(file)
376 self._newfiles.add(file)
377 # add enough data to the journal to do the truncate
377 # add enough data to the journal to do the truncate
378 self._file.write(b"%s\0%d\n" % (file, offset))
378 self._file.write(b"%s\0%d\n" % (file, offset))
379 self._file.flush()
379 self._file.flush()
380
380
381 @active
381 @active
382 def addbackup(self, file, hardlink=True, location=b'', for_offset=False):
382 def addbackup(self, file, hardlink=True, location=b'', for_offset=False):
383 """Adds a backup of the file to the transaction
383 """Adds a backup of the file to the transaction
384
384
385 Calling addbackup() creates a hardlink backup of the specified file
385 Calling addbackup() creates a hardlink backup of the specified file
386 that is used to recover the file in the event of the transaction
386 that is used to recover the file in the event of the transaction
387 aborting.
387 aborting.
388
388
389 * `file`: the file path, relative to .hg/store
389 * `file`: the file path, relative to .hg/store
390 * `hardlink`: use a hardlink to quickly create the backup
390 * `hardlink`: use a hardlink to quickly create the backup
391
391
392 If `for_offset` is set, we expect a offset for this file to have been previously recorded
392 If `for_offset` is set, we expect a offset for this file to have been previously recorded
393 """
393 """
394 if self._queue:
394 if self._queue:
395 msg = b'cannot use transaction.addbackup inside "group"'
395 msg = b'cannot use transaction.addbackup inside "group"'
396 raise error.ProgrammingError(msg)
396 raise error.ProgrammingError(msg)
397
397
398 if file in self._newfiles or file in self._backupmap:
398 if file in self._newfiles or file in self._backupmap:
399 return
399 return
400 elif file in self._offsetmap and not for_offset:
400 elif file in self._offsetmap and not for_offset:
401 return
401 return
402 elif for_offset and file not in self._offsetmap:
402 elif for_offset and file not in self._offsetmap:
403 msg = (
403 msg = (
404 'calling `addbackup` with `for_offmap=True`, '
404 'calling `addbackup` with `for_offmap=True`, '
405 'but no offset recorded: [%r] %r'
405 'but no offset recorded: [%r] %r'
406 )
406 )
407 msg %= (location, file)
407 msg %= (location, file)
408 raise error.ProgrammingError(msg)
408 raise error.ProgrammingError(msg)
409
409
410 vfs = self._vfsmap[location]
410 vfs = self._vfsmap[location]
411 dirname, filename = vfs.split(file)
411 dirname, filename = vfs.split(file)
412 backupfilename = b"%s.backup.%s" % (self._journal, filename)
412 backupfilename = b"%s.backup.%s" % (self._journal, filename)
413 backupfile = vfs.reljoin(dirname, backupfilename)
413 backupfile = vfs.reljoin(dirname, backupfilename)
414 if vfs.exists(file):
414 if vfs.exists(file):
415 filepath = vfs.join(file)
415 filepath = vfs.join(file)
416 backuppath = vfs.join(backupfile)
416 backuppath = vfs.join(backupfile)
417 # store encoding may result in different directory here.
418 # so we have to ensure the destination directory exist
419 final_dir_name = os.path.dirname(backuppath)
420 util.makedirs(final_dir_name, mode=vfs.createmode, notindexed=True)
421 # then we can copy the backup
417 util.copyfile(filepath, backuppath, hardlink=hardlink)
422 util.copyfile(filepath, backuppath, hardlink=hardlink)
418 else:
423 else:
419 backupfile = b''
424 backupfile = b''
420
425
421 self._addbackupentry((location, file, backupfile, False))
426 self._addbackupentry((location, file, backupfile, False))
422
427
423 def _addbackupentry(self, entry):
428 def _addbackupentry(self, entry):
424 """register a new backup entry and write it to disk"""
429 """register a new backup entry and write it to disk"""
425 self._backupentries.append(entry)
430 self._backupentries.append(entry)
426 self._backupmap[entry[1]] = len(self._backupentries) - 1
431 self._backupmap[entry[1]] = len(self._backupentries) - 1
427 self._backupsfile.write(b"%s\0%s\0%s\0%d\n" % entry)
432 self._backupsfile.write(b"%s\0%s\0%s\0%d\n" % entry)
428 self._backupsfile.flush()
433 self._backupsfile.flush()
429
434
430 @active
435 @active
431 def registertmp(self, tmpfile, location=b''):
436 def registertmp(self, tmpfile, location=b''):
432 """register a temporary transaction file
437 """register a temporary transaction file
433
438
434 Such files will be deleted when the transaction exits (on both
439 Such files will be deleted when the transaction exits (on both
435 failure and success).
440 failure and success).
436 """
441 """
437 self._addbackupentry((location, b'', tmpfile, False))
442 self._addbackupentry((location, b'', tmpfile, False))
438
443
439 @active
444 @active
440 def addfilegenerator(
445 def addfilegenerator(
441 self,
446 self,
442 genid,
447 genid,
443 filenames,
448 filenames,
444 genfunc,
449 genfunc,
445 order=0,
450 order=0,
446 location=b'',
451 location=b'',
447 post_finalize=False,
452 post_finalize=False,
448 ):
453 ):
449 """add a function to generates some files at transaction commit
454 """add a function to generates some files at transaction commit
450
455
451 The `genfunc` argument is a function capable of generating proper
456 The `genfunc` argument is a function capable of generating proper
452 content of each entry in the `filename` tuple.
457 content of each entry in the `filename` tuple.
453
458
454 At transaction close time, `genfunc` will be called with one file
459 At transaction close time, `genfunc` will be called with one file
455 object argument per entries in `filenames`.
460 object argument per entries in `filenames`.
456
461
457 The transaction itself is responsible for the backup, creation and
462 The transaction itself is responsible for the backup, creation and
458 final write of such file.
463 final write of such file.
459
464
460 The `genid` argument is used to ensure the same set of file is only
465 The `genid` argument is used to ensure the same set of file is only
461 generated once. Call to `addfilegenerator` for a `genid` already
466 generated once. Call to `addfilegenerator` for a `genid` already
462 present will overwrite the old entry.
467 present will overwrite the old entry.
463
468
464 The `order` argument may be used to control the order in which multiple
469 The `order` argument may be used to control the order in which multiple
465 generator will be executed.
470 generator will be executed.
466
471
467 The `location` arguments may be used to indicate the files are located
472 The `location` arguments may be used to indicate the files are located
468 outside of the the standard directory for transaction. It should match
473 outside of the the standard directory for transaction. It should match
469 one of the key of the `transaction.vfsmap` dictionary.
474 one of the key of the `transaction.vfsmap` dictionary.
470
475
471 The `post_finalize` argument can be set to `True` for file generation
476 The `post_finalize` argument can be set to `True` for file generation
472 that must be run after the transaction has been finalized.
477 that must be run after the transaction has been finalized.
473 """
478 """
474 # For now, we are unable to do proper backup and restore of custom vfs
479 # For now, we are unable to do proper backup and restore of custom vfs
475 # but for bookmarks that are handled outside this mechanism.
480 # but for bookmarks that are handled outside this mechanism.
476 entry = (order, filenames, genfunc, location, post_finalize)
481 entry = (order, filenames, genfunc, location, post_finalize)
477 self._filegenerators[genid] = entry
482 self._filegenerators[genid] = entry
478
483
479 @active
484 @active
480 def removefilegenerator(self, genid):
485 def removefilegenerator(self, genid):
481 """reverse of addfilegenerator, remove a file generator function"""
486 """reverse of addfilegenerator, remove a file generator function"""
482 if genid in self._filegenerators:
487 if genid in self._filegenerators:
483 del self._filegenerators[genid]
488 del self._filegenerators[genid]
484
489
485 def _generatefiles(self, suffix=b'', group=GEN_GROUP_ALL):
490 def _generatefiles(self, suffix=b'', group=GEN_GROUP_ALL):
486 # write files registered for generation
491 # write files registered for generation
487 any = False
492 any = False
488
493
489 if group == GEN_GROUP_ALL:
494 if group == GEN_GROUP_ALL:
490 skip_post = skip_pre = False
495 skip_post = skip_pre = False
491 else:
496 else:
492 skip_pre = group == GEN_GROUP_POST_FINALIZE
497 skip_pre = group == GEN_GROUP_POST_FINALIZE
493 skip_post = group == GEN_GROUP_PRE_FINALIZE
498 skip_post = group == GEN_GROUP_PRE_FINALIZE
494
499
495 for id, entry in sorted(self._filegenerators.items()):
500 for id, entry in sorted(self._filegenerators.items()):
496 any = True
501 any = True
497 order, filenames, genfunc, location, post_finalize = entry
502 order, filenames, genfunc, location, post_finalize = entry
498
503
499 # for generation at closing, check if it's before or after finalize
504 # for generation at closing, check if it's before or after finalize
500 if skip_post and post_finalize:
505 if skip_post and post_finalize:
501 continue
506 continue
502 elif skip_pre and not post_finalize:
507 elif skip_pre and not post_finalize:
503 continue
508 continue
504
509
505 vfs = self._vfsmap[location]
510 vfs = self._vfsmap[location]
506 files = []
511 files = []
507 try:
512 try:
508 for name in filenames:
513 for name in filenames:
509 name += suffix
514 name += suffix
510 if suffix:
515 if suffix:
511 self.registertmp(name, location=location)
516 self.registertmp(name, location=location)
512 checkambig = False
517 checkambig = False
513 else:
518 else:
514 self.addbackup(name, location=location)
519 self.addbackup(name, location=location)
515 checkambig = (name, location) in self._checkambigfiles
520 checkambig = (name, location) in self._checkambigfiles
516 files.append(
521 files.append(
517 vfs(name, b'w', atomictemp=True, checkambig=checkambig)
522 vfs(name, b'w', atomictemp=True, checkambig=checkambig)
518 )
523 )
519 genfunc(*files)
524 genfunc(*files)
520 for f in files:
525 for f in files:
521 f.close()
526 f.close()
522 # skip discard() loop since we're sure no open file remains
527 # skip discard() loop since we're sure no open file remains
523 del files[:]
528 del files[:]
524 finally:
529 finally:
525 for f in files:
530 for f in files:
526 f.discard()
531 f.discard()
527 return any
532 return any
528
533
529 @active
534 @active
530 def findoffset(self, file):
535 def findoffset(self, file):
531 if file in self._newfiles:
536 if file in self._newfiles:
532 return 0
537 return 0
533 return self._offsetmap.get(file)
538 return self._offsetmap.get(file)
534
539
535 @active
540 @active
536 def readjournal(self):
541 def readjournal(self):
537 self._file.seek(0)
542 self._file.seek(0)
538 entries = []
543 entries = []
539 for l in self._file.readlines():
544 for l in self._file.readlines():
540 file, troffset = l.split(b'\0')
545 file, troffset = l.split(b'\0')
541 entries.append((file, int(troffset)))
546 entries.append((file, int(troffset)))
542 return entries
547 return entries
543
548
544 @active
549 @active
545 def replace(self, file, offset):
550 def replace(self, file, offset):
546 """
551 """
547 replace can only replace already committed entries
552 replace can only replace already committed entries
548 that are not pending in the queue
553 that are not pending in the queue
549 """
554 """
550 if file in self._newfiles:
555 if file in self._newfiles:
551 if not offset:
556 if not offset:
552 return
557 return
553 self._newfiles.remove(file)
558 self._newfiles.remove(file)
554 self._offsetmap[file] = offset
559 self._offsetmap[file] = offset
555 elif file in self._offsetmap:
560 elif file in self._offsetmap:
556 if not offset:
561 if not offset:
557 del self._offsetmap[file]
562 del self._offsetmap[file]
558 self._newfiles.add(file)
563 self._newfiles.add(file)
559 else:
564 else:
560 self._offsetmap[file] = offset
565 self._offsetmap[file] = offset
561 else:
566 else:
562 raise KeyError(file)
567 raise KeyError(file)
563 self._file.write(b"%s\0%d\n" % (file, offset))
568 self._file.write(b"%s\0%d\n" % (file, offset))
564 self._file.flush()
569 self._file.flush()
565
570
566 @active
571 @active
567 def nest(self, name='<unnamed>'):
572 def nest(self, name='<unnamed>'):
568 self._count += 1
573 self._count += 1
569 self._usages += 1
574 self._usages += 1
570 self._names.append(name)
575 self._names.append(name)
571 return self
576 return self
572
577
573 def release(self):
578 def release(self):
574 if self._count > 0:
579 if self._count > 0:
575 self._usages -= 1
580 self._usages -= 1
576 if self._names:
581 if self._names:
577 self._names.pop()
582 self._names.pop()
578 # if the transaction scopes are left without being closed, fail
583 # if the transaction scopes are left without being closed, fail
579 if self._count > 0 and self._usages == 0:
584 if self._count > 0 and self._usages == 0:
580 self._abort()
585 self._abort()
581
586
582 def running(self):
587 def running(self):
583 return self._count > 0
588 return self._count > 0
584
589
585 def addpending(self, category, callback):
590 def addpending(self, category, callback):
586 """add a callback to be called when the transaction is pending
591 """add a callback to be called when the transaction is pending
587
592
588 The transaction will be given as callback's first argument.
593 The transaction will be given as callback's first argument.
589
594
590 Category is a unique identifier to allow overwriting an old callback
595 Category is a unique identifier to allow overwriting an old callback
591 with a newer callback.
596 with a newer callback.
592 """
597 """
593 self._pendingcallback[category] = callback
598 self._pendingcallback[category] = callback
594
599
595 @active
600 @active
596 def writepending(self):
601 def writepending(self):
597 """write pending file to temporary version
602 """write pending file to temporary version
598
603
599 This is used to allow hooks to view a transaction before commit"""
604 This is used to allow hooks to view a transaction before commit"""
600 categories = sorted(self._pendingcallback)
605 categories = sorted(self._pendingcallback)
601 for cat in categories:
606 for cat in categories:
602 # remove callback since the data will have been flushed
607 # remove callback since the data will have been flushed
603 any = self._pendingcallback.pop(cat)(self)
608 any = self._pendingcallback.pop(cat)(self)
604 self._anypending = self._anypending or any
609 self._anypending = self._anypending or any
605 self._anypending |= self._generatefiles(suffix=b'.pending')
610 self._anypending |= self._generatefiles(suffix=b'.pending')
606 return self._anypending
611 return self._anypending
607
612
608 @active
613 @active
609 def hasfinalize(self, category):
614 def hasfinalize(self, category):
610 """check is a callback already exist for a category"""
615 """check is a callback already exist for a category"""
611 return category in self._finalizecallback
616 return category in self._finalizecallback
612
617
613 @active
618 @active
614 def addfinalize(self, category, callback):
619 def addfinalize(self, category, callback):
615 """add a callback to be called when the transaction is closed
620 """add a callback to be called when the transaction is closed
616
621
617 The transaction will be given as callback's first argument.
622 The transaction will be given as callback's first argument.
618
623
619 Category is a unique identifier to allow overwriting old callbacks with
624 Category is a unique identifier to allow overwriting old callbacks with
620 newer callbacks.
625 newer callbacks.
621 """
626 """
622 self._finalizecallback[category] = callback
627 self._finalizecallback[category] = callback
623
628
624 @active
629 @active
625 def addpostclose(self, category, callback):
630 def addpostclose(self, category, callback):
626 """add or replace a callback to be called after the transaction closed
631 """add or replace a callback to be called after the transaction closed
627
632
628 The transaction will be given as callback's first argument.
633 The transaction will be given as callback's first argument.
629
634
630 Category is a unique identifier to allow overwriting an old callback
635 Category is a unique identifier to allow overwriting an old callback
631 with a newer callback.
636 with a newer callback.
632 """
637 """
633 self._postclosecallback[category] = callback
638 self._postclosecallback[category] = callback
634
639
635 @active
640 @active
636 def getpostclose(self, category):
641 def getpostclose(self, category):
637 """return a postclose callback added before, or None"""
642 """return a postclose callback added before, or None"""
638 return self._postclosecallback.get(category, None)
643 return self._postclosecallback.get(category, None)
639
644
640 @active
645 @active
641 def addabort(self, category, callback):
646 def addabort(self, category, callback):
642 """add a callback to be called when the transaction is aborted.
647 """add a callback to be called when the transaction is aborted.
643
648
644 The transaction will be given as the first argument to the callback.
649 The transaction will be given as the first argument to the callback.
645
650
646 Category is a unique identifier to allow overwriting an old callback
651 Category is a unique identifier to allow overwriting an old callback
647 with a newer callback.
652 with a newer callback.
648 """
653 """
649 self._abortcallback[category] = callback
654 self._abortcallback[category] = callback
650
655
651 @active
656 @active
652 def addvalidator(self, category, callback):
657 def addvalidator(self, category, callback):
653 """adds a callback to be called when validating the transaction.
658 """adds a callback to be called when validating the transaction.
654
659
655 The transaction will be given as the first argument to the callback.
660 The transaction will be given as the first argument to the callback.
656
661
657 callback should raise exception if to abort transaction"""
662 callback should raise exception if to abort transaction"""
658 self._validatecallback[category] = callback
663 self._validatecallback[category] = callback
659
664
660 @active
665 @active
661 def close(self):
666 def close(self):
662 '''commit the transaction'''
667 '''commit the transaction'''
663 if self._count == 1:
668 if self._count == 1:
664 for category in sorted(self._validatecallback):
669 for category in sorted(self._validatecallback):
665 self._validatecallback[category](self)
670 self._validatecallback[category](self)
666 self._validatecallback = None # Help prevent cycles.
671 self._validatecallback = None # Help prevent cycles.
667 self._generatefiles(group=GEN_GROUP_PRE_FINALIZE)
672 self._generatefiles(group=GEN_GROUP_PRE_FINALIZE)
668 while self._finalizecallback:
673 while self._finalizecallback:
669 callbacks = self._finalizecallback
674 callbacks = self._finalizecallback
670 self._finalizecallback = {}
675 self._finalizecallback = {}
671 categories = sorted(callbacks)
676 categories = sorted(callbacks)
672 for cat in categories:
677 for cat in categories:
673 callbacks[cat](self)
678 callbacks[cat](self)
674 # Prevent double usage and help clear cycles.
679 # Prevent double usage and help clear cycles.
675 self._finalizecallback = None
680 self._finalizecallback = None
676 self._generatefiles(group=GEN_GROUP_POST_FINALIZE)
681 self._generatefiles(group=GEN_GROUP_POST_FINALIZE)
677
682
678 self._count -= 1
683 self._count -= 1
679 if self._count != 0:
684 if self._count != 0:
680 return
685 return
681 self._file.close()
686 self._file.close()
682 self._backupsfile.close()
687 self._backupsfile.close()
683 # cleanup temporary files
688 # cleanup temporary files
684 for l, f, b, c in self._backupentries:
689 for l, f, b, c in self._backupentries:
685 if l not in self._vfsmap and c:
690 if l not in self._vfsmap and c:
686 self._report(
691 self._report(
687 b"couldn't remove %s: unknown cache location %s\n" % (b, l)
692 b"couldn't remove %s: unknown cache location %s\n" % (b, l)
688 )
693 )
689 continue
694 continue
690 vfs = self._vfsmap[l]
695 vfs = self._vfsmap[l]
691 if not f and b and vfs.exists(b):
696 if not f and b and vfs.exists(b):
692 try:
697 try:
693 vfs.unlink(b)
698 vfs.unlink(b)
694 except (IOError, OSError, error.Abort) as inst:
699 except (IOError, OSError, error.Abort) as inst:
695 if not c:
700 if not c:
696 raise
701 raise
697 # Abort may be raise by read only opener
702 # Abort may be raise by read only opener
698 self._report(
703 self._report(
699 b"couldn't remove %s: %s\n" % (vfs.join(b), inst)
704 b"couldn't remove %s: %s\n" % (vfs.join(b), inst)
700 )
705 )
701 self._offsetmap = {}
706 self._offsetmap = {}
702 self._newfiles = set()
707 self._newfiles = set()
703 self._writeundo()
708 self._writeundo()
704 if self._after:
709 if self._after:
705 self._after()
710 self._after()
706 self._after = None # Help prevent cycles.
711 self._after = None # Help prevent cycles.
707 if self._opener.isfile(self._backupjournal):
712 if self._opener.isfile(self._backupjournal):
708 self._opener.unlink(self._backupjournal)
713 self._opener.unlink(self._backupjournal)
709 if self._opener.isfile(self._journal):
714 if self._opener.isfile(self._journal):
710 self._opener.unlink(self._journal)
715 self._opener.unlink(self._journal)
711 for l, _f, b, c in self._backupentries:
716 for l, _f, b, c in self._backupentries:
712 if l not in self._vfsmap and c:
717 if l not in self._vfsmap and c:
713 self._report(
718 self._report(
714 b"couldn't remove %s: unknown cache location"
719 b"couldn't remove %s: unknown cache location"
715 b"%s\n" % (b, l)
720 b"%s\n" % (b, l)
716 )
721 )
717 continue
722 continue
718 vfs = self._vfsmap[l]
723 vfs = self._vfsmap[l]
719 if b and vfs.exists(b):
724 if b and vfs.exists(b):
720 try:
725 try:
721 vfs.unlink(b)
726 vfs.unlink(b)
722 except (IOError, OSError, error.Abort) as inst:
727 except (IOError, OSError, error.Abort) as inst:
723 if not c:
728 if not c:
724 raise
729 raise
725 # Abort may be raise by read only opener
730 # Abort may be raise by read only opener
726 self._report(
731 self._report(
727 b"couldn't remove %s: %s\n" % (vfs.join(b), inst)
732 b"couldn't remove %s: %s\n" % (vfs.join(b), inst)
728 )
733 )
729 self._backupentries = []
734 self._backupentries = []
730 self._journal = None
735 self._journal = None
731
736
732 self._releasefn(self, True) # notify success of closing transaction
737 self._releasefn(self, True) # notify success of closing transaction
733 self._releasefn = None # Help prevent cycles.
738 self._releasefn = None # Help prevent cycles.
734
739
735 # run post close action
740 # run post close action
736 categories = sorted(self._postclosecallback)
741 categories = sorted(self._postclosecallback)
737 for cat in categories:
742 for cat in categories:
738 self._postclosecallback[cat](self)
743 self._postclosecallback[cat](self)
739 # Prevent double usage and help clear cycles.
744 # Prevent double usage and help clear cycles.
740 self._postclosecallback = None
745 self._postclosecallback = None
741
746
742 @active
747 @active
743 def abort(self):
748 def abort(self):
744 """abort the transaction (generally called on error, or when the
749 """abort the transaction (generally called on error, or when the
745 transaction is not explicitly committed before going out of
750 transaction is not explicitly committed before going out of
746 scope)"""
751 scope)"""
747 self._abort()
752 self._abort()
748
753
749 @active
754 @active
750 def add_journal(self, vfs_id, path):
755 def add_journal(self, vfs_id, path):
751 self._journal_files.append((vfs_id, path))
756 self._journal_files.append((vfs_id, path))
752
757
753 def _writeundo(self):
758 def _writeundo(self):
754 """write transaction data for possible future undo call"""
759 """write transaction data for possible future undo call"""
755 if self._undoname is None:
760 if self._undoname is None:
756 return
761 return
757 cleanup_undo_files(
762 cleanup_undo_files(
758 self._report,
763 self._report,
759 self._vfsmap,
764 self._vfsmap,
760 undo_prefix=self._undoname,
765 undo_prefix=self._undoname,
761 )
766 )
762
767
763 def undoname(fn: bytes) -> bytes:
768 def undoname(fn: bytes) -> bytes:
764 base, name = os.path.split(fn)
769 base, name = os.path.split(fn)
765 assert name.startswith(self._journal)
770 assert name.startswith(self._journal)
766 new_name = name.replace(self._journal, self._undoname, 1)
771 new_name = name.replace(self._journal, self._undoname, 1)
767 return os.path.join(base, new_name)
772 return os.path.join(base, new_name)
768
773
769 undo_backup_path = b"%s.backupfiles" % self._undoname
774 undo_backup_path = b"%s.backupfiles" % self._undoname
770 undobackupfile = self._opener.open(undo_backup_path, b'w')
775 undobackupfile = self._opener.open(undo_backup_path, b'w')
771 undobackupfile.write(b'%d\n' % version)
776 undobackupfile.write(b'%d\n' % version)
772 for l, f, b, c in self._backupentries:
777 for l, f, b, c in self._backupentries:
773 if not f: # temporary file
778 if not f: # temporary file
774 continue
779 continue
775 if not b:
780 if not b:
776 u = b''
781 u = b''
777 else:
782 else:
778 if l not in self._vfsmap and c:
783 if l not in self._vfsmap and c:
779 self._report(
784 self._report(
780 b"couldn't remove %s: unknown cache location"
785 b"couldn't remove %s: unknown cache location"
781 b"%s\n" % (b, l)
786 b"%s\n" % (b, l)
782 )
787 )
783 continue
788 continue
784 vfs = self._vfsmap[l]
789 vfs = self._vfsmap[l]
785 u = undoname(b)
790 u = undoname(b)
786 util.copyfile(vfs.join(b), vfs.join(u), hardlink=True)
791 util.copyfile(vfs.join(b), vfs.join(u), hardlink=True)
787 undobackupfile.write(b"%s\0%s\0%s\0%d\n" % (l, f, u, c))
792 undobackupfile.write(b"%s\0%s\0%s\0%d\n" % (l, f, u, c))
788 undobackupfile.close()
793 undobackupfile.close()
789 for vfs, src in self._journal_files:
794 for vfs, src in self._journal_files:
790 dest = undoname(src)
795 dest = undoname(src)
791 # if src and dest refer to a same file, vfs.rename is a no-op,
796 # if src and dest refer to a same file, vfs.rename is a no-op,
792 # leaving both src and dest on disk. delete dest to make sure
797 # leaving both src and dest on disk. delete dest to make sure
793 # the rename couldn't be such a no-op.
798 # the rename couldn't be such a no-op.
794 vfs.tryunlink(dest)
799 vfs.tryunlink(dest)
795 try:
800 try:
796 vfs.rename(src, dest)
801 vfs.rename(src, dest)
797 except FileNotFoundError: # journal file does not yet exist
802 except FileNotFoundError: # journal file does not yet exist
798 pass
803 pass
799
804
800 def _abort(self):
805 def _abort(self):
801 entries = self.readjournal()
806 entries = self.readjournal()
802 self._count = 0
807 self._count = 0
803 self._usages = 0
808 self._usages = 0
804 self._file.close()
809 self._file.close()
805 self._backupsfile.close()
810 self._backupsfile.close()
806
811
807 quick = self._can_quick_abort(entries)
812 quick = self._can_quick_abort(entries)
808 try:
813 try:
809 if not quick:
814 if not quick:
810 self._report(_(b"transaction abort!\n"))
815 self._report(_(b"transaction abort!\n"))
811 for cat in sorted(self._abortcallback):
816 for cat in sorted(self._abortcallback):
812 self._abortcallback[cat](self)
817 self._abortcallback[cat](self)
813 # Prevent double usage and help clear cycles.
818 # Prevent double usage and help clear cycles.
814 self._abortcallback = None
819 self._abortcallback = None
815 if quick:
820 if quick:
816 self._do_quick_abort(entries)
821 self._do_quick_abort(entries)
817 else:
822 else:
818 self._do_full_abort(entries)
823 self._do_full_abort(entries)
819 finally:
824 finally:
820 self._journal = None
825 self._journal = None
821 self._releasefn(self, False) # notify failure of transaction
826 self._releasefn(self, False) # notify failure of transaction
822 self._releasefn = None # Help prevent cycles.
827 self._releasefn = None # Help prevent cycles.
823
828
824 def _can_quick_abort(self, entries):
829 def _can_quick_abort(self, entries):
825 """False if any semantic content have been written on disk
830 """False if any semantic content have been written on disk
826
831
827 True if nothing, except temporary files has been writen on disk."""
832 True if nothing, except temporary files has been writen on disk."""
828 if entries:
833 if entries:
829 return False
834 return False
830 for e in self._backupentries:
835 for e in self._backupentries:
831 if e[1]:
836 if e[1]:
832 return False
837 return False
833 return True
838 return True
834
839
835 def _do_quick_abort(self, entries):
840 def _do_quick_abort(self, entries):
836 """(Silently) do a quick cleanup (see _can_quick_abort)"""
841 """(Silently) do a quick cleanup (see _can_quick_abort)"""
837 assert self._can_quick_abort(entries)
842 assert self._can_quick_abort(entries)
838 tmp_files = [e for e in self._backupentries if not e[1]]
843 tmp_files = [e for e in self._backupentries if not e[1]]
839 for vfs_id, old_path, tmp_path, xxx in tmp_files:
844 for vfs_id, old_path, tmp_path, xxx in tmp_files:
840 vfs = self._vfsmap[vfs_id]
845 vfs = self._vfsmap[vfs_id]
841 try:
846 try:
842 vfs.unlink(tmp_path)
847 vfs.unlink(tmp_path)
843 except FileNotFoundError:
848 except FileNotFoundError:
844 pass
849 pass
845 if self._backupjournal:
850 if self._backupjournal:
846 self._opener.unlink(self._backupjournal)
851 self._opener.unlink(self._backupjournal)
847 if self._journal:
852 if self._journal:
848 self._opener.unlink(self._journal)
853 self._opener.unlink(self._journal)
849
854
850 def _do_full_abort(self, entries):
855 def _do_full_abort(self, entries):
851 """(Noisily) rollback all the change introduced by the transaction"""
856 """(Noisily) rollback all the change introduced by the transaction"""
852 try:
857 try:
853 _playback(
858 _playback(
854 self._journal,
859 self._journal,
855 self._report,
860 self._report,
856 self._opener,
861 self._opener,
857 self._vfsmap,
862 self._vfsmap,
858 entries,
863 entries,
859 self._backupentries,
864 self._backupentries,
860 False,
865 False,
861 checkambigfiles=self._checkambigfiles,
866 checkambigfiles=self._checkambigfiles,
862 )
867 )
863 self._report(_(b"rollback completed\n"))
868 self._report(_(b"rollback completed\n"))
864 except BaseException as exc:
869 except BaseException as exc:
865 self._report(_(b"rollback failed - please run hg recover\n"))
870 self._report(_(b"rollback failed - please run hg recover\n"))
866 self._report(
871 self._report(
867 _(b"(failure reason: %s)\n") % stringutil.forcebytestr(exc)
872 _(b"(failure reason: %s)\n") % stringutil.forcebytestr(exc)
868 )
873 )
869
874
870
875
871 BAD_VERSION_MSG = _(
876 BAD_VERSION_MSG = _(
872 b"journal was created by a different version of Mercurial\n"
877 b"journal was created by a different version of Mercurial\n"
873 )
878 )
874
879
875
880
876 def read_backup_files(report, fp):
881 def read_backup_files(report, fp):
877 """parse an (already open) backup file an return contained backup entries
882 """parse an (already open) backup file an return contained backup entries
878
883
879 entries are in the form: (location, file, backupfile, xxx)
884 entries are in the form: (location, file, backupfile, xxx)
880
885
881 :location: the vfs identifier (vfsmap's key)
886 :location: the vfs identifier (vfsmap's key)
882 :file: original file path (in the vfs)
887 :file: original file path (in the vfs)
883 :backupfile: path of the backup (in the vfs)
888 :backupfile: path of the backup (in the vfs)
884 :cache: a boolean currently always set to False
889 :cache: a boolean currently always set to False
885 """
890 """
886 lines = fp.readlines()
891 lines = fp.readlines()
887 backupentries = []
892 backupentries = []
888 if lines:
893 if lines:
889 ver = lines[0][:-1]
894 ver = lines[0][:-1]
890 if ver != (b'%d' % version):
895 if ver != (b'%d' % version):
891 report(BAD_VERSION_MSG)
896 report(BAD_VERSION_MSG)
892 else:
897 else:
893 for line in lines[1:]:
898 for line in lines[1:]:
894 if line:
899 if line:
895 # Shave off the trailing newline
900 # Shave off the trailing newline
896 line = line[:-1]
901 line = line[:-1]
897 l, f, b, c = line.split(b'\0')
902 l, f, b, c = line.split(b'\0')
898 backupentries.append((l, f, b, bool(c)))
903 backupentries.append((l, f, b, bool(c)))
899 return backupentries
904 return backupentries
900
905
901
906
902 def rollback(
907 def rollback(
903 opener,
908 opener,
904 vfsmap,
909 vfsmap,
905 file,
910 file,
906 report,
911 report,
907 checkambigfiles=None,
912 checkambigfiles=None,
908 skip_journal_pattern=None,
913 skip_journal_pattern=None,
909 ):
914 ):
910 """Rolls back the transaction contained in the given file
915 """Rolls back the transaction contained in the given file
911
916
912 Reads the entries in the specified file, and the corresponding
917 Reads the entries in the specified file, and the corresponding
913 '*.backupfiles' file, to recover from an incomplete transaction.
918 '*.backupfiles' file, to recover from an incomplete transaction.
914
919
915 * `file`: a file containing a list of entries, specifying where
920 * `file`: a file containing a list of entries, specifying where
916 to truncate each file. The file should contain a list of
921 to truncate each file. The file should contain a list of
917 file\0offset pairs, delimited by newlines. The corresponding
922 file\0offset pairs, delimited by newlines. The corresponding
918 '*.backupfiles' file should contain a list of file\0backupfile
923 '*.backupfiles' file should contain a list of file\0backupfile
919 pairs, delimited by \0.
924 pairs, delimited by \0.
920
925
921 `checkambigfiles` is a set of (path, vfs-location) tuples,
926 `checkambigfiles` is a set of (path, vfs-location) tuples,
922 which determine whether file stat ambiguity should be avoided at
927 which determine whether file stat ambiguity should be avoided at
923 restoring corresponded files.
928 restoring corresponded files.
924 """
929 """
925 entries = []
930 entries = []
926 backupentries = []
931 backupentries = []
927
932
928 with opener.open(file) as fp:
933 with opener.open(file) as fp:
929 lines = fp.readlines()
934 lines = fp.readlines()
930 for l in lines:
935 for l in lines:
931 try:
936 try:
932 f, o = l.split(b'\0')
937 f, o = l.split(b'\0')
933 entries.append((f, int(o)))
938 entries.append((f, int(o)))
934 except ValueError:
939 except ValueError:
935 report(
940 report(
936 _(b"couldn't read journal entry %r!\n") % pycompat.bytestr(l)
941 _(b"couldn't read journal entry %r!\n") % pycompat.bytestr(l)
937 )
942 )
938
943
939 backupjournal = b"%s.backupfiles" % file
944 backupjournal = b"%s.backupfiles" % file
940 if opener.exists(backupjournal):
945 if opener.exists(backupjournal):
941 with opener.open(backupjournal) as fp:
946 with opener.open(backupjournal) as fp:
942 backupentries = read_backup_files(report, fp)
947 backupentries = read_backup_files(report, fp)
943 if skip_journal_pattern is not None:
948 if skip_journal_pattern is not None:
944 keep = lambda x: not skip_journal_pattern.match(x[1])
949 keep = lambda x: not skip_journal_pattern.match(x[1])
945 backupentries = [x for x in backupentries if keep(x)]
950 backupentries = [x for x in backupentries if keep(x)]
946
951
947 _playback(
952 _playback(
948 file,
953 file,
949 report,
954 report,
950 opener,
955 opener,
951 vfsmap,
956 vfsmap,
952 entries,
957 entries,
953 backupentries,
958 backupentries,
954 checkambigfiles=checkambigfiles,
959 checkambigfiles=checkambigfiles,
955 )
960 )
@@ -1,683 +1,689 b''
1 # upgrade.py - functions for in place upgrade of Mercurial repository
1 # upgrade.py - functions for in place upgrade of Mercurial repository
2 #
2 #
3 # Copyright (c) 2016-present, Gregory Szorc
3 # Copyright (c) 2016-present, Gregory Szorc
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8
8
9 import stat
9 import stat
10
10
11 from ..i18n import _
11 from ..i18n import _
12 from ..pycompat import getattr
12 from ..pycompat import getattr
13 from .. import (
13 from .. import (
14 changelog,
14 changelog,
15 error,
15 error,
16 filelog,
16 filelog,
17 manifest,
17 manifest,
18 metadata,
18 metadata,
19 pycompat,
19 pycompat,
20 requirements,
20 requirements,
21 scmutil,
21 scmutil,
22 store,
22 store,
23 util,
23 util,
24 vfs as vfsmod,
24 vfs as vfsmod,
25 )
25 )
26 from ..revlogutils import (
26 from ..revlogutils import (
27 constants as revlogconst,
27 constants as revlogconst,
28 flagutil,
28 flagutil,
29 nodemap,
29 nodemap,
30 sidedata as sidedatamod,
30 sidedata as sidedatamod,
31 )
31 )
32 from . import actions as upgrade_actions
32 from . import actions as upgrade_actions
33
33
34
34
35 def get_sidedata_helpers(srcrepo, dstrepo):
35 def get_sidedata_helpers(srcrepo, dstrepo):
36 use_w = srcrepo.ui.configbool(b'experimental', b'worker.repository-upgrade')
36 use_w = srcrepo.ui.configbool(b'experimental', b'worker.repository-upgrade')
37 sequential = pycompat.iswindows or not use_w
37 sequential = pycompat.iswindows or not use_w
38 if not sequential:
38 if not sequential:
39 srcrepo.register_sidedata_computer(
39 srcrepo.register_sidedata_computer(
40 revlogconst.KIND_CHANGELOG,
40 revlogconst.KIND_CHANGELOG,
41 sidedatamod.SD_FILES,
41 sidedatamod.SD_FILES,
42 (sidedatamod.SD_FILES,),
42 (sidedatamod.SD_FILES,),
43 metadata._get_worker_sidedata_adder(srcrepo, dstrepo),
43 metadata._get_worker_sidedata_adder(srcrepo, dstrepo),
44 flagutil.REVIDX_HASCOPIESINFO,
44 flagutil.REVIDX_HASCOPIESINFO,
45 replace=True,
45 replace=True,
46 )
46 )
47 return sidedatamod.get_sidedata_helpers(srcrepo, dstrepo._wanted_sidedata)
47 return sidedatamod.get_sidedata_helpers(srcrepo, dstrepo._wanted_sidedata)
48
48
49
49
50 def _revlogfrompath(repo, rl_type, path):
50 def _revlogfrompath(repo, rl_type, path):
51 """Obtain a revlog from a repo path.
51 """Obtain a revlog from a repo path.
52
52
53 An instance of the appropriate class is returned.
53 An instance of the appropriate class is returned.
54 """
54 """
55 if rl_type & store.FILEFLAGS_CHANGELOG:
55 if rl_type & store.FILEFLAGS_CHANGELOG:
56 return changelog.changelog(repo.svfs)
56 return changelog.changelog(repo.svfs)
57 elif rl_type & store.FILEFLAGS_MANIFESTLOG:
57 elif rl_type & store.FILEFLAGS_MANIFESTLOG:
58 mandir = b''
58 mandir = b''
59 if b'/' in path:
59 if b'/' in path:
60 mandir = path.rsplit(b'/', 1)[0]
60 mandir = path.rsplit(b'/', 1)[0]
61 return manifest.manifestrevlog(
61 return manifest.manifestrevlog(
62 repo.nodeconstants, repo.svfs, tree=mandir
62 repo.nodeconstants, repo.svfs, tree=mandir
63 )
63 )
64 else:
64 else:
65 # drop the extension and the `data/` prefix
65 # drop the extension and the `data/` prefix
66 path_part = path.rsplit(b'.', 1)[0].split(b'/', 1)
66 path_part = path.rsplit(b'.', 1)[0].split(b'/', 1)
67 if len(path_part) < 2:
67 if len(path_part) < 2:
68 msg = _(b'cannot recognize revlog from filename: %s')
68 msg = _(b'cannot recognize revlog from filename: %s')
69 msg %= path
69 msg %= path
70 raise error.Abort(msg)
70 raise error.Abort(msg)
71 path = path_part[1]
71 path = path_part[1]
72 return filelog.filelog(repo.svfs, path)
72 return filelog.filelog(repo.svfs, path)
73
73
74
74
75 def _copyrevlog(tr, destrepo, oldrl, rl_type, unencodedname):
75 def _copyrevlog(tr, destrepo, oldrl, rl_type, unencodedname):
76 """copy all relevant files for `oldrl` into `destrepo` store
76 """copy all relevant files for `oldrl` into `destrepo` store
77
77
78 Files are copied "as is" without any transformation. The copy is performed
78 Files are copied "as is" without any transformation. The copy is performed
79 without extra checks. Callers are responsible for making sure the copied
79 without extra checks. Callers are responsible for making sure the copied
80 content is compatible with format of the destination repository.
80 content is compatible with format of the destination repository.
81 """
81 """
82 oldrl = getattr(oldrl, '_revlog', oldrl)
82 oldrl = getattr(oldrl, '_revlog', oldrl)
83 newrl = _revlogfrompath(destrepo, rl_type, unencodedname)
83 newrl = _revlogfrompath(destrepo, rl_type, unencodedname)
84 newrl = getattr(newrl, '_revlog', newrl)
84 newrl = getattr(newrl, '_revlog', newrl)
85
85
86 oldvfs = oldrl.opener
86 oldvfs = oldrl.opener
87 newvfs = newrl.opener
87 newvfs = newrl.opener
88 oldindex = oldvfs.join(oldrl._indexfile)
88 oldindex = oldvfs.join(oldrl._indexfile)
89 newindex = newvfs.join(newrl._indexfile)
89 newindex = newvfs.join(newrl._indexfile)
90 olddata = oldvfs.join(oldrl._datafile)
90 olddata = oldvfs.join(oldrl._datafile)
91 newdata = newvfs.join(newrl._datafile)
91 newdata = newvfs.join(newrl._datafile)
92
92
93 with newvfs(newrl._indexfile, b'w'):
93 with newvfs(newrl._indexfile, b'w'):
94 pass # create all the directories
94 pass # create all the directories
95
95
96 util.copyfile(oldindex, newindex)
96 util.copyfile(oldindex, newindex)
97 copydata = oldrl.opener.exists(oldrl._datafile)
97 copydata = oldrl.opener.exists(oldrl._datafile)
98 if copydata:
98 if copydata:
99 util.copyfile(olddata, newdata)
99 util.copyfile(olddata, newdata)
100
100
101 if rl_type & store.FILEFLAGS_FILELOG:
101 if rl_type & store.FILEFLAGS_FILELOG:
102 destrepo.svfs.fncache.add(unencodedname)
102 destrepo.svfs.fncache.add(unencodedname)
103 if copydata:
103 if copydata:
104 destrepo.svfs.fncache.add(unencodedname[:-2] + b'.d')
104 destrepo.svfs.fncache.add(unencodedname[:-2] + b'.d')
105
105
106
106
107 UPGRADE_CHANGELOG = b"changelog"
107 UPGRADE_CHANGELOG = b"changelog"
108 UPGRADE_MANIFEST = b"manifest"
108 UPGRADE_MANIFEST = b"manifest"
109 UPGRADE_FILELOGS = b"all-filelogs"
109 UPGRADE_FILELOGS = b"all-filelogs"
110
110
111 UPGRADE_ALL_REVLOGS = frozenset(
111 UPGRADE_ALL_REVLOGS = frozenset(
112 [UPGRADE_CHANGELOG, UPGRADE_MANIFEST, UPGRADE_FILELOGS]
112 [UPGRADE_CHANGELOG, UPGRADE_MANIFEST, UPGRADE_FILELOGS]
113 )
113 )
114
114
115
115
116 def matchrevlog(revlogfilter, rl_type):
116 def matchrevlog(revlogfilter, rl_type):
117 """check if a revlog is selected for cloning.
117 """check if a revlog is selected for cloning.
118
118
119 In other words, are there any updates which need to be done on revlog
119 In other words, are there any updates which need to be done on revlog
120 or it can be blindly copied.
120 or it can be blindly copied.
121
121
122 The store entry is checked against the passed filter"""
122 The store entry is checked against the passed filter"""
123 if rl_type & store.FILEFLAGS_CHANGELOG:
123 if rl_type & store.FILEFLAGS_CHANGELOG:
124 return UPGRADE_CHANGELOG in revlogfilter
124 return UPGRADE_CHANGELOG in revlogfilter
125 elif rl_type & store.FILEFLAGS_MANIFESTLOG:
125 elif rl_type & store.FILEFLAGS_MANIFESTLOG:
126 return UPGRADE_MANIFEST in revlogfilter
126 return UPGRADE_MANIFEST in revlogfilter
127 assert rl_type & store.FILEFLAGS_FILELOG
127 assert rl_type & store.FILEFLAGS_FILELOG
128 return UPGRADE_FILELOGS in revlogfilter
128 return UPGRADE_FILELOGS in revlogfilter
129
129
130
130
131 def _perform_clone(
131 def _perform_clone(
132 ui,
132 ui,
133 dstrepo,
133 dstrepo,
134 tr,
134 tr,
135 old_revlog,
135 old_revlog,
136 rl_type,
136 rl_type,
137 unencoded,
137 unencoded,
138 upgrade_op,
138 upgrade_op,
139 sidedata_helpers,
139 sidedata_helpers,
140 oncopiedrevision,
140 oncopiedrevision,
141 ):
141 ):
142 """returns the new revlog object created"""
142 """returns the new revlog object created"""
143 newrl = None
143 newrl = None
144 if matchrevlog(upgrade_op.revlogs_to_process, rl_type):
144 if matchrevlog(upgrade_op.revlogs_to_process, rl_type):
145 ui.note(
145 ui.note(
146 _(b'cloning %d revisions from %s\n') % (len(old_revlog), unencoded)
146 _(b'cloning %d revisions from %s\n') % (len(old_revlog), unencoded)
147 )
147 )
148 newrl = _revlogfrompath(dstrepo, rl_type, unencoded)
148 newrl = _revlogfrompath(dstrepo, rl_type, unencoded)
149 old_revlog.clone(
149 old_revlog.clone(
150 tr,
150 tr,
151 newrl,
151 newrl,
152 addrevisioncb=oncopiedrevision,
152 addrevisioncb=oncopiedrevision,
153 deltareuse=upgrade_op.delta_reuse_mode,
153 deltareuse=upgrade_op.delta_reuse_mode,
154 forcedeltabothparents=upgrade_op.force_re_delta_both_parents,
154 forcedeltabothparents=upgrade_op.force_re_delta_both_parents,
155 sidedata_helpers=sidedata_helpers,
155 sidedata_helpers=sidedata_helpers,
156 )
156 )
157 else:
157 else:
158 msg = _(b'blindly copying %s containing %i revisions\n')
158 msg = _(b'blindly copying %s containing %i revisions\n')
159 ui.note(msg % (unencoded, len(old_revlog)))
159 ui.note(msg % (unencoded, len(old_revlog)))
160 _copyrevlog(tr, dstrepo, old_revlog, rl_type, unencoded)
160 _copyrevlog(tr, dstrepo, old_revlog, rl_type, unencoded)
161
161
162 newrl = _revlogfrompath(dstrepo, rl_type, unencoded)
162 newrl = _revlogfrompath(dstrepo, rl_type, unencoded)
163 return newrl
163 return newrl
164
164
165
165
166 def _clonerevlogs(
166 def _clonerevlogs(
167 ui,
167 ui,
168 srcrepo,
168 srcrepo,
169 dstrepo,
169 dstrepo,
170 tr,
170 tr,
171 upgrade_op,
171 upgrade_op,
172 ):
172 ):
173 """Copy revlogs between 2 repos."""
173 """Copy revlogs between 2 repos."""
174 revcount = 0
174 revcount = 0
175 srcsize = 0
175 srcsize = 0
176 srcrawsize = 0
176 srcrawsize = 0
177 dstsize = 0
177 dstsize = 0
178 fcount = 0
178 fcount = 0
179 frevcount = 0
179 frevcount = 0
180 fsrcsize = 0
180 fsrcsize = 0
181 frawsize = 0
181 frawsize = 0
182 fdstsize = 0
182 fdstsize = 0
183 mcount = 0
183 mcount = 0
184 mrevcount = 0
184 mrevcount = 0
185 msrcsize = 0
185 msrcsize = 0
186 mrawsize = 0
186 mrawsize = 0
187 mdstsize = 0
187 mdstsize = 0
188 crevcount = 0
188 crevcount = 0
189 csrcsize = 0
189 csrcsize = 0
190 crawsize = 0
190 crawsize = 0
191 cdstsize = 0
191 cdstsize = 0
192
192
193 alldatafiles = list(srcrepo.store.walk())
193 alldatafiles = list(srcrepo.store.walk())
194 # mapping of data files which needs to be cloned
194 # mapping of data files which needs to be cloned
195 # key is unencoded filename
195 # key is unencoded filename
196 # value is revlog_object_from_srcrepo
196 # value is revlog_object_from_srcrepo
197 manifests = {}
197 manifests = {}
198 changelogs = {}
198 changelogs = {}
199 filelogs = {}
199 filelogs = {}
200
200
201 # Perform a pass to collect metadata. This validates we can open all
201 # Perform a pass to collect metadata. This validates we can open all
202 # source files and allows a unified progress bar to be displayed.
202 # source files and allows a unified progress bar to be displayed.
203 for rl_type, unencoded, size in alldatafiles:
203 for rl_type, unencoded, size in alldatafiles:
204 if not rl_type & store.FILEFLAGS_REVLOG_MAIN:
204 if not rl_type & store.FILEFLAGS_REVLOG_MAIN:
205 continue
205 continue
206
206
207 # the store.walk function will wrongly pickup transaction backup and
207 # the store.walk function will wrongly pickup transaction backup and
208 # get confused. As a quick fix for 5.9 release, we ignore those.
208 # get confused. As a quick fix for 5.9 release, we ignore those.
209 # (this is not a module constants because it seems better to keep the
209 # (this is not a module constants because it seems better to keep the
210 # hack together)
210 # hack together)
211 skip_undo = (
211 skip_undo = (
212 b'undo.backup.00changelog.i',
212 b'undo.backup.00changelog.i',
213 b'undo.backup.00manifest.i',
213 b'undo.backup.00manifest.i',
214 )
214 )
215 if unencoded in skip_undo:
215 if unencoded in skip_undo:
216 continue
216 continue
217
217
218 rl = _revlogfrompath(srcrepo, rl_type, unencoded)
218 rl = _revlogfrompath(srcrepo, rl_type, unencoded)
219
219
220 info = rl.storageinfo(
220 info = rl.storageinfo(
221 exclusivefiles=True,
221 exclusivefiles=True,
222 revisionscount=True,
222 revisionscount=True,
223 trackedsize=True,
223 trackedsize=True,
224 storedsize=True,
224 storedsize=True,
225 )
225 )
226
226
227 revcount += info[b'revisionscount'] or 0
227 revcount += info[b'revisionscount'] or 0
228 datasize = info[b'storedsize'] or 0
228 datasize = info[b'storedsize'] or 0
229 rawsize = info[b'trackedsize'] or 0
229 rawsize = info[b'trackedsize'] or 0
230
230
231 srcsize += datasize
231 srcsize += datasize
232 srcrawsize += rawsize
232 srcrawsize += rawsize
233
233
234 # This is for the separate progress bars.
234 # This is for the separate progress bars.
235 if rl_type & store.FILEFLAGS_CHANGELOG:
235 if rl_type & store.FILEFLAGS_CHANGELOG:
236 changelogs[unencoded] = rl_type
236 changelogs[unencoded] = rl_type
237 crevcount += len(rl)
237 crevcount += len(rl)
238 csrcsize += datasize
238 csrcsize += datasize
239 crawsize += rawsize
239 crawsize += rawsize
240 elif rl_type & store.FILEFLAGS_MANIFESTLOG:
240 elif rl_type & store.FILEFLAGS_MANIFESTLOG:
241 manifests[unencoded] = rl_type
241 manifests[unencoded] = rl_type
242 mcount += 1
242 mcount += 1
243 mrevcount += len(rl)
243 mrevcount += len(rl)
244 msrcsize += datasize
244 msrcsize += datasize
245 mrawsize += rawsize
245 mrawsize += rawsize
246 elif rl_type & store.FILEFLAGS_FILELOG:
246 elif rl_type & store.FILEFLAGS_FILELOG:
247 filelogs[unencoded] = rl_type
247 filelogs[unencoded] = rl_type
248 fcount += 1
248 fcount += 1
249 frevcount += len(rl)
249 frevcount += len(rl)
250 fsrcsize += datasize
250 fsrcsize += datasize
251 frawsize += rawsize
251 frawsize += rawsize
252 else:
252 else:
253 error.ProgrammingError(b'unknown revlog type')
253 error.ProgrammingError(b'unknown revlog type')
254
254
255 if not revcount:
255 if not revcount:
256 return
256 return
257
257
258 ui.status(
258 ui.status(
259 _(
259 _(
260 b'migrating %d total revisions (%d in filelogs, %d in manifests, '
260 b'migrating %d total revisions (%d in filelogs, %d in manifests, '
261 b'%d in changelog)\n'
261 b'%d in changelog)\n'
262 )
262 )
263 % (revcount, frevcount, mrevcount, crevcount)
263 % (revcount, frevcount, mrevcount, crevcount)
264 )
264 )
265 ui.status(
265 ui.status(
266 _(b'migrating %s in store; %s tracked data\n')
266 _(b'migrating %s in store; %s tracked data\n')
267 % ((util.bytecount(srcsize), util.bytecount(srcrawsize)))
267 % ((util.bytecount(srcsize), util.bytecount(srcrawsize)))
268 )
268 )
269
269
270 # Used to keep track of progress.
270 # Used to keep track of progress.
271 progress = None
271 progress = None
272
272
273 def oncopiedrevision(rl, rev, node):
273 def oncopiedrevision(rl, rev, node):
274 progress.increment()
274 progress.increment()
275
275
276 sidedata_helpers = get_sidedata_helpers(srcrepo, dstrepo)
276 sidedata_helpers = get_sidedata_helpers(srcrepo, dstrepo)
277
277
278 # Migrating filelogs
278 # Migrating filelogs
279 ui.status(
279 ui.status(
280 _(
280 _(
281 b'migrating %d filelogs containing %d revisions '
281 b'migrating %d filelogs containing %d revisions '
282 b'(%s in store; %s tracked data)\n'
282 b'(%s in store; %s tracked data)\n'
283 )
283 )
284 % (
284 % (
285 fcount,
285 fcount,
286 frevcount,
286 frevcount,
287 util.bytecount(fsrcsize),
287 util.bytecount(fsrcsize),
288 util.bytecount(frawsize),
288 util.bytecount(frawsize),
289 )
289 )
290 )
290 )
291 progress = srcrepo.ui.makeprogress(_(b'file revisions'), total=frevcount)
291 progress = srcrepo.ui.makeprogress(_(b'file revisions'), total=frevcount)
292 for unencoded, rl_type in sorted(filelogs.items()):
292 for unencoded, rl_type in sorted(filelogs.items()):
293 oldrl = _revlogfrompath(srcrepo, rl_type, unencoded)
293 oldrl = _revlogfrompath(srcrepo, rl_type, unencoded)
294
294
295 newrl = _perform_clone(
295 newrl = _perform_clone(
296 ui,
296 ui,
297 dstrepo,
297 dstrepo,
298 tr,
298 tr,
299 oldrl,
299 oldrl,
300 rl_type,
300 rl_type,
301 unencoded,
301 unencoded,
302 upgrade_op,
302 upgrade_op,
303 sidedata_helpers,
303 sidedata_helpers,
304 oncopiedrevision,
304 oncopiedrevision,
305 )
305 )
306 info = newrl.storageinfo(storedsize=True)
306 info = newrl.storageinfo(storedsize=True)
307 fdstsize += info[b'storedsize'] or 0
307 fdstsize += info[b'storedsize'] or 0
308 ui.status(
308 ui.status(
309 _(
309 _(
310 b'finished migrating %d filelog revisions across %d '
310 b'finished migrating %d filelog revisions across %d '
311 b'filelogs; change in size: %s\n'
311 b'filelogs; change in size: %s\n'
312 )
312 )
313 % (frevcount, fcount, util.bytecount(fdstsize - fsrcsize))
313 % (frevcount, fcount, util.bytecount(fdstsize - fsrcsize))
314 )
314 )
315
315
316 # Migrating manifests
316 # Migrating manifests
317 ui.status(
317 ui.status(
318 _(
318 _(
319 b'migrating %d manifests containing %d revisions '
319 b'migrating %d manifests containing %d revisions '
320 b'(%s in store; %s tracked data)\n'
320 b'(%s in store; %s tracked data)\n'
321 )
321 )
322 % (
322 % (
323 mcount,
323 mcount,
324 mrevcount,
324 mrevcount,
325 util.bytecount(msrcsize),
325 util.bytecount(msrcsize),
326 util.bytecount(mrawsize),
326 util.bytecount(mrawsize),
327 )
327 )
328 )
328 )
329 if progress:
329 if progress:
330 progress.complete()
330 progress.complete()
331 progress = srcrepo.ui.makeprogress(
331 progress = srcrepo.ui.makeprogress(
332 _(b'manifest revisions'), total=mrevcount
332 _(b'manifest revisions'), total=mrevcount
333 )
333 )
334 for unencoded, rl_type in sorted(manifests.items()):
334 for unencoded, rl_type in sorted(manifests.items()):
335 oldrl = _revlogfrompath(srcrepo, rl_type, unencoded)
335 oldrl = _revlogfrompath(srcrepo, rl_type, unencoded)
336 newrl = _perform_clone(
336 newrl = _perform_clone(
337 ui,
337 ui,
338 dstrepo,
338 dstrepo,
339 tr,
339 tr,
340 oldrl,
340 oldrl,
341 rl_type,
341 rl_type,
342 unencoded,
342 unencoded,
343 upgrade_op,
343 upgrade_op,
344 sidedata_helpers,
344 sidedata_helpers,
345 oncopiedrevision,
345 oncopiedrevision,
346 )
346 )
347 info = newrl.storageinfo(storedsize=True)
347 info = newrl.storageinfo(storedsize=True)
348 mdstsize += info[b'storedsize'] or 0
348 mdstsize += info[b'storedsize'] or 0
349 ui.status(
349 ui.status(
350 _(
350 _(
351 b'finished migrating %d manifest revisions across %d '
351 b'finished migrating %d manifest revisions across %d '
352 b'manifests; change in size: %s\n'
352 b'manifests; change in size: %s\n'
353 )
353 )
354 % (mrevcount, mcount, util.bytecount(mdstsize - msrcsize))
354 % (mrevcount, mcount, util.bytecount(mdstsize - msrcsize))
355 )
355 )
356
356
357 # Migrating changelog
357 # Migrating changelog
358 ui.status(
358 ui.status(
359 _(
359 _(
360 b'migrating changelog containing %d revisions '
360 b'migrating changelog containing %d revisions '
361 b'(%s in store; %s tracked data)\n'
361 b'(%s in store; %s tracked data)\n'
362 )
362 )
363 % (
363 % (
364 crevcount,
364 crevcount,
365 util.bytecount(csrcsize),
365 util.bytecount(csrcsize),
366 util.bytecount(crawsize),
366 util.bytecount(crawsize),
367 )
367 )
368 )
368 )
369 if progress:
369 if progress:
370 progress.complete()
370 progress.complete()
371 progress = srcrepo.ui.makeprogress(
371 progress = srcrepo.ui.makeprogress(
372 _(b'changelog revisions'), total=crevcount
372 _(b'changelog revisions'), total=crevcount
373 )
373 )
374 for unencoded, rl_type in sorted(changelogs.items()):
374 for unencoded, rl_type in sorted(changelogs.items()):
375 oldrl = _revlogfrompath(srcrepo, rl_type, unencoded)
375 oldrl = _revlogfrompath(srcrepo, rl_type, unencoded)
376 newrl = _perform_clone(
376 newrl = _perform_clone(
377 ui,
377 ui,
378 dstrepo,
378 dstrepo,
379 tr,
379 tr,
380 oldrl,
380 oldrl,
381 rl_type,
381 rl_type,
382 unencoded,
382 unencoded,
383 upgrade_op,
383 upgrade_op,
384 sidedata_helpers,
384 sidedata_helpers,
385 oncopiedrevision,
385 oncopiedrevision,
386 )
386 )
387 info = newrl.storageinfo(storedsize=True)
387 info = newrl.storageinfo(storedsize=True)
388 cdstsize += info[b'storedsize'] or 0
388 cdstsize += info[b'storedsize'] or 0
389 progress.complete()
389 progress.complete()
390 ui.status(
390 ui.status(
391 _(
391 _(
392 b'finished migrating %d changelog revisions; change in size: '
392 b'finished migrating %d changelog revisions; change in size: '
393 b'%s\n'
393 b'%s\n'
394 )
394 )
395 % (crevcount, util.bytecount(cdstsize - csrcsize))
395 % (crevcount, util.bytecount(cdstsize - csrcsize))
396 )
396 )
397
397
398 dstsize = fdstsize + mdstsize + cdstsize
398 dstsize = fdstsize + mdstsize + cdstsize
399 ui.status(
399 ui.status(
400 _(
400 _(
401 b'finished migrating %d total revisions; total change in store '
401 b'finished migrating %d total revisions; total change in store '
402 b'size: %s\n'
402 b'size: %s\n'
403 )
403 )
404 % (revcount, util.bytecount(dstsize - srcsize))
404 % (revcount, util.bytecount(dstsize - srcsize))
405 )
405 )
406
406
407
407
408 def _files_to_copy_post_revlog_clone(srcrepo):
408 def _files_to_copy_post_revlog_clone(srcrepo):
409 """yields files which should be copied to destination after revlogs
409 """yields files which should be copied to destination after revlogs
410 are cloned"""
410 are cloned"""
411 for path, kind, st in sorted(srcrepo.store.vfs.readdir(b'', stat=True)):
411 for path, kind, st in sorted(srcrepo.store.vfs.readdir(b'', stat=True)):
412 # don't copy revlogs as they are already cloned
412 # don't copy revlogs as they are already cloned
413 if store.revlog_type(path) is not None:
413 if store.revlog_type(path) is not None:
414 continue
414 continue
415 # Skip transaction related files.
415 # Skip transaction related files.
416 if path.startswith(b'undo'):
416 if path.startswith(b'undo'):
417 continue
417 continue
418 # Only copy regular files.
418 # Only copy regular files.
419 if kind != stat.S_IFREG:
419 if kind != stat.S_IFREG:
420 continue
420 continue
421 # Skip other skipped files.
421 # Skip other skipped files.
422 if path in (b'lock', b'fncache'):
422 if path in (b'lock', b'fncache'):
423 continue
423 continue
424 # TODO: should we skip cache too?
424 # TODO: should we skip cache too?
425
425
426 yield path
426 yield path
427
427
428
428
429 def _replacestores(currentrepo, upgradedrepo, backupvfs, upgrade_op):
429 def _replacestores(currentrepo, upgradedrepo, backupvfs, upgrade_op):
430 """Replace the stores after current repository is upgraded
430 """Replace the stores after current repository is upgraded
431
431
432 Creates a backup of current repository store at backup path
432 Creates a backup of current repository store at backup path
433 Replaces upgraded store files in current repo from upgraded one
433 Replaces upgraded store files in current repo from upgraded one
434
434
435 Arguments:
435 Arguments:
436 currentrepo: repo object of current repository
436 currentrepo: repo object of current repository
437 upgradedrepo: repo object of the upgraded data
437 upgradedrepo: repo object of the upgraded data
438 backupvfs: vfs object for the backup path
438 backupvfs: vfs object for the backup path
439 upgrade_op: upgrade operation object
439 upgrade_op: upgrade operation object
440 to be used to decide what all is upgraded
440 to be used to decide what all is upgraded
441 """
441 """
442 # TODO: don't blindly rename everything in store
442 # TODO: don't blindly rename everything in store
443 # There can be upgrades where store is not touched at all
443 # There can be upgrades where store is not touched at all
444 if upgrade_op.backup_store:
444 if upgrade_op.backup_store:
445 util.rename(currentrepo.spath, backupvfs.join(b'store'))
445 util.rename(currentrepo.spath, backupvfs.join(b'store'))
446 else:
446 else:
447 currentrepo.vfs.rmtree(b'store', forcibly=True)
447 currentrepo.vfs.rmtree(b'store', forcibly=True)
448 util.rename(upgradedrepo.spath, currentrepo.spath)
448 util.rename(upgradedrepo.spath, currentrepo.spath)
449
449
450
450
451 def finishdatamigration(ui, srcrepo, dstrepo, requirements):
451 def finishdatamigration(ui, srcrepo, dstrepo, requirements):
452 """Hook point for extensions to perform additional actions during upgrade.
452 """Hook point for extensions to perform additional actions during upgrade.
453
453
454 This function is called after revlogs and store files have been copied but
454 This function is called after revlogs and store files have been copied but
455 before the new store is swapped into the original location.
455 before the new store is swapped into the original location.
456 """
456 """
457
457
458
458
459 def upgrade(ui, srcrepo, dstrepo, upgrade_op):
459 def upgrade(ui, srcrepo, dstrepo, upgrade_op):
460 """Do the low-level work of upgrading a repository.
460 """Do the low-level work of upgrading a repository.
461
461
462 The upgrade is effectively performed as a copy between a source
462 The upgrade is effectively performed as a copy between a source
463 repository and a temporary destination repository.
463 repository and a temporary destination repository.
464
464
465 The source repository is unmodified for as long as possible so the
465 The source repository is unmodified for as long as possible so the
466 upgrade can abort at any time without causing loss of service for
466 upgrade can abort at any time without causing loss of service for
467 readers and without corrupting the source repository.
467 readers and without corrupting the source repository.
468 """
468 """
469 assert srcrepo.currentwlock()
469 assert srcrepo.currentwlock()
470 assert dstrepo.currentwlock()
470 assert dstrepo.currentwlock()
471 backuppath = None
471 backuppath = None
472 backupvfs = None
472 backupvfs = None
473
473
474 ui.status(
474 ui.status(
475 _(
475 _(
476 b'(it is safe to interrupt this process any time before '
476 b'(it is safe to interrupt this process any time before '
477 b'data migration completes)\n'
477 b'data migration completes)\n'
478 )
478 )
479 )
479 )
480
480
481 if upgrade_actions.dirstatev2 in upgrade_op.upgrade_actions:
481 if upgrade_actions.dirstatev2 in upgrade_op.upgrade_actions:
482 ui.status(_(b'upgrading to dirstate-v2 from v1\n'))
482 ui.status(_(b'upgrading to dirstate-v2 from v1\n'))
483 upgrade_dirstate(ui, srcrepo, upgrade_op, b'v1', b'v2')
483 upgrade_dirstate(ui, srcrepo, upgrade_op, b'v1', b'v2')
484 upgrade_op.upgrade_actions.remove(upgrade_actions.dirstatev2)
484 upgrade_op.upgrade_actions.remove(upgrade_actions.dirstatev2)
485
485
486 if upgrade_actions.dirstatev2 in upgrade_op.removed_actions:
486 if upgrade_actions.dirstatev2 in upgrade_op.removed_actions:
487 ui.status(_(b'downgrading from dirstate-v2 to v1\n'))
487 ui.status(_(b'downgrading from dirstate-v2 to v1\n'))
488 upgrade_dirstate(ui, srcrepo, upgrade_op, b'v2', b'v1')
488 upgrade_dirstate(ui, srcrepo, upgrade_op, b'v2', b'v1')
489 upgrade_op.removed_actions.remove(upgrade_actions.dirstatev2)
489 upgrade_op.removed_actions.remove(upgrade_actions.dirstatev2)
490
490
491 if upgrade_actions.dirstatetrackedkey in upgrade_op.upgrade_actions:
491 if upgrade_actions.dirstatetrackedkey in upgrade_op.upgrade_actions:
492 ui.status(_(b'create dirstate-tracked-hint file\n'))
492 ui.status(_(b'create dirstate-tracked-hint file\n'))
493 upgrade_tracked_hint(ui, srcrepo, upgrade_op, add=True)
493 upgrade_tracked_hint(ui, srcrepo, upgrade_op, add=True)
494 upgrade_op.upgrade_actions.remove(upgrade_actions.dirstatetrackedkey)
494 upgrade_op.upgrade_actions.remove(upgrade_actions.dirstatetrackedkey)
495 elif upgrade_actions.dirstatetrackedkey in upgrade_op.removed_actions:
495 elif upgrade_actions.dirstatetrackedkey in upgrade_op.removed_actions:
496 ui.status(_(b'remove dirstate-tracked-hint file\n'))
496 ui.status(_(b'remove dirstate-tracked-hint file\n'))
497 upgrade_tracked_hint(ui, srcrepo, upgrade_op, add=False)
497 upgrade_tracked_hint(ui, srcrepo, upgrade_op, add=False)
498 upgrade_op.removed_actions.remove(upgrade_actions.dirstatetrackedkey)
498 upgrade_op.removed_actions.remove(upgrade_actions.dirstatetrackedkey)
499
499
500 if not (upgrade_op.upgrade_actions or upgrade_op.removed_actions):
500 if not (upgrade_op.upgrade_actions or upgrade_op.removed_actions):
501 return
501 return
502
502
503 if upgrade_op.requirements_only:
503 if upgrade_op.requirements_only:
504 ui.status(_(b'upgrading repository requirements\n'))
504 ui.status(_(b'upgrading repository requirements\n'))
505 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
505 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
506 # if there is only one action and that is persistent nodemap upgrade
506 # if there is only one action and that is persistent nodemap upgrade
507 # directly write the nodemap file and update requirements instead of going
507 # directly write the nodemap file and update requirements instead of going
508 # through the whole cloning process
508 # through the whole cloning process
509 elif (
509 elif (
510 len(upgrade_op.upgrade_actions) == 1
510 len(upgrade_op.upgrade_actions) == 1
511 and b'persistent-nodemap' in upgrade_op.upgrade_actions_names
511 and b'persistent-nodemap' in upgrade_op.upgrade_actions_names
512 and not upgrade_op.removed_actions
512 and not upgrade_op.removed_actions
513 ):
513 ):
514 ui.status(
514 ui.status(
515 _(b'upgrading repository to use persistent nodemap feature\n')
515 _(b'upgrading repository to use persistent nodemap feature\n')
516 )
516 )
517 with srcrepo.transaction(b'upgrade') as tr:
517 with srcrepo.transaction(b'upgrade') as tr:
518 unfi = srcrepo.unfiltered()
518 unfi = srcrepo.unfiltered()
519 cl = unfi.changelog
519 cl = unfi.changelog
520 nodemap.persist_nodemap(tr, cl, force=True)
520 nodemap.persist_nodemap(tr, cl, force=True)
521 # we want to directly operate on the underlying revlog to force
521 # we want to directly operate on the underlying revlog to force
522 # create a nodemap file. This is fine since this is upgrade code
522 # create a nodemap file. This is fine since this is upgrade code
523 # and it heavily relies on repository being revlog based
523 # and it heavily relies on repository being revlog based
524 # hence accessing private attributes can be justified
524 # hence accessing private attributes can be justified
525 nodemap.persist_nodemap(
525 nodemap.persist_nodemap(
526 tr, unfi.manifestlog._rootstore._revlog, force=True
526 tr, unfi.manifestlog._rootstore._revlog, force=True
527 )
527 )
528 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
528 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
529 elif (
529 elif (
530 len(upgrade_op.removed_actions) == 1
530 len(upgrade_op.removed_actions) == 1
531 and [
531 and [
532 x
532 x
533 for x in upgrade_op.removed_actions
533 for x in upgrade_op.removed_actions
534 if x.name == b'persistent-nodemap'
534 if x.name == b'persistent-nodemap'
535 ]
535 ]
536 and not upgrade_op.upgrade_actions
536 and not upgrade_op.upgrade_actions
537 ):
537 ):
538 ui.status(
538 ui.status(
539 _(b'downgrading repository to not use persistent nodemap feature\n')
539 _(b'downgrading repository to not use persistent nodemap feature\n')
540 )
540 )
541 with srcrepo.transaction(b'upgrade') as tr:
541 with srcrepo.transaction(b'upgrade') as tr:
542 unfi = srcrepo.unfiltered()
542 unfi = srcrepo.unfiltered()
543 cl = unfi.changelog
543 cl = unfi.changelog
544 nodemap.delete_nodemap(tr, srcrepo, cl)
544 nodemap.delete_nodemap(tr, srcrepo, cl)
545 # check comment 20 lines above for accessing private attributes
545 # check comment 20 lines above for accessing private attributes
546 nodemap.delete_nodemap(
546 nodemap.delete_nodemap(
547 tr, srcrepo, unfi.manifestlog._rootstore._revlog
547 tr, srcrepo, unfi.manifestlog._rootstore._revlog
548 )
548 )
549 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
549 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
550 else:
550 else:
551 with dstrepo.transaction(b'upgrade') as tr:
551 with dstrepo.transaction(b'upgrade') as tr:
552 _clonerevlogs(
552 _clonerevlogs(
553 ui,
553 ui,
554 srcrepo,
554 srcrepo,
555 dstrepo,
555 dstrepo,
556 tr,
556 tr,
557 upgrade_op,
557 upgrade_op,
558 )
558 )
559
559
560 # Now copy other files in the store directory.
560 # Now copy other files in the store directory.
561 for p in _files_to_copy_post_revlog_clone(srcrepo):
561 for p in _files_to_copy_post_revlog_clone(srcrepo):
562 srcrepo.ui.status(_(b'copying %s\n') % p)
562 srcrepo.ui.status(_(b'copying %s\n') % p)
563 src = srcrepo.store.rawvfs.join(p)
563 src = srcrepo.store.rawvfs.join(p)
564 dst = dstrepo.store.rawvfs.join(p)
564 dst = dstrepo.store.rawvfs.join(p)
565 util.copyfile(src, dst, copystat=True)
565 util.copyfile(src, dst, copystat=True)
566
566
567 finishdatamigration(ui, srcrepo, dstrepo, requirements)
567 finishdatamigration(ui, srcrepo, dstrepo, requirements)
568
568
569 ui.status(_(b'data fully upgraded in a temporary repository\n'))
569 ui.status(_(b'data fully upgraded in a temporary repository\n'))
570
570
571 if upgrade_op.backup_store:
571 if upgrade_op.backup_store:
572 backuppath = pycompat.mkdtemp(
572 backuppath = pycompat.mkdtemp(
573 prefix=b'upgradebackup.', dir=srcrepo.path
573 prefix=b'upgradebackup.', dir=srcrepo.path
574 )
574 )
575 backupvfs = vfsmod.vfs(backuppath)
575 backupvfs = vfsmod.vfs(backuppath)
576
576
577 # Make a backup of requires file first, as it is the first to be modified.
577 # Make a backup of requires file first, as it is the first to be modified.
578 util.copyfile(
578 util.copyfile(
579 srcrepo.vfs.join(b'requires'), backupvfs.join(b'requires')
579 srcrepo.vfs.join(b'requires'), backupvfs.join(b'requires')
580 )
580 )
581
581
582 # We install an arbitrary requirement that clients must not support
582 # We install an arbitrary requirement that clients must not support
583 # as a mechanism to lock out new clients during the data swap. This is
583 # as a mechanism to lock out new clients during the data swap. This is
584 # better than allowing a client to continue while the repository is in
584 # better than allowing a client to continue while the repository is in
585 # an inconsistent state.
585 # an inconsistent state.
586 ui.status(
586 ui.status(
587 _(
587 _(
588 b'marking source repository as being upgraded; clients will be '
588 b'marking source repository as being upgraded; clients will be '
589 b'unable to read from repository\n'
589 b'unable to read from repository\n'
590 )
590 )
591 )
591 )
592 scmutil.writereporequirements(
592 scmutil.writereporequirements(
593 srcrepo, srcrepo.requirements | {b'upgradeinprogress'}
593 srcrepo, srcrepo.requirements | {b'upgradeinprogress'}
594 )
594 )
595
595
596 ui.status(_(b'starting in-place swap of repository data\n'))
596 ui.status(_(b'starting in-place swap of repository data\n'))
597 if upgrade_op.backup_store:
597 if upgrade_op.backup_store:
598 ui.status(
598 ui.status(
599 _(b'replaced files will be backed up at %s\n') % backuppath
599 _(b'replaced files will be backed up at %s\n') % backuppath
600 )
600 )
601
601
602 # Now swap in the new store directory. Doing it as a rename should make
602 # Now swap in the new store directory. Doing it as a rename should make
603 # the operation nearly instantaneous and atomic (at least in well-behaved
603 # the operation nearly instantaneous and atomic (at least in well-behaved
604 # environments).
604 # environments).
605 ui.status(_(b'replacing store...\n'))
605 ui.status(_(b'replacing store...\n'))
606 tstart = util.timer()
606 tstart = util.timer()
607 _replacestores(srcrepo, dstrepo, backupvfs, upgrade_op)
607 _replacestores(srcrepo, dstrepo, backupvfs, upgrade_op)
608 elapsed = util.timer() - tstart
608 elapsed = util.timer() - tstart
609 ui.status(
609 ui.status(
610 _(
610 _(
611 b'store replacement complete; repository was inconsistent for '
611 b'store replacement complete; repository was inconsistent for '
612 b'%0.1fs\n'
612 b'%0.1fs\n'
613 )
613 )
614 % elapsed
614 % elapsed
615 )
615 )
616
616
617 # We first write the requirements file. Any new requirements will lock
617 # We first write the requirements file. Any new requirements will lock
618 # out legacy clients.
618 # out legacy clients.
619 ui.status(
619 ui.status(
620 _(
620 _(
621 b'finalizing requirements file and making repository readable '
621 b'finalizing requirements file and making repository readable '
622 b'again\n'
622 b'again\n'
623 )
623 )
624 )
624 )
625 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
625 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
626
626
627 if upgrade_op.backup_store:
627 if upgrade_op.backup_store:
628 # The lock file from the old store won't be removed because nothing has a
628 # The lock file from the old store won't be removed because nothing has a
629 # reference to its new location. So clean it up manually. Alternatively, we
629 # reference to its new location. So clean it up manually. Alternatively, we
630 # could update srcrepo.svfs and other variables to point to the new
630 # could update srcrepo.svfs and other variables to point to the new
631 # location. This is simpler.
631 # location. This is simpler.
632 assert backupvfs is not None # help pytype
632 assert backupvfs is not None # help pytype
633 backupvfs.unlink(b'store/lock')
633 backupvfs.unlink(b'store/lock')
634
634
635 return backuppath
635 return backuppath
636
636
637
637
638 def upgrade_dirstate(ui, srcrepo, upgrade_op, old, new):
638 def upgrade_dirstate(ui, srcrepo, upgrade_op, old, new):
639 if upgrade_op.backup_store:
639 if upgrade_op.backup_store:
640 backuppath = pycompat.mkdtemp(
640 backuppath = pycompat.mkdtemp(
641 prefix=b'upgradebackup.', dir=srcrepo.path
641 prefix=b'upgradebackup.', dir=srcrepo.path
642 )
642 )
643 ui.status(_(b'replaced files will be backed up at %s\n') % backuppath)
643 ui.status(_(b'replaced files will be backed up at %s\n') % backuppath)
644 backupvfs = vfsmod.vfs(backuppath)
644 backupvfs = vfsmod.vfs(backuppath)
645 util.copyfile(
645 util.copyfile(
646 srcrepo.vfs.join(b'requires'), backupvfs.join(b'requires')
646 srcrepo.vfs.join(b'requires'), backupvfs.join(b'requires')
647 )
647 )
648 try:
648 try:
649 util.copyfile(
649 util.copyfile(
650 srcrepo.vfs.join(b'dirstate'), backupvfs.join(b'dirstate')
650 srcrepo.vfs.join(b'dirstate'), backupvfs.join(b'dirstate')
651 )
651 )
652 except FileNotFoundError:
652 except FileNotFoundError:
653 # The dirstate does not exist on an empty repo or a repo with no
653 # The dirstate does not exist on an empty repo or a repo with no
654 # revision checked out
654 # revision checked out
655 pass
655 pass
656
656
657 assert srcrepo.dirstate._use_dirstate_v2 == (old == b'v2')
657 assert srcrepo.dirstate._use_dirstate_v2 == (old == b'v2')
658 use_v2 = new == b'v2'
659 if use_v2:
660 # Write the requirements *before* upgrading
661 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
662
658 srcrepo.dirstate._map.preload()
663 srcrepo.dirstate._map.preload()
659 srcrepo.dirstate._use_dirstate_v2 = new == b'v2'
664 srcrepo.dirstate._use_dirstate_v2 = use_v2
660 srcrepo.dirstate._map._use_dirstate_v2 = srcrepo.dirstate._use_dirstate_v2
665 srcrepo.dirstate._map._use_dirstate_v2 = use_v2
661 srcrepo.dirstate._dirty = True
666 srcrepo.dirstate._dirty = True
662 try:
667 try:
663 srcrepo.vfs.unlink(b'dirstate')
668 srcrepo.vfs.unlink(b'dirstate')
664 except FileNotFoundError:
669 except FileNotFoundError:
665 # The dirstate does not exist on an empty repo or a repo with no
670 # The dirstate does not exist on an empty repo or a repo with no
666 # revision checked out
671 # revision checked out
667 pass
672 pass
668
673
669 srcrepo.dirstate.write(None)
674 srcrepo.dirstate.write(None)
670
675 if not use_v2:
671 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
676 # Remove the v2 requirement *after* downgrading
677 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
672
678
673
679
674 def upgrade_tracked_hint(ui, srcrepo, upgrade_op, add):
680 def upgrade_tracked_hint(ui, srcrepo, upgrade_op, add):
675 if add:
681 if add:
676 srcrepo.dirstate._use_tracked_hint = True
682 srcrepo.dirstate._use_tracked_hint = True
677 srcrepo.dirstate._dirty = True
683 srcrepo.dirstate._dirty = True
678 srcrepo.dirstate._dirty_tracked_set = True
684 srcrepo.dirstate._dirty_tracked_set = True
679 srcrepo.dirstate.write(None)
685 srcrepo.dirstate.write(None)
680 if not add:
686 if not add:
681 srcrepo.dirstate.delete_tracked_hint()
687 srcrepo.dirstate.delete_tracked_hint()
682
688
683 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
689 scmutil.writereporequirements(srcrepo, upgrade_op.new_requirements)
@@ -1,813 +1,817 b''
1 # vfs.py - Mercurial 'vfs' classes
1 # vfs.py - Mercurial 'vfs' classes
2 #
2 #
3 # Copyright Olivia Mackall <olivia@selenic.com>
3 # Copyright Olivia Mackall <olivia@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 import contextlib
8 import contextlib
9 import os
9 import os
10 import shutil
10 import shutil
11 import stat
11 import stat
12 import threading
12 import threading
13
13
14 from typing import (
14 from typing import (
15 Optional,
15 Optional,
16 )
16 )
17
17
18 from .i18n import _
18 from .i18n import _
19 from .pycompat import (
19 from .pycompat import (
20 delattr,
20 delattr,
21 getattr,
21 getattr,
22 setattr,
22 setattr,
23 )
23 )
24 from . import (
24 from . import (
25 encoding,
25 encoding,
26 error,
26 error,
27 pathutil,
27 pathutil,
28 pycompat,
28 pycompat,
29 util,
29 util,
30 )
30 )
31
31
32
32
33 def _avoidambig(path: bytes, oldstat):
33 def _avoidambig(path: bytes, oldstat):
34 """Avoid file stat ambiguity forcibly
34 """Avoid file stat ambiguity forcibly
35
35
36 This function causes copying ``path`` file, if it is owned by
36 This function causes copying ``path`` file, if it is owned by
37 another (see issue5418 and issue5584 for detail).
37 another (see issue5418 and issue5584 for detail).
38 """
38 """
39
39
40 def checkandavoid():
40 def checkandavoid():
41 newstat = util.filestat.frompath(path)
41 newstat = util.filestat.frompath(path)
42 # return whether file stat ambiguity is (already) avoided
42 # return whether file stat ambiguity is (already) avoided
43 return not newstat.isambig(oldstat) or newstat.avoidambig(path, oldstat)
43 return not newstat.isambig(oldstat) or newstat.avoidambig(path, oldstat)
44
44
45 if not checkandavoid():
45 if not checkandavoid():
46 # simply copy to change owner of path to get privilege to
46 # simply copy to change owner of path to get privilege to
47 # advance mtime (see issue5418)
47 # advance mtime (see issue5418)
48 util.rename(util.mktempcopy(path), path)
48 util.rename(util.mktempcopy(path), path)
49 checkandavoid()
49 checkandavoid()
50
50
51
51
52 class abstractvfs:
52 class abstractvfs:
53 """Abstract base class; cannot be instantiated"""
53 """Abstract base class; cannot be instantiated"""
54
54
55 # default directory separator for vfs
55 # default directory separator for vfs
56 #
56 #
57 # Other vfs code always use `/` and this works fine because python file API
57 # Other vfs code always use `/` and this works fine because python file API
58 # abstract the use of `/` and make it work transparently. For consistency
58 # abstract the use of `/` and make it work transparently. For consistency
59 # vfs will always use `/` when joining. This avoid some confusion in
59 # vfs will always use `/` when joining. This avoid some confusion in
60 # encoded vfs (see issue6546)
60 # encoded vfs (see issue6546)
61 _dir_sep = b'/'
61 _dir_sep = b'/'
62
62
63 def __init__(self, *args, **kwargs):
63 def __init__(self, *args, **kwargs):
64 '''Prevent instantiation; don't call this from subclasses.'''
64 '''Prevent instantiation; don't call this from subclasses.'''
65 raise NotImplementedError('attempted instantiating ' + str(type(self)))
65 raise NotImplementedError('attempted instantiating ' + str(type(self)))
66
66
67 # TODO: type return, which is util.posixfile wrapped by a proxy
67 # TODO: type return, which is util.posixfile wrapped by a proxy
68 def __call__(self, path: bytes, mode: bytes = b'rb', **kwargs):
68 def __call__(self, path: bytes, mode: bytes = b'rb', **kwargs):
69 raise NotImplementedError
69 raise NotImplementedError
70
70
71 def _auditpath(self, path: bytes, mode: bytes):
71 def _auditpath(self, path: bytes, mode: bytes):
72 raise NotImplementedError
72 raise NotImplementedError
73
73
74 def join(self, path: Optional[bytes], *insidef: bytes) -> bytes:
74 def join(self, path: Optional[bytes], *insidef: bytes) -> bytes:
75 raise NotImplementedError
75 raise NotImplementedError
76
76
77 def tryread(self, path: bytes) -> bytes:
77 def tryread(self, path: bytes) -> bytes:
78 '''gracefully return an empty string for missing files'''
78 '''gracefully return an empty string for missing files'''
79 try:
79 try:
80 return self.read(path)
80 return self.read(path)
81 except FileNotFoundError:
81 except FileNotFoundError:
82 pass
82 pass
83 return b""
83 return b""
84
84
85 def tryreadlines(self, path: bytes, mode: bytes = b'rb'):
85 def tryreadlines(self, path: bytes, mode: bytes = b'rb'):
86 '''gracefully return an empty array for missing files'''
86 '''gracefully return an empty array for missing files'''
87 try:
87 try:
88 return self.readlines(path, mode=mode)
88 return self.readlines(path, mode=mode)
89 except FileNotFoundError:
89 except FileNotFoundError:
90 pass
90 pass
91 return []
91 return []
92
92
93 @util.propertycache
93 @util.propertycache
94 def open(self):
94 def open(self):
95 """Open ``path`` file, which is relative to vfs root.
95 """Open ``path`` file, which is relative to vfs root.
96
96
97 Newly created directories are marked as "not to be indexed by
97 Newly created directories are marked as "not to be indexed by
98 the content indexing service", if ``notindexed`` is specified
98 the content indexing service", if ``notindexed`` is specified
99 for "write" mode access.
99 for "write" mode access.
100 """
100 """
101 return self.__call__
101 return self.__call__
102
102
103 def read(self, path: bytes) -> bytes:
103 def read(self, path: bytes) -> bytes:
104 with self(path, b'rb') as fp:
104 with self(path, b'rb') as fp:
105 return fp.read()
105 return fp.read()
106
106
107 def readlines(self, path: bytes, mode: bytes = b'rb'):
107 def readlines(self, path: bytes, mode: bytes = b'rb'):
108 with self(path, mode=mode) as fp:
108 with self(path, mode=mode) as fp:
109 return fp.readlines()
109 return fp.readlines()
110
110
111 def write(
111 def write(
112 self, path: bytes, data: bytes, backgroundclose=False, **kwargs
112 self, path: bytes, data: bytes, backgroundclose=False, **kwargs
113 ) -> int:
113 ) -> int:
114 with self(path, b'wb', backgroundclose=backgroundclose, **kwargs) as fp:
114 with self(path, b'wb', backgroundclose=backgroundclose, **kwargs) as fp:
115 return fp.write(data)
115 return fp.write(data)
116
116
117 def writelines(
117 def writelines(
118 self, path: bytes, data: bytes, mode: bytes = b'wb', notindexed=False
118 self, path: bytes, data: bytes, mode: bytes = b'wb', notindexed=False
119 ) -> None:
119 ) -> None:
120 with self(path, mode=mode, notindexed=notindexed) as fp:
120 with self(path, mode=mode, notindexed=notindexed) as fp:
121 return fp.writelines(data)
121 return fp.writelines(data)
122
122
123 def append(self, path: bytes, data: bytes) -> int:
123 def append(self, path: bytes, data: bytes) -> int:
124 with self(path, b'ab') as fp:
124 with self(path, b'ab') as fp:
125 return fp.write(data)
125 return fp.write(data)
126
126
127 def basename(self, path: bytes) -> bytes:
127 def basename(self, path: bytes) -> bytes:
128 """return base element of a path (as os.path.basename would do)
128 """return base element of a path (as os.path.basename would do)
129
129
130 This exists to allow handling of strange encoding if needed."""
130 This exists to allow handling of strange encoding if needed."""
131 return os.path.basename(path)
131 return os.path.basename(path)
132
132
133 def chmod(self, path: bytes, mode: int) -> None:
133 def chmod(self, path: bytes, mode: int) -> None:
134 return os.chmod(self.join(path), mode)
134 return os.chmod(self.join(path), mode)
135
135
136 def dirname(self, path: bytes) -> bytes:
136 def dirname(self, path: bytes) -> bytes:
137 """return dirname element of a path (as os.path.dirname would do)
137 """return dirname element of a path (as os.path.dirname would do)
138
138
139 This exists to allow handling of strange encoding if needed."""
139 This exists to allow handling of strange encoding if needed."""
140 return os.path.dirname(path)
140 return os.path.dirname(path)
141
141
142 def exists(self, path: Optional[bytes] = None) -> bool:
142 def exists(self, path: Optional[bytes] = None) -> bool:
143 return os.path.exists(self.join(path))
143 return os.path.exists(self.join(path))
144
144
145 def fstat(self, fp):
145 def fstat(self, fp):
146 return util.fstat(fp)
146 return util.fstat(fp)
147
147
148 def isdir(self, path: Optional[bytes] = None) -> bool:
148 def isdir(self, path: Optional[bytes] = None) -> bool:
149 return os.path.isdir(self.join(path))
149 return os.path.isdir(self.join(path))
150
150
151 def isfile(self, path: Optional[bytes] = None) -> bool:
151 def isfile(self, path: Optional[bytes] = None) -> bool:
152 return os.path.isfile(self.join(path))
152 return os.path.isfile(self.join(path))
153
153
154 def islink(self, path: Optional[bytes] = None) -> bool:
154 def islink(self, path: Optional[bytes] = None) -> bool:
155 return os.path.islink(self.join(path))
155 return os.path.islink(self.join(path))
156
156
157 def isfileorlink(self, path: Optional[bytes] = None) -> bool:
157 def isfileorlink(self, path: Optional[bytes] = None) -> bool:
158 """return whether path is a regular file or a symlink
158 """return whether path is a regular file or a symlink
159
159
160 Unlike isfile, this doesn't follow symlinks."""
160 Unlike isfile, this doesn't follow symlinks."""
161 try:
161 try:
162 st = self.lstat(path)
162 st = self.lstat(path)
163 except OSError:
163 except OSError:
164 return False
164 return False
165 mode = st.st_mode
165 mode = st.st_mode
166 return stat.S_ISREG(mode) or stat.S_ISLNK(mode)
166 return stat.S_ISREG(mode) or stat.S_ISLNK(mode)
167
167
168 def _join(self, *paths: bytes) -> bytes:
168 def _join(self, *paths: bytes) -> bytes:
169 root_idx = 0
169 root_idx = 0
170 for idx, p in enumerate(paths):
170 for idx, p in enumerate(paths):
171 if os.path.isabs(p) or p.startswith(self._dir_sep):
171 if os.path.isabs(p) or p.startswith(self._dir_sep):
172 root_idx = idx
172 root_idx = idx
173 if root_idx != 0:
173 if root_idx != 0:
174 paths = paths[root_idx:]
174 paths = paths[root_idx:]
175 paths = [p for p in paths if p]
175 paths = [p for p in paths if p]
176 return self._dir_sep.join(paths)
176 return self._dir_sep.join(paths)
177
177
178 def reljoin(self, *paths: bytes) -> bytes:
178 def reljoin(self, *paths: bytes) -> bytes:
179 """join various elements of a path together (as os.path.join would do)
179 """join various elements of a path together (as os.path.join would do)
180
180
181 The vfs base is not injected so that path stay relative. This exists
181 The vfs base is not injected so that path stay relative. This exists
182 to allow handling of strange encoding if needed."""
182 to allow handling of strange encoding if needed."""
183 return self._join(*paths)
183 return self._join(*paths)
184
184
185 def split(self, path: bytes):
185 def split(self, path: bytes):
186 """split top-most element of a path (as os.path.split would do)
186 """split top-most element of a path (as os.path.split would do)
187
187
188 This exists to allow handling of strange encoding if needed."""
188 This exists to allow handling of strange encoding if needed."""
189 return os.path.split(path)
189 return os.path.split(path)
190
190
191 def lexists(self, path: Optional[bytes] = None) -> bool:
191 def lexists(self, path: Optional[bytes] = None) -> bool:
192 return os.path.lexists(self.join(path))
192 return os.path.lexists(self.join(path))
193
193
194 def lstat(self, path: Optional[bytes] = None):
194 def lstat(self, path: Optional[bytes] = None):
195 return os.lstat(self.join(path))
195 return os.lstat(self.join(path))
196
196
197 def listdir(self, path: Optional[bytes] = None):
197 def listdir(self, path: Optional[bytes] = None):
198 return os.listdir(self.join(path))
198 return os.listdir(self.join(path))
199
199
200 def makedir(self, path: Optional[bytes] = None, notindexed=True):
200 def makedir(self, path: Optional[bytes] = None, notindexed=True):
201 return util.makedir(self.join(path), notindexed)
201 return util.makedir(self.join(path), notindexed)
202
202
203 def makedirs(
203 def makedirs(
204 self, path: Optional[bytes] = None, mode: Optional[int] = None
204 self, path: Optional[bytes] = None, mode: Optional[int] = None
205 ):
205 ):
206 return util.makedirs(self.join(path), mode)
206 return util.makedirs(self.join(path), mode)
207
207
208 def makelock(self, info, path: bytes):
208 def makelock(self, info, path: bytes):
209 return util.makelock(info, self.join(path))
209 return util.makelock(info, self.join(path))
210
210
211 def mkdir(self, path: Optional[bytes] = None):
211 def mkdir(self, path: Optional[bytes] = None):
212 return os.mkdir(self.join(path))
212 return os.mkdir(self.join(path))
213
213
214 def mkstemp(
214 def mkstemp(
215 self,
215 self,
216 suffix: bytes = b'',
216 suffix: bytes = b'',
217 prefix: bytes = b'tmp',
217 prefix: bytes = b'tmp',
218 dir: Optional[bytes] = None,
218 dir: Optional[bytes] = None,
219 ):
219 ):
220 fd, name = pycompat.mkstemp(
220 fd, name = pycompat.mkstemp(
221 suffix=suffix, prefix=prefix, dir=self.join(dir)
221 suffix=suffix, prefix=prefix, dir=self.join(dir)
222 )
222 )
223 dname, fname = util.split(name)
223 dname, fname = util.split(name)
224 if dir:
224 if dir:
225 return fd, os.path.join(dir, fname)
225 return fd, os.path.join(dir, fname)
226 else:
226 else:
227 return fd, fname
227 return fd, fname
228
228
229 def readdir(self, path: Optional[bytes] = None, stat=None, skip=None):
229 def readdir(self, path: Optional[bytes] = None, stat=None, skip=None):
230 return util.listdir(self.join(path), stat, skip)
230 return util.listdir(self.join(path), stat, skip)
231
231
232 def readlock(self, path: bytes) -> bytes:
232 def readlock(self, path: bytes) -> bytes:
233 return util.readlock(self.join(path))
233 return util.readlock(self.join(path))
234
234
235 def rename(self, src: bytes, dst: bytes, checkambig=False):
235 def rename(self, src: bytes, dst: bytes, checkambig=False):
236 """Rename from src to dst
236 """Rename from src to dst
237
237
238 checkambig argument is used with util.filestat, and is useful
238 checkambig argument is used with util.filestat, and is useful
239 only if destination file is guarded by any lock
239 only if destination file is guarded by any lock
240 (e.g. repo.lock or repo.wlock).
240 (e.g. repo.lock or repo.wlock).
241
241
242 To avoid file stat ambiguity forcibly, checkambig=True involves
242 To avoid file stat ambiguity forcibly, checkambig=True involves
243 copying ``src`` file, if it is owned by another. Therefore, use
243 copying ``src`` file, if it is owned by another. Therefore, use
244 checkambig=True only in limited cases (see also issue5418 and
244 checkambig=True only in limited cases (see also issue5418 and
245 issue5584 for detail).
245 issue5584 for detail).
246 """
246 """
247 self._auditpath(dst, b'w')
247 self._auditpath(dst, b'w')
248 srcpath = self.join(src)
248 srcpath = self.join(src)
249 dstpath = self.join(dst)
249 dstpath = self.join(dst)
250 oldstat = checkambig and util.filestat.frompath(dstpath)
250 oldstat = checkambig and util.filestat.frompath(dstpath)
251 if oldstat and oldstat.stat:
251 if oldstat and oldstat.stat:
252 ret = util.rename(srcpath, dstpath)
252 ret = util.rename(srcpath, dstpath)
253 _avoidambig(dstpath, oldstat)
253 _avoidambig(dstpath, oldstat)
254 return ret
254 return ret
255 return util.rename(srcpath, dstpath)
255 return util.rename(srcpath, dstpath)
256
256
257 def readlink(self, path: bytes) -> bytes:
257 def readlink(self, path: bytes) -> bytes:
258 return util.readlink(self.join(path))
258 return util.readlink(self.join(path))
259
259
260 def removedirs(self, path: Optional[bytes] = None):
260 def removedirs(self, path: Optional[bytes] = None):
261 """Remove a leaf directory and all empty intermediate ones"""
261 """Remove a leaf directory and all empty intermediate ones"""
262 return util.removedirs(self.join(path))
262 return util.removedirs(self.join(path))
263
263
264 def rmdir(self, path: Optional[bytes] = None):
264 def rmdir(self, path: Optional[bytes] = None):
265 """Remove an empty directory."""
265 """Remove an empty directory."""
266 return os.rmdir(self.join(path))
266 return os.rmdir(self.join(path))
267
267
268 def rmtree(
268 def rmtree(
269 self, path: Optional[bytes] = None, ignore_errors=False, forcibly=False
269 self, path: Optional[bytes] = None, ignore_errors=False, forcibly=False
270 ):
270 ):
271 """Remove a directory tree recursively
271 """Remove a directory tree recursively
272
272
273 If ``forcibly``, this tries to remove READ-ONLY files, too.
273 If ``forcibly``, this tries to remove READ-ONLY files, too.
274 """
274 """
275 if forcibly:
275 if forcibly:
276
276
277 def onerror(function, path, excinfo):
277 def onerror(function, path, excinfo):
278 if function is not os.remove:
278 if function is not os.remove:
279 raise
279 raise
280 # read-only files cannot be unlinked under Windows
280 # read-only files cannot be unlinked under Windows
281 s = os.stat(path)
281 s = os.stat(path)
282 if (s.st_mode & stat.S_IWRITE) != 0:
282 if (s.st_mode & stat.S_IWRITE) != 0:
283 raise
283 raise
284 os.chmod(path, stat.S_IMODE(s.st_mode) | stat.S_IWRITE)
284 os.chmod(path, stat.S_IMODE(s.st_mode) | stat.S_IWRITE)
285 os.remove(path)
285 os.remove(path)
286
286
287 else:
287 else:
288 onerror = None
288 onerror = None
289 return shutil.rmtree(
289 return shutil.rmtree(
290 self.join(path), ignore_errors=ignore_errors, onerror=onerror
290 self.join(path), ignore_errors=ignore_errors, onerror=onerror
291 )
291 )
292
292
293 def setflags(self, path: bytes, l: bool, x: bool):
293 def setflags(self, path: bytes, l: bool, x: bool):
294 return util.setflags(self.join(path), l, x)
294 return util.setflags(self.join(path), l, x)
295
295
296 def stat(self, path: Optional[bytes] = None):
296 def stat(self, path: Optional[bytes] = None):
297 return os.stat(self.join(path))
297 return os.stat(self.join(path))
298
298
299 def unlink(self, path: Optional[bytes] = None):
299 def unlink(self, path: Optional[bytes] = None):
300 return util.unlink(self.join(path))
300 return util.unlink(self.join(path))
301
301
302 def tryunlink(self, path: Optional[bytes] = None):
302 def tryunlink(self, path: Optional[bytes] = None):
303 """Attempt to remove a file, ignoring missing file errors."""
303 """Attempt to remove a file, ignoring missing file errors."""
304 util.tryunlink(self.join(path))
304 util.tryunlink(self.join(path))
305
305
306 def unlinkpath(
306 def unlinkpath(
307 self, path: Optional[bytes] = None, ignoremissing=False, rmdir=True
307 self, path: Optional[bytes] = None, ignoremissing=False, rmdir=True
308 ):
308 ):
309 return util.unlinkpath(
309 return util.unlinkpath(
310 self.join(path), ignoremissing=ignoremissing, rmdir=rmdir
310 self.join(path), ignoremissing=ignoremissing, rmdir=rmdir
311 )
311 )
312
312
313 def utime(self, path: Optional[bytes] = None, t=None):
313 def utime(self, path: Optional[bytes] = None, t=None):
314 return os.utime(self.join(path), t)
314 return os.utime(self.join(path), t)
315
315
316 def walk(self, path: Optional[bytes] = None, onerror=None):
316 def walk(self, path: Optional[bytes] = None, onerror=None):
317 """Yield (dirpath, dirs, files) tuple for each directories under path
317 """Yield (dirpath, dirs, files) tuple for each directories under path
318
318
319 ``dirpath`` is relative one from the root of this vfs. This
319 ``dirpath`` is relative one from the root of this vfs. This
320 uses ``os.sep`` as path separator, even you specify POSIX
320 uses ``os.sep`` as path separator, even you specify POSIX
321 style ``path``.
321 style ``path``.
322
322
323 "The root of this vfs" is represented as empty ``dirpath``.
323 "The root of this vfs" is represented as empty ``dirpath``.
324 """
324 """
325 root = os.path.normpath(self.join(None))
325 root = os.path.normpath(self.join(None))
326 # when dirpath == root, dirpath[prefixlen:] becomes empty
326 # when dirpath == root, dirpath[prefixlen:] becomes empty
327 # because len(dirpath) < prefixlen.
327 # because len(dirpath) < prefixlen.
328 prefixlen = len(pathutil.normasprefix(root))
328 prefixlen = len(pathutil.normasprefix(root))
329 for dirpath, dirs, files in os.walk(self.join(path), onerror=onerror):
329 for dirpath, dirs, files in os.walk(self.join(path), onerror=onerror):
330 yield (dirpath[prefixlen:], dirs, files)
330 yield (dirpath[prefixlen:], dirs, files)
331
331
332 @contextlib.contextmanager
332 @contextlib.contextmanager
333 def backgroundclosing(self, ui, expectedcount=-1):
333 def backgroundclosing(self, ui, expectedcount=-1):
334 """Allow files to be closed asynchronously.
334 """Allow files to be closed asynchronously.
335
335
336 When this context manager is active, ``backgroundclose`` can be passed
336 When this context manager is active, ``backgroundclose`` can be passed
337 to ``__call__``/``open`` to result in the file possibly being closed
337 to ``__call__``/``open`` to result in the file possibly being closed
338 asynchronously, on a background thread.
338 asynchronously, on a background thread.
339 """
339 """
340 # Sharing backgroundfilecloser between threads is complex and using
340 # Sharing backgroundfilecloser between threads is complex and using
341 # multiple instances puts us at risk of running out of file descriptors
341 # multiple instances puts us at risk of running out of file descriptors
342 # only allow to use backgroundfilecloser when in main thread.
342 # only allow to use backgroundfilecloser when in main thread.
343 if not isinstance(
343 if not isinstance(
344 threading.current_thread(),
344 threading.current_thread(),
345 threading._MainThread, # pytype: disable=module-attr
345 threading._MainThread, # pytype: disable=module-attr
346 ):
346 ):
347 yield
347 yield
348 return
348 return
349 vfs = getattr(self, 'vfs', self)
349 vfs = getattr(self, 'vfs', self)
350 if getattr(vfs, '_backgroundfilecloser', None):
350 if getattr(vfs, '_backgroundfilecloser', None):
351 raise error.Abort(
351 raise error.Abort(
352 _(b'can only have 1 active background file closer')
352 _(b'can only have 1 active background file closer')
353 )
353 )
354
354
355 with backgroundfilecloser(ui, expectedcount=expectedcount) as bfc:
355 with backgroundfilecloser(ui, expectedcount=expectedcount) as bfc:
356 try:
356 try:
357 vfs._backgroundfilecloser = (
357 vfs._backgroundfilecloser = (
358 bfc # pytype: disable=attribute-error
358 bfc # pytype: disable=attribute-error
359 )
359 )
360 yield bfc
360 yield bfc
361 finally:
361 finally:
362 vfs._backgroundfilecloser = (
362 vfs._backgroundfilecloser = (
363 None # pytype: disable=attribute-error
363 None # pytype: disable=attribute-error
364 )
364 )
365
365
366 def register_file(self, path):
366 def register_file(self, path):
367 """generic hook point to lets fncache steer its stew"""
367 """generic hook point to lets fncache steer its stew"""
368
368
369
369
370 class vfs(abstractvfs):
370 class vfs(abstractvfs):
371 """Operate files relative to a base directory
371 """Operate files relative to a base directory
372
372
373 This class is used to hide the details of COW semantics and
373 This class is used to hide the details of COW semantics and
374 remote file access from higher level code.
374 remote file access from higher level code.
375
375
376 'cacheaudited' should be enabled only if (a) vfs object is short-lived, or
376 'cacheaudited' should be enabled only if (a) vfs object is short-lived, or
377 (b) the base directory is managed by hg and considered sort-of append-only.
377 (b) the base directory is managed by hg and considered sort-of append-only.
378 See pathutil.pathauditor() for details.
378 See pathutil.pathauditor() for details.
379 """
379 """
380
380
381 def __init__(
381 def __init__(
382 self,
382 self,
383 base: bytes,
383 base: bytes,
384 audit=True,
384 audit=True,
385 cacheaudited=False,
385 cacheaudited=False,
386 expandpath=False,
386 expandpath=False,
387 realpath=False,
387 realpath=False,
388 ):
388 ):
389 if expandpath:
389 if expandpath:
390 base = util.expandpath(base)
390 base = util.expandpath(base)
391 if realpath:
391 if realpath:
392 base = os.path.realpath(base)
392 base = os.path.realpath(base)
393 self.base = base
393 self.base = base
394 self._audit = audit
394 self._audit = audit
395 if audit:
395 if audit:
396 self.audit = pathutil.pathauditor(self.base, cached=cacheaudited)
396 self.audit = pathutil.pathauditor(self.base, cached=cacheaudited)
397 else:
397 else:
398 self.audit = lambda path, mode=None: True
398 self.audit = lambda path, mode=None: True
399 self.createmode = None
399 self.createmode = None
400 self._trustnlink = None
400 self._trustnlink = None
401 self.options = {}
401 self.options = {}
402
402
403 @util.propertycache
403 @util.propertycache
404 def _cansymlink(self) -> bool:
404 def _cansymlink(self) -> bool:
405 return util.checklink(self.base)
405 return util.checklink(self.base)
406
406
407 @util.propertycache
407 @util.propertycache
408 def _chmod(self):
408 def _chmod(self):
409 return util.checkexec(self.base)
409 return util.checkexec(self.base)
410
410
411 def _fixfilemode(self, name):
411 def _fixfilemode(self, name):
412 if self.createmode is None or not self._chmod:
412 if self.createmode is None or not self._chmod:
413 return
413 return
414 os.chmod(name, self.createmode & 0o666)
414 os.chmod(name, self.createmode & 0o666)
415
415
416 def _auditpath(self, path, mode) -> None:
416 def _auditpath(self, path, mode) -> None:
417 if self._audit:
417 if self._audit:
418 if os.path.isabs(path) and path.startswith(self.base):
418 if os.path.isabs(path) and path.startswith(self.base):
419 path = os.path.relpath(path, self.base)
419 path = os.path.relpath(path, self.base)
420 r = util.checkosfilename(path)
420 r = util.checkosfilename(path)
421 if r:
421 if r:
422 raise error.Abort(b"%s: %r" % (r, path))
422 raise error.Abort(b"%s: %r" % (r, path))
423 self.audit(path, mode=mode)
423 self.audit(path, mode=mode)
424
424
425 def isfileorlink_checkdir(
425 def isfileorlink_checkdir(
426 self, dircache, path: Optional[bytes] = None
426 self, dircache, path: Optional[bytes] = None
427 ) -> bool:
427 ) -> bool:
428 """return True if the path is a regular file or a symlink and
428 """return True if the path is a regular file or a symlink and
429 the directories along the path are "normal", that is
429 the directories along the path are "normal", that is
430 not symlinks or nested hg repositories.
430 not symlinks or nested hg repositories.
431
431
432 Ignores the `_audit` setting, and checks the directories regardless.
432 Ignores the `_audit` setting, and checks the directories regardless.
433 `dircache` is used to cache the directory checks.
433 `dircache` is used to cache the directory checks.
434 """
434 """
435 try:
435 try:
436 for prefix in pathutil.finddirs_rev_noroot(util.localpath(path)):
436 for prefix in pathutil.finddirs_rev_noroot(util.localpath(path)):
437 if prefix in dircache:
437 if prefix in dircache:
438 res = dircache[prefix]
438 res = dircache[prefix]
439 else:
439 else:
440 res = pathutil.pathauditor._checkfs_exists(
440 res = pathutil.pathauditor._checkfs_exists(
441 self.base, prefix, path
441 self.base, prefix, path
442 )
442 )
443 dircache[prefix] = res
443 dircache[prefix] = res
444 if not res:
444 if not res:
445 return False
445 return False
446 except (OSError, error.Abort):
446 except (OSError, error.Abort):
447 return False
447 return False
448 return self.isfileorlink(path)
448 return self.isfileorlink(path)
449
449
450 def __call__(
450 def __call__(
451 self,
451 self,
452 path: bytes,
452 path: bytes,
453 mode: bytes = b"rb",
453 mode: bytes = b"rb",
454 atomictemp=False,
454 atomictemp=False,
455 notindexed=False,
455 notindexed=False,
456 backgroundclose=False,
456 backgroundclose=False,
457 checkambig=False,
457 checkambig=False,
458 auditpath=True,
458 auditpath=True,
459 makeparentdirs=True,
459 makeparentdirs=True,
460 ):
460 ):
461 """Open ``path`` file, which is relative to vfs root.
461 """Open ``path`` file, which is relative to vfs root.
462
462
463 By default, parent directories are created as needed. Newly created
463 By default, parent directories are created as needed. Newly created
464 directories are marked as "not to be indexed by the content indexing
464 directories are marked as "not to be indexed by the content indexing
465 service", if ``notindexed`` is specified for "write" mode access.
465 service", if ``notindexed`` is specified for "write" mode access.
466 Set ``makeparentdirs=False`` to not create directories implicitly.
466 Set ``makeparentdirs=False`` to not create directories implicitly.
467
467
468 If ``backgroundclose`` is passed, the file may be closed asynchronously.
468 If ``backgroundclose`` is passed, the file may be closed asynchronously.
469 It can only be used if the ``self.backgroundclosing()`` context manager
469 It can only be used if the ``self.backgroundclosing()`` context manager
470 is active. This should only be specified if the following criteria hold:
470 is active. This should only be specified if the following criteria hold:
471
471
472 1. There is a potential for writing thousands of files. Unless you
472 1. There is a potential for writing thousands of files. Unless you
473 are writing thousands of files, the performance benefits of
473 are writing thousands of files, the performance benefits of
474 asynchronously closing files is not realized.
474 asynchronously closing files is not realized.
475 2. Files are opened exactly once for the ``backgroundclosing``
475 2. Files are opened exactly once for the ``backgroundclosing``
476 active duration and are therefore free of race conditions between
476 active duration and are therefore free of race conditions between
477 closing a file on a background thread and reopening it. (If the
477 closing a file on a background thread and reopening it. (If the
478 file were opened multiple times, there could be unflushed data
478 file were opened multiple times, there could be unflushed data
479 because the original file handle hasn't been flushed/closed yet.)
479 because the original file handle hasn't been flushed/closed yet.)
480
480
481 ``checkambig`` argument is passed to atomictempfile (valid
481 ``checkambig`` argument is passed to atomictempfile (valid
482 only for writing), and is useful only if target file is
482 only for writing), and is useful only if target file is
483 guarded by any lock (e.g. repo.lock or repo.wlock).
483 guarded by any lock (e.g. repo.lock or repo.wlock).
484
484
485 To avoid file stat ambiguity forcibly, checkambig=True involves
485 To avoid file stat ambiguity forcibly, checkambig=True involves
486 copying ``path`` file opened in "append" mode (e.g. for
486 copying ``path`` file opened in "append" mode (e.g. for
487 truncation), if it is owned by another. Therefore, use
487 truncation), if it is owned by another. Therefore, use
488 combination of append mode and checkambig=True only in limited
488 combination of append mode and checkambig=True only in limited
489 cases (see also issue5418 and issue5584 for detail).
489 cases (see also issue5418 and issue5584 for detail).
490 """
490 """
491 if auditpath:
491 if auditpath:
492 self._auditpath(path, mode)
492 self._auditpath(path, mode)
493 f = self.join(path)
493 f = self.join(path)
494
494
495 if b"b" not in mode:
495 if b"b" not in mode:
496 mode += b"b" # for that other OS
496 mode += b"b" # for that other OS
497
497
498 nlink = -1
498 nlink = -1
499 if mode not in (b'r', b'rb'):
499 if mode not in (b'r', b'rb'):
500 dirname, basename = util.split(f)
500 dirname, basename = util.split(f)
501 # If basename is empty, then the path is malformed because it points
501 # If basename is empty, then the path is malformed because it points
502 # to a directory. Let the posixfile() call below raise IOError.
502 # to a directory. Let the posixfile() call below raise IOError.
503 if basename:
503 if basename:
504 if atomictemp:
504 if atomictemp:
505 if makeparentdirs:
505 if makeparentdirs:
506 util.makedirs(dirname, self.createmode, notindexed)
506 util.makedirs(dirname, self.createmode, notindexed)
507 return util.atomictempfile(
507 return util.atomictempfile(
508 f, mode, self.createmode, checkambig=checkambig
508 f, mode, self.createmode, checkambig=checkambig
509 )
509 )
510 try:
510 try:
511 if b'w' in mode:
511 if b'w' in mode:
512 util.unlink(f)
512 util.unlink(f)
513 nlink = 0
513 nlink = 0
514 else:
514 else:
515 # nlinks() may behave differently for files on Windows
515 # nlinks() may behave differently for files on Windows
516 # shares if the file is open.
516 # shares if the file is open.
517 with util.posixfile(f):
517 with util.posixfile(f):
518 nlink = util.nlinks(f)
518 nlink = util.nlinks(f)
519 if nlink < 1:
519 if nlink < 1:
520 nlink = 2 # force mktempcopy (issue1922)
520 nlink = 2 # force mktempcopy (issue1922)
521 except FileNotFoundError:
521 except FileNotFoundError:
522 nlink = 0
522 nlink = 0
523 if makeparentdirs:
523 if makeparentdirs:
524 util.makedirs(dirname, self.createmode, notindexed)
524 util.makedirs(dirname, self.createmode, notindexed)
525 if nlink > 0:
525 if nlink > 0:
526 if self._trustnlink is None:
526 if self._trustnlink is None:
527 self._trustnlink = nlink > 1 or util.checknlink(f)
527 self._trustnlink = nlink > 1 or util.checknlink(f)
528 if nlink > 1 or not self._trustnlink:
528 if nlink > 1 or not self._trustnlink:
529 util.rename(util.mktempcopy(f), f)
529 util.rename(util.mktempcopy(f), f)
530 fp = util.posixfile(f, mode)
530 fp = util.posixfile(f, mode)
531 if nlink == 0:
531 if nlink == 0:
532 self._fixfilemode(f)
532 self._fixfilemode(f)
533
533
534 if checkambig:
534 if checkambig:
535 if mode in (b'r', b'rb'):
535 if mode in (b'r', b'rb'):
536 raise error.Abort(
536 raise error.Abort(
537 _(
537 _(
538 b'implementation error: mode %s is not'
538 b'implementation error: mode %s is not'
539 b' valid for checkambig=True'
539 b' valid for checkambig=True'
540 )
540 )
541 % mode
541 % mode
542 )
542 )
543 fp = checkambigatclosing(fp)
543 fp = checkambigatclosing(fp)
544
544
545 if backgroundclose and isinstance(
545 if backgroundclose and isinstance(
546 threading.current_thread(),
546 threading.current_thread(),
547 threading._MainThread, # pytype: disable=module-attr
547 threading._MainThread, # pytype: disable=module-attr
548 ):
548 ):
549 if (
549 if (
550 not self._backgroundfilecloser # pytype: disable=attribute-error
550 not self._backgroundfilecloser # pytype: disable=attribute-error
551 ):
551 ):
552 raise error.Abort(
552 raise error.Abort(
553 _(
553 _(
554 b'backgroundclose can only be used when a '
554 b'backgroundclose can only be used when a '
555 b'backgroundclosing context manager is active'
555 b'backgroundclosing context manager is active'
556 )
556 )
557 )
557 )
558
558
559 fp = delayclosedfile(
559 fp = delayclosedfile(
560 fp,
560 fp,
561 self._backgroundfilecloser, # pytype: disable=attribute-error
561 self._backgroundfilecloser, # pytype: disable=attribute-error
562 )
562 )
563
563
564 return fp
564 return fp
565
565
566 def symlink(self, src: bytes, dst: bytes) -> None:
566 def symlink(self, src: bytes, dst: bytes) -> None:
567 self.audit(dst)
567 self.audit(dst)
568 linkname = self.join(dst)
568 linkname = self.join(dst)
569 util.tryunlink(linkname)
569 util.tryunlink(linkname)
570
570
571 util.makedirs(os.path.dirname(linkname), self.createmode)
571 util.makedirs(os.path.dirname(linkname), self.createmode)
572
572
573 if self._cansymlink:
573 if self._cansymlink:
574 try:
574 try:
575 os.symlink(src, linkname)
575 os.symlink(src, linkname)
576 except OSError as err:
576 except OSError as err:
577 raise OSError(
577 raise OSError(
578 err.errno,
578 err.errno,
579 _(b'could not symlink to %r: %s')
579 _(b'could not symlink to %r: %s')
580 % (src, encoding.strtolocal(err.strerror)),
580 % (src, encoding.strtolocal(err.strerror)),
581 linkname,
581 linkname,
582 )
582 )
583 else:
583 else:
584 self.write(dst, src)
584 self.write(dst, src)
585
585
586 def join(self, path: Optional[bytes], *insidef: bytes) -> bytes:
586 def join(self, path: Optional[bytes], *insidef: bytes) -> bytes:
587 if path:
587 if path:
588 parts = [self.base, path]
588 parts = [self.base, path]
589 parts.extend(insidef)
589 parts.extend(insidef)
590 return self._join(*parts)
590 return self._join(*parts)
591 else:
591 else:
592 return self.base
592 return self.base
593
593
594
594
595 opener = vfs
595 opener = vfs
596
596
597
597
598 class proxyvfs(abstractvfs):
598 class proxyvfs(abstractvfs):
599 def __init__(self, vfs: "vfs"):
599 def __init__(self, vfs: "vfs"):
600 self.vfs = vfs
600 self.vfs = vfs
601
601
602 @property
603 def createmode(self):
604 return self.vfs.createmode
605
602 def _auditpath(self, path, mode):
606 def _auditpath(self, path, mode):
603 return self.vfs._auditpath(path, mode)
607 return self.vfs._auditpath(path, mode)
604
608
605 @property
609 @property
606 def options(self):
610 def options(self):
607 return self.vfs.options
611 return self.vfs.options
608
612
609 @options.setter
613 @options.setter
610 def options(self, value):
614 def options(self, value):
611 self.vfs.options = value
615 self.vfs.options = value
612
616
613
617
614 class filtervfs(proxyvfs, abstractvfs):
618 class filtervfs(proxyvfs, abstractvfs):
615 '''Wrapper vfs for filtering filenames with a function.'''
619 '''Wrapper vfs for filtering filenames with a function.'''
616
620
617 def __init__(self, vfs: "vfs", filter):
621 def __init__(self, vfs: "vfs", filter):
618 proxyvfs.__init__(self, vfs)
622 proxyvfs.__init__(self, vfs)
619 self._filter = filter
623 self._filter = filter
620
624
621 def __call__(self, path: bytes, *args, **kwargs):
625 def __call__(self, path: bytes, *args, **kwargs):
622 return self.vfs(self._filter(path), *args, **kwargs)
626 return self.vfs(self._filter(path), *args, **kwargs)
623
627
624 def join(self, path: Optional[bytes], *insidef: bytes) -> bytes:
628 def join(self, path: Optional[bytes], *insidef: bytes) -> bytes:
625 if path:
629 if path:
626 return self.vfs.join(self._filter(self.vfs.reljoin(path, *insidef)))
630 return self.vfs.join(self._filter(self.vfs.reljoin(path, *insidef)))
627 else:
631 else:
628 return self.vfs.join(path)
632 return self.vfs.join(path)
629
633
630
634
631 filteropener = filtervfs
635 filteropener = filtervfs
632
636
633
637
634 class readonlyvfs(proxyvfs):
638 class readonlyvfs(proxyvfs):
635 '''Wrapper vfs preventing any writing.'''
639 '''Wrapper vfs preventing any writing.'''
636
640
637 def __init__(self, vfs: "vfs"):
641 def __init__(self, vfs: "vfs"):
638 proxyvfs.__init__(self, vfs)
642 proxyvfs.__init__(self, vfs)
639
643
640 def __call__(self, path: bytes, mode: bytes = b'rb', *args, **kw):
644 def __call__(self, path: bytes, mode: bytes = b'rb', *args, **kw):
641 if mode not in (b'r', b'rb'):
645 if mode not in (b'r', b'rb'):
642 raise error.Abort(_(b'this vfs is read only'))
646 raise error.Abort(_(b'this vfs is read only'))
643 return self.vfs(path, mode, *args, **kw)
647 return self.vfs(path, mode, *args, **kw)
644
648
645 def join(self, path: Optional[bytes], *insidef: bytes) -> bytes:
649 def join(self, path: Optional[bytes], *insidef: bytes) -> bytes:
646 return self.vfs.join(path, *insidef)
650 return self.vfs.join(path, *insidef)
647
651
648
652
649 class closewrapbase:
653 class closewrapbase:
650 """Base class of wrapper, which hooks closing
654 """Base class of wrapper, which hooks closing
651
655
652 Do not instantiate outside of the vfs layer.
656 Do not instantiate outside of the vfs layer.
653 """
657 """
654
658
655 def __init__(self, fh):
659 def __init__(self, fh):
656 object.__setattr__(self, '_origfh', fh)
660 object.__setattr__(self, '_origfh', fh)
657
661
658 def __getattr__(self, attr):
662 def __getattr__(self, attr):
659 return getattr(self._origfh, attr)
663 return getattr(self._origfh, attr)
660
664
661 def __setattr__(self, attr, value):
665 def __setattr__(self, attr, value):
662 return setattr(self._origfh, attr, value)
666 return setattr(self._origfh, attr, value)
663
667
664 def __delattr__(self, attr):
668 def __delattr__(self, attr):
665 return delattr(self._origfh, attr)
669 return delattr(self._origfh, attr)
666
670
667 def __enter__(self):
671 def __enter__(self):
668 self._origfh.__enter__()
672 self._origfh.__enter__()
669 return self
673 return self
670
674
671 def __exit__(self, exc_type, exc_value, exc_tb):
675 def __exit__(self, exc_type, exc_value, exc_tb):
672 raise NotImplementedError('attempted instantiating ' + str(type(self)))
676 raise NotImplementedError('attempted instantiating ' + str(type(self)))
673
677
674 def close(self):
678 def close(self):
675 raise NotImplementedError('attempted instantiating ' + str(type(self)))
679 raise NotImplementedError('attempted instantiating ' + str(type(self)))
676
680
677
681
678 class delayclosedfile(closewrapbase):
682 class delayclosedfile(closewrapbase):
679 """Proxy for a file object whose close is delayed.
683 """Proxy for a file object whose close is delayed.
680
684
681 Do not instantiate outside of the vfs layer.
685 Do not instantiate outside of the vfs layer.
682 """
686 """
683
687
684 def __init__(self, fh, closer):
688 def __init__(self, fh, closer):
685 super(delayclosedfile, self).__init__(fh)
689 super(delayclosedfile, self).__init__(fh)
686 object.__setattr__(self, '_closer', closer)
690 object.__setattr__(self, '_closer', closer)
687
691
688 def __exit__(self, exc_type, exc_value, exc_tb):
692 def __exit__(self, exc_type, exc_value, exc_tb):
689 self._closer.close(self._origfh)
693 self._closer.close(self._origfh)
690
694
691 def close(self):
695 def close(self):
692 self._closer.close(self._origfh)
696 self._closer.close(self._origfh)
693
697
694
698
695 class backgroundfilecloser:
699 class backgroundfilecloser:
696 """Coordinates background closing of file handles on multiple threads."""
700 """Coordinates background closing of file handles on multiple threads."""
697
701
698 def __init__(self, ui, expectedcount=-1):
702 def __init__(self, ui, expectedcount=-1):
699 self._running = False
703 self._running = False
700 self._entered = False
704 self._entered = False
701 self._threads = []
705 self._threads = []
702 self._threadexception = None
706 self._threadexception = None
703
707
704 # Only Windows/NTFS has slow file closing. So only enable by default
708 # Only Windows/NTFS has slow file closing. So only enable by default
705 # on that platform. But allow to be enabled elsewhere for testing.
709 # on that platform. But allow to be enabled elsewhere for testing.
706 defaultenabled = pycompat.iswindows
710 defaultenabled = pycompat.iswindows
707 enabled = ui.configbool(b'worker', b'backgroundclose', defaultenabled)
711 enabled = ui.configbool(b'worker', b'backgroundclose', defaultenabled)
708
712
709 if not enabled:
713 if not enabled:
710 return
714 return
711
715
712 # There is overhead to starting and stopping the background threads.
716 # There is overhead to starting and stopping the background threads.
713 # Don't do background processing unless the file count is large enough
717 # Don't do background processing unless the file count is large enough
714 # to justify it.
718 # to justify it.
715 minfilecount = ui.configint(b'worker', b'backgroundcloseminfilecount')
719 minfilecount = ui.configint(b'worker', b'backgroundcloseminfilecount')
716 # FUTURE dynamically start background threads after minfilecount closes.
720 # FUTURE dynamically start background threads after minfilecount closes.
717 # (We don't currently have any callers that don't know their file count)
721 # (We don't currently have any callers that don't know their file count)
718 if expectedcount > 0 and expectedcount < minfilecount:
722 if expectedcount > 0 and expectedcount < minfilecount:
719 return
723 return
720
724
721 maxqueue = ui.configint(b'worker', b'backgroundclosemaxqueue')
725 maxqueue = ui.configint(b'worker', b'backgroundclosemaxqueue')
722 threadcount = ui.configint(b'worker', b'backgroundclosethreadcount')
726 threadcount = ui.configint(b'worker', b'backgroundclosethreadcount')
723
727
724 ui.debug(
728 ui.debug(
725 b'starting %d threads for background file closing\n' % threadcount
729 b'starting %d threads for background file closing\n' % threadcount
726 )
730 )
727
731
728 self._queue = pycompat.queue.Queue(maxsize=maxqueue)
732 self._queue = pycompat.queue.Queue(maxsize=maxqueue)
729 self._running = True
733 self._running = True
730
734
731 for i in range(threadcount):
735 for i in range(threadcount):
732 t = threading.Thread(target=self._worker, name='backgroundcloser')
736 t = threading.Thread(target=self._worker, name='backgroundcloser')
733 self._threads.append(t)
737 self._threads.append(t)
734 t.start()
738 t.start()
735
739
736 def __enter__(self):
740 def __enter__(self):
737 self._entered = True
741 self._entered = True
738 return self
742 return self
739
743
740 def __exit__(self, exc_type, exc_value, exc_tb):
744 def __exit__(self, exc_type, exc_value, exc_tb):
741 self._running = False
745 self._running = False
742
746
743 # Wait for threads to finish closing so open files don't linger for
747 # Wait for threads to finish closing so open files don't linger for
744 # longer than lifetime of context manager.
748 # longer than lifetime of context manager.
745 for t in self._threads:
749 for t in self._threads:
746 t.join()
750 t.join()
747
751
748 def _worker(self):
752 def _worker(self):
749 """Main routine for worker thread."""
753 """Main routine for worker thread."""
750 while True:
754 while True:
751 try:
755 try:
752 fh = self._queue.get(block=True, timeout=0.100)
756 fh = self._queue.get(block=True, timeout=0.100)
753 # Need to catch or the thread will terminate and
757 # Need to catch or the thread will terminate and
754 # we could orphan file descriptors.
758 # we could orphan file descriptors.
755 try:
759 try:
756 fh.close()
760 fh.close()
757 except Exception as e:
761 except Exception as e:
758 # Stash so can re-raise from main thread later.
762 # Stash so can re-raise from main thread later.
759 self._threadexception = e
763 self._threadexception = e
760 except pycompat.queue.Empty:
764 except pycompat.queue.Empty:
761 if not self._running:
765 if not self._running:
762 break
766 break
763
767
764 def close(self, fh):
768 def close(self, fh):
765 """Schedule a file for closing."""
769 """Schedule a file for closing."""
766 if not self._entered:
770 if not self._entered:
767 raise error.Abort(
771 raise error.Abort(
768 _(b'can only call close() when context manager active')
772 _(b'can only call close() when context manager active')
769 )
773 )
770
774
771 # If a background thread encountered an exception, raise now so we fail
775 # If a background thread encountered an exception, raise now so we fail
772 # fast. Otherwise we may potentially go on for minutes until the error
776 # fast. Otherwise we may potentially go on for minutes until the error
773 # is acted on.
777 # is acted on.
774 if self._threadexception:
778 if self._threadexception:
775 e = self._threadexception
779 e = self._threadexception
776 self._threadexception = None
780 self._threadexception = None
777 raise e
781 raise e
778
782
779 # If we're not actively running, close synchronously.
783 # If we're not actively running, close synchronously.
780 if not self._running:
784 if not self._running:
781 fh.close()
785 fh.close()
782 return
786 return
783
787
784 self._queue.put(fh, block=True, timeout=None)
788 self._queue.put(fh, block=True, timeout=None)
785
789
786
790
787 class checkambigatclosing(closewrapbase):
791 class checkambigatclosing(closewrapbase):
788 """Proxy for a file object, to avoid ambiguity of file stat
792 """Proxy for a file object, to avoid ambiguity of file stat
789
793
790 See also util.filestat for detail about "ambiguity of file stat".
794 See also util.filestat for detail about "ambiguity of file stat".
791
795
792 This proxy is useful only if the target file is guarded by any
796 This proxy is useful only if the target file is guarded by any
793 lock (e.g. repo.lock or repo.wlock)
797 lock (e.g. repo.lock or repo.wlock)
794
798
795 Do not instantiate outside of the vfs layer.
799 Do not instantiate outside of the vfs layer.
796 """
800 """
797
801
798 def __init__(self, fh):
802 def __init__(self, fh):
799 super(checkambigatclosing, self).__init__(fh)
803 super(checkambigatclosing, self).__init__(fh)
800 object.__setattr__(self, '_oldstat', util.filestat.frompath(fh.name))
804 object.__setattr__(self, '_oldstat', util.filestat.frompath(fh.name))
801
805
802 def _checkambig(self):
806 def _checkambig(self):
803 oldstat = self._oldstat
807 oldstat = self._oldstat
804 if oldstat.stat:
808 if oldstat.stat:
805 _avoidambig(self._origfh.name, oldstat)
809 _avoidambig(self._origfh.name, oldstat)
806
810
807 def __exit__(self, exc_type, exc_value, exc_tb):
811 def __exit__(self, exc_type, exc_value, exc_tb):
808 self._origfh.__exit__(exc_type, exc_value, exc_tb)
812 self._origfh.__exit__(exc_type, exc_value, exc_tb)
809 self._checkambig()
813 self._checkambig()
810
814
811 def close(self):
815 def close(self):
812 self._origfh.close()
816 self._origfh.close()
813 self._checkambig()
817 self._checkambig()
@@ -1,190 +1,203 b''
1 = Mercurial 6.4.3 =
2
3 * chg: declare environ (issue6812)
4 * chg: set CHGHG before connecting to command server
5 * delta-find: never do anything fancy when general delta is off
6 * delta-find: add a simple safeguard to prevent bad non-general-delta
7 * debug-delta: add minimal documentation for `devel.bundle-delta` option
8 * fix: highlight the required configuration and behavior of the fixer tools
9 * rhg: don't print copy source when --no-status is passed
10 * rhg: correctly relativize copy source path
11 * repo-upgrade: write new requirement before upgrading the dirstate
12 * backup: fix issue when the backup end up in a different directory
13
1 = Mercurial 6.4.2 =
14 = Mercurial 6.4.2 =
2
15
3 Exceptional bugfix release due to a corruption bug that happens when using
16 Exceptional bugfix release due to a corruption bug that happens when using
4 clonebundles on repositories with large files.
17 clonebundles on repositories with large files.
5
18
6 * revlog-split: make sure the self._indexfile attribute is reset (issue6811)
19 * revlog-split: make sure the self._indexfile attribute is reset (issue6811)
7
20
8
21
9 = Mercurial 6.4.1 =
22 = Mercurial 6.4.1 =
10
23
11 * rhg: fix a bug in path encoding
24 * rhg: fix a bug in path encoding
12 * rhg: don't crash on empty directory names in path_encode, just in case
25 * rhg: don't crash on empty directory names in path_encode, just in case
13 * commands: correct documentation of hg serve’s --ipv6 options
26 * commands: correct documentation of hg serve’s --ipv6 options
14 * run-tests: remove obsolete coverage check and packaging import (issue6805)
27 * run-tests: remove obsolete coverage check and packaging import (issue6805)
15 * chg: populate CHGHG if not set
28 * chg: populate CHGHG if not set
16 * match: sort patterns before compiling them into a regex
29 * match: sort patterns before compiling them into a regex
17 * match: match explicit file using a set
30 * match: match explicit file using a set
18 * rebase: do not cleanup the working copy when --dry-run is used (issue6802)
31 * rebase: do not cleanup the working copy when --dry-run is used (issue6802)
19 * sslutil: set context security level for legacy tls testing (issue6760)
32 * sslutil: set context security level for legacy tls testing (issue6760)
20
33
21
34
22 = Mercurial 6.4 =
35 = Mercurial 6.4 =
23
36
24 == New Features ==
37 == New Features ==
25
38
26 * There is a new internal merge tool called `internal:union-other-first`.
39 * There is a new internal merge tool called `internal:union-other-first`.
27 It works like `internal:union` but add other side on top of local.
40 It works like `internal:union` but add other side on top of local.
28 * Pullbundles are enabled by default
41 * Pullbundles are enabled by default
29 * delta-find: add a way to control the number of bases tested at the same time
42 * delta-find: add a way to control the number of bases tested at the same time
30 * changelog-v2: add a configuration to disable rank computation
43 * changelog-v2: add a configuration to disable rank computation
31 * debug: add an option to display statistic about a bundling operation
44 * debug: add an option to display statistic about a bundling operation
32 * debug: add an option to display statistic about a unbundling operation
45 * debug: add an option to display statistic about a unbundling operation
33 * delta-find: add a delta-reuse policy that blindly accepts incoming deltas
46 * delta-find: add a delta-reuse policy that blindly accepts incoming deltas
34 * debug: add debug-revlog-stats command
47 * debug: add debug-revlog-stats command
35 * dirstate: add narrow support to `verify`
48 * dirstate: add narrow support to `verify`
36 * verify: also check dirstate
49 * verify: also check dirstate
37 * commit: add --draft option to use draft phase
50 * commit: add --draft option to use draft phase
38 * amend: add a --draft option to set phase to draft
51 * amend: add a --draft option to set phase to draft
39 * debug: add a config to abort update early
52 * debug: add a config to abort update early
40 * rhg: implement checkexec to support weird filesystems
53 * rhg: implement checkexec to support weird filesystems
41 * debugshell: allow commands to be specified as a CLI argument
54 * debugshell: allow commands to be specified as a CLI argument
42 * rhg-files: add support for narrow when specifying a revision
55 * rhg-files: add support for narrow when specifying a revision
43 * rust-narrow: enable narrow support for plain `rhg files`
56 * rust-narrow: enable narrow support for plain `rhg files`
44
57
45 == Bug Fixes ==
58 == Bug Fixes ==
46
59
47 Aside from the following (unordered) commits which made it through a manual filter, there are a bunch of typing improvements and fixes, removal of deprecated code and general code cleanup.
60 Aside from the following (unordered) commits which made it through a manual filter, there are a bunch of typing improvements and fixes, removal of deprecated code and general code cleanup.
48
61
49 * lfs: improve an exception message for blob corruption detected on transfer
62 * lfs: improve an exception message for blob corruption detected on transfer
50 * revlog: use the user facing filename as the display_id for filelogs
63 * revlog: use the user facing filename as the display_id for filelogs
51 * rust-status: query fs traversal metadata lazily
64 * rust-status: query fs traversal metadata lazily
52 * shelve: add Shelf.changed_files for resolving changed files in a plugin
65 * shelve: add Shelf.changed_files for resolving changed files in a plugin
53 * demandimport: ensure lazyloaderex sets loader attributes (issue6725)
66 * demandimport: ensure lazyloaderex sets loader attributes (issue6725)
54 * typing: fix a syntax error in mercurial/cext/bdiff.pyi
67 * typing: fix a syntax error in mercurial/cext/bdiff.pyi
55 * cffi: fix a bytes vs str issue on macOS when listing directories
68 * cffi: fix a bytes vs str issue on macOS when listing directories
56 * changelog-v2: fix the docket `struct`
69 * changelog-v2: fix the docket `struct`
57 * schemes: fix a broken check for drive letter conflicts
70 * schemes: fix a broken check for drive letter conflicts
58 * worker: avoid reading 1 byte at a time from the OS pipe
71 * worker: avoid reading 1 byte at a time from the OS pipe
59 * rust-narrow: fix loop that never loops
72 * rust-narrow: fix loop that never loops
60 * setup: Ensure target directory exists with building rust extension
73 * setup: Ensure target directory exists with building rust extension
61 * dirstate: invalidate changes when parent-change fails
74 * dirstate: invalidate changes when parent-change fails
62 * dirstate: warn about non-explicitly rolledback parent-change
75 * dirstate: warn about non-explicitly rolledback parent-change
63 * dirstate: write dirstate on successful exit of changing_parents context
76 * dirstate: write dirstate on successful exit of changing_parents context
64 * largefile: make sure we hold the lock when updating the second dirstate
77 * largefile: make sure we hold the lock when updating the second dirstate
65 * dirstate: enforce holding the lock while doing any changes
78 * dirstate: enforce holding the lock while doing any changes
66 * run-tests: stop ignoring venv-installed packages
79 * run-tests: stop ignoring venv-installed packages
67 * transaction: run abort callback in all cases
80 * transaction: run abort callback in all cases
68 * transaction: quietly rollback if no other changes than temporary files
81 * transaction: quietly rollback if no other changes than temporary files
69 * debugrebuilddirstate: double check that no transaction is open
82 * debugrebuilddirstate: double check that no transaction is open
70 * dirstate: do not write an empty dirstate just for backup
83 * dirstate: do not write an empty dirstate just for backup
71 * locking: take the `wlock` for the full `hg add` duration
84 * locking: take the `wlock` for the full `hg add` duration
72 * locking: take the `wlock` for the full `hg remove` duration
85 * locking: take the `wlock` for the full `hg remove` duration
73 * locking: take the `wlock` for the full `hg forget` duration
86 * locking: take the `wlock` for the full `hg forget` duration
74 * locking: take the `wlock` for the full `hg addremove` duration
87 * locking: take the `wlock` for the full `hg addremove` duration
75 * locking: grab the wlock before touching the dirstate in `perfdirstatewrite`
88 * locking: grab the wlock before touching the dirstate in `perfdirstatewrite`
76 * locking: hold the wlock for the full duration of the "keyword demo"
89 * locking: hold the wlock for the full duration of the "keyword demo"
77 * mq: properly take the wlock during the full qfold operation
90 * mq: properly take the wlock during the full qfold operation
78 * dirstate: invalidate the dirstate change on transaction failure
91 * dirstate: invalidate the dirstate change on transaction failure
79 * status: fix post status writing
92 * status: fix post status writing
80 * status: fix post status invalidation
93 * status: fix post status invalidation
81 * dirstate: avoid transaction backup/restore if we do not hold the lock
94 * dirstate: avoid transaction backup/restore if we do not hold the lock
82 * rollback: explicitly skip dirstate rollback when applicable
95 * rollback: explicitly skip dirstate rollback when applicable
83 * dirstate-guard: remove the feature
96 * dirstate-guard: remove the feature
84 * dirstate: make `restorebackup` more robust when it is a noop
97 * dirstate: make `restorebackup` more robust when it is a noop
85 * dirstate: generalize the dirstate's invalidation on transaction abort
98 * dirstate: generalize the dirstate's invalidation on transaction abort
86 * dirstate: detect potential fishy transaction patterns while changing
99 * dirstate: detect potential fishy transaction patterns while changing
87 * mq: write the dirstate before stripping
100 * mq: write the dirstate before stripping
88 * dirstate: explicitly backup the datafile
101 * dirstate: explicitly backup the datafile
89 * localrepo: enforce a clean dirstate when the transaction open
102 * localrepo: enforce a clean dirstate when the transaction open
90 * localrepo: "blindly" do a dirstate backup at the end of the transaction
103 * localrepo: "blindly" do a dirstate backup at the end of the transaction
91 * dirstate: remove the dedicated backup logic
104 * dirstate: remove the dedicated backup logic
92 * rhg: fix a bug in path_encode
105 * rhg: fix a bug in path_encode
93 * dirstate: invalidate on all exceptions
106 * dirstate: invalidate on all exceptions
94 * large-files: make sure we write newly initialized standin file early
107 * large-files: make sure we write newly initialized standin file early
95 * dirstate: warn if dirty when starting an edition
108 * dirstate: warn if dirty when starting an edition
96 * dirstate: track that changes are pending in a transaction
109 * dirstate: track that changes are pending in a transaction
97 * dirstate: distinct transaction callback from largefile
110 * dirstate: distinct transaction callback from largefile
98 * automv: lock the repository before searching for renames
111 * automv: lock the repository before searching for renames
99 * dirstate: only reload the dirstate when it may have changed
112 * dirstate: only reload the dirstate when it may have changed
100 * dirstate: cleanup the `_map` property cache
113 * dirstate: cleanup the `_map` property cache
101 * status: invalidate dirstate on LockError
114 * status: invalidate dirstate on LockError
102 * dirstate: check that dirstate is clean at the initial context opening
115 * dirstate: check that dirstate is clean at the initial context opening
103 * dirstate: have `running_status` write the dirstate when holding the lock
116 * dirstate: have `running_status` write the dirstate when holding the lock
104 * dirstate: have `running_status` warn when exiting with a dirty dirstate
117 * dirstate: have `running_status` warn when exiting with a dirty dirstate
105 * narrow: widden the lock context in `tracking`
118 * narrow: widden the lock context in `tracking`
106 * narrow: enforce that narrow spec is written within a transaction
119 * narrow: enforce that narrow spec is written within a transaction
107 * transaction: no longer explicitly cache phaseroots
120 * transaction: no longer explicitly cache phaseroots
108 * transaction: no longer explicitly cache bookmarks
121 * transaction: no longer explicitly cache bookmarks
109 * transaction: use the standard transaction mechanism to backup branch
122 * transaction: use the standard transaction mechanism to backup branch
110 * bundlerepo: handle changegroup induced phase movement in the associated method
123 * bundlerepo: handle changegroup induced phase movement in the associated method
111 * bundlerepo: apply phase data stored in the bundle instead of assuming `draft`
124 * bundlerepo: apply phase data stored in the bundle instead of assuming `draft`
112 * config-item: declare undeclared path suboption
125 * config-item: declare undeclared path suboption
113 * narrow: read pending file when applicable
126 * narrow: read pending file when applicable
114 * rust: fix building on macOS (issue6801)
127 * rust: fix building on macOS (issue6801)
115 * run-tests: fix a crash when using the coverage options
128 * run-tests: fix a crash when using the coverage options
116 * undo-files: also remove the undo.backupfiles
129 * undo-files: also remove the undo.backupfiles
117 * undo-files: cleanup backup when cleaning undos
130 * undo-files: cleanup backup when cleaning undos
118 * undo-files: clean existing files up before writing new one
131 * undo-files: clean existing files up before writing new one
119 * undo-files: cleanup legacy files when applicable
132 * undo-files: cleanup legacy files when applicable
120 * dirstate-v2: fix an incorrect handling of readdir errors
133 * dirstate-v2: fix an incorrect handling of readdir errors
121 * rust: update zstd dependency
134 * rust: update zstd dependency
122 * rust: upgrade `rayon` dependency
135 * rust: upgrade `rayon` dependency
123 * dirstate: fix the bug in [status] dealing with committed&ignored directories
136 * dirstate: fix the bug in [status] dealing with committed&ignored directories
124 * dirstate: fix a potential traceback when in `copy` and `rename`
137 * dirstate: fix a potential traceback when in `copy` and `rename`
125 * histedit: fix diff colors
138 * histedit: fix diff colors
126 * cext: fix for PyLong refactoring in CPython 3.12
139 * cext: fix for PyLong refactoring in CPython 3.12
127 * py3: fix for Python 3.12 emitting SyntaxWarning on invalid escape sequences
140 * py3: fix for Python 3.12 emitting SyntaxWarning on invalid escape sequences
128 * statprof: with Python 3.12, lineno is (more) often None
141 * statprof: with Python 3.12, lineno is (more) often None
129 * transaction: properly clean up backup file outside of .hg/store/
142 * transaction: properly clean up backup file outside of .hg/store/
130 * transaction: raise on backup restoration error
143 * transaction: raise on backup restoration error
131 * revlog: improve the robustness of the splitting process
144 * revlog: improve the robustness of the splitting process
132 * debugdeltachain: stop summing the same chain over and over
145 * debugdeltachain: stop summing the same chain over and over
133 * url: don't ignore timeout for https connections
146 * url: don't ignore timeout for https connections
134 * py3: fix for Python 3.12 emitting SyntaxWarning on invalid escape sequences
147 * py3: fix for Python 3.12 emitting SyntaxWarning on invalid escape sequences
135 * tests: accept a test output change in [tests/test-serve.t]
148 * tests: accept a test output change in [tests/test-serve.t]
136 * rust: fix thread cap (for real this time)
149 * rust: fix thread cap (for real this time)
137 * dirstate: try refreshing the changelog when parent are unknown
150 * dirstate: try refreshing the changelog when parent are unknown
138 * hooks: invalidate the repo after the hooks
151 * hooks: invalidate the repo after the hooks
139
152
140 == Backwards Compatibility Changes ==
153 == Backwards Compatibility Changes ==
141 * rust: upgrade supported Rust toolchain version
154 * rust: upgrade supported Rust toolchain version
142 * rust: move all crates in the main workspace to edition 2021
155 * rust: move all crates in the main workspace to edition 2021
143 * hg-core: upgrade `zstd` dependency
156 * hg-core: upgrade `zstd` dependency
144 * hg-core: upgrade `clap` dependency
157 * hg-core: upgrade `clap` dependency
145 * hg-core: upgrade all remaining dependencies
158 * hg-core: upgrade all remaining dependencies
146 * hg-cpython: upgrade dependencies
159 * hg-cpython: upgrade dependencies
147 * rhg: upgrade `clap` dependency
160 * rhg: upgrade `clap` dependency
148 * rhg: upgrade the remainder of the dependencies
161 * rhg: upgrade the remainder of the dependencies
149
162
150 == Internal API Changes ==
163 == Internal API Changes ==
151
164
152 * Many APIs around the dirstate have been made much stricter with regards to
165 * Many APIs around the dirstate have been made much stricter with regards to
153 locking and transaction handling
166 locking and transaction handling
154 * Some dirstate APIs have been renamed/removed
167 * Some dirstate APIs have been renamed/removed
155 * In both cases, you should get loud complaints in your tests if you do
168 * In both cases, you should get loud complaints in your tests if you do
156 something wrong.
169 something wrong.
157
170
158 == Miscellaneous ==
171 == Miscellaneous ==
159
172
160 * pullbundle support no longer requires setting a server-side option,
173 * pullbundle support no longer requires setting a server-side option,
161 providing a .hg/pullbundles.manifest according to the syntax specified in
174 providing a .hg/pullbundles.manifest according to the syntax specified in
162 'hg help -e clonebundles' is enough.
175 'hg help -e clonebundles' is enough.
163 * debug-delta-find: add a --source option
176 * debug-delta-find: add a --source option
164 * delta-find: add debug information about reuse of cached data
177 * delta-find: add debug information about reuse of cached data
165 * delta-find: set the default candidate chunk size to 10
178 * delta-find: set the default candidate chunk size to 10
166 * attr: vendor 22.1.0
179 * attr: vendor 22.1.0
167 * configitems: add a default value for "merge-tools.xxx.regappend"
180 * configitems: add a default value for "merge-tools.xxx.regappend"
168 * debugrevlog: display total stored information
181 * debugrevlog: display total stored information
169 * emitrevision: if we need to compute a delta on the fly, try p1 or p2 first
182 * emitrevision: if we need to compute a delta on the fly, try p1 or p2 first
170 * emitrevision: consider ancestors revision to emit as available base
183 * emitrevision: consider ancestors revision to emit as available base
171 * find-delta: pass the cache-delta usage policy alongside the cache-delta
184 * find-delta: pass the cache-delta usage policy alongside the cache-delta
172 * delta-find: use a smarter object for snapshot caching
185 * delta-find: use a smarter object for snapshot caching
173 * delta-find: use sets instead of list in the snapshot cache
186 * delta-find: use sets instead of list in the snapshot cache
174 * delta-find: make sure we only use newer full snapshot as candidate
187 * delta-find: make sure we only use newer full snapshot as candidate
175 * delta-find: use a single snapshot cache when applying a group to an object
188 * delta-find: use a single snapshot cache when applying a group to an object
176 * bundleoperation: optionnaly record the `remote` that produced the bundle
189 * bundleoperation: optionnaly record the `remote` that produced the bundle
177 * bundle: when forcing acceptance of incoming delta also accept snapshot
190 * bundle: when forcing acceptance of incoming delta also accept snapshot
178 * bundle: emit full snapshot as is, without doing a redelta
191 * bundle: emit full snapshot as is, without doing a redelta
179 * pathutil: slightly faster path audit in the common case
192 * pathutil: slightly faster path audit in the common case
180 * merge: don't pay for pathconflicts if there are none
193 * merge: don't pay for pathconflicts if there are none
181 * merge: short-circuit the _checkfs loop upon getting ENOENT
194 * merge: short-circuit the _checkfs loop upon getting ENOENT
182 * merge: disable the whole filesystem access loop if [_realfs] is false
195 * merge: disable the whole filesystem access loop if [_realfs] is false
183 * merge: cache the fs checks made during [_checkunknownfiles]
196 * merge: cache the fs checks made during [_checkunknownfiles]
184 * rust: use `logging_timer` instead of `micro_timer`
197 * rust: use `logging_timer` instead of `micro_timer`
185 * rust: run `cargo clippy`
198 * rust: run `cargo clippy`
186 * makefile: add `cargo clippy` to tests if cargo is available
199 * makefile: add `cargo clippy` to tests if cargo is available
187 * heptapod-ci: add `clippy` to the CI
200 * heptapod-ci: add `clippy` to the CI
188 * convert: use a priority queue for sorting commits, to make sorting faster
201 * convert: use a priority queue for sorting commits, to make sorting faster
189 * delta-find: adjust the default candidate group chunk size
202 * delta-find: adjust the default candidate group chunk size
190 * delta-find: declare the "paths..*:pulled-delta-reuse-policy option No newline at end of file
203 * delta-find: declare the "paths..*:pulled-delta-reuse-policy option
@@ -1,670 +1,675 b''
1 // status.rs
1 // status.rs
2 //
2 //
3 // Copyright 2020, Georges Racinet <georges.racinets@octobus.net>
3 // Copyright 2020, Georges Racinet <georges.racinets@octobus.net>
4 //
4 //
5 // This software may be used and distributed according to the terms of the
5 // This software may be used and distributed according to the terms of the
6 // GNU General Public License version 2 or any later version.
6 // GNU General Public License version 2 or any later version.
7
7
8 use crate::error::CommandError;
8 use crate::error::CommandError;
9 use crate::ui::{
9 use crate::ui::{
10 format_pattern_file_warning, print_narrow_sparse_warnings, Ui,
10 format_pattern_file_warning, print_narrow_sparse_warnings, Ui,
11 };
11 };
12 use crate::utils::path_utils::RelativizePaths;
12 use crate::utils::path_utils::RelativizePaths;
13 use clap::Arg;
13 use clap::Arg;
14 use format_bytes::format_bytes;
14 use format_bytes::format_bytes;
15 use hg::config::Config;
15 use hg::config::Config;
16 use hg::dirstate::has_exec_bit;
16 use hg::dirstate::has_exec_bit;
17 use hg::dirstate::status::StatusPath;
17 use hg::dirstate::status::StatusPath;
18 use hg::dirstate::TruncatedTimestamp;
18 use hg::dirstate::TruncatedTimestamp;
19 use hg::errors::{HgError, IoResultExt};
19 use hg::errors::{HgError, IoResultExt};
20 use hg::lock::LockError;
20 use hg::lock::LockError;
21 use hg::manifest::Manifest;
21 use hg::manifest::Manifest;
22 use hg::matchers::{AlwaysMatcher, IntersectionMatcher};
22 use hg::matchers::{AlwaysMatcher, IntersectionMatcher};
23 use hg::repo::Repo;
23 use hg::repo::Repo;
24 use hg::utils::debug::debug_wait_for_file;
24 use hg::utils::debug::debug_wait_for_file;
25 use hg::utils::files::get_bytes_from_os_string;
25 use hg::utils::files::get_bytes_from_os_string;
26 use hg::utils::files::get_path_from_bytes;
26 use hg::utils::files::get_path_from_bytes;
27 use hg::utils::hg_path::{hg_path_to_path_buf, HgPath};
27 use hg::utils::hg_path::{hg_path_to_path_buf, HgPath};
28 use hg::DirstateStatus;
28 use hg::DirstateStatus;
29 use hg::PatternFileWarning;
29 use hg::PatternFileWarning;
30 use hg::StatusError;
30 use hg::StatusError;
31 use hg::StatusOptions;
31 use hg::StatusOptions;
32 use hg::{self, narrow, sparse};
32 use hg::{self, narrow, sparse};
33 use log::info;
33 use log::info;
34 use rayon::prelude::*;
34 use rayon::prelude::*;
35 use std::io;
35 use std::io;
36 use std::path::PathBuf;
36 use std::path::PathBuf;
37
37
38 pub const HELP_TEXT: &str = "
38 pub const HELP_TEXT: &str = "
39 Show changed files in the working directory
39 Show changed files in the working directory
40
40
41 This is a pure Rust version of `hg status`.
41 This is a pure Rust version of `hg status`.
42
42
43 Some options might be missing, check the list below.
43 Some options might be missing, check the list below.
44 ";
44 ";
45
45
46 pub fn args() -> clap::Command {
46 pub fn args() -> clap::Command {
47 clap::command!("status")
47 clap::command!("status")
48 .alias("st")
48 .alias("st")
49 .about(HELP_TEXT)
49 .about(HELP_TEXT)
50 .arg(
50 .arg(
51 Arg::new("all")
51 Arg::new("all")
52 .help("show status of all files")
52 .help("show status of all files")
53 .short('A')
53 .short('A')
54 .action(clap::ArgAction::SetTrue)
54 .action(clap::ArgAction::SetTrue)
55 .long("all"),
55 .long("all"),
56 )
56 )
57 .arg(
57 .arg(
58 Arg::new("modified")
58 Arg::new("modified")
59 .help("show only modified files")
59 .help("show only modified files")
60 .short('m')
60 .short('m')
61 .action(clap::ArgAction::SetTrue)
61 .action(clap::ArgAction::SetTrue)
62 .long("modified"),
62 .long("modified"),
63 )
63 )
64 .arg(
64 .arg(
65 Arg::new("added")
65 Arg::new("added")
66 .help("show only added files")
66 .help("show only added files")
67 .short('a')
67 .short('a')
68 .action(clap::ArgAction::SetTrue)
68 .action(clap::ArgAction::SetTrue)
69 .long("added"),
69 .long("added"),
70 )
70 )
71 .arg(
71 .arg(
72 Arg::new("removed")
72 Arg::new("removed")
73 .help("show only removed files")
73 .help("show only removed files")
74 .short('r')
74 .short('r')
75 .action(clap::ArgAction::SetTrue)
75 .action(clap::ArgAction::SetTrue)
76 .long("removed"),
76 .long("removed"),
77 )
77 )
78 .arg(
78 .arg(
79 Arg::new("clean")
79 Arg::new("clean")
80 .help("show only clean files")
80 .help("show only clean files")
81 .short('c')
81 .short('c')
82 .action(clap::ArgAction::SetTrue)
82 .action(clap::ArgAction::SetTrue)
83 .long("clean"),
83 .long("clean"),
84 )
84 )
85 .arg(
85 .arg(
86 Arg::new("deleted")
86 Arg::new("deleted")
87 .help("show only deleted files")
87 .help("show only deleted files")
88 .short('d')
88 .short('d')
89 .action(clap::ArgAction::SetTrue)
89 .action(clap::ArgAction::SetTrue)
90 .long("deleted"),
90 .long("deleted"),
91 )
91 )
92 .arg(
92 .arg(
93 Arg::new("unknown")
93 Arg::new("unknown")
94 .help("show only unknown (not tracked) files")
94 .help("show only unknown (not tracked) files")
95 .short('u')
95 .short('u')
96 .action(clap::ArgAction::SetTrue)
96 .action(clap::ArgAction::SetTrue)
97 .long("unknown"),
97 .long("unknown"),
98 )
98 )
99 .arg(
99 .arg(
100 Arg::new("ignored")
100 Arg::new("ignored")
101 .help("show only ignored files")
101 .help("show only ignored files")
102 .short('i')
102 .short('i')
103 .action(clap::ArgAction::SetTrue)
103 .action(clap::ArgAction::SetTrue)
104 .long("ignored"),
104 .long("ignored"),
105 )
105 )
106 .arg(
106 .arg(
107 Arg::new("copies")
107 Arg::new("copies")
108 .help("show source of copied files (DEFAULT: ui.statuscopies)")
108 .help("show source of copied files (DEFAULT: ui.statuscopies)")
109 .short('C')
109 .short('C')
110 .action(clap::ArgAction::SetTrue)
110 .action(clap::ArgAction::SetTrue)
111 .long("copies"),
111 .long("copies"),
112 )
112 )
113 .arg(
113 .arg(
114 Arg::new("print0")
114 Arg::new("print0")
115 .help("end filenames with NUL, for use with xargs")
115 .help("end filenames with NUL, for use with xargs")
116 .short('0')
116 .short('0')
117 .action(clap::ArgAction::SetTrue)
117 .action(clap::ArgAction::SetTrue)
118 .long("print0"),
118 .long("print0"),
119 )
119 )
120 .arg(
120 .arg(
121 Arg::new("no-status")
121 Arg::new("no-status")
122 .help("hide status prefix")
122 .help("hide status prefix")
123 .short('n')
123 .short('n')
124 .action(clap::ArgAction::SetTrue)
124 .action(clap::ArgAction::SetTrue)
125 .long("no-status"),
125 .long("no-status"),
126 )
126 )
127 .arg(
127 .arg(
128 Arg::new("verbose")
128 Arg::new("verbose")
129 .help("enable additional output")
129 .help("enable additional output")
130 .short('v')
130 .short('v')
131 .action(clap::ArgAction::SetTrue)
131 .action(clap::ArgAction::SetTrue)
132 .long("verbose"),
132 .long("verbose"),
133 )
133 )
134 }
134 }
135
135
136 /// Pure data type allowing the caller to specify file states to display
136 /// Pure data type allowing the caller to specify file states to display
137 #[derive(Copy, Clone, Debug)]
137 #[derive(Copy, Clone, Debug)]
138 pub struct DisplayStates {
138 pub struct DisplayStates {
139 pub modified: bool,
139 pub modified: bool,
140 pub added: bool,
140 pub added: bool,
141 pub removed: bool,
141 pub removed: bool,
142 pub clean: bool,
142 pub clean: bool,
143 pub deleted: bool,
143 pub deleted: bool,
144 pub unknown: bool,
144 pub unknown: bool,
145 pub ignored: bool,
145 pub ignored: bool,
146 }
146 }
147
147
148 pub const DEFAULT_DISPLAY_STATES: DisplayStates = DisplayStates {
148 pub const DEFAULT_DISPLAY_STATES: DisplayStates = DisplayStates {
149 modified: true,
149 modified: true,
150 added: true,
150 added: true,
151 removed: true,
151 removed: true,
152 clean: false,
152 clean: false,
153 deleted: true,
153 deleted: true,
154 unknown: true,
154 unknown: true,
155 ignored: false,
155 ignored: false,
156 };
156 };
157
157
158 pub const ALL_DISPLAY_STATES: DisplayStates = DisplayStates {
158 pub const ALL_DISPLAY_STATES: DisplayStates = DisplayStates {
159 modified: true,
159 modified: true,
160 added: true,
160 added: true,
161 removed: true,
161 removed: true,
162 clean: true,
162 clean: true,
163 deleted: true,
163 deleted: true,
164 unknown: true,
164 unknown: true,
165 ignored: true,
165 ignored: true,
166 };
166 };
167
167
168 impl DisplayStates {
168 impl DisplayStates {
169 pub fn is_empty(&self) -> bool {
169 pub fn is_empty(&self) -> bool {
170 !(self.modified
170 !(self.modified
171 || self.added
171 || self.added
172 || self.removed
172 || self.removed
173 || self.clean
173 || self.clean
174 || self.deleted
174 || self.deleted
175 || self.unknown
175 || self.unknown
176 || self.ignored)
176 || self.ignored)
177 }
177 }
178 }
178 }
179
179
180 fn has_unfinished_merge(repo: &Repo) -> Result<bool, CommandError> {
180 fn has_unfinished_merge(repo: &Repo) -> Result<bool, CommandError> {
181 Ok(repo.dirstate_parents()?.is_merge())
181 Ok(repo.dirstate_parents()?.is_merge())
182 }
182 }
183
183
184 fn has_unfinished_state(repo: &Repo) -> Result<bool, CommandError> {
184 fn has_unfinished_state(repo: &Repo) -> Result<bool, CommandError> {
185 // These are all the known values for the [fname] argument of
185 // These are all the known values for the [fname] argument of
186 // [addunfinished] function in [state.py]
186 // [addunfinished] function in [state.py]
187 let known_state_files: &[&str] = &[
187 let known_state_files: &[&str] = &[
188 "bisect.state",
188 "bisect.state",
189 "graftstate",
189 "graftstate",
190 "histedit-state",
190 "histedit-state",
191 "rebasestate",
191 "rebasestate",
192 "shelvedstate",
192 "shelvedstate",
193 "transplant/journal",
193 "transplant/journal",
194 "updatestate",
194 "updatestate",
195 ];
195 ];
196 if has_unfinished_merge(repo)? {
196 if has_unfinished_merge(repo)? {
197 return Ok(true);
197 return Ok(true);
198 };
198 };
199 for f in known_state_files {
199 for f in known_state_files {
200 if repo.hg_vfs().join(f).exists() {
200 if repo.hg_vfs().join(f).exists() {
201 return Ok(true);
201 return Ok(true);
202 }
202 }
203 }
203 }
204 Ok(false)
204 Ok(false)
205 }
205 }
206
206
207 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
207 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
208 // TODO: lift these limitations
208 // TODO: lift these limitations
209 if invocation
209 if invocation
210 .config
210 .config
211 .get(b"commands", b"status.terse")
211 .get(b"commands", b"status.terse")
212 .is_some()
212 .is_some()
213 {
213 {
214 return Err(CommandError::unsupported(
214 return Err(CommandError::unsupported(
215 "status.terse is not yet supported with rhg status",
215 "status.terse is not yet supported with rhg status",
216 ));
216 ));
217 }
217 }
218
218
219 let ui = invocation.ui;
219 let ui = invocation.ui;
220 let config = invocation.config;
220 let config = invocation.config;
221 let args = invocation.subcommand_args;
221 let args = invocation.subcommand_args;
222
222
223 let print0 = args.get_flag("print0");
223 let print0 = args.get_flag("print0");
224 let verbose = args.get_flag("verbose")
224 let verbose = args.get_flag("verbose")
225 || config.get_bool(b"ui", b"verbose")?
225 || config.get_bool(b"ui", b"verbose")?
226 || config.get_bool(b"commands", b"status.verbose")?;
226 || config.get_bool(b"commands", b"status.verbose")?;
227 let verbose = verbose && !print0;
227 let verbose = verbose && !print0;
228
228
229 let all = args.get_flag("all");
229 let all = args.get_flag("all");
230 let display_states = if all {
230 let display_states = if all {
231 // TODO when implementing `--quiet`: it excludes clean files
231 // TODO when implementing `--quiet`: it excludes clean files
232 // from `--all`
232 // from `--all`
233 ALL_DISPLAY_STATES
233 ALL_DISPLAY_STATES
234 } else {
234 } else {
235 let requested = DisplayStates {
235 let requested = DisplayStates {
236 modified: args.get_flag("modified"),
236 modified: args.get_flag("modified"),
237 added: args.get_flag("added"),
237 added: args.get_flag("added"),
238 removed: args.get_flag("removed"),
238 removed: args.get_flag("removed"),
239 clean: args.get_flag("clean"),
239 clean: args.get_flag("clean"),
240 deleted: args.get_flag("deleted"),
240 deleted: args.get_flag("deleted"),
241 unknown: args.get_flag("unknown"),
241 unknown: args.get_flag("unknown"),
242 ignored: args.get_flag("ignored"),
242 ignored: args.get_flag("ignored"),
243 };
243 };
244 if requested.is_empty() {
244 if requested.is_empty() {
245 DEFAULT_DISPLAY_STATES
245 DEFAULT_DISPLAY_STATES
246 } else {
246 } else {
247 requested
247 requested
248 }
248 }
249 };
249 };
250 let no_status = args.get_flag("no-status");
250 let no_status = args.get_flag("no-status");
251 let list_copies = all
251 let list_copies = all
252 || args.get_flag("copies")
252 || args.get_flag("copies")
253 || config.get_bool(b"ui", b"statuscopies")?;
253 || config.get_bool(b"ui", b"statuscopies")?;
254
254
255 let repo = invocation.repo?;
255 let repo = invocation.repo?;
256
256
257 if verbose && has_unfinished_state(repo)? {
257 if verbose && has_unfinished_state(repo)? {
258 return Err(CommandError::unsupported(
258 return Err(CommandError::unsupported(
259 "verbose status output is not supported by rhg (and is needed because we're in an unfinished operation)",
259 "verbose status output is not supported by rhg (and is needed because we're in an unfinished operation)",
260 ));
260 ));
261 }
261 }
262
262
263 let mut dmap = repo.dirstate_map_mut()?;
263 let mut dmap = repo.dirstate_map_mut()?;
264
264
265 let check_exec = hg::checkexec::check_exec(repo.working_directory_path());
265 let check_exec = hg::checkexec::check_exec(repo.working_directory_path());
266
266
267 let options = StatusOptions {
267 let options = StatusOptions {
268 check_exec,
268 check_exec,
269 list_clean: display_states.clean,
269 list_clean: display_states.clean,
270 list_unknown: display_states.unknown,
270 list_unknown: display_states.unknown,
271 list_ignored: display_states.ignored,
271 list_ignored: display_states.ignored,
272 list_copies,
272 list_copies,
273 collect_traversed_dirs: false,
273 collect_traversed_dirs: false,
274 };
274 };
275
275
276 type StatusResult<'a> =
276 type StatusResult<'a> =
277 Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>;
277 Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>;
278
278
279 let after_status = |res: StatusResult| -> Result<_, CommandError> {
279 let after_status = |res: StatusResult| -> Result<_, CommandError> {
280 let (mut ds_status, pattern_warnings) = res?;
280 let (mut ds_status, pattern_warnings) = res?;
281 for warning in pattern_warnings {
281 for warning in pattern_warnings {
282 ui.write_stderr(&format_pattern_file_warning(&warning, repo))?;
282 ui.write_stderr(&format_pattern_file_warning(&warning, repo))?;
283 }
283 }
284
284
285 for (path, error) in ds_status.bad {
285 for (path, error) in ds_status.bad {
286 let error = match error {
286 let error = match error {
287 hg::BadMatch::OsError(code) => {
287 hg::BadMatch::OsError(code) => {
288 std::io::Error::from_raw_os_error(code).to_string()
288 std::io::Error::from_raw_os_error(code).to_string()
289 }
289 }
290 hg::BadMatch::BadType(ty) => {
290 hg::BadMatch::BadType(ty) => {
291 format!("unsupported file type (type is {})", ty)
291 format!("unsupported file type (type is {})", ty)
292 }
292 }
293 };
293 };
294 ui.write_stderr(&format_bytes!(
294 ui.write_stderr(&format_bytes!(
295 b"{}: {}\n",
295 b"{}: {}\n",
296 path.as_bytes(),
296 path.as_bytes(),
297 error.as_bytes()
297 error.as_bytes()
298 ))?
298 ))?
299 }
299 }
300 if !ds_status.unsure.is_empty() {
300 if !ds_status.unsure.is_empty() {
301 info!(
301 info!(
302 "Files to be rechecked by retrieval from filelog: {:?}",
302 "Files to be rechecked by retrieval from filelog: {:?}",
303 ds_status.unsure.iter().map(|s| &s.path).collect::<Vec<_>>()
303 ds_status.unsure.iter().map(|s| &s.path).collect::<Vec<_>>()
304 );
304 );
305 }
305 }
306 let mut fixup = Vec::new();
306 let mut fixup = Vec::new();
307 if !ds_status.unsure.is_empty()
307 if !ds_status.unsure.is_empty()
308 && (display_states.modified || display_states.clean)
308 && (display_states.modified || display_states.clean)
309 {
309 {
310 let p1 = repo.dirstate_parents()?.p1;
310 let p1 = repo.dirstate_parents()?.p1;
311 let manifest = repo.manifest_for_node(p1).map_err(|e| {
311 let manifest = repo.manifest_for_node(p1).map_err(|e| {
312 CommandError::from((e, &*format!("{:x}", p1.short())))
312 CommandError::from((e, &*format!("{:x}", p1.short())))
313 })?;
313 })?;
314 let working_directory_vfs = repo.working_directory_vfs();
314 let working_directory_vfs = repo.working_directory_vfs();
315 let store_vfs = repo.store_vfs();
315 let store_vfs = repo.store_vfs();
316 let res: Vec<_> = ds_status
316 let res: Vec<_> = ds_status
317 .unsure
317 .unsure
318 .into_par_iter()
318 .into_par_iter()
319 .map(|to_check| {
319 .map(|to_check| {
320 // The compiler seems to get a bit confused with complex
320 // The compiler seems to get a bit confused with complex
321 // inference when using a parallel iterator + map
321 // inference when using a parallel iterator + map
322 // + map_err + collect, so let's just inline some of the
322 // + map_err + collect, so let's just inline some of the
323 // logic.
323 // logic.
324 match unsure_is_modified(
324 match unsure_is_modified(
325 working_directory_vfs,
325 working_directory_vfs,
326 store_vfs,
326 store_vfs,
327 check_exec,
327 check_exec,
328 &manifest,
328 &manifest,
329 &to_check.path,
329 &to_check.path,
330 ) {
330 ) {
331 Err(HgError::IoError { .. }) => {
331 Err(HgError::IoError { .. }) => {
332 // IO errors most likely stem from the file being
332 // IO errors most likely stem from the file being
333 // deleted even though we know it's in the
333 // deleted even though we know it's in the
334 // dirstate.
334 // dirstate.
335 Ok((to_check, UnsureOutcome::Deleted))
335 Ok((to_check, UnsureOutcome::Deleted))
336 }
336 }
337 Ok(outcome) => Ok((to_check, outcome)),
337 Ok(outcome) => Ok((to_check, outcome)),
338 Err(e) => Err(e),
338 Err(e) => Err(e),
339 }
339 }
340 })
340 })
341 .collect::<Result<_, _>>()?;
341 .collect::<Result<_, _>>()?;
342 for (status_path, outcome) in res.into_iter() {
342 for (status_path, outcome) in res.into_iter() {
343 match outcome {
343 match outcome {
344 UnsureOutcome::Clean => {
344 UnsureOutcome::Clean => {
345 if display_states.clean {
345 if display_states.clean {
346 ds_status.clean.push(status_path.clone());
346 ds_status.clean.push(status_path.clone());
347 }
347 }
348 fixup.push(status_path.path.into_owned())
348 fixup.push(status_path.path.into_owned())
349 }
349 }
350 UnsureOutcome::Modified => {
350 UnsureOutcome::Modified => {
351 if display_states.modified {
351 if display_states.modified {
352 ds_status.modified.push(status_path);
352 ds_status.modified.push(status_path);
353 }
353 }
354 }
354 }
355 UnsureOutcome::Deleted => {
355 UnsureOutcome::Deleted => {
356 if display_states.deleted {
356 if display_states.deleted {
357 ds_status.deleted.push(status_path);
357 ds_status.deleted.push(status_path);
358 }
358 }
359 }
359 }
360 }
360 }
361 }
361 }
362 }
362 }
363 let relative_paths = config
363 let relative_paths = config
364 .get_option(b"commands", b"status.relative")?
364 .get_option(b"commands", b"status.relative")?
365 .unwrap_or(config.get_bool(b"ui", b"relative-paths")?);
365 .unwrap_or(config.get_bool(b"ui", b"relative-paths")?);
366 let output = DisplayStatusPaths {
366 let output = DisplayStatusPaths {
367 ui,
367 ui,
368 no_status,
368 no_status,
369 relativize: if relative_paths {
369 relativize: if relative_paths {
370 Some(RelativizePaths::new(repo)?)
370 Some(RelativizePaths::new(repo)?)
371 } else {
371 } else {
372 None
372 None
373 },
373 },
374 print0,
374 print0,
375 };
375 };
376 if display_states.modified {
376 if display_states.modified {
377 output.display(b"M ", "status.modified", ds_status.modified)?;
377 output.display(b"M ", "status.modified", ds_status.modified)?;
378 }
378 }
379 if display_states.added {
379 if display_states.added {
380 output.display(b"A ", "status.added", ds_status.added)?;
380 output.display(b"A ", "status.added", ds_status.added)?;
381 }
381 }
382 if display_states.removed {
382 if display_states.removed {
383 output.display(b"R ", "status.removed", ds_status.removed)?;
383 output.display(b"R ", "status.removed", ds_status.removed)?;
384 }
384 }
385 if display_states.deleted {
385 if display_states.deleted {
386 output.display(b"! ", "status.deleted", ds_status.deleted)?;
386 output.display(b"! ", "status.deleted", ds_status.deleted)?;
387 }
387 }
388 if display_states.unknown {
388 if display_states.unknown {
389 output.display(b"? ", "status.unknown", ds_status.unknown)?;
389 output.display(b"? ", "status.unknown", ds_status.unknown)?;
390 }
390 }
391 if display_states.ignored {
391 if display_states.ignored {
392 output.display(b"I ", "status.ignored", ds_status.ignored)?;
392 output.display(b"I ", "status.ignored", ds_status.ignored)?;
393 }
393 }
394 if display_states.clean {
394 if display_states.clean {
395 output.display(b"C ", "status.clean", ds_status.clean)?;
395 output.display(b"C ", "status.clean", ds_status.clean)?;
396 }
396 }
397
397
398 let dirstate_write_needed = ds_status.dirty;
398 let dirstate_write_needed = ds_status.dirty;
399 let filesystem_time_at_status_start =
399 let filesystem_time_at_status_start =
400 ds_status.filesystem_time_at_status_start;
400 ds_status.filesystem_time_at_status_start;
401
401
402 Ok((
402 Ok((
403 fixup,
403 fixup,
404 dirstate_write_needed,
404 dirstate_write_needed,
405 filesystem_time_at_status_start,
405 filesystem_time_at_status_start,
406 ))
406 ))
407 };
407 };
408 let (narrow_matcher, narrow_warnings) = narrow::matcher(repo)?;
408 let (narrow_matcher, narrow_warnings) = narrow::matcher(repo)?;
409 let (sparse_matcher, sparse_warnings) = sparse::matcher(repo)?;
409 let (sparse_matcher, sparse_warnings) = sparse::matcher(repo)?;
410 let matcher = match (repo.has_narrow(), repo.has_sparse()) {
410 let matcher = match (repo.has_narrow(), repo.has_sparse()) {
411 (true, true) => {
411 (true, true) => {
412 Box::new(IntersectionMatcher::new(narrow_matcher, sparse_matcher))
412 Box::new(IntersectionMatcher::new(narrow_matcher, sparse_matcher))
413 }
413 }
414 (true, false) => narrow_matcher,
414 (true, false) => narrow_matcher,
415 (false, true) => sparse_matcher,
415 (false, true) => sparse_matcher,
416 (false, false) => Box::new(AlwaysMatcher),
416 (false, false) => Box::new(AlwaysMatcher),
417 };
417 };
418
418
419 print_narrow_sparse_warnings(
419 print_narrow_sparse_warnings(
420 &narrow_warnings,
420 &narrow_warnings,
421 &sparse_warnings,
421 &sparse_warnings,
422 ui,
422 ui,
423 repo,
423 repo,
424 )?;
424 )?;
425 let (fixup, mut dirstate_write_needed, filesystem_time_at_status_start) =
425 let (fixup, mut dirstate_write_needed, filesystem_time_at_status_start) =
426 dmap.with_status(
426 dmap.with_status(
427 matcher.as_ref(),
427 matcher.as_ref(),
428 repo.working_directory_path().to_owned(),
428 repo.working_directory_path().to_owned(),
429 ignore_files(repo, config),
429 ignore_files(repo, config),
430 options,
430 options,
431 after_status,
431 after_status,
432 )?;
432 )?;
433
433
434 // Development config option to test write races
434 // Development config option to test write races
435 if let Err(e) =
435 if let Err(e) =
436 debug_wait_for_file(config, "status.pre-dirstate-write-file")
436 debug_wait_for_file(config, "status.pre-dirstate-write-file")
437 {
437 {
438 ui.write_stderr(e.as_bytes()).ok();
438 ui.write_stderr(e.as_bytes()).ok();
439 }
439 }
440
440
441 if (fixup.is_empty() || filesystem_time_at_status_start.is_none())
441 if (fixup.is_empty() || filesystem_time_at_status_start.is_none())
442 && !dirstate_write_needed
442 && !dirstate_write_needed
443 {
443 {
444 // Nothing to update
444 // Nothing to update
445 return Ok(());
445 return Ok(());
446 }
446 }
447
447
448 // Update the dirstate on disk if we can
448 // Update the dirstate on disk if we can
449 let with_lock_result =
449 let with_lock_result =
450 repo.try_with_wlock_no_wait(|| -> Result<(), CommandError> {
450 repo.try_with_wlock_no_wait(|| -> Result<(), CommandError> {
451 if let Some(mtime_boundary) = filesystem_time_at_status_start {
451 if let Some(mtime_boundary) = filesystem_time_at_status_start {
452 for hg_path in fixup {
452 for hg_path in fixup {
453 use std::os::unix::fs::MetadataExt;
453 use std::os::unix::fs::MetadataExt;
454 let fs_path = hg_path_to_path_buf(&hg_path)
454 let fs_path = hg_path_to_path_buf(&hg_path)
455 .expect("HgPath conversion");
455 .expect("HgPath conversion");
456 // Specifically do not reuse `fs_metadata` from
456 // Specifically do not reuse `fs_metadata` from
457 // `unsure_is_clean` which was needed before reading
457 // `unsure_is_clean` which was needed before reading
458 // contents. Here we access metadata again after reading
458 // contents. Here we access metadata again after reading
459 // content, in case it changed in the meantime.
459 // content, in case it changed in the meantime.
460 let metadata_res = repo
460 let metadata_res = repo
461 .working_directory_vfs()
461 .working_directory_vfs()
462 .symlink_metadata(&fs_path);
462 .symlink_metadata(&fs_path);
463 let fs_metadata = match metadata_res {
463 let fs_metadata = match metadata_res {
464 Ok(meta) => meta,
464 Ok(meta) => meta,
465 Err(err) => match err {
465 Err(err) => match err {
466 HgError::IoError { .. } => {
466 HgError::IoError { .. } => {
467 // The file has probably been deleted. In any
467 // The file has probably been deleted. In any
468 // case, it was in the dirstate before, so
468 // case, it was in the dirstate before, so
469 // let's ignore the error.
469 // let's ignore the error.
470 continue;
470 continue;
471 }
471 }
472 _ => return Err(err.into()),
472 _ => return Err(err.into()),
473 },
473 },
474 };
474 };
475 if let Some(mtime) =
475 if let Some(mtime) =
476 TruncatedTimestamp::for_reliable_mtime_of(
476 TruncatedTimestamp::for_reliable_mtime_of(
477 &fs_metadata,
477 &fs_metadata,
478 &mtime_boundary,
478 &mtime_boundary,
479 )
479 )
480 .when_reading_file(&fs_path)?
480 .when_reading_file(&fs_path)?
481 {
481 {
482 let mode = fs_metadata.mode();
482 let mode = fs_metadata.mode();
483 let size = fs_metadata.len();
483 let size = fs_metadata.len();
484 dmap.set_clean(&hg_path, mode, size as u32, mtime)?;
484 dmap.set_clean(&hg_path, mode, size as u32, mtime)?;
485 dirstate_write_needed = true
485 dirstate_write_needed = true
486 }
486 }
487 }
487 }
488 }
488 }
489 drop(dmap); // Avoid "already mutably borrowed" RefCell panics
489 drop(dmap); // Avoid "already mutably borrowed" RefCell panics
490 if dirstate_write_needed {
490 if dirstate_write_needed {
491 repo.write_dirstate()?
491 repo.write_dirstate()?
492 }
492 }
493 Ok(())
493 Ok(())
494 });
494 });
495 match with_lock_result {
495 match with_lock_result {
496 Ok(closure_result) => closure_result?,
496 Ok(closure_result) => closure_result?,
497 Err(LockError::AlreadyHeld) => {
497 Err(LockError::AlreadyHeld) => {
498 // Not updating the dirstate is not ideal but not critical:
498 // Not updating the dirstate is not ideal but not critical:
499 // don’t keep our caller waiting until some other Mercurial
499 // don’t keep our caller waiting until some other Mercurial
500 // process releases the lock.
500 // process releases the lock.
501 log::info!("not writing dirstate from `status`: lock is held")
501 log::info!("not writing dirstate from `status`: lock is held")
502 }
502 }
503 Err(LockError::Other(HgError::IoError { error, .. }))
503 Err(LockError::Other(HgError::IoError { error, .. }))
504 if error.kind() == io::ErrorKind::PermissionDenied =>
504 if error.kind() == io::ErrorKind::PermissionDenied =>
505 {
505 {
506 // `hg status` on a read-only repository is fine
506 // `hg status` on a read-only repository is fine
507 }
507 }
508 Err(LockError::Other(error)) => {
508 Err(LockError::Other(error)) => {
509 // Report other I/O errors
509 // Report other I/O errors
510 Err(error)?
510 Err(error)?
511 }
511 }
512 }
512 }
513 Ok(())
513 Ok(())
514 }
514 }
515
515
516 fn ignore_files(repo: &Repo, config: &Config) -> Vec<PathBuf> {
516 fn ignore_files(repo: &Repo, config: &Config) -> Vec<PathBuf> {
517 let mut ignore_files = Vec::new();
517 let mut ignore_files = Vec::new();
518 let repo_ignore = repo.working_directory_vfs().join(".hgignore");
518 let repo_ignore = repo.working_directory_vfs().join(".hgignore");
519 if repo_ignore.exists() {
519 if repo_ignore.exists() {
520 ignore_files.push(repo_ignore)
520 ignore_files.push(repo_ignore)
521 }
521 }
522 for (key, value) in config.iter_section(b"ui") {
522 for (key, value) in config.iter_section(b"ui") {
523 if key == b"ignore" || key.starts_with(b"ignore.") {
523 if key == b"ignore" || key.starts_with(b"ignore.") {
524 let path = get_path_from_bytes(value);
524 let path = get_path_from_bytes(value);
525 // TODO: expand "~/" and environment variable here, like Python
525 // TODO: expand "~/" and environment variable here, like Python
526 // does with `os.path.expanduser` and `os.path.expandvars`
526 // does with `os.path.expanduser` and `os.path.expandvars`
527
527
528 let joined = repo.working_directory_path().join(path);
528 let joined = repo.working_directory_path().join(path);
529 ignore_files.push(joined);
529 ignore_files.push(joined);
530 }
530 }
531 }
531 }
532 ignore_files
532 ignore_files
533 }
533 }
534
534
535 struct DisplayStatusPaths<'a> {
535 struct DisplayStatusPaths<'a> {
536 ui: &'a Ui,
536 ui: &'a Ui,
537 no_status: bool,
537 no_status: bool,
538 relativize: Option<RelativizePaths>,
538 relativize: Option<RelativizePaths>,
539 print0: bool,
539 print0: bool,
540 }
540 }
541
541
542 impl DisplayStatusPaths<'_> {
542 impl DisplayStatusPaths<'_> {
543 // Probably more elegant to use a Deref or Borrow trait rather than
543 // Probably more elegant to use a Deref or Borrow trait rather than
544 // harcode HgPathBuf, but probably not really useful at this point
544 // harcode HgPathBuf, but probably not really useful at this point
545 fn display(
545 fn display(
546 &self,
546 &self,
547 status_prefix: &[u8],
547 status_prefix: &[u8],
548 label: &'static str,
548 label: &'static str,
549 mut paths: Vec<StatusPath<'_>>,
549 mut paths: Vec<StatusPath<'_>>,
550 ) -> Result<(), CommandError> {
550 ) -> Result<(), CommandError> {
551 paths.sort_unstable();
551 paths.sort_unstable();
552 // TODO: get the stdout lock once for the whole loop
552 // TODO: get the stdout lock once for the whole loop
553 // instead of in each write
553 // instead of in each write
554 for StatusPath { path, copy_source } in paths {
554 for StatusPath { path, copy_source } in paths {
555 let relative;
555 let relative_path;
556 let path = if let Some(relativize) = &self.relativize {
556 let relative_source;
557 relative = relativize.relativize(&path);
557 let (path, copy_source) = if let Some(relativize) =
558 &*relative
558 &self.relativize
559 {
560 relative_path = relativize.relativize(&path);
561 relative_source =
562 copy_source.as_ref().map(|s| relativize.relativize(s));
563 (&*relative_path, relative_source.as_deref())
559 } else {
564 } else {
560 path.as_bytes()
565 (path.as_bytes(), copy_source.as_ref().map(|s| s.as_bytes()))
561 };
566 };
562 // TODO: Add a way to use `write_bytes!` instead of `format_bytes!`
567 // TODO: Add a way to use `write_bytes!` instead of `format_bytes!`
563 // in order to stream to stdout instead of allocating an
568 // in order to stream to stdout instead of allocating an
564 // itermediate `Vec<u8>`.
569 // itermediate `Vec<u8>`.
565 if !self.no_status {
570 if !self.no_status {
566 self.ui.write_stdout_labelled(status_prefix, label)?
571 self.ui.write_stdout_labelled(status_prefix, label)?
567 }
572 }
568 let linebreak = if self.print0 { b"\x00" } else { b"\n" };
573 let linebreak = if self.print0 { b"\x00" } else { b"\n" };
569 self.ui.write_stdout_labelled(
574 self.ui.write_stdout_labelled(
570 &format_bytes!(b"{}{}", path, linebreak),
575 &format_bytes!(b"{}{}", path, linebreak),
571 label,
576 label,
572 )?;
577 )?;
573 if let Some(source) = copy_source {
578 if let Some(source) = copy_source.filter(|_| !self.no_status) {
574 let label = "status.copied";
579 let label = "status.copied";
575 self.ui.write_stdout_labelled(
580 self.ui.write_stdout_labelled(
576 &format_bytes!(b" {}{}", source.as_bytes(), linebreak),
581 &format_bytes!(b" {}{}", source, linebreak),
577 label,
582 label,
578 )?
583 )?
579 }
584 }
580 }
585 }
581 Ok(())
586 Ok(())
582 }
587 }
583 }
588 }
584
589
585 /// Outcome of the additional check for an ambiguous tracked file
590 /// Outcome of the additional check for an ambiguous tracked file
586 enum UnsureOutcome {
591 enum UnsureOutcome {
587 /// The file is actually clean
592 /// The file is actually clean
588 Clean,
593 Clean,
589 /// The file has been modified
594 /// The file has been modified
590 Modified,
595 Modified,
591 /// The file was deleted on disk (or became another type of fs entry)
596 /// The file was deleted on disk (or became another type of fs entry)
592 Deleted,
597 Deleted,
593 }
598 }
594
599
595 /// Check if a file is modified by comparing actual repo store and file system.
600 /// Check if a file is modified by comparing actual repo store and file system.
596 ///
601 ///
597 /// This meant to be used for those that the dirstate cannot resolve, due
602 /// This meant to be used for those that the dirstate cannot resolve, due
598 /// to time resolution limits.
603 /// to time resolution limits.
599 fn unsure_is_modified(
604 fn unsure_is_modified(
600 working_directory_vfs: hg::vfs::Vfs,
605 working_directory_vfs: hg::vfs::Vfs,
601 store_vfs: hg::vfs::Vfs,
606 store_vfs: hg::vfs::Vfs,
602 check_exec: bool,
607 check_exec: bool,
603 manifest: &Manifest,
608 manifest: &Manifest,
604 hg_path: &HgPath,
609 hg_path: &HgPath,
605 ) -> Result<UnsureOutcome, HgError> {
610 ) -> Result<UnsureOutcome, HgError> {
606 let vfs = working_directory_vfs;
611 let vfs = working_directory_vfs;
607 let fs_path = hg_path_to_path_buf(hg_path).expect("HgPath conversion");
612 let fs_path = hg_path_to_path_buf(hg_path).expect("HgPath conversion");
608 let fs_metadata = vfs.symlink_metadata(&fs_path)?;
613 let fs_metadata = vfs.symlink_metadata(&fs_path)?;
609 let is_symlink = fs_metadata.file_type().is_symlink();
614 let is_symlink = fs_metadata.file_type().is_symlink();
610
615
611 let entry = manifest
616 let entry = manifest
612 .find_by_path(hg_path)?
617 .find_by_path(hg_path)?
613 .expect("ambgious file not in p1");
618 .expect("ambgious file not in p1");
614
619
615 // TODO: Also account for `FALLBACK_SYMLINK` and `FALLBACK_EXEC` from the
620 // TODO: Also account for `FALLBACK_SYMLINK` and `FALLBACK_EXEC` from the
616 // dirstate
621 // dirstate
617 let fs_flags = if is_symlink {
622 let fs_flags = if is_symlink {
618 Some(b'l')
623 Some(b'l')
619 } else if check_exec && has_exec_bit(&fs_metadata) {
624 } else if check_exec && has_exec_bit(&fs_metadata) {
620 Some(b'x')
625 Some(b'x')
621 } else {
626 } else {
622 None
627 None
623 };
628 };
624
629
625 let entry_flags = if check_exec {
630 let entry_flags = if check_exec {
626 entry.flags
631 entry.flags
627 } else if entry.flags == Some(b'x') {
632 } else if entry.flags == Some(b'x') {
628 None
633 None
629 } else {
634 } else {
630 entry.flags
635 entry.flags
631 };
636 };
632
637
633 if entry_flags != fs_flags {
638 if entry_flags != fs_flags {
634 return Ok(UnsureOutcome::Modified);
639 return Ok(UnsureOutcome::Modified);
635 }
640 }
636 let filelog = hg::filelog::Filelog::open_vfs(&store_vfs, hg_path)?;
641 let filelog = hg::filelog::Filelog::open_vfs(&store_vfs, hg_path)?;
637 let fs_len = fs_metadata.len();
642 let fs_len = fs_metadata.len();
638 let file_node = entry.node_id()?;
643 let file_node = entry.node_id()?;
639 let filelog_entry = filelog.entry_for_node(file_node).map_err(|_| {
644 let filelog_entry = filelog.entry_for_node(file_node).map_err(|_| {
640 HgError::corrupted(format!(
645 HgError::corrupted(format!(
641 "filelog {:?} missing node {:?} from manifest",
646 "filelog {:?} missing node {:?} from manifest",
642 hg_path, file_node
647 hg_path, file_node
643 ))
648 ))
644 })?;
649 })?;
645 if filelog_entry.file_data_len_not_equal_to(fs_len) {
650 if filelog_entry.file_data_len_not_equal_to(fs_len) {
646 // No need to read file contents:
651 // No need to read file contents:
647 // it cannot be equal if it has a different length.
652 // it cannot be equal if it has a different length.
648 return Ok(UnsureOutcome::Modified);
653 return Ok(UnsureOutcome::Modified);
649 }
654 }
650
655
651 let p1_filelog_data = filelog_entry.data()?;
656 let p1_filelog_data = filelog_entry.data()?;
652 let p1_contents = p1_filelog_data.file_data()?;
657 let p1_contents = p1_filelog_data.file_data()?;
653 if p1_contents.len() as u64 != fs_len {
658 if p1_contents.len() as u64 != fs_len {
654 // No need to read file contents:
659 // No need to read file contents:
655 // it cannot be equal if it has a different length.
660 // it cannot be equal if it has a different length.
656 return Ok(UnsureOutcome::Modified);
661 return Ok(UnsureOutcome::Modified);
657 }
662 }
658
663
659 let fs_contents = if is_symlink {
664 let fs_contents = if is_symlink {
660 get_bytes_from_os_string(vfs.read_link(fs_path)?.into_os_string())
665 get_bytes_from_os_string(vfs.read_link(fs_path)?.into_os_string())
661 } else {
666 } else {
662 vfs.read(fs_path)?
667 vfs.read(fs_path)?
663 };
668 };
664
669
665 Ok(if p1_contents != &*fs_contents {
670 Ok(if p1_contents != &*fs_contents {
666 UnsureOutcome::Modified
671 UnsureOutcome::Modified
667 } else {
672 } else {
668 UnsureOutcome::Clean
673 UnsureOutcome::Clean
669 })
674 })
670 }
675 }
@@ -1,555 +1,572 b''
1 #require chg
1 #require chg
2
2
3 Scale the timeout for the chg-server to the test timeout scaling.
3 Scale the timeout for the chg-server to the test timeout scaling.
4 This is done to reduce the flakiness of this test on heavy load.
4 This is done to reduce the flakiness of this test on heavy load.
5
5
6 $ CHGTIMEOUT=`expr $HGTEST_TIMEOUT / 6`
6 $ CHGTIMEOUT=`expr $HGTEST_TIMEOUT / 6`
7 $ export CHGTIMEOUT
7 $ export CHGTIMEOUT
8
8
9 $ mkdir log
9 $ mkdir log
10 $ cp $HGRCPATH $HGRCPATH.unconfigured
10 $ cp $HGRCPATH $HGRCPATH.unconfigured
11 $ cat <<'EOF' >> $HGRCPATH
11 $ cat <<'EOF' >> $HGRCPATH
12 > [cmdserver]
12 > [cmdserver]
13 > log = $TESTTMP/log/server.log
13 > log = $TESTTMP/log/server.log
14 > max-log-files = 1
14 > max-log-files = 1
15 > max-log-size = 10 kB
15 > max-log-size = 10 kB
16 > EOF
16 > EOF
17 $ cp $HGRCPATH $HGRCPATH.orig
17 $ cp $HGRCPATH $HGRCPATH.orig
18
18
19 $ filterlog () {
19 $ filterlog () {
20 > sed -e 's!^[0-9/]* [0-9:]* ([0-9]*)>!YYYY/MM/DD HH:MM:SS (PID)>!' \
20 > sed -e 's!^[0-9/]* [0-9:]* ([0-9]*)>!YYYY/MM/DD HH:MM:SS (PID)>!' \
21 > -e 's!\(setprocname\|received fds\|setenv\): .*!\1: ...!' \
21 > -e 's!\(setprocname\|received fds\|setenv\): .*!\1: ...!' \
22 > -e 's!\(confighash\|mtimehash\) = [0-9a-f]*!\1 = ...!g' \
22 > -e 's!\(confighash\|mtimehash\) = [0-9a-f]*!\1 = ...!g' \
23 > -e 's!\(in \)[0-9.]*s\b!\1 ...s!g' \
23 > -e 's!\(in \)[0-9.]*s\b!\1 ...s!g' \
24 > -e 's!\(pid\)=[0-9]*!\1=...!g' \
24 > -e 's!\(pid\)=[0-9]*!\1=...!g' \
25 > -e 's!\(/server-\)[0-9a-f]*!\1...!g'
25 > -e 's!\(/server-\)[0-9a-f]*!\1...!g'
26 > }
26 > }
27
27
28 init repo
28 init repo
29
29
30 $ chg init foo
30 $ chg init foo
31 $ cd foo
31 $ cd foo
32
32
33 ill-formed config
33 ill-formed config
34
34
35 $ chg status
35 $ chg status
36 $ echo '=brokenconfig' >> $HGRCPATH
36 $ echo '=brokenconfig' >> $HGRCPATH
37 $ chg status
37 $ chg status
38 config error at * =brokenconfig (glob)
38 config error at * =brokenconfig (glob)
39 [30]
39 [30]
40
40
41 $ cp $HGRCPATH.orig $HGRCPATH
41 $ cp $HGRCPATH.orig $HGRCPATH
42
42
43 long socket path
43 long socket path
44
44
45 $ sockpath=$TESTTMP/this/path/should/be/longer/than/one-hundred-and-seven/characters/where/107/is/the/typical/size/limit/of/unix-domain-socket
45 $ sockpath=$TESTTMP/this/path/should/be/longer/than/one-hundred-and-seven/characters/where/107/is/the/typical/size/limit/of/unix-domain-socket
46 $ mkdir -p $sockpath
46 $ mkdir -p $sockpath
47 $ bakchgsockname=$CHGSOCKNAME
47 $ bakchgsockname=$CHGSOCKNAME
48 $ CHGSOCKNAME=$sockpath/server
48 $ CHGSOCKNAME=$sockpath/server
49 $ export CHGSOCKNAME
49 $ export CHGSOCKNAME
50 $ chg root
50 $ chg root
51 $TESTTMP/foo
51 $TESTTMP/foo
52 $ rm -rf $sockpath
52 $ rm -rf $sockpath
53 $ CHGSOCKNAME=$bakchgsockname
53 $ CHGSOCKNAME=$bakchgsockname
54 $ export CHGSOCKNAME
54 $ export CHGSOCKNAME
55
55
56 $ cd ..
56 $ cd ..
57
57
58 editor
58 editor
59 ------
59 ------
60
60
61 $ cat >> pushbuffer.py <<EOF
61 $ cat >> pushbuffer.py <<EOF
62 > def reposetup(ui, repo):
62 > def reposetup(ui, repo):
63 > repo.ui.pushbuffer(subproc=True)
63 > repo.ui.pushbuffer(subproc=True)
64 > EOF
64 > EOF
65
65
66 $ chg init editor
66 $ chg init editor
67 $ cd editor
67 $ cd editor
68
68
69 by default, system() should be redirected to the client:
69 by default, system() should be redirected to the client:
70
70
71 $ touch foo
71 $ touch foo
72 $ CHGDEBUG= HGEDITOR=cat chg ci -Am channeled --edit 2>&1 \
72 $ CHGDEBUG= HGEDITOR=cat chg ci -Am channeled --edit 2>&1 \
73 > | egrep "HG:|run 'cat"
73 > | egrep "HG:|run 'cat"
74 chg: debug: * run 'cat "*"' at '$TESTTMP/editor' (glob)
74 chg: debug: * run 'cat "*"' at '$TESTTMP/editor' (glob)
75 HG: Enter commit message. Lines beginning with 'HG:' are removed.
75 HG: Enter commit message. Lines beginning with 'HG:' are removed.
76 HG: Leave message empty to abort commit.
76 HG: Leave message empty to abort commit.
77 HG: --
77 HG: --
78 HG: user: test
78 HG: user: test
79 HG: branch 'default'
79 HG: branch 'default'
80 HG: added foo
80 HG: added foo
81
81
82 but no redirection should be made if output is captured:
82 but no redirection should be made if output is captured:
83
83
84 $ touch bar
84 $ touch bar
85 $ CHGDEBUG= HGEDITOR=cat chg ci -Am bufferred --edit \
85 $ CHGDEBUG= HGEDITOR=cat chg ci -Am bufferred --edit \
86 > --config extensions.pushbuffer="$TESTTMP/pushbuffer.py" 2>&1 \
86 > --config extensions.pushbuffer="$TESTTMP/pushbuffer.py" 2>&1 \
87 > | egrep "HG:|run 'cat"
87 > | egrep "HG:|run 'cat"
88 [1]
88 [1]
89
89
90 check that commit commands succeeded:
90 check that commit commands succeeded:
91
91
92 $ hg log -T '{rev}:{desc}\n'
92 $ hg log -T '{rev}:{desc}\n'
93 1:bufferred
93 1:bufferred
94 0:channeled
94 0:channeled
95
95
96 $ cd ..
96 $ cd ..
97
97
98 pager
98 pager
99 -----
99 -----
100
100
101 $ cat >> fakepager.py <<EOF
101 $ cat >> fakepager.py <<EOF
102 > import sys
102 > import sys
103 > for line in sys.stdin:
103 > for line in sys.stdin:
104 > sys.stdout.write('paged! %r\n' % line)
104 > sys.stdout.write('paged! %r\n' % line)
105 > EOF
105 > EOF
106
106
107 enable pager extension globally, but spawns the master server with no tty:
107 enable pager extension globally, but spawns the master server with no tty:
108
108
109 $ chg init pager
109 $ chg init pager
110 $ cd pager
110 $ cd pager
111 $ cat >> $HGRCPATH <<EOF
111 $ cat >> $HGRCPATH <<EOF
112 > [extensions]
112 > [extensions]
113 > pager =
113 > pager =
114 > [pager]
114 > [pager]
115 > pager = "$PYTHON" $TESTTMP/fakepager.py
115 > pager = "$PYTHON" $TESTTMP/fakepager.py
116 > EOF
116 > EOF
117 $ chg version > /dev/null
117 $ chg version > /dev/null
118 $ touch foo
118 $ touch foo
119 $ chg ci -qAm foo
119 $ chg ci -qAm foo
120
120
121 pager should be enabled if the attached client has a tty:
121 pager should be enabled if the attached client has a tty:
122
122
123 $ chg log -l1 -q --config ui.formatted=True
123 $ chg log -l1 -q --config ui.formatted=True
124 paged! '0:1f7b0de80e11\n'
124 paged! '0:1f7b0de80e11\n'
125 $ chg log -l1 -q --config ui.formatted=False
125 $ chg log -l1 -q --config ui.formatted=False
126 0:1f7b0de80e11
126 0:1f7b0de80e11
127
127
128 chg waits for pager if runcommand raises
128 chg waits for pager if runcommand raises
129
129
130 $ cat > $TESTTMP/crash.py <<EOF
130 $ cat > $TESTTMP/crash.py <<EOF
131 > from mercurial import registrar
131 > from mercurial import registrar
132 > cmdtable = {}
132 > cmdtable = {}
133 > command = registrar.command(cmdtable)
133 > command = registrar.command(cmdtable)
134 > @command(b'crash')
134 > @command(b'crash')
135 > def pagercrash(ui, repo, *pats, **opts):
135 > def pagercrash(ui, repo, *pats, **opts):
136 > ui.write(b'going to crash\n')
136 > ui.write(b'going to crash\n')
137 > raise Exception('.')
137 > raise Exception('.')
138 > EOF
138 > EOF
139
139
140 $ cat > $TESTTMP/fakepager.py <<EOF
140 $ cat > $TESTTMP/fakepager.py <<EOF
141 > import sys
141 > import sys
142 > import time
142 > import time
143 > for line in iter(sys.stdin.readline, ''):
143 > for line in iter(sys.stdin.readline, ''):
144 > if 'crash' in line: # only interested in lines containing 'crash'
144 > if 'crash' in line: # only interested in lines containing 'crash'
145 > # if chg exits when pager is sleeping (incorrectly), the output
145 > # if chg exits when pager is sleeping (incorrectly), the output
146 > # will be captured by the next test case
146 > # will be captured by the next test case
147 > time.sleep(1)
147 > time.sleep(1)
148 > sys.stdout.write('crash-pager: %s' % line)
148 > sys.stdout.write('crash-pager: %s' % line)
149 > EOF
149 > EOF
150
150
151 $ cat >> .hg/hgrc <<EOF
151 $ cat >> .hg/hgrc <<EOF
152 > [extensions]
152 > [extensions]
153 > crash = $TESTTMP/crash.py
153 > crash = $TESTTMP/crash.py
154 > EOF
154 > EOF
155
155
156 $ chg crash --pager=on --config ui.formatted=True 2>/dev/null
156 $ chg crash --pager=on --config ui.formatted=True 2>/dev/null
157 crash-pager: going to crash
157 crash-pager: going to crash
158 [255]
158 [255]
159
159
160 no stdout data should be printed after pager quits, and the buffered data
160 no stdout data should be printed after pager quits, and the buffered data
161 should never persist (issue6207)
161 should never persist (issue6207)
162
162
163 "killed!" may be printed if terminated by SIGPIPE, which isn't important
163 "killed!" may be printed if terminated by SIGPIPE, which isn't important
164 in this test.
164 in this test.
165
165
166 $ cat > $TESTTMP/bulkwrite.py <<'EOF'
166 $ cat > $TESTTMP/bulkwrite.py <<'EOF'
167 > import time
167 > import time
168 > from mercurial import error, registrar
168 > from mercurial import error, registrar
169 > cmdtable = {}
169 > cmdtable = {}
170 > command = registrar.command(cmdtable)
170 > command = registrar.command(cmdtable)
171 > @command(b'bulkwrite')
171 > @command(b'bulkwrite')
172 > def bulkwrite(ui, repo, *pats, **opts):
172 > def bulkwrite(ui, repo, *pats, **opts):
173 > ui.write(b'going to write massive data\n')
173 > ui.write(b'going to write massive data\n')
174 > ui.flush()
174 > ui.flush()
175 > t = time.time()
175 > t = time.time()
176 > while time.time() - t < 2:
176 > while time.time() - t < 2:
177 > ui.write(b'x' * 1023 + b'\n') # will be interrupted by SIGPIPE
177 > ui.write(b'x' * 1023 + b'\n') # will be interrupted by SIGPIPE
178 > raise error.Abort(b"write() doesn't block")
178 > raise error.Abort(b"write() doesn't block")
179 > EOF
179 > EOF
180
180
181 $ cat > $TESTTMP/fakepager.py <<'EOF'
181 $ cat > $TESTTMP/fakepager.py <<'EOF'
182 > import sys
182 > import sys
183 > import time
183 > import time
184 > sys.stdout.write('paged! %r\n' % sys.stdin.readline())
184 > sys.stdout.write('paged! %r\n' % sys.stdin.readline())
185 > time.sleep(1) # new data will be written
185 > time.sleep(1) # new data will be written
186 > EOF
186 > EOF
187
187
188 $ cat >> .hg/hgrc <<EOF
188 $ cat >> .hg/hgrc <<EOF
189 > [extensions]
189 > [extensions]
190 > bulkwrite = $TESTTMP/bulkwrite.py
190 > bulkwrite = $TESTTMP/bulkwrite.py
191 > EOF
191 > EOF
192
192
193 $ chg bulkwrite --pager=on --color no --config ui.formatted=True
193 $ chg bulkwrite --pager=on --color no --config ui.formatted=True
194 paged! 'going to write massive data\n'
194 paged! 'going to write massive data\n'
195 killed! (?)
195 killed! (?)
196 [255]
196 [255]
197
197
198 $ chg bulkwrite --pager=on --color no --config ui.formatted=True
198 $ chg bulkwrite --pager=on --color no --config ui.formatted=True
199 paged! 'going to write massive data\n'
199 paged! 'going to write massive data\n'
200 killed! (?)
200 killed! (?)
201 [255]
201 [255]
202
202
203 $ cd ..
203 $ cd ..
204
204
205 missing stdio
205 missing stdio
206 -------------
206 -------------
207
207
208 $ CHGDEBUG=1 chg version -q 0<&-
208 $ CHGDEBUG=1 chg version -q 0<&-
209 chg: debug: * stdio fds are missing (glob)
209 chg: debug: * stdio fds are missing (glob)
210 chg: debug: * execute original hg (glob)
210 chg: debug: * execute original hg (glob)
211 Mercurial Distributed SCM * (glob)
211 Mercurial Distributed SCM * (glob)
212
212
213 server lifecycle
213 server lifecycle
214 ----------------
214 ----------------
215
215
216 chg server should be restarted on code change, and old server will shut down
216 chg server should be restarted on code change, and old server will shut down
217 automatically. In this test, we use the following time parameters:
217 automatically. In this test, we use the following time parameters:
218
218
219 - "sleep 1" to make mtime different
219 - "sleep 1" to make mtime different
220 - "sleep 2" to notice mtime change (polling interval is 1 sec)
220 - "sleep 2" to notice mtime change (polling interval is 1 sec)
221
221
222 set up repository with an extension:
222 set up repository with an extension:
223
223
224 $ chg init extreload
224 $ chg init extreload
225 $ cd extreload
225 $ cd extreload
226 $ touch dummyext.py
226 $ touch dummyext.py
227 $ cat <<EOF >> .hg/hgrc
227 $ cat <<EOF >> .hg/hgrc
228 > [extensions]
228 > [extensions]
229 > dummyext = dummyext.py
229 > dummyext = dummyext.py
230 > EOF
230 > EOF
231
231
232 isolate socket directory for stable result:
232 isolate socket directory for stable result:
233
233
234 $ OLDCHGSOCKNAME=$CHGSOCKNAME
234 $ OLDCHGSOCKNAME=$CHGSOCKNAME
235 $ mkdir chgsock
235 $ mkdir chgsock
236 $ CHGSOCKNAME=`pwd`/chgsock/server
236 $ CHGSOCKNAME=`pwd`/chgsock/server
237
237
238 warm up server:
238 warm up server:
239
239
240 $ CHGDEBUG= chg log 2>&1 | egrep 'instruction|start'
240 $ CHGDEBUG= chg log 2>&1 | egrep 'instruction|start'
241 chg: debug: * start cmdserver at $TESTTMP/extreload/chgsock/server.* (glob)
241 chg: debug: * start cmdserver at $TESTTMP/extreload/chgsock/server.* (glob)
242
242
243 new server should be started if extension modified:
243 new server should be started if extension modified:
244
244
245 $ sleep 1
245 $ sleep 1
246 $ touch dummyext.py
246 $ touch dummyext.py
247 $ CHGDEBUG= chg log 2>&1 | egrep 'instruction|start'
247 $ CHGDEBUG= chg log 2>&1 | egrep 'instruction|start'
248 chg: debug: * instruction: unlink $TESTTMP/extreload/chgsock/server-* (glob)
248 chg: debug: * instruction: unlink $TESTTMP/extreload/chgsock/server-* (glob)
249 chg: debug: * instruction: reconnect (glob)
249 chg: debug: * instruction: reconnect (glob)
250 chg: debug: * start cmdserver at $TESTTMP/extreload/chgsock/server.* (glob)
250 chg: debug: * start cmdserver at $TESTTMP/extreload/chgsock/server.* (glob)
251
251
252 old server will shut down, while new server should still be reachable:
252 old server will shut down, while new server should still be reachable:
253
253
254 $ sleep 2
254 $ sleep 2
255 $ CHGDEBUG= chg log 2>&1 | (egrep 'instruction|start' || true)
255 $ CHGDEBUG= chg log 2>&1 | (egrep 'instruction|start' || true)
256
256
257 socket file should never be unlinked by old server:
257 socket file should never be unlinked by old server:
258 (simulates unowned socket by updating mtime, which makes sure server exits
258 (simulates unowned socket by updating mtime, which makes sure server exits
259 at polling cycle)
259 at polling cycle)
260
260
261 $ ls chgsock/server-*
261 $ ls chgsock/server-*
262 chgsock/server-* (glob)
262 chgsock/server-* (glob)
263 $ touch chgsock/server-*
263 $ touch chgsock/server-*
264 $ sleep 2
264 $ sleep 2
265 $ ls chgsock/server-*
265 $ ls chgsock/server-*
266 chgsock/server-* (glob)
266 chgsock/server-* (glob)
267
267
268 since no server is reachable from socket file, new server should be started:
268 since no server is reachable from socket file, new server should be started:
269 (this test makes sure that old server shut down automatically)
269 (this test makes sure that old server shut down automatically)
270
270
271 $ CHGDEBUG= chg log 2>&1 | egrep 'instruction|start'
271 $ CHGDEBUG= chg log 2>&1 | egrep 'instruction|start'
272 chg: debug: * start cmdserver at $TESTTMP/extreload/chgsock/server.* (glob)
272 chg: debug: * start cmdserver at $TESTTMP/extreload/chgsock/server.* (glob)
273
273
274 shut down servers and restore environment:
274 shut down servers and restore environment:
275
275
276 $ rm -R chgsock
276 $ rm -R chgsock
277 $ sleep 2
277 $ sleep 2
278 $ CHGSOCKNAME=$OLDCHGSOCKNAME
278 $ CHGSOCKNAME=$OLDCHGSOCKNAME
279 $ cd ..
279 $ cd ..
280
280
281 check that server events are recorded:
281 check that server events are recorded:
282
282
283 $ ls log
283 $ ls log
284 server.log
284 server.log
285 server.log.1
285 server.log.1
286
286
287 print only the last 10 lines, since we aren't sure how many records are
287 print only the last 10 lines, since we aren't sure how many records are
288 preserved (since setprocname isn't available on py3 and pure version,
288 preserved (since setprocname isn't available on py3 and pure version,
289 the 10th-most-recent line is different when using py3):
289 the 10th-most-recent line is different when using py3):
290
290
291 $ cat log/server.log.1 log/server.log | tail -10 | filterlog
291 $ cat log/server.log.1 log/server.log | tail -10 | filterlog
292 YYYY/MM/DD HH:MM:SS (PID)> confighash = ... mtimehash = ... (no-setprocname !)
292 YYYY/MM/DD HH:MM:SS (PID)> confighash = ... mtimehash = ... (no-setprocname !)
293 YYYY/MM/DD HH:MM:SS (PID)> forked worker process (pid=...)
293 YYYY/MM/DD HH:MM:SS (PID)> forked worker process (pid=...)
294 YYYY/MM/DD HH:MM:SS (PID)> setprocname: ... (setprocname !)
294 YYYY/MM/DD HH:MM:SS (PID)> setprocname: ... (setprocname !)
295 YYYY/MM/DD HH:MM:SS (PID)> received fds: ...
295 YYYY/MM/DD HH:MM:SS (PID)> received fds: ...
296 YYYY/MM/DD HH:MM:SS (PID)> chdir to '$TESTTMP/extreload'
296 YYYY/MM/DD HH:MM:SS (PID)> chdir to '$TESTTMP/extreload'
297 YYYY/MM/DD HH:MM:SS (PID)> setumask 18
297 YYYY/MM/DD HH:MM:SS (PID)> setumask 18
298 YYYY/MM/DD HH:MM:SS (PID)> setenv: ...
298 YYYY/MM/DD HH:MM:SS (PID)> setenv: ...
299 YYYY/MM/DD HH:MM:SS (PID)> confighash = ... mtimehash = ...
299 YYYY/MM/DD HH:MM:SS (PID)> confighash = ... mtimehash = ...
300 YYYY/MM/DD HH:MM:SS (PID)> validate: []
300 YYYY/MM/DD HH:MM:SS (PID)> validate: []
301 YYYY/MM/DD HH:MM:SS (PID)> worker process exited (pid=...)
301 YYYY/MM/DD HH:MM:SS (PID)> worker process exited (pid=...)
302 YYYY/MM/DD HH:MM:SS (PID)> $TESTTMP/extreload/chgsock/server-... is not owned, exiting.
302 YYYY/MM/DD HH:MM:SS (PID)> $TESTTMP/extreload/chgsock/server-... is not owned, exiting.
303
303
304 global data mutated by schems
304 global data mutated by schems
305 -----------------------------
305 -----------------------------
306
306
307 $ hg init schemes
307 $ hg init schemes
308 $ cd schemes
308 $ cd schemes
309
309
310 initial state
310 initial state
311
311
312 $ cat > .hg/hgrc <<'EOF'
312 $ cat > .hg/hgrc <<'EOF'
313 > [extensions]
313 > [extensions]
314 > schemes =
314 > schemes =
315 > [schemes]
315 > [schemes]
316 > foo = https://foo.example.org/
316 > foo = https://foo.example.org/
317 > EOF
317 > EOF
318 $ hg debugexpandscheme foo://expanded
318 $ hg debugexpandscheme foo://expanded
319 https://foo.example.org/expanded
319 https://foo.example.org/expanded
320 $ hg debugexpandscheme bar://unexpanded
320 $ hg debugexpandscheme bar://unexpanded
321 bar://unexpanded
321 bar://unexpanded
322
322
323 add bar
323 add bar
324
324
325 $ cat > .hg/hgrc <<'EOF'
325 $ cat > .hg/hgrc <<'EOF'
326 > [extensions]
326 > [extensions]
327 > schemes =
327 > schemes =
328 > [schemes]
328 > [schemes]
329 > foo = https://foo.example.org/
329 > foo = https://foo.example.org/
330 > bar = https://bar.example.org/
330 > bar = https://bar.example.org/
331 > EOF
331 > EOF
332 $ hg debugexpandscheme foo://expanded
332 $ hg debugexpandscheme foo://expanded
333 https://foo.example.org/expanded
333 https://foo.example.org/expanded
334 $ hg debugexpandscheme bar://expanded
334 $ hg debugexpandscheme bar://expanded
335 https://bar.example.org/expanded
335 https://bar.example.org/expanded
336
336
337 remove foo
337 remove foo
338
338
339 $ cat > .hg/hgrc <<'EOF'
339 $ cat > .hg/hgrc <<'EOF'
340 > [extensions]
340 > [extensions]
341 > schemes =
341 > schemes =
342 > [schemes]
342 > [schemes]
343 > bar = https://bar.example.org/
343 > bar = https://bar.example.org/
344 > EOF
344 > EOF
345 $ hg debugexpandscheme foo://unexpanded
345 $ hg debugexpandscheme foo://unexpanded
346 foo://unexpanded
346 foo://unexpanded
347 $ hg debugexpandscheme bar://expanded
347 $ hg debugexpandscheme bar://expanded
348 https://bar.example.org/expanded
348 https://bar.example.org/expanded
349
349
350 $ cd ..
350 $ cd ..
351
351
352 repository cache
352 repository cache
353 ----------------
353 ----------------
354
354
355 $ cp $HGRCPATH.unconfigured $HGRCPATH
355 $ cp $HGRCPATH.unconfigured $HGRCPATH
356 $ cat <<'EOF' >> $HGRCPATH
356 $ cat <<'EOF' >> $HGRCPATH
357 > [cmdserver]
357 > [cmdserver]
358 > log = $TESTTMP/log/server-cached.log
358 > log = $TESTTMP/log/server-cached.log
359 > max-repo-cache = 1
359 > max-repo-cache = 1
360 > track-log = command, repocache
360 > track-log = command, repocache
361 > EOF
361 > EOF
362
362
363 isolate socket directory for stable result:
363 isolate socket directory for stable result:
364
364
365 $ OLDCHGSOCKNAME=$CHGSOCKNAME
365 $ OLDCHGSOCKNAME=$CHGSOCKNAME
366 $ mkdir chgsock
366 $ mkdir chgsock
367 $ CHGSOCKNAME=`pwd`/chgsock/server
367 $ CHGSOCKNAME=`pwd`/chgsock/server
368
368
369 create empty repo and cache it:
369 create empty repo and cache it:
370
370
371 $ hg init cached
371 $ hg init cached
372 $ hg id -R cached
372 $ hg id -R cached
373 000000000000 tip
373 000000000000 tip
374 $ sleep 1
374 $ sleep 1
375
375
376 modify repo (and cache will be invalidated):
376 modify repo (and cache will be invalidated):
377
377
378 $ touch cached/a
378 $ touch cached/a
379 $ hg ci -R cached -Am 'add a'
379 $ hg ci -R cached -Am 'add a'
380 adding a
380 adding a
381 $ sleep 1
381 $ sleep 1
382
382
383 read cached repo:
383 read cached repo:
384
384
385 $ hg log -R cached
385 $ hg log -R cached
386 changeset: 0:ac82d8b1f7c4
386 changeset: 0:ac82d8b1f7c4
387 tag: tip
387 tag: tip
388 user: test
388 user: test
389 date: Thu Jan 01 00:00:00 1970 +0000
389 date: Thu Jan 01 00:00:00 1970 +0000
390 summary: add a
390 summary: add a
391
391
392 $ sleep 1
392 $ sleep 1
393
393
394 discard cached from LRU cache:
394 discard cached from LRU cache:
395
395
396 $ hg clone cached cached2
396 $ hg clone cached cached2
397 updating to branch default
397 updating to branch default
398 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
398 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
399 $ hg id -R cached2
399 $ hg id -R cached2
400 ac82d8b1f7c4 tip
400 ac82d8b1f7c4 tip
401 $ sleep 1
401 $ sleep 1
402
402
403 read uncached repo:
403 read uncached repo:
404
404
405 $ hg log -R cached
405 $ hg log -R cached
406 changeset: 0:ac82d8b1f7c4
406 changeset: 0:ac82d8b1f7c4
407 tag: tip
407 tag: tip
408 user: test
408 user: test
409 date: Thu Jan 01 00:00:00 1970 +0000
409 date: Thu Jan 01 00:00:00 1970 +0000
410 summary: add a
410 summary: add a
411
411
412 $ sleep 1
412 $ sleep 1
413
413
414 shut down servers and restore environment:
414 shut down servers and restore environment:
415
415
416 $ rm -R chgsock
416 $ rm -R chgsock
417 $ sleep 2
417 $ sleep 2
418 $ CHGSOCKNAME=$OLDCHGSOCKNAME
418 $ CHGSOCKNAME=$OLDCHGSOCKNAME
419
419
420 check server log:
420 check server log:
421
421
422 $ cat log/server-cached.log | filterlog
422 $ cat log/server-cached.log | filterlog
423 YYYY/MM/DD HH:MM:SS (PID)> init cached
423 YYYY/MM/DD HH:MM:SS (PID)> init cached
424 YYYY/MM/DD HH:MM:SS (PID)> id -R cached
424 YYYY/MM/DD HH:MM:SS (PID)> id -R cached
425 YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached (in ...s)
425 YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached (in ...s)
426 YYYY/MM/DD HH:MM:SS (PID)> repo from cache: $TESTTMP/cached
426 YYYY/MM/DD HH:MM:SS (PID)> repo from cache: $TESTTMP/cached
427 YYYY/MM/DD HH:MM:SS (PID)> ci -R cached -Am 'add a'
427 YYYY/MM/DD HH:MM:SS (PID)> ci -R cached -Am 'add a'
428 YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached (in ...s)
428 YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached (in ...s)
429 YYYY/MM/DD HH:MM:SS (PID)> repo from cache: $TESTTMP/cached
429 YYYY/MM/DD HH:MM:SS (PID)> repo from cache: $TESTTMP/cached
430 YYYY/MM/DD HH:MM:SS (PID)> log -R cached
430 YYYY/MM/DD HH:MM:SS (PID)> log -R cached
431 YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached (in ...s)
431 YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached (in ...s)
432 YYYY/MM/DD HH:MM:SS (PID)> clone cached cached2
432 YYYY/MM/DD HH:MM:SS (PID)> clone cached cached2
433 YYYY/MM/DD HH:MM:SS (PID)> id -R cached2
433 YYYY/MM/DD HH:MM:SS (PID)> id -R cached2
434 YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached2 (in ...s)
434 YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached2 (in ...s)
435 YYYY/MM/DD HH:MM:SS (PID)> log -R cached
435 YYYY/MM/DD HH:MM:SS (PID)> log -R cached
436 YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached (in ...s)
436 YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached (in ...s)
437
437
438 Test that -R is interpreted relative to --cwd.
438 Test that -R is interpreted relative to --cwd.
439
439
440 $ hg init repo1
440 $ hg init repo1
441 $ mkdir -p a/b
441 $ mkdir -p a/b
442 $ hg init a/b/repo2
442 $ hg init a/b/repo2
443 $ printf "[alias]\ntest=repo1\n" >> repo1/.hg/hgrc
443 $ printf "[alias]\ntest=repo1\n" >> repo1/.hg/hgrc
444 $ printf "[alias]\ntest=repo2\n" >> a/b/repo2/.hg/hgrc
444 $ printf "[alias]\ntest=repo2\n" >> a/b/repo2/.hg/hgrc
445 $ cd a
445 $ cd a
446 $ chg --cwd .. -R repo1 show alias.test
446 $ chg --cwd .. -R repo1 show alias.test
447 repo1
447 repo1
448 $ chg --cwd . -R b/repo2 show alias.test
448 $ chg --cwd . -R b/repo2 show alias.test
449 repo2
449 repo2
450 $ cd ..
450 $ cd ..
451
451
452 Test that chg works (sets to the user's actual LC_CTYPE) even when python
452 Test that chg works (sets to the user's actual LC_CTYPE) even when python
453 "coerces" the locale (py3.7+)
453 "coerces" the locale (py3.7+)
454
454
455 $ cat > $TESTTMP/debugenv.py <<EOF
455 $ cat > $TESTTMP/debugenv.py <<EOF
456 > from mercurial import encoding
456 > from mercurial import encoding
457 > from mercurial import registrar
457 > from mercurial import registrar
458 > cmdtable = {}
458 > cmdtable = {}
459 > command = registrar.command(cmdtable)
459 > command = registrar.command(cmdtable)
460 > @command(b'debugenv', [], b'', norepo=True)
460 > @command(b'debugenv', [], b'', norepo=True)
461 > def debugenv(ui):
461 > def debugenv(ui):
462 > for k in [b'LC_ALL', b'LC_CTYPE', b'LANG']:
462 > for k in [b'LC_ALL', b'LC_CTYPE', b'LANG']:
463 > v = encoding.environ.get(k)
463 > v = encoding.environ.get(k)
464 > if v is not None:
464 > if v is not None:
465 > ui.write(b'%s=%s\n' % (k, encoding.environ[k]))
465 > ui.write(b'%s=%s\n' % (k, encoding.environ[k]))
466 > EOF
466 > EOF
467 (hg keeps python's modified LC_CTYPE, chg doesn't)
467 (hg keeps python's modified LC_CTYPE, chg doesn't)
468 $ (unset LC_ALL; unset LANG; LC_CTYPE= "$CHGHG" \
468 $ (unset LC_ALL; unset LANG; LC_CTYPE= "$CHGHG" \
469 > --config extensions.debugenv=$TESTTMP/debugenv.py debugenv)
469 > --config extensions.debugenv=$TESTTMP/debugenv.py debugenv)
470 LC_CTYPE=C.UTF-8 (py37 !)
470 LC_CTYPE=C.UTF-8 (py37 !)
471 LC_CTYPE= (no-py37 !)
471 LC_CTYPE= (no-py37 !)
472 $ (unset LC_ALL; unset LANG; LC_CTYPE= chg \
472 $ (unset LC_ALL; unset LANG; LC_CTYPE= chg \
473 > --config extensions.debugenv=$TESTTMP/debugenv.py debugenv)
473 > --config extensions.debugenv=$TESTTMP/debugenv.py debugenv)
474 LC_CTYPE=
474 LC_CTYPE=
475 $ (unset LC_ALL; unset LANG; LC_CTYPE=unsupported_value chg \
475 $ (unset LC_ALL; unset LANG; LC_CTYPE=unsupported_value chg \
476 > --config extensions.debugenv=$TESTTMP/debugenv.py debugenv)
476 > --config extensions.debugenv=$TESTTMP/debugenv.py debugenv)
477 *cannot change locale* (glob) (?)
477 *cannot change locale* (glob) (?)
478 LC_CTYPE=unsupported_value
478 LC_CTYPE=unsupported_value
479 $ (unset LC_ALL; unset LANG; LC_CTYPE= chg \
479 $ (unset LC_ALL; unset LANG; LC_CTYPE= chg \
480 > --config extensions.debugenv=$TESTTMP/debugenv.py debugenv)
480 > --config extensions.debugenv=$TESTTMP/debugenv.py debugenv)
481 LC_CTYPE=
481 LC_CTYPE=
482 $ LANG= LC_ALL= LC_CTYPE= chg \
482 $ LANG= LC_ALL= LC_CTYPE= chg \
483 > --config extensions.debugenv=$TESTTMP/debugenv.py debugenv
483 > --config extensions.debugenv=$TESTTMP/debugenv.py debugenv
484 LC_ALL=
484 LC_ALL=
485 LC_CTYPE=
485 LC_CTYPE=
486 LANG=
486 LANG=
487
487
488 Profiling isn't permanently enabled or carried over between chg invocations that
488 Profiling isn't permanently enabled or carried over between chg invocations that
489 share the same server
489 share the same server
490 $ cp $HGRCPATH.orig $HGRCPATH
490 $ cp $HGRCPATH.orig $HGRCPATH
491 $ hg init $TESTTMP/profiling
491 $ hg init $TESTTMP/profiling
492 $ cd $TESTTMP/profiling
492 $ cd $TESTTMP/profiling
493 $ filteredchg() {
493 $ filteredchg() {
494 > CHGDEBUG=1 chg "$@" 2>&1 | sed -rn 's_^No samples recorded.*$_Sample count: 0_; /Sample count/p; /start cmdserver/p'
494 > CHGDEBUG=1 chg "$@" 2>&1 | sed -rn 's_^No samples recorded.*$_Sample count: 0_; /Sample count/p; /start cmdserver/p'
495 > }
495 > }
496 $ newchg() {
496 $ newchg() {
497 > chg --kill-chg-daemon
497 > chg --kill-chg-daemon
498 > filteredchg "$@" | egrep -v 'start cmdserver' || true
498 > filteredchg "$@" | egrep -v 'start cmdserver' || true
499 > }
499 > }
500 (--profile isn't permanently on just because it was specified when chg was
500 (--profile isn't permanently on just because it was specified when chg was
501 started)
501 started)
502 $ newchg log -r . --profile
502 $ newchg log -r . --profile
503 Sample count: * (glob)
503 Sample count: * (glob)
504 $ filteredchg log -r .
504 $ filteredchg log -r .
505 (enabling profiling via config works, even on the first chg command that starts
505 (enabling profiling via config works, even on the first chg command that starts
506 a cmdserver)
506 a cmdserver)
507 $ cat >> $HGRCPATH <<EOF
507 $ cat >> $HGRCPATH <<EOF
508 > [profiling]
508 > [profiling]
509 > type=stat
509 > type=stat
510 > enabled=1
510 > enabled=1
511 > EOF
511 > EOF
512 $ newchg log -r .
512 $ newchg log -r .
513 Sample count: * (glob)
513 Sample count: * (glob)
514 $ filteredchg log -r .
514 $ filteredchg log -r .
515 Sample count: * (glob)
515 Sample count: * (glob)
516 (test that we aren't accumulating more and more samples each run)
516 (test that we aren't accumulating more and more samples each run)
517 $ cat > $TESTTMP/debugsleep.py <<EOF
517 $ cat > $TESTTMP/debugsleep.py <<EOF
518 > import time
518 > import time
519 > from mercurial import registrar
519 > from mercurial import registrar
520 > cmdtable = {}
520 > cmdtable = {}
521 > command = registrar.command(cmdtable)
521 > command = registrar.command(cmdtable)
522 > @command(b'debugsleep', [], b'', norepo=True)
522 > @command(b'debugsleep', [], b'', norepo=True)
523 > def debugsleep(ui):
523 > def debugsleep(ui):
524 > start = time.time()
524 > start = time.time()
525 > x = 0
525 > x = 0
526 > while time.time() < start + 0.5:
526 > while time.time() < start + 0.5:
527 > time.sleep(.1)
527 > time.sleep(.1)
528 > x += 1
528 > x += 1
529 > ui.status(b'%d debugsleep iterations in %.03fs\n' % (x, time.time() - start))
529 > ui.status(b'%d debugsleep iterations in %.03fs\n' % (x, time.time() - start))
530 > EOF
530 > EOF
531 $ cat >> $HGRCPATH <<EOF
531 $ cat >> $HGRCPATH <<EOF
532 > [extensions]
532 > [extensions]
533 > debugsleep = $TESTTMP/debugsleep.py
533 > debugsleep = $TESTTMP/debugsleep.py
534 > EOF
534 > EOF
535 $ newchg debugsleep > run_1
535 $ newchg debugsleep > run_1
536 $ filteredchg debugsleep > run_2
536 $ filteredchg debugsleep > run_2
537 $ filteredchg debugsleep > run_3
537 $ filteredchg debugsleep > run_3
538 $ filteredchg debugsleep > run_4
538 $ filteredchg debugsleep > run_4
539 FIXME: Run 4 should not be >3x Run 1's number of samples.
539 FIXME: Run 4 should not be >3x Run 1's number of samples.
540 $ "$PYTHON" <<EOF
540 $ "$PYTHON" <<EOF
541 > r1 = int(open("run_1", "r").read().split()[-1])
541 > r1 = int(open("run_1", "r").read().split()[-1])
542 > r4 = int(open("run_4", "r").read().split()[-1])
542 > r4 = int(open("run_4", "r").read().split()[-1])
543 > print("Run 1: %d samples\nRun 4: %d samples\nRun 4 > 3 * Run 1: %s" %
543 > print("Run 1: %d samples\nRun 4: %d samples\nRun 4 > 3 * Run 1: %s" %
544 > (r1, r4, r4 > (r1 * 3)))
544 > (r1, r4, r4 > (r1 * 3)))
545 > EOF
545 > EOF
546 Run 1: * samples (glob)
546 Run 1: * samples (glob)
547 Run 4: * samples (glob)
547 Run 4: * samples (glob)
548 Run 4 > 3 * Run 1: False
548 Run 4 > 3 * Run 1: False
549 (Disabling with --no-profile on the commandline still works, but isn't permanent)
549 (Disabling with --no-profile on the commandline still works, but isn't permanent)
550 $ newchg log -r . --no-profile
550 $ newchg log -r . --no-profile
551 $ filteredchg log -r .
551 $ filteredchg log -r .
552 Sample count: * (glob)
552 Sample count: * (glob)
553 $ filteredchg log -r . --no-profile
553 $ filteredchg log -r . --no-profile
554 $ filteredchg log -r .
554 $ filteredchg log -r .
555 Sample count: * (glob)
555 Sample count: * (glob)
556
557 chg setting CHGHG itself
558 ------------------------
559
560 If CHGHG is not set, chg will set it before spawning the command server.
561 $ hg --kill-chg-daemon
562 $ HG=$CHGHG CHGHG= CHGDEBUG= hg debugshell -c \
563 > 'ui.write(b"CHGHG=%s\n" % ui.environ.get(b"CHGHG"))' 2>&1 \
564 > | egrep 'CHGHG|start'
565 chg: debug: * start cmdserver at * (glob)
566 CHGHG=/*/install/bin/hg (glob)
567
568 Running the same command a second time shouldn't spawn a new command server.
569 $ HG=$CHGHG CHGHG= CHGDEBUG= hg debugshell -c \
570 > 'ui.write(b"CHGHG=%s\n" % ui.environ.get(b"CHGHG"))' 2>&1 \
571 > | egrep 'CHGHG|start'
572 CHGHG=/*/install/bin/hg (glob)
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now