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:

Diagram of GitHub Repositories

Fig. 88 Diagram of GitHub Repositories

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.

  1. File updates from Upstream are downloaded (pulled) to Local.

  2. After changes are made, file updates from Local are uploaded (pushed) to Origin.

  3. 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:

  1. Update Local with the latest from Upstream.

  2. Create a branch from Upstream.

  3. Edit files as needed in Local.

  4. Push the changes in a commit to Origin.

  5. 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.