From: "Sven M. Hallberg" Subject: Re: [patch] preserve and show author dates To: gameoftrees@openbsd.org Date: Sat, 03 Aug 2024 22:29:02 +0200 Sven M. Hallberg on Thu, Aug 01 2024: > I have also not touched cvg or added any tests at this point. Here it is for cvg, pretty much identical to the got code, minus rebase. BTW, is there a conscious reason for got and cvg to have so much code in common or is it just a case of "to be refactored"? -p diff refs/heads/authortime refs/heads/authortime-cvg commit - 49b650bb078a73e7a05703caa4e47cdae61ae1fe commit + 9a2e7ad4870891a7244450ed93be14d82bbd104b blob - f2dbcb38ea508b565dbea5ebfbccbf5530868b1c blob + 88997c4dc6287b86ef27dd022bbeadf189573cb0 --- cvg/cvg.c +++ cvg/cvg.c @@ -3345,7 +3345,7 @@ done: } static char * -get_datestr(time_t *time, char *datebuf) +get_datestr(const time_t *time, char *datebuf) { struct tm mytm, *tm; char *p, *s; @@ -3633,6 +3633,18 @@ printfile(FILE *f) return NULL; } +/* print a date line unless an error occurs (or fail silently) */ +static void +print_date(const char *prefix, const time_t *t) +{ + char datebuf[26]; + char *datestr; + + datestr = get_datestr(t, datebuf); + if (datestr) + printf("%s %s UTC\n", prefix, datestr); +} + static const struct got_error * print_commit(struct got_commit_object *commit, struct got_object_id *id, struct got_repository *repo, const char *path, @@ -3643,9 +3655,8 @@ print_commit(struct got_commit_object *commit, struct { const struct got_error *err = NULL; FILE *f = NULL; - char *id_str, *datestr, *logmsg0, *logmsg, *line; - char datebuf[26]; - time_t committer_time; + char *id_str, *logmsg0, *logmsg, *line; + time_t author_time, committer_time; const char *author, *committer; char *refs_str = NULL; @@ -3675,15 +3686,20 @@ print_commit(struct got_commit_object *commit, struct id_str = NULL; free(refs_str); refs_str = NULL; - printf("from: %s\n", got_object_commit_get_author(commit)); + + /* author and committer data */ author = got_object_commit_get_author(commit); + author_time = got_object_commit_get_author_time(commit); committer = got_object_commit_get_committer(commit); + committer_time = got_object_commit_get_committer_time(commit); + printf("from: %s\n", got_object_commit_get_author(commit)); if (strcmp(author, committer) != 0) printf("via: %s\n", committer); - committer_time = got_object_commit_get_committer_time(commit); - datestr = get_datestr(&committer_time, datebuf); - if (datestr) - printf("date: %s UTC\n", datestr); + print_date("date:", &committer_time); + if (author_time != committer_time) + print_date("orig:", &author_time); + + /* parent commits */ if (got_object_commit_get_nparents(commit) > 1) { const struct got_object_id_queue *parent_ids; struct got_object_qid *qid; @@ -7909,8 +7925,11 @@ cmd_commit(int argc, char *argv[]) if (error) goto done; - if (author == NULL) + if (author == NULL) { + /* got_worktree_cvg_commit() treats committer as optional */ author = committer; + committer = NULL; /* => author timestamp is ignored */ + } remote_name = GOT_SEND_DEFAULT_REMOTE_NAME; worktree_conf = got_worktree_get_gotconfig(worktree); @@ -8023,9 +8042,10 @@ cmd_commit(int argc, char *argv[]) cl_arg.repo_path = got_repo_get_path(repo); cl_arg.dial_proto = proto; error = got_worktree_cvg_commit(&id, worktree, &paths, author, - committer, allow_bad_symlinks, show_diff, commit_conflicts, - collect_commit_logmsg, &cl_arg, print_status, NULL, proto, host, - port, server_path, verbosity, remote, check_cancelled, repo); + time(NULL), committer, allow_bad_symlinks, show_diff, + commit_conflicts, collect_commit_logmsg, &cl_arg, print_status, + NULL, proto, host, port, server_path, verbosity, remote, + check_cancelled, repo); if (error) { if (error->code != GOT_ERR_COMMIT_MSG_EMPTY && cl_arg.logmsg_path != NULL) blob - 5607eff4903ac486cf8766910d0e6ea7a47f928a blob + 0ea849834dcb2c8bdb84b998209dc58648b302d7 --- include/got_worktree_cvg.h +++ include/got_worktree_cvg.h @@ -23,12 +23,14 @@ * current base commit. * An author and a non-empty log message must be specified. * The name of the committer is optional (may be NULL). + * If a committer is given, a separate author timestamp can be specified + * which is ignored otherwise. * If a path to be committed contains a symlink which points outside * of the path space under version control, raise an error unless * committing of such paths is being forced by the caller. */ const struct got_error *got_worktree_cvg_commit(struct got_object_id **, - struct got_worktree *, struct got_pathlist_head *, const char *, + struct got_worktree *, struct got_pathlist_head *, const char *, time_t, const char *, int, int, int, got_worktree_commit_msg_cb, void *, got_worktree_status_cb, void *, const char *, const char *, const char *, const char *, int, const struct got_remote_repo *, got_cancel_cb, blob - da97321077d9a4c57c2b10105cd568a1bc9c944e blob + ba550d94227fc2d310d5e48355462f0c1ee487b3 --- lib/worktree_cvg.c +++ lib/worktree_cvg.c @@ -2229,8 +2229,8 @@ commit_worktree(struct got_object_id **new_commit_id, struct got_object_id *head_commit_id, struct got_object_id *parent_id2, struct got_worktree *worktree, - const char *author, const char *committer, char *diff_path, - got_worktree_commit_msg_cb commit_msg_cb, void *commit_arg, + const char *author, time_t author_time, const char *committer, + char *diff_path, got_worktree_commit_msg_cb commit_msg_cb, void *commit_arg, got_worktree_status_cb status_cb, void *status_arg, struct got_repository *repo) { @@ -2315,8 +2315,10 @@ commit_worktree(struct got_object_id **new_commit_id, nparents++; } timestamp = time(NULL); + if (committer == NULL) + author_time = timestamp; err = got_object_commit_create(new_commit_id, new_tree_id, &parent_ids, - nparents, author, timestamp, committer, timestamp, logmsg, repo); + nparents, author, author_time, committer, timestamp, logmsg, repo); if (logmsg != NULL) free(logmsg); if (err) @@ -2904,8 +2906,8 @@ done: const struct got_error * got_worktree_cvg_commit(struct got_object_id **new_commit_id, struct got_worktree *worktree, struct got_pathlist_head *paths, - const char *author, const char *committer, int allow_bad_symlinks, - int show_diff, int commit_conflicts, + const char *author, time_t author_time, const char *committer, + int allow_bad_symlinks, int show_diff, int commit_conflicts, got_worktree_commit_msg_cb commit_msg_cb, void *commit_arg, got_worktree_status_cb status_cb, void *status_arg, const char *proto, const char *host, const char *port, @@ -3046,7 +3048,7 @@ got_worktree_cvg_commit(struct got_object_id **new_com } err = commit_worktree(new_commit_id, &commitable_paths, - head_commit_id, NULL, worktree, author, committer, + head_commit_id, NULL, worktree, author, author_time, committer, (diff_path && cc_arg.diff_header_shown) ? diff_path : NULL, commit_msg_cb, commit_arg, status_cb, status_arg, repo); if (err)