Dear Richard, All, Finally, I've found a bit of time to implement the first draft of the ranges functionality I was posting a couple of months ago (http://www.mail-archive.com/fossil-users@lists.fossil-scm.org/msg07419.html).
This is my first contribution to the project so apologize if anything is not that clean and tidy as it should be. >From a user point of view the patch changes the way users can do commits. First 'fossil changes' lists changes with additional column indicating the row number, e.g.: 1 EDITED src/checkin.c 2 EDITED src/main.mk 3 EDITED src/makemake.tcl 4 ADDED src/ranges.c 5 EDITED win/Makefile.dmc 6 EDITED win/Makefile.mingw 7 EDITED win/Makefile.msc Then using 'fossil commit --range|-r RANGE_LIST' the user can easily pick only these files they want to check-in, e.g. 'fossil commit -r 1,3-4 -m "added an extension to..."' is equivalent to 'fossil commit -m "added an extension to..." src/checkin.c src/makemake.tcl src/ranges.c' Internally, 'fossil changes' creates a "temporary" table in _FOSSIL_ where it stores row numbers, vfile.id and pathname. This is enough to restore the proper file ids during 'fossil commit -r ...' and also detect some circumstances which prevent from "safe" commit using ranges. For example, if after above 'fossil changes' the user issues 'fossil rm src/main.mk' and then 'fossil commit -r 2', the code will complain and guide the user to refresh the changes list. I'd be glad if anyone can have a look on this and exercise the code to see if the approach is reasonable. If you like it, the next target might be 'fossil rm' and then 'fossil extra' and 'fossil add'. P.S. After patching the code please issue 'tclsh makemake.tcl' in the 'src' directory to regenerate src/main.mk and win makefiles. Cheers, Jacek
ranges.patch
Description: Binary data
#include "config.h" #include "ranges.h" #include <errno.h> /* ** ** */ static int parse_file_range_token(const char* rangeString, int* range, int startIndex) { char* endptr; errno = 0; range[startIndex] = strtol(rangeString, &endptr, 10); if (errno != 0 || range[startIndex] <= 0) { fossil_fatal("error parsing ranges"); } else if (*endptr == '-') { char* upper = endptr; range[startIndex + 1] = strtol(upper, &endptr, 10); if (errno != 0 || *endptr != '\0' || range[startIndex + 1] == 0) { fossil_fatal("error parsing ranges"); } return 2; } else if (*endptr != '\0') { fossil_fatal("error parsing ranges"); } return 1; } /* ** Parses a string into an array of integers denoting value ranges. ** The acceptable input string is in form: \d+((-\d+)?(,\d+)?)* ** For example: '1', '1,2', '1-5,7', '1-3,20-25,9' are all acceptable. ** ** The returned array is zero-terminated and allocated on the heap. ** Negative values indicate an upper bound of a range and must be preceded by ** a positive value -- the lower bound. ** ** For the above examples the function will return following arrays: ** [1], [1, 2], [1, -5, 7], [1, -3, 20, -25, 9] ** */ int* parse_file_range(const char* rangeString) { /* An arbitraty initial value; must be larger than 2. */ int reallocLimit = 20; char *comma; int *range = fossil_malloc(sizeof(int) * reallocLimit); int n = 0; while ((comma = strchr(rangeString, ',')) != NULL) { *comma = 0; n += parse_file_range_token(rangeString, range, n); *comma = ','; rangeString = comma + 1; if (n >= reallocLimit - 2) { reallocLimit *= 2; range = realloc(range, sizeof(int) * reallocLimit); } } n += parse_file_range_token(rangeString, range, n); range[n] = 0; return range; } /* ** This is a helper function that prints contents of an integer range on ** standard output. ** */ void print_file_range(int* range) { int i = 0; printf("Range: "); while (range[i] != 0) { printf("%d ", range[i++]); } printf("\n"); }
_______________________________________________ fossil-users mailing list fossil-users@lists.fossil-scm.org http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users