Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recommend a procedure for branch management #475

Closed
jaraco opened this issue Aug 20, 2022 · 14 comments
Closed

Recommend a procedure for branch management #475

jaraco opened this issue Aug 20, 2022 · 14 comments

Comments

@jaraco
Copy link
Member

jaraco commented Aug 20, 2022

I discord, @ambv made a simple request:

can you use your own fork for PRs in the future instead of adding branches to python/cpython

And at face value, it sounds like a small request to tweak one's approach in a single project, when in fact the situation is much more complicated.

@jaraco responded

There are advantages to using the canonical repo.
One is that I end up with one fewer repos to manage and keep synced. I already have two machines across which I periodically need to sync multiple branches (main, 3.11, ...). Adding a fork in Github means having yet another code location to manage.
Another advantage is that Github will automatically re-point PRs from an intermediate branch to the main branch when merged. I'm not sure it will do this across forks. That is, I don't think I can create a PR in the canonical repo that targets a branch in a fork and then have that PR re-point to the canonical main once the targeted branch is merged into the canonical repo.
That said, I'd be happy to devise an approach that doesn't cause this consternation. Can you tell me more about the harm experienced by getting those branches? Is it the increased latency due to the extra revisions downloaded or the noise of branch names in the UI output or the cognitive overhead of ignoring those branches or the fact that if everyone adopted this approach it would be unscalable or some combination of those? I'd like to understand the problem better as I'd like to devise a solution that addresses those concerns and my own (or at least capture the concerns for potential future innovation).
I plan to explore creating (once again) a fork in Github, but I would appreciate some advice/guidance on how to keep that fork and the forks of that fork up to date. The current developer guide only goes as far as to say "make forks of forks" without much about how to maintain those forks. In particular, how should I configure the client (how many remotes, how to name those remotes, how to configure those remotes (push/pull)), and how can I automate keeping the upstream branches in sync? Do you have any suggestions on how to manage dependent PRs?
Perhaps since this issue isn't a simple choice, we should track the issues in core-workflow?

This is that issue.

See python/cpython#94528 for an example of a dependent PR (no longer currently dependent).

@jaraco
Copy link
Member Author

jaraco commented Aug 20, 2022

Additional points were discussed but omitted for privacy.

@jaraco
Copy link
Member Author

jaraco commented Aug 20, 2022

Problems

I'll try to elaborate on the problems I see with the forks-of-forks methodology:

lack of guidance, divergent approaches

Although some developers have an intuition for how to manage changes from a private fork, it's also a convention. There's no default practice to follow, as is evidenced by a commiter prefacing their workflow with "My local checkout...". Especially if it's a recommended procedure, it would be nice if the developer documentation provided explicit guidance on a methodology that one could follow. It would include terminology ("origin", "upstream") that could be re-used in discussions to reason about it. A developer could adopt a different workflow, but at least someone following the guidance wouldn't have to make these decisions about concerns that haven't affected them.

dependent PR tracking

Github has a feature that allows one PR to target the branch of another PR on which it depends, and when that PR is merged, the dependent PR is re-targeted to the merge target of the original PR, allowing for the creation of series of changes that depend on each other but which should be merged separately. This feature is particularly valuable when introducing a deprecation, where the deprecation step and the removal step are necessarily separated by time between releases.

It's not obvious if Github supports repointing a PR from one org to another based on dependencies. In fact, I'm not even sure that would make sense, because the dependent PR couldn't be created in the origin project.

continuous integration missing

When pushing changes to one's private fork, there's no CI, so one must necessarily create a PR in order to get some confidence in the viability of the code. When pushing to a canonical repo, the CI is run automatically.

It appears it's just a matter of enabling the workflows in the private fork to enable CI.

UI navigation is more difficult

Something of a nitpick, when working on a change, one needs to navigate to the fork. However, when using gh browse, it takes me to the canonical repo, where there's no quick way to navigate to the fork. One must manually override the URL with the user's name or follow the dropdown to "your existing forks" (two additional clicks). In other words, even Github's own cli treats the "upstream" as primary even a fork exists as "origin".

custody of changes

By my recollection, if a PR is submitted from a fork and that fork is deleted, the PR is closed and the changes are lost. It becomes the responsibility of the fork owner to maintain a dependent relationship of their repo on the upstream repo.

It seems risky for a project to potentially lose a contribution because the contributor pulled their fork.

