Skip to contentSkip to conversation

pull: avoid running both merge and rebase

PATCH In review Elijah Newren via GitGitGadget 6 participants 7 messages Mar 27, 2020 – Apr 4, 2020

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 pull: avoid running both merge and rebase

From: Elijah Newren <[email protected]>

When opt_rebase is true, we still first check if we can fast-forward. If the branch is fast-forwardable, then we can avoid the rebase and just use merge to do the fast-forward logic. However, when commit a6d7eb2c7a ("pull: optionally rebase submodules (remote submodule changes only)", 2017-06-23) added the ability to rebase submodules it accidentally caused us to run BOTH a merge and a rebase. Add a flag to avoid doing both.

This was found when a user had both pull.rebase and rebase.autosquash set to true. In such a case, the running of both merge and rebase would cause ORIG_HEAD to be updated twice (and match HEAD at the end instead of the commit before the rebase started), against expectation.

---
pull: avoid running both merge and rebase

Cc: Norbert Kiesel [email protected] [[email protected]], Jeff King [email protected] [[email protected]]

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-739%2Fnewren%2Favoid-merge-and-rebase-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-739/newren/avoid-merge-and-rebase-v1
Pull-Request: https://github.com/git/git/pull/739

 builtin/pull.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
builtin/pull.c +4 -1
index 3e624d1e008..19899b45c1d 100644
@@ -976,6 +976,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 
 	if (opt_rebase) {
 		int ret = 0;
+		int ran_ff = 0;
 		if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
 		     recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&
 		    submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))
@@ -992,10 +993,12 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 			if (is_descendant_of(merge_head, list)) {
 				/* we can fast-forward this without invoking rebase */
 				opt_ff = "--ff-only";
+				ran_ff = 1;
 				ret = run_merge();
 			}
 		}
-		ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
+		if (!ran_ff)
+			ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
 
 		if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON ||
 			     recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND))

base-commit: 274b9cc25322d9ee79aa8e6d4e86f0ffe5ced925

Signature · 1 line
gitgitgadget
#1 lore raw
Quoted 9 lines · Elijah Newren via GitGitGadget

From: Elijah Newren <[email protected]>

When opt_rebase is true, we still first check if we can fast-forward. If the branch is fast-forwardable, then we can avoid the rebase and just use merge to do the fast-forward logic. However, when commit a6d7eb2c7a ("pull: optionally rebase submodules (remote submodule changes only)", 2017-06-23) added the ability to rebase submodules it accidentally caused us to run BOTH a merge and a rebase. Add a flag to avoid doing both.

This is a fun one. Thanks for digging to the bottom of the issue.

Quoted 28 lines
builtin/pull.c +4 -1
index 3e624d1e008..19899b45c1d 100644
@@ -976,6 +976,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 
 	if (opt_rebase) {
 		int ret = 0;
+		int ran_ff = 0;
 		if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
 		     recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&
 		    submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))
@@ -992,10 +993,12 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 			if (is_descendant_of(merge_head, list)) {
 				/* we can fast-forward this without invoking rebase */
 				opt_ff = "--ff-only";
+				ran_ff = 1;
 				ret = run_merge();
 			}
 		}
-		ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
+		if (!ran_ff)
+			ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
 
 		if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON ||
 			     recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND))

base-commit: 274b9cc25322d9ee79aa8e6d4e86f0ffe5ced925

#2 lore raw
In reply to Elijah Newren via GitGitGadget
Quoted 13 lines · Elijah Newren via GitGitGadget

When opt_rebase is true, we still first check if we can fast-forward. If the branch is fast-forwardable, then we can avoid the rebase and just use merge to do the fast-forward logic. However, when commit a6d7eb2c7a ("pull: optionally rebase submodules (remote submodule changes only)", 2017-06-23) added the ability to rebase submodules it accidentally caused us to run BOTH a merge and a rebase. Add a flag to avoid doing both.

This was found when a user had both pull.rebase and rebase.autosquash set to true. In such a case, the running of both merge and rebase would cause ORIG_HEAD to be updated twice (and match HEAD at the end instead of the commit before the rebase started), against expectation.

Quoted 6 lines

