Fossil SCM
Re-implemented and drastically simplified the mini-checkin F-card generator.
Commit
39262b420a38906a95204531a3548c14b87b594d7c014dd6f96e4547eda0a98f
Parent
fcdd76f6fbcf2ea…
1 file changed
+53
-117
+53
-117
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -2866,11 +2866,10 @@ | ||
| 2866 | 2866 | }else{ |
| 2867 | 2867 | /* File was removed from parent delta. */ |
| 2868 | 2868 | blob_appendf(pOut, "F %F\n", p->zName); |
| 2869 | 2869 | } |
| 2870 | 2870 | } |
| 2871 | - | |
| 2872 | 2871 | /* |
| 2873 | 2872 | ** Handles the F-card parts for create_manifest_mini(). |
| 2874 | 2873 | ** |
| 2875 | 2874 | ** If asDelta is true, F-cards will be handled as for a delta |
| 2876 | 2875 | ** manifest, and the caller MUST have added a B-card to pOut before |
| @@ -2881,150 +2880,87 @@ | ||
| 2881 | 2880 | */ |
| 2882 | 2881 | static int create_manifest_mini_fcards( Blob * pOut, |
| 2883 | 2882 | CheckinMiniInfo * pCI, |
| 2884 | 2883 | int asDelta, |
| 2885 | 2884 | Blob * pErr){ |
| 2886 | - ManifestFile *pFile; /* One file entry from pCI->pParent */ | |
| 2887 | - const char *zFilename = 0; /* filename for new F-card */ | |
| 2888 | - const char *zUuid = 0; /* UUID for new F-card */ | |
| 2889 | - int cmp = 0; /* filename comparison result */ | |
| 2890 | - int iFCursor = 0; /* Cursor into pCI->pParent->aFile if | |
| 2891 | - pCI->pParent is a delta. */ | |
| 2892 | - int postProcess = -1; /* How to traverse post-pCI->zFilename | |
| 2893 | - F-cards at the end of the function: | |
| 2894 | - 0=none, 1=normal traversal, | |
| 2895 | - 2=delta-clone tranversal. */ | |
| 2885 | + int wroteThisCard = 0; | |
| 2886 | + const ManifestFile * pFile; | |
| 2896 | 2887 | int (*fncmp)(char const *, char const *) = /* filename comparator */ |
| 2897 | 2888 | filenames_are_case_sensitive() |
| 2898 | 2889 | ? fossil_strcmp |
| 2899 | 2890 | : fossil_stricmp; |
| 2900 | 2891 | #define mf_err(EXPR) if(pErr) blob_appendf EXPR; return 0 |
| 2892 | +#define write_this_card(NAME) \ | |
| 2893 | + blob_appendf(pOut, "F %F %b%s\n", (NAME), &pCI->fileHash, \ | |
| 2894 | + mfile_permint_mstring(pCI->filePerm)); \ | |
| 2895 | + wroteThisCard = 1 | |
| 2901 | 2896 | |
| 2902 | 2897 | assert(pCI->filePerm!=PERM_LNK && "This should have been validated before."); |
| 2903 | 2898 | assert(pCI->filePerm==PERM_REG || pCI->filePerm==PERM_EXE); |
| 2904 | 2899 | if(PERM_LNK==pCI->filePerm){ |
| 2905 | 2900 | goto err_no_symlink; |
| 2906 | 2901 | } |
| 2907 | 2902 | manifest_file_rewind(pCI->pParent); |
| 2908 | - if(asDelta){ | |
| 2909 | - if(pCI->pParent->zBaseline==0 || pCI->pParent->nFile==0 ){ | |
| 2910 | - /* Parent is a baseline or a delta with no F-cards, so this is | |
| 2911 | - ** the simplest case: create a delta with a single F-card. | |
| 2912 | - */ | |
| 2913 | - pFile = manifest_file_find(pCI->pParent, pCI->zFilename); | |
| 2914 | - if(pFile==0){/* New file */ | |
| 2915 | - zFilename = pCI->zFilename; | |
| 2916 | - }else{/* Replacement file */ | |
| 2917 | - if(manifest_file_mperm(pFile)==PERM_LNK){ | |
| 2918 | - goto err_no_symlink; | |
| 2919 | - } | |
| 2920 | - zFilename = pFile->zName | |
| 2921 | - /* use original name in case of name-case difference */; | |
| 2922 | - } | |
| 2923 | - postProcess = 0; | |
| 2903 | + if(asDelta!=0 && (pCI->pParent->zBaseline==0 | |
| 2904 | + || pCI->pParent->nFile==0)){ | |
| 2905 | + /* Parent is a baseline or a delta with no F-cards, so this is | |
| 2906 | + ** the simplest case: create a delta with a single F-card. | |
| 2907 | + */ | |
| 2908 | + pFile = manifest_file_find(pCI->pParent, pCI->zFilename); | |
| 2909 | + if(pFile!=0 && manifest_file_mperm(pFile)==PERM_LNK){ | |
| 2910 | + goto err_no_symlink; | |
| 2911 | + } | |
| 2912 | + write_this_card(pFile ? pFile->zName : pCI->zFilename); | |
| 2913 | + return 1; | |
| 2914 | + } | |
| 2915 | + while(1){ | |
| 2916 | + int cmp; | |
| 2917 | + if(asDelta==0){ | |
| 2918 | + pFile = manifest_file_next(pCI->pParent, 0); | |
| 2924 | 2919 | }else{ |
| 2925 | 2920 | /* Parent is a delta manifest with F-cards. Traversal of delta |
| 2926 | 2921 | ** manifest file entries is normally done via |
| 2927 | 2922 | ** manifest_file_next(), which takes into account the |
| 2928 | 2923 | ** differences between the delta and its parent and returns |
| 2929 | 2924 | ** F-cards from both. Each successive delta from the same |
| 2930 | 2925 | ** baseline includes all F-card changes from the previous |
| 2931 | - ** deltas, so we instead "clone" the parent's F-cards except for | |
| 2932 | - ** the one (if any) which matches the new file. | |
| 2933 | - */ | |
| 2934 | - Manifest * p = pCI->pParent; | |
| 2935 | - cmp = -1; | |
| 2936 | - assert(p->nFile > 0); | |
| 2937 | - iFCursor = 0; | |
| 2938 | - pFile = &p->aFile[iFCursor]; | |
| 2939 | - /* Write F-cards which lexically preceed pCI->zFilename */ | |
| 2940 | - for( ; iFCursor<p->nFile; ){ | |
| 2941 | - pFile = &p->aFile[iFCursor]; | |
| 2942 | - cmp = fncmp(pFile->zName, pCI->zFilename); | |
| 2943 | - if(cmp<0){ | |
| 2944 | - ++iFCursor; | |
| 2945 | - checkin_mini_append_fcard(pOut,pFile); | |
| 2946 | - }else{ | |
| 2947 | - break; | |
| 2948 | - } | |
| 2949 | - } | |
| 2950 | - if(0==cmp){/* Match: override this F-card */ | |
| 2951 | - assert(pFile); | |
| 2952 | - if(manifest_file_mperm(pFile)==PERM_LNK){ | |
| 2953 | - goto err_no_symlink; | |
| 2954 | - } | |
| 2955 | - ++iFCursor; | |
| 2956 | - zFilename = pFile->zName | |
| 2957 | - /* use original name in case of name-case difference */; | |
| 2958 | - }else{/* This is a new file */ | |
| 2959 | - zFilename = pCI->zFilename; | |
| 2960 | - } | |
| 2961 | - postProcess = 2; | |
| 2962 | - } | |
| 2963 | - }else{/* Non-delta: write F-cards which lexically preceed | |
| 2964 | - pCI->zFilename */ | |
| 2965 | - cmp = -1; | |
| 2966 | - while((pFile = manifest_file_next(pCI->pParent, 0)) | |
| 2967 | - && (cmp = fncmp(pFile->zName, pCI->zFilename))<0){ | |
| 2968 | - checkin_mini_append_fcard(pOut,pFile); | |
| 2969 | - } | |
| 2970 | - if(cmp==0){/* Match: override this F-card*/ | |
| 2971 | - if(manifest_file_mperm(pFile)==PERM_LNK){ | |
| 2972 | - goto err_no_symlink; | |
| 2973 | - } | |
| 2974 | - zFilename = pFile->zName | |
| 2975 | - /* use original name in case of name-case difference */; | |
| 2976 | - }else{/* This is a new file. */ | |
| 2977 | - zFilename = pCI->zFilename; | |
| 2978 | - if(pFile!=0){ | |
| 2979 | - assert(cmp>0); | |
| 2980 | - assert(pCI->pParent->iFile>0); | |
| 2981 | - --pCI->pParent->iFile | |
| 2982 | - /* So that the post-processing loop picks up this file | |
| 2983 | - again.*/; | |
| 2984 | - } | |
| 2985 | - } | |
| 2986 | - postProcess = 1; | |
| 2987 | - } | |
| 2988 | - /* Finally add the new file's F-card... */ | |
| 2989 | - pFile = 0; | |
| 2990 | - zUuid = blob_str(&pCI->fileHash); | |
| 2991 | - assert(zFilename); | |
| 2992 | - assert(zUuid); | |
| 2993 | - assert(postProcess==0 || postProcess==1 || postProcess==2); | |
| 2994 | - blob_appendf(pOut, "F %F %s%s\n", zFilename, zUuid, | |
| 2995 | - mfile_permint_mstring(pCI->filePerm)); | |
| 2996 | - while(postProcess>0){ | |
| 2997 | - /* Write F-cards which lexically follow pCI->zFilename */ | |
| 2998 | - if(postProcess==1){ /* non-delta parent */ | |
| 2999 | - pFile = manifest_file_next(pCI->pParent, 0); | |
| 3000 | - }else{ /* clone directly from delta parent */ | |
| 3001 | - pFile = iFCursor<pCI->pParent->nFile | |
| 3002 | - ? &pCI->pParent->aFile[iFCursor++] : 0; | |
| 3003 | - } | |
| 3004 | - if(pFile==0){ | |
| 3005 | - break; | |
| 3006 | - } | |
| 3007 | -#ifndef NDEBUG | |
| 3008 | - cmp = fncmp(pFile->zName, pCI->zFilename); | |
| 3009 | - assert(cmp>0); | |
| 3010 | - if(cmp<=0){ | |
| 3011 | - mf_err((pErr,"Internal error: mis-ordering of " | |
| 3012 | - "F-cards detected.")); | |
| 3013 | - } | |
| 3014 | -#endif | |
| 3015 | - assert(pFile->zUuid || 2==postProcess); | |
| 3016 | - checkin_mini_append_fcard(pOut,pFile); | |
| 2926 | + ** deltas, so we instead clone the parent's F-cards except for | |
| 2927 | + ** the one (if any) which matches the new file. | |
| 2928 | + */ | |
| 2929 | + pFile = pCI->pParent->iFile < pCI->pParent->nFile | |
| 2930 | + ? &pCI->pParent->aFile[pCI->pParent->iFile++] | |
| 2931 | + : 0; | |
| 2932 | + } | |
| 2933 | + if(0==pFile) break; | |
| 2934 | + cmp = fncmp(pFile->zName, pCI->zFilename); | |
| 2935 | + if(cmp<0){ | |
| 2936 | + checkin_mini_append_fcard(pOut,pFile); | |
| 2937 | + }else{ | |
| 2938 | + if(cmp==0 || 0==wroteThisCard){ | |
| 2939 | + assert(0==wroteThisCard); | |
| 2940 | + if(PERM_LNK==manifest_file_mperm(pFile)){ | |
| 2941 | + goto err_no_symlink; | |
| 2942 | + } | |
| 2943 | + write_this_card(cmp==0 ? pFile->zName : pCI->zFilename); | |
| 2944 | + } | |
| 2945 | + if(cmp>0){ | |
| 2946 | + assert(wroteThisCard!=0); | |
| 2947 | + checkin_mini_append_fcard(pOut,pFile); | |
| 2948 | + } | |
| 2949 | + } | |
| 2950 | + } | |
| 2951 | + if(wroteThisCard==0){ | |
| 2952 | + write_this_card(pCI->zFilename); | |
| 3017 | 2953 | } |
| 3018 | 2954 | return 1; |
| 3019 | 2955 | err_no_symlink: |
| 3020 | 2956 | mf_err((pErr,"Cannot commit or overwrite symlinks " |
| 3021 | 2957 | "via mini-checkin.")); |
| 3022 | 2958 | return 0; |
| 2959 | +#undef write_this_card | |
| 3023 | 2960 | #undef mf_err |
| 3024 | 2961 | } |
| 3025 | - | |
| 3026 | 2962 | |
| 3027 | 2963 | /* |
| 3028 | 2964 | ** Creates a manifest file, written to pOut, from the state in the |
| 3029 | 2965 | ** fully-populated and semantically valid pCI argument. pCI is not |
| 3030 | 2966 | ** *semantically* modified but cannot be const because blob_str() may |
| @@ -3063,12 +2999,12 @@ | ||
| 3063 | 2999 | |
| 3064 | 3000 | if((CIMINI_PREFER_DELTA & pCI->flags) |
| 3065 | 3001 | && ((CIMINI_STRONGLY_PREFER_DELTA & pCI->flags) |
| 3066 | 3002 | || (pCI->pParent->pBaseline |
| 3067 | 3003 | ? pCI->pParent->pBaseline |
| 3068 | - : pCI->pParent)->nFile > 10 | |
| 3069 | - /* 10 is arbitrary: don't create a delta when there is only a | |
| 3004 | + : pCI->pParent)->nFile > 15 | |
| 3005 | + /* 15 is arbitrary: don't create a delta when there is only a | |
| 3070 | 3006 | ** tiny gain for doing so. */) |
| 3071 | 3007 | && !db_get_boolean("forbid-delta-manifests",0) |
| 3072 | 3008 | ){ |
| 3073 | 3009 | asDelta = 1; |
| 3074 | 3010 | blob_appendf(pOut, "B %s\n", |
| @@ -3080,11 +3016,11 @@ | ||
| 3080 | 3016 | blob_appendf(pOut, "C %F\n", blob_str(&pCI->comment)); |
| 3081 | 3017 | }else{ |
| 3082 | 3018 | blob_append(pOut, "C (no\\scomment)\n", 16); |
| 3083 | 3019 | } |
| 3084 | 3020 | blob_appendf(pOut, "D %z\n", pCI->zDate); |
| 3085 | - if(!create_manifest_mini_fcards(pOut,pCI,asDelta,pErr)){ | |
| 3021 | + if(create_manifest_mini_fcards(pOut,pCI,asDelta,pErr)==0){ | |
| 3086 | 3022 | return 0; |
| 3087 | 3023 | } |
| 3088 | 3024 | if(pCI->zMimetype!=0 && pCI->zMimetype[0]!=0){ |
| 3089 | 3025 | blob_appendf(pOut, "N %F\n", pCI->zMimetype); |
| 3090 | 3026 | } |
| 3091 | 3027 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -2866,11 +2866,10 @@ | |
| 2866 | }else{ |
| 2867 | /* File was removed from parent delta. */ |
| 2868 | blob_appendf(pOut, "F %F\n", p->zName); |
| 2869 | } |
| 2870 | } |
| 2871 | |
| 2872 | /* |
| 2873 | ** Handles the F-card parts for create_manifest_mini(). |
| 2874 | ** |
| 2875 | ** If asDelta is true, F-cards will be handled as for a delta |
| 2876 | ** manifest, and the caller MUST have added a B-card to pOut before |
| @@ -2881,150 +2880,87 @@ | |
| 2881 | */ |
| 2882 | static int create_manifest_mini_fcards( Blob * pOut, |
| 2883 | CheckinMiniInfo * pCI, |
| 2884 | int asDelta, |
| 2885 | Blob * pErr){ |
| 2886 | ManifestFile *pFile; /* One file entry from pCI->pParent */ |
| 2887 | const char *zFilename = 0; /* filename for new F-card */ |
| 2888 | const char *zUuid = 0; /* UUID for new F-card */ |
| 2889 | int cmp = 0; /* filename comparison result */ |
| 2890 | int iFCursor = 0; /* Cursor into pCI->pParent->aFile if |
| 2891 | pCI->pParent is a delta. */ |
| 2892 | int postProcess = -1; /* How to traverse post-pCI->zFilename |
| 2893 | F-cards at the end of the function: |
| 2894 | 0=none, 1=normal traversal, |
| 2895 | 2=delta-clone tranversal. */ |
| 2896 | int (*fncmp)(char const *, char const *) = /* filename comparator */ |
| 2897 | filenames_are_case_sensitive() |
| 2898 | ? fossil_strcmp |
| 2899 | : fossil_stricmp; |
| 2900 | #define mf_err(EXPR) if(pErr) blob_appendf EXPR; return 0 |
| 2901 | |
| 2902 | assert(pCI->filePerm!=PERM_LNK && "This should have been validated before."); |
| 2903 | assert(pCI->filePerm==PERM_REG || pCI->filePerm==PERM_EXE); |
| 2904 | if(PERM_LNK==pCI->filePerm){ |
| 2905 | goto err_no_symlink; |
| 2906 | } |
| 2907 | manifest_file_rewind(pCI->pParent); |
| 2908 | if(asDelta){ |
| 2909 | if(pCI->pParent->zBaseline==0 || pCI->pParent->nFile==0 ){ |
| 2910 | /* Parent is a baseline or a delta with no F-cards, so this is |
| 2911 | ** the simplest case: create a delta with a single F-card. |
| 2912 | */ |
| 2913 | pFile = manifest_file_find(pCI->pParent, pCI->zFilename); |
| 2914 | if(pFile==0){/* New file */ |
| 2915 | zFilename = pCI->zFilename; |
| 2916 | }else{/* Replacement file */ |
| 2917 | if(manifest_file_mperm(pFile)==PERM_LNK){ |
| 2918 | goto err_no_symlink; |
| 2919 | } |
| 2920 | zFilename = pFile->zName |
| 2921 | /* use original name in case of name-case difference */; |
| 2922 | } |
| 2923 | postProcess = 0; |
| 2924 | }else{ |
| 2925 | /* Parent is a delta manifest with F-cards. Traversal of delta |
| 2926 | ** manifest file entries is normally done via |
| 2927 | ** manifest_file_next(), which takes into account the |
| 2928 | ** differences between the delta and its parent and returns |
| 2929 | ** F-cards from both. Each successive delta from the same |
| 2930 | ** baseline includes all F-card changes from the previous |
| 2931 | ** deltas, so we instead "clone" the parent's F-cards except for |
| 2932 | ** the one (if any) which matches the new file. |
| 2933 | */ |
| 2934 | Manifest * p = pCI->pParent; |
| 2935 | cmp = -1; |
| 2936 | assert(p->nFile > 0); |
| 2937 | iFCursor = 0; |
| 2938 | pFile = &p->aFile[iFCursor]; |
| 2939 | /* Write F-cards which lexically preceed pCI->zFilename */ |
| 2940 | for( ; iFCursor<p->nFile; ){ |
| 2941 | pFile = &p->aFile[iFCursor]; |
| 2942 | cmp = fncmp(pFile->zName, pCI->zFilename); |
| 2943 | if(cmp<0){ |
| 2944 | ++iFCursor; |
| 2945 | checkin_mini_append_fcard(pOut,pFile); |
| 2946 | }else{ |
| 2947 | break; |
| 2948 | } |
| 2949 | } |
| 2950 | if(0==cmp){/* Match: override this F-card */ |
| 2951 | assert(pFile); |
| 2952 | if(manifest_file_mperm(pFile)==PERM_LNK){ |
| 2953 | goto err_no_symlink; |
| 2954 | } |
| 2955 | ++iFCursor; |
| 2956 | zFilename = pFile->zName |
| 2957 | /* use original name in case of name-case difference */; |
| 2958 | }else{/* This is a new file */ |
| 2959 | zFilename = pCI->zFilename; |
| 2960 | } |
| 2961 | postProcess = 2; |
| 2962 | } |
| 2963 | }else{/* Non-delta: write F-cards which lexically preceed |
| 2964 | pCI->zFilename */ |
| 2965 | cmp = -1; |
| 2966 | while((pFile = manifest_file_next(pCI->pParent, 0)) |
| 2967 | && (cmp = fncmp(pFile->zName, pCI->zFilename))<0){ |
| 2968 | checkin_mini_append_fcard(pOut,pFile); |
| 2969 | } |
| 2970 | if(cmp==0){/* Match: override this F-card*/ |
| 2971 | if(manifest_file_mperm(pFile)==PERM_LNK){ |
| 2972 | goto err_no_symlink; |
| 2973 | } |
| 2974 | zFilename = pFile->zName |
| 2975 | /* use original name in case of name-case difference */; |
| 2976 | }else{/* This is a new file. */ |
| 2977 | zFilename = pCI->zFilename; |
| 2978 | if(pFile!=0){ |
| 2979 | assert(cmp>0); |
| 2980 | assert(pCI->pParent->iFile>0); |
| 2981 | --pCI->pParent->iFile |
| 2982 | /* So that the post-processing loop picks up this file |
| 2983 | again.*/; |
| 2984 | } |
| 2985 | } |
| 2986 | postProcess = 1; |
| 2987 | } |
| 2988 | /* Finally add the new file's F-card... */ |
| 2989 | pFile = 0; |
| 2990 | zUuid = blob_str(&pCI->fileHash); |
| 2991 | assert(zFilename); |
| 2992 | assert(zUuid); |
| 2993 | assert(postProcess==0 || postProcess==1 || postProcess==2); |
| 2994 | blob_appendf(pOut, "F %F %s%s\n", zFilename, zUuid, |
| 2995 | mfile_permint_mstring(pCI->filePerm)); |
| 2996 | while(postProcess>0){ |
| 2997 | /* Write F-cards which lexically follow pCI->zFilename */ |
| 2998 | if(postProcess==1){ /* non-delta parent */ |
| 2999 | pFile = manifest_file_next(pCI->pParent, 0); |
| 3000 | }else{ /* clone directly from delta parent */ |
| 3001 | pFile = iFCursor<pCI->pParent->nFile |
| 3002 | ? &pCI->pParent->aFile[iFCursor++] : 0; |
| 3003 | } |
| 3004 | if(pFile==0){ |
| 3005 | break; |
| 3006 | } |
| 3007 | #ifndef NDEBUG |
| 3008 | cmp = fncmp(pFile->zName, pCI->zFilename); |
| 3009 | assert(cmp>0); |
| 3010 | if(cmp<=0){ |
| 3011 | mf_err((pErr,"Internal error: mis-ordering of " |
| 3012 | "F-cards detected.")); |
| 3013 | } |
| 3014 | #endif |
| 3015 | assert(pFile->zUuid || 2==postProcess); |
| 3016 | checkin_mini_append_fcard(pOut,pFile); |
| 3017 | } |
| 3018 | return 1; |
| 3019 | err_no_symlink: |
| 3020 | mf_err((pErr,"Cannot commit or overwrite symlinks " |
| 3021 | "via mini-checkin.")); |
| 3022 | return 0; |
| 3023 | #undef mf_err |
| 3024 | } |
| 3025 | |
| 3026 | |
| 3027 | /* |
| 3028 | ** Creates a manifest file, written to pOut, from the state in the |
| 3029 | ** fully-populated and semantically valid pCI argument. pCI is not |
| 3030 | ** *semantically* modified but cannot be const because blob_str() may |
| @@ -3063,12 +2999,12 @@ | |
| 3063 | |
| 3064 | if((CIMINI_PREFER_DELTA & pCI->flags) |
| 3065 | && ((CIMINI_STRONGLY_PREFER_DELTA & pCI->flags) |
| 3066 | || (pCI->pParent->pBaseline |
| 3067 | ? pCI->pParent->pBaseline |
| 3068 | : pCI->pParent)->nFile > 10 |
| 3069 | /* 10 is arbitrary: don't create a delta when there is only a |
| 3070 | ** tiny gain for doing so. */) |
| 3071 | && !db_get_boolean("forbid-delta-manifests",0) |
| 3072 | ){ |
| 3073 | asDelta = 1; |
| 3074 | blob_appendf(pOut, "B %s\n", |
| @@ -3080,11 +3016,11 @@ | |
| 3080 | blob_appendf(pOut, "C %F\n", blob_str(&pCI->comment)); |
| 3081 | }else{ |
| 3082 | blob_append(pOut, "C (no\\scomment)\n", 16); |
| 3083 | } |
| 3084 | blob_appendf(pOut, "D %z\n", pCI->zDate); |
| 3085 | if(!create_manifest_mini_fcards(pOut,pCI,asDelta,pErr)){ |
| 3086 | return 0; |
| 3087 | } |
| 3088 | if(pCI->zMimetype!=0 && pCI->zMimetype[0]!=0){ |
| 3089 | blob_appendf(pOut, "N %F\n", pCI->zMimetype); |
| 3090 | } |
| 3091 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -2866,11 +2866,10 @@ | |
| 2866 | }else{ |
| 2867 | /* File was removed from parent delta. */ |
| 2868 | blob_appendf(pOut, "F %F\n", p->zName); |
| 2869 | } |
| 2870 | } |
| 2871 | /* |
| 2872 | ** Handles the F-card parts for create_manifest_mini(). |
| 2873 | ** |
| 2874 | ** If asDelta is true, F-cards will be handled as for a delta |
| 2875 | ** manifest, and the caller MUST have added a B-card to pOut before |
| @@ -2881,150 +2880,87 @@ | |
| 2880 | */ |
| 2881 | static int create_manifest_mini_fcards( Blob * pOut, |
| 2882 | CheckinMiniInfo * pCI, |
| 2883 | int asDelta, |
| 2884 | Blob * pErr){ |
| 2885 | int wroteThisCard = 0; |
| 2886 | const ManifestFile * pFile; |
| 2887 | int (*fncmp)(char const *, char const *) = /* filename comparator */ |
| 2888 | filenames_are_case_sensitive() |
| 2889 | ? fossil_strcmp |
| 2890 | : fossil_stricmp; |
| 2891 | #define mf_err(EXPR) if(pErr) blob_appendf EXPR; return 0 |
| 2892 | #define write_this_card(NAME) \ |
| 2893 | blob_appendf(pOut, "F %F %b%s\n", (NAME), &pCI->fileHash, \ |
| 2894 | mfile_permint_mstring(pCI->filePerm)); \ |
| 2895 | wroteThisCard = 1 |
| 2896 | |
| 2897 | assert(pCI->filePerm!=PERM_LNK && "This should have been validated before."); |
| 2898 | assert(pCI->filePerm==PERM_REG || pCI->filePerm==PERM_EXE); |
| 2899 | if(PERM_LNK==pCI->filePerm){ |
| 2900 | goto err_no_symlink; |
| 2901 | } |
| 2902 | manifest_file_rewind(pCI->pParent); |
| 2903 | if(asDelta!=0 && (pCI->pParent->zBaseline==0 |
| 2904 | || pCI->pParent->nFile==0)){ |
| 2905 | /* Parent is a baseline or a delta with no F-cards, so this is |
| 2906 | ** the simplest case: create a delta with a single F-card. |
| 2907 | */ |
| 2908 | pFile = manifest_file_find(pCI->pParent, pCI->zFilename); |
| 2909 | if(pFile!=0 && manifest_file_mperm(pFile)==PERM_LNK){ |
| 2910 | goto err_no_symlink; |
| 2911 | } |
| 2912 | write_this_card(pFile ? pFile->zName : pCI->zFilename); |
| 2913 | return 1; |
| 2914 | } |
| 2915 | while(1){ |
| 2916 | int cmp; |
| 2917 | if(asDelta==0){ |
| 2918 | pFile = manifest_file_next(pCI->pParent, 0); |
| 2919 | }else{ |
| 2920 | /* Parent is a delta manifest with F-cards. Traversal of delta |
| 2921 | ** manifest file entries is normally done via |
| 2922 | ** manifest_file_next(), which takes into account the |
| 2923 | ** differences between the delta and its parent and returns |
| 2924 | ** F-cards from both. Each successive delta from the same |
| 2925 | ** baseline includes all F-card changes from the previous |
| 2926 | ** deltas, so we instead clone the parent's F-cards except for |
| 2927 | ** the one (if any) which matches the new file. |
| 2928 | */ |
| 2929 | pFile = pCI->pParent->iFile < pCI->pParent->nFile |
| 2930 | ? &pCI->pParent->aFile[pCI->pParent->iFile++] |
| 2931 | : 0; |
| 2932 | } |
| 2933 | if(0==pFile) break; |
| 2934 | cmp = fncmp(pFile->zName, pCI->zFilename); |
| 2935 | if(cmp<0){ |
| 2936 | checkin_mini_append_fcard(pOut,pFile); |
| 2937 | }else{ |
| 2938 | if(cmp==0 || 0==wroteThisCard){ |
| 2939 | assert(0==wroteThisCard); |
| 2940 | if(PERM_LNK==manifest_file_mperm(pFile)){ |
| 2941 | goto err_no_symlink; |
| 2942 | } |
| 2943 | write_this_card(cmp==0 ? pFile->zName : pCI->zFilename); |
| 2944 | } |
| 2945 | if(cmp>0){ |
| 2946 | assert(wroteThisCard!=0); |
| 2947 | checkin_mini_append_fcard(pOut,pFile); |
| 2948 | } |
| 2949 | } |
| 2950 | } |
| 2951 | if(wroteThisCard==0){ |
| 2952 | write_this_card(pCI->zFilename); |
| 2953 | } |
| 2954 | return 1; |
| 2955 | err_no_symlink: |
| 2956 | mf_err((pErr,"Cannot commit or overwrite symlinks " |
| 2957 | "via mini-checkin.")); |
| 2958 | return 0; |
| 2959 | #undef write_this_card |
| 2960 | #undef mf_err |
| 2961 | } |
| 2962 | |
| 2963 | /* |
| 2964 | ** Creates a manifest file, written to pOut, from the state in the |
| 2965 | ** fully-populated and semantically valid pCI argument. pCI is not |
| 2966 | ** *semantically* modified but cannot be const because blob_str() may |
| @@ -3063,12 +2999,12 @@ | |
| 2999 | |
| 3000 | if((CIMINI_PREFER_DELTA & pCI->flags) |
| 3001 | && ((CIMINI_STRONGLY_PREFER_DELTA & pCI->flags) |
| 3002 | || (pCI->pParent->pBaseline |
| 3003 | ? pCI->pParent->pBaseline |
| 3004 | : pCI->pParent)->nFile > 15 |
| 3005 | /* 15 is arbitrary: don't create a delta when there is only a |
| 3006 | ** tiny gain for doing so. */) |
| 3007 | && !db_get_boolean("forbid-delta-manifests",0) |
| 3008 | ){ |
| 3009 | asDelta = 1; |
| 3010 | blob_appendf(pOut, "B %s\n", |
| @@ -3080,11 +3016,11 @@ | |
| 3016 | blob_appendf(pOut, "C %F\n", blob_str(&pCI->comment)); |
| 3017 | }else{ |
| 3018 | blob_append(pOut, "C (no\\scomment)\n", 16); |
| 3019 | } |
| 3020 | blob_appendf(pOut, "D %z\n", pCI->zDate); |
| 3021 | if(create_manifest_mini_fcards(pOut,pCI,asDelta,pErr)==0){ |
| 3022 | return 0; |
| 3023 | } |
| 3024 | if(pCI->zMimetype!=0 && pCI->zMimetype[0]!=0){ |
| 3025 | blob_appendf(pOut, "N %F\n", pCI->zMimetype); |
| 3026 | } |
| 3027 |