AmendHub

Download:

jcs

/

amend

/

amendments

/

64

committer: Update file metadata on commit even if no text changes

When diffing each file, if there is no text change but a
size/mtime/ctime change that caused us to examine the file to begin
with, we should save that new data on commit so we don't have to
examine it again on the next commit.

jcs made amendment 64 over 2 years ago
--- committer.c Thu Feb 3 16:38:11 2022 +++ committer.c Sat Apr 16 13:30:03 2022 @@ -356,7 +356,7 @@ committer_update_menu(struct committer *committer) EnableItem(edit_menu, EDIT_MENU_PASTE_ID); } - if ((*(committer->log_te))->nLines > 0 && committer->ndiffed_files) + if ((*(committer->log_te))->nLines > 0 && committer->allow_commit) HiliteControl(committer->commit_button, 0); else HiliteControl(committer->commit_button, 255); @@ -380,6 +380,7 @@ committer_generate_diff(struct committer *committer) short i, all_files; short *selected_files = NULL; short nselected_files = 0; + short diff_text = 0; TextStyle style; SetCursor(*(GetCursor(watchCursor))); @@ -394,7 +395,9 @@ committer_generate_diff(struct committer *committer) committer->diff_adds = 0; committer->diff_subs = 0; committer->ndiffed_files = 0; - committer->diffed_files = xmalloc(sizeof(short) * nselected_files); + committer->allow_commit = 0; + committer->diffed_files = xmalloc(sizeof(struct diffed_file) * + nselected_files); cur_committer = committer; committer->diff_too_big = 0; @@ -406,23 +409,33 @@ committer_generate_diff(struct committer *committer) TESetStyle(doFont | doSize, &style, false, cur_committer->diff_te); all_files = browser_is_all_files_selected(committer->browser); - + for (i = 0; i < nselected_files; i++) { file = repo_file_with_id(committer->browser->repo, selected_files[i]); if (file == NULL) - err(1, "Failed to find file with id %d", selected_files[i]); + err(1, "Failed to find file in repo with id %d", + selected_files[i]); - if (!all_files || - repo_file_changed(committer->browser->repo, file)) { - progress("Diffing %s...", file->filename); - if (repo_diff_file(committer->browser->repo, file)) - committer->diffed_files[committer->ndiffed_files++] = - file->id; - diff_finish(); - } else{ + if (all_files && !repo_file_changed(committer->browser->repo, + file)) { progress("Skipping unchanged %s...", file->filename); + continue; } + + committer->diffed_files[committer->ndiffed_files].file = file; + committer->diffed_files[committer->ndiffed_files].flags = + DIFFED_FILE_METADATA; + + progress("Diffing %s...", file->filename); + if (repo_diff_file(committer->browser->repo, file)) { + committer->diffed_files[committer->ndiffed_files].flags |= + DIFFED_FILE_TEXT; + committer->allow_commit = 1; + } + + diff_finish(); + committer->ndiffed_files++; } HUnlock(committer->diff_te); @@ -438,7 +451,7 @@ done_diffing: free(selected_files); SetCursor(&arrow); - if (committer->ndiffed_files == 0) { + if (committer->allow_commit == 0) { warnx("No changes detected"); browser_close_committer(committer->browser); } --- committer.h Mon Oct 18 15:49:37 2021 +++ committer.h Sat Apr 16 13:08:55 2022 @@ -31,7 +31,8 @@ struct committer { ControlHandle diff_scroller; ControlHandle commit_button; short ndiffed_files; - short *diffed_files; + struct diffed_file *diffed_files; + short allow_commit; short diff_adds; short diff_subs; short diff_too_big; --- repo.c Thu Feb 3 17:40:39 2022 +++ repo.c Sat Apr 16 13:40:12 2022 @@ -92,7 +92,7 @@ repo_create(void) REPO_TYPE); } if (bile == NULL) - err(1, "Failed to create %s: %d", PtoCstr(reply.fName), error); + panic("Failed to create %s: %d", PtoCstr(reply.fName), error); return repo_init(bile, 1); } @@ -129,7 +129,7 @@ repo_init(struct bile *bile, short is_new) panic("no %ld file, but count said it should be there", i); size = bile_read_alloc(bile, REPO_FILE_RTYPE, bob->id, &data); if (size == 0) - err(1, "failed fetching file %ld", bob->id); + panic("failed fetching file %ld", bob->id); repo->files[i] = repo_parse_file(bob->id, (unsigned char *)data, size); if (repo->files[i]->id >= repo->next_file_id) @@ -151,7 +151,7 @@ repo_init(struct bile *bile, short is_new) size = bile_read_alloc(bile, REPO_COMMIT_RTYPE, bob->id, &data); if (size == 0) - err(1, "failed fetching commit %ld", bob->id); + panic("failed fetching commit %ld", bob->id); repo->commits[i] = repo_parse_commit(bob->id, (unsigned char *)data, size); if (repo->commits[i]->id >= repo->next_commit_id) @@ -243,7 +243,7 @@ repo_parse_file(unsigned long id, unsigned char *data, datapos += 1; if (datapos != size) - err(1, "repo_parse_file object size %lu, data position %d", size, + panic("repo_parse_file object size %lu, data position %d", size, datapos); return file; @@ -381,7 +381,7 @@ repo_show_diff_text(struct repo *repo, struct repo_com diff_len = bob->size; if (diff_len == 0) - err(1, "diff zero bytes"); + panic("diff zero bytes"); header_len = repo_diff_header(repo, commit, &buf); @@ -587,7 +587,7 @@ repo_file_update(struct repo *repo, struct repo_file * datapos += 1; if (datapos != len) - err(1, "repo_file_update: datapos %lu, expected %d", datapos, len); + panic("repo_file_update: datapos %lu, expected %d", datapos, len); size = bile_write(repo->bile, REPO_FILE_RTYPE, file->id, data, datapos); if (size != datapos) @@ -652,7 +652,7 @@ repo_checkout_file(struct repo *repo, struct repo_file error = FSOpen(filename, vrefnum, &frefnum); if (error) - err(1, "Failed to open file %s: %d", PtoCstr(filename), error); + panic("Failed to open file %s: %d", PtoCstr(filename), error); error = SetEOF(frefnum, 0); if (error) @@ -731,16 +731,16 @@ repo_diff_file(struct repo *repo, struct repo_file *fi error = Create(fromfilename, repo->bile->vrefnum, file->creator, file->type); if (error && error != dupFNErr) - err(1, "Failed to create file %s: %d", PtoCstr(fromfilename), + panic("Failed to create file %s: %d", PtoCstr(fromfilename), error); error = FSOpen(fromfilename, repo->bile->vrefnum, &frefnum); if (error) - err(1, "Failed to open file %s: %d", PtoCstr(fromfilename), error); + panic("Failed to open file %s: %d", PtoCstr(fromfilename), error); error = SetEOF(frefnum, 0); if (error) - err(1, "Failed to truncate file %s: %d", PtoCstr(fromfilename), + panic("Failed to truncate file %s: %d", PtoCstr(fromfilename), error); if (file->flags & REPO_FILE_DELETED) { @@ -753,7 +753,7 @@ repo_diff_file(struct repo *repo, struct repo_file *fi if (size > 0) { error = FSWrite(frefnum, &size, text); if (error) - err(1, "Failed to write old file to %s: %d", + panic("Failed to write old file to %s: %d", PtoCstr(fromfilename), error); free(text); } @@ -777,13 +777,13 @@ repo_diff_file(struct repo *repo, struct repo_file *fi error = Create(tofilename, repo->bile->vrefnum, file->creator, file->type); if (error && error != dupFNErr) - err(1, "Failed to create file %s: %d", PtoCstr(tofilename), + panic("Failed to create file %s: %d", PtoCstr(tofilename), error); getpath(repo->bile->vrefnum, tofilename, &tofilepath, true); tofile_empty = 1; } else if (error) - err(1, "Failed to get info for %s", PtoCstr(tofilename)); + panic("Failed to get info for %s", PtoCstr(tofilename)); /* specify diff header labels to avoid printing tmp filename */ /* (TODO: use paths relative to repo) */ @@ -805,13 +805,13 @@ repo_diff_file(struct repo *repo, struct repo_file *fi /* delete temp file */ error = FSDelete(fromfilename, repo->bile->vrefnum); if (error) - err(1, "Failed to delete temp file %s: %d", PtoCstr(fromfilename), + panic("Failed to delete temp file %s: %d", PtoCstr(fromfilename), error); if (tofile_empty) { error = FSDelete(tofilename, repo->bile->vrefnum); if (error) - err(1, "Failed to delete temp file %s: %d", + panic("Failed to delete temp file %s: %d", PtoCstr(tofilename), error); } @@ -870,7 +870,7 @@ repo_export_patch(struct repo *repo, struct repo_commi bob = bile_find(repo->bile, REPO_DIFF_RTYPE, commit->id); if (bob == NULL) - err(1, "failed finding DIFF %d", commit->id); + panic("failed finding DIFF %d", commit->id); /* * Don't use our creator here because we don't want finder opening us @@ -885,17 +885,17 @@ repo_export_patch(struct repo *repo, struct repo_commi error = FSOpen(filename, vrefnum, &frefnum); if (error) - err(1, "Failed to open file %s: %d", PtoCstr(filename), error); + panic("Failed to open file %s: %d", PtoCstr(filename), error); error = SetEOF(frefnum, 0); if (error) - err(1, "Failed to truncate file %s: %d", PtoCstr(filename), + panic("Failed to truncate file %s: %d", PtoCstr(filename), error); size = repo_diff_header(repo, commit, &buf); error = FSWrite(frefnum, &size, buf); if (error) - err(1, "Failed to write diff header to %s: %d", PtoCstr(filename), + panic("Failed to write diff header to %s: %d", PtoCstr(filename), error); free(buf); @@ -903,7 +903,7 @@ repo_export_patch(struct repo *repo, struct repo_commi size = bile_read_object(repo->bile, bob, buf, bob->size); error = FSWrite(frefnum, &size, buf); if (error) - err(1, "Failed to write diff to %s: %d", PtoCstr(filename), error); + panic("Failed to write diff to %s: %d", PtoCstr(filename), error); free(buf); free(bob); @@ -911,19 +911,18 @@ repo_export_patch(struct repo *repo, struct repo_commi } void -repo_commit(struct repo *repo, short *files, short nfiles, short adds, - short subs, char *author, Handle log, short loglen, Handle diff, - unsigned long difflen) +repo_commit(struct repo *repo, struct diffed_file *diffed_files, + short nfiles, short adds, short subs, char *author, Handle log, + short loglen, Handle diff, unsigned long difflen) { Str255 tfilename; - struct repo_file *file; unsigned char *commit, *tdata, *fdata; FInfo finfo; size_t size; short commit_len, pos = 0, len; + short i, commit_id, id, error, frefnum, actual_nfiles; time_t date; long fsize; - short i, commit_id, id, error, frefnum; /* date (long) */ commit_len = sizeof(long); @@ -931,8 +930,17 @@ repo_commit(struct repo *repo, short *files, short nfi /* author (pstr) */ commit_len += 1 + strlen(author); + /* find files with actual data changes */ + actual_nfiles = 0; + for (i = 0; i < nfiles; i++) { + if (diffed_files[i].flags & DIFFED_FILE_TEXT) + actual_nfiles++; + } + if (actual_nfiles == 0) + panic("repo_commit passed nfiles %d but actual files is 0", nfiles); + /* nfiles (short) */ - commit_len += sizeof(short) + (nfiles * sizeof(short)); + commit_len += sizeof(short) + (actual_nfiles * sizeof(short)); /* adds (short) */ commit_len += sizeof(short); @@ -955,11 +963,14 @@ repo_commit(struct repo *repo, short *files, short nfi for (i = 0; i < strlen(author); i++) commit[pos++] = author[i]; - commit[pos++] = (nfiles >> 8) & 0xff; - commit[pos++] = nfiles & 0xff; + commit[pos++] = (actual_nfiles >> 8) & 0xff; + commit[pos++] = actual_nfiles & 0xff; for (i = 0; i < nfiles; i++) { - commit[pos++] = (files[i] >> 8) & 0xff; - commit[pos++] = files[i] & 0xff; + if (!(diffed_files[i].flags & DIFFED_FILE_TEXT)) + continue; + + commit[pos++] = (diffed_files[i].file->id >> 8) & 0xff; + commit[pos++] = diffed_files[i].file->id & 0xff; } commit[pos++] = (adds >> 8) & 0xff; @@ -976,7 +987,7 @@ repo_commit(struct repo *repo, short *files, short nfi HUnlock(log); if (pos != commit_len) - err(1, "repo_commit: accumulated len %d != expected %d", pos, + panic("repo_commit: accumulated len %d != expected %d", pos, commit_len); commit_id = repo->next_commit_id; @@ -1000,46 +1011,47 @@ repo_commit(struct repo *repo, short *files, short nfi /* store new versions of each file */ for (i = 0; i < nfiles; i++) { - file = repo_file_with_id(repo, files[i]); - if (file == NULL) - panic("Bogus file %d in commit", files[i]); + if (diffed_files[i].flags & DIFFED_FILE_TEXT) { + strlcpy((char *)tfilename, diffed_files[i].file->filename, + sizeof(tfilename)); + CtoPstr(tfilename); - strlcpy((char *)tfilename, file->filename, sizeof(tfilename)); - CtoPstr(tfilename); - - /* update file contents if file wasn't deleted */ - error = GetFInfo(tfilename, repo->bile->vrefnum, &finfo); - if (error && error != fnfErr) - panic("Error getting file info for %s", PtoCstr(tfilename)); + /* update file contents if file wasn't deleted */ + error = GetFInfo(tfilename, repo->bile->vrefnum, &finfo); + if (error && error != fnfErr) + panic("Error getting file info for %s", + PtoCstr(tfilename)); - if (error != fnfErr) { - error = FSOpen(tfilename, repo->bile->vrefnum, &frefnum); - if (error) - panic("Failed to open file %s: %d", PtoCstr(tfilename), - error); - - error = GetEOF(frefnum, &fsize); - if (error) - panic("Failed to get size of file %s: %d", - PtoCstr(tfilename), error); - - tdata = xmalloc(fsize); - error = FSRead(frefnum, &fsize, tdata); - if (error) - panic("Failed to read %ul of file %s: %d", fsize, - PtoCstr(tfilename), error); - - FSClose(frefnum); - - size = bile_write(repo->bile, REPO_TEXT_RTYPE, files[i], tdata, - fsize); - if (size != fsize) - panic("Failed to write new text file at %s: %d", - PtoCstr(tfilename), bile_error(repo->bile)); - free(tdata); + if (error != fnfErr) { + error = FSOpen(tfilename, repo->bile->vrefnum, &frefnum); + if (error) + panic("Failed to open file %s: %d", PtoCstr(tfilename), + error); + + error = GetEOF(frefnum, &fsize); + if (error) + panic("Failed to get size of file %s: %d", + PtoCstr(tfilename), error); + + tdata = xmalloc(fsize); + error = FSRead(frefnum, &fsize, tdata); + if (error) + panic("Failed to read %ul of file %s: %d", fsize, + PtoCstr(tfilename), error); + + FSClose(frefnum); + + size = bile_write(repo->bile, REPO_TEXT_RTYPE, + diffed_files[i].file->id, tdata, fsize); + if (size != fsize) + panic("Failed to write new text file at %s: %d", + PtoCstr(tfilename), bile_error(repo->bile)); + free(tdata); + } } - repo_file_update(repo, file); + if (diffed_files[i].flags & DIFFED_FILE_METADATA) + repo_file_update(repo, diffed_files[i].file); } /* flush volume */ @@ -1114,7 +1126,7 @@ repo_migrate(struct repo *repo, short is_new) for (i = 0; i < ntmpls; i++) { h = GetIndResource('TMPL', i + 1); if (h == NULL) - err(1, "Failed fetching TMPL %d", i + 1); + panic("Failed fetching TMPL %d", i + 1); GetResInfo(h, &id, &type, &tname); /* @@ -1154,7 +1166,7 @@ repo_backup(struct repo *repo) if (getpath(repo->bile->vrefnum, repo->bile->filename, &path, false) != 0) - err(1, "Failed resolving path of open repo"); + panic("Failed resolving path of open repo"); PtoCstr(path); memcpy(repo_filename, repo->bile->filename, sizeof(repo_filename)); @@ -1168,5 +1180,5 @@ repo_backup(struct repo *repo) error = copy_file(source_filename, dest_filename, true); if (error) - err(1, "Failed backing up repo: %d", error); + panic("Failed backing up repo: %d", error); } --- repo.h Mon Jan 10 20:52:11 2022 +++ repo.h Sat Apr 16 13:31:24 2022 @@ -54,6 +54,13 @@ struct repo_file_attrs { unsigned long mtime; }; +struct diffed_file { + struct repo_file *file; + short flags; +#define DIFFED_FILE_TEXT (1 << 0) +#define DIFFED_FILE_METADATA (1 << 1) +}; + struct repo_commit { short id; time_t date; @@ -95,9 +102,9 @@ short repo_checkout_file(struct repo *repo, struct rep short vrefnum, Str255 filename); void repo_export_patch(struct repo *repo, struct repo_commit *commit, short vrefnum, Str255 filename); -void repo_commit(struct repo *repo, short *files, short nfiles, short adds, - short subs, char *author, Handle log, short loglen, Handle diff, - unsigned long difflen); +void repo_commit(struct repo *repo, struct diffed_file *diffed_files, + short nfiles, short adds, short subs, char *author, Handle log, + short loglen, Handle diff, unsigned long difflen); void repo_backup(struct repo *repo); #endif