GitHub & Git

This page contains information on how to use GitHub and Git when developing Trixi.jl.

Development workflow

For adding modifications to Trixi.jl, we generally follow these steps:

Create an issue (optional)

In many cases it makes sense to start by creating an issue on GitHub. For example, if the implementation approach for a new feature is not yet clear or if there should be a discussion about the desired outcome, it is good practice to first get a consensus on what is the expected result of this modification. A GitHub issue is the place to lead this discussion, as it preserves it in the project and - together with the actual code changes - allows in the future to revisit the reasons for a particular choice of implementation or feature.

Create a branch and immediately create a pull request

All feature development, bug fixes etc. should be developed in a branch and not directly on main. If you do not have write access to the main repository on GitHub, first create a fork of the Trixi.jl repository and clone the fork to your machine. Then, create a branch locally by executing git checkout -b yourbranch, push it to the repository, and create a pull request (PR).

If you have already cloned Trixi.jl from the main repo to your local machine, you can also work in that clone. You just need to add your fork as additional remote repository and push your new branch there.

git remote add myfork git@github.com:YOUR_NAME/Trixi.jl.git
# get latest main from the main repo
git checkout main
git pull
# create a new branch for a cool new feature, bug fix, ...
git checkout -b YOUR_BRANCH_NAME
# do some work and push it to your fork
git push -u myfork
# go to https://github.com/trixi-framework/Trixi.jl/pull
# and create a PR from your new branch
Why using pull requests?

Immediately creating a PR for your branch has the benefit that all code discussions can now be held directly next to the corresponding code. Also, the PR allows to easily compare your branch to the upstream branch (usually main) to see what you have changed. Moreover, tests will run automatically.

Make changes

With a branch and PR in place, you can now write your code and commit it to your branch. If you request feedback from someone else, make sure to push your branch to the repository such that the others can easily review your changes or dive in and change something themselves.

Avoid committing unwanted files

When you use git add . or similar catch-all versions, make sure you do not accidentally commit unwanted files (e.g., Trixi.jl output files, images or videos etc.). If it happens anyways, you can undo the last commit (also multiple times) by running git reset HEAD~ (see also Undo last commit). However, this strategy only works if you have not yet pushed your changes. If you did push your changes, please talk to one of the core developers on how to proceed.

Keep your branch in sync with main

For larger features with longer-living branches, it may make sense to synchronize your branch with the current main, e.g., if there was a bug fix in main that is relevant for you. In this case, perform the following steps to merge the current main to your branch:

  1. Commit all your local changes to your branch and push it. This allows you to delete your clone in case you make a mistake and need to abort the merge.
  2. Execute git fetch to get the latest changes from the repository.
  3. Make sure you are in the correct branch by checking the output of git status or by running git checkout yourbranch.
  4. Merge main using git merge main. If there were no conflicts, hooray!, you are done. Otherwise you need to resolve your merge conflicts and commit the changes afterwards. A good guide for resolving merge conflicts can be found here.

In general, always use git merge and not git rebase to get the latest changes from main. It is less error-prone and does not create problems on branches that are worked on collaboratively.

Prepare for review

If you feel like your branch is ready to be merged to main, prepare it for review. That is, you should

  • merge the current main to your branch
  • run tests if available, but at least ensure that you did not accidentally change the results for one of the existing example elixirs
  • properly comment your code
  • delete old/unused code, especially commented lines (unless they contain helpful code, in which case you should add a comment on why you keep this around)
  • remove debug statements
  • add a elixir_xxx.jl that uses your feature (only relevant for new features)
  • make sure your code formatting adheres to the Style guide
  • describe changes in NEWS.md if appropriate

After you are confident that your branch is cleaned up properly, commit all changes and push them to the repository.

Get reviewed

Ask one of the core developers to review your code. Sometimes this will be done directly, either face-to-face or via a video call. Other times a review will be conducted asynchronously, with the reviewer leaving comments and annotations. In some cases it will be necessary to do multiple rounds of reviews, especially if there are larger changes to be added. Just commit and push your changes to your branch, and the corresponding pull request will be updated automatically.

Please note that a review has nothing to do with the lack of experience of the person developing changes: We try to review all code before it gets added to main, even from the most experienced developers. This is good practice and helps to keep the error rate low while ensuring that the code is developed in a consistent fashion. Furthermore, do not take criticism of your code personally - we just try to keep Trixi.jl as accessible and easy to use for everyone.

Merge branch

Once your branch is reviewed and declared ready for merging by the reviewer, make sure that all the latest changes have been pushed. Then, one of the developers will merge your PR. If you are one of the developers, you can also go to the pull request page on GitHub and and click on Merge pull request. Voilà, you are done! Your branch will have been merged to main and the source branch will have been deleted in the GitHub repository (if you are not working in your own fork).

Update your working copy

Once you have merged your branch by accepting the PR on GitHub, you should clean up your local working copy of the repository by performing the following steps:

  1. Update your clone by running git fetch.
  2. Check out main using git checkout main.
  3. Delete merged branch locally with git branch -d yourbranch.
  4. Remove local references to deleted remote branch by executing git remote prune origin.

You can now proceed with your next changes by starting again at the top.

Using Git

Resources for learning Git

Here are a few resources for learning do use Git that at least one of us found helpful in the past (roughly ordered from novice to advanced to expert):

Tips and tricks

This is an unordered collection of different tips and tricks that can be helpful while working with Git. As usual, your mileage might vary.

Undo last commit

If you made a mistake in your last commit, e.g., by committing an unwanted file, you can undo the latest commit by running

git reset HEAD~

This only works if you have not yet pushed your branch to the GitHub repository. In this case, please talk to one of the core developers on how to proceed. Especially when you accidentally committed a large file (image, or video), please let us know as fast as possible, since the effort to fix the repository grows considerably over time.

Remove large file from repository

If a large file was accidentally committed and pushed to the Trixi.jl repository, please talk to one of the core developers as soon as possible so that they can fix it.

Large files

You should never try to fix this yourself, as it potentially disrupts/destroys the work of others!

Based on the instructions found here and here, the following steps need to be taken (as documented for GitLab in issue #33):

  1. Tell everyone to commit and push their changes to the repository.

  2. Fix the branch in which the file was committed by removing it and committing the removal. This is especially important on main.

  3. Perform the following steps to clean up the Git repository:

    cd /tmp
    
    # Download bfg-1.13.0.jar from https://rtyley.github.io/bfg-repo-cleaner/
    
    # Get fresh clone of repo (so you can throw it away in case there is a problem)
    git clone --mirror git@github.com:trixi-framework/Trixi.jl.git
    
    # Clean up repo of all files larger than 10M
    java -jar bfg-1.13.0.jar --strip-blobs-bigger-than 10M Trixi.jl.git
    
    # Enter repo
    cd Trixi.jl.git
    
    # Clean up reflog and force aggressive garbage collection
    git reflog expire --expire=now --all && git gc --prune=now --aggressive
    
    # Push changes
    git push
    
    # Delete clone
    rm -rf Trixi.jl.git
  4. Tell everyone to clean up their local working copies by performing the following steps (also do this yourself):

    # Enter repo
    cd Trixi.jl
    
    # Get current changes
    git fetch
    
    # Check out the fixed branch
    git checkout branchname
    
    # IMPORTANT: Do a rebase instead of a pull!
    git rebase
    
    # Clean reflog and force garbage collection
    git reflog expire --expire=now --all && git gc --prune=now --aggressive

    IMPORTANT: You need to do a git rebase instead of a git pull when updating the fixed branch.