Consider for example python/cpython#94528, which because it's marked DO-NOT-MERGE until Python 3.14, will be around for some time. Do we want to rely on the contributor to maintain their fork for that duration, even if they may not be around to update it when it's ready to be merged?

stale main

It's always the case that clones of the repo will be stale as soon as new commits are accepted to upstream/main. By introducing an intermediate fork, it exacerbates this problem. Even if one sync's main to a local checkout, the intermediate fork is always stale unless one takes action to keep it up to date. The same applies for other official branches (3.x).

Maybe it's okay for the intermediate forks to always be stale, but I personally find it annoying that it exists, especially when not in use.

mistaken PRs

I've more than once run into an issue where I'll attempt to submit a PR for a change I've made and accidentally submit the PR to the fork, introducing noise and toil. Those failed PRs get linked to issues and send notifications, magnifying the mistake.

deviation from workflows in other projects

Many projects follow a more simple methodology, simply cloning the canonical repo and pushing branches to it. There's one remote and none of the problems included herein. If a developer works on one of those projects and cpython, they need to maintain mental models of both forms and determine which form is in use for a given project. It adds to the cognitive burden of switching between projects, or they must adopt the CPython methodology across all projects and the additional overhead/burden that brings. And for self-hosted projects, it's not possible to create a fork (e.g. I can't fork jaraco/keyring).

shared development

Something we don't do enough of is pair programming or shared development, and the private fork model is an impediment to pair development. Users typically don't grant access of their private fork to other individuals, and even if they did, it's an asymmetric relationship, with one person having custody of the code. The Github PR mechanism does help in this regard - if one is at the stage of a review, the PR workflow might grant others access to push additional changes.

For branches in the canonical repo, however, it's straightforward and a symmetric relationship, with developers having a simple relationship to any branch on which they may share development work.

branch proliferation (non-problem)

At first, I thought that the use of multiple forks would exacerbate branch proliferation, but in practice, I don't think it does, and indeed, private forks may help alleviate the problem of branch proliferation by grouping branches by contributor (thereby hiding irrelevant changes across contributors).

@jaraco
Copy link
Member Author

jaraco commented Aug 20, 2022

Basically all workflows going outside the norm wind up in [a bad state]. It has features, most don't know about them and those that do may not really won't understand how to use them or know when their understanding is inaccurate. So my advice is: KISS principal: stay away.

If we're following the KISS principle, the simplest solution is one with the least proliferation of forks, where everyone shares the same remote and there's one remote repo to reason about. For someone just getting familiar with version control, a single remote is the only workflow. For smaller projects with a few developers, pushing to a single repo is the norm. Even some large companies have a single monorepo with branches right off that repo. The Mercurial project uses Heptapod and all contributors push branches direct to the main repo (no private forks).

I understand that for CPython, and many large Github projects, the private fork (fork of forks) model is the norm, but that doesn't mean it has to be the case.

dependent PRs (aka PR chains) are a feature GitHub simply lacks.

This is demonstrably false. As observed in python/cpython#94528, when merging the PR on which that one depended, it automatically repointed the target:

image

I stumbled on this feature earlier this year and was pleased to see that it was a feature that Github was working on. Here's a blog describing in detail how one might use it. That blog and other resources acknowledge that the functionality exposes some ambiguity and has room for improvement. It may be the case that this feature only works if the developer is pushing branches to the canonical repo. If the methodology that CPython uses prohibits or discourages this type of workflow, it's a major disadvantage to everything but the most simple contributions.

@jaraco
Copy link
Member Author

jaraco commented Aug 20, 2022

To better understand the motivation for a private-fork recommendation, I'd still like to see answers to these questions:

Can you tell me more about the harm experienced by getting those branches? Is it the increased latency due to the extra revisions downloaded or the noise of branch names in the UI output or the cognitive overhead of ignoring those branches or the fact that if everyone adopted this approach it would be unscalable or some combination of those?

In particular, what is the harm if a handful of developers push direct to the canonical repo? What is the harm if everyone does it?

@ambv
Copy link

ambv commented Aug 20, 2022

what is the harm if a handful of developers push direct to the canonical repo? What is the harm if everyone does it?

The harm is that it's noise. When you clone the repo, you're not getting any of my in-flight changes because I keep them in my fork. Unless you go and look for an open PR, those changes don't get in the way of your own work.

They do get in the way because now you're sharing a flat namespace for branches with random other developers. There is no convention for naming PR branches and even if we put one in the devguide, automation will ignore it, the Github UI will ignore it, and -- guaranteed! -- some core developers will ignore it.

All branches on the main repository for a project with >100 committers look official and long-living. This is not true for branches only created out of convenience by a handful of core developers. They aren't official, they aren't long-living projects, as we require PRs for every change (besides some release management shenanigans).

There is already a pre-existing recommendation against pushing to the main repository:
Screen Shot 2022-08-20 at 17 47 31

As such, this issue here isn't about choosing a recommendation, it's about whether we want to change the existing recommendation to allow for branches littering the main repository. I'm -1 to such a change.

@jaraco
Copy link
Member Author

jaraco commented Aug 20, 2022

There is already a pre-existing recommendation against pushing to the main repository.

Thanks for this reference. I'd missed it when explicitly looking for it. It may be worth linking this recommendation from other locations so it's more prominent.

Thanks also for articulating the harm. That's helpful for making tradeoffs between that and other concerns.

I'm -1 to such a change.

It feels to me like you're weighting the concern of noise far greater than any of the concerns raised above (or discounting them entirely), including concerns that have no feasible solution in a fork-only scenario. In one sentence, you've declared "wontfix" on a whole suite of problems. Was that your intention?

@serhiy-storchaka
Copy link
Member

$ git branch | wc -l
331

Do you want to get all these branches on your local computer? And there are 20-30 other active core developers.

@gpshead
Copy link
Member

gpshead commented Aug 21, 2022

To summarize: GitHub sucks for serious development practices. We knew that going in. It still beat what we had by a long shot and enabled new contributors - https://peps.python.org/pep-0512/.

An issue isn't a good place for these conversations. Use discuss.python.org.

This narrow scope issue looks to me like one merely to clarify our existing defacto "don't push branches on purpose" community standard in whatever committer dev guide docs we have if needed.

Nobody is debating that GH lacks productivity features many of us take for granted in professional environments. But this isn't the place for it. That can't be planned enumerated and resolved in an issue tracker.

@gpshead
Copy link
Member

gpshead commented Aug 21, 2022

Also: you quoted people from a private chat. Sure, you later edited that to "remove" the content. But it was already too late - it was sent out in emails and remained available in the edit history on the comment. I've deleted the old revisions of the comment edit history that I found as GH happens to let me. (But all of that has been sent via email to anyone watching the full firehose of the repo or live scraping).

In the future please don't paste conversation snippets from a private forum into another access level one without explicit permission from everyone first.

@ezio-melotti
Copy link
Member

lack of guidance, divergent approaches

[...] Especially if it's a recommended procedure, it would be nice if the developer documentation provided explicit guidance on a methodology that one could follow. It would include terminology ("origin", "upstream") that could be re-used in discussions to reason about it. [...]

These are documented and used throughout the docs:

dependent PR tracking

Github has a feature that allows one PR to target the branch of another PR on which it depends, and when that PR is merged, the dependent PR is re-targeted to the merge target of the original PR, [...]

It would be interesting to figure out how to handle such workflow and document it in the devguide. Locally you would usually create a branch A from main, and then a branch B from A, but once you push these branches, there are a few more variables involved:

  • whether you push them on your fork or upstream
  • the target branch of the PR (which can also be updated)
  • the merge type enforced by the upstream repo (squash, merge, rebase)

continuous integration missing

[...] It appears it's just a matter of enabling the workflows in the private fork to enable CI.

There is a related discussion here: python/bedevere#461 (comment)

custody of changes

By my recollection, if a PR is submitted from a fork and that fork is deleted, the PR is closed and the changes are lost. It becomes the responsibility of the fork owner to maintain a dependent relationship of their repo on the upstream repo.

I haven't found anything official in the GitHub docs (there is an article about what happens to the forks when upstream is deleted, but not what happens to PRs when the fork is deleted.

I give it a try in zware/test#7 and even though deleting my fork closed the PR, the changes still seem visible and there is a "Reopen" button.

[...] Do we want to rely on the contributor to maintain their fork for that duration, even if they may not be around to update it when it's ready to be merged?

If they allow maintainers to push changes to the branch, then this might not be an issue (even though I'm not sure if it's possible after the fork is deleted). I guess another option would be to create a new branch off of the one created by the OP.

stale main

[...] Maybe it's okay for the intermediate forks to always be stale, but I personally find it annoying that it exists, especially when not in use.

Other than the annoyance this might cause, this is generally not an issue. Locally I pull main from upstream, make changes in a new branch, push the branch on my fork, and create the PR. The status of the main branch of my fork is inconsequential. It's also possible to update it with just a click from the GitHub UI, if you want to update it every once in a while.

mistaken PRs

I've more than once run into an issue where I'll attempt to submit a PR for a change I've made and accidentally submit the PR to the fork, introducing noise and toil. Those failed PRs get linked to issues and send notifications, magnifying the mistake.

This used to happened to me too occasionally, but not anymore. When you push the branch to your fork, it shows you a link that you can follow to create the PR upstream. Alternatively you can go to the main page of the upstream repo, and a green button at the top will let you create a PR from the branch you just pushed to the fork. Both these solutions already have the target branch set automatically to the upstream main, so you don't have to fiddle with it.

deviation from workflows in other projects

[...] If a developer works on one of those projects and cpython, they need to maintain mental models of both forms and determine which form is in use for a given project.

This is true, but expected. I work on a number of projects, some of which I have access to (and I can push branches/commit to main, even if I don't always do), and many where I'm merely an external contributor with no write access and I have to go through my fork. If anything, going through the fork would be the solution that works for all cases, regardless of permissions.

@ambv
Copy link

ambv commented Aug 21, 2022

Nobody is debating that GH lacks productivity features many of us take for granted in professional environments. But this isn't the place for it. That can't be planned enumerated and resolved in an issue tracker.

Definitely not on a Github issue tracker 😂

@hugovk
Copy link
Member

hugovk commented Aug 21, 2022

In particular, what is the harm if a handful of developers push direct to the canonical repo? What is the harm if everyone does it?

CI resources are limited per org or user account where the repo is (e.g. 20 concurrent jobs).

If everyone pushed branches directly to the upstream repo, the CI would get backed up and it would take longer to get feedback from tests, for them and all other PR authors.

@jaraco
Copy link
Member Author

jaraco commented Aug 28, 2022

Thanks for all the tips. I'm working on migrating my workflows to align with the recommendations.

One thing I noticed when following the current guidance is that the main branch doesn't track upstream, but instead tracks origin, so git pull leaves main stale:

 draft $ git clone gh://jaraco/cpython
Cloning into 'cpython'...
remote: Enumerating objects: 908778, done.
remote: Total 908778 (delta 0), reused 0 (delta 0), pack-reused 908778
Receiving objects: 100% (908778/908778), 492.95 MiB | 4.64 MiB/s, done.
Resolving deltas: 100% (720624/720624), done.
 draft $ cd cpython
 cpython main $ git remote add upstream gh://python/cpython
 cpython main $ git pull
Already up to date.
 cpython main $ git pull upstream
remote: Enumerating objects: 1574, done.
remote: Counting objects: 100% (966/966), done.
remote: Compressing objects: 100% (90/90), done.
remote: Total 1574 (delta 899), reused 923 (delta 876), pack-reused 608
Receiving objects: 100% (1574/1574), 2.18 MiB | 10.00 MiB/s, done.
Resolving deltas: 100% (1123/1123), completed with 385 local objects.
From https://github.com/python/cpython
 * [new branch]            3.10                                     -> upstream/3.10
 * [new branch]            3.11                                     -> upstream/3.11
 * [new branch]            3.7                                      -> upstream/3.7
 * [new branch]            3.8                                      -> upstream/3.8
 * [new branch]            3.9                                      -> upstream/3.9
 * [new branch]            add-to-asyncio-proj                      -> upstream/add-to-asyncio-proj
 * [new branch]            gh-93963/remove-importlib-resources-abcs -> upstream/gh-93963/remove-importlib-resources-abcs
 * [new branch]            main                                     -> upstream/main
 * [new branch]            refactor-wait_for                        -> upstream/refactor-wait_for
 * [new branch]            shared-testcase                          -> upstream/shared-testcase
You asked to pull from the remote 'upstream', but did not specify
a branch. Because this is not the default configured remote
for your current branch, you must specify a branch on the command line.

I think there's a step missing to set branch.main.remote=upstream. That got configured when I ran gh repo fork to create the fork and allowed it to configure the remotes.

 cpython main $ git config --local branch.main.remote upstream
 cpython main $ git pull
Updating e0d54a4a79..e860e521ec
Fast-forward
 .github/CODEOWNERS                                                               |    4 +-
 .gitignore                                                                       |    2 +
 Doc/c-api/init.rst                                                               |   24 +
 Doc/c-api/typeobj.rst                                                            |    6 +-
 Doc/data/refcounts.dat                                                           |    8 +
 Doc/howto/logging-cookbook.rst                                                   |   82 ++++
 Doc/includes/sqlite3/rowclass.py                                                 |   14 -
 Doc/library/asyncio-task.rst                                                     |    2 +-
 Doc/library/bisect.rst                                                           |    2 +-
 Doc/library/csv.rst                                                              |    4 +
 Doc/library/functions.rst                                                        |    4 +
 Doc/library/io.rst                                                               |    8 +-
 Doc/library/itertools.rst                                                        |   19 +
 Doc/library/json.rst                                                             |   43 ++
 Doc/library/logging.handlers.rst                                                 |    6 +
 Doc/library/multiprocessing.rst                                                  |   10 +
 Doc/library/pathlib.rst                                                          |    2 +-
 Doc/library/sqlite3.rst                                                          |  251 +++++-----
 Doc/library/threading.rst                                                        |   32 +-
 Doc/reference/lexical_analysis.rst                                               |   33 +-
 Doc/tutorial/datastructures.rst                                                  |    2 +-
 Doc/using/configure.rst                                                          |    2 +-
 Include/cpython/ceval.h                                                          |    2 +
 Include/internal/pycore_ceval.h                                                  |    3 +
 Include/internal/pycore_compile.h                                                |    5 +
 Include/internal/pycore_frame.h                                                  |    4 +-
 Include/internal/pycore_global_objects.h                                         |    2 +
 Include/internal/pycore_global_strings.h                                         |    2 +
 Include/internal/pycore_pystate.h                                                |    7 +-
 Include/internal/pycore_runtime_init_generated.h                                 |   14 +
 Lib/argparse.py                                                                  |    4 +-
 Lib/asyncio/streams.py                                                           |    4 +-
 Lib/csv.py                                                                       |    4 +
 Lib/inspect.py                                                                   |    6 +-
 Lib/json/__init__.py                                                             |   52 +-
 Lib/logging/__init__.py                                                          |    2 +-
 Lib/logging/handlers.py                                                          |   21 +-
 Lib/test/support/bytecode_helper.py                                              |   93 ++++
 Lib/test/test_argparse.py                                                        |    7 +
 Lib/test/test_builtin.py                                                         |    5 +
 Lib/test/test_capi.py                                                            |   15 +
 Lib/test/test_compile.py                                                         |    5 +-
 Lib/test/test_coroutines.py                                                      |   24 +
 Lib/test/test_csv.py                                                             |   28 ++
 Lib/test/test_imp.py                                                             |    6 +-
 Lib/test/test_importlib/test_abc.py                                              |    4 +-
 Lib/test/test_json/__init__.py                                                   |    1 +
 Lib/test/test_json/test_attrdict.py                                              |  145 ++++++
 Lib/test/test_launcher.py                                                        |    8 +-
 Lib/test/test_logging.py                                                         |    8 +
 Lib/test/test_minidom.py                                                         |   16 +-
 Lib/test/test_peepholer.py                                                       |   78 ++-
 Lib/test/test_socket.py                                                          |   15 +-
 Lib/test/test_source_encoding.py                                                 |  105 ++--
 Lib/test/test_threading.py                                                       |   59 +++
 Lib/test/test_unicodedata.py                                                     |   20 +-
 Lib/test/test_unittest/test_async_case.py                                        |    9 +-
 Lib/threading.py                                                                 |   27 +-
 Lib/xml/dom/minidom.py                                                           |    2 +
 Makefile.pre.in                                                                  |   51 +-
 Misc/ACKS                                                                        |    3 +
 Misc/NEWS.d/next/Build/2022-08-15-10-56-07.gh-issue-95973.Bsswsc.rst             |    2 +
 Misc/NEWS.d/next/Build/2022-08-26-11-50-03.gh-issue-96269.x_J5h0.rst             |    3 +
 Misc/NEWS.d/next/C API/2022-06-06-16-04-14.gh-issue-93503.MHJTu8.rst             |    7 +
 Misc/NEWS.d/next/Core and Builtins/2022-08-15-20-52-41.gh-issue-93678.X7GuIJ.rst |    1 +
 Misc/NEWS.d/next/Core and Builtins/2022-08-18-13-47-59.gh-issue-96046.5Hqbka.rst |    4 +
 Misc/NEWS.d/next/Core and Builtins/2022-08-22-21-33-28.gh-issue-96187.W_6SRG.rst |    2 +
 Misc/NEWS.d/next/Core and Builtins/2022-08-24-14-30-26.gh-issue-96237.msif5f.rst |    5 +
 Misc/NEWS.d/next/Documentation/2022-08-19-17-07-45.gh-issue-96098.nDp43u.rst     |    3 +
 Misc/NEWS.d/next/Library/2022-04-01-09-43-54.bpo-32547.NIUiNC.rst                |    1 +
 Misc/NEWS.d/next/Library/2022-05-09-21-31-41.gh-issue-92445.tJosdm.rst           |    3 +
 Misc/NEWS.d/next/Library/2022-08-20-12-56-15.gh-issue-96145.8ah3pE.rst           |    1 +
 Misc/NEWS.d/next/Library/2022-08-22-13-54-20.gh-issue-96175.bH7zGU.rst           |    1 +
 Misc/NEWS.d/next/Library/2022-08-22-18-42-17.gh-issue-96159.3bFU39.rst           |    1 +
 Misc/NEWS.d/next/Library/2022-08-23-13-30-30.gh-issue-96172.7WTHer.rst           |    3 +
 Misc/NEWS.d/next/Library/2022-08-27-14-38-49.gh-issue-90467.VOOB0p.rst           |    2 +
 Misc/NEWS.d/next/Tests/2022-08-22-14-59-42.gh-issue-95243.DeD66V.rst             |    3 +
 Modules/_testinternalcapi.c                                                      |   30 +-
 Modules/atexitmodule.c                                                           |    2 +-
 Modules/clinic/_testinternalcapi.c.h                                             |   68 +++
 Modules/makesetup                                                                |    2 +-
 Modules/unicodedata_db.h                                                         | 1107 +++++++++++++++++++++--------------------
 Objects/codeobject.c                                                             |    2 +-
 Objects/frameobject.c                                                            |    8 +-
 Objects/object_layout.md                                                         |   82 ++++
 Objects/object_layout_312.gv                                                     |   50 ++
 Objects/object_layout_312.png                                                    |  Bin 0 -> 30688 bytes
 Objects/object_layout_full_312.gv                                                |   25 +
 Objects/object_layout_full_312.png                                               |  Bin 0 -> 17092 bytes
 Objects/typeobject.c                                                             |   35 +-
 Objects/unicodeobject.c                                                          |   39 +-
 PCbuild/_freeze_module.vcxproj                                                   |    1 +
 PCbuild/_freeze_module.vcxproj.filters                                           |    3 +
 PCbuild/pythoncore.vcxproj                                                       |    2 +-
 PCbuild/pythoncore.vcxproj.filters                                               |    6 +-
 Python/ceval.c                                                                   |  701 +++-----------------------
 Python/ceval_gil.c                                                               |  986 +++++++++++++++++++++++++++++++++++++
 Python/ceval_gil.h                                                               |  333 -------------
 Python/clinic/sysmodule.c.h                                                      |   26 +-
 Python/compile.c                                                                 |  319 +++++++++---
 Python/frame.c                                                                   |    4 +-
 Python/sysmodule.c                                                               |   61 +++
 Tools/c-analyzer/c_parser/info.py                                                |    1 +
 Tools/c-analyzer/cpython/_analyzer.py                                            |   72 +++
 Tools/c-analyzer/cpython/_parser.py                                              |    1 -
 Tools/c-analyzer/cpython/globals-to-fix.tsv                                      |    4 +-
 Tools/c-analyzer/cpython/ignored.tsv                                             | 1541 +---------------------------------------------------------
 Tools/gdb/libpython.py                                                           |    2 +-
 Tools/msi/build.bat                                                              |   19 +-
 Tools/msi/buildrelease.bat                                                       |   43 +-
 Tools/unicode/makeunicodedata.py                                                 |   32 +-
 configure                                                                        |   86 +++-
 configure.ac                                                                     |   33 +-
 113 files changed, 3726 insertions(+), 3468 deletions(-)
 delete mode 100644 Doc/includes/sqlite3/rowclass.py
 create mode 100644 Lib/test/test_json/test_attrdict.py
 create mode 100644 Misc/NEWS.d/next/Build/2022-08-15-10-56-07.gh-issue-95973.Bsswsc.rst
 create mode 100644 Misc/NEWS.d/next/Build/2022-08-26-11-50-03.gh-issue-96269.x_J5h0.rst
 create mode 100644 Misc/NEWS.d/next/C API/2022-06-06-16-04-14.gh-issue-93503.MHJTu8.rst
 create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-08-15-20-52-41.gh-issue-93678.X7GuIJ.rst
 create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-08-18-13-47-59.gh-issue-96046.5Hqbka.rst
 create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-08-22-21-33-28.gh-issue-96187.W_6SRG.rst
 create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-08-24-14-30-26.gh-issue-96237.msif5f.rst
 create mode 100644 Misc/NEWS.d/next/Documentation/2022-08-19-17-07-45.gh-issue-96098.nDp43u.rst
 create mode 100644 Misc/NEWS.d/next/Library/2022-04-01-09-43-54.bpo-32547.NIUiNC.rst
 create mode 100644 Misc/NEWS.d/next/Library/2022-05-09-21-31-41.gh-issue-92445.tJosdm.rst
 create mode 100644 Misc/NEWS.d/next/Library/2022-08-20-12-56-15.gh-issue-96145.8ah3pE.rst
 create mode 100644 Misc/NEWS.d/next/Library/2022-08-22-13-54-20.gh-issue-96175.bH7zGU.rst
 create mode 100644 Misc/NEWS.d/next/Library/2022-08-22-18-42-17.gh-issue-96159.3bFU39.rst
 create mode 100644 Misc/NEWS.d/next/Library/2022-08-23-13-30-30.gh-issue-96172.7WTHer.rst
 create mode 100644 Misc/NEWS.d/next/Library/2022-08-27-14-38-49.gh-issue-90467.VOOB0p.rst
 create mode 100644 Misc/NEWS.d/next/Tests/2022-08-22-14-59-42.gh-issue-95243.DeD66V.rst
 create mode 100644 Modules/clinic/_testinternalcapi.c.h
 create mode 100644 Objects/object_layout.md
 create mode 100644 Objects/object_layout_312.gv
 create mode 100644 Objects/object_layout_312.png
 create mode 100644 Objects/object_layout_full_312.gv
 create mode 100644 Objects/object_layout_full_312.png
 create mode 100644 Python/ceval_gil.c
 delete mode 100644 Python/ceval_gil.h

@jaraco
Copy link
Member Author

jaraco commented Aug 28, 2022

I may or may not follow up on chained PRs. And the documentation is actually quite complete. I'm unsure where I got the impression that the documentation did not capture some basic guidance on branching strategy.

@jaraco jaraco closed this as completed Aug 28, 2022
ezio-melotti added a commit to python/devguide that referenced this issue Oct 30, 2022
* Update docs to configure 'main' to pull from 'upstream'. Ref python/core-workflow#475.

* Quote 'main'.

Co-authored-by: Ezio Melotti <ezio.melotti@gmail.com>

* Direct 'upstream' push to the user's fork. Now pull comes from upstream and push goes to origin.

* Apply the changes also to the git boot camp.

* Prefer https for upstream fetch.

Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM>

* Update expectations and sync guidance for d7e9065. Remove superfluous .git from https.

Co-authored-by: Ezio Melotti <ezio.melotti@gmail.com>
Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM>
kitarefake added a commit to kitarefake/devguide that referenced this issue Jul 15, 2024
* Update docs to configure 'main' to pull from 'upstream'. Ref python/core-workflow#475.

* Quote 'main'.

Co-authored-by: Ezio Melotti <ezio.melotti@gmail.com>

* Direct 'upstream' push to the user's fork. Now pull comes from upstream and push goes to origin.

* Apply the changes also to the git boot camp.

* Prefer https for upstream fetch.

Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM>

* Update expectations and sync guidance for d7e9065cbf37. Remove superfluous .git from https.

Co-authored-by: Ezio Melotti <ezio.melotti@gmail.com>
Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants