agit: improve ref and session explanation

I recommended AGit to two Codeberg users and IRL friends, and they had
difficulty understanding the Refspec concept.

This detail about Git, as well as the exact definition of a local
reference, is not inherently clear to the reader. I attached a few
further resources for those that want to read up on the subject,
and I also clarified that the refspec is not a placeholder (thus,
semantically relevant) by reusing existing content and
restructuring.

I also added a few sections and explanations behind the session
parameter, and remove some redundancies.

I tried to make the article easy to follow even for those with
no interest in learning further details.
This commit is contained in:
Panagiotis "Ivory" Vasilopoulos 2025-03-23 15:30:11 +01:00 committed by Panagiotis Vasilopoulos
parent 0df093be8a
commit 6cdf7fb80f

View file

@ -24,16 +24,29 @@ Suppose that you cloned a repository and created a new commit on top of the `mai
git push origin HEAD:refs/for/main -o topic="agit-typo-fixes" git push origin HEAD:refs/for/main -o topic="agit-typo-fixes"
``` ```
The topic will be visible in the Pull Request and it will be used to associate further commits to the same Pull Request. Under the hood, it is essentially just a branch. Note that `HEAD:refs/for/main` is the [Refspec](https://git-scm.com/book/en/v2/Git-Internals-The-Refspec). `HEAD` refers to the [checked out reference](https://git-scm.com/book/en/v2/Git-Internals-Git-References), but can be replaced with any ["local ref"](https://git-scm.com/docs/git-push). `refs/for/main` refers to the destination (**"remote ref"**), with `main` being the "target branch", as in the branch that your submitted change should be applied to.
It can also be supplied directly using the `<session>` parameter in the **Refspec**, which will set the topic as `topic-branch` and push the **currently checked out branch**: The topic will be visible in the Pull Request. The topic is used to associate further commits with the same Pull Request, instead of creating a new Pull Request. Under the hood, a "topic" is used to create a new branch in the target repository.
#### Setting a topic using the session parameter.
Topics can also be defined using the `<session>` parameter in the **Refspec**. In the following example, we create a new pull request using the currently checked out reference (`HEAD`). The target branch will be `main`. The topic will be `topic-branch`.
```shell ```shell
# topic-branch is the session parameter and the topic # topic-branch is the session parameter and the topic
git push origin HEAD:refs/for/main/topic-branch git push origin HEAD:refs/for/main/topic-branch
``` ```
A detailed explanation illustrating the difference between using `-o topic` and `<session>` will follow shortly. #### Pushing a non-checked-out reference (non-HEAD)
Suppose you would like to submit a Pull Request meant for a remote branch called `remote-branch` using topic `topic`.
However, the changes that you want to submit reside in a local branch called `local-branch` that you have not checked out. In order to submit the changes residing in the `local-branch` branch **without** checking it out, you can supply the name of the local branch (`local-branch`) as follows:
```shell
git push origin local-branch:refs/for/remote-branch/topic
```
#### Setting a title and a description in AGit
It is also possible to use some additional parameters, such as `title` and `description`. Here's another example targeting the `main` branch: It is also possible to use some additional parameters, such as `title` and `description`. Here's another example targeting the `main` branch:
@ -45,7 +58,9 @@ This can be **any** markdown content.\n
- [x] Ok" - [x] Ok"
``` ```
To be able to easily push new commits to your pull request, you first need to switch the [default push method](https://git-scm.com/docs/git-config#Documentation/git-config.txt-pushdefault) to "upstream": #### Changing the default push method
To push commits to your Pull Request without having to specify the Refspec, you can modify the [default push method](https://git-scm.com/docs/git-config#Documentation/git-config.txt-pushdefault) to `upstream` in your Git configuration:
```shell ```shell
# To only set this option for this specific repository # To only set this option for this specific repository
@ -63,17 +78,6 @@ git config branch.local-branch.merge refs/for/main/topic-branch
After doing so, you can now simply run `git push` to push commits to your pull request, without having to specify the refspec. After doing so, you can now simply run `git push` to push commits to your pull request, without having to specify the refspec.
This also will allow you to pull, fetch, rebase, etc. from the AGit pull request by default. This also will allow you to pull, fetch, rebase, etc. from the AGit pull request by default.
#### Pushing a non-checked-out reference (non-HEAD)
While most users will likely be pushing HEAD most of the time, it is worth noting that AGit flow supports pushing any local reference (just like `push` in general).
Suppose you would like to submit a Pull Request meant for a remote branch called `remote-branch` using topic `topic`.
However, the changes that you want to submit reside in a local branch called `local-branch` that you have not checked out. In order to submit the changes residing in the `local-branch` branch **without** checking it out, you can supply the name of the local branch (`local-branch`) as follows:
```shell
git push origin local-branch:refs/for/remote-branch/topic
```
### Parameters ### Parameters
The following parameters are available: The following parameters are available:
@ -87,8 +91,8 @@ The following parameters are available:
- `topic`: Essentially an identifier. **If left empty,** the value of `<session>`, if present, will also be used for the topic. Otherwise, Forgejo will return an error. If you want to push additional commits to a Pull Request that was created using AGit, you **must** use the same topic. - `topic`: Essentially an identifier. **If left empty,** the value of `<session>`, if present, will also be used for the topic. Otherwise, Forgejo will return an error. If you want to push additional commits to a Pull Request that was created using AGit, you **must** use the same topic.
- `title`: Title of the Pull Request. **If left empty,** the first line of the first new Git commit will be used instead. - `title`: Title of the Pull Request. **If left empty,** the first line of the first new Git commit will be used instead.
- `description`: Description of the Pull Request. - `description`: Description of the Pull Request.
- `force-push`: Necessary when rebasing, amending or [retroactively modifying](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History) your previous commits. Otherwise, a new Pull Request will be opened, **even if you use the same topic**. If used, the value of this parameter should be set to `true`. - `force-push`: Necessary when rebasing, amending or [retroactively modifying](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History) your previous commits. Otherwise, a new Pull Request will be opened. If used, the value of this parameter should be set to `true`.
Forgejo relies on the `topic` parameter and a linear commit history in order to associate new commits with an existing Pull Request. Forgejo relies on the `topic` parameter and a linear commit history in order to associate new commits with an existing Pull Request. Should you wish to overwrite the contents of an existing pull request, use the `force-push` parameter.
**For Gerrit users:** Forgejo does not support [Gerrit's Change-Ids](https://gerrit-review.googlesource.com/Documentation/user-changeid.html). **For Gerrit users:** Forgejo does not support [Gerrit's Change-Ids](https://gerrit-review.googlesource.com/Documentation/user-changeid.html).