Git bootcamp and cheat sheet#
Note
This section provides instructions on common tasks in CPython’s workflow. It’s designed to assist new contributors who have some familiarity with Git and GitHub.
If you are new to Git and GitHub, please become comfortable with these instructions before submitting a pull request. As there are several ways to accomplish these tasks using Git and GitHub, this section reflects one method suitable for new contributors. Experienced contributors may desire a different approach.
In this section, we will go over some commonly used Git commands that are relevant to CPython’s workflow.
Note
Setting up Git aliases for common tasks can be useful to you. You can get more information about that in Git documentation
Forking CPython GitHub repository#
You will only need to do this once.
Press
Forkon the top right.When asked where to fork the repository, choose to fork it to your username.
Your forked CPython repository will be created at https://github.com/<username>/cpython.
Cloning a forked CPython repository#
You will only need to do this once per machine. From your command line:
git clone git@github.com:<username>/cpython.git
It is also recommended to configure an upstream remote repository:
cd cpython
git remote add upstream https://github.com/python/cpython
You can also use SSH-based or HTTPS-based URLs.
Configure the remotes#
Configure git to pull main from the upstream remote:
git config --local branch.main.remote upstream
Since one should never attempt to push to upstream, configure
git to push always to origin:
git remote set-url --push upstream git@github.com:<username>/cpython.git
Listing the remote repositories#
To list the remote repositories that are configured, along with their URLs:
git remote -v
You should have two remote repositories: origin pointing to your forked CPython repository,
and upstream pointing to the official CPython repository:
origin git@github.com:<username>/cpython.git (fetch)
origin git@github.com:<username>/cpython.git (push)
upstream https://github.com/python/cpython (fetch)
upstream git@github.com:<username>/cpython.git (push)
To verify the upstream for main:
git config branch.main.remote
It should emit upstream, indicating to track/pull changes for main from the
upstream remote.
Setting up your name and email address#
git config --global user.name "Your Name"
git config --global user.email your.email@example.com
The --global flag sets these parameters globally while
the --local flag sets them only for the current project.
Enabling autocrlf on Windows#
The autocrlf option will fix automatically any Windows-specific line endings.
This should be enabled on Windows, since the public repository has a hook which
will reject all changesets having the wrong line endings:
git config --global core.autocrlf input
Creating and switching branches#
Important
Never commit directly to the main branch.
Create a new branch from main and switch to it:
git switch -c <branch-name> main
This is equivalent to:
# create a new branch from main
git branch <branch-name> main
# switch to the new branch
git switch <branch-name>
To find the branch you are currently on:
git branch
The current branch will have an asterisk next to the branch name. Note, this will only list all of your local branches.
To list all the branches, including the remote branches:
git branch -a
To switch to a different branch:
git switch <another-branch-name>
Other releases are just branches in the repository. For example, to work
on the 2.7 release from the upstream remote:
git switch -c 2.7 upstream/2.7
Deleting branches#
To delete a local branch that you no longer need:
git switch main
git branch -D <branch-name>
To delete a remote branch:
git push origin -d <branch-name>
You may specify more than one branch for deletion.
Renaming branch#
The CPython repository’s default branch was renamed from master to
main after the Python 3.10b1 release.
If you have a fork on GitHub (as described in Forking CPython GitHub repository) that was created before the rename, you should visit the GitHub page for your fork to rename the branch there. You only have to do this once. GitHub should provide you with a dialog for this. If it doesn’t (or the dialog was already dismissed), you can rename the branch in your fork manually by following these GitHub instructions.
After renaming the branch in your fork, you need to update any local clones as well. This only has to be done once per clone:
git branch -m master main
git fetch origin
git branch -u origin/main main
git remote set-head origin -a
(GitHub also provides these instructions after you rename the branch.)
If you do not have a fork on GitHub, but rather a direct clone of the main repo created before the branch rename, you still have to update your local clones. This still only has to be done once per clone. In that case, you can rename your local branch as follows:
git branch -m master main
git fetch upstream
git branch -u upstream/main main
Staging and committing files#
To show the current changes:
git statusTo stage the files to be included in your commit:
git add -p # to review and add changes to existing files git add <filename1> <filename2> # to add new files
To commit the files that have been staged (done in step 2):
git commit -m "This is the commit message."
Reverting changes#
To revert changes to a file that has not been committed yet:
git checkout <filename>
If the change has been committed, and now you want to reset it to whatever the origin is at:
git reset --hard HEAD
Stashing changes#
To stash away changes that are not ready to be committed yet:
git stash
To re-apply the last stashed change:
git stash pop
Comparing changes#
View all non-commited changes:
git diff
Compare to the main branch:
git diff main
Exclude generated files from diff using an attr
pathspec (note the
single quotes):
git diff main ':(attr:!generated)'
Exclude generated files from diff by default:
git config diff.generated.binary true
The generated attribute is
defined in .gitattributes, found in the repository root.
Pushing changes#
Once your changes are ready for a review or a pull request, you will need to push them to the remote repository.
git switch <branch-name>
git push origin <branch-name>
Creating a pull request#
Press the
New pull requestbutton.Click the
compare across forkslink.Select the base repository:
python/cpythonand base branch:main.Select the head repository:
<username>/cpythonand head branch: the branch containing your changes.Press the
Create pull requestbutton.
You should include the issue number in the title of the PR,
in the format gh-NNNNN: <PR Title>.
Linking to issues and pull requests#
You can link to issues and pull requests using gh-NNNNN (this form is
preferred over #NNNNN). If the reference appears in a list, the link
will be expanded to show the status and title of the issue/PR.
When you create a PR that includes gh-NNNNN in the title, bedevere
will automatically add a link to the issue in the first message.
In addition, pull requests support special keywords that can be used to link to an issue and automatically close it when the PR is merged. However, issues often require multiple PRs before they can be closed (e.g. backports to other branches), so this features is only useful if you know for sure that a single PR is enough to address and close the issue.
Updating your CPython fork#
Scenario:
You forked the CPython repository some time ago.
Time passes.
There have been new commits made in the upstream CPython repository.
Your forked CPython repository is no longer up to date.
You now want to update your forked CPython repository to be the same as the upstream CPython repository.
Please do not try to solve this by creating a pull request from
python:main to <username>:main as the authors of the patches will
get notified unnecessarily.
Solution:
git switch main
git pull upstream main
git push origin main
Note
For the above commands to work, please follow the instructions found in the Get the source code section.
Another scenario:
You created
some-branchsome time ago.Time passes.
You made some commits to
some-branch.Meanwhile, there are recent changes from the upstream CPython repository.
You want to incorporate the recent changes from the upstream CPython repository into
some-branch.
Solution:
git switch some-branch
git fetch upstream
git merge upstream/main
git push origin some-branch
You may see error messages like “CONFLICT” and “Automatic merge failed;” when
you run git merge upstream/main.
When it happens, you need to resolve conflict. See these articles about resolving conflicts:
Applying a patch to Git#
Scenario: