##// END OF EJS Templates
merge with stable
Pulkit Goyal -
r42152:b1bc6e5f merge default
parent child Browse files
Show More
@@ -1,178 +1,179 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,191 +1,192 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
@@ -1,3352 +1,3374 b''
1 # cmdutil.py - help for command processing in mercurial
1 # cmdutil.py - help for command processing in mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@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 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import copy as copymod
10 import errno
11 import errno
11 import os
12 import os
12 import re
13 import re
13
14
14 from .i18n import _
15 from .i18n import _
15 from .node import (
16 from .node import (
16 hex,
17 hex,
17 nullid,
18 nullid,
18 nullrev,
19 nullrev,
19 short,
20 short,
20 )
21 )
21
22
22 from . import (
23 from . import (
23 bookmarks,
24 bookmarks,
24 changelog,
25 changelog,
25 copies,
26 copies,
26 crecord as crecordmod,
27 crecord as crecordmod,
27 dirstateguard,
28 dirstateguard,
28 encoding,
29 encoding,
29 error,
30 error,
30 formatter,
31 formatter,
31 logcmdutil,
32 logcmdutil,
32 match as matchmod,
33 match as matchmod,
33 merge as mergemod,
34 merge as mergemod,
34 mergeutil,
35 mergeutil,
35 obsolete,
36 obsolete,
36 patch,
37 patch,
37 pathutil,
38 pathutil,
38 phases,
39 phases,
39 pycompat,
40 pycompat,
40 revlog,
41 revlog,
41 rewriteutil,
42 rewriteutil,
42 scmutil,
43 scmutil,
43 smartset,
44 smartset,
44 subrepoutil,
45 subrepoutil,
45 templatekw,
46 templatekw,
46 templater,
47 templater,
47 util,
48 util,
48 vfs as vfsmod,
49 vfs as vfsmod,
49 )
50 )
50
51
51 from .utils import (
52 from .utils import (
52 dateutil,
53 dateutil,
53 stringutil,
54 stringutil,
54 )
55 )
55
56
56 stringio = util.stringio
57 stringio = util.stringio
57
58
58 # templates of common command options
59 # templates of common command options
59
60
60 dryrunopts = [
61 dryrunopts = [
61 ('n', 'dry-run', None,
62 ('n', 'dry-run', None,
62 _('do not perform actions, just print output')),
63 _('do not perform actions, just print output')),
63 ]
64 ]
64
65
65 confirmopts = [
66 confirmopts = [
66 ('', 'confirm', None,
67 ('', 'confirm', None,
67 _('ask before applying actions')),
68 _('ask before applying actions')),
68 ]
69 ]
69
70
70 remoteopts = [
71 remoteopts = [
71 ('e', 'ssh', '',
72 ('e', 'ssh', '',
72 _('specify ssh command to use'), _('CMD')),
73 _('specify ssh command to use'), _('CMD')),
73 ('', 'remotecmd', '',
74 ('', 'remotecmd', '',
74 _('specify hg command to run on the remote side'), _('CMD')),
75 _('specify hg command to run on the remote side'), _('CMD')),
75 ('', 'insecure', None,
76 ('', 'insecure', None,
76 _('do not verify server certificate (ignoring web.cacerts config)')),
77 _('do not verify server certificate (ignoring web.cacerts config)')),
77 ]
78 ]
78
79
79 walkopts = [
80 walkopts = [
80 ('I', 'include', [],
81 ('I', 'include', [],
81 _('include names matching the given patterns'), _('PATTERN')),
82 _('include names matching the given patterns'), _('PATTERN')),
82 ('X', 'exclude', [],
83 ('X', 'exclude', [],
83 _('exclude names matching the given patterns'), _('PATTERN')),
84 _('exclude names matching the given patterns'), _('PATTERN')),
84 ]
85 ]
85
86
86 commitopts = [
87 commitopts = [
87 ('m', 'message', '',
88 ('m', 'message', '',
88 _('use text as commit message'), _('TEXT')),
89 _('use text as commit message'), _('TEXT')),
89 ('l', 'logfile', '',
90 ('l', 'logfile', '',
90 _('read commit message from file'), _('FILE')),
91 _('read commit message from file'), _('FILE')),
91 ]
92 ]
92
93
93 commitopts2 = [
94 commitopts2 = [
94 ('d', 'date', '',
95 ('d', 'date', '',
95 _('record the specified date as commit date'), _('DATE')),
96 _('record the specified date as commit date'), _('DATE')),
96 ('u', 'user', '',
97 ('u', 'user', '',
97 _('record the specified user as committer'), _('USER')),
98 _('record the specified user as committer'), _('USER')),
98 ]
99 ]
99
100
100 formatteropts = [
101 formatteropts = [
101 ('T', 'template', '',
102 ('T', 'template', '',
102 _('display with template'), _('TEMPLATE')),
103 _('display with template'), _('TEMPLATE')),
103 ]
104 ]
104
105
105 templateopts = [
106 templateopts = [
106 ('', 'style', '',
107 ('', 'style', '',
107 _('display using template map file (DEPRECATED)'), _('STYLE')),
108 _('display using template map file (DEPRECATED)'), _('STYLE')),
108 ('T', 'template', '',
109 ('T', 'template', '',
109 _('display with template'), _('TEMPLATE')),
110 _('display with template'), _('TEMPLATE')),
110 ]
111 ]
111
112
112 logopts = [
113 logopts = [
113 ('p', 'patch', None, _('show patch')),
114 ('p', 'patch', None, _('show patch')),
114 ('g', 'git', None, _('use git extended diff format')),
115 ('g', 'git', None, _('use git extended diff format')),
115 ('l', 'limit', '',
116 ('l', 'limit', '',
116 _('limit number of changes displayed'), _('NUM')),
117 _('limit number of changes displayed'), _('NUM')),
117 ('M', 'no-merges', None, _('do not show merges')),
118 ('M', 'no-merges', None, _('do not show merges')),
118 ('', 'stat', None, _('output diffstat-style summary of changes')),
119 ('', 'stat', None, _('output diffstat-style summary of changes')),
119 ('G', 'graph', None, _("show the revision DAG")),
120 ('G', 'graph', None, _("show the revision DAG")),
120 ] + templateopts
121 ] + templateopts
121
122
122 diffopts = [
123 diffopts = [
123 ('a', 'text', None, _('treat all files as text')),
124 ('a', 'text', None, _('treat all files as text')),
124 ('g', 'git', None, _('use git extended diff format')),
125 ('g', 'git', None, _('use git extended diff format')),
125 ('', 'binary', None, _('generate binary diffs in git mode (default)')),
126 ('', 'binary', None, _('generate binary diffs in git mode (default)')),
126 ('', 'nodates', None, _('omit dates from diff headers'))
127 ('', 'nodates', None, _('omit dates from diff headers'))
127 ]
128 ]
128
129
129 diffwsopts = [
130 diffwsopts = [
130 ('w', 'ignore-all-space', None,
131 ('w', 'ignore-all-space', None,
131 _('ignore white space when comparing lines')),
132 _('ignore white space when comparing lines')),
132 ('b', 'ignore-space-change', None,
133 ('b', 'ignore-space-change', None,
133 _('ignore changes in the amount of white space')),
134 _('ignore changes in the amount of white space')),
134 ('B', 'ignore-blank-lines', None,
135 ('B', 'ignore-blank-lines', None,
135 _('ignore changes whose lines are all blank')),
136 _('ignore changes whose lines are all blank')),
136 ('Z', 'ignore-space-at-eol', None,
137 ('Z', 'ignore-space-at-eol', None,
137 _('ignore changes in whitespace at EOL')),
138 _('ignore changes in whitespace at EOL')),
138 ]
139 ]
139
140
140 diffopts2 = [
141 diffopts2 = [
141 ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
142 ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
142 ('p', 'show-function', None, _('show which function each change is in')),
143 ('p', 'show-function', None, _('show which function each change is in')),
143 ('', 'reverse', None, _('produce a diff that undoes the changes')),
144 ('', 'reverse', None, _('produce a diff that undoes the changes')),
144 ] + diffwsopts + [
145 ] + diffwsopts + [
145 ('U', 'unified', '',
146 ('U', 'unified', '',
146 _('number of lines of context to show'), _('NUM')),
147 _('number of lines of context to show'), _('NUM')),
147 ('', 'stat', None, _('output diffstat-style summary of changes')),
148 ('', 'stat', None, _('output diffstat-style summary of changes')),
148 ('', 'root', '', _('produce diffs relative to subdirectory'), _('DIR')),
149 ('', 'root', '', _('produce diffs relative to subdirectory'), _('DIR')),
149 ]
150 ]
150
151
151 mergetoolopts = [
152 mergetoolopts = [
152 ('t', 'tool', '', _('specify merge tool'), _('TOOL')),
153 ('t', 'tool', '', _('specify merge tool'), _('TOOL')),
153 ]
154 ]
154
155
155 similarityopts = [
156 similarityopts = [
156 ('s', 'similarity', '',
157 ('s', 'similarity', '',
157 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
158 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
158 ]
159 ]
159
160
160 subrepoopts = [
161 subrepoopts = [
161 ('S', 'subrepos', None,
162 ('S', 'subrepos', None,
162 _('recurse into subrepositories'))
163 _('recurse into subrepositories'))
163 ]
164 ]
164
165
165 debugrevlogopts = [
166 debugrevlogopts = [
166 ('c', 'changelog', False, _('open changelog')),
167 ('c', 'changelog', False, _('open changelog')),
167 ('m', 'manifest', False, _('open manifest')),
168 ('m', 'manifest', False, _('open manifest')),
168 ('', 'dir', '', _('open directory manifest')),
169 ('', 'dir', '', _('open directory manifest')),
169 ]
170 ]
170
171
171 # special string such that everything below this line will be ingored in the
172 # special string such that everything below this line will be ingored in the
172 # editor text
173 # editor text
173 _linebelow = "^HG: ------------------------ >8 ------------------------$"
174 _linebelow = "^HG: ------------------------ >8 ------------------------$"
174
175
175 def ishunk(x):
176 def ishunk(x):
176 hunkclasses = (crecordmod.uihunk, patch.recordhunk)
177 hunkclasses = (crecordmod.uihunk, patch.recordhunk)
177 return isinstance(x, hunkclasses)
178 return isinstance(x, hunkclasses)
178
179
179 def newandmodified(chunks, originalchunks):
180 def newandmodified(chunks, originalchunks):
180 newlyaddedandmodifiedfiles = set()
181 newlyaddedandmodifiedfiles = set()
181 for chunk in chunks:
182 for chunk in chunks:
182 if (ishunk(chunk) and chunk.header.isnewfile() and chunk not in
183 if (ishunk(chunk) and chunk.header.isnewfile() and chunk not in
183 originalchunks):
184 originalchunks):
184 newlyaddedandmodifiedfiles.add(chunk.header.filename())
185 newlyaddedandmodifiedfiles.add(chunk.header.filename())
185 return newlyaddedandmodifiedfiles
186 return newlyaddedandmodifiedfiles
186
187
187 def parsealiases(cmd):
188 def parsealiases(cmd):
188 return cmd.split("|")
189 return cmd.split("|")
189
190
190 def setupwrapcolorwrite(ui):
191 def setupwrapcolorwrite(ui):
191 # wrap ui.write so diff output can be labeled/colorized
192 # wrap ui.write so diff output can be labeled/colorized
192 def wrapwrite(orig, *args, **kw):
193 def wrapwrite(orig, *args, **kw):
193 label = kw.pop(r'label', '')
194 label = kw.pop(r'label', '')
194 for chunk, l in patch.difflabel(lambda: args):
195 for chunk, l in patch.difflabel(lambda: args):
195 orig(chunk, label=label + l)
196 orig(chunk, label=label + l)
196
197
197 oldwrite = ui.write
198 oldwrite = ui.write
198 def wrap(*args, **kwargs):
199 def wrap(*args, **kwargs):
199 return wrapwrite(oldwrite, *args, **kwargs)
200 return wrapwrite(oldwrite, *args, **kwargs)
200 setattr(ui, 'write', wrap)
201 setattr(ui, 'write', wrap)
201 return oldwrite
202 return oldwrite
202
203
203 def filterchunks(ui, originalhunks, usecurses, testfile, operation=None):
204 def filterchunks(ui, originalhunks, usecurses, testfile, operation=None):
204 try:
205 try:
205 if usecurses:
206 if usecurses:
206 if testfile:
207 if testfile:
207 recordfn = crecordmod.testdecorator(
208 recordfn = crecordmod.testdecorator(
208 testfile, crecordmod.testchunkselector)
209 testfile, crecordmod.testchunkselector)
209 else:
210 else:
210 recordfn = crecordmod.chunkselector
211 recordfn = crecordmod.chunkselector
211
212
212 return crecordmod.filterpatch(ui, originalhunks, recordfn,
213 return crecordmod.filterpatch(ui, originalhunks, recordfn,
213 operation)
214 operation)
214 except crecordmod.fallbackerror as e:
215 except crecordmod.fallbackerror as e:
215 ui.warn('%s\n' % e.message)
216 ui.warn('%s\n' % e.message)
216 ui.warn(_('falling back to text mode\n'))
217 ui.warn(_('falling back to text mode\n'))
217
218
218 return patch.filterpatch(ui, originalhunks, operation)
219 return patch.filterpatch(ui, originalhunks, operation)
219
220
220 def recordfilter(ui, originalhunks, operation=None):
221 def recordfilter(ui, originalhunks, operation=None):
221 """ Prompts the user to filter the originalhunks and return a list of
222 """ Prompts the user to filter the originalhunks and return a list of
222 selected hunks.
223 selected hunks.
223 *operation* is used for to build ui messages to indicate the user what
224 *operation* is used for to build ui messages to indicate the user what
224 kind of filtering they are doing: reverting, committing, shelving, etc.
225 kind of filtering they are doing: reverting, committing, shelving, etc.
225 (see patch.filterpatch).
226 (see patch.filterpatch).
226 """
227 """
227 usecurses = crecordmod.checkcurses(ui)
228 usecurses = crecordmod.checkcurses(ui)
228 testfile = ui.config('experimental', 'crecordtest')
229 testfile = ui.config('experimental', 'crecordtest')
229 oldwrite = setupwrapcolorwrite(ui)
230 oldwrite = setupwrapcolorwrite(ui)
230 try:
231 try:
231 newchunks, newopts = filterchunks(ui, originalhunks, usecurses,
232 newchunks, newopts = filterchunks(ui, originalhunks, usecurses,
232 testfile, operation)
233 testfile, operation)
233 finally:
234 finally:
234 ui.write = oldwrite
235 ui.write = oldwrite
235 return newchunks, newopts
236 return newchunks, newopts
236
237
237 def dorecord(ui, repo, commitfunc, cmdsuggest, backupall,
238 def dorecord(ui, repo, commitfunc, cmdsuggest, backupall,
238 filterfn, *pats, **opts):
239 filterfn, *pats, **opts):
239 opts = pycompat.byteskwargs(opts)
240 opts = pycompat.byteskwargs(opts)
240 if not ui.interactive():
241 if not ui.interactive():
241 if cmdsuggest:
242 if cmdsuggest:
242 msg = _('running non-interactively, use %s instead') % cmdsuggest
243 msg = _('running non-interactively, use %s instead') % cmdsuggest
243 else:
244 else:
244 msg = _('running non-interactively')
245 msg = _('running non-interactively')
245 raise error.Abort(msg)
246 raise error.Abort(msg)
246
247
247 # make sure username is set before going interactive
248 # make sure username is set before going interactive
248 if not opts.get('user'):
249 if not opts.get('user'):
249 ui.username() # raise exception, username not provided
250 ui.username() # raise exception, username not provided
250
251
251 def recordfunc(ui, repo, message, match, opts):
252 def recordfunc(ui, repo, message, match, opts):
252 """This is generic record driver.
253 """This is generic record driver.
253
254
254 Its job is to interactively filter local changes, and
255 Its job is to interactively filter local changes, and
255 accordingly prepare working directory into a state in which the
256 accordingly prepare working directory into a state in which the
256 job can be delegated to a non-interactive commit command such as
257 job can be delegated to a non-interactive commit command such as
257 'commit' or 'qrefresh'.
258 'commit' or 'qrefresh'.
258
259
259 After the actual job is done by non-interactive command, the
260 After the actual job is done by non-interactive command, the
260 working directory is restored to its original state.
261 working directory is restored to its original state.
261
262
262 In the end we'll record interesting changes, and everything else
263 In the end we'll record interesting changes, and everything else
263 will be left in place, so the user can continue working.
264 will be left in place, so the user can continue working.
264 """
265 """
265
266
266 checkunfinished(repo, commit=True)
267 checkunfinished(repo, commit=True)
267 wctx = repo[None]
268 wctx = repo[None]
268 merge = len(wctx.parents()) > 1
269 merge = len(wctx.parents()) > 1
269 if merge:
270 if merge:
270 raise error.Abort(_('cannot partially commit a merge '
271 raise error.Abort(_('cannot partially commit a merge '
271 '(use "hg commit" instead)'))
272 '(use "hg commit" instead)'))
272
273
274 status = repo.status(match=match)
275
276 overrides = {(b'ui', b'commitsubrepos'): True}
277
278 with repo.ui.configoverride(overrides, b'record'):
279 # subrepoutil.precommit() modifies the status
280 tmpstatus = scmutil.status(copymod.copy(status[0]),
281 copymod.copy(status[1]),
282 copymod.copy(status[2]),
283 copymod.copy(status[3]),
284 copymod.copy(status[4]),
285 copymod.copy(status[5]),
286 copymod.copy(status[6]))
287
288 # Force allows -X subrepo to skip the subrepo.
289 subs, commitsubs, newstate = subrepoutil.precommit(
290 repo.ui, wctx, tmpstatus, match, force=True)
291 for s in subs:
292 if s in commitsubs:
293 dirtyreason = wctx.sub(s).dirtyreason(True)
294 raise error.Abort(dirtyreason)
295
273 def fail(f, msg):
296 def fail(f, msg):
274 raise error.Abort('%s: %s' % (f, msg))
297 raise error.Abort('%s: %s' % (f, msg))
275
298
276 force = opts.get('force')
299 force = opts.get('force')
277 if not force:
300 if not force:
278 vdirs = []
301 vdirs = []
279 match.explicitdir = vdirs.append
302 match.explicitdir = vdirs.append
280 match.bad = fail
303 match.bad = fail
281
304
282 status = repo.status(match=match)
283 if not force:
305 if not force:
284 repo.checkcommitpatterns(wctx, vdirs, match, status, fail)
306 repo.checkcommitpatterns(wctx, vdirs, match, status, fail)
285 diffopts = patch.difffeatureopts(ui, opts=opts, whitespace=True,
307 diffopts = patch.difffeatureopts(ui, opts=opts, whitespace=True,
286 section='commands',
308 section='commands',
287 configprefix='commit.interactive.')
309 configprefix='commit.interactive.')
288 diffopts.nodates = True
310 diffopts.nodates = True
289 diffopts.git = True
311 diffopts.git = True
290 diffopts.showfunc = True
312 diffopts.showfunc = True
291 originaldiff = patch.diff(repo, changes=status, opts=diffopts)
313 originaldiff = patch.diff(repo, changes=status, opts=diffopts)
292 originalchunks = patch.parsepatch(originaldiff)
314 originalchunks = patch.parsepatch(originaldiff)
293
315
294 # 1. filter patch, since we are intending to apply subset of it
316 # 1. filter patch, since we are intending to apply subset of it
295 try:
317 try:
296 chunks, newopts = filterfn(ui, originalchunks)
318 chunks, newopts = filterfn(ui, originalchunks)
297 except error.PatchError as err:
319 except error.PatchError as err:
298 raise error.Abort(_('error parsing patch: %s') % err)
320 raise error.Abort(_('error parsing patch: %s') % err)
299 opts.update(newopts)
321 opts.update(newopts)
300
322
301 # We need to keep a backup of files that have been newly added and
323 # We need to keep a backup of files that have been newly added and
302 # modified during the recording process because there is a previous
324 # modified during the recording process because there is a previous
303 # version without the edit in the workdir
325 # version without the edit in the workdir
304 newlyaddedandmodifiedfiles = newandmodified(chunks, originalchunks)
326 newlyaddedandmodifiedfiles = newandmodified(chunks, originalchunks)
305 contenders = set()
327 contenders = set()
306 for h in chunks:
328 for h in chunks:
307 try:
329 try:
308 contenders.update(set(h.files()))
330 contenders.update(set(h.files()))
309 except AttributeError:
331 except AttributeError:
310 pass
332 pass
311
333
312 changed = status.modified + status.added + status.removed
334 changed = status.modified + status.added + status.removed
313 newfiles = [f for f in changed if f in contenders]
335 newfiles = [f for f in changed if f in contenders]
314 if not newfiles:
336 if not newfiles:
315 ui.status(_('no changes to record\n'))
337 ui.status(_('no changes to record\n'))
316 return 0
338 return 0
317
339
318 modified = set(status.modified)
340 modified = set(status.modified)
319
341
320 # 2. backup changed files, so we can restore them in the end
342 # 2. backup changed files, so we can restore them in the end
321
343
322 if backupall:
344 if backupall:
323 tobackup = changed
345 tobackup = changed
324 else:
346 else:
325 tobackup = [f for f in newfiles if f in modified or f in
347 tobackup = [f for f in newfiles if f in modified or f in
326 newlyaddedandmodifiedfiles]
348 newlyaddedandmodifiedfiles]
327 backups = {}
349 backups = {}
328 if tobackup:
350 if tobackup:
329 backupdir = repo.vfs.join('record-backups')
351 backupdir = repo.vfs.join('record-backups')
330 try:
352 try:
331 os.mkdir(backupdir)
353 os.mkdir(backupdir)
332 except OSError as err:
354 except OSError as err:
333 if err.errno != errno.EEXIST:
355 if err.errno != errno.EEXIST:
334 raise
356 raise
335 try:
357 try:
336 # backup continues
358 # backup continues
337 for f in tobackup:
359 for f in tobackup:
338 fd, tmpname = pycompat.mkstemp(prefix=f.replace('/', '_') + '.',
360 fd, tmpname = pycompat.mkstemp(prefix=f.replace('/', '_') + '.',
339 dir=backupdir)
361 dir=backupdir)
340 os.close(fd)
362 os.close(fd)
341 ui.debug('backup %r as %r\n' % (f, tmpname))
363 ui.debug('backup %r as %r\n' % (f, tmpname))
342 util.copyfile(repo.wjoin(f), tmpname, copystat=True)
364 util.copyfile(repo.wjoin(f), tmpname, copystat=True)
343 backups[f] = tmpname
365 backups[f] = tmpname
344
366
345 fp = stringio()
367 fp = stringio()
346 for c in chunks:
368 for c in chunks:
347 fname = c.filename()
369 fname = c.filename()
348 if fname in backups:
370 if fname in backups:
349 c.write(fp)
371 c.write(fp)
350 dopatch = fp.tell()
372 dopatch = fp.tell()
351 fp.seek(0)
373 fp.seek(0)
352
374
353 # 2.5 optionally review / modify patch in text editor
375 # 2.5 optionally review / modify patch in text editor
354 if opts.get('review', False):
376 if opts.get('review', False):
355 patchtext = (crecordmod.diffhelptext
377 patchtext = (crecordmod.diffhelptext
356 + crecordmod.patchhelptext
378 + crecordmod.patchhelptext
357 + fp.read())
379 + fp.read())
358 reviewedpatch = ui.edit(patchtext, "",
380 reviewedpatch = ui.edit(patchtext, "",
359 action="diff",
381 action="diff",
360 repopath=repo.path)
382 repopath=repo.path)
361 fp.truncate(0)
383 fp.truncate(0)
362 fp.write(reviewedpatch)
384 fp.write(reviewedpatch)
363 fp.seek(0)
385 fp.seek(0)
364
386
365 [os.unlink(repo.wjoin(c)) for c in newlyaddedandmodifiedfiles]
387 [os.unlink(repo.wjoin(c)) for c in newlyaddedandmodifiedfiles]
366 # 3a. apply filtered patch to clean repo (clean)
388 # 3a. apply filtered patch to clean repo (clean)
367 if backups:
389 if backups:
368 # Equivalent to hg.revert
390 # Equivalent to hg.revert
369 m = scmutil.matchfiles(repo, backups.keys())
391 m = scmutil.matchfiles(repo, backups.keys())
370 mergemod.update(repo, repo.dirstate.p1(), branchmerge=False,
392 mergemod.update(repo, repo.dirstate.p1(), branchmerge=False,
371 force=True, matcher=m)
393 force=True, matcher=m)
372
394
373 # 3b. (apply)
395 # 3b. (apply)
374 if dopatch:
396 if dopatch:
375 try:
397 try:
376 ui.debug('applying patch\n')
398 ui.debug('applying patch\n')
377 ui.debug(fp.getvalue())
399 ui.debug(fp.getvalue())
378 patch.internalpatch(ui, repo, fp, 1, eolmode=None)
400 patch.internalpatch(ui, repo, fp, 1, eolmode=None)
379 except error.PatchError as err:
401 except error.PatchError as err:
380 raise error.Abort(pycompat.bytestr(err))
402 raise error.Abort(pycompat.bytestr(err))
381 del fp
403 del fp
382
404
383 # 4. We prepared working directory according to filtered
405 # 4. We prepared working directory according to filtered
384 # patch. Now is the time to delegate the job to
406 # patch. Now is the time to delegate the job to
385 # commit/qrefresh or the like!
407 # commit/qrefresh or the like!
386
408
387 # Make all of the pathnames absolute.
409 # Make all of the pathnames absolute.
388 newfiles = [repo.wjoin(nf) for nf in newfiles]
410 newfiles = [repo.wjoin(nf) for nf in newfiles]
389 return commitfunc(ui, repo, *newfiles, **pycompat.strkwargs(opts))
411 return commitfunc(ui, repo, *newfiles, **pycompat.strkwargs(opts))
390 finally:
412 finally:
391 # 5. finally restore backed-up files
413 # 5. finally restore backed-up files
392 try:
414 try:
393 dirstate = repo.dirstate
415 dirstate = repo.dirstate
394 for realname, tmpname in backups.iteritems():
416 for realname, tmpname in backups.iteritems():
395 ui.debug('restoring %r to %r\n' % (tmpname, realname))
417 ui.debug('restoring %r to %r\n' % (tmpname, realname))
396
418
397 if dirstate[realname] == 'n':
419 if dirstate[realname] == 'n':
398 # without normallookup, restoring timestamp
420 # without normallookup, restoring timestamp
399 # may cause partially committed files
421 # may cause partially committed files
400 # to be treated as unmodified
422 # to be treated as unmodified
401 dirstate.normallookup(realname)
423 dirstate.normallookup(realname)
402
424
403 # copystat=True here and above are a hack to trick any
425 # copystat=True here and above are a hack to trick any
404 # editors that have f open that we haven't modified them.
426 # editors that have f open that we haven't modified them.
405 #
427 #
406 # Also note that this racy as an editor could notice the
428 # Also note that this racy as an editor could notice the
407 # file's mtime before we've finished writing it.
429 # file's mtime before we've finished writing it.
408 util.copyfile(tmpname, repo.wjoin(realname), copystat=True)
430 util.copyfile(tmpname, repo.wjoin(realname), copystat=True)
409 os.unlink(tmpname)
431 os.unlink(tmpname)
410 if tobackup:
432 if tobackup:
411 os.rmdir(backupdir)
433 os.rmdir(backupdir)
412 except OSError:
434 except OSError:
413 pass
435 pass
414
436
415 def recordinwlock(ui, repo, message, match, opts):
437 def recordinwlock(ui, repo, message, match, opts):
416 with repo.wlock():
438 with repo.wlock():
417 return recordfunc(ui, repo, message, match, opts)
439 return recordfunc(ui, repo, message, match, opts)
418
440
419 return commit(ui, repo, recordinwlock, pats, opts)
441 return commit(ui, repo, recordinwlock, pats, opts)
420
442
421 class dirnode(object):
443 class dirnode(object):
422 """
444 """
423 Represent a directory in user working copy with information required for
445 Represent a directory in user working copy with information required for
424 the purpose of tersing its status.
446 the purpose of tersing its status.
425
447
426 path is the path to the directory, without a trailing '/'
448 path is the path to the directory, without a trailing '/'
427
449
428 statuses is a set of statuses of all files in this directory (this includes
450 statuses is a set of statuses of all files in this directory (this includes
429 all the files in all the subdirectories too)
451 all the files in all the subdirectories too)
430
452
431 files is a list of files which are direct child of this directory
453 files is a list of files which are direct child of this directory
432
454
433 subdirs is a dictionary of sub-directory name as the key and it's own
455 subdirs is a dictionary of sub-directory name as the key and it's own
434 dirnode object as the value
456 dirnode object as the value
435 """
457 """
436
458
437 def __init__(self, dirpath):
459 def __init__(self, dirpath):
438 self.path = dirpath
460 self.path = dirpath
439 self.statuses = set([])
461 self.statuses = set([])
440 self.files = []
462 self.files = []
441 self.subdirs = {}
463 self.subdirs = {}
442
464
443 def _addfileindir(self, filename, status):
465 def _addfileindir(self, filename, status):
444 """Add a file in this directory as a direct child."""
466 """Add a file in this directory as a direct child."""
445 self.files.append((filename, status))
467 self.files.append((filename, status))
446
468
447 def addfile(self, filename, status):
469 def addfile(self, filename, status):
448 """
470 """
449 Add a file to this directory or to its direct parent directory.
471 Add a file to this directory or to its direct parent directory.
450
472
451 If the file is not direct child of this directory, we traverse to the
473 If the file is not direct child of this directory, we traverse to the
452 directory of which this file is a direct child of and add the file
474 directory of which this file is a direct child of and add the file
453 there.
475 there.
454 """
476 """
455
477
456 # the filename contains a path separator, it means it's not the direct
478 # the filename contains a path separator, it means it's not the direct
457 # child of this directory
479 # child of this directory
458 if '/' in filename:
480 if '/' in filename:
459 subdir, filep = filename.split('/', 1)
481 subdir, filep = filename.split('/', 1)
460
482
461 # does the dirnode object for subdir exists
483 # does the dirnode object for subdir exists
462 if subdir not in self.subdirs:
484 if subdir not in self.subdirs:
463 subdirpath = pathutil.join(self.path, subdir)
485 subdirpath = pathutil.join(self.path, subdir)
464 self.subdirs[subdir] = dirnode(subdirpath)
486 self.subdirs[subdir] = dirnode(subdirpath)
465
487
466 # try adding the file in subdir
488 # try adding the file in subdir
467 self.subdirs[subdir].addfile(filep, status)
489 self.subdirs[subdir].addfile(filep, status)
468
490
469 else:
491 else:
470 self._addfileindir(filename, status)
492 self._addfileindir(filename, status)
471
493
472 if status not in self.statuses:
494 if status not in self.statuses:
473 self.statuses.add(status)
495 self.statuses.add(status)
474
496
475 def iterfilepaths(self):
497 def iterfilepaths(self):
476 """Yield (status, path) for files directly under this directory."""
498 """Yield (status, path) for files directly under this directory."""
477 for f, st in self.files:
499 for f, st in self.files:
478 yield st, pathutil.join(self.path, f)
500 yield st, pathutil.join(self.path, f)
479
501
480 def tersewalk(self, terseargs):
502 def tersewalk(self, terseargs):
481 """
503 """
482 Yield (status, path) obtained by processing the status of this
504 Yield (status, path) obtained by processing the status of this
483 dirnode.
505 dirnode.
484
506
485 terseargs is the string of arguments passed by the user with `--terse`
507 terseargs is the string of arguments passed by the user with `--terse`
486 flag.
508 flag.
487
509
488 Following are the cases which can happen:
510 Following are the cases which can happen:
489
511
490 1) All the files in the directory (including all the files in its
512 1) All the files in the directory (including all the files in its
491 subdirectories) share the same status and the user has asked us to terse
513 subdirectories) share the same status and the user has asked us to terse
492 that status. -> yield (status, dirpath). dirpath will end in '/'.
514 that status. -> yield (status, dirpath). dirpath will end in '/'.
493
515
494 2) Otherwise, we do following:
516 2) Otherwise, we do following:
495
517
496 a) Yield (status, filepath) for all the files which are in this
518 a) Yield (status, filepath) for all the files which are in this
497 directory (only the ones in this directory, not the subdirs)
519 directory (only the ones in this directory, not the subdirs)
498
520
499 b) Recurse the function on all the subdirectories of this
521 b) Recurse the function on all the subdirectories of this
500 directory
522 directory
501 """
523 """
502
524
503 if len(self.statuses) == 1:
525 if len(self.statuses) == 1:
504 onlyst = self.statuses.pop()
526 onlyst = self.statuses.pop()
505
527
506 # Making sure we terse only when the status abbreviation is
528 # Making sure we terse only when the status abbreviation is
507 # passed as terse argument
529 # passed as terse argument
508 if onlyst in terseargs:
530 if onlyst in terseargs:
509 yield onlyst, self.path + '/'
531 yield onlyst, self.path + '/'
510 return
532 return
511
533
512 # add the files to status list
534 # add the files to status list
513 for st, fpath in self.iterfilepaths():
535 for st, fpath in self.iterfilepaths():
514 yield st, fpath
536 yield st, fpath
515
537
516 #recurse on the subdirs
538 #recurse on the subdirs
517 for dirobj in self.subdirs.values():
539 for dirobj in self.subdirs.values():
518 for st, fpath in dirobj.tersewalk(terseargs):
540 for st, fpath in dirobj.tersewalk(terseargs):
519 yield st, fpath
541 yield st, fpath
520
542
521 def tersedir(statuslist, terseargs):
543 def tersedir(statuslist, terseargs):
522 """
544 """
523 Terse the status if all the files in a directory shares the same status.
545 Terse the status if all the files in a directory shares the same status.
524
546
525 statuslist is scmutil.status() object which contains a list of files for
547 statuslist is scmutil.status() object which contains a list of files for
526 each status.
548 each status.
527 terseargs is string which is passed by the user as the argument to `--terse`
549 terseargs is string which is passed by the user as the argument to `--terse`
528 flag.
550 flag.
529
551
530 The function makes a tree of objects of dirnode class, and at each node it
552 The function makes a tree of objects of dirnode class, and at each node it
531 stores the information required to know whether we can terse a certain
553 stores the information required to know whether we can terse a certain
532 directory or not.
554 directory or not.
533 """
555 """
534 # the order matters here as that is used to produce final list
556 # the order matters here as that is used to produce final list
535 allst = ('m', 'a', 'r', 'd', 'u', 'i', 'c')
557 allst = ('m', 'a', 'r', 'd', 'u', 'i', 'c')
536
558
537 # checking the argument validity
559 # checking the argument validity
538 for s in pycompat.bytestr(terseargs):
560 for s in pycompat.bytestr(terseargs):
539 if s not in allst:
561 if s not in allst:
540 raise error.Abort(_("'%s' not recognized") % s)
562 raise error.Abort(_("'%s' not recognized") % s)
541
563
542 # creating a dirnode object for the root of the repo
564 # creating a dirnode object for the root of the repo
543 rootobj = dirnode('')
565 rootobj = dirnode('')
544 pstatus = ('modified', 'added', 'deleted', 'clean', 'unknown',
566 pstatus = ('modified', 'added', 'deleted', 'clean', 'unknown',
545 'ignored', 'removed')
567 'ignored', 'removed')
546
568
547 tersedict = {}
569 tersedict = {}
548 for attrname in pstatus:
570 for attrname in pstatus:
549 statuschar = attrname[0:1]
571 statuschar = attrname[0:1]
550 for f in getattr(statuslist, attrname):
572 for f in getattr(statuslist, attrname):
551 rootobj.addfile(f, statuschar)
573 rootobj.addfile(f, statuschar)
552 tersedict[statuschar] = []
574 tersedict[statuschar] = []
553
575
554 # we won't be tersing the root dir, so add files in it
576 # we won't be tersing the root dir, so add files in it
555 for st, fpath in rootobj.iterfilepaths():
577 for st, fpath in rootobj.iterfilepaths():
556 tersedict[st].append(fpath)
578 tersedict[st].append(fpath)
557
579
558 # process each sub-directory and build tersedict
580 # process each sub-directory and build tersedict
559 for subdir in rootobj.subdirs.values():
581 for subdir in rootobj.subdirs.values():
560 for st, f in subdir.tersewalk(terseargs):
582 for st, f in subdir.tersewalk(terseargs):
561 tersedict[st].append(f)
583 tersedict[st].append(f)
562
584
563 tersedlist = []
585 tersedlist = []
564 for st in allst:
586 for st in allst:
565 tersedict[st].sort()
587 tersedict[st].sort()
566 tersedlist.append(tersedict[st])
588 tersedlist.append(tersedict[st])
567
589
568 return tersedlist
590 return tersedlist
569
591
570 def _commentlines(raw):
592 def _commentlines(raw):
571 '''Surround lineswith a comment char and a new line'''
593 '''Surround lineswith a comment char and a new line'''
572 lines = raw.splitlines()
594 lines = raw.splitlines()
573 commentedlines = ['# %s' % line for line in lines]
595 commentedlines = ['# %s' % line for line in lines]
574 return '\n'.join(commentedlines) + '\n'
596 return '\n'.join(commentedlines) + '\n'
575
597
576 def _conflictsmsg(repo):
598 def _conflictsmsg(repo):
577 mergestate = mergemod.mergestate.read(repo)
599 mergestate = mergemod.mergestate.read(repo)
578 if not mergestate.active():
600 if not mergestate.active():
579 return
601 return
580
602
581 m = scmutil.match(repo[None])
603 m = scmutil.match(repo[None])
582 unresolvedlist = [f for f in mergestate.unresolved() if m(f)]
604 unresolvedlist = [f for f in mergestate.unresolved() if m(f)]
583 if unresolvedlist:
605 if unresolvedlist:
584 mergeliststr = '\n'.join(
606 mergeliststr = '\n'.join(
585 [' %s' % util.pathto(repo.root, encoding.getcwd(), path)
607 [' %s' % util.pathto(repo.root, encoding.getcwd(), path)
586 for path in sorted(unresolvedlist)])
608 for path in sorted(unresolvedlist)])
587 msg = _('''Unresolved merge conflicts:
609 msg = _('''Unresolved merge conflicts:
588
610
589 %s
611 %s
590
612
591 To mark files as resolved: hg resolve --mark FILE''') % mergeliststr
613 To mark files as resolved: hg resolve --mark FILE''') % mergeliststr
592 else:
614 else:
593 msg = _('No unresolved merge conflicts.')
615 msg = _('No unresolved merge conflicts.')
594
616
595 return _commentlines(msg)
617 return _commentlines(msg)
596
618
597 def _helpmessage(continuecmd, abortcmd):
619 def _helpmessage(continuecmd, abortcmd):
598 msg = _('To continue: %s\n'
620 msg = _('To continue: %s\n'
599 'To abort: %s') % (continuecmd, abortcmd)
621 'To abort: %s') % (continuecmd, abortcmd)
600 return _commentlines(msg)
622 return _commentlines(msg)
601
623
602 def _rebasemsg():
624 def _rebasemsg():
603 return _helpmessage('hg rebase --continue', 'hg rebase --abort')
625 return _helpmessage('hg rebase --continue', 'hg rebase --abort')
604
626
605 def _histeditmsg():
627 def _histeditmsg():
606 return _helpmessage('hg histedit --continue', 'hg histedit --abort')
628 return _helpmessage('hg histedit --continue', 'hg histedit --abort')
607
629
608 def _unshelvemsg():
630 def _unshelvemsg():
609 return _helpmessage('hg unshelve --continue', 'hg unshelve --abort')
631 return _helpmessage('hg unshelve --continue', 'hg unshelve --abort')
610
632
611 def _graftmsg():
633 def _graftmsg():
612 return _helpmessage('hg graft --continue', 'hg graft --abort')
634 return _helpmessage('hg graft --continue', 'hg graft --abort')
613
635
614 def _mergemsg():
636 def _mergemsg():
615 return _helpmessage('hg commit', 'hg merge --abort')
637 return _helpmessage('hg commit', 'hg merge --abort')
616
638
617 def _bisectmsg():
639 def _bisectmsg():
618 msg = _('To mark the changeset good: hg bisect --good\n'
640 msg = _('To mark the changeset good: hg bisect --good\n'
619 'To mark the changeset bad: hg bisect --bad\n'
641 'To mark the changeset bad: hg bisect --bad\n'
620 'To abort: hg bisect --reset\n')
642 'To abort: hg bisect --reset\n')
621 return _commentlines(msg)
643 return _commentlines(msg)
622
644
623 def fileexistspredicate(filename):
645 def fileexistspredicate(filename):
624 return lambda repo: repo.vfs.exists(filename)
646 return lambda repo: repo.vfs.exists(filename)
625
647
626 def _mergepredicate(repo):
648 def _mergepredicate(repo):
627 return len(repo[None].parents()) > 1
649 return len(repo[None].parents()) > 1
628
650
629 STATES = (
651 STATES = (
630 # (state, predicate to detect states, helpful message function)
652 # (state, predicate to detect states, helpful message function)
631 ('histedit', fileexistspredicate('histedit-state'), _histeditmsg),
653 ('histedit', fileexistspredicate('histedit-state'), _histeditmsg),
632 ('bisect', fileexistspredicate('bisect.state'), _bisectmsg),
654 ('bisect', fileexistspredicate('bisect.state'), _bisectmsg),
633 ('graft', fileexistspredicate('graftstate'), _graftmsg),
655 ('graft', fileexistspredicate('graftstate'), _graftmsg),
634 ('unshelve', fileexistspredicate('shelvedstate'), _unshelvemsg),
656 ('unshelve', fileexistspredicate('shelvedstate'), _unshelvemsg),
635 ('rebase', fileexistspredicate('rebasestate'), _rebasemsg),
657 ('rebase', fileexistspredicate('rebasestate'), _rebasemsg),
636 # The merge state is part of a list that will be iterated over.
658 # The merge state is part of a list that will be iterated over.
637 # They need to be last because some of the other unfinished states may also
659 # They need to be last because some of the other unfinished states may also
638 # be in a merge or update state (eg. rebase, histedit, graft, etc).
660 # be in a merge or update state (eg. rebase, histedit, graft, etc).
639 # We want those to have priority.
661 # We want those to have priority.
640 ('merge', _mergepredicate, _mergemsg),
662 ('merge', _mergepredicate, _mergemsg),
641 )
663 )
642
664
643 def _getrepostate(repo):
665 def _getrepostate(repo):
644 # experimental config: commands.status.skipstates
666 # experimental config: commands.status.skipstates
645 skip = set(repo.ui.configlist('commands', 'status.skipstates'))
667 skip = set(repo.ui.configlist('commands', 'status.skipstates'))
646 for state, statedetectionpredicate, msgfn in STATES:
668 for state, statedetectionpredicate, msgfn in STATES:
647 if state in skip:
669 if state in skip:
648 continue
670 continue
649 if statedetectionpredicate(repo):
671 if statedetectionpredicate(repo):
650 return (state, statedetectionpredicate, msgfn)
672 return (state, statedetectionpredicate, msgfn)
651
673
652 def morestatus(repo, fm):
674 def morestatus(repo, fm):
653 statetuple = _getrepostate(repo)
675 statetuple = _getrepostate(repo)
654 label = 'status.morestatus'
676 label = 'status.morestatus'
655 if statetuple:
677 if statetuple:
656 state, statedetectionpredicate, helpfulmsg = statetuple
678 state, statedetectionpredicate, helpfulmsg = statetuple
657 statemsg = _('The repository is in an unfinished *%s* state.') % state
679 statemsg = _('The repository is in an unfinished *%s* state.') % state
658 fm.plain('%s\n' % _commentlines(statemsg), label=label)
680 fm.plain('%s\n' % _commentlines(statemsg), label=label)
659 conmsg = _conflictsmsg(repo)
681 conmsg = _conflictsmsg(repo)
660 if conmsg:
682 if conmsg:
661 fm.plain('%s\n' % conmsg, label=label)
683 fm.plain('%s\n' % conmsg, label=label)
662 if helpfulmsg:
684 if helpfulmsg:
663 helpmsg = helpfulmsg()
685 helpmsg = helpfulmsg()
664 fm.plain('%s\n' % helpmsg, label=label)
686 fm.plain('%s\n' % helpmsg, label=label)
665
687
666 def findpossible(cmd, table, strict=False):
688 def findpossible(cmd, table, strict=False):
667 """
689 """
668 Return cmd -> (aliases, command table entry)
690 Return cmd -> (aliases, command table entry)
669 for each matching command.
691 for each matching command.
670 Return debug commands (or their aliases) only if no normal command matches.
692 Return debug commands (or their aliases) only if no normal command matches.
671 """
693 """
672 choice = {}
694 choice = {}
673 debugchoice = {}
695 debugchoice = {}
674
696
675 if cmd in table:
697 if cmd in table:
676 # short-circuit exact matches, "log" alias beats "log|history"
698 # short-circuit exact matches, "log" alias beats "log|history"
677 keys = [cmd]
699 keys = [cmd]
678 else:
700 else:
679 keys = table.keys()
701 keys = table.keys()
680
702
681 allcmds = []
703 allcmds = []
682 for e in keys:
704 for e in keys:
683 aliases = parsealiases(e)
705 aliases = parsealiases(e)
684 allcmds.extend(aliases)
706 allcmds.extend(aliases)
685 found = None
707 found = None
686 if cmd in aliases:
708 if cmd in aliases:
687 found = cmd
709 found = cmd
688 elif not strict:
710 elif not strict:
689 for a in aliases:
711 for a in aliases:
690 if a.startswith(cmd):
712 if a.startswith(cmd):
691 found = a
713 found = a
692 break
714 break
693 if found is not None:
715 if found is not None:
694 if aliases[0].startswith("debug") or found.startswith("debug"):
716 if aliases[0].startswith("debug") or found.startswith("debug"):
695 debugchoice[found] = (aliases, table[e])
717 debugchoice[found] = (aliases, table[e])
696 else:
718 else:
697 choice[found] = (aliases, table[e])
719 choice[found] = (aliases, table[e])
698
720
699 if not choice and debugchoice:
721 if not choice and debugchoice:
700 choice = debugchoice
722 choice = debugchoice
701
723
702 return choice, allcmds
724 return choice, allcmds
703
725
704 def findcmd(cmd, table, strict=True):
726 def findcmd(cmd, table, strict=True):
705 """Return (aliases, command table entry) for command string."""
727 """Return (aliases, command table entry) for command string."""
706 choice, allcmds = findpossible(cmd, table, strict)
728 choice, allcmds = findpossible(cmd, table, strict)
707
729
708 if cmd in choice:
730 if cmd in choice:
709 return choice[cmd]
731 return choice[cmd]
710
732
711 if len(choice) > 1:
733 if len(choice) > 1:
712 clist = sorted(choice)
734 clist = sorted(choice)
713 raise error.AmbiguousCommand(cmd, clist)
735 raise error.AmbiguousCommand(cmd, clist)
714
736
715 if choice:
737 if choice:
716 return list(choice.values())[0]
738 return list(choice.values())[0]
717
739
718 raise error.UnknownCommand(cmd, allcmds)
740 raise error.UnknownCommand(cmd, allcmds)
719
741
720 def changebranch(ui, repo, revs, label):
742 def changebranch(ui, repo, revs, label):
721 """ Change the branch name of given revs to label """
743 """ Change the branch name of given revs to label """
722
744
723 with repo.wlock(), repo.lock(), repo.transaction('branches'):
745 with repo.wlock(), repo.lock(), repo.transaction('branches'):
724 # abort in case of uncommitted merge or dirty wdir
746 # abort in case of uncommitted merge or dirty wdir
725 bailifchanged(repo)
747 bailifchanged(repo)
726 revs = scmutil.revrange(repo, revs)
748 revs = scmutil.revrange(repo, revs)
727 if not revs:
749 if not revs:
728 raise error.Abort("empty revision set")
750 raise error.Abort("empty revision set")
729 roots = repo.revs('roots(%ld)', revs)
751 roots = repo.revs('roots(%ld)', revs)
730 if len(roots) > 1:
752 if len(roots) > 1:
731 raise error.Abort(_("cannot change branch of non-linear revisions"))
753 raise error.Abort(_("cannot change branch of non-linear revisions"))
732 rewriteutil.precheck(repo, revs, 'change branch of')
754 rewriteutil.precheck(repo, revs, 'change branch of')
733
755
734 root = repo[roots.first()]
756 root = repo[roots.first()]
735 rpb = {parent.branch() for parent in root.parents()}
757 rpb = {parent.branch() for parent in root.parents()}
736 if label not in rpb and label in repo.branchmap():
758 if label not in rpb and label in repo.branchmap():
737 raise error.Abort(_("a branch of the same name already exists"))
759 raise error.Abort(_("a branch of the same name already exists"))
738
760
739 if repo.revs('obsolete() and %ld', revs):
761 if repo.revs('obsolete() and %ld', revs):
740 raise error.Abort(_("cannot change branch of a obsolete changeset"))
762 raise error.Abort(_("cannot change branch of a obsolete changeset"))
741
763
742 # make sure only topological heads
764 # make sure only topological heads
743 if repo.revs('heads(%ld) - head()', revs):
765 if repo.revs('heads(%ld) - head()', revs):
744 raise error.Abort(_("cannot change branch in middle of a stack"))
766 raise error.Abort(_("cannot change branch in middle of a stack"))
745
767
746 replacements = {}
768 replacements = {}
747 # avoid import cycle mercurial.cmdutil -> mercurial.context ->
769 # avoid import cycle mercurial.cmdutil -> mercurial.context ->
748 # mercurial.subrepo -> mercurial.cmdutil
770 # mercurial.subrepo -> mercurial.cmdutil
749 from . import context
771 from . import context
750 for rev in revs:
772 for rev in revs:
751 ctx = repo[rev]
773 ctx = repo[rev]
752 oldbranch = ctx.branch()
774 oldbranch = ctx.branch()
753 # check if ctx has same branch
775 # check if ctx has same branch
754 if oldbranch == label:
776 if oldbranch == label:
755 continue
777 continue
756
778
757 def filectxfn(repo, newctx, path):
779 def filectxfn(repo, newctx, path):
758 try:
780 try:
759 return ctx[path]
781 return ctx[path]
760 except error.ManifestLookupError:
782 except error.ManifestLookupError:
761 return None
783 return None
762
784
763 ui.debug("changing branch of '%s' from '%s' to '%s'\n"
785 ui.debug("changing branch of '%s' from '%s' to '%s'\n"
764 % (hex(ctx.node()), oldbranch, label))
786 % (hex(ctx.node()), oldbranch, label))
765 extra = ctx.extra()
787 extra = ctx.extra()
766 extra['branch_change'] = hex(ctx.node())
788 extra['branch_change'] = hex(ctx.node())
767 # While changing branch of set of linear commits, make sure that
789 # While changing branch of set of linear commits, make sure that
768 # we base our commits on new parent rather than old parent which
790 # we base our commits on new parent rather than old parent which
769 # was obsoleted while changing the branch
791 # was obsoleted while changing the branch
770 p1 = ctx.p1().node()
792 p1 = ctx.p1().node()
771 p2 = ctx.p2().node()
793 p2 = ctx.p2().node()
772 if p1 in replacements:
794 if p1 in replacements:
773 p1 = replacements[p1][0]
795 p1 = replacements[p1][0]
774 if p2 in replacements:
796 if p2 in replacements:
775 p2 = replacements[p2][0]
797 p2 = replacements[p2][0]
776
798
777 mc = context.memctx(repo, (p1, p2),
799 mc = context.memctx(repo, (p1, p2),
778 ctx.description(),
800 ctx.description(),
779 ctx.files(),
801 ctx.files(),
780 filectxfn,
802 filectxfn,
781 user=ctx.user(),
803 user=ctx.user(),
782 date=ctx.date(),
804 date=ctx.date(),
783 extra=extra,
805 extra=extra,
784 branch=label)
806 branch=label)
785
807
786 newnode = repo.commitctx(mc)
808 newnode = repo.commitctx(mc)
787 replacements[ctx.node()] = (newnode,)
809 replacements[ctx.node()] = (newnode,)
788 ui.debug('new node id is %s\n' % hex(newnode))
810 ui.debug('new node id is %s\n' % hex(newnode))
789
811
790 # create obsmarkers and move bookmarks
812 # create obsmarkers and move bookmarks
791 scmutil.cleanupnodes(repo, replacements, 'branch-change', fixphase=True)
813 scmutil.cleanupnodes(repo, replacements, 'branch-change', fixphase=True)
792
814
793 # move the working copy too
815 # move the working copy too
794 wctx = repo[None]
816 wctx = repo[None]
795 # in-progress merge is a bit too complex for now.
817 # in-progress merge is a bit too complex for now.
796 if len(wctx.parents()) == 1:
818 if len(wctx.parents()) == 1:
797 newid = replacements.get(wctx.p1().node())
819 newid = replacements.get(wctx.p1().node())
798 if newid is not None:
820 if newid is not None:
799 # avoid import cycle mercurial.cmdutil -> mercurial.hg ->
821 # avoid import cycle mercurial.cmdutil -> mercurial.hg ->
800 # mercurial.cmdutil
822 # mercurial.cmdutil
801 from . import hg
823 from . import hg
802 hg.update(repo, newid[0], quietempty=True)
824 hg.update(repo, newid[0], quietempty=True)
803
825
804 ui.status(_("changed branch on %d changesets\n") % len(replacements))
826 ui.status(_("changed branch on %d changesets\n") % len(replacements))
805
827
806 def findrepo(p):
828 def findrepo(p):
807 while not os.path.isdir(os.path.join(p, ".hg")):
829 while not os.path.isdir(os.path.join(p, ".hg")):
808 oldp, p = p, os.path.dirname(p)
830 oldp, p = p, os.path.dirname(p)
809 if p == oldp:
831 if p == oldp:
810 return None
832 return None
811
833
812 return p
834 return p
813
835
814 def bailifchanged(repo, merge=True, hint=None):
836 def bailifchanged(repo, merge=True, hint=None):
815 """ enforce the precondition that working directory must be clean.
837 """ enforce the precondition that working directory must be clean.
816
838
817 'merge' can be set to false if a pending uncommitted merge should be
839 'merge' can be set to false if a pending uncommitted merge should be
818 ignored (such as when 'update --check' runs).
840 ignored (such as when 'update --check' runs).
819
841
820 'hint' is the usual hint given to Abort exception.
842 'hint' is the usual hint given to Abort exception.
821 """
843 """
822
844
823 if merge and repo.dirstate.p2() != nullid:
845 if merge and repo.dirstate.p2() != nullid:
824 raise error.Abort(_('outstanding uncommitted merge'), hint=hint)
846 raise error.Abort(_('outstanding uncommitted merge'), hint=hint)
825 modified, added, removed, deleted = repo.status()[:4]
847 modified, added, removed, deleted = repo.status()[:4]
826 if modified or added or removed or deleted:
848 if modified or added or removed or deleted:
827 raise error.Abort(_('uncommitted changes'), hint=hint)
849 raise error.Abort(_('uncommitted changes'), hint=hint)
828 ctx = repo[None]
850 ctx = repo[None]
829 for s in sorted(ctx.substate):
851 for s in sorted(ctx.substate):
830 ctx.sub(s).bailifchanged(hint=hint)
852 ctx.sub(s).bailifchanged(hint=hint)
831
853
832 def logmessage(ui, opts):
854 def logmessage(ui, opts):
833 """ get the log message according to -m and -l option """
855 """ get the log message according to -m and -l option """
834 message = opts.get('message')
856 message = opts.get('message')
835 logfile = opts.get('logfile')
857 logfile = opts.get('logfile')
836
858
837 if message and logfile:
859 if message and logfile:
838 raise error.Abort(_('options --message and --logfile are mutually '
860 raise error.Abort(_('options --message and --logfile are mutually '
839 'exclusive'))
861 'exclusive'))
840 if not message and logfile:
862 if not message and logfile:
841 try:
863 try:
842 if isstdiofilename(logfile):
864 if isstdiofilename(logfile):
843 message = ui.fin.read()
865 message = ui.fin.read()
844 else:
866 else:
845 message = '\n'.join(util.readfile(logfile).splitlines())
867 message = '\n'.join(util.readfile(logfile).splitlines())
846 except IOError as inst:
868 except IOError as inst:
847 raise error.Abort(_("can't read commit message '%s': %s") %
869 raise error.Abort(_("can't read commit message '%s': %s") %
848 (logfile, encoding.strtolocal(inst.strerror)))
870 (logfile, encoding.strtolocal(inst.strerror)))
849 return message
871 return message
850
872
851 def mergeeditform(ctxorbool, baseformname):
873 def mergeeditform(ctxorbool, baseformname):
852 """return appropriate editform name (referencing a committemplate)
874 """return appropriate editform name (referencing a committemplate)
853
875
854 'ctxorbool' is either a ctx to be committed, or a bool indicating whether
876 'ctxorbool' is either a ctx to be committed, or a bool indicating whether
855 merging is committed.
877 merging is committed.
856
878
857 This returns baseformname with '.merge' appended if it is a merge,
879 This returns baseformname with '.merge' appended if it is a merge,
858 otherwise '.normal' is appended.
880 otherwise '.normal' is appended.
859 """
881 """
860 if isinstance(ctxorbool, bool):
882 if isinstance(ctxorbool, bool):
861 if ctxorbool:
883 if ctxorbool:
862 return baseformname + ".merge"
884 return baseformname + ".merge"
863 elif len(ctxorbool.parents()) > 1:
885 elif len(ctxorbool.parents()) > 1:
864 return baseformname + ".merge"
886 return baseformname + ".merge"
865
887
866 return baseformname + ".normal"
888 return baseformname + ".normal"
867
889
868 def getcommiteditor(edit=False, finishdesc=None, extramsg=None,
890 def getcommiteditor(edit=False, finishdesc=None, extramsg=None,
869 editform='', **opts):
891 editform='', **opts):
870 """get appropriate commit message editor according to '--edit' option
892 """get appropriate commit message editor according to '--edit' option
871
893
872 'finishdesc' is a function to be called with edited commit message
894 'finishdesc' is a function to be called with edited commit message
873 (= 'description' of the new changeset) just after editing, but
895 (= 'description' of the new changeset) just after editing, but
874 before checking empty-ness. It should return actual text to be
896 before checking empty-ness. It should return actual text to be
875 stored into history. This allows to change description before
897 stored into history. This allows to change description before
876 storing.
898 storing.
877
899
878 'extramsg' is a extra message to be shown in the editor instead of
900 'extramsg' is a extra message to be shown in the editor instead of
879 'Leave message empty to abort commit' line. 'HG: ' prefix and EOL
901 'Leave message empty to abort commit' line. 'HG: ' prefix and EOL
880 is automatically added.
902 is automatically added.
881
903
882 'editform' is a dot-separated list of names, to distinguish
904 'editform' is a dot-separated list of names, to distinguish
883 the purpose of commit text editing.
905 the purpose of commit text editing.
884
906
885 'getcommiteditor' returns 'commitforceeditor' regardless of
907 'getcommiteditor' returns 'commitforceeditor' regardless of
886 'edit', if one of 'finishdesc' or 'extramsg' is specified, because
908 'edit', if one of 'finishdesc' or 'extramsg' is specified, because
887 they are specific for usage in MQ.
909 they are specific for usage in MQ.
888 """
910 """
889 if edit or finishdesc or extramsg:
911 if edit or finishdesc or extramsg:
890 return lambda r, c, s: commitforceeditor(r, c, s,
912 return lambda r, c, s: commitforceeditor(r, c, s,
891 finishdesc=finishdesc,
913 finishdesc=finishdesc,
892 extramsg=extramsg,
914 extramsg=extramsg,
893 editform=editform)
915 editform=editform)
894 elif editform:
916 elif editform:
895 return lambda r, c, s: commiteditor(r, c, s, editform=editform)
917 return lambda r, c, s: commiteditor(r, c, s, editform=editform)
896 else:
918 else:
897 return commiteditor
919 return commiteditor
898
920
899 def _escapecommandtemplate(tmpl):
921 def _escapecommandtemplate(tmpl):
900 parts = []
922 parts = []
901 for typ, start, end in templater.scantemplate(tmpl, raw=True):
923 for typ, start, end in templater.scantemplate(tmpl, raw=True):
902 if typ == b'string':
924 if typ == b'string':
903 parts.append(stringutil.escapestr(tmpl[start:end]))
925 parts.append(stringutil.escapestr(tmpl[start:end]))
904 else:
926 else:
905 parts.append(tmpl[start:end])
927 parts.append(tmpl[start:end])
906 return b''.join(parts)
928 return b''.join(parts)
907
929
908 def rendercommandtemplate(ui, tmpl, props):
930 def rendercommandtemplate(ui, tmpl, props):
909 r"""Expand a literal template 'tmpl' in a way suitable for command line
931 r"""Expand a literal template 'tmpl' in a way suitable for command line
910
932
911 '\' in outermost string is not taken as an escape character because it
933 '\' in outermost string is not taken as an escape character because it
912 is a directory separator on Windows.
934 is a directory separator on Windows.
913
935
914 >>> from . import ui as uimod
936 >>> from . import ui as uimod
915 >>> ui = uimod.ui()
937 >>> ui = uimod.ui()
916 >>> rendercommandtemplate(ui, b'c:\\{path}', {b'path': b'foo'})
938 >>> rendercommandtemplate(ui, b'c:\\{path}', {b'path': b'foo'})
917 'c:\\foo'
939 'c:\\foo'
918 >>> rendercommandtemplate(ui, b'{"c:\\{path}"}', {'path': b'foo'})
940 >>> rendercommandtemplate(ui, b'{"c:\\{path}"}', {'path': b'foo'})
919 'c:{path}'
941 'c:{path}'
920 """
942 """
921 if not tmpl:
943 if not tmpl:
922 return tmpl
944 return tmpl
923 t = formatter.maketemplater(ui, _escapecommandtemplate(tmpl))
945 t = formatter.maketemplater(ui, _escapecommandtemplate(tmpl))
924 return t.renderdefault(props)
946 return t.renderdefault(props)
925
947
926 def rendertemplate(ctx, tmpl, props=None):
948 def rendertemplate(ctx, tmpl, props=None):
927 """Expand a literal template 'tmpl' byte-string against one changeset
949 """Expand a literal template 'tmpl' byte-string against one changeset
928
950
929 Each props item must be a stringify-able value or a callable returning
951 Each props item must be a stringify-able value or a callable returning
930 such value, i.e. no bare list nor dict should be passed.
952 such value, i.e. no bare list nor dict should be passed.
931 """
953 """
932 repo = ctx.repo()
954 repo = ctx.repo()
933 tres = formatter.templateresources(repo.ui, repo)
955 tres = formatter.templateresources(repo.ui, repo)
934 t = formatter.maketemplater(repo.ui, tmpl, defaults=templatekw.keywords,
956 t = formatter.maketemplater(repo.ui, tmpl, defaults=templatekw.keywords,
935 resources=tres)
957 resources=tres)
936 mapping = {'ctx': ctx}
958 mapping = {'ctx': ctx}
937 if props:
959 if props:
938 mapping.update(props)
960 mapping.update(props)
939 return t.renderdefault(mapping)
961 return t.renderdefault(mapping)
940
962
941 def _buildfntemplate(pat, total=None, seqno=None, revwidth=None, pathname=None):
963 def _buildfntemplate(pat, total=None, seqno=None, revwidth=None, pathname=None):
942 r"""Convert old-style filename format string to template string
964 r"""Convert old-style filename format string to template string
943
965
944 >>> _buildfntemplate(b'foo-%b-%n.patch', seqno=0)
966 >>> _buildfntemplate(b'foo-%b-%n.patch', seqno=0)
945 'foo-{reporoot|basename}-{seqno}.patch'
967 'foo-{reporoot|basename}-{seqno}.patch'
946 >>> _buildfntemplate(b'%R{tags % "{tag}"}%H')
968 >>> _buildfntemplate(b'%R{tags % "{tag}"}%H')
947 '{rev}{tags % "{tag}"}{node}'
969 '{rev}{tags % "{tag}"}{node}'
948
970
949 '\' in outermost strings has to be escaped because it is a directory
971 '\' in outermost strings has to be escaped because it is a directory
950 separator on Windows:
972 separator on Windows:
951
973
952 >>> _buildfntemplate(b'c:\\tmp\\%R\\%n.patch', seqno=0)
974 >>> _buildfntemplate(b'c:\\tmp\\%R\\%n.patch', seqno=0)
953 'c:\\\\tmp\\\\{rev}\\\\{seqno}.patch'
975 'c:\\\\tmp\\\\{rev}\\\\{seqno}.patch'
954 >>> _buildfntemplate(b'\\\\foo\\bar.patch')
976 >>> _buildfntemplate(b'\\\\foo\\bar.patch')
955 '\\\\\\\\foo\\\\bar.patch'
977 '\\\\\\\\foo\\\\bar.patch'
956 >>> _buildfntemplate(b'\\{tags % "{tag}"}')
978 >>> _buildfntemplate(b'\\{tags % "{tag}"}')
957 '\\\\{tags % "{tag}"}'
979 '\\\\{tags % "{tag}"}'
958
980
959 but inner strings follow the template rules (i.e. '\' is taken as an
981 but inner strings follow the template rules (i.e. '\' is taken as an
960 escape character):
982 escape character):
961
983
962 >>> _buildfntemplate(br'{"c:\tmp"}', seqno=0)
984 >>> _buildfntemplate(br'{"c:\tmp"}', seqno=0)
963 '{"c:\\tmp"}'
985 '{"c:\\tmp"}'
964 """
986 """
965 expander = {
987 expander = {
966 b'H': b'{node}',
988 b'H': b'{node}',
967 b'R': b'{rev}',
989 b'R': b'{rev}',
968 b'h': b'{node|short}',
990 b'h': b'{node|short}',
969 b'm': br'{sub(r"[^\w]", "_", desc|firstline)}',
991 b'm': br'{sub(r"[^\w]", "_", desc|firstline)}',
970 b'r': b'{if(revwidth, pad(rev, revwidth, "0", left=True), rev)}',
992 b'r': b'{if(revwidth, pad(rev, revwidth, "0", left=True), rev)}',
971 b'%': b'%',
993 b'%': b'%',
972 b'b': b'{reporoot|basename}',
994 b'b': b'{reporoot|basename}',
973 }
995 }
974 if total is not None:
996 if total is not None:
975 expander[b'N'] = b'{total}'
997 expander[b'N'] = b'{total}'
976 if seqno is not None:
998 if seqno is not None:
977 expander[b'n'] = b'{seqno}'
999 expander[b'n'] = b'{seqno}'
978 if total is not None and seqno is not None:
1000 if total is not None and seqno is not None:
979 expander[b'n'] = b'{pad(seqno, total|stringify|count, "0", left=True)}'
1001 expander[b'n'] = b'{pad(seqno, total|stringify|count, "0", left=True)}'
980 if pathname is not None:
1002 if pathname is not None:
981 expander[b's'] = b'{pathname|basename}'
1003 expander[b's'] = b'{pathname|basename}'
982 expander[b'd'] = b'{if(pathname|dirname, pathname|dirname, ".")}'
1004 expander[b'd'] = b'{if(pathname|dirname, pathname|dirname, ".")}'
983 expander[b'p'] = b'{pathname}'
1005 expander[b'p'] = b'{pathname}'
984
1006
985 newname = []
1007 newname = []
986 for typ, start, end in templater.scantemplate(pat, raw=True):
1008 for typ, start, end in templater.scantemplate(pat, raw=True):
987 if typ != b'string':
1009 if typ != b'string':
988 newname.append(pat[start:end])
1010 newname.append(pat[start:end])
989 continue
1011 continue
990 i = start
1012 i = start
991 while i < end:
1013 while i < end:
992 n = pat.find(b'%', i, end)
1014 n = pat.find(b'%', i, end)
993 if n < 0:
1015 if n < 0:
994 newname.append(stringutil.escapestr(pat[i:end]))
1016 newname.append(stringutil.escapestr(pat[i:end]))
995 break
1017 break
996 newname.append(stringutil.escapestr(pat[i:n]))
1018 newname.append(stringutil.escapestr(pat[i:n]))
997 if n + 2 > end:
1019 if n + 2 > end:
998 raise error.Abort(_("incomplete format spec in output "
1020 raise error.Abort(_("incomplete format spec in output "
999 "filename"))
1021 "filename"))
1000 c = pat[n + 1:n + 2]
1022 c = pat[n + 1:n + 2]
1001 i = n + 2
1023 i = n + 2
1002 try:
1024 try:
1003 newname.append(expander[c])
1025 newname.append(expander[c])
1004 except KeyError:
1026 except KeyError:
1005 raise error.Abort(_("invalid format spec '%%%s' in output "
1027 raise error.Abort(_("invalid format spec '%%%s' in output "
1006 "filename") % c)
1028 "filename") % c)
1007 return ''.join(newname)
1029 return ''.join(newname)
1008
1030
1009 def makefilename(ctx, pat, **props):
1031 def makefilename(ctx, pat, **props):
1010 if not pat:
1032 if not pat:
1011 return pat
1033 return pat
1012 tmpl = _buildfntemplate(pat, **props)
1034 tmpl = _buildfntemplate(pat, **props)
1013 # BUG: alias expansion shouldn't be made against template fragments
1035 # BUG: alias expansion shouldn't be made against template fragments
1014 # rewritten from %-format strings, but we have no easy way to partially
1036 # rewritten from %-format strings, but we have no easy way to partially
1015 # disable the expansion.
1037 # disable the expansion.
1016 return rendertemplate(ctx, tmpl, pycompat.byteskwargs(props))
1038 return rendertemplate(ctx, tmpl, pycompat.byteskwargs(props))
1017
1039
1018 def isstdiofilename(pat):
1040 def isstdiofilename(pat):
1019 """True if the given pat looks like a filename denoting stdin/stdout"""
1041 """True if the given pat looks like a filename denoting stdin/stdout"""
1020 return not pat or pat == '-'
1042 return not pat or pat == '-'
1021
1043
1022 class _unclosablefile(object):
1044 class _unclosablefile(object):
1023 def __init__(self, fp):
1045 def __init__(self, fp):
1024 self._fp = fp
1046 self._fp = fp
1025
1047
1026 def close(self):
1048 def close(self):
1027 pass
1049 pass
1028
1050
1029 def __iter__(self):
1051 def __iter__(self):
1030 return iter(self._fp)
1052 return iter(self._fp)
1031
1053
1032 def __getattr__(self, attr):
1054 def __getattr__(self, attr):
1033 return getattr(self._fp, attr)
1055 return getattr(self._fp, attr)
1034
1056
1035 def __enter__(self):
1057 def __enter__(self):
1036 return self
1058 return self
1037
1059
1038 def __exit__(self, exc_type, exc_value, exc_tb):
1060 def __exit__(self, exc_type, exc_value, exc_tb):
1039 pass
1061 pass
1040
1062
1041 def makefileobj(ctx, pat, mode='wb', **props):
1063 def makefileobj(ctx, pat, mode='wb', **props):
1042 writable = mode not in ('r', 'rb')
1064 writable = mode not in ('r', 'rb')
1043
1065
1044 if isstdiofilename(pat):
1066 if isstdiofilename(pat):
1045 repo = ctx.repo()
1067 repo = ctx.repo()
1046 if writable:
1068 if writable:
1047 fp = repo.ui.fout
1069 fp = repo.ui.fout
1048 else:
1070 else:
1049 fp = repo.ui.fin
1071 fp = repo.ui.fin
1050 return _unclosablefile(fp)
1072 return _unclosablefile(fp)
1051 fn = makefilename(ctx, pat, **props)
1073 fn = makefilename(ctx, pat, **props)
1052 return open(fn, mode)
1074 return open(fn, mode)
1053
1075
1054 def openstorage(repo, cmd, file_, opts, returnrevlog=False):
1076 def openstorage(repo, cmd, file_, opts, returnrevlog=False):
1055 """opens the changelog, manifest, a filelog or a given revlog"""
1077 """opens the changelog, manifest, a filelog or a given revlog"""
1056 cl = opts['changelog']
1078 cl = opts['changelog']
1057 mf = opts['manifest']
1079 mf = opts['manifest']
1058 dir = opts['dir']
1080 dir = opts['dir']
1059 msg = None
1081 msg = None
1060 if cl and mf:
1082 if cl and mf:
1061 msg = _('cannot specify --changelog and --manifest at the same time')
1083 msg = _('cannot specify --changelog and --manifest at the same time')
1062 elif cl and dir:
1084 elif cl and dir:
1063 msg = _('cannot specify --changelog and --dir at the same time')
1085 msg = _('cannot specify --changelog and --dir at the same time')
1064 elif cl or mf or dir:
1086 elif cl or mf or dir:
1065 if file_:
1087 if file_:
1066 msg = _('cannot specify filename with --changelog or --manifest')
1088 msg = _('cannot specify filename with --changelog or --manifest')
1067 elif not repo:
1089 elif not repo:
1068 msg = _('cannot specify --changelog or --manifest or --dir '
1090 msg = _('cannot specify --changelog or --manifest or --dir '
1069 'without a repository')
1091 'without a repository')
1070 if msg:
1092 if msg:
1071 raise error.Abort(msg)
1093 raise error.Abort(msg)
1072
1094
1073 r = None
1095 r = None
1074 if repo:
1096 if repo:
1075 if cl:
1097 if cl:
1076 r = repo.unfiltered().changelog
1098 r = repo.unfiltered().changelog
1077 elif dir:
1099 elif dir:
1078 if 'treemanifest' not in repo.requirements:
1100 if 'treemanifest' not in repo.requirements:
1079 raise error.Abort(_("--dir can only be used on repos with "
1101 raise error.Abort(_("--dir can only be used on repos with "
1080 "treemanifest enabled"))
1102 "treemanifest enabled"))
1081 if not dir.endswith('/'):
1103 if not dir.endswith('/'):
1082 dir = dir + '/'
1104 dir = dir + '/'
1083 dirlog = repo.manifestlog.getstorage(dir)
1105 dirlog = repo.manifestlog.getstorage(dir)
1084 if len(dirlog):
1106 if len(dirlog):
1085 r = dirlog
1107 r = dirlog
1086 elif mf:
1108 elif mf:
1087 r = repo.manifestlog.getstorage(b'')
1109 r = repo.manifestlog.getstorage(b'')
1088 elif file_:
1110 elif file_:
1089 filelog = repo.file(file_)
1111 filelog = repo.file(file_)
1090 if len(filelog):
1112 if len(filelog):
1091 r = filelog
1113 r = filelog
1092
1114
1093 # Not all storage may be revlogs. If requested, try to return an actual
1115 # Not all storage may be revlogs. If requested, try to return an actual
1094 # revlog instance.
1116 # revlog instance.
1095 if returnrevlog:
1117 if returnrevlog:
1096 if isinstance(r, revlog.revlog):
1118 if isinstance(r, revlog.revlog):
1097 pass
1119 pass
1098 elif util.safehasattr(r, '_revlog'):
1120 elif util.safehasattr(r, '_revlog'):
1099 r = r._revlog
1121 r = r._revlog
1100 elif r is not None:
1122 elif r is not None:
1101 raise error.Abort(_('%r does not appear to be a revlog') % r)
1123 raise error.Abort(_('%r does not appear to be a revlog') % r)
1102
1124
1103 if not r:
1125 if not r:
1104 if not returnrevlog:
1126 if not returnrevlog:
1105 raise error.Abort(_('cannot give path to non-revlog'))
1127 raise error.Abort(_('cannot give path to non-revlog'))
1106
1128
1107 if not file_:
1129 if not file_:
1108 raise error.CommandError(cmd, _('invalid arguments'))
1130 raise error.CommandError(cmd, _('invalid arguments'))
1109 if not os.path.isfile(file_):
1131 if not os.path.isfile(file_):
1110 raise error.Abort(_("revlog '%s' not found") % file_)
1132 raise error.Abort(_("revlog '%s' not found") % file_)
1111 r = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False),
1133 r = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False),
1112 file_[:-2] + ".i")
1134 file_[:-2] + ".i")
1113 return r
1135 return r
1114
1136
1115 def openrevlog(repo, cmd, file_, opts):
1137 def openrevlog(repo, cmd, file_, opts):
1116 """Obtain a revlog backing storage of an item.
1138 """Obtain a revlog backing storage of an item.
1117
1139
1118 This is similar to ``openstorage()`` except it always returns a revlog.
1140 This is similar to ``openstorage()`` except it always returns a revlog.
1119
1141
1120 In most cases, a caller cares about the main storage object - not the
1142 In most cases, a caller cares about the main storage object - not the
1121 revlog backing it. Therefore, this function should only be used by code
1143 revlog backing it. Therefore, this function should only be used by code
1122 that needs to examine low-level revlog implementation details. e.g. debug
1144 that needs to examine low-level revlog implementation details. e.g. debug
1123 commands.
1145 commands.
1124 """
1146 """
1125 return openstorage(repo, cmd, file_, opts, returnrevlog=True)
1147 return openstorage(repo, cmd, file_, opts, returnrevlog=True)
1126
1148
1127 def copy(ui, repo, pats, opts, rename=False):
1149 def copy(ui, repo, pats, opts, rename=False):
1128 # called with the repo lock held
1150 # called with the repo lock held
1129 #
1151 #
1130 # hgsep => pathname that uses "/" to separate directories
1152 # hgsep => pathname that uses "/" to separate directories
1131 # ossep => pathname that uses os.sep to separate directories
1153 # ossep => pathname that uses os.sep to separate directories
1132 cwd = repo.getcwd()
1154 cwd = repo.getcwd()
1133 targets = {}
1155 targets = {}
1134 after = opts.get("after")
1156 after = opts.get("after")
1135 dryrun = opts.get("dry_run")
1157 dryrun = opts.get("dry_run")
1136 wctx = repo[None]
1158 wctx = repo[None]
1137
1159
1138 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
1160 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
1139 def walkpat(pat):
1161 def walkpat(pat):
1140 srcs = []
1162 srcs = []
1141 if after:
1163 if after:
1142 badstates = '?'
1164 badstates = '?'
1143 else:
1165 else:
1144 badstates = '?r'
1166 badstates = '?r'
1145 m = scmutil.match(wctx, [pat], opts, globbed=True)
1167 m = scmutil.match(wctx, [pat], opts, globbed=True)
1146 for abs in wctx.walk(m):
1168 for abs in wctx.walk(m):
1147 state = repo.dirstate[abs]
1169 state = repo.dirstate[abs]
1148 rel = uipathfn(abs)
1170 rel = uipathfn(abs)
1149 exact = m.exact(abs)
1171 exact = m.exact(abs)
1150 if state in badstates:
1172 if state in badstates:
1151 if exact and state == '?':
1173 if exact and state == '?':
1152 ui.warn(_('%s: not copying - file is not managed\n') % rel)
1174 ui.warn(_('%s: not copying - file is not managed\n') % rel)
1153 if exact and state == 'r':
1175 if exact and state == 'r':
1154 ui.warn(_('%s: not copying - file has been marked for'
1176 ui.warn(_('%s: not copying - file has been marked for'
1155 ' remove\n') % rel)
1177 ' remove\n') % rel)
1156 continue
1178 continue
1157 # abs: hgsep
1179 # abs: hgsep
1158 # rel: ossep
1180 # rel: ossep
1159 srcs.append((abs, rel, exact))
1181 srcs.append((abs, rel, exact))
1160 return srcs
1182 return srcs
1161
1183
1162 # abssrc: hgsep
1184 # abssrc: hgsep
1163 # relsrc: ossep
1185 # relsrc: ossep
1164 # otarget: ossep
1186 # otarget: ossep
1165 def copyfile(abssrc, relsrc, otarget, exact):
1187 def copyfile(abssrc, relsrc, otarget, exact):
1166 abstarget = pathutil.canonpath(repo.root, cwd, otarget)
1188 abstarget = pathutil.canonpath(repo.root, cwd, otarget)
1167 if '/' in abstarget:
1189 if '/' in abstarget:
1168 # We cannot normalize abstarget itself, this would prevent
1190 # We cannot normalize abstarget itself, this would prevent
1169 # case only renames, like a => A.
1191 # case only renames, like a => A.
1170 abspath, absname = abstarget.rsplit('/', 1)
1192 abspath, absname = abstarget.rsplit('/', 1)
1171 abstarget = repo.dirstate.normalize(abspath) + '/' + absname
1193 abstarget = repo.dirstate.normalize(abspath) + '/' + absname
1172 reltarget = repo.pathto(abstarget, cwd)
1194 reltarget = repo.pathto(abstarget, cwd)
1173 target = repo.wjoin(abstarget)
1195 target = repo.wjoin(abstarget)
1174 src = repo.wjoin(abssrc)
1196 src = repo.wjoin(abssrc)
1175 state = repo.dirstate[abstarget]
1197 state = repo.dirstate[abstarget]
1176
1198
1177 scmutil.checkportable(ui, abstarget)
1199 scmutil.checkportable(ui, abstarget)
1178
1200
1179 # check for collisions
1201 # check for collisions
1180 prevsrc = targets.get(abstarget)
1202 prevsrc = targets.get(abstarget)
1181 if prevsrc is not None:
1203 if prevsrc is not None:
1182 ui.warn(_('%s: not overwriting - %s collides with %s\n') %
1204 ui.warn(_('%s: not overwriting - %s collides with %s\n') %
1183 (reltarget, repo.pathto(abssrc, cwd),
1205 (reltarget, repo.pathto(abssrc, cwd),
1184 repo.pathto(prevsrc, cwd)))
1206 repo.pathto(prevsrc, cwd)))
1185 return True # report a failure
1207 return True # report a failure
1186
1208
1187 # check for overwrites
1209 # check for overwrites
1188 exists = os.path.lexists(target)
1210 exists = os.path.lexists(target)
1189 samefile = False
1211 samefile = False
1190 if exists and abssrc != abstarget:
1212 if exists and abssrc != abstarget:
1191 if (repo.dirstate.normalize(abssrc) ==
1213 if (repo.dirstate.normalize(abssrc) ==
1192 repo.dirstate.normalize(abstarget)):
1214 repo.dirstate.normalize(abstarget)):
1193 if not rename:
1215 if not rename:
1194 ui.warn(_("%s: can't copy - same file\n") % reltarget)
1216 ui.warn(_("%s: can't copy - same file\n") % reltarget)
1195 return True # report a failure
1217 return True # report a failure
1196 exists = False
1218 exists = False
1197 samefile = True
1219 samefile = True
1198
1220
1199 if not after and exists or after and state in 'mn':
1221 if not after and exists or after and state in 'mn':
1200 if not opts['force']:
1222 if not opts['force']:
1201 if state in 'mn':
1223 if state in 'mn':
1202 msg = _('%s: not overwriting - file already committed\n')
1224 msg = _('%s: not overwriting - file already committed\n')
1203 if after:
1225 if after:
1204 flags = '--after --force'
1226 flags = '--after --force'
1205 else:
1227 else:
1206 flags = '--force'
1228 flags = '--force'
1207 if rename:
1229 if rename:
1208 hint = _("('hg rename %s' to replace the file by "
1230 hint = _("('hg rename %s' to replace the file by "
1209 'recording a rename)\n') % flags
1231 'recording a rename)\n') % flags
1210 else:
1232 else:
1211 hint = _("('hg copy %s' to replace the file by "
1233 hint = _("('hg copy %s' to replace the file by "
1212 'recording a copy)\n') % flags
1234 'recording a copy)\n') % flags
1213 else:
1235 else:
1214 msg = _('%s: not overwriting - file exists\n')
1236 msg = _('%s: not overwriting - file exists\n')
1215 if rename:
1237 if rename:
1216 hint = _("('hg rename --after' to record the rename)\n")
1238 hint = _("('hg rename --after' to record the rename)\n")
1217 else:
1239 else:
1218 hint = _("('hg copy --after' to record the copy)\n")
1240 hint = _("('hg copy --after' to record the copy)\n")
1219 ui.warn(msg % reltarget)
1241 ui.warn(msg % reltarget)
1220 ui.warn(hint)
1242 ui.warn(hint)
1221 return True # report a failure
1243 return True # report a failure
1222
1244
1223 if after:
1245 if after:
1224 if not exists:
1246 if not exists:
1225 if rename:
1247 if rename:
1226 ui.warn(_('%s: not recording move - %s does not exist\n') %
1248 ui.warn(_('%s: not recording move - %s does not exist\n') %
1227 (relsrc, reltarget))
1249 (relsrc, reltarget))
1228 else:
1250 else:
1229 ui.warn(_('%s: not recording copy - %s does not exist\n') %
1251 ui.warn(_('%s: not recording copy - %s does not exist\n') %
1230 (relsrc, reltarget))
1252 (relsrc, reltarget))
1231 return True # report a failure
1253 return True # report a failure
1232 elif not dryrun:
1254 elif not dryrun:
1233 try:
1255 try:
1234 if exists:
1256 if exists:
1235 os.unlink(target)
1257 os.unlink(target)
1236 targetdir = os.path.dirname(target) or '.'
1258 targetdir = os.path.dirname(target) or '.'
1237 if not os.path.isdir(targetdir):
1259 if not os.path.isdir(targetdir):
1238 os.makedirs(targetdir)
1260 os.makedirs(targetdir)
1239 if samefile:
1261 if samefile:
1240 tmp = target + "~hgrename"
1262 tmp = target + "~hgrename"
1241 os.rename(src, tmp)
1263 os.rename(src, tmp)
1242 os.rename(tmp, target)
1264 os.rename(tmp, target)
1243 else:
1265 else:
1244 # Preserve stat info on renames, not on copies; this matches
1266 # Preserve stat info on renames, not on copies; this matches
1245 # Linux CLI behavior.
1267 # Linux CLI behavior.
1246 util.copyfile(src, target, copystat=rename)
1268 util.copyfile(src, target, copystat=rename)
1247 srcexists = True
1269 srcexists = True
1248 except IOError as inst:
1270 except IOError as inst:
1249 if inst.errno == errno.ENOENT:
1271 if inst.errno == errno.ENOENT:
1250 ui.warn(_('%s: deleted in working directory\n') % relsrc)
1272 ui.warn(_('%s: deleted in working directory\n') % relsrc)
1251 srcexists = False
1273 srcexists = False
1252 else:
1274 else:
1253 ui.warn(_('%s: cannot copy - %s\n') %
1275 ui.warn(_('%s: cannot copy - %s\n') %
1254 (relsrc, encoding.strtolocal(inst.strerror)))
1276 (relsrc, encoding.strtolocal(inst.strerror)))
1255 return True # report a failure
1277 return True # report a failure
1256
1278
1257 if ui.verbose or not exact:
1279 if ui.verbose or not exact:
1258 if rename:
1280 if rename:
1259 ui.status(_('moving %s to %s\n') % (relsrc, reltarget))
1281 ui.status(_('moving %s to %s\n') % (relsrc, reltarget))
1260 else:
1282 else:
1261 ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
1283 ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
1262
1284
1263 targets[abstarget] = abssrc
1285 targets[abstarget] = abssrc
1264
1286
1265 # fix up dirstate
1287 # fix up dirstate
1266 scmutil.dirstatecopy(ui, repo, wctx, abssrc, abstarget,
1288 scmutil.dirstatecopy(ui, repo, wctx, abssrc, abstarget,
1267 dryrun=dryrun, cwd=cwd)
1289 dryrun=dryrun, cwd=cwd)
1268 if rename and not dryrun:
1290 if rename and not dryrun:
1269 if not after and srcexists and not samefile:
1291 if not after and srcexists and not samefile:
1270 rmdir = repo.ui.configbool('experimental', 'removeemptydirs')
1292 rmdir = repo.ui.configbool('experimental', 'removeemptydirs')
1271 repo.wvfs.unlinkpath(abssrc, rmdir=rmdir)
1293 repo.wvfs.unlinkpath(abssrc, rmdir=rmdir)
1272 wctx.forget([abssrc])
1294 wctx.forget([abssrc])
1273
1295
1274 # pat: ossep
1296 # pat: ossep
1275 # dest ossep
1297 # dest ossep
1276 # srcs: list of (hgsep, hgsep, ossep, bool)
1298 # srcs: list of (hgsep, hgsep, ossep, bool)
1277 # return: function that takes hgsep and returns ossep
1299 # return: function that takes hgsep and returns ossep
1278 def targetpathfn(pat, dest, srcs):
1300 def targetpathfn(pat, dest, srcs):
1279 if os.path.isdir(pat):
1301 if os.path.isdir(pat):
1280 abspfx = pathutil.canonpath(repo.root, cwd, pat)
1302 abspfx = pathutil.canonpath(repo.root, cwd, pat)
1281 abspfx = util.localpath(abspfx)
1303 abspfx = util.localpath(abspfx)
1282 if destdirexists:
1304 if destdirexists:
1283 striplen = len(os.path.split(abspfx)[0])
1305 striplen = len(os.path.split(abspfx)[0])
1284 else:
1306 else:
1285 striplen = len(abspfx)
1307 striplen = len(abspfx)
1286 if striplen:
1308 if striplen:
1287 striplen += len(pycompat.ossep)
1309 striplen += len(pycompat.ossep)
1288 res = lambda p: os.path.join(dest, util.localpath(p)[striplen:])
1310 res = lambda p: os.path.join(dest, util.localpath(p)[striplen:])
1289 elif destdirexists:
1311 elif destdirexists:
1290 res = lambda p: os.path.join(dest,
1312 res = lambda p: os.path.join(dest,
1291 os.path.basename(util.localpath(p)))
1313 os.path.basename(util.localpath(p)))
1292 else:
1314 else:
1293 res = lambda p: dest
1315 res = lambda p: dest
1294 return res
1316 return res
1295
1317
1296 # pat: ossep
1318 # pat: ossep
1297 # dest ossep
1319 # dest ossep
1298 # srcs: list of (hgsep, hgsep, ossep, bool)
1320 # srcs: list of (hgsep, hgsep, ossep, bool)
1299 # return: function that takes hgsep and returns ossep
1321 # return: function that takes hgsep and returns ossep
1300 def targetpathafterfn(pat, dest, srcs):
1322 def targetpathafterfn(pat, dest, srcs):
1301 if matchmod.patkind(pat):
1323 if matchmod.patkind(pat):
1302 # a mercurial pattern
1324 # a mercurial pattern
1303 res = lambda p: os.path.join(dest,
1325 res = lambda p: os.path.join(dest,
1304 os.path.basename(util.localpath(p)))
1326 os.path.basename(util.localpath(p)))
1305 else:
1327 else:
1306 abspfx = pathutil.canonpath(repo.root, cwd, pat)
1328 abspfx = pathutil.canonpath(repo.root, cwd, pat)
1307 if len(abspfx) < len(srcs[0][0]):
1329 if len(abspfx) < len(srcs[0][0]):
1308 # A directory. Either the target path contains the last
1330 # A directory. Either the target path contains the last
1309 # component of the source path or it does not.
1331 # component of the source path or it does not.
1310 def evalpath(striplen):
1332 def evalpath(striplen):
1311 score = 0
1333 score = 0
1312 for s in srcs:
1334 for s in srcs:
1313 t = os.path.join(dest, util.localpath(s[0])[striplen:])
1335 t = os.path.join(dest, util.localpath(s[0])[striplen:])
1314 if os.path.lexists(t):
1336 if os.path.lexists(t):
1315 score += 1
1337 score += 1
1316 return score
1338 return score
1317
1339
1318 abspfx = util.localpath(abspfx)
1340 abspfx = util.localpath(abspfx)
1319 striplen = len(abspfx)
1341 striplen = len(abspfx)
1320 if striplen:
1342 if striplen:
1321 striplen += len(pycompat.ossep)
1343 striplen += len(pycompat.ossep)
1322 if os.path.isdir(os.path.join(dest, os.path.split(abspfx)[1])):
1344 if os.path.isdir(os.path.join(dest, os.path.split(abspfx)[1])):
1323 score = evalpath(striplen)
1345 score = evalpath(striplen)
1324 striplen1 = len(os.path.split(abspfx)[0])
1346 striplen1 = len(os.path.split(abspfx)[0])
1325 if striplen1:
1347 if striplen1:
1326 striplen1 += len(pycompat.ossep)
1348 striplen1 += len(pycompat.ossep)
1327 if evalpath(striplen1) > score:
1349 if evalpath(striplen1) > score:
1328 striplen = striplen1
1350 striplen = striplen1
1329 res = lambda p: os.path.join(dest,
1351 res = lambda p: os.path.join(dest,
1330 util.localpath(p)[striplen:])
1352 util.localpath(p)[striplen:])
1331 else:
1353 else:
1332 # a file
1354 # a file
1333 if destdirexists:
1355 if destdirexists:
1334 res = lambda p: os.path.join(dest,
1356 res = lambda p: os.path.join(dest,
1335 os.path.basename(util.localpath(p)))
1357 os.path.basename(util.localpath(p)))
1336 else:
1358 else:
1337 res = lambda p: dest
1359 res = lambda p: dest
1338 return res
1360 return res
1339
1361
1340 pats = scmutil.expandpats(pats)
1362 pats = scmutil.expandpats(pats)
1341 if not pats:
1363 if not pats:
1342 raise error.Abort(_('no source or destination specified'))
1364 raise error.Abort(_('no source or destination specified'))
1343 if len(pats) == 1:
1365 if len(pats) == 1:
1344 raise error.Abort(_('no destination specified'))
1366 raise error.Abort(_('no destination specified'))
1345 dest = pats.pop()
1367 dest = pats.pop()
1346 destdirexists = os.path.isdir(dest) and not os.path.islink(dest)
1368 destdirexists = os.path.isdir(dest) and not os.path.islink(dest)
1347 if not destdirexists:
1369 if not destdirexists:
1348 if len(pats) > 1 or matchmod.patkind(pats[0]):
1370 if len(pats) > 1 or matchmod.patkind(pats[0]):
1349 raise error.Abort(_('with multiple sources, destination must be an '
1371 raise error.Abort(_('with multiple sources, destination must be an '
1350 'existing directory'))
1372 'existing directory'))
1351 if util.endswithsep(dest):
1373 if util.endswithsep(dest):
1352 raise error.Abort(_('destination %s is not a directory') % dest)
1374 raise error.Abort(_('destination %s is not a directory') % dest)
1353
1375
1354 tfn = targetpathfn
1376 tfn = targetpathfn
1355 if after:
1377 if after:
1356 tfn = targetpathafterfn
1378 tfn = targetpathafterfn
1357 copylist = []
1379 copylist = []
1358 for pat in pats:
1380 for pat in pats:
1359 srcs = walkpat(pat)
1381 srcs = walkpat(pat)
1360 if not srcs:
1382 if not srcs:
1361 continue
1383 continue
1362 copylist.append((tfn(pat, dest, srcs), srcs))
1384 copylist.append((tfn(pat, dest, srcs), srcs))
1363 if not copylist:
1385 if not copylist:
1364 raise error.Abort(_('no files to copy'))
1386 raise error.Abort(_('no files to copy'))
1365
1387
1366 errors = 0
1388 errors = 0
1367 for targetpath, srcs in copylist:
1389 for targetpath, srcs in copylist:
1368 for abssrc, relsrc, exact in srcs:
1390 for abssrc, relsrc, exact in srcs:
1369 if copyfile(abssrc, relsrc, targetpath(abssrc), exact):
1391 if copyfile(abssrc, relsrc, targetpath(abssrc), exact):
1370 errors += 1
1392 errors += 1
1371
1393
1372 return errors != 0
1394 return errors != 0
1373
1395
1374 ## facility to let extension process additional data into an import patch
1396 ## facility to let extension process additional data into an import patch
1375 # list of identifier to be executed in order
1397 # list of identifier to be executed in order
1376 extrapreimport = [] # run before commit
1398 extrapreimport = [] # run before commit
1377 extrapostimport = [] # run after commit
1399 extrapostimport = [] # run after commit
1378 # mapping from identifier to actual import function
1400 # mapping from identifier to actual import function
1379 #
1401 #
1380 # 'preimport' are run before the commit is made and are provided the following
1402 # 'preimport' are run before the commit is made and are provided the following
1381 # arguments:
1403 # arguments:
1382 # - repo: the localrepository instance,
1404 # - repo: the localrepository instance,
1383 # - patchdata: data extracted from patch header (cf m.patch.patchheadermap),
1405 # - patchdata: data extracted from patch header (cf m.patch.patchheadermap),
1384 # - extra: the future extra dictionary of the changeset, please mutate it,
1406 # - extra: the future extra dictionary of the changeset, please mutate it,
1385 # - opts: the import options.
1407 # - opts: the import options.
1386 # XXX ideally, we would just pass an ctx ready to be computed, that would allow
1408 # XXX ideally, we would just pass an ctx ready to be computed, that would allow
1387 # mutation of in memory commit and more. Feel free to rework the code to get
1409 # mutation of in memory commit and more. Feel free to rework the code to get
1388 # there.
1410 # there.
1389 extrapreimportmap = {}
1411 extrapreimportmap = {}
1390 # 'postimport' are run after the commit is made and are provided the following
1412 # 'postimport' are run after the commit is made and are provided the following
1391 # argument:
1413 # argument:
1392 # - ctx: the changectx created by import.
1414 # - ctx: the changectx created by import.
1393 extrapostimportmap = {}
1415 extrapostimportmap = {}
1394
1416
1395 def tryimportone(ui, repo, patchdata, parents, opts, msgs, updatefunc):
1417 def tryimportone(ui, repo, patchdata, parents, opts, msgs, updatefunc):
1396 """Utility function used by commands.import to import a single patch
1418 """Utility function used by commands.import to import a single patch
1397
1419
1398 This function is explicitly defined here to help the evolve extension to
1420 This function is explicitly defined here to help the evolve extension to
1399 wrap this part of the import logic.
1421 wrap this part of the import logic.
1400
1422
1401 The API is currently a bit ugly because it a simple code translation from
1423 The API is currently a bit ugly because it a simple code translation from
1402 the import command. Feel free to make it better.
1424 the import command. Feel free to make it better.
1403
1425
1404 :patchdata: a dictionary containing parsed patch data (such as from
1426 :patchdata: a dictionary containing parsed patch data (such as from
1405 ``patch.extract()``)
1427 ``patch.extract()``)
1406 :parents: nodes that will be parent of the created commit
1428 :parents: nodes that will be parent of the created commit
1407 :opts: the full dict of option passed to the import command
1429 :opts: the full dict of option passed to the import command
1408 :msgs: list to save commit message to.
1430 :msgs: list to save commit message to.
1409 (used in case we need to save it when failing)
1431 (used in case we need to save it when failing)
1410 :updatefunc: a function that update a repo to a given node
1432 :updatefunc: a function that update a repo to a given node
1411 updatefunc(<repo>, <node>)
1433 updatefunc(<repo>, <node>)
1412 """
1434 """
1413 # avoid cycle context -> subrepo -> cmdutil
1435 # avoid cycle context -> subrepo -> cmdutil
1414 from . import context
1436 from . import context
1415
1437
1416 tmpname = patchdata.get('filename')
1438 tmpname = patchdata.get('filename')
1417 message = patchdata.get('message')
1439 message = patchdata.get('message')
1418 user = opts.get('user') or patchdata.get('user')
1440 user = opts.get('user') or patchdata.get('user')
1419 date = opts.get('date') or patchdata.get('date')
1441 date = opts.get('date') or patchdata.get('date')
1420 branch = patchdata.get('branch')
1442 branch = patchdata.get('branch')
1421 nodeid = patchdata.get('nodeid')
1443 nodeid = patchdata.get('nodeid')
1422 p1 = patchdata.get('p1')
1444 p1 = patchdata.get('p1')
1423 p2 = patchdata.get('p2')
1445 p2 = patchdata.get('p2')
1424
1446
1425 nocommit = opts.get('no_commit')
1447 nocommit = opts.get('no_commit')
1426 importbranch = opts.get('import_branch')
1448 importbranch = opts.get('import_branch')
1427 update = not opts.get('bypass')
1449 update = not opts.get('bypass')
1428 strip = opts["strip"]
1450 strip = opts["strip"]
1429 prefix = opts["prefix"]
1451 prefix = opts["prefix"]
1430 sim = float(opts.get('similarity') or 0)
1452 sim = float(opts.get('similarity') or 0)
1431
1453
1432 if not tmpname:
1454 if not tmpname:
1433 return None, None, False
1455 return None, None, False
1434
1456
1435 rejects = False
1457 rejects = False
1436
1458
1437 cmdline_message = logmessage(ui, opts)
1459 cmdline_message = logmessage(ui, opts)
1438 if cmdline_message:
1460 if cmdline_message:
1439 # pickup the cmdline msg
1461 # pickup the cmdline msg
1440 message = cmdline_message
1462 message = cmdline_message
1441 elif message:
1463 elif message:
1442 # pickup the patch msg
1464 # pickup the patch msg
1443 message = message.strip()
1465 message = message.strip()
1444 else:
1466 else:
1445 # launch the editor
1467 # launch the editor
1446 message = None
1468 message = None
1447 ui.debug('message:\n%s\n' % (message or ''))
1469 ui.debug('message:\n%s\n' % (message or ''))
1448
1470
1449 if len(parents) == 1:
1471 if len(parents) == 1:
1450 parents.append(repo[nullid])
1472 parents.append(repo[nullid])
1451 if opts.get('exact'):
1473 if opts.get('exact'):
1452 if not nodeid or not p1:
1474 if not nodeid or not p1:
1453 raise error.Abort(_('not a Mercurial patch'))
1475 raise error.Abort(_('not a Mercurial patch'))
1454 p1 = repo[p1]
1476 p1 = repo[p1]
1455 p2 = repo[p2 or nullid]
1477 p2 = repo[p2 or nullid]
1456 elif p2:
1478 elif p2:
1457 try:
1479 try:
1458 p1 = repo[p1]
1480 p1 = repo[p1]
1459 p2 = repo[p2]
1481 p2 = repo[p2]
1460 # Without any options, consider p2 only if the
1482 # Without any options, consider p2 only if the
1461 # patch is being applied on top of the recorded
1483 # patch is being applied on top of the recorded
1462 # first parent.
1484 # first parent.
1463 if p1 != parents[0]:
1485 if p1 != parents[0]:
1464 p1 = parents[0]
1486 p1 = parents[0]
1465 p2 = repo[nullid]
1487 p2 = repo[nullid]
1466 except error.RepoError:
1488 except error.RepoError:
1467 p1, p2 = parents
1489 p1, p2 = parents
1468 if p2.node() == nullid:
1490 if p2.node() == nullid:
1469 ui.warn(_("warning: import the patch as a normal revision\n"
1491 ui.warn(_("warning: import the patch as a normal revision\n"
1470 "(use --exact to import the patch as a merge)\n"))
1492 "(use --exact to import the patch as a merge)\n"))
1471 else:
1493 else:
1472 p1, p2 = parents
1494 p1, p2 = parents
1473
1495
1474 n = None
1496 n = None
1475 if update:
1497 if update:
1476 if p1 != parents[0]:
1498 if p1 != parents[0]:
1477 updatefunc(repo, p1.node())
1499 updatefunc(repo, p1.node())
1478 if p2 != parents[1]:
1500 if p2 != parents[1]:
1479 repo.setparents(p1.node(), p2.node())
1501 repo.setparents(p1.node(), p2.node())
1480
1502
1481 if opts.get('exact') or importbranch:
1503 if opts.get('exact') or importbranch:
1482 repo.dirstate.setbranch(branch or 'default')
1504 repo.dirstate.setbranch(branch or 'default')
1483
1505
1484 partial = opts.get('partial', False)
1506 partial = opts.get('partial', False)
1485 files = set()
1507 files = set()
1486 try:
1508 try:
1487 patch.patch(ui, repo, tmpname, strip=strip, prefix=prefix,
1509 patch.patch(ui, repo, tmpname, strip=strip, prefix=prefix,
1488 files=files, eolmode=None, similarity=sim / 100.0)
1510 files=files, eolmode=None, similarity=sim / 100.0)
1489 except error.PatchError as e:
1511 except error.PatchError as e:
1490 if not partial:
1512 if not partial:
1491 raise error.Abort(pycompat.bytestr(e))
1513 raise error.Abort(pycompat.bytestr(e))
1492 if partial:
1514 if partial:
1493 rejects = True
1515 rejects = True
1494
1516
1495 files = list(files)
1517 files = list(files)
1496 if nocommit:
1518 if nocommit:
1497 if message:
1519 if message:
1498 msgs.append(message)
1520 msgs.append(message)
1499 else:
1521 else:
1500 if opts.get('exact') or p2:
1522 if opts.get('exact') or p2:
1501 # If you got here, you either use --force and know what
1523 # If you got here, you either use --force and know what
1502 # you are doing or used --exact or a merge patch while
1524 # you are doing or used --exact or a merge patch while
1503 # being updated to its first parent.
1525 # being updated to its first parent.
1504 m = None
1526 m = None
1505 else:
1527 else:
1506 m = scmutil.matchfiles(repo, files or [])
1528 m = scmutil.matchfiles(repo, files or [])
1507 editform = mergeeditform(repo[None], 'import.normal')
1529 editform = mergeeditform(repo[None], 'import.normal')
1508 if opts.get('exact'):
1530 if opts.get('exact'):
1509 editor = None
1531 editor = None
1510 else:
1532 else:
1511 editor = getcommiteditor(editform=editform,
1533 editor = getcommiteditor(editform=editform,
1512 **pycompat.strkwargs(opts))
1534 **pycompat.strkwargs(opts))
1513 extra = {}
1535 extra = {}
1514 for idfunc in extrapreimport:
1536 for idfunc in extrapreimport:
1515 extrapreimportmap[idfunc](repo, patchdata, extra, opts)
1537 extrapreimportmap[idfunc](repo, patchdata, extra, opts)
1516 overrides = {}
1538 overrides = {}
1517 if partial:
1539 if partial:
1518 overrides[('ui', 'allowemptycommit')] = True
1540 overrides[('ui', 'allowemptycommit')] = True
1519 with repo.ui.configoverride(overrides, 'import'):
1541 with repo.ui.configoverride(overrides, 'import'):
1520 n = repo.commit(message, user,
1542 n = repo.commit(message, user,
1521 date, match=m,
1543 date, match=m,
1522 editor=editor, extra=extra)
1544 editor=editor, extra=extra)
1523 for idfunc in extrapostimport:
1545 for idfunc in extrapostimport:
1524 extrapostimportmap[idfunc](repo[n])
1546 extrapostimportmap[idfunc](repo[n])
1525 else:
1547 else:
1526 if opts.get('exact') or importbranch:
1548 if opts.get('exact') or importbranch:
1527 branch = branch or 'default'
1549 branch = branch or 'default'
1528 else:
1550 else:
1529 branch = p1.branch()
1551 branch = p1.branch()
1530 store = patch.filestore()
1552 store = patch.filestore()
1531 try:
1553 try:
1532 files = set()
1554 files = set()
1533 try:
1555 try:
1534 patch.patchrepo(ui, repo, p1, store, tmpname, strip, prefix,
1556 patch.patchrepo(ui, repo, p1, store, tmpname, strip, prefix,
1535 files, eolmode=None)
1557 files, eolmode=None)
1536 except error.PatchError as e:
1558 except error.PatchError as e:
1537 raise error.Abort(stringutil.forcebytestr(e))
1559 raise error.Abort(stringutil.forcebytestr(e))
1538 if opts.get('exact'):
1560 if opts.get('exact'):
1539 editor = None
1561 editor = None
1540 else:
1562 else:
1541 editor = getcommiteditor(editform='import.bypass')
1563 editor = getcommiteditor(editform='import.bypass')
1542 memctx = context.memctx(repo, (p1.node(), p2.node()),
1564 memctx = context.memctx(repo, (p1.node(), p2.node()),
1543 message,
1565 message,
1544 files=files,
1566 files=files,
1545 filectxfn=store,
1567 filectxfn=store,
1546 user=user,
1568 user=user,
1547 date=date,
1569 date=date,
1548 branch=branch,
1570 branch=branch,
1549 editor=editor)
1571 editor=editor)
1550 n = memctx.commit()
1572 n = memctx.commit()
1551 finally:
1573 finally:
1552 store.close()
1574 store.close()
1553 if opts.get('exact') and nocommit:
1575 if opts.get('exact') and nocommit:
1554 # --exact with --no-commit is still useful in that it does merge
1576 # --exact with --no-commit is still useful in that it does merge
1555 # and branch bits
1577 # and branch bits
1556 ui.warn(_("warning: can't check exact import with --no-commit\n"))
1578 ui.warn(_("warning: can't check exact import with --no-commit\n"))
1557 elif opts.get('exact') and (not n or hex(n) != nodeid):
1579 elif opts.get('exact') and (not n or hex(n) != nodeid):
1558 raise error.Abort(_('patch is damaged or loses information'))
1580 raise error.Abort(_('patch is damaged or loses information'))
1559 msg = _('applied to working directory')
1581 msg = _('applied to working directory')
1560 if n:
1582 if n:
1561 # i18n: refers to a short changeset id
1583 # i18n: refers to a short changeset id
1562 msg = _('created %s') % short(n)
1584 msg = _('created %s') % short(n)
1563 return msg, n, rejects
1585 return msg, n, rejects
1564
1586
1565 # facility to let extensions include additional data in an exported patch
1587 # facility to let extensions include additional data in an exported patch
1566 # list of identifiers to be executed in order
1588 # list of identifiers to be executed in order
1567 extraexport = []
1589 extraexport = []
1568 # mapping from identifier to actual export function
1590 # mapping from identifier to actual export function
1569 # function as to return a string to be added to the header or None
1591 # function as to return a string to be added to the header or None
1570 # it is given two arguments (sequencenumber, changectx)
1592 # it is given two arguments (sequencenumber, changectx)
1571 extraexportmap = {}
1593 extraexportmap = {}
1572
1594
1573 def _exportsingle(repo, ctx, fm, match, switch_parent, seqno, diffopts):
1595 def _exportsingle(repo, ctx, fm, match, switch_parent, seqno, diffopts):
1574 node = scmutil.binnode(ctx)
1596 node = scmutil.binnode(ctx)
1575 parents = [p.node() for p in ctx.parents() if p]
1597 parents = [p.node() for p in ctx.parents() if p]
1576 branch = ctx.branch()
1598 branch = ctx.branch()
1577 if switch_parent:
1599 if switch_parent:
1578 parents.reverse()
1600 parents.reverse()
1579
1601
1580 if parents:
1602 if parents:
1581 prev = parents[0]
1603 prev = parents[0]
1582 else:
1604 else:
1583 prev = nullid
1605 prev = nullid
1584
1606
1585 fm.context(ctx=ctx)
1607 fm.context(ctx=ctx)
1586 fm.plain('# HG changeset patch\n')
1608 fm.plain('# HG changeset patch\n')
1587 fm.write('user', '# User %s\n', ctx.user())
1609 fm.write('user', '# User %s\n', ctx.user())
1588 fm.plain('# Date %d %d\n' % ctx.date())
1610 fm.plain('# Date %d %d\n' % ctx.date())
1589 fm.write('date', '# %s\n', fm.formatdate(ctx.date()))
1611 fm.write('date', '# %s\n', fm.formatdate(ctx.date()))
1590 fm.condwrite(branch and branch != 'default',
1612 fm.condwrite(branch and branch != 'default',
1591 'branch', '# Branch %s\n', branch)
1613 'branch', '# Branch %s\n', branch)
1592 fm.write('node', '# Node ID %s\n', hex(node))
1614 fm.write('node', '# Node ID %s\n', hex(node))
1593 fm.plain('# Parent %s\n' % hex(prev))
1615 fm.plain('# Parent %s\n' % hex(prev))
1594 if len(parents) > 1:
1616 if len(parents) > 1:
1595 fm.plain('# Parent %s\n' % hex(parents[1]))
1617 fm.plain('# Parent %s\n' % hex(parents[1]))
1596 fm.data(parents=fm.formatlist(pycompat.maplist(hex, parents), name='node'))
1618 fm.data(parents=fm.formatlist(pycompat.maplist(hex, parents), name='node'))
1597
1619
1598 # TODO: redesign extraexportmap function to support formatter
1620 # TODO: redesign extraexportmap function to support formatter
1599 for headerid in extraexport:
1621 for headerid in extraexport:
1600 header = extraexportmap[headerid](seqno, ctx)
1622 header = extraexportmap[headerid](seqno, ctx)
1601 if header is not None:
1623 if header is not None:
1602 fm.plain('# %s\n' % header)
1624 fm.plain('# %s\n' % header)
1603
1625
1604 fm.write('desc', '%s\n', ctx.description().rstrip())
1626 fm.write('desc', '%s\n', ctx.description().rstrip())
1605 fm.plain('\n')
1627 fm.plain('\n')
1606
1628
1607 if fm.isplain():
1629 if fm.isplain():
1608 chunkiter = patch.diffui(repo, prev, node, match, opts=diffopts)
1630 chunkiter = patch.diffui(repo, prev, node, match, opts=diffopts)
1609 for chunk, label in chunkiter:
1631 for chunk, label in chunkiter:
1610 fm.plain(chunk, label=label)
1632 fm.plain(chunk, label=label)
1611 else:
1633 else:
1612 chunkiter = patch.diff(repo, prev, node, match, opts=diffopts)
1634 chunkiter = patch.diff(repo, prev, node, match, opts=diffopts)
1613 # TODO: make it structured?
1635 # TODO: make it structured?
1614 fm.data(diff=b''.join(chunkiter))
1636 fm.data(diff=b''.join(chunkiter))
1615
1637
1616 def _exportfile(repo, revs, fm, dest, switch_parent, diffopts, match):
1638 def _exportfile(repo, revs, fm, dest, switch_parent, diffopts, match):
1617 """Export changesets to stdout or a single file"""
1639 """Export changesets to stdout or a single file"""
1618 for seqno, rev in enumerate(revs, 1):
1640 for seqno, rev in enumerate(revs, 1):
1619 ctx = repo[rev]
1641 ctx = repo[rev]
1620 if not dest.startswith('<'):
1642 if not dest.startswith('<'):
1621 repo.ui.note("%s\n" % dest)
1643 repo.ui.note("%s\n" % dest)
1622 fm.startitem()
1644 fm.startitem()
1623 _exportsingle(repo, ctx, fm, match, switch_parent, seqno, diffopts)
1645 _exportsingle(repo, ctx, fm, match, switch_parent, seqno, diffopts)
1624
1646
1625 def _exportfntemplate(repo, revs, basefm, fntemplate, switch_parent, diffopts,
1647 def _exportfntemplate(repo, revs, basefm, fntemplate, switch_parent, diffopts,
1626 match):
1648 match):
1627 """Export changesets to possibly multiple files"""
1649 """Export changesets to possibly multiple files"""
1628 total = len(revs)
1650 total = len(revs)
1629 revwidth = max(len(str(rev)) for rev in revs)
1651 revwidth = max(len(str(rev)) for rev in revs)
1630 filemap = util.sortdict() # filename: [(seqno, rev), ...]
1652 filemap = util.sortdict() # filename: [(seqno, rev), ...]
1631
1653
1632 for seqno, rev in enumerate(revs, 1):
1654 for seqno, rev in enumerate(revs, 1):
1633 ctx = repo[rev]
1655 ctx = repo[rev]
1634 dest = makefilename(ctx, fntemplate,
1656 dest = makefilename(ctx, fntemplate,
1635 total=total, seqno=seqno, revwidth=revwidth)
1657 total=total, seqno=seqno, revwidth=revwidth)
1636 filemap.setdefault(dest, []).append((seqno, rev))
1658 filemap.setdefault(dest, []).append((seqno, rev))
1637
1659
1638 for dest in filemap:
1660 for dest in filemap:
1639 with formatter.maybereopen(basefm, dest) as fm:
1661 with formatter.maybereopen(basefm, dest) as fm:
1640 repo.ui.note("%s\n" % dest)
1662 repo.ui.note("%s\n" % dest)
1641 for seqno, rev in filemap[dest]:
1663 for seqno, rev in filemap[dest]:
1642 fm.startitem()
1664 fm.startitem()
1643 ctx = repo[rev]
1665 ctx = repo[rev]
1644 _exportsingle(repo, ctx, fm, match, switch_parent, seqno,
1666 _exportsingle(repo, ctx, fm, match, switch_parent, seqno,
1645 diffopts)
1667 diffopts)
1646
1668
1647 def export(repo, revs, basefm, fntemplate='hg-%h.patch', switch_parent=False,
1669 def export(repo, revs, basefm, fntemplate='hg-%h.patch', switch_parent=False,
1648 opts=None, match=None):
1670 opts=None, match=None):
1649 '''export changesets as hg patches
1671 '''export changesets as hg patches
1650
1672
1651 Args:
1673 Args:
1652 repo: The repository from which we're exporting revisions.
1674 repo: The repository from which we're exporting revisions.
1653 revs: A list of revisions to export as revision numbers.
1675 revs: A list of revisions to export as revision numbers.
1654 basefm: A formatter to which patches should be written.
1676 basefm: A formatter to which patches should be written.
1655 fntemplate: An optional string to use for generating patch file names.
1677 fntemplate: An optional string to use for generating patch file names.
1656 switch_parent: If True, show diffs against second parent when not nullid.
1678 switch_parent: If True, show diffs against second parent when not nullid.
1657 Default is false, which always shows diff against p1.
1679 Default is false, which always shows diff against p1.
1658 opts: diff options to use for generating the patch.
1680 opts: diff options to use for generating the patch.
1659 match: If specified, only export changes to files matching this matcher.
1681 match: If specified, only export changes to files matching this matcher.
1660
1682
1661 Returns:
1683 Returns:
1662 Nothing.
1684 Nothing.
1663
1685
1664 Side Effect:
1686 Side Effect:
1665 "HG Changeset Patch" data is emitted to one of the following
1687 "HG Changeset Patch" data is emitted to one of the following
1666 destinations:
1688 destinations:
1667 fntemplate specified: Each rev is written to a unique file named using
1689 fntemplate specified: Each rev is written to a unique file named using
1668 the given template.
1690 the given template.
1669 Otherwise: All revs will be written to basefm.
1691 Otherwise: All revs will be written to basefm.
1670 '''
1692 '''
1671 scmutil.prefetchfiles(repo, revs, match)
1693 scmutil.prefetchfiles(repo, revs, match)
1672
1694
1673 if not fntemplate:
1695 if not fntemplate:
1674 _exportfile(repo, revs, basefm, '<unnamed>', switch_parent, opts, match)
1696 _exportfile(repo, revs, basefm, '<unnamed>', switch_parent, opts, match)
1675 else:
1697 else:
1676 _exportfntemplate(repo, revs, basefm, fntemplate, switch_parent, opts,
1698 _exportfntemplate(repo, revs, basefm, fntemplate, switch_parent, opts,
1677 match)
1699 match)
1678
1700
1679 def exportfile(repo, revs, fp, switch_parent=False, opts=None, match=None):
1701 def exportfile(repo, revs, fp, switch_parent=False, opts=None, match=None):
1680 """Export changesets to the given file stream"""
1702 """Export changesets to the given file stream"""
1681 scmutil.prefetchfiles(repo, revs, match)
1703 scmutil.prefetchfiles(repo, revs, match)
1682
1704
1683 dest = getattr(fp, 'name', '<unnamed>')
1705 dest = getattr(fp, 'name', '<unnamed>')
1684 with formatter.formatter(repo.ui, fp, 'export', {}) as fm:
1706 with formatter.formatter(repo.ui, fp, 'export', {}) as fm:
1685 _exportfile(repo, revs, fm, dest, switch_parent, opts, match)
1707 _exportfile(repo, revs, fm, dest, switch_parent, opts, match)
1686
1708
1687 def showmarker(fm, marker, index=None):
1709 def showmarker(fm, marker, index=None):
1688 """utility function to display obsolescence marker in a readable way
1710 """utility function to display obsolescence marker in a readable way
1689
1711
1690 To be used by debug function."""
1712 To be used by debug function."""
1691 if index is not None:
1713 if index is not None:
1692 fm.write('index', '%i ', index)
1714 fm.write('index', '%i ', index)
1693 fm.write('prednode', '%s ', hex(marker.prednode()))
1715 fm.write('prednode', '%s ', hex(marker.prednode()))
1694 succs = marker.succnodes()
1716 succs = marker.succnodes()
1695 fm.condwrite(succs, 'succnodes', '%s ',
1717 fm.condwrite(succs, 'succnodes', '%s ',
1696 fm.formatlist(map(hex, succs), name='node'))
1718 fm.formatlist(map(hex, succs), name='node'))
1697 fm.write('flag', '%X ', marker.flags())
1719 fm.write('flag', '%X ', marker.flags())
1698 parents = marker.parentnodes()
1720 parents = marker.parentnodes()
1699 if parents is not None:
1721 if parents is not None:
1700 fm.write('parentnodes', '{%s} ',
1722 fm.write('parentnodes', '{%s} ',
1701 fm.formatlist(map(hex, parents), name='node', sep=', '))
1723 fm.formatlist(map(hex, parents), name='node', sep=', '))
1702 fm.write('date', '(%s) ', fm.formatdate(marker.date()))
1724 fm.write('date', '(%s) ', fm.formatdate(marker.date()))
1703 meta = marker.metadata().copy()
1725 meta = marker.metadata().copy()
1704 meta.pop('date', None)
1726 meta.pop('date', None)
1705 smeta = pycompat.rapply(pycompat.maybebytestr, meta)
1727 smeta = pycompat.rapply(pycompat.maybebytestr, meta)
1706 fm.write('metadata', '{%s}', fm.formatdict(smeta, fmt='%r: %r', sep=', '))
1728 fm.write('metadata', '{%s}', fm.formatdict(smeta, fmt='%r: %r', sep=', '))
1707 fm.plain('\n')
1729 fm.plain('\n')
1708
1730
1709 def finddate(ui, repo, date):
1731 def finddate(ui, repo, date):
1710 """Find the tipmost changeset that matches the given date spec"""
1732 """Find the tipmost changeset that matches the given date spec"""
1711
1733
1712 df = dateutil.matchdate(date)
1734 df = dateutil.matchdate(date)
1713 m = scmutil.matchall(repo)
1735 m = scmutil.matchall(repo)
1714 results = {}
1736 results = {}
1715
1737
1716 def prep(ctx, fns):
1738 def prep(ctx, fns):
1717 d = ctx.date()
1739 d = ctx.date()
1718 if df(d[0]):
1740 if df(d[0]):
1719 results[ctx.rev()] = d
1741 results[ctx.rev()] = d
1720
1742
1721 for ctx in walkchangerevs(repo, m, {'rev': None}, prep):
1743 for ctx in walkchangerevs(repo, m, {'rev': None}, prep):
1722 rev = ctx.rev()
1744 rev = ctx.rev()
1723 if rev in results:
1745 if rev in results:
1724 ui.status(_("found revision %s from %s\n") %
1746 ui.status(_("found revision %s from %s\n") %
1725 (rev, dateutil.datestr(results[rev])))
1747 (rev, dateutil.datestr(results[rev])))
1726 return '%d' % rev
1748 return '%d' % rev
1727
1749
1728 raise error.Abort(_("revision matching date not found"))
1750 raise error.Abort(_("revision matching date not found"))
1729
1751
1730 def increasingwindows(windowsize=8, sizelimit=512):
1752 def increasingwindows(windowsize=8, sizelimit=512):
1731 while True:
1753 while True:
1732 yield windowsize
1754 yield windowsize
1733 if windowsize < sizelimit:
1755 if windowsize < sizelimit:
1734 windowsize *= 2
1756 windowsize *= 2
1735
1757
1736 def _walkrevs(repo, opts):
1758 def _walkrevs(repo, opts):
1737 # Default --rev value depends on --follow but --follow behavior
1759 # Default --rev value depends on --follow but --follow behavior
1738 # depends on revisions resolved from --rev...
1760 # depends on revisions resolved from --rev...
1739 follow = opts.get('follow') or opts.get('follow_first')
1761 follow = opts.get('follow') or opts.get('follow_first')
1740 if opts.get('rev'):
1762 if opts.get('rev'):
1741 revs = scmutil.revrange(repo, opts['rev'])
1763 revs = scmutil.revrange(repo, opts['rev'])
1742 elif follow and repo.dirstate.p1() == nullid:
1764 elif follow and repo.dirstate.p1() == nullid:
1743 revs = smartset.baseset()
1765 revs = smartset.baseset()
1744 elif follow:
1766 elif follow:
1745 revs = repo.revs('reverse(:.)')
1767 revs = repo.revs('reverse(:.)')
1746 else:
1768 else:
1747 revs = smartset.spanset(repo)
1769 revs = smartset.spanset(repo)
1748 revs.reverse()
1770 revs.reverse()
1749 return revs
1771 return revs
1750
1772
1751 class FileWalkError(Exception):
1773 class FileWalkError(Exception):
1752 pass
1774 pass
1753
1775
1754 def walkfilerevs(repo, match, follow, revs, fncache):
1776 def walkfilerevs(repo, match, follow, revs, fncache):
1755 '''Walks the file history for the matched files.
1777 '''Walks the file history for the matched files.
1756
1778
1757 Returns the changeset revs that are involved in the file history.
1779 Returns the changeset revs that are involved in the file history.
1758
1780
1759 Throws FileWalkError if the file history can't be walked using
1781 Throws FileWalkError if the file history can't be walked using
1760 filelogs alone.
1782 filelogs alone.
1761 '''
1783 '''
1762 wanted = set()
1784 wanted = set()
1763 copies = []
1785 copies = []
1764 minrev, maxrev = min(revs), max(revs)
1786 minrev, maxrev = min(revs), max(revs)
1765 def filerevs(filelog, last):
1787 def filerevs(filelog, last):
1766 """
1788 """
1767 Only files, no patterns. Check the history of each file.
1789 Only files, no patterns. Check the history of each file.
1768
1790
1769 Examines filelog entries within minrev, maxrev linkrev range
1791 Examines filelog entries within minrev, maxrev linkrev range
1770 Returns an iterator yielding (linkrev, parentlinkrevs, copied)
1792 Returns an iterator yielding (linkrev, parentlinkrevs, copied)
1771 tuples in backwards order
1793 tuples in backwards order
1772 """
1794 """
1773 cl_count = len(repo)
1795 cl_count = len(repo)
1774 revs = []
1796 revs = []
1775 for j in pycompat.xrange(0, last + 1):
1797 for j in pycompat.xrange(0, last + 1):
1776 linkrev = filelog.linkrev(j)
1798 linkrev = filelog.linkrev(j)
1777 if linkrev < minrev:
1799 if linkrev < minrev:
1778 continue
1800 continue
1779 # only yield rev for which we have the changelog, it can
1801 # only yield rev for which we have the changelog, it can
1780 # happen while doing "hg log" during a pull or commit
1802 # happen while doing "hg log" during a pull or commit
1781 if linkrev >= cl_count:
1803 if linkrev >= cl_count:
1782 break
1804 break
1783
1805
1784 parentlinkrevs = []
1806 parentlinkrevs = []
1785 for p in filelog.parentrevs(j):
1807 for p in filelog.parentrevs(j):
1786 if p != nullrev:
1808 if p != nullrev:
1787 parentlinkrevs.append(filelog.linkrev(p))
1809 parentlinkrevs.append(filelog.linkrev(p))
1788 n = filelog.node(j)
1810 n = filelog.node(j)
1789 revs.append((linkrev, parentlinkrevs,
1811 revs.append((linkrev, parentlinkrevs,
1790 follow and filelog.renamed(n)))
1812 follow and filelog.renamed(n)))
1791
1813
1792 return reversed(revs)
1814 return reversed(revs)
1793 def iterfiles():
1815 def iterfiles():
1794 pctx = repo['.']
1816 pctx = repo['.']
1795 for filename in match.files():
1817 for filename in match.files():
1796 if follow:
1818 if follow:
1797 if filename not in pctx:
1819 if filename not in pctx:
1798 raise error.Abort(_('cannot follow file not in parent '
1820 raise error.Abort(_('cannot follow file not in parent '
1799 'revision: "%s"') % filename)
1821 'revision: "%s"') % filename)
1800 yield filename, pctx[filename].filenode()
1822 yield filename, pctx[filename].filenode()
1801 else:
1823 else:
1802 yield filename, None
1824 yield filename, None
1803 for filename_node in copies:
1825 for filename_node in copies:
1804 yield filename_node
1826 yield filename_node
1805
1827
1806 for file_, node in iterfiles():
1828 for file_, node in iterfiles():
1807 filelog = repo.file(file_)
1829 filelog = repo.file(file_)
1808 if not len(filelog):
1830 if not len(filelog):
1809 if node is None:
1831 if node is None:
1810 # A zero count may be a directory or deleted file, so
1832 # A zero count may be a directory or deleted file, so
1811 # try to find matching entries on the slow path.
1833 # try to find matching entries on the slow path.
1812 if follow:
1834 if follow:
1813 raise error.Abort(
1835 raise error.Abort(
1814 _('cannot follow nonexistent file: "%s"') % file_)
1836 _('cannot follow nonexistent file: "%s"') % file_)
1815 raise FileWalkError("Cannot walk via filelog")
1837 raise FileWalkError("Cannot walk via filelog")
1816 else:
1838 else:
1817 continue
1839 continue
1818
1840
1819 if node is None:
1841 if node is None:
1820 last = len(filelog) - 1
1842 last = len(filelog) - 1
1821 else:
1843 else:
1822 last = filelog.rev(node)
1844 last = filelog.rev(node)
1823
1845
1824 # keep track of all ancestors of the file
1846 # keep track of all ancestors of the file
1825 ancestors = {filelog.linkrev(last)}
1847 ancestors = {filelog.linkrev(last)}
1826
1848
1827 # iterate from latest to oldest revision
1849 # iterate from latest to oldest revision
1828 for rev, flparentlinkrevs, copied in filerevs(filelog, last):
1850 for rev, flparentlinkrevs, copied in filerevs(filelog, last):
1829 if not follow:
1851 if not follow:
1830 if rev > maxrev:
1852 if rev > maxrev:
1831 continue
1853 continue
1832 else:
1854 else:
1833 # Note that last might not be the first interesting
1855 # Note that last might not be the first interesting
1834 # rev to us:
1856 # rev to us:
1835 # if the file has been changed after maxrev, we'll
1857 # if the file has been changed after maxrev, we'll
1836 # have linkrev(last) > maxrev, and we still need
1858 # have linkrev(last) > maxrev, and we still need
1837 # to explore the file graph
1859 # to explore the file graph
1838 if rev not in ancestors:
1860 if rev not in ancestors:
1839 continue
1861 continue
1840 # XXX insert 1327 fix here
1862 # XXX insert 1327 fix here
1841 if flparentlinkrevs:
1863 if flparentlinkrevs:
1842 ancestors.update(flparentlinkrevs)
1864 ancestors.update(flparentlinkrevs)
1843
1865
1844 fncache.setdefault(rev, []).append(file_)
1866 fncache.setdefault(rev, []).append(file_)
1845 wanted.add(rev)
1867 wanted.add(rev)
1846 if copied:
1868 if copied:
1847 copies.append(copied)
1869 copies.append(copied)
1848
1870
1849 return wanted
1871 return wanted
1850
1872
1851 class _followfilter(object):
1873 class _followfilter(object):
1852 def __init__(self, repo, onlyfirst=False):
1874 def __init__(self, repo, onlyfirst=False):
1853 self.repo = repo
1875 self.repo = repo
1854 self.startrev = nullrev
1876 self.startrev = nullrev
1855 self.roots = set()
1877 self.roots = set()
1856 self.onlyfirst = onlyfirst
1878 self.onlyfirst = onlyfirst
1857
1879
1858 def match(self, rev):
1880 def match(self, rev):
1859 def realparents(rev):
1881 def realparents(rev):
1860 if self.onlyfirst:
1882 if self.onlyfirst:
1861 return self.repo.changelog.parentrevs(rev)[0:1]
1883 return self.repo.changelog.parentrevs(rev)[0:1]
1862 else:
1884 else:
1863 return filter(lambda x: x != nullrev,
1885 return filter(lambda x: x != nullrev,
1864 self.repo.changelog.parentrevs(rev))
1886 self.repo.changelog.parentrevs(rev))
1865
1887
1866 if self.startrev == nullrev:
1888 if self.startrev == nullrev:
1867 self.startrev = rev
1889 self.startrev = rev
1868 return True
1890 return True
1869
1891
1870 if rev > self.startrev:
1892 if rev > self.startrev:
1871 # forward: all descendants
1893 # forward: all descendants
1872 if not self.roots:
1894 if not self.roots:
1873 self.roots.add(self.startrev)
1895 self.roots.add(self.startrev)
1874 for parent in realparents(rev):
1896 for parent in realparents(rev):
1875 if parent in self.roots:
1897 if parent in self.roots:
1876 self.roots.add(rev)
1898 self.roots.add(rev)
1877 return True
1899 return True
1878 else:
1900 else:
1879 # backwards: all parents
1901 # backwards: all parents
1880 if not self.roots:
1902 if not self.roots:
1881 self.roots.update(realparents(self.startrev))
1903 self.roots.update(realparents(self.startrev))
1882 if rev in self.roots:
1904 if rev in self.roots:
1883 self.roots.remove(rev)
1905 self.roots.remove(rev)
1884 self.roots.update(realparents(rev))
1906 self.roots.update(realparents(rev))
1885 return True
1907 return True
1886
1908
1887 return False
1909 return False
1888
1910
1889 def walkchangerevs(repo, match, opts, prepare):
1911 def walkchangerevs(repo, match, opts, prepare):
1890 '''Iterate over files and the revs in which they changed.
1912 '''Iterate over files and the revs in which they changed.
1891
1913
1892 Callers most commonly need to iterate backwards over the history
1914 Callers most commonly need to iterate backwards over the history
1893 in which they are interested. Doing so has awful (quadratic-looking)
1915 in which they are interested. Doing so has awful (quadratic-looking)
1894 performance, so we use iterators in a "windowed" way.
1916 performance, so we use iterators in a "windowed" way.
1895
1917
1896 We walk a window of revisions in the desired order. Within the
1918 We walk a window of revisions in the desired order. Within the
1897 window, we first walk forwards to gather data, then in the desired
1919 window, we first walk forwards to gather data, then in the desired
1898 order (usually backwards) to display it.
1920 order (usually backwards) to display it.
1899
1921
1900 This function returns an iterator yielding contexts. Before
1922 This function returns an iterator yielding contexts. Before
1901 yielding each context, the iterator will first call the prepare
1923 yielding each context, the iterator will first call the prepare
1902 function on each context in the window in forward order.'''
1924 function on each context in the window in forward order.'''
1903
1925
1904 allfiles = opts.get('all_files')
1926 allfiles = opts.get('all_files')
1905 follow = opts.get('follow') or opts.get('follow_first')
1927 follow = opts.get('follow') or opts.get('follow_first')
1906 revs = _walkrevs(repo, opts)
1928 revs = _walkrevs(repo, opts)
1907 if not revs:
1929 if not revs:
1908 return []
1930 return []
1909 wanted = set()
1931 wanted = set()
1910 slowpath = match.anypats() or (not match.always() and opts.get('removed'))
1932 slowpath = match.anypats() or (not match.always() and opts.get('removed'))
1911 fncache = {}
1933 fncache = {}
1912 change = repo.__getitem__
1934 change = repo.__getitem__
1913
1935
1914 # First step is to fill wanted, the set of revisions that we want to yield.
1936 # First step is to fill wanted, the set of revisions that we want to yield.
1915 # When it does not induce extra cost, we also fill fncache for revisions in
1937 # When it does not induce extra cost, we also fill fncache for revisions in
1916 # wanted: a cache of filenames that were changed (ctx.files()) and that
1938 # wanted: a cache of filenames that were changed (ctx.files()) and that
1917 # match the file filtering conditions.
1939 # match the file filtering conditions.
1918
1940
1919 if match.always() or allfiles:
1941 if match.always() or allfiles:
1920 # No files, no patterns. Display all revs.
1942 # No files, no patterns. Display all revs.
1921 wanted = revs
1943 wanted = revs
1922 elif not slowpath:
1944 elif not slowpath:
1923 # We only have to read through the filelog to find wanted revisions
1945 # We only have to read through the filelog to find wanted revisions
1924
1946
1925 try:
1947 try:
1926 wanted = walkfilerevs(repo, match, follow, revs, fncache)
1948 wanted = walkfilerevs(repo, match, follow, revs, fncache)
1927 except FileWalkError:
1949 except FileWalkError:
1928 slowpath = True
1950 slowpath = True
1929
1951
1930 # We decided to fall back to the slowpath because at least one
1952 # We decided to fall back to the slowpath because at least one
1931 # of the paths was not a file. Check to see if at least one of them
1953 # of the paths was not a file. Check to see if at least one of them
1932 # existed in history, otherwise simply return
1954 # existed in history, otherwise simply return
1933 for path in match.files():
1955 for path in match.files():
1934 if path == '.' or path in repo.store:
1956 if path == '.' or path in repo.store:
1935 break
1957 break
1936 else:
1958 else:
1937 return []
1959 return []
1938
1960
1939 if slowpath:
1961 if slowpath:
1940 # We have to read the changelog to match filenames against
1962 # We have to read the changelog to match filenames against
1941 # changed files
1963 # changed files
1942
1964
1943 if follow:
1965 if follow:
1944 raise error.Abort(_('can only follow copies/renames for explicit '
1966 raise error.Abort(_('can only follow copies/renames for explicit '
1945 'filenames'))
1967 'filenames'))
1946
1968
1947 # The slow path checks files modified in every changeset.
1969 # The slow path checks files modified in every changeset.
1948 # This is really slow on large repos, so compute the set lazily.
1970 # This is really slow on large repos, so compute the set lazily.
1949 class lazywantedset(object):
1971 class lazywantedset(object):
1950 def __init__(self):
1972 def __init__(self):
1951 self.set = set()
1973 self.set = set()
1952 self.revs = set(revs)
1974 self.revs = set(revs)
1953
1975
1954 # No need to worry about locality here because it will be accessed
1976 # No need to worry about locality here because it will be accessed
1955 # in the same order as the increasing window below.
1977 # in the same order as the increasing window below.
1956 def __contains__(self, value):
1978 def __contains__(self, value):
1957 if value in self.set:
1979 if value in self.set:
1958 return True
1980 return True
1959 elif not value in self.revs:
1981 elif not value in self.revs:
1960 return False
1982 return False
1961 else:
1983 else:
1962 self.revs.discard(value)
1984 self.revs.discard(value)
1963 ctx = change(value)
1985 ctx = change(value)
1964 if allfiles:
1986 if allfiles:
1965 matches = list(ctx.manifest().walk(match))
1987 matches = list(ctx.manifest().walk(match))
1966 else:
1988 else:
1967 matches = [f for f in ctx.files() if match(f)]
1989 matches = [f for f in ctx.files() if match(f)]
1968 if matches:
1990 if matches:
1969 fncache[value] = matches
1991 fncache[value] = matches
1970 self.set.add(value)
1992 self.set.add(value)
1971 return True
1993 return True
1972 return False
1994 return False
1973
1995
1974 def discard(self, value):
1996 def discard(self, value):
1975 self.revs.discard(value)
1997 self.revs.discard(value)
1976 self.set.discard(value)
1998 self.set.discard(value)
1977
1999
1978 wanted = lazywantedset()
2000 wanted = lazywantedset()
1979
2001
1980 # it might be worthwhile to do this in the iterator if the rev range
2002 # it might be worthwhile to do this in the iterator if the rev range
1981 # is descending and the prune args are all within that range
2003 # is descending and the prune args are all within that range
1982 for rev in opts.get('prune', ()):
2004 for rev in opts.get('prune', ()):
1983 rev = repo[rev].rev()
2005 rev = repo[rev].rev()
1984 ff = _followfilter(repo)
2006 ff = _followfilter(repo)
1985 stop = min(revs[0], revs[-1])
2007 stop = min(revs[0], revs[-1])
1986 for x in pycompat.xrange(rev, stop - 1, -1):
2008 for x in pycompat.xrange(rev, stop - 1, -1):
1987 if ff.match(x):
2009 if ff.match(x):
1988 wanted = wanted - [x]
2010 wanted = wanted - [x]
1989
2011
1990 # Now that wanted is correctly initialized, we can iterate over the
2012 # Now that wanted is correctly initialized, we can iterate over the
1991 # revision range, yielding only revisions in wanted.
2013 # revision range, yielding only revisions in wanted.
1992 def iterate():
2014 def iterate():
1993 if follow and match.always():
2015 if follow and match.always():
1994 ff = _followfilter(repo, onlyfirst=opts.get('follow_first'))
2016 ff = _followfilter(repo, onlyfirst=opts.get('follow_first'))
1995 def want(rev):
2017 def want(rev):
1996 return ff.match(rev) and rev in wanted
2018 return ff.match(rev) and rev in wanted
1997 else:
2019 else:
1998 def want(rev):
2020 def want(rev):
1999 return rev in wanted
2021 return rev in wanted
2000
2022
2001 it = iter(revs)
2023 it = iter(revs)
2002 stopiteration = False
2024 stopiteration = False
2003 for windowsize in increasingwindows():
2025 for windowsize in increasingwindows():
2004 nrevs = []
2026 nrevs = []
2005 for i in pycompat.xrange(windowsize):
2027 for i in pycompat.xrange(windowsize):
2006 rev = next(it, None)
2028 rev = next(it, None)
2007 if rev is None:
2029 if rev is None:
2008 stopiteration = True
2030 stopiteration = True
2009 break
2031 break
2010 elif want(rev):
2032 elif want(rev):
2011 nrevs.append(rev)
2033 nrevs.append(rev)
2012 for rev in sorted(nrevs):
2034 for rev in sorted(nrevs):
2013 fns = fncache.get(rev)
2035 fns = fncache.get(rev)
2014 ctx = change(rev)
2036 ctx = change(rev)
2015 if not fns:
2037 if not fns:
2016 def fns_generator():
2038 def fns_generator():
2017 if allfiles:
2039 if allfiles:
2018 fiter = iter(ctx)
2040 fiter = iter(ctx)
2019 else:
2041 else:
2020 fiter = ctx.files()
2042 fiter = ctx.files()
2021 for f in fiter:
2043 for f in fiter:
2022 if match(f):
2044 if match(f):
2023 yield f
2045 yield f
2024 fns = fns_generator()
2046 fns = fns_generator()
2025 prepare(ctx, fns)
2047 prepare(ctx, fns)
2026 for rev in nrevs:
2048 for rev in nrevs:
2027 yield change(rev)
2049 yield change(rev)
2028
2050
2029 if stopiteration:
2051 if stopiteration:
2030 break
2052 break
2031
2053
2032 return iterate()
2054 return iterate()
2033
2055
2034 def add(ui, repo, match, prefix, uipathfn, explicitonly, **opts):
2056 def add(ui, repo, match, prefix, uipathfn, explicitonly, **opts):
2035 bad = []
2057 bad = []
2036
2058
2037 badfn = lambda x, y: bad.append(x) or match.bad(x, y)
2059 badfn = lambda x, y: bad.append(x) or match.bad(x, y)
2038 names = []
2060 names = []
2039 wctx = repo[None]
2061 wctx = repo[None]
2040 cca = None
2062 cca = None
2041 abort, warn = scmutil.checkportabilityalert(ui)
2063 abort, warn = scmutil.checkportabilityalert(ui)
2042 if abort or warn:
2064 if abort or warn:
2043 cca = scmutil.casecollisionauditor(ui, abort, repo.dirstate)
2065 cca = scmutil.casecollisionauditor(ui, abort, repo.dirstate)
2044
2066
2045 match = repo.narrowmatch(match, includeexact=True)
2067 match = repo.narrowmatch(match, includeexact=True)
2046 badmatch = matchmod.badmatch(match, badfn)
2068 badmatch = matchmod.badmatch(match, badfn)
2047 dirstate = repo.dirstate
2069 dirstate = repo.dirstate
2048 # We don't want to just call wctx.walk here, since it would return a lot of
2070 # We don't want to just call wctx.walk here, since it would return a lot of
2049 # clean files, which we aren't interested in and takes time.
2071 # clean files, which we aren't interested in and takes time.
2050 for f in sorted(dirstate.walk(badmatch, subrepos=sorted(wctx.substate),
2072 for f in sorted(dirstate.walk(badmatch, subrepos=sorted(wctx.substate),
2051 unknown=True, ignored=False, full=False)):
2073 unknown=True, ignored=False, full=False)):
2052 exact = match.exact(f)
2074 exact = match.exact(f)
2053 if exact or not explicitonly and f not in wctx and repo.wvfs.lexists(f):
2075 if exact or not explicitonly and f not in wctx and repo.wvfs.lexists(f):
2054 if cca:
2076 if cca:
2055 cca(f)
2077 cca(f)
2056 names.append(f)
2078 names.append(f)
2057 if ui.verbose or not exact:
2079 if ui.verbose or not exact:
2058 ui.status(_('adding %s\n') % uipathfn(f),
2080 ui.status(_('adding %s\n') % uipathfn(f),
2059 label='ui.addremove.added')
2081 label='ui.addremove.added')
2060
2082
2061 for subpath in sorted(wctx.substate):
2083 for subpath in sorted(wctx.substate):
2062 sub = wctx.sub(subpath)
2084 sub = wctx.sub(subpath)
2063 try:
2085 try:
2064 submatch = matchmod.subdirmatcher(subpath, match)
2086 submatch = matchmod.subdirmatcher(subpath, match)
2065 subprefix = repo.wvfs.reljoin(prefix, subpath)
2087 subprefix = repo.wvfs.reljoin(prefix, subpath)
2066 subuipathfn = scmutil.subdiruipathfn(subpath, uipathfn)
2088 subuipathfn = scmutil.subdiruipathfn(subpath, uipathfn)
2067 if opts.get(r'subrepos'):
2089 if opts.get(r'subrepos'):
2068 bad.extend(sub.add(ui, submatch, subprefix, subuipathfn, False,
2090 bad.extend(sub.add(ui, submatch, subprefix, subuipathfn, False,
2069 **opts))
2091 **opts))
2070 else:
2092 else:
2071 bad.extend(sub.add(ui, submatch, subprefix, subuipathfn, True,
2093 bad.extend(sub.add(ui, submatch, subprefix, subuipathfn, True,
2072 **opts))
2094 **opts))
2073 except error.LookupError:
2095 except error.LookupError:
2074 ui.status(_("skipping missing subrepository: %s\n")
2096 ui.status(_("skipping missing subrepository: %s\n")
2075 % uipathfn(subpath))
2097 % uipathfn(subpath))
2076
2098
2077 if not opts.get(r'dry_run'):
2099 if not opts.get(r'dry_run'):
2078 rejected = wctx.add(names, prefix)
2100 rejected = wctx.add(names, prefix)
2079 bad.extend(f for f in rejected if f in match.files())
2101 bad.extend(f for f in rejected if f in match.files())
2080 return bad
2102 return bad
2081
2103
2082 def addwebdirpath(repo, serverpath, webconf):
2104 def addwebdirpath(repo, serverpath, webconf):
2083 webconf[serverpath] = repo.root
2105 webconf[serverpath] = repo.root
2084 repo.ui.debug('adding %s = %s\n' % (serverpath, repo.root))
2106 repo.ui.debug('adding %s = %s\n' % (serverpath, repo.root))
2085
2107
2086 for r in repo.revs('filelog("path:.hgsub")'):
2108 for r in repo.revs('filelog("path:.hgsub")'):
2087 ctx = repo[r]
2109 ctx = repo[r]
2088 for subpath in ctx.substate:
2110 for subpath in ctx.substate:
2089 ctx.sub(subpath).addwebdirpath(serverpath, webconf)
2111 ctx.sub(subpath).addwebdirpath(serverpath, webconf)
2090
2112
2091 def forget(ui, repo, match, prefix, uipathfn, explicitonly, dryrun,
2113 def forget(ui, repo, match, prefix, uipathfn, explicitonly, dryrun,
2092 interactive):
2114 interactive):
2093 if dryrun and interactive:
2115 if dryrun and interactive:
2094 raise error.Abort(_("cannot specify both --dry-run and --interactive"))
2116 raise error.Abort(_("cannot specify both --dry-run and --interactive"))
2095 bad = []
2117 bad = []
2096 badfn = lambda x, y: bad.append(x) or match.bad(x, y)
2118 badfn = lambda x, y: bad.append(x) or match.bad(x, y)
2097 wctx = repo[None]
2119 wctx = repo[None]
2098 forgot = []
2120 forgot = []
2099
2121
2100 s = repo.status(match=matchmod.badmatch(match, badfn), clean=True)
2122 s = repo.status(match=matchmod.badmatch(match, badfn), clean=True)
2101 forget = sorted(s.modified + s.added + s.deleted + s.clean)
2123 forget = sorted(s.modified + s.added + s.deleted + s.clean)
2102 if explicitonly:
2124 if explicitonly:
2103 forget = [f for f in forget if match.exact(f)]
2125 forget = [f for f in forget if match.exact(f)]
2104
2126
2105 for subpath in sorted(wctx.substate):
2127 for subpath in sorted(wctx.substate):
2106 sub = wctx.sub(subpath)
2128 sub = wctx.sub(subpath)
2107 submatch = matchmod.subdirmatcher(subpath, match)
2129 submatch = matchmod.subdirmatcher(subpath, match)
2108 subprefix = repo.wvfs.reljoin(prefix, subpath)
2130 subprefix = repo.wvfs.reljoin(prefix, subpath)
2109 subuipathfn = scmutil.subdiruipathfn(subpath, uipathfn)
2131 subuipathfn = scmutil.subdiruipathfn(subpath, uipathfn)
2110 try:
2132 try:
2111 subbad, subforgot = sub.forget(submatch, subprefix, subuipathfn,
2133 subbad, subforgot = sub.forget(submatch, subprefix, subuipathfn,
2112 dryrun=dryrun,
2134 dryrun=dryrun,
2113 interactive=interactive)
2135 interactive=interactive)
2114 bad.extend([subpath + '/' + f for f in subbad])
2136 bad.extend([subpath + '/' + f for f in subbad])
2115 forgot.extend([subpath + '/' + f for f in subforgot])
2137 forgot.extend([subpath + '/' + f for f in subforgot])
2116 except error.LookupError:
2138 except error.LookupError:
2117 ui.status(_("skipping missing subrepository: %s\n")
2139 ui.status(_("skipping missing subrepository: %s\n")
2118 % uipathfn(subpath))
2140 % uipathfn(subpath))
2119
2141
2120 if not explicitonly:
2142 if not explicitonly:
2121 for f in match.files():
2143 for f in match.files():
2122 if f not in repo.dirstate and not repo.wvfs.isdir(f):
2144 if f not in repo.dirstate and not repo.wvfs.isdir(f):
2123 if f not in forgot:
2145 if f not in forgot:
2124 if repo.wvfs.exists(f):
2146 if repo.wvfs.exists(f):
2125 # Don't complain if the exact case match wasn't given.
2147 # Don't complain if the exact case match wasn't given.
2126 # But don't do this until after checking 'forgot', so
2148 # But don't do this until after checking 'forgot', so
2127 # that subrepo files aren't normalized, and this op is
2149 # that subrepo files aren't normalized, and this op is
2128 # purely from data cached by the status walk above.
2150 # purely from data cached by the status walk above.
2129 if repo.dirstate.normalize(f) in repo.dirstate:
2151 if repo.dirstate.normalize(f) in repo.dirstate:
2130 continue
2152 continue
2131 ui.warn(_('not removing %s: '
2153 ui.warn(_('not removing %s: '
2132 'file is already untracked\n')
2154 'file is already untracked\n')
2133 % uipathfn(f))
2155 % uipathfn(f))
2134 bad.append(f)
2156 bad.append(f)
2135
2157
2136 if interactive:
2158 if interactive:
2137 responses = _('[Ynsa?]'
2159 responses = _('[Ynsa?]'
2138 '$$ &Yes, forget this file'
2160 '$$ &Yes, forget this file'
2139 '$$ &No, skip this file'
2161 '$$ &No, skip this file'
2140 '$$ &Skip remaining files'
2162 '$$ &Skip remaining files'
2141 '$$ Include &all remaining files'
2163 '$$ Include &all remaining files'
2142 '$$ &? (display help)')
2164 '$$ &? (display help)')
2143 for filename in forget[:]:
2165 for filename in forget[:]:
2144 r = ui.promptchoice(_('forget %s %s') %
2166 r = ui.promptchoice(_('forget %s %s') %
2145 (uipathfn(filename), responses))
2167 (uipathfn(filename), responses))
2146 if r == 4: # ?
2168 if r == 4: # ?
2147 while r == 4:
2169 while r == 4:
2148 for c, t in ui.extractchoices(responses)[1]:
2170 for c, t in ui.extractchoices(responses)[1]:
2149 ui.write('%s - %s\n' % (c, encoding.lower(t)))
2171 ui.write('%s - %s\n' % (c, encoding.lower(t)))
2150 r = ui.promptchoice(_('forget %s %s') %
2172 r = ui.promptchoice(_('forget %s %s') %
2151 (uipathfn(filename), responses))
2173 (uipathfn(filename), responses))
2152 if r == 0: # yes
2174 if r == 0: # yes
2153 continue
2175 continue
2154 elif r == 1: # no
2176 elif r == 1: # no
2155 forget.remove(filename)
2177 forget.remove(filename)
2156 elif r == 2: # Skip
2178 elif r == 2: # Skip
2157 fnindex = forget.index(filename)
2179 fnindex = forget.index(filename)
2158 del forget[fnindex:]
2180 del forget[fnindex:]
2159 break
2181 break
2160 elif r == 3: # All
2182 elif r == 3: # All
2161 break
2183 break
2162
2184
2163 for f in forget:
2185 for f in forget:
2164 if ui.verbose or not match.exact(f) or interactive:
2186 if ui.verbose or not match.exact(f) or interactive:
2165 ui.status(_('removing %s\n') % uipathfn(f),
2187 ui.status(_('removing %s\n') % uipathfn(f),
2166 label='ui.addremove.removed')
2188 label='ui.addremove.removed')
2167
2189
2168 if not dryrun:
2190 if not dryrun:
2169 rejected = wctx.forget(forget, prefix)
2191 rejected = wctx.forget(forget, prefix)
2170 bad.extend(f for f in rejected if f in match.files())
2192 bad.extend(f for f in rejected if f in match.files())
2171 forgot.extend(f for f in forget if f not in rejected)
2193 forgot.extend(f for f in forget if f not in rejected)
2172 return bad, forgot
2194 return bad, forgot
2173
2195
2174 def files(ui, ctx, m, uipathfn, fm, fmt, subrepos):
2196 def files(ui, ctx, m, uipathfn, fm, fmt, subrepos):
2175 ret = 1
2197 ret = 1
2176
2198
2177 needsfctx = ui.verbose or {'size', 'flags'} & fm.datahint()
2199 needsfctx = ui.verbose or {'size', 'flags'} & fm.datahint()
2178 for f in ctx.matches(m):
2200 for f in ctx.matches(m):
2179 fm.startitem()
2201 fm.startitem()
2180 fm.context(ctx=ctx)
2202 fm.context(ctx=ctx)
2181 if needsfctx:
2203 if needsfctx:
2182 fc = ctx[f]
2204 fc = ctx[f]
2183 fm.write('size flags', '% 10d % 1s ', fc.size(), fc.flags())
2205 fm.write('size flags', '% 10d % 1s ', fc.size(), fc.flags())
2184 fm.data(path=f)
2206 fm.data(path=f)
2185 fm.plain(fmt % uipathfn(f))
2207 fm.plain(fmt % uipathfn(f))
2186 ret = 0
2208 ret = 0
2187
2209
2188 for subpath in sorted(ctx.substate):
2210 for subpath in sorted(ctx.substate):
2189 submatch = matchmod.subdirmatcher(subpath, m)
2211 submatch = matchmod.subdirmatcher(subpath, m)
2190 subuipathfn = scmutil.subdiruipathfn(subpath, uipathfn)
2212 subuipathfn = scmutil.subdiruipathfn(subpath, uipathfn)
2191 if (subrepos or m.exact(subpath) or any(submatch.files())):
2213 if (subrepos or m.exact(subpath) or any(submatch.files())):
2192 sub = ctx.sub(subpath)
2214 sub = ctx.sub(subpath)
2193 try:
2215 try:
2194 recurse = m.exact(subpath) or subrepos
2216 recurse = m.exact(subpath) or subrepos
2195 if sub.printfiles(ui, submatch, subuipathfn, fm, fmt,
2217 if sub.printfiles(ui, submatch, subuipathfn, fm, fmt,
2196 recurse) == 0:
2218 recurse) == 0:
2197 ret = 0
2219 ret = 0
2198 except error.LookupError:
2220 except error.LookupError:
2199 ui.status(_("skipping missing subrepository: %s\n")
2221 ui.status(_("skipping missing subrepository: %s\n")
2200 % uipathfn(subpath))
2222 % uipathfn(subpath))
2201
2223
2202 return ret
2224 return ret
2203
2225
2204 def remove(ui, repo, m, prefix, uipathfn, after, force, subrepos, dryrun,
2226 def remove(ui, repo, m, prefix, uipathfn, after, force, subrepos, dryrun,
2205 warnings=None):
2227 warnings=None):
2206 ret = 0
2228 ret = 0
2207 s = repo.status(match=m, clean=True)
2229 s = repo.status(match=m, clean=True)
2208 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
2230 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
2209
2231
2210 wctx = repo[None]
2232 wctx = repo[None]
2211
2233
2212 if warnings is None:
2234 if warnings is None:
2213 warnings = []
2235 warnings = []
2214 warn = True
2236 warn = True
2215 else:
2237 else:
2216 warn = False
2238 warn = False
2217
2239
2218 subs = sorted(wctx.substate)
2240 subs = sorted(wctx.substate)
2219 progress = ui.makeprogress(_('searching'), total=len(subs),
2241 progress = ui.makeprogress(_('searching'), total=len(subs),
2220 unit=_('subrepos'))
2242 unit=_('subrepos'))
2221 for subpath in subs:
2243 for subpath in subs:
2222 submatch = matchmod.subdirmatcher(subpath, m)
2244 submatch = matchmod.subdirmatcher(subpath, m)
2223 subprefix = repo.wvfs.reljoin(prefix, subpath)
2245 subprefix = repo.wvfs.reljoin(prefix, subpath)
2224 subuipathfn = scmutil.subdiruipathfn(subpath, uipathfn)
2246 subuipathfn = scmutil.subdiruipathfn(subpath, uipathfn)
2225 if subrepos or m.exact(subpath) or any(submatch.files()):
2247 if subrepos or m.exact(subpath) or any(submatch.files()):
2226 progress.increment()
2248 progress.increment()
2227 sub = wctx.sub(subpath)
2249 sub = wctx.sub(subpath)
2228 try:
2250 try:
2229 if sub.removefiles(submatch, subprefix, subuipathfn, after,
2251 if sub.removefiles(submatch, subprefix, subuipathfn, after,
2230 force, subrepos, dryrun, warnings):
2252 force, subrepos, dryrun, warnings):
2231 ret = 1
2253 ret = 1
2232 except error.LookupError:
2254 except error.LookupError:
2233 warnings.append(_("skipping missing subrepository: %s\n")
2255 warnings.append(_("skipping missing subrepository: %s\n")
2234 % uipathfn(subpath))
2256 % uipathfn(subpath))
2235 progress.complete()
2257 progress.complete()
2236
2258
2237 # warn about failure to delete explicit files/dirs
2259 # warn about failure to delete explicit files/dirs
2238 deleteddirs = util.dirs(deleted)
2260 deleteddirs = util.dirs(deleted)
2239 files = m.files()
2261 files = m.files()
2240 progress = ui.makeprogress(_('deleting'), total=len(files),
2262 progress = ui.makeprogress(_('deleting'), total=len(files),
2241 unit=_('files'))
2263 unit=_('files'))
2242 for f in files:
2264 for f in files:
2243 def insubrepo():
2265 def insubrepo():
2244 for subpath in wctx.substate:
2266 for subpath in wctx.substate:
2245 if f.startswith(subpath + '/'):
2267 if f.startswith(subpath + '/'):
2246 return True
2268 return True
2247 return False
2269 return False
2248
2270
2249 progress.increment()
2271 progress.increment()
2250 isdir = f in deleteddirs or wctx.hasdir(f)
2272 isdir = f in deleteddirs or wctx.hasdir(f)
2251 if (f in repo.dirstate or isdir or f == '.'
2273 if (f in repo.dirstate or isdir or f == '.'
2252 or insubrepo() or f in subs):
2274 or insubrepo() or f in subs):
2253 continue
2275 continue
2254
2276
2255 if repo.wvfs.exists(f):
2277 if repo.wvfs.exists(f):
2256 if repo.wvfs.isdir(f):
2278 if repo.wvfs.isdir(f):
2257 warnings.append(_('not removing %s: no tracked files\n')
2279 warnings.append(_('not removing %s: no tracked files\n')
2258 % uipathfn(f))
2280 % uipathfn(f))
2259 else:
2281 else:
2260 warnings.append(_('not removing %s: file is untracked\n')
2282 warnings.append(_('not removing %s: file is untracked\n')
2261 % uipathfn(f))
2283 % uipathfn(f))
2262 # missing files will generate a warning elsewhere
2284 # missing files will generate a warning elsewhere
2263 ret = 1
2285 ret = 1
2264 progress.complete()
2286 progress.complete()
2265
2287
2266 if force:
2288 if force:
2267 list = modified + deleted + clean + added
2289 list = modified + deleted + clean + added
2268 elif after:
2290 elif after:
2269 list = deleted
2291 list = deleted
2270 remaining = modified + added + clean
2292 remaining = modified + added + clean
2271 progress = ui.makeprogress(_('skipping'), total=len(remaining),
2293 progress = ui.makeprogress(_('skipping'), total=len(remaining),
2272 unit=_('files'))
2294 unit=_('files'))
2273 for f in remaining:
2295 for f in remaining:
2274 progress.increment()
2296 progress.increment()
2275 if ui.verbose or (f in files):
2297 if ui.verbose or (f in files):
2276 warnings.append(_('not removing %s: file still exists\n')
2298 warnings.append(_('not removing %s: file still exists\n')
2277 % uipathfn(f))
2299 % uipathfn(f))
2278 ret = 1
2300 ret = 1
2279 progress.complete()
2301 progress.complete()
2280 else:
2302 else:
2281 list = deleted + clean
2303 list = deleted + clean
2282 progress = ui.makeprogress(_('skipping'),
2304 progress = ui.makeprogress(_('skipping'),
2283 total=(len(modified) + len(added)),
2305 total=(len(modified) + len(added)),
2284 unit=_('files'))
2306 unit=_('files'))
2285 for f in modified:
2307 for f in modified:
2286 progress.increment()
2308 progress.increment()
2287 warnings.append(_('not removing %s: file is modified (use -f'
2309 warnings.append(_('not removing %s: file is modified (use -f'
2288 ' to force removal)\n') % uipathfn(f))
2310 ' to force removal)\n') % uipathfn(f))
2289 ret = 1
2311 ret = 1
2290 for f in added:
2312 for f in added:
2291 progress.increment()
2313 progress.increment()
2292 warnings.append(_("not removing %s: file has been marked for add"
2314 warnings.append(_("not removing %s: file has been marked for add"
2293 " (use 'hg forget' to undo add)\n") % uipathfn(f))
2315 " (use 'hg forget' to undo add)\n") % uipathfn(f))
2294 ret = 1
2316 ret = 1
2295 progress.complete()
2317 progress.complete()
2296
2318
2297 list = sorted(list)
2319 list = sorted(list)
2298 progress = ui.makeprogress(_('deleting'), total=len(list),
2320 progress = ui.makeprogress(_('deleting'), total=len(list),
2299 unit=_('files'))
2321 unit=_('files'))
2300 for f in list:
2322 for f in list:
2301 if ui.verbose or not m.exact(f):
2323 if ui.verbose or not m.exact(f):
2302 progress.increment()
2324 progress.increment()
2303 ui.status(_('removing %s\n') % uipathfn(f),
2325 ui.status(_('removing %s\n') % uipathfn(f),
2304 label='ui.addremove.removed')
2326 label='ui.addremove.removed')
2305 progress.complete()
2327 progress.complete()
2306
2328
2307 if not dryrun:
2329 if not dryrun:
2308 with repo.wlock():
2330 with repo.wlock():
2309 if not after:
2331 if not after:
2310 for f in list:
2332 for f in list:
2311 if f in added:
2333 if f in added:
2312 continue # we never unlink added files on remove
2334 continue # we never unlink added files on remove
2313 rmdir = repo.ui.configbool('experimental',
2335 rmdir = repo.ui.configbool('experimental',
2314 'removeemptydirs')
2336 'removeemptydirs')
2315 repo.wvfs.unlinkpath(f, ignoremissing=True, rmdir=rmdir)
2337 repo.wvfs.unlinkpath(f, ignoremissing=True, rmdir=rmdir)
2316 repo[None].forget(list)
2338 repo[None].forget(list)
2317
2339
2318 if warn:
2340 if warn:
2319 for warning in warnings:
2341 for warning in warnings:
2320 ui.warn(warning)
2342 ui.warn(warning)
2321
2343
2322 return ret
2344 return ret
2323
2345
2324 def _updatecatformatter(fm, ctx, matcher, path, decode):
2346 def _updatecatformatter(fm, ctx, matcher, path, decode):
2325 """Hook for adding data to the formatter used by ``hg cat``.
2347 """Hook for adding data to the formatter used by ``hg cat``.
2326
2348
2327 Extensions (e.g., lfs) can wrap this to inject keywords/data, but must call
2349 Extensions (e.g., lfs) can wrap this to inject keywords/data, but must call
2328 this method first."""
2350 this method first."""
2329 data = ctx[path].data()
2351 data = ctx[path].data()
2330 if decode:
2352 if decode:
2331 data = ctx.repo().wwritedata(path, data)
2353 data = ctx.repo().wwritedata(path, data)
2332 fm.startitem()
2354 fm.startitem()
2333 fm.context(ctx=ctx)
2355 fm.context(ctx=ctx)
2334 fm.write('data', '%s', data)
2356 fm.write('data', '%s', data)
2335 fm.data(path=path)
2357 fm.data(path=path)
2336
2358
2337 def cat(ui, repo, ctx, matcher, basefm, fntemplate, prefix, **opts):
2359 def cat(ui, repo, ctx, matcher, basefm, fntemplate, prefix, **opts):
2338 err = 1
2360 err = 1
2339 opts = pycompat.byteskwargs(opts)
2361 opts = pycompat.byteskwargs(opts)
2340
2362
2341 def write(path):
2363 def write(path):
2342 filename = None
2364 filename = None
2343 if fntemplate:
2365 if fntemplate:
2344 filename = makefilename(ctx, fntemplate,
2366 filename = makefilename(ctx, fntemplate,
2345 pathname=os.path.join(prefix, path))
2367 pathname=os.path.join(prefix, path))
2346 # attempt to create the directory if it does not already exist
2368 # attempt to create the directory if it does not already exist
2347 try:
2369 try:
2348 os.makedirs(os.path.dirname(filename))
2370 os.makedirs(os.path.dirname(filename))
2349 except OSError:
2371 except OSError:
2350 pass
2372 pass
2351 with formatter.maybereopen(basefm, filename) as fm:
2373 with formatter.maybereopen(basefm, filename) as fm:
2352 _updatecatformatter(fm, ctx, matcher, path, opts.get('decode'))
2374 _updatecatformatter(fm, ctx, matcher, path, opts.get('decode'))
2353
2375
2354 # Automation often uses hg cat on single files, so special case it
2376 # Automation often uses hg cat on single files, so special case it
2355 # for performance to avoid the cost of parsing the manifest.
2377 # for performance to avoid the cost of parsing the manifest.
2356 if len(matcher.files()) == 1 and not matcher.anypats():
2378 if len(matcher.files()) == 1 and not matcher.anypats():
2357 file = matcher.files()[0]
2379 file = matcher.files()[0]
2358 mfl = repo.manifestlog
2380 mfl = repo.manifestlog
2359 mfnode = ctx.manifestnode()
2381 mfnode = ctx.manifestnode()
2360 try:
2382 try:
2361 if mfnode and mfl[mfnode].find(file)[0]:
2383 if mfnode and mfl[mfnode].find(file)[0]:
2362 scmutil.prefetchfiles(repo, [ctx.rev()], matcher)
2384 scmutil.prefetchfiles(repo, [ctx.rev()], matcher)
2363 write(file)
2385 write(file)
2364 return 0
2386 return 0
2365 except KeyError:
2387 except KeyError:
2366 pass
2388 pass
2367
2389
2368 scmutil.prefetchfiles(repo, [ctx.rev()], matcher)
2390 scmutil.prefetchfiles(repo, [ctx.rev()], matcher)
2369
2391
2370 for abs in ctx.walk(matcher):
2392 for abs in ctx.walk(matcher):
2371 write(abs)
2393 write(abs)
2372 err = 0
2394 err = 0
2373
2395
2374 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2396 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2375 for subpath in sorted(ctx.substate):
2397 for subpath in sorted(ctx.substate):
2376 sub = ctx.sub(subpath)
2398 sub = ctx.sub(subpath)
2377 try:
2399 try:
2378 submatch = matchmod.subdirmatcher(subpath, matcher)
2400 submatch = matchmod.subdirmatcher(subpath, matcher)
2379 subprefix = os.path.join(prefix, subpath)
2401 subprefix = os.path.join(prefix, subpath)
2380 if not sub.cat(submatch, basefm, fntemplate, subprefix,
2402 if not sub.cat(submatch, basefm, fntemplate, subprefix,
2381 **pycompat.strkwargs(opts)):
2403 **pycompat.strkwargs(opts)):
2382 err = 0
2404 err = 0
2383 except error.RepoLookupError:
2405 except error.RepoLookupError:
2384 ui.status(_("skipping missing subrepository: %s\n") %
2406 ui.status(_("skipping missing subrepository: %s\n") %
2385 uipathfn(subpath))
2407 uipathfn(subpath))
2386
2408
2387 return err
2409 return err
2388
2410
2389 def commit(ui, repo, commitfunc, pats, opts):
2411 def commit(ui, repo, commitfunc, pats, opts):
2390 '''commit the specified files or all outstanding changes'''
2412 '''commit the specified files or all outstanding changes'''
2391 date = opts.get('date')
2413 date = opts.get('date')
2392 if date:
2414 if date:
2393 opts['date'] = dateutil.parsedate(date)
2415 opts['date'] = dateutil.parsedate(date)
2394 message = logmessage(ui, opts)
2416 message = logmessage(ui, opts)
2395 matcher = scmutil.match(repo[None], pats, opts)
2417 matcher = scmutil.match(repo[None], pats, opts)
2396
2418
2397 dsguard = None
2419 dsguard = None
2398 # extract addremove carefully -- this function can be called from a command
2420 # extract addremove carefully -- this function can be called from a command
2399 # that doesn't support addremove
2421 # that doesn't support addremove
2400 if opts.get('addremove'):
2422 if opts.get('addremove'):
2401 dsguard = dirstateguard.dirstateguard(repo, 'commit')
2423 dsguard = dirstateguard.dirstateguard(repo, 'commit')
2402 with dsguard or util.nullcontextmanager():
2424 with dsguard or util.nullcontextmanager():
2403 if dsguard:
2425 if dsguard:
2404 relative = scmutil.anypats(pats, opts)
2426 relative = scmutil.anypats(pats, opts)
2405 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
2427 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
2406 if scmutil.addremove(repo, matcher, "", uipathfn, opts) != 0:
2428 if scmutil.addremove(repo, matcher, "", uipathfn, opts) != 0:
2407 raise error.Abort(
2429 raise error.Abort(
2408 _("failed to mark all new/missing files as added/removed"))
2430 _("failed to mark all new/missing files as added/removed"))
2409
2431
2410 return commitfunc(ui, repo, message, matcher, opts)
2432 return commitfunc(ui, repo, message, matcher, opts)
2411
2433
2412 def samefile(f, ctx1, ctx2):
2434 def samefile(f, ctx1, ctx2):
2413 if f in ctx1.manifest():
2435 if f in ctx1.manifest():
2414 a = ctx1.filectx(f)
2436 a = ctx1.filectx(f)
2415 if f in ctx2.manifest():
2437 if f in ctx2.manifest():
2416 b = ctx2.filectx(f)
2438 b = ctx2.filectx(f)
2417 return (not a.cmp(b)
2439 return (not a.cmp(b)
2418 and a.flags() == b.flags())
2440 and a.flags() == b.flags())
2419 else:
2441 else:
2420 return False
2442 return False
2421 else:
2443 else:
2422 return f not in ctx2.manifest()
2444 return f not in ctx2.manifest()
2423
2445
2424 def amend(ui, repo, old, extra, pats, opts):
2446 def amend(ui, repo, old, extra, pats, opts):
2425 # avoid cycle context -> subrepo -> cmdutil
2447 # avoid cycle context -> subrepo -> cmdutil
2426 from . import context
2448 from . import context
2427
2449
2428 # amend will reuse the existing user if not specified, but the obsolete
2450 # amend will reuse the existing user if not specified, but the obsolete
2429 # marker creation requires that the current user's name is specified.
2451 # marker creation requires that the current user's name is specified.
2430 if obsolete.isenabled(repo, obsolete.createmarkersopt):
2452 if obsolete.isenabled(repo, obsolete.createmarkersopt):
2431 ui.username() # raise exception if username not set
2453 ui.username() # raise exception if username not set
2432
2454
2433 ui.note(_('amending changeset %s\n') % old)
2455 ui.note(_('amending changeset %s\n') % old)
2434 base = old.p1()
2456 base = old.p1()
2435
2457
2436 with repo.wlock(), repo.lock(), repo.transaction('amend'):
2458 with repo.wlock(), repo.lock(), repo.transaction('amend'):
2437 # Participating changesets:
2459 # Participating changesets:
2438 #
2460 #
2439 # wctx o - workingctx that contains changes from working copy
2461 # wctx o - workingctx that contains changes from working copy
2440 # | to go into amending commit
2462 # | to go into amending commit
2441 # |
2463 # |
2442 # old o - changeset to amend
2464 # old o - changeset to amend
2443 # |
2465 # |
2444 # base o - first parent of the changeset to amend
2466 # base o - first parent of the changeset to amend
2445 wctx = repo[None]
2467 wctx = repo[None]
2446
2468
2447 # Copy to avoid mutating input
2469 # Copy to avoid mutating input
2448 extra = extra.copy()
2470 extra = extra.copy()
2449 # Update extra dict from amended commit (e.g. to preserve graft
2471 # Update extra dict from amended commit (e.g. to preserve graft
2450 # source)
2472 # source)
2451 extra.update(old.extra())
2473 extra.update(old.extra())
2452
2474
2453 # Also update it from the from the wctx
2475 # Also update it from the from the wctx
2454 extra.update(wctx.extra())
2476 extra.update(wctx.extra())
2455
2477
2456 user = opts.get('user') or old.user()
2478 user = opts.get('user') or old.user()
2457
2479
2458 datemaydiffer = False # date-only change should be ignored?
2480 datemaydiffer = False # date-only change should be ignored?
2459 if opts.get('date') and opts.get('currentdate'):
2481 if opts.get('date') and opts.get('currentdate'):
2460 raise error.Abort(_('--date and --currentdate are mutually '
2482 raise error.Abort(_('--date and --currentdate are mutually '
2461 'exclusive'))
2483 'exclusive'))
2462 if opts.get('date'):
2484 if opts.get('date'):
2463 date = dateutil.parsedate(opts.get('date'))
2485 date = dateutil.parsedate(opts.get('date'))
2464 elif opts.get('currentdate'):
2486 elif opts.get('currentdate'):
2465 date = dateutil.makedate()
2487 date = dateutil.makedate()
2466 elif (ui.configbool('rewrite', 'update-timestamp')
2488 elif (ui.configbool('rewrite', 'update-timestamp')
2467 and opts.get('currentdate') is None):
2489 and opts.get('currentdate') is None):
2468 date = dateutil.makedate()
2490 date = dateutil.makedate()
2469 datemaydiffer = True
2491 datemaydiffer = True
2470 else:
2492 else:
2471 date = old.date()
2493 date = old.date()
2472
2494
2473 if len(old.parents()) > 1:
2495 if len(old.parents()) > 1:
2474 # ctx.files() isn't reliable for merges, so fall back to the
2496 # ctx.files() isn't reliable for merges, so fall back to the
2475 # slower repo.status() method
2497 # slower repo.status() method
2476 files = set([fn for st in base.status(old)[:3]
2498 files = set([fn for st in base.status(old)[:3]
2477 for fn in st])
2499 for fn in st])
2478 else:
2500 else:
2479 files = set(old.files())
2501 files = set(old.files())
2480
2502
2481 # add/remove the files to the working copy if the "addremove" option
2503 # add/remove the files to the working copy if the "addremove" option
2482 # was specified.
2504 # was specified.
2483 matcher = scmutil.match(wctx, pats, opts)
2505 matcher = scmutil.match(wctx, pats, opts)
2484 relative = scmutil.anypats(pats, opts)
2506 relative = scmutil.anypats(pats, opts)
2485 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
2507 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
2486 if (opts.get('addremove')
2508 if (opts.get('addremove')
2487 and scmutil.addremove(repo, matcher, "", uipathfn, opts)):
2509 and scmutil.addremove(repo, matcher, "", uipathfn, opts)):
2488 raise error.Abort(
2510 raise error.Abort(
2489 _("failed to mark all new/missing files as added/removed"))
2511 _("failed to mark all new/missing files as added/removed"))
2490
2512
2491 # Check subrepos. This depends on in-place wctx._status update in
2513 # Check subrepos. This depends on in-place wctx._status update in
2492 # subrepo.precommit(). To minimize the risk of this hack, we do
2514 # subrepo.precommit(). To minimize the risk of this hack, we do
2493 # nothing if .hgsub does not exist.
2515 # nothing if .hgsub does not exist.
2494 if '.hgsub' in wctx or '.hgsub' in old:
2516 if '.hgsub' in wctx or '.hgsub' in old:
2495 subs, commitsubs, newsubstate = subrepoutil.precommit(
2517 subs, commitsubs, newsubstate = subrepoutil.precommit(
2496 ui, wctx, wctx._status, matcher)
2518 ui, wctx, wctx._status, matcher)
2497 # amend should abort if commitsubrepos is enabled
2519 # amend should abort if commitsubrepos is enabled
2498 assert not commitsubs
2520 assert not commitsubs
2499 if subs:
2521 if subs:
2500 subrepoutil.writestate(repo, newsubstate)
2522 subrepoutil.writestate(repo, newsubstate)
2501
2523
2502 ms = mergemod.mergestate.read(repo)
2524 ms = mergemod.mergestate.read(repo)
2503 mergeutil.checkunresolved(ms)
2525 mergeutil.checkunresolved(ms)
2504
2526
2505 filestoamend = set(f for f in wctx.files() if matcher(f))
2527 filestoamend = set(f for f in wctx.files() if matcher(f))
2506
2528
2507 changes = (len(filestoamend) > 0)
2529 changes = (len(filestoamend) > 0)
2508 if changes:
2530 if changes:
2509 # Recompute copies (avoid recording a -> b -> a)
2531 # Recompute copies (avoid recording a -> b -> a)
2510 copied = copies.pathcopies(base, wctx, matcher)
2532 copied = copies.pathcopies(base, wctx, matcher)
2511 if old.p2:
2533 if old.p2:
2512 copied.update(copies.pathcopies(old.p2(), wctx, matcher))
2534 copied.update(copies.pathcopies(old.p2(), wctx, matcher))
2513
2535
2514 # Prune files which were reverted by the updates: if old
2536 # Prune files which were reverted by the updates: if old
2515 # introduced file X and the file was renamed in the working
2537 # introduced file X and the file was renamed in the working
2516 # copy, then those two files are the same and
2538 # copy, then those two files are the same and
2517 # we can discard X from our list of files. Likewise if X
2539 # we can discard X from our list of files. Likewise if X
2518 # was removed, it's no longer relevant. If X is missing (aka
2540 # was removed, it's no longer relevant. If X is missing (aka
2519 # deleted), old X must be preserved.
2541 # deleted), old X must be preserved.
2520 files.update(filestoamend)
2542 files.update(filestoamend)
2521 files = [f for f in files if (not samefile(f, wctx, base)
2543 files = [f for f in files if (not samefile(f, wctx, base)
2522 or f in wctx.deleted())]
2544 or f in wctx.deleted())]
2523
2545
2524 def filectxfn(repo, ctx_, path):
2546 def filectxfn(repo, ctx_, path):
2525 try:
2547 try:
2526 # If the file being considered is not amongst the files
2548 # If the file being considered is not amongst the files
2527 # to be amended, we should return the file context from the
2549 # to be amended, we should return the file context from the
2528 # old changeset. This avoids issues when only some files in
2550 # old changeset. This avoids issues when only some files in
2529 # the working copy are being amended but there are also
2551 # the working copy are being amended but there are also
2530 # changes to other files from the old changeset.
2552 # changes to other files from the old changeset.
2531 if path not in filestoamend:
2553 if path not in filestoamend:
2532 return old.filectx(path)
2554 return old.filectx(path)
2533
2555
2534 # Return None for removed files.
2556 # Return None for removed files.
2535 if path in wctx.removed():
2557 if path in wctx.removed():
2536 return None
2558 return None
2537
2559
2538 fctx = wctx[path]
2560 fctx = wctx[path]
2539 flags = fctx.flags()
2561 flags = fctx.flags()
2540 mctx = context.memfilectx(repo, ctx_,
2562 mctx = context.memfilectx(repo, ctx_,
2541 fctx.path(), fctx.data(),
2563 fctx.path(), fctx.data(),
2542 islink='l' in flags,
2564 islink='l' in flags,
2543 isexec='x' in flags,
2565 isexec='x' in flags,
2544 copied=copied.get(path))
2566 copied=copied.get(path))
2545 return mctx
2567 return mctx
2546 except KeyError:
2568 except KeyError:
2547 return None
2569 return None
2548 else:
2570 else:
2549 ui.note(_('copying changeset %s to %s\n') % (old, base))
2571 ui.note(_('copying changeset %s to %s\n') % (old, base))
2550
2572
2551 # Use version of files as in the old cset
2573 # Use version of files as in the old cset
2552 def filectxfn(repo, ctx_, path):
2574 def filectxfn(repo, ctx_, path):
2553 try:
2575 try:
2554 return old.filectx(path)
2576 return old.filectx(path)
2555 except KeyError:
2577 except KeyError:
2556 return None
2578 return None
2557
2579
2558 # See if we got a message from -m or -l, if not, open the editor with
2580 # See if we got a message from -m or -l, if not, open the editor with
2559 # the message of the changeset to amend.
2581 # the message of the changeset to amend.
2560 message = logmessage(ui, opts)
2582 message = logmessage(ui, opts)
2561
2583
2562 editform = mergeeditform(old, 'commit.amend')
2584 editform = mergeeditform(old, 'commit.amend')
2563 editor = getcommiteditor(editform=editform,
2585 editor = getcommiteditor(editform=editform,
2564 **pycompat.strkwargs(opts))
2586 **pycompat.strkwargs(opts))
2565
2587
2566 if not message:
2588 if not message:
2567 editor = getcommiteditor(edit=True, editform=editform)
2589 editor = getcommiteditor(edit=True, editform=editform)
2568 message = old.description()
2590 message = old.description()
2569
2591
2570 pureextra = extra.copy()
2592 pureextra = extra.copy()
2571 extra['amend_source'] = old.hex()
2593 extra['amend_source'] = old.hex()
2572
2594
2573 new = context.memctx(repo,
2595 new = context.memctx(repo,
2574 parents=[base.node(), old.p2().node()],
2596 parents=[base.node(), old.p2().node()],
2575 text=message,
2597 text=message,
2576 files=files,
2598 files=files,
2577 filectxfn=filectxfn,
2599 filectxfn=filectxfn,
2578 user=user,
2600 user=user,
2579 date=date,
2601 date=date,
2580 extra=extra,
2602 extra=extra,
2581 editor=editor)
2603 editor=editor)
2582
2604
2583 newdesc = changelog.stripdesc(new.description())
2605 newdesc = changelog.stripdesc(new.description())
2584 if ((not changes)
2606 if ((not changes)
2585 and newdesc == old.description()
2607 and newdesc == old.description()
2586 and user == old.user()
2608 and user == old.user()
2587 and (date == old.date() or datemaydiffer)
2609 and (date == old.date() or datemaydiffer)
2588 and pureextra == old.extra()):
2610 and pureextra == old.extra()):
2589 # nothing changed. continuing here would create a new node
2611 # nothing changed. continuing here would create a new node
2590 # anyway because of the amend_source noise.
2612 # anyway because of the amend_source noise.
2591 #
2613 #
2592 # This not what we expect from amend.
2614 # This not what we expect from amend.
2593 return old.node()
2615 return old.node()
2594
2616
2595 commitphase = None
2617 commitphase = None
2596 if opts.get('secret'):
2618 if opts.get('secret'):
2597 commitphase = phases.secret
2619 commitphase = phases.secret
2598 newid = repo.commitctx(new)
2620 newid = repo.commitctx(new)
2599
2621
2600 # Reroute the working copy parent to the new changeset
2622 # Reroute the working copy parent to the new changeset
2601 repo.setparents(newid, nullid)
2623 repo.setparents(newid, nullid)
2602 mapping = {old.node(): (newid,)}
2624 mapping = {old.node(): (newid,)}
2603 obsmetadata = None
2625 obsmetadata = None
2604 if opts.get('note'):
2626 if opts.get('note'):
2605 obsmetadata = {'note': encoding.fromlocal(opts['note'])}
2627 obsmetadata = {'note': encoding.fromlocal(opts['note'])}
2606 backup = ui.configbool('rewrite', 'backup-bundle')
2628 backup = ui.configbool('rewrite', 'backup-bundle')
2607 scmutil.cleanupnodes(repo, mapping, 'amend', metadata=obsmetadata,
2629 scmutil.cleanupnodes(repo, mapping, 'amend', metadata=obsmetadata,
2608 fixphase=True, targetphase=commitphase,
2630 fixphase=True, targetphase=commitphase,
2609 backup=backup)
2631 backup=backup)
2610
2632
2611 # Fixing the dirstate because localrepo.commitctx does not update
2633 # Fixing the dirstate because localrepo.commitctx does not update
2612 # it. This is rather convenient because we did not need to update
2634 # it. This is rather convenient because we did not need to update
2613 # the dirstate for all the files in the new commit which commitctx
2635 # the dirstate for all the files in the new commit which commitctx
2614 # could have done if it updated the dirstate. Now, we can
2636 # could have done if it updated the dirstate. Now, we can
2615 # selectively update the dirstate only for the amended files.
2637 # selectively update the dirstate only for the amended files.
2616 dirstate = repo.dirstate
2638 dirstate = repo.dirstate
2617
2639
2618 # Update the state of the files which were added and
2640 # Update the state of the files which were added and
2619 # and modified in the amend to "normal" in the dirstate.
2641 # and modified in the amend to "normal" in the dirstate.
2620 normalfiles = set(wctx.modified() + wctx.added()) & filestoamend
2642 normalfiles = set(wctx.modified() + wctx.added()) & filestoamend
2621 for f in normalfiles:
2643 for f in normalfiles:
2622 dirstate.normal(f)
2644 dirstate.normal(f)
2623
2645
2624 # Update the state of files which were removed in the amend
2646 # Update the state of files which were removed in the amend
2625 # to "removed" in the dirstate.
2647 # to "removed" in the dirstate.
2626 removedfiles = set(wctx.removed()) & filestoamend
2648 removedfiles = set(wctx.removed()) & filestoamend
2627 for f in removedfiles:
2649 for f in removedfiles:
2628 dirstate.drop(f)
2650 dirstate.drop(f)
2629
2651
2630 return newid
2652 return newid
2631
2653
2632 def commiteditor(repo, ctx, subs, editform=''):
2654 def commiteditor(repo, ctx, subs, editform=''):
2633 if ctx.description():
2655 if ctx.description():
2634 return ctx.description()
2656 return ctx.description()
2635 return commitforceeditor(repo, ctx, subs, editform=editform,
2657 return commitforceeditor(repo, ctx, subs, editform=editform,
2636 unchangedmessagedetection=True)
2658 unchangedmessagedetection=True)
2637
2659
2638 def commitforceeditor(repo, ctx, subs, finishdesc=None, extramsg=None,
2660 def commitforceeditor(repo, ctx, subs, finishdesc=None, extramsg=None,
2639 editform='', unchangedmessagedetection=False):
2661 editform='', unchangedmessagedetection=False):
2640 if not extramsg:
2662 if not extramsg:
2641 extramsg = _("Leave message empty to abort commit.")
2663 extramsg = _("Leave message empty to abort commit.")
2642
2664
2643 forms = [e for e in editform.split('.') if e]
2665 forms = [e for e in editform.split('.') if e]
2644 forms.insert(0, 'changeset')
2666 forms.insert(0, 'changeset')
2645 templatetext = None
2667 templatetext = None
2646 while forms:
2668 while forms:
2647 ref = '.'.join(forms)
2669 ref = '.'.join(forms)
2648 if repo.ui.config('committemplate', ref):
2670 if repo.ui.config('committemplate', ref):
2649 templatetext = committext = buildcommittemplate(
2671 templatetext = committext = buildcommittemplate(
2650 repo, ctx, subs, extramsg, ref)
2672 repo, ctx, subs, extramsg, ref)
2651 break
2673 break
2652 forms.pop()
2674 forms.pop()
2653 else:
2675 else:
2654 committext = buildcommittext(repo, ctx, subs, extramsg)
2676 committext = buildcommittext(repo, ctx, subs, extramsg)
2655
2677
2656 # run editor in the repository root
2678 # run editor in the repository root
2657 olddir = encoding.getcwd()
2679 olddir = encoding.getcwd()
2658 os.chdir(repo.root)
2680 os.chdir(repo.root)
2659
2681
2660 # make in-memory changes visible to external process
2682 # make in-memory changes visible to external process
2661 tr = repo.currenttransaction()
2683 tr = repo.currenttransaction()
2662 repo.dirstate.write(tr)
2684 repo.dirstate.write(tr)
2663 pending = tr and tr.writepending() and repo.root
2685 pending = tr and tr.writepending() and repo.root
2664
2686
2665 editortext = repo.ui.edit(committext, ctx.user(), ctx.extra(),
2687 editortext = repo.ui.edit(committext, ctx.user(), ctx.extra(),
2666 editform=editform, pending=pending,
2688 editform=editform, pending=pending,
2667 repopath=repo.path, action='commit')
2689 repopath=repo.path, action='commit')
2668 text = editortext
2690 text = editortext
2669
2691
2670 # strip away anything below this special string (used for editors that want
2692 # strip away anything below this special string (used for editors that want
2671 # to display the diff)
2693 # to display the diff)
2672 stripbelow = re.search(_linebelow, text, flags=re.MULTILINE)
2694 stripbelow = re.search(_linebelow, text, flags=re.MULTILINE)
2673 if stripbelow:
2695 if stripbelow:
2674 text = text[:stripbelow.start()]
2696 text = text[:stripbelow.start()]
2675
2697
2676 text = re.sub("(?m)^HG:.*(\n|$)", "", text)
2698 text = re.sub("(?m)^HG:.*(\n|$)", "", text)
2677 os.chdir(olddir)
2699 os.chdir(olddir)
2678
2700
2679 if finishdesc:
2701 if finishdesc:
2680 text = finishdesc(text)
2702 text = finishdesc(text)
2681 if not text.strip():
2703 if not text.strip():
2682 raise error.Abort(_("empty commit message"))
2704 raise error.Abort(_("empty commit message"))
2683 if unchangedmessagedetection and editortext == templatetext:
2705 if unchangedmessagedetection and editortext == templatetext:
2684 raise error.Abort(_("commit message unchanged"))
2706 raise error.Abort(_("commit message unchanged"))
2685
2707
2686 return text
2708 return text
2687
2709
2688 def buildcommittemplate(repo, ctx, subs, extramsg, ref):
2710 def buildcommittemplate(repo, ctx, subs, extramsg, ref):
2689 ui = repo.ui
2711 ui = repo.ui
2690 spec = formatter.templatespec(ref, None, None)
2712 spec = formatter.templatespec(ref, None, None)
2691 t = logcmdutil.changesettemplater(ui, repo, spec)
2713 t = logcmdutil.changesettemplater(ui, repo, spec)
2692 t.t.cache.update((k, templater.unquotestring(v))
2714 t.t.cache.update((k, templater.unquotestring(v))
2693 for k, v in repo.ui.configitems('committemplate'))
2715 for k, v in repo.ui.configitems('committemplate'))
2694
2716
2695 if not extramsg:
2717 if not extramsg:
2696 extramsg = '' # ensure that extramsg is string
2718 extramsg = '' # ensure that extramsg is string
2697
2719
2698 ui.pushbuffer()
2720 ui.pushbuffer()
2699 t.show(ctx, extramsg=extramsg)
2721 t.show(ctx, extramsg=extramsg)
2700 return ui.popbuffer()
2722 return ui.popbuffer()
2701
2723
2702 def hgprefix(msg):
2724 def hgprefix(msg):
2703 return "\n".join(["HG: %s" % a for a in msg.split("\n") if a])
2725 return "\n".join(["HG: %s" % a for a in msg.split("\n") if a])
2704
2726
2705 def buildcommittext(repo, ctx, subs, extramsg):
2727 def buildcommittext(repo, ctx, subs, extramsg):
2706 edittext = []
2728 edittext = []
2707 modified, added, removed = ctx.modified(), ctx.added(), ctx.removed()
2729 modified, added, removed = ctx.modified(), ctx.added(), ctx.removed()
2708 if ctx.description():
2730 if ctx.description():
2709 edittext.append(ctx.description())
2731 edittext.append(ctx.description())
2710 edittext.append("")
2732 edittext.append("")
2711 edittext.append("") # Empty line between message and comments.
2733 edittext.append("") # Empty line between message and comments.
2712 edittext.append(hgprefix(_("Enter commit message."
2734 edittext.append(hgprefix(_("Enter commit message."
2713 " Lines beginning with 'HG:' are removed.")))
2735 " Lines beginning with 'HG:' are removed.")))
2714 edittext.append(hgprefix(extramsg))
2736 edittext.append(hgprefix(extramsg))
2715 edittext.append("HG: --")
2737 edittext.append("HG: --")
2716 edittext.append(hgprefix(_("user: %s") % ctx.user()))
2738 edittext.append(hgprefix(_("user: %s") % ctx.user()))
2717 if ctx.p2():
2739 if ctx.p2():
2718 edittext.append(hgprefix(_("branch merge")))
2740 edittext.append(hgprefix(_("branch merge")))
2719 if ctx.branch():
2741 if ctx.branch():
2720 edittext.append(hgprefix(_("branch '%s'") % ctx.branch()))
2742 edittext.append(hgprefix(_("branch '%s'") % ctx.branch()))
2721 if bookmarks.isactivewdirparent(repo):
2743 if bookmarks.isactivewdirparent(repo):
2722 edittext.append(hgprefix(_("bookmark '%s'") % repo._activebookmark))
2744 edittext.append(hgprefix(_("bookmark '%s'") % repo._activebookmark))
2723 edittext.extend([hgprefix(_("subrepo %s") % s) for s in subs])
2745 edittext.extend([hgprefix(_("subrepo %s") % s) for s in subs])
2724 edittext.extend([hgprefix(_("added %s") % f) for f in added])
2746 edittext.extend([hgprefix(_("added %s") % f) for f in added])
2725 edittext.extend([hgprefix(_("changed %s") % f) for f in modified])
2747 edittext.extend([hgprefix(_("changed %s") % f) for f in modified])
2726 edittext.extend([hgprefix(_("removed %s") % f) for f in removed])
2748 edittext.extend([hgprefix(_("removed %s") % f) for f in removed])
2727 if not added and not modified and not removed:
2749 if not added and not modified and not removed:
2728 edittext.append(hgprefix(_("no files changed")))
2750 edittext.append(hgprefix(_("no files changed")))
2729 edittext.append("")
2751 edittext.append("")
2730
2752
2731 return "\n".join(edittext)
2753 return "\n".join(edittext)
2732
2754
2733 def commitstatus(repo, node, branch, bheads=None, opts=None):
2755 def commitstatus(repo, node, branch, bheads=None, opts=None):
2734 if opts is None:
2756 if opts is None:
2735 opts = {}
2757 opts = {}
2736 ctx = repo[node]
2758 ctx = repo[node]
2737 parents = ctx.parents()
2759 parents = ctx.parents()
2738
2760
2739 if (not opts.get('amend') and bheads and node not in bheads and not
2761 if (not opts.get('amend') and bheads and node not in bheads and not
2740 [x for x in parents if x.node() in bheads and x.branch() == branch]):
2762 [x for x in parents if x.node() in bheads and x.branch() == branch]):
2741 repo.ui.status(_('created new head\n'))
2763 repo.ui.status(_('created new head\n'))
2742 # The message is not printed for initial roots. For the other
2764 # The message is not printed for initial roots. For the other
2743 # changesets, it is printed in the following situations:
2765 # changesets, it is printed in the following situations:
2744 #
2766 #
2745 # Par column: for the 2 parents with ...
2767 # Par column: for the 2 parents with ...
2746 # N: null or no parent
2768 # N: null or no parent
2747 # B: parent is on another named branch
2769 # B: parent is on another named branch
2748 # C: parent is a regular non head changeset
2770 # C: parent is a regular non head changeset
2749 # H: parent was a branch head of the current branch
2771 # H: parent was a branch head of the current branch
2750 # Msg column: whether we print "created new head" message
2772 # Msg column: whether we print "created new head" message
2751 # In the following, it is assumed that there already exists some
2773 # In the following, it is assumed that there already exists some
2752 # initial branch heads of the current branch, otherwise nothing is
2774 # initial branch heads of the current branch, otherwise nothing is
2753 # printed anyway.
2775 # printed anyway.
2754 #
2776 #
2755 # Par Msg Comment
2777 # Par Msg Comment
2756 # N N y additional topo root
2778 # N N y additional topo root
2757 #
2779 #
2758 # B N y additional branch root
2780 # B N y additional branch root
2759 # C N y additional topo head
2781 # C N y additional topo head
2760 # H N n usual case
2782 # H N n usual case
2761 #
2783 #
2762 # B B y weird additional branch root
2784 # B B y weird additional branch root
2763 # C B y branch merge
2785 # C B y branch merge
2764 # H B n merge with named branch
2786 # H B n merge with named branch
2765 #
2787 #
2766 # C C y additional head from merge
2788 # C C y additional head from merge
2767 # C H n merge with a head
2789 # C H n merge with a head
2768 #
2790 #
2769 # H H n head merge: head count decreases
2791 # H H n head merge: head count decreases
2770
2792
2771 if not opts.get('close_branch'):
2793 if not opts.get('close_branch'):
2772 for r in parents:
2794 for r in parents:
2773 if r.closesbranch() and r.branch() == branch:
2795 if r.closesbranch() and r.branch() == branch:
2774 repo.ui.status(_('reopening closed branch head %d\n') % r.rev())
2796 repo.ui.status(_('reopening closed branch head %d\n') % r.rev())
2775
2797
2776 if repo.ui.debugflag:
2798 if repo.ui.debugflag:
2777 repo.ui.write(_('committed changeset %d:%s\n') % (ctx.rev(), ctx.hex()))
2799 repo.ui.write(_('committed changeset %d:%s\n') % (ctx.rev(), ctx.hex()))
2778 elif repo.ui.verbose:
2800 elif repo.ui.verbose:
2779 repo.ui.write(_('committed changeset %d:%s\n') % (ctx.rev(), ctx))
2801 repo.ui.write(_('committed changeset %d:%s\n') % (ctx.rev(), ctx))
2780
2802
2781 def postcommitstatus(repo, pats, opts):
2803 def postcommitstatus(repo, pats, opts):
2782 return repo.status(match=scmutil.match(repo[None], pats, opts))
2804 return repo.status(match=scmutil.match(repo[None], pats, opts))
2783
2805
2784 def revert(ui, repo, ctx, parents, *pats, **opts):
2806 def revert(ui, repo, ctx, parents, *pats, **opts):
2785 opts = pycompat.byteskwargs(opts)
2807 opts = pycompat.byteskwargs(opts)
2786 parent, p2 = parents
2808 parent, p2 = parents
2787 node = ctx.node()
2809 node = ctx.node()
2788
2810
2789 mf = ctx.manifest()
2811 mf = ctx.manifest()
2790 if node == p2:
2812 if node == p2:
2791 parent = p2
2813 parent = p2
2792
2814
2793 # need all matching names in dirstate and manifest of target rev,
2815 # need all matching names in dirstate and manifest of target rev,
2794 # so have to walk both. do not print errors if files exist in one
2816 # so have to walk both. do not print errors if files exist in one
2795 # but not other. in both cases, filesets should be evaluated against
2817 # but not other. in both cases, filesets should be evaluated against
2796 # workingctx to get consistent result (issue4497). this means 'set:**'
2818 # workingctx to get consistent result (issue4497). this means 'set:**'
2797 # cannot be used to select missing files from target rev.
2819 # cannot be used to select missing files from target rev.
2798
2820
2799 # `names` is a mapping for all elements in working copy and target revision
2821 # `names` is a mapping for all elements in working copy and target revision
2800 # The mapping is in the form:
2822 # The mapping is in the form:
2801 # <abs path in repo> -> (<path from CWD>, <exactly specified by matcher?>)
2823 # <abs path in repo> -> (<path from CWD>, <exactly specified by matcher?>)
2802 names = {}
2824 names = {}
2803 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2825 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
2804
2826
2805 with repo.wlock():
2827 with repo.wlock():
2806 ## filling of the `names` mapping
2828 ## filling of the `names` mapping
2807 # walk dirstate to fill `names`
2829 # walk dirstate to fill `names`
2808
2830
2809 interactive = opts.get('interactive', False)
2831 interactive = opts.get('interactive', False)
2810 wctx = repo[None]
2832 wctx = repo[None]
2811 m = scmutil.match(wctx, pats, opts)
2833 m = scmutil.match(wctx, pats, opts)
2812
2834
2813 # we'll need this later
2835 # we'll need this later
2814 targetsubs = sorted(s for s in wctx.substate if m(s))
2836 targetsubs = sorted(s for s in wctx.substate if m(s))
2815
2837
2816 if not m.always():
2838 if not m.always():
2817 matcher = matchmod.badmatch(m, lambda x, y: False)
2839 matcher = matchmod.badmatch(m, lambda x, y: False)
2818 for abs in wctx.walk(matcher):
2840 for abs in wctx.walk(matcher):
2819 names[abs] = m.exact(abs)
2841 names[abs] = m.exact(abs)
2820
2842
2821 # walk target manifest to fill `names`
2843 # walk target manifest to fill `names`
2822
2844
2823 def badfn(path, msg):
2845 def badfn(path, msg):
2824 if path in names:
2846 if path in names:
2825 return
2847 return
2826 if path in ctx.substate:
2848 if path in ctx.substate:
2827 return
2849 return
2828 path_ = path + '/'
2850 path_ = path + '/'
2829 for f in names:
2851 for f in names:
2830 if f.startswith(path_):
2852 if f.startswith(path_):
2831 return
2853 return
2832 ui.warn("%s: %s\n" % (uipathfn(path), msg))
2854 ui.warn("%s: %s\n" % (uipathfn(path), msg))
2833
2855
2834 for abs in ctx.walk(matchmod.badmatch(m, badfn)):
2856 for abs in ctx.walk(matchmod.badmatch(m, badfn)):
2835 if abs not in names:
2857 if abs not in names:
2836 names[abs] = m.exact(abs)
2858 names[abs] = m.exact(abs)
2837
2859
2838 # Find status of all file in `names`.
2860 # Find status of all file in `names`.
2839 m = scmutil.matchfiles(repo, names)
2861 m = scmutil.matchfiles(repo, names)
2840
2862
2841 changes = repo.status(node1=node, match=m,
2863 changes = repo.status(node1=node, match=m,
2842 unknown=True, ignored=True, clean=True)
2864 unknown=True, ignored=True, clean=True)
2843 else:
2865 else:
2844 changes = repo.status(node1=node, match=m)
2866 changes = repo.status(node1=node, match=m)
2845 for kind in changes:
2867 for kind in changes:
2846 for abs in kind:
2868 for abs in kind:
2847 names[abs] = m.exact(abs)
2869 names[abs] = m.exact(abs)
2848
2870
2849 m = scmutil.matchfiles(repo, names)
2871 m = scmutil.matchfiles(repo, names)
2850
2872
2851 modified = set(changes.modified)
2873 modified = set(changes.modified)
2852 added = set(changes.added)
2874 added = set(changes.added)
2853 removed = set(changes.removed)
2875 removed = set(changes.removed)
2854 _deleted = set(changes.deleted)
2876 _deleted = set(changes.deleted)
2855 unknown = set(changes.unknown)
2877 unknown = set(changes.unknown)
2856 unknown.update(changes.ignored)
2878 unknown.update(changes.ignored)
2857 clean = set(changes.clean)
2879 clean = set(changes.clean)
2858 modadded = set()
2880 modadded = set()
2859
2881
2860 # We need to account for the state of the file in the dirstate,
2882 # We need to account for the state of the file in the dirstate,
2861 # even when we revert against something else than parent. This will
2883 # even when we revert against something else than parent. This will
2862 # slightly alter the behavior of revert (doing back up or not, delete
2884 # slightly alter the behavior of revert (doing back up or not, delete
2863 # or just forget etc).
2885 # or just forget etc).
2864 if parent == node:
2886 if parent == node:
2865 dsmodified = modified
2887 dsmodified = modified
2866 dsadded = added
2888 dsadded = added
2867 dsremoved = removed
2889 dsremoved = removed
2868 # store all local modifications, useful later for rename detection
2890 # store all local modifications, useful later for rename detection
2869 localchanges = dsmodified | dsadded
2891 localchanges = dsmodified | dsadded
2870 modified, added, removed = set(), set(), set()
2892 modified, added, removed = set(), set(), set()
2871 else:
2893 else:
2872 changes = repo.status(node1=parent, match=m)
2894 changes = repo.status(node1=parent, match=m)
2873 dsmodified = set(changes.modified)
2895 dsmodified = set(changes.modified)
2874 dsadded = set(changes.added)
2896 dsadded = set(changes.added)
2875 dsremoved = set(changes.removed)
2897 dsremoved = set(changes.removed)
2876 # store all local modifications, useful later for rename detection
2898 # store all local modifications, useful later for rename detection
2877 localchanges = dsmodified | dsadded
2899 localchanges = dsmodified | dsadded
2878
2900
2879 # only take into account for removes between wc and target
2901 # only take into account for removes between wc and target
2880 clean |= dsremoved - removed
2902 clean |= dsremoved - removed
2881 dsremoved &= removed
2903 dsremoved &= removed
2882 # distinct between dirstate remove and other
2904 # distinct between dirstate remove and other
2883 removed -= dsremoved
2905 removed -= dsremoved
2884
2906
2885 modadded = added & dsmodified
2907 modadded = added & dsmodified
2886 added -= modadded
2908 added -= modadded
2887
2909
2888 # tell newly modified apart.
2910 # tell newly modified apart.
2889 dsmodified &= modified
2911 dsmodified &= modified
2890 dsmodified |= modified & dsadded # dirstate added may need backup
2912 dsmodified |= modified & dsadded # dirstate added may need backup
2891 modified -= dsmodified
2913 modified -= dsmodified
2892
2914
2893 # We need to wait for some post-processing to update this set
2915 # We need to wait for some post-processing to update this set
2894 # before making the distinction. The dirstate will be used for
2916 # before making the distinction. The dirstate will be used for
2895 # that purpose.
2917 # that purpose.
2896 dsadded = added
2918 dsadded = added
2897
2919
2898 # in case of merge, files that are actually added can be reported as
2920 # in case of merge, files that are actually added can be reported as
2899 # modified, we need to post process the result
2921 # modified, we need to post process the result
2900 if p2 != nullid:
2922 if p2 != nullid:
2901 mergeadd = set(dsmodified)
2923 mergeadd = set(dsmodified)
2902 for path in dsmodified:
2924 for path in dsmodified:
2903 if path in mf:
2925 if path in mf:
2904 mergeadd.remove(path)
2926 mergeadd.remove(path)
2905 dsadded |= mergeadd
2927 dsadded |= mergeadd
2906 dsmodified -= mergeadd
2928 dsmodified -= mergeadd
2907
2929
2908 # if f is a rename, update `names` to also revert the source
2930 # if f is a rename, update `names` to also revert the source
2909 for f in localchanges:
2931 for f in localchanges:
2910 src = repo.dirstate.copied(f)
2932 src = repo.dirstate.copied(f)
2911 # XXX should we check for rename down to target node?
2933 # XXX should we check for rename down to target node?
2912 if src and src not in names and repo.dirstate[src] == 'r':
2934 if src and src not in names and repo.dirstate[src] == 'r':
2913 dsremoved.add(src)
2935 dsremoved.add(src)
2914 names[src] = True
2936 names[src] = True
2915
2937
2916 # determine the exact nature of the deleted changesets
2938 # determine the exact nature of the deleted changesets
2917 deladded = set(_deleted)
2939 deladded = set(_deleted)
2918 for path in _deleted:
2940 for path in _deleted:
2919 if path in mf:
2941 if path in mf:
2920 deladded.remove(path)
2942 deladded.remove(path)
2921 deleted = _deleted - deladded
2943 deleted = _deleted - deladded
2922
2944
2923 # distinguish between file to forget and the other
2945 # distinguish between file to forget and the other
2924 added = set()
2946 added = set()
2925 for abs in dsadded:
2947 for abs in dsadded:
2926 if repo.dirstate[abs] != 'a':
2948 if repo.dirstate[abs] != 'a':
2927 added.add(abs)
2949 added.add(abs)
2928 dsadded -= added
2950 dsadded -= added
2929
2951
2930 for abs in deladded:
2952 for abs in deladded:
2931 if repo.dirstate[abs] == 'a':
2953 if repo.dirstate[abs] == 'a':
2932 dsadded.add(abs)
2954 dsadded.add(abs)
2933 deladded -= dsadded
2955 deladded -= dsadded
2934
2956
2935 # For files marked as removed, we check if an unknown file is present at
2957 # For files marked as removed, we check if an unknown file is present at
2936 # the same path. If a such file exists it may need to be backed up.
2958 # the same path. If a such file exists it may need to be backed up.
2937 # Making the distinction at this stage helps have simpler backup
2959 # Making the distinction at this stage helps have simpler backup
2938 # logic.
2960 # logic.
2939 removunk = set()
2961 removunk = set()
2940 for abs in removed:
2962 for abs in removed:
2941 target = repo.wjoin(abs)
2963 target = repo.wjoin(abs)
2942 if os.path.lexists(target):
2964 if os.path.lexists(target):
2943 removunk.add(abs)
2965 removunk.add(abs)
2944 removed -= removunk
2966 removed -= removunk
2945
2967
2946 dsremovunk = set()
2968 dsremovunk = set()
2947 for abs in dsremoved:
2969 for abs in dsremoved:
2948 target = repo.wjoin(abs)
2970 target = repo.wjoin(abs)
2949 if os.path.lexists(target):
2971 if os.path.lexists(target):
2950 dsremovunk.add(abs)
2972 dsremovunk.add(abs)
2951 dsremoved -= dsremovunk
2973 dsremoved -= dsremovunk
2952
2974
2953 # action to be actually performed by revert
2975 # action to be actually performed by revert
2954 # (<list of file>, message>) tuple
2976 # (<list of file>, message>) tuple
2955 actions = {'revert': ([], _('reverting %s\n')),
2977 actions = {'revert': ([], _('reverting %s\n')),
2956 'add': ([], _('adding %s\n')),
2978 'add': ([], _('adding %s\n')),
2957 'remove': ([], _('removing %s\n')),
2979 'remove': ([], _('removing %s\n')),
2958 'drop': ([], _('removing %s\n')),
2980 'drop': ([], _('removing %s\n')),
2959 'forget': ([], _('forgetting %s\n')),
2981 'forget': ([], _('forgetting %s\n')),
2960 'undelete': ([], _('undeleting %s\n')),
2982 'undelete': ([], _('undeleting %s\n')),
2961 'noop': (None, _('no changes needed to %s\n')),
2983 'noop': (None, _('no changes needed to %s\n')),
2962 'unknown': (None, _('file not managed: %s\n')),
2984 'unknown': (None, _('file not managed: %s\n')),
2963 }
2985 }
2964
2986
2965 # "constant" that convey the backup strategy.
2987 # "constant" that convey the backup strategy.
2966 # All set to `discard` if `no-backup` is set do avoid checking
2988 # All set to `discard` if `no-backup` is set do avoid checking
2967 # no_backup lower in the code.
2989 # no_backup lower in the code.
2968 # These values are ordered for comparison purposes
2990 # These values are ordered for comparison purposes
2969 backupinteractive = 3 # do backup if interactively modified
2991 backupinteractive = 3 # do backup if interactively modified
2970 backup = 2 # unconditionally do backup
2992 backup = 2 # unconditionally do backup
2971 check = 1 # check if the existing file differs from target
2993 check = 1 # check if the existing file differs from target
2972 discard = 0 # never do backup
2994 discard = 0 # never do backup
2973 if opts.get('no_backup'):
2995 if opts.get('no_backup'):
2974 backupinteractive = backup = check = discard
2996 backupinteractive = backup = check = discard
2975 if interactive:
2997 if interactive:
2976 dsmodifiedbackup = backupinteractive
2998 dsmodifiedbackup = backupinteractive
2977 else:
2999 else:
2978 dsmodifiedbackup = backup
3000 dsmodifiedbackup = backup
2979 tobackup = set()
3001 tobackup = set()
2980
3002
2981 backupanddel = actions['remove']
3003 backupanddel = actions['remove']
2982 if not opts.get('no_backup'):
3004 if not opts.get('no_backup'):
2983 backupanddel = actions['drop']
3005 backupanddel = actions['drop']
2984
3006
2985 disptable = (
3007 disptable = (
2986 # dispatch table:
3008 # dispatch table:
2987 # file state
3009 # file state
2988 # action
3010 # action
2989 # make backup
3011 # make backup
2990
3012
2991 ## Sets that results that will change file on disk
3013 ## Sets that results that will change file on disk
2992 # Modified compared to target, no local change
3014 # Modified compared to target, no local change
2993 (modified, actions['revert'], discard),
3015 (modified, actions['revert'], discard),
2994 # Modified compared to target, but local file is deleted
3016 # Modified compared to target, but local file is deleted
2995 (deleted, actions['revert'], discard),
3017 (deleted, actions['revert'], discard),
2996 # Modified compared to target, local change
3018 # Modified compared to target, local change
2997 (dsmodified, actions['revert'], dsmodifiedbackup),
3019 (dsmodified, actions['revert'], dsmodifiedbackup),
2998 # Added since target
3020 # Added since target
2999 (added, actions['remove'], discard),
3021 (added, actions['remove'], discard),
3000 # Added in working directory
3022 # Added in working directory
3001 (dsadded, actions['forget'], discard),
3023 (dsadded, actions['forget'], discard),
3002 # Added since target, have local modification
3024 # Added since target, have local modification
3003 (modadded, backupanddel, backup),
3025 (modadded, backupanddel, backup),
3004 # Added since target but file is missing in working directory
3026 # Added since target but file is missing in working directory
3005 (deladded, actions['drop'], discard),
3027 (deladded, actions['drop'], discard),
3006 # Removed since target, before working copy parent
3028 # Removed since target, before working copy parent
3007 (removed, actions['add'], discard),
3029 (removed, actions['add'], discard),
3008 # Same as `removed` but an unknown file exists at the same path
3030 # Same as `removed` but an unknown file exists at the same path
3009 (removunk, actions['add'], check),
3031 (removunk, actions['add'], check),
3010 # Removed since targe, marked as such in working copy parent
3032 # Removed since targe, marked as such in working copy parent
3011 (dsremoved, actions['undelete'], discard),
3033 (dsremoved, actions['undelete'], discard),
3012 # Same as `dsremoved` but an unknown file exists at the same path
3034 # Same as `dsremoved` but an unknown file exists at the same path
3013 (dsremovunk, actions['undelete'], check),
3035 (dsremovunk, actions['undelete'], check),
3014 ## the following sets does not result in any file changes
3036 ## the following sets does not result in any file changes
3015 # File with no modification
3037 # File with no modification
3016 (clean, actions['noop'], discard),
3038 (clean, actions['noop'], discard),
3017 # Existing file, not tracked anywhere
3039 # Existing file, not tracked anywhere
3018 (unknown, actions['unknown'], discard),
3040 (unknown, actions['unknown'], discard),
3019 )
3041 )
3020
3042
3021 for abs, exact in sorted(names.items()):
3043 for abs, exact in sorted(names.items()):
3022 # target file to be touch on disk (relative to cwd)
3044 # target file to be touch on disk (relative to cwd)
3023 target = repo.wjoin(abs)
3045 target = repo.wjoin(abs)
3024 # search the entry in the dispatch table.
3046 # search the entry in the dispatch table.
3025 # if the file is in any of these sets, it was touched in the working
3047 # if the file is in any of these sets, it was touched in the working
3026 # directory parent and we are sure it needs to be reverted.
3048 # directory parent and we are sure it needs to be reverted.
3027 for table, (xlist, msg), dobackup in disptable:
3049 for table, (xlist, msg), dobackup in disptable:
3028 if abs not in table:
3050 if abs not in table:
3029 continue
3051 continue
3030 if xlist is not None:
3052 if xlist is not None:
3031 xlist.append(abs)
3053 xlist.append(abs)
3032 if dobackup:
3054 if dobackup:
3033 # If in interactive mode, don't automatically create
3055 # If in interactive mode, don't automatically create
3034 # .orig files (issue4793)
3056 # .orig files (issue4793)
3035 if dobackup == backupinteractive:
3057 if dobackup == backupinteractive:
3036 tobackup.add(abs)
3058 tobackup.add(abs)
3037 elif (backup <= dobackup or wctx[abs].cmp(ctx[abs])):
3059 elif (backup <= dobackup or wctx[abs].cmp(ctx[abs])):
3038 absbakname = scmutil.backuppath(ui, repo, abs)
3060 absbakname = scmutil.backuppath(ui, repo, abs)
3039 bakname = os.path.relpath(absbakname,
3061 bakname = os.path.relpath(absbakname,
3040 start=repo.root)
3062 start=repo.root)
3041 ui.note(_('saving current version of %s as %s\n') %
3063 ui.note(_('saving current version of %s as %s\n') %
3042 (uipathfn(abs), uipathfn(bakname)))
3064 (uipathfn(abs), uipathfn(bakname)))
3043 if not opts.get('dry_run'):
3065 if not opts.get('dry_run'):
3044 if interactive:
3066 if interactive:
3045 util.copyfile(target, absbakname)
3067 util.copyfile(target, absbakname)
3046 else:
3068 else:
3047 util.rename(target, absbakname)
3069 util.rename(target, absbakname)
3048 if opts.get('dry_run'):
3070 if opts.get('dry_run'):
3049 if ui.verbose or not exact:
3071 if ui.verbose or not exact:
3050 ui.status(msg % uipathfn(abs))
3072 ui.status(msg % uipathfn(abs))
3051 elif exact:
3073 elif exact:
3052 ui.warn(msg % uipathfn(abs))
3074 ui.warn(msg % uipathfn(abs))
3053 break
3075 break
3054
3076
3055 if not opts.get('dry_run'):
3077 if not opts.get('dry_run'):
3056 needdata = ('revert', 'add', 'undelete')
3078 needdata = ('revert', 'add', 'undelete')
3057 oplist = [actions[name][0] for name in needdata]
3079 oplist = [actions[name][0] for name in needdata]
3058 prefetch = scmutil.prefetchfiles
3080 prefetch = scmutil.prefetchfiles
3059 matchfiles = scmutil.matchfiles
3081 matchfiles = scmutil.matchfiles
3060 prefetch(repo, [ctx.rev()],
3082 prefetch(repo, [ctx.rev()],
3061 matchfiles(repo,
3083 matchfiles(repo,
3062 [f for sublist in oplist for f in sublist]))
3084 [f for sublist in oplist for f in sublist]))
3063 _performrevert(repo, parents, ctx, names, uipathfn, actions,
3085 _performrevert(repo, parents, ctx, names, uipathfn, actions,
3064 interactive, tobackup)
3086 interactive, tobackup)
3065
3087
3066 if targetsubs:
3088 if targetsubs:
3067 # Revert the subrepos on the revert list
3089 # Revert the subrepos on the revert list
3068 for sub in targetsubs:
3090 for sub in targetsubs:
3069 try:
3091 try:
3070 wctx.sub(sub).revert(ctx.substate[sub], *pats,
3092 wctx.sub(sub).revert(ctx.substate[sub], *pats,
3071 **pycompat.strkwargs(opts))
3093 **pycompat.strkwargs(opts))
3072 except KeyError:
3094 except KeyError:
3073 raise error.Abort("subrepository '%s' does not exist in %s!"
3095 raise error.Abort("subrepository '%s' does not exist in %s!"
3074 % (sub, short(ctx.node())))
3096 % (sub, short(ctx.node())))
3075
3097
3076 def _performrevert(repo, parents, ctx, names, uipathfn, actions,
3098 def _performrevert(repo, parents, ctx, names, uipathfn, actions,
3077 interactive=False, tobackup=None):
3099 interactive=False, tobackup=None):
3078 """function that actually perform all the actions computed for revert
3100 """function that actually perform all the actions computed for revert
3079
3101
3080 This is an independent function to let extension to plug in and react to
3102 This is an independent function to let extension to plug in and react to
3081 the imminent revert.
3103 the imminent revert.
3082
3104
3083 Make sure you have the working directory locked when calling this function.
3105 Make sure you have the working directory locked when calling this function.
3084 """
3106 """
3085 parent, p2 = parents
3107 parent, p2 = parents
3086 node = ctx.node()
3108 node = ctx.node()
3087 excluded_files = []
3109 excluded_files = []
3088
3110
3089 def checkout(f):
3111 def checkout(f):
3090 fc = ctx[f]
3112 fc = ctx[f]
3091 repo.wwrite(f, fc.data(), fc.flags())
3113 repo.wwrite(f, fc.data(), fc.flags())
3092
3114
3093 def doremove(f):
3115 def doremove(f):
3094 try:
3116 try:
3095 rmdir = repo.ui.configbool('experimental', 'removeemptydirs')
3117 rmdir = repo.ui.configbool('experimental', 'removeemptydirs')
3096 repo.wvfs.unlinkpath(f, rmdir=rmdir)
3118 repo.wvfs.unlinkpath(f, rmdir=rmdir)
3097 except OSError:
3119 except OSError:
3098 pass
3120 pass
3099 repo.dirstate.remove(f)
3121 repo.dirstate.remove(f)
3100
3122
3101 def prntstatusmsg(action, f):
3123 def prntstatusmsg(action, f):
3102 exact = names[f]
3124 exact = names[f]
3103 if repo.ui.verbose or not exact:
3125 if repo.ui.verbose or not exact:
3104 repo.ui.status(actions[action][1] % uipathfn(f))
3126 repo.ui.status(actions[action][1] % uipathfn(f))
3105
3127
3106 audit_path = pathutil.pathauditor(repo.root, cached=True)
3128 audit_path = pathutil.pathauditor(repo.root, cached=True)
3107 for f in actions['forget'][0]:
3129 for f in actions['forget'][0]:
3108 if interactive:
3130 if interactive:
3109 choice = repo.ui.promptchoice(
3131 choice = repo.ui.promptchoice(
3110 _("forget added file %s (Yn)?$$ &Yes $$ &No") % uipathfn(f))
3132 _("forget added file %s (Yn)?$$ &Yes $$ &No") % uipathfn(f))
3111 if choice == 0:
3133 if choice == 0:
3112 prntstatusmsg('forget', f)
3134 prntstatusmsg('forget', f)
3113 repo.dirstate.drop(f)
3135 repo.dirstate.drop(f)
3114 else:
3136 else:
3115 excluded_files.append(f)
3137 excluded_files.append(f)
3116 else:
3138 else:
3117 prntstatusmsg('forget', f)
3139 prntstatusmsg('forget', f)
3118 repo.dirstate.drop(f)
3140 repo.dirstate.drop(f)
3119 for f in actions['remove'][0]:
3141 for f in actions['remove'][0]:
3120 audit_path(f)
3142 audit_path(f)
3121 if interactive:
3143 if interactive:
3122 choice = repo.ui.promptchoice(
3144 choice = repo.ui.promptchoice(
3123 _("remove added file %s (Yn)?$$ &Yes $$ &No") % uipathfn(f))
3145 _("remove added file %s (Yn)?$$ &Yes $$ &No") % uipathfn(f))
3124 if choice == 0:
3146 if choice == 0:
3125 prntstatusmsg('remove', f)
3147 prntstatusmsg('remove', f)
3126 doremove(f)
3148 doremove(f)
3127 else:
3149 else:
3128 excluded_files.append(f)
3150 excluded_files.append(f)
3129 else:
3151 else:
3130 prntstatusmsg('remove', f)
3152 prntstatusmsg('remove', f)
3131 doremove(f)
3153 doremove(f)
3132 for f in actions['drop'][0]:
3154 for f in actions['drop'][0]:
3133 audit_path(f)
3155 audit_path(f)
3134 prntstatusmsg('drop', f)
3156 prntstatusmsg('drop', f)
3135 repo.dirstate.remove(f)
3157 repo.dirstate.remove(f)
3136
3158
3137 normal = None
3159 normal = None
3138 if node == parent:
3160 if node == parent:
3139 # We're reverting to our parent. If possible, we'd like status
3161 # We're reverting to our parent. If possible, we'd like status
3140 # to report the file as clean. We have to use normallookup for
3162 # to report the file as clean. We have to use normallookup for
3141 # merges to avoid losing information about merged/dirty files.
3163 # merges to avoid losing information about merged/dirty files.
3142 if p2 != nullid:
3164 if p2 != nullid:
3143 normal = repo.dirstate.normallookup
3165 normal = repo.dirstate.normallookup
3144 else:
3166 else:
3145 normal = repo.dirstate.normal
3167 normal = repo.dirstate.normal
3146
3168
3147 newlyaddedandmodifiedfiles = set()
3169 newlyaddedandmodifiedfiles = set()
3148 if interactive:
3170 if interactive:
3149 # Prompt the user for changes to revert
3171 # Prompt the user for changes to revert
3150 torevert = [f for f in actions['revert'][0] if f not in excluded_files]
3172 torevert = [f for f in actions['revert'][0] if f not in excluded_files]
3151 m = scmutil.matchfiles(repo, torevert)
3173 m = scmutil.matchfiles(repo, torevert)
3152 diffopts = patch.difffeatureopts(repo.ui, whitespace=True,
3174 diffopts = patch.difffeatureopts(repo.ui, whitespace=True,
3153 section='commands',
3175 section='commands',
3154 configprefix='revert.interactive.')
3176 configprefix='revert.interactive.')
3155 diffopts.nodates = True
3177 diffopts.nodates = True
3156 diffopts.git = True
3178 diffopts.git = True
3157 operation = 'discard'
3179 operation = 'discard'
3158 reversehunks = True
3180 reversehunks = True
3159 if node != parent:
3181 if node != parent:
3160 operation = 'apply'
3182 operation = 'apply'
3161 reversehunks = False
3183 reversehunks = False
3162 if reversehunks:
3184 if reversehunks:
3163 diff = patch.diff(repo, ctx.node(), None, m, opts=diffopts)
3185 diff = patch.diff(repo, ctx.node(), None, m, opts=diffopts)
3164 else:
3186 else:
3165 diff = patch.diff(repo, None, ctx.node(), m, opts=diffopts)
3187 diff = patch.diff(repo, None, ctx.node(), m, opts=diffopts)
3166 originalchunks = patch.parsepatch(diff)
3188 originalchunks = patch.parsepatch(diff)
3167
3189
3168 try:
3190 try:
3169
3191
3170 chunks, opts = recordfilter(repo.ui, originalchunks,
3192 chunks, opts = recordfilter(repo.ui, originalchunks,
3171 operation=operation)
3193 operation=operation)
3172 if reversehunks:
3194 if reversehunks:
3173 chunks = patch.reversehunks(chunks)
3195 chunks = patch.reversehunks(chunks)
3174
3196
3175 except error.PatchError as err:
3197 except error.PatchError as err:
3176 raise error.Abort(_('error parsing patch: %s') % err)
3198 raise error.Abort(_('error parsing patch: %s') % err)
3177
3199
3178 newlyaddedandmodifiedfiles = newandmodified(chunks, originalchunks)
3200 newlyaddedandmodifiedfiles = newandmodified(chunks, originalchunks)
3179 if tobackup is None:
3201 if tobackup is None:
3180 tobackup = set()
3202 tobackup = set()
3181 # Apply changes
3203 # Apply changes
3182 fp = stringio()
3204 fp = stringio()
3183 # chunks are serialized per file, but files aren't sorted
3205 # chunks are serialized per file, but files aren't sorted
3184 for f in sorted(set(c.header.filename() for c in chunks if ishunk(c))):
3206 for f in sorted(set(c.header.filename() for c in chunks if ishunk(c))):
3185 prntstatusmsg('revert', f)
3207 prntstatusmsg('revert', f)
3186 for c in chunks:
3208 for c in chunks:
3187 if ishunk(c):
3209 if ishunk(c):
3188 abs = c.header.filename()
3210 abs = c.header.filename()
3189 # Create a backup file only if this hunk should be backed up
3211 # Create a backup file only if this hunk should be backed up
3190 if c.header.filename() in tobackup:
3212 if c.header.filename() in tobackup:
3191 target = repo.wjoin(abs)
3213 target = repo.wjoin(abs)
3192 bakname = scmutil.backuppath(repo.ui, repo, abs)
3214 bakname = scmutil.backuppath(repo.ui, repo, abs)
3193 util.copyfile(target, bakname)
3215 util.copyfile(target, bakname)
3194 tobackup.remove(abs)
3216 tobackup.remove(abs)
3195 c.write(fp)
3217 c.write(fp)
3196 dopatch = fp.tell()
3218 dopatch = fp.tell()
3197 fp.seek(0)
3219 fp.seek(0)
3198 if dopatch:
3220 if dopatch:
3199 try:
3221 try:
3200 patch.internalpatch(repo.ui, repo, fp, 1, eolmode=None)
3222 patch.internalpatch(repo.ui, repo, fp, 1, eolmode=None)
3201 except error.PatchError as err:
3223 except error.PatchError as err:
3202 raise error.Abort(pycompat.bytestr(err))
3224 raise error.Abort(pycompat.bytestr(err))
3203 del fp
3225 del fp
3204 else:
3226 else:
3205 for f in actions['revert'][0]:
3227 for f in actions['revert'][0]:
3206 prntstatusmsg('revert', f)
3228 prntstatusmsg('revert', f)
3207 checkout(f)
3229 checkout(f)
3208 if normal:
3230 if normal:
3209 normal(f)
3231 normal(f)
3210
3232
3211 for f in actions['add'][0]:
3233 for f in actions['add'][0]:
3212 # Don't checkout modified files, they are already created by the diff
3234 # Don't checkout modified files, they are already created by the diff
3213 if f not in newlyaddedandmodifiedfiles:
3235 if f not in newlyaddedandmodifiedfiles:
3214 prntstatusmsg('add', f)
3236 prntstatusmsg('add', f)
3215 checkout(f)
3237 checkout(f)
3216 repo.dirstate.add(f)
3238 repo.dirstate.add(f)
3217
3239
3218 normal = repo.dirstate.normallookup
3240 normal = repo.dirstate.normallookup
3219 if node == parent and p2 == nullid:
3241 if node == parent and p2 == nullid:
3220 normal = repo.dirstate.normal
3242 normal = repo.dirstate.normal
3221 for f in actions['undelete'][0]:
3243 for f in actions['undelete'][0]:
3222 if interactive:
3244 if interactive:
3223 choice = repo.ui.promptchoice(
3245 choice = repo.ui.promptchoice(
3224 _("add back removed file %s (Yn)?$$ &Yes $$ &No") % f)
3246 _("add back removed file %s (Yn)?$$ &Yes $$ &No") % f)
3225 if choice == 0:
3247 if choice == 0:
3226 prntstatusmsg('undelete', f)
3248 prntstatusmsg('undelete', f)
3227 checkout(f)
3249 checkout(f)
3228 normal(f)
3250 normal(f)
3229 else:
3251 else:
3230 excluded_files.append(f)
3252 excluded_files.append(f)
3231 else:
3253 else:
3232 prntstatusmsg('undelete', f)
3254 prntstatusmsg('undelete', f)
3233 checkout(f)
3255 checkout(f)
3234 normal(f)
3256 normal(f)
3235
3257
3236 copied = copies.pathcopies(repo[parent], ctx)
3258 copied = copies.pathcopies(repo[parent], ctx)
3237
3259
3238 for f in actions['add'][0] + actions['undelete'][0] + actions['revert'][0]:
3260 for f in actions['add'][0] + actions['undelete'][0] + actions['revert'][0]:
3239 if f in copied:
3261 if f in copied:
3240 repo.dirstate.copy(copied[f], f)
3262 repo.dirstate.copy(copied[f], f)
3241
3263
3242 # a list of (ui, repo, otherpeer, opts, missing) functions called by
3264 # a list of (ui, repo, otherpeer, opts, missing) functions called by
3243 # commands.outgoing. "missing" is "missing" of the result of
3265 # commands.outgoing. "missing" is "missing" of the result of
3244 # "findcommonoutgoing()"
3266 # "findcommonoutgoing()"
3245 outgoinghooks = util.hooks()
3267 outgoinghooks = util.hooks()
3246
3268
3247 # a list of (ui, repo) functions called by commands.summary
3269 # a list of (ui, repo) functions called by commands.summary
3248 summaryhooks = util.hooks()
3270 summaryhooks = util.hooks()
3249
3271
3250 # a list of (ui, repo, opts, changes) functions called by commands.summary.
3272 # a list of (ui, repo, opts, changes) functions called by commands.summary.
3251 #
3273 #
3252 # functions should return tuple of booleans below, if 'changes' is None:
3274 # functions should return tuple of booleans below, if 'changes' is None:
3253 # (whether-incomings-are-needed, whether-outgoings-are-needed)
3275 # (whether-incomings-are-needed, whether-outgoings-are-needed)
3254 #
3276 #
3255 # otherwise, 'changes' is a tuple of tuples below:
3277 # otherwise, 'changes' is a tuple of tuples below:
3256 # - (sourceurl, sourcebranch, sourcepeer, incoming)
3278 # - (sourceurl, sourcebranch, sourcepeer, incoming)
3257 # - (desturl, destbranch, destpeer, outgoing)
3279 # - (desturl, destbranch, destpeer, outgoing)
3258 summaryremotehooks = util.hooks()
3280 summaryremotehooks = util.hooks()
3259
3281
3260 # A list of state files kept by multistep operations like graft.
3282 # A list of state files kept by multistep operations like graft.
3261 # Since graft cannot be aborted, it is considered 'clearable' by update.
3283 # Since graft cannot be aborted, it is considered 'clearable' by update.
3262 # note: bisect is intentionally excluded
3284 # note: bisect is intentionally excluded
3263 # (state file, clearable, allowcommit, error, hint)
3285 # (state file, clearable, allowcommit, error, hint)
3264 unfinishedstates = [
3286 unfinishedstates = [
3265 ('graftstate', True, False, _('graft in progress'),
3287 ('graftstate', True, False, _('graft in progress'),
3266 _("use 'hg graft --continue' or 'hg graft --stop' to stop")),
3288 _("use 'hg graft --continue' or 'hg graft --stop' to stop")),
3267 ('updatestate', True, False, _('last update was interrupted'),
3289 ('updatestate', True, False, _('last update was interrupted'),
3268 _("use 'hg update' to get a consistent checkout"))
3290 _("use 'hg update' to get a consistent checkout"))
3269 ]
3291 ]
3270
3292
3271 def checkunfinished(repo, commit=False):
3293 def checkunfinished(repo, commit=False):
3272 '''Look for an unfinished multistep operation, like graft, and abort
3294 '''Look for an unfinished multistep operation, like graft, and abort
3273 if found. It's probably good to check this right before
3295 if found. It's probably good to check this right before
3274 bailifchanged().
3296 bailifchanged().
3275 '''
3297 '''
3276 # Check for non-clearable states first, so things like rebase will take
3298 # Check for non-clearable states first, so things like rebase will take
3277 # precedence over update.
3299 # precedence over update.
3278 for f, clearable, allowcommit, msg, hint in unfinishedstates:
3300 for f, clearable, allowcommit, msg, hint in unfinishedstates:
3279 if clearable or (commit and allowcommit):
3301 if clearable or (commit and allowcommit):
3280 continue
3302 continue
3281 if repo.vfs.exists(f):
3303 if repo.vfs.exists(f):
3282 raise error.Abort(msg, hint=hint)
3304 raise error.Abort(msg, hint=hint)
3283
3305
3284 for f, clearable, allowcommit, msg, hint in unfinishedstates:
3306 for f, clearable, allowcommit, msg, hint in unfinishedstates:
3285 if not clearable or (commit and allowcommit):
3307 if not clearable or (commit and allowcommit):
3286 continue
3308 continue
3287 if repo.vfs.exists(f):
3309 if repo.vfs.exists(f):
3288 raise error.Abort(msg, hint=hint)
3310 raise error.Abort(msg, hint=hint)
3289
3311
3290 def clearunfinished(repo):
3312 def clearunfinished(repo):
3291 '''Check for unfinished operations (as above), and clear the ones
3313 '''Check for unfinished operations (as above), and clear the ones
3292 that are clearable.
3314 that are clearable.
3293 '''
3315 '''
3294 for f, clearable, allowcommit, msg, hint in unfinishedstates:
3316 for f, clearable, allowcommit, msg, hint in unfinishedstates:
3295 if not clearable and repo.vfs.exists(f):
3317 if not clearable and repo.vfs.exists(f):
3296 raise error.Abort(msg, hint=hint)
3318 raise error.Abort(msg, hint=hint)
3297 for f, clearable, allowcommit, msg, hint in unfinishedstates:
3319 for f, clearable, allowcommit, msg, hint in unfinishedstates:
3298 if clearable and repo.vfs.exists(f):
3320 if clearable and repo.vfs.exists(f):
3299 util.unlink(repo.vfs.join(f))
3321 util.unlink(repo.vfs.join(f))
3300
3322
3301 afterresolvedstates = [
3323 afterresolvedstates = [
3302 ('graftstate',
3324 ('graftstate',
3303 _('hg graft --continue')),
3325 _('hg graft --continue')),
3304 ]
3326 ]
3305
3327
3306 def howtocontinue(repo):
3328 def howtocontinue(repo):
3307 '''Check for an unfinished operation and return the command to finish
3329 '''Check for an unfinished operation and return the command to finish
3308 it.
3330 it.
3309
3331
3310 afterresolvedstates tuples define a .hg/{file} and the corresponding
3332 afterresolvedstates tuples define a .hg/{file} and the corresponding
3311 command needed to finish it.
3333 command needed to finish it.
3312
3334
3313 Returns a (msg, warning) tuple. 'msg' is a string and 'warning' is
3335 Returns a (msg, warning) tuple. 'msg' is a string and 'warning' is
3314 a boolean.
3336 a boolean.
3315 '''
3337 '''
3316 contmsg = _("continue: %s")
3338 contmsg = _("continue: %s")
3317 for f, msg in afterresolvedstates:
3339 for f, msg in afterresolvedstates:
3318 if repo.vfs.exists(f):
3340 if repo.vfs.exists(f):
3319 return contmsg % msg, True
3341 return contmsg % msg, True
3320 if repo[None].dirty(missing=True, merge=False, branch=False):
3342 if repo[None].dirty(missing=True, merge=False, branch=False):
3321 return contmsg % _("hg commit"), False
3343 return contmsg % _("hg commit"), False
3322 return None, None
3344 return None, None
3323
3345
3324 def checkafterresolved(repo):
3346 def checkafterresolved(repo):
3325 '''Inform the user about the next action after completing hg resolve
3347 '''Inform the user about the next action after completing hg resolve
3326
3348
3327 If there's a matching afterresolvedstates, howtocontinue will yield
3349 If there's a matching afterresolvedstates, howtocontinue will yield
3328 repo.ui.warn as the reporter.
3350 repo.ui.warn as the reporter.
3329
3351
3330 Otherwise, it will yield repo.ui.note.
3352 Otherwise, it will yield repo.ui.note.
3331 '''
3353 '''
3332 msg, warning = howtocontinue(repo)
3354 msg, warning = howtocontinue(repo)
3333 if msg is not None:
3355 if msg is not None:
3334 if warning:
3356 if warning:
3335 repo.ui.warn("%s\n" % msg)
3357 repo.ui.warn("%s\n" % msg)
3336 else:
3358 else:
3337 repo.ui.note("%s\n" % msg)
3359 repo.ui.note("%s\n" % msg)
3338
3360
3339 def wrongtooltocontinue(repo, task):
3361 def wrongtooltocontinue(repo, task):
3340 '''Raise an abort suggesting how to properly continue if there is an
3362 '''Raise an abort suggesting how to properly continue if there is an
3341 active task.
3363 active task.
3342
3364
3343 Uses howtocontinue() to find the active task.
3365 Uses howtocontinue() to find the active task.
3344
3366
3345 If there's no task (repo.ui.note for 'hg commit'), it does not offer
3367 If there's no task (repo.ui.note for 'hg commit'), it does not offer
3346 a hint.
3368 a hint.
3347 '''
3369 '''
3348 after = howtocontinue(repo)
3370 after = howtocontinue(repo)
3349 hint = None
3371 hint = None
3350 if after[1]:
3372 if after[1]:
3351 hint = after[0]
3373 hint = after[0]
3352 raise error.Abort(_('no %s in progress') % task, hint=hint)
3374 raise error.Abort(_('no %s in progress') % task, hint=hint)
@@ -1,154 +1,167 b''
1 #testcases obsstore-off obsstore-on
1 #testcases obsstore-off obsstore-on
2
2
3 $ cat << EOF >> $HGRCPATH
3 $ cat << EOF >> $HGRCPATH
4 > [extensions]
4 > [extensions]
5 > amend =
5 > amend =
6 > EOF
6 > EOF
7
7
8 #if obsstore-on
8 #if obsstore-on
9 $ cat << EOF >> $HGRCPATH
9 $ cat << EOF >> $HGRCPATH
10 > [experimental]
10 > [experimental]
11 > evolution.createmarkers = True
11 > evolution.createmarkers = True
12 > EOF
12 > EOF
13 #endif
13 #endif
14
14
15 Prepare parent repo
15 Prepare parent repo
16 -------------------
16 -------------------
17
17
18 $ hg init r
18 $ hg init r
19 $ cd r
19 $ cd r
20
20
21 $ echo a > a
21 $ echo a > a
22 $ hg ci -Am0
22 $ hg ci -Am0
23 adding a
23 adding a
24
24
25 Link first subrepo
25 Link first subrepo
26 ------------------
26 ------------------
27
27
28 $ echo 's = s' >> .hgsub
28 $ echo 's = s' >> .hgsub
29 $ hg add .hgsub
29 $ hg add .hgsub
30 $ hg init s
30 $ hg init s
31
31
32 amend without .hgsub
32 amend without .hgsub
33
33
34 $ hg amend s
34 $ hg amend s
35 abort: can't commit subrepos without .hgsub
35 abort: can't commit subrepos without .hgsub
36 [255]
36 [255]
37
37
38 amend with subrepo
38 amend with subrepo
39
39
40 $ hg amend
40 $ hg amend
41 saved backup bundle to * (glob) (obsstore-off !)
41 saved backup bundle to * (glob) (obsstore-off !)
42 $ hg status --change .
42 $ hg status --change .
43 A .hgsub
43 A .hgsub
44 A .hgsubstate
44 A .hgsubstate
45 A a
45 A a
46 $ cat .hgsubstate
46 $ cat .hgsubstate
47 0000000000000000000000000000000000000000 s
47 0000000000000000000000000000000000000000 s
48
48
49 Update subrepo
49 Update subrepo
50 --------------
50 --------------
51
51
52 add new commit to be amended
52 add new commit to be amended
53
53
54 $ echo a >> a
54 $ echo a >> a
55 $ hg ci -m1
55 $ hg ci -m1
56
56
57 amend with dirty subrepo
57 amend with dirty subrepo
58
58
59 $ echo a >> s/a
59 $ echo a >> s/a
60 $ hg add -R s
60 $ hg add -R s
61 adding s/a
61 adding s/a
62 $ hg amend
62 $ hg amend
63 abort: uncommitted changes in subrepository "s"
63 abort: uncommitted changes in subrepository "s"
64 (use --subrepos for recursive commit)
64 (use --subrepos for recursive commit)
65 [255]
65 [255]
66
66
67 amend with modified subrepo
67 amend with modified subrepo
68
68
69 $ hg ci -R s -m0
69 $ hg ci -R s -m0
70 $ hg amend
70 $ hg amend
71 saved backup bundle to * (glob) (obsstore-off !)
71 saved backup bundle to * (glob) (obsstore-off !)
72 $ hg status --change .
72 $ hg status --change .
73 M .hgsubstate
73 M .hgsubstate
74 M a
74 M a
75 $ cat .hgsubstate
75 $ cat .hgsubstate
76 f7b1eb17ad24730a1651fccd46c43826d1bbc2ac s
76 f7b1eb17ad24730a1651fccd46c43826d1bbc2ac s
77
77
78 revert subrepo change
78 revert subrepo change
79
79
80 $ hg up -R s -q null
80 $ hg up -R s -q null
81 $ hg amend
81 $ hg amend
82 saved backup bundle to * (glob) (obsstore-off !)
82 saved backup bundle to * (glob) (obsstore-off !)
83 $ hg status --change .
83 $ hg status --change .
84 M a
84 M a
85
85
86 Link another subrepo
86 Link another subrepo
87 --------------------
87 --------------------
88
88
89 add new commit to be amended
89 add new commit to be amended
90
90
91 $ echo b >> b
91 $ echo b >> b
92 $ hg ci -qAm2
92 $ hg ci -qAm2
93
93
94 also checks if non-subrepo change is included
94 also checks if non-subrepo change is included
95
95
96 $ echo a >> a
96 $ echo a >> a
97
97
98 amend with another subrepo
98 amend with another subrepo
99
99
100 $ hg init t
100 $ hg init t
101 $ echo b >> t/b
101 $ echo b >> t/b
102 $ hg ci -R t -Am0
102 $ hg ci -R t -Am0
103 adding b
103 adding b
104 $ echo 't = t' >> .hgsub
104 $ echo 't = t' >> .hgsub
105 $ hg amend
105 $ hg amend
106 saved backup bundle to * (glob) (obsstore-off !)
106 saved backup bundle to * (glob) (obsstore-off !)
107 $ hg status --change .
107 $ hg status --change .
108 M .hgsub
108 M .hgsub
109 M .hgsubstate
109 M .hgsubstate
110 M a
110 M a
111 A b
111 A b
112 $ cat .hgsubstate
112 $ cat .hgsubstate
113 0000000000000000000000000000000000000000 s
113 0000000000000000000000000000000000000000 s
114 bfb1a4fb358498a9533dabf4f2043d94162f1fcd t
114 bfb1a4fb358498a9533dabf4f2043d94162f1fcd t
115
115
116 Unlink one subrepo
116 Unlink one subrepo
117 ------------------
117 ------------------
118
118
119 add new commit to be amended
119 add new commit to be amended
120
120
121 $ echo a >> a
121 $ echo a >> a
122 $ hg ci -m3
122 $ hg ci -m3
123
123
124 $ echo 't = t' > .hgsub
125
126 --interactive won't silently ignore dirty subrepos
127
128 $ echo modified > t/b
129 $ hg amend --interactive --config ui.interactive=True
130 abort: uncommitted changes in subrepository "t"
131 [255]
132 $ hg amend --interactive --config ui.interactive=True --config ui.commitsubrepos=True
133 abort: uncommitted changes in subrepository "t"
134 [255]
135
136 $ hg -R t revert -q --all --no-backup
137
124 amend with one subrepo dropped
138 amend with one subrepo dropped
125
139
126 $ echo 't = t' > .hgsub
127 $ hg amend
140 $ hg amend
128 saved backup bundle to * (glob) (obsstore-off !)
141 saved backup bundle to * (glob) (obsstore-off !)
129 $ hg status --change .
142 $ hg status --change .
130 M .hgsub
143 M .hgsub
131 M .hgsubstate
144 M .hgsubstate
132 M a
145 M a
133 $ cat .hgsubstate
146 $ cat .hgsubstate
134 bfb1a4fb358498a9533dabf4f2043d94162f1fcd t
147 bfb1a4fb358498a9533dabf4f2043d94162f1fcd t
135
148
136 Unlink subrepos completely
149 Unlink subrepos completely
137 --------------------------
150 --------------------------
138
151
139 add new commit to be amended
152 add new commit to be amended
140
153
141 $ echo a >> a
154 $ echo a >> a
142 $ hg ci -m3
155 $ hg ci -m3
143
156
144 amend with .hgsub removed
157 amend with .hgsub removed
145
158
146 $ hg rm .hgsub
159 $ hg rm .hgsub
147 $ hg amend
160 $ hg amend
148 saved backup bundle to * (glob) (obsstore-off !)
161 saved backup bundle to * (glob) (obsstore-off !)
149 $ hg status --change .
162 $ hg status --change .
150 M a
163 M a
151 R .hgsub
164 R .hgsub
152 R .hgsubstate
165 R .hgsubstate
153
166
154 $ cd ..
167 $ cd ..
@@ -1,675 +1,681 b''
1 #require serve ssl
1 #require serve ssl
2
2
3 Proper https client requires the built-in ssl from Python 2.6.
3 Proper https client requires the built-in ssl from Python 2.6.
4
4
5 Disable the system configuration which may set stricter TLS requirements.
6 This test expects that legacy TLS versions are supported.
7
8 $ OPENSSL_CONF=
9 $ export OPENSSL_CONF
10
5 Make server certificates:
11 Make server certificates:
6
12
7 $ CERTSDIR="$TESTDIR/sslcerts"
13 $ CERTSDIR="$TESTDIR/sslcerts"
8 $ cat "$CERTSDIR/priv.pem" "$CERTSDIR/pub.pem" >> server.pem
14 $ cat "$CERTSDIR/priv.pem" "$CERTSDIR/pub.pem" >> server.pem
9 $ PRIV=`pwd`/server.pem
15 $ PRIV=`pwd`/server.pem
10 $ cat "$CERTSDIR/priv.pem" "$CERTSDIR/pub-not-yet.pem" > server-not-yet.pem
16 $ cat "$CERTSDIR/priv.pem" "$CERTSDIR/pub-not-yet.pem" > server-not-yet.pem
11 $ cat "$CERTSDIR/priv.pem" "$CERTSDIR/pub-expired.pem" > server-expired.pem
17 $ cat "$CERTSDIR/priv.pem" "$CERTSDIR/pub-expired.pem" > server-expired.pem
12
18
13 $ hg init test
19 $ hg init test
14 $ cd test
20 $ cd test
15 $ echo foo>foo
21 $ echo foo>foo
16 $ mkdir foo.d foo.d/bAr.hg.d foo.d/baR.d.hg
22 $ mkdir foo.d foo.d/bAr.hg.d foo.d/baR.d.hg
17 $ echo foo>foo.d/foo
23 $ echo foo>foo.d/foo
18 $ echo bar>foo.d/bAr.hg.d/BaR
24 $ echo bar>foo.d/bAr.hg.d/BaR
19 $ echo bar>foo.d/baR.d.hg/bAR
25 $ echo bar>foo.d/baR.d.hg/bAR
20 $ hg commit -A -m 1
26 $ hg commit -A -m 1
21 adding foo
27 adding foo
22 adding foo.d/bAr.hg.d/BaR
28 adding foo.d/bAr.hg.d/BaR
23 adding foo.d/baR.d.hg/bAR
29 adding foo.d/baR.d.hg/bAR
24 adding foo.d/foo
30 adding foo.d/foo
25 $ hg serve -p $HGPORT -d --pid-file=../hg0.pid --certificate=$PRIV
31 $ hg serve -p $HGPORT -d --pid-file=../hg0.pid --certificate=$PRIV
26 $ cat ../hg0.pid >> $DAEMON_PIDS
32 $ cat ../hg0.pid >> $DAEMON_PIDS
27
33
28 cacert not found
34 cacert not found
29
35
30 $ hg in --config web.cacerts=no-such.pem https://localhost:$HGPORT/
36 $ hg in --config web.cacerts=no-such.pem https://localhost:$HGPORT/
31 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
37 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
32 abort: could not find web.cacerts: no-such.pem
38 abort: could not find web.cacerts: no-such.pem
33 [255]
39 [255]
34
40
35 Test server address cannot be reused
41 Test server address cannot be reused
36
42
37 $ hg serve -p $HGPORT --certificate=$PRIV 2>&1
43 $ hg serve -p $HGPORT --certificate=$PRIV 2>&1
38 abort: cannot start server at 'localhost:$HGPORT': $EADDRINUSE$
44 abort: cannot start server at 'localhost:$HGPORT': $EADDRINUSE$
39 [255]
45 [255]
40
46
41 $ cd ..
47 $ cd ..
42
48
43 Our test cert is not signed by a trusted CA. It should fail to verify if
49 Our test cert is not signed by a trusted CA. It should fail to verify if
44 we are able to load CA certs.
50 we are able to load CA certs.
45
51
46 #if sslcontext defaultcacerts no-defaultcacertsloaded
52 #if sslcontext defaultcacerts no-defaultcacertsloaded
47 $ hg clone https://localhost:$HGPORT/ copy-pull
53 $ hg clone https://localhost:$HGPORT/ copy-pull
48 (an attempt was made to load CA certificates but none were loaded; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this error)
54 (an attempt was made to load CA certificates but none were loaded; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this error)
49 abort: error: *certificate verify failed* (glob)
55 abort: error: *certificate verify failed* (glob)
50 [255]
56 [255]
51 #endif
57 #endif
52
58
53 #if no-sslcontext defaultcacerts
59 #if no-sslcontext defaultcacerts
54 $ hg clone https://localhost:$HGPORT/ copy-pull
60 $ hg clone https://localhost:$HGPORT/ copy-pull
55 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
61 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
56 (using CA certificates from *; if you see this message, your Mercurial install is not properly configured; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this message) (glob) (?)
62 (using CA certificates from *; if you see this message, your Mercurial install is not properly configured; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this message) (glob) (?)
57 abort: error: *certificate verify failed* (glob)
63 abort: error: *certificate verify failed* (glob)
58 [255]
64 [255]
59 #endif
65 #endif
60
66
61 #if no-sslcontext windows
67 #if no-sslcontext windows
62 $ hg clone https://localhost:$HGPORT/ copy-pull
68 $ hg clone https://localhost:$HGPORT/ copy-pull
63 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info
69 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info
64 (unable to load Windows CA certificates; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this message)
70 (unable to load Windows CA certificates; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this message)
65 abort: error: *certificate verify failed* (glob)
71 abort: error: *certificate verify failed* (glob)
66 [255]
72 [255]
67 #endif
73 #endif
68
74
69 #if no-sslcontext osx
75 #if no-sslcontext osx
70 $ hg clone https://localhost:$HGPORT/ copy-pull
76 $ hg clone https://localhost:$HGPORT/ copy-pull
71 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info
77 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info
72 (unable to load CA certificates; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this message)
78 (unable to load CA certificates; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this message)
73 abort: localhost certificate error: no certificate received
79 abort: localhost certificate error: no certificate received
74 (set hostsecurity.localhost:certfingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e config setting or use --insecure to connect insecurely)
80 (set hostsecurity.localhost:certfingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e config setting or use --insecure to connect insecurely)
75 [255]
81 [255]
76 #endif
82 #endif
77
83
78 #if defaultcacertsloaded
84 #if defaultcacertsloaded
79 $ hg clone https://localhost:$HGPORT/ copy-pull
85 $ hg clone https://localhost:$HGPORT/ copy-pull
80 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
86 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
81 (using CA certificates from *; if you see this message, your Mercurial install is not properly configured; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this message) (glob) (?)
87 (using CA certificates from *; if you see this message, your Mercurial install is not properly configured; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this message) (glob) (?)
82 (the full certificate chain may not be available locally; see "hg help debugssl") (windows !)
88 (the full certificate chain may not be available locally; see "hg help debugssl") (windows !)
83 abort: error: *certificate verify failed* (glob)
89 abort: error: *certificate verify failed* (glob)
84 [255]
90 [255]
85 #endif
91 #endif
86
92
87 #if no-defaultcacerts
93 #if no-defaultcacerts
88 $ hg clone https://localhost:$HGPORT/ copy-pull
94 $ hg clone https://localhost:$HGPORT/ copy-pull
89 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
95 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
90 (unable to load * certificates; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this message) (glob) (?)
96 (unable to load * certificates; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this message) (glob) (?)
91 abort: localhost certificate error: no certificate received
97 abort: localhost certificate error: no certificate received
92 (set hostsecurity.localhost:certfingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e config setting or use --insecure to connect insecurely)
98 (set hostsecurity.localhost:certfingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e config setting or use --insecure to connect insecurely)
93 [255]
99 [255]
94 #endif
100 #endif
95
101
96 Specifying a per-host certificate file that doesn't exist will abort. The full
102 Specifying a per-host certificate file that doesn't exist will abort. The full
97 C:/path/to/msysroot will print on Windows.
103 C:/path/to/msysroot will print on Windows.
98
104
99 $ hg --config hostsecurity.localhost:verifycertsfile=/does/not/exist clone https://localhost:$HGPORT/
105 $ hg --config hostsecurity.localhost:verifycertsfile=/does/not/exist clone https://localhost:$HGPORT/
100 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
106 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
101 abort: path specified by hostsecurity.localhost:verifycertsfile does not exist: */does/not/exist (glob)
107 abort: path specified by hostsecurity.localhost:verifycertsfile does not exist: */does/not/exist (glob)
102 [255]
108 [255]
103
109
104 A malformed per-host certificate file will raise an error
110 A malformed per-host certificate file will raise an error
105
111
106 $ echo baddata > badca.pem
112 $ echo baddata > badca.pem
107 #if sslcontext
113 #if sslcontext
108 $ hg --config hostsecurity.localhost:verifycertsfile=badca.pem clone https://localhost:$HGPORT/
114 $ hg --config hostsecurity.localhost:verifycertsfile=badca.pem clone https://localhost:$HGPORT/
109 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
115 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
110 abort: error loading CA file badca.pem: * (glob)
116 abort: error loading CA file badca.pem: * (glob)
111 (file is empty or malformed?)
117 (file is empty or malformed?)
112 [255]
118 [255]
113 #else
119 #else
114 $ hg --config hostsecurity.localhost:verifycertsfile=badca.pem clone https://localhost:$HGPORT/
120 $ hg --config hostsecurity.localhost:verifycertsfile=badca.pem clone https://localhost:$HGPORT/
115 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
121 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
116 abort: error: * (glob)
122 abort: error: * (glob)
117 [255]
123 [255]
118 #endif
124 #endif
119
125
120 A per-host certificate mismatching the server will fail verification
126 A per-host certificate mismatching the server will fail verification
121
127
122 (modern ssl is able to discern whether the loaded cert is a CA cert)
128 (modern ssl is able to discern whether the loaded cert is a CA cert)
123 #if sslcontext
129 #if sslcontext
124 $ hg --config hostsecurity.localhost:verifycertsfile="$CERTSDIR/client-cert.pem" clone https://localhost:$HGPORT/
130 $ hg --config hostsecurity.localhost:verifycertsfile="$CERTSDIR/client-cert.pem" clone https://localhost:$HGPORT/
125 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
131 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
126 (an attempt was made to load CA certificates but none were loaded; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this error)
132 (an attempt was made to load CA certificates but none were loaded; see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this error)
127 (the full certificate chain may not be available locally; see "hg help debugssl") (windows !)
133 (the full certificate chain may not be available locally; see "hg help debugssl") (windows !)
128 abort: error: *certificate verify failed* (glob)
134 abort: error: *certificate verify failed* (glob)
129 [255]
135 [255]
130 #else
136 #else
131 $ hg --config hostsecurity.localhost:verifycertsfile="$CERTSDIR/client-cert.pem" clone https://localhost:$HGPORT/
137 $ hg --config hostsecurity.localhost:verifycertsfile="$CERTSDIR/client-cert.pem" clone https://localhost:$HGPORT/
132 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
138 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
133 abort: error: *certificate verify failed* (glob)
139 abort: error: *certificate verify failed* (glob)
134 [255]
140 [255]
135 #endif
141 #endif
136
142
137 A per-host certificate matching the server's cert will be accepted
143 A per-host certificate matching the server's cert will be accepted
138
144
139 $ hg --config hostsecurity.localhost:verifycertsfile="$CERTSDIR/pub.pem" clone -U https://localhost:$HGPORT/ perhostgood1
145 $ hg --config hostsecurity.localhost:verifycertsfile="$CERTSDIR/pub.pem" clone -U https://localhost:$HGPORT/ perhostgood1
140 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
146 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
141 requesting all changes
147 requesting all changes
142 adding changesets
148 adding changesets
143 adding manifests
149 adding manifests
144 adding file changes
150 adding file changes
145 added 1 changesets with 4 changes to 4 files
151 added 1 changesets with 4 changes to 4 files
146 new changesets 8b6053c928fe
152 new changesets 8b6053c928fe
147
153
148 A per-host certificate with multiple certs and one matching will be accepted
154 A per-host certificate with multiple certs and one matching will be accepted
149
155
150 $ cat "$CERTSDIR/client-cert.pem" "$CERTSDIR/pub.pem" > perhost.pem
156 $ cat "$CERTSDIR/client-cert.pem" "$CERTSDIR/pub.pem" > perhost.pem
151 $ hg --config hostsecurity.localhost:verifycertsfile=perhost.pem clone -U https://localhost:$HGPORT/ perhostgood2
157 $ hg --config hostsecurity.localhost:verifycertsfile=perhost.pem clone -U https://localhost:$HGPORT/ perhostgood2
152 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
158 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
153 requesting all changes
159 requesting all changes
154 adding changesets
160 adding changesets
155 adding manifests
161 adding manifests
156 adding file changes
162 adding file changes
157 added 1 changesets with 4 changes to 4 files
163 added 1 changesets with 4 changes to 4 files
158 new changesets 8b6053c928fe
164 new changesets 8b6053c928fe
159
165
160 Defining both per-host certificate and a fingerprint will print a warning
166 Defining both per-host certificate and a fingerprint will print a warning
161
167
162 $ hg --config hostsecurity.localhost:verifycertsfile="$CERTSDIR/pub.pem" --config hostsecurity.localhost:fingerprints=sha1:ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03 clone -U https://localhost:$HGPORT/ caandfingerwarning
168 $ hg --config hostsecurity.localhost:verifycertsfile="$CERTSDIR/pub.pem" --config hostsecurity.localhost:fingerprints=sha1:ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03 clone -U https://localhost:$HGPORT/ caandfingerwarning
163 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
169 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
164 (hostsecurity.localhost:verifycertsfile ignored when host fingerprints defined; using host fingerprints for verification)
170 (hostsecurity.localhost:verifycertsfile ignored when host fingerprints defined; using host fingerprints for verification)
165 requesting all changes
171 requesting all changes
166 adding changesets
172 adding changesets
167 adding manifests
173 adding manifests
168 adding file changes
174 adding file changes
169 added 1 changesets with 4 changes to 4 files
175 added 1 changesets with 4 changes to 4 files
170 new changesets 8b6053c928fe
176 new changesets 8b6053c928fe
171
177
172 $ DISABLECACERTS="--config devel.disableloaddefaultcerts=true"
178 $ DISABLECACERTS="--config devel.disableloaddefaultcerts=true"
173
179
174 Inability to verify peer certificate will result in abort
180 Inability to verify peer certificate will result in abort
175
181
176 $ hg clone https://localhost:$HGPORT/ copy-pull $DISABLECACERTS
182 $ hg clone https://localhost:$HGPORT/ copy-pull $DISABLECACERTS
177 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
183 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
178 abort: unable to verify security of localhost (no loaded CA certificates); refusing to connect
184 abort: unable to verify security of localhost (no loaded CA certificates); refusing to connect
179 (see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this error or set hostsecurity.localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e to trust this server)
185 (see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this error or set hostsecurity.localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e to trust this server)
180 [255]
186 [255]
181
187
182 $ hg clone --insecure https://localhost:$HGPORT/ copy-pull
188 $ hg clone --insecure https://localhost:$HGPORT/ copy-pull
183 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
189 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
184 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
190 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
185 requesting all changes
191 requesting all changes
186 adding changesets
192 adding changesets
187 adding manifests
193 adding manifests
188 adding file changes
194 adding file changes
189 added 1 changesets with 4 changes to 4 files
195 added 1 changesets with 4 changes to 4 files
190 new changesets 8b6053c928fe
196 new changesets 8b6053c928fe
191 updating to branch default
197 updating to branch default
192 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
198 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 $ hg verify -R copy-pull
199 $ hg verify -R copy-pull
194 checking changesets
200 checking changesets
195 checking manifests
201 checking manifests
196 crosschecking files in changesets and manifests
202 crosschecking files in changesets and manifests
197 checking files
203 checking files
198 checked 1 changesets with 4 changes to 4 files
204 checked 1 changesets with 4 changes to 4 files
199 $ cd test
205 $ cd test
200 $ echo bar > bar
206 $ echo bar > bar
201 $ hg commit -A -d '1 0' -m 2
207 $ hg commit -A -d '1 0' -m 2
202 adding bar
208 adding bar
203 $ cd ..
209 $ cd ..
204
210
205 pull without cacert
211 pull without cacert
206
212
207 $ cd copy-pull
213 $ cd copy-pull
208 $ cat >> .hg/hgrc <<EOF
214 $ cat >> .hg/hgrc <<EOF
209 > [hooks]
215 > [hooks]
210 > changegroup = sh -c "printenv.py --line changegroup"
216 > changegroup = sh -c "printenv.py --line changegroup"
211 > EOF
217 > EOF
212 $ hg pull $DISABLECACERTS
218 $ hg pull $DISABLECACERTS
213 pulling from https://localhost:$HGPORT/
219 pulling from https://localhost:$HGPORT/
214 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
220 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
215 abort: unable to verify security of localhost (no loaded CA certificates); refusing to connect
221 abort: unable to verify security of localhost (no loaded CA certificates); refusing to connect
216 (see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this error or set hostsecurity.localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e to trust this server)
222 (see https://mercurial-scm.org/wiki/SecureConnections for how to configure Mercurial to avoid this error or set hostsecurity.localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e to trust this server)
217 [255]
223 [255]
218
224
219 $ hg pull --insecure
225 $ hg pull --insecure
220 pulling from https://localhost:$HGPORT/
226 pulling from https://localhost:$HGPORT/
221 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
227 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
222 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
228 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
223 searching for changes
229 searching for changes
224 adding changesets
230 adding changesets
225 adding manifests
231 adding manifests
226 adding file changes
232 adding file changes
227 added 1 changesets with 1 changes to 1 files
233 added 1 changesets with 1 changes to 1 files
228 new changesets 5fed3813f7f5
234 new changesets 5fed3813f7f5
229 changegroup hook: HG_HOOKNAME=changegroup
235 changegroup hook: HG_HOOKNAME=changegroup
230 HG_HOOKTYPE=changegroup
236 HG_HOOKTYPE=changegroup
231 HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
237 HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
232 HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
238 HG_NODE_LAST=5fed3813f7f5e1824344fdc9cf8f63bb662c292d
233 HG_SOURCE=pull
239 HG_SOURCE=pull
234 HG_TXNID=TXN:$ID$
240 HG_TXNID=TXN:$ID$
235 HG_TXNNAME=pull
241 HG_TXNNAME=pull
236 https://localhost:$HGPORT/
242 https://localhost:$HGPORT/
237 HG_URL=https://localhost:$HGPORT/
243 HG_URL=https://localhost:$HGPORT/
238
244
239 (run 'hg update' to get a working copy)
245 (run 'hg update' to get a working copy)
240 $ cd ..
246 $ cd ..
241
247
242 cacert configured in local repo
248 cacert configured in local repo
243
249
244 $ cp copy-pull/.hg/hgrc copy-pull/.hg/hgrc.bu
250 $ cp copy-pull/.hg/hgrc copy-pull/.hg/hgrc.bu
245 $ echo "[web]" >> copy-pull/.hg/hgrc
251 $ echo "[web]" >> copy-pull/.hg/hgrc
246 $ echo "cacerts=$CERTSDIR/pub.pem" >> copy-pull/.hg/hgrc
252 $ echo "cacerts=$CERTSDIR/pub.pem" >> copy-pull/.hg/hgrc
247 $ hg -R copy-pull pull
253 $ hg -R copy-pull pull
248 pulling from https://localhost:$HGPORT/
254 pulling from https://localhost:$HGPORT/
249 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
255 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
250 searching for changes
256 searching for changes
251 no changes found
257 no changes found
252 $ mv copy-pull/.hg/hgrc.bu copy-pull/.hg/hgrc
258 $ mv copy-pull/.hg/hgrc.bu copy-pull/.hg/hgrc
253
259
254 cacert configured globally, also testing expansion of environment
260 cacert configured globally, also testing expansion of environment
255 variables in the filename
261 variables in the filename
256
262
257 $ echo "[web]" >> $HGRCPATH
263 $ echo "[web]" >> $HGRCPATH
258 $ echo 'cacerts=$P/pub.pem' >> $HGRCPATH
264 $ echo 'cacerts=$P/pub.pem' >> $HGRCPATH
259 $ P="$CERTSDIR" hg -R copy-pull pull
265 $ P="$CERTSDIR" hg -R copy-pull pull
260 pulling from https://localhost:$HGPORT/
266 pulling from https://localhost:$HGPORT/
261 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
267 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
262 searching for changes
268 searching for changes
263 no changes found
269 no changes found
264 $ P="$CERTSDIR" hg -R copy-pull pull --insecure
270 $ P="$CERTSDIR" hg -R copy-pull pull --insecure
265 pulling from https://localhost:$HGPORT/
271 pulling from https://localhost:$HGPORT/
266 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
272 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
267 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
273 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
268 searching for changes
274 searching for changes
269 no changes found
275 no changes found
270
276
271 empty cacert file
277 empty cacert file
272
278
273 $ touch emptycafile
279 $ touch emptycafile
274
280
275 #if sslcontext
281 #if sslcontext
276 $ hg --config web.cacerts=emptycafile -R copy-pull pull
282 $ hg --config web.cacerts=emptycafile -R copy-pull pull
277 pulling from https://localhost:$HGPORT/
283 pulling from https://localhost:$HGPORT/
278 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
284 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
279 abort: error loading CA file emptycafile: * (glob)
285 abort: error loading CA file emptycafile: * (glob)
280 (file is empty or malformed?)
286 (file is empty or malformed?)
281 [255]
287 [255]
282 #else
288 #else
283 $ hg --config web.cacerts=emptycafile -R copy-pull pull
289 $ hg --config web.cacerts=emptycafile -R copy-pull pull
284 pulling from https://localhost:$HGPORT/
290 pulling from https://localhost:$HGPORT/
285 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
291 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
286 abort: error: * (glob)
292 abort: error: * (glob)
287 [255]
293 [255]
288 #endif
294 #endif
289
295
290 cacert mismatch
296 cacert mismatch
291
297
292 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub.pem" \
298 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub.pem" \
293 > https://$LOCALIP:$HGPORT/
299 > https://$LOCALIP:$HGPORT/
294 pulling from https://*:$HGPORT/ (glob)
300 pulling from https://*:$HGPORT/ (glob)
295 warning: connecting to $LOCALIP using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
301 warning: connecting to $LOCALIP using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
296 abort: $LOCALIP certificate error: certificate is for localhost (glob)
302 abort: $LOCALIP certificate error: certificate is for localhost (glob)
297 (set hostsecurity.$LOCALIP:certfingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e config setting or use --insecure to connect insecurely)
303 (set hostsecurity.$LOCALIP:certfingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e config setting or use --insecure to connect insecurely)
298 [255]
304 [255]
299 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub.pem" \
305 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub.pem" \
300 > https://$LOCALIP:$HGPORT/ --insecure
306 > https://$LOCALIP:$HGPORT/ --insecure
301 pulling from https://*:$HGPORT/ (glob)
307 pulling from https://*:$HGPORT/ (glob)
302 warning: connecting to $LOCALIP using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
308 warning: connecting to $LOCALIP using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
303 warning: connection security to $LOCALIP is disabled per current settings; communication is susceptible to eavesdropping and tampering (glob)
309 warning: connection security to $LOCALIP is disabled per current settings; communication is susceptible to eavesdropping and tampering (glob)
304 searching for changes
310 searching for changes
305 no changes found
311 no changes found
306 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub-other.pem"
312 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub-other.pem"
307 pulling from https://localhost:$HGPORT/
313 pulling from https://localhost:$HGPORT/
308 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
314 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
309 (the full certificate chain may not be available locally; see "hg help debugssl") (windows !)
315 (the full certificate chain may not be available locally; see "hg help debugssl") (windows !)
310 abort: error: *certificate verify failed* (glob)
316 abort: error: *certificate verify failed* (glob)
311 [255]
317 [255]
312 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub-other.pem" \
318 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub-other.pem" \
313 > --insecure
319 > --insecure
314 pulling from https://localhost:$HGPORT/
320 pulling from https://localhost:$HGPORT/
315 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
321 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
316 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
322 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
317 searching for changes
323 searching for changes
318 no changes found
324 no changes found
319
325
320 Test server cert which isn't valid yet
326 Test server cert which isn't valid yet
321
327
322 $ hg serve -R test -p $HGPORT1 -d --pid-file=hg1.pid --certificate=server-not-yet.pem
328 $ hg serve -R test -p $HGPORT1 -d --pid-file=hg1.pid --certificate=server-not-yet.pem
323 $ cat hg1.pid >> $DAEMON_PIDS
329 $ cat hg1.pid >> $DAEMON_PIDS
324 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub-not-yet.pem" \
330 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub-not-yet.pem" \
325 > https://localhost:$HGPORT1/
331 > https://localhost:$HGPORT1/
326 pulling from https://localhost:$HGPORT1/
332 pulling from https://localhost:$HGPORT1/
327 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
333 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
328 (the full certificate chain may not be available locally; see "hg help debugssl") (windows !)
334 (the full certificate chain may not be available locally; see "hg help debugssl") (windows !)
329 abort: error: *certificate verify failed* (glob)
335 abort: error: *certificate verify failed* (glob)
330 [255]
336 [255]
331
337
332 Test server cert which no longer is valid
338 Test server cert which no longer is valid
333
339
334 $ hg serve -R test -p $HGPORT2 -d --pid-file=hg2.pid --certificate=server-expired.pem
340 $ hg serve -R test -p $HGPORT2 -d --pid-file=hg2.pid --certificate=server-expired.pem
335 $ cat hg2.pid >> $DAEMON_PIDS
341 $ cat hg2.pid >> $DAEMON_PIDS
336 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub-expired.pem" \
342 $ hg -R copy-pull pull --config web.cacerts="$CERTSDIR/pub-expired.pem" \
337 > https://localhost:$HGPORT2/
343 > https://localhost:$HGPORT2/
338 pulling from https://localhost:$HGPORT2/
344 pulling from https://localhost:$HGPORT2/
339 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
345 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
340 (the full certificate chain may not be available locally; see "hg help debugssl") (windows !)
346 (the full certificate chain may not be available locally; see "hg help debugssl") (windows !)
341 abort: error: *certificate verify failed* (glob)
347 abort: error: *certificate verify failed* (glob)
342 [255]
348 [255]
343
349
344 Disabling the TLS 1.0 warning works
350 Disabling the TLS 1.0 warning works
345 $ hg -R copy-pull id https://localhost:$HGPORT/ \
351 $ hg -R copy-pull id https://localhost:$HGPORT/ \
346 > --config hostsecurity.localhost:fingerprints=sha1:ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03 \
352 > --config hostsecurity.localhost:fingerprints=sha1:ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03 \
347 > --config hostsecurity.disabletls10warning=true
353 > --config hostsecurity.disabletls10warning=true
348 5fed3813f7f5
354 5fed3813f7f5
349
355
350 Error message for setting ciphers is different depending on SSLContext support
356 Error message for setting ciphers is different depending on SSLContext support
351
357
352 #if no-sslcontext
358 #if no-sslcontext
353 $ P="$CERTSDIR" hg --config hostsecurity.ciphers=invalid -R copy-pull id https://localhost:$HGPORT/
359 $ P="$CERTSDIR" hg --config hostsecurity.ciphers=invalid -R copy-pull id https://localhost:$HGPORT/
354 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info
360 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info
355 abort: *No cipher can be selected. (glob)
361 abort: *No cipher can be selected. (glob)
356 [255]
362 [255]
357
363
358 $ P="$CERTSDIR" hg --config hostsecurity.ciphers=HIGH -R copy-pull id https://localhost:$HGPORT/
364 $ P="$CERTSDIR" hg --config hostsecurity.ciphers=HIGH -R copy-pull id https://localhost:$HGPORT/
359 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info
365 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info
360 5fed3813f7f5
366 5fed3813f7f5
361 #endif
367 #endif
362
368
363 #if sslcontext
369 #if sslcontext
364 Setting ciphers to an invalid value aborts
370 Setting ciphers to an invalid value aborts
365 $ P="$CERTSDIR" hg --config hostsecurity.ciphers=invalid -R copy-pull id https://localhost:$HGPORT/
371 $ P="$CERTSDIR" hg --config hostsecurity.ciphers=invalid -R copy-pull id https://localhost:$HGPORT/
366 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
372 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
367 abort: could not set ciphers: No cipher can be selected.
373 abort: could not set ciphers: No cipher can be selected.
368 (change cipher string (invalid) in config)
374 (change cipher string (invalid) in config)
369 [255]
375 [255]
370
376
371 $ P="$CERTSDIR" hg --config hostsecurity.localhost:ciphers=invalid -R copy-pull id https://localhost:$HGPORT/
377 $ P="$CERTSDIR" hg --config hostsecurity.localhost:ciphers=invalid -R copy-pull id https://localhost:$HGPORT/
372 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
378 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
373 abort: could not set ciphers: No cipher can be selected.
379 abort: could not set ciphers: No cipher can be selected.
374 (change cipher string (invalid) in config)
380 (change cipher string (invalid) in config)
375 [255]
381 [255]
376
382
377 Changing the cipher string works
383 Changing the cipher string works
378
384
379 $ P="$CERTSDIR" hg --config hostsecurity.ciphers=HIGH -R copy-pull id https://localhost:$HGPORT/
385 $ P="$CERTSDIR" hg --config hostsecurity.ciphers=HIGH -R copy-pull id https://localhost:$HGPORT/
380 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
386 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
381 5fed3813f7f5
387 5fed3813f7f5
382 #endif
388 #endif
383
389
384 Fingerprints
390 Fingerprints
385
391
386 - works without cacerts (hostfingerprints)
392 - works without cacerts (hostfingerprints)
387 $ hg -R copy-pull id https://localhost:$HGPORT/ --insecure --config hostfingerprints.localhost=ec:d8:7c:d6:b3:86:d0:4f:c1:b8:b4:1c:9d:8f:5e:16:8e:ef:1c:03
393 $ hg -R copy-pull id https://localhost:$HGPORT/ --insecure --config hostfingerprints.localhost=ec:d8:7c:d6:b3:86:d0:4f:c1:b8:b4:1c:9d:8f:5e:16:8e:ef:1c:03
388 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
394 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
389 (SHA-1 fingerprint for localhost found in legacy [hostfingerprints] section; if you trust this fingerprint, remove the old SHA-1 fingerprint from [hostfingerprints] and add the following entry to the new [hostsecurity] section: localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e)
395 (SHA-1 fingerprint for localhost found in legacy [hostfingerprints] section; if you trust this fingerprint, remove the old SHA-1 fingerprint from [hostfingerprints] and add the following entry to the new [hostsecurity] section: localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e)
390 5fed3813f7f5
396 5fed3813f7f5
391
397
392 - works without cacerts (hostsecurity)
398 - works without cacerts (hostsecurity)
393 $ hg -R copy-pull id https://localhost:$HGPORT/ --config hostsecurity.localhost:fingerprints=sha1:ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03
399 $ hg -R copy-pull id https://localhost:$HGPORT/ --config hostsecurity.localhost:fingerprints=sha1:ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03
394 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
400 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
395 5fed3813f7f5
401 5fed3813f7f5
396
402
397 $ hg -R copy-pull id https://localhost:$HGPORT/ --config hostsecurity.localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e
403 $ hg -R copy-pull id https://localhost:$HGPORT/ --config hostsecurity.localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e
398 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
404 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
399 5fed3813f7f5
405 5fed3813f7f5
400
406
401 - multiple fingerprints specified and first matches
407 - multiple fingerprints specified and first matches
402 $ hg --config 'hostfingerprints.localhost=ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03, deadbeefdeadbeefdeadbeefdeadbeefdeadbeef' -R copy-pull id https://localhost:$HGPORT/ --insecure
408 $ hg --config 'hostfingerprints.localhost=ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03, deadbeefdeadbeefdeadbeefdeadbeefdeadbeef' -R copy-pull id https://localhost:$HGPORT/ --insecure
403 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
409 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
404 (SHA-1 fingerprint for localhost found in legacy [hostfingerprints] section; if you trust this fingerprint, remove the old SHA-1 fingerprint from [hostfingerprints] and add the following entry to the new [hostsecurity] section: localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e)
410 (SHA-1 fingerprint for localhost found in legacy [hostfingerprints] section; if you trust this fingerprint, remove the old SHA-1 fingerprint from [hostfingerprints] and add the following entry to the new [hostsecurity] section: localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e)
405 5fed3813f7f5
411 5fed3813f7f5
406
412
407 $ hg --config 'hostsecurity.localhost:fingerprints=sha1:ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03, sha1:deadbeefdeadbeefdeadbeefdeadbeefdeadbeef' -R copy-pull id https://localhost:$HGPORT/
413 $ hg --config 'hostsecurity.localhost:fingerprints=sha1:ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03, sha1:deadbeefdeadbeefdeadbeefdeadbeefdeadbeef' -R copy-pull id https://localhost:$HGPORT/
408 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
414 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
409 5fed3813f7f5
415 5fed3813f7f5
410
416
411 - multiple fingerprints specified and last matches
417 - multiple fingerprints specified and last matches
412 $ hg --config 'hostfingerprints.localhost=deadbeefdeadbeefdeadbeefdeadbeefdeadbeef, ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03' -R copy-pull id https://localhost:$HGPORT/ --insecure
418 $ hg --config 'hostfingerprints.localhost=deadbeefdeadbeefdeadbeefdeadbeefdeadbeef, ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03' -R copy-pull id https://localhost:$HGPORT/ --insecure
413 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
419 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
414 (SHA-1 fingerprint for localhost found in legacy [hostfingerprints] section; if you trust this fingerprint, remove the old SHA-1 fingerprint from [hostfingerprints] and add the following entry to the new [hostsecurity] section: localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e)
420 (SHA-1 fingerprint for localhost found in legacy [hostfingerprints] section; if you trust this fingerprint, remove the old SHA-1 fingerprint from [hostfingerprints] and add the following entry to the new [hostsecurity] section: localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e)
415 5fed3813f7f5
421 5fed3813f7f5
416
422
417 $ hg --config 'hostsecurity.localhost:fingerprints=sha1:deadbeefdeadbeefdeadbeefdeadbeefdeadbeef, sha1:ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03' -R copy-pull id https://localhost:$HGPORT/
423 $ hg --config 'hostsecurity.localhost:fingerprints=sha1:deadbeefdeadbeefdeadbeefdeadbeefdeadbeef, sha1:ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03' -R copy-pull id https://localhost:$HGPORT/
418 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
424 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
419 5fed3813f7f5
425 5fed3813f7f5
420
426
421 - multiple fingerprints specified and none match
427 - multiple fingerprints specified and none match
422
428
423 $ hg --config 'hostfingerprints.localhost=deadbeefdeadbeefdeadbeefdeadbeefdeadbeef, aeadbeefdeadbeefdeadbeefdeadbeefdeadbeef' -R copy-pull id https://localhost:$HGPORT/ --insecure
429 $ hg --config 'hostfingerprints.localhost=deadbeefdeadbeefdeadbeefdeadbeefdeadbeef, aeadbeefdeadbeefdeadbeefdeadbeefdeadbeef' -R copy-pull id https://localhost:$HGPORT/ --insecure
424 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
430 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
425 abort: certificate for localhost has unexpected fingerprint ec:d8:7c:d6:b3:86:d0:4f:c1:b8:b4:1c:9d:8f:5e:16:8e:ef:1c:03
431 abort: certificate for localhost has unexpected fingerprint ec:d8:7c:d6:b3:86:d0:4f:c1:b8:b4:1c:9d:8f:5e:16:8e:ef:1c:03
426 (check hostfingerprint configuration)
432 (check hostfingerprint configuration)
427 [255]
433 [255]
428
434
429 $ hg --config 'hostsecurity.localhost:fingerprints=sha1:deadbeefdeadbeefdeadbeefdeadbeefdeadbeef, sha1:aeadbeefdeadbeefdeadbeefdeadbeefdeadbeef' -R copy-pull id https://localhost:$HGPORT/
435 $ hg --config 'hostsecurity.localhost:fingerprints=sha1:deadbeefdeadbeefdeadbeefdeadbeefdeadbeef, sha1:aeadbeefdeadbeefdeadbeefdeadbeefdeadbeef' -R copy-pull id https://localhost:$HGPORT/
430 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
436 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
431 abort: certificate for localhost has unexpected fingerprint sha1:ec:d8:7c:d6:b3:86:d0:4f:c1:b8:b4:1c:9d:8f:5e:16:8e:ef:1c:03
437 abort: certificate for localhost has unexpected fingerprint sha1:ec:d8:7c:d6:b3:86:d0:4f:c1:b8:b4:1c:9d:8f:5e:16:8e:ef:1c:03
432 (check hostsecurity configuration)
438 (check hostsecurity configuration)
433 [255]
439 [255]
434
440
435 - fails when cert doesn't match hostname (port is ignored)
441 - fails when cert doesn't match hostname (port is ignored)
436 $ hg -R copy-pull id https://localhost:$HGPORT1/ --config hostfingerprints.localhost=ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03
442 $ hg -R copy-pull id https://localhost:$HGPORT1/ --config hostfingerprints.localhost=ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03
437 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
443 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
438 abort: certificate for localhost has unexpected fingerprint f4:2f:5a:0c:3e:52:5b:db:e7:24:a8:32:1d:18:97:6d:69:b5:87:84
444 abort: certificate for localhost has unexpected fingerprint f4:2f:5a:0c:3e:52:5b:db:e7:24:a8:32:1d:18:97:6d:69:b5:87:84
439 (check hostfingerprint configuration)
445 (check hostfingerprint configuration)
440 [255]
446 [255]
441
447
442
448
443 - ignores that certificate doesn't match hostname
449 - ignores that certificate doesn't match hostname
444 $ hg -R copy-pull id https://$LOCALIP:$HGPORT/ --config hostfingerprints.$LOCALIP=ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03
450 $ hg -R copy-pull id https://$LOCALIP:$HGPORT/ --config hostfingerprints.$LOCALIP=ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03
445 warning: connecting to $LOCALIP using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
451 warning: connecting to $LOCALIP using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
446 (SHA-1 fingerprint for $LOCALIP found in legacy [hostfingerprints] section; if you trust this fingerprint, remove the old SHA-1 fingerprint from [hostfingerprints] and add the following entry to the new [hostsecurity] section: $LOCALIP:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e)
452 (SHA-1 fingerprint for $LOCALIP found in legacy [hostfingerprints] section; if you trust this fingerprint, remove the old SHA-1 fingerprint from [hostfingerprints] and add the following entry to the new [hostsecurity] section: $LOCALIP:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e)
447 5fed3813f7f5
453 5fed3813f7f5
448
454
449 Ports used by next test. Kill servers.
455 Ports used by next test. Kill servers.
450
456
451 $ killdaemons.py hg0.pid
457 $ killdaemons.py hg0.pid
452 $ killdaemons.py hg1.pid
458 $ killdaemons.py hg1.pid
453 $ killdaemons.py hg2.pid
459 $ killdaemons.py hg2.pid
454
460
455 #if sslcontext tls1.2
461 #if sslcontext tls1.2
456 Start servers running supported TLS versions
462 Start servers running supported TLS versions
457
463
458 $ cd test
464 $ cd test
459 $ hg serve -p $HGPORT -d --pid-file=../hg0.pid --certificate=$PRIV \
465 $ hg serve -p $HGPORT -d --pid-file=../hg0.pid --certificate=$PRIV \
460 > --config devel.serverexactprotocol=tls1.0
466 > --config devel.serverexactprotocol=tls1.0
461 $ cat ../hg0.pid >> $DAEMON_PIDS
467 $ cat ../hg0.pid >> $DAEMON_PIDS
462 $ hg serve -p $HGPORT1 -d --pid-file=../hg1.pid --certificate=$PRIV \
468 $ hg serve -p $HGPORT1 -d --pid-file=../hg1.pid --certificate=$PRIV \
463 > --config devel.serverexactprotocol=tls1.1
469 > --config devel.serverexactprotocol=tls1.1
464 $ cat ../hg1.pid >> $DAEMON_PIDS
470 $ cat ../hg1.pid >> $DAEMON_PIDS
465 $ hg serve -p $HGPORT2 -d --pid-file=../hg2.pid --certificate=$PRIV \
471 $ hg serve -p $HGPORT2 -d --pid-file=../hg2.pid --certificate=$PRIV \
466 > --config devel.serverexactprotocol=tls1.2
472 > --config devel.serverexactprotocol=tls1.2
467 $ cat ../hg2.pid >> $DAEMON_PIDS
473 $ cat ../hg2.pid >> $DAEMON_PIDS
468 $ cd ..
474 $ cd ..
469
475
470 Clients talking same TLS versions work
476 Clients talking same TLS versions work
471
477
472 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.0 id https://localhost:$HGPORT/
478 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.0 id https://localhost:$HGPORT/
473 5fed3813f7f5
479 5fed3813f7f5
474 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.1 id https://localhost:$HGPORT1/
480 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.1 id https://localhost:$HGPORT1/
475 5fed3813f7f5
481 5fed3813f7f5
476 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.2 id https://localhost:$HGPORT2/
482 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.2 id https://localhost:$HGPORT2/
477 5fed3813f7f5
483 5fed3813f7f5
478
484
479 Clients requiring newer TLS version than what server supports fail
485 Clients requiring newer TLS version than what server supports fail
480
486
481 $ P="$CERTSDIR" hg id https://localhost:$HGPORT/
487 $ P="$CERTSDIR" hg id https://localhost:$HGPORT/
482 (could not negotiate a common security protocol (tls1.1+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
488 (could not negotiate a common security protocol (tls1.1+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
483 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
489 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
484 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
490 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
485 abort: error: *unsupported protocol* (glob)
491 abort: error: *unsupported protocol* (glob)
486 [255]
492 [255]
487
493
488 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.1 id https://localhost:$HGPORT/
494 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.1 id https://localhost:$HGPORT/
489 (could not negotiate a common security protocol (tls1.1+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
495 (could not negotiate a common security protocol (tls1.1+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
490 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
496 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
491 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
497 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
492 abort: error: *unsupported protocol* (glob)
498 abort: error: *unsupported protocol* (glob)
493 [255]
499 [255]
494 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.2 id https://localhost:$HGPORT/
500 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.2 id https://localhost:$HGPORT/
495 (could not negotiate a common security protocol (tls1.2+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
501 (could not negotiate a common security protocol (tls1.2+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
496 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
502 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
497 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
503 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
498 abort: error: *unsupported protocol* (glob)
504 abort: error: *unsupported protocol* (glob)
499 [255]
505 [255]
500 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.2 id https://localhost:$HGPORT1/
506 $ P="$CERTSDIR" hg --config hostsecurity.minimumprotocol=tls1.2 id https://localhost:$HGPORT1/
501 (could not negotiate a common security protocol (tls1.2+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
507 (could not negotiate a common security protocol (tls1.2+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
502 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
508 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
503 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
509 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
504 abort: error: *unsupported protocol* (glob)
510 abort: error: *unsupported protocol* (glob)
505 [255]
511 [255]
506
512
507 --insecure will allow TLS 1.0 connections and override configs
513 --insecure will allow TLS 1.0 connections and override configs
508
514
509 $ hg --config hostsecurity.minimumprotocol=tls1.2 id --insecure https://localhost:$HGPORT1/
515 $ hg --config hostsecurity.minimumprotocol=tls1.2 id --insecure https://localhost:$HGPORT1/
510 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
516 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
511 5fed3813f7f5
517 5fed3813f7f5
512
518
513 The per-host config option overrides the default
519 The per-host config option overrides the default
514
520
515 $ P="$CERTSDIR" hg id https://localhost:$HGPORT/ \
521 $ P="$CERTSDIR" hg id https://localhost:$HGPORT/ \
516 > --config hostsecurity.minimumprotocol=tls1.2 \
522 > --config hostsecurity.minimumprotocol=tls1.2 \
517 > --config hostsecurity.localhost:minimumprotocol=tls1.0
523 > --config hostsecurity.localhost:minimumprotocol=tls1.0
518 5fed3813f7f5
524 5fed3813f7f5
519
525
520 The per-host config option by itself works
526 The per-host config option by itself works
521
527
522 $ P="$CERTSDIR" hg id https://localhost:$HGPORT/ \
528 $ P="$CERTSDIR" hg id https://localhost:$HGPORT/ \
523 > --config hostsecurity.localhost:minimumprotocol=tls1.2
529 > --config hostsecurity.localhost:minimumprotocol=tls1.2
524 (could not negotiate a common security protocol (tls1.2+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
530 (could not negotiate a common security protocol (tls1.2+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
525 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
531 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
526 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
532 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
527 abort: error: *unsupported protocol* (glob)
533 abort: error: *unsupported protocol* (glob)
528 [255]
534 [255]
529
535
530 .hg/hgrc file [hostsecurity] settings are applied to remote ui instances (issue5305)
536 .hg/hgrc file [hostsecurity] settings are applied to remote ui instances (issue5305)
531
537
532 $ cat >> copy-pull/.hg/hgrc << EOF
538 $ cat >> copy-pull/.hg/hgrc << EOF
533 > [hostsecurity]
539 > [hostsecurity]
534 > localhost:minimumprotocol=tls1.2
540 > localhost:minimumprotocol=tls1.2
535 > EOF
541 > EOF
536 $ P="$CERTSDIR" hg -R copy-pull id https://localhost:$HGPORT/
542 $ P="$CERTSDIR" hg -R copy-pull id https://localhost:$HGPORT/
537 (could not negotiate a common security protocol (tls1.2+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
543 (could not negotiate a common security protocol (tls1.2+) with localhost; the likely cause is Mercurial is configured to be more secure than the server can support)
538 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
544 (consider contacting the operator of this server and ask them to support modern TLS protocol versions; or, set hostsecurity.localhost:minimumprotocol=tls1.0 to allow use of legacy, less secure protocols when communicating with this server)
539 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
545 (see https://mercurial-scm.org/wiki/SecureConnections for more info)
540 abort: error: *unsupported protocol* (glob)
546 abort: error: *unsupported protocol* (glob)
541 [255]
547 [255]
542
548
543 $ killdaemons.py hg0.pid
549 $ killdaemons.py hg0.pid
544 $ killdaemons.py hg1.pid
550 $ killdaemons.py hg1.pid
545 $ killdaemons.py hg2.pid
551 $ killdaemons.py hg2.pid
546 #endif
552 #endif
547
553
548 Prepare for connecting through proxy
554 Prepare for connecting through proxy
549
555
550 $ hg serve -R test -p $HGPORT -d --pid-file=hg0.pid --certificate=$PRIV
556 $ hg serve -R test -p $HGPORT -d --pid-file=hg0.pid --certificate=$PRIV
551 $ cat hg0.pid >> $DAEMON_PIDS
557 $ cat hg0.pid >> $DAEMON_PIDS
552 $ hg serve -R test -p $HGPORT2 -d --pid-file=hg2.pid --certificate=server-expired.pem
558 $ hg serve -R test -p $HGPORT2 -d --pid-file=hg2.pid --certificate=server-expired.pem
553 $ cat hg2.pid >> $DAEMON_PIDS
559 $ cat hg2.pid >> $DAEMON_PIDS
554 tinyproxy.py doesn't fully detach, so killing it may result in extra output
560 tinyproxy.py doesn't fully detach, so killing it may result in extra output
555 from the shell. So don't kill it.
561 from the shell. So don't kill it.
556 $ tinyproxy.py $HGPORT1 localhost >proxy.log </dev/null 2>&1 &
562 $ tinyproxy.py $HGPORT1 localhost >proxy.log </dev/null 2>&1 &
557 $ while [ ! -f proxy.pid ]; do sleep 0; done
563 $ while [ ! -f proxy.pid ]; do sleep 0; done
558 $ cat proxy.pid >> $DAEMON_PIDS
564 $ cat proxy.pid >> $DAEMON_PIDS
559
565
560 $ echo "[http_proxy]" >> copy-pull/.hg/hgrc
566 $ echo "[http_proxy]" >> copy-pull/.hg/hgrc
561 $ echo "always=True" >> copy-pull/.hg/hgrc
567 $ echo "always=True" >> copy-pull/.hg/hgrc
562 $ echo "[hostfingerprints]" >> copy-pull/.hg/hgrc
568 $ echo "[hostfingerprints]" >> copy-pull/.hg/hgrc
563 $ echo "localhost =" >> copy-pull/.hg/hgrc
569 $ echo "localhost =" >> copy-pull/.hg/hgrc
564
570
565 Test unvalidated https through proxy
571 Test unvalidated https through proxy
566
572
567 $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull --insecure
573 $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull --insecure
568 pulling from https://localhost:$HGPORT/
574 pulling from https://localhost:$HGPORT/
569 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
575 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
570 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
576 warning: connection security to localhost is disabled per current settings; communication is susceptible to eavesdropping and tampering
571 searching for changes
577 searching for changes
572 no changes found
578 no changes found
573
579
574 Test https with cacert and fingerprint through proxy
580 Test https with cacert and fingerprint through proxy
575
581
576 $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull \
582 $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull \
577 > --config web.cacerts="$CERTSDIR/pub.pem"
583 > --config web.cacerts="$CERTSDIR/pub.pem"
578 pulling from https://localhost:$HGPORT/
584 pulling from https://localhost:$HGPORT/
579 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
585 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
580 searching for changes
586 searching for changes
581 no changes found
587 no changes found
582 $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull https://localhost:$HGPORT/ --config hostfingerprints.localhost=ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03 --trace
588 $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull https://localhost:$HGPORT/ --config hostfingerprints.localhost=ecd87cd6b386d04fc1b8b41c9d8f5e168eef1c03 --trace
583 pulling from https://*:$HGPORT/ (glob)
589 pulling from https://*:$HGPORT/ (glob)
584 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
590 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
585 (SHA-1 fingerprint for localhost found in legacy [hostfingerprints] section; if you trust this fingerprint, remove the old SHA-1 fingerprint from [hostfingerprints] and add the following entry to the new [hostsecurity] section: localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e)
591 (SHA-1 fingerprint for localhost found in legacy [hostfingerprints] section; if you trust this fingerprint, remove the old SHA-1 fingerprint from [hostfingerprints] and add the following entry to the new [hostsecurity] section: localhost:fingerprints=sha256:20:de:b3:ad:b4:cd:a5:42:f0:74:41:1c:a2:70:1e:da:6e:c0:5c:16:9e:e7:22:0f:f1:b7:e5:6e:e4:92:af:7e)
586 searching for changes
592 searching for changes
587 no changes found
593 no changes found
588
594
589 Test https with cert problems through proxy
595 Test https with cert problems through proxy
590
596
591 $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull \
597 $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull \
592 > --config web.cacerts="$CERTSDIR/pub-other.pem"
598 > --config web.cacerts="$CERTSDIR/pub-other.pem"
593 pulling from https://localhost:$HGPORT/
599 pulling from https://localhost:$HGPORT/
594 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
600 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
595 (the full certificate chain may not be available locally; see "hg help debugssl") (windows !)
601 (the full certificate chain may not be available locally; see "hg help debugssl") (windows !)
596 abort: error: *certificate verify failed* (glob)
602 abort: error: *certificate verify failed* (glob)
597 [255]
603 [255]
598 $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull \
604 $ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull \
599 > --config web.cacerts="$CERTSDIR/pub-expired.pem" https://localhost:$HGPORT2/
605 > --config web.cacerts="$CERTSDIR/pub-expired.pem" https://localhost:$HGPORT2/
600 pulling from https://localhost:$HGPORT2/
606 pulling from https://localhost:$HGPORT2/
601 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
607 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
602 (the full certificate chain may not be available locally; see "hg help debugssl") (windows !)
608 (the full certificate chain may not be available locally; see "hg help debugssl") (windows !)
603 abort: error: *certificate verify failed* (glob)
609 abort: error: *certificate verify failed* (glob)
604 [255]
610 [255]
605
611
606
612
607 $ killdaemons.py hg0.pid
613 $ killdaemons.py hg0.pid
608
614
609 #if sslcontext
615 #if sslcontext
610
616
611 $ cd test
617 $ cd test
612
618
613 Missing certificate file(s) are detected
619 Missing certificate file(s) are detected
614
620
615 $ hg serve -p $HGPORT --certificate=/missing/certificate \
621 $ hg serve -p $HGPORT --certificate=/missing/certificate \
616 > --config devel.servercafile=$PRIV --config devel.serverrequirecert=true
622 > --config devel.servercafile=$PRIV --config devel.serverrequirecert=true
617 abort: referenced certificate file (*/missing/certificate) does not exist (glob)
623 abort: referenced certificate file (*/missing/certificate) does not exist (glob)
618 [255]
624 [255]
619
625
620 $ hg serve -p $HGPORT --certificate=$PRIV \
626 $ hg serve -p $HGPORT --certificate=$PRIV \
621 > --config devel.servercafile=/missing/cafile --config devel.serverrequirecert=true
627 > --config devel.servercafile=/missing/cafile --config devel.serverrequirecert=true
622 abort: referenced certificate file (*/missing/cafile) does not exist (glob)
628 abort: referenced certificate file (*/missing/cafile) does not exist (glob)
623 [255]
629 [255]
624
630
625 Start hgweb that requires client certificates:
631 Start hgweb that requires client certificates:
626
632
627 $ hg serve -p $HGPORT -d --pid-file=../hg0.pid --certificate=$PRIV \
633 $ hg serve -p $HGPORT -d --pid-file=../hg0.pid --certificate=$PRIV \
628 > --config devel.servercafile=$PRIV --config devel.serverrequirecert=true
634 > --config devel.servercafile=$PRIV --config devel.serverrequirecert=true
629 $ cat ../hg0.pid >> $DAEMON_PIDS
635 $ cat ../hg0.pid >> $DAEMON_PIDS
630 $ cd ..
636 $ cd ..
631
637
632 without client certificate:
638 without client certificate:
633
639
634 $ P="$CERTSDIR" hg id https://localhost:$HGPORT/
640 $ P="$CERTSDIR" hg id https://localhost:$HGPORT/
635 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
641 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
636 abort: error: *handshake failure* (glob)
642 abort: error: .*(\$ECONNRESET\$|certificate required|handshake failure).* (re)
637 [255]
643 [255]
638
644
639 with client certificate:
645 with client certificate:
640
646
641 $ cat << EOT >> $HGRCPATH
647 $ cat << EOT >> $HGRCPATH
642 > [auth]
648 > [auth]
643 > l.prefix = localhost
649 > l.prefix = localhost
644 > l.cert = $CERTSDIR/client-cert.pem
650 > l.cert = $CERTSDIR/client-cert.pem
645 > l.key = $CERTSDIR/client-key.pem
651 > l.key = $CERTSDIR/client-key.pem
646 > EOT
652 > EOT
647
653
648 $ P="$CERTSDIR" hg id https://localhost:$HGPORT/ \
654 $ P="$CERTSDIR" hg id https://localhost:$HGPORT/ \
649 > --config auth.l.key="$CERTSDIR/client-key-decrypted.pem"
655 > --config auth.l.key="$CERTSDIR/client-key-decrypted.pem"
650 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
656 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
651 5fed3813f7f5
657 5fed3813f7f5
652
658
653 $ printf '1234\n' | env P="$CERTSDIR" hg id https://localhost:$HGPORT/ \
659 $ printf '1234\n' | env P="$CERTSDIR" hg id https://localhost:$HGPORT/ \
654 > --config ui.interactive=True --config ui.nontty=True
660 > --config ui.interactive=True --config ui.nontty=True
655 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
661 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
656 passphrase for */client-key.pem: 5fed3813f7f5 (glob)
662 passphrase for */client-key.pem: 5fed3813f7f5 (glob)
657
663
658 $ env P="$CERTSDIR" hg id https://localhost:$HGPORT/
664 $ env P="$CERTSDIR" hg id https://localhost:$HGPORT/
659 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
665 warning: connecting to localhost using legacy security technology (TLS 1.0); see https://mercurial-scm.org/wiki/SecureConnections for more info (?)
660 abort: error: * (glob)
666 abort: error: * (glob)
661 [255]
667 [255]
662
668
663 Missing certficate and key files result in error
669 Missing certficate and key files result in error
664
670
665 $ hg id https://localhost:$HGPORT/ --config auth.l.cert=/missing/cert
671 $ hg id https://localhost:$HGPORT/ --config auth.l.cert=/missing/cert
666 abort: certificate file (*/missing/cert) does not exist; cannot connect to localhost (glob)
672 abort: certificate file (*/missing/cert) does not exist; cannot connect to localhost (glob)
667 (restore missing file or fix references in Mercurial config)
673 (restore missing file or fix references in Mercurial config)
668 [255]
674 [255]
669
675
670 $ hg id https://localhost:$HGPORT/ --config auth.l.key=/missing/key
676 $ hg id https://localhost:$HGPORT/ --config auth.l.key=/missing/key
671 abort: certificate file (*/missing/key) does not exist; cannot connect to localhost (glob)
677 abort: certificate file (*/missing/key) does not exist; cannot connect to localhost (glob)
672 (restore missing file or fix references in Mercurial config)
678 (restore missing file or fix references in Mercurial config)
673 [255]
679 [255]
674
680
675 #endif
681 #endif
@@ -1,628 +1,609 b''
1 $ cat <<EOF >> $HGRCPATH
1 $ cat <<EOF >> $HGRCPATH
2 > [ui]
2 > [ui]
3 > commitsubrepos = Yes
3 > commitsubrepos = Yes
4 > [extensions]
4 > [extensions]
5 > mq =
5 > mq =
6 > record =
6 > record =
7 > [diff]
7 > [diff]
8 > nodates = 1
8 > nodates = 1
9 > EOF
9 > EOF
10
10
11 $ stdin=`pwd`/stdin.tmp
11 $ stdin=`pwd`/stdin.tmp
12
12
13 fn to create new repository w/dirty subrepo, and cd into it
13 fn to create new repository w/dirty subrepo, and cd into it
14 $ mkrepo() {
14 $ mkrepo() {
15 > hg init $1
15 > hg init $1
16 > cd $1
16 > cd $1
17 > hg qinit
17 > hg qinit
18 > }
18 > }
19
19
20 fn to create dirty subrepo
20 fn to create dirty subrepo
21 $ mksubrepo() {
21 $ mksubrepo() {
22 > hg init $1
22 > hg init $1
23 > cd $1
23 > cd $1
24 > echo a > a
24 > echo a > a
25 > hg add
25 > hg add
26 > cd ..
26 > cd ..
27 > }
27 > }
28
28
29 $ testadd() {
29 $ testadd() {
30 > cat - > "$stdin"
30 > cat - > "$stdin"
31 > mksubrepo sub
31 > mksubrepo sub
32 > echo sub = sub >> .hgsub
32 > echo sub = sub >> .hgsub
33 > hg add .hgsub
33 > hg add .hgsub
34 > echo % abort when adding .hgsub w/dirty subrepo
34 > echo % abort when adding .hgsub w/dirty subrepo
35 > hg status -S
35 > hg status -S
36 > echo '%' $*
36 > echo '%' $*
37 > cat "$stdin" | hg $*
37 > cat "$stdin" | hg $*
38 > echo [$?]
38 > echo [$?]
39 > hg -R sub ci -m0sub
39 > hg -R sub ci -m0sub
40 > echo % update substate when adding .hgsub w/clean updated subrepo
40 > echo % update substate when adding .hgsub w/clean updated subrepo
41 > hg status -S
41 > hg status -S
42 > echo '%' $*
42 > echo '%' $*
43 > cat "$stdin" | hg $*
43 > cat "$stdin" | hg $*
44 > hg debugsub
44 > hg debugsub
45 > }
45 > }
46
46
47 $ testmod() {
47 $ testmod() {
48 > cat - > "$stdin"
48 > cat - > "$stdin"
49 > mksubrepo sub2
49 > mksubrepo sub2
50 > echo sub2 = sub2 >> .hgsub
50 > echo sub2 = sub2 >> .hgsub
51 > echo % abort when modifying .hgsub w/dirty subrepo
51 > echo % abort when modifying .hgsub w/dirty subrepo
52 > hg status -S
52 > hg status -S
53 > echo '%' $*
53 > echo '%' $*
54 > cat "$stdin" | hg $*
54 > cat "$stdin" | hg $*
55 > echo [$?]
55 > echo [$?]
56 > hg -R sub2 ci -m0sub2
56 > hg -R sub2 ci -m0sub2
57 > echo % update substate when modifying .hgsub w/clean updated subrepo
57 > echo % update substate when modifying .hgsub w/clean updated subrepo
58 > hg status -S
58 > hg status -S
59 > echo '%' $*
59 > echo '%' $*
60 > cat "$stdin" | hg $*
60 > cat "$stdin" | hg $*
61 > hg debugsub
61 > hg debugsub
62 > }
62 > }
63
63
64 $ testrm1() {
64 $ testrm1() {
65 > cat - > "$stdin"
65 > cat - > "$stdin"
66 > mksubrepo sub3
66 > mksubrepo sub3
67 > echo sub3 = sub3 >> .hgsub
67 > echo sub3 = sub3 >> .hgsub
68 > hg ci -Aqmsub3
68 > hg ci -Aqmsub3
69 > $EXTRA
69 > $EXTRA
70 > echo b >> sub3/a
70 > echo b >> sub3/a
71 > hg rm .hgsub
71 > hg rm .hgsub
72 > echo % update substate when removing .hgsub w/dirty subrepo
72 > echo % update substate when removing .hgsub w/dirty subrepo
73 > hg status -S
73 > hg status -S
74 > echo '%' $*
74 > echo '%' $*
75 > cat "$stdin" | hg $*
75 > cat "$stdin" | hg $*
76 > echo % debugsub should be empty
76 > echo % debugsub should be empty
77 > hg debugsub
77 > hg debugsub
78 > }
78 > }
79
79
80 $ testrm2() {
80 $ testrm2() {
81 > cat - > "$stdin"
81 > cat - > "$stdin"
82 > mksubrepo sub4
82 > mksubrepo sub4
83 > echo sub4 = sub4 >> .hgsub
83 > echo sub4 = sub4 >> .hgsub
84 > hg ci -Aqmsub4
84 > hg ci -Aqmsub4
85 > $EXTRA
85 > $EXTRA
86 > hg rm .hgsub
86 > hg rm .hgsub
87 > echo % update substate when removing .hgsub w/clean updated subrepo
87 > echo % update substate when removing .hgsub w/clean updated subrepo
88 > hg status -S
88 > hg status -S
89 > echo '%' $*
89 > echo '%' $*
90 > cat "$stdin" | hg $*
90 > cat "$stdin" | hg $*
91 > echo % debugsub should be empty
91 > echo % debugsub should be empty
92 > hg debugsub
92 > hg debugsub
93 > }
93 > }
94
94
95
95
96 handle subrepos safely on qnew
96 handle subrepos safely on qnew
97
97
98 $ mkrepo repo-2499-qnew
98 $ mkrepo repo-2499-qnew
99 $ testadd qnew -X path:no-effect -m0 0.diff
99 $ testadd qnew -X path:no-effect -m0 0.diff
100 adding a
100 adding a
101 % abort when adding .hgsub w/dirty subrepo
101 % abort when adding .hgsub w/dirty subrepo
102 A .hgsub
102 A .hgsub
103 A sub/a
103 A sub/a
104 % qnew -X path:no-effect -m0 0.diff
104 % qnew -X path:no-effect -m0 0.diff
105 abort: uncommitted changes in subrepository "sub"
105 abort: uncommitted changes in subrepository "sub"
106 [255]
106 [255]
107 % update substate when adding .hgsub w/clean updated subrepo
107 % update substate when adding .hgsub w/clean updated subrepo
108 A .hgsub
108 A .hgsub
109 A sub/a
109 A sub/a
110 % qnew -X path:no-effect -m0 0.diff
110 % qnew -X path:no-effect -m0 0.diff
111 path sub
111 path sub
112 source sub
112 source sub
113 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
113 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
114
114
115 $ testmod qnew --cwd .. -R repo-2499-qnew -X path:no-effect -m1 1.diff
115 $ testmod qnew --cwd .. -R repo-2499-qnew -X path:no-effect -m1 1.diff
116 adding a
116 adding a
117 % abort when modifying .hgsub w/dirty subrepo
117 % abort when modifying .hgsub w/dirty subrepo
118 M .hgsub
118 M .hgsub
119 A sub2/a
119 A sub2/a
120 % qnew --cwd .. -R repo-2499-qnew -X path:no-effect -m1 1.diff
120 % qnew --cwd .. -R repo-2499-qnew -X path:no-effect -m1 1.diff
121 abort: uncommitted changes in subrepository "sub2"
121 abort: uncommitted changes in subrepository "sub2"
122 [255]
122 [255]
123 % update substate when modifying .hgsub w/clean updated subrepo
123 % update substate when modifying .hgsub w/clean updated subrepo
124 M .hgsub
124 M .hgsub
125 A sub2/a
125 A sub2/a
126 % qnew --cwd .. -R repo-2499-qnew -X path:no-effect -m1 1.diff
126 % qnew --cwd .. -R repo-2499-qnew -X path:no-effect -m1 1.diff
127 path sub
127 path sub
128 source sub
128 source sub
129 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
129 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
130 path sub2
130 path sub2
131 source sub2
131 source sub2
132 revision 1f94c7611cc6b74f5a17b16121a1170d44776845
132 revision 1f94c7611cc6b74f5a17b16121a1170d44776845
133
133
134 $ hg qpop -qa
134 $ hg qpop -qa
135 patch queue now empty
135 patch queue now empty
136 $ testrm1 qnew -m2 2.diff
136 $ testrm1 qnew -m2 2.diff
137 adding a
137 adding a
138 % update substate when removing .hgsub w/dirty subrepo
138 % update substate when removing .hgsub w/dirty subrepo
139 M sub3/a
139 M sub3/a
140 R .hgsub
140 R .hgsub
141 % qnew -m2 2.diff
141 % qnew -m2 2.diff
142 % debugsub should be empty
142 % debugsub should be empty
143
143
144 $ hg qpop -qa
144 $ hg qpop -qa
145 patch queue now empty
145 patch queue now empty
146 $ testrm2 qnew -m3 3.diff
146 $ testrm2 qnew -m3 3.diff
147 adding a
147 adding a
148 % update substate when removing .hgsub w/clean updated subrepo
148 % update substate when removing .hgsub w/clean updated subrepo
149 R .hgsub
149 R .hgsub
150 % qnew -m3 3.diff
150 % qnew -m3 3.diff
151 % debugsub should be empty
151 % debugsub should be empty
152
152
153 $ cd ..
153 $ cd ..
154
154
155
155
156 handle subrepos safely on qrefresh
156 handle subrepos safely on qrefresh
157
157
158 $ mkrepo repo-2499-qrefresh
158 $ mkrepo repo-2499-qrefresh
159 $ hg qnew -m0 0.diff
159 $ hg qnew -m0 0.diff
160 $ testadd qrefresh
160 $ testadd qrefresh
161 adding a
161 adding a
162 % abort when adding .hgsub w/dirty subrepo
162 % abort when adding .hgsub w/dirty subrepo
163 A .hgsub
163 A .hgsub
164 A sub/a
164 A sub/a
165 % qrefresh
165 % qrefresh
166 abort: uncommitted changes in subrepository "sub"
166 abort: uncommitted changes in subrepository "sub"
167 [255]
167 [255]
168 % update substate when adding .hgsub w/clean updated subrepo
168 % update substate when adding .hgsub w/clean updated subrepo
169 A .hgsub
169 A .hgsub
170 A sub/a
170 A sub/a
171 % qrefresh
171 % qrefresh
172 path sub
172 path sub
173 source sub
173 source sub
174 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
174 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
175
175
176 $ hg qnew -m1 1.diff
176 $ hg qnew -m1 1.diff
177 $ testmod qrefresh
177 $ testmod qrefresh
178 adding a
178 adding a
179 % abort when modifying .hgsub w/dirty subrepo
179 % abort when modifying .hgsub w/dirty subrepo
180 M .hgsub
180 M .hgsub
181 A sub2/a
181 A sub2/a
182 % qrefresh
182 % qrefresh
183 abort: uncommitted changes in subrepository "sub2"
183 abort: uncommitted changes in subrepository "sub2"
184 [255]
184 [255]
185 % update substate when modifying .hgsub w/clean updated subrepo
185 % update substate when modifying .hgsub w/clean updated subrepo
186 M .hgsub
186 M .hgsub
187 A sub2/a
187 A sub2/a
188 % qrefresh
188 % qrefresh
189 path sub
189 path sub
190 source sub
190 source sub
191 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
191 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
192 path sub2
192 path sub2
193 source sub2
193 source sub2
194 revision 1f94c7611cc6b74f5a17b16121a1170d44776845
194 revision 1f94c7611cc6b74f5a17b16121a1170d44776845
195
195
196 $ hg qpop -qa
196 $ hg qpop -qa
197 patch queue now empty
197 patch queue now empty
198 $ EXTRA='hg qnew -m2 2.diff'
198 $ EXTRA='hg qnew -m2 2.diff'
199 $ testrm1 qrefresh
199 $ testrm1 qrefresh
200 adding a
200 adding a
201 % update substate when removing .hgsub w/dirty subrepo
201 % update substate when removing .hgsub w/dirty subrepo
202 M sub3/a
202 M sub3/a
203 R .hgsub
203 R .hgsub
204 % qrefresh
204 % qrefresh
205 % debugsub should be empty
205 % debugsub should be empty
206
206
207 $ hg qpop -qa
207 $ hg qpop -qa
208 patch queue now empty
208 patch queue now empty
209 $ EXTRA='hg qnew -m3 3.diff'
209 $ EXTRA='hg qnew -m3 3.diff'
210 $ testrm2 qrefresh
210 $ testrm2 qrefresh
211 adding a
211 adding a
212 % update substate when removing .hgsub w/clean updated subrepo
212 % update substate when removing .hgsub w/clean updated subrepo
213 R .hgsub
213 R .hgsub
214 % qrefresh
214 % qrefresh
215 % debugsub should be empty
215 % debugsub should be empty
216 $ EXTRA=
216 $ EXTRA=
217
217
218 $ cd ..
218 $ cd ..
219
219
220
220
221 handle subrepos safely on qpush/qpop
221 handle subrepos safely on qpush/qpop
222 (and we cannot qpop / qpush with a modified subrepo)
222 (and we cannot qpop / qpush with a modified subrepo)
223
223
224 $ mkrepo repo-2499-qpush
224 $ mkrepo repo-2499-qpush
225 $ mksubrepo sub
225 $ mksubrepo sub
226 adding a
226 adding a
227 $ hg -R sub ci -m0sub
227 $ hg -R sub ci -m0sub
228 $ echo sub = sub > .hgsub
228 $ echo sub = sub > .hgsub
229 $ hg add .hgsub
229 $ hg add .hgsub
230 $ hg commit -m0
230 $ hg commit -m0
231 $ hg debugsub
231 $ hg debugsub
232 path sub
232 path sub
233 source sub
233 source sub
234 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
234 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
235 $ echo foo > ./sub/a
235 $ echo foo > ./sub/a
236 $ hg -R sub commit -m foo
236 $ hg -R sub commit -m foo
237 $ hg commit -m1
237 $ hg commit -m1
238 $ hg qimport -r "0:tip"
238 $ hg qimport -r "0:tip"
239 $ hg -R sub id --id
239 $ hg -R sub id --id
240 aa037b301eba
240 aa037b301eba
241
241
242 qpop
242 qpop
243 $ hg -R sub update 0000
243 $ hg -R sub update 0000
244 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
244 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
245 $ hg qpop
245 $ hg qpop
246 abort: local changed subrepos found, qrefresh first
246 abort: local changed subrepos found, qrefresh first
247 [255]
247 [255]
248 $ hg revert sub
248 $ hg revert sub
249 reverting subrepo sub
249 reverting subrepo sub
250 adding sub/a
250 adding sub/a
251 $ hg qpop
251 $ hg qpop
252 popping 1
252 popping 1
253 now at: 0
253 now at: 0
254 $ hg status -AS
254 $ hg status -AS
255 C .hgsub
255 C .hgsub
256 C .hgsubstate
256 C .hgsubstate
257 C sub/a
257 C sub/a
258 $ hg -R sub id --id
258 $ hg -R sub id --id
259 b2fdb12cd82b
259 b2fdb12cd82b
260
260
261 qpush
261 qpush
262 $ hg -R sub update 0000
262 $ hg -R sub update 0000
263 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
263 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
264 $ hg qpush
264 $ hg qpush
265 abort: local changed subrepos found, qrefresh first
265 abort: local changed subrepos found, qrefresh first
266 [255]
266 [255]
267 $ hg revert sub
267 $ hg revert sub
268 reverting subrepo sub
268 reverting subrepo sub
269 adding sub/a
269 adding sub/a
270 $ hg qpush
270 $ hg qpush
271 applying 1
271 applying 1
272 subrepository sub diverged (local revision: b2fdb12cd82b, remote revision: aa037b301eba)
272 subrepository sub diverged (local revision: b2fdb12cd82b, remote revision: aa037b301eba)
273 (M)erge, keep (l)ocal or keep (r)emote? m
273 (M)erge, keep (l)ocal or keep (r)emote? m
274 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
274 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
275 now at: 1
275 now at: 1
276 $ hg status -AS
276 $ hg status -AS
277 C .hgsub
277 C .hgsub
278 C .hgsubstate
278 C .hgsubstate
279 C sub/a
279 C sub/a
280 $ hg -R sub id --id
280 $ hg -R sub id --id
281 aa037b301eba
281 aa037b301eba
282
282
283 $ cd ..
283 $ cd ..
284
284
285
285
286 handle subrepos safely on qrecord
286 handle subrepos safely on qrecord
287
287
288 $ mkrepo repo-2499-qrecord
288 $ mkrepo repo-2499-qrecord
289 $ testadd qrecord --config ui.interactive=1 -m0 0.diff <<EOF
289 $ testadd qrecord --config ui.interactive=1 -m0 0.diff <<EOF
290 > y
290 > y
291 > y
291 > y
292 > EOF
292 > EOF
293 adding a
293 adding a
294 % abort when adding .hgsub w/dirty subrepo
294 % abort when adding .hgsub w/dirty subrepo
295 A .hgsub
295 A .hgsub
296 A sub/a
296 A sub/a
297 % qrecord --config ui.interactive=1 -m0 0.diff
297 % qrecord --config ui.interactive=1 -m0 0.diff
298 diff --git a/.hgsub b/.hgsub
299 new file mode 100644
300 examine changes to '.hgsub'? [Ynesfdaq?] y
301
302 @@ -0,0 +1,1 @@
303 +sub = sub
304 record this change to '.hgsub'? [Ynesfdaq?] y
305
306 warning: subrepo spec file '.hgsub' not found
307 warning: subrepo spec file '.hgsub' not found
308 abort: uncommitted changes in subrepository "sub"
298 abort: uncommitted changes in subrepository "sub"
309 [255]
299 [255]
310 % update substate when adding .hgsub w/clean updated subrepo
300 % update substate when adding .hgsub w/clean updated subrepo
311 A .hgsub
301 A .hgsub
312 A sub/a
302 A sub/a
313 % qrecord --config ui.interactive=1 -m0 0.diff
303 % qrecord --config ui.interactive=1 -m0 0.diff
314 diff --git a/.hgsub b/.hgsub
304 diff --git a/.hgsub b/.hgsub
315 new file mode 100644
305 new file mode 100644
316 examine changes to '.hgsub'? [Ynesfdaq?] y
306 examine changes to '.hgsub'? [Ynesfdaq?] y
317
307
318 @@ -0,0 +1,1 @@
308 @@ -0,0 +1,1 @@
319 +sub = sub
309 +sub = sub
320 record this change to '.hgsub'? [Ynesfdaq?] y
310 record this change to '.hgsub'? [Ynesfdaq?] y
321
311
322 warning: subrepo spec file '.hgsub' not found
312 warning: subrepo spec file '.hgsub' not found
323 warning: subrepo spec file '.hgsub' not found
313 warning: subrepo spec file '.hgsub' not found
324 path sub
314 path sub
325 source sub
315 source sub
326 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
316 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
327 $ testmod qrecord --config ui.interactive=1 -m1 1.diff <<EOF
317 $ testmod qrecord --config ui.interactive=1 -m1 1.diff <<EOF
328 > y
318 > y
329 > y
319 > y
330 > EOF
320 > EOF
331 adding a
321 adding a
332 % abort when modifying .hgsub w/dirty subrepo
322 % abort when modifying .hgsub w/dirty subrepo
333 M .hgsub
323 M .hgsub
334 A sub2/a
324 A sub2/a
335 % qrecord --config ui.interactive=1 -m1 1.diff
325 % qrecord --config ui.interactive=1 -m1 1.diff
336 diff --git a/.hgsub b/.hgsub
337 1 hunks, 1 lines changed
338 examine changes to '.hgsub'? [Ynesfdaq?] y
339
340 @@ -1,1 +1,2 @@
341 sub = sub
342 +sub2 = sub2
343 record this change to '.hgsub'? [Ynesfdaq?] y
344
345 abort: uncommitted changes in subrepository "sub2"
326 abort: uncommitted changes in subrepository "sub2"
346 [255]
327 [255]
347 % update substate when modifying .hgsub w/clean updated subrepo
328 % update substate when modifying .hgsub w/clean updated subrepo
348 M .hgsub
329 M .hgsub
349 A sub2/a
330 A sub2/a
350 % qrecord --config ui.interactive=1 -m1 1.diff
331 % qrecord --config ui.interactive=1 -m1 1.diff
351 diff --git a/.hgsub b/.hgsub
332 diff --git a/.hgsub b/.hgsub
352 1 hunks, 1 lines changed
333 1 hunks, 1 lines changed
353 examine changes to '.hgsub'? [Ynesfdaq?] y
334 examine changes to '.hgsub'? [Ynesfdaq?] y
354
335
355 @@ -1,1 +1,2 @@
336 @@ -1,1 +1,2 @@
356 sub = sub
337 sub = sub
357 +sub2 = sub2
338 +sub2 = sub2
358 record this change to '.hgsub'? [Ynesfdaq?] y
339 record this change to '.hgsub'? [Ynesfdaq?] y
359
340
360 path sub
341 path sub
361 source sub
342 source sub
362 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
343 revision b2fdb12cd82b021c3b7053d67802e77b6eeaee31
363 path sub2
344 path sub2
364 source sub2
345 source sub2
365 revision 1f94c7611cc6b74f5a17b16121a1170d44776845
346 revision 1f94c7611cc6b74f5a17b16121a1170d44776845
366
347
367 $ hg qpop -qa
348 $ hg qpop -qa
368 patch queue now empty
349 patch queue now empty
369 $ testrm1 qrecord --config ui.interactive=1 -m2 2.diff <<EOF
350 $ testrm1 qrecord --config ui.interactive=1 -m2 2.diff <<EOF
370 > y
351 > y
371 > y
352 > y
372 > EOF
353 > EOF
373 adding a
354 adding a
374 % update substate when removing .hgsub w/dirty subrepo
355 % update substate when removing .hgsub w/dirty subrepo
375 M sub3/a
356 M sub3/a
376 R .hgsub
357 R .hgsub
377 % qrecord --config ui.interactive=1 -m2 2.diff
358 % qrecord --config ui.interactive=1 -m2 2.diff
378 diff --git a/.hgsub b/.hgsub
359 diff --git a/.hgsub b/.hgsub
379 deleted file mode 100644
360 deleted file mode 100644
380 examine changes to '.hgsub'? [Ynesfdaq?] y
361 examine changes to '.hgsub'? [Ynesfdaq?] y
381
362
382 % debugsub should be empty
363 % debugsub should be empty
383
364
384 $ hg qpop -qa
365 $ hg qpop -qa
385 patch queue now empty
366 patch queue now empty
386 $ testrm2 qrecord --config ui.interactive=1 -m3 3.diff <<EOF
367 $ testrm2 qrecord --config ui.interactive=1 -m3 3.diff <<EOF
387 > y
368 > y
388 > y
369 > y
389 > EOF
370 > EOF
390 adding a
371 adding a
391 % update substate when removing .hgsub w/clean updated subrepo
372 % update substate when removing .hgsub w/clean updated subrepo
392 R .hgsub
373 R .hgsub
393 % qrecord --config ui.interactive=1 -m3 3.diff
374 % qrecord --config ui.interactive=1 -m3 3.diff
394 diff --git a/.hgsub b/.hgsub
375 diff --git a/.hgsub b/.hgsub
395 deleted file mode 100644
376 deleted file mode 100644
396 examine changes to '.hgsub'? [Ynesfdaq?] y
377 examine changes to '.hgsub'? [Ynesfdaq?] y
397
378
398 % debugsub should be empty
379 % debugsub should be empty
399
380
400 $ cd ..
381 $ cd ..
401
382
402
383
403 correctly handle subrepos with patch queues
384 correctly handle subrepos with patch queues
404 $ mkrepo repo-subrepo-with-queue
385 $ mkrepo repo-subrepo-with-queue
405 $ mksubrepo sub
386 $ mksubrepo sub
406 adding a
387 adding a
407 $ hg -R sub qnew sub0.diff
388 $ hg -R sub qnew sub0.diff
408 $ echo sub = sub >> .hgsub
389 $ echo sub = sub >> .hgsub
409 $ hg add .hgsub
390 $ hg add .hgsub
410 $ hg qnew 0.diff
391 $ hg qnew 0.diff
411
392
412 $ cd ..
393 $ cd ..
413
394
414 check whether MQ operations can import updated .hgsubstate correctly
395 check whether MQ operations can import updated .hgsubstate correctly
415 both into 'revision' and 'patch file under .hg/patches':
396 both into 'revision' and 'patch file under .hg/patches':
416
397
417 $ hg init importing-hgsubstate
398 $ hg init importing-hgsubstate
418 $ cd importing-hgsubstate
399 $ cd importing-hgsubstate
419
400
420 $ echo a > a
401 $ echo a > a
421 $ hg commit -u test -d '0 0' -Am '#0 in parent'
402 $ hg commit -u test -d '0 0' -Am '#0 in parent'
422 adding a
403 adding a
423 $ hg init sub
404 $ hg init sub
424 $ echo sa > sub/sa
405 $ echo sa > sub/sa
425 $ hg -R sub commit -u test -d '0 0' -Am '#0 in sub'
406 $ hg -R sub commit -u test -d '0 0' -Am '#0 in sub'
426 adding sa
407 adding sa
427 $ echo 'sub = sub' > .hgsub
408 $ echo 'sub = sub' > .hgsub
428 $ touch .hgsubstate
409 $ touch .hgsubstate
429 $ hg add .hgsub .hgsubstate
410 $ hg add .hgsub .hgsubstate
430
411
431 $ hg qnew -u test -d '0 0' import-at-qnew
412 $ hg qnew -u test -d '0 0' import-at-qnew
432 $ hg -R sub parents --template '{node} sub\n'
413 $ hg -R sub parents --template '{node} sub\n'
433 b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
414 b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
434 $ cat .hgsubstate
415 $ cat .hgsubstate
435 b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
416 b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
436 $ hg diff -c tip
417 $ hg diff -c tip
437 diff -r f499373e340c -r f69e96d86e75 .hgsub
418 diff -r f499373e340c -r f69e96d86e75 .hgsub
438 --- /dev/null
419 --- /dev/null
439 +++ b/.hgsub
420 +++ b/.hgsub
440 @@ -0,0 +1,1 @@
421 @@ -0,0 +1,1 @@
441 +sub = sub
422 +sub = sub
442 diff -r f499373e340c -r f69e96d86e75 .hgsubstate
423 diff -r f499373e340c -r f69e96d86e75 .hgsubstate
443 --- /dev/null
424 --- /dev/null
444 +++ b/.hgsubstate
425 +++ b/.hgsubstate
445 @@ -0,0 +1,1 @@
426 @@ -0,0 +1,1 @@
446 +b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
427 +b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
447 $ cat .hg/patches/import-at-qnew
428 $ cat .hg/patches/import-at-qnew
448 # HG changeset patch
429 # HG changeset patch
449 # User test
430 # User test
450 # Date 0 0
431 # Date 0 0
451 # Parent f499373e340cdca5d01dee904aeb42dd2a325e71
432 # Parent f499373e340cdca5d01dee904aeb42dd2a325e71
452
433
453 diff -r f499373e340c -r f69e96d86e75 .hgsub
434 diff -r f499373e340c -r f69e96d86e75 .hgsub
454 --- /dev/null
435 --- /dev/null
455 +++ b/.hgsub
436 +++ b/.hgsub
456 @@ -0,0 +1,1 @@
437 @@ -0,0 +1,1 @@
457 +sub = sub
438 +sub = sub
458 diff -r f499373e340c -r f69e96d86e75 .hgsubstate
439 diff -r f499373e340c -r f69e96d86e75 .hgsubstate
459 --- /dev/null
440 --- /dev/null
460 +++ b/.hgsubstate
441 +++ b/.hgsubstate
461 @@ -0,0 +1,1 @@
442 @@ -0,0 +1,1 @@
462 +b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
443 +b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
463 $ hg parents --template '{node}\n'
444 $ hg parents --template '{node}\n'
464 f69e96d86e75a6d4fd88285dc9697acb23951041
445 f69e96d86e75a6d4fd88285dc9697acb23951041
465 $ hg parents --template '{files}\n'
446 $ hg parents --template '{files}\n'
466 .hgsub .hgsubstate
447 .hgsub .hgsubstate
467
448
468 check also whether qnew not including ".hgsubstate" explicitly causes
449 check also whether qnew not including ".hgsubstate" explicitly causes
469 as same result (in node hash) as one including it.
450 as same result (in node hash) as one including it.
470
451
471 $ hg qpop -a -q
452 $ hg qpop -a -q
472 patch queue now empty
453 patch queue now empty
473 $ hg qdelete import-at-qnew
454 $ hg qdelete import-at-qnew
474 $ echo 'sub = sub' > .hgsub
455 $ echo 'sub = sub' > .hgsub
475 $ hg add .hgsub
456 $ hg add .hgsub
476 $ rm -f .hgsubstate
457 $ rm -f .hgsubstate
477 $ hg qnew -u test -d '0 0' import-at-qnew
458 $ hg qnew -u test -d '0 0' import-at-qnew
478 $ hg parents --template '{node}\n'
459 $ hg parents --template '{node}\n'
479 f69e96d86e75a6d4fd88285dc9697acb23951041
460 f69e96d86e75a6d4fd88285dc9697acb23951041
480 $ hg parents --template '{files}\n'
461 $ hg parents --template '{files}\n'
481 .hgsub .hgsubstate
462 .hgsub .hgsubstate
482
463
483 check whether qrefresh imports updated .hgsubstate correctly
464 check whether qrefresh imports updated .hgsubstate correctly
484
465
485 $ hg qpop
466 $ hg qpop
486 popping import-at-qnew
467 popping import-at-qnew
487 patch queue now empty
468 patch queue now empty
488 $ hg qpush
469 $ hg qpush
489 applying import-at-qnew
470 applying import-at-qnew
490 now at: import-at-qnew
471 now at: import-at-qnew
491 $ hg parents --template '{files}\n'
472 $ hg parents --template '{files}\n'
492 .hgsub .hgsubstate
473 .hgsub .hgsubstate
493
474
494 $ hg qnew import-at-qrefresh
475 $ hg qnew import-at-qrefresh
495 $ echo sb > sub/sb
476 $ echo sb > sub/sb
496 $ hg -R sub commit -u test -d '0 0' -Am '#1 in sub'
477 $ hg -R sub commit -u test -d '0 0' -Am '#1 in sub'
497 adding sb
478 adding sb
498 $ hg qrefresh -u test -d '0 0'
479 $ hg qrefresh -u test -d '0 0'
499 $ hg -R sub parents --template '{node} sub\n'
480 $ hg -R sub parents --template '{node} sub\n'
500 88ac1bef5ed43b689d1d200b59886b675dec474b sub
481 88ac1bef5ed43b689d1d200b59886b675dec474b sub
501 $ cat .hgsubstate
482 $ cat .hgsubstate
502 88ac1bef5ed43b689d1d200b59886b675dec474b sub
483 88ac1bef5ed43b689d1d200b59886b675dec474b sub
503 $ hg diff -c tip
484 $ hg diff -c tip
504 diff -r 05b056bb9c8c -r d987bec230f4 .hgsubstate
485 diff -r 05b056bb9c8c -r d987bec230f4 .hgsubstate
505 --- a/.hgsubstate
486 --- a/.hgsubstate
506 +++ b/.hgsubstate
487 +++ b/.hgsubstate
507 @@ -1,1 +1,1 @@
488 @@ -1,1 +1,1 @@
508 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
489 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
509 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
490 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
510 $ cat .hg/patches/import-at-qrefresh
491 $ cat .hg/patches/import-at-qrefresh
511 # HG changeset patch
492 # HG changeset patch
512 # User test
493 # User test
513 # Date 0 0
494 # Date 0 0
514 # Parent 05b056bb9c8c05ff15258b84fd42ab3527271033
495 # Parent 05b056bb9c8c05ff15258b84fd42ab3527271033
515
496
516 diff -r 05b056bb9c8c .hgsubstate
497 diff -r 05b056bb9c8c .hgsubstate
517 --- a/.hgsubstate
498 --- a/.hgsubstate
518 +++ b/.hgsubstate
499 +++ b/.hgsubstate
519 @@ -1,1 +1,1 @@
500 @@ -1,1 +1,1 @@
520 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
501 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
521 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
502 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
522 $ hg parents --template '{files}\n'
503 $ hg parents --template '{files}\n'
523 .hgsubstate
504 .hgsubstate
524
505
525 $ hg qrefresh -u test -d '0 0'
506 $ hg qrefresh -u test -d '0 0'
526 $ cat .hgsubstate
507 $ cat .hgsubstate
527 88ac1bef5ed43b689d1d200b59886b675dec474b sub
508 88ac1bef5ed43b689d1d200b59886b675dec474b sub
528 $ hg diff -c tip
509 $ hg diff -c tip
529 diff -r 05b056bb9c8c -r d987bec230f4 .hgsubstate
510 diff -r 05b056bb9c8c -r d987bec230f4 .hgsubstate
530 --- a/.hgsubstate
511 --- a/.hgsubstate
531 +++ b/.hgsubstate
512 +++ b/.hgsubstate
532 @@ -1,1 +1,1 @@
513 @@ -1,1 +1,1 @@
533 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
514 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
534 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
515 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
535 $ cat .hg/patches/import-at-qrefresh
516 $ cat .hg/patches/import-at-qrefresh
536 # HG changeset patch
517 # HG changeset patch
537 # User test
518 # User test
538 # Date 0 0
519 # Date 0 0
539 # Parent 05b056bb9c8c05ff15258b84fd42ab3527271033
520 # Parent 05b056bb9c8c05ff15258b84fd42ab3527271033
540
521
541 diff -r 05b056bb9c8c .hgsubstate
522 diff -r 05b056bb9c8c .hgsubstate
542 --- a/.hgsubstate
523 --- a/.hgsubstate
543 +++ b/.hgsubstate
524 +++ b/.hgsubstate
544 @@ -1,1 +1,1 @@
525 @@ -1,1 +1,1 @@
545 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
526 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
546 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
527 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
547 $ hg parents --template '{files}\n'
528 $ hg parents --template '{files}\n'
548 .hgsubstate
529 .hgsubstate
549
530
550 $ hg update -C tip
531 $ hg update -C tip
551 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
532 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
552 $ hg qpop -a
533 $ hg qpop -a
553 popping import-at-qrefresh
534 popping import-at-qrefresh
554 popping import-at-qnew
535 popping import-at-qnew
555 patch queue now empty
536 patch queue now empty
556
537
557 $ hg -R sub update -C 0
538 $ hg -R sub update -C 0
558 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
539 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
559 $ echo 'sub = sub' > .hgsub
540 $ echo 'sub = sub' > .hgsub
560 $ hg commit -Am '#1 in parent'
541 $ hg commit -Am '#1 in parent'
561 adding .hgsub
542 adding .hgsub
562 $ hg -R sub update -C 1
543 $ hg -R sub update -C 1
563 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
544 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
564 $ hg commit -Am '#2 in parent (but will be rolled back soon)'
545 $ hg commit -Am '#2 in parent (but will be rolled back soon)'
565 $ hg rollback
546 $ hg rollback
566 repository tip rolled back to revision 1 (undo commit)
547 repository tip rolled back to revision 1 (undo commit)
567 working directory now based on revision 1
548 working directory now based on revision 1
568 $ hg status
549 $ hg status
569 M .hgsubstate
550 M .hgsubstate
570 $ hg qnew -u test -d '0 0' checkstate-at-qnew
551 $ hg qnew -u test -d '0 0' checkstate-at-qnew
571 $ hg -R sub parents --template '{node} sub\n'
552 $ hg -R sub parents --template '{node} sub\n'
572 88ac1bef5ed43b689d1d200b59886b675dec474b sub
553 88ac1bef5ed43b689d1d200b59886b675dec474b sub
573 $ cat .hgsubstate
554 $ cat .hgsubstate
574 88ac1bef5ed43b689d1d200b59886b675dec474b sub
555 88ac1bef5ed43b689d1d200b59886b675dec474b sub
575 $ hg diff -c tip
556 $ hg diff -c tip
576 diff -r 4d91eb2fa1d1 -r 1259c112d884 .hgsubstate
557 diff -r 4d91eb2fa1d1 -r 1259c112d884 .hgsubstate
577 --- a/.hgsubstate
558 --- a/.hgsubstate
578 +++ b/.hgsubstate
559 +++ b/.hgsubstate
579 @@ -1,1 +1,1 @@
560 @@ -1,1 +1,1 @@
580 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
561 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
581 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
562 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
582 $ cat .hg/patches/checkstate-at-qnew
563 $ cat .hg/patches/checkstate-at-qnew
583 # HG changeset patch
564 # HG changeset patch
584 # User test
565 # User test
585 # Date 0 0
566 # Date 0 0
586 # Parent 4d91eb2fa1d1b22ec513347b9cd06f6b49d470fa
567 # Parent 4d91eb2fa1d1b22ec513347b9cd06f6b49d470fa
587
568
588 diff -r 4d91eb2fa1d1 -r 1259c112d884 .hgsubstate
569 diff -r 4d91eb2fa1d1 -r 1259c112d884 .hgsubstate
589 --- a/.hgsubstate
570 --- a/.hgsubstate
590 +++ b/.hgsubstate
571 +++ b/.hgsubstate
591 @@ -1,1 +1,1 @@
572 @@ -1,1 +1,1 @@
592 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
573 -b6f6e9c41f3dfd374a6d2ed4535c87951cf979cf sub
593 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
574 +88ac1bef5ed43b689d1d200b59886b675dec474b sub
594 $ hg parents --template '{files}\n'
575 $ hg parents --template '{files}\n'
595 .hgsubstate
576 .hgsubstate
596
577
597 check whether qrefresh not including ".hgsubstate" explicitly causes
578 check whether qrefresh not including ".hgsubstate" explicitly causes
598 as same result (in node hash) as one including it.
579 as same result (in node hash) as one including it.
599
580
600 $ hg update -C -q 0
581 $ hg update -C -q 0
601 $ hg qpop -a -q
582 $ hg qpop -a -q
602 patch queue now empty
583 patch queue now empty
603 $ hg qnew -u test -d '0 0' add-hgsub-at-qrefresh
584 $ hg qnew -u test -d '0 0' add-hgsub-at-qrefresh
604 $ echo 'sub = sub' > .hgsub
585 $ echo 'sub = sub' > .hgsub
605 $ echo > .hgsubstate
586 $ echo > .hgsubstate
606 $ hg add .hgsub .hgsubstate
587 $ hg add .hgsub .hgsubstate
607 $ hg qrefresh -u test -d '0 0'
588 $ hg qrefresh -u test -d '0 0'
608 $ hg parents --template '{node}\n'
589 $ hg parents --template '{node}\n'
609 7c48c35501aae6770ed9c2517014628615821a8e
590 7c48c35501aae6770ed9c2517014628615821a8e
610 $ hg parents --template '{files}\n'
591 $ hg parents --template '{files}\n'
611 .hgsub .hgsubstate
592 .hgsub .hgsubstate
612
593
613 $ hg qpop -a -q
594 $ hg qpop -a -q
614 patch queue now empty
595 patch queue now empty
615 $ hg qdelete add-hgsub-at-qrefresh
596 $ hg qdelete add-hgsub-at-qrefresh
616 $ hg qnew -u test -d '0 0' add-hgsub-at-qrefresh
597 $ hg qnew -u test -d '0 0' add-hgsub-at-qrefresh
617 $ echo 'sub = sub' > .hgsub
598 $ echo 'sub = sub' > .hgsub
618 $ hg add .hgsub
599 $ hg add .hgsub
619 $ rm -f .hgsubstate
600 $ rm -f .hgsubstate
620 $ hg qrefresh -u test -d '0 0'
601 $ hg qrefresh -u test -d '0 0'
621 $ hg parents --template '{node}\n'
602 $ hg parents --template '{node}\n'
622 7c48c35501aae6770ed9c2517014628615821a8e
603 7c48c35501aae6770ed9c2517014628615821a8e
623 $ hg parents --template '{files}\n'
604 $ hg parents --template '{files}\n'
624 .hgsub .hgsubstate
605 .hgsub .hgsubstate
625
606
626 $ cd ..
607 $ cd ..
627
608
628 $ cd ..
609 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now