commit - f990756a3987ba6410baf611d561e9b8f285f047
commit + 123836732402b1204e5be68f98a69084285c316d
blob - bb1825eecded3623bbabcf0541bce55367696327
blob + b6cc16e8e5a4b02bf33a4f2af21bc0fd0f58c4bd
--- got/got.1
+++ got/got.1
.Tg ci
.It Xo
.Cm commit
-.Op Fl NnS
+.Op Fl CNnS
.Op Fl A Ar author
.Op Fl F Ar path
.Op Fl m Ar message
environment variable, or
.Xr got.conf 5 ,
or Git configuration settings.
+.It Fl C
+Allow committing files in conflicted status.
+.Pp
+Committing files with conflict markers should generally be avoided.
+Cases where conflict markers must be stored in the repository for
+some legitimate reason should be very rare.
+There are usually ways to avoid storing conflict markers verbatim by
+applying appropriate programming tricks.
.It Fl F Ar path
Use the prepared log message stored in the file found at
.Ar path
.Tg rb
.It Xo
.Cm rebase
-.Op Fl aclX
+.Op Fl aCclX
.Op Ar branch
.Xc
.Dl Pq alias: Cm rb
.It Fl a
Abort an interrupted rebase operation.
If this option is used, no other command-line arguments are allowed.
+.It Fl C
+Allow a rebase operation to continue with files in conflicted status.
+This option should generally be avoided, and can only be used with the
+.Fl c
+option.
.It Fl c
Continue an interrupted rebase operation.
If this option is used, no other command-line arguments are allowed.
.Tg he
.It Xo
.Cm histedit
-.Op Fl acdeflmX
+.Op Fl aCcdeflmX
.Op Fl F Ar histedit-script
.Op Ar branch
.Xc
.It Fl a
Abort an interrupted histedit operation.
If this option is used, no other command-line arguments are allowed.
+.It Fl C
+Allow a histedit operation to continue with files in conflicted status.
+This option should generally be avoided, and can only be used with the
+.Fl c
+option.
.It Fl c
Continue an interrupted histedit operation.
If this option is used, no other command-line arguments are allowed.
.Tg mg
.It Xo
.Cm merge
-.Op Fl acn
+.Op Fl aCcn
.Op Ar branch
.Xc
.Dl Pq alias: Cm mg
.It Fl a
Abort an interrupted merge operation.
If this option is used, no other command-line arguments are allowed.
+.It Fl C
+Allow a merge operation to continue with files in conflicted status.
+This option should generally be avoided, and can only be used with the
+.Fl c
+option.
.It Fl c
Continue an interrupted merge operation.
If this option is used, no other command-line arguments are allowed.
blob - 97e8fcfb43b02a9fb38a2a41964a9a6249b31c2b
blob + 438e15cb2486d96840625d284c94c90018d7917b
--- got/got.c
+++ got/got.c
__dead static void
usage_commit(void)
{
- fprintf(stderr, "usage: %s commit [-NnS] [-A author] [-F path] "
+ fprintf(stderr, "usage: %s commit [-CNnS] [-A author] [-F path] "
"[-m message] [path ...]\n", getprogname());
exit(1);
}
char *gitconfig_path = NULL, *editor = NULL, *committer = NULL;
int ch, rebase_in_progress, histedit_in_progress, preserve_logmsg = 0;
int allow_bad_symlinks = 0, non_interactive = 0, merge_in_progress = 0;
- int show_diff = 1;
+ int show_diff = 1, commit_conflicts = 0;
struct got_pathlist_head paths;
struct got_reflist_head refs;
struct got_reflist_entry *re;
err(1, "pledge");
#endif
- while ((ch = getopt(argc, argv, "A:F:m:NnS")) != -1) {
+ while ((ch = getopt(argc, argv, "A:CF:m:NnS")) != -1) {
switch (ch) {
case 'A':
author = optarg;
if (error)
return error;
break;
+ case 'C':
+ commit_conflicts = 1;
+ break;
case 'F':
if (logmsg != NULL)
option_conflict('F', 'm');
}
cl_arg.repo_path = got_repo_get_path(repo);
error = got_worktree_commit(&id, worktree, &paths, author, committer,
- allow_bad_symlinks, show_diff, collect_commit_logmsg, &cl_arg,
- print_status, NULL, repo);
+ 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 &&
cl_arg.logmsg_path != NULL)
__dead static void
usage_rebase(void)
{
- fprintf(stderr, "usage: %s rebase [-aclX] [branch]\n", getprogname());
+ fprintf(stderr, "usage: %s rebase [-aCclX] [branch]\n", getprogname());
exit(1);
}
rebase_commit(struct got_pathlist_head *merged_paths,
struct got_worktree *worktree, struct got_fileindex *fileindex,
struct got_reference *tmp_branch, const char *committer,
- struct got_object_id *commit_id, struct got_repository *repo)
+ struct got_object_id *commit_id, int allow_conflict,
+ struct got_repository *repo)
{
const struct got_error *error;
struct got_commit_object *commit;
error = got_worktree_rebase_commit(&new_commit_id, merged_paths,
worktree, fileindex, tmp_branch, committer, commit, commit_id,
- repo);
+ allow_conflict, repo);
if (error) {
if (error->code != GOT_ERR_COMMIT_NO_CHANGES)
goto done;
int ch, rebase_in_progress = 0, abort_rebase = 0, continue_rebase = 0;
int histedit_in_progress = 0, merge_in_progress = 0;
int create_backup = 1, list_backups = 0, delete_backups = 0;
+ int allow_conflict = 0;
struct got_object_id_queue commits;
struct got_pathlist_head merged_paths;
const struct got_object_id_queue *parent_ids;
err(1, "pledge");
#endif
- while ((ch = getopt(argc, argv, "aclX")) != -1) {
+ while ((ch = getopt(argc, argv, "aCclX")) != -1) {
switch (ch) {
case 'a':
abort_rebase = 1;
break;
+ case 'C':
+ allow_conflict = 1;
+ break;
case 'c':
continue_rebase = 1;
break;
if (list_backups) {
if (abort_rebase)
option_conflict('l', 'a');
+ if (allow_conflict)
+ option_conflict('l', 'C');
if (continue_rebase)
option_conflict('l', 'c');
if (delete_backups)
} else if (delete_backups) {
if (abort_rebase)
option_conflict('X', 'a');
+ if (allow_conflict)
+ option_conflict('X', 'C');
if (continue_rebase)
option_conflict('X', 'c');
if (list_backups)
option_conflict('l', 'X');
if (argc != 0 && argc != 1)
usage_rebase();
+ } else if (allow_conflict) {
+ if (abort_rebase)
+ option_conflict('C', 'a');
+ if (!continue_rebase)
+ errx(1, "-C option requires -c");
} else {
if (abort_rebase && continue_rebase)
usage_rebase();
goto done;
error = rebase_commit(NULL, worktree, fileindex, tmp_branch,
- committer, resume_commit_id, repo);
+ committer, resume_commit_id, allow_conflict, repo);
if (error)
goto done;
}
error = rebase_commit(&merged_paths, worktree, fileindex,
- tmp_branch, committer, commit_id, repo);
+ tmp_branch, committer, commit_id, 0, repo);
got_pathlist_free(&merged_paths, GOT_PATHLIST_FREE_PATH);
if (error)
goto done;
__dead static void
usage_histedit(void)
{
- fprintf(stderr, "usage: %s histedit [-acdeflmX] [-F histedit-script] "
+ fprintf(stderr, "usage: %s histedit [-aCcdeflmX] [-F histedit-script] "
"[branch]\n", getprogname());
exit(1);
}
histedit_commit(struct got_pathlist_head *merged_paths,
struct got_worktree *worktree, struct got_fileindex *fileindex,
struct got_reference *tmp_branch, struct got_histedit_list_entry *hle,
- const char *committer, struct got_repository *repo)
+ const char *committer, int allow_conflict, struct got_repository *repo)
{
const struct got_error *err;
struct got_commit_object *commit;
err = got_worktree_histedit_commit(&new_commit_id, merged_paths,
worktree, fileindex, tmp_branch, committer, commit, hle->commit_id,
- hle->logmsg, repo);
+ hle->logmsg, allow_conflict, repo);
if (err) {
if (err->code != GOT_ERR_COMMIT_NO_CHANGES)
goto done;
struct got_update_progress_arg upa;
int edit_in_progress = 0, abort_edit = 0, continue_edit = 0;
int drop_only = 0, edit_logmsg_only = 0, fold_only = 0, edit_only = 0;
- int list_backups = 0, delete_backups = 0;
+ int allow_conflict = 0, list_backups = 0, delete_backups = 0;
const char *edit_script_path = NULL;
struct got_object_id_queue commits;
struct got_pathlist_head merged_paths;
err(1, "pledge");
#endif
- while ((ch = getopt(argc, argv, "acdeF:flmX")) != -1) {
+ while ((ch = getopt(argc, argv, "aCcdeF:flmX")) != -1) {
switch (ch) {
case 'a':
abort_edit = 1;
break;
+ case 'C':
+ allow_conflict = 1;
+ break;
case 'c':
continue_edit = 1;
break;
argc -= optind;
argv += optind;
+ if (abort_edit && allow_conflict)
+ option_conflict('a', 'C');
if (abort_edit && continue_edit)
option_conflict('a', 'c');
+ if (edit_script_path && allow_conflict)
+ option_conflict('F', 'C');
if (edit_script_path && edit_logmsg_only)
option_conflict('F', 'm');
if (abort_edit && edit_logmsg_only)
option_conflict('a', 'm');
+ if (edit_logmsg_only && allow_conflict)
+ option_conflict('m', 'C');
if (continue_edit && edit_logmsg_only)
option_conflict('c', 'm');
if (abort_edit && fold_only)
option_conflict('a', 'f');
+ if (fold_only && allow_conflict)
+ option_conflict('f', 'C');
if (continue_edit && fold_only)
option_conflict('c', 'f');
if (fold_only && edit_logmsg_only)
option_conflict('f', 'e');
if (drop_only && abort_edit)
option_conflict('d', 'a');
+ if (drop_only && allow_conflict)
+ option_conflict('d', 'C');
if (drop_only && continue_edit)
option_conflict('d', 'c');
if (drop_only && edit_logmsg_only)
if (list_backups) {
if (abort_edit)
option_conflict('l', 'a');
+ if (allow_conflict)
+ option_conflict('l', 'C');
if (continue_edit)
option_conflict('l', 'c');
if (edit_script_path)
} else if (delete_backups) {
if (abort_edit)
option_conflict('X', 'a');
+ if (allow_conflict)
+ option_conflict('X', 'C');
if (continue_edit)
option_conflict('X', 'c');
if (drop_only)
option_conflict('X', 'l');
if (argc != 0 && argc != 1)
usage_histedit();
- } else if (argc != 0)
+ } else if (allow_conflict && !continue_edit)
+ errx(1, "-C option requires -c");
+ else if (argc != 0)
usage_histedit();
/*
if (have_changes) {
error = histedit_commit(NULL, worktree,
fileindex, tmp_branch, hle,
- committer, repo);
+ committer, allow_conflict, repo);
if (error)
goto done;
} else {
}
error = histedit_commit(&merged_paths, worktree, fileindex,
- tmp_branch, hle, committer, repo);
+ tmp_branch, hle, committer, allow_conflict, repo);
got_pathlist_free(&merged_paths, GOT_PATHLIST_FREE_PATH);
if (error)
goto done;
__dead static void
usage_merge(void)
{
- fprintf(stderr, "usage: %s merge [-acn] [branch]\n", getprogname());
+ fprintf(stderr, "usage: %s merge [-aCcn] [branch]\n", getprogname());
exit(1);
}
struct got_object_id *branch_tip = NULL, *yca_id = NULL;
struct got_object_id *wt_branch_tip = NULL;
int ch, merge_in_progress = 0, abort_merge = 0, continue_merge = 0;
- int interrupt_merge = 0;
+ int allow_conflict = 0, interrupt_merge = 0;
struct got_update_progress_arg upa;
struct got_object_id *merge_commit_id = NULL;
char *branch_name = NULL;
err(1, "pledge");
#endif
- while ((ch = getopt(argc, argv, "acn")) != -1) {
+ while ((ch = getopt(argc, argv, "aCcn")) != -1) {
switch (ch) {
case 'a':
abort_merge = 1;
break;
+ case 'C':
+ allow_conflict = 1;
case 'c':
continue_merge = 1;
break;
argc -= optind;
argv += optind;
+ if (allow_conflict) {
+ if (abort_merge)
+ option_conflict('a', 'C');
+ if (!continue_merge)
+ errx(1, "-C option requires -c");
+ }
if (abort_merge && continue_merge)
option_conflict('a', 'c');
if (abort_merge || continue_merge) {
} else {
error = got_worktree_merge_commit(&merge_commit_id, worktree,
fileindex, author, NULL, 1, branch_tip, branch_name,
- repo, continue_merge ? print_status : NULL, NULL);
+ allow_conflict, repo, continue_merge ? print_status : NULL,
+ NULL);
if (error)
goto done;
error = got_worktree_merge_complete(worktree, fileindex, repo);
blob - 4ea02aaea560daeba058d4b8541f5ea222eb7586
blob + f7de090bfb2bd10312bdd0c389b5eabe41a33fdd
--- include/got_worktree.h
+++ include/got_worktree.h
*/
const struct got_error *got_worktree_commit(struct got_object_id **,
struct got_worktree *, struct got_pathlist_head *, const char *,
- const char *, int, int, got_worktree_commit_msg_cb, void *,
+ const char *, int, int, int, got_worktree_commit_msg_cb, void *,
got_worktree_status_cb, void *, struct got_repository *);
/* Get the path of a commitable worktree item. */
const struct got_error *got_worktree_rebase_commit(struct got_object_id **,
struct got_pathlist_head *, struct got_worktree *, struct got_fileindex *,
struct got_reference *, const char *, struct got_commit_object *,
- struct got_object_id *, struct got_repository *);
+ struct got_object_id *, int, struct got_repository *);
/* Postpone the rebase operation. Should be called after a merge conflict. */
const struct got_error *got_worktree_rebase_postpone(struct got_worktree *,
const struct got_error *got_worktree_histedit_commit(struct got_object_id **,
struct got_pathlist_head *, struct got_worktree *, struct got_fileindex *,
struct got_reference *, const char *, struct got_commit_object *,
- struct got_object_id *, const char *, struct got_repository *);
+ struct got_object_id *, const char *, int, struct got_repository *);
/*
* Record the specified commit as skipped during histedit.
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,
- struct got_repository *repo,
+ int allow_conflict, struct got_repository *repo,
got_worktree_status_cb status_cb, void *status_arg);
/*
blob - c4fc2f02d953c285d633a68f2ef9f0cebc512bca
blob + 055da929b846e6b27b801620463ae896ca9faf0a
--- lib/worktree.c
+++ lib/worktree.c
return err;
}
-/* Upgrade STATUS_MODIFY to STATUS_CONFLICT if a conflict marker is found. */
+/*
+ * Upgrade STATUS_MODIFY to STATUS_CONFLICT if a
+ * conflict marker is found in newly added lines only.
+ */
static const struct got_error *
-get_modified_file_content_status(unsigned char *status, FILE *f)
+get_modified_file_content_status(unsigned char *status,
+ struct got_blob_object *blob, const char *path, struct stat *sb,
+ FILE *ondisk_file)
{
const struct got_error *err = NULL;
const char *markers[3] = {
GOT_DIFF_CONFLICT_MARKER_SEP,
GOT_DIFF_CONFLICT_MARKER_END
};
+ FILE *f = NULL, *f1 = NULL;
int i = 0;
char *line = NULL;
size_t linesize = 0;
ssize_t linelen;
+ off_t sz1 = 0;
+ if (*status == GOT_STATUS_MODIFY) {
+ f = got_opentemp();
+ if (f == NULL)
+ return got_error_from_errno("got_opentemp");
+
+ f1 = got_opentemp();
+ if (f1 == NULL) {
+ err = got_error_from_errno("got_opentemp");
+ goto done;
+ }
+
+ if (blob) {
+ err = got_object_blob_dump_to_file(&sz1, NULL, NULL,
+ f1, blob);
+ if (err)
+ goto done;
+ }
+
+ err = got_diff_blob_file(blob, f1, sz1, NULL, ondisk_file, 1,
+ sb, path, GOT_DIFF_ALGORITHM_MYERS, 0, 0, 0, NULL, f);
+ if (err)
+ goto done;
+
+ if (fflush(f) == EOF) {
+ err = got_error_from_errno("fflush");
+ goto done;
+ }
+ if (fseeko(f, 0L, SEEK_SET) == -1) {
+ err = got_error_from_errno("fseek");
+ goto done;
+ }
+ }
+
while (*status == GOT_STATUS_MODIFY) {
linelen = getline(&line, &linesize, f);
if (linelen == -1) {
break;
}
- if (strncmp(line, markers[i], strlen(markers[i])) == 0) {
+ if (*line == '+' &&
+ strncmp(line + 1, markers[i], strlen(markers[i])) == 0) {
if (strcmp(markers[i], GOT_DIFF_CONFLICT_MARKER_END)
== 0)
*status = GOT_STATUS_CONFLICT;
i++;
}
}
+
+done:
free(line);
+ if (f != NULL && fclose(f) == EOF && err == NULL)
+ err = got_error_from_errno("fclose");
+ if (f1 != NULL && fclose(f1) == EOF && err == NULL)
+ err = got_error_from_errno("fclose");
return err;
}
if (*status == GOT_STATUS_MODIFY) {
rewind(f);
- err = get_modified_file_content_status(status, f);
+ err = get_modified_file_content_status(status, blob, ie->path,
+ sb, f);
} else if (xbit_differs(ie, sb->st_mode))
*status = GOT_STATUS_MODE_CHANGE;
done:
int have_staged_files;
int allow_bad_symlinks;
int diff_header_shown;
+ int commit_conflicts;
FILE *diff_outfile;
FILE *f1;
FILE *f2;
} else {
if (ct->status != GOT_STATUS_MODIFY &&
ct->status != GOT_STATUS_ADD &&
- ct->status != GOT_STATUS_DELETE)
+ ct->status != GOT_STATUS_DELETE &&
+ ct->status != GOT_STATUS_CONFLICT)
return NULL;
}
staged_status != GOT_STATUS_DELETE)
return NULL;
} else {
- if (status == GOT_STATUS_CONFLICT)
+ if (status == GOT_STATUS_CONFLICT && !a->commit_conflicts) {
+ printf("C %s\n", relpath);
return got_error(GOT_ERR_COMMIT_CONFLICT);
+ }
if (status != GOT_STATUS_MODIFY &&
status != GOT_STATUS_MODE_CHANGE &&
status != GOT_STATUS_ADD &&
- status != GOT_STATUS_DELETE)
+ status != GOT_STATUS_DELETE &&
+ status != GOT_STATUS_CONFLICT)
return NULL;
}
if (ct->staged_status == GOT_STATUS_NO_CHANGE) {
if (ct->status != GOT_STATUS_MODIFY &&
ct->status != GOT_STATUS_MODE_CHANGE &&
- ct->status != GOT_STATUS_DELETE)
+ ct->status != GOT_STATUS_DELETE &&
+ ct->status != GOT_STATUS_CONFLICT)
continue;
} else {
if (ct->staged_status != GOT_STATUS_MODIFY &&
/* NB: Deleted entries get dropped here. */
if (ct->status == GOT_STATUS_MODIFY ||
ct->status == GOT_STATUS_MODE_CHANGE ||
+ ct->status == GOT_STATUS_CONFLICT ||
ct->staged_status == GOT_STATUS_MODIFY) {
err = alloc_modified_blob_tree_entry(
&new_te, te, ct);
if (ct->status != GOT_STATUS_ADD &&
ct->status != GOT_STATUS_MODIFY &&
- ct->status != GOT_STATUS_MODE_CHANGE)
+ ct->status != GOT_STATUS_MODE_CHANGE &&
+ ct->status != GOT_STATUS_CONFLICT)
continue;
if (asprintf(&ondisk_path, "%s/%s",
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, got_worktree_commit_msg_cb commit_msg_cb, void *commit_arg,
+ 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)
{
cc_arg.have_staged_files = have_staged_files;
cc_arg.allow_bad_symlinks = allow_bad_symlinks;
cc_arg.diff_header_shown = 0;
+ cc_arg.commit_conflicts = commit_conflicts;
if (show_diff) {
err = got_opentemp_named(&diff_path, &cc_arg.diff_outfile,
GOT_TMPDIR_STR "/got", ".diff");
struct got_worktree *worktree, struct got_fileindex *fileindex,
struct got_reference *tmp_branch, const char *committer,
struct got_commit_object *orig_commit, const char *new_logmsg,
- struct got_repository *repo)
+ int allow_conflict, struct got_repository *repo)
{
const struct got_error *err, *sync_err;
struct got_pathlist_head commitable_paths;
cc_arg.worktree = worktree;
cc_arg.repo = repo;
cc_arg.have_staged_files = 0;
+ cc_arg.commit_conflicts = allow_conflict;
/*
* If possible get the status of individual files directly to
* avoid crawling the entire work tree once per rebased commit.
struct got_pathlist_head *merged_paths, struct got_worktree *worktree,
struct got_fileindex *fileindex, struct got_reference *tmp_branch,
const char *committer, struct got_commit_object *orig_commit,
- struct got_object_id *orig_commit_id, struct got_repository *repo)
+ struct got_object_id *orig_commit_id, int allow_conflict,
+ struct got_repository *repo)
{
const struct got_error *err;
char *commit_ref_name;
err = rebase_commit(new_commit_id, merged_paths, commit_ref,
worktree, fileindex, tmp_branch, committer, orig_commit,
- NULL, repo);
+ NULL, allow_conflict, repo);
done:
if (commit_ref)
got_ref_close(commit_ref);
struct got_fileindex *fileindex, struct got_reference *tmp_branch,
const char *committer, struct got_commit_object *orig_commit,
struct got_object_id *orig_commit_id, const char *new_logmsg,
- struct got_repository *repo)
+ int allow_conflict, struct got_repository *repo)
{
const struct got_error *err;
char *commit_ref_name;
err = rebase_commit(new_commit_id, merged_paths, commit_ref,
worktree, fileindex, tmp_branch, committer, orig_commit,
- new_logmsg, repo);
+ new_logmsg, allow_conflict, repo);
done:
if (commit_ref)
got_ref_close(commit_ref);
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,
- struct got_repository *repo,
+ int allow_conflict, struct got_repository *repo,
got_worktree_status_cb status_cb, void *status_arg)
{
cc_arg.repo = repo;
cc_arg.have_staged_files = have_staged_files;
cc_arg.allow_bad_symlinks = allow_bad_symlinks;
+ cc_arg.commit_conflicts = allow_conflict;
err = worktree_status(worktree, "", fileindex, repo,
collect_commitables, &cc_arg, NULL, NULL, 1, 0);
if (err)
blob - 0543d4bebab658396a069f968553a9b43594ca74
blob + 488cdaf04a738a2e6a11df99d0d5df6b7a604c83
--- regress/cmdline/commit.sh
+++ regress/cmdline/commit.sh
echo "modified alpha" > $testroot/wt/alpha
(cd $testroot/wt && got commit -m "modified alpha" >/dev/null)
+ local commit_id1=`git_show_head $testroot/repo`
(cd $testroot/wt && got update -c $initial_rev > /dev/null)
(cd $testroot/wt && got commit -m 'commit it' > $testroot/stdout \
2> $testroot/stderr)
+ ret=$?
+ if [ $ret -eq 0 ]; then
+ echo "got commit succeeded unexpectedly"
+ test_done "$testroot" "$ret"
+ return 1
+ fi
- echo -n > $testroot/stdout.expected
+ echo "C alpha" > $testroot/stdout.expected
echo "got: cannot commit file in conflicted status" \
> $testroot/stderr.expected
ret=$?
if [ $ret -ne 0 ]; then
diff -u $testroot/stderr.expected $testroot/stderr
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/wt && got commit -C -m 'commit it' > $testroot/stdout \
+ 2> $testroot/stderr)
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ echo "got commit failed unexpectedly"
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ # make sure the conflicted commit produces a diff
+ local conflict_commit=`git_show_head $testroot/repo`
+ local blob_minus=`got tree -r $testroot/repo -c $commit_id1 -i | \
+ grep 'alpha$' | cut -d' ' -f1`
+ local blob_plus=`got tree -r $testroot/repo -c $conflict_commit -i | \
+ grep 'alpha$' | cut -d' ' -f1`
+
+ 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 diff -c master > $testroot/stdout)
+
+ echo -n > $testroot/stdout.expected
+ cat > $testroot/stdout.expected <<EOF
+diff $commit_id1 refs/heads/master
+commit - $commit_id1
+commit + $conflict_commit
+blob - $blob_minus
+blob + $blob_plus
+--- alpha
++++ alpha
+@@ -1 +1,7 @@
++<<<<<<< merged change: commit $commit_id1
+ modified alpha
++||||||| 3-way merge base: commit $initial_rev
++alpha
++=======
++modified alpha, too
++>>>>>>>
+EOF
+
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
fi
+
+ (cd $testroot/wt && got status > $testroot/stdout)
+
+ echo -n > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ fi
test_done "$testroot" "$ret"
}
blob - afb98ebb0b2de07c90dfa887d9d20fe0cb5f0db4
blob + 1ab6bfe75bae74735e4040c6d98ea1dea7cd9dc3
--- regress/cmdline/update.sh
+++ regress/cmdline/update.sh
fi
(cd $testroot/wt && got status > $testroot/stdout)
- echo 'C foo' > $testroot/stdout.expected
+ echo 'M foo' > $testroot/stdout.expected
echo -n '? ' >> $testroot/stdout.expected
(cd $testroot/wt && ls foo-1-* >> $testroot/stdout.expected)
echo -n '? ' >> $testroot/stdout.expected