---
pull: avoid running both merge and rebase

Cc: Norbert Kiesel [email protected] [[email protected]], Jeff King [email protected] [[email protected]]

I'm not sure how cc is supposed to work with GGG, but it clearly didn't here. :)

Anyway, the patch looks good. Thanks for following through on this.

builtin/pull.c int cmd_pull(int argc, const char **argv, const char *prefix) · line 1001

Quoted 11 lines
builtin/pull.c +3 -1
@@ -992,10 +993,12 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
 			if (is_descendant_of(merge_head, list)) {
 				/* we can fast-forward this without invoking rebase */
 				opt_ff = "--ff-only";
+				ran_ff = 1;
 				ret = run_merge();
 			}
 		}
-		ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
+		if (!ran_ff)
+			ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);

It feels like there should be some arrangement of the conditionals that doesn't require setting an extra flag, but I actually don't think there is. And anyway, doing the most obvious and minimal fix here is the right place to start. We don't need more regressions. ;)

-Peff

#3 lore raw
Quoted 19 lines · Jeff King
Quoted 17 lines · Elijah Newren via GitGitGadget

When opt_rebase is true, we still first check if we can fast-forward. If the branch is fast-forwardable, then we can avoid the rebase and just use merge to do the fast-forward logic. However, when commit a6d7eb2c7a ("pull: optionally rebase submodules (remote submodule changes only)", 2017-06-23) added the ability to rebase submodules it accidentally caused us to run BOTH a merge and a rebase. Add a flag to avoid doing both.

This was found when a user had both pull.rebase and rebase.autosquash set to true. In such a case, the running of both merge and rebase would cause ORIG_HEAD to be updated twice (and match HEAD at the end instead of the commit before the rebase started), against expectation.

---
pull: avoid running both merge and rebase

Quoted 5 lines
Quoted 2 lines

Cc: Norbert Kiesel [email protected] [[email protected]], Jeff King [email protected] [[email protected]]

I'm not sure how cc is supposed to work with GGG, but it clearly didn't here. :)

Angle brackets would work instead of square brackets:

Cc Norbert Keisel <[email protected]>

for example. Personally, I drop the names and only use email addresses so I don't make this same mistake.

-Stolee

#4 lore raw
Quoted 27 lines · Derrick Stolee
Quoted 19 lines · Jeff King
Quoted 17 lines · Elijah Newren via GitGitGadget

When opt_rebase is true, we still first check if we can fast-forward. If the branch is fast-forwardable, then we can avoid the rebase and just use merge to do the fast-forward logic. However, when commit a6d7eb2c7a ("pull: optionally rebase submodules (remote submodule changes only)", 2017-06-23) added the ability to rebase submodules it accidentally caused us to run BOTH a merge and a rebase. Add a flag to avoid doing both.

This was found when a user had both pull.rebase and rebase.autosquash set to true. In such a case, the running of both merge and rebase would cause ORIG_HEAD to be updated twice (and match HEAD at the end instead of the commit before the rebase started), against expectation.

---
pull: avoid running both merge and rebase

Quoted 5 lines
Quoted 2 lines

Cc: Norbert Kiesel [email protected] [[email protected]], Jeff King [email protected] [[email protected]]

I'm not sure how cc is supposed to work with GGG, but it clearly didn't here. :)

Quoted 6 lines

Angle brackets would work instead of square brackets:

Cc Norbert Keisel <[email protected]>

for example. Personally, I drop the names and only use email addresses so I don't make this same mistake.

My original did have angle brackets; it was literally the following line:

Cc Norbert Kiesel <[email protected]>, Jeff King <[email protected]>

Not sure why it came through with duplicated email addresses with one inside of square brackets. Maybe GitHub markup does something to the angle brackets, and GGG doesn't get the original text but the markdown-interpreted clobbering thereof? Or something like that?

#5 lore raw
In reply to Jeff King
Quoted 20 lines · Jeff King
Quoted 17 lines · Elijah Newren via GitGitGadget

When opt_rebase is true, we still first check if we can fast-forward. If the branch is fast-forwardable, then we can avoid the rebase and just use merge to do the fast-forward logic. However, when commit a6d7eb2c7a ("pull: optionally rebase submodules (remote submodule changes only)", 2017-06-23) added the ability to rebase submodules it accidentally caused us to run BOTH a merge and a rebase. Add a flag to avoid doing both.

