Fossil SCM
Added new 'touch' command to set the mtime of files to their SCM-side values.
Commit
4d9ec3e33c44ab59ff891051f1a3be28d9436d57efd9570f9140091dcc339517
Parent
34fcaf829a908db…
1 file changed
+104
+104
| --- src/file.c | ||
| +++ src/file.c | ||
| @@ -1798,5 +1798,109 @@ | ||
| 1798 | 1798 | } |
| 1799 | 1799 | zDir = g.argv[2]; |
| 1800 | 1800 | zGlob = g.argc==4 ? g.argv[3] : 0; |
| 1801 | 1801 | fossil_print("%d\n", file_directory_size(zDir, zGlob, omitDotFiles)); |
| 1802 | 1802 | } |
| 1803 | + | |
| 1804 | + | |
| 1805 | +/* | |
| 1806 | +** COMMAND: touch* | |
| 1807 | +** | |
| 1808 | +** Usage: %fossil touch ?OPTIONS? | |
| 1809 | +** | |
| 1810 | +** For each file in the current checkout matching one of the | |
| 1811 | +** comma-separated list of glob patterns, or all files if no glob is | |
| 1812 | +** provided, set the file's mtime to the time of the last checkin | |
| 1813 | +** which modified that file. | |
| 1814 | +** | |
| 1815 | +** This command gets its name from the conventional Unix "touch" | |
| 1816 | +** command. | |
| 1817 | +** | |
| 1818 | +** Options: | |
| 1819 | +** -g GLOBLIST Comma-separated list of glob patterns. Default | |
| 1820 | +** is to touch all SCM-control files. | |
| 1821 | +** -G GLOBFILE Similar to -g but reads its globs from a | |
| 1822 | +** fossil-conventional glob list file. | |
| 1823 | +** -v|-verbose If true, outputs information about its globs | |
| 1824 | +** and each file it touches. | |
| 1825 | +** -n|--dry-run If given, outputs which files would | |
| 1826 | +** require touching, but does not touch them. | |
| 1827 | +** | |
| 1828 | +** Only one of -g or -G may be used. | |
| 1829 | +** | |
| 1830 | +*/ | |
| 1831 | +void touch_cmd(){ | |
| 1832 | + const char * zGlobList; /* -g List of glob patterns */ | |
| 1833 | + const char * zGlobFile; /* -G File of glob patterns */ | |
| 1834 | + Glob * pGlob = 0; /* List of glob patterns */ | |
| 1835 | + int verboseFlag; | |
| 1836 | + int dryRunFlag; | |
| 1837 | + int vid; /* Checkout version */ | |
| 1838 | + int changeCount = 0; /* Number of files touched */ | |
| 1839 | + Stmt q; | |
| 1840 | + | |
| 1841 | + verboseFlag = find_option("verbose","v",0)!=0; | |
| 1842 | + dryRunFlag = find_option("dry-run","n",0)!=0; | |
| 1843 | + zGlobList = find_option("glob", "g",1); | |
| 1844 | + zGlobFile = find_option("globfile", "G",1); | |
| 1845 | + | |
| 1846 | + verify_all_options(); | |
| 1847 | + if(zGlobList && zGlobFile){ | |
| 1848 | + fossil_fatal("Cannot use both -g and -G options."); | |
| 1849 | + } | |
| 1850 | + | |
| 1851 | + db_must_be_within_tree(); | |
| 1852 | + vid = db_lget_int("checkout", 0); | |
| 1853 | + if(vid==0){ | |
| 1854 | + fossil_fatal("Cannot determine checkout version."); | |
| 1855 | + } | |
| 1856 | + if(zGlobList){ | |
| 1857 | + pGlob = *zGlobList ? glob_create(zGlobList) : 0; | |
| 1858 | + }else if(zGlobFile){ | |
| 1859 | + Blob globs; | |
| 1860 | + blob_read_from_file(&globs, zGlobFile, ExtFILE); | |
| 1861 | + pGlob = glob_create( globs.aData ); | |
| 1862 | + blob_reset(&globs); | |
| 1863 | + } | |
| 1864 | + db_begin_transaction(); | |
| 1865 | + db_prepare(&q, "SELECT vfile.mrid, pathname " | |
| 1866 | + "FROM vfile LEFT JOIN blob ON vfile.mrid=blob.rid " | |
| 1867 | + "WHERE vid=%d", vid); | |
| 1868 | + if( pGlob && verboseFlag!=0 ){ | |
| 1869 | + int i; | |
| 1870 | + for(i=0; i<pGlob->nPattern; ++i){ | |
| 1871 | + fossil_print("glob: %s\n", pGlob->azPattern[i]); | |
| 1872 | + } | |
| 1873 | + } | |
| 1874 | + while(SQLITE_ROW==db_step(&q)){ | |
| 1875 | + const char * zName = db_column_text(&q, 1); | |
| 1876 | + int const fid = db_column_int(&q, 0); | |
| 1877 | + i64 scmMtime; | |
| 1878 | + i64 currentMtime; | |
| 1879 | + if(pGlob){ | |
| 1880 | + if(glob_match(pGlob, zName)==0) continue; | |
| 1881 | + } | |
| 1882 | + currentMtime = file_mtime(zName, 0); | |
| 1883 | + if( mtime_of_manifest_file(vid, fid, &scmMtime)==0 ){ | |
| 1884 | + if( currentMtime!=scmMtime ){ | |
| 1885 | + ++changeCount; | |
| 1886 | + if( dryRunFlag!=0 ){ | |
| 1887 | + fossil_print( "dry-run: %s\n", zName ); | |
| 1888 | + }else{ | |
| 1889 | + file_set_mtime(zName, scmMtime); | |
| 1890 | + if( verboseFlag!=0 ){ | |
| 1891 | + fossil_print( "touched %s\n", zName ); | |
| 1892 | + } | |
| 1893 | + } | |
| 1894 | + } | |
| 1895 | + } | |
| 1896 | + } | |
| 1897 | + db_finalize(&q); | |
| 1898 | + db_end_transaction(0); | |
| 1899 | + glob_free(pGlob); | |
| 1900 | + if( dryRunFlag!=0 ){ | |
| 1901 | + fossil_print("dry-run: would have touched %d file(s)\n", | |
| 1902 | + changeCount); | |
| 1903 | + }else if( verboseFlag!=0 ){ | |
| 1904 | + fossil_print("Touched %d file(s)\n", changeCount); | |
| 1905 | + } | |
| 1906 | +} | |
| 1803 | 1907 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -1798,5 +1798,109 @@ | |
| 1798 | } |
| 1799 | zDir = g.argv[2]; |
| 1800 | zGlob = g.argc==4 ? g.argv[3] : 0; |
| 1801 | fossil_print("%d\n", file_directory_size(zDir, zGlob, omitDotFiles)); |
| 1802 | } |
| 1803 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -1798,5 +1798,109 @@ | |
| 1798 | } |
| 1799 | zDir = g.argv[2]; |
| 1800 | zGlob = g.argc==4 ? g.argv[3] : 0; |
| 1801 | fossil_print("%d\n", file_directory_size(zDir, zGlob, omitDotFiles)); |
| 1802 | } |
| 1803 | |
| 1804 | |
| 1805 | /* |
| 1806 | ** COMMAND: touch* |
| 1807 | ** |
| 1808 | ** Usage: %fossil touch ?OPTIONS? |
| 1809 | ** |
| 1810 | ** For each file in the current checkout matching one of the |
| 1811 | ** comma-separated list of glob patterns, or all files if no glob is |
| 1812 | ** provided, set the file's mtime to the time of the last checkin |
| 1813 | ** which modified that file. |
| 1814 | ** |
| 1815 | ** This command gets its name from the conventional Unix "touch" |
| 1816 | ** command. |
| 1817 | ** |
| 1818 | ** Options: |
| 1819 | ** -g GLOBLIST Comma-separated list of glob patterns. Default |
| 1820 | ** is to touch all SCM-control files. |
| 1821 | ** -G GLOBFILE Similar to -g but reads its globs from a |
| 1822 | ** fossil-conventional glob list file. |
| 1823 | ** -v|-verbose If true, outputs information about its globs |
| 1824 | ** and each file it touches. |
| 1825 | ** -n|--dry-run If given, outputs which files would |
| 1826 | ** require touching, but does not touch them. |
| 1827 | ** |
| 1828 | ** Only one of -g or -G may be used. |
| 1829 | ** |
| 1830 | */ |
| 1831 | void touch_cmd(){ |
| 1832 | const char * zGlobList; /* -g List of glob patterns */ |
| 1833 | const char * zGlobFile; /* -G File of glob patterns */ |
| 1834 | Glob * pGlob = 0; /* List of glob patterns */ |
| 1835 | int verboseFlag; |
| 1836 | int dryRunFlag; |
| 1837 | int vid; /* Checkout version */ |
| 1838 | int changeCount = 0; /* Number of files touched */ |
| 1839 | Stmt q; |
| 1840 | |
| 1841 | verboseFlag = find_option("verbose","v",0)!=0; |
| 1842 | dryRunFlag = find_option("dry-run","n",0)!=0; |
| 1843 | zGlobList = find_option("glob", "g",1); |
| 1844 | zGlobFile = find_option("globfile", "G",1); |
| 1845 | |
| 1846 | verify_all_options(); |
| 1847 | if(zGlobList && zGlobFile){ |
| 1848 | fossil_fatal("Cannot use both -g and -G options."); |
| 1849 | } |
| 1850 | |
| 1851 | db_must_be_within_tree(); |
| 1852 | vid = db_lget_int("checkout", 0); |
| 1853 | if(vid==0){ |
| 1854 | fossil_fatal("Cannot determine checkout version."); |
| 1855 | } |
| 1856 | if(zGlobList){ |
| 1857 | pGlob = *zGlobList ? glob_create(zGlobList) : 0; |
| 1858 | }else if(zGlobFile){ |
| 1859 | Blob globs; |
| 1860 | blob_read_from_file(&globs, zGlobFile, ExtFILE); |
| 1861 | pGlob = glob_create( globs.aData ); |
| 1862 | blob_reset(&globs); |
| 1863 | } |
| 1864 | db_begin_transaction(); |
| 1865 | db_prepare(&q, "SELECT vfile.mrid, pathname " |
| 1866 | "FROM vfile LEFT JOIN blob ON vfile.mrid=blob.rid " |
| 1867 | "WHERE vid=%d", vid); |
| 1868 | if( pGlob && verboseFlag!=0 ){ |
| 1869 | int i; |
| 1870 | for(i=0; i<pGlob->nPattern; ++i){ |
| 1871 | fossil_print("glob: %s\n", pGlob->azPattern[i]); |
| 1872 | } |
| 1873 | } |
| 1874 | while(SQLITE_ROW==db_step(&q)){ |
| 1875 | const char * zName = db_column_text(&q, 1); |
| 1876 | int const fid = db_column_int(&q, 0); |
| 1877 | i64 scmMtime; |
| 1878 | i64 currentMtime; |
| 1879 | if(pGlob){ |
| 1880 | if(glob_match(pGlob, zName)==0) continue; |
| 1881 | } |
| 1882 | currentMtime = file_mtime(zName, 0); |
| 1883 | if( mtime_of_manifest_file(vid, fid, &scmMtime)==0 ){ |
| 1884 | if( currentMtime!=scmMtime ){ |
| 1885 | ++changeCount; |
| 1886 | if( dryRunFlag!=0 ){ |
| 1887 | fossil_print( "dry-run: %s\n", zName ); |
| 1888 | }else{ |
| 1889 | file_set_mtime(zName, scmMtime); |
| 1890 | if( verboseFlag!=0 ){ |
| 1891 | fossil_print( "touched %s\n", zName ); |
| 1892 | } |
| 1893 | } |
| 1894 | } |
| 1895 | } |
| 1896 | } |
| 1897 | db_finalize(&q); |
| 1898 | db_end_transaction(0); |
| 1899 | glob_free(pGlob); |
| 1900 | if( dryRunFlag!=0 ){ |
| 1901 | fossil_print("dry-run: would have touched %d file(s)\n", |
| 1902 | changeCount); |
| 1903 | }else if( verboseFlag!=0 ){ |
| 1904 | fossil_print("Touched %d file(s)\n", changeCount); |
| 1905 | } |
| 1906 | } |
| 1907 |