commit - 768705e331a0ff020ecc806142aecdecdbfb2e89
commit + ba34626bc13877c93836c8ee873acf1be8429ead
blob - c408a296cf7c404394c1001c724ca9a0355c7e6a
blob + 87a57e122c712ef21868c139097562f10ce37ee6
--- got/got.1
+++ got/got.1
.It Cm ig
Short alias for
.Cm integrate .
-.It Cm merge Oo Fl a Oc Oo Fl c Oc Op Ar branch
+.It Cm merge Oo Fl a Oc Oo Fl c Oc Oo Fl n Oc Op Ar branch
Create a merge commit based on the current branch of the work tree and
the specified
.Ar branch .
.It Fl c
Continue an interrupted merge operation.
If this option is used, no other command-line arguments are allowed.
+.It Fl n
+Merge changes into the work tree as usual but do not create a merge
+commit immediately.
+The merge result can be adjusted as desired before a merge commit is
+created with
+.Cm got merge -c .
+Alternatively, the merge may be aborted with
+.Cm got merge -a .
.El
.It Cm mg
Short alias for
blob - ad95c4f4600316e0434df71d4de1a2c764eaa8ff
blob + 7e1da95f5c59517cd657b81619f6f8e89e5c425e
--- got/got.c
+++ got/got.c
__dead static void
usage_merge(void)
{
- fprintf(stderr, "usage: %s merge [-a] [-c] [branch]\n",
+ fprintf(stderr, "usage: %s merge [-a] [-c] [-n] [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;
struct got_update_progress_arg upa;
struct got_object_id *merge_commit_id = NULL;
char *branch_name = NULL;
memset(&upa, 0, sizeof(upa));
- while ((ch = getopt(argc, argv, "ac")) != -1) {
+ while ((ch = getopt(argc, argv, "acn")) != -1) {
switch (ch) {
case 'a':
abort_merge = 1;
case 'c':
continue_merge = 1;
break;
+ case 'n':
+ interrupt_merge = 1;
+ break;
default:
usage_rebase();
/* NOTREACHED */
}
}
- if (upa.conflicts > 0 || upa.missing > 0) {
+ if (interrupt_merge) {
error = got_worktree_merge_postpone(worktree, fileindex);
if (error)
goto done;
+ printf("Merge of %s interrupted on request\n", branch_name);
+ } else if (upa.conflicts > 0 || upa.missing > 0) {
+ error = got_worktree_merge_postpone(worktree, fileindex);
+ if (error)
+ goto done;
if (upa.conflicts > 0 && upa.missing == 0) {
error = got_error_msg(GOT_ERR_CONFLICTS,
"conflicts must be resolved before merging "
blob - 1d534c5958a2e7da9413b01d8fcff42599c6f25b
blob + 38220a83f2af8fc1c889f9271a2cd263cbed1dad
--- regress/cmdline/merge.sh
+++ regress/cmdline/merge.sh
fi
test_done "$testroot" "$ret"
}
+
+test_merge_interrupt() {
+ local testroot=`test_init merge_interrupt`
+ local commit0=`git_show_head $testroot/repo`
+ local commit0_author_time=`git_show_author_time $testroot/repo`
+
+ (cd $testroot/repo && git checkout -q -b newbranch)
+ echo "modified alpha on branch" > $testroot/repo/alpha
+ git_commit $testroot/repo -m "committing to alpha on newbranch"
+ local branch_commit0=`git_show_branch_head $testroot/repo newbranch`
+
+ got checkout -b master $testroot/repo $testroot/wt > /dev/null
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "got checkout failed unexpectedly" >&2
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ # create a non-conflicting commit
+ (cd $testroot/repo && git checkout -q master)
+ echo "modified beta on master" > $testroot/repo/beta
+ git_commit $testroot/repo -m "committing to beta on master"
+ local master_commit=`git_show_head $testroot/repo`
+ # need an up-to-date work tree for 'got merge'
+ (cd $testroot/wt && got update > /dev/null)
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "got update failed unexpectedly" >&2
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/wt && got merge -n newbranch \
+ > $testroot/stdout 2> $testroot/stderr)
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "got merge failed unexpectedly" >&2
+ test_done "$testroot" "1"
+ return 1
+ fi
+
+ echo "G alpha" > $testroot/stdout.expected
+ echo "Merge of refs/heads/newbranch interrupted on request" \
+ >> $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/wt && got status > $testroot/stdout)
+
+ echo "M alpha" > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "modified alpha on branch" > $testroot/content.expected
+ cat $testroot/wt/alpha > $testroot/content
+ cmp -s $testroot/content.expected $testroot/content
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/content.expected $testroot/content
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ # adjust merge result
+ echo "adjusted merge result" > $testroot/wt/alpha
+
+ # continue the merge
+ (cd $testroot/wt && got merge -c > $testroot/stdout)
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "got merge failed unexpectedly" >&2
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ local merge_commit=`git_show_head $testroot/repo`
+
+ echo -n "Merged refs/heads/newbranch into refs/heads/master: " \
+ > $testroot/stdout.expected
+ echo $merge_commit >> $testroot/stdout.expected
+
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "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" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/wt && got log -l3 | grep ^commit > $testroot/stdout)
+ echo "commit $merge_commit (master)" > $testroot/stdout.expected
+ echo "commit $master_commit" >> $testroot/stdout.expected
+ echo "commit $commit0" >> $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/wt && got update > $testroot/stdout)
+
+ echo 'Already up-to-date' > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ # We should have created a merge commit with two parents.
+ (cd $testroot/wt && got log -l1 | grep ^parent > $testroot/stdout)
+ echo "parent 1: $master_commit" > $testroot/stdout.expected
+ echo "parent 2: $branch_commit0" >> $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ fi
+ test_done "$testroot" "$ret"
+}
+
test_parseargs "$@"
run_test test_merge_basic
run_test test_merge_continue
run_test test_merge_missing_file
run_test test_merge_no_op
run_test test_merge_imported_branch
+run_test test_merge_interrupt