This was found when a user had both pull.rebase and rebase.autosquash set to true. In such a case, the running of both merge and rebase would cause ORIG_HEAD to be updated twice (and match HEAD at the end instead of the commit before the rebase started), against expectation.

---
pull: avoid running both merge and rebase

Quoted 5 lines
Quoted 2 lines

Cc: Norbert Kiesel [email protected] [[email protected]], Jeff King [email protected] [[email protected]]

I'm not sure how cc is supposed to work with GGG, but it clearly didn't here. :)

Yeah, I clearly don't either. I even looked up another submission from Dscho (https://github.com/git/git/pull/728) and attempted to mimic it, but still managed to get it wrong somehow and I don't know how.

Quoted 18 lines

Anyway, the patch looks good. Thanks for following through on this.

builtin/pull.c int cmd_pull(int argc, const char **argv, const char *prefix) · line 1001

Quoted 11 lines
builtin/pull.c +3 -1
@@ -992,10 +993,12 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
                      if (is_descendant_of(merge_head, list)) {
                              /* we can fast-forward this without invoking rebase */
                              opt_ff = "--ff-only";
+                             ran_ff = 1;
                              ret = run_merge();
                      }
              }
-             ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
+             if (!ran_ff)
+                     ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);

It feels like there should be some arrangement of the conditionals that doesn't require setting an extra flag, but I actually don't think there is. And anyway, doing the most obvious and minimal fix here is the right place to start. We don't need more regressions. ;)

Thanks for reviewing it.

#6 lore raw

GGG Cc: bug, was Re: [PATCH] pull: avoid running both merge and rebase

Hi Elijah,

Quoted 24 lines · Elijah Newren
Quoted 23 lines · Jeff King
Quoted 19 lines · Elijah Newren via GitGitGadget

When opt_rebase is true, we still first check if we can fast-forward. If the branch is fast-forwardable, then we can avoid the rebase and just use merge to do the fast-forward logic. However, when commit a6d7eb2c7a ("pull: optionally rebase submodules (remote submodule changes only)", 2017-06-23) added the ability to rebase submodules it accidentally caused us to run BOTH a merge and a rebase. Add a flag to avoid doing both.

This was found when a user had both pull.rebase and rebase.autosquash set to true. In such a case, the running of both merge and rebase would cause ORIG_HEAD to be updated twice (and match HEAD at the end instead of the commit before the rebase started), against expectation.

---
pull: avoid running both merge and rebase

Cc: Norbert Kiesel [email protected] [[email protected]], Jeff King [email protected] [[email protected]]

Quoted 7 lines
Quoted 2 lines

I'm not sure how cc is supposed to work with GGG, but it clearly didn't here. :)

Yeah, I clearly don't either. I even looked up another submission from Dscho (https://github.com/git/git/pull/728) and attempted to mimic it, but still managed to get it wrong somehow and I don't know how.

It might be a bug in the way I implemented folding the cover letter into single-patch mails. I simply might not pick up the Cc:s there.

However, I am seriously under water right now and won't be able to work on a fix for that. Would you mind opening a ticket at
https://github.com/gitgitgadget/gitgitgadget/issues/new?

Thanks,
Dscho

Quoted 22 lines
Quoted 19 lines

Anyway, the patch looks good. Thanks for following through on this.

builtin/pull.c int cmd_pull(int argc, const char **argv, const char *prefix) · line 1001

Quoted 11 lines
builtin/pull.c +3 -1
@@ -992,10 +993,12 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
                      if (is_descendant_of(merge_head, list)) {
                              /* we can fast-forward this without invoking rebase */
                              opt_ff = "--ff-only";
+                             ran_ff = 1;
                              ret = run_merge();
                      }
              }
-             ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
+             if (!ran_ff)
+                     ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);

It feels like there should be some arrangement of the conditionals that doesn't require setting an extra flag, but I actually don't think there is. And anyway, doing the most obvious and minimal fix here is the right place to start. We don't need more regressions. ;)

Thanks for reviewing it.