Zulip Chat Archive

Stream: mathlib4

Topic: stacks of pull requests


Antoine Chambert-Loir (Apr 02 2024 at 14:09):

Damiano Testa said:

For instance, this is how the latest batch of Joël's "big PR" looks like.

I have a question to @Joël Riou and git experts:

  • what is the procedure to pile up PR like this?
  • what happens every time one PR is accepted after modifications?

Damiano Testa (Apr 02 2024 at 14:21):

I do not know what Joël's approach is, but I would regularly git merge the PRs with modifications and manually take care of breakage.

Damiano Testa (Apr 02 2024 at 14:22):

(At least this is what I normally do when I have PRs that are blocked by other PR.)

Damiano Testa (Apr 02 2024 at 14:23):

I know that you get slightly better merge behaviour if you "start right": I normally branch off bigger changes from smaller ones. I think that simply starting merging a small PR into a bigger one probably sets you up correctly anyway.

Damiano Testa (Apr 02 2024 at 14:24):

I am pretty sure though that, even in the absence of merge conflicts, there is no automation to automatically reduce the diff to master, once the smaller pieces have landed.

Anatole Dedecker (Apr 02 2024 at 14:29):

I think one of the reasons we don't have more documentation on this is that the precise setup depends on everyone's taste. What is common is the following:

  • from GitHub's/bors' point of view, there is no dependence between branch, so if you have multiple PRs depending on one another you have to indicate it in the way suggested when creating a PR
  • at any point you can merge the changes from any branch A into your current branch B by doing git merge origin/A (or git merge A if you specifically want to use your local copy of branch A, but I think in most cases that's not what you want). This includes pulling into B some changes that you made in A (e.g during the review) or, keeping B up do date with origin/master (e.g after A has been merged)

Antoine Chambert-Loir (Apr 02 2024 at 14:30):

So the idea would be:

  • PR a little thing
  • PR that little thing plus something else as a second PR and tag the first PR in the comment
  • etc.
    so that when the PR are accepted in the natural order, each PR is merged in the next one.
    But if some substantial modification is made in the first one, it will have to be echoed many times, that could be a nightmare…

Damiano Testa (Apr 02 2024 at 14:31):

Antoine, yes, this is how I have been doing it.

Damiano Testa (Apr 02 2024 at 14:31):

After all, if you change the first PR, then the subsequent ones will likely have to adapt and there is virtually no support for automating that, right now.

Damiano Testa (Apr 02 2024 at 14:32):

(Not saying that this is ideal, simply that I do not have a better alternative.)

Joël Riou (Apr 02 2024 at 14:36):

@Antoine Chambert-Loir: I have a working draft branch where all the material is, and then I copied chunks of code into new PRs as you suggested.

In this particular case, the dependence tree is not completely trivial: I have a paper where I have written the numbers of the PRs and the names of the branches, so that if one PR is changed, I know which other PRs I need to update.

Antoine Chambert-Loir (Apr 02 2024 at 14:38):

Thanks!

Kevin Buzzard (Apr 02 2024 at 17:53):

@Siddhartha Gadgil this discussion might be relevant to you.

Jireh Loreaux (Apr 03 2024 at 03:00):

Note that if B depends on A, and then A gets merged with lots of changes, and B has not changed, then an easy way to incorporate all the new changes is: merge -X theirs master.

However, take care: If there are merge conflicts other than the ones created by the changes from A, this may not do what you want. Nevertheless, I find it useful.

Jireh Loreaux (Apr 03 2024 at 03:02):

There is an alternate strategy: keep one big PR, make all changes there, and then cherry pick them into the dependencies. I find this harder to do, but sometimes it's better.

Yaël Dillies (Apr 03 2024 at 05:59):

Personally I replace "one big PR" with "a separate repo with instructions for future me"

llllvvuu (Apr 03 2024 at 06:04):

--update-refs option helps with updating the stack: https://andrewlock.net/working-with-stacked-branches-in-git-is-easier-with-update-refs/

also note: don't make the mistake I did of basing each PR off of the previous PR. While that makes the diff cleaner, mathlib or bors seems to automatically delete branches upon merging, which will close any PRs based upon it, with no way to re-open.

Yaël Dillies (Apr 03 2024 at 06:05):

llllvvuu said:

... with no way to re-open.

That's wrong, you can reopen them, but you first need to undo bors' closing of the base branch in the previous PR

llllvvuu (Apr 03 2024 at 06:07):

TIL, thanks!

Joachim Breitner (Apr 03 2024 at 10:58):

Jireh Loreaux said:

Note that if B depends on A, and then A gets merged with lots of changes, and B has not changed, then an easy way to incorporate all the new changes is: merge -X theirs master.

However, take care: If there are merge conflicts other than the ones created by the changes from A, this may not do what you want. Nevertheless, I find it useful.

The safer way is to go back to A's branch, run git merge origin/master (should go through without conflict), then go to B's branch and run git merge -. This two step process helps git to understand the “conflicts” between A's changes on A's branch and A's squashed commit. I've been using this regularly on lean repository.

Joachim Breitner (Apr 03 2024 at 11:01):

At a previous project which only allowed strict squash merges, I automated the process (https://github.com/nomeata/git-post-squash). This won't work on mathlib or lean4, but the above manual two-merge should work reasonably well.

Eric Rodriguez (Apr 03 2024 at 11:20):

I wonder if the Facebook people really are onto something with their stacked diffs or whatever it is

Joachim Breitner (Apr 03 2024 at 11:22):

Is that phabricator? GHC used it for a while, supposedly really much better UI for that use case.

Eric Rodriguez (Apr 03 2024 at 11:28):

Yeah it appears so! Just heard anecdotally of it not sure of the precise differences

Jireh Loreaux (Apr 03 2024 at 15:10):

Joachim Breitner said:

The safer way is to go back to A's branch, run git merge origin/master (should go through without conflict), then go to B's branch and run git merge -. This two step process helps git to understand the “conflicts” between A's changes on A's branch and A's squashed commit. I've been using this regularly on lean repository.

That's nice indeed, but it also comes with a small hiccup. There could be issues with git merge origin/master into A's branch if there were edits made in the GitHub UI before merging, and you don't have the latest version locally (and the branch on GitHub was deleted by bors); this can happen especially with delegated PRs. Nevertheless, this is a minor inconvenience and I think your approach is better.


Last updated: May 02 2025 at 03:31 UTC