commit - 8c25a0e66cb5f6ea96b120f8e80703e83a6ce85e
commit + 02a9e99535e18f69e38c094b381dbd90621a2783
blob - 4e9891df54e61ef79c78c24c78c772e6664da73a
blob + 145bd98f76a62eda56e68cde432493c01e1f315d
--- got/got.c
+++ got/got.c
if (error)
goto done;
- if (author == NULL)
+ if (author == NULL) {
+ /* got_worktree_commit() treats committer as the optional one */
author = committer;
+ committer = NULL; /* => author timestamp is ignored */
+ }
if (logmsg == NULL || strlen(logmsg) == 0) {
error = get_editor(&editor);
cl_arg.branch_name += 11;
}
cl_arg.repo_path = got_repo_get_path(repo);
- error = got_worktree_commit(&id, worktree, &paths, author, committer,
- allow_bad_symlinks, show_diff, commit_conflicts,
+ error = got_worktree_commit(&id, worktree, &paths, author, time(NULL),
+ committer, allow_bad_symlinks, show_diff, commit_conflicts,
collect_commit_logmsg, &cl_arg, print_status, NULL, repo);
if (error) {
if (error->code != GOT_ERR_COMMIT_MSG_EMPTY &&
goto done;
} else {
error = got_worktree_merge_commit(&merge_commit_id, worktree,
- fileindex, author, NULL, 1, branch_tip, branch_name,
+ fileindex, author, 0, NULL, 1, branch_tip, branch_name,
allow_conflict, repo, continue_merge ? print_status : NULL,
NULL);
if (error)
blob - 83894a63327d718f09bcb4236d42ccb4c872da6b
blob + 02eac9d035f16856319eb37dc346588302cb7a2e
--- include/got_worktree.h
+++ include/got_worktree.h
* 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_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 *, struct got_repository *);
const struct got_error *
got_worktree_merge_commit(struct got_object_id **new_commit_id,
struct got_worktree *worktree, struct got_fileindex *fileindex,
- const char *author, const char *committer, int allow_bad_symlinks,
- struct got_object_id *branch_tip, const char *branch_name,
- int allow_conflict, struct got_repository *repo,
+ const char *author, time_t author_time, const char *committer,
+ int allow_bad_symlinks, struct got_object_id *branch_tip,
+ const char *branch_name, int allow_conflict, struct got_repository *repo,
got_worktree_status_cb status_cb, void *status_arg);
/*
blob - d089bc9ca0d1abc94a4a52d9c1aaa70f7b02ef28
blob + ec38218e360c5bf4089f0760557e463daffa3a38
--- lib/worktree.c
+++ lib/worktree.c
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)
{
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)
const struct got_error *
got_worktree_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,
struct got_repository *repo)
}
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)
/* NB: commit_worktree will call free(logmsg) */
err = commit_worktree(new_commit_id, &commitable_paths, head_commit_id,
NULL, worktree, got_object_commit_get_author(orig_commit),
+ got_object_commit_get_author_time(orig_commit),
committer ? committer :
got_object_commit_get_committer(orig_commit), NULL,
collect_rebase_commit_msg, logmsg, rebase_status, NULL, repo);
const struct got_error *
got_worktree_merge_commit(struct got_object_id **new_commit_id,
struct got_worktree *worktree, struct got_fileindex *fileindex,
- const char *author, const char *committer, int allow_bad_symlinks,
- struct got_object_id *branch_tip, const char *branch_name,
- int allow_conflict, struct got_repository *repo,
+ const char *author, time_t author_time, const char *committer,
+ int allow_bad_symlinks, struct got_object_id *branch_tip,
+ const char *branch_name, int allow_conflict, struct got_repository *repo,
got_worktree_status_cb status_cb, void *status_arg)
-
{
const struct got_error *err = NULL, *sync_err;
struct got_pathlist_head commitable_paths;
mcm_arg.worktree = worktree;
mcm_arg.branch_name = branch_name;
err = commit_worktree(new_commit_id, &commitable_paths,
- head_commit_id, branch_tip, worktree, author, committer, NULL,
- merge_commit_msg_cb, &mcm_arg, status_cb, status_arg, repo);
+ head_commit_id, branch_tip, worktree, author, author_time,
+ committer, NULL, merge_commit_msg_cb, &mcm_arg, status_cb,
+ status_arg, repo);
if (err)
goto done;
blob - 84c24828bea9475f7b0841d4f7fe0ffec5264646
blob + 98d40ea3754215fd3024137b6c6a860b8d17eca8
--- regress/cmdline/rebase.sh
+++ regress/cmdline/rebase.sh
test_done "$testroot" "$ret"
}
+test_rebase_preserves_author_data() {
+ local testroot=`test_init rebase_preserves_author_data`
+
+ git -C $testroot/repo checkout -q -b newbranch
+ echo "modified delta on branch" > $testroot/repo/gamma/delta
+ TZ=EST git_commit $testroot/repo -m "modified delta on newbranch"
+
+ sleep 1 # get a new timestamp
+ echo "modified alpha on branch" > $testroot/repo/alpha
+ TZ=CET git_commit $testroot/repo -m "modified alpha on newbranch"
+
+ local orig_commit1=`git_show_parent_commit $testroot/repo`
+ local orig_commit2=`git_show_head $testroot/repo`
+
+ (cd $testroot/repo && got cat $orig_commit1 $orig_commit2 | \
+ grep '^author ' > $testroot/author_data.expected)
+
+ git -C $testroot/repo checkout -q master
+ echo "modified zeta on master" > $testroot/repo/epsilon/zeta
+ git_commit $testroot/repo -m "committing to zeta on master"
+ local master_commit=`git_show_head $testroot/repo`
+
+ got checkout $testroot/repo $testroot/wt > /dev/null
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ sleep 1 # get a new timestamp
+ (cd $testroot/wt && got rebase newbranch > /dev/null \
+ 2> $testroot/stderr)
+
+ git -C $testroot/repo checkout -q newbranch
+ local new_commit1=`git_show_parent_commit $testroot/repo`
+ local new_commit2=`git_show_head $testroot/repo`
+
+ echo -n > $testroot/stderr.expected
+ cmp -s $testroot/stderr.expected $testroot/stderr
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/stderr.expected $testroot/stderr
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/wt && got cat $new_commit1 $new_commit2 | \
+ grep '^author ' > $testroot/author_data)
+ # note: got deliberately clobbers the timezone to UTC, so expect that
+ ed -s $testroot/author_data.expected <<-EOF
+ ,s/ [+-][0-9]\{4\}\$/ +0000/
+ w
+ EOF
+ cmp -s $testroot/author_data.expected $testroot/author_data
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/author_data.expected $testroot/author_data
+ fi
+
+ test_done "$testroot" "$ret"
+}
+
test_rebase_no_commits_to_rebase() {
local testroot=`test_init rebase_no_commits_to_rebase`
run_test test_rebase_in_progress
run_test test_rebase_path_prefix
run_test test_rebase_preserves_logmsg
+run_test test_rebase_preserves_author_data
run_test test_rebase_no_commits_to_rebase
run_test test_rebase_forward
run_test test_rebase_forward_path_prefix