##// END OF EJS Templates
Merge with crew-stable
Bryan O'Sullivan -
r17702:57fe5aca merge default
parent child Browse files
Show More

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

@@ -1,60 +1,61 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=
@@ -1,73 +1,74 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
@@ -1,1105 +1,1106 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, commands, util, cmdutil, scmutil, match as match_, \
14 from mercurial import hg, commands, util, cmdutil, scmutil, match as match_, \
15 node, archival, error, merge
15 node, archival, error, merge
16 from mercurial.i18n import _
16 from mercurial.i18n import _
17 from mercurial.node import hex
17 from mercurial.node import hex
18 from hgext import rebase
18 from hgext import rebase
19
19
20 import lfutil
20 import lfutil
21 import lfcommands
21 import lfcommands
22
22
23 # -- Utility functions: commonly/repeatedly needed functionality ---------------
23 # -- Utility functions: commonly/repeatedly needed functionality ---------------
24
24
25 def installnormalfilesmatchfn(manifest):
25 def installnormalfilesmatchfn(manifest):
26 '''overrides scmutil.match so that the matcher it returns will ignore all
26 '''overrides scmutil.match so that the matcher it returns will ignore all
27 largefiles'''
27 largefiles'''
28 oldmatch = None # for the closure
28 oldmatch = None # for the closure
29 def overridematch(ctx, pats=[], opts={}, globbed=False,
29 def overridematch(ctx, pats=[], opts={}, globbed=False,
30 default='relpath'):
30 default='relpath'):
31 match = oldmatch(ctx, pats, opts, globbed, default)
31 match = oldmatch(ctx, pats, opts, globbed, default)
32 m = copy.copy(match)
32 m = copy.copy(match)
33 notlfile = lambda f: not (lfutil.isstandin(f) or lfutil.standin(f) in
33 notlfile = lambda f: not (lfutil.isstandin(f) or lfutil.standin(f) in
34 manifest)
34 manifest)
35 m._files = filter(notlfile, m._files)
35 m._files = filter(notlfile, m._files)
36 m._fmap = set(m._files)
36 m._fmap = set(m._files)
37 origmatchfn = m.matchfn
37 origmatchfn = m.matchfn
38 m.matchfn = lambda f: notlfile(f) and origmatchfn(f) or None
38 m.matchfn = lambda f: notlfile(f) and origmatchfn(f) or None
39 return m
39 return m
40 oldmatch = installmatchfn(overridematch)
40 oldmatch = installmatchfn(overridematch)
41
41
42 def installmatchfn(f):
42 def installmatchfn(f):
43 oldmatch = scmutil.match
43 oldmatch = scmutil.match
44 setattr(f, 'oldmatch', oldmatch)
44 setattr(f, 'oldmatch', oldmatch)
45 scmutil.match = f
45 scmutil.match = f
46 return oldmatch
46 return oldmatch
47
47
48 def restorematchfn():
48 def restorematchfn():
49 '''restores scmutil.match to what it was before installnormalfilesmatchfn
49 '''restores scmutil.match to what it was before installnormalfilesmatchfn
50 was called. no-op if scmutil.match is its original function.
50 was called. no-op if scmutil.match is its original function.
51
51
52 Note that n calls to installnormalfilesmatchfn will require n calls to
52 Note that n calls to installnormalfilesmatchfn will require n calls to
53 restore matchfn to reverse'''
53 restore matchfn to reverse'''
54 scmutil.match = getattr(scmutil.match, 'oldmatch', scmutil.match)
54 scmutil.match = getattr(scmutil.match, 'oldmatch', scmutil.match)
55
55
56 def addlargefiles(ui, repo, *pats, **opts):
56 def addlargefiles(ui, repo, *pats, **opts):
57 large = opts.pop('large', None)
57 large = opts.pop('large', None)
58 lfsize = lfutil.getminsize(
58 lfsize = lfutil.getminsize(
59 ui, lfutil.islfilesrepo(repo), opts.pop('lfsize', None))
59 ui, lfutil.islfilesrepo(repo), opts.pop('lfsize', None))
60
60
61 lfmatcher = None
61 lfmatcher = None
62 if lfutil.islfilesrepo(repo):
62 if lfutil.islfilesrepo(repo):
63 lfpats = ui.configlist(lfutil.longname, 'patterns', default=[])
63 lfpats = ui.configlist(lfutil.longname, 'patterns', default=[])
64 if lfpats:
64 if lfpats:
65 lfmatcher = match_.match(repo.root, '', list(lfpats))
65 lfmatcher = match_.match(repo.root, '', list(lfpats))
66
66
67 lfnames = []
67 lfnames = []
68 m = scmutil.match(repo[None], pats, opts)
68 m = scmutil.match(repo[None], pats, opts)
69 m.bad = lambda x, y: None
69 m.bad = lambda x, y: None
70 wctx = repo[None]
70 wctx = repo[None]
71 for f in repo.walk(m):
71 for f in repo.walk(m):
72 exact = m.exact(f)
72 exact = m.exact(f)
73 lfile = lfutil.standin(f) in wctx
73 lfile = lfutil.standin(f) in wctx
74 nfile = f in wctx
74 nfile = f in wctx
75 exists = lfile or nfile
75 exists = lfile or nfile
76
76
77 # Don't warn the user when they attempt to add a normal tracked file.
77 # Don't warn the user when they attempt to add a normal tracked file.
78 # The normal add code will do that for us.
78 # The normal add code will do that for us.
79 if exact and exists:
79 if exact and exists:
80 if lfile:
80 if lfile:
81 ui.warn(_('%s already a largefile\n') % f)
81 ui.warn(_('%s already a largefile\n') % f)
82 continue
82 continue
83
83
84 if (exact or not exists) and not lfutil.isstandin(f):
84 if (exact or not exists) and not lfutil.isstandin(f):
85 wfile = repo.wjoin(f)
85 wfile = repo.wjoin(f)
86
86
87 # In case the file was removed previously, but not committed
87 # In case the file was removed previously, but not committed
88 # (issue3507)
88 # (issue3507)
89 if not os.path.exists(wfile):
89 if not os.path.exists(wfile):
90 continue
90 continue
91
91
92 abovemin = (lfsize and
92 abovemin = (lfsize and
93 os.lstat(wfile).st_size >= lfsize * 1024 * 1024)
93 os.lstat(wfile).st_size >= lfsize * 1024 * 1024)
94 if large or abovemin or (lfmatcher and lfmatcher(f)):
94 if large or abovemin or (lfmatcher and lfmatcher(f)):
95 lfnames.append(f)
95 lfnames.append(f)
96 if ui.verbose or not exact:
96 if ui.verbose or not exact:
97 ui.status(_('adding %s as a largefile\n') % m.rel(f))
97 ui.status(_('adding %s as a largefile\n') % m.rel(f))
98
98
99 bad = []
99 bad = []
100 standins = []
100 standins = []
101
101
102 # Need to lock, otherwise there could be a race condition between
102 # Need to lock, otherwise there could be a race condition between
103 # when standins are created and added to the repo.
103 # when standins are created and added to the repo.
104 wlock = repo.wlock()
104 wlock = repo.wlock()
105 try:
105 try:
106 if not opts.get('dry_run'):
106 if not opts.get('dry_run'):
107 lfdirstate = lfutil.openlfdirstate(ui, repo)
107 lfdirstate = lfutil.openlfdirstate(ui, repo)
108 for f in lfnames:
108 for f in lfnames:
109 standinname = lfutil.standin(f)
109 standinname = lfutil.standin(f)
110 lfutil.writestandin(repo, standinname, hash='',
110 lfutil.writestandin(repo, standinname, hash='',
111 executable=lfutil.getexecutable(repo.wjoin(f)))
111 executable=lfutil.getexecutable(repo.wjoin(f)))
112 standins.append(standinname)
112 standins.append(standinname)
113 if lfdirstate[f] == 'r':
113 if lfdirstate[f] == 'r':
114 lfdirstate.normallookup(f)
114 lfdirstate.normallookup(f)
115 else:
115 else:
116 lfdirstate.add(f)
116 lfdirstate.add(f)
117 lfdirstate.write()
117 lfdirstate.write()
118 bad += [lfutil.splitstandin(f)
118 bad += [lfutil.splitstandin(f)
119 for f in lfutil.repoadd(repo, standins)
119 for f in lfutil.repoadd(repo, standins)
120 if f in m.files()]
120 if f in m.files()]
121 finally:
121 finally:
122 wlock.release()
122 wlock.release()
123 return bad
123 return bad
124
124
125 def removelargefiles(ui, repo, *pats, **opts):
125 def removelargefiles(ui, repo, *pats, **opts):
126 after = opts.get('after')
126 after = opts.get('after')
127 if not pats and not after:
127 if not pats and not after:
128 raise util.Abort(_('no files specified'))
128 raise util.Abort(_('no files specified'))
129 m = scmutil.match(repo[None], pats, opts)
129 m = scmutil.match(repo[None], pats, opts)
130 try:
130 try:
131 repo.lfstatus = True
131 repo.lfstatus = True
132 s = repo.status(match=m, clean=True)
132 s = repo.status(match=m, clean=True)
133 finally:
133 finally:
134 repo.lfstatus = False
134 repo.lfstatus = False
135 manifest = repo[None].manifest()
135 manifest = repo[None].manifest()
136 modified, added, deleted, clean = [[f for f in list
136 modified, added, deleted, clean = [[f for f in list
137 if lfutil.standin(f) in manifest]
137 if lfutil.standin(f) in manifest]
138 for list in [s[0], s[1], s[3], s[6]]]
138 for list in [s[0], s[1], s[3], s[6]]]
139
139
140 def warn(files, reason):
140 def warn(files, reason):
141 for f in files:
141 for f in files:
142 ui.warn(_('not removing %s: %s (use forget to undo)\n')
142 ui.warn(_('not removing %s: %s (use forget to undo)\n')
143 % (m.rel(f), reason))
143 % (m.rel(f), reason))
144 return int(len(files) > 0)
144 return int(len(files) > 0)
145
145
146 result = 0
146 result = 0
147
147
148 if after:
148 if after:
149 remove, forget = deleted, []
149 remove, forget = deleted, []
150 result = warn(modified + added + clean, _('file still exists'))
150 result = warn(modified + added + clean, _('file still exists'))
151 else:
151 else:
152 remove, forget = deleted + clean, []
152 remove, forget = deleted + clean, []
153 result = warn(modified, _('file is modified'))
153 result = warn(modified, _('file is modified'))
154 result = warn(added, _('file has been marked for add')) or result
154 result = warn(added, _('file has been marked for add')) or result
155
155
156 for f in sorted(remove + forget):
156 for f in sorted(remove + forget):
157 if ui.verbose or not m.exact(f):
157 if ui.verbose or not m.exact(f):
158 ui.status(_('removing %s\n') % m.rel(f))
158 ui.status(_('removing %s\n') % m.rel(f))
159
159
160 # Need to lock because standin files are deleted then removed from the
160 # Need to lock because standin files are deleted then removed from the
161 # repository and we could race in-between.
161 # repository and we could race in-between.
162 wlock = repo.wlock()
162 wlock = repo.wlock()
163 try:
163 try:
164 lfdirstate = lfutil.openlfdirstate(ui, repo)
164 lfdirstate = lfutil.openlfdirstate(ui, repo)
165 for f in remove:
165 for f in remove:
166 if not after:
166 if not after:
167 # If this is being called by addremove, notify the user that we
167 # If this is being called by addremove, notify the user that we
168 # are removing the file.
168 # are removing the file.
169 if getattr(repo, "_isaddremove", False):
169 if getattr(repo, "_isaddremove", False):
170 ui.status(_('removing %s\n') % f)
170 ui.status(_('removing %s\n') % f)
171 if os.path.exists(repo.wjoin(f)):
171 if os.path.exists(repo.wjoin(f)):
172 util.unlinkpath(repo.wjoin(f))
172 util.unlinkpath(repo.wjoin(f))
173 lfdirstate.remove(f)
173 lfdirstate.remove(f)
174 lfdirstate.write()
174 lfdirstate.write()
175 forget = [lfutil.standin(f) for f in forget]
175 forget = [lfutil.standin(f) for f in forget]
176 remove = [lfutil.standin(f) for f in remove]
176 remove = [lfutil.standin(f) for f in remove]
177 lfutil.repoforget(repo, forget)
177 lfutil.repoforget(repo, forget)
178 # If this is being called by addremove, let the original addremove
178 # If this is being called by addremove, let the original addremove
179 # function handle this.
179 # function handle this.
180 if not getattr(repo, "_isaddremove", False):
180 if not getattr(repo, "_isaddremove", False):
181 lfutil.reporemove(repo, remove, unlink=True)
181 lfutil.reporemove(repo, remove, unlink=True)
182 else:
182 else:
183 lfutil.reporemove(repo, remove, unlink=False)
183 lfutil.reporemove(repo, remove, unlink=False)
184 finally:
184 finally:
185 wlock.release()
185 wlock.release()
186
186
187 return result
187 return result
188
188
189 # For overriding mercurial.hgweb.webcommands so that largefiles will
189 # For overriding mercurial.hgweb.webcommands so that largefiles will
190 # appear at their right place in the manifests.
190 # appear at their right place in the manifests.
191 def decodepath(orig, path):
191 def decodepath(orig, path):
192 return lfutil.splitstandin(path) or path
192 return lfutil.splitstandin(path) or path
193
193
194 # -- Wrappers: modify existing commands --------------------------------
194 # -- Wrappers: modify existing commands --------------------------------
195
195
196 # Add works by going through the files that the user wanted to add and
196 # Add works by going through the files that the user wanted to add and
197 # checking if they should be added as largefiles. Then it makes a new
197 # checking if they should be added as largefiles. Then it makes a new
198 # matcher which matches only the normal files and runs the original
198 # matcher which matches only the normal files and runs the original
199 # version of add.
199 # version of add.
200 def overrideadd(orig, ui, repo, *pats, **opts):
200 def overrideadd(orig, ui, repo, *pats, **opts):
201 normal = opts.pop('normal')
201 normal = opts.pop('normal')
202 if normal:
202 if normal:
203 if opts.get('large'):
203 if opts.get('large'):
204 raise util.Abort(_('--normal cannot be used with --large'))
204 raise util.Abort(_('--normal cannot be used with --large'))
205 return orig(ui, repo, *pats, **opts)
205 return orig(ui, repo, *pats, **opts)
206 bad = addlargefiles(ui, repo, *pats, **opts)
206 bad = addlargefiles(ui, repo, *pats, **opts)
207 installnormalfilesmatchfn(repo[None].manifest())
207 installnormalfilesmatchfn(repo[None].manifest())
208 result = orig(ui, repo, *pats, **opts)
208 result = orig(ui, repo, *pats, **opts)
209 restorematchfn()
209 restorematchfn()
210
210
211 return (result == 1 or bad) and 1 or 0
211 return (result == 1 or bad) and 1 or 0
212
212
213 def overrideremove(orig, ui, repo, *pats, **opts):
213 def overrideremove(orig, ui, repo, *pats, **opts):
214 installnormalfilesmatchfn(repo[None].manifest())
214 installnormalfilesmatchfn(repo[None].manifest())
215 result = orig(ui, repo, *pats, **opts)
215 result = orig(ui, repo, *pats, **opts)
216 restorematchfn()
216 restorematchfn()
217 return removelargefiles(ui, repo, *pats, **opts) or result
217 return removelargefiles(ui, repo, *pats, **opts) or result
218
218
219 def overridestatusfn(orig, repo, rev2, **opts):
219 def overridestatusfn(orig, repo, rev2, **opts):
220 try:
220 try:
221 repo._repo.lfstatus = True
221 repo._repo.lfstatus = True
222 return orig(repo, rev2, **opts)
222 return orig(repo, rev2, **opts)
223 finally:
223 finally:
224 repo._repo.lfstatus = False
224 repo._repo.lfstatus = False
225
225
226 def overridestatus(orig, ui, repo, *pats, **opts):
226 def overridestatus(orig, ui, repo, *pats, **opts):
227 try:
227 try:
228 repo.lfstatus = True
228 repo.lfstatus = True
229 return orig(ui, repo, *pats, **opts)
229 return orig(ui, repo, *pats, **opts)
230 finally:
230 finally:
231 repo.lfstatus = False
231 repo.lfstatus = False
232
232
233 def overridedirty(orig, repo, ignoreupdate=False):
233 def overridedirty(orig, repo, ignoreupdate=False):
234 try:
234 try:
235 repo._repo.lfstatus = True
235 repo._repo.lfstatus = True
236 return orig(repo, ignoreupdate)
236 return orig(repo, ignoreupdate)
237 finally:
237 finally:
238 repo._repo.lfstatus = False
238 repo._repo.lfstatus = False
239
239
240 def overridelog(orig, ui, repo, *pats, **opts):
240 def overridelog(orig, ui, repo, *pats, **opts):
241 try:
241 try:
242 repo.lfstatus = True
242 repo.lfstatus = True
243 return orig(ui, repo, *pats, **opts)
243 return orig(ui, repo, *pats, **opts)
244 finally:
244 finally:
245 repo.lfstatus = False
245 repo.lfstatus = False
246
246
247 def overrideverify(orig, ui, repo, *pats, **opts):
247 def overrideverify(orig, ui, repo, *pats, **opts):
248 large = opts.pop('large', False)
248 large = opts.pop('large', False)
249 all = opts.pop('lfa', False)
249 all = opts.pop('lfa', False)
250 contents = opts.pop('lfc', False)
250 contents = opts.pop('lfc', False)
251
251
252 result = orig(ui, repo, *pats, **opts)
252 result = orig(ui, repo, *pats, **opts)
253 if large:
253 if large:
254 result = result or lfcommands.verifylfiles(ui, repo, all, contents)
254 result = result or lfcommands.verifylfiles(ui, repo, all, contents)
255 return result
255 return result
256
256
257 # Override needs to refresh standins so that update's normal merge
257 # Override needs to refresh standins so that update's normal merge
258 # will go through properly. Then the other update hook (overriding repo.update)
258 # will go through properly. Then the other update hook (overriding repo.update)
259 # will get the new files. Filemerge is also overridden so that the merge
259 # will get the new files. Filemerge is also overridden so that the merge
260 # will merge standins correctly.
260 # will merge standins correctly.
261 def overrideupdate(orig, ui, repo, *pats, **opts):
261 def overrideupdate(orig, ui, repo, *pats, **opts):
262 lfdirstate = lfutil.openlfdirstate(ui, repo)
262 lfdirstate = lfutil.openlfdirstate(ui, repo)
263 s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False,
263 s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False,
264 False, False)
264 False, False)
265 (unsure, modified, added, removed, missing, unknown, ignored, clean) = s
265 (unsure, modified, added, removed, missing, unknown, ignored, clean) = s
266
266
267 # Need to lock between the standins getting updated and their
267 # Need to lock between the standins getting updated and their
268 # largefiles getting updated
268 # largefiles getting updated
269 wlock = repo.wlock()
269 wlock = repo.wlock()
270 try:
270 try:
271 if opts['check']:
271 if opts['check']:
272 mod = len(modified) > 0
272 mod = len(modified) > 0
273 for lfile in unsure:
273 for lfile in unsure:
274 standin = lfutil.standin(lfile)
274 standin = lfutil.standin(lfile)
275 if repo['.'][standin].data().strip() != \
275 if repo['.'][standin].data().strip() != \
276 lfutil.hashfile(repo.wjoin(lfile)):
276 lfutil.hashfile(repo.wjoin(lfile)):
277 mod = True
277 mod = True
278 else:
278 else:
279 lfdirstate.normal(lfile)
279 lfdirstate.normal(lfile)
280 lfdirstate.write()
280 lfdirstate.write()
281 if mod:
281 if mod:
282 raise util.Abort(_('uncommitted local changes'))
282 raise util.Abort(_('uncommitted local changes'))
283 # XXX handle removed differently
283 # XXX handle removed differently
284 if not opts['clean']:
284 if not opts['clean']:
285 for lfile in unsure + modified + added:
285 for lfile in unsure + modified + added:
286 lfutil.updatestandin(repo, lfutil.standin(lfile))
286 lfutil.updatestandin(repo, lfutil.standin(lfile))
287 finally:
287 finally:
288 wlock.release()
288 wlock.release()
289 return orig(ui, repo, *pats, **opts)
289 return orig(ui, repo, *pats, **opts)
290
290
291 # Before starting the manifest merge, merge.updates will call
291 # Before starting the manifest merge, merge.updates will call
292 # _checkunknown to check if there are any files in the merged-in
292 # _checkunknown to check if there are any files in the merged-in
293 # changeset that collide with unknown files in the working copy.
293 # changeset that collide with unknown files in the working copy.
294 #
294 #
295 # The largefiles are seen as unknown, so this prevents us from merging
295 # The largefiles are seen as unknown, so this prevents us from merging
296 # in a file 'foo' if we already have a largefile with the same name.
296 # in a file 'foo' if we already have a largefile with the same name.
297 #
297 #
298 # The overridden function filters the unknown files by removing any
298 # The overridden function filters the unknown files by removing any
299 # largefiles. This makes the merge proceed and we can then handle this
299 # largefiles. This makes the merge proceed and we can then handle this
300 # case further in the overridden manifestmerge function below.
300 # case further in the overridden manifestmerge function below.
301 def overridecheckunknownfile(origfn, repo, wctx, mctx, f):
301 def overridecheckunknownfile(origfn, repo, wctx, mctx, f):
302 if lfutil.standin(f) in wctx:
302 if lfutil.standin(f) in wctx:
303 return False
303 return False
304 return origfn(repo, wctx, mctx, f)
304 return origfn(repo, wctx, mctx, f)
305
305
306 # The manifest merge handles conflicts on the manifest level. We want
306 # The manifest merge handles conflicts on the manifest level. We want
307 # to handle changes in largefile-ness of files at this level too.
307 # to handle changes in largefile-ness of files at this level too.
308 #
308 #
309 # The strategy is to run the original manifestmerge and then process
309 # The strategy is to run the original manifestmerge and then process
310 # the action list it outputs. There are two cases we need to deal with:
310 # the action list it outputs. There are two cases we need to deal with:
311 #
311 #
312 # 1. Normal file in p1, largefile in p2. Here the largefile is
312 # 1. Normal file in p1, largefile in p2. Here the largefile is
313 # detected via its standin file, which will enter the working copy
313 # detected via its standin file, which will enter the working copy
314 # with a "get" action. It is not "merge" since the standin is all
314 # with a "get" action. It is not "merge" since the standin is all
315 # Mercurial is concerned with at this level -- the link to the
315 # Mercurial is concerned with at this level -- the link to the
316 # existing normal file is not relevant here.
316 # existing normal file is not relevant here.
317 #
317 #
318 # 2. Largefile in p1, normal file in p2. Here we get a "merge" action
318 # 2. Largefile in p1, normal file in p2. Here we get a "merge" action
319 # since the largefile will be present in the working copy and
319 # since the largefile will be present in the working copy and
320 # different from the normal file in p2. Mercurial therefore
320 # different from the normal file in p2. Mercurial therefore
321 # triggers a merge action.
321 # triggers a merge action.
322 #
322 #
323 # In both cases, we prompt the user and emit new actions to either
323 # In both cases, we prompt the user and emit new actions to either
324 # remove the standin (if the normal file was kept) or to remove the
324 # remove the standin (if the normal file was kept) or to remove the
325 # normal file and get the standin (if the largefile was kept). The
325 # normal file and get the standin (if the largefile was kept). The
326 # default prompt answer is to use the largefile version since it was
326 # default prompt answer is to use the largefile version since it was
327 # presumably changed on purpose.
327 # presumably changed on purpose.
328 #
328 #
329 # Finally, the merge.applyupdates function will then take care of
329 # Finally, the merge.applyupdates function will then take care of
330 # writing the files into the working copy and lfcommands.updatelfiles
330 # writing the files into the working copy and lfcommands.updatelfiles
331 # will update the largefiles.
331 # will update the largefiles.
332 def overridemanifestmerge(origfn, repo, p1, p2, pa, overwrite, partial):
332 def overridemanifestmerge(origfn, repo, p1, p2, pa, overwrite, partial):
333 actions = origfn(repo, p1, p2, pa, overwrite, partial)
333 actions = origfn(repo, p1, p2, pa, overwrite, partial)
334 processed = []
334 processed = []
335
335
336 for action in actions:
336 for action in actions:
337 if overwrite:
337 if overwrite:
338 processed.append(action)
338 processed.append(action)
339 continue
339 continue
340 f, m = action[:2]
340 f, m = action[:2]
341
341
342 choices = (_('&Largefile'), _('&Normal file'))
342 choices = (_('&Largefile'), _('&Normal file'))
343 if m == "g" and lfutil.splitstandin(f) in p1 and f in p2:
343 if m == "g" and lfutil.splitstandin(f) in p1 and f in p2:
344 # Case 1: normal file in the working copy, largefile in
344 # Case 1: normal file in the working copy, largefile in
345 # the second parent
345 # the second parent
346 lfile = lfutil.splitstandin(f)
346 lfile = lfutil.splitstandin(f)
347 standin = f
347 standin = f
348 msg = _('%s has been turned into a largefile\n'
348 msg = _('%s has been turned into a largefile\n'
349 'use (l)argefile or keep as (n)ormal file?') % lfile
349 'use (l)argefile or keep as (n)ormal file?') % lfile
350 if repo.ui.promptchoice(msg, choices, 0) == 0:
350 if repo.ui.promptchoice(msg, choices, 0) == 0:
351 processed.append((lfile, "r"))
351 processed.append((lfile, "r"))
352 processed.append((standin, "g", p2.flags(standin)))
352 processed.append((standin, "g", p2.flags(standin)))
353 else:
353 else:
354 processed.append((standin, "r"))
354 processed.append((standin, "r"))
355 elif m == "g" and lfutil.standin(f) in p1 and f in p2:
355 elif m == "g" and lfutil.standin(f) in p1 and f in p2:
356 # Case 2: largefile in the working copy, normal file in
356 # Case 2: largefile in the working copy, normal file in
357 # the second parent
357 # the second parent
358 standin = lfutil.standin(f)
358 standin = lfutil.standin(f)
359 lfile = f
359 lfile = f
360 msg = _('%s has been turned into a normal file\n'
360 msg = _('%s has been turned into a normal file\n'
361 'keep as (l)argefile or use (n)ormal file?') % lfile
361 'keep as (l)argefile or use (n)ormal file?') % lfile
362 if repo.ui.promptchoice(msg, choices, 0) == 0:
362 if repo.ui.promptchoice(msg, choices, 0) == 0:
363 processed.append((lfile, "r"))
363 processed.append((lfile, "r"))
364 else:
364 else:
365 processed.append((standin, "r"))
365 processed.append((standin, "r"))
366 processed.append((lfile, "g", p2.flags(lfile)))
366 processed.append((lfile, "g", p2.flags(lfile)))
367 else:
367 else:
368 processed.append(action)
368 processed.append(action)
369
369
370 return processed
370 return processed
371
371
372 # Override filemerge to prompt the user about how they wish to merge
372 # Override filemerge to prompt the user about how they wish to merge
373 # largefiles. This will handle identical edits, and copy/rename +
373 # largefiles. This will handle identical edits, and copy/rename +
374 # edit without prompting the user.
374 # edit without prompting the user.
375 def overridefilemerge(origfn, repo, mynode, orig, fcd, fco, fca):
375 def overridefilemerge(origfn, repo, mynode, orig, fcd, fco, fca):
376 # Use better variable names here. Because this is a wrapper we cannot
376 # Use better variable names here. Because this is a wrapper we cannot
377 # change the variable names in the function declaration.
377 # change the variable names in the function declaration.
378 fcdest, fcother, fcancestor = fcd, fco, fca
378 fcdest, fcother, fcancestor = fcd, fco, fca
379 if not lfutil.isstandin(orig):
379 if not lfutil.isstandin(orig):
380 return origfn(repo, mynode, orig, fcdest, fcother, fcancestor)
380 return origfn(repo, mynode, orig, fcdest, fcother, fcancestor)
381 else:
381 else:
382 if not fcother.cmp(fcdest): # files identical?
382 if not fcother.cmp(fcdest): # files identical?
383 return None
383 return None
384
384
385 # backwards, use working dir parent as ancestor
385 # backwards, use working dir parent as ancestor
386 if fcancestor == fcother:
386 if fcancestor == fcother:
387 fcancestor = fcdest.parents()[0]
387 fcancestor = fcdest.parents()[0]
388
388
389 if orig != fcother.path():
389 if orig != fcother.path():
390 repo.ui.status(_('merging %s and %s to %s\n')
390 repo.ui.status(_('merging %s and %s to %s\n')
391 % (lfutil.splitstandin(orig),
391 % (lfutil.splitstandin(orig),
392 lfutil.splitstandin(fcother.path()),
392 lfutil.splitstandin(fcother.path()),
393 lfutil.splitstandin(fcdest.path())))
393 lfutil.splitstandin(fcdest.path())))
394 else:
394 else:
395 repo.ui.status(_('merging %s\n')
395 repo.ui.status(_('merging %s\n')
396 % lfutil.splitstandin(fcdest.path()))
396 % lfutil.splitstandin(fcdest.path()))
397
397
398 if fcancestor.path() != fcother.path() and fcother.data() == \
398 if fcancestor.path() != fcother.path() and fcother.data() == \
399 fcancestor.data():
399 fcancestor.data():
400 return 0
400 return 0
401 if fcancestor.path() != fcdest.path() and fcdest.data() == \
401 if fcancestor.path() != fcdest.path() and fcdest.data() == \
402 fcancestor.data():
402 fcancestor.data():
403 repo.wwrite(fcdest.path(), fcother.data(), fcother.flags())
403 repo.wwrite(fcdest.path(), fcother.data(), fcother.flags())
404 return 0
404 return 0
405
405
406 if repo.ui.promptchoice(_('largefile %s has a merge conflict\n'
406 if repo.ui.promptchoice(_('largefile %s has a merge conflict\n'
407 'keep (l)ocal or take (o)ther?') %
407 'keep (l)ocal or take (o)ther?') %
408 lfutil.splitstandin(orig),
408 lfutil.splitstandin(orig),
409 (_('&Local'), _('&Other')), 0) == 0:
409 (_('&Local'), _('&Other')), 0) == 0:
410 return 0
410 return 0
411 else:
411 else:
412 repo.wwrite(fcdest.path(), fcother.data(), fcother.flags())
412 repo.wwrite(fcdest.path(), fcother.data(), fcother.flags())
413 return 0
413 return 0
414
414
415 # Copy first changes the matchers to match standins instead of
415 # Copy first changes the matchers to match standins instead of
416 # largefiles. Then it overrides util.copyfile in that function it
416 # largefiles. Then it overrides util.copyfile in that function it
417 # checks if the destination largefile already exists. It also keeps a
417 # checks if the destination largefile already exists. It also keeps a
418 # list of copied files so that the largefiles can be copied and the
418 # list of copied files so that the largefiles can be copied and the
419 # dirstate updated.
419 # dirstate updated.
420 def overridecopy(orig, ui, repo, pats, opts, rename=False):
420 def overridecopy(orig, ui, repo, pats, opts, rename=False):
421 # doesn't remove largefile on rename
421 # doesn't remove largefile on rename
422 if len(pats) < 2:
422 if len(pats) < 2:
423 # this isn't legal, let the original function deal with it
423 # this isn't legal, let the original function deal with it
424 return orig(ui, repo, pats, opts, rename)
424 return orig(ui, repo, pats, opts, rename)
425
425
426 def makestandin(relpath):
426 def makestandin(relpath):
427 path = scmutil.canonpath(repo.root, repo.getcwd(), relpath)
427 path = scmutil.canonpath(repo.root, repo.getcwd(), relpath)
428 return os.path.join(repo.wjoin(lfutil.standin(path)))
428 return os.path.join(repo.wjoin(lfutil.standin(path)))
429
429
430 fullpats = scmutil.expandpats(pats)
430 fullpats = scmutil.expandpats(pats)
431 dest = fullpats[-1]
431 dest = fullpats[-1]
432
432
433 if os.path.isdir(dest):
433 if os.path.isdir(dest):
434 if not os.path.isdir(makestandin(dest)):
434 if not os.path.isdir(makestandin(dest)):
435 os.makedirs(makestandin(dest))
435 os.makedirs(makestandin(dest))
436 # This could copy both lfiles and normal files in one command,
436 # This could copy both lfiles and normal files in one command,
437 # but we don't want to do that. First replace their matcher to
437 # but we don't want to do that. First replace their matcher to
438 # only match normal files and run it, then replace it to just
438 # only match normal files and run it, then replace it to just
439 # match largefiles and run it again.
439 # match largefiles and run it again.
440 nonormalfiles = False
440 nonormalfiles = False
441 nolfiles = False
441 nolfiles = False
442 try:
442 try:
443 try:
443 try:
444 installnormalfilesmatchfn(repo[None].manifest())
444 installnormalfilesmatchfn(repo[None].manifest())
445 result = orig(ui, repo, pats, opts, rename)
445 result = orig(ui, repo, pats, opts, rename)
446 except util.Abort, e:
446 except util.Abort, e:
447 if str(e) != _('no files to copy'):
447 if str(e) != _('no files to copy'):
448 raise e
448 raise e
449 else:
449 else:
450 nonormalfiles = True
450 nonormalfiles = True
451 result = 0
451 result = 0
452 finally:
452 finally:
453 restorematchfn()
453 restorematchfn()
454
454
455 # The first rename can cause our current working directory to be removed.
455 # The first rename can cause our current working directory to be removed.
456 # In that case there is nothing left to copy/rename so just quit.
456 # In that case there is nothing left to copy/rename so just quit.
457 try:
457 try:
458 repo.getcwd()
458 repo.getcwd()
459 except OSError:
459 except OSError:
460 return result
460 return result
461
461
462 try:
462 try:
463 try:
463 try:
464 # When we call orig below it creates the standins but we don't add
464 # When we call orig below it creates the standins but we don't add
465 # them to the dir state until later so lock during that time.
465 # them to the dir state until later so lock during that time.
466 wlock = repo.wlock()
466 wlock = repo.wlock()
467
467
468 manifest = repo[None].manifest()
468 manifest = repo[None].manifest()
469 oldmatch = None # for the closure
469 oldmatch = None # for the closure
470 def overridematch(ctx, pats=[], opts={}, globbed=False,
470 def overridematch(ctx, pats=[], opts={}, globbed=False,
471 default='relpath'):
471 default='relpath'):
472 newpats = []
472 newpats = []
473 # The patterns were previously mangled to add the standin
473 # The patterns were previously mangled to add the standin
474 # directory; we need to remove that now
474 # directory; we need to remove that now
475 for pat in pats:
475 for pat in pats:
476 if match_.patkind(pat) is None and lfutil.shortname in pat:
476 if match_.patkind(pat) is None and lfutil.shortname in pat:
477 newpats.append(pat.replace(lfutil.shortname, ''))
477 newpats.append(pat.replace(lfutil.shortname, ''))
478 else:
478 else:
479 newpats.append(pat)
479 newpats.append(pat)
480 match = oldmatch(ctx, newpats, opts, globbed, default)
480 match = oldmatch(ctx, newpats, opts, globbed, default)
481 m = copy.copy(match)
481 m = copy.copy(match)
482 lfile = lambda f: lfutil.standin(f) in manifest
482 lfile = lambda f: lfutil.standin(f) in manifest
483 m._files = [lfutil.standin(f) for f in m._files if lfile(f)]
483 m._files = [lfutil.standin(f) for f in m._files if lfile(f)]
484 m._fmap = set(m._files)
484 m._fmap = set(m._files)
485 origmatchfn = m.matchfn
485 origmatchfn = m.matchfn
486 m.matchfn = lambda f: (lfutil.isstandin(f) and
486 m.matchfn = lambda f: (lfutil.isstandin(f) and
487 (f in manifest) and
487 (f in manifest) and
488 origmatchfn(lfutil.splitstandin(f)) or
488 origmatchfn(lfutil.splitstandin(f)) or
489 None)
489 None)
490 return m
490 return m
491 oldmatch = installmatchfn(overridematch)
491 oldmatch = installmatchfn(overridematch)
492 listpats = []
492 listpats = []
493 for pat in pats:
493 for pat in pats:
494 if match_.patkind(pat) is not None:
494 if match_.patkind(pat) is not None:
495 listpats.append(pat)
495 listpats.append(pat)
496 else:
496 else:
497 listpats.append(makestandin(pat))
497 listpats.append(makestandin(pat))
498
498
499 try:
499 try:
500 origcopyfile = util.copyfile
500 origcopyfile = util.copyfile
501 copiedfiles = []
501 copiedfiles = []
502 def overridecopyfile(src, dest):
502 def overridecopyfile(src, dest):
503 if (lfutil.shortname in src and
503 if (lfutil.shortname in src and
504 dest.startswith(repo.wjoin(lfutil.shortname))):
504 dest.startswith(repo.wjoin(lfutil.shortname))):
505 destlfile = dest.replace(lfutil.shortname, '')
505 destlfile = dest.replace(lfutil.shortname, '')
506 if not opts['force'] and os.path.exists(destlfile):
506 if not opts['force'] and os.path.exists(destlfile):
507 raise IOError('',
507 raise IOError('',
508 _('destination largefile already exists'))
508 _('destination largefile already exists'))
509 copiedfiles.append((src, dest))
509 copiedfiles.append((src, dest))
510 origcopyfile(src, dest)
510 origcopyfile(src, dest)
511
511
512 util.copyfile = overridecopyfile
512 util.copyfile = overridecopyfile
513 result += orig(ui, repo, listpats, opts, rename)
513 result += orig(ui, repo, listpats, opts, rename)
514 finally:
514 finally:
515 util.copyfile = origcopyfile
515 util.copyfile = origcopyfile
516
516
517 lfdirstate = lfutil.openlfdirstate(ui, repo)
517 lfdirstate = lfutil.openlfdirstate(ui, repo)
518 for (src, dest) in copiedfiles:
518 for (src, dest) in copiedfiles:
519 if (lfutil.shortname in src and
519 if (lfutil.shortname in src and
520 dest.startswith(repo.wjoin(lfutil.shortname))):
520 dest.startswith(repo.wjoin(lfutil.shortname))):
521 srclfile = src.replace(repo.wjoin(lfutil.standin('')), '')
521 srclfile = src.replace(repo.wjoin(lfutil.standin('')), '')
522 destlfile = dest.replace(repo.wjoin(lfutil.standin('')), '')
522 destlfile = dest.replace(repo.wjoin(lfutil.standin('')), '')
523 destlfiledir = os.path.dirname(repo.wjoin(destlfile)) or '.'
523 destlfiledir = os.path.dirname(repo.wjoin(destlfile)) or '.'
524 if not os.path.isdir(destlfiledir):
524 if not os.path.isdir(destlfiledir):
525 os.makedirs(destlfiledir)
525 os.makedirs(destlfiledir)
526 if rename:
526 if rename:
527 os.rename(repo.wjoin(srclfile), repo.wjoin(destlfile))
527 os.rename(repo.wjoin(srclfile), repo.wjoin(destlfile))
528 lfdirstate.remove(srclfile)
528 lfdirstate.remove(srclfile)
529 else:
529 else:
530 util.copyfile(repo.wjoin(srclfile),
530 util.copyfile(repo.wjoin(srclfile),
531 repo.wjoin(destlfile))
531 repo.wjoin(destlfile))
532
532
533 lfdirstate.add(destlfile)
533 lfdirstate.add(destlfile)
534 lfdirstate.write()
534 lfdirstate.write()
535 except util.Abort, e:
535 except util.Abort, e:
536 if str(e) != _('no files to copy'):
536 if str(e) != _('no files to copy'):
537 raise e
537 raise e
538 else:
538 else:
539 nolfiles = True
539 nolfiles = True
540 finally:
540 finally:
541 restorematchfn()
541 restorematchfn()
542 wlock.release()
542 wlock.release()
543
543
544 if nolfiles and nonormalfiles:
544 if nolfiles and nonormalfiles:
545 raise util.Abort(_('no files to copy'))
545 raise util.Abort(_('no files to copy'))
546
546
547 return result
547 return result
548
548
549 # When the user calls revert, we have to be careful to not revert any
549 # When the user calls revert, we have to be careful to not revert any
550 # changes to other largefiles accidentally. This means we have to keep
550 # changes to other largefiles accidentally. This means we have to keep
551 # track of the largefiles that are being reverted so we only pull down
551 # track of the largefiles that are being reverted so we only pull down
552 # the necessary largefiles.
552 # the necessary largefiles.
553 #
553 #
554 # Standins are only updated (to match the hash of largefiles) before
554 # Standins are only updated (to match the hash of largefiles) before
555 # commits. Update the standins then run the original revert, changing
555 # commits. Update the standins then run the original revert, changing
556 # the matcher to hit standins instead of largefiles. Based on the
556 # the matcher to hit standins instead of largefiles. Based on the
557 # resulting standins update the largefiles. Then return the standins
557 # resulting standins update the largefiles. Then return the standins
558 # to their proper state
558 # to their proper state
559 def overriderevert(orig, ui, repo, *pats, **opts):
559 def overriderevert(orig, ui, repo, *pats, **opts):
560 # Because we put the standins in a bad state (by updating them)
560 # Because we put the standins in a bad state (by updating them)
561 # and then return them to a correct state we need to lock to
561 # and then return them to a correct state we need to lock to
562 # prevent others from changing them in their incorrect state.
562 # prevent others from changing them in their incorrect state.
563 wlock = repo.wlock()
563 wlock = repo.wlock()
564 try:
564 try:
565 lfdirstate = lfutil.openlfdirstate(ui, repo)
565 lfdirstate = lfutil.openlfdirstate(ui, repo)
566 (modified, added, removed, missing, unknown, ignored, clean) = \
566 (modified, added, removed, missing, unknown, ignored, clean) = \
567 lfutil.lfdirstatestatus(lfdirstate, repo, repo['.'].rev())
567 lfutil.lfdirstatestatus(lfdirstate, repo, repo['.'].rev())
568 for lfile in modified:
568 for lfile in modified:
569 lfutil.updatestandin(repo, lfutil.standin(lfile))
569 lfutil.updatestandin(repo, lfutil.standin(lfile))
570 for lfile in missing:
570 for lfile in missing:
571 if (os.path.exists(repo.wjoin(lfutil.standin(lfile)))):
571 if (os.path.exists(repo.wjoin(lfutil.standin(lfile)))):
572 os.unlink(repo.wjoin(lfutil.standin(lfile)))
572 os.unlink(repo.wjoin(lfutil.standin(lfile)))
573
573
574 try:
574 try:
575 ctx = scmutil.revsingle(repo, opts.get('rev'))
575 ctx = scmutil.revsingle(repo, opts.get('rev'))
576 oldmatch = None # for the closure
576 oldmatch = None # for the closure
577 def overridematch(ctx, pats=[], opts={}, globbed=False,
577 def overridematch(ctx, pats=[], opts={}, globbed=False,
578 default='relpath'):
578 default='relpath'):
579 match = oldmatch(ctx, pats, opts, globbed, default)
579 match = oldmatch(ctx, pats, opts, globbed, default)
580 m = copy.copy(match)
580 m = copy.copy(match)
581 def tostandin(f):
581 def tostandin(f):
582 if lfutil.standin(f) in ctx:
582 if lfutil.standin(f) in ctx:
583 return lfutil.standin(f)
583 return lfutil.standin(f)
584 elif lfutil.standin(f) in repo[None]:
584 elif lfutil.standin(f) in repo[None]:
585 return None
585 return None
586 return f
586 return f
587 m._files = [tostandin(f) for f in m._files]
587 m._files = [tostandin(f) for f in m._files]
588 m._files = [f for f in m._files if f is not None]
588 m._files = [f for f in m._files if f is not None]
589 m._fmap = set(m._files)
589 m._fmap = set(m._files)
590 origmatchfn = m.matchfn
590 origmatchfn = m.matchfn
591 def matchfn(f):
591 def matchfn(f):
592 if lfutil.isstandin(f):
592 if lfutil.isstandin(f):
593 # We need to keep track of what largefiles are being
593 # We need to keep track of what largefiles are being
594 # matched so we know which ones to update later --
594 # matched so we know which ones to update later --
595 # otherwise we accidentally revert changes to other
595 # otherwise we accidentally revert changes to other
596 # largefiles. This is repo-specific, so duckpunch the
596 # largefiles. This is repo-specific, so duckpunch the
597 # repo object to keep the list of largefiles for us
597 # repo object to keep the list of largefiles for us
598 # later.
598 # later.
599 if origmatchfn(lfutil.splitstandin(f)) and \
599 if origmatchfn(lfutil.splitstandin(f)) and \
600 (f in repo[None] or f in ctx):
600 (f in repo[None] or f in ctx):
601 lfileslist = getattr(repo, '_lfilestoupdate', [])
601 lfileslist = getattr(repo, '_lfilestoupdate', [])
602 lfileslist.append(lfutil.splitstandin(f))
602 lfileslist.append(lfutil.splitstandin(f))
603 repo._lfilestoupdate = lfileslist
603 repo._lfilestoupdate = lfileslist
604 return True
604 return True
605 else:
605 else:
606 return False
606 return False
607 return origmatchfn(f)
607 return origmatchfn(f)
608 m.matchfn = matchfn
608 m.matchfn = matchfn
609 return m
609 return m
610 oldmatch = installmatchfn(overridematch)
610 oldmatch = installmatchfn(overridematch)
611 scmutil.match
611 scmutil.match
612 matches = overridematch(repo[None], pats, opts)
612 matches = overridematch(repo[None], pats, opts)
613 orig(ui, repo, *pats, **opts)
613 orig(ui, repo, *pats, **opts)
614 finally:
614 finally:
615 restorematchfn()
615 restorematchfn()
616 lfileslist = getattr(repo, '_lfilestoupdate', [])
616 lfileslist = getattr(repo, '_lfilestoupdate', [])
617 lfcommands.updatelfiles(ui, repo, filelist=lfileslist,
617 lfcommands.updatelfiles(ui, repo, filelist=lfileslist,
618 printmessage=False)
618 printmessage=False)
619
619
620 # empty out the largefiles list so we start fresh next time
620 # empty out the largefiles list so we start fresh next time
621 repo._lfilestoupdate = []
621 repo._lfilestoupdate = []
622 for lfile in modified:
622 for lfile in modified:
623 if lfile in lfileslist:
623 if lfile in lfileslist:
624 if os.path.exists(repo.wjoin(lfutil.standin(lfile))) and lfile\
624 if os.path.exists(repo.wjoin(lfutil.standin(lfile))) and lfile\
625 in repo['.']:
625 in repo['.']:
626 lfutil.writestandin(repo, lfutil.standin(lfile),
626 lfutil.writestandin(repo, lfutil.standin(lfile),
627 repo['.'][lfile].data().strip(),
627 repo['.'][lfile].data().strip(),
628 'x' in repo['.'][lfile].flags())
628 'x' in repo['.'][lfile].flags())
629 lfdirstate = lfutil.openlfdirstate(ui, repo)
629 lfdirstate = lfutil.openlfdirstate(ui, repo)
630 for lfile in added:
630 for lfile in added:
631 standin = lfutil.standin(lfile)
631 standin = lfutil.standin(lfile)
632 if standin not in ctx and (standin in matches or opts.get('all')):
632 if standin not in ctx and (standin in matches or opts.get('all')):
633 if lfile in lfdirstate:
633 if lfile in lfdirstate:
634 lfdirstate.drop(lfile)
634 lfdirstate.drop(lfile)
635 util.unlinkpath(repo.wjoin(standin))
635 util.unlinkpath(repo.wjoin(standin))
636 lfdirstate.write()
636 lfdirstate.write()
637 finally:
637 finally:
638 wlock.release()
638 wlock.release()
639
639
640 def hgupdate(orig, repo, node):
640 def hgupdate(orig, repo, node):
641 # Only call updatelfiles the standins that have changed to save time
641 # Only call updatelfiles the standins that have changed to save time
642 oldstandins = lfutil.getstandinsstate(repo)
642 oldstandins = lfutil.getstandinsstate(repo)
643 result = orig(repo, node)
643 result = orig(repo, node)
644 newstandins = lfutil.getstandinsstate(repo)
644 newstandins = lfutil.getstandinsstate(repo)
645 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
645 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
646 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist, printmessage=True)
646 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist, printmessage=True)
647 return result
647 return result
648
648
649 def hgclean(orig, repo, node, show_stats=True):
649 def hgclean(orig, repo, node, show_stats=True):
650 result = orig(repo, node, show_stats)
650 result = orig(repo, node, show_stats)
651 lfcommands.updatelfiles(repo.ui, repo)
651 lfcommands.updatelfiles(repo.ui, repo)
652 return result
652 return result
653
653
654 def hgmerge(orig, repo, node, force=None, remind=True):
654 def hgmerge(orig, repo, node, force=None, remind=True):
655 # Mark the repo as being in the middle of a merge, so that
655 # Mark the repo as being in the middle of a merge, so that
656 # updatelfiles() will know that it needs to trust the standins in
656 # updatelfiles() will know that it needs to trust the standins in
657 # the working copy, not in the standins in the current node
657 # the working copy, not in the standins in the current node
658 repo._ismerging = True
658 repo._ismerging = True
659 try:
659 try:
660 result = orig(repo, node, force, remind)
660 result = orig(repo, node, force, remind)
661 lfcommands.updatelfiles(repo.ui, repo)
661 lfcommands.updatelfiles(repo.ui, repo)
662 finally:
662 finally:
663 repo._ismerging = False
663 repo._ismerging = False
664 return result
664 return result
665
665
666 # When we rebase a repository with remotely changed largefiles, we need to
666 # When we rebase a repository with remotely changed largefiles, we need to
667 # take some extra care so that the largefiles are correctly updated in the
667 # take some extra care so that the largefiles are correctly updated in the
668 # working copy
668 # working copy
669 def overridepull(orig, ui, repo, source=None, **opts):
669 def overridepull(orig, ui, repo, source=None, **opts):
670 revsprepull = len(repo)
670 revsprepull = len(repo)
671 if opts.get('rebase', False):
671 if opts.get('rebase', False):
672 repo._isrebasing = True
672 repo._isrebasing = True
673 try:
673 try:
674 if opts.get('update'):
674 if opts.get('update'):
675 del opts['update']
675 del opts['update']
676 ui.debug('--update and --rebase are not compatible, ignoring '
676 ui.debug('--update and --rebase are not compatible, ignoring '
677 'the update flag\n')
677 'the update flag\n')
678 del opts['rebase']
678 del opts['rebase']
679 cmdutil.bailifchanged(repo)
679 cmdutil.bailifchanged(repo)
680 origpostincoming = commands.postincoming
680 origpostincoming = commands.postincoming
681 def _dummy(*args, **kwargs):
681 def _dummy(*args, **kwargs):
682 pass
682 pass
683 commands.postincoming = _dummy
683 commands.postincoming = _dummy
684 repo.lfpullsource = source
684 repo.lfpullsource = source
685 if not source:
685 if not source:
686 source = 'default'
686 source = 'default'
687 try:
687 try:
688 result = commands.pull(ui, repo, source, **opts)
688 result = commands.pull(ui, repo, source, **opts)
689 finally:
689 finally:
690 commands.postincoming = origpostincoming
690 commands.postincoming = origpostincoming
691 revspostpull = len(repo)
691 revspostpull = len(repo)
692 if revspostpull > revsprepull:
692 if revspostpull > revsprepull:
693 result = result or rebase.rebase(ui, repo)
693 result = result or rebase.rebase(ui, repo)
694 finally:
694 finally:
695 repo._isrebasing = False
695 repo._isrebasing = False
696 else:
696 else:
697 repo.lfpullsource = source
697 repo.lfpullsource = source
698 if not source:
698 if not source:
699 source = 'default'
699 source = 'default'
700 oldheads = lfutil.getcurrentheads(repo)
700 oldheads = lfutil.getcurrentheads(repo)
701 result = orig(ui, repo, source, **opts)
701 result = orig(ui, repo, source, **opts)
702 # If we do not have the new largefiles for any new heads we pulled, we
702 # If we do not have the new largefiles for any new heads we pulled, we
703 # will run into a problem later if we try to merge or rebase with one of
703 # will run into a problem later if we try to merge or rebase with one of
704 # these heads, so cache the largefiles now directly into the system
704 # these heads, so cache the largefiles now directly into the system
705 # cache.
705 # cache.
706 ui.status(_("caching new largefiles\n"))
706 ui.status(_("caching new largefiles\n"))
707 numcached = 0
707 numcached = 0
708 heads = lfutil.getcurrentheads(repo)
708 heads = lfutil.getcurrentheads(repo)
709 newheads = set(heads).difference(set(oldheads))
709 newheads = set(heads).difference(set(oldheads))
710 for head in newheads:
710 for head in newheads:
711 (cached, missing) = lfcommands.cachelfiles(ui, repo, head)
711 (cached, missing) = lfcommands.cachelfiles(ui, repo, head)
712 numcached += len(cached)
712 numcached += len(cached)
713 ui.status(_("%d largefiles cached\n") % numcached)
713 ui.status(_("%d largefiles cached\n") % numcached)
714 if opts.get('all_largefiles'):
714 if opts.get('all_largefiles'):
715 revspostpull = len(repo)
715 revspostpull = len(repo)
716 revs = []
716 revs = []
717 for rev in xrange(revsprepull + 1, revspostpull):
717 for rev in xrange(revsprepull + 1, revspostpull):
718 revs.append(repo[rev].rev())
718 revs.append(repo[rev].rev())
719 lfcommands.downloadlfiles(ui, repo, revs)
719 lfcommands.downloadlfiles(ui, repo, revs)
720 return result
720 return result
721
721
722 def overrideclone(orig, ui, source, dest=None, **opts):
722 def overrideclone(orig, ui, source, dest=None, **opts):
723 d = dest
723 d = dest
724 if d is None:
724 if d is None:
725 d = hg.defaultdest(source)
725 d = hg.defaultdest(source)
726 if opts.get('all_largefiles') and not hg.islocal(d):
726 if opts.get('all_largefiles') and not hg.islocal(d):
727 raise util.Abort(_(
727 raise util.Abort(_(
728 '--all-largefiles is incompatible with non-local destination %s' %
728 '--all-largefiles is incompatible with non-local destination %s' %
729 d))
729 d))
730
730
731 return orig(ui, source, dest, **opts)
731 return orig(ui, source, dest, **opts)
732
732
733 def hgclone(orig, ui, opts, *args, **kwargs):
733 def hgclone(orig, ui, opts, *args, **kwargs):
734 result = orig(ui, opts, *args, **kwargs)
734 result = orig(ui, opts, *args, **kwargs)
735
735
736 if result is not None and opts.get('all_largefiles'):
736 if result is not None and opts.get('all_largefiles'):
737 sourcerepo, destrepo = result
737 sourcerepo, destrepo = result
738 repo = destrepo.local()
738 repo = destrepo.local()
739
739
740 # The .hglf directory must exist for the standin matcher to match
740 # The .hglf directory must exist for the standin matcher to match
741 # anything (which listlfiles uses for each rev), and .hg/largefiles is
741 # anything (which listlfiles uses for each rev), and .hg/largefiles is
742 # assumed to exist by the code that caches the downloaded file. These
742 # assumed to exist by the code that caches the downloaded file. These
743 # directories exist if clone updated to any rev.
743 # directories exist if clone updated to any rev.
744 if opts.get('noupdate'):
744 if opts.get('noupdate'):
745 util.makedirs(repo.pathto(lfutil.shortname))
745 util.makedirs(repo.pathto(lfutil.shortname))
746 util.makedirs(repo.join(lfutil.longname))
746 util.makedirs(repo.join(lfutil.longname))
747
747
748 # Caching is implicitly limited to 'rev' option, since the dest repo was
748 # Caching is implicitly limited to 'rev' option, since the dest repo was
749 # truncated at that point.
749 # truncated at that point.
750 success, missing = lfcommands.downloadlfiles(ui, repo, None)
750 success, missing = lfcommands.downloadlfiles(ui, repo, None)
751
751
752 if missing != 0:
752 if missing != 0:
753 return None
753 return None
754
754
755 return result
755 return result
756
756
757 def overriderebase(orig, ui, repo, **opts):
757 def overriderebase(orig, ui, repo, **opts):
758 repo._isrebasing = True
758 repo._isrebasing = True
759 try:
759 try:
760 return orig(ui, repo, **opts)
760 return orig(ui, repo, **opts)
761 finally:
761 finally:
762 repo._isrebasing = False
762 repo._isrebasing = False
763
763
764 def overridearchive(orig, repo, dest, node, kind, decode=True, matchfn=None,
764 def overridearchive(orig, repo, dest, node, kind, decode=True, matchfn=None,
765 prefix=None, mtime=None, subrepos=None):
765 prefix=None, mtime=None, subrepos=None):
766 # No need to lock because we are only reading history and
766 # No need to lock because we are only reading history and
767 # largefile caches, neither of which are modified.
767 # largefile caches, neither of which are modified.
768 lfcommands.cachelfiles(repo.ui, repo, node)
768 lfcommands.cachelfiles(repo.ui, repo, node)
769
769
770 if kind not in archival.archivers:
770 if kind not in archival.archivers:
771 raise util.Abort(_("unknown archive type '%s'") % kind)
771 raise util.Abort(_("unknown archive type '%s'") % kind)
772
772
773 ctx = repo[node]
773 ctx = repo[node]
774
774
775 if kind == 'files':
775 if kind == 'files':
776 if prefix:
776 if prefix:
777 raise util.Abort(
777 raise util.Abort(
778 _('cannot give prefix when archiving to files'))
778 _('cannot give prefix when archiving to files'))
779 else:
779 else:
780 prefix = archival.tidyprefix(dest, kind, prefix)
780 prefix = archival.tidyprefix(dest, kind, prefix)
781
781
782 def write(name, mode, islink, getdata):
782 def write(name, mode, islink, getdata):
783 if matchfn and not matchfn(name):
783 if matchfn and not matchfn(name):
784 return
784 return
785 data = getdata()
785 data = getdata()
786 if decode:
786 if decode:
787 data = repo.wwritedata(name, data)
787 data = repo.wwritedata(name, data)
788 archiver.addfile(prefix + name, mode, islink, data)
788 archiver.addfile(prefix + name, mode, islink, data)
789
789
790 archiver = archival.archivers[kind](dest, mtime or ctx.date()[0])
790 archiver = archival.archivers[kind](dest, mtime or ctx.date()[0])
791
791
792 if repo.ui.configbool("ui", "archivemeta", True):
792 if repo.ui.configbool("ui", "archivemeta", True):
793 def metadata():
793 def metadata():
794 base = 'repo: %s\nnode: %s\nbranch: %s\n' % (
794 base = 'repo: %s\nnode: %s\nbranch: %s\n' % (
795 hex(repo.changelog.node(0)), hex(node), ctx.branch())
795 hex(repo.changelog.node(0)), hex(node), ctx.branch())
796
796
797 tags = ''.join('tag: %s\n' % t for t in ctx.tags()
797 tags = ''.join('tag: %s\n' % t for t in ctx.tags()
798 if repo.tagtype(t) == 'global')
798 if repo.tagtype(t) == 'global')
799 if not tags:
799 if not tags:
800 repo.ui.pushbuffer()
800 repo.ui.pushbuffer()
801 opts = {'template': '{latesttag}\n{latesttagdistance}',
801 opts = {'template': '{latesttag}\n{latesttagdistance}',
802 'style': '', 'patch': None, 'git': None}
802 'style': '', 'patch': None, 'git': None}
803 cmdutil.show_changeset(repo.ui, repo, opts).show(ctx)
803 cmdutil.show_changeset(repo.ui, repo, opts).show(ctx)
804 ltags, dist = repo.ui.popbuffer().split('\n')
804 ltags, dist = repo.ui.popbuffer().split('\n')
805 tags = ''.join('latesttag: %s\n' % t for t in ltags.split(':'))
805 tags = ''.join('latesttag: %s\n' % t for t in ltags.split(':'))
806 tags += 'latesttagdistance: %s\n' % dist
806 tags += 'latesttagdistance: %s\n' % dist
807
807
808 return base + tags
808 return base + tags
809
809
810 write('.hg_archival.txt', 0644, False, metadata)
810 write('.hg_archival.txt', 0644, False, metadata)
811
811
812 for f in ctx:
812 for f in ctx:
813 ff = ctx.flags(f)
813 ff = ctx.flags(f)
814 getdata = ctx[f].data
814 getdata = ctx[f].data
815 if lfutil.isstandin(f):
815 if lfutil.isstandin(f):
816 path = lfutil.findfile(repo, getdata().strip())
816 path = lfutil.findfile(repo, getdata().strip())
817 if path is None:
817 if path is None:
818 raise util.Abort(
818 raise util.Abort(
819 _('largefile %s not found in repo store or system cache')
819 _('largefile %s not found in repo store or system cache')
820 % lfutil.splitstandin(f))
820 % lfutil.splitstandin(f))
821 f = lfutil.splitstandin(f)
821 f = lfutil.splitstandin(f)
822
822
823 def getdatafn():
823 def getdatafn():
824 fd = None
824 fd = None
825 try:
825 try:
826 fd = open(path, 'rb')
826 fd = open(path, 'rb')
827 return fd.read()
827 return fd.read()
828 finally:
828 finally:
829 if fd:
829 if fd:
830 fd.close()
830 fd.close()
831
831
832 getdata = getdatafn
832 getdata = getdatafn
833 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
833 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
834
834
835 if subrepos:
835 if subrepos:
836 for subpath in ctx.substate:
836 for subpath in ctx.substate:
837 sub = ctx.sub(subpath)
837 sub = ctx.sub(subpath)
838 submatch = match_.narrowmatcher(subpath, matchfn)
838 submatch = match_.narrowmatcher(subpath, matchfn)
839 sub.archive(repo.ui, archiver, prefix, submatch)
839 sub.archive(repo.ui, archiver, prefix, submatch)
840
840
841 archiver.done()
841 archiver.done()
842
842
843 def hgsubrepoarchive(orig, repo, ui, archiver, prefix, match=None):
843 def hgsubrepoarchive(orig, repo, ui, archiver, prefix, match=None):
844 repo._get(repo._state + ('hg',))
844 rev = repo._state[1]
845 rev = repo._state[1]
845 ctx = repo._repo[rev]
846 ctx = repo._repo[rev]
846
847
847 lfcommands.cachelfiles(ui, repo._repo, ctx.node())
848 lfcommands.cachelfiles(ui, repo._repo, ctx.node())
848
849
849 def write(name, mode, islink, getdata):
850 def write(name, mode, islink, getdata):
850 # At this point, the standin has been replaced with the largefile name,
851 # At this point, the standin has been replaced with the largefile name,
851 # so the normal matcher works here without the lfutil variants.
852 # so the normal matcher works here without the lfutil variants.
852 if match and not match(f):
853 if match and not match(f):
853 return
854 return
854 data = getdata()
855 data = getdata()
855
856
856 archiver.addfile(prefix + repo._path + '/' + name, mode, islink, data)
857 archiver.addfile(prefix + repo._path + '/' + name, mode, islink, data)
857
858
858 for f in ctx:
859 for f in ctx:
859 ff = ctx.flags(f)
860 ff = ctx.flags(f)
860 getdata = ctx[f].data
861 getdata = ctx[f].data
861 if lfutil.isstandin(f):
862 if lfutil.isstandin(f):
862 path = lfutil.findfile(repo._repo, getdata().strip())
863 path = lfutil.findfile(repo._repo, getdata().strip())
863 if path is None:
864 if path is None:
864 raise util.Abort(
865 raise util.Abort(
865 _('largefile %s not found in repo store or system cache')
866 _('largefile %s not found in repo store or system cache')
866 % lfutil.splitstandin(f))
867 % lfutil.splitstandin(f))
867 f = lfutil.splitstandin(f)
868 f = lfutil.splitstandin(f)
868
869
869 def getdatafn():
870 def getdatafn():
870 fd = None
871 fd = None
871 try:
872 try:
872 fd = open(os.path.join(prefix, path), 'rb')
873 fd = open(os.path.join(prefix, path), 'rb')
873 return fd.read()
874 return fd.read()
874 finally:
875 finally:
875 if fd:
876 if fd:
876 fd.close()
877 fd.close()
877
878
878 getdata = getdatafn
879 getdata = getdatafn
879
880
880 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
881 write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
881
882
882 for subpath in ctx.substate:
883 for subpath in ctx.substate:
883 sub = ctx.sub(subpath)
884 sub = ctx.sub(subpath)
884 submatch = match_.narrowmatcher(subpath, match)
885 submatch = match_.narrowmatcher(subpath, match)
885 sub.archive(ui, archiver, os.path.join(prefix, repo._path) + '/',
886 sub.archive(ui, archiver, os.path.join(prefix, repo._path) + '/',
886 submatch)
887 submatch)
887
888
888 # If a largefile is modified, the change is not reflected in its
889 # If a largefile is modified, the change is not reflected in its
889 # standin until a commit. cmdutil.bailifchanged() raises an exception
890 # standin until a commit. cmdutil.bailifchanged() raises an exception
890 # if the repo has uncommitted changes. Wrap it to also check if
891 # if the repo has uncommitted changes. Wrap it to also check if
891 # largefiles were changed. This is used by bisect and backout.
892 # largefiles were changed. This is used by bisect and backout.
892 def overridebailifchanged(orig, repo):
893 def overridebailifchanged(orig, repo):
893 orig(repo)
894 orig(repo)
894 repo.lfstatus = True
895 repo.lfstatus = True
895 modified, added, removed, deleted = repo.status()[:4]
896 modified, added, removed, deleted = repo.status()[:4]
896 repo.lfstatus = False
897 repo.lfstatus = False
897 if modified or added or removed or deleted:
898 if modified or added or removed or deleted:
898 raise util.Abort(_('outstanding uncommitted changes'))
899 raise util.Abort(_('outstanding uncommitted changes'))
899
900
900 # Fetch doesn't use cmdutil.bailifchanged so override it to add the check
901 # Fetch doesn't use cmdutil.bailifchanged so override it to add the check
901 def overridefetch(orig, ui, repo, *pats, **opts):
902 def overridefetch(orig, ui, repo, *pats, **opts):
902 repo.lfstatus = True
903 repo.lfstatus = True
903 modified, added, removed, deleted = repo.status()[:4]
904 modified, added, removed, deleted = repo.status()[:4]
904 repo.lfstatus = False
905 repo.lfstatus = False
905 if modified or added or removed or deleted:
906 if modified or added or removed or deleted:
906 raise util.Abort(_('outstanding uncommitted changes'))
907 raise util.Abort(_('outstanding uncommitted changes'))
907 return orig(ui, repo, *pats, **opts)
908 return orig(ui, repo, *pats, **opts)
908
909
909 def overrideforget(orig, ui, repo, *pats, **opts):
910 def overrideforget(orig, ui, repo, *pats, **opts):
910 installnormalfilesmatchfn(repo[None].manifest())
911 installnormalfilesmatchfn(repo[None].manifest())
911 result = orig(ui, repo, *pats, **opts)
912 result = orig(ui, repo, *pats, **opts)
912 restorematchfn()
913 restorematchfn()
913 m = scmutil.match(repo[None], pats, opts)
914 m = scmutil.match(repo[None], pats, opts)
914
915
915 try:
916 try:
916 repo.lfstatus = True
917 repo.lfstatus = True
917 s = repo.status(match=m, clean=True)
918 s = repo.status(match=m, clean=True)
918 finally:
919 finally:
919 repo.lfstatus = False
920 repo.lfstatus = False
920 forget = sorted(s[0] + s[1] + s[3] + s[6])
921 forget = sorted(s[0] + s[1] + s[3] + s[6])
921 forget = [f for f in forget if lfutil.standin(f) in repo[None].manifest()]
922 forget = [f for f in forget if lfutil.standin(f) in repo[None].manifest()]
922
923
923 for f in forget:
924 for f in forget:
924 if lfutil.standin(f) not in repo.dirstate and not \
925 if lfutil.standin(f) not in repo.dirstate and not \
925 os.path.isdir(m.rel(lfutil.standin(f))):
926 os.path.isdir(m.rel(lfutil.standin(f))):
926 ui.warn(_('not removing %s: file is already untracked\n')
927 ui.warn(_('not removing %s: file is already untracked\n')
927 % m.rel(f))
928 % m.rel(f))
928 result = 1
929 result = 1
929
930
930 for f in forget:
931 for f in forget:
931 if ui.verbose or not m.exact(f):
932 if ui.verbose or not m.exact(f):
932 ui.status(_('removing %s\n') % m.rel(f))
933 ui.status(_('removing %s\n') % m.rel(f))
933
934
934 # Need to lock because standin files are deleted then removed from the
935 # Need to lock because standin files are deleted then removed from the
935 # repository and we could race in-between.
936 # repository and we could race in-between.
936 wlock = repo.wlock()
937 wlock = repo.wlock()
937 try:
938 try:
938 lfdirstate = lfutil.openlfdirstate(ui, repo)
939 lfdirstate = lfutil.openlfdirstate(ui, repo)
939 for f in forget:
940 for f in forget:
940 if lfdirstate[f] == 'a':
941 if lfdirstate[f] == 'a':
941 lfdirstate.drop(f)
942 lfdirstate.drop(f)
942 else:
943 else:
943 lfdirstate.remove(f)
944 lfdirstate.remove(f)
944 lfdirstate.write()
945 lfdirstate.write()
945 lfutil.reporemove(repo, [lfutil.standin(f) for f in forget],
946 lfutil.reporemove(repo, [lfutil.standin(f) for f in forget],
946 unlink=True)
947 unlink=True)
947 finally:
948 finally:
948 wlock.release()
949 wlock.release()
949
950
950 return result
951 return result
951
952
952 def getoutgoinglfiles(ui, repo, dest=None, **opts):
953 def getoutgoinglfiles(ui, repo, dest=None, **opts):
953 dest = ui.expandpath(dest or 'default-push', dest or 'default')
954 dest = ui.expandpath(dest or 'default-push', dest or 'default')
954 dest, branches = hg.parseurl(dest, opts.get('branch'))
955 dest, branches = hg.parseurl(dest, opts.get('branch'))
955 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
956 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
956 if revs:
957 if revs:
957 revs = [repo.lookup(rev) for rev in scmutil.revrange(repo, revs)]
958 revs = [repo.lookup(rev) for rev in scmutil.revrange(repo, revs)]
958
959
959 try:
960 try:
960 remote = hg.peer(repo, opts, dest)
961 remote = hg.peer(repo, opts, dest)
961 except error.RepoError:
962 except error.RepoError:
962 return None
963 return None
963 o = lfutil.findoutgoing(repo, remote, False)
964 o = lfutil.findoutgoing(repo, remote, False)
964 if not o:
965 if not o:
965 return None
966 return None
966 o = repo.changelog.nodesbetween(o, revs)[0]
967 o = repo.changelog.nodesbetween(o, revs)[0]
967 if opts.get('newest_first'):
968 if opts.get('newest_first'):
968 o.reverse()
969 o.reverse()
969
970
970 toupload = set()
971 toupload = set()
971 for n in o:
972 for n in o:
972 parents = [p for p in repo.changelog.parents(n) if p != node.nullid]
973 parents = [p for p in repo.changelog.parents(n) if p != node.nullid]
973 ctx = repo[n]
974 ctx = repo[n]
974 files = set(ctx.files())
975 files = set(ctx.files())
975 if len(parents) == 2:
976 if len(parents) == 2:
976 mc = ctx.manifest()
977 mc = ctx.manifest()
977 mp1 = ctx.parents()[0].manifest()
978 mp1 = ctx.parents()[0].manifest()
978 mp2 = ctx.parents()[1].manifest()
979 mp2 = ctx.parents()[1].manifest()
979 for f in mp1:
980 for f in mp1:
980 if f not in mc:
981 if f not in mc:
981 files.add(f)
982 files.add(f)
982 for f in mp2:
983 for f in mp2:
983 if f not in mc:
984 if f not in mc:
984 files.add(f)
985 files.add(f)
985 for f in mc:
986 for f in mc:
986 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
987 if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
987 files.add(f)
988 files.add(f)
988 toupload = toupload.union(
989 toupload = toupload.union(
989 set([f for f in files if lfutil.isstandin(f) and f in ctx]))
990 set([f for f in files if lfutil.isstandin(f) and f in ctx]))
990 return toupload
991 return toupload
991
992
992 def overrideoutgoing(orig, ui, repo, dest=None, **opts):
993 def overrideoutgoing(orig, ui, repo, dest=None, **opts):
993 result = orig(ui, repo, dest, **opts)
994 result = orig(ui, repo, dest, **opts)
994
995
995 if opts.pop('large', None):
996 if opts.pop('large', None):
996 toupload = getoutgoinglfiles(ui, repo, dest, **opts)
997 toupload = getoutgoinglfiles(ui, repo, dest, **opts)
997 if toupload is None:
998 if toupload is None:
998 ui.status(_('largefiles: No remote repo\n'))
999 ui.status(_('largefiles: No remote repo\n'))
999 else:
1000 else:
1000 ui.status(_('largefiles to upload:\n'))
1001 ui.status(_('largefiles to upload:\n'))
1001 for file in toupload:
1002 for file in toupload:
1002 ui.status(lfutil.splitstandin(file) + '\n')
1003 ui.status(lfutil.splitstandin(file) + '\n')
1003 ui.status('\n')
1004 ui.status('\n')
1004
1005
1005 return result
1006 return result
1006
1007
1007 def overridesummary(orig, ui, repo, *pats, **opts):
1008 def overridesummary(orig, ui, repo, *pats, **opts):
1008 try:
1009 try:
1009 repo.lfstatus = True
1010 repo.lfstatus = True
1010 orig(ui, repo, *pats, **opts)
1011 orig(ui, repo, *pats, **opts)
1011 finally:
1012 finally:
1012 repo.lfstatus = False
1013 repo.lfstatus = False
1013
1014
1014 if opts.pop('large', None):
1015 if opts.pop('large', None):
1015 toupload = getoutgoinglfiles(ui, repo, None, **opts)
1016 toupload = getoutgoinglfiles(ui, repo, None, **opts)
1016 if toupload is None:
1017 if toupload is None:
1017 ui.status(_('largefiles: No remote repo\n'))
1018 ui.status(_('largefiles: No remote repo\n'))
1018 else:
1019 else:
1019 ui.status(_('largefiles: %d to upload\n') % len(toupload))
1020 ui.status(_('largefiles: %d to upload\n') % len(toupload))
1020
1021
1021 def scmutiladdremove(orig, repo, pats=[], opts={}, dry_run=None,
1022 def scmutiladdremove(orig, repo, pats=[], opts={}, dry_run=None,
1022 similarity=None):
1023 similarity=None):
1023 if not lfutil.islfilesrepo(repo):
1024 if not lfutil.islfilesrepo(repo):
1024 return orig(repo, pats, opts, dry_run, similarity)
1025 return orig(repo, pats, opts, dry_run, similarity)
1025 # Get the list of missing largefiles so we can remove them
1026 # Get the list of missing largefiles so we can remove them
1026 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
1027 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
1027 s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False,
1028 s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False,
1028 False, False)
1029 False, False)
1029 (unsure, modified, added, removed, missing, unknown, ignored, clean) = s
1030 (unsure, modified, added, removed, missing, unknown, ignored, clean) = s
1030
1031
1031 # Call into the normal remove code, but the removing of the standin, we want
1032 # Call into the normal remove code, but the removing of the standin, we want
1032 # to have handled by original addremove. Monkey patching here makes sure
1033 # to have handled by original addremove. Monkey patching here makes sure
1033 # we don't remove the standin in the largefiles code, preventing a very
1034 # we don't remove the standin in the largefiles code, preventing a very
1034 # confused state later.
1035 # confused state later.
1035 if missing:
1036 if missing:
1036 m = [repo.wjoin(f) for f in missing]
1037 m = [repo.wjoin(f) for f in missing]
1037 repo._isaddremove = True
1038 repo._isaddremove = True
1038 removelargefiles(repo.ui, repo, *m, **opts)
1039 removelargefiles(repo.ui, repo, *m, **opts)
1039 repo._isaddremove = False
1040 repo._isaddremove = False
1040 # Call into the normal add code, and any files that *should* be added as
1041 # Call into the normal add code, and any files that *should* be added as
1041 # largefiles will be
1042 # largefiles will be
1042 addlargefiles(repo.ui, repo, *pats, **opts)
1043 addlargefiles(repo.ui, repo, *pats, **opts)
1043 # Now that we've handled largefiles, hand off to the original addremove
1044 # Now that we've handled largefiles, hand off to the original addremove
1044 # function to take care of the rest. Make sure it doesn't do anything with
1045 # function to take care of the rest. Make sure it doesn't do anything with
1045 # largefiles by installing a matcher that will ignore them.
1046 # largefiles by installing a matcher that will ignore them.
1046 installnormalfilesmatchfn(repo[None].manifest())
1047 installnormalfilesmatchfn(repo[None].manifest())
1047 result = orig(repo, pats, opts, dry_run, similarity)
1048 result = orig(repo, pats, opts, dry_run, similarity)
1048 restorematchfn()
1049 restorematchfn()
1049 return result
1050 return result
1050
1051
1051 # Calling purge with --all will cause the largefiles to be deleted.
1052 # Calling purge with --all will cause the largefiles to be deleted.
1052 # Override repo.status to prevent this from happening.
1053 # Override repo.status to prevent this from happening.
1053 def overridepurge(orig, ui, repo, *dirs, **opts):
1054 def overridepurge(orig, ui, repo, *dirs, **opts):
1054 oldstatus = repo.status
1055 oldstatus = repo.status
1055 def overridestatus(node1='.', node2=None, match=None, ignored=False,
1056 def overridestatus(node1='.', node2=None, match=None, ignored=False,
1056 clean=False, unknown=False, listsubrepos=False):
1057 clean=False, unknown=False, listsubrepos=False):
1057 r = oldstatus(node1, node2, match, ignored, clean, unknown,
1058 r = oldstatus(node1, node2, match, ignored, clean, unknown,
1058 listsubrepos)
1059 listsubrepos)
1059 lfdirstate = lfutil.openlfdirstate(ui, repo)
1060 lfdirstate = lfutil.openlfdirstate(ui, repo)
1060 modified, added, removed, deleted, unknown, ignored, clean = r
1061 modified, added, removed, deleted, unknown, ignored, clean = r
1061 unknown = [f for f in unknown if lfdirstate[f] == '?']
1062 unknown = [f for f in unknown if lfdirstate[f] == '?']
1062 ignored = [f for f in ignored if lfdirstate[f] == '?']
1063 ignored = [f for f in ignored if lfdirstate[f] == '?']
1063 return modified, added, removed, deleted, unknown, ignored, clean
1064 return modified, added, removed, deleted, unknown, ignored, clean
1064 repo.status = overridestatus
1065 repo.status = overridestatus
1065 orig(ui, repo, *dirs, **opts)
1066 orig(ui, repo, *dirs, **opts)
1066 repo.status = oldstatus
1067 repo.status = oldstatus
1067
1068
1068 def overriderollback(orig, ui, repo, **opts):
1069 def overriderollback(orig, ui, repo, **opts):
1069 result = orig(ui, repo, **opts)
1070 result = orig(ui, repo, **opts)
1070 merge.update(repo, node=None, branchmerge=False, force=True,
1071 merge.update(repo, node=None, branchmerge=False, force=True,
1071 partial=lfutil.isstandin)
1072 partial=lfutil.isstandin)
1072 wlock = repo.wlock()
1073 wlock = repo.wlock()
1073 try:
1074 try:
1074 lfdirstate = lfutil.openlfdirstate(ui, repo)
1075 lfdirstate = lfutil.openlfdirstate(ui, repo)
1075 lfiles = lfutil.listlfiles(repo)
1076 lfiles = lfutil.listlfiles(repo)
1076 oldlfiles = lfutil.listlfiles(repo, repo[None].parents()[0].rev())
1077 oldlfiles = lfutil.listlfiles(repo, repo[None].parents()[0].rev())
1077 for file in lfiles:
1078 for file in lfiles:
1078 if file in oldlfiles:
1079 if file in oldlfiles:
1079 lfdirstate.normallookup(file)
1080 lfdirstate.normallookup(file)
1080 else:
1081 else:
1081 lfdirstate.add(file)
1082 lfdirstate.add(file)
1082 lfdirstate.write()
1083 lfdirstate.write()
1083 finally:
1084 finally:
1084 wlock.release()
1085 wlock.release()
1085 return result
1086 return result
1086
1087
1087 def overridetransplant(orig, ui, repo, *revs, **opts):
1088 def overridetransplant(orig, ui, repo, *revs, **opts):
1088 try:
1089 try:
1089 oldstandins = lfutil.getstandinsstate(repo)
1090 oldstandins = lfutil.getstandinsstate(repo)
1090 repo._istransplanting = True
1091 repo._istransplanting = True
1091 result = orig(ui, repo, *revs, **opts)
1092 result = orig(ui, repo, *revs, **opts)
1092 newstandins = lfutil.getstandinsstate(repo)
1093 newstandins = lfutil.getstandinsstate(repo)
1093 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
1094 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
1094 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
1095 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
1095 printmessage=True)
1096 printmessage=True)
1096 finally:
1097 finally:
1097 repo._istransplanting = False
1098 repo._istransplanting = False
1098 return result
1099 return result
1099
1100
1100 def overridecat(orig, ui, repo, file1, *pats, **opts):
1101 def overridecat(orig, ui, repo, file1, *pats, **opts):
1101 ctx = scmutil.revsingle(repo, opts.get('rev'))
1102 ctx = scmutil.revsingle(repo, opts.get('rev'))
1102 if not lfutil.standin(file1) in ctx:
1103 if not lfutil.standin(file1) in ctx:
1103 result = orig(ui, repo, file1, *pats, **opts)
1104 result = orig(ui, repo, file1, *pats, **opts)
1104 return result
1105 return result
1105 return lfcommands.catlfile(repo, file1, ctx.rev(), opts.get('output'))
1106 return lfcommands.catlfile(repo, file1, ctx.rev(), opts.get('output'))
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now