How to Submit a Pull Request
A Pull Request (PR), also commonly known as a Merge Request, is a mechanism to “pull” code from one repository into another one and merge the change into the source repository.
Before we go much further, let us take a few minutes to describe what happened when you Set up a Development Environment and to define a few terms that will help with further instructions. Starting with a diagram of the setup of the three locations where code resides:
As part of the Compiling Freeciv21 process, one of the programs installed is git
. This program
is used to interact with the varying places that code can reside. The git
program has a relatively
standard way of referring to things that are in the diagram. If you have not worked with git
much,
it is highly recommended you read the first three chapters of the
Pro Git Book before continuing.
Upstream: This refers to the source (original) repository. For us this is the Longturn Freeciv21 or Games repositories.
Origin: This refers to the fork you made in your own personal GitHub account.
Local: This is not a
git
term per se, but is a well understood industry standard way of referring to the copy of code on a person’s computer. This is where the changes are made and eventually make it back up to origin and over to upstream via a Pull Request.
The arrows represent the path that updates (e.g. changes) of files occur.
File updates from Upstream are downloaded (pulled) to Local.
After changes are made, file updates from Local are uploaded (pushed) to Origin.
File updates from Origin are transferred to Upstream laterally via a Pull Request.
With this in mind, submitting a Pull Request generally entails these steps:
Update Local with the latest from Upstream.
Create a branch from Upstream.
Edit files as needed in Local.
Push the changes in a commit to Origin.
Requesting a Pull Request from Origin to Upstream.
1. Update Local with the Latest Updates from Upstream
Assuming you are in the appropriate Local directory, issue these commands to get the latest code from Upstream:
~/GitHub/freeciv21$ git checkout master
~/GitHub/freeciv21$ git pull upstream master --ff-only
The first command sets the working branch to master
on Local. The second command downloads the changes
from Upstream to Local.
Note
If you want git pull
to always do a “fast-forward” (which is preferred), you can set a local
repository configuration option with this command: git config --local pull.ff only
. You only need to
do this once. After the config is set, you can drop the --ff-only
option from the last command
above.
2. Create a Branch from Upstream
Now that things are all up to date with the latest code, let’s create a branch to do your work in.
~/GitHub/freeciv21$ git checkout -b [some_feature] upstream/master
The tag [some_feature]
should be replaced by something that matches what you are planning to work on.
For example, it could be as easy as issue_123
, meaning that this branch is changes to resolve GitHub
Issue 123 in the Freeciv21 Issues list.
Attention
It is recommended to never make changes in the master
branch. Best practice is to make changes in a
different branch. This makes it much easier to evaluate changes as part of the Pull Request evaluation
process and keeps things much cleaner from a repository management perspective.
3. Edit Files as Needed in Local
This step is as simple as it sounds. Edit the files in the Local area as needed to complete the work you want to work on. Depending on what you are doing, it is likely that you will want to compile the code to test your work. Here are some quick steps that you can use to run through quick compiles of code and/or documentation updates.
~/GitHub/freeciv21$ rm -Rf build
~/GitHub/freeciv21$ cmake . -B build -G Ninja -DCMAKE_INSTALL_PREFIX=$PWD/build/install -DCMAKE_BUILD_TYPE=Debug
~/GitHub/freeciv21$ cmake --build build
~/GitHub/freeciv21$ cmake --build build --target install
~/GitHub/freeciv21$ cmake --build build --target docs
The first command cleans out the build
directory to start with a fresh configuration. The second
command runs a configure process and then sets things up to do the install portion inside the same
build
directory, keeping work in progress all in one place.
The third and fourth commands compile and install the code. The last command is used to generate the
documentation that you are reading right now. You can open ./build/docs/index.html
to see a locally
generated copy of the documentation prior to pushing a change up.
Note
You do not have to start from the top of the list of commands every time you want to check on things. If you
have already done a full pass to install and then make some more changes, you can go straight to the build
and install commands. The cmake
program is smart enough to determine what changed and only compile
those files again. It’s much faster to do things this way!
One more thing to note here, this section is only talking about making changes to the Freeciv21 repository and has not really talked about the Games repository, nor talked about Rulesets or Tilesets. In this scenario, there is not any compiling going on. The Ruleset or Tileset editor is editing files and testing locally. The Longturn Games repository is effectively a repository of Rulesets.
4. Push the Changes in a Commit to Origin
Now the moment arrives, you have a fully completed set of changes you want to share! The next step is to
evaluate what all has changed and build a commit. A commit is an organized set of changes all bundled up
together. There are lots of ways to organize commits, for this set of instructions we are going to assume
that all of your changes are going to be bundled into one commit. If you want to learn how to build more than
one commit into a Pull Request then you can read about git add and
git commit. Most of the work is handled with git add
.
~/GitHub/freeciv21$ git status
~/GitHub/freeciv21$ git add --all
~/GitHub/freeciv21$ git clang-format --binary /usr/bin/clang-format-11
~/GitHub/freeciv21$ git add --all
~/GitHub/freeciv21$ git commit
The git status
command is used to list out all the changes that git
has seen. Changed files,
new files, moved files, etc. are all listed. This command comes in handy when you want to organize your Pull
Request into more than one commit. It’s also very useful to ensure that what you see as changed follows along
with what you THINK you have actually changed. Sometimes in the course of editing you may inadvertently made
a change to another file that you did not intend to actually change. If you find that you accidentally changed
a file, you can use the git restore <file>
command. This is also shown on the git status
command output.
The git add --all
command then adds all the changed files into a single commit. The
git clang-format
command then runs a pre-processor to format any code changes to support the Longturn
community’s code standards. We use clang-format-11
. If your system’s version of clang-format
is
different, you can use the binaries for clang-format-11
using the command:
git clang-format --binary <path-to-clang-format-11>
. If git clang-format
modifies any files,
it will tell you so. If that happens, then you need to run a subsequent git add --all
command to get
those files added back into the commit.
Once everything looks good from a git status
perspective, then issue the last command. The last
command, git commit
, will open a text editor (in Debian based systems this is often nano
). Put
a message at the bottom below all of the hashes ( #
) and then save.
You now have a commit of changes that you need to push to Origin.
5. Requesting a Pull Request from Origin to Upstream
This is the last major step in the process. To push the commit to your fork, issue this command:
~/GitHub/freeciv21$ git push origin
You will be prompted for your SSH passkey and then the changes in the branch you created in 2. Create a Branch from Upstream will be pushed to your Fork. Once complete, you can open your Fork in a web browser and GitHub will notice the change and prompt you to open a Pull Request. The complete steps are documented here.