commit - 2822a3526b8c61302ec86e0871e724c07a4b078d
commit + 3aef623b225b81a61fd3786dc79d091f47b68225
blob - c2246a9a4a1eb2d49378c3096a50bcbf472739e2
blob + 5423c33764d81bfc3fd2c71dc7f9ca32f22bad4a
--- got/got.c
+++ got/got.c
static const struct got_error *
check_linear_ancestry(struct got_object_id *commit_id,
- struct got_object_id *base_commit_id, struct got_repository *repo)
+ struct got_object_id *base_commit_id, int allow_forwards_in_time_only,
+ struct got_repository *repo)
{
const struct got_error *err = NULL;
struct got_object_id *yca_id;
* Update forwards in time: A (base/yca) - B - C - D (commit)
* Update backwards in time: D (base) - C - B - A (commit/yca)
*/
- if (got_object_id_cmp(commit_id, yca_id) != 0 &&
+ if (allow_forwards_in_time_only) {
+ if (got_object_id_cmp(base_commit_id, yca_id) != 0)
+ return got_error(GOT_ERR_ANCESTRY);
+ } else if (got_object_id_cmp(commit_id, yca_id) != 0 &&
got_object_id_cmp(base_commit_id, yca_id) != 0)
return got_error(GOT_ERR_ANCESTRY);
if (error)
goto done;
error = check_linear_ancestry(commit_id,
- got_worktree_get_base_commit_id(worktree), repo);
+ got_worktree_get_base_commit_id(worktree), 0, repo);
if (error != NULL) {
free(commit_id);
goto done;
}
err = check_linear_ancestry(commit_id,
- got_worktree_get_base_commit_id(worktree), repo);
+ got_worktree_get_base_commit_id(worktree), 0, repo);
if (err) {
if (err->code != GOT_ERR_ANCESTRY)
return err;
error = got_ref_resolve(&head_commit_id, repo, head_ref);
if (error)
goto done;
- error = check_linear_ancestry(commit_id, head_commit_id, repo);
+ error = check_linear_ancestry(commit_id, head_commit_id, 0,
+ repo);
free(head_commit_id);
if (error != NULL)
goto done;
goto done;
} else {
error = check_linear_ancestry(commit_id,
- got_worktree_get_base_commit_id(worktree), repo);
+ got_worktree_get_base_commit_id(worktree), 0, repo);
if (error != NULL) {
if (error->code == GOT_ERR_ANCESTRY)
error = got_error(GOT_ERR_BRANCH_MOVED);
goto done;
}
- error = check_linear_ancestry(commit_id, base_commit_id, repo);
+ error = check_linear_ancestry(commit_id, base_commit_id, 1, repo);
if (error) {
if (error->code == GOT_ERR_ANCESTRY)
error = got_error(GOT_ERR_REBASE_REQUIRED);
blob - 86d2fa9ed1614f01bad8d546d2b87b57266c3147
blob + 35a98a41a609ebbd3f4945600522a843e17529f2
--- regress/cmdline/integrate.sh
+++ regress/cmdline/integrate.sh
fi
test_done "$testroot" "$ret"
}
+
+function test_integrate_backwards_in_time {
+ local testroot=`test_init integrate_backwards_in_time`
+
+ (cd $testroot/repo && git checkout -q -b newbranch)
+ echo "modified delta on branch" > $testroot/repo/gamma/delta
+ git_commit $testroot/repo -m "committing to delta on newbranch"
+
+ echo "modified alpha on branch" > $testroot/repo/alpha
+ (cd $testroot/repo && git rm -q beta)
+ echo "new file on branch" > $testroot/repo/epsilon/new
+ (cd $testroot/repo && git add epsilon/new)
+ git_commit $testroot/repo -m "committing more changes on newbranch"
+
+ local orig_commit1=`git_show_parent_commit $testroot/repo`
+ local orig_commit2=`git_show_head $testroot/repo`
+
+ (cd $testroot/repo && git 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" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+ (cd $testroot/wt && got rebase newbranch > /dev/null)
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "got rebase failed unexpectedly"
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/repo && git checkout -q newbranch)
+ local new_commit1=`git_show_parent_commit $testroot/repo`
+ local new_commit2=`git_show_head $testroot/repo`
+
+ # attempt to integrate master into newbranch (wrong way around)
+ (cd $testroot/wt && got update -b newbranch > /dev/null)
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "got update failed unexpectedly"
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/wt && got integrate master \
+ > $testroot/stdout 2> $testroot/stderr)
+ ret="$?"
+ if [ "$ret" == "0" ]; then
+ echo "got integrate succeeded unexpectedly"
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ 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
+
+ echo "got: specified branch must be rebased first" \
+ > $testroot/stderr.expected
+ cmp -s $testroot/stderr.expected $testroot/stderr
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stderr.expected $testroot/stderr
+ fi
+ test_done "$testroot" "$ret"
+}
+
run_test test_integrate_basic
run_test test_integrate_requires_rebase_first
run_test test_integrate_path_prefix
+run_test test_integrate_backwards_in_time