1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172
|
#compdef git git-add git-am git-annotate git-apply git-applymbox git-applypatch git-archimport git-archive git-bisect git-blame git-branch git-cat-file git-check-attr git-check-ref-format git-checkout git-checkout-index git-cherry git-cherry-pick git-clean git-clone git-clone-pack git-commit git-commit-tree git-convert-objects git-count-objects git-cvsexportcommit git-cvsimport git-cvsserver git-daemon git-describe git-diff git-diff-files git-diff-index git-diff-stages git-diff-tree git-fast-import git-fetch git-fetch-pack git-fmt-merge-msg git-for-each-ref git-format-patch git-fsck git-gc git-get-tar-commit-id git-grep git-hash-object git-http-fetch git-http-push git-imap-send git-index-pack git-init git-instaweb git-local-fetch git-log git-lost-found git-ls-files git-ls-remote git-ls-tree git-mailinfo git-mailsplit git-merge git-merge-base git-merge-file git-merge-index git-merge-one-file git-merge-tree git-mergetool git-mktag git-mktree git-mv git-name-rev git-octopus git-pack-objects git-pack-redundant git-pack-refs git-patch-id git-peek-remote git-prune git-prune-packed git-pull git-push git-quiltimport git-read-tree git-rebase git-receive-pack git-reflog git-relink git-remote git-repack gut-runstatus git-config git-request-pull git-rerere git-reset git-rev-list git-rev-parse git-revert git-rm git-send-email git-send-pack git-sh-setup git-shell git-shortlog git-show git-show-branch git-show-index git-show-ref git-ssh-fetch git-ssh-upload git-status git-stripspace git-svn git-svnimport git-symbolic-ref git-tag git-tar-tree git-unpack-file git-unpack-objects git-update-index git-update-ref git-update-server-info git-upload-archive git-upload-pack git-var git-verify-pack git-verify-tag git-whatchanged git-write-tree
# TODO: All if (( words[(I)-option] )) should be turned into
# if (( words[(I)-option] > 0 && words[(I)-option] < CURRENT )), as the user
# may go back and want to add an option before -option and in that case should
# be able to complete whatever may come before -option.
# TODO: suggested zstyles:
#
# zstyle ':completion::*:git-{name-rev,add,rm}:*' ignore-line true
_git() {
local nul_arg abbrev_arg find_copies_harder_arg diff_l_arg pretty_arg exec_arg
local author_conversion_file_arg long_author_conversion_file_arg verbose_arg
local help_arg template_arg shared_arg thin_arg author_conversion_file_arg_spec
local -a diff_args fetch_args merge_args force_ref_arg tags_fetch_arg
local -a upload_pack_arg common_fetch_args common_apply_args
local -a revision_arguments
nul_arg='-z[use NUL termination on output]'
abbrev_arg='--abbrev=-[set minimum SHA1 display-length]: :_guard "[[\:digit\:]]#" length'
find_copies_harder_arg='--find-copies-harder[try harder to find copies]'
diff_l_arg='-l-[limit number of rename/copy targets to run]: :_guard "[[\:digit\:]]#" number'
diff_args=(
'--diff-filter=-[select certain kinds of files for diff]: :_guard "[ACDMRTUXB*]#" kinds'
$find_copies_harder_arg
'(--name-only --name-status -u -p --stat --patch-with-stat --patch-with-raw --raw --numstat --shortstat --summary)--name-only[show only names of changed files]'
'(--name-only --name-status -u -p --stat --patch-with-stat --patch-with-raw --raw --numstat --shortstat --summary)--name-status[show only names and status of changed files]'
'(--name-only --name-status -u -p --stat --patch-with-stat --patch-with-raw --raw --numstat --shortstat --summary)'{-u,-p}'[generate diff in patch format]'
'(--name-only --name-status -u -p --stat --patch-with-stat --patch-with-raw --raw --numstat --shortstat --summary)--stat=-[generate a diffstat instead of a patch]:: :__git_guard_diff-stat-width' \
'(--name-only --name-status -u -p --stat --patch-with-stat --patch-with-raw --raw --numstat --shortstat --summary)--patch-with-stat[generate patch and prepend its diffstat]' \
'(--name-only --name-status -u -p --stat --patch-with-stat --patch-with-raw --raw --numstat --shortstat --summary)--patch-with-raw[generate patch but also keep the default raw diff output]' \
'(--name-only --name-status -u -p --stat --patch-with-stat --patch-with-raw --raw --numstat --shortstat --summary)--raw[generate the default raw diff output]' \
'(--name-only --name-status -u -p --stat --patch-with-stat --patch-with-raw --raw --numstat --shortstat --summary)--numstat[generate a more machine-friendly diffstat]' \
'(--name-only --name-status -u -p --stat --patch-with-stat --patch-with-raw --raw --numstat --shortstat --summary)--shortstat[generate a summary diffstat]' \
'(--name-only --name-status -u -p --stat --patch-with-stat --patch-with-raw --raw --numstat --shortstat --summary)--summary[generate a condensed summary of extended header information]' \
'(--name-only --name-status -u -p --stat --patch-with-stat --patch-with-raw --raw --numstat --shortstat --summary)--dirstat[generate a dirstat]' \
'-B-[break complete rewrite changes into pairs of given size]: :_guard "[[\:digit\:]]#" size'
'-C-[detect copies as well as renames with given scope]: :_guard "[[\:digit\:]]#" size'
$diff_l_arg
'-M-[detect renames with given scope]: :_guard "[[\:digit\:]]#" size'
'-O-[output patch in the order of glob-pattern lines in given file]:file:_files'
'-R[do a reverse diff]'
'-S-[look for differences that contain the given string]:string'
'--pickaxe-all[when -S finds a change, show all changes in that changeset]'
'--pickaxe-regex[treat argument of -S as regular expression]'
'--full-index[show full object name of pre- and post-image blob]'
'(--full-index)--binary[in addition to --full-index, output binary diffs for git-apply]'
'( --no-color --color-words)--color[show colored diff]'
'(--color --color-words)--no-color[turn off colored diff]'
'(--color --no-color )--color-words[show colored-word diff]'
'--no-renames[turn off rename detection]'
'--check[warn if changes introduce trailing whitespace or space/tab indents]'
'(-a --text)'{-a,--text}'[treat all files as text]'
'(-b --ignore-space-change -w --ignore-all-space)'{-b,--ignore-space-change}'[ignore changes in amount of white space]'
'(-b --ignore-space-change -w --ignore-all-space)'{-w,--ignore-all-space}'[ignore white space when comparing lines]'
$abbrev_arg
$nul_arg
'--exit-code[report exit code 1 if differences, 0 otherwise]'
'(--exit-code)--quiet[disable all output]'
'--relative=:path:_files -/'
)
pretty_arg='--pretty=-[pretty print commit messages]::pretty print:((raw\:"the raw commits"
medium\:"most parts of the messages"
short\:"few headers and only subject of messages"
full\:"all parts of the commit messages"
oneline\:"commit-ids and subject of messages"))'
exec_arg='--exec=-[specify path to git-upload-pack on remote side]:remote path'
fetch_args=(
'-c[fetch commit objects]'
'-t[fetch trees associated with commit objects]'
'-a[fetch all objects]'
'-v[show what is downloaded]'
'-w[write commit-id into the filename under "$GIT_DIR/refs/<filename>"]:filename'
'--recover[recover from a failed fetch]'
)
# TODO: Add descriptions to strategies (stupid is undocumented).
merge_args=(
'(-n --no-summary)'{-n,--no-summary}'[do not show diffstat at the end of the merge]'
'--no-commit[perform the merge but do not autocommit]'
'--squash[merge, but do not make a commit]'
'*'{-s,--strategy=-}'[use given merge strategy]:merge strategy:__git_merge_strategies'
)
force_ref_arg=('(-f --force)'{-f,--force}'[allow refs that are not ancestors to be updated]')
tags_fetch_arg=(
'(--no-tags -t --tags)--no-tags[disable automatic tag following]'
'(--no-tags -t --tags)'{-t,--tags}'[fetch remote tags]'
)
author_conversion_file_arg_spec='[specify author-conversion file]:author-conversion file:_files'
author_conversion_file_arg='-A'$author_conversion_file_arg_spec
long_author_conversion_file_arg='--authors-file=-'$author_conversion_file_arg_spec
verbose_arg='-v[produce verbose output]'
help_arg='-h[display usage information]'
upload_pack_arg=('(-u --upload-pack)'{-u,--upload-pack=-}'[specify path to git-upload-pack on remote side]:remote path')
common_fetch_args=(
'(-a --append)'{-a,--append}'[append ref names and object names of fetched refs to "$GIT_DIR/FETCH_HEAD"]'
$upload_pack_arg
$force_ref_arg
$tags_fetch_arg
'(-k --keep)'{-k,--keep}'[keep downloaded pack]'
'(-u --update-head-ok)'{-u,--update-head-ok}'[allow updates of current branch head]'
'--depth=-[deepen the history of a shallow repository by the given number of commits]: :_guard "[[\:guard\:]]" "depth"'
)
common_apply_args=(
'--whitespace=-[detect a new or modified line that ends with trailing whitespaces]: :__git_apply_whitespace_strategies'
'-p-[remove N leading slashes from traditional diff paths]: :_guard "[[\:digit\:]]#" number'
'-C-[ensure at least N lines of context match before and after each change]: :_guard "[[\:digit\:]]#" number')
template_arg='--template=-[directory to use as a template for the object database]:directory:_directories'
shared_arg='--shared=-[share repository amongst several users]::permissions:__git_repository_permissions'
thin_arg='--thin[minimize number of objects to be sent]'
__git_zstyle_default () {
zstyle -t $1 $2
if (( $status == 2 )); then
zstyle $*
fi
}
# TODO: Either skip uninteresting commands or skip the description - the list
# is just too long.
# NOTE: I'm coming to the opinion that skipping the description is the right
# thing to do…, but not 100% sure yet.
(( $+functions[_git_commands] )) ||
_git_commands () {
local -a base_commands
base_commands=(
'add:add paths to the index'
'apply:apply patch on a git index file and a work tree'
'bisect:find the change that introduced a bug'
'branch:create and show branches'
'checkout:checkout and switch to a branch'
'cherry-pick:cherry-pick the effect of an existing commit'
'clone:clone a repository into a new directory'
'commit:record changes to the repository'
'diff:show changes between commits, commit and working tree, etc.'
'fetch:download objects and a head from another repository'
'gc:cleanup unnecessary files and optimize the local repository'
'grep:print lines matching a pattern'
'init:create empty git object database'
'log:show commit logs'
'merge:grand unified merge driver'
'mv:move or rename file, directory, or symlink'
'prune:prune all unreachable objects from the object database'
'pull:fetch from and merge with a remote repository'
'push:update remote refs along with associated objects'
'rebase:rebase local commits to new upstream head'
'reset:reset current HEAD to the specified state'
'revert:revert existing commit'
'rm:remove files from the working tree and from the index'
'show-branch:show branches and their commits'
'status:show working-tree'\''s status'
'tag:create tag object signed with GPG'
'verify-tag:check GPG signature of a tag')
local -a additional_commands
additional_commands=(
'am:apply patches from a mailbox (cooler than applymbox)'
'annotate:annotate file lines with commit info'
'applymbox:apply patches from a mailbox'
'applypatch:apply one patch extracted from an e-mail'
'archive:create an archive of files from a named tree'
'blame:blame file lines on commits'
'cat-file:provide content or type information for repository objects'
'check-attr:display gitattributes information'
'check-ref-format:makes sure that a reference-name is well formed'
'checkout-index:copy files from the index to the working directory'
'cherry:find commits not merged upstream'
'clean:remove untracked files from the working tree'
'clone-pack:clone a repository into the current repository (transport)'
'commit-tree:create a new commit object'
'count-objects:count unpacked objects and display their disk consumption'
'describe:show the most recent tag that is reachable from a commit'
'diff-files:compare files in the working tree and the index'
'diff-index:compare content and mode of blobs between index and repository'
'diff-stages:compare two "merge states" in the index file'
'diff-tree:compare the content and mode of blobs found via two tree objects'
'fetch-pack:receive missing objects from another repository'
'imap-send:dump mailbox from stdin into imap folder'
'index-pack:build pack index file for an existing packed archive'
'local-fetch:duplicate another git repository on a local system'
'ls-remote:show references in a remote or local repository'
'ls-tree:display tree object in human-readable form'
'mailinfo:extract patch from a single e-mail message'
'mailsplit:split mbox file into a list of files'
'merge-base:find as good a common ancestor as possible for a merge'
'merge-file:run a three-way file merge'
'merge-index:run merge for files needing merging'
'merge-tree:show three-way merge without touching index'
'mktag:create tag object'
'mktree:build tree-object from ls-tree formatted text'
'name-rev:find symbolic names for given revisions'
'octopus:merge more than two commits'
'pack-objects:create packed archive of objects'
'pack-redundant:find redundant pack files'
'pack-refs:pack heads and tags for efficient repository access'
'parse-remote:routines to help parsing $GIT_DIR/remotes/'
'peek-remote:list references on a remote repository using the upload-pack protocol'
'prune-packed:remove extra objects that are already in pack files'
'read-tree:read tree information into the directory index'
'reflog:manage reflog information'
'relink:hardlink common objects in local repositories'
'repack:pack unpacked objects in a repository'
'request-pull:generate summary of pending changes'
'rerere:reuse recorded resolve'
'rev-list:list commit object in reverse chronological order'
'shortlog:summarize git log output'
'show:show various types of objects'
'show-index:display contents of a pack idx file'
'show-ref:list references in a local repository'
'symbolic-ref:read and modify symbolic references'
'tar-tree:create tar archive of the files in the named tree'
'unpack-file:create temporary file with blob'\''s contents'
'unpack-objects:unpack objects out of packed archive'
'update-ref:update object name stored in a reference safely'
'update-server-info:update auxiliary information on a dumb server'
'var:display git logical variable'
'verify-pack:validate packed git archive files'
'whatchanged:show commit-logs and differences they introduce'
'write-tree:create tree from the current index')
local -a useful_commands
useful_commands=(
'format-patch:prepare patches for e-mail submission'
'ls-files:information about files in the index/working directory'
'instaweb:instantly browse your working repository in gitweb'
'remote:manage set of tracked repositories'
'send-email:send patch-e-mails out of "format-patch" output'
'update-index:modify index in some given way')
local -a interoperability_commands
interoperability_commands=(
'archimport:import an Arch repository into git'
'cvsexportcommit:export a commit to a CVS checkout'
'cvsimport:import a CVS "repository" into a git repository'
'svnimport:import SVN repository into git'
'quiltimport:apply a quilt patchset'
'svn:bidirectional operation between a single Subversion branch and git')
local -a ancillary_commands
ancillary_commands=(
'config:get and set repository or global options'
'convert-objects:convert old-style git repository'
'for-each-ref:output information on each ref'
'get-tar-commit-id:extract commit ID from an archive created using tar-tree'
'hash-object:compute object ID from a file'
'patch-id:compute unique ID for a patch'
'fsck:verify the connectivity and validity of the objects in the database'
'lost-found:recover lost references that luckily have not yet been pruned'
'mergetool:run merge conflict resolution tools to resolve merge conflicts')
local -a internal_commands
internal_commands=(
'daemon:start a really simple server for git repositories'
'fast-import:import information into git directly'
'fmt-merge-msg:produce merge commit message'
'http-fetch:download remote git repository via HTTP'
'http-push:push missing objects using HTTP/DAV'
'merge-one-file:standard helper-program to use with merge-index'
'receive-pack:command invoked by send-pack to receive what is pushed to it'
'rev-parse:pick out and massage parameters for other git commands'
'runstatus:a helper for git-status and git-commit'
'send-pack:push to remote repository, intelligently'
'shell:restricted login shell for GIT-only SSH access'
'ssh-fetch:pull from remote repository over an SSH connection'
'ssh-upload:"server-side" helper program used by ssh-fetch'
'stripspace:filter out empty lines'
'upload-archive:send archive back to git-archive'
'upload-pack:command invoked by clone-pack and fetch-pack')
local wanted_commands
zstyle -s ':completion:${curcontext}:' commands wanted_commands || wanted_commands="all -internal"
local -aU unique_wanted_commands
unique_wanted_commands=($=wanted_commands)
integer index_of_all=$(( $unique_wanted_commands[(I)all] ))
if (( index_of_all > 0 )); then
unique_wanted_commands[index_of_all]=()
unique_wanted_commands+=(base additional useful interoperability ancillary internal)
fi
for (( i = 0; i < $#unique_wanted_commands; i++ )); do
if [[ $unique_wanted_commands[i] == (#bq)-(*) ]]; then
unique_wanted_commands[i]=()
unique_wanted_commands[(I)$match[1]]=()
fi
done
local -a commands
for wanted_command in $unique_wanted_commands; do
case $wanted_command in
(base)
commands+=($base_commands) ;;
(additional)
commands+=($additional_commands) ;;
(useful)
commands+=($useful_commands) ;;
(interoperability)
commands+=($interoperability_commands) ;;
(ancillary)
commands+=($ancillary_commands) ;;
(internal)
commands+=($internal_commands) ;;
esac
done
_describe -t commands 'git command' commands && ret=0
}
(( $+functions[__git_aliases] )) ||
__git_aliases () {
declare -a aliases
# TODO: See __git_config_gettable_name for discussion on how to actually get
# out the names, skipping the values.
# TODO: Should check if the terminal is unicode capable. If so, use ‘ and ’
# instead of '.
aliases=(${^${${(M)${(f)"$(_call_program aliases git config --list)"}:#alias.*}#alias.}/(#b)=(*)/:alias for \'$match[1]}\')
__git_command_successful || return 0
local expl
_describe -t aliases 'git alias' aliases
}
(( $+functions[__git_aliases_and_commands] )) ||
__git_aliases_and_commands () {
_alternative \
'aliases: :__git_aliases' \
'commands: :_git_commands'
}
# NOTE: -c is undocumented.
# TODO: Perhaps provide some sort of completion or guard for line range (-L).
# NOTE: --score-debug is undocumented.
# NOTE: --show-name is undocumented.
# NOTE: --show-number is undocumented.
(( $+functions[_git-annotate] )) ||
_git-annotate () {
_arguments -S \
'-b[show blank SHA-1 for boundary commits]' \
'--root[do not treat root commits as boundaries]' \
'--show-stats[include additional statistics at the end of blame output]' \
'-c[undocumented]' \
'-l[show long rev]' \
'-t[show raw timestamp]' \
'-S[use revs from revs-file]:revs-file:_files' \
'-M-[detect moving lines in the file as well]:: :_guard "[[\:digit\:]]" "number of characters"' \
'*-C-[detect copied lines from other files from same commit as well]:: :_guard "[[\:digit\:]]" "number of characters"' \
'-L[annotate only the given line range]:line range' \
'--contents[annotate against the given file if no rev is specified]:file:_files' \
'--incremental[show results incrementally for machine processing]' \
'--score-debug[uncodumented]' \
'(-f --show-name)'{-f,--show-name}'[undocumented]' \
'(-n --show-number)'{-n,--show-number}'[undocumented]' \
'(-p --porcelain)'{-p,--porcelain}'[show results designed for machine processing]' \
'(-h --help)'{-h,--help}'[show help message]' \
':file:__git_cached_files' \
'::revision:__git_revisions' && ret=0
}
(( $+functions[_git-apply] )) ||
_git-apply () {
_arguments \
$nul_arg \
'--allow-binary-replacement[allow binary files to be patched]' \
'--apply[apply patches that would otherwise not be applied]' \
'--cached[apply patches without touching the working tree]' \
'--check[check if patches are applicable (turns off "apply")]' \
'--exclude=-[skip files matching specified pattern]:pattern' \
'--inaccurate-eof[work around missing-new-line-at-EOF bugs]' \
'--index[make sure that the patch is applicable to the index]' \
'--index-info[output information about original version of a blob if available]' \
'--no-add[ignore additions made by the patch]' \
'--numstat[same as --stat but in decimal notation and complete pathnames (turns off "apply")]' \
'(-R --reverse)'{-R,--reverse}'[apply patches in reverse]' \
'--reject[apply as much as possible, and leave rejected hunks in .rej files]' \
'--stat[output diffstat for the input (turns off "apply")]' \
'--summary[output summary of git-diff extended headers (turns off "apply")]' \
'--unidiff-zero[disable unified-diff-context check]' \
'(-v --verbose)'{-v,--verbose}'[report progress to stderr]' \
$common_apply_args \
'*::patch:_files' && ret=0
}
# NOTE: Documentation mentions options that don’t exist anymore, for example,
# --since, and shows -C twice!aa
(( $+functions[_git-blame] )) ||
_git-blame () {
_git-annotate
}
(( $+functions[_git-checkout-index] )) ||
_git-checkout-index () {
_arguments -S \
$nul_arg \
'(-a --all :)'{-a,--all}'[check out all files in the index]' \
'(-f --force)'{-f,--force}'[force overwrite of existing files]' \
'(-n --no-create)'{-n,--no-create}'[do not checkout new files]' \
'--stage=-[check out files from named stage]:stage:(1 2 3 all)' \
'--stdin[read list of paths from the standard input]' \
'--temp[write the content to temporary files]' \
'--prefix=-[prefix to use when creating files]:directory:_directories' \
'(-q --quiet)'{-q,--quiet}'[do not complain about existing files or missing files]' \
'(-u --index)'{-u,--index}'[update stat information in index]' \
'*::file:__git_cached_files' && ret=0
}
(( $+functions[_git-clean] )) ||
_git-clean () {
_arguments \
'-d[remove untracked directories]' \
'-n[just show what would be done]' \
'-q[be quiet, only report errors]' \
'(-X -x)-x[do use ignore rules]' \
'(-X -x)-X[remove only files ignored by git]' && ret=0
}
(( $+functions[_git-commit-tree] )) ||
_git-commit-tree () {
if (( CURRENT == 2 )); then
__git_trees && ret=0
elif [[ $words[CURRENT-1] == -p ]]; then
local expl
_description commits expl 'parent commit'
__git_objects $expl && ret=0
else
compadd - '-p'
fi
}
(( $+functions[_git-hash-object] )) ||
_git-hash-object () {
_arguments -S \
'(:)--stdin[read object from standard input]' \
'-t[the type of object to create]:object type:((blob\:"a blob of data"
commit\:"a tree with parent commits"
tag\:"a symbolic name for another object"
tree\:"a recursive tree of blobs"))' \
'-w[write the object to the object database]' \
'(--stdin):file:_files' && ret=0
}
(( $+functions[_git-index-pack] )) ||
_git-index-pack () {
local -a stdin_arguments
if (( words[(I)--stdin] )); then
stdin_arguments=(
'--fix-thin[record deltified objects, based on objects not included]'
'--keep=-[create .keep file]::reason:')
fi
_arguments \
'-v[report progress to stderr]' \
'-o[write generated pack index into specified file]:file:_files' \
'--stdin[read pack from stdin and instead write to specified file]' \
$stdin_arguments \
':pack file:_files -g "*.pack"' && ret=0
}
(( $+functions[_git-init] )) ||
_git-init () {
_arguments \
$shared_arg \
$template_arg && ret=0
}
(( $+functions[_git-merge-file] )) ||
_git-merge-file () {
integer n_labels=${#${(M)words[1,CURRENT-1]:#-L}}
local label_argument
if (( n_labels < 3 )) || [[ $words[CURRENT-1] == -L ]]; then
local -a ordinals
ordinals=(first second third)
label_argument="*-L[label to use for the $ordinals[n_labels+1] file]:label"
fi
_arguments \
$label_argument \
'(-p --stdout)'{-p,--stdout}'[send merged file to standard output instead of overwriting first file]' \
'(-q --quiet)'{-q,--quiet}'[do not warn about conflicts]' \
':current file:_files' \
':base file:_files' \
':other file:_files' && ret=0
}
(( $+functions[_git-merge-index] )) ||
_git-merge-index () {
if (( CURRENT > 2 )) && [[ $words[CURRENT-1] != -[oq] ]]; then
_arguments -S \
'(:)-a[run merge against all files in the index that need merging]' \
'*:index file:__git_cached_files' && ret=0
else
declare -a arguments
(( CURRENT == 2 )) && arguments+='-o[skip failed merges]'
(( CURRENT == 2 || CURRENT == 3 )) && arguments+='(-o)-q[do not complain about failed merges]'
(( 2 <= CURRENT && CURRENT <= 4 )) && arguments+='*:merge program:_files -g "*(*)"'
_arguments -S $arguments && ret=0
fi
}
# TODO: Shouldn’t we add a __git_branches type completion?
(( $+functions[_git-merge-tree] )) ||
_git-merge-tree () {
_arguments \
':base-tree:__git_tree_ishs' \
':branch 1:__git_tree_ishs' \
':branch 2:__git_tree_ishs' && ret=0
}
(( $+functions[_git-mktag] )) ||
_git-mktag () {
_message 'no arguments allowed; only accepts tags on standard input'
}
(( $+functions[_git-mktree] )) ||
_git-mktree () {
_arguments \
'-z[read NUL-terminated ls-tree -z output]' && ret=0
}
(( $+functions[_git-pack-objects] )) ||
_git-pack-objects () {
_arguments \
'(--revs)--all[include all refs as well as revisions already specified]' \
'--all-progress[force progress output, even during write-out phase]' \
'--delta-base-offset[use delta-base-offset packing]' \
'--depth=-[maximum delta depth]: :_guard "[[\:digit\:]]#" number' \
'--incremental[ignore objects that have already been packed]' \
'--no-reuse-delta[do not reuse existing deltas, but compute them from scratch]' \
'--non-empty[only create a package if it contains at least one object]' \
'--local[similar to --incremental, but only ignore unpacked non-local objects]' \
'--progress[force progress output]' \
'--revs[read revision arguments from standard input]' \
'(:)--stdout[write the pack to standard output]' \
'-q[do not report progress]' \
'(--revs)--unpacked[limit objects to pack to those not already packed]' \
'--window=-[number of objects to use per delta compression]: :_guard "[[\:digit\:]]#" number' \
'(--stdout):base-name:_files' && ret=0
}
(( $+functions[_git-prune-packed] )) ||
_git-prune-packed () {
_arguments -S \
'-n[only list the objects that would be removed]' \
'-q[suppress progress output]' && ret=0
}
(( $+functions[_git-read-tree] )) ||
_git-read-tree () {
local aggressive_arg
if (( words[(I)-m] )); then
aggressive_arg='--aggressive[try harder to resolve merge conflicts]'
fi
local -a ui_args
if (( words[(I)(-m|--reset|--prefix)] )); then
ui_args=(
'( -i)-u[update the work tree after successful merge]'
'(-u )-i[update only the index; ignore changes in work tree]')
fi
local exclude_per_directory_arg
if (( words[(I)-u] )); then
exclude_per_directory_arg='--exclude-per-directory=-[specify .gitignore file]:.gitignore file:_files'
fi
_arguments -A '-*' \
'( --reset --prefix)-m[perform a merge, not just a read]' \
'(-m --prefix)--reset[perform a merge, not just a read, ignoring unmerged entries]' \
'(-m --reset 2 3)--prefix=-[read the contents of specified tree-ish under specified directory]:prefix:_directories -r ""' \
$aggressive_arg \
$ui_args \
$exclude_per_directory_arg \
'1:first tree-ish to be read/merged:__git_tree_ishs' \
'2:second tree-ish to be read/merged:__git_tree_ishs' \
'3:third tree-ish to be read/merged:__git_tree_ishs' && ret=0
}
# TODO: Complete value regex somehow?
(( $+functions[_git-config] )) ||
_git-config () {
local name_arg
if (( words[(I)--get-regexp] )); then
name_arg=':name regex'
elif (( words[(I)--get(-all|)] )); then
name_arg=':name:__git_config_gettable_name'
else
name_arg=':name:__git_config_name'
fi
_arguments -A '--*' \
'( --global)--system[use system-wide config file]' \
'(--system )--global[use user-global config file]' \
'( --bool)--int[setting is an integer]' \
'(--int )--bool[setting is a boolean]' \
$name_arg \
":value:__git_config_values $words[CURRENT-1]" \
'::value regex' \
- '(actions)' \
'(: -)--rename-section[rename the given section]:section:__git_config_section_names:new name' \
'(: -)--remove-section[remove the given section]:section:__git_config_section_names' \
'(3 -)--add[add new value without altering any existing ones]' \
'(2 -)--unset[remove the first matching value of the key]' \
'(2 -)--unset-all[remove all matching values of the key]' \
'(2 -)--get[get the first matching value of the key]' \
'(2 -)--get-all[get all matching values of the key]' \
'(2 -)--get-regexp[like "--get-all", but interpret "name" as a regular expression]' \
'(-)--replace-all[replace all values of the given key]' \
'(: --int --bool)'{-l,--list}'[list all variables set in config file]' && ret=0
}
# NOTE: --track is undocumented.
# TODO: --track, -t, --master, and -m should take remote branches, I guess.
# NOTE: --master is undocumented.
# NOTE: --fetch is undocumented.
(( $+functions[_git-remote] )) ||
_git-remote () {
local curcontext=$curcontext state line
declare -A opt_args
_arguments -C \
':command:->command' \
'*::options:->options' && ret=0
case $state in
(command)
declare -a commands
commands=(
'add:add a new remote'
'show:show information about a given remote'
'prune:delete all stale tracking branches for a given remote'
'update:fetch updates for a set of remotes')
_describe -t commands 'sub-command' commands && ret=0
;;
(options)
case $line[1] in
(add)
_arguments \
'*'{--track,-t}'[track given branch instead of default glob refspec]:branch:__git_branch_names' \
'(--master -m)'{--master,-m}'[set the remote'\''s HEAD to point to given master branch]:branch:__git_branch_names' \
'(--fetch -f)'{--fetch,-f}'[run git-fetch on the new remote after it has been created]' \
':branch name:__git_remotes' \
':url:_urls' && ret=0
;;
(show|name|prune)
__git_remotes && ret=0
;;
(update)
__git_remote-groups && ret=0
;;
esac
;;
esac
}
(( $+functions[_git-unpack-objects] )) ||
_git-unpack-objects () {
_arguments \
'-n[only list the objects that would be unpacked]' \
'-q[run quietly]' \
'-r[try recovering objects from corrupt packs]' && ret=0
}
(( $+functions[_git-update-index] )) ||
_git-update-index () {
local nul_arg
if (( words[(I)--stdin] )); then
nul_arg='-z[paths are separated with NUL instead of LF for --stdin]'
fi
_arguments -S \
$refreshables \
'--add[add files not already in the index]' \
'( --force-remove)--remove[remove files that are in the index but are missing from the work tree]' \
'(--remove )--force-remove[remove files from both work tree and the index]' \
'(-q --unmerged --ignore-missing)--refresh[refresh the index]' \
'-q[run quietly]' \
'--unmerged[if unmerged changes exists, ignore them instead of exiting]' \
'--ignore-missing[ignore missing files when refreshing the index]' \
'*--cacheinfo[insert information directly into the cache]: :_guard "[0-7]#" "octal file mode": :_guard "[[\:xdigit\:]]#" "object id":file:_files' \
'(: -)--index-info[read index information from stdin.]' \
'--chmod=-[set the execute permissions on the updated files]:permission:((-x\:executable +x\:"not executable"))' \
'( --no-assume-unchanged)--assume-unchanged[set the "assume unchanged" bit for the given paths]' \
'(--assume-unchanged )--no-assume-unchanged[unset the "assume unchanged" bit for the given paths]' \
'(-)'{-g,--again}'[run git-update-index on differing index entries]' \
'(-)--unresolve[restore "unmerged" or "needs updating" state of files]' \
'--info-only[only insert files object-IDs into index]' \
'--replace[replace files already in the index if necessary]' \
'(: -)--stdin[read list of paths from standard input]' \
'--verbose[report what is being added and removed from the index]' \
$nul_arg \
'*::file:_files' && ret=0
}
(( $+functions[_git-write-tree] )) ||
_git-write-tree () {
_arguments \
'--missing-ok[ignore objects in the index that are missing in the object database]'
'--prefix=-[write tree representing given sub-directory]:sub-directory:_directories -r ""' && ret=0
}
(( $+functions[_git-cat-file] )) ||
_git-cat-file () {
_arguments \
'( -s -e -p 1)-t[show the type of the given object]' \
'(-t -e -p 1)-s[show the size of the given object]' \
'(-t -s -p 1)-e[exit with zero status if object exists]' \
'(-t -s -e 1)-p[pretty-print the given object]' \
'(-t -s -e -p ):object type:(blob commit tag tree)' \
'(-t -s -e -p ):object:__git_objects' && ret=0
}
(( $+functions[_git-describe] )) ||
_git-describe () {
_arguments \
$abbrev_arg \
'--all[use any ref found in "$GIT_DIR/refs/"]' \
'--tags[use any tag found in "$GIT_DIR/refs/tags/"]' \
$abbrev_arg \
'--candidates=-[consider up to given number of canditates]: :_guard "[[\:digit\:]]##" "number of canditates"' \
'--debug[display information about the searching strategy]' \
'*:committish:__git_committishs' && ret=0
}
# TODO: Use __git_modified_files instead?
(( $+functions[_git-diff-index] )) ||
_git-diff-index () {
_arguments -S \
$diff_args \
'--cached[do not consider the work tree at all]' \
'-m[flag non-checked-out files as up-to-date]' \
':tree-ish:__git_tree_ishs' \
'*::index file:__git_cached_files' && ret=0
}
# TODO: Use __git_modified_files instead?
(( $+functions[_git-diff-files] )) ||
_git-diff-files () {
_arguments \
$diff_args \
'(-0 -1 -2 -3 --base --ours --theirs -c --cc --no-index)-0[omit diff output for unmerged entries]' \
'(-0 -1 -2 -3 --base --ours --theirs -c --cc --no-index)'{-1,--base}'[diff against "base" version]' \
'(-0 -1 -2 -3 --base --ours --theirs -c --cc --no-index)'{-2,--ours}'[diff against "our branch" version]' \
'(-0 -1 -2 -3 --base --ours --theirs -c --cc --no-index)'{-3,--theirs}'[diff against "their branch" version]' \
'(-0 -1 -2 -3 --base --ours --theirs -c --cc --no-index)'{-c,--cc}'[compare "our branch", "their branch" and working tree files]' \
'(-0 -1 -2 -3 --base --ours --theirs -c --cc --no-index --exit-code *)--no-index[compare given files / directories]' \
'-q[remain silent even on nonexisting files]' \
'1:file:_files' \
'2:file:_files' \
'*::file:_files' && ret=0
}
# TODO: Use __git_modified_files instead?
(( $+functions[_git-diff-stages] )) ||
_git-diff-stages () {
_arguments \
$diff_args \
':stage 1:__git_stages' \
':stage 2:__git_stages' \
'*::index file:_files' && ret=0
}
# TODO: Use __git_modified_files instead?
(( $+functions[_git-diff-tree] )) ||
_git-diff-tree () {
local curcontext=$curcontext state line
declare -A opt_args
_arguments -C -S \
$diff_args \
$pretty_arg \
'--encoding=-[re-code commit log-message in given encoding]::log-message encoding:__git_encodings' \
'--no-commit-id[skip output of commit IDs]' \
'--root[show diff against the empty tree]' \
'--stdin[read commit and tree information from standard input]' \
'-m[show merge commits]' \
'-r[recurse into subdirectories]' \
'(-r)-t[show tree entry itself as well as subtrees (implies -r)]' \
'-s[do not show differences]' \
'-v[show commit message before the differences]' \
'(-c --cc)-c[show differences from each of the parents to the merge result]' \
'(-c --cc)--cc[how differences from each of the parents and omit differences from only one parent]' \
'--always[always show commit itself and the commit log message]' \
':tree-ish:__git_tree_ishs' \
'*::file:->files' && ret=0
case $state in
files)
if (( $#line > 2 )); then
# TODO: this is probably just stupid to do.
# What'd be nice would be
# common files:
# ...
# original tree:
# ...
# new tree:
# ...
_alternative \
"original tree:original tree:__git_tree_files . $line[1]" \
"new tree:new tree:__git_tree_files . $line[2]" && ret=0
else
_alternative \
': :__git_tree_ishs' \
": :__git_tree_files . $line[1]" && ret=0
fi
;;
esac
}
# TODO: Better completion for --format: should complete %(field) stuff, that
# is, %(refname), %(objecttype), %(objectsize), %(objectname) with optional ‘*’
# in front.
# TODO: Documentation says that --count can be given * number of times, but
# sources beg to differ, allowing only one.
(( $+functions[_git-for-each-ref] )) ||
_git-for-each-ref () {
_arguments -S \
'--format=-[output format of ref information]:format' \
'(-s --shell -p --perl --python --tcl)'{-s,--shell}'[use string literals suitable for sh]' \
'(-s --shell -p --perl --python --tcl)'{-p,--perl}'[use string literals suitable for Perl]' \
'(-s --shell -p --perl --tcl)'--python'[use string literals suitable for Python]' \
'(-s --shell -p --perl --python )'--tcl'[use string literals suitable for Tcl]' \
'--count=-[maximum number of refs to iterate over]: :_guard "[[\:digit\:]]#" "maximum number of refs"' \
'--sort=-[key to sort refs by]:sort key:__git_ref_sort_keys' \
':: :_guard "([^-]?#|)" pattern' && ret=0
}
(( $+functions[_git-fmt-merge-msg] )) ||
_git-fmt-merge-msg () {
arguments \
'( --no-summary)--summary[add one-line descriptions from commits being merged]' \
'(--summary )--no-summary[do not add one-line descriptions from commits being merged]' \
'(-F --file)'{-F,--file}'[specify list of merged objects from file]:file:_files' && ret=0
}
(( $+functions[_git-fsck] )) ||
_git-fsck () {
_arguments \
'--cache[consider objects recorded in the index as head nodes for reachability traces]' \
'--full[check all object directories]' \
'--root[show root nodes]' \
'--strict[do strict checking]' \
'--tags[show tags]' \
'--unreachable[show objects that are unreferenced in the object database]' \
'*::object:__git_objects' && ret=0
}
(( $+functions[_git-ls-files] )) ||
_git-ls-files () {
local no_empty_directory_arg
if (( words[(I)--directory] )); then
no_empty_directory_arg='--no-empty-directory[do not list empty directories]'
fi
_arguments -S \
$nul_arg \
'(-c --cached)'{-c,--cached}'[show cached files in the output]' \
'(-d --deleted)'{-d,--deleted}'[show deleted files in the output]' \
'(-i --ignored)'{-i,--ignored}'[show ignored files in the output]' \
'(-k --killed)'{-k,--killed}'[show killed files in the output]' \
'(-m --modified)'{-m,--modified}'[show modified files in the output]' \
'(-o --others)'{-o,--others}'[show other files in the output]' \
'(-s --stage)'{-s,--stage}'[show stage files in the output]' \
'(-u --unmerged)'{-u,--unmerged}'[show unmerged files in the output]' \
'( -v)-t[identify each files status (HMRCK?)]' \
'(-t )-v[identify each files status (hmrck?)]' \
'*'{-x,--exclude=-}'[skip files matching given pattern]:file pattern' \
'*'{-X,--exclude-from=-}'[skip files matching patterns in given file]:file:_files' \
'*--exclude-per-directory=-[skip directories matching patterns in given file]:file:_files' \
'--directory[if a whole directory is classified as "other", show just its name]' \
$no_empty_directory_arg \
'--error-unmatch[if any <file> does not appear in the index, treat this as an error]' \
'--full-name[force paths to be output relative to the project top directory]' \
$abbrev_arg \
'*::index file:_files' && ret=0
}
(( $+functions[_git-ls-tree] )) ||
_git-ls-tree () {
local curcontext=$curcontext state line
declare -A opt_args
_arguments -C \
$nul_arg \
$abbrev_arg \
'(-t)-d[do not show children of given tree (implies -t)]' \
{--name-only,--name-status}'[list only filenames, one per line]' \
'-r[recurse into subdirectories]' \
'-t[show tree entries even when going to recurse them]' \
'--full-name[output full path-names]' \
':tree-ish:__git_tree_ishs' \
'*::tree file:->files' && ret=0
case $state in
files)
__git_tree_files . $line[1] && ret=0
;;
esac
}
(( $+functions[_git-imap-send] )) ||
_git-imap-send () {
_message 'no arguments allowed; accepts mailbox file on standard input'
}
(( $+functions[_git-quiltimport] )) ||
_git-quiltimport () {
_arguments \
'--dry-run[check patches and warn if they can'\''t be imported]' \
'--author[default author name and email address to use for patches]' \
'--patches[set directory containing patches]:patch directory:_directories' && ret=0
}
(( $+functions[_git-merge-base] )) ||
_git-merge-base () {
_arguments \
'(-a --all)'{-a,--all}'[show all common ancestors]' \
':commit 1:__git_commits' \
':commit 2:__git_commits' && ret=0
}
(( $+functions[_git-name-rev] )) ||
_git-name-rev () {
_arguments -S \
'--tags[only use tags to name the commits]' \
'--refs=-[only use refs matching given pattern]: :_guard "?#" "shell pattern"' \
'(--stdin :)--all[list all commits reachable from all refs]' \
'(--all :)--stdin[read from stdin and append revision-name]' \
'(--stdin --all)*:commit-ish:__git_revisions' && ret=0
}
(( $+functions[_git-pack-redundant] )) ||
_git-pack-redundant () {
_arguments \
'(:)--all[process all packs]' \
'--alt-odb[do not require objects to be present in local packs]' \
'--verbose[output some statistics to stderr]' \
'(--all)*::packs:_files -g "*.pack"' && ret=0
}
# TODO: --timestamp undocumented.
# TODO: __git_commits2 should be reworked/reworded.
(( $+functions[_git-rev-list] )) ||
_git-rev-list () {
if (( words[(I)--] && words[(I)--] != CURRENT )); then
_arguments \
'*:index file:__git_cached_files' && ret=0
else
__git_setup_revision_arguments
_arguments -S \
$revision_arguments \
'(--pretty)--header[show commit headers]' \
'--remote-empty[stop when a given path disappears from the tree]' \
'--timestamp[undocumented]' \
'( --bisect-vars)--bisect[show only the middlemost commit object]' \
'(--bisect )--bisect-vars[same as --bisect, outputing shell-evalable code]' \
'--stdin[read commit objects from standard input]' \
'*:commit id:__git_commits2' && ret=0
fi
}
(( $+functions[_git-show-ref] )) ||
_git-show-ref () {
_arguments -S \
- list \
'(-h --head)'{-h,--head}'[show the HEAD reference]' \
'--tags[show only "refs/tags"]' \
'--heads[show only "refs/heads"]' \
'(-d --dereference)'{-d,--dereference}'[dereference tags into object IDs as well]' \
'(-s --hash)'{-s+,--hash=-}'[only show the SHA-1 hash, not the reference name]:: :_guard "[[\:digit\:]]#" length' \
'--verify[enable stricter reference checking]' \
$abbrev_arg \
'(-q --quiet)'{-q,--quiet}'[do not print any results to stdout]' \
'*: :_guard "([^-]?#|)" pattern' \
- exclude \
'--exclude-existing=-[filter out existing refs from stdin]:: :_guard "([^-]?#|)" pattern' && ret=0
}
(( $+functions[_git-show] )) ||
_git-show () {
local curcontext=$curcontext state line
typeset -A opt_args
__git_setup_revision_arguments
_arguments -S \
$revision_arguments \
'*:object:__git_objects' && ret=0
}
(( $+functions[_git-show-index] )) ||
_git-show-index () {
_message 'no arguments allowed; accepts index file on standard input'
}
(( $+functions[_git-tar-tree] )) ||
_git-tar-tree () {
_arguments \
'--remote=-[retrieve a tar archive from a remote repository]:__git_remote_repository' \
':tree-ish:__git_tree_ishs' \
':base:_files' && ret=0
}
(( $+functions[_git-unpack-file] )) ||
_git-unpack-file () {
_arguments \
':blob id:__git_blobs' && ret=0
}
(( $+functions[_git-var] )) ||
_git-var () {
_arguments \
'(:)-l[show logical variables]' \
'(-):variable:((GIT_AUTHOR_IDENT\:"name and email of the author" \
GIT_COMMITTER_IDENT\:"name and email of committer"))' && ret=0
}
(( $+functions[_git-verify-pack] )) ||
_git-verify-pack () {
_arguments -S \
'-v[show objects contained in pack]' \
'*:index file:_files -g "*.idx"' && ret=0
}
(( $+functions[_git-clone-pack] )) ||
_git-clone-pack () {
_arguments \
$exec_arg \
':repository:__git_any_repositories' \
'*:head:__git_heads' && ret=0
}
(( $+functions[_git-fetch-pack] )) ||
_git-fetch-pack () {
_arguments \
'--all[fetch all remote refs]' \
'(-q --quiet)'{-q,--quiet}'[make output less verbose]' \
'(-k --keep)'{-k,--keep}'[do not invoke git-unpack-objects on received data]' \
$thin_arg \
'(--upload-pack --exec)'{--upload-pack=-,--exec=-}'[specify path to git-upload-pack on remote side]:remote path' \
'--depth=-[limit fetching to ancestor-chains not longer than given number]: :_guard "[[\:digit\:]]#" "maximum ancestor-chain length"' \
'--no-progress[do not show progress]' \
$verbose_arg \
':repository:__git_any_repositories' \
'*:references:__git_references' && ret=0
}
(( $+functions[_git-fast-import] )) ||
_git-fast-import () {
_arguments \
'--date-format=-[specify the types of dates being passed]:((raw\:"native git format"
rfc2822\:"standard email format"
now\:"use current time and timezone"))' \
'--max-pack-size=-[maximum size of each packfile]: :_guard "[[\:digit\:]]#" "maximum pack size"' \
'--depth=-[maximum delta depth for blob and tree deltification]: :_guard "[[\:digit\:]]#" "maximum delta depth"' \
'--active-branches=-[maximum number of branches to maintain active at once]: :_guard "[[\:digit\:]]#" "maximum number of branches"' \
'--export-marks=-[dump the internal marks table to given file]:export file:_files' \
'--export-pack-edges=-[list packfiles and last commit on branches in them in given file]:export file:_files' \
'--force[force updating modified existing branches]' \
'--quiet[disable all non-fatal output]' \
'--stats[display statistics about object created]' && ret=0
}
(( $+functions[_git-http-fetch] )) ||
_git-http-fetch () {
_arguments \
$fetch_args \
'(1)--stdin[read commit ids and refs from standard input]' \
':commit id:__git_commits' \
':URL:_urls' && ret=0
}
(( $+functions[_git-http-push] )) ||
_git-http-push () {
_arguments \
'--all[verify that all objects in local ref history exist remotely]' \
'--complete[do not assume that the remote repository is complete]' \
'--force[allow refs that are not ancestors to be updated]' \
'--verbose[report the list of objects being walked locally and sent to the remote]' \
'( -D)-d[remove refs from remote repository]' \
'(-d )-D[forcefully remove refs from remote repository]' \
':URL:_urls' \
'*:remote refs:__git_remote_references' && ret=0
}
(( $+functions[_git-local-fetch] )) ||
_git-local-fetch () {
_arguments \
$fetch_args \
'-l[hard-link objects]' \
'-n[do not copy objects]' \
'-s[sym-link objects]' \
'(1)--stdin[read commit ids and refs from standard input]' \
':commit id:__git_commits' \
':directory:_directories' && ret=0
}
# TODO: --tags undocumented.
# TODO: --heads undocumented.
# TODO: --refs undocumented.
(( $+functions[_git-peek-remote] )) ||
_git-peek-remote () {
_arguments \
'--upload-pack=-[specify path to git-upload-pack on remote side]:remote path' \
$exec_arg \
'--tags[undocumented]' \
'--heads[undocumented]' \
'--refs[undocumented]' \
':repository:__git_repository' && ret=0
}
(( $+functions[_git-sh-setup] )) ||
_git-sh-setup () {
_message "you probably should not be issuing this command; it is an internal git helper"
}
# TODO: --dry-run undocumented.
# TODO: -n undocumented.
# TODO: --stale-fix undocumented.
# TODO: --verbose undocumented.
# TODO: -- undocumented.
(( $+functions[_git-reflog] )) ||
_git-reflog () {
__git_setup_revision_arguments
if (( CURRENT == 2 )); then
local curcontext=$curcontext state line
declare -A opt_args
_arguments -C \
$revision_arguments \
':subcommand:->subcommand' && ret=0
case $state in
(subcommand)
declare -a reflog_cmds
reflog_cmds=(
'expire:prune old reflog entries'
'show:show log of the current branch')
_describe -t subcommands 'subcommands' reflog_cmds && ret=0
;;
esac
else
case $words[2] in
(expire)
_arguments -S \
'(-n --dry-run)'{-n,--dry-run}'[undocumented]' \
'--expire=-[prune entries older than given time]:date' \
'--expire-unreachable=-[prune entries older than given time and unreachable]:date' \
'--stale-fix[undocumented]' \
'--all[prune all refs]' \
'--verbose' && ret=0
;;
(show|--*)
_arguments -S \
$revision_arguments \
':subcommand:' && ret=0
;;
esac
fi
}
(( $+functions[_git-receive-pack] )) ||
_git-receive-pack () {
_arguments \
':directory to sync into:_directories' && ret=0
}
(( $+functions[_git-shell] )) ||
_git-shell () {
local curcontext=$curcontext state line
declare -A opt_args
_arguments -C \
'-c[command to execute]:command:->commands' \
':argument to command:->arguments' && ret=0
case $state in
(commands)
declare -a commands
commands=(git-receive-pack git-upload-pack)
_describe -t commands command commands && ret=0
;;
(arguments)
case $line[1] in
(git-receive-pack)
local expl
_description directories expl 'directory to sync into'
_directories $expl
;;
(git-upload-pack)
local expl
_description directories expl 'directory to sync from'
_directories $expl
;;
esac
;;
esac
}
(( $+functions[_git-upload-archive] )) ||
_git-upload-archive () {
_arguments \
':directory to get tar archive from:_directories' && ret=0
}
(( $+functions[_git-send-pack] )) ||
_git-send-pack () {
_arguments \
'(--receive-pack --exec)'{--receive-pack=-,--exec=-}'[specify path to git-receive-pack on remote side]:remote path'
'--all[update all refs that exist locally]' \
'--force[update remote orphaned refs]' \
$verbose_arg \
$thin_arg \
':repository:__git_any_repositories' \
'*:remote refs:__git_remote_references' && ret=0
}
(( $+functions[_git-ssh-fetch] )) ||
_git-ssh-fetch () {
_arguments \
$fetch_args \
':commit id:__git_commits' \
':URL:_urls' && ret=0
}
(( $+functions[_git-ssh-upload] )) ||
_git-ssh-upload () {
_arguments \
$fetch_args \
':commit id:__git_commits' \
':URL:_urls' && ret=0
}
(( $+functions[_git-update-server-info] )) ||
_git-update-server-info () {
_arguments \
'(-f --force)'{-f,--force}'[update the info files from scratch]' && ret=0
}
(( $+functions[_git-upload-pack] )) ||
_git-upload-pack () {
_arguments \
'--strict[do not try <directory>/.git/ if <directory> is not a git directory' \
'--timeout=-[interrupt transfer after given number of seconds of inactivity]: :_guard "[[\:digit\:]]" "inactivity timeout"' \
':directory:_directories' && ret=0
}
(( $+functions[_git-add] )) ||
_git-add () {
local curcontext=$curcontext state line
declare -A opt_args
_arguments -C -S \
'-n[do not actually add files; only show which ones would be added]' \
'-v[show files as they are added]' \
'-f[allow adding otherwise ignored files]' \
'(-i --interactive : -)'{-i,--interactive}'[add contents interactively to the index]' \
'*:file:->files' && ret=0
case $state in
(files)
declare -a ignored_files_alternatives
if (( words[(I)-f] )); then
ignored_files_alternatives=(
'ignored-modified-files:ignored modified files:__git_modified_files --ignored'
'ignored-other-files:ignored other files:__git_other_files --ignored')
fi
_alternative \
'modified-files:modified files:__git_modified_files' \
'other-files:other files:__git_other_files' \
$ignored_files_alternatives && ret=0
;;
esac
}
__git_zstyle_default ':completion::complete:git-add:argument-rest:*' ignore-line yes
(( $+functions[_git-am] )) ||
_git-am () {
_arguments \
'--3way[use 3-way merge if patch does not apply cleanly]' \
'--binary[pass "--allow-binary-replacement" to "git-apply"]' \
'--dotest=-[use given directory as working area instead of .dotest]:directory:_directories' \
'--interactive[apply patches interactively]' \
'--keep[pass "-k" flag to "git-mailinfo"]' \
'--resolved[continue after resolving patch failure by hand]' \
'--signoff[add "Signed-off-by:" line to the commit message]' \
'--skip[skip the current patch]' \
'--utf8[pass "-u" flag to "git-mailinfo"]' \
'--no-utf8[do not pass "-u" flag to "git-mailinfo"]' \
$common_apply_args \
'*:mbox file:_files' && ret=0
}
(( $+functions[_git-archive] )) ||
_git-archive () {
local curcontext=$curcontext state line
declare -A opt_args
declare -a backend_args
if (( words[(I)--format=*] > 0 && words[(I)--format=*] < CURRENT )); then
case ${words[$words[(I)--format=*]]#--format=} in
(zip)
backend_args=(
'-0[do not deflate files]'
'-1[minimum compression]'
'-2[a little more compression]'
'-3[slightly more compression]'
'-4[a bit more compression]'
'-5[even more compression]'
'-6[slightly even more compression]'
'-7[getting there]'
'-8[close to maximum compression]'
'-9[maximum compression]')
;;
esac
fi
_arguments -C \
'--format=-[format of the resulting archive]:archive format:__git_archive_formats' \
'(- :)--list[list available archive formats]' \
'--prefix=-[prepend the given path prefix to to each filename]:path prefix:_directories -r ""' \
$backend_args \
'--remote=-[archive remote repository]:remote repository:__git_any_repositories' \
':tree-ish:__git_tree_ishs' \
'*:tree file:->files' && ret=0
case $state in
(files)
__git_tree_files . $line[1] && ret=0
;;
esac
}
(( $+functions[_git-applymbox] )) ||
_git-applymbox () {
_arguments -A '-*' \
'-k[do not modify "Subject:" header]' \
'-m[apply patches with "git-apply" and fail if patch is unclean]' \
'-q[apply patches interactively]' \
'-u[encode commit information in UTF-8]' \
'(1)-c[restart command after fixing an unclean patch]:patch:_files -g ".dotest/0*"' \
':mbox file:_files' \
'::signoff file:__git_signoff_file' && ret=0
}
(( $+functions[_git-bisect] )) ||
_git-bisect () {
local bisect_cmds
bisect_cmds=(
bad:"mark current or given revision as bad"
good:"mark current or given revision as good"
log:"show the log of the current bisection"
next:"find next bisection to test and check it out"
replay:"replay a bisection log"
reset:"finish bisection search and return to the given branch (or master)"
start:"reset bisection state and start a new bisection"
visualize:"show the remaining revisions in gitk"
skip:"choose a nearby commit"
run:"run evaluation script"
)
if (( CURRENT == 2 )); then
_describe -t command "git-bisect commands" bisect_cmds && ret=0
else
case $words[2] in
(bad)
_arguments \
'2:revision:__git_commits' && ret=0
;;
(good|skip)
_arguments \
'*:revision:__git_commits' && ret=0
;;
(replay)
_arguments \
'2:file:_files' && ret=0
;;
(reset)
_arguments \
'2:branch:__git_heads' && ret=0
;;
(run)
_arguments \
'*::arguments: _normal' && ret=0
;;
(*)
_nothing
;;
esac
fi
}
# TODO: complete branch names?
(( $+functions[_git-branch] )) ||
_git-branch () {
local my_abbrev_arg
if (( words[(I)-v] > 0 && words[(I)-v] < CURRENT )); then
my_abbrev_arg=$abbrev_arg
fi
declare -a dependent_deletion_args
if (( words[(I)-d] || words[(I)-D] )); then
dependent_deletion_args=(
'-r[delete remote-tracking branches]'
'*:branch-name:__git_branch_names')
fi
declare -a dependent_modification_args
if (( words[(I)-m] || words[(I)-M] )); then
dependent_modification_args=(
':old or new branch-name:__git_branch_names'
'::new branch-name:__git_branch_names')
fi
# TODO: I’m not happy with having to force a pattern with -A.
_arguments -S -A "-*" \
- list \
'( --no-color)--color[turn on branch coloring]' \
'(--color )--no-color[turn off branch coloring]' \
'( -a)-r[list only the remote-tracking branches]' \
'(-r )-a[list both remote-tracking branches and local branches]' \
'-v[show SHA1 and commit subject line for each head]' \
$my_abbrev_arg \
- create \
'-l[create the branch'\''s reflog]' \
'-f[force the creation of a new branch]' \
':branch-name:__git_branch_names' \
'::start-point:__git_revisions' \
- modify \
'( -M)-m[rename a branch and the corresponding reflog]' \
'(-m )-M[rename a branch even if the new branch-name already exists]' \
$dependent_modification_args \
- delete \
'( -D)-d[delete a fully merged branch]' \
'(-d )-D[delete a branch]' \
$dependent_deletion_args && ret=0
}
__git_zstyle_default ':completion::complete:git-branch:delete-argument-rest:*' ignore-line yes
# TODO: __git_tree_ishs is just stupid. It should be giving us a list of tags
# and perhaps also allow all that just with ^{tree} and so on. Not quite sure
# how to do that, though.
(( $+functions[_git-checkout] )) ||
_git-checkout () {
local curcontext=$curcontext state line
declare -A opt_args
local new_branch_reflog_arg
if (( words[(I)-b] > 0 )); then
new_branch_reflog_arg='-l[create the new branch'\''s reflog]'
fi
# TODO: This isn’t quite correct in regards of the handling of the “--”
# option, as it should prevent us from seeing a branch, not stop matching
# options.
_arguments -C -S -A "-*" \
- switch-branch \
'-q[suppress feedback messages]' \
'-f[force a complete re-read]' \
'-b[create a new branch based at given branch]: :__git_guard_branch-name' \
$new_branch_reflog_arg \
'-m[3way merge current branch, working tree and new branch]' \
'::branch:__git_revisions' \
- update-files \
'::tree-ish:__git_tree_ishs' \
'::file:->files' && ret=0
case $state in
(files)
if [[ -n $line[1] ]]; then
__git_tree_files . $line[1] && ret=0
else
__git_cached_files && ret=0
fi
;;
esac
}
(( $+functions[_git-cherry-pick] )) ||
_git-cherry-pick () {
_arguments \
'(-e --edit)'{-e,--edit}'[edit commit before committing the revert]' \
'(-n --no-commit)'{-n,--no-commit}'[do not make the actually commit]' \
'(-r --replay)'{-r,--replay}'[use original commit message intact]' \
'-x[append information about what commit was cherry-picked]' \
':commit:__git_revisions' && ret=0
}
(( $+functions[_git-clean] )) ||
_git-clean () {
_arguments -S \
'-d[also remove untracked directories]' \
'-n[do a dry run]' \
'-q[run quietly]' \
'(-X )-x[also remove ignored files]' \
'( -x)-X[remove only ignored files]' \
'*:file:_files' && ret=0
}
# TODO: The --no-checkout is undocumented.
(( $+functions[_git-clone] )) ||
_git-clone () {
local -a shared
if (( words[(I)(-l|--local)] )); then
shared=('(-s --shared)'{-s,--shared}'[share the objects with the source repository]')
fi
_arguments \
'--bare[make a bare GIT repository]' \
'(-l --local)'{-l,--local}'[perform a local cloning of a repository]' \
$shared \
'--reference[reference repository]:repository:_directories' \
'(-q --quiet)'{-q,--quiet}'[operate quietly]' \
'-n[do not checkout HEAD after clone is complete]' \
'(-o --origin)'{-o,--origin}'[use given name instead of "origin" as branch name]:name:__git_guard_branch-name' \
$upload_pack_arg \
$template_arg \
'--depth[create a shallow clone, given number of revisions deep]: :_guard "[[\:digit\:]]##" depth' \
':repository:__git_any_repositories' \
'*:directory:_directories' && ret=0
}
(( $+functions[_git-commit] )) ||
_git-commit () {
_arguments -S \
'(-a --all)'{-a,--all}'[update all paths in the index file]' \
'--author[override the author name used in the commit]:author name' \
'(-e --edit)'{-e,--edit}'[edit the commit message before committing]' \
'(-o --only -i --include)'{-i,--include}'[update the given files and commit the whole index]' \
'(-o --only -i --include)'{-o,--only}'[commit only the given files]' \
'(-n --no-verify)'{-n,--no-verify}'[do not look for suspicious lines the commit introduces]' \
'(-s --signoff)'{-s,--signoff}'[add Signed-off-by line at the end of the commit message]' \
'(-q --quiet -v --verbose)'{-q,--quiet}'[suppress commit summary message]' \
'(-q --quiet -v --verbose)'{-v,--verbose}'[show unified diff of all file changes]' \
'(-u --untracked-files)'{-u,--untracked-files}'[show files in untracked directories]' \
'*:file:__git_changed_files' \
- '(message)' \
'--amend[amend the tip of the current branch]' \
{-c,--reedit-message=}'[use existing commit object and edit log message]:commit:__git_commits' \
{-C,--reuse-message=}'[use existing commit object with same log message]:commit:__git_commits' \
{-F,--file=}'[read commit message from given file]:file:_files' \
{-m,--message=}'[use the given message as the commit message]:message' && ret=0
}
__git_zstyle_default ':completion::complete:git-commit:argument-rest:*' ignore-line yes
# TODO: __git_files should be __git_tree_files (do like in git-diff-tree and
# such)
(( $+functions[_git-diff] )) ||
_git-diff () {
_arguments -S \
$diff_args \
'--cached[show diff between index and named commit]' \
'::original revision:__git_commits' \
'::new revision:__git_commits' \
'*::index file:__git_modified_files' && ret=0
}
(( $+functions[_git-fetch] )) ||
_git-fetch () {
_arguments \
$common_fetch_args \
':repository:__git_any_repositories' \
'*:refspec:__git_ref_specs' && ret=0
}
(( $+functions[_git-format-patch] )) ||
_git-format-patch () {
_arguments \
$diff_args \
'(-h --help)'{-h,--help}'[display usage information]' \
'(-k --keep-subject -n --numbered)'{-k,--keep-subject}'[do not strip/add \[PATCH\] from the first line of the commit message]' \
'(-k --keep-subject -n --numbered)'{-n,--numbered}'[name output in \[PATCH n/m\] format]' \
'--start-number=[start numbering patches at given number]: :_guard "[[\:digit\:]]" "patch number"' \
'(-o --output-directory --stdout)'{-o,--output-directory}'[store resulting files in given directory]:directory:_directories' \
'(-o --output-directory)--stdout[output the generated mbox on standard output (implies --mbox)]' \
'(-s --signoff)'{-s,--signoff}'[add "Signed-off-by:" line to the commit message]' \
'--attach=-[create attachments instead of inlining patches]::git version string' \
'--thread[make the second and subsequent mails refer to the first]' \
'--in-reply-to=[make the first mail a reply to the given message]:message id' \
'--ignore-if-in-upstream[do not include a patch that matches a commit in the given range]' \
'--suffix[use the given suffix for filenames]:filename suffix' \
':commit range:__git_commit_ranges' && ret=0
}
(( $+functions[_git-gc] )) ||
_git-gc () {
_arguments \
'--aggressive[more aggressively optimize]' \
'--auto[check whether housekeeping is required]' \
'--quiet[suppress all progress reports]' && ret=0
}
(( $+functions[_git-grep] )) ||
_git-grep () {
local -a pattern_operators
if (( words[(I)-e] == CURRENT - 2 )); then
pattern_operators=(
'--and[both patterns must match]'
'--or[either pattern must match]'
'--not[the following pattern must not match]')
fi
local curcontext=$curcontext state line
declare -A opt_args
_arguments -A '--*' \
'--cached[grep blobs registered in index file instead of working tree]' \
'(-a --text)'{-a,--text}'[process binary files as if they were text]' \
'(-i --ignore-case)'{-i,--ignore-case}'[ignore case when matching]' \
'(-w --word-regexp)'{-w,--word-regexp}'[match only whole words]' \
'(-v --invert-match)'{-v,--invert-match}'[select non-matching lines]' \
'( -H)-h[supress output of filenames]' \
'(-h )-H[show filenames]' \
'--full-name[output paths relative to the project top directory]' \
'(-E --extended-regexp -G --basic-regexp)'{-E,--extended-regexp}'[use POSIX extended regexes]' \
'(-E --extended-regexp -G --basic-regexp)'{-G,--basic-regexp}'[use POSIX basic regexes]' \
'-n[prefix the line number to matching lines]' \
'(-l --files-with-matches -L --files-without-match --name-only)'{-l,--files-with-matches,--name-only}'[show only names of matching files]' \
'(-l --files-with-matches -L --files-without-match)'{-L,--files-without-match}'[show only names of non-matching files]' \
'(-c --count)'{-c,--count}'[show number of matching lines in files]' \
'-A[show trailing context]: :_guard "[[\:digit\:]]#" lines' \
'-B[show leading context]: :_guard "[[\:digit\:]]#" lines' \
'-C[show context]: :_guard "[[\:digit\:]]#" lines' \
'(1)*-f[read patterns from given file]:pattern file:_files' \
'(1)*-e[use the given pattern for matching]:pattern' \
$pattern_operators \
'--all-match[all patterns must match]' \
':pattern:' \
'*::tree-or-file:->files' && ret=0
case $state in
(files)
integer first_tree last_tree start end
(( start = words[(I)(-f|-e)] > 0 ? 1 : 2 ))
(( end = $#line - 1 ))
for (( i = start; i <= end; i++ )); do
[[ line[i] == '--' ]] && break
git cat-file -e "${(Q)line[i]}^{tree}" 2>/dev/null || break
if (( first_tree == 0 )); then
(( first_tree = last_tree = i ))
else
(( last_tree = i ))
fi
done
if (( last_tree == 0 || last_tree == end )); then
if (( first_tree == 0 )); then
_alternative \
'tree:tree:__git_trees' \
"file:file:__git_cached_files" && ret=0
else
_alternative \
'tree:tree:__git_trees' \
"tree file:tree-files:__git_tree_files . $line[first_tree,last_tree]" && ret=0
fi
else
if (( first_tree == 0 )); then
__git_cached_files
else
__git_tree_files . $line[first_tree,last_tree]
fi
fi
;;
esac
}
(( $+functions[_git-log] )) ||
_git-log () {
local curcontext=$curcontext state line
declare -A opt_args
__git_setup_revision_arguments
_arguments -S \
$revision_arguments \
'*:file-or-branch:->files' && ret=0
case $state in
(files)
_alternative \
'files:index file:__git_cached_files' \
'branches:branch:__git_branch_names' && ret=0
;;
esac
}
# TODO: repository needs fixing
(( $+functions[_git-ls-remote] )) ||
_git-ls-remote () {
_arguments \
'(-h --heads)'{-h,--heads}'[show only refs under refs/heads]' \
'(-t --tags)'{-t,--tags}'[show only refs under refs/tags]' \
$upload_pack_arg \
':repository:__git_any_repositories' \
'*: :__git_references' && ret=0
}
(( $+functions[_git-merge] )) ||
_git-merge () {
_arguments \
"$merge_args[@]" \
'-m:merge message' \
'*:remote:__git_commits' && ret=0
}
(( $+functions[_git-mv] )) ||
_git-mv () {
_arguments \
'-f[force renaming/moving even if targets exist]' \
'-k[skip move/renames that would lead to errors]' \
'-n[only show what would happen]' \
'*:source:__git_cached_files' \
':destination:_files' && ret=0
}
(( $+functions[_git-octupus] )) ||
_git-octupus () {
_nothing
}
(( $+functions[_git-pull] )) ||
_git-pull () {
_arguments \
"$merge_args[@]" \
$common_fetch_args \
':repository:__git_any_repositories' \
'*:refspec:__git_ref_specs' && ret=0
}
# NOTE: For --receive-pack we use _files to complete, even though this will
# only complete files on the local end, not the remote end. Still, it may be
# helpful to get some sort of completion going, perhaps modifying the path
# later on to match the remote end.
(( $+functions[_git-push] )) ||
_git-push () {
_arguments \
$force_ref_arg \
'--all[fetch all refs]' \
'--tags[all tags under "$GIT_DIR/refs/tags" are pushed]' \
'(--receive-pack --exec)'{--receive-pack=-,--exec=-}'[path to git-receive-pack on remote]:remote path:_files' \
'--repo=-[default repository to use]:repository:__git_any_repositories' \
'( --no-thin)--thin[try to minimize number of objects to be sent]' \
'(--thin )--no-thin[do not try to minimize number of objects to be sent]' \
$verbose_arg \
'::repository:__git_any_repositories' \
'*::refspec:__git_ref_specs' && ret=0
}
(( $+functions[_git-rebase] )) ||
_git-rebase () {
if [[ $words[2] == --(abort|continue|skip) ]]; then
_message 'no more options'
else
_arguments \
'--onto[start new branch with HEAD equal to "newbase"]:newbase' \
'--continue[continue after failure]' \
'--abort[abort current rebase]' \
'--skip[skip the current patch]' \
'--merge[use merging strategies to rebase]' \
'*'{-s,--strategy=-}'[use given merge strategy]:merge strategy:__git_merge_strategies' \
$verbose_arg \
'-C-[ensure that given lines of surrounding context match]: :_guard "[[\:digit\:]]##" "lines of context"' \
':upstream branch:__git_revisions' \
'::working branch:__git_revisions' && ret=0
fi
}
(( $+functions[_git-repack] )) ||
_git-repack () {
_arguments \
'-a[pack all objects into a single pack]' \
'-d[remove redundant packs after packing]' \
'-f[pass "--no-reuse-delta" option to "git pack-objects"]' \
'-l[pass "--local" option to "git pack-objects"]' \
'-n[do not update server information]' \
'-q[pass "-q" option to "git pack-objects"]' \
'--window=-[number of objects to consider when doing delta compression]' \
'--depth=-[maximum delta depth]' && ret=0
}
(( $+functions[_git-rerere] )) ||
_git-rerere () {
declare -a commands
commands=(
'clear:reset the metadata used by rerere'
'diff:output diffs for the current state of the resolution'
'status:like diff, but only output filesames'
'gc:prune old records of conflicted merges')
_describe -t commands 'command' commands
}
(( $+functions[_git-reset] )) ||
_git-reset () {
local commit_arg path_arg
if [[ $words[2] == --mixed ]]; then
commit_arg=':commit:__git_revisions'
path_arg="*:file:__git_tree_files . $words[3]"
else
commit_arg='::commit:__git_revisions'
fi
_arguments -S -A '--*' \
'( --soft --hard)--mixed[like --soft but report what has not been updated (default)]' \
'(--mixed --hard)--soft[do not touch the index file nor the working tree]' \
'(--mixed --soft )--hard[match the working tree and index to the given tree]' \
$commit_arg \
$path_arg && ret=0
}
(( $+functions[_git-revert] )) ||
_git-revert () {
_arguments \
'(-e --edit --no-edit)'{-e,--edit}'[edit the commit before committing the revert]' \
'(-e --edit --no-edit)--no-edit[do not start the commit message editor]' \
'(-n --no-commit)'{-n,--no-commit}'[do not commit the reversion]' \
':commit:__git_commits' && ret=0
}
# TODO: should take all arguments found in setup_revisions() (probably more or
# less what git-rev-list takes).
(( $+functions[_git-shortlog] )) ||
_git-shortlog () {
__git_setup_revision_arguments
_arguments -S \
$revision_arguments \
'(: -)'{-h,--help}'[print a short usage message and exit]' \
'(-n --numbered)'{-n,--numbered}'[sort according to number of commits]' \
'(-s --summary)'{-s,--summary}'[suppress commit description]' \
'*::commitish:__git_committishs' && ret=0
}
# TODO: --date-order is undocumented.
# TODO: Better completion of --reflog.
(( $+functions[_git-show-branch] )) ||
_git-show-branch () {
_arguments -S \
'(--more --independent --merge-base)--list[synonym to "--more=-1"]' \
- branches \
'(-a --all)'{-a,--all}'[show both remote-tracking branches and local branches]' \
'(-r --remotes)'{-r,--remotes}'[show remote-tracking branches]' \
'( --list --independent --merge-base)--more=-[go given number of commit beyond common ancestor (no ancestry if negative)]:: :_guard "[[\:digit\:]]" limit' \
'(--more --list --merge-base)--independent[show only the reference that can not be reached from any of the other]' \
'(--more --list --independent )--merge-base[act like "git-merge-base -a" but with two heads]' \
'--current[include current branch to the list of revs]' \
'( --sha1-name)--no-name[do not show naming strings for each commit]' \
'(--no-name )--sha1-name[name commits with unique prefix of object names]' \
'--topo-order[show commits in topological order]' \
'--topics[show only commits that are NOT on the first branch given]' \
'--sparse[output merges that are reachable from multiple tips being shown]' \
'--date-order[undocumented]' \
'*:revision:__git_revisions' \
- reflogs \
'(-g --reflog)'{-g,--reflog=-}'[show reflog entries for given ref]::number of entries and base' \
':reference:__git_references' && ret=0
}
(( $+functions[_git-status] )) ||
_git-status () {
_git-commit
}
__git_zstyle_default ':completion::complete:git-status:argument-rest:*' ignore-line yes
(( $+functions[_git-verify-tag] )) ||
_git-verify-tag () {
_arguments \
':tag:__git_tags' && ret=0
}
# TODO: This should take those arguments that git-diff-tree can take, as well.
(( $+functions[_git-whatchanged] )) ||
_git-whatchanged () {
__git_setup_revision_arguments
_arguments -S \
$revision_arguments \
'1::commit id:__git_commits2' \
'*:managed file:__git_cached_files' && ret=0
}
(( $+functions[_git-applypatch] )) ||
_git-applypatch () {
_arguments \
':message file:_files' \
':patch file:_files' \
':info file:_files' \
'::signoff file:__git_signoff_file' && ret=0
}
# TODO: Need to combine the list of attributes defined in __git_attributes.
(( $+functions[_git-check-attr] )) ||
_git-check-attr () {
local -a attributes
attributes=(crlf ident filter diff merge)
local only_attributes=1
for (( i = 2; i < $#words; i++ )); do
if (( attributes[(I)$words[i]] == 0 )); then
only_attributes=0
break
fi
done
if (( !only_attributes || words[(I)--] )); then
__git_files && ret=0
else
_alternative \
'files:file:__git_files' \
'attributes:attribute:__git_attributes' && ret=0
fi
}
# TODO: archive/branch can use _arch_archives perhaps?
(( $+functions[_git-archimport] )) ||
_git-archimport () {
_arguments \
'-a[auto-register archives at http://mirrors.sourcecontrol.net]' \
'-D[attempt to import trees that have been merged from]: :_guard "[[\:digit\:]]#" depth' \
'-f[use the fast patchset import strategy]' \
$help_arg \
'-o[use old-style branch names]' \
'-T[create a tag for every commit]' \
'-t[use given directory as temporary directory]:directory:_directories' \
$verbose_arg \
':archive/branch' \
'::archive/branch'
}
(( $+functions[_git-convert-objects] )) ||
_git-convert-objects () {
_nothing
}
# TODO: Could use _cvs_root from _cvs for completing argument to -d.
# TODO: -h is undocumented.
(( $+functions[_git-cvsexportcommit] )) ||
_git-cvsexportcommit () {
_arguments \
'-c[commit automatically if the patch applied cleanly]' \
'-p[be pedantic (paranoid) when applying patches]' \
'-a[add authorship information]' \
'-d[set an alternative CVSROOT to use]:cvsroot' \
'-f[force the merge, even if the files are not up to date]' \
'-P[force the parent commit, even if it is not a direct parent]' \
'-m[prepend the commit message with the provided prefix]:message prefix' \
$verbose_arg \
$help_arg \
'::parent commit id:__git_commits' \
':commit id:__git_commits' && ret=0
}
# TODO: _cvs_root for -d would be nice
(( $+functions[_git-cvsimport] )) ||
_git-cvsimport () {
_arguments \
$author_conversion_file_arg \
'-C[specify the git repository to import into]:directory:_directories' \
'-d[specify the root of the CVS archive]:cvsroot' \
$help_arg \
'-i[do not perform a checkout after importing]' \
'-k[remove keywords from source files in the CVS archive]' \
'-m[attempt to detect merges based on the commit message]' \
'*-M[attempt to detect merges based on the commit message with custom pattern]:pattern' \
'-o[specify the branch into which you wish to import]:branch:__git_branch_names' \
'-P[read cvsps output file]:file:_files' \
'-p[specify additionaly options for cvsps]:cvsps-options' \
'-s[substitute the "/" character in branch names with given substitution]:substitute' \
'-u[convert underscores in tag and branch names to dots]' \
'-S[skip paths matching given regex]:regex' \
'-a[import all commits, including recent ones]' \
'-L[limit the number of commits imported]: :_guard "[[\:digit\:]]" limit' \
$verbose_arg \
'-z[specify timestamp fuzz factor to cvsps]:fuzz-factor' \
':cvsmodule' && ret=0
}
(( $+functions[_git-cvsserver] )) ||
_git-cvsserver () {
_message "you probably should not be issuing this command; it is an internal git helper"
}
(( $+functions[_git-lost-found] )) ||
_git-lost-found () {
_nothing
}
(( $+functions[_git-pack-refs] )) ||
_git-pack-refs () {
_arguments \
'--all[pack all refs]' \
'( --no-prune)--prune[remove loose refs after packing them]' \
'(--prune )--no-prune[don'\''t remove loose refs after packing them]' && ret=0
}
# TODO: something better
(( $+functions[_git-merge-one-file] )) ||
_git-merge-one-file () {
_message "you probably should not be issuing this command"
}
(( $+functions[_git-prune] )) ||
_git-prune () {
_arguments -S \
'-n[do not remove anything; just report what would have been removed]' \
'--expire:time:' \
'*::heads:__git_heads' && ret=0
}
(( $+functions[_git-relink] )) ||
_git-relink () {
_arguments \
'--safe[stop if two objects with the same hash exist but have different sizes]' \
':directory:_directories' \
':directory:_directories' \
'*:directory:_directories' && ret=0
}
# TODO: import stuff from _svn
# TODO: Improve completion of -P argument.
(( $+functions[_git-svnimport] )) ||
_git-svnimport () {
_arguments \
$author_conversion_file_arg \
'-b[specify the name of the SVN branches directory]:directory:_directories' \
'-C[specify the git repository to import into]:directory:_directories' \
'-d[use direct HTTP-requests if possible for logs only]:path' \
'-D[use direct HTTP-requests if possible]:path' \
$help_arg \
'-i[do not perform a checkout after importing]' \
'-l[limit the number of SVN changesets to pull]: :_guard "[[\:digit\:]]#" number' \
'-m[attempt to detect merges based on the commit message]' \
'-M[attempt to detect merges based on the commit message with custom pattern]:pattern' \
'-o[specify the branch into which you wish to import]:branch' \
'-r[prepend "rX: " to commit messages, where X is the subversion revision]' \
'-s[specify the change number to start importing from]:start-revision' \
'-T[specify the name of the SVN tags directory]:directory:_directories' \
'-t[specify the name of the SVN trunk]:trunk:_directories' \
'-I[import svn:ignore directory property to files with given name]:ignored file:_files' \
'-R[specify how often git repository should be repacked]: :_guard "[[\:digit\:]]#" "number of revisions"' \
'-P[import only given path of the SVN tree]::_directory' \
$verbose_arg \
':svn-repositry-url:_urls' \
'::directory:_directories' && ret=0
}
# TODO: how do we complete argument 1?
(( $+functions[_git-symbolic-ref] )) ||
_git-symbolic-ref () {
_arguments -A '-*' \
'-q[do not issue error if specified name is not a symbolic ref]' \
'-m[update reflog for specified name with specied reason]:reason for update' \
':symbolic reference' \
'::reference:__git_references' && ret=0
}
(( $+functions[_git-tag] )) ||
_git-tag () {
local message_args=
if (( words[(I)-[asu]] )); then
message_args=(
'( -F)-m[specify tag message]:message'
'(-m )-F[read tag message from given file]:message file:_files')
fi
_arguments -A '-*' \
- creation \
'( -s -u)-a[create an unsigned, annotated tag]' \
'(-a -u)-s[create an signed and annotated tag]' \
'(-a -s )-u[create a tag, annotated and signed with the given key]:secret key:__git_gpg_secret_keys' \
'( -v)-f[create a new tag even if one with the same name already exists]' \
'(-f )-v[verifies the gpg signutare of the given tag]' \
$message_args \
':tag name:__git_tags' \
'::head:__git_revisions' \
- deletion \
'-d[delete tags]:*:tag names:__git_tags' \
- listing \
'-l[list tags matching pattern]:pattern' && ret=0
}
__git_zstyle_default ':completion::complete:git-tag:deletion-option-d-rest:*' ignore-line yes
(( $+functions[_git-update-ref] )) ||
_git-update-ref () {
_arguments \
'-m[update reflog for specified name with specied reason]:reason for update' \
'(:)-d[delete given reference after verifying its value]:symbolic reference:__git_revisions:old reference:__git_revisions' \
':symbolic reference:__git_revisions' \
':new reference:__git_revisions' \
'::old reference:__git_revisions' && ret=0
}
(( $+functions[_git-check-ref-format] )) ||
_git-check-ref-format () {
_arguments \
':reference:__git_revisions' && ret=0
}
(( $+functions[_git-cherry] )) ||
_git-cherry () {
_arguments \
$verbose_arg \
':upstream:__git_revisions' \
'::head:__git_revisions' \
'::limit:__git_revisions' && ret=0
}
(( $+functions[_git-count-objects] )) ||
_git-count-objects () {
_arguments \
'-v[also report number of in-pack objects and objects that can be removed]' && ret=0
}
# TODO: do better than _directories? The directory needs to be a git-repository,
# so one could check for a required file in the given directory.
# TODO: --interpolated-path should complete %H, %CH, %IP, %P, and %D.
(( $+functions[_git-daemon] )) ||
_git-daemon () {
_arguments -S \
'--strict-paths[match paths exactly]' \
'--base-path=-[remap all the path requests as relative to the given path]:path:_directories' \
'--interpolated-path=-[dynamically construct alternate paths]:path:_directories' \
'--export-all[allow pulling from all repositories without verification]' \
'(--port --listen --user --group)--inetd[run server as an inetd service]' \
'(--inetd)--listen=-[listen on a specific IP address or hostname]:hostname:_hosts' \
'(--inetd)--port=-[specify port to listen to]:port:_ports' \
'--init-timeout=-[specify timeout between connection and request]: :_guard "[[\:digit\:]]#" timeout' \
'--timeout=-[specify timeout for sub-requests]: :_guard "[[\:digit\:]]#" timeout' \
'--syslog[log to syslog instead of stderr]' \
'--user-path=-[allow ~user notation to be used in requests]::path:_directories' \
'--verbose[log details about incoming connections and requested files]' \
'--reuseaddr[reuse addresses when already bound]' \
'(--syslog)--detach[detach from the shell]' \
'--pid-file=-[save the process id in given file]:pid file:_files' \
'--user=-[set uid of daemon]:user:_users' \
'--group=-[set gid of daemon]:group:_groups' \
'--enable=-[enable site-wide service]:service:__git_daemon_service' \
'--disable=-[disable site-wide service]:service:__git_daemon_service' \
'--allow-override[allow overriding site-wide service]:service:__git_daemon_service' \
'--forbid-override[forbid overriding site-wide service]:service:__git_daemon_service' \
'*:repository:_directories' && ret=0
}
(( $+functions[_git-get-tar-commit-id] )) ||
_git-get-tar-commit-id () {
_message 'no arguments allowed; accepts tar-file on standard input'
}
(( $+functions[_git-instaweb] )) ||
_git-instaweb () {
_arguments \
'(-l --local)'{-l,--local}'[bind the web server to 127.0.0.1]' \
'(-d --httpd)'{-d,--httpd=}'[HTTP-daemon command-line that will be executed]:command line' \
'(-m --module-path)'{-m,--module-path=}'[module path for the Apache HTTP-daemon]:module path:_directories' \
'(-p --port)'{-p,--port=}'[port to bind web server to]: :_guard "[[\:digit\:]]" port' \
'(-b --browser)'{-b,--browser=}'[web-browser command-line that will be executed]:command line' \
'--start[start the HTTP-daemon and exit]' \
'--stop[start the HTTP-daemon and exit]' \
'--restart[restart the HTTP-daemon and exit]' && ret=0
}
(( $+functions[_git-mailinfo] )) ||
_git-mailinfo () {
_arguments \
'-k[do not strip/add \[PATCH\] from the first line of the commit message]' \
'(-u --encoding)-u[encode commit information in UTF-8]' \
'(-u --encoding)--encoding[encode commit information in given encoding]:encoding:__git_encodings' \
':message file:_files' \
':patch file:_files' && ret=0
}
# TODO:
# /* Backwards compatibility: if no -o specified, accept
# <mbox> <dir> or just <dir> */
(( $+functions[_git-mailsplit] )) ||
_git-mailsplit () {
_arguments -S \
'-b[if file does not begin with "From " line, assume it is a single mail message]' \
'-d-[specify number of leading zeros]: :_guard "[[\:digit\:]]#" precision' \
'-f-[skip the first N numbers]: :_guard "[[\:digit\:]]#" number' \
'-o-[directory in which to place individual messages]:directory:_directories' \
'*::mbox file:_files' && ret=0
}
(( $+functions[_git-patch-id] )) ||
_git-patch-id () {
_message 'no arguments allowed; accepts patch on standard input'
}
(( $+functions[_git-request-pull] )) ||
_git-request-pull () {
_arguments \
':start commit:__git_commits' \
':url:_urls' \
'::end commit:__git_commits'
}
(( $+functions[_git-rev-parse] )) ||
_git-rev-parse () {
_arguments \
'(--revs-only --no-revs)--revs-only[do not output flags and parameters not meant for "git-rev-list"]' \
'(--revs-only --no-revs)--no-revs[do not output flags and parameters meant for "git-rev-list"]' \
'(--flags --no-flags)--flags[do not output non-flag parameters]' \
'(--flags --no-flags)--no-flags[do not output flag parameters]' \
'--default[use "arg" if there is no parameter given]:arg' \
'--verify[verify parameter to be usable]' \
'--sq[output single shell-quoted line]' \
'--not[toggle ^ prefix of object names]' \
'--symbolic[output in a format as true to input as possible]' \
'--all[show all refs found in $GIT_DIR/refs]' \
'--branches[show branch refs found in $GIT_DIR/refs/heads]' \
'--tags[show tag refs found in $GIT_DIR/refs/tags]' \
'--remotes[show tag refs found in $GIT_DIR/refs/remotes]' \
'--show-prefix[show path of current directory relative to top-leve directory]' \
'--show-cdup[show path of top-level directory relative to current directory]' \
'--git-dir[show "$GIT_DIR" if defined else show path to ".git" directory]' \
'--short=-[show only handful hexdigits prefix]:: :_guard "[[\:digit\:]]#" number' \
{--after=-,--since=-}'[show "--max-age=" parameter corresponding given date string]:datestring' \
{--berore=-,--until=-}'[show "--min-age=" parameter corresponding given date string]:datestring' \
'*:objects:__git_objects' && ret=0
}
(( $+functions[_git-runstatus] )) ||
_git-runstatus () {
_arguments \
'--color[show colored status, highlighting modified files]' \
'--nocolor[turn of colored output]' \
'--amend[show status based on HEAD^1 instead of HEAD]' \
'--verbose[show unified diff of all file changes]' \
'--untracked[show files in untracked directories]' && ret=0
}
(( $+functions[_git-rm] )) ||
_git-rm () {
_arguments -S -A '-*' \
'-f[override the up-to-date check]' \
'-n[don'\''t actually remove the files, just show if they exist in the index]' \
'-r[allow recursive removal when a leading directory-name is given]' \
'--cached[only remove files from the index]' \
'*:files:__git_cached_files' && ret=0
}
(( $+functions[_git-send-email] )) ||
_git-send-email () {
_arguments \
'--bcc=["Bcc:" value for each email]:email address:_email_addresses' \
'--cc=[starting "Cc:" value for each email]:email address:_email_addresses' \
'(--no-chain-reply-to)--chain-reply-to[each email will be sent as a reply to the previous one sent]' \
'(--chain-reply-to)--no-chain-reply-to[all emails after the first will be sent as replies to the first one]' \
'--compose[use $EDITOR to edit an introductory message for the patch series]' \
'--from=[specify the sender of the emails]:email address:_email_addresses' \
'--in-reply-to=[specify the contents of the first In-Reply-To header]:message-id' \
'--no-signed-off-by-cc[do not add emails foudn in "Signed-off-by:" lines to the "Cc:" list]' \
'--quiet[be less verbose]' \
'--smtp-server=[specify the outgoing smtp server]:smtp server:_hosts' \
'--subject=[specify the initial subject of the email thread]:subject' \
'--suppress-from[do not add the "From:" address to the "Cc:" list]' \
'--dry-run[do everything except actually send the emails]' \
'--envelope-sender[specify the envelope sender used to send the emails]:email address:_email_addresses' \
'--to=[specify the primary recipient of the emails]:email address:_email_addresses' \
'*:file:_files' && ret=0
}
# TODO: -h, -H, and --help are undocumented.
# TODO: -V and --version are undocumented.
# TODO: --minimize-connections is undocumented.
# TODO: --remote is undocumented.
# TODO: --log-window-size is undocumented.
# TODO: --config-dir is undocumented.
# TODO: --no-auth-cache is undocumented.
# TODO: -C and --copy-similarity are undocumented.
# TODO: --fetch-all and --all are undocumented.
# TODO: -v and --verbose are undocumented.
# TODO: -r and --revisions for show-ignore are undocumented.
# TODO: migrate is undocumented.
# TODO: --minimize for migrate is undocumented.
# TODO: -r, --color, --pager, and --non-recursive for log are undocumented.
# TODO: --local for rebase is undocumented.
# TODO: --message, -m, --file, -F, --revision, and -r for commit-diff are
# undocumented.
(( $+functions[_git-svn] )) ||
_git-svn () {
local curcontext=$curcontext state line
declare -A opt_args
_arguments -C \
'(- :)--version[display version information]' \
'(- :)--help[display help message]' \
':command:->command' \
'*::options:->options' && ret=0
case $state in
(command)
declare -a commands
commands=(
'init:initialize an empty git repository with additional svn data'
'fetch:fetch revisions from the SVN remote'
'clone:same as init, followed by fetch'
'rebase:fetch revs from SVN parent of HEAD and rebase current work on it'
'dcommit:commit diffs from given head onto SVN repository'
'log:output SVN log-messages'
'find-rev:output git commit corresponding to the given SVN revision'\''s hash'
'set-tree:commit given commit or tree to SVN repository'
'show-ignore:output corresponding .gitignore file of svn:ignore'
'commit-diff:commit diff of two tree-ishs')
_describe -t commands command commands && ret=0
;;
(options)
declare -a arguments
if [[ $line[1] == (fetch|clone|dcommit|set-tree|rebase|migrate|init) ]]; then
arguments+=(
'--username=[username to use for SVN transport]:username:_users'
'--config-dir=[undocumented]:configuration directory:_directories'
'--no-auth-cache[undocumented]')
fi
if [[ $line[1] == (fetch|clone|dcommit|set-tree|rebase|log) ]]; then
arguments+=(
'( --authors-file)'$author_conversion_file_arg
'(-A )'$long_author_conversion_file_arg)
fi
# TODO: --repack-flags can be improved by actually completing the legal
# flags to git-repack.
if [[ $line[1] == (fetch|clone|dcommit|set-tree|rebase) ]]; then
arguments+=(
'(-q --quiet)'{-q,--quiet}'[make git-svn less verbose]'
'--repack=[repack files (for given number of revisions)]:: :_guard "[[\:digit\:]]#" "revision limit"'
'(--repack-flags --repack-args --repack-opts)'{--repack-flags=,--repack-args=,--repack-opts=}'[flags to pass to git-repack]:git-repack flags'
'( --no-follow-parent)--follow-parent[follow parent commit]'
'(--follow-parent )--no-follow-parent[do not follow parent commit]'
'--log-window-size=[undocumented]')
fi
if [[ $line[1] == (clone|init) ]]; then
arguments+=(
$shared_arg
$template_arg
'(-T --trunk)'{-T-,--trunk=}'[set trunk sub-directory]:trunk sub-directory:->subdirectory'
'(-t --tags)'{-t-,--tags=}'[set tags sub-directory]:tags sub-directory:->subdirectory'
'(-b --branches)'{-b-,--branches=}'[set branches sub-directory]:branches sub-directory:->subdirectory'
'--no-metadata[set svn-remote.X.noMetadata]'
'--use-svm-props[set svn-remote.X.useSvmProps]'
'--use-svnsync-props[set svn-remote.X.useSvnsyncProps]'
'--rewrite-root=[set svn-remote.X.rewriteRoot]:new root'
'--prefix=[prefix to use for names of remotes]:path prefix:_directories -r ""')
fi
if [[ $line[1] == (dcommit|set-tree|commit-diff) ]]; then
arguments+=(
'--rmdir[remove empty directories from SVN tree after commit]'
'(-e --edit)'{-e,--edit}'[edit commit message before committing]'
$find_copies_harder_arg
$diff_l_arg
'(-C --copy-similarity)'{-C-,--copy-similarity=}'[undocumented]:number')
fi
# FIXME: What arguments does clone actually take here?
if [[ $line[1] == (fetch|clone) ]]; then
arguments+=(
'(-r --revision)'{-r,--revision}'[only fetch given revision or revision range]:revision:->__git_svn_revisions'
'::svn remote:__git_svn-remotes')
fi
if [[ $line[1] == (dcommit|rebase) ]]; then
arguments+=(
'(-m --merge)'{-m,--merge}'[use merging strategies, if necessary]')
fi
if [[ $line[1] == (fetch|dcommit|rebase) ]]; then
arguments+=(
'(--fetch-all --all)'{--fetch-all,--all}'[undocumented]')
fi
if [[ $line[1] == (dcommit|rebase) ]]; then
arguments+=(
'*'{-s,--strategy=-}'[use given merge strategy]:merge strategy:__git_merge_strategies')
fi
if [[ $line[1] == (dcommit|log|rebase) ]]; then
arguments+=(
'(- --verbose)'{-v,--verbose}'[output extra information]')
fi
case $line[1] in
(clone)
arguments+=(
':url:_urls'
'::directory:_directories')
;;
(set-tree)
arguments+=('--stdin[read list of commits to commit from stdin]')
;;
(show-ignore)
arguments+=('-r --revision)'{-r,--revision)'[undocumented]:revision:->__git_svn_revisions'
(dcommit)
arguments+=(
'(-n --dry-run)'{-n,--dry-run}'[output git-commands that would show diffs that would be committed]')
;;
(migrate)
arguments+=(
'--minimize[undocumented]')
;;
(log)
__git_setup_revision_arguments
arguments+=(
$revision_arguments
'(-r --revision)'{-r-,--revision=}'[revisions to output log information for]: :__git_svn_revision_numbers'
'--limit=[like --max-count, but not counting merged/excluded commits]: :_guard "[[\:digit\:]]#" limit'
'--incremental[give output suitable for concatenation]'
'--show-commit[output git commit SHA-1, as well]'
'--oneline[similar to --pretty=oneline]'
'--color[undocumented]'
'--pager[undocumented]:pager:_files -g *(*)'
'--non-recursive[undocumented]')
;;
(rebase)
arguments+=(
'--local[undocumented]')
;;
(commit-diff)
arguments+=(
'(-m --message)'{-m-,--message=}'[undocumented]:message'
'(-F --file)'{-F-,--file=}'[undocumented]:file:_files'
'(-r --revision)'{-r-,--revision=}'[undocumented]:revision:__git_svn_revisions')
;;
esac
_arguments -C \
'(-h -H --help)'{-h,-H,--help}'[display usage information]' \
'(-V --version)'{-V,--version}'[display version information]' \
'--minimize-connections[undocumented]' \
'(-R --svn-remote --remote)'{-R,--svn-remote,--remote}'[svn remote to use]:svn remote:__git_svn-remotes' \
'(-i --id)'{-i,--id}'[set GIT_SVN_ID]:GIT_SVN_ID' \
$arguments && ret=0
case $state in
(subdirectory)
_alternative \
'sub-directories:sub-directory:_directories' \
'urls: :_urls' && ret=0
;;
esac
;;
esac
}
(( $+functions[_git-stripspace] )) ||
_git-stripspace () {
_message 'no arguments allowed; accepts input file on standard input'
}
(( $+functions[_git-mergetool] )) ||
_git-mergetool () {
local curcontext=$curcontext state line
typeset -A opt_args
_arguments -C \
'(-t --tool)'{-t,--tool=}':merge resolution tool:(kdiff3 tkdiff meld xxdiff emerge vimdiff gvimdiff opendiff)' \
'*:conflicted file:_files' && ret=0
}
# ---
(( $+functions[__git_guard] )) ||
__git_guard () {
declare -A opts
zparseopts -K -D -A opts M: J: V: 1 2 n F: X:
[[ "$PREFIX$SUFFIX" != $~1 ]] && return 1
if (( $+opts[-X] )); then
_message -r $opts[-X]
else
_message -e $2
fi
[[ -n "$PREFIX$SUFFIX" ]]
}
__git_guard_branch-name () {
if [[ -n "$PREFIX$SUFFIX" ]]; then
_call_program check-ref-format git check-ref-format "refs/heads/$PREFIX$SUFFIX" &>/dev/null
(( ${#pipestatus:#0} > 0 )) && return 1
fi
_message -e 'branch-name'
[[ -n "$PREFIX$SUFFIX" ]]
}
__git_guard_diff-stat-width () {
if [[ $PREFIX == *,* ]]; then
compset -P '*,'
_guard "[[:digit:]]#" "filename width"
else
compset -S ',*'
_guard "[[:digit:]]#" "width"
fi
}
(( $+functions[__git_command_successful] )) ||
__git_command_successful () {
if (( ${#pipestatus:#0} > 0 )); then
_message 'not a git repository'
return 1
fi
return 0
}
(( $+functions[__git_objects] )) ||
__git_objects () {
compset -P '*:'
if [[ -n $IPREFIX ]]; then
__git_tree_files "$PREFIX" "${IPREFIX%:}"
else
_alternative \
'revisions:revision:__git_revisions' \
'files:file:__git_files'
fi
}
(( $+functions[__git_trees] )) ||
__git_trees () {
__git_objects
}
(( $+functions[__git_tree_ishs] )) ||
__git_tree_ishs () {
__git_commits
}
(( $+functions[__git_blobs] )) ||
__git_blobs () {
__git_objects
}
(( $+functions[__git_stages] )) ||
__git_stages () {
__git_guard $* "[[:digit:]]#" 'stage'
}
(( $+functions[__git_files] )) ||
__git_files () {
local expl files ls_opts opts gitdir
zparseopts -D -E -a opts -- -cached -deleted -modified -others -ignored -unmerged -killed
gitdir=$(_call_program gitdir git rev-parse --git-dir 2>/dev/null)
__git_command_successful || return
ls_opts=("--exclude-per-directory=.gitignore")
[[ -f "$gitdir/info/exclude" ]] && ls_opts+="--exclude-from=$gitdir/info/exclude"
files=(${(ps:\0:)"$(_call_program files git ls-files -z $ls_opts $opts 2>/dev/null)"})
__git_command_successful || return
_wanted files expl 'index file' _multi_parts $@ - / files
}
(( $+functions[__git_cached_files] )) ||
__git_cached_files () {
__git_files $* --cached
}
(( $+functions[__git_deleted_files] )) ||
__git_deleted_files () {
__git_files $* --deleted
}
(( $+functions[__git_killed_files] )) ||
__git_killed_files () {
__git_files $* --killed
}
(( $+functions[__git_modified_files] )) ||
__git_modified_files () {
__git_files $* --modified
}
(( $+functions[__git_other_files] )) ||
__git_other_files () {
__git_files $* --others
}
(( $+functions[__git_unmerged_files] )) ||
__git_unmerged_files () {
__git_files $* --unmerged
}
#this is for git-commit which can take files both git-added and not
(( $+functions[__git_changed_files] )) ||
__git_changed_files () {
local -a files
files=(${(ps:\0:)"$(_call_program files git diff-index -z --name-only --no-color HEAD 2>/dev/null)"})
__git_command_successful || return
_wanted files expl 'index file' _multi_parts $@ - / files
}
(( $+functions[__git_tree_files] )) ||
__git_tree_files () {
local multi_parts_opts
zparseopts -D -E -a multi_parts_opts M: J: V: 1 2 n F: X:
local tree Path
integer at_least_one_tree_added
local -a tree_files
[[ "$1" == */ ]] && Path="$1" || Path="${1:h}/"
shift
(( at_least_one_tree_added = 0 ))
for tree in $*; do
tree_files+=(${(ps:\0:)"$(_call_program tree-files git ls-tree --name-only -z $tree $Path 2>/dev/null)"})
__git_command_successful && (( at_least_one_tree_added = 1 ))
done
if (( !at_least_one_tree_added )); then
return
fi
local expl
_wanted files expl 'tree file' compadd $multi_parts_opts -f -a tree_files
}
# TODO: deal with things that __git_heads and __git_tags has in common (i.e.,
# if both exists, they need to be completed to heads/x and tags/x.
(( $+functions[__git_commits] )) ||
__git_commits () {
_alternative \
'heads::__git_heads' \
'tags::__git_tags'
}
(( $+functions[__git_committishs] )) ||
__git_committishs () {
__git_commits
}
# TODO: deal with prefixes and suffixes listed in git-rev-parse
(( $+functions[__git_revisions] )) ||
__git_revisions () {
__git_commits $*
}
(( $+functions[__git_commits2] )) ||
__git_commits2 () {
compset -P '\\\^'
__git_commits
}
(( $+functions[__git_commit_ranges] )) ||
__git_commit_ranges () {
compset -P '*..'
__git_commits $*
}
# FIXME: these should be imported from _ssh
# TODO: this should take -/ to only get directories
_remote_files () {
# There should be coloring based on all the different ls -F classifiers.
local expl rempat remfiles remdispf remdispd args suf ret=1
if zstyle -T ":completion:${curcontext}:files" remote-access; then
zparseopts -D -E -a args p: 1 2 4 6 F:
if [[ -z $QIPREFIX ]]
then rempat="${PREFIX%%[^./][^/]#}\*"
else rempat="${(q)PREFIX%%[^./][^/]#}\*"
fi
remfiles=(${(M)${(f)"$(_call_program files ssh $args -a -x ${IPREFIX%:} ls -d1FL "$rempat" 2>/dev/null)"}%%[^/]#(|/)})
compset -P '*/'
compset -S '/*' || suf='remote file'
# remdispf=(${remfiles:#*/})
remdispd=(${(M)remfiles:#*/})
_tags files
while _tags; do
while _next_label files expl ${suf:-remote directory}; do
# [[ -n $suf ]] && compadd "$@" "$expl[@]" -d remdispf \
# ${(q)remdispf%[*=@|]} && ret=0
compadd ${suf:+-S/} "$@" "$expl[@]" -d remdispd \
${(q)remdispd%/} && ret=0
done
(( ret )) || return 0
done
return ret
else
_message -e remote-files 'remote file'
fi
}
(( $+functions[__git_remote_repository] )) ||
__git_remote_repository () {
local service
service= _ssh
if compset -P '*:'; then
_remote_files
else
_ssh_hosts -S:
fi
}
(( $+functions[__git_repository] )) ||
__git_repository () {
_alternative \
'directories::_directories' \
'remote repositories::__git_remote_repository'
}
# should also be $GIT_DIR/remotes/origin
(( $+functions[__git_any_repositories] )) ||
__git_any_repositories () {
_alternative \
'directories::_directories' \
'remotes::__git_remotes' \
'remote repositories::__git_remote_repository'
}
(( $+functions[__git_remotes] )) ||
__git_remotes () {
local expl gitdir remotes
gitdir=$(_call_program gitdir git rev-parse --git-dir 2>/dev/null)
__git_command_successful || return
# zparseopts -a opts X+:
#
# if (( !$opts[(I)-X] )); then
# descr=remote
# fi
remotes=(${${(f)"$(_call_program remotes git config --get-regexp '"^remote\..*\.url$"')"}//#(#b)remote.(*).url */$match[1]})
__git_command_successful || return
# TODO: Should combine the two instead of either or.
if (( $#remotes > 0 )); then
_wanted remotes expl remote compadd $* - $remotes
else
_wanted remotes expl remote _files $* - -W "($gitdir/remotes)" -g "$gitdir/remotes/*"
fi
}
(( $+functions[__git_ref_specs] )) ||
__git_ref_specs () {
if compset -P '*:'; then
__git_heads
else
compset -P '+'
if compset -S ':*'; then
__git_heads
else
_alternative \
'tags:tag:__git_tags' \
'heads:head:__git_heads -qS :'
fi
fi
}
(( $+functions[__git_signoff_file] )) ||
__git_signoff_file () {
_alternative \
'signoffs:signoff:(yes true me please)' \
'files:signoff file:_files'
}
(( $+functions[__git_tag_ids] )) ||
__git_tag_ids () {
}
(( $+functions[__git_heads] )) ||
__git_heads () {
local expl
declare -a branch_names
branch_names=(${${(f)"$(_call_program heads git branch --no-color -a 2>/dev/null)"}#[* ] })
__git_command_successful || return
_wanted heads expl branch-name compadd $* - $branch_names
}
(( $+functions[__git_tags] )) ||
__git_tags () {
local expl
declare -a tag_names
tag_names=(${${(f)"$(_call_program tags git tag -l 2>/dev/null)"}#[* ] })
__git_command_successful || return
_wanted tags expl tag-name compadd $* - $tag_names
}
# TODO: depending on what options are on the command-line already, complete
# only tags or heads
# TODO: perhaps caching is unnecessary. usually won’t contain that much data
# TODO: perhaps provide alternative here for both heads and tags (and use
# __git_heads and __git_tags)
# TODO: instead of "./.", we should be looking in the repository specified as
# an argument to the command (but default to "./." I suppose (why not "."?))
(( $+functions[__git_references] )) ||
__git_references () {
# _alternative \
# 'heads::__git_heads' \
# 'tags::__git_tags' && ret=0
local expl
# TODO: deal with GIT_DIR
if [[ $_git_refs_cache_pwd != $PWD ]]; then
_git_refs_cache=(${${${(f)"$(_call_program references git ls-remote ./. 2>/dev/null)"}#*$'\t'}#refs/(heads|tags)/})
__git_command_successful || return
_git_refs_cache_pwd=$PWD
fi
_wanted references expl 'references' compadd - $_git_refs_cache
}
(( $+functions[__git_local_references] )) ||
__git_local_references () {
local expl
if [[ $_git_local_refs_cache_pwd != $PWD ]]; then
_git_local_refs_cache=(${${${(f)"$(_call_program references git ls-remote ./. 2>/dev/null)"}#*$'\t'}#refs/})
__git_command_successful || return
_git_local_refs_cache_pwd=$PWD
fi
_wanted references expl 'references' compadd - $_git_local_refs_cache
}
(( $+functions[__git_remote_references] )) ||
__git_remote_references () {
__git_references
}
(( $+functions[__git_branch_names] )) ||
__git_branch_names () {
local expl
declare -a branch_names
branch_names=(${${(f)"$(_call_program branch-names git branch --no-color 2>/dev/null)"}#[* ] })
__git_command_successful || return
_wanted branch-names expl branch-name compadd $* - $branch_names
}
# TODO: Add merge.*.(name|driver|recursive) and diff.*.(command|funcname) (see
# gitattributes(5)).
(( $+functions[__git_config_name] )) ||
__git_config_name () {
local label=names
declare -a names
if [[ -prefix alias.* ]]; then
_message 'command-alias name'
elif [[ -prefix branch.*.* ]]; then
compset -P 'branch.*.'
names=(
'remote:what remote git-fetch should fetch'
'merge:default refspec to be marked for merging')
elif [[ -prefix branch.* ]]; then
compset -P 'branch.'
__git_branch_names -S '.' -r '.'
return
elif [[ -prefix remote.*.* ]]; then
compset -P 'remote.*.'
names=(
'url:URL of a remote repository'
'fetch:default set of refspecs for git-fetch'
'push:default set of refspecs for git-push'
'skipDefaultUpdate:whether to skip this remote when running git-remote'
'receivepack:default program to execute on remote when pushing'
'uploadpack:default program to execute on remote when fetching'
'tagopt:options for retrieving remote tags')
elif [[ -prefix remote.* ]]; then
compset -P 'remote.'
__git_remotes -S '.' -r '.'
return
elif [[ -prefix remotes.* ]]; then
compset -P 'remotes.'
__git_remote-groups
return
elif [[ -prefix gitcvs.* ]]; then
names=(
'enabled:whether the cvs pserver interface is enabled'
'logfile:name of log file for cvs pserver'
'allbinary:whether to treat all files from CVS as binary')
if [[ -prefix gitcvs.*.* ]]; then
compset -P 'gitcvs.*.'
label="gitcvs ${${words[CURRENT]#gitcvs.}%.*}-specific setting"
else
compset -P 'gitcvs.'
label='gitcvs setting'
names+=(
'dbname:name of database to use'
'dbdriver:name of DBI driver to use'
'dbuser:username to connect to database as'
'dbpass:password to use when connecting to database')
declare -a suffixed_names
suffixed_names=(
'ext:ext-connection-method-specific settings'
'pserver:pserver-connection-method-specific settings')
_describe -t suffixed-names 'gitcvs connection-specific setting' suffixed_names -M 'm:{a-zA-Z}={A-Za-z}' -M 'r:|.=* r:|=*' -S '.' -r '.' && ret=0
fi
elif [[ -prefix svn-remote.*.* ]]; then
compset -P 'svn.*.'
label="git-svn ${${words[CURRENT]#svn.}%.*}-specific setting"
names=(
'noMetadata:disable git-svn-id\: lines at end of commits (fetch, clone, dcommit, set-tree, rebase)'
'useSvmProps:whether to use remappings of URLs and UUIDs from mirrors (fetch, clone, dcommit, set-tree, rebase)'
'useSvnsyncProps:similar to useSvmProps, but for the svnsync command (fetch, clone, dcommit, set-tree, rebase)'
'rewriteRoot:alternate root URL to use')
elif [[ -prefix svn-remote.* ]]; then
compset -P 'svn-remote.'
__git_svn-remotes -M 'm:{a-zA-Z}={A-Za-z}' -M 'r:|.=* r:|=*' -S '.' -r '.' && ret=0
return
else
names=(
'core.fileMode:whether differences in the executable bit is relevant'
'core.autocrlf:what type of conversion of CRLF'\''s git should do'
'core.symlinks:whether symlinks are treated as special files or not'
'core.gitProxy:command to execute to establish a connection to remote server'
'core.ignoreStat:whether modification times of files are ignored'
'core.preferSymlinkRefs:whether symbolic-reference files should be symlinks'
'core.bare:whether this repository has a working tree or not'
'core.logAllRefUpdates:whether to log updates of references'
'core.repositoryFormatVersion:internal variable determining the repository version'
'core.sharedRepository:what kind of sharing is done for this repository'
'core.warnAmbiguousRefs:whether to warn if a ref name is ambiguous'
'core.compression:level of compression to apply to packs'
'core.legacyheaders:whether to use the legacy object-header-format'
'core.packedGitWindowSize:size of mappings of pack files'
'core.packedGitLimit:maximum number of bytes to map from pack files'
'core.deltaBaseCacheLimit:maximum size of cache for base objects'
'apply.whitespace:default value for the --whitespace option to git-apply'
'color.branch:when to color output of git-branch'
'color.branch.current:color of the current branch'
'color.branch.local:color of a local branch'
'color.branch.remote:color of a remote branch'
'color.branch.plain:color of other branches'
'color.diff:when to color diff output'
'color.diff.plain:color of context text'
'color.diff.meta:color of metainformation'
'color.diff.frag:color of hunk headers'
'color.diff.old:color of removed lines'
'color.diff.new:color of added lines'
'color.diff.commit:color of commit headers'
'color.diff.whitespace:color of dubious whitespace'
'color.pager:whether the pager is fed colored output'
'color.status:when to color output of git-status'
'color.status.header:color of header text'
'color.status.added:color of added, but not yet committed, files'
'color.status.updated:color of updated, but not yet committed, files'
'color.status.changed:color of changed, but not yet added in the index, files'
'color.status.untracked:color of files not currently being tracked'
'diff.renameLimit:number of files to consider when detecting copy/renames'
'diff.renames:how hard to try to detect renames'
'fetch.unpackLimit:maximum number of objects to unpack when fetching'
'format.headers:additional email headers to include in email patches'
'format.suffix:default suffix for output files from git-format-patch'
'gc.packrefs:whether to allow git-gc to run git-pack-refs or not'
'gc.reflogexpire:default age for "git reflog expire"'
'gc.reflogexpireunreachable:default age for "git reflog expire" for unreachable'
'gc.rerereresolved:number of days to keep records of resolved merges'
'gc.rerereunresolved:number of days to keep records of unresolved merges'
'http.sslVerify:whether to verify the SSL certificate for HTTPS'
'http.sslCert:file containing SSL certificates for HTTPS'
'http.sslKey:file containing the SSL private key for HTTPS'
'http.sslCAInfo:file containing CA certificates to verify against for HTTPS'
'http.sslCAPath:path containing files with CA certificates to verify against for HTTPS'
'http.maxRequests:how many HTTP requests to launch in parallel'
'http.lowSpeedLimit:lower limit for HTTP transfer-speed'
'http.lowSpeedTime:duration for http.lowSpeedLimit'
'http.noEPSV:whether to disable the use of the EPSV ftp-command'
'i18n.commitEncoding:character encoding commit messages are stored in'
'i18n.logOutputEncoding:character encoding commit messages are output in'
'log.showroot:whether to show initial commit as a diff against an empty tree or not'
'merge.summary:whether to include summaries of merged commits'
'merge.tool:tool to use for merges (by git-mergetool)'
'merge.verbosity:amount of output shown by recursive merge strategy'
'pack.window:size of window used by git-pack-objects'
'pull.octopus:default merge strategy to use when pulling multiple branches'
'pull.twohead:default merge strategy to use when pulling a single branch'
'repack.usedeltabaseoffset:whether to allow git-repack to use delta-base offsets'
'show.difftree:default git-diff-tree options for git-show'
'showbranch.default:default set of branches for git-show-branch'
'tar.umask:umask to apply for git-tar-tree'
'user.email:email address used for commits'
'user.name:full name used for commits'
'user.signingkey:default GPG key to use when creating signed tags'
'whatchanged.difftree:default git-diff-tree arguments for git-whatchanged'
'receive.unpackLimit:maximum number of objects to unpack when pushing'
'receive.denyNonFastforwards:whether git-receive-pack denies ref updates which are not fast-forwards'
'transfer.unpackLimit:default value for fetch.unpackLimit and receive.unpackLimit'
'imap.Folder:IMAP folder to use with git-imap-send'
'imap.Tunnel:tunneling command to use for git-imap-send'
'imap.Host:host git-imap-send should connect to'
'imap.User:user git-imap-send should log in as'
'imap.Pass:password git-imap-send should use when logging in'
'imap.Port:port git-imap-send should connect on'
'instaweb.local:whether instaweb should bind to 127.0.0.1'
'instaweb.httpd:HTTP-daemon command-line to execute for instaweb'
'instaweb.port:port to bind HTTP daemon to for instaweb'
'instaweb.browser:web-browser command-line to execute for instaweb'
'instaweb.modulepath:module path for the Apache HTTP-daemon for instaweb'
'svn.noMetadata:disable git-svn-id\: lines at end of commits (fetch, clone, dcommit, set-tree, rebase)'
'svn.useSvmProps:whether to use remappings of URLs and UUIDs from mirrors (fetch, clone, dcommit, set-tree, rebase)'
'svn.useSvnsyncProps:similar to useSvmProps, but for the svnsync command (fetch, clone, dcommit, set-tree, rebase)'
'svn.followparent:whether to follow parent commit (fetch, clone, dcommit, set-tree, rebase)'
'svn.authorsfile:default authors file to use (fetch, clone, dcommit, set-tree, rebase)'
'svn.username:username to use for SVN transport (fetch, clone, dcommit, set-tree, rebase, init)'
'svn.configdir:configuration directory to use (fetch, clone, dcommit, set-tree, rebase, init)'
'svn.noauthcache:undocumented (fetch, clone, dcommit, set-tree, rebase, init)'
'svn.quiet:make git-svn less verbose (fetch, clone, dcommit, set-tree, rebase)'
'svn.repack:repack files (for given number of revisions) (fetch, clone, dcommit, set-tree, rebase)'
'svn.repackflags:flags to pass to git-repack (fetch, clone, dcommit, set-tree, rebase)'
'svn.logwindowsize:undocumented (fetch, clone, dcommit, set-tree, rebase)'
'svn.shared:share repository amongst several users (init, clone)'
'svn.template:directory to use as a template for the object database (init, clone)'
'svn.trunk:trunk sub-directory to use (init, clone)'
'svn.tags:tags sub-directory to use (init, clone)'
'svn.branches:branches sub-directory to use (init, clone)'
'svn.prefix:prefix to use for names on remotes (init, clone)'
'svn.rmdir:remove empty directories from SVN tree after commit (dcommit, set-tree, commit-diff)'
'svn.edit:edit commit message before committing (dcommit, set-tree, commit-diff)'
'svn.findcopiesharder:try harder to find copies (dcommit, set-tree, commit-diff)'
'svn.l:limit number of rename/copy targets to run (dcommit, set-tree, commit-diff)'
'svn.copysimilarity:undocumented (dcommit, set-tree, commit-diff)'
'svn.revision:only use given revision or revision range (fetch, clone, show-ignore, log, commit-diff)'
'svn.merge:use merging strategies, if necessary (dcommit, rebase)'
'svn.fetch-all:undocumented (fetch, dcommit, rebase)'
'svn.stdin:read list of commits to commit from stdin (set-tree)'
'svn.strategy:use given merge strategy (dcommit, rebase)'
'svn.verbose:output extra information (dcommit, log, rebase)'
'svn.dryrun:output git-commands that would show diffs that would be committed (dcommit)'
'svn.minimize:undocumented (migrate)'
'svn.limit:like --max-count, but not counting merged/excluded commits (log)'
'svn.incremental:give output suitable for concatenation (log)'
'svn.showcommit:output git commit SHA-1, as well (log)'
'svn.oneline:similar to --pretty=oneline (log)'
'svn.color:undocumented (log)'
'svn.pager:undocumented (log)'
'svn.nonrecursive:undocumented (log)'
'svn.local:undocumented (rebase)'
'svn.message:undocumented (commit-diff)'
'svn.file:(commit-diff) undocumented')
declare -a suffixed_names
suffixed_names=(
'alias:command aliases'
'branch:prefix for branch-specific variables'
'remote:prefix for remote-repository variables'
'remotes:prefix for remote-groups'
'gitcvs:prefix for git-cvsserver-specific variables'
'svn-remote:prefix for git-svn remote-repository variables')
_describe -t suffixed-names 'special name' suffixed_names -M 'm:{a-zA-Z}={A-Za-z}' -M 'r:|.=* r:|=*' -S '.' -r '.' && ret=0
fi
_describe -t names $label names -M 'm:{a-zA-Z}={A-Za-z}' -M 'r:|.=* r:|=*' && ret=0
}
(( $+functions[__git_config_gettable_name] )) ||
__git_config_gettable_name () {
local expl
declare -a names
# TODO: This is strictly not correct, as names can have equal signs in them
# as well. However, there’s no good way to tell from the output of
# git-config, so this’ll have to do until we write our own .git/config
# parser (which will never happen because it’s not worth the trouble).
names=(${${(f)"$(_call_program names git config --list)"}%%\=*})
__git_command_successful || return
_wanted names expl 'names' compadd $names
}
(( $+functions[__git_config_filtered_gettable_name] )) ||
__git_config_filtered_gettable_name () {
local expl
declare -a names
# TODO: See __git_config_gettable_name for discussion on how to actually get
# out the names, skipping the values.
names=(${${(M)${${(f)"$(_call_program $2 git config --list)"}%%\=*}:#$1.*}#$1.})
__git_command_successful || return
_wanted $2 expl $3 compadd $names
}
(( $+functions[__git_remote-groups] )) ||
__git_remote-groups () {
__git_config_filtered_gettable_name 'remotes' remote-groups 'remote-groups'
}
(( $+functions[__git_svn-remotes] )) ||
__git_svn-remotes () {
local expl
declare -a names
# TODO: See __git_config_gettable_name for discussion on how to actually get
# out the names, skipping the values.
names=(${${${(M)${${(f)"$(_call_program $2 git config --list)"}%%\=*}:#svn-remote.*}#svn-remote.}%%.*})
__git_command_successful || return
_wanted svn-remotes expl 'svn remote' compadd $names
}
# TODO: It’d be really cool if both the default and the current value could be
# shown for all values.
(( $+functions[__git_config_values] )) ||
__git_config_values () {
local compadd_opts
zparseopts -D -E -a compadd_opts M: J: V: 1 2 n F: X:
case $1 in
((#i)core.fileMode)
declare -a booleans
booleans=(
{true,yes}':track changes to executable bit of files'
{false,no}':ignore changes to executable bit of files')
_describe -t boolean 'boolean' booleans
;;
((#i)core.autocrlf)
declare -a modes
modes=(
{true,yes}':convert CRLF to LF when reading and LF to CRLF when writing'
{false,no}':leave CRLF at the end of lines in text files as is'
'input:convert CRLF to LF when reading')
_describe -t crlfmode 'crlf mode' modes
;;
((#i)core.symlinks)
declare -a booleans
booleans=(
{true,yes}':record symlink files as such'
{false,no}':check out symlinks as plain files that contain the link text')
_describe -t boolean 'boolean' booleans
;;
((#i)core.gitProxy)
_message 'proxy command'
;;
((#i)core.ignoreStat)
declare -a booleans
booleans=(
{true,yes}':working-copy files are unchanged until marked as changed'
{false,no}':use lstat() to determine if a file has changed')
_describe -t boolean 'boolean' booleans
;;
((#i)core.preferSymlinkRefs)
declare -a booleans
booleans=(
{true,yes}':use symbolic links for symbolic reference files'
{false,no}':use "symref" files for symbolic reference files')
_describe -t boolean 'boolean' booleans
;;
((#i)core.bare)
declare -a booleans
booleans=(
{true,yes}':the repository does not have a working directory'
{false,no}':the repository has a working directory')
_describe -t boolean 'boolean' booleans
;;
((#i)core.logAllRefUpdates)
declare -a booleans
booleans=(
{true,yes}':create ref files for branch heads'
{false,no}':don'\''t automatically create ref files')
_describe -t boolean 'boolean' booleans
;;
((#i)core.repositoryFormatVersion)
_message 'repository format version string (internal)'
;;
((#i)core.sharedRepository)
__git_repository_permissions
;;
((#i)core.warnAmbiguousRefs)
declare -a booleans
booleans=(
{true,yes}':warn if a ref name matches multiple refs'
{false,no}':ignore ambiguous ref names')
_describe -t boolean 'boolean' booleans
;;
((#i)core.compression)
declare -a levels
levels=(
'-1:default level of compression'
'0:do not deflate files'
'1:minimum compression'
'2:a little more compression'
'3:slightly more compression'
'4:a bit more compression'
'5:even more compression'
'6:slightly even more compression'
'7:getting there'
'8:close to maximum compression'
'9:maximum compression')
_describe -t compression-level 'compression level' levels
;;
((#i)core.legacyheaders)
declare -a booleans
booleans=(
{true,yes}':use compatiblity format for loose objects'
{false,no}':use new, more efficient, format for loose objects')
_describe -t boolean 'boolean' booleans
;;
((#i)core.(packedGit(WindowSize|Limit)|deltaBaseCacheLimit))
_guard '[[:digit:]]#([kmg]|)' 'number of bytes'
;;
((#i)alias.*)
_message 'git sub-command with arguments'
;;
((#i)apply.whitespace)
__git_apply_whitespace_strategies
;;
((#i)branch.*.remote)
__git_remotes
;;
((#i)branch.*.merge)
__git_references
;;
((#i)color.(branch|diff|pager|status))
declare -a booleans
booleans=(
{always,true}':always output in color'
{never,false}':never output in color'
'auto:output in color if to a terminal')
_describe -t boolean 'boolean' booleans
;;
((#i)color.*.*)
compset -P '* '
case ($words[CURRENT]) in
(?*' '?*' '*)
if [[ $words[CURRENT] == *(bold|dim|ul|blink|reverse)* ]]; then
__git_colors
else
__git_color_attributes
fi
;;
(*)
local suffix q_flag
if [[ $words[CURRENT] == [\"\']* ]]; then
suffix=' '
q_flag=-q
else
suffix='\ '
fi
if [[ $words[CURRENT] == *(bold|dim|ul|blink|reverse)* ]]; then
__git_colors -S $suffix $q_flag
else
_alternative \
'colors:color:__git_colors -S $suffix $q_flag' \
'attributes:attribute:__git_color_attributes -S $suffix $q_flag'
fi
;;
esac
;;
((#i)diff.renameLimit)
_guard "[[:digit:]]#" number
;;
((#i)diff.renames)
declare -a settings
settings=(
{true,yes}':enable basic rename detection'
{false,no}':don'\''t try to detect renames'
{copies,copy}':detect file renames and copies')
_describe -t values 'rename-detection setting' settings
;;
((#i)(fetch|receive|transfer).unpackLimit)
_guard "[[:digit:]]#" 'maximum number of objects to unpack'
;;
((#i)format.headers)
_message 'email header'
;;
((#i)format.suffix)
_message 'filename suffix'
;;
((#i)gc.packrefs)
declare -a values
values=(
{true,yes}':pack references when collecting garbage'
{false,no}':leave references alone when collecting garbage'
'notbare:pack references if the repository has a working directory')
_describe -t values 'value' values
;;
((#i)gc.(reflogexpire(unreachable|)|rerere(un|)resolved))
# TODO: It would be nice if the default value was shown under a separate
# description/tag.
__git_datetimes
;;
((#i)gitcvs.(*.|)enabled)
declare -a booleans
booleans=(
{true,yes}':enable the cvs server interface'
{false,no}':don'\''t enable the cvs server interface')
_describe -t booleans 'boolean' booleans
;;
((#i)gitcvs.(*.|)logfile)
_files
;;
((#i)gitcvs.(*.|)allbinary)
declare -a booleans
booleans=(
{true,yes}':tell the client to treat all files as binary'
{false,no}':treat files normally')
_describe -t booleans 'boolean' booleans
;;
((#i)gitcvs.dbname)
# TODO: In the future, when computers are self-aware and this won’t
# really matter anymore, one could inspect what gitcvs.dbdriver is set to
# and complete possible databases for that DBI driver.
_message -e 'database name'
;;
((#i)gitcvs.dbdriver)
declare -a drivers
# TODO: Would be nice to only include those that are installed, but I
# couldn’t figure out a good way of doing that when I wrote this code.
drivers=(
'SQLite:use the SQLite database driver (default)'
'Pg:use the Pg database driver')
_describe -t dbi-drivers 'DBI driver' drivers
;;
((#i)gitcvs.dbuser)
local expl
_description users expl 'database user'
_users $expl
;;
((#i)gitcvs.dbpass)
_message -e 'database password'
;;
((#i)http.sslVerify)
declare -a booleans
booleans=(
{true,yes}':verify SSL certificates when fetching or pushing over HTTP'
{false,no}':skip verification of SSL certificates')
_describe -t booleans 'boolean' booleans
;;
((#i)http.sslCert)
local expl
_wanted files expl 'SSL certificate file' _files
;;
((#i)http.sslKey)
local expl
_wanted files expl 'SSL private-key file' _files
;;
((#i)http.sslCAInfo)
local expl
_wanted files expl 'certificates file' _files
;;
((#i)http.sslCAPath)
local expl
_wanted files expl 'CA certificates file' _files
;;
((#i)http.maxRequests)
_guard "[[:digit:]]#" 'maximum number of requests'
;;
((#i)http.lowSpeedLimit)
# TODO: Need a better description
_guard "[[:digit:]]#([kmg]|)" number
;;
((#i)http.lowSpeedTime)
_guard "[[:digit:]]#" seconds
;;
((#i)http.noEPSV)
declare -a booleans
booleans=(
{true,yes}':don'\''t use EPSV mode over FTP (for stupid servers)'
{false,no}':use EPSV mode over FTP')
_describe -t booleans 'boolean' booleans
;;
((#i)i18n.(commitEncoding|logOutputEncoding))
__git_encodings
;;
((#i)log.showroot)
declare -a booleans
booleans=(
{true,yes}':show initial commit as a diff against an empty tree'
{false,no}':hide initial commit')
_describe -t booleans 'boolean' booleans
;;
((#i)merge.summary)
declare -a booleans
# TODO: Use (default) in more descriptions.
booleans=(
{true,yes}':include summaries in merge commit messages'
{false,no}':don'\''t add summaries to merge commit messages (default)')
_describe -t booleans 'boolean' booleans
;;
((#i)merge.tool)
declare -a tools
tools=(kdiff3 tkdiff meld xxdiff emerge vimdiff)
_describe -t merge-tools 'merge tool' tools
;;
((#i)merge.verbosity)
declare -a levels
levels=(
'0:only final error message if conflicts were detected'
'1:conflicts'
'2:conflicts and file changes'
'5:debugging information')
_describe -t verbosity-levels 'verbosity level' levels
;;
((#i)pack.window)
_guard '[[:digit:]]#' 'window size'
;;
((#i)pull.(octopus|twohead))
__git_merge_strategies
;;
((#i)remote.*.url)
_urls
;;
((#i)remote.*.fetch)
: TODO
;;
((#i)remote.*.push)
: TODO
;;
((#i)remote.*.skipDefaultUpdate)
declare -a booleans
booleans=(
{true,yes}':skip this remote by default'
{false,no}':update this remote by default')
_describe -t booleans 'boolean' booleans
;;
((#i)remote.*.(receivepack|uploadpack))
# TODO: Perhaps actually use SSH here?
local expl
_wanted files expl "remote git-${${1##*.}%pack}-pack program" _files -g *(*)
;;
((#i)remote.*.tagopt)
declare -a opts
opts=(
'--no-tags:don'\''t fetch tags automatically'
'"":fetch tags as usual')
_describe -t tag-options 'tag retrieval' opts
;;
((#i)remotes.*)
compset -P '* '
local suffix
if [[ $words[CURRENT] == [\"\']* ]]; then
suffix=' '
else
suffix='\ '
fi
# TODO: Should really only complete unique remotes, that is, not the same
# remote more than once in the list.
__git_remotes -S $suffix -q
;;
((#i)repack.usedeltabaseoffset)
declare -a booleans
booleas=(
{true,yes}':allow creation of delta-base-offset packs'
{false,no}':don'\''t create delta-base-offset packs')
_describe -t booleans 'boolean' booleans
;;
((#i)show.difftree)
# TODO: This should complete the options available to these two commands.
_message 'default options to git-diff-tree and git-show'
;;
((#i)showbranch.default)
__git_branch_names
;;
((#i)tar.umask)
_alternative \
'number: :_guard "[0-7]#" "numeric mode"' \
'values:special value:((user:"use user'\''s current umask"))'
;;
((#i)user.email)
_email_addresses
;;
((#i)user.name)
_users
;;
((#i)user.signingkey)
__git_gpg_secret_keys
;;
((#i)whatchanged.difftree)
# TODO: This should complete the options available to git-diff-tree.
_message 'default options to git-diff-tree when invoking git-whatchanged'
;;
((#i)receive.denyNonFastForwards)
declare -a booleans
booleans=(
{true,yes}':git-receive-pack will deny a ref update that isn'\''t a fast forward'
{false,no}':allow a ref update that isn'\''t a fast forward')
_describe -t booleans 'boolean' booleans
;;
((#i)imap.folder)
_mailboxes
;;
((#i)imap.tunnel)
_message -e commands 'imap tunneling command'
;;
((#i)imap.host)
_hosts
;;
((#i)imap.user)
# TODO: If imap.host is set, complete users on that system?
_users
;;
((#i)imap.pass)
_message -e passwords 'imap password'
;;
((#i)imap.port)
_ports
;;
((#i)instaweb.local)
declare -a booleans
booleans=(
{true,yes}':bind the HTTP daemon to 127.0.0.1'
{false,no}':don'\''t bind the HTTP daemon to a specific address')
_describe -t booleans 'boolean' booleans
;;
((#i)instaweb.httpd)
_message -e command-lines 'HTTP-daemon command-line'
;;
((#i)instaweb.port)
_ports
;;
((#i)instaweb.browser)
_message -e command-lines 'web-browser command-line'
;;
((#i)instaweb.modulepath)
local expl
_description directories expl 'module path'
_directories $expl
;;
((#i)(svn.|svn-remote.*.)noMetaData)
declare -a booleans
booleans=(
{true,yes}':disable git-svn-id: lines at end of commits'
{false,no}':add git-svn-id: lines at end of commits')
_describe -t booleans 'boolean' booleans
;;
((#i)(svn.|svn-remote.*.)(useSvmProps|useSvnsyncProps))
declare -a booleans
booleans=(
{true,yes}':remap URLs and UUIDs for mirrors'
{false,no}':don'\''t remap URLs and UUIDs for mirrors')
_describe -t booleans 'boolean' booleans
;;
((#i)svn.followparent)
__git_boolean_settings true 'follow parent commit'
;;
((#i)svn.authorsfile)
local expl
_description files expl 'authors-conversion file'
_files $expl
;;
((#i)svn.username)
_users
;;
((#i)svn.configdir)
_directories
;;
((#i)svn.noauthcache)
# TODO: Update description once this gets documented.
__git_boolean_settings false 'use auth cache'
;;
((#i)svn.quiet)
__git_boolean_settings false 'make git-svn less verbose' 'let git-svn produce verbose output'
;;
((#i)svn.repack)
_guard '[[:digit:]]#' 'revision limit'
;;
((#i)svn.repackflags)
# TODO: Should complete git-repack arguments
_message -e 'git-repack flags'
;;
((#i)svn.logwindowsize)
# TODO: Update description once this gets documented.
_guard '[[:digit:]]#' 'log-window size'
;;
((#i)svn.shared)
__git_repository_permissions
;;
((#i)svn.template)
# NOTE: This is of course ridiculous, as this can never be useful. Only
# here for completeness.
_directories
;;
((#i)svn.(trunk|tags|branches))
_alternative \
'sub-directories:sub-directory:_directories' \
'urls: :_urls' && ret=0
;;
((#i)svn.prefix)
_message -e 'prefix'
;;
((#i)svn.rmdir)
__git_boolean_settings false 'remove empty directories from SVN tree after commit' 'leave empty directories from SVN tree after commit'
;;
((#i)svn.edit)
__git_boolean_settings false 'edit commit message before committing' 'use commit message from SVN'
;;
((#i)svn.findcopiesharder)
__git_boolean_settings false 'try harder to find copies' 'use simple copy-finding algorithm'
;;
((#i)svn.l)
_guard "[[:digit:]]#" number
;;
((#i)svn.copysimilarity)
__git_boolean_settings false 'undocumented'
;;
((#i)svn.revision)
__git_svn_revisions
;;
((#i)svn.merge)
__git_boolean_settings false 'use merging strategies' 'don'\''t try to merge'
;;
((#i)svn.fetch-all)
__git_boolean_settings false 'undocumented'
;;
((#i)svn.stdin)
__git_boolean_settings false 'read list of commits to commit from stdin' 'don'\''t necessarily read list of commits to commit from stdin'
;;
((#i)svn.strategy)
__git_merge_strategies
;;
((#i)svn.verbose)
__git_boolean_settings false 'output extra information'
;;
((#i)svn.dryrun)
__git_boolean_settings false 'output git-commands that would show diffs that would be committed' 'actually run the git commands'
;;
((#i)svn.minimize)
__git_boolean_settings false 'undocumented'
;;
((#i)svn.limit)
_guard "[[:digit:]]#" limit
;;
((#i)svn.incremental)
__git_boolean_settings false 'give output suitable for concatenation'
;;
((#i)svn.showcommit)
__git_boolean_settings false 'output git commit SHA-1, as well' 'don'\''t output git commit SHA-1'
;;
((#i)svn.online)
__git_boolean_settings false 'produce output similar to --pretty=oneline'
;;
((#i)svn.color)
__git_boolean_settings false 'undocumented'
;;
((#i)svn.pager)
_message -e 'undocumented'
;;
((#i)svn.nonrecursive)
__git_boolean_settings false 'undocumented'
;;
((#i)svn.local)
__git_boolean_settings false 'undocumented'
;;
((#i)svn.message)
_message -e 'undocumented'
;;
((#i)svn.file)
_message -e 'undocumented'
;;
((#i)svn-remote.*.rewriteRoot)
_message -e 'new root'
;;
(*)
_message 'value'
;;
esac
}
# __git_boolean_settings [-t TAG] [-l LABEL] DEFAULT 'follow parent commit' ['follow HEAD commit']
#
# -t can be used to specify a tag to use (default: booleans).
# -l can be used to specify a label to use (default: 'boolean').
#
# The first argument is the default value, so that the description of the
# default value can be suffixed with " (default)". The second argument
# is the description for the true value. If a third argument is given,
# it is used as the description for the false value. If it is not given,
# the description will be the true value's description with the prefix
# "don't ".
(( $+functions[__git_boolean_settings] )) ||
__git_boolean_settings () {
local tag label garbage
zparseopts -D -E -a garba S: M: J: V: 1 2 n F: X: -t=tag -l=label
declare -A descriptions
descriptions=(true $2 false 'don'\''t '"$2")
if (( $# > 2 )); then
descriptions[false]=$3
fi
descriptions[$1]+=" (default)"
declare -a booleans
booleans=(
{true,yes}':'$descriptions[true]
{false,no}':'$descriptions[false])
_describe -t ${tag:-booleans} ${label:-boolean} booleans
}
# TODO: Use this function in other places.
(( $+functions[__git_colors] )) ||
__git_colors () {
declare -a colors
colors=(black red green yellow blue magenta cyan white)
_describe -t colors 'color' colors $*
}
# TODO: Use this function in other places.
(( $+functions[__git_color_attributes] )) ||
__git_color_attributes () {
declare -a attributes
attributes=(bold dim ul blink reverse)
_describe -t attributes 'attribute' attributes $*
}
(( $+functions[__git_config_section_names] )) ||
__git_config_section_names () {
# TODO: Come up with a good way of extracting this information.
_guard "?#" "section name"
}
(( $+functions[__git_archive_formats] )) ||
__git_archive_formats () {
local expl
declare -a formats
formats=(${${(f)"$(_call_program archive-formats git archive --list)"}})
__git_command_successful || return
_wanted archive-formats expl 'archive format' compadd $formats
}
(( $+functions[__git_gpg_secret_keys] )) ||
__git_gpg_secret_keys () {
local expl
_wanted secret-keys expl 'secret key' compadd \
${${(Mo)$(_call_program secret-keys gpg --list-secret-keys 2>/dev/null):%<*>}//(<|>)/}
}
(( $+functions[__git_merge_strategies] )) ||
__git_merge_strategies () {
declare -a merge_strategies_cache
merge_strategies_cache=(${${=${${(M)${(f)"$(<$(git --exec-path)/git-merge)"}:#all_strategies*}##all_strategies=\'}%%\'}:#recur})
local expl
_wanted merge-strategies expl 'merge strategy' compadd - $merge_strategies_cache
}
# TODO: Use this in more places.
(( $+functions[__git_datetimes] )) ||
__git_datetimes () {
_guard "*" 'time specification'
}
# TODO: Use this in more places.
# TODO: Use better algorithm, as shown in iconv completer (separate it to a new
# Type).
(( $+functions[__git_encodings] )) ||
__git_encodings () {
local expl
_wanted encodings expl 'encoding' compadd "$@" \
-M 'm:{a-zA-Z}={A-Za-z} r:|-=* r:|=*' \
${${${(f)"$(_call_program encodings iconv --list)"}## #}%//}
}
(( $+functions[__git_repository_permissions] )) ||
__git_repository_permissions () {
declare -a permissions
permissions=(
{group,true,yes}':files and objects are group-writable'
{all,world,everybody}':files and objects are readable by all users and group-shareable'
{umask,false}':use permissions reported by umask()')
_describe -t permissions 'permission' permissions
}
(( $+functions[__git_apply_whitespace_strategies] )) ||
__git_apply_whitespace_strategies () {
declare -a strategies
strategies=(
'nowarn:turn off the trailing-whitespace warning'
'warn:output trailing-whitespace warning, but apply patch'
'error:output trailing-whitespace warning and refuse to apply patch'
'error-all:same as "error", but output warnings for all files'
'strip:output trailing-whitespace warning and strip trailing whitespace')
_describe -t strategies 'trailing-whitespace resolution strategy' strategies
}
(( $+functions[__git_svn_revisions] )) ||
__git_svn_revisions () {
if [[ -prefix *: ]]; then
compset -P '*:'
_alternative \
'revision-numbers: :__git_svn_revision_numbers' \
'symbolic-revisions:symbolic revision:((HEAD\:"the topmost revision of the SVN repository"))'
else
_alternative \
'revision-numbers: :__git_svn_revision_numbers' \
'symbolic-revisions:symbolic revision:__git_svn_base_revisions'
fi
}
(( $+functions[__git_svn_revision_numbers] )) ||
__git_svn_revision_numbers () {
_guard "[[:digit:]]#" "revision number"
}
(( $+functions[__git_svn_base_revisions] )) ||
__git_svn_base_revisions () {
declare -a revisions
revisions=(
'BASE:the bottommost revision of the SVN repository')
# TODO: How do we deal with $*?
_describe -t symbolic-revisions 'symbolic revision' revisions -S ':' -r ': '
}
# TODO: numparent is undocumented.
(( $+functions[__git_ref_sort_keys] )) ||
__git_ref_sort_keys () {
compset -P '-'
local -a keys
keys=(
'refname:the name of the ref'
'objecttype:the type of the object'
'objectsize:the size of the object'
'objectname:the object name (SHA-1)'
'tree:the tree header-field'
'parent:the parent header-field'
'numparent:undocumented'
'object:the object header-field'
'type:the type header-field'
'tag:the tag header-field'
'author:the author header-field'
'authorname:the name component of the author header-field'
'authoremail:the email component of the author header-field'
'authordate:the date component of the author header-field'
'committername:the name component of the committer header-field'
'committeremail:the email component of the committer header-field'
'committerdate:the date component of the committer header-field'
'taggername:the name component of the tagger header-field'
'taggeremail:the email component of the tagger header-field'
'taggerdate:the date component of the tagger header-field'
'creatorname:the name component of the creator header-field'
'creatordate:the date component of the creator header-field'
'subject:the subject of the message'
'body:the body of the message'
'body:the contents of the message (subject and body)')
_describe -t sort-keys 'sort key' keys
}
(( $+functions[__git_daemon_service] )) ||
__git_daemon_service () {
local -a services
services=(
'upload-pack:serve git-fetch-pack and git-peek-remote clients'
'upload-archive:serve git-archive --remote clients')
_describe -t services 'service' services
}
(( $+functions[__git_attributes] )) ||
__git_attributes () {
local -a attributes
attributes=(
'crlf:line-ending convention'
'ident:ident substitution'
'filter:filters'
'diff:textual diff'
'merge:merging strategy')
_describe -t attributes 'attribute' attributes
}
# ---
# TODO: How do we do -/n/ here?
# --reflog undocumented
# -m undocumented
# -v undocumented
# --root undocumented
# --no-commit-id undocumented
# --always undocumented
# --abbrev undocumented
# --abbrev-commit undocumented
# --full-diff undocumented
# --full-history undocumented
# --all-match undocumented
# optional argument to --unpacked undocumented
(( $+functions[__git_setup_revision_arguments] )) ||
__git_setup_revision_arguments () {
revision_arguments=(
'(-n --max-count -)'{-n+,--max-count=-}'[maximum number of commits to output]: :_guard "[[\:digit\:]]#" number'
'--skip=-[skip given number of commits before output]: :_guard "[[\:digit\:]]#" number'
'( --since --after)--max-age=-[maximum age of commits to output]: :_guard "[[\:digit\:]]#" timestamp'
'(--max-age --since --after)'{--since=-,--after=-}'[show commits more recent than given date]:date'
'( --until --before)--min-age[minimum age of commits to output]: :_guard "[[\:digit\:]]#" timestamp'
'(--min-age --until --before)'{--until=-,--before=-}'[show commits older than given date]: :_guard "[[\:digit\:]]#" timestamp'
'--all[show all commits from refs]'
'--cherry-pick[omit any same-change commits]'
'--reflog[show all commits from reflogs]'
'(-g --walk-reflogs)'{-g,--walk-reflogs}'[walk reflog entries from most recent to oldest]'
'*--not[reverses meaning of ^ prefix for revisions that follow]'
'--default[use argument as default revision]:default revision:__git_revisions'
'--merge[after a failed merge, show refs that touch files having a conflict]'
'( --date-order)--topo-order[show commits in topological order]'
'(--topo-order )--date-order[show commits in date order]'
'--parents[show parent commits]'
'( --sparse)--dense[this is the inverse of --sparse, and is also the default]'
'(--dense )--sparse[when paths are given, output only commits that changes any of them]'
'--remove-empty[stop when a given path disappears from the tree]'
'--no-merges[do not print commits with more than one parent]'
'--boundary[output uninteresting commits at the boundary]'
'--left-right[mark which side of a symmetric diff a commit is reachable from]'
'( --objects-edge)--objects[show object ids of objects referenced by the listed commits]'
'(--objects )--objects-edge[show object ids of objects referenced by the listed and excluded commits]'
'( -t)-r[show recursive diffs]'
'(-r )-t[show the tree objects in the diff output]'
'-m[do not ignore merges]'
'( --cc --full-diff)-c[show merge diffs from parents simultaneously]'
'(-c --full-diff)--cc[show merge diffs from parents simultaneously without one-parent diffs]'
'(-c --cc )--full-diff[undocumented]'
'( --pretty --header)-v[show verbose header]'
'(-v --header)'$pretty_arg
'--root[show root diff]'
'--no-commit-id[do not show commit ids]'
'--always[always show header]'
$abbrev_arg
'--abbrev-commit[undocumented]'
'--full-history[undocumented]'
'--relative-date[show dates relative to the current time]'
'--date=-[format of date output]:date format:((relative\:"show dates relative to the current time"
local\:"show timestamps in user'\''s local timezone"
default\:"show timestamp in the original timezone"))'
'--author=-[limit commits to those by the given author]:author'
'--committer=-[limit commits to those by the given committer]:committer'
'--grep=-[limit commits to those with log messages matching the given pattern]:pattern'
'--all-match[undocumented]'
'--encoding=-[output log messages in given encoding]::encoding:__git_encodings'
$diff_args)
if (( words[(I)--objects(|-edge)] )); then
revision_arguments+=('--unpacked=-[print object IDs that are not in packs]::object')
fi
}
# ---
(( $+functions[__git_is_indexed] )) ||
__git_is_indexed () {
[[ -n $(git ls-files $REPLY) ]]
}
local curcontext=$curcontext ret=1
# fun with $words[] and $CURRENT to enable completion for args
# to git aliases (eg. git co <TAB>)
local -A git_aliases
# TODO: filling git_aliases like this is ugly. I didn't get it working elegantly.
local oifs=$IFS
IFS=$'\0'
git_aliases=(${=${(0)${(@)${${${(f)"$(git config --get-regexp alias.\*)"}/(#s)alias./}/ /$'\0'}}}})
IFS=$oifs ; unset oifs
if (( CURRENT >= 3 )) && [[ -n ${git_aliases[$words[2]]} ]] ; then
local -a tmpwords
tmpwords=(${words[1]} ${(z)git_aliases[$words[2]]})
if [[ -z "${words[3,-1]}" ]] ; then
tmpwords[$(( ${#tmpwords} + 1 ))]=""
else
tmpwords+=("${words[3,-1]}")
fi
words=("${tmpwords[@]}")
(( CURRENT += ${#${(z)git_aliases[$words[2]]}} - 1 ))
unset tmpwords
fi
if [[ $service == git ]]; then
local state line
declare -A opt_args
_arguments -C \
'(- :)--version[display version information]' \
'(- :)--help[display help message]' \
'--exec-path=-[path containing core git-programs]::directory:_directories' \
'(-p --paginate)'{-p,--paginate}'[pipe output into $PAGER]' \
'--git-dir=-[path to repository]:directory:_directories' \
'--bare[use $PWD as repository]' \
':command:->command' \
'*::options:->options' && ret=0
case $state in
(command)
__git_aliases_and_commands
;;
(options)
curcontext="${curcontext%:*:*}:git-$words[1]:"
_call_function ret _git-$words[1]
;;
esac
else
_call_function ret _$service
fi
}
_git
|