##// END OF EJS Templates
merge with stable
Matt Mackall -
r23706:33146646 merge default
parent child Browse files
Show More
@@ -1,101 +1,102 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,114 +1,115 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
@@ -1,579 +1,566 b''
1 # Copyright 2009-2010 Gregory P. Ward
1 # Copyright 2009-2010 Gregory P. Ward
2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
3 # Copyright 2010-2011 Fog Creek Software
3 # Copyright 2010-2011 Fog Creek Software
4 # Copyright 2010-2011 Unity Technologies
4 # Copyright 2010-2011 Unity Technologies
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 '''High-level command function for lfconvert, plus the cmdtable.'''
9 '''High-level command function for lfconvert, plus the cmdtable.'''
10
10
11 import os, errno
11 import os, errno
12 import shutil
12 import shutil
13
13
14 from mercurial import util, match as match_, hg, node, context, error, \
14 from mercurial import util, match as match_, hg, node, context, error, \
15 cmdutil, scmutil, commands
15 cmdutil, scmutil, commands
16 from mercurial.i18n import _
16 from mercurial.i18n import _
17 from mercurial.lock import release
17 from mercurial.lock import release
18
18
19 import lfutil
19 import lfutil
20 import basestore
20 import basestore
21
21
22 # -- Commands ----------------------------------------------------------
22 # -- Commands ----------------------------------------------------------
23
23
24 cmdtable = {}
24 cmdtable = {}
25 command = cmdutil.command(cmdtable)
25 command = cmdutil.command(cmdtable)
26
26
27 @command('lfconvert',
27 @command('lfconvert',
28 [('s', 'size', '',
28 [('s', 'size', '',
29 _('minimum size (MB) for files to be converted as largefiles'), 'SIZE'),
29 _('minimum size (MB) for files to be converted as largefiles'), 'SIZE'),
30 ('', 'to-normal', False,
30 ('', 'to-normal', False,
31 _('convert from a largefiles repo to a normal repo')),
31 _('convert from a largefiles repo to a normal repo')),
32 ],
32 ],
33 _('hg lfconvert SOURCE DEST [FILE ...]'),
33 _('hg lfconvert SOURCE DEST [FILE ...]'),
34 norepo=True,
34 norepo=True,
35 inferrepo=True)
35 inferrepo=True)
36 def lfconvert(ui, src, dest, *pats, **opts):
36 def lfconvert(ui, src, dest, *pats, **opts):
37 '''convert a normal repository to a largefiles repository
37 '''convert a normal repository to a largefiles repository
38
38
39 Convert repository SOURCE to a new repository DEST, identical to
39 Convert repository SOURCE to a new repository DEST, identical to
40 SOURCE except that certain files will be converted as largefiles:
40 SOURCE except that certain files will be converted as largefiles:
41 specifically, any file that matches any PATTERN *or* whose size is
41 specifically, any file that matches any PATTERN *or* whose size is
42 above the minimum size threshold is converted as a largefile. The
42 above the minimum size threshold is converted as a largefile. The
43 size used to determine whether or not to track a file as a
43 size used to determine whether or not to track a file as a
44 largefile is the size of the first version of the file. The
44 largefile is the size of the first version of the file. The
45 minimum size can be specified either with --size or in
45 minimum size can be specified either with --size or in
46 configuration as ``largefiles.size``.
46 configuration as ``largefiles.size``.
47
47
48 After running this command you will need to make sure that
48 After running this command you will need to make sure that
49 largefiles is enabled anywhere you intend to push the new
49 largefiles is enabled anywhere you intend to push the new
50 repository.
50 repository.
51
51
52 Use --to-normal to convert largefiles back to normal files; after
52 Use --to-normal to convert largefiles back to normal files; after
53 this, the DEST repository can be used without largefiles at all.'''
53 this, the DEST repository can be used without largefiles at all.'''
54
54
55 if opts['to_normal']:
55 if opts['to_normal']:
56 tolfile = False
56 tolfile = False
57 else:
57 else:
58 tolfile = True
58 tolfile = True
59 size = lfutil.getminsize(ui, True, opts.get('size'), default=None)
59 size = lfutil.getminsize(ui, True, opts.get('size'), default=None)
60
60
61 if not hg.islocal(src):
61 if not hg.islocal(src):
62 raise util.Abort(_('%s is not a local Mercurial repo') % src)
62 raise util.Abort(_('%s is not a local Mercurial repo') % src)
63 if not hg.islocal(dest):
63 if not hg.islocal(dest):
64 raise util.Abort(_('%s is not a local Mercurial repo') % dest)
64 raise util.Abort(_('%s is not a local Mercurial repo') % dest)
65
65
66 rsrc = hg.repository(ui, src)
66 rsrc = hg.repository(ui, src)
67 ui.status(_('initializing destination %s\n') % dest)
67 ui.status(_('initializing destination %s\n') % dest)
68 rdst = hg.repository(ui, dest, create=True)
68 rdst = hg.repository(ui, dest, create=True)
69
69
70 success = False
70 success = False
71 dstwlock = dstlock = None
71 dstwlock = dstlock = None
72 try:
72 try:
73 # Lock destination to prevent modification while it is converted to.
73 # Lock destination to prevent modification while it is converted to.
74 # Don't need to lock src because we are just reading from its history
74 # Don't need to lock src because we are just reading from its history
75 # which can't change.
75 # which can't change.
76 dstwlock = rdst.wlock()
76 dstwlock = rdst.wlock()
77 dstlock = rdst.lock()
77 dstlock = rdst.lock()
78
78
79 # Get a list of all changesets in the source. The easy way to do this
79 # Get a list of all changesets in the source. The easy way to do this
80 # is to simply walk the changelog, using changelog.nodesbetween().
80 # is to simply walk the changelog, using changelog.nodesbetween().
81 # Take a look at mercurial/revlog.py:639 for more details.
81 # Take a look at mercurial/revlog.py:639 for more details.
82 # Use a generator instead of a list to decrease memory usage
82 # Use a generator instead of a list to decrease memory usage
83 ctxs = (rsrc[ctx] for ctx in rsrc.changelog.nodesbetween(None,
83 ctxs = (rsrc[ctx] for ctx in rsrc.changelog.nodesbetween(None,
84 rsrc.heads())[0])
84 rsrc.heads())[0])
85 revmap = {node.nullid: node.nullid}
85 revmap = {node.nullid: node.nullid}
86 if tolfile:
86 if tolfile:
87 lfiles = set()
87 lfiles = set()
88 normalfiles = set()
88 normalfiles = set()
89 if not pats:
89 if not pats:
90 pats = ui.configlist(lfutil.longname, 'patterns', default=[])
90 pats = ui.configlist(lfutil.longname, 'patterns', default=[])
91 if pats:
91 if pats:
92 matcher = match_.match(rsrc.root, '', list(pats))
92 matcher = match_.match(rsrc.root, '', list(pats))
93 else:
93 else:
94 matcher = None
94 matcher = None
95
95
96 lfiletohash = {}
96 lfiletohash = {}
97 for ctx in ctxs:
97 for ctx in ctxs:
98 ui.progress(_('converting revisions'), ctx.rev(),
98 ui.progress(_('converting revisions'), ctx.rev(),
99 unit=_('revision'), total=rsrc['tip'].rev())
99 unit=_('revision'), total=rsrc['tip'].rev())
100 _lfconvert_addchangeset(rsrc, rdst, ctx, revmap,
100 _lfconvert_addchangeset(rsrc, rdst, ctx, revmap,
101 lfiles, normalfiles, matcher, size, lfiletohash)
101 lfiles, normalfiles, matcher, size, lfiletohash)
102 ui.progress(_('converting revisions'), None)
102 ui.progress(_('converting revisions'), None)
103
103
104 if os.path.exists(rdst.wjoin(lfutil.shortname)):
104 if os.path.exists(rdst.wjoin(lfutil.shortname)):
105 shutil.rmtree(rdst.wjoin(lfutil.shortname))
105 shutil.rmtree(rdst.wjoin(lfutil.shortname))
106
106
107 for f in lfiletohash.keys():
107 for f in lfiletohash.keys():
108 if os.path.isfile(rdst.wjoin(f)):
108 if os.path.isfile(rdst.wjoin(f)):
109 os.unlink(rdst.wjoin(f))
109 os.unlink(rdst.wjoin(f))
110 try:
110 try:
111 os.removedirs(os.path.dirname(rdst.wjoin(f)))
111 os.removedirs(os.path.dirname(rdst.wjoin(f)))
112 except OSError:
112 except OSError:
113 pass
113 pass
114
114
115 # If there were any files converted to largefiles, add largefiles
115 # If there were any files converted to largefiles, add largefiles
116 # to the destination repository's requirements.
116 # to the destination repository's requirements.
117 if lfiles:
117 if lfiles:
118 rdst.requirements.add('largefiles')
118 rdst.requirements.add('largefiles')
119 rdst._writerequirements()
119 rdst._writerequirements()
120 else:
120 else:
121 for ctx in ctxs:
121 for ctx in ctxs:
122 ui.progress(_('converting revisions'), ctx.rev(),
122 ui.progress(_('converting revisions'), ctx.rev(),
123 unit=_('revision'), total=rsrc['tip'].rev())
123 unit=_('revision'), total=rsrc['tip'].rev())
124 _addchangeset(ui, rsrc, rdst, ctx, revmap)
124 _addchangeset(ui, rsrc, rdst, ctx, revmap)
125
125
126 ui.progress(_('converting revisions'), None)
126 ui.progress(_('converting revisions'), None)
127 success = True
127 success = True
128 finally:
128 finally:
129 rdst.dirstate.clear()
129 rdst.dirstate.clear()
130 release(dstlock, dstwlock)
130 release(dstlock, dstwlock)
131 if not success:
131 if not success:
132 # we failed, remove the new directory
132 # we failed, remove the new directory
133 shutil.rmtree(rdst.root)
133 shutil.rmtree(rdst.root)
134
134
135 def _addchangeset(ui, rsrc, rdst, ctx, revmap):
135 def _addchangeset(ui, rsrc, rdst, ctx, revmap):
136 # Convert src parents to dst parents
136 # Convert src parents to dst parents
137 parents = _convertparents(ctx, revmap)
137 parents = _convertparents(ctx, revmap)
138
138
139 # Generate list of changed files
139 # Generate list of changed files
140 files = _getchangedfiles(ctx, parents)
140 files = _getchangedfiles(ctx, parents)
141
141
142 def getfilectx(repo, memctx, f):
142 def getfilectx(repo, memctx, f):
143 if lfutil.standin(f) in files:
143 if lfutil.standin(f) in files:
144 # if the file isn't in the manifest then it was removed
144 # if the file isn't in the manifest then it was removed
145 # or renamed, raise IOError to indicate this
145 # or renamed, raise IOError to indicate this
146 try:
146 try:
147 fctx = ctx.filectx(lfutil.standin(f))
147 fctx = ctx.filectx(lfutil.standin(f))
148 except error.LookupError:
148 except error.LookupError:
149 return None
149 return None
150 renamed = fctx.renamed()
150 renamed = fctx.renamed()
151 if renamed:
151 if renamed:
152 renamed = lfutil.splitstandin(renamed[0])
152 renamed = lfutil.splitstandin(renamed[0])
153
153
154 hash = fctx.data().strip()
154 hash = fctx.data().strip()
155 path = lfutil.findfile(rsrc, hash)
155 path = lfutil.findfile(rsrc, hash)
156
156
157 # If one file is missing, likely all files from this rev are
157 # If one file is missing, likely all files from this rev are
158 if path is None:
158 if path is None:
159 cachelfiles(ui, rsrc, ctx.node())
159 cachelfiles(ui, rsrc, ctx.node())
160 path = lfutil.findfile(rsrc, hash)
160 path = lfutil.findfile(rsrc, hash)
161
161
162 if path is None:
162 if path is None:
163 raise util.Abort(
163 raise util.Abort(
164 _("missing largefile \'%s\' from revision %s")
164 _("missing largefile \'%s\' from revision %s")
165 % (f, node.hex(ctx.node())))
165 % (f, node.hex(ctx.node())))
166
166
167 data = ''
167 data = ''
168 fd = None
168 fd = None
169 try:
169 try:
170 fd = open(path, 'rb')
170 fd = open(path, 'rb')
171 data = fd.read()
171 data = fd.read()
172 finally:
172 finally:
173 if fd:
173 if fd:
174 fd.close()
174 fd.close()
175 return context.memfilectx(repo, f, data, 'l' in fctx.flags(),
175 return context.memfilectx(repo, f, data, 'l' in fctx.flags(),
176 'x' in fctx.flags(), renamed)
176 'x' in fctx.flags(), renamed)
177 else:
177 else:
178 return _getnormalcontext(repo, ctx, f, revmap)
178 return _getnormalcontext(repo, ctx, f, revmap)
179
179
180 dstfiles = []
180 dstfiles = []
181 for file in files:
181 for file in files:
182 if lfutil.isstandin(file):
182 if lfutil.isstandin(file):
183 dstfiles.append(lfutil.splitstandin(file))
183 dstfiles.append(lfutil.splitstandin(file))
184 else:
184 else:
185 dstfiles.append(file)
185 dstfiles.append(file)
186 # Commit
186 # Commit
187 _commitcontext(rdst, parents, ctx, dstfiles, getfilectx, revmap)
187 _commitcontext(rdst, parents, ctx, dstfiles, getfilectx, revmap)
188
188
189 def _lfconvert_addchangeset(rsrc, rdst, ctx, revmap, lfiles, normalfiles,
189 def _lfconvert_addchangeset(rsrc, rdst, ctx, revmap, lfiles, normalfiles,
190 matcher, size, lfiletohash):
190 matcher, size, lfiletohash):
191 # Convert src parents to dst parents
191 # Convert src parents to dst parents
192 parents = _convertparents(ctx, revmap)
192 parents = _convertparents(ctx, revmap)
193
193
194 # Generate list of changed files
194 # Generate list of changed files
195 files = _getchangedfiles(ctx, parents)
195 files = _getchangedfiles(ctx, parents)
196
196
197 dstfiles = []
197 dstfiles = []
198 for f in files:
198 for f in files:
199 if f not in lfiles and f not in normalfiles:
199 if f not in lfiles and f not in normalfiles:
200 islfile = _islfile(f, ctx, matcher, size)
200 islfile = _islfile(f, ctx, matcher, size)
201 # If this file was renamed or copied then copy
201 # If this file was renamed or copied then copy
202 # the largefile-ness of its predecessor
202 # the largefile-ness of its predecessor
203 if f in ctx.manifest():
203 if f in ctx.manifest():
204 fctx = ctx.filectx(f)
204 fctx = ctx.filectx(f)
205 renamed = fctx.renamed()
205 renamed = fctx.renamed()
206 renamedlfile = renamed and renamed[0] in lfiles
206 renamedlfile = renamed and renamed[0] in lfiles
207 islfile |= renamedlfile
207 islfile |= renamedlfile
208 if 'l' in fctx.flags():
208 if 'l' in fctx.flags():
209 if renamedlfile:
209 if renamedlfile:
210 raise util.Abort(
210 raise util.Abort(
211 _('renamed/copied largefile %s becomes symlink')
211 _('renamed/copied largefile %s becomes symlink')
212 % f)
212 % f)
213 islfile = False
213 islfile = False
214 if islfile:
214 if islfile:
215 lfiles.add(f)
215 lfiles.add(f)
216 else:
216 else:
217 normalfiles.add(f)
217 normalfiles.add(f)
218
218
219 if f in lfiles:
219 if f in lfiles:
220 dstfiles.append(lfutil.standin(f))
220 dstfiles.append(lfutil.standin(f))
221 # largefile in manifest if it has not been removed/renamed
221 # largefile in manifest if it has not been removed/renamed
222 if f in ctx.manifest():
222 if f in ctx.manifest():
223 fctx = ctx.filectx(f)
223 fctx = ctx.filectx(f)
224 if 'l' in fctx.flags():
224 if 'l' in fctx.flags():
225 renamed = fctx.renamed()
225 renamed = fctx.renamed()
226 if renamed and renamed[0] in lfiles:
226 if renamed and renamed[0] in lfiles:
227 raise util.Abort(_('largefile %s becomes symlink') % f)
227 raise util.Abort(_('largefile %s becomes symlink') % f)
228
228
229 # largefile was modified, update standins
229 # largefile was modified, update standins
230 m = util.sha1('')
230 m = util.sha1('')
231 m.update(ctx[f].data())
231 m.update(ctx[f].data())
232 hash = m.hexdigest()
232 hash = m.hexdigest()
233 if f not in lfiletohash or lfiletohash[f] != hash:
233 if f not in lfiletohash or lfiletohash[f] != hash:
234 rdst.wwrite(f, ctx[f].data(), ctx[f].flags())
234 rdst.wwrite(f, ctx[f].data(), ctx[f].flags())
235 executable = 'x' in ctx[f].flags()
235 executable = 'x' in ctx[f].flags()
236 lfutil.writestandin(rdst, lfutil.standin(f), hash,
236 lfutil.writestandin(rdst, lfutil.standin(f), hash,
237 executable)
237 executable)
238 lfiletohash[f] = hash
238 lfiletohash[f] = hash
239 else:
239 else:
240 # normal file
240 # normal file
241 dstfiles.append(f)
241 dstfiles.append(f)
242
242
243 def getfilectx(repo, memctx, f):
243 def getfilectx(repo, memctx, f):
244 if lfutil.isstandin(f):
244 if lfutil.isstandin(f):
245 # if the file isn't in the manifest then it was removed
245 # if the file isn't in the manifest then it was removed
246 # or renamed, raise IOError to indicate this
246 # or renamed, raise IOError to indicate this
247 srcfname = lfutil.splitstandin(f)
247 srcfname = lfutil.splitstandin(f)
248 try:
248 try:
249 fctx = ctx.filectx(srcfname)
249 fctx = ctx.filectx(srcfname)
250 except error.LookupError:
250 except error.LookupError:
251 return None
251 return None
252 renamed = fctx.renamed()
252 renamed = fctx.renamed()
253 if renamed:
253 if renamed:
254 # standin is always a largefile because largefile-ness
254 # standin is always a largefile because largefile-ness
255 # doesn't change after rename or copy
255 # doesn't change after rename or copy
256 renamed = lfutil.standin(renamed[0])
256 renamed = lfutil.standin(renamed[0])
257
257
258 return context.memfilectx(repo, f, lfiletohash[srcfname] + '\n',
258 return context.memfilectx(repo, f, lfiletohash[srcfname] + '\n',
259 'l' in fctx.flags(), 'x' in fctx.flags(),
259 'l' in fctx.flags(), 'x' in fctx.flags(),
260 renamed)
260 renamed)
261 else:
261 else:
262 return _getnormalcontext(repo, ctx, f, revmap)
262 return _getnormalcontext(repo, ctx, f, revmap)
263
263
264 # Commit
264 # Commit
265 _commitcontext(rdst, parents, ctx, dstfiles, getfilectx, revmap)
265 _commitcontext(rdst, parents, ctx, dstfiles, getfilectx, revmap)
266
266
267 def _commitcontext(rdst, parents, ctx, dstfiles, getfilectx, revmap):
267 def _commitcontext(rdst, parents, ctx, dstfiles, getfilectx, revmap):
268 mctx = context.memctx(rdst, parents, ctx.description(), dstfiles,
268 mctx = context.memctx(rdst, parents, ctx.description(), dstfiles,
269 getfilectx, ctx.user(), ctx.date(), ctx.extra())
269 getfilectx, ctx.user(), ctx.date(), ctx.extra())
270 ret = rdst.commitctx(mctx)
270 ret = rdst.commitctx(mctx)
271 lfutil.copyalltostore(rdst, ret)
271 lfutil.copyalltostore(rdst, ret)
272 rdst.setparents(ret)
272 rdst.setparents(ret)
273 revmap[ctx.node()] = rdst.changelog.tip()
273 revmap[ctx.node()] = rdst.changelog.tip()
274
274
275 # Generate list of changed files
275 # Generate list of changed files
276 def _getchangedfiles(ctx, parents):
276 def _getchangedfiles(ctx, parents):
277 files = set(ctx.files())
277 files = set(ctx.files())
278 if node.nullid not in parents:
278 if node.nullid not in parents:
279 mc = ctx.manifest()
279 mc = ctx.manifest()
280 mp1 = ctx.parents()[0].manifest()
280 mp1 = ctx.parents()[0].manifest()
281 mp2 = ctx.parents()[1].manifest()
281 mp2 = ctx.parents()[1].manifest()
282 files |= (set(mp1) | set(mp2)) - set(mc)
282 files |= (set(mp1) | set(mp2)) - set(mc)
283 for f in mc:
283 for f in mc:
284 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
284 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
285 files.add(f)
285 files.add(f)
286 return files
286 return files
287
287
288 # Convert src parents to dst parents
288 # Convert src parents to dst parents
289 def _convertparents(ctx, revmap):
289 def _convertparents(ctx, revmap):
290 parents = []
290 parents = []
291 for p in ctx.parents():
291 for p in ctx.parents():
292 parents.append(revmap[p.node()])
292 parents.append(revmap[p.node()])
293 while len(parents) < 2:
293 while len(parents) < 2:
294 parents.append(node.nullid)
294 parents.append(node.nullid)
295 return parents
295 return parents
296
296
297 # Get memfilectx for a normal file
297 # Get memfilectx for a normal file
298 def _getnormalcontext(repo, ctx, f, revmap):
298 def _getnormalcontext(repo, ctx, f, revmap):
299 try:
299 try:
300 fctx = ctx.filectx(f)
300 fctx = ctx.filectx(f)
301 except error.LookupError:
301 except error.LookupError:
302 return None
302 return None
303 renamed = fctx.renamed()
303 renamed = fctx.renamed()
304 if renamed:
304 if renamed:
305 renamed = renamed[0]
305 renamed = renamed[0]
306
306
307 data = fctx.data()
307 data = fctx.data()
308 if f == '.hgtags':
308 if f == '.hgtags':
309 data = _converttags (repo.ui, revmap, data)
309 data = _converttags (repo.ui, revmap, data)
310 return context.memfilectx(repo, f, data, 'l' in fctx.flags(),
310 return context.memfilectx(repo, f, data, 'l' in fctx.flags(),
311 'x' in fctx.flags(), renamed)
311 'x' in fctx.flags(), renamed)
312
312
313 # Remap tag data using a revision map
313 # Remap tag data using a revision map
314 def _converttags(ui, revmap, data):
314 def _converttags(ui, revmap, data):
315 newdata = []
315 newdata = []
316 for line in data.splitlines():
316 for line in data.splitlines():
317 try:
317 try:
318 id, name = line.split(' ', 1)
318 id, name = line.split(' ', 1)
319 except ValueError:
319 except ValueError:
320 ui.warn(_('skipping incorrectly formatted tag %s\n')
320 ui.warn(_('skipping incorrectly formatted tag %s\n')
321 % line)
321 % line)
322 continue
322 continue
323 try:
323 try:
324 newid = node.bin(id)
324 newid = node.bin(id)
325 except TypeError:
325 except TypeError:
326 ui.warn(_('skipping incorrectly formatted id %s\n')
326 ui.warn(_('skipping incorrectly formatted id %s\n')
327 % id)
327 % id)
328 continue
328 continue
329 try:
329 try:
330 newdata.append('%s %s\n' % (node.hex(revmap[newid]),
330 newdata.append('%s %s\n' % (node.hex(revmap[newid]),
331 name))
331 name))
332 except KeyError:
332 except KeyError:
333 ui.warn(_('no mapping for id %s\n') % id)
333 ui.warn(_('no mapping for id %s\n') % id)
334 continue
334 continue
335 return ''.join(newdata)
335 return ''.join(newdata)
336
336
337 def _islfile(file, ctx, matcher, size):
337 def _islfile(file, ctx, matcher, size):
338 '''Return true if file should be considered a largefile, i.e.
338 '''Return true if file should be considered a largefile, i.e.
339 matcher matches it or it is larger than size.'''
339 matcher matches it or it is larger than size.'''
340 # never store special .hg* files as largefiles
340 # never store special .hg* files as largefiles
341 if file == '.hgtags' or file == '.hgignore' or file == '.hgsigs':
341 if file == '.hgtags' or file == '.hgignore' or file == '.hgsigs':
342 return False
342 return False
343 if matcher and matcher(file):
343 if matcher and matcher(file):
344 return True
344 return True
345 try:
345 try:
346 return ctx.filectx(file).size() >= size * 1024 * 1024
346 return ctx.filectx(file).size() >= size * 1024 * 1024
347 except error.LookupError:
347 except error.LookupError:
348 return False
348 return False
349
349
350 def uploadlfiles(ui, rsrc, rdst, files):
350 def uploadlfiles(ui, rsrc, rdst, files):
351 '''upload largefiles to the central store'''
351 '''upload largefiles to the central store'''
352
352
353 if not files:
353 if not files:
354 return
354 return
355
355
356 store = basestore._openstore(rsrc, rdst, put=True)
356 store = basestore._openstore(rsrc, rdst, put=True)
357
357
358 at = 0
358 at = 0
359 ui.debug("sending statlfile command for %d largefiles\n" % len(files))
359 ui.debug("sending statlfile command for %d largefiles\n" % len(files))
360 retval = store.exists(files)
360 retval = store.exists(files)
361 files = filter(lambda h: not retval[h], files)
361 files = filter(lambda h: not retval[h], files)
362 ui.debug("%d largefiles need to be uploaded\n" % len(files))
362 ui.debug("%d largefiles need to be uploaded\n" % len(files))
363
363
364 for hash in files:
364 for hash in files:
365 ui.progress(_('uploading largefiles'), at, unit='largefile',
365 ui.progress(_('uploading largefiles'), at, unit='largefile',
366 total=len(files))
366 total=len(files))
367 source = lfutil.findfile(rsrc, hash)
367 source = lfutil.findfile(rsrc, hash)
368 if not source:
368 if not source:
369 raise util.Abort(_('largefile %s missing from store'
369 raise util.Abort(_('largefile %s missing from store'
370 ' (needs to be uploaded)') % hash)
370 ' (needs to be uploaded)') % hash)
371 # XXX check for errors here
371 # XXX check for errors here
372 store.put(source, hash)
372 store.put(source, hash)
373 at += 1
373 at += 1
374 ui.progress(_('uploading largefiles'), None)
374 ui.progress(_('uploading largefiles'), None)
375
375
376 def verifylfiles(ui, repo, all=False, contents=False):
376 def verifylfiles(ui, repo, all=False, contents=False):
377 '''Verify that every largefile revision in the current changeset
377 '''Verify that every largefile revision in the current changeset
378 exists in the central store. With --contents, also verify that
378 exists in the central store. With --contents, also verify that
379 the contents of each local largefile file revision are correct (SHA-1 hash
379 the contents of each local largefile file revision are correct (SHA-1 hash
380 matches the revision ID). With --all, check every changeset in
380 matches the revision ID). With --all, check every changeset in
381 this repository.'''
381 this repository.'''
382 if all:
382 if all:
383 # Pass a list to the function rather than an iterator because we know a
383 # Pass a list to the function rather than an iterator because we know a
384 # list will work.
384 # list will work.
385 revs = range(len(repo))
385 revs = range(len(repo))
386 else:
386 else:
387 revs = ['.']
387 revs = ['.']
388
388
389 store = basestore._openstore(repo)
389 store = basestore._openstore(repo)
390 return store.verify(revs, contents=contents)
390 return store.verify(revs, contents=contents)
391
391
392 def cachelfiles(ui, repo, node, filelist=None):
392 def cachelfiles(ui, repo, node, filelist=None):
393 '''cachelfiles ensures that all largefiles needed by the specified revision
393 '''cachelfiles ensures that all largefiles needed by the specified revision
394 are present in the repository's largefile cache.
394 are present in the repository's largefile cache.
395
395
396 returns a tuple (cached, missing). cached is the list of files downloaded
396 returns a tuple (cached, missing). cached is the list of files downloaded
397 by this operation; missing is the list of files that were needed but could
397 by this operation; missing is the list of files that were needed but could
398 not be found.'''
398 not be found.'''
399 lfiles = lfutil.listlfiles(repo, node)
399 lfiles = lfutil.listlfiles(repo, node)
400 if filelist:
400 if filelist:
401 lfiles = set(lfiles) & set(filelist)
401 lfiles = set(lfiles) & set(filelist)
402 toget = []
402 toget = []
403
403
404 for lfile in lfiles:
404 for lfile in lfiles:
405 try:
405 try:
406 expectedhash = repo[node][lfutil.standin(lfile)].data().strip()
406 expectedhash = repo[node][lfutil.standin(lfile)].data().strip()
407 except IOError, err:
407 except IOError, err:
408 if err.errno == errno.ENOENT:
408 if err.errno == errno.ENOENT:
409 continue # node must be None and standin wasn't found in wctx
409 continue # node must be None and standin wasn't found in wctx
410 raise
410 raise
411 if not lfutil.findfile(repo, expectedhash):
411 if not lfutil.findfile(repo, expectedhash):
412 toget.append((lfile, expectedhash))
412 toget.append((lfile, expectedhash))
413
413
414 if toget:
414 if toget:
415 store = basestore._openstore(repo)
415 store = basestore._openstore(repo)
416 ret = store.get(toget)
416 ret = store.get(toget)
417 return ret
417 return ret
418
418
419 return ([], [])
419 return ([], [])
420
420
421 def downloadlfiles(ui, repo, rev=None):
421 def downloadlfiles(ui, repo, rev=None):
422 matchfn = scmutil.match(repo[None],
422 matchfn = scmutil.match(repo[None],
423 [repo.wjoin(lfutil.shortname)], {})
423 [repo.wjoin(lfutil.shortname)], {})
424 def prepare(ctx, fns):
424 def prepare(ctx, fns):
425 pass
425 pass
426 totalsuccess = 0
426 totalsuccess = 0
427 totalmissing = 0
427 totalmissing = 0
428 if rev != []: # walkchangerevs on empty list would return all revs
428 if rev != []: # walkchangerevs on empty list would return all revs
429 for ctx in cmdutil.walkchangerevs(repo, matchfn, {'rev' : rev},
429 for ctx in cmdutil.walkchangerevs(repo, matchfn, {'rev' : rev},
430 prepare):
430 prepare):
431 success, missing = cachelfiles(ui, repo, ctx.node())
431 success, missing = cachelfiles(ui, repo, ctx.node())
432 totalsuccess += len(success)
432 totalsuccess += len(success)
433 totalmissing += len(missing)
433 totalmissing += len(missing)
434 ui.status(_("%d additional largefiles cached\n") % totalsuccess)
434 ui.status(_("%d additional largefiles cached\n") % totalsuccess)
435 if totalmissing > 0:
435 if totalmissing > 0:
436 ui.status(_("%d largefiles failed to download\n") % totalmissing)
436 ui.status(_("%d largefiles failed to download\n") % totalmissing)
437 return totalsuccess, totalmissing
437 return totalsuccess, totalmissing
438
438
439 def updatelfiles(ui, repo, filelist=None, printmessage=None,
439 def updatelfiles(ui, repo, filelist=None, printmessage=None,
440 normallookup=False):
440 normallookup=False):
441 '''Update largefiles according to standins in the working directory
441 '''Update largefiles according to standins in the working directory
442
442
443 If ``printmessage`` is other than ``None``, it means "print (or
443 If ``printmessage`` is other than ``None``, it means "print (or
444 ignore, for false) message forcibly".
444 ignore, for false) message forcibly".
445 '''
445 '''
446 statuswriter = lfutil.getstatuswriter(ui, repo, printmessage)
446 statuswriter = lfutil.getstatuswriter(ui, repo, printmessage)
447 wlock = repo.wlock()
447 wlock = repo.wlock()
448 try:
448 try:
449 lfdirstate = lfutil.openlfdirstate(ui, repo)
449 lfdirstate = lfutil.openlfdirstate(ui, repo)
450 lfiles = set(lfutil.listlfiles(repo)) | set(lfdirstate)
450 lfiles = set(lfutil.listlfiles(repo)) | set(lfdirstate)
451
451
452 if filelist is not None:
452 if filelist is not None:
453 filelist = set(filelist)
453 filelist = set(filelist)
454 lfiles = [f for f in lfiles if f in filelist]
454 lfiles = [f for f in lfiles if f in filelist]
455
455
456 update = {}
456 update = {}
457 updated, removed = 0, 0
457 updated, removed = 0, 0
458 for lfile in lfiles:
458 for lfile in lfiles:
459 abslfile = repo.wjoin(lfile)
459 abslfile = repo.wjoin(lfile)
460 absstandin = repo.wjoin(lfutil.standin(lfile))
460 absstandin = repo.wjoin(lfutil.standin(lfile))
461 if os.path.exists(absstandin):
461 if os.path.exists(absstandin):
462 if (os.path.exists(absstandin + '.orig') and
462 if (os.path.exists(absstandin + '.orig') and
463 os.path.exists(abslfile)):
463 os.path.exists(abslfile)):
464 shutil.copyfile(abslfile, abslfile + '.orig')
464 shutil.copyfile(abslfile, abslfile + '.orig')
465 util.unlinkpath(absstandin + '.orig')
465 util.unlinkpath(absstandin + '.orig')
466 expecthash = lfutil.readstandin(repo, lfile)
466 expecthash = lfutil.readstandin(repo, lfile)
467 if (expecthash != '' and
467 if (expecthash != '' and
468 (not os.path.exists(abslfile) or
468 (not os.path.exists(abslfile) or
469 expecthash != lfutil.hashfile(abslfile))):
469 expecthash != lfutil.hashfile(abslfile))):
470 if lfile not in repo[None]: # not switched to normal file
470 if lfile not in repo[None]: # not switched to normal file
471 util.unlinkpath(abslfile, ignoremissing=True)
471 util.unlinkpath(abslfile, ignoremissing=True)
472 # use normallookup() to allocate an entry in largefiles
472 # use normallookup() to allocate an entry in largefiles
473 # dirstate, because lack of it misleads
473 # dirstate, because lack of it misleads
474 # lfilesrepo.status() into recognition that such cache
474 # lfilesrepo.status() into recognition that such cache
475 # missing files are removed.
475 # missing files are removed.
476 lfdirstate.normallookup(lfile)
476 lfdirstate.normallookup(lfile)
477 update[lfile] = expecthash
477 update[lfile] = expecthash
478 else:
478 else:
479 # Remove lfiles for which the standin is deleted, unless the
479 # Remove lfiles for which the standin is deleted, unless the
480 # lfile is added to the repository again. This happens when a
480 # lfile is added to the repository again. This happens when a
481 # largefile is converted back to a normal file: the standin
481 # largefile is converted back to a normal file: the standin
482 # disappears, but a new (normal) file appears as the lfile.
482 # disappears, but a new (normal) file appears as the lfile.
483 if (os.path.exists(abslfile) and
483 if (os.path.exists(abslfile) and
484 repo.dirstate.normalize(lfile) not in repo[None]):
484 repo.dirstate.normalize(lfile) not in repo[None]):
485 util.unlinkpath(abslfile)
485 util.unlinkpath(abslfile)
486 removed += 1
486 removed += 1
487
487
488 # largefile processing might be slow and be interrupted - be prepared
488 # largefile processing might be slow and be interrupted - be prepared
489 lfdirstate.write()
489 lfdirstate.write()
490
490
491 if lfiles:
491 if lfiles:
492 statuswriter(_('getting changed largefiles\n'))
492 statuswriter(_('getting changed largefiles\n'))
493 cachelfiles(ui, repo, None, lfiles)
493 cachelfiles(ui, repo, None, lfiles)
494
494
495 for lfile in lfiles:
495 for lfile in lfiles:
496 update1 = 0
496 update1 = 0
497
497
498 expecthash = update.get(lfile)
498 expecthash = update.get(lfile)
499 if expecthash:
499 if expecthash:
500 if not lfutil.copyfromcache(repo, expecthash, lfile):
500 if not lfutil.copyfromcache(repo, expecthash, lfile):
501 # failed ... but already removed and set to normallookup
501 # failed ... but already removed and set to normallookup
502 continue
502 continue
503 # Synchronize largefile dirstate to the last modified
503 # Synchronize largefile dirstate to the last modified
504 # time of the file
504 # time of the file
505 lfdirstate.normal(lfile)
505 lfdirstate.normal(lfile)
506 update1 = 1
506 update1 = 1
507
507
508 # copy the state of largefile standin from the repository's
508 # copy the state of largefile standin from the repository's
509 # dirstate to its state in the lfdirstate.
509 # dirstate to its state in the lfdirstate.
510 abslfile = repo.wjoin(lfile)
510 abslfile = repo.wjoin(lfile)
511 absstandin = repo.wjoin(lfutil.standin(lfile))
511 absstandin = repo.wjoin(lfutil.standin(lfile))
512 if os.path.exists(absstandin):
512 if os.path.exists(absstandin):
513 mode = os.stat(absstandin).st_mode
513 mode = os.stat(absstandin).st_mode
514 if mode != os.stat(abslfile).st_mode:
514 if mode != os.stat(abslfile).st_mode:
515 os.chmod(abslfile, mode)
515 os.chmod(abslfile, mode)
516 update1 = 1
516 update1 = 1
517
517
518 updated += update1
518 updated += update1
519
519
520 lfutil.synclfdirstate(repo, lfdirstate, lfile, normallookup)
520 lfutil.synclfdirstate(repo, lfdirstate, lfile, normallookup)
521
521
522 if filelist is not None:
523 # If "local largefile" is chosen at file merging, it is
524 # not listed in "filelist" (= dirstate syncing is
525 # omitted), because the standin file is not changed before and
526 # after merging.
527 # But the status of such files may have to be changed by
528 # merging. For example, locally modified ("M") largefile
529 # has to become re-added("A"), if it is "normal" file in
530 # the target revision of linear-merging.
531 for lfile in lfdirstate:
532 if lfile not in filelist:
533 lfutil.synclfdirstate(repo, lfdirstate, lfile, True)
534
535 lfdirstate.write()
522 lfdirstate.write()
536 if lfiles:
523 if lfiles:
537 statuswriter(_('%d largefiles updated, %d removed\n') % (updated,
524 statuswriter(_('%d largefiles updated, %d removed\n') % (updated,
538 removed))
525 removed))
539 finally:
526 finally:
540 wlock.release()
527 wlock.release()
541
528
542 @command('lfpull',
529 @command('lfpull',
543 [('r', 'rev', [], _('pull largefiles for these revisions'))
530 [('r', 'rev', [], _('pull largefiles for these revisions'))
544 ] + commands.remoteopts,
531 ] + commands.remoteopts,
545 _('-r REV... [-e CMD] [--remotecmd CMD] [SOURCE]'))
532 _('-r REV... [-e CMD] [--remotecmd CMD] [SOURCE]'))
546 def lfpull(ui, repo, source="default", **opts):
533 def lfpull(ui, repo, source="default", **opts):
547 """pull largefiles for the specified revisions from the specified source
534 """pull largefiles for the specified revisions from the specified source
548
535
549 Pull largefiles that are referenced from local changesets but missing
536 Pull largefiles that are referenced from local changesets but missing
550 locally, pulling from a remote repository to the local cache.
537 locally, pulling from a remote repository to the local cache.
551
538
552 If SOURCE is omitted, the 'default' path will be used.
539 If SOURCE is omitted, the 'default' path will be used.
553 See :hg:`help urls` for more information.
540 See :hg:`help urls` for more information.
554
541
555 .. container:: verbose
542 .. container:: verbose
556
543
557 Some examples:
544 Some examples:
558
545
559 - pull largefiles for all branch heads::
546 - pull largefiles for all branch heads::
560
547
561 hg lfpull -r "head() and not closed()"
548 hg lfpull -r "head() and not closed()"
562
549
563 - pull largefiles on the default branch::
550 - pull largefiles on the default branch::
564
551
565 hg lfpull -r "branch(default)"
552 hg lfpull -r "branch(default)"
566 """
553 """
567 repo.lfpullsource = source
554 repo.lfpullsource = source
568
555
569 revs = opts.get('rev', [])
556 revs = opts.get('rev', [])
570 if not revs:
557 if not revs:
571 raise util.Abort(_('no revisions specified'))
558 raise util.Abort(_('no revisions specified'))
572 revs = scmutil.revrange(repo, revs)
559 revs = scmutil.revrange(repo, revs)
573
560
574 numcached = 0
561 numcached = 0
575 for rev in revs:
562 for rev in revs:
576 ui.note(_('pulling largefiles for revision %s\n') % rev)
563 ui.note(_('pulling largefiles for revision %s\n') % rev)
577 (cached, missing) = cachelfiles(ui, repo, rev)
564 (cached, missing) = cachelfiles(ui, repo, rev)
578 numcached += len(cached)
565 numcached += len(cached)
579 ui.status(_("%d largefiles cached\n") % numcached)
566 ui.status(_("%d largefiles cached\n") % numcached)
@@ -1,1302 +1,1306 b''
1 # Copyright 2009-2010 Gregory P. Ward
1 # Copyright 2009-2010 Gregory P. Ward
2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
3 # Copyright 2010-2011 Fog Creek Software
3 # Copyright 2010-2011 Fog Creek Software
4 # Copyright 2010-2011 Unity Technologies
4 # Copyright 2010-2011 Unity Technologies
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 '''Overridden Mercurial commands and functions for the largefiles extension'''
9 '''Overridden Mercurial commands and functions for the largefiles extension'''
10
10
11 import os
11 import os
12 import copy
12 import copy
13
13
14 from mercurial import hg, util, cmdutil, scmutil, match as match_, \
14 from mercurial import hg, util, cmdutil, scmutil, match as match_, \
15 archival, pathutil, revset
15 archival, pathutil, revset
16 from mercurial.i18n import _
16 from mercurial.i18n import _
17 from mercurial.node import hex
17 from mercurial.node import hex
18
18
19 import lfutil
19 import lfutil
20 import lfcommands
20 import lfcommands
21 import basestore
21 import basestore
22
22
23 # -- Utility functions: commonly/repeatedly needed functionality ---------------
23 # -- Utility functions: commonly/repeatedly needed functionality ---------------
24
24
25 def composelargefilematcher(match, manifest):
25 def composelargefilematcher(match, manifest):
26 '''create a matcher that matches only the largefiles in the original
26 '''create a matcher that matches only the largefiles in the original
27 matcher'''
27 matcher'''
28 m = copy.copy(match)
28 m = copy.copy(match)
29 lfile = lambda f: lfutil.standin(f) in manifest
29 lfile = lambda f: lfutil.standin(f) in manifest
30 m._files = filter(lfile, m._files)
30 m._files = filter(lfile, m._files)
31 m._fmap = set(m._files)
31 m._fmap = set(m._files)
32 m._always = False
32 m._always = False
33 origmatchfn = m.matchfn
33 origmatchfn = m.matchfn
34 m.matchfn = lambda f: lfile(f) and origmatchfn(f)
34 m.matchfn = lambda f: lfile(f) and origmatchfn(f)
35 return m
35 return m
36
36
37 def composenormalfilematcher(match, manifest):
37 def composenormalfilematcher(match, manifest):
38 m = copy.copy(match)
38 m = copy.copy(match)
39 notlfile = lambda f: not (lfutil.isstandin(f) or lfutil.standin(f) in
39 notlfile = lambda f: not (lfutil.isstandin(f) or lfutil.standin(f) in
40 manifest)
40 manifest)
41 m._files = filter(notlfile, m._files)
41 m._files = filter(notlfile, m._files)
42 m._fmap = set(m._files)
42 m._fmap = set(m._files)
43 m._always = False
43 m._always = False
44 origmatchfn = m.matchfn
44 origmatchfn = m.matchfn
45 m.matchfn = lambda f: notlfile(f) and origmatchfn(f)
45 m.matchfn = lambda f: notlfile(f) and origmatchfn(f)
46 return m
46 return m
47
47
48 def installnormalfilesmatchfn(manifest):
48 def installnormalfilesmatchfn(manifest):
49 '''installmatchfn with a matchfn that ignores all largefiles'''
49 '''installmatchfn with a matchfn that ignores all largefiles'''
50 def overridematch(ctx, pats=[], opts={}, globbed=False,
50 def overridematch(ctx, pats=[], opts={}, globbed=False,
51 default='relpath'):
51 default='relpath'):
52 match = oldmatch(ctx, pats, opts, globbed, default)
52 match = oldmatch(ctx, pats, opts, globbed, default)
53 return composenormalfilematcher(match, manifest)
53 return composenormalfilematcher(match, manifest)
54 oldmatch = installmatchfn(overridematch)
54 oldmatch = installmatchfn(overridematch)
55
55
56 def installmatchfn(f):
56 def installmatchfn(f):
57 '''monkey patch the scmutil module with a custom match function.
57 '''monkey patch the scmutil module with a custom match function.
58 Warning: it is monkey patching the _module_ on runtime! Not thread safe!'''
58 Warning: it is monkey patching the _module_ on runtime! Not thread safe!'''
59 oldmatch = scmutil.match
59 oldmatch = scmutil.match
60 setattr(f, 'oldmatch', oldmatch)
60 setattr(f, 'oldmatch', oldmatch)
61 scmutil.match = f
61 scmutil.match = f
62 return oldmatch
62 return oldmatch
63
63
64 def restorematchfn():
64 def restorematchfn():
65 '''restores scmutil.match to what it was before installmatchfn
65 '''restores scmutil.match to what it was before installmatchfn
66 was called. no-op if scmutil.match is its original function.
66 was called. no-op if scmutil.match is its original function.
67
67
68 Note that n calls to installmatchfn will require n calls to
68 Note that n calls to installmatchfn will require n calls to
69 restore the original matchfn.'''
69 restore the original matchfn.'''
70 scmutil.match = getattr(scmutil.match, 'oldmatch')
70 scmutil.match = getattr(scmutil.match, 'oldmatch')
71
71
72 def installmatchandpatsfn(f):
72 def installmatchandpatsfn(f):
73 oldmatchandpats = scmutil.matchandpats
73 oldmatchandpats = scmutil.matchandpats
74 setattr(f, 'oldmatchandpats', oldmatchandpats)
74 setattr(f, 'oldmatchandpats', oldmatchandpats)
75 scmutil.matchandpats = f
75 scmutil.matchandpats = f
76 return oldmatchandpats
76 return oldmatchandpats
77
77
78 def restorematchandpatsfn():
78 def restorematchandpatsfn():
79 '''restores scmutil.matchandpats to what it was before
79 '''restores scmutil.matchandpats to what it was before
80 installmatchandpatsfn was called. No-op if scmutil.matchandpats
80 installmatchandpatsfn was called. No-op if scmutil.matchandpats
81 is its original function.
81 is its original function.
82
82
83 Note that n calls to installmatchandpatsfn will require n calls
83 Note that n calls to installmatchandpatsfn will require n calls
84 to restore the original matchfn.'''
84 to restore the original matchfn.'''
85 scmutil.matchandpats = getattr(scmutil.matchandpats, 'oldmatchandpats',
85 scmutil.matchandpats = getattr(scmutil.matchandpats, 'oldmatchandpats',
86 scmutil.matchandpats)
86 scmutil.matchandpats)
87
87
88 def addlargefiles(ui, repo, matcher, **opts):
88 def addlargefiles(ui, repo, matcher, **opts):
89 large = opts.pop('large', None)
89 large = opts.pop('large', None)
90 lfsize = lfutil.getminsize(
90 lfsize = lfutil.getminsize(
91 ui, lfutil.islfilesrepo(repo), opts.pop('lfsize', None))
91 ui, lfutil.islfilesrepo(repo), opts.pop('lfsize', None))
92
92
93 lfmatcher = None
93 lfmatcher = None
94 if lfutil.islfilesrepo(repo):
94 if lfutil.islfilesrepo(repo):
95 lfpats = ui.configlist(lfutil.longname, 'patterns', default=[])
95 lfpats = ui.configlist(lfutil.longname, 'patterns', default=[])
96 if lfpats:
96 if lfpats:
97 lfmatcher = match_.match(repo.root, '', list(lfpats))
97 lfmatcher = match_.match(repo.root, '', list(lfpats))
98
98
99 lfnames = []
99 lfnames = []
100 m = copy.copy(matcher)
100 m = copy.copy(matcher)
101 m.bad = lambda x, y: None
101 m.bad = lambda x, y: None
102 wctx = repo[None]
102 wctx = repo[None]
103 for f in repo.walk(m):
103 for f in repo.walk(m):
104 exact = m.exact(f)
104 exact = m.exact(f)
105 lfile = lfutil.standin(f) in wctx
105 lfile = lfutil.standin(f) in wctx
106 nfile = f in wctx
106 nfile = f in wctx
107 exists = lfile or nfile
107 exists = lfile or nfile
108
108
109 # Don't warn the user when they attempt to add a normal tracked file.
109 # Don't warn the user when they attempt to add a normal tracked file.
110 # The normal add code will do that for us.
110 # The normal add code will do that for us.
111 if exact and exists:
111 if exact and exists:
112 if lfile:
112 if lfile:
113 ui.warn(_('%s already a largefile\n') % f)
113 ui.warn(_('%s already a largefile\n') % f)
114 continue
114 continue
115
115
116 if (exact or not exists) and not lfutil.isstandin(f):
116 if (exact or not exists) and not lfutil.isstandin(f):
117 wfile = repo.wjoin(f)
117 wfile = repo.wjoin(f)
118
118
119 # In case the file was removed previously, but not committed
119 # In case the file was removed previously, but not committed
120 # (issue3507)
120 # (issue3507)
121 if not os.path.exists(wfile):
121 if not os.path.exists(wfile):
122 continue
122 continue
123
123
124 abovemin = (lfsize and
124 abovemin = (lfsize and
125 os.lstat(wfile).st_size >= lfsize * 1024 * 1024)
125 os.lstat(wfile).st_size >= lfsize * 1024 * 1024)
126 if large or abovemin or (lfmatcher and lfmatcher(f)):
126 if large or abovemin or (lfmatcher and lfmatcher(f)):
127 lfnames.append(f)
127 lfnames.append(f)
128 if ui.verbose or not exact:
128 if ui.verbose or not exact:
129 ui.status(_('adding %s as a largefile\n') % m.rel(f))
129 ui.status(_('adding %s as a largefile\n') % m.rel(f))
130
130
131 bad = []
131 bad = []
132
132
133 # Need to lock, otherwise there could be a race condition between
133 # Need to lock, otherwise there could be a race condition between
134 # when standins are created and added to the repo.
134 # when standins are created and added to the repo.
135 wlock = repo.wlock()
135 wlock = repo.wlock()
136 try:
136 try:
137 if not opts.get('dry_run'):
137 if not opts.get('dry_run'):
138 standins = []
138 standins = []
139 lfdirstate = lfutil.openlfdirstate(ui, repo)
139 lfdirstate = lfutil.openlfdirstate(ui, repo)
140 for f in lfnames:
140 for f in lfnames:
141 standinname = lfutil.standin(f)
141 standinname = lfutil.standin(f)
142 lfutil.writestandin(repo, standinname, hash='',
142 lfutil.writestandin(repo, standinname, hash='',
143 executable=lfutil.getexecutable(repo.wjoin(f)))
143 executable=lfutil.getexecutable(repo.wjoin(f)))
144 standins.append(standinname)
144 standins.append(standinname)
145 if lfdirstate[f] == 'r':
145 if lfdirstate[f] == 'r':
146 lfdirstate.normallookup(f)
146 lfdirstate.normallookup(f)
147 else:
147 else:
148 lfdirstate.add(f)
148 lfdirstate.add(f)
149 lfdirstate.write()
149 lfdirstate.write()
150 bad += [lfutil.splitstandin(f)
150 bad += [lfutil.splitstandin(f)
151 for f in repo[None].add(standins)
151 for f in repo[None].add(standins)
152 if f in m.files()]
152 if f in m.files()]
153 finally:
153 finally:
154 wlock.release()
154 wlock.release()
155 return bad
155 return bad
156
156
157 def removelargefiles(ui, repo, isaddremove, *pats, **opts):
157 def removelargefiles(ui, repo, isaddremove, *pats, **opts):
158 after = opts.get('after')
158 after = opts.get('after')
159 if not pats and not after:
159 if not pats and not after:
160 raise util.Abort(_('no files specified'))
160 raise util.Abort(_('no files specified'))
161 m = composelargefilematcher(scmutil.match(repo[None], pats, opts),
161 m = composelargefilematcher(scmutil.match(repo[None], pats, opts),
162 repo[None].manifest())
162 repo[None].manifest())
163 try:
163 try:
164 repo.lfstatus = True
164 repo.lfstatus = True
165 s = repo.status(match=m, clean=True)
165 s = repo.status(match=m, clean=True)
166 finally:
166 finally:
167 repo.lfstatus = False
167 repo.lfstatus = False
168 manifest = repo[None].manifest()
168 manifest = repo[None].manifest()
169 modified, added, deleted, clean = [[f for f in list
169 modified, added, deleted, clean = [[f for f in list
170 if lfutil.standin(f) in manifest]
170 if lfutil.standin(f) in manifest]
171 for list in (s.modified, s.added,
171 for list in (s.modified, s.added,
172 s.deleted, s.clean)]
172 s.deleted, s.clean)]
173
173
174 def warn(files, msg):
174 def warn(files, msg):
175 for f in files:
175 for f in files:
176 ui.warn(msg % m.rel(f))
176 ui.warn(msg % m.rel(f))
177 return int(len(files) > 0)
177 return int(len(files) > 0)
178
178
179 result = 0
179 result = 0
180
180
181 if after:
181 if after:
182 remove = deleted
182 remove = deleted
183 result = warn(modified + added + clean,
183 result = warn(modified + added + clean,
184 _('not removing %s: file still exists\n'))
184 _('not removing %s: file still exists\n'))
185 else:
185 else:
186 remove = deleted + clean
186 remove = deleted + clean
187 result = warn(modified, _('not removing %s: file is modified (use -f'
187 result = warn(modified, _('not removing %s: file is modified (use -f'
188 ' to force removal)\n'))
188 ' to force removal)\n'))
189 result = warn(added, _('not removing %s: file has been marked for add'
189 result = warn(added, _('not removing %s: file has been marked for add'
190 ' (use forget to undo)\n')) or result
190 ' (use forget to undo)\n')) or result
191
191
192 # Need to lock because standin files are deleted then removed from the
192 # Need to lock because standin files are deleted then removed from the
193 # repository and we could race in-between.
193 # repository and we could race in-between.
194 wlock = repo.wlock()
194 wlock = repo.wlock()
195 try:
195 try:
196 lfdirstate = lfutil.openlfdirstate(ui, repo)
196 lfdirstate = lfutil.openlfdirstate(ui, repo)
197 for f in sorted(remove):
197 for f in sorted(remove):
198 if isaddremove:
198 if isaddremove:
199 ui.status(_('removing %s\n') % f)
199 ui.status(_('removing %s\n') % f)
200 elif ui.verbose or not m.exact(f):
200 elif ui.verbose or not m.exact(f):
201 ui.status(_('removing %s\n') % m.rel(f))
201 ui.status(_('removing %s\n') % m.rel(f))
202
202
203 if not opts.get('dry_run'):
203 if not opts.get('dry_run'):
204 if not after:
204 if not after:
205 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
205 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
206 lfdirstate.remove(f)
206 lfdirstate.remove(f)
207
207
208 if opts.get('dry_run'):
208 if opts.get('dry_run'):
209 return result
209 return result
210
210
211 lfdirstate.write()
211 lfdirstate.write()
212 remove = [lfutil.standin(f) for f in remove]
212 remove = [lfutil.standin(f) for f in remove]
213 # If this is being called by addremove, let the original addremove
213 # If this is being called by addremove, let the original addremove
214 # function handle this.
214 # function handle this.
215 if not isaddremove:
215 if not isaddremove:
216 for f in remove:
216 for f in remove:
217 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
217 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
218 repo[None].forget(remove)
218 repo[None].forget(remove)
219 finally:
219 finally:
220 wlock.release()
220 wlock.release()
221
221
222 return result
222 return result
223
223
224 # For overriding mercurial.hgweb.webcommands so that largefiles will
224 # For overriding mercurial.hgweb.webcommands so that largefiles will
225 # appear at their right place in the manifests.
225 # appear at their right place in the manifests.
226 def decodepath(orig, path):
226 def decodepath(orig, path):
227 return lfutil.splitstandin(path) or path
227 return lfutil.splitstandin(path) or path
228
228
229 # -- Wrappers: modify existing commands --------------------------------
229 # -- Wrappers: modify existing commands --------------------------------
230
230
231 # Add works by going through the files that the user wanted to add and
231 # Add works by going through the files that the user wanted to add and
232 # checking if they should be added as largefiles. Then it makes a new
232 # checking if they should be added as largefiles. Then it makes a new
233 # matcher which matches only the normal files and runs the original
233 # matcher which matches only the normal files and runs the original
234 # version of add.
234 # version of add.
235 def overrideadd(orig, ui, repo, *pats, **opts):
235 def overrideadd(orig, ui, repo, *pats, **opts):
236 normal = opts.pop('normal')
236 normal = opts.pop('normal')
237 if normal:
237 if normal:
238 if opts.get('large'):
238 if opts.get('large'):
239 raise util.Abort(_('--normal cannot be used with --large'))
239 raise util.Abort(_('--normal cannot be used with --large'))
240 return orig(ui, repo, *pats, **opts)
240 return orig(ui, repo, *pats, **opts)
241 matcher = scmutil.match(repo[None], pats, opts)
241 matcher = scmutil.match(repo[None], pats, opts)
242 bad = addlargefiles(ui, repo, matcher, **opts)
242 bad = addlargefiles(ui, repo, matcher, **opts)
243 installnormalfilesmatchfn(repo[None].manifest())
243 installnormalfilesmatchfn(repo[None].manifest())
244 result = orig(ui, repo, *pats, **opts)
244 result = orig(ui, repo, *pats, **opts)
245 restorematchfn()
245 restorematchfn()
246
246
247 return (result == 1 or bad) and 1 or 0
247 return (result == 1 or bad) and 1 or 0
248
248
249 def overrideremove(orig, ui, repo, *pats, **opts):
249 def overrideremove(orig, ui, repo, *pats, **opts):
250 installnormalfilesmatchfn(repo[None].manifest())
250 installnormalfilesmatchfn(repo[None].manifest())
251 result = orig(ui, repo, *pats, **opts)
251 result = orig(ui, repo, *pats, **opts)
252 restorematchfn()
252 restorematchfn()
253 return removelargefiles(ui, repo, False, *pats, **opts) or result
253 return removelargefiles(ui, repo, False, *pats, **opts) or result
254
254
255 def overridestatusfn(orig, repo, rev2, **opts):
255 def overridestatusfn(orig, repo, rev2, **opts):
256 try:
256 try:
257 repo._repo.lfstatus = True
257 repo._repo.lfstatus = True
258 return orig(repo, rev2, **opts)
258 return orig(repo, rev2, **opts)
259 finally:
259 finally:
260 repo._repo.lfstatus = False
260 repo._repo.lfstatus = False
261
261
262 def overridestatus(orig, ui, repo, *pats, **opts):
262 def overridestatus(orig, ui, repo, *pats, **opts):
263 try:
263 try:
264 repo.lfstatus = True
264 repo.lfstatus = True
265 return orig(ui, repo, *pats, **opts)
265 return orig(ui, repo, *pats, **opts)
266 finally:
266 finally:
267 repo.lfstatus = False
267 repo.lfstatus = False
268
268
269 def overridedirty(orig, repo, ignoreupdate=False):
269 def overridedirty(orig, repo, ignoreupdate=False):
270 try:
270 try:
271 repo._repo.lfstatus = True
271 repo._repo.lfstatus = True
272 return orig(repo, ignoreupdate)
272 return orig(repo, ignoreupdate)
273 finally:
273 finally:
274 repo._repo.lfstatus = False
274 repo._repo.lfstatus = False
275
275
276 def overridelog(orig, ui, repo, *pats, **opts):
276 def overridelog(orig, ui, repo, *pats, **opts):
277 def overridematchandpats(ctx, pats=[], opts={}, globbed=False,
277 def overridematchandpats(ctx, pats=[], opts={}, globbed=False,
278 default='relpath'):
278 default='relpath'):
279 """Matcher that merges root directory with .hglf, suitable for log.
279 """Matcher that merges root directory with .hglf, suitable for log.
280 It is still possible to match .hglf directly.
280 It is still possible to match .hglf directly.
281 For any listed files run log on the standin too.
281 For any listed files run log on the standin too.
282 matchfn tries both the given filename and with .hglf stripped.
282 matchfn tries both the given filename and with .hglf stripped.
283 """
283 """
284 matchandpats = oldmatchandpats(ctx, pats, opts, globbed, default)
284 matchandpats = oldmatchandpats(ctx, pats, opts, globbed, default)
285 m, p = copy.copy(matchandpats)
285 m, p = copy.copy(matchandpats)
286
286
287 if m.always():
287 if m.always():
288 # We want to match everything anyway, so there's no benefit trying
288 # We want to match everything anyway, so there's no benefit trying
289 # to add standins.
289 # to add standins.
290 return matchandpats
290 return matchandpats
291
291
292 pats = set(p)
292 pats = set(p)
293 # TODO: handling of patterns in both cases below
293 # TODO: handling of patterns in both cases below
294 if m._cwd:
294 if m._cwd:
295 if os.path.isabs(m._cwd):
295 if os.path.isabs(m._cwd):
296 # TODO: handle largefile magic when invoked from other cwd
296 # TODO: handle largefile magic when invoked from other cwd
297 return matchandpats
297 return matchandpats
298 back = (m._cwd.count('/') + 1) * '../'
298 back = (m._cwd.count('/') + 1) * '../'
299 pats.update(back + lfutil.standin(m._cwd + '/' + f) for f in p)
299 pats.update(back + lfutil.standin(m._cwd + '/' + f) for f in p)
300 else:
300 else:
301 pats.update(lfutil.standin(f) for f in p)
301 pats.update(lfutil.standin(f) for f in p)
302
302
303 for i in range(0, len(m._files)):
303 for i in range(0, len(m._files)):
304 standin = lfutil.standin(m._files[i])
304 standin = lfutil.standin(m._files[i])
305 if standin in repo[ctx.node()]:
305 if standin in repo[ctx.node()]:
306 m._files[i] = standin
306 m._files[i] = standin
307 elif m._files[i] not in repo[ctx.node()]:
307 elif m._files[i] not in repo[ctx.node()]:
308 m._files.append(standin)
308 m._files.append(standin)
309 pats.add(standin)
309 pats.add(standin)
310
310
311 m._fmap = set(m._files)
311 m._fmap = set(m._files)
312 m._always = False
312 m._always = False
313 origmatchfn = m.matchfn
313 origmatchfn = m.matchfn
314 def lfmatchfn(f):
314 def lfmatchfn(f):
315 lf = lfutil.splitstandin(f)
315 lf = lfutil.splitstandin(f)
316 if lf is not None and origmatchfn(lf):
316 if lf is not None and origmatchfn(lf):
317 return True
317 return True
318 r = origmatchfn(f)
318 r = origmatchfn(f)
319 return r
319 return r
320 m.matchfn = lfmatchfn
320 m.matchfn = lfmatchfn
321
321
322 return m, pats
322 return m, pats
323
323
324 # For hg log --patch, the match object is used in two different senses:
324 # For hg log --patch, the match object is used in two different senses:
325 # (1) to determine what revisions should be printed out, and
325 # (1) to determine what revisions should be printed out, and
326 # (2) to determine what files to print out diffs for.
326 # (2) to determine what files to print out diffs for.
327 # The magic matchandpats override should be used for case (1) but not for
327 # The magic matchandpats override should be used for case (1) but not for
328 # case (2).
328 # case (2).
329 def overridemakelogfilematcher(repo, pats, opts):
329 def overridemakelogfilematcher(repo, pats, opts):
330 pctx = repo[None]
330 pctx = repo[None]
331 match, pats = oldmatchandpats(pctx, pats, opts)
331 match, pats = oldmatchandpats(pctx, pats, opts)
332 return lambda rev: match
332 return lambda rev: match
333
333
334 oldmatchandpats = installmatchandpatsfn(overridematchandpats)
334 oldmatchandpats = installmatchandpatsfn(overridematchandpats)
335 oldmakelogfilematcher = cmdutil._makenofollowlogfilematcher
335 oldmakelogfilematcher = cmdutil._makenofollowlogfilematcher
336 setattr(cmdutil, '_makenofollowlogfilematcher', overridemakelogfilematcher)
336 setattr(cmdutil, '_makenofollowlogfilematcher', overridemakelogfilematcher)
337
337
338 try:
338 try:
339 return orig(ui, repo, *pats, **opts)
339 return orig(ui, repo, *pats, **opts)
340 finally:
340 finally:
341 restorematchandpatsfn()
341 restorematchandpatsfn()
342 setattr(cmdutil, '_makenofollowlogfilematcher', oldmakelogfilematcher)
342 setattr(cmdutil, '_makenofollowlogfilematcher', oldmakelogfilematcher)
343
343
344 def overrideverify(orig, ui, repo, *pats, **opts):
344 def overrideverify(orig, ui, repo, *pats, **opts):
345 large = opts.pop('large', False)
345 large = opts.pop('large', False)
346 all = opts.pop('lfa', False)
346 all = opts.pop('lfa', False)
347 contents = opts.pop('lfc', False)
347 contents = opts.pop('lfc', False)
348
348
349 result = orig(ui, repo, *pats, **opts)
349 result = orig(ui, repo, *pats, **opts)
350 if large or all or contents:
350 if large or all or contents:
351 result = result or lfcommands.verifylfiles(ui, repo, all, contents)
351 result = result or lfcommands.verifylfiles(ui, repo, all, contents)
352 return result
352 return result
353
353
354 def overridedebugstate(orig, ui, repo, *pats, **opts):
354 def overridedebugstate(orig, ui, repo, *pats, **opts):
355 large = opts.pop('large', False)
355 large = opts.pop('large', False)
356 if large:
356 if large:
357 class fakerepo(object):
357 class fakerepo(object):
358 dirstate = lfutil.openlfdirstate(ui, repo)
358 dirstate = lfutil.openlfdirstate(ui, repo)
359 orig(ui, fakerepo, *pats, **opts)
359 orig(ui, fakerepo, *pats, **opts)
360 else:
360 else:
361 orig(ui, repo, *pats, **opts)
361 orig(ui, repo, *pats, **opts)
362
362
363 # Override needs to refresh standins so that update's normal merge
363 # Override needs to refresh standins so that update's normal merge
364 # will go through properly. Then the other update hook (overriding repo.update)
364 # will go through properly. Then the other update hook (overriding repo.update)
365 # will get the new files. Filemerge is also overridden so that the merge
365 # will get the new files. Filemerge is also overridden so that the merge
366 # will merge standins correctly.
366 # will merge standins correctly.
367 def overrideupdate(orig, ui, repo, *pats, **opts):
367 def overrideupdate(orig, ui, repo, *pats, **opts):
368 # Need to lock between the standins getting updated and their
368 # Need to lock between the standins getting updated and their
369 # largefiles getting updated
369 # largefiles getting updated
370 wlock = repo.wlock()
370 wlock = repo.wlock()
371 try:
371 try:
372 if opts['check']:
372 if opts['check']:
373 lfdirstate = lfutil.openlfdirstate(ui, repo)
373 lfdirstate = lfutil.openlfdirstate(ui, repo)
374 unsure, s = lfdirstate.status(
374 unsure, s = lfdirstate.status(
375 match_.always(repo.root, repo.getcwd()),
375 match_.always(repo.root, repo.getcwd()),
376 [], False, False, False)
376 [], False, False, False)
377
377
378 mod = len(s.modified) > 0
378 mod = len(s.modified) > 0
379 for lfile in unsure:
379 for lfile in unsure:
380 standin = lfutil.standin(lfile)
380 standin = lfutil.standin(lfile)
381 if repo['.'][standin].data().strip() != \
381 if repo['.'][standin].data().strip() != \
382 lfutil.hashfile(repo.wjoin(lfile)):
382 lfutil.hashfile(repo.wjoin(lfile)):
383 mod = True
383 mod = True
384 else:
384 else:
385 lfdirstate.normal(lfile)
385 lfdirstate.normal(lfile)
386 lfdirstate.write()
386 lfdirstate.write()
387 if mod:
387 if mod:
388 raise util.Abort(_('uncommitted changes'))
388 raise util.Abort(_('uncommitted changes'))
389 return orig(ui, repo, *pats, **opts)
389 return orig(ui, repo, *pats, **opts)
390 finally:
390 finally:
391 wlock.release()
391 wlock.release()
392
392
393 # Before starting the manifest merge, merge.updates will call
393 # Before starting the manifest merge, merge.updates will call
394 # _checkunknownfile to check if there are any files in the merged-in
394 # _checkunknownfile to check if there are any files in the merged-in
395 # changeset that collide with unknown files in the working copy.
395 # changeset that collide with unknown files in the working copy.
396 #
396 #
397 # The largefiles are seen as unknown, so this prevents us from merging
397 # The largefiles are seen as unknown, so this prevents us from merging
398 # in a file 'foo' if we already have a largefile with the same name.
398 # in a file 'foo' if we already have a largefile with the same name.
399 #
399 #
400 # The overridden function filters the unknown files by removing any
400 # The overridden function filters the unknown files by removing any
401 # largefiles. This makes the merge proceed and we can then handle this
401 # largefiles. This makes the merge proceed and we can then handle this
402 # case further in the overridden calculateupdates function below.
402 # case further in the overridden calculateupdates function below.
403 def overridecheckunknownfile(origfn, repo, wctx, mctx, f, f2=None):
403 def overridecheckunknownfile(origfn, repo, wctx, mctx, f, f2=None):
404 if lfutil.standin(repo.dirstate.normalize(f)) in wctx:
404 if lfutil.standin(repo.dirstate.normalize(f)) in wctx:
405 return False
405 return False
406 return origfn(repo, wctx, mctx, f, f2)
406 return origfn(repo, wctx, mctx, f, f2)
407
407
408 # The manifest merge handles conflicts on the manifest level. We want
408 # The manifest merge handles conflicts on the manifest level. We want
409 # to handle changes in largefile-ness of files at this level too.
409 # to handle changes in largefile-ness of files at this level too.
410 #
410 #
411 # The strategy is to run the original calculateupdates and then process
411 # The strategy is to run the original calculateupdates and then process
412 # the action list it outputs. There are two cases we need to deal with:
412 # the action list it outputs. There are two cases we need to deal with:
413 #
413 #
414 # 1. Normal file in p1, largefile in p2. Here the largefile is
414 # 1. Normal file in p1, largefile in p2. Here the largefile is
415 # detected via its standin file, which will enter the working copy
415 # detected via its standin file, which will enter the working copy
416 # with a "get" action. It is not "merge" since the standin is all
416 # with a "get" action. It is not "merge" since the standin is all
417 # Mercurial is concerned with at this level -- the link to the
417 # Mercurial is concerned with at this level -- the link to the
418 # existing normal file is not relevant here.
418 # existing normal file is not relevant here.
419 #
419 #
420 # 2. Largefile in p1, normal file in p2. Here we get a "merge" action
420 # 2. Largefile in p1, normal file in p2. Here we get a "merge" action
421 # since the largefile will be present in the working copy and
421 # since the largefile will be present in the working copy and
422 # different from the normal file in p2. Mercurial therefore
422 # different from the normal file in p2. Mercurial therefore
423 # triggers a merge action.
423 # triggers a merge action.
424 #
424 #
425 # In both cases, we prompt the user and emit new actions to either
425 # In both cases, we prompt the user and emit new actions to either
426 # remove the standin (if the normal file was kept) or to remove the
426 # remove the standin (if the normal file was kept) or to remove the
427 # normal file and get the standin (if the largefile was kept). The
427 # normal file and get the standin (if the largefile was kept). The
428 # default prompt answer is to use the largefile version since it was
428 # default prompt answer is to use the largefile version since it was
429 # presumably changed on purpose.
429 # presumably changed on purpose.
430 #
430 #
431 # Finally, the merge.applyupdates function will then take care of
431 # Finally, the merge.applyupdates function will then take care of
432 # writing the files into the working copy and lfcommands.updatelfiles
432 # writing the files into the working copy and lfcommands.updatelfiles
433 # will update the largefiles.
433 # will update the largefiles.
434 def overridecalculateupdates(origfn, repo, p1, p2, pas, branchmerge, force,
434 def overridecalculateupdates(origfn, repo, p1, p2, pas, branchmerge, force,
435 partial, acceptremote, followcopies):
435 partial, acceptremote, followcopies):
436 overwrite = force and not branchmerge
436 overwrite = force and not branchmerge
437 actions, diverge, renamedelete = origfn(
437 actions, diverge, renamedelete = origfn(
438 repo, p1, p2, pas, branchmerge, force, partial, acceptremote,
438 repo, p1, p2, pas, branchmerge, force, partial, acceptremote,
439 followcopies)
439 followcopies)
440
440
441 if overwrite:
441 if overwrite:
442 return actions, diverge, renamedelete
442 return actions, diverge, renamedelete
443
443
444 # Convert to dictionary with filename as key and action as value.
444 # Convert to dictionary with filename as key and action as value.
445 lfiles = set()
445 lfiles = set()
446 for f in actions:
446 for f in actions:
447 splitstandin = f and lfutil.splitstandin(f)
447 splitstandin = f and lfutil.splitstandin(f)
448 if splitstandin in p1:
448 if splitstandin in p1:
449 lfiles.add(splitstandin)
449 lfiles.add(splitstandin)
450 elif lfutil.standin(f) in p1:
450 elif lfutil.standin(f) in p1:
451 lfiles.add(f)
451 lfiles.add(f)
452
452
453 for lfile in lfiles:
453 for lfile in lfiles:
454 standin = lfutil.standin(lfile)
454 standin = lfutil.standin(lfile)
455 (lm, largs, lmsg) = actions.get(lfile, (None, None, None))
455 (lm, largs, lmsg) = actions.get(lfile, (None, None, None))
456 (sm, sargs, smsg) = actions.get(standin, (None, None, None))
456 (sm, sargs, smsg) = actions.get(standin, (None, None, None))
457 if sm in ('g', 'dc') and lm != 'r':
457 if sm in ('g', 'dc') and lm != 'r':
458 # Case 1: normal file in the working copy, largefile in
458 # Case 1: normal file in the working copy, largefile in
459 # the second parent
459 # the second parent
460 usermsg = _('remote turned local normal file %s into a largefile\n'
460 usermsg = _('remote turned local normal file %s into a largefile\n'
461 'use (l)argefile or keep (n)ormal file?'
461 'use (l)argefile or keep (n)ormal file?'
462 '$$ &Largefile $$ &Normal file') % lfile
462 '$$ &Largefile $$ &Normal file') % lfile
463 if repo.ui.promptchoice(usermsg, 0) == 0: # pick remote largefile
463 if repo.ui.promptchoice(usermsg, 0) == 0: # pick remote largefile
464 actions[lfile] = ('r', None, 'replaced by standin')
464 actions[lfile] = ('r', None, 'replaced by standin')
465 actions[standin] = ('g', sargs, 'replaces standin')
465 actions[standin] = ('g', sargs, 'replaces standin')
466 else: # keep local normal file
466 else: # keep local normal file
467 actions[lfile] = ('k', None, 'replaces standin')
467 actions[lfile] = ('k', None, 'replaces standin')
468 if branchmerge:
468 if branchmerge:
469 actions[standin] = ('k', None, 'replaced by non-standin')
469 actions[standin] = ('k', None, 'replaced by non-standin')
470 else:
470 else:
471 actions[standin] = ('r', None, 'replaced by non-standin')
471 actions[standin] = ('r', None, 'replaced by non-standin')
472 elif lm in ('g', 'dc') and sm != 'r':
472 elif lm in ('g', 'dc') and sm != 'r':
473 # Case 2: largefile in the working copy, normal file in
473 # Case 2: largefile in the working copy, normal file in
474 # the second parent
474 # the second parent
475 usermsg = _('remote turned local largefile %s into a normal file\n'
475 usermsg = _('remote turned local largefile %s into a normal file\n'
476 'keep (l)argefile or use (n)ormal file?'
476 'keep (l)argefile or use (n)ormal file?'
477 '$$ &Largefile $$ &Normal file') % lfile
477 '$$ &Largefile $$ &Normal file') % lfile
478 if repo.ui.promptchoice(usermsg, 0) == 0: # keep local largefile
478 if repo.ui.promptchoice(usermsg, 0) == 0: # keep local largefile
479 if branchmerge:
479 if branchmerge:
480 # largefile can be restored from standin safely
480 # largefile can be restored from standin safely
481 actions[lfile] = ('k', None, 'replaced by standin')
481 actions[lfile] = ('k', None, 'replaced by standin')
482 actions[standin] = ('k', None, 'replaces standin')
482 actions[standin] = ('k', None, 'replaces standin')
483 else:
483 else:
484 # "lfile" should be marked as "removed" without
484 # "lfile" should be marked as "removed" without
485 # removal of itself
485 # removal of itself
486 actions[lfile] = ('lfmr', None,
486 actions[lfile] = ('lfmr', None,
487 'forget non-standin largefile')
487 'forget non-standin largefile')
488
488
489 # linear-merge should treat this largefile as 're-added'
489 # linear-merge should treat this largefile as 're-added'
490 actions[standin] = ('a', None, 'keep standin')
490 actions[standin] = ('a', None, 'keep standin')
491 else: # pick remote normal file
491 else: # pick remote normal file
492 actions[lfile] = ('g', largs, 'replaces standin')
492 actions[lfile] = ('g', largs, 'replaces standin')
493 actions[standin] = ('r', None, 'replaced by non-standin')
493 actions[standin] = ('r', None, 'replaced by non-standin')
494
494
495 return actions, diverge, renamedelete
495 return actions, diverge, renamedelete
496
496
497 def mergerecordupdates(orig, repo, actions, branchmerge):
497 def mergerecordupdates(orig, repo, actions, branchmerge):
498 if 'lfmr' in actions:
498 if 'lfmr' in actions:
499 # this should be executed before 'orig', to execute 'remove'
499 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
500 # before all other actions
501 for lfile, args, msg in actions['lfmr']:
500 for lfile, args, msg in actions['lfmr']:
501 # this should be executed before 'orig', to execute 'remove'
502 # before all other actions
502 repo.dirstate.remove(lfile)
503 repo.dirstate.remove(lfile)
504 # make sure lfile doesn't get synclfdirstate'd as normal
505 lfdirstate.add(lfile)
506 lfdirstate.write()
503
507
504 return orig(repo, actions, branchmerge)
508 return orig(repo, actions, branchmerge)
505
509
506
510
507 # Override filemerge to prompt the user about how they wish to merge
511 # Override filemerge to prompt the user about how they wish to merge
508 # largefiles. This will handle identical edits without prompting the user.
512 # largefiles. This will handle identical edits without prompting the user.
509 def overridefilemerge(origfn, repo, mynode, orig, fcd, fco, fca, labels=None):
513 def overridefilemerge(origfn, repo, mynode, orig, fcd, fco, fca, labels=None):
510 if not lfutil.isstandin(orig):
514 if not lfutil.isstandin(orig):
511 return origfn(repo, mynode, orig, fcd, fco, fca, labels=labels)
515 return origfn(repo, mynode, orig, fcd, fco, fca, labels=labels)
512
516
513 ahash = fca.data().strip().lower()
517 ahash = fca.data().strip().lower()
514 dhash = fcd.data().strip().lower()
518 dhash = fcd.data().strip().lower()
515 ohash = fco.data().strip().lower()
519 ohash = fco.data().strip().lower()
516 if (ohash != ahash and
520 if (ohash != ahash and
517 ohash != dhash and
521 ohash != dhash and
518 (dhash == ahash or
522 (dhash == ahash or
519 repo.ui.promptchoice(
523 repo.ui.promptchoice(
520 _('largefile %s has a merge conflict\nancestor was %s\n'
524 _('largefile %s has a merge conflict\nancestor was %s\n'
521 'keep (l)ocal %s or\ntake (o)ther %s?'
525 'keep (l)ocal %s or\ntake (o)ther %s?'
522 '$$ &Local $$ &Other') %
526 '$$ &Local $$ &Other') %
523 (lfutil.splitstandin(orig), ahash, dhash, ohash),
527 (lfutil.splitstandin(orig), ahash, dhash, ohash),
524 0) == 1)):
528 0) == 1)):
525 repo.wwrite(fcd.path(), fco.data(), fco.flags())
529 repo.wwrite(fcd.path(), fco.data(), fco.flags())
526 return 0
530 return 0
527
531
528 # Copy first changes the matchers to match standins instead of
532 # Copy first changes the matchers to match standins instead of
529 # largefiles. Then it overrides util.copyfile in that function it
533 # largefiles. Then it overrides util.copyfile in that function it
530 # checks if the destination largefile already exists. It also keeps a
534 # checks if the destination largefile already exists. It also keeps a
531 # list of copied files so that the largefiles can be copied and the
535 # list of copied files so that the largefiles can be copied and the
532 # dirstate updated.
536 # dirstate updated.
533 def overridecopy(orig, ui, repo, pats, opts, rename=False):
537 def overridecopy(orig, ui, repo, pats, opts, rename=False):
534 # doesn't remove largefile on rename
538 # doesn't remove largefile on rename
535 if len(pats) < 2:
539 if len(pats) < 2:
536 # this isn't legal, let the original function deal with it
540 # this isn't legal, let the original function deal with it
537 return orig(ui, repo, pats, opts, rename)
541 return orig(ui, repo, pats, opts, rename)
538
542
539 def makestandin(relpath):
543 def makestandin(relpath):
540 path = pathutil.canonpath(repo.root, repo.getcwd(), relpath)
544 path = pathutil.canonpath(repo.root, repo.getcwd(), relpath)
541 return os.path.join(repo.wjoin(lfutil.standin(path)))
545 return os.path.join(repo.wjoin(lfutil.standin(path)))
542
546
543 fullpats = scmutil.expandpats(pats)
547 fullpats = scmutil.expandpats(pats)
544 dest = fullpats[-1]
548 dest = fullpats[-1]
545
549
546 if os.path.isdir(dest):
550 if os.path.isdir(dest):
547 if not os.path.isdir(makestandin(dest)):
551 if not os.path.isdir(makestandin(dest)):
548 os.makedirs(makestandin(dest))
552 os.makedirs(makestandin(dest))
549 # This could copy both lfiles and normal files in one command,
553 # This could copy both lfiles and normal files in one command,
550 # but we don't want to do that. First replace their matcher to
554 # but we don't want to do that. First replace their matcher to
551 # only match normal files and run it, then replace it to just
555 # only match normal files and run it, then replace it to just
552 # match largefiles and run it again.
556 # match largefiles and run it again.
553 nonormalfiles = False
557 nonormalfiles = False
554 nolfiles = False
558 nolfiles = False
555 installnormalfilesmatchfn(repo[None].manifest())
559 installnormalfilesmatchfn(repo[None].manifest())
556 try:
560 try:
557 try:
561 try:
558 result = orig(ui, repo, pats, opts, rename)
562 result = orig(ui, repo, pats, opts, rename)
559 except util.Abort, e:
563 except util.Abort, e:
560 if str(e) != _('no files to copy'):
564 if str(e) != _('no files to copy'):
561 raise e
565 raise e
562 else:
566 else:
563 nonormalfiles = True
567 nonormalfiles = True
564 result = 0
568 result = 0
565 finally:
569 finally:
566 restorematchfn()
570 restorematchfn()
567
571
568 # The first rename can cause our current working directory to be removed.
572 # The first rename can cause our current working directory to be removed.
569 # In that case there is nothing left to copy/rename so just quit.
573 # In that case there is nothing left to copy/rename so just quit.
570 try:
574 try:
571 repo.getcwd()
575 repo.getcwd()
572 except OSError:
576 except OSError:
573 return result
577 return result
574
578
575 try:
579 try:
576 try:
580 try:
577 # When we call orig below it creates the standins but we don't add
581 # When we call orig below it creates the standins but we don't add
578 # them to the dir state until later so lock during that time.
582 # them to the dir state until later so lock during that time.
579 wlock = repo.wlock()
583 wlock = repo.wlock()
580
584
581 manifest = repo[None].manifest()
585 manifest = repo[None].manifest()
582 def overridematch(ctx, pats=[], opts={}, globbed=False,
586 def overridematch(ctx, pats=[], opts={}, globbed=False,
583 default='relpath'):
587 default='relpath'):
584 newpats = []
588 newpats = []
585 # The patterns were previously mangled to add the standin
589 # The patterns were previously mangled to add the standin
586 # directory; we need to remove that now
590 # directory; we need to remove that now
587 for pat in pats:
591 for pat in pats:
588 if match_.patkind(pat) is None and lfutil.shortname in pat:
592 if match_.patkind(pat) is None and lfutil.shortname in pat:
589 newpats.append(pat.replace(lfutil.shortname, ''))
593 newpats.append(pat.replace(lfutil.shortname, ''))
590 else:
594 else:
591 newpats.append(pat)
595 newpats.append(pat)
592 match = oldmatch(ctx, newpats, opts, globbed, default)
596 match = oldmatch(ctx, newpats, opts, globbed, default)
593 m = copy.copy(match)
597 m = copy.copy(match)
594 lfile = lambda f: lfutil.standin(f) in manifest
598 lfile = lambda f: lfutil.standin(f) in manifest
595 m._files = [lfutil.standin(f) for f in m._files if lfile(f)]
599 m._files = [lfutil.standin(f) for f in m._files if lfile(f)]
596 m._fmap = set(m._files)
600 m._fmap = set(m._files)
597 origmatchfn = m.matchfn
601 origmatchfn = m.matchfn
598 m.matchfn = lambda f: (lfutil.isstandin(f) and
602 m.matchfn = lambda f: (lfutil.isstandin(f) and
599 (f in manifest) and
603 (f in manifest) and
600 origmatchfn(lfutil.splitstandin(f)) or
604 origmatchfn(lfutil.splitstandin(f)) or
601 None)
605 None)
602 return m
606 return m
603 oldmatch = installmatchfn(overridematch)
607 oldmatch = installmatchfn(overridematch)
604 listpats = []
608 listpats = []
605 for pat in pats:
609 for pat in pats:
606 if match_.patkind(pat) is not None:
610 if match_.patkind(pat) is not None:
607 listpats.append(pat)
611 listpats.append(pat)
608 else:
612 else:
609 listpats.append(makestandin(pat))
613 listpats.append(makestandin(pat))
610
614
611 try:
615 try:
612 origcopyfile = util.copyfile
616 origcopyfile = util.copyfile
613 copiedfiles = []
617 copiedfiles = []
614 def overridecopyfile(src, dest):
618 def overridecopyfile(src, dest):
615 if (lfutil.shortname in src and
619 if (lfutil.shortname in src and
616 dest.startswith(repo.wjoin(lfutil.shortname))):
620 dest.startswith(repo.wjoin(lfutil.shortname))):
617 destlfile = dest.replace(lfutil.shortname, '')
621 destlfile = dest.replace(lfutil.shortname, '')
618 if not opts['force'] and os.path.exists(destlfile):
622 if not opts['force'] and os.path.exists(destlfile):
619 raise IOError('',
623 raise IOError('',
620 _('destination largefile already exists'))
624 _('destination largefile already exists'))
621 copiedfiles.append((src, dest))
625 copiedfiles.append((src, dest))
622 origcopyfile(src, dest)
626 origcopyfile(src, dest)
623
627
624 util.copyfile = overridecopyfile
628 util.copyfile = overridecopyfile
625 result += orig(ui, repo, listpats, opts, rename)
629 result += orig(ui, repo, listpats, opts, rename)
626 finally:
630 finally:
627 util.copyfile = origcopyfile
631 util.copyfile = origcopyfile
628
632
629 lfdirstate = lfutil.openlfdirstate(ui, repo)
633 lfdirstate = lfutil.openlfdirstate(ui, repo)
630 for (src, dest) in copiedfiles:
634 for (src, dest) in copiedfiles:
631 if (lfutil.shortname in src and
635 if (lfutil.shortname in src and
632 dest.startswith(repo.wjoin(lfutil.shortname))):
636 dest.startswith(repo.wjoin(lfutil.shortname))):
633 srclfile = src.replace(repo.wjoin(lfutil.standin('')), '')
637 srclfile = src.replace(repo.wjoin(lfutil.standin('')), '')
634 destlfile = dest.replace(repo.wjoin(lfutil.standin('')), '')
638 destlfile = dest.replace(repo.wjoin(lfutil.standin('')), '')
635 destlfiledir = os.path.dirname(repo.wjoin(destlfile)) or '.'
639 destlfiledir = os.path.dirname(repo.wjoin(destlfile)) or '.'
636 if not os.path.isdir(destlfiledir):
640 if not os.path.isdir(destlfiledir):
637 os.makedirs(destlfiledir)
641 os.makedirs(destlfiledir)
638 if rename:
642 if rename:
639 os.rename(repo.wjoin(srclfile), repo.wjoin(destlfile))
643 os.rename(repo.wjoin(srclfile), repo.wjoin(destlfile))
640
644
641 # The file is gone, but this deletes any empty parent
645 # The file is gone, but this deletes any empty parent
642 # directories as a side-effect.
646 # directories as a side-effect.
643 util.unlinkpath(repo.wjoin(srclfile), True)
647 util.unlinkpath(repo.wjoin(srclfile), True)
644 lfdirstate.remove(srclfile)
648 lfdirstate.remove(srclfile)
645 else:
649 else:
646 util.copyfile(repo.wjoin(srclfile),
650 util.copyfile(repo.wjoin(srclfile),
647 repo.wjoin(destlfile))
651 repo.wjoin(destlfile))
648
652
649 lfdirstate.add(destlfile)
653 lfdirstate.add(destlfile)
650 lfdirstate.write()
654 lfdirstate.write()
651 except util.Abort, e:
655 except util.Abort, e:
652 if str(e) != _('no files to copy'):
656 if str(e) != _('no files to copy'):
653 raise e
657 raise e
654 else:
658 else:
655 nolfiles = True
659 nolfiles = True
656 finally:
660 finally:
657 restorematchfn()
661 restorematchfn()
658 wlock.release()
662 wlock.release()
659
663
660 if nolfiles and nonormalfiles:
664 if nolfiles and nonormalfiles:
661 raise util.Abort(_('no files to copy'))
665 raise util.Abort(_('no files to copy'))
662
666
663 return result
667 return result
664
668
665 # When the user calls revert, we have to be careful to not revert any
669 # When the user calls revert, we have to be careful to not revert any
666 # changes to other largefiles accidentally. This means we have to keep
670 # changes to other largefiles accidentally. This means we have to keep
667 # track of the largefiles that are being reverted so we only pull down
671 # track of the largefiles that are being reverted so we only pull down
668 # the necessary largefiles.
672 # the necessary largefiles.
669 #
673 #
670 # Standins are only updated (to match the hash of largefiles) before
674 # Standins are only updated (to match the hash of largefiles) before
671 # commits. Update the standins then run the original revert, changing
675 # commits. Update the standins then run the original revert, changing
672 # the matcher to hit standins instead of largefiles. Based on the
676 # the matcher to hit standins instead of largefiles. Based on the
673 # resulting standins update the largefiles.
677 # resulting standins update the largefiles.
674 def overriderevert(orig, ui, repo, *pats, **opts):
678 def overriderevert(orig, ui, repo, *pats, **opts):
675 # Because we put the standins in a bad state (by updating them)
679 # Because we put the standins in a bad state (by updating them)
676 # and then return them to a correct state we need to lock to
680 # and then return them to a correct state we need to lock to
677 # prevent others from changing them in their incorrect state.
681 # prevent others from changing them in their incorrect state.
678 wlock = repo.wlock()
682 wlock = repo.wlock()
679 try:
683 try:
680 lfdirstate = lfutil.openlfdirstate(ui, repo)
684 lfdirstate = lfutil.openlfdirstate(ui, repo)
681 s = lfutil.lfdirstatestatus(lfdirstate, repo)
685 s = lfutil.lfdirstatestatus(lfdirstate, repo)
682 lfdirstate.write()
686 lfdirstate.write()
683 for lfile in s.modified:
687 for lfile in s.modified:
684 lfutil.updatestandin(repo, lfutil.standin(lfile))
688 lfutil.updatestandin(repo, lfutil.standin(lfile))
685 for lfile in s.deleted:
689 for lfile in s.deleted:
686 if (os.path.exists(repo.wjoin(lfutil.standin(lfile)))):
690 if (os.path.exists(repo.wjoin(lfutil.standin(lfile)))):
687 os.unlink(repo.wjoin(lfutil.standin(lfile)))
691 os.unlink(repo.wjoin(lfutil.standin(lfile)))
688
692
689 oldstandins = lfutil.getstandinsstate(repo)
693 oldstandins = lfutil.getstandinsstate(repo)
690
694
691 def overridematch(ctx, pats=[], opts={}, globbed=False,
695 def overridematch(ctx, pats=[], opts={}, globbed=False,
692 default='relpath'):
696 default='relpath'):
693 match = oldmatch(ctx, pats, opts, globbed, default)
697 match = oldmatch(ctx, pats, opts, globbed, default)
694 m = copy.copy(match)
698 m = copy.copy(match)
695 def tostandin(f):
699 def tostandin(f):
696 if lfutil.standin(f) in ctx:
700 if lfutil.standin(f) in ctx:
697 return lfutil.standin(f)
701 return lfutil.standin(f)
698 elif lfutil.standin(f) in repo[None]:
702 elif lfutil.standin(f) in repo[None]:
699 return None
703 return None
700 return f
704 return f
701 m._files = [tostandin(f) for f in m._files]
705 m._files = [tostandin(f) for f in m._files]
702 m._files = [f for f in m._files if f is not None]
706 m._files = [f for f in m._files if f is not None]
703 m._fmap = set(m._files)
707 m._fmap = set(m._files)
704 origmatchfn = m.matchfn
708 origmatchfn = m.matchfn
705 def matchfn(f):
709 def matchfn(f):
706 if lfutil.isstandin(f):
710 if lfutil.isstandin(f):
707 return (origmatchfn(lfutil.splitstandin(f)) and
711 return (origmatchfn(lfutil.splitstandin(f)) and
708 (f in repo[None] or f in ctx))
712 (f in repo[None] or f in ctx))
709 return origmatchfn(f)
713 return origmatchfn(f)
710 m.matchfn = matchfn
714 m.matchfn = matchfn
711 return m
715 return m
712 oldmatch = installmatchfn(overridematch)
716 oldmatch = installmatchfn(overridematch)
713 try:
717 try:
714 orig(ui, repo, *pats, **opts)
718 orig(ui, repo, *pats, **opts)
715 finally:
719 finally:
716 restorematchfn()
720 restorematchfn()
717
721
718 newstandins = lfutil.getstandinsstate(repo)
722 newstandins = lfutil.getstandinsstate(repo)
719 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
723 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
720 # lfdirstate should be 'normallookup'-ed for updated files,
724 # lfdirstate should be 'normallookup'-ed for updated files,
721 # because reverting doesn't touch dirstate for 'normal' files
725 # because reverting doesn't touch dirstate for 'normal' files
722 # when target revision is explicitly specified: in such case,
726 # when target revision is explicitly specified: in such case,
723 # 'n' and valid timestamp in dirstate doesn't ensure 'clean'
727 # 'n' and valid timestamp in dirstate doesn't ensure 'clean'
724 # of target (standin) file.
728 # of target (standin) file.
725 lfcommands.updatelfiles(ui, repo, filelist, printmessage=False,
729 lfcommands.updatelfiles(ui, repo, filelist, printmessage=False,
726 normallookup=True)
730 normallookup=True)
727
731
728 finally:
732 finally:
729 wlock.release()
733 wlock.release()
730
734
731 # after pulling changesets, we need to take some extra care to get
735 # after pulling changesets, we need to take some extra care to get
732 # largefiles updated remotely
736 # largefiles updated remotely
733 def overridepull(orig, ui, repo, source=None, **opts):
737 def overridepull(orig, ui, repo, source=None, **opts):
734 revsprepull = len(repo)
738 revsprepull = len(repo)
735 if not source:
739 if not source:
736 source = 'default'
740 source = 'default'
737 repo.lfpullsource = source
741 repo.lfpullsource = source
738 result = orig(ui, repo, source, **opts)
742 result = orig(ui, repo, source, **opts)
739 revspostpull = len(repo)
743 revspostpull = len(repo)
740 lfrevs = opts.get('lfrev', [])
744 lfrevs = opts.get('lfrev', [])
741 if opts.get('all_largefiles'):
745 if opts.get('all_largefiles'):
742 lfrevs.append('pulled()')
746 lfrevs.append('pulled()')
743 if lfrevs and revspostpull > revsprepull:
747 if lfrevs and revspostpull > revsprepull:
744 numcached = 0
748 numcached = 0
745 repo.firstpulled = revsprepull # for pulled() revset expression
749 repo.firstpulled = revsprepull # for pulled() revset expression
746 try:
750 try:
747 for rev in scmutil.revrange(repo, lfrevs):
751 for rev in scmutil.revrange(repo, lfrevs):
748 ui.note(_('pulling largefiles for revision %s\n') % rev)
752 ui.note(_('pulling largefiles for revision %s\n') % rev)
749 (cached, missing) = lfcommands.cachelfiles(ui, repo, rev)
753 (cached, missing) = lfcommands.cachelfiles(ui, repo, rev)
750 numcached += len(cached)
754 numcached += len(cached)
751 finally:
755 finally:
752 del repo.firstpulled
756 del repo.firstpulled
753 ui.status(_("%d largefiles cached\n") % numcached)
757 ui.status(_("%d largefiles cached\n") % numcached)
754 return result
758 return result
755
759
756 def pulledrevsetsymbol(repo, subset, x):
760 def pulledrevsetsymbol(repo, subset, x):
757 """``pulled()``
761 """``pulled()``
758 Changesets that just has been pulled.
762 Changesets that just has been pulled.
759
763
760 Only available with largefiles from pull --lfrev expressions.
764 Only available with largefiles from pull --lfrev expressions.
761
765
762 .. container:: verbose
766 .. container:: verbose
763
767
764 Some examples:
768 Some examples:
765
769
766 - pull largefiles for all new changesets::
770 - pull largefiles for all new changesets::
767
771
768 hg pull -lfrev "pulled()"
772 hg pull -lfrev "pulled()"
769
773
770 - pull largefiles for all new branch heads::
774 - pull largefiles for all new branch heads::
771
775
772 hg pull -lfrev "head(pulled()) and not closed()"
776 hg pull -lfrev "head(pulled()) and not closed()"
773
777
774 """
778 """
775
779
776 try:
780 try:
777 firstpulled = repo.firstpulled
781 firstpulled = repo.firstpulled
778 except AttributeError:
782 except AttributeError:
779 raise util.Abort(_("pulled() only available in --lfrev"))
783 raise util.Abort(_("pulled() only available in --lfrev"))
780 return revset.baseset([r for r in subset if r >= firstpulled])
784 return revset.baseset([r for r in subset if r >= firstpulled])
781
785
782 def overrideclone(orig, ui, source, dest=None, **opts):
786 def overrideclone(orig, ui, source, dest=None, **opts):
783 d = dest
787 d = dest
784 if d is None:
788 if d is None:
785 d = hg.defaultdest(source)
789 d = hg.defaultdest(source)
786 if opts.get('all_largefiles') and not hg.islocal(d):
790 if opts.get('all_largefiles') and not hg.islocal(d):
787 raise util.Abort(_(
791 raise util.Abort(_(
788 '--all-largefiles is incompatible with non-local destination %s') %
792 '--all-largefiles is incompatible with non-local destination %s') %
789 d)
793 d)
790
794
791 return orig(ui, source, dest, **opts)
795 return orig(ui, source, dest, **opts)
792
796
793 def hgclone(orig, ui, opts, *args, **kwargs):
797 def hgclone(orig, ui, opts, *args, **kwargs):
794 result = orig(ui, opts, *args, **kwargs)
798 result = orig(ui, opts, *args, **kwargs)
795
799
796 if result is not None:
800 if result is not None:
797 sourcerepo, destrepo = result
801 sourcerepo, destrepo = result
798 repo = destrepo.local()
802 repo = destrepo.local()
799
803
800 # Caching is implicitly limited to 'rev' option, since the dest repo was
804 # Caching is implicitly limited to 'rev' option, since the dest repo was
801 # truncated at that point. The user may expect a download count with
805 # truncated at that point. The user may expect a download count with
802 # this option, so attempt whether or not this is a largefile repo.
806 # this option, so attempt whether or not this is a largefile repo.
803 if opts.get('all_largefiles'):
807 if opts.get('all_largefiles'):
804 success, missing = lfcommands.downloadlfiles(ui, repo, None)
808 success, missing = lfcommands.downloadlfiles(ui, repo, None)
805
809
806 if missing != 0:
810 if missing != 0:
807 return None
811 return None
808
812
809 return result
813 return result
810
814
811 def overriderebase(orig, ui, repo, **opts):
815 def overriderebase(orig, ui, repo, **opts):
812 resuming = opts.get('continue')
816 resuming = opts.get('continue')
813 repo._lfcommithooks.append(lfutil.automatedcommithook(resuming))
817 repo._lfcommithooks.append(lfutil.automatedcommithook(resuming))
814 repo._lfstatuswriters.append(lambda *msg, **opts: None)
818 repo._lfstatuswriters.append(lambda *msg, **opts: None)
815 try:
819 try:
816 return orig(ui, repo, **opts)
820 return orig(ui, repo, **opts)
817 finally:
821 finally:
818 repo._lfstatuswriters.pop()
822 repo._lfstatuswriters.pop()
819 repo._lfcommithooks.pop()
823 repo._lfcommithooks.pop()
820
824
821 def overridearchive(orig, repo, dest, node, kind, decode=True, matchfn=None,
825 def overridearchive(orig, repo, dest, node, kind, decode=True, matchfn=None,
822 prefix=None, mtime=None, subrepos=None):
826 prefix=None, mtime=None, subrepos=None):
823 # No need to lock because we are only reading history and
827 # No need to lock because we are only reading history and
824 # largefile caches, neither of which are modified.
828 # largefile caches, neither of which are modified.
825 lfcommands.cachelfiles(repo.ui, repo, node)
829 lfcommands.cachelfiles(repo.ui, repo, node)
826
830
827 if kind not in archival.archivers:
831 if kind not in archival.archivers:
828 raise util.Abort(_("unknown archive type '%s'") % kind)
832 raise util.Abort(_("unknown archive type '%s'") % kind)
829
833
830 ctx = repo[node]
834 ctx = repo[node]
831
835
832 if kind == 'files':
836 if kind == 'files':
833 if prefix:
837 if prefix:
834 raise util.Abort(
838 raise util.Abort(
835 _('cannot give prefix when archiving to files'))
839 _('cannot give prefix when archiving to files'))
836 else:
840 else:
837 prefix = archival.tidyprefix(dest, kind, prefix)
841 prefix = archival.tidyprefix(dest, kind, prefix)
838
842
839 def write(name, mode, islink, getdata):
843 def write(name, mode, islink, getdata):
840 if matchfn and not matchfn(name):
844 if matchfn and not matchfn(name):
841 return
845 return
842 data = getdata()
846 data = getdata()
843 if decode:
847 if decode:
844 data = repo.wwritedata(name, data)
848 data = repo.wwritedata(name, data)
845 archiver.addfile(prefix + name, mode, islink, data)
849 archiver.addfile(prefix + name, mode, islink, data)
846
850
847 archiver = archival.archivers[kind](dest, mtime or ctx.date()[0])
851 archiver = archival.archivers[kind](dest, mtime or ctx.date()[0])
848
852
849 if repo.ui.configbool("ui", "archivemeta", True):
853 if repo.ui.configbool("ui", "archivemeta", True):
850 def metadata():
854 def metadata():
851 base = 'repo: %s\nnode: %s\nbranch: %s\n' % (
855 base = 'repo: %s\nnode: %s\nbranch: %s\n' % (
852 hex(repo.changelog.node(0)), hex(node), ctx.branch())
856 hex(repo.changelog.node(0)), hex(node), ctx.branch())
853
857
854 tags = ''.join('tag: %s\n' % t for t in ctx.tags()
858 tags = ''.join('tag: %s\n' % t for t in ctx.tags()
855 if repo.tagtype(t) == 'global')
859 if repo.tagtype(t) == 'global')
856 if not tags:
860 if not tags:
857 repo.ui.pushbuffer()
861 repo.ui.pushbuffer()
858 opts = {'template': '{latesttag}\n{latesttagdistance}',
862 opts = {'template': '{latesttag}\n{latesttagdistance}',
859 'style': '', 'patch': None, 'git': None}
863 'style': '', 'patch': None, 'git': None}
860 cmdutil.show_changeset(repo.ui, repo, opts).show(ctx)
864 cmdutil.show_changeset(repo.ui, repo, opts).show(ctx)
861 ltags, dist = repo.ui.popbuffer().split('\n')
865 ltags, dist = repo.ui.popbuffer().split('\n')
862 tags = ''.join('latesttag: %s\n' % t for t in ltags.split(':'))
866 tags = ''.join('latesttag: %s\n' % t for t in ltags.split(':'))
863 tags += 'latesttagdistance: %s\n' % dist
867 tags += 'latesttagdistance: %s\n' % dist
864
868
865 return base + tags
869 return base + tags
866
870
867 write('.hg_archival.txt', 0644, False, metadata)
871 write('.hg_archival.txt', 0644, False, metadata)
868
872
869 for f in ctx:
873 for f in ctx:
870 ff = ctx.flags(f)
874 ff = ctx.flags(f)
871 getdata = ctx[f].data
875 getdata = ctx[f].data
872 if lfutil.isstandin(f):
876 if lfutil.isstandin(f):
873 path = lfutil.findfile(repo, getdata().strip())
877 path = lfutil.findfile(repo, getdata().strip())
874 if path is None:
878 if path is None:
875 raise util.Abort(
879 raise util.Abort(
876 _('largefile %s not found in repo store or system cache')
880 _('largefile %s not found in repo store or system cache')
877 % lfutil.splitstandin(f))
881 % lfutil.splitstandin(f))
878 f = lfutil.splitstandin(f)
882 f = lfutil.splitstandin(f)
879
883
880 def getdatafn():
884 def getdatafn():
881 fd = None
885 fd = None
882 try:
886 try:
883 fd = open(path, 'rb')
887 fd = open(path, 'rb')
884 return fd.read()
888 return fd.read()
885 finally:
889 finally:
886 if fd:
890 if fd:
887 fd.close()
891 fd.close()
888
892
889 getdata = getdatafn
893 getdata = getdatafn
890 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
894 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
891
895
892 if subrepos:
896 if subrepos:
893 for subpath in sorted(ctx.substate):
897 for subpath in sorted(ctx.substate):
894 sub = ctx.sub(subpath)
898 sub = ctx.sub(subpath)
895 submatch = match_.narrowmatcher(subpath, matchfn)
899 submatch = match_.narrowmatcher(subpath, matchfn)
896 sub.archive(archiver, prefix, submatch)
900 sub.archive(archiver, prefix, submatch)
897
901
898 archiver.done()
902 archiver.done()
899
903
900 def hgsubrepoarchive(orig, repo, archiver, prefix, match=None):
904 def hgsubrepoarchive(orig, repo, archiver, prefix, match=None):
901 repo._get(repo._state + ('hg',))
905 repo._get(repo._state + ('hg',))
902 rev = repo._state[1]
906 rev = repo._state[1]
903 ctx = repo._repo[rev]
907 ctx = repo._repo[rev]
904
908
905 lfcommands.cachelfiles(repo.ui, repo._repo, ctx.node())
909 lfcommands.cachelfiles(repo.ui, repo._repo, ctx.node())
906
910
907 def write(name, mode, islink, getdata):
911 def write(name, mode, islink, getdata):
908 # At this point, the standin has been replaced with the largefile name,
912 # At this point, the standin has been replaced with the largefile name,
909 # so the normal matcher works here without the lfutil variants.
913 # so the normal matcher works here without the lfutil variants.
910 if match and not match(f):
914 if match and not match(f):
911 return
915 return
912 data = getdata()
916 data = getdata()
913
917
914 archiver.addfile(prefix + repo._path + '/' + name, mode, islink, data)
918 archiver.addfile(prefix + repo._path + '/' + name, mode, islink, data)
915
919
916 for f in ctx:
920 for f in ctx:
917 ff = ctx.flags(f)
921 ff = ctx.flags(f)
918 getdata = ctx[f].data
922 getdata = ctx[f].data
919 if lfutil.isstandin(f):
923 if lfutil.isstandin(f):
920 path = lfutil.findfile(repo._repo, getdata().strip())
924 path = lfutil.findfile(repo._repo, getdata().strip())
921 if path is None:
925 if path is None:
922 raise util.Abort(
926 raise util.Abort(
923 _('largefile %s not found in repo store or system cache')
927 _('largefile %s not found in repo store or system cache')
924 % lfutil.splitstandin(f))
928 % lfutil.splitstandin(f))
925 f = lfutil.splitstandin(f)
929 f = lfutil.splitstandin(f)
926
930
927 def getdatafn():
931 def getdatafn():
928 fd = None
932 fd = None
929 try:
933 try:
930 fd = open(os.path.join(prefix, path), 'rb')
934 fd = open(os.path.join(prefix, path), 'rb')
931 return fd.read()
935 return fd.read()
932 finally:
936 finally:
933 if fd:
937 if fd:
934 fd.close()
938 fd.close()
935
939
936 getdata = getdatafn
940 getdata = getdatafn
937
941
938 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
942 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
939
943
940 for subpath in sorted(ctx.substate):
944 for subpath in sorted(ctx.substate):
941 sub = ctx.sub(subpath)
945 sub = ctx.sub(subpath)
942 submatch = match_.narrowmatcher(subpath, match)
946 submatch = match_.narrowmatcher(subpath, match)
943 sub.archive(archiver, os.path.join(prefix, repo._path) + '/', submatch)
947 sub.archive(archiver, os.path.join(prefix, repo._path) + '/', submatch)
944
948
945 # If a largefile is modified, the change is not reflected in its
949 # If a largefile is modified, the change is not reflected in its
946 # standin until a commit. cmdutil.bailifchanged() raises an exception
950 # standin until a commit. cmdutil.bailifchanged() raises an exception
947 # if the repo has uncommitted changes. Wrap it to also check if
951 # if the repo has uncommitted changes. Wrap it to also check if
948 # largefiles were changed. This is used by bisect, backout and fetch.
952 # largefiles were changed. This is used by bisect, backout and fetch.
949 def overridebailifchanged(orig, repo):
953 def overridebailifchanged(orig, repo):
950 orig(repo)
954 orig(repo)
951 repo.lfstatus = True
955 repo.lfstatus = True
952 s = repo.status()
956 s = repo.status()
953 repo.lfstatus = False
957 repo.lfstatus = False
954 if s.modified or s.added or s.removed or s.deleted:
958 if s.modified or s.added or s.removed or s.deleted:
955 raise util.Abort(_('uncommitted changes'))
959 raise util.Abort(_('uncommitted changes'))
956
960
957 def overrideforget(orig, ui, repo, *pats, **opts):
961 def overrideforget(orig, ui, repo, *pats, **opts):
958 installnormalfilesmatchfn(repo[None].manifest())
962 installnormalfilesmatchfn(repo[None].manifest())
959 result = orig(ui, repo, *pats, **opts)
963 result = orig(ui, repo, *pats, **opts)
960 restorematchfn()
964 restorematchfn()
961 m = composelargefilematcher(scmutil.match(repo[None], pats, opts),
965 m = composelargefilematcher(scmutil.match(repo[None], pats, opts),
962 repo[None].manifest())
966 repo[None].manifest())
963
967
964 try:
968 try:
965 repo.lfstatus = True
969 repo.lfstatus = True
966 s = repo.status(match=m, clean=True)
970 s = repo.status(match=m, clean=True)
967 finally:
971 finally:
968 repo.lfstatus = False
972 repo.lfstatus = False
969 forget = sorted(s.modified + s.added + s.deleted + s.clean)
973 forget = sorted(s.modified + s.added + s.deleted + s.clean)
970 forget = [f for f in forget if lfutil.standin(f) in repo[None].manifest()]
974 forget = [f for f in forget if lfutil.standin(f) in repo[None].manifest()]
971
975
972 for f in forget:
976 for f in forget:
973 if lfutil.standin(f) not in repo.dirstate and not \
977 if lfutil.standin(f) not in repo.dirstate and not \
974 repo.wvfs.isdir(lfutil.standin(f)):
978 repo.wvfs.isdir(lfutil.standin(f)):
975 ui.warn(_('not removing %s: file is already untracked\n')
979 ui.warn(_('not removing %s: file is already untracked\n')
976 % m.rel(f))
980 % m.rel(f))
977 result = 1
981 result = 1
978
982
979 for f in forget:
983 for f in forget:
980 if ui.verbose or not m.exact(f):
984 if ui.verbose or not m.exact(f):
981 ui.status(_('removing %s\n') % m.rel(f))
985 ui.status(_('removing %s\n') % m.rel(f))
982
986
983 # Need to lock because standin files are deleted then removed from the
987 # Need to lock because standin files are deleted then removed from the
984 # repository and we could race in-between.
988 # repository and we could race in-between.
985 wlock = repo.wlock()
989 wlock = repo.wlock()
986 try:
990 try:
987 lfdirstate = lfutil.openlfdirstate(ui, repo)
991 lfdirstate = lfutil.openlfdirstate(ui, repo)
988 for f in forget:
992 for f in forget:
989 if lfdirstate[f] == 'a':
993 if lfdirstate[f] == 'a':
990 lfdirstate.drop(f)
994 lfdirstate.drop(f)
991 else:
995 else:
992 lfdirstate.remove(f)
996 lfdirstate.remove(f)
993 lfdirstate.write()
997 lfdirstate.write()
994 standins = [lfutil.standin(f) for f in forget]
998 standins = [lfutil.standin(f) for f in forget]
995 for f in standins:
999 for f in standins:
996 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
1000 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
997 repo[None].forget(standins)
1001 repo[None].forget(standins)
998 finally:
1002 finally:
999 wlock.release()
1003 wlock.release()
1000
1004
1001 return result
1005 return result
1002
1006
1003 def _getoutgoings(repo, other, missing, addfunc):
1007 def _getoutgoings(repo, other, missing, addfunc):
1004 """get pairs of filename and largefile hash in outgoing revisions
1008 """get pairs of filename and largefile hash in outgoing revisions
1005 in 'missing'.
1009 in 'missing'.
1006
1010
1007 largefiles already existing on 'other' repository are ignored.
1011 largefiles already existing on 'other' repository are ignored.
1008
1012
1009 'addfunc' is invoked with each unique pairs of filename and
1013 'addfunc' is invoked with each unique pairs of filename and
1010 largefile hash value.
1014 largefile hash value.
1011 """
1015 """
1012 knowns = set()
1016 knowns = set()
1013 lfhashes = set()
1017 lfhashes = set()
1014 def dedup(fn, lfhash):
1018 def dedup(fn, lfhash):
1015 k = (fn, lfhash)
1019 k = (fn, lfhash)
1016 if k not in knowns:
1020 if k not in knowns:
1017 knowns.add(k)
1021 knowns.add(k)
1018 lfhashes.add(lfhash)
1022 lfhashes.add(lfhash)
1019 lfutil.getlfilestoupload(repo, missing, dedup)
1023 lfutil.getlfilestoupload(repo, missing, dedup)
1020 if lfhashes:
1024 if lfhashes:
1021 lfexists = basestore._openstore(repo, other).exists(lfhashes)
1025 lfexists = basestore._openstore(repo, other).exists(lfhashes)
1022 for fn, lfhash in knowns:
1026 for fn, lfhash in knowns:
1023 if not lfexists[lfhash]: # lfhash doesn't exist on "other"
1027 if not lfexists[lfhash]: # lfhash doesn't exist on "other"
1024 addfunc(fn, lfhash)
1028 addfunc(fn, lfhash)
1025
1029
1026 def outgoinghook(ui, repo, other, opts, missing):
1030 def outgoinghook(ui, repo, other, opts, missing):
1027 if opts.pop('large', None):
1031 if opts.pop('large', None):
1028 lfhashes = set()
1032 lfhashes = set()
1029 if ui.debugflag:
1033 if ui.debugflag:
1030 toupload = {}
1034 toupload = {}
1031 def addfunc(fn, lfhash):
1035 def addfunc(fn, lfhash):
1032 if fn not in toupload:
1036 if fn not in toupload:
1033 toupload[fn] = []
1037 toupload[fn] = []
1034 toupload[fn].append(lfhash)
1038 toupload[fn].append(lfhash)
1035 lfhashes.add(lfhash)
1039 lfhashes.add(lfhash)
1036 def showhashes(fn):
1040 def showhashes(fn):
1037 for lfhash in sorted(toupload[fn]):
1041 for lfhash in sorted(toupload[fn]):
1038 ui.debug(' %s\n' % (lfhash))
1042 ui.debug(' %s\n' % (lfhash))
1039 else:
1043 else:
1040 toupload = set()
1044 toupload = set()
1041 def addfunc(fn, lfhash):
1045 def addfunc(fn, lfhash):
1042 toupload.add(fn)
1046 toupload.add(fn)
1043 lfhashes.add(lfhash)
1047 lfhashes.add(lfhash)
1044 def showhashes(fn):
1048 def showhashes(fn):
1045 pass
1049 pass
1046 _getoutgoings(repo, other, missing, addfunc)
1050 _getoutgoings(repo, other, missing, addfunc)
1047
1051
1048 if not toupload:
1052 if not toupload:
1049 ui.status(_('largefiles: no files to upload\n'))
1053 ui.status(_('largefiles: no files to upload\n'))
1050 else:
1054 else:
1051 ui.status(_('largefiles to upload (%d entities):\n')
1055 ui.status(_('largefiles to upload (%d entities):\n')
1052 % (len(lfhashes)))
1056 % (len(lfhashes)))
1053 for file in sorted(toupload):
1057 for file in sorted(toupload):
1054 ui.status(lfutil.splitstandin(file) + '\n')
1058 ui.status(lfutil.splitstandin(file) + '\n')
1055 showhashes(file)
1059 showhashes(file)
1056 ui.status('\n')
1060 ui.status('\n')
1057
1061
1058 def summaryremotehook(ui, repo, opts, changes):
1062 def summaryremotehook(ui, repo, opts, changes):
1059 largeopt = opts.get('large', False)
1063 largeopt = opts.get('large', False)
1060 if changes is None:
1064 if changes is None:
1061 if largeopt:
1065 if largeopt:
1062 return (False, True) # only outgoing check is needed
1066 return (False, True) # only outgoing check is needed
1063 else:
1067 else:
1064 return (False, False)
1068 return (False, False)
1065 elif largeopt:
1069 elif largeopt:
1066 url, branch, peer, outgoing = changes[1]
1070 url, branch, peer, outgoing = changes[1]
1067 if peer is None:
1071 if peer is None:
1068 # i18n: column positioning for "hg summary"
1072 # i18n: column positioning for "hg summary"
1069 ui.status(_('largefiles: (no remote repo)\n'))
1073 ui.status(_('largefiles: (no remote repo)\n'))
1070 return
1074 return
1071
1075
1072 toupload = set()
1076 toupload = set()
1073 lfhashes = set()
1077 lfhashes = set()
1074 def addfunc(fn, lfhash):
1078 def addfunc(fn, lfhash):
1075 toupload.add(fn)
1079 toupload.add(fn)
1076 lfhashes.add(lfhash)
1080 lfhashes.add(lfhash)
1077 _getoutgoings(repo, peer, outgoing.missing, addfunc)
1081 _getoutgoings(repo, peer, outgoing.missing, addfunc)
1078
1082
1079 if not toupload:
1083 if not toupload:
1080 # i18n: column positioning for "hg summary"
1084 # i18n: column positioning for "hg summary"
1081 ui.status(_('largefiles: (no files to upload)\n'))
1085 ui.status(_('largefiles: (no files to upload)\n'))
1082 else:
1086 else:
1083 # i18n: column positioning for "hg summary"
1087 # i18n: column positioning for "hg summary"
1084 ui.status(_('largefiles: %d entities for %d files to upload\n')
1088 ui.status(_('largefiles: %d entities for %d files to upload\n')
1085 % (len(lfhashes), len(toupload)))
1089 % (len(lfhashes), len(toupload)))
1086
1090
1087 def overridesummary(orig, ui, repo, *pats, **opts):
1091 def overridesummary(orig, ui, repo, *pats, **opts):
1088 try:
1092 try:
1089 repo.lfstatus = True
1093 repo.lfstatus = True
1090 orig(ui, repo, *pats, **opts)
1094 orig(ui, repo, *pats, **opts)
1091 finally:
1095 finally:
1092 repo.lfstatus = False
1096 repo.lfstatus = False
1093
1097
1094 def scmutiladdremove(orig, repo, matcher, prefix, opts={}, dry_run=None,
1098 def scmutiladdremove(orig, repo, matcher, prefix, opts={}, dry_run=None,
1095 similarity=None):
1099 similarity=None):
1096 if not lfutil.islfilesrepo(repo):
1100 if not lfutil.islfilesrepo(repo):
1097 return orig(repo, matcher, prefix, opts, dry_run, similarity)
1101 return orig(repo, matcher, prefix, opts, dry_run, similarity)
1098 # Get the list of missing largefiles so we can remove them
1102 # Get the list of missing largefiles so we can remove them
1099 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
1103 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
1100 unsure, s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [],
1104 unsure, s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [],
1101 False, False, False)
1105 False, False, False)
1102
1106
1103 # Call into the normal remove code, but the removing of the standin, we want
1107 # Call into the normal remove code, but the removing of the standin, we want
1104 # to have handled by original addremove. Monkey patching here makes sure
1108 # to have handled by original addremove. Monkey patching here makes sure
1105 # we don't remove the standin in the largefiles code, preventing a very
1109 # we don't remove the standin in the largefiles code, preventing a very
1106 # confused state later.
1110 # confused state later.
1107 if s.deleted:
1111 if s.deleted:
1108 m = [repo.wjoin(f) for f in s.deleted]
1112 m = [repo.wjoin(f) for f in s.deleted]
1109 removelargefiles(repo.ui, repo, True, *m, **opts)
1113 removelargefiles(repo.ui, repo, True, *m, **opts)
1110 # Call into the normal add code, and any files that *should* be added as
1114 # Call into the normal add code, and any files that *should* be added as
1111 # largefiles will be
1115 # largefiles will be
1112 addlargefiles(repo.ui, repo, matcher, **opts)
1116 addlargefiles(repo.ui, repo, matcher, **opts)
1113 # Now that we've handled largefiles, hand off to the original addremove
1117 # Now that we've handled largefiles, hand off to the original addremove
1114 # function to take care of the rest. Make sure it doesn't do anything with
1118 # function to take care of the rest. Make sure it doesn't do anything with
1115 # largefiles by passing a matcher that will ignore them.
1119 # largefiles by passing a matcher that will ignore them.
1116 matcher = composenormalfilematcher(matcher, repo[None].manifest())
1120 matcher = composenormalfilematcher(matcher, repo[None].manifest())
1117 return orig(repo, matcher, prefix, opts, dry_run, similarity)
1121 return orig(repo, matcher, prefix, opts, dry_run, similarity)
1118
1122
1119 # Calling purge with --all will cause the largefiles to be deleted.
1123 # Calling purge with --all will cause the largefiles to be deleted.
1120 # Override repo.status to prevent this from happening.
1124 # Override repo.status to prevent this from happening.
1121 def overridepurge(orig, ui, repo, *dirs, **opts):
1125 def overridepurge(orig, ui, repo, *dirs, **opts):
1122 # XXX Monkey patching a repoview will not work. The assigned attribute will
1126 # XXX Monkey patching a repoview will not work. The assigned attribute will
1123 # be set on the unfiltered repo, but we will only lookup attributes in the
1127 # be set on the unfiltered repo, but we will only lookup attributes in the
1124 # unfiltered repo if the lookup in the repoview object itself fails. As the
1128 # unfiltered repo if the lookup in the repoview object itself fails. As the
1125 # monkey patched method exists on the repoview class the lookup will not
1129 # monkey patched method exists on the repoview class the lookup will not
1126 # fail. As a result, the original version will shadow the monkey patched
1130 # fail. As a result, the original version will shadow the monkey patched
1127 # one, defeating the monkey patch.
1131 # one, defeating the monkey patch.
1128 #
1132 #
1129 # As a work around we use an unfiltered repo here. We should do something
1133 # As a work around we use an unfiltered repo here. We should do something
1130 # cleaner instead.
1134 # cleaner instead.
1131 repo = repo.unfiltered()
1135 repo = repo.unfiltered()
1132 oldstatus = repo.status
1136 oldstatus = repo.status
1133 def overridestatus(node1='.', node2=None, match=None, ignored=False,
1137 def overridestatus(node1='.', node2=None, match=None, ignored=False,
1134 clean=False, unknown=False, listsubrepos=False):
1138 clean=False, unknown=False, listsubrepos=False):
1135 r = oldstatus(node1, node2, match, ignored, clean, unknown,
1139 r = oldstatus(node1, node2, match, ignored, clean, unknown,
1136 listsubrepos)
1140 listsubrepos)
1137 lfdirstate = lfutil.openlfdirstate(ui, repo)
1141 lfdirstate = lfutil.openlfdirstate(ui, repo)
1138 unknown = [f for f in r.unknown if lfdirstate[f] == '?']
1142 unknown = [f for f in r.unknown if lfdirstate[f] == '?']
1139 ignored = [f for f in r.ignored if lfdirstate[f] == '?']
1143 ignored = [f for f in r.ignored if lfdirstate[f] == '?']
1140 return scmutil.status(r.modified, r.added, r.removed, r.deleted,
1144 return scmutil.status(r.modified, r.added, r.removed, r.deleted,
1141 unknown, ignored, r.clean)
1145 unknown, ignored, r.clean)
1142 repo.status = overridestatus
1146 repo.status = overridestatus
1143 orig(ui, repo, *dirs, **opts)
1147 orig(ui, repo, *dirs, **opts)
1144 repo.status = oldstatus
1148 repo.status = oldstatus
1145 def overriderollback(orig, ui, repo, **opts):
1149 def overriderollback(orig, ui, repo, **opts):
1146 wlock = repo.wlock()
1150 wlock = repo.wlock()
1147 try:
1151 try:
1148 before = repo.dirstate.parents()
1152 before = repo.dirstate.parents()
1149 orphans = set(f for f in repo.dirstate
1153 orphans = set(f for f in repo.dirstate
1150 if lfutil.isstandin(f) and repo.dirstate[f] != 'r')
1154 if lfutil.isstandin(f) and repo.dirstate[f] != 'r')
1151 result = orig(ui, repo, **opts)
1155 result = orig(ui, repo, **opts)
1152 after = repo.dirstate.parents()
1156 after = repo.dirstate.parents()
1153 if before == after:
1157 if before == after:
1154 return result # no need to restore standins
1158 return result # no need to restore standins
1155
1159
1156 pctx = repo['.']
1160 pctx = repo['.']
1157 for f in repo.dirstate:
1161 for f in repo.dirstate:
1158 if lfutil.isstandin(f):
1162 if lfutil.isstandin(f):
1159 orphans.discard(f)
1163 orphans.discard(f)
1160 if repo.dirstate[f] == 'r':
1164 if repo.dirstate[f] == 'r':
1161 repo.wvfs.unlinkpath(f, ignoremissing=True)
1165 repo.wvfs.unlinkpath(f, ignoremissing=True)
1162 elif f in pctx:
1166 elif f in pctx:
1163 fctx = pctx[f]
1167 fctx = pctx[f]
1164 repo.wwrite(f, fctx.data(), fctx.flags())
1168 repo.wwrite(f, fctx.data(), fctx.flags())
1165 else:
1169 else:
1166 # content of standin is not so important in 'a',
1170 # content of standin is not so important in 'a',
1167 # 'm' or 'n' (coming from the 2nd parent) cases
1171 # 'm' or 'n' (coming from the 2nd parent) cases
1168 lfutil.writestandin(repo, f, '', False)
1172 lfutil.writestandin(repo, f, '', False)
1169 for standin in orphans:
1173 for standin in orphans:
1170 repo.wvfs.unlinkpath(standin, ignoremissing=True)
1174 repo.wvfs.unlinkpath(standin, ignoremissing=True)
1171
1175
1172 lfdirstate = lfutil.openlfdirstate(ui, repo)
1176 lfdirstate = lfutil.openlfdirstate(ui, repo)
1173 orphans = set(lfdirstate)
1177 orphans = set(lfdirstate)
1174 lfiles = lfutil.listlfiles(repo)
1178 lfiles = lfutil.listlfiles(repo)
1175 for file in lfiles:
1179 for file in lfiles:
1176 lfutil.synclfdirstate(repo, lfdirstate, file, True)
1180 lfutil.synclfdirstate(repo, lfdirstate, file, True)
1177 orphans.discard(file)
1181 orphans.discard(file)
1178 for lfile in orphans:
1182 for lfile in orphans:
1179 lfdirstate.drop(lfile)
1183 lfdirstate.drop(lfile)
1180 lfdirstate.write()
1184 lfdirstate.write()
1181 finally:
1185 finally:
1182 wlock.release()
1186 wlock.release()
1183 return result
1187 return result
1184
1188
1185 def overridetransplant(orig, ui, repo, *revs, **opts):
1189 def overridetransplant(orig, ui, repo, *revs, **opts):
1186 resuming = opts.get('continue')
1190 resuming = opts.get('continue')
1187 repo._lfcommithooks.append(lfutil.automatedcommithook(resuming))
1191 repo._lfcommithooks.append(lfutil.automatedcommithook(resuming))
1188 repo._lfstatuswriters.append(lambda *msg, **opts: None)
1192 repo._lfstatuswriters.append(lambda *msg, **opts: None)
1189 try:
1193 try:
1190 result = orig(ui, repo, *revs, **opts)
1194 result = orig(ui, repo, *revs, **opts)
1191 finally:
1195 finally:
1192 repo._lfstatuswriters.pop()
1196 repo._lfstatuswriters.pop()
1193 repo._lfcommithooks.pop()
1197 repo._lfcommithooks.pop()
1194 return result
1198 return result
1195
1199
1196 def overridecat(orig, ui, repo, file1, *pats, **opts):
1200 def overridecat(orig, ui, repo, file1, *pats, **opts):
1197 ctx = scmutil.revsingle(repo, opts.get('rev'))
1201 ctx = scmutil.revsingle(repo, opts.get('rev'))
1198 err = 1
1202 err = 1
1199 notbad = set()
1203 notbad = set()
1200 m = scmutil.match(ctx, (file1,) + pats, opts)
1204 m = scmutil.match(ctx, (file1,) + pats, opts)
1201 origmatchfn = m.matchfn
1205 origmatchfn = m.matchfn
1202 def lfmatchfn(f):
1206 def lfmatchfn(f):
1203 if origmatchfn(f):
1207 if origmatchfn(f):
1204 return True
1208 return True
1205 lf = lfutil.splitstandin(f)
1209 lf = lfutil.splitstandin(f)
1206 if lf is None:
1210 if lf is None:
1207 return False
1211 return False
1208 notbad.add(lf)
1212 notbad.add(lf)
1209 return origmatchfn(lf)
1213 return origmatchfn(lf)
1210 m.matchfn = lfmatchfn
1214 m.matchfn = lfmatchfn
1211 origbadfn = m.bad
1215 origbadfn = m.bad
1212 def lfbadfn(f, msg):
1216 def lfbadfn(f, msg):
1213 if not f in notbad:
1217 if not f in notbad:
1214 origbadfn(f, msg)
1218 origbadfn(f, msg)
1215 m.bad = lfbadfn
1219 m.bad = lfbadfn
1216 for f in ctx.walk(m):
1220 for f in ctx.walk(m):
1217 fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
1221 fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
1218 pathname=f)
1222 pathname=f)
1219 lf = lfutil.splitstandin(f)
1223 lf = lfutil.splitstandin(f)
1220 if lf is None or origmatchfn(f):
1224 if lf is None or origmatchfn(f):
1221 # duplicating unreachable code from commands.cat
1225 # duplicating unreachable code from commands.cat
1222 data = ctx[f].data()
1226 data = ctx[f].data()
1223 if opts.get('decode'):
1227 if opts.get('decode'):
1224 data = repo.wwritedata(f, data)
1228 data = repo.wwritedata(f, data)
1225 fp.write(data)
1229 fp.write(data)
1226 else:
1230 else:
1227 hash = lfutil.readstandin(repo, lf, ctx.rev())
1231 hash = lfutil.readstandin(repo, lf, ctx.rev())
1228 if not lfutil.inusercache(repo.ui, hash):
1232 if not lfutil.inusercache(repo.ui, hash):
1229 store = basestore._openstore(repo)
1233 store = basestore._openstore(repo)
1230 success, missing = store.get([(lf, hash)])
1234 success, missing = store.get([(lf, hash)])
1231 if len(success) != 1:
1235 if len(success) != 1:
1232 raise util.Abort(
1236 raise util.Abort(
1233 _('largefile %s is not in cache and could not be '
1237 _('largefile %s is not in cache and could not be '
1234 'downloaded') % lf)
1238 'downloaded') % lf)
1235 path = lfutil.usercachepath(repo.ui, hash)
1239 path = lfutil.usercachepath(repo.ui, hash)
1236 fpin = open(path, "rb")
1240 fpin = open(path, "rb")
1237 for chunk in util.filechunkiter(fpin, 128 * 1024):
1241 for chunk in util.filechunkiter(fpin, 128 * 1024):
1238 fp.write(chunk)
1242 fp.write(chunk)
1239 fpin.close()
1243 fpin.close()
1240 fp.close()
1244 fp.close()
1241 err = 0
1245 err = 0
1242 return err
1246 return err
1243
1247
1244 def mergeupdate(orig, repo, node, branchmerge, force, partial,
1248 def mergeupdate(orig, repo, node, branchmerge, force, partial,
1245 *args, **kwargs):
1249 *args, **kwargs):
1246 wlock = repo.wlock()
1250 wlock = repo.wlock()
1247 try:
1251 try:
1248 # branch | | |
1252 # branch | | |
1249 # merge | force | partial | action
1253 # merge | force | partial | action
1250 # -------+-------+---------+--------------
1254 # -------+-------+---------+--------------
1251 # x | x | x | linear-merge
1255 # x | x | x | linear-merge
1252 # o | x | x | branch-merge
1256 # o | x | x | branch-merge
1253 # x | o | x | overwrite (as clean update)
1257 # x | o | x | overwrite (as clean update)
1254 # o | o | x | force-branch-merge (*1)
1258 # o | o | x | force-branch-merge (*1)
1255 # x | x | o | (*)
1259 # x | x | o | (*)
1256 # o | x | o | (*)
1260 # o | x | o | (*)
1257 # x | o | o | overwrite (as revert)
1261 # x | o | o | overwrite (as revert)
1258 # o | o | o | (*)
1262 # o | o | o | (*)
1259 #
1263 #
1260 # (*) don't care
1264 # (*) don't care
1261 # (*1) deprecated, but used internally (e.g: "rebase --collapse")
1265 # (*1) deprecated, but used internally (e.g: "rebase --collapse")
1262
1266
1263 linearmerge = not branchmerge and not force and not partial
1267 linearmerge = not branchmerge and not force and not partial
1264
1268
1265 if linearmerge or (branchmerge and force and not partial):
1269 if linearmerge or (branchmerge and force and not partial):
1266 # update standins for linear-merge or force-branch-merge,
1270 # update standins for linear-merge or force-branch-merge,
1267 # because largefiles in the working directory may be modified
1271 # because largefiles in the working directory may be modified
1268 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
1272 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
1269 unsure, s = lfdirstate.status(match_.always(repo.root,
1273 unsure, s = lfdirstate.status(match_.always(repo.root,
1270 repo.getcwd()),
1274 repo.getcwd()),
1271 [], False, False, False)
1275 [], False, False, False)
1272 for lfile in unsure + s.modified + s.added:
1276 for lfile in unsure + s.modified + s.added:
1273 lfutil.updatestandin(repo, lfutil.standin(lfile))
1277 lfutil.updatestandin(repo, lfutil.standin(lfile))
1274
1278
1275 if linearmerge:
1279 if linearmerge:
1276 # Only call updatelfiles on the standins that have changed
1280 # Only call updatelfiles on the standins that have changed
1277 # to save time
1281 # to save time
1278 oldstandins = lfutil.getstandinsstate(repo)
1282 oldstandins = lfutil.getstandinsstate(repo)
1279
1283
1280 result = orig(repo, node, branchmerge, force, partial, *args, **kwargs)
1284 result = orig(repo, node, branchmerge, force, partial, *args, **kwargs)
1281
1285
1282 filelist = None
1286 filelist = None
1283 if linearmerge:
1287 if linearmerge:
1284 newstandins = lfutil.getstandinsstate(repo)
1288 newstandins = lfutil.getstandinsstate(repo)
1285 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
1289 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
1286
1290
1287 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
1291 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
1288 normallookup=partial)
1292 normallookup=partial)
1289
1293
1290 return result
1294 return result
1291 finally:
1295 finally:
1292 wlock.release()
1296 wlock.release()
1293
1297
1294 def scmutilmarktouched(orig, repo, files, *args, **kwargs):
1298 def scmutilmarktouched(orig, repo, files, *args, **kwargs):
1295 result = orig(repo, files, *args, **kwargs)
1299 result = orig(repo, files, *args, **kwargs)
1296
1300
1297 filelist = [lfutil.splitstandin(f) for f in files if lfutil.isstandin(f)]
1301 filelist = [lfutil.splitstandin(f) for f in files if lfutil.isstandin(f)]
1298 if filelist:
1302 if filelist:
1299 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
1303 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
1300 printmessage=False, normallookup=True)
1304 printmessage=False, normallookup=True)
1301
1305
1302 return result
1306 return result
@@ -1,647 +1,661 b''
1 This file focuses mainly on updating largefiles in the working
1 This file focuses mainly on updating largefiles in the working
2 directory (and ".hg/largefiles/dirstate")
2 directory (and ".hg/largefiles/dirstate")
3
3
4 $ cat >> $HGRCPATH <<EOF
4 $ cat >> $HGRCPATH <<EOF
5 > [ui]
5 > [ui]
6 > merge = internal:fail
6 > merge = internal:fail
7 > [extensions]
7 > [extensions]
8 > largefiles =
8 > largefiles =
9 > EOF
9 > EOF
10
10
11 $ hg init repo
11 $ hg init repo
12 $ cd repo
12 $ cd repo
13
13
14 $ echo large1 > large1
14 $ echo large1 > large1
15 $ echo large2 > large2
15 $ echo large2 > large2
16 $ hg add --large large1 large2
16 $ hg add --large large1 large2
17 $ echo normal1 > normal1
17 $ echo normal1 > normal1
18 $ hg add normal1
18 $ hg add normal1
19 $ hg commit -m '#0'
19 $ hg commit -m '#0'
20 $ echo 'large1 in #1' > large1
20 $ echo 'large1 in #1' > large1
21 $ echo 'normal1 in #1' > normal1
21 $ echo 'normal1 in #1' > normal1
22 $ hg commit -m '#1'
22 $ hg commit -m '#1'
23 $ hg update -q -C 0
23 $ hg update -q -C 0
24 $ echo 'large2 in #2' > large2
24 $ echo 'large2 in #2' > large2
25 $ hg commit -m '#2'
25 $ hg commit -m '#2'
26 created new head
26 created new head
27
27
28 Test that lfdirstate keeps track of last modification of largefiles and
29 prevents unnecessary hashing of content - also after linear/noop update
30
31 $ sleep 1
32 $ hg st
33 $ hg debugdirstate --large --nodate
34 n 644 7 large1
35 n 644 13 large2
36 $ hg up
37 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 $ hg debugdirstate --large --nodate
39 n 644 7 large1
40 n 644 13 large2
41
28 Test that "hg merge" updates largefiles from "other" correctly
42 Test that "hg merge" updates largefiles from "other" correctly
29
43
30 (getting largefiles from "other" normally)
44 (getting largefiles from "other" normally)
31
45
32 $ hg status -A large1
46 $ hg status -A large1
33 C large1
47 C large1
34 $ cat large1
48 $ cat large1
35 large1
49 large1
36 $ cat .hglf/large1
50 $ cat .hglf/large1
37 4669e532d5b2c093a78eca010077e708a071bb64
51 4669e532d5b2c093a78eca010077e708a071bb64
38 $ hg merge --config debug.dirstate.delaywrite=2
52 $ hg merge --config debug.dirstate.delaywrite=2
39 getting changed largefiles
53 getting changed largefiles
40 1 largefiles updated, 0 removed
54 1 largefiles updated, 0 removed
41 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
55 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
42 (branch merge, don't forget to commit)
56 (branch merge, don't forget to commit)
43 $ hg status -A large1
57 $ hg status -A large1
44 M large1
58 M large1
45 $ cat large1
59 $ cat large1
46 large1 in #1
60 large1 in #1
47 $ cat .hglf/large1
61 $ cat .hglf/large1
48 58e24f733a964da346e2407a2bee99d9001184f5
62 58e24f733a964da346e2407a2bee99d9001184f5
49 $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
63 $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
50 -4669e532d5b2c093a78eca010077e708a071bb64
64 -4669e532d5b2c093a78eca010077e708a071bb64
51 +58e24f733a964da346e2407a2bee99d9001184f5
65 +58e24f733a964da346e2407a2bee99d9001184f5
52
66
53 (getting largefiles from "other" via conflict prompt)
67 (getting largefiles from "other" via conflict prompt)
54
68
55 $ hg update -q -C 2
69 $ hg update -q -C 2
56 $ echo 'large1 in #3' > large1
70 $ echo 'large1 in #3' > large1
57 $ echo 'normal1 in #3' > normal1
71 $ echo 'normal1 in #3' > normal1
58 $ hg commit -m '#3'
72 $ hg commit -m '#3'
59 $ cat .hglf/large1
73 $ cat .hglf/large1
60 e5bb990443d6a92aaf7223813720f7566c9dd05b
74 e5bb990443d6a92aaf7223813720f7566c9dd05b
61 $ hg merge --config debug.dirstate.delaywrite=2 --config ui.interactive=True <<EOF
75 $ hg merge --config debug.dirstate.delaywrite=2 --config ui.interactive=True <<EOF
62 > o
76 > o
63 > EOF
77 > EOF
64 largefile large1 has a merge conflict
78 largefile large1 has a merge conflict
65 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
79 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
66 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
80 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
67 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
81 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
68 merging normal1
82 merging normal1
69 warning: conflicts during merge.
83 warning: conflicts during merge.
70 merging normal1 incomplete! (edit conflicts, then use 'hg resolve --mark')
84 merging normal1 incomplete! (edit conflicts, then use 'hg resolve --mark')
71 getting changed largefiles
85 getting changed largefiles
72 1 largefiles updated, 0 removed
86 1 largefiles updated, 0 removed
73 0 files updated, 1 files merged, 0 files removed, 1 files unresolved
87 0 files updated, 1 files merged, 0 files removed, 1 files unresolved
74 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
88 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
75 [1]
89 [1]
76 $ hg status -A large1
90 $ hg status -A large1
77 M large1
91 M large1
78 $ cat large1
92 $ cat large1
79 large1 in #1
93 large1 in #1
80 $ cat .hglf/large1
94 $ cat .hglf/large1
81 58e24f733a964da346e2407a2bee99d9001184f5
95 58e24f733a964da346e2407a2bee99d9001184f5
82
96
83 Test that "hg revert -r REV" updates largefiles from "REV" correctly
97 Test that "hg revert -r REV" updates largefiles from "REV" correctly
84
98
85 $ hg update -q -C 3
99 $ hg update -q -C 3
86 $ hg status -A large1
100 $ hg status -A large1
87 C large1
101 C large1
88 $ cat large1
102 $ cat large1
89 large1 in #3
103 large1 in #3
90 $ cat .hglf/large1
104 $ cat .hglf/large1
91 e5bb990443d6a92aaf7223813720f7566c9dd05b
105 e5bb990443d6a92aaf7223813720f7566c9dd05b
92 $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
106 $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
93 -4669e532d5b2c093a78eca010077e708a071bb64
107 -4669e532d5b2c093a78eca010077e708a071bb64
94 +58e24f733a964da346e2407a2bee99d9001184f5
108 +58e24f733a964da346e2407a2bee99d9001184f5
95 $ hg revert --no-backup -r 1 --config debug.dirstate.delaywrite=2 large1
109 $ hg revert --no-backup -r 1 --config debug.dirstate.delaywrite=2 large1
96 $ hg status -A large1
110 $ hg status -A large1
97 M large1
111 M large1
98 $ cat large1
112 $ cat large1
99 large1 in #1
113 large1 in #1
100 $ cat .hglf/large1
114 $ cat .hglf/large1
101 58e24f733a964da346e2407a2bee99d9001184f5
115 58e24f733a964da346e2407a2bee99d9001184f5
102
116
103 Test that "hg rollback" restores status of largefiles correctly
117 Test that "hg rollback" restores status of largefiles correctly
104
118
105 $ hg update -C -q
119 $ hg update -C -q
106 $ hg remove large1
120 $ hg remove large1
107 $ test -f .hglf/large1
121 $ test -f .hglf/large1
108 [1]
122 [1]
109 $ hg forget large2
123 $ hg forget large2
110 $ test -f .hglf/large2
124 $ test -f .hglf/large2
111 [1]
125 [1]
112 $ echo largeX > largeX
126 $ echo largeX > largeX
113 $ hg add --large largeX
127 $ hg add --large largeX
114 $ cat .hglf/largeX
128 $ cat .hglf/largeX
115
129
116 $ hg commit -m 'will be rollback-ed soon'
130 $ hg commit -m 'will be rollback-ed soon'
117 $ echo largeY > largeY
131 $ echo largeY > largeY
118 $ hg add --large largeY
132 $ hg add --large largeY
119 #if windows
133 #if windows
120 $ hg status -A large1
134 $ hg status -A large1
121 large1: * (glob)
135 large1: * (glob)
122 #else
136 #else
123 $ hg status -A large1
137 $ hg status -A large1
124 large1: No such file or directory
138 large1: No such file or directory
125 #endif
139 #endif
126 $ hg status -A large2
140 $ hg status -A large2
127 ? large2
141 ? large2
128 $ hg status -A largeX
142 $ hg status -A largeX
129 C largeX
143 C largeX
130 $ hg status -A largeY
144 $ hg status -A largeY
131 A largeY
145 A largeY
132 $ hg rollback
146 $ hg rollback
133 repository tip rolled back to revision 3 (undo commit)
147 repository tip rolled back to revision 3 (undo commit)
134 working directory now based on revision 3
148 working directory now based on revision 3
135 $ hg status -A large1
149 $ hg status -A large1
136 R large1
150 R large1
137 $ test -f .hglf/large1
151 $ test -f .hglf/large1
138 [1]
152 [1]
139 $ hg status -A large2
153 $ hg status -A large2
140 R large2
154 R large2
141 $ test -f .hglf/large2
155 $ test -f .hglf/large2
142 [1]
156 [1]
143 $ hg status -A largeX
157 $ hg status -A largeX
144 A largeX
158 A largeX
145 $ cat .hglf/largeX
159 $ cat .hglf/largeX
146
160
147 $ hg status -A largeY
161 $ hg status -A largeY
148 ? largeY
162 ? largeY
149 $ test -f .hglf/largeY
163 $ test -f .hglf/largeY
150 [1]
164 [1]
151
165
152 Test that "hg rollback" restores standins correctly
166 Test that "hg rollback" restores standins correctly
153
167
154 $ hg commit -m 'will be rollback-ed soon'
168 $ hg commit -m 'will be rollback-ed soon'
155 $ hg update -q -C 2
169 $ hg update -q -C 2
156 $ cat large1
170 $ cat large1
157 large1
171 large1
158 $ cat .hglf/large1
172 $ cat .hglf/large1
159 4669e532d5b2c093a78eca010077e708a071bb64
173 4669e532d5b2c093a78eca010077e708a071bb64
160 $ cat large2
174 $ cat large2
161 large2 in #2
175 large2 in #2
162 $ cat .hglf/large2
176 $ cat .hglf/large2
163 3cfce6277e7668985707b6887ce56f9f62f6ccd9
177 3cfce6277e7668985707b6887ce56f9f62f6ccd9
164
178
165 $ hg rollback -q -f
179 $ hg rollback -q -f
166 $ cat large1
180 $ cat large1
167 large1
181 large1
168 $ cat .hglf/large1
182 $ cat .hglf/large1
169 4669e532d5b2c093a78eca010077e708a071bb64
183 4669e532d5b2c093a78eca010077e708a071bb64
170 $ cat large2
184 $ cat large2
171 large2 in #2
185 large2 in #2
172 $ cat .hglf/large2
186 $ cat .hglf/large2
173 3cfce6277e7668985707b6887ce56f9f62f6ccd9
187 3cfce6277e7668985707b6887ce56f9f62f6ccd9
174
188
175 (rollback the parent of the working directory, when the parent of it
189 (rollback the parent of the working directory, when the parent of it
176 is not branch-tip)
190 is not branch-tip)
177
191
178 $ hg update -q -C 1
192 $ hg update -q -C 1
179 $ cat .hglf/large1
193 $ cat .hglf/large1
180 58e24f733a964da346e2407a2bee99d9001184f5
194 58e24f733a964da346e2407a2bee99d9001184f5
181 $ cat .hglf/large2
195 $ cat .hglf/large2
182 1deebade43c8c498a3c8daddac0244dc55d1331d
196 1deebade43c8c498a3c8daddac0244dc55d1331d
183
197
184 $ echo normalX > normalX
198 $ echo normalX > normalX
185 $ hg add normalX
199 $ hg add normalX
186 $ hg commit -m 'will be rollback-ed soon'
200 $ hg commit -m 'will be rollback-ed soon'
187 $ hg rollback -q
201 $ hg rollback -q
188
202
189 $ cat .hglf/large1
203 $ cat .hglf/large1
190 58e24f733a964da346e2407a2bee99d9001184f5
204 58e24f733a964da346e2407a2bee99d9001184f5
191 $ cat .hglf/large2
205 $ cat .hglf/large2
192 1deebade43c8c498a3c8daddac0244dc55d1331d
206 1deebade43c8c498a3c8daddac0244dc55d1331d
193
207
194 Test that "hg status" shows status of largefiles correctly just after
208 Test that "hg status" shows status of largefiles correctly just after
195 automated commit like rebase/transplant
209 automated commit like rebase/transplant
196
210
197 $ cat >> .hg/hgrc <<EOF
211 $ cat >> .hg/hgrc <<EOF
198 > [extensions]
212 > [extensions]
199 > rebase =
213 > rebase =
200 > strip =
214 > strip =
201 > transplant =
215 > transplant =
202 > EOF
216 > EOF
203 $ hg update -q -C 1
217 $ hg update -q -C 1
204 $ hg remove large1
218 $ hg remove large1
205 $ echo largeX > largeX
219 $ echo largeX > largeX
206 $ hg add --large largeX
220 $ hg add --large largeX
207 $ hg commit -m '#4'
221 $ hg commit -m '#4'
208
222
209 $ hg rebase -s 1 -d 2 --keep
223 $ hg rebase -s 1 -d 2 --keep
210 rebasing 1:72518492caa6 "#1"
224 rebasing 1:72518492caa6 "#1"
211 rebasing 4:07d6153b5c04 "#4" (tip)
225 rebasing 4:07d6153b5c04 "#4" (tip)
212 #if windows
226 #if windows
213 $ hg status -A large1
227 $ hg status -A large1
214 large1: * (glob)
228 large1: * (glob)
215 #else
229 #else
216 $ hg status -A large1
230 $ hg status -A large1
217 large1: No such file or directory
231 large1: No such file or directory
218 #endif
232 #endif
219 $ hg status -A largeX
233 $ hg status -A largeX
220 C largeX
234 C largeX
221 $ hg strip -q 5
235 $ hg strip -q 5
222
236
223 $ hg update -q -C 2
237 $ hg update -q -C 2
224 $ hg transplant -q 1 4
238 $ hg transplant -q 1 4
225 #if windows
239 #if windows
226 $ hg status -A large1
240 $ hg status -A large1
227 large1: * (glob)
241 large1: * (glob)
228 #else
242 #else
229 $ hg status -A large1
243 $ hg status -A large1
230 large1: No such file or directory
244 large1: No such file or directory
231 #endif
245 #endif
232 $ hg status -A largeX
246 $ hg status -A largeX
233 C largeX
247 C largeX
234 $ hg strip -q 5
248 $ hg strip -q 5
235
249
236 $ hg update -q -C 2
250 $ hg update -q -C 2
237 $ hg transplant -q --merge 1 --merge 4
251 $ hg transplant -q --merge 1 --merge 4
238 #if windows
252 #if windows
239 $ hg status -A large1
253 $ hg status -A large1
240 large1: * (glob)
254 large1: * (glob)
241 #else
255 #else
242 $ hg status -A large1
256 $ hg status -A large1
243 large1: No such file or directory
257 large1: No such file or directory
244 #endif
258 #endif
245 $ hg status -A largeX
259 $ hg status -A largeX
246 C largeX
260 C largeX
247 $ hg strip -q 5
261 $ hg strip -q 5
248
262
249 Test that linear merge can detect modification (and conflict) correctly
263 Test that linear merge can detect modification (and conflict) correctly
250
264
251 (linear merge without conflict)
265 (linear merge without conflict)
252
266
253 $ echo 'large2 for linear merge (no conflict)' > large2
267 $ echo 'large2 for linear merge (no conflict)' > large2
254 $ hg update 3 --config debug.dirstate.delaywrite=2
268 $ hg update 3 --config debug.dirstate.delaywrite=2
255 getting changed largefiles
269 getting changed largefiles
256 1 largefiles updated, 0 removed
270 1 largefiles updated, 0 removed
257 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
271 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
258 $ hg status -A large2
272 $ hg status -A large2
259 M large2
273 M large2
260 $ cat large2
274 $ cat large2
261 large2 for linear merge (no conflict)
275 large2 for linear merge (no conflict)
262 $ cat .hglf/large2
276 $ cat .hglf/large2
263 9c4bf8f1b33536d6e5f89447e10620cfe52ea710
277 9c4bf8f1b33536d6e5f89447e10620cfe52ea710
264
278
265 (linear merge with conflict, choosing "other")
279 (linear merge with conflict, choosing "other")
266
280
267 $ hg update -q -C 2
281 $ hg update -q -C 2
268 $ echo 'large1 for linear merge (conflict)' > large1
282 $ echo 'large1 for linear merge (conflict)' > large1
269 $ hg update 3 --config ui.interactive=True <<EOF
283 $ hg update 3 --config ui.interactive=True <<EOF
270 > o
284 > o
271 > EOF
285 > EOF
272 largefile large1 has a merge conflict
286 largefile large1 has a merge conflict
273 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
287 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
274 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
288 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
275 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? o
289 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? o
276 getting changed largefiles
290 getting changed largefiles
277 1 largefiles updated, 0 removed
291 1 largefiles updated, 0 removed
278 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
292 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
279 $ hg status -A large1
293 $ hg status -A large1
280 C large1
294 C large1
281 $ cat large1
295 $ cat large1
282 large1 in #3
296 large1 in #3
283 $ cat .hglf/large1
297 $ cat .hglf/large1
284 e5bb990443d6a92aaf7223813720f7566c9dd05b
298 e5bb990443d6a92aaf7223813720f7566c9dd05b
285
299
286 (linear merge with conflict, choosing "local")
300 (linear merge with conflict, choosing "local")
287
301
288 $ hg update -q -C 2
302 $ hg update -q -C 2
289 $ echo 'large1 for linear merge (conflict)' > large1
303 $ echo 'large1 for linear merge (conflict)' > large1
290 $ hg update 3 --config debug.dirstate.delaywrite=2
304 $ hg update 3 --config debug.dirstate.delaywrite=2
291 largefile large1 has a merge conflict
305 largefile large1 has a merge conflict
292 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
306 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
293 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
307 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
294 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
308 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
295 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
309 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
296 $ hg status -A large1
310 $ hg status -A large1
297 M large1
311 M large1
298 $ cat large1
312 $ cat large1
299 large1 for linear merge (conflict)
313 large1 for linear merge (conflict)
300 $ cat .hglf/large1
314 $ cat .hglf/large1
301 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
315 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
302
316
303 Test a linear merge to a revision containing same-name normal file
317 Test a linear merge to a revision containing same-name normal file
304
318
305 $ hg update -q -C 3
319 $ hg update -q -C 3
306 $ hg remove large2
320 $ hg remove large2
307 $ echo 'large2 as normal file' > large2
321 $ echo 'large2 as normal file' > large2
308 $ hg add large2
322 $ hg add large2
309 $ echo 'large3 as normal file' > large3
323 $ echo 'large3 as normal file' > large3
310 $ hg add large3
324 $ hg add large3
311 $ hg commit -m '#5'
325 $ hg commit -m '#5'
312 $ hg manifest
326 $ hg manifest
313 .hglf/large1
327 .hglf/large1
314 large2
328 large2
315 large3
329 large3
316 normal1
330 normal1
317
331
318 (modified largefile is already switched to normal)
332 (modified largefile is already switched to normal)
319
333
320 $ hg update -q -C 2
334 $ hg update -q -C 2
321 $ echo 'modified large2 for linear merge' > large2
335 $ echo 'modified large2 for linear merge' > large2
322 $ hg update -q 5
336 $ hg update -q 5
323 remote turned local largefile large2 into a normal file
337 remote turned local largefile large2 into a normal file
324 keep (l)argefile or use (n)ormal file? l
338 keep (l)argefile or use (n)ormal file? l
325 $ hg debugdirstate --nodates | grep large2
339 $ hg debugdirstate --nodates | grep large2
326 a 0 -1 .hglf/large2
340 a 0 -1 .hglf/large2
327 r 0 0 large2
341 r 0 0 large2
328 $ hg status -A large2
342 $ hg status -A large2
329 A large2
343 A large2
330 $ cat large2
344 $ cat large2
331 modified large2 for linear merge
345 modified large2 for linear merge
332
346
333 (added largefile is already committed as normal)
347 (added largefile is already committed as normal)
334
348
335 $ hg update -q -C 2
349 $ hg update -q -C 2
336 $ echo 'large3 as large file for linear merge' > large3
350 $ echo 'large3 as large file for linear merge' > large3
337 $ hg add --large large3
351 $ hg add --large large3
338 $ hg update -q 5
352 $ hg update -q 5
339 remote turned local largefile large3 into a normal file
353 remote turned local largefile large3 into a normal file
340 keep (l)argefile or use (n)ormal file? l
354 keep (l)argefile or use (n)ormal file? l
341 $ hg debugdirstate --nodates | grep large3
355 $ hg debugdirstate --nodates | grep large3
342 a 0 -1 .hglf/large3
356 a 0 -1 .hglf/large3
343 r 0 0 large3
357 r 0 0 large3
344 $ hg status -A large3
358 $ hg status -A large3
345 A large3
359 A large3
346 $ cat large3
360 $ cat large3
347 large3 as large file for linear merge
361 large3 as large file for linear merge
348 $ rm -f large3 .hglf/large3
362 $ rm -f large3 .hglf/large3
349
363
350 Test that the internal linear merging works correctly
364 Test that the internal linear merging works correctly
351 (both heads are stripped to keep pairing of revision number and commit log)
365 (both heads are stripped to keep pairing of revision number and commit log)
352
366
353 $ hg update -q -C 2
367 $ hg update -q -C 2
354 $ hg strip 3 4
368 $ hg strip 3 4
355 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/9530e27857f7-backup.hg (glob)
369 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/9530e27857f7-backup.hg (glob)
356 $ mv .hg/strip-backup/9530e27857f7-backup.hg $TESTTMP
370 $ mv .hg/strip-backup/9530e27857f7-backup.hg $TESTTMP
357
371
358 (internal linear merging at "hg pull --update")
372 (internal linear merging at "hg pull --update")
359
373
360 $ echo 'large1 for linear merge (conflict)' > large1
374 $ echo 'large1 for linear merge (conflict)' > large1
361 $ echo 'large2 for linear merge (conflict with normal file)' > large2
375 $ echo 'large2 for linear merge (conflict with normal file)' > large2
362 $ hg pull --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-backup.hg
376 $ hg pull --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-backup.hg
363 pulling from $TESTTMP/9530e27857f7-backup.hg (glob)
377 pulling from $TESTTMP/9530e27857f7-backup.hg (glob)
364 searching for changes
378 searching for changes
365 adding changesets
379 adding changesets
366 adding manifests
380 adding manifests
367 adding file changes
381 adding file changes
368 added 3 changesets with 5 changes to 5 files
382 added 3 changesets with 5 changes to 5 files
369 remote turned local largefile large2 into a normal file
383 remote turned local largefile large2 into a normal file
370 keep (l)argefile or use (n)ormal file? l
384 keep (l)argefile or use (n)ormal file? l
371 largefile large1 has a merge conflict
385 largefile large1 has a merge conflict
372 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
386 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
373 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
387 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
374 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
388 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
375 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
389 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
376
390
377 $ hg status -A large1
391 $ hg status -A large1
378 M large1
392 M large1
379 $ cat large1
393 $ cat large1
380 large1 for linear merge (conflict)
394 large1 for linear merge (conflict)
381 $ cat .hglf/large1
395 $ cat .hglf/large1
382 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
396 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
383 $ hg status -A large2
397 $ hg status -A large2
384 A large2
398 A large2
385 $ cat large2
399 $ cat large2
386 large2 for linear merge (conflict with normal file)
400 large2 for linear merge (conflict with normal file)
387 $ cat .hglf/large2
401 $ cat .hglf/large2
388 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
402 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
389
403
390 (internal linear merging at "hg unbundle --update")
404 (internal linear merging at "hg unbundle --update")
391
405
392 $ hg update -q -C 2
406 $ hg update -q -C 2
393 $ hg rollback -q
407 $ hg rollback -q
394
408
395 $ echo 'large1 for linear merge (conflict)' > large1
409 $ echo 'large1 for linear merge (conflict)' > large1
396 $ echo 'large2 for linear merge (conflict with normal file)' > large2
410 $ echo 'large2 for linear merge (conflict with normal file)' > large2
397 $ hg unbundle --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-backup.hg
411 $ hg unbundle --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-backup.hg
398 adding changesets
412 adding changesets
399 adding manifests
413 adding manifests
400 adding file changes
414 adding file changes
401 added 3 changesets with 5 changes to 5 files
415 added 3 changesets with 5 changes to 5 files
402 remote turned local largefile large2 into a normal file
416 remote turned local largefile large2 into a normal file
403 keep (l)argefile or use (n)ormal file? l
417 keep (l)argefile or use (n)ormal file? l
404 largefile large1 has a merge conflict
418 largefile large1 has a merge conflict
405 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
419 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
406 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
420 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
407 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
421 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
408 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
422 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
409
423
410 $ hg status -A large1
424 $ hg status -A large1
411 M large1
425 M large1
412 $ cat large1
426 $ cat large1
413 large1 for linear merge (conflict)
427 large1 for linear merge (conflict)
414 $ cat .hglf/large1
428 $ cat .hglf/large1
415 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
429 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
416 $ hg status -A large2
430 $ hg status -A large2
417 A large2
431 A large2
418 $ cat large2
432 $ cat large2
419 large2 for linear merge (conflict with normal file)
433 large2 for linear merge (conflict with normal file)
420 $ cat .hglf/large2
434 $ cat .hglf/large2
421 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
435 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
422
436
423 (internal linear merging in subrepo at "hg update")
437 (internal linear merging in subrepo at "hg update")
424
438
425 $ cd ..
439 $ cd ..
426 $ hg init subparent
440 $ hg init subparent
427 $ cd subparent
441 $ cd subparent
428
442
429 $ hg clone -q -u 2 ../repo sub
443 $ hg clone -q -u 2 ../repo sub
430 $ cat > .hgsub <<EOF
444 $ cat > .hgsub <<EOF
431 > sub = sub
445 > sub = sub
432 > EOF
446 > EOF
433 $ hg add .hgsub
447 $ hg add .hgsub
434 $ hg commit -m '#0@parent'
448 $ hg commit -m '#0@parent'
435 $ cat .hgsubstate
449 $ cat .hgsubstate
436 f74e50bd9e5594b7cf1e6c5cbab86ddd25f3ca2f sub
450 f74e50bd9e5594b7cf1e6c5cbab86ddd25f3ca2f sub
437 $ hg -R sub update -q
451 $ hg -R sub update -q
438 $ hg commit -m '#1@parent'
452 $ hg commit -m '#1@parent'
439 $ cat .hgsubstate
453 $ cat .hgsubstate
440 d65e59e952a9638e2ce863b41a420ca723dd3e8d sub
454 d65e59e952a9638e2ce863b41a420ca723dd3e8d sub
441 $ hg update -q 0
455 $ hg update -q 0
442
456
443 $ echo 'large1 for linear merge (conflict)' > sub/large1
457 $ echo 'large1 for linear merge (conflict)' > sub/large1
444 $ echo 'large2 for linear merge (conflict with normal file)' > sub/large2
458 $ echo 'large2 for linear merge (conflict with normal file)' > sub/large2
445 $ hg update --config ui.interactive=True --config debug.dirstate.delaywrite=2 <<EOF
459 $ hg update --config ui.interactive=True --config debug.dirstate.delaywrite=2 <<EOF
446 > m
460 > m
447 > r
461 > r
448 > l
462 > l
449 > l
463 > l
450 > EOF
464 > EOF
451 subrepository sub diverged (local revision: f74e50bd9e55, remote revision: d65e59e952a9)
465 subrepository sub diverged (local revision: f74e50bd9e55, remote revision: d65e59e952a9)
452 (M)erge, keep (l)ocal or keep (r)emote? m
466 (M)erge, keep (l)ocal or keep (r)emote? m
453 subrepository sources for sub differ (in checked out version)
467 subrepository sources for sub differ (in checked out version)
454 use (l)ocal source (f74e50bd9e55) or (r)emote source (d65e59e952a9)? r
468 use (l)ocal source (f74e50bd9e55) or (r)emote source (d65e59e952a9)? r
455 remote turned local largefile large2 into a normal file
469 remote turned local largefile large2 into a normal file
456 keep (l)argefile or use (n)ormal file? l
470 keep (l)argefile or use (n)ormal file? l
457 largefile large1 has a merge conflict
471 largefile large1 has a merge conflict
458 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
472 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
459 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
473 keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or
460 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
474 take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l
461 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
475 2 files updated, 1 files merged, 0 files removed, 0 files unresolved
462 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
476 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
463
477
464 $ hg -R sub status -A sub/large1
478 $ hg -R sub status -A sub/large1
465 M sub/large1
479 M sub/large1
466 $ cat sub/large1
480 $ cat sub/large1
467 large1 for linear merge (conflict)
481 large1 for linear merge (conflict)
468 $ cat sub/.hglf/large1
482 $ cat sub/.hglf/large1
469 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
483 ba94c2efe5b7c5e0af8d189295ce00553b0612b7
470 $ hg -R sub status -A sub/large2
484 $ hg -R sub status -A sub/large2
471 A sub/large2
485 A sub/large2
472 $ cat sub/large2
486 $ cat sub/large2
473 large2 for linear merge (conflict with normal file)
487 large2 for linear merge (conflict with normal file)
474 $ cat sub/.hglf/large2
488 $ cat sub/.hglf/large2
475 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
489 d7591fe9be0f6227d90bddf3e4f52ff41fc1f544
476
490
477 $ cd ..
491 $ cd ..
478 $ cd repo
492 $ cd repo
479
493
480 Test that rebase updates largefiles in the working directory even if
494 Test that rebase updates largefiles in the working directory even if
481 it is aborted by conflict.
495 it is aborted by conflict.
482
496
483 $ hg update -q -C 3
497 $ hg update -q -C 3
484 $ cat .hglf/large1
498 $ cat .hglf/large1
485 e5bb990443d6a92aaf7223813720f7566c9dd05b
499 e5bb990443d6a92aaf7223813720f7566c9dd05b
486 $ cat large1
500 $ cat large1
487 large1 in #3
501 large1 in #3
488 $ hg rebase -s 1 -d 3 --keep --config ui.interactive=True <<EOF
502 $ hg rebase -s 1 -d 3 --keep --config ui.interactive=True <<EOF
489 > o
503 > o
490 > EOF
504 > EOF
491 rebasing 1:72518492caa6 "#1"
505 rebasing 1:72518492caa6 "#1"
492 largefile large1 has a merge conflict
506 largefile large1 has a merge conflict
493 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
507 ancestor was 4669e532d5b2c093a78eca010077e708a071bb64
494 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
508 keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or
495 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
509 take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o
496 merging normal1
510 merging normal1
497 warning: conflicts during merge.
511 warning: conflicts during merge.
498 merging normal1 incomplete! (edit conflicts, then use 'hg resolve --mark')
512 merging normal1 incomplete! (edit conflicts, then use 'hg resolve --mark')
499 unresolved conflicts (see hg resolve, then hg rebase --continue)
513 unresolved conflicts (see hg resolve, then hg rebase --continue)
500 [1]
514 [1]
501 $ cat .hglf/large1
515 $ cat .hglf/large1
502 58e24f733a964da346e2407a2bee99d9001184f5
516 58e24f733a964da346e2407a2bee99d9001184f5
503 $ cat large1
517 $ cat large1
504 large1 in #1
518 large1 in #1
505
519
506 Test that rebase updates standins for manually modified largefiles at
520 Test that rebase updates standins for manually modified largefiles at
507 the 1st commit of resuming.
521 the 1st commit of resuming.
508
522
509 $ echo "manually modified before 'hg rebase --continue'" > large1
523 $ echo "manually modified before 'hg rebase --continue'" > large1
510 $ hg resolve -m normal1
524 $ hg resolve -m normal1
511 (no more unresolved files)
525 (no more unresolved files)
512 $ hg rebase --continue --config ui.interactive=True <<EOF
526 $ hg rebase --continue --config ui.interactive=True <<EOF
513 > c
527 > c
514 > EOF
528 > EOF
515 rebasing 1:72518492caa6 "#1"
529 rebasing 1:72518492caa6 "#1"
516 rebasing 4:07d6153b5c04 "#4"
530 rebasing 4:07d6153b5c04 "#4"
517 local changed .hglf/large1 which remote deleted
531 local changed .hglf/large1 which remote deleted
518 use (c)hanged version or (d)elete? c
532 use (c)hanged version or (d)elete? c
519
533
520 $ hg diff -c "tip~1" --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
534 $ hg diff -c "tip~1" --nodates .hglf/large1 | grep '^[+-][0-9a-z]'
521 -e5bb990443d6a92aaf7223813720f7566c9dd05b
535 -e5bb990443d6a92aaf7223813720f7566c9dd05b
522 +8a4f783556e7dea21139ca0466eafce954c75c13
536 +8a4f783556e7dea21139ca0466eafce954c75c13
523 $ rm -f large1
537 $ rm -f large1
524 $ hg update -q -C tip
538 $ hg update -q -C tip
525 $ cat large1
539 $ cat large1
526 manually modified before 'hg rebase --continue'
540 manually modified before 'hg rebase --continue'
527
541
528 Test that transplant updates largefiles, of which standins are safely
542 Test that transplant updates largefiles, of which standins are safely
529 changed, even if it is aborted by conflict of other.
543 changed, even if it is aborted by conflict of other.
530
544
531 $ hg update -q -C 5
545 $ hg update -q -C 5
532 $ cat .hglf/large1
546 $ cat .hglf/large1
533 e5bb990443d6a92aaf7223813720f7566c9dd05b
547 e5bb990443d6a92aaf7223813720f7566c9dd05b
534 $ cat large1
548 $ cat large1
535 large1 in #3
549 large1 in #3
536 $ hg diff -c 4 .hglf/largeX | grep '^[+-][0-9a-z]'
550 $ hg diff -c 4 .hglf/largeX | grep '^[+-][0-9a-z]'
537 +fa44618ea25181aff4f48b70428294790cec9f61
551 +fa44618ea25181aff4f48b70428294790cec9f61
538 $ hg transplant 4
552 $ hg transplant 4
539 applying 07d6153b5c04
553 applying 07d6153b5c04
540 patching file .hglf/large1
554 patching file .hglf/large1
541 Hunk #1 FAILED at 0
555 Hunk #1 FAILED at 0
542 1 out of 1 hunks FAILED -- saving rejects to file .hglf/large1.rej
556 1 out of 1 hunks FAILED -- saving rejects to file .hglf/large1.rej
543 patch failed to apply
557 patch failed to apply
544 abort: fix up the merge and run hg transplant --continue
558 abort: fix up the merge and run hg transplant --continue
545 [255]
559 [255]
546 $ hg status -A large1
560 $ hg status -A large1
547 C large1
561 C large1
548 $ cat .hglf/large1
562 $ cat .hglf/large1
549 e5bb990443d6a92aaf7223813720f7566c9dd05b
563 e5bb990443d6a92aaf7223813720f7566c9dd05b
550 $ cat large1
564 $ cat large1
551 large1 in #3
565 large1 in #3
552 $ hg status -A largeX
566 $ hg status -A largeX
553 A largeX
567 A largeX
554 $ cat .hglf/largeX
568 $ cat .hglf/largeX
555 fa44618ea25181aff4f48b70428294790cec9f61
569 fa44618ea25181aff4f48b70428294790cec9f61
556 $ cat largeX
570 $ cat largeX
557 largeX
571 largeX
558
572
559 Test that transplant updates standins for manually modified largefiles
573 Test that transplant updates standins for manually modified largefiles
560 at the 1st commit of resuming.
574 at the 1st commit of resuming.
561
575
562 $ echo "manually modified before 'hg transplant --continue'" > large1
576 $ echo "manually modified before 'hg transplant --continue'" > large1
563 $ hg transplant --continue
577 $ hg transplant --continue
564 07d6153b5c04 transplanted as f1bf30eb88cc
578 07d6153b5c04 transplanted as f1bf30eb88cc
565 $ hg diff -c tip .hglf/large1 | grep '^[+-][0-9a-z]'
579 $ hg diff -c tip .hglf/large1 | grep '^[+-][0-9a-z]'
566 -e5bb990443d6a92aaf7223813720f7566c9dd05b
580 -e5bb990443d6a92aaf7223813720f7566c9dd05b
567 +6a4f36d4075fbe0f30ec1d26ca44e63c05903671
581 +6a4f36d4075fbe0f30ec1d26ca44e63c05903671
568 $ rm -f large1
582 $ rm -f large1
569 $ hg update -q -C tip
583 $ hg update -q -C tip
570 $ cat large1
584 $ cat large1
571 manually modified before 'hg transplant --continue'
585 manually modified before 'hg transplant --continue'
572
586
573 Test that "hg status" doesn't show removal of largefiles not managed
587 Test that "hg status" doesn't show removal of largefiles not managed
574 in the target context.
588 in the target context.
575
589
576 $ hg update -q -C 4
590 $ hg update -q -C 4
577 $ hg remove largeX
591 $ hg remove largeX
578 $ hg status -A largeX
592 $ hg status -A largeX
579 R largeX
593 R largeX
580 $ hg status -A --rev '.^1' largeX
594 $ hg status -A --rev '.^1' largeX
581
595
582 #if execbit
596 #if execbit
583
597
584 Test that "hg status" against revisions other than parent notices exec
598 Test that "hg status" against revisions other than parent notices exec
585 bit changes of largefiles.
599 bit changes of largefiles.
586
600
587 $ hg update -q -C 4
601 $ hg update -q -C 4
588
602
589 (the case that large2 doesn't have exec bit in the target context but
603 (the case that large2 doesn't have exec bit in the target context but
590 in the working context)
604 in the working context)
591
605
592 $ chmod +x large2
606 $ chmod +x large2
593 $ hg status -A --rev 0 large2
607 $ hg status -A --rev 0 large2
594 M large2
608 M large2
595 $ hg commit -m 'chmod +x large2'
609 $ hg commit -m 'chmod +x large2'
596
610
597 (the case that large2 has exec bit in the target context but not in
611 (the case that large2 has exec bit in the target context but not in
598 the working context)
612 the working context)
599
613
600 $ echo dummy > dummy
614 $ echo dummy > dummy
601 $ hg add dummy
615 $ hg add dummy
602 $ hg commit -m 'revision for separation'
616 $ hg commit -m 'revision for separation'
603 $ chmod -x large2
617 $ chmod -x large2
604 $ hg status -A --rev '.^1' large2
618 $ hg status -A --rev '.^1' large2
605 M large2
619 M large2
606
620
607 #else
621 #else
608
622
609 Test that "hg status" against revisions other than parent ignores exec
623 Test that "hg status" against revisions other than parent ignores exec
610 bit correctly on the platform being unaware of it.
624 bit correctly on the platform being unaware of it.
611
625
612 $ hg update -q -C 4
626 $ hg update -q -C 4
613
627
614 $ cat > exec-bit.patch <<EOF
628 $ cat > exec-bit.patch <<EOF
615 > # HG changeset patch
629 > # HG changeset patch
616 > # User test
630 > # User test
617 > # Date 0 0
631 > # Date 0 0
618 > # Thu Jan 01 00:00:00 1970 +0000
632 > # Thu Jan 01 00:00:00 1970 +0000
619 > # Node ID be1b433a65b12b27b5519d92213e14f7e1769b90
633 > # Node ID be1b433a65b12b27b5519d92213e14f7e1769b90
620 > # Parent 07d6153b5c04313efb75deec9ba577de7faeb727
634 > # Parent 07d6153b5c04313efb75deec9ba577de7faeb727
621 > chmod +x large2
635 > chmod +x large2
622 >
636 >
623 > diff --git a/.hglf/large2 b/.hglf/large2
637 > diff --git a/.hglf/large2 b/.hglf/large2
624 > old mode 100644
638 > old mode 100644
625 > new mode 100755
639 > new mode 100755
626 > EOF
640 > EOF
627 $ hg import --exact --bypass exec-bit.patch
641 $ hg import --exact --bypass exec-bit.patch
628 applying exec-bit.patch
642 applying exec-bit.patch
629 $ hg status -A --rev tip large2
643 $ hg status -A --rev tip large2
630 C large2
644 C large2
631
645
632 #endif
646 #endif
633
647
634 $ cd ..
648 $ cd ..
635
649
636 Test that "hg convert" avoids copying largefiles from the working
650 Test that "hg convert" avoids copying largefiles from the working
637 directory into store, because "hg convert" doesn't update largefiles
651 directory into store, because "hg convert" doesn't update largefiles
638 in the working directory (removing files under ".cache/largefiles"
652 in the working directory (removing files under ".cache/largefiles"
639 forces "hg convert" to copy corresponding largefiles)
653 forces "hg convert" to copy corresponding largefiles)
640
654
641 $ cat >> $HGRCPATH <<EOF
655 $ cat >> $HGRCPATH <<EOF
642 > [extensions]
656 > [extensions]
643 > convert =
657 > convert =
644 > EOF
658 > EOF
645
659
646 $ rm $TESTTMP/.cache/largefiles/6a4f36d4075fbe0f30ec1d26ca44e63c05903671
660 $ rm $TESTTMP/.cache/largefiles/6a4f36d4075fbe0f30ec1d26ca44e63c05903671
647 $ hg convert -q repo repo.converted
661 $ hg convert -q repo repo.converted
General Comments 0
You need to be logged in to leave comments. Login now