summaryrefslogtreecommitdiff
path: root/builtin/pull.c
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <gitster@pobox.com>2021-11-10 15:01:19 -0800
committerLibravatar Junio C Hamano <gitster@pobox.com>2021-11-10 15:01:19 -0800
commit7c7cf62c485f527bee6d3eb7e37dcfbf8064cab2 (patch)
tree1ae588b26347be9651758ca0c3137245f07b0fef /builtin/pull.c
parentGit 2.34-rc2 (diff)
parentpull: --ff-only should make it a noop when already-up-to-date (diff)
downloadtgif-7c7cf62c485f527bee6d3eb7e37dcfbf8064cab2.tar.xz
Merge branch 'jc/fix-pull-ff-only-when-already-up-to-date'
"git pull --ff-only" and "git pull --rebase --ff-only" should make it a no-op to attempt pulling from a remote that is behind us, but instead the command errored out by saying it was impossible to fast-forward, which may technically be true, but not a useful thing to diagnose as an error. This has been corrected. * jc/fix-pull-ff-only-when-already-up-to-date: pull: --ff-only should make it a noop when already-up-to-date
Diffstat (limited to 'builtin/pull.c')
-rw-r--r--builtin/pull.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/builtin/pull.c b/builtin/pull.c
index efe4f4a81f..127798ba84 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -937,6 +937,33 @@ static int get_can_ff(struct object_id *orig_head,
return ret;
}
+/*
+ * Is orig_head a descendant of _all_ merge_heads?
+ * Unfortunately is_descendant_of() cannot be used as it asks
+ * if orig_head is a descendant of at least one of them.
+ */
+static int already_up_to_date(struct object_id *orig_head,
+ struct oid_array *merge_heads)
+{
+ int i;
+ struct commit *ours;
+
+ ours = lookup_commit_reference(the_repository, orig_head);
+ for (i = 0; i < merge_heads->nr; i++) {
+ struct commit_list *list = NULL;
+ struct commit *theirs;
+ int ok;
+
+ theirs = lookup_commit_reference(the_repository, &merge_heads->oid[i]);
+ commit_list_insert(theirs, &list);
+ ok = repo_is_descendant_of(the_repository, ours, list);
+ free_commit_list(list);
+ if (!ok)
+ return 0;
+ }
+ return 1;
+}
+
static void show_advice_pull_non_ff(void)
{
advise(_("You have divergent branches and need to specify how to reconcile them.\n"
@@ -1078,7 +1105,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
/* ff-only takes precedence over rebase */
if (opt_ff && !strcmp(opt_ff, "--ff-only")) {
- if (!can_ff)
+ if (!can_ff && !already_up_to_date(&orig_head, &merge_heads))
die_ff_impossible();
opt_rebase = REBASE_FALSE;
}