about summary refs log tree commit
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2020-03-26 17:11:21 -0700
committerJunio C Hamano <gitster@pobox.com>2020-03-26 17:11:21 -0700
commitfb4175b0e4bec59b97dae84a0073d8a5334508d6 (patch)
tree737f3835be75b15214fa58b42594f912d36c9c66
parent4e4baee3f44da26a5eaab27c76d597b04fef5259 (diff)
parentf08132f889c00a8108f61541e047649ad0e660e4 (diff)
downloadgit-fb4175b0e4bec59b97dae84a0073d8a5334508d6.tar.gz
The "--fork-point" mode of "git rebase" regressed when the command
was rewritten in C back in 2.20 era, which has been corrected.

* at/rebase-fork-point-regression-fix:
  rebase: --fork-point regression fix
-rw-r--r--builtin/merge-base.c12
-rw-r--r--commit.c15
-rwxr-xr-xt/t3431-rebase-fork-point.sh20
3 files changed, 34 insertions, 13 deletions
diff --git a/builtin/merge-base.c b/builtin/merge-base.c
index e3f8da13b6..6719ac198d 100644
--- a/builtin/merge-base.c
+++ b/builtin/merge-base.c
@@ -114,26 +114,16 @@ static int handle_is_ancestor(int argc, const char **argv)
 static int handle_fork_point(int argc, const char **argv)
 {
         struct object_id oid;
-        char *refname;
         struct commit *derived, *fork_point;
         const char *commitname;
 
-        switch (dwim_ref(argv[0], strlen(argv[0]), &oid, &refname)) {
-        case 0:
-                die("No such ref: '%s'", argv[0]);
-        case 1:
-                break; /* good */
-        default:
-                die("Ambiguous refname: '%s'", argv[0]);
-        }
-
         commitname = (argc == 2) ? argv[1] : "HEAD";
         if (get_oid(commitname, &oid))
                 die("Not a valid object name: '%s'", commitname);
 
         derived = lookup_commit_reference(the_repository, &oid);
 
-        fork_point = get_fork_point(refname, derived);
+        fork_point = get_fork_point(argv[0], derived);
 
         if (!fork_point)
                 return 1;
diff --git a/commit.c b/commit.c
index 534e14f22a..c7099daeac 100644
--- a/commit.c
+++ b/commit.c
@@ -927,12 +927,22 @@ struct commit *get_fork_point(const char *refname, struct commit *commit)
         struct commit_list *bases;
         int i;
         struct commit *ret = NULL;
+        char *full_refname;
+
+        switch (dwim_ref(refname, strlen(refname), &oid, &full_refname)) {
+        case 0:
+                die("No such ref: '%s'", refname);
+        case 1:
+                break; /* good */
+        default:
+                die("Ambiguous refname: '%s'", refname);
+        }
 
         memset(&revs, 0, sizeof(revs));
         revs.initial = 1;
-        for_each_reflog_ent(refname, collect_one_reflog_ent, &revs);
+        for_each_reflog_ent(full_refname, collect_one_reflog_ent, &revs);
 
-        if (!revs.nr && !get_oid(refname, &oid))
+        if (!revs.nr)
                 add_one_commit(&oid, &revs);
 
         for (i = 0; i < revs.nr; i++)
@@ -958,6 +968,7 @@ struct commit *get_fork_point(const char *refname, struct commit *commit)
 
 cleanup_return:
         free_commit_list(bases);
+        free(full_refname);
         return ret;
 }
 
diff --git a/t/t3431-rebase-fork-point.sh b/t/t3431-rebase-fork-point.sh
index 78851b9a2a..172562789e 100755
--- a/t/t3431-rebase-fork-point.sh
+++ b/t/t3431-rebase-fork-point.sh
@@ -47,11 +47,31 @@ test_rebase 'G F B A' --keep-base
 test_rebase 'G F C E D B A' --no-fork-point
 test_rebase 'G F C D B A' --no-fork-point --onto D
 test_rebase 'G F C B A' --no-fork-point --keep-base
+
 test_rebase 'G F E D B A' --fork-point refs/heads/master
+test_rebase 'G F E D B A' --fork-point master
+
 test_rebase 'G F D B A' --fork-point --onto D refs/heads/master
+test_rebase 'G F D B A' --fork-point --onto D master
+
 test_rebase 'G F B A' --fork-point --keep-base refs/heads/master
+test_rebase 'G F B A' --fork-point --keep-base master
+
 test_rebase 'G F C E D B A' refs/heads/master
+test_rebase 'G F C E D B A' master
+
 test_rebase 'G F C D B A' --onto D refs/heads/master
+test_rebase 'G F C D B A' --onto D master
+
 test_rebase 'G F C B A' --keep-base refs/heads/master
+test_rebase 'G F C B A' --keep-base master
+
+test_expect_success 'git rebase --fork-point with ambigous refname' '
+        git checkout master &&
+        git checkout -b one &&
+        git checkout side &&
+        git tag one &&
+        test_must_fail git rebase --fork-point --onto D one
+'
 
 test_done