Fossil SCM
Add options -t/-T to 'blame'/'praise' to display for each tracked file the last modifying check-in, its author, and (with -T) a comment snippet.
Commit
644134097e74c2c711bd4f7645c909bac14a4d073b360aea0600358e2b787724
Parent
d83de4a2d36a222…
2 files changed
+30
-7
+21
-1
+30
-7
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -714,16 +714,17 @@ | ||
| 714 | 714 | } |
| 715 | 715 | |
| 716 | 716 | /* |
| 717 | 717 | ** Take care of -r version of ls command |
| 718 | 718 | */ |
| 719 | -static void ls_cmd_rev( | |
| 719 | +void ls_cmd_rev( | |
| 720 | 720 | const char *zRev, /* Revision string given */ |
| 721 | 721 | int verboseFlag, /* Verbose flag given */ |
| 722 | 722 | int showAge, /* Age flag given */ |
| 723 | 723 | int showFileHash, /* Show file hash flag given */ |
| 724 | 724 | int showCkinHash, /* Show check-in hash flag given */ |
| 725 | + int showCkinInfo, /* Show check-in infos */ | |
| 725 | 726 | int timeOrder, /* Order by time flag given */ |
| 726 | 727 | int treeFmt /* Show output in the tree format */ |
| 727 | 728 | ){ |
| 728 | 729 | Stmt q; |
| 729 | 730 | char *zOrderBy = "pathname COLLATE nocase"; |
| @@ -763,22 +764,36 @@ | ||
| 763 | 764 | if( timeOrder ){ |
| 764 | 765 | zOrderBy = "mtime DESC"; |
| 765 | 766 | } |
| 766 | 767 | |
| 767 | 768 | compute_fileage(rid,0); |
| 768 | - db_prepare(&q, | |
| 769 | + if( showCkinInfo ){ | |
| 770 | + db_prepare(&q, | |
| 771 | + "SELECT datetime(fileage.mtime, toLocal()), fileage.pathname,\n" | |
| 772 | + " bfh.size, fileage.uuid, bch.uuid,\n" | |
| 773 | + " coalesce(e.ecomment, e.comment), coalesce(e.euser, e.user)\n" | |
| 774 | + " FROM fileage, blob bfh, blob bch, event e\n" | |
| 775 | + " WHERE bfh.rid=fileage.fid AND bch.rid=fileage.mid\n" | |
| 776 | + " AND e.objid = fileage.mid %s\n" | |
| 777 | + " ORDER BY %s;", | |
| 778 | + blob_sql_text(&where), | |
| 779 | + zOrderBy /*safe-for-%s*/ | |
| 780 | + ); | |
| 781 | + }else{ | |
| 782 | + db_prepare(&q, | |
| 769 | 783 | "SELECT datetime(fileage.mtime, toLocal()), fileage.pathname,\n" |
| 770 | 784 | " bfh.size, fileage.uuid %s\n" |
| 771 | 785 | " FROM fileage, blob bfh %s\n" |
| 772 | 786 | " WHERE bfh.rid=fileage.fid %s %s\n" |
| 773 | - " ORDER BY %s;", | |
| 787 | + " ORDER BY %s;", | |
| 774 | 788 | showCkinHash ? ", bch.uuid" : "", |
| 775 | 789 | showCkinHash ? ", blob bch" : "", |
| 776 | 790 | showCkinHash ? "\n AND bch.rid=fileage.mid" : "", |
| 777 | 791 | blob_sql_text(&where), |
| 778 | 792 | zOrderBy /*safe-for-%s*/ |
| 779 | - ); | |
| 793 | + ); | |
| 794 | + } | |
| 780 | 795 | blob_reset(&where); |
| 781 | 796 | if( treeFmt ) blob_init(&out, 0, 0); |
| 782 | 797 | |
| 783 | 798 | while( db_step(&q)==SQLITE_ROW ){ |
| 784 | 799 | const char *zTime = db_column_text(&q,0); |
| @@ -785,11 +800,18 @@ | ||
| 785 | 800 | const char *zFile = db_column_text(&q,1); |
| 786 | 801 | int size = db_column_int(&q,2); |
| 787 | 802 | if( treeFmt ){ |
| 788 | 803 | blob_appendf(&out, "%s\n", zFile); |
| 789 | 804 | }else if( verboseFlag ){ |
| 790 | - if( showFileHash ){ | |
| 805 | + if( showCkinInfo ){ | |
| 806 | + const char *zUuidC = db_column_text(&q,4); | |
| 807 | + const char *zComm = db_column_text(&q,5); | |
| 808 | + const char *zUser = db_column_text(&q,6); | |
| 809 | + fossil_print("%s [%S] %12s ", zTime, zUuidC, zUser); | |
| 810 | + if( showCkinInfo==2 ) fossil_print("%-20.20s ", zComm); | |
| 811 | + fossil_print("%s\n", zFile); | |
| 812 | + }else if( showFileHash ){ | |
| 791 | 813 | const char *zUuidF = db_column_text(&q,3); |
| 792 | 814 | fossil_print("%s %7d [%S] %s\n", zTime, size, zUuidF, zFile); |
| 793 | 815 | }else if( showCkinHash ){ |
| 794 | 816 | const char *zUuidC = db_column_text(&q,4); |
| 795 | 817 | fossil_print("%s %7d [%S] %s\n", zTime, size, zUuidC, zFile); |
| @@ -887,11 +909,12 @@ | ||
| 887 | 909 | } |
| 888 | 910 | |
| 889 | 911 | if( zRev!=0 ){ |
| 890 | 912 | db_find_and_open_repository(0, 0); |
| 891 | 913 | verify_all_options(); |
| 892 | - ls_cmd_rev(zRev,verboseFlag,showAge,showFHash,showCHash,timeOrder,treeFmt); | |
| 914 | + ls_cmd_rev(zRev, verboseFlag, showAge, showFHash, showCHash, 0, timeOrder, | |
| 915 | + treeFmt); | |
| 893 | 916 | return; |
| 894 | 917 | }else if( find_option("R",0,1)!=0 ){ |
| 895 | 918 | fossil_fatal("the -r is required in addition to -R"); |
| 896 | 919 | } |
| 897 | 920 | |
| @@ -1010,11 +1033,11 @@ | ||
| 1010 | 1033 | |
| 1011 | 1034 | zRev = find_option("r","r",1); |
| 1012 | 1035 | if( zRev==0 ) zRev = "current"; |
| 1013 | 1036 | db_find_and_open_repository(0, 0); |
| 1014 | 1037 | verify_all_options(); |
| 1015 | - ls_cmd_rev(zRev,0,0,0,0,0,1); | |
| 1038 | + ls_cmd_rev(zRev,0,0,0,0,0,0,1); | |
| 1016 | 1039 | } |
| 1017 | 1040 | |
| 1018 | 1041 | /* |
| 1019 | 1042 | ** COMMAND: extras |
| 1020 | 1043 | ** |
| 1021 | 1044 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -714,16 +714,17 @@ | |
| 714 | } |
| 715 | |
| 716 | /* |
| 717 | ** Take care of -r version of ls command |
| 718 | */ |
| 719 | static void ls_cmd_rev( |
| 720 | const char *zRev, /* Revision string given */ |
| 721 | int verboseFlag, /* Verbose flag given */ |
| 722 | int showAge, /* Age flag given */ |
| 723 | int showFileHash, /* Show file hash flag given */ |
| 724 | int showCkinHash, /* Show check-in hash flag given */ |
| 725 | int timeOrder, /* Order by time flag given */ |
| 726 | int treeFmt /* Show output in the tree format */ |
| 727 | ){ |
| 728 | Stmt q; |
| 729 | char *zOrderBy = "pathname COLLATE nocase"; |
| @@ -763,22 +764,36 @@ | |
| 763 | if( timeOrder ){ |
| 764 | zOrderBy = "mtime DESC"; |
| 765 | } |
| 766 | |
| 767 | compute_fileage(rid,0); |
| 768 | db_prepare(&q, |
| 769 | "SELECT datetime(fileage.mtime, toLocal()), fileage.pathname,\n" |
| 770 | " bfh.size, fileage.uuid %s\n" |
| 771 | " FROM fileage, blob bfh %s\n" |
| 772 | " WHERE bfh.rid=fileage.fid %s %s\n" |
| 773 | " ORDER BY %s;", |
| 774 | showCkinHash ? ", bch.uuid" : "", |
| 775 | showCkinHash ? ", blob bch" : "", |
| 776 | showCkinHash ? "\n AND bch.rid=fileage.mid" : "", |
| 777 | blob_sql_text(&where), |
| 778 | zOrderBy /*safe-for-%s*/ |
| 779 | ); |
| 780 | blob_reset(&where); |
| 781 | if( treeFmt ) blob_init(&out, 0, 0); |
| 782 | |
| 783 | while( db_step(&q)==SQLITE_ROW ){ |
| 784 | const char *zTime = db_column_text(&q,0); |
| @@ -785,11 +800,18 @@ | |
| 785 | const char *zFile = db_column_text(&q,1); |
| 786 | int size = db_column_int(&q,2); |
| 787 | if( treeFmt ){ |
| 788 | blob_appendf(&out, "%s\n", zFile); |
| 789 | }else if( verboseFlag ){ |
| 790 | if( showFileHash ){ |
| 791 | const char *zUuidF = db_column_text(&q,3); |
| 792 | fossil_print("%s %7d [%S] %s\n", zTime, size, zUuidF, zFile); |
| 793 | }else if( showCkinHash ){ |
| 794 | const char *zUuidC = db_column_text(&q,4); |
| 795 | fossil_print("%s %7d [%S] %s\n", zTime, size, zUuidC, zFile); |
| @@ -887,11 +909,12 @@ | |
| 887 | } |
| 888 | |
| 889 | if( zRev!=0 ){ |
| 890 | db_find_and_open_repository(0, 0); |
| 891 | verify_all_options(); |
| 892 | ls_cmd_rev(zRev,verboseFlag,showAge,showFHash,showCHash,timeOrder,treeFmt); |
| 893 | return; |
| 894 | }else if( find_option("R",0,1)!=0 ){ |
| 895 | fossil_fatal("the -r is required in addition to -R"); |
| 896 | } |
| 897 | |
| @@ -1010,11 +1033,11 @@ | |
| 1010 | |
| 1011 | zRev = find_option("r","r",1); |
| 1012 | if( zRev==0 ) zRev = "current"; |
| 1013 | db_find_and_open_repository(0, 0); |
| 1014 | verify_all_options(); |
| 1015 | ls_cmd_rev(zRev,0,0,0,0,0,1); |
| 1016 | } |
| 1017 | |
| 1018 | /* |
| 1019 | ** COMMAND: extras |
| 1020 | ** |
| 1021 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -714,16 +714,17 @@ | |
| 714 | } |
| 715 | |
| 716 | /* |
| 717 | ** Take care of -r version of ls command |
| 718 | */ |
| 719 | void ls_cmd_rev( |
| 720 | const char *zRev, /* Revision string given */ |
| 721 | int verboseFlag, /* Verbose flag given */ |
| 722 | int showAge, /* Age flag given */ |
| 723 | int showFileHash, /* Show file hash flag given */ |
| 724 | int showCkinHash, /* Show check-in hash flag given */ |
| 725 | int showCkinInfo, /* Show check-in infos */ |
| 726 | int timeOrder, /* Order by time flag given */ |
| 727 | int treeFmt /* Show output in the tree format */ |
| 728 | ){ |
| 729 | Stmt q; |
| 730 | char *zOrderBy = "pathname COLLATE nocase"; |
| @@ -763,22 +764,36 @@ | |
| 764 | if( timeOrder ){ |
| 765 | zOrderBy = "mtime DESC"; |
| 766 | } |
| 767 | |
| 768 | compute_fileage(rid,0); |
| 769 | if( showCkinInfo ){ |
| 770 | db_prepare(&q, |
| 771 | "SELECT datetime(fileage.mtime, toLocal()), fileage.pathname,\n" |
| 772 | " bfh.size, fileage.uuid, bch.uuid,\n" |
| 773 | " coalesce(e.ecomment, e.comment), coalesce(e.euser, e.user)\n" |
| 774 | " FROM fileage, blob bfh, blob bch, event e\n" |
| 775 | " WHERE bfh.rid=fileage.fid AND bch.rid=fileage.mid\n" |
| 776 | " AND e.objid = fileage.mid %s\n" |
| 777 | " ORDER BY %s;", |
| 778 | blob_sql_text(&where), |
| 779 | zOrderBy /*safe-for-%s*/ |
| 780 | ); |
| 781 | }else{ |
| 782 | db_prepare(&q, |
| 783 | "SELECT datetime(fileage.mtime, toLocal()), fileage.pathname,\n" |
| 784 | " bfh.size, fileage.uuid %s\n" |
| 785 | " FROM fileage, blob bfh %s\n" |
| 786 | " WHERE bfh.rid=fileage.fid %s %s\n" |
| 787 | " ORDER BY %s;", |
| 788 | showCkinHash ? ", bch.uuid" : "", |
| 789 | showCkinHash ? ", blob bch" : "", |
| 790 | showCkinHash ? "\n AND bch.rid=fileage.mid" : "", |
| 791 | blob_sql_text(&where), |
| 792 | zOrderBy /*safe-for-%s*/ |
| 793 | ); |
| 794 | } |
| 795 | blob_reset(&where); |
| 796 | if( treeFmt ) blob_init(&out, 0, 0); |
| 797 | |
| 798 | while( db_step(&q)==SQLITE_ROW ){ |
| 799 | const char *zTime = db_column_text(&q,0); |
| @@ -785,11 +800,18 @@ | |
| 800 | const char *zFile = db_column_text(&q,1); |
| 801 | int size = db_column_int(&q,2); |
| 802 | if( treeFmt ){ |
| 803 | blob_appendf(&out, "%s\n", zFile); |
| 804 | }else if( verboseFlag ){ |
| 805 | if( showCkinInfo ){ |
| 806 | const char *zUuidC = db_column_text(&q,4); |
| 807 | const char *zComm = db_column_text(&q,5); |
| 808 | const char *zUser = db_column_text(&q,6); |
| 809 | fossil_print("%s [%S] %12s ", zTime, zUuidC, zUser); |
| 810 | if( showCkinInfo==2 ) fossil_print("%-20.20s ", zComm); |
| 811 | fossil_print("%s\n", zFile); |
| 812 | }else if( showFileHash ){ |
| 813 | const char *zUuidF = db_column_text(&q,3); |
| 814 | fossil_print("%s %7d [%S] %s\n", zTime, size, zUuidF, zFile); |
| 815 | }else if( showCkinHash ){ |
| 816 | const char *zUuidC = db_column_text(&q,4); |
| 817 | fossil_print("%s %7d [%S] %s\n", zTime, size, zUuidC, zFile); |
| @@ -887,11 +909,12 @@ | |
| 909 | } |
| 910 | |
| 911 | if( zRev!=0 ){ |
| 912 | db_find_and_open_repository(0, 0); |
| 913 | verify_all_options(); |
| 914 | ls_cmd_rev(zRev, verboseFlag, showAge, showFHash, showCHash, 0, timeOrder, |
| 915 | treeFmt); |
| 916 | return; |
| 917 | }else if( find_option("R",0,1)!=0 ){ |
| 918 | fossil_fatal("the -r is required in addition to -R"); |
| 919 | } |
| 920 | |
| @@ -1010,11 +1033,11 @@ | |
| 1033 | |
| 1034 | zRev = find_option("r","r",1); |
| 1035 | if( zRev==0 ) zRev = "current"; |
| 1036 | db_find_and_open_repository(0, 0); |
| 1037 | verify_all_options(); |
| 1038 | ls_cmd_rev(zRev,0,0,0,0,0,0,1); |
| 1039 | } |
| 1040 | |
| 1041 | /* |
| 1042 | ** COMMAND: extras |
| 1043 | ** |
| 1044 |
+21
-1
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -3622,11 +3622,11 @@ | ||
| 3622 | 3622 | iLimit = 0; |
| 3623 | 3623 | mxTime = current_time_in_milliseconds()+1000; |
| 3624 | 3624 | } |
| 3625 | 3625 | db_begin_transaction(); |
| 3626 | 3626 | |
| 3627 | - /* Get the artifact ID for the check-in begin analyzed */ | |
| 3627 | + /* Get the artifact ID for the check-in being analyzed */ | |
| 3628 | 3628 | if( zRevision ){ |
| 3629 | 3629 | cid = name_to_typed_rid(zRevision, "ci"); |
| 3630 | 3630 | }else{ |
| 3631 | 3631 | db_must_be_within_tree(); |
| 3632 | 3632 | cid = db_lget_int("checkout", 0); |
| @@ -3939,10 +3939,15 @@ | ||
| 3939 | 3939 | ** (example: "-o trunk") then these commands show changes moving towards |
| 3940 | 3940 | ** that alternative origin. Thus using "-o trunk" on an historical version |
| 3941 | 3941 | ** of the file shows the first time each line in the file was changed or |
| 3942 | 3942 | ** removed by any subsequent check-in. |
| 3943 | 3943 | ** |
| 3944 | +** With -t or -T, the "blame" and "praise" commands show for each file the | |
| 3945 | +** latest (relative to the revision given by -r) check-in that modified it and | |
| 3946 | +** the check-in's author. If not given, the revision defaults to "current" for | |
| 3947 | +** a check-out. Option -T additionally shows a comment snippet for the check-in. | |
| 3948 | +** | |
| 3944 | 3949 | ** Options: |
| 3945 | 3950 | ** --filevers Show file version numbers rather than |
| 3946 | 3951 | ** check-in versions |
| 3947 | 3952 | ** -r|--revision VERSION The specific check-in containing the file |
| 3948 | 3953 | ** -l|--log List all versions analyzed |
| @@ -3954,10 +3959,13 @@ | ||
| 3954 | 3959 | ** root of the repository. Set to the name of |
| 3955 | 3960 | ** the main branch (usually "trunk") or |
| 3956 | 3961 | ** similar for a reverse annotation. |
| 3957 | 3962 | ** -w|--ignore-all-space Ignore white space when comparing lines |
| 3958 | 3963 | ** -Z|--ignore-trailing-space Ignore whitespace at line end |
| 3964 | +** -t Show latest check-in and its author for each | |
| 3965 | +** tracked file in the tree as of VERSION | |
| 3966 | +** -T Like -t, plus comment snippet | |
| 3959 | 3967 | ** |
| 3960 | 3968 | ** See also: [[info]], [[finfo]], [[timeline]] |
| 3961 | 3969 | */ |
| 3962 | 3970 | void annotate_cmd(void){ |
| 3963 | 3971 | const char *zRevision; /* Revision name, or NULL for current check-in */ |
| @@ -3967,16 +3975,28 @@ | ||
| 3967 | 3975 | const char *zOrig; /* The value for -o|--origin */ |
| 3968 | 3976 | int showLog; /* True to show the log */ |
| 3969 | 3977 | int fileVers; /* Show file version instead of check-in versions */ |
| 3970 | 3978 | u64 annFlags = 0; /* Flags to control annotation properties */ |
| 3971 | 3979 | int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */ |
| 3980 | + int bTreeInfo = 0; /* Show for the entire tree: 1=checkin, 2=with comment */ | |
| 3972 | 3981 | int szHash; /* Display size of a version hash */ |
| 3973 | 3982 | Blob treename; /* Name of file to be annotated */ |
| 3974 | 3983 | char *zFilename; /* Name of file to be annotated */ |
| 3975 | 3984 | |
| 3976 | 3985 | bBlame = g.argv[1][0]!='a'; |
| 3986 | + if( find_option("t","t",0)!=0 ) bTreeInfo = 1; | |
| 3987 | + if( find_option("T","T",0)!=0 ) bTreeInfo = 2; | |
| 3977 | 3988 | zRevision = find_option("revision","r",1); |
| 3989 | + if( bBlame && bTreeInfo ){ | |
| 3990 | + if( find_repository_option()!=0 && zRevision==0 ){ | |
| 3991 | + fossil_fatal("the -r is required in addition to -R"); | |
| 3992 | + } | |
| 3993 | + db_find_and_open_repository(0, 0); | |
| 3994 | + if( zRevision==0 ) zRevision = "current"; | |
| 3995 | + ls_cmd_rev(zRevision,1,1,0,1,bTreeInfo,0,0); | |
| 3996 | + return; | |
| 3997 | + } | |
| 3978 | 3998 | zLimit = find_option("limit","n",1); |
| 3979 | 3999 | zOrig = find_option("origin","o",1); |
| 3980 | 4000 | showLog = find_option("log","l",0)!=0; |
| 3981 | 4001 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 3982 | 4002 | annFlags = DIFF_IGNORE_EOLWS; |
| 3983 | 4003 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -3622,11 +3622,11 @@ | |
| 3622 | iLimit = 0; |
| 3623 | mxTime = current_time_in_milliseconds()+1000; |
| 3624 | } |
| 3625 | db_begin_transaction(); |
| 3626 | |
| 3627 | /* Get the artifact ID for the check-in begin analyzed */ |
| 3628 | if( zRevision ){ |
| 3629 | cid = name_to_typed_rid(zRevision, "ci"); |
| 3630 | }else{ |
| 3631 | db_must_be_within_tree(); |
| 3632 | cid = db_lget_int("checkout", 0); |
| @@ -3939,10 +3939,15 @@ | |
| 3939 | ** (example: "-o trunk") then these commands show changes moving towards |
| 3940 | ** that alternative origin. Thus using "-o trunk" on an historical version |
| 3941 | ** of the file shows the first time each line in the file was changed or |
| 3942 | ** removed by any subsequent check-in. |
| 3943 | ** |
| 3944 | ** Options: |
| 3945 | ** --filevers Show file version numbers rather than |
| 3946 | ** check-in versions |
| 3947 | ** -r|--revision VERSION The specific check-in containing the file |
| 3948 | ** -l|--log List all versions analyzed |
| @@ -3954,10 +3959,13 @@ | |
| 3954 | ** root of the repository. Set to the name of |
| 3955 | ** the main branch (usually "trunk") or |
| 3956 | ** similar for a reverse annotation. |
| 3957 | ** -w|--ignore-all-space Ignore white space when comparing lines |
| 3958 | ** -Z|--ignore-trailing-space Ignore whitespace at line end |
| 3959 | ** |
| 3960 | ** See also: [[info]], [[finfo]], [[timeline]] |
| 3961 | */ |
| 3962 | void annotate_cmd(void){ |
| 3963 | const char *zRevision; /* Revision name, or NULL for current check-in */ |
| @@ -3967,16 +3975,28 @@ | |
| 3967 | const char *zOrig; /* The value for -o|--origin */ |
| 3968 | int showLog; /* True to show the log */ |
| 3969 | int fileVers; /* Show file version instead of check-in versions */ |
| 3970 | u64 annFlags = 0; /* Flags to control annotation properties */ |
| 3971 | int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */ |
| 3972 | int szHash; /* Display size of a version hash */ |
| 3973 | Blob treename; /* Name of file to be annotated */ |
| 3974 | char *zFilename; /* Name of file to be annotated */ |
| 3975 | |
| 3976 | bBlame = g.argv[1][0]!='a'; |
| 3977 | zRevision = find_option("revision","r",1); |
| 3978 | zLimit = find_option("limit","n",1); |
| 3979 | zOrig = find_option("origin","o",1); |
| 3980 | showLog = find_option("log","l",0)!=0; |
| 3981 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 3982 | annFlags = DIFF_IGNORE_EOLWS; |
| 3983 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -3622,11 +3622,11 @@ | |
| 3622 | iLimit = 0; |
| 3623 | mxTime = current_time_in_milliseconds()+1000; |
| 3624 | } |
| 3625 | db_begin_transaction(); |
| 3626 | |
| 3627 | /* Get the artifact ID for the check-in being analyzed */ |
| 3628 | if( zRevision ){ |
| 3629 | cid = name_to_typed_rid(zRevision, "ci"); |
| 3630 | }else{ |
| 3631 | db_must_be_within_tree(); |
| 3632 | cid = db_lget_int("checkout", 0); |
| @@ -3939,10 +3939,15 @@ | |
| 3939 | ** (example: "-o trunk") then these commands show changes moving towards |
| 3940 | ** that alternative origin. Thus using "-o trunk" on an historical version |
| 3941 | ** of the file shows the first time each line in the file was changed or |
| 3942 | ** removed by any subsequent check-in. |
| 3943 | ** |
| 3944 | ** With -t or -T, the "blame" and "praise" commands show for each file the |
| 3945 | ** latest (relative to the revision given by -r) check-in that modified it and |
| 3946 | ** the check-in's author. If not given, the revision defaults to "current" for |
| 3947 | ** a check-out. Option -T additionally shows a comment snippet for the check-in. |
| 3948 | ** |
| 3949 | ** Options: |
| 3950 | ** --filevers Show file version numbers rather than |
| 3951 | ** check-in versions |
| 3952 | ** -r|--revision VERSION The specific check-in containing the file |
| 3953 | ** -l|--log List all versions analyzed |
| @@ -3954,10 +3959,13 @@ | |
| 3959 | ** root of the repository. Set to the name of |
| 3960 | ** the main branch (usually "trunk") or |
| 3961 | ** similar for a reverse annotation. |
| 3962 | ** -w|--ignore-all-space Ignore white space when comparing lines |
| 3963 | ** -Z|--ignore-trailing-space Ignore whitespace at line end |
| 3964 | ** -t Show latest check-in and its author for each |
| 3965 | ** tracked file in the tree as of VERSION |
| 3966 | ** -T Like -t, plus comment snippet |
| 3967 | ** |
| 3968 | ** See also: [[info]], [[finfo]], [[timeline]] |
| 3969 | */ |
| 3970 | void annotate_cmd(void){ |
| 3971 | const char *zRevision; /* Revision name, or NULL for current check-in */ |
| @@ -3967,16 +3975,28 @@ | |
| 3975 | const char *zOrig; /* The value for -o|--origin */ |
| 3976 | int showLog; /* True to show the log */ |
| 3977 | int fileVers; /* Show file version instead of check-in versions */ |
| 3978 | u64 annFlags = 0; /* Flags to control annotation properties */ |
| 3979 | int bBlame = 0; /* True for BLAME output. False for ANNOTATE. */ |
| 3980 | int bTreeInfo = 0; /* Show for the entire tree: 1=checkin, 2=with comment */ |
| 3981 | int szHash; /* Display size of a version hash */ |
| 3982 | Blob treename; /* Name of file to be annotated */ |
| 3983 | char *zFilename; /* Name of file to be annotated */ |
| 3984 | |
| 3985 | bBlame = g.argv[1][0]!='a'; |
| 3986 | if( find_option("t","t",0)!=0 ) bTreeInfo = 1; |
| 3987 | if( find_option("T","T",0)!=0 ) bTreeInfo = 2; |
| 3988 | zRevision = find_option("revision","r",1); |
| 3989 | if( bBlame && bTreeInfo ){ |
| 3990 | if( find_repository_option()!=0 && zRevision==0 ){ |
| 3991 | fossil_fatal("the -r is required in addition to -R"); |
| 3992 | } |
| 3993 | db_find_and_open_repository(0, 0); |
| 3994 | if( zRevision==0 ) zRevision = "current"; |
| 3995 | ls_cmd_rev(zRevision,1,1,0,1,bTreeInfo,0,0); |
| 3996 | return; |
| 3997 | } |
| 3998 | zLimit = find_option("limit","n",1); |
| 3999 | zOrig = find_option("origin","o",1); |
| 4000 | showLog = find_option("log","l",0)!=0; |
| 4001 | if( find_option("ignore-trailing-space","Z",0)!=0 ){ |
| 4002 | annFlags = DIFF_IGNORE_EOLWS; |
| 4003 |