Heptapod and Mercurial#

Currently, we are experimenting with using Mercurial instead of Git. I (Pierre Augier) think that modern Mercurial with Heptapod can be a good technical choice for this project; in addition, using Mercurial for this project would tend to increase the diversity in terms of versioning tools which is a good thing considering the current situation of Git monopoly.

However, since most potential developers are used to Git, it represents a technical barrier for contribution. We try to make this barrier as small as possible by providing good documentation on contributing with Heptapod and Mercurial.

Important

Unless you really know what you’re doing, read at least the first sections of this page before contributing.

Unless you really know what you’re doing, install and setup Mercurial as described below!

Get the developer or maintainer role#

No need to fork the repositories to contribute! The first step instead is to log in on https://foss.heptapod.net (one can use a GitHub or GitLab account) and send a message in this issue to get the “developer” or “maintainer” role for https://foss.heptapod.net/py-edu-fr.

Contribute via the web interface#

Once you became “developer” or “maintainer” of the project, you can modify a file via the web interface. Click on edit in the Heptapod interface showing a file, edit the file and commit the changes in a new GitLab branch.

Important

Since the GitLab branch HAS to corresponds to a Mercurial topic, you HAVE to choose a name in the form topic/default/my-nice-topic-name (replace my-nice-topic-name with something appropriate).

Contribute with local development using Mercurial#

Differences compared to the common GitHub workflow#

  • No need to fork the repo to contribute!

  • hg pull just gets the commits and does not update to the tip of the current branch.

  • For feature branches, we use Mercurial topics. To create a new feature branch use

    hg pull
    hg up default
    hg topic my-topic-name
    

    and not hg branch my-branch-name, which corresponds to something else in Mercurial!

  • Unlike Git, there is no notion of index in Mercurial. Unless you want to track a new file, there is no need to use hg add. If you want to commit only some of the current changes, you can use hg commit my_file or hg commit -i (interactive).

Add a ssh key to foss.heptapod.net#

Add a ssh key here https://foss.heptapod.net/-/user_settings/ssh_keys. As usual with GitHub and GitLab, this is not mandatory but (i) not difficult and (ii) much more convenient than using https in the long term.

Install and setup modern Mercurial#

For this project, we use modern Mercurial using the topic and evolve extensions. General Mercurial installation instructions are given here https://www.mercurial-scm.org/install, however, unless you really know what you’re doing, I STRONGLY SUGGEST THAT YOU JUST SERIOUSLY FOLLOW THESE INSTRUCTIONS. For that, you will need UV, which can be installed as described here: https://docs.astral.sh/uv/#installation.

Important

It is really easy with other installation methods to get a broken installation without the topic and evolve extensions and you need them to contribute to this project. You can check your installation by running hg help topic, which has to print the help for the topic command.

Tip

If hg help topic does not work, you can consider these questions:

  • Did you install Mercurial AND the Python package hg-evolve?

  • Did you forget to correctly setup your Mercurial configuration file, for example with uvx hg-setup init?

Important

If you have any issue with this step, do not struggle alone more than 2 minutes!!! Explain your problem in our issue tracker or let’s discuss on https://matrix.to/#/#py-edu-fr:matrix.org.

Clone the repository#

Finally, you should be able to clone a repo with

hg clone ssh://hg@foss.heptapod.net/py-edu-fr/py-edu-fr.pages.heptapod.net py-edu-fr-website
hg clone ssh://hg@foss.heptapod.net/py-edu-fr/py-edu-fr
hg clone ssh://hg@foss.heptapod.net/py-edu-fr/py-edu-fr-gallery

Note

No need to fork! No kidding, you just have to copy/paste exactly this line.

Commit and send changes#

This project uses basically the same workflow as Mercurial itself: see https://wiki.mercurial-scm.org/Heptapod for a more thorough overview.

To submit a topic-based merge request, use things like:

  • Example short version:

# pull: pull all commits (does not change the working directory)
hg pull
# update: update working directory and quit potential current topic
hg up default  # up or update
# topic: set current topic (used for feature branches)
hg topic improve-something
#
# file edition ...
#
make format
make
# commit: create a new changeset (a "commit") with outstanding changes
hg commit -m "setup: fix ..."
# push: push commits to the remote web repository
hg push
  • Example longer version:

hg pull
# log: show revision history
# lg is an alias for log --graph (check the `@` to see where you are)
hg lg
hg up default  # up or update
hg topic improve-something
# summary: summarize working directory state
hg sum  # sum is an alias for summary
#
# edit/add/remove files...
#
# format the code
make format
# check that it builds
make
# st or status: list files status
hg st

If there are new or deleted files, one can use hg add, hg addre or hg remove. This is not needed if there are only modifications of tracked files.

# stack: list the commits in the topic and other information
hg stack
# diff: diff repository (or selected files)
hg diff
# meld: use the external program Meld to diff repository
hg meld
hg commit -m "setup: fix ..."
hg push

It can be useful to run hg path to show addresses for remote repositories.

Tip

If you created a commit in default (not in a topic), you won’t be able to push it into the remote repository. You can put it in a topic with hg topic -r . my-topic-name.

Tip

You might want to add this text in you user configuration file (usually ~/.hgrc but more precisely Path.home() / (".hgrc" if os.name != "nt" else "mercurial.ini")):

[experimental]
# Force the user to specify the topic when committing.
# Use `topic-mode = random` to generate a random topic name
topic-mode = enforce

One can do it by running uvx hg-setup init -f, saving the new config file, edit it with hg config --edit and replace topic-mode = warning by topic-mode = enforce.

Get some help#

hg help and hg help a-command are your friends. You can read the help for commands and other subjects in https://www.mercurial-scm.org/.

If you encounter issues with Mercurial while working on py-edu-fr, do not hesitate to open an issue in our issue tracker and/or ask questions/explain problems in our dedicated chat.

Introduction to history edition with Mercurial#

With the topic and evolve extensions, Mercurial is strong for collaborative and safe history edition. One can watch this short video to discover what it means.

When you work on a topic, the following commands can be useful for you.

# stack: list all changesets in a topic and other information
hg stack

# evolve: fix common issues related to collaborative history edition
# You will be told when you need to use this command.
# You will mostly encounter that when the history of your current topic has
# been modified not locally, for example by a "rebase" done remotely
# (from the web interface or on another computer).
hg evolve

# rebase: move commits (usually to the tip of the default branch)
# most of the time rebase can be used without argument and does the right thing
hg rebase

# amend: modify a commit
hg amend
# to edit the commit message
hg amend --edit

# fold: fold multiple commits into a single one
# example to fold all the commits in your topic:
hg fold -r 'topic(.)' --exact

# absorb: incorporate corrections into the stack of draft changesets
hg absorb

# revert: restore files to their checkout state
# example for a single file:
hg revert path/towards/a/file.md