Skip to content

Managing your XOOPS XoopsCore Fork

Richard Griffith edited this page May 19, 2015 · 1 revision

Tips for Managing your XOOPS/XoopsCore Fork

XOOPS source code is now managed using git, a source code management system. Our main repository is hosted on GitHub.

Git is a distributed system. Each working copy of a repository has an index that contains its complete history. Most of that history is shared between all of the working copies, known as forks. That index serves as the basis for calculating and expressing changes, so that those changes can be shared with other repositories by merging.

This document is targeted to developers, and describes how to set up your own working repository so that it can easily stay up to date with changes in the main XOOPS/XoopsCore repository.

The first step is to establish a GitHub account. Then visit the main XOOPS/XoopsCore repository and "Fork" it. This creates a copy of that repository in your own account.

While you can work with the code directly in the GitHub interface, it is better to make a copy on a local computer, where you can use an IDE, such as PHPStorm, to work with the code, and a web stack, such as LAMP or WAMP, to install and test the code.

Work Smarter

For a production XOOPS system, it is highly recommended for security reasons to move and rename certain directories. For a development system, this creates numerous problems, since moving the directories makes git think the files were deleted. It is much easier to keep track of your changes if the whole repository remains intact. Simply point your web server to use the htdocs directory as the web root. (For Apache, this is part of VirtualHost definition.) Manage security concerns by restricting access to the web server to only allow the access you will need for development and testing (i.e. only allow access from local host, or from your private LAN.)

Trying to separate the directories while still maintaining the git relationships is potentially very error prone, as it will require moving and/or copying files before and after many common git operations. One wrong move can make your working copy unusable with git, or perhaps even worse, loose your local changes.

Tools

Depending on your platform choice, there are a variety of tools available to work with git repositories. While there are GUI tools which can make many aspects of git usage simpler, the git command line is the common language used in git documentation, and in help sources, such as StackOverflow.

I personally use GitHub for Windows when on a Windows platform. In addition to a very capable interface for the most commonly needed tasks (such as cloning, reviewing changes, building commits, branching, and more,) it includes a git shell that provides ready access to the command line when needed.

Setting up a new working copy

When you first make a new working copy, there are a few extra steps required to make syncing with the main XOOPS/XoopsCore repository easier. Here are the steps from the command line:

git clone https://github.com/yourGithubUsername/XoopsCore.git
cd XoopsCore
git remote add upstream https://github.com/XOOPS/XoopsCore.git

If you use a tool, such as GitHub for Windows to create your working copy, open that copy in the shell and add the upstream remote, with this command:

git remote add upstream https://github.com/XOOPS/XoopsCore.git

Now your working copy knows where to get the updates, when needed.

Making your Changes

Git branches make it possible to track multiple concurrent changes. The default branch is named master and should be used as a point of reference for your working copy, not for making your changes. You can easily create a new branch just for your changes. A GUI tool, such as GitHub for Windows, can make easy work of creating a new branch, commit your changes and pushing them to your fork on GitHub. The command line equivalents go like this:

git checkout -b mynewbranchname
git add path/to/mychangedfile.php
git commit -m "Changes to mychangedfile"
git push origin mynewbranchname

Avoid committing your changes to master. That will cause extra changes in the index when you sync with upstream changes. This will leave a trail of extra commits and messages that will follow any changes you push. It also leaves you without an easy reference to the current code from upstream.

Once you have pushed the branch with your changes, you can create a pull request (PR) on GitHub to request the changes be considered for inclusion in XOOPS/XoopsCore. GitHub will prompt you to make a PR for several minutes with a special message and button when you look at the main page for your fork.

Sync with XOOPS/XoopsCore

Upstream changes between the time you create your working copy and the time you are finished making a change are quite likely. Assuming you have added the upstream remote, as detailed above, and kept your master branch free of local changes as advised, here is how to sync those changes:

git checkout master
git fetch upstream
git merge upstream/master

Assuming everything has worked correctly, you should push this now synced master branch back to your fork on GitHub:

git push

Now you have an up to date working copy, locally, and an up to date fork on GitHub.

Dealing with Merge Conflicts

It is good idea to do a sync immediately before you start to make changes. But, if your changes are long running, or a separate change to the same code comes in while you are working on yours, your changes might not merge cleanly. On GitHub, it will warn you that it can't automatically merge your changes.

The world hasn't ended, and the sky isn't falling, but it will require some work. You might want to ask for advice if the differences are large. Small differences are easy to fix.

Please note, you might need a new tool. Git has support for a mergetool, which is a program that can display the conflicting versions of a file, and allow you to choose code from either version, or edit the code manually to resolve a conflict. One such tool is Meld. Git will check to see if suitable tool is installed on the system, and use it if it can, or issue an error if can't find one.

Here is how you can check ahead of time, and resolve any conflicts that might exist. First, do the upstream sync as described above, so you have a current working copy. Now switch to your branch and bring it current, too:

git checkout mynewbranchname
git merge master

If this goes without error, you are clean and ready to push this branch to your fork, and then issue a PR as described above. If things go wrong, git will tell you, and you will need to do this:

git mergetool

This will bring up each conflicting change in your merge tool, and you can decide how to fix each one. After the conflicts are resolved, you will need to manually commit the results of the merge:

git commit

Now, you can test the results of the merge. If everything passes, push the results to your fork on GitHub:

git push origin mynewbranchname

What happens after making a Pull Request

When you create a PR, several checks will be run on it automatically. One of those is unit testing on Travis-CI. Another is an automated code review using Scrutinizer-CI. You can check on the status of these two checks by looking at the PR on GitHub. Both of these are expected to pass. There occasionaly are failures unrelated to code changes, such as systems being unavailable. In general, your changes should pass the unit tests on Travis, and not introduce any new errors in Scrutinizer.

Once that step is passed, your changes will be reviewed by a project maintainer. The involves looking at each changed line, as well as running the changed code in scenarios chosen to test its function.

If all goes well, your PR will be merged. If not, the reasons it is not merged will be left in the PR comments.

Once the PR is merged, you should clean up by deleting the branch. When looking at the PR on GitHub, there will be a delete branch button, only shown to you. You can click that to remove the branch from your fork.

Cleaning up your working copy is basically a sync, with one extra step:

git checkout master
git fetch upstream
git merge upstream/master
git push
git branch -d mynewbranchname