# Mercurial workflow

## 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

  ```sh
  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
[OUR INSTRUCTIONS](./mercurial-install.md)**. 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](https://foss.heptapod.net/py-edu-fr/py-edu-fr.pages.heptapod.net)
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

`````{tab-set}
````{tab-item} pedagogical content
```sh
hg clone ssh://hg@foss.heptapod.net/py-edu-fr/py-edu-fr
```
````

````{tab-item} python.cnrs website
```sh
hg clone ssh://hg@foss.heptapod.net/py-edu-fr/py-edu-fr.pages.heptapod.net py-edu-fr-website
```
````

````{tab-item} gallery
```sh
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:

```sh
# 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:

```sh
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.

```sh
# 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](https://foss.heptapod.net/py-edu-fr/py-edu-fr.pages.heptapod.net/-/issues)
and/or ask questions/explain problems in
[our dedicated chat](https://matrix.to/#/#mercurial.py-edu-fr:matrix.org).

## 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](https://fosdem.org/2025/schedule/event/fosdem-2025-5989-a-glimpse-into-a-smoother-version-control-experience/)
to discover what it means.

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

```sh
# 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
```

[evolve]: https://www.mercurial-scm.org/doc/evolution/
[topic]: https://www.mercurial-scm.org/doc/evolution/tutorials/topic-tutorial.html
[uv]: https://docs.astral.sh/uv/
