2050 lines
85 KiB
Text
2050 lines
85 KiB
Text
|
|
This is forge.info, produced by makeinfo version 7.1.1 from forge.texi.
|
|||
|
|
|
|||
|
|
Copyright (C) 2018-2026 Jonas Bernoulli
|
|||
|
|
<emacs.forge@jonas.bernoulli.dev>
|
|||
|
|
|
|||
|
|
You can redistribute this document and/or modify it under the terms
|
|||
|
|
of the GNU General Public License as published by the Free Software
|
|||
|
|
Foundation, either version 3 of the License, or (at your option)
|
|||
|
|
any later version.
|
|||
|
|
|
|||
|
|
This document is distributed in the hope that it will be useful,
|
|||
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|||
|
|
General Public License for more details.
|
|||
|
|
|
|||
|
|
INFO-DIR-SECTION Emacs
|
|||
|
|
START-INFO-DIR-ENTRY
|
|||
|
|
* Forge: (forge). Access Git Forges from Magit.
|
|||
|
|
END-INFO-DIR-ENTRY
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Top, Next: Introduction, Up: (dir)
|
|||
|
|
|
|||
|
|
Forge User and Developer Manual
|
|||
|
|
*******************************
|
|||
|
|
|
|||
|
|
Forge allows you to work with Git forges, currently Github and Gitlab,
|
|||
|
|
from the comfort of Magit and Emacs.
|
|||
|
|
|
|||
|
|
This manual is for Forge version 0.6.8.
|
|||
|
|
|
|||
|
|
Copyright (C) 2018-2026 Jonas Bernoulli
|
|||
|
|
<emacs.forge@jonas.bernoulli.dev>
|
|||
|
|
|
|||
|
|
You can redistribute this document and/or modify it under the terms
|
|||
|
|
of the GNU General Public License as published by the Free Software
|
|||
|
|
Foundation, either version 3 of the License, or (at your option)
|
|||
|
|
any later version.
|
|||
|
|
|
|||
|
|
This document is distributed in the hope that it will be useful,
|
|||
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|||
|
|
General Public License for more details.
|
|||
|
|
|
|||
|
|
* Menu:
|
|||
|
|
|
|||
|
|
* Introduction::
|
|||
|
|
* Initial Setup::
|
|||
|
|
* Initial Pull::
|
|||
|
|
* Getting Started::
|
|||
|
|
* Lists and Menus::
|
|||
|
|
* Visiting Topics::
|
|||
|
|
* Creating Topics and Posts::
|
|||
|
|
* Editing Topics::
|
|||
|
|
* Pulling::
|
|||
|
|
* Branching::
|
|||
|
|
* Miscellaneous Commands::
|
|||
|
|
* Miscellaneous Options::
|
|||
|
|
* How Forge Detection Works::
|
|||
|
|
* Supported Forges and Hosts::
|
|||
|
|
* FAQ::
|
|||
|
|
* Keystroke Index::
|
|||
|
|
* Function and Command Index::
|
|||
|
|
* Variable Index::
|
|||
|
|
|
|||
|
|
-- The Detailed Node Listing --
|
|||
|
|
|
|||
|
|
Initial Setup
|
|||
|
|
|
|||
|
|
* Setup for Github.com: Setup for Githubcom.
|
|||
|
|
* Setup for Another Github Instance::
|
|||
|
|
* Setup for Gitlab.com: Setup for Gitlabcom.
|
|||
|
|
* Setup for Another Gitlab Instance::
|
|||
|
|
* Setup a Partially Supported Host::
|
|||
|
|
|
|||
|
|
Supported Forges and Hosts
|
|||
|
|
|
|||
|
|
* Supported Forges::
|
|||
|
|
* Partially Supported Forges::
|
|||
|
|
* Supported Semi-Forges::
|
|||
|
|
|
|||
|
|
FAQ
|
|||
|
|
|
|||
|
|
* ‘error in process filter HTTP Error 502, "Bad gateway"’: error in process filter HTTP Error 502 "Bad gateway".
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Introduction, Next: Initial Setup, Prev: Top, Up: Top
|
|||
|
|
|
|||
|
|
1 Introduction
|
|||
|
|
**************
|
|||
|
|
|
|||
|
|
Forge allows you to work with Git forges, currently Github and Gitlab,
|
|||
|
|
from the comfort of Magit and Emacs.
|
|||
|
|
|
|||
|
|
Forge fetches issues, pull-requests and other data using the forge's
|
|||
|
|
API and stores the retrieved information in a local database.
|
|||
|
|
Additionally it fetches pull-request references using Git.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Initial Setup, Next: Initial Pull, Prev: Introduction, Up: Top
|
|||
|
|
|
|||
|
|
2 Initial Setup
|
|||
|
|
***************
|
|||
|
|
|
|||
|
|
Please first do the common setup below and then carefully follow the
|
|||
|
|
instructions for your forge instance. Once you have completed the
|
|||
|
|
setup, you can start tracking repositories (see *note Initial Pull::).
|
|||
|
|
|
|||
|
|
If you run into difficulties during setup or the initial pull, then
|
|||
|
|
please also see *note How Forge Detection Works:: and *note
|
|||
|
|
(ghub)Getting Started::.
|
|||
|
|
|
|||
|
|
* Menu:
|
|||
|
|
|
|||
|
|
* Setup for Github.com: Setup for Githubcom.
|
|||
|
|
* Setup for Another Github Instance::
|
|||
|
|
* Setup for Gitlab.com: Setup for Gitlabcom.
|
|||
|
|
* Setup for Another Gitlab Instance::
|
|||
|
|
* Setup a Partially Supported Host::
|
|||
|
|
|
|||
|
|
Common Setup
|
|||
|
|
============
|
|||
|
|
|
|||
|
|
Loading Magit doesn't cause Forge to be loaded automatically. Adding
|
|||
|
|
something like this to your init file takes care of that:
|
|||
|
|
|
|||
|
|
(with-eval-after-load 'magit
|
|||
|
|
(require 'forge))
|
|||
|
|
|
|||
|
|
Or if you use ‘use-package’:
|
|||
|
|
|
|||
|
|
(use-package forge
|
|||
|
|
:after magit)
|
|||
|
|
|
|||
|
|
By default Forge adds some bindings to Magit keymaps and menus, and
|
|||
|
|
some sections to Magit buffers. If you would like to prevent that, you
|
|||
|
|
have to set ‘forge-add-default-bindings’ and/or
|
|||
|
|
‘forge-add-default-sections’ to ‘nil’, before ‘magit’ (not just ‘forge’)
|
|||
|
|
is loaded.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Setup for Githubcom, Next: Setup for Another Github Instance, Up: Initial Setup
|
|||
|
|
|
|||
|
|
2.1 Setup for Github.com
|
|||
|
|
========================
|
|||
|
|
|
|||
|
|
Set your Username
|
|||
|
|
-----------------
|
|||
|
|
|
|||
|
|
First inform Forge about your <https://github.com> username:
|
|||
|
|
|
|||
|
|
git config --global github.user USERNAME
|
|||
|
|
|
|||
|
|
If you need to identify as another user in a particular repository,
|
|||
|
|
then you have to set that variable locally:
|
|||
|
|
|
|||
|
|
cd /path/to/repo
|
|||
|
|
git config --local github.user USERNAME
|
|||
|
|
|
|||
|
|
Create and Store an Access Token
|
|||
|
|
--------------------------------
|
|||
|
|
|
|||
|
|
Visit <https://github.com/settings/tokens> in a browser to generate a
|
|||
|
|
new "classic" token using the ‘repo’, ‘user’ and ‘read:org’ scopes. Do
|
|||
|
|
not close the browser window just yet, because the token will only be
|
|||
|
|
shown once.
|
|||
|
|
|
|||
|
|
The built-in Auth-Source (*note (auth)Top::) package is used to store
|
|||
|
|
the token generated in the previous step. The ‘auth-sources’ variable
|
|||
|
|
controls how and where Auth-Source keeps its secrets. The default value
|
|||
|
|
is a list of three files: ‘("~/.authinfo" "~/.authinfo.gpg"
|
|||
|
|
"~/.netrc")’, but that can lead to confusing behavior, so you should
|
|||
|
|
make sure that only one of these files exists, and then you should also
|
|||
|
|
adjust the value of the variable to only ever use that file, for
|
|||
|
|
example:
|
|||
|
|
|
|||
|
|
(setq auth-sources '("~/.authinfo"))
|
|||
|
|
|
|||
|
|
In ‘~/.authinfo’ secrets are stored in plain text. If you don't want
|
|||
|
|
that, then you should use the encrypted ‘~/.authinfo.gpg’ instead:
|
|||
|
|
|
|||
|
|
(setq auth-sources '("~/.authinfo.gpg"))
|
|||
|
|
|
|||
|
|
Make sure you put one of these forms in your init file *and* to
|
|||
|
|
evaluate it in the current Emacs instance as well, by placing the cursor
|
|||
|
|
after the final closing parenthesis and typing ‘C-x C-e’
|
|||
|
|
(‘eval-last-sexp’).
|
|||
|
|
|
|||
|
|
Next add a line like the following to the chosen file:
|
|||
|
|
|
|||
|
|
machine api.github.com login USERNAME^forge password TOKEN
|
|||
|
|
|
|||
|
|
• The value of ‘machine’ must be ‘api.github.com’. Variations of
|
|||
|
|
this won't work.
|
|||
|
|
|
|||
|
|
• USERNAME must be the same as the value used for the ‘github.user’
|
|||
|
|
Git variable above. You *must* append ‘^forge’ to that, without
|
|||
|
|
any space in between.
|
|||
|
|
|
|||
|
|
• TOKEN is the token you generated earlier.
|
|||
|
|
|
|||
|
|
Finish by typing ‘M-x auth-source-forget-all-cached RET’. If you
|
|||
|
|
don't do this, then Auth-Source may fail to look up the token.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Setup for Another Github Instance, Next: Setup for Gitlabcom, Prev: Setup for Githubcom, Up: Initial Setup
|
|||
|
|
|
|||
|
|
2.2 Setup for Another Github Instance
|
|||
|
|
=====================================
|
|||
|
|
|
|||
|
|
Before you setup a Github instance that is not <https://github.com>,
|
|||
|
|
please first setup the latter. The setup for <https://github.com> is
|
|||
|
|
easier, and if that works but the setup for the other Github instance
|
|||
|
|
fails, then we can tentatively narrow the issue down to the parts that
|
|||
|
|
differ between <https://github.com> and other instances.
|
|||
|
|
|
|||
|
|
Tell Forge about the Instance
|
|||
|
|
-----------------------------
|
|||
|
|
|
|||
|
|
While Forge knows about <https://github.com>, it does not know about
|
|||
|
|
your other Github instances. Forge instances are configured using the
|
|||
|
|
option ‘forge-alist’ (also see its docstring). The entry for
|
|||
|
|
<https://github.com> in that variable looks like this:
|
|||
|
|
|
|||
|
|
While Forge knows about <https://github.com> out of the box, for all
|
|||
|
|
other instances you have to add a new entry to option ‘forge-alist’.
|
|||
|
|
|
|||
|
|
The entry for <https://github.com> looks like this:
|
|||
|
|
|
|||
|
|
("github.com" ; GITHOST
|
|||
|
|
"api.github.com" ; APIHOST
|
|||
|
|
"github.com" ; WEBHOST and INSTANCE-ID
|
|||
|
|
forge-github-repository) ; CLASS
|
|||
|
|
|
|||
|
|
You have to add an entry for your instance. For example, assuming
|
|||
|
|
your company uses <https://example.com>, this might be correct:
|
|||
|
|
|
|||
|
|
(push '("example.com" ; GITHOST
|
|||
|
|
"api.example.com" ; APIHOST
|
|||
|
|
"example.com" ; WEBHOST and INSTANCE-ID
|
|||
|
|
forge-github-repository) ; CLASS
|
|||
|
|
forge-alist)
|
|||
|
|
|
|||
|
|
Your company may use hostnames that follow a different format. You
|
|||
|
|
should be able to easily determine and verify GITHOST and WEBHOST, but
|
|||
|
|
determining APIHOST is more difficult; you might have to ask a coworker.
|
|||
|
|
APIHOST could be something like ‘api.example.com’, but it could also be
|
|||
|
|
something like ‘example.com/api’.
|
|||
|
|
|
|||
|
|
If the REST API's end point is ‘/v3’ and the GraphQL API's end point
|
|||
|
|
is ‘/graphql’, then use something like ‘example.com/v3’ as APIHOST.
|
|||
|
|
This is a historic accident. See
|
|||
|
|
<https://github.com/magit/forge/issues/174>.
|
|||
|
|
|
|||
|
|
We will use INSTANCE-ID (aka WEBHOST) and APIHOST below.
|
|||
|
|
|
|||
|
|
Set your Username
|
|||
|
|
-----------------
|
|||
|
|
|
|||
|
|
Inform Forge about your username for the Github instance in question:
|
|||
|
|
|
|||
|
|
git config --global github.INSTANCE-ID.user USERNAME
|
|||
|
|
|
|||
|
|
So if INSTANCE-ID is ‘example.com’ and USERNAME is ‘tarsius’ then
|
|||
|
|
use:
|
|||
|
|
|
|||
|
|
git config --global github.example.com.user tarsius
|
|||
|
|
|
|||
|
|
Create and Store an Access Token
|
|||
|
|
--------------------------------
|
|||
|
|
|
|||
|
|
Visit your forge in a browser. Follow a link to "Settings", from there
|
|||
|
|
to "Developer settings", from there to "Personal access tokens", and
|
|||
|
|
finally to "Tokens (classic)". On that page generate a new token using
|
|||
|
|
the ‘repo’, ‘user’ and ‘read:org’ scopes. Do not close the browser
|
|||
|
|
window just yet, because the token will only be shown once.
|
|||
|
|
|
|||
|
|
The built-in Auth-Source (*note (auth)Top::) package is used to store
|
|||
|
|
the token generated in the previous step. The ‘auth-sources’ variable
|
|||
|
|
controls how and where Auth-Source keeps its secrets. The default value
|
|||
|
|
is a list of three files: ‘("~/.authinfo" "~/.authinfo.gpg"
|
|||
|
|
"~/.netrc")’, but that can lead to confusing behavior, so you should
|
|||
|
|
make sure that only one of these files exists, and then you should also
|
|||
|
|
adjust the value of the variable to only ever use that file, for
|
|||
|
|
example:
|
|||
|
|
|
|||
|
|
(setq auth-sources '("~/.authinfo"))
|
|||
|
|
|
|||
|
|
In ‘~/.authinfo’ secrets are stored in plain text. If you don't want
|
|||
|
|
that, then you should use the encrypted ‘~/.authinfo.gpg’ instead:
|
|||
|
|
|
|||
|
|
(setq auth-sources '("~/.authinfo.gpg"))
|
|||
|
|
|
|||
|
|
Make sure you put one of these forms in your init file *and* to
|
|||
|
|
evaluate it in the current Emacs instance as well, by placing the cursor
|
|||
|
|
after the final closing parenthesis and typing ‘C-x C-e’
|
|||
|
|
(‘eval-last-sexp’).
|
|||
|
|
|
|||
|
|
Next add a line like the following to the chosen file:
|
|||
|
|
|
|||
|
|
machine APIHOST login USERNAME^forge password TOKEN
|
|||
|
|
|
|||
|
|
• APIHOST must be the same as the second element of the entry we
|
|||
|
|
added to ‘forge-alist’. In the above example that would be
|
|||
|
|
‘api.example.com’. Do *not* instead use GITHOST or INSTANCE-ID
|
|||
|
|
(aka WEBHOST).
|
|||
|
|
|
|||
|
|
• USERNAME must be the same username you used above as the value of
|
|||
|
|
the Git variable. You *must* append ‘^forge’ to that, without any
|
|||
|
|
space in between.
|
|||
|
|
|
|||
|
|
• TOKEN is the token you generated earlier.
|
|||
|
|
|
|||
|
|
Finish by typing ‘M-x auth-source-forget-all-cached RET’. If you
|
|||
|
|
don't do this, then Auth-Source may fail to look up the token.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Setup for Gitlabcom, Next: Setup for Another Gitlab Instance, Prev: Setup for Another Github Instance, Up: Initial Setup
|
|||
|
|
|
|||
|
|
2.3 Setup for Gitlab.com
|
|||
|
|
========================
|
|||
|
|
|
|||
|
|
Set your Username
|
|||
|
|
-----------------
|
|||
|
|
|
|||
|
|
First inform Forge about your <https://gitlab.com> username:
|
|||
|
|
|
|||
|
|
git config --global gitlab.user USERNAME
|
|||
|
|
|
|||
|
|
If you need to identify as another user in a particular repository,
|
|||
|
|
then you have to set that variable locally:
|
|||
|
|
|
|||
|
|
cd /path/to/repo
|
|||
|
|
git config --local gitlab.user USERNAME
|
|||
|
|
|
|||
|
|
Create and Store an Access Token
|
|||
|
|
--------------------------------
|
|||
|
|
|
|||
|
|
Visit <https://gitlab.com/-/user_settings/personal_access_tokens> in a
|
|||
|
|
browser to generate a new token using the ‘api’, ‘read_api’ and
|
|||
|
|
‘read_user’ scopes. Do not close the browser window just yet, because
|
|||
|
|
the token will only be shown once.
|
|||
|
|
|
|||
|
|
The built-in Auth-Source (*note (auth)Top::) package is used to store
|
|||
|
|
the token generated in the previous step. The ‘auth-sources’ variable
|
|||
|
|
controls how and where Auth-Source keeps its secrets. The default value
|
|||
|
|
is a list of three files: ‘("~/.authinfo" "~/.authinfo.gpg"
|
|||
|
|
"~/.netrc")’, but that can lead to confusing behavior, so you should
|
|||
|
|
make sure that only one of these files exists, and then you should also
|
|||
|
|
adjust the value of the variable to only ever use that file, for
|
|||
|
|
example:
|
|||
|
|
|
|||
|
|
(setq auth-sources '("~/.authinfo"))
|
|||
|
|
|
|||
|
|
In ‘~/.authinfo’ secrets are stored in plain text. If you don't want
|
|||
|
|
that, then you should use the encrypted ‘~/.authinfo.gpg’ instead:
|
|||
|
|
|
|||
|
|
(setq auth-sources '("~/.authinfo.gpg"))
|
|||
|
|
|
|||
|
|
Make sure you put one of these forms in your init file *and* to
|
|||
|
|
evaluate it in the current Emacs instance as well, by placing the cursor
|
|||
|
|
after the final closing parenthesis and typing ‘C-x C-e’
|
|||
|
|
(‘eval-last-sexp’).
|
|||
|
|
|
|||
|
|
Next add a line like the following to the chosen file:
|
|||
|
|
|
|||
|
|
machine gitlab.com login USERNAME^forge password TOKEN
|
|||
|
|
|
|||
|
|
• The value of ‘machine’ should be ‘gitlab.com’. For historic
|
|||
|
|
reasons ‘gitlab.com’ is also supported.
|
|||
|
|
|
|||
|
|
• Note that if you instead use the ‘auth-source-pass’ backend, then
|
|||
|
|
you *must* use ‘gitlab.com’ as ‘host’.
|
|||
|
|
|
|||
|
|
• USERNAME must be the same as the value used for the ‘gitlab.user’
|
|||
|
|
Git variable above. You *must* append ‘^forge’ to that, without
|
|||
|
|
any space in between.
|
|||
|
|
|
|||
|
|
• TOKEN is the token you generated earlier.
|
|||
|
|
|
|||
|
|
Finish by typing ‘M-x auth-source-forget-all-cached RET’. If you
|
|||
|
|
don't do this, then Auth-Source may fail to look up the token.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Setup for Another Gitlab Instance, Next: Setup a Partially Supported Host, Prev: Setup for Gitlabcom, Up: Initial Setup
|
|||
|
|
|
|||
|
|
2.4 Setup for Another Gitlab Instance
|
|||
|
|
=====================================
|
|||
|
|
|
|||
|
|
Before you setup a Gitlab instance that is not <https://gitlab.com>,
|
|||
|
|
please first setup the latter. The setup for <https://gitlab.com> is
|
|||
|
|
easier, and if that works but the setup for the other Gitlab instance
|
|||
|
|
fails, then we can tentatively narrow the issue down to the parts that
|
|||
|
|
differ between <https://gitlab.com> and other instances.
|
|||
|
|
|
|||
|
|
Tell Forge about the Instance
|
|||
|
|
-----------------------------
|
|||
|
|
|
|||
|
|
While Forge knows about <https://gitlab.com> (and a few other well-known
|
|||
|
|
instances) out of the box, for other instances you have to add a new
|
|||
|
|
entry to option ‘forge-alist’.
|
|||
|
|
|
|||
|
|
The entry for <https://gitlab.com> looks like this:
|
|||
|
|
|
|||
|
|
("gitlab.com" ; GITHOST
|
|||
|
|
"gitlab.com/api/v4" ; APIHOST
|
|||
|
|
"gitlab.com" ; WEBHOST and INSTANCE-ID
|
|||
|
|
forge-gitlab-repository) ; CLASS
|
|||
|
|
|
|||
|
|
For historic reasons, APIHOST actually has to be a host followed by a
|
|||
|
|
path.
|
|||
|
|
|
|||
|
|
You have to add an entry for your instance. For example, assuming
|
|||
|
|
your company/organisation uses <https://example.com>, this might be
|
|||
|
|
correct:
|
|||
|
|
|
|||
|
|
(push '("example.com" ; GITHOST
|
|||
|
|
"example.com/api/v4" ; APIHOST
|
|||
|
|
"example.com" ; WEBHOST and INSTANCE-ID
|
|||
|
|
forge-gitlab-repository) ; CLASS
|
|||
|
|
forge-alist)
|
|||
|
|
|
|||
|
|
Your company may use hostnames that follow a different format. You
|
|||
|
|
should be able to easily determine and verify GITHOST and WEBHOST, but
|
|||
|
|
determining APIHOST is more difficult; you might have to ask a
|
|||
|
|
colleague.
|
|||
|
|
|
|||
|
|
We will use INSTANCE-ID (aka WEBHOST) and APIHOST below.
|
|||
|
|
|
|||
|
|
Set your Username
|
|||
|
|
-----------------
|
|||
|
|
|
|||
|
|
Inform Forge about your username for the Gitlab instance in question:
|
|||
|
|
|
|||
|
|
git config --global gitlab.INSTANCE-ID.user USERNAME
|
|||
|
|
|
|||
|
|
So if INSTANCE-ID is ‘example.com’ and USERNAME is ‘tarsius’ then
|
|||
|
|
use:
|
|||
|
|
|
|||
|
|
git config --global gitlab.example.com.user tarsius
|
|||
|
|
|
|||
|
|
Create and Store an Access Token
|
|||
|
|
--------------------------------
|
|||
|
|
|
|||
|
|
Visit your forge in a browser. Follow a link to "Preferences" and from
|
|||
|
|
there to "Access Tokens". On that page generate a new "Personal access
|
|||
|
|
token" using the ‘api’, ‘read_api’ and ‘read_user’ scopes. Do not close
|
|||
|
|
the browser window just yet, because the token will only be shown once.
|
|||
|
|
|
|||
|
|
The built-in Auth-Source (*note (auth)Top::) package is used to store
|
|||
|
|
the token generated in the previous step. The ‘auth-sources’ variable
|
|||
|
|
controls how and where Auth-Source keeps its secrets. The default value
|
|||
|
|
is a list of three files: ‘("~/.authinfo" "~/.authinfo.gpg"
|
|||
|
|
"~/.netrc")’, but that can lead to confusing behavior, so you should
|
|||
|
|
make sure that only one of these files exists, and then you should also
|
|||
|
|
adjust the value of the variable to only ever use that file, for
|
|||
|
|
example:
|
|||
|
|
|
|||
|
|
(setq auth-sources '("~/.authinfo"))
|
|||
|
|
|
|||
|
|
In ‘~/.authinfo’ secrets are stored in plain text. If you don't want
|
|||
|
|
that, then you should use the encrypted ‘~/.authinfo.gpg’ instead:
|
|||
|
|
|
|||
|
|
(setq auth-sources '("~/.authinfo.gpg"))
|
|||
|
|
|
|||
|
|
Make sure you put one of these forms in your init file *and* to
|
|||
|
|
evaluate it in the current Emacs instance as well, by placing the cursor
|
|||
|
|
after the final closing parenthesis and typing ‘C-x C-e’
|
|||
|
|
(‘eval-last-sexp’).
|
|||
|
|
|
|||
|
|
Next add a line like the following to the chosen file:
|
|||
|
|
|
|||
|
|
machine APIHOST login USERNAME^forge password TOKEN
|
|||
|
|
|
|||
|
|
• APIHOST must be either the same as the second element of the entry
|
|||
|
|
we added to ‘forge-alist’, or that element with the path suffix
|
|||
|
|
removed. For example, if the APIHOST, specified in an
|
|||
|
|
‘forge-alist’ entry, is ‘example.com/api/v4’, then you can use
|
|||
|
|
‘example.com/api/v4’ or ‘example.com’.
|
|||
|
|
|
|||
|
|
Historically only the former was supported, but that was a design
|
|||
|
|
mistake, which we are now stuck with, and using just ‘example.com’
|
|||
|
|
as APIHOST in ‘~/.authsource’ is now recommended. For the time
|
|||
|
|
being, in ‘forge-alist’ you must still always use
|
|||
|
|
‘example.com/api/v4’ as APIHOST.
|
|||
|
|
|
|||
|
|
If you instead use the ‘auth-source-pass’ backend, then you *must*
|
|||
|
|
use ‘example.com’ as the value of ‘host’. Using
|
|||
|
|
‘example.com/api/v4’ does not work with that backend.
|
|||
|
|
|
|||
|
|
• USERNAME must be the same username you used above as the value of
|
|||
|
|
the Git variable. You *must* append ‘^forge’ to that, without any
|
|||
|
|
space in between.
|
|||
|
|
|
|||
|
|
• TOKEN is the token you generated earlier.
|
|||
|
|
|
|||
|
|
Finish by typing ‘M-x auth-source-forget-all-cached RET’. If you
|
|||
|
|
don't do this, then Auth-Source may fail to look up the token.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Setup a Partially Supported Host, Prev: Setup for Another Gitlab Instance, Up: Initial Setup
|
|||
|
|
|
|||
|
|
2.5 Setup a Partially Supported Host
|
|||
|
|
====================================
|
|||
|
|
|
|||
|
|
Forge currently only supports the Github and Gitlab APIs.
|
|||
|
|
|
|||
|
|
It does however partially support a few additional forge types (see
|
|||
|
|
*note Partially Supported Forges::) and other lighter weight software
|
|||
|
|
used to host Git repositories, which also provide a web interfaces (see
|
|||
|
|
*note Supported Semi-Forges::). Forge doesn't use the APIs of such
|
|||
|
|
forges, but registering the host and adding repositories to the local
|
|||
|
|
database at least enables the use of commands such as ‘forge-browse’.
|
|||
|
|
|
|||
|
|
Tell Forge about the Instance
|
|||
|
|
-----------------------------
|
|||
|
|
|
|||
|
|
A few hosts, which use partially supported forge types, are available
|
|||
|
|
out-of-the-box, because they have an entry in the default value of
|
|||
|
|
option ‘forge-alist’ (also see its docstring). For example, the entry
|
|||
|
|
for <https://codeberg.org> in that variable looks like this:
|
|||
|
|
|
|||
|
|
("codeberg.org" ; GITHOST
|
|||
|
|
"codeberg.org/api/v1" ; APIHOST
|
|||
|
|
"codeberg.org" ; WEBHOST and INSTANCE-ID
|
|||
|
|
forge-gitea-repository) ; CLASS
|
|||
|
|
|
|||
|
|
To be able to add repositories from a, so far, unknown forge instance
|
|||
|
|
to your local database, you have to add an entry for that instance to
|
|||
|
|
‘forge-alist’. For example, assuming you use another Gitea instance,
|
|||
|
|
hosted at <https://example.com>, this might be correct:
|
|||
|
|
|
|||
|
|
(push '("example.com" ; GITHOST
|
|||
|
|
"example.com/api/v1" ; APIHOST
|
|||
|
|
"example.com" ; WEBHOST and INSTANCE-ID
|
|||
|
|
forge-gitea-repository) ; CLASS
|
|||
|
|
forge-alist)
|
|||
|
|
|
|||
|
|
Look at ‘forge-alist’ entries of other hosts using the same forge
|
|||
|
|
type as the instance you are configuring, to see what format *might* be
|
|||
|
|
appropriate. You should be able to easily determine and verify GITHOST
|
|||
|
|
and WEBHOST, but determining APIHOST is more difficult; you might have
|
|||
|
|
to ask a colleague. APIHOST could be something like
|
|||
|
|
‘example.com/api/vi’, but it could also be something like
|
|||
|
|
‘api.example.com’.
|
|||
|
|
|
|||
|
|
Add Support for Additional Forge Types
|
|||
|
|
--------------------------------------
|
|||
|
|
|
|||
|
|
For each fully or partially supported forge type, Forge defines at least
|
|||
|
|
a class. The following example is taken from ‘forge-semi.el’:
|
|||
|
|
|
|||
|
|
(defclass forge-cgit-repository (forge-noapi-repository)
|
|||
|
|
((commit-url-format :initform "https://%h/%p.git/commit/?id=%r")
|
|||
|
|
(branch-url-format :initform "https://%h/%p.git/log/?h=%r")
|
|||
|
|
(remote-url-format :initform "https://%h/%p.git/about"))
|
|||
|
|
"Cgit from https://git.zx2c4.com/cgit/about.
|
|||
|
|
Different hosts use different url schemata, so we need multiple
|
|||
|
|
classes. See their definitions in \"forge-semi.el\".")
|
|||
|
|
|
|||
|
|
Once you add a host using that class to ‘forge-alist’ and then a
|
|||
|
|
repository from that host to the local database, you will be able to use
|
|||
|
|
commands such as ‘forge-browse-branch’ (but not much more).
|
|||
|
|
|
|||
|
|
If you want to add a repository from another host, which happens to
|
|||
|
|
use another software or another URL schemata, then you might have to
|
|||
|
|
define an additional class first. See ‘forge-semi.el’ for simple
|
|||
|
|
examples and grep for ‘defclass forge-.*-repository’ for more complex
|
|||
|
|
ones.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Initial Pull, Next: Getting Started, Prev: Initial Setup, Up: Top
|
|||
|
|
|
|||
|
|
3 Initial Pull
|
|||
|
|
**************
|
|||
|
|
|
|||
|
|
To start using Forge in a certain repository, visit the Magit status
|
|||
|
|
buffer for that repository and type ‘N / a’ (‘forge-add-repository’).
|
|||
|
|
You are given a choice to pull all topics, all topics that were updated
|
|||
|
|
after a certain date, or only individual topics.
|
|||
|
|
|
|||
|
|
Beside adding the repository to the database, this also adds a new
|
|||
|
|
value to the Git variable ‘remote.<remote>.fetch’, which causes all
|
|||
|
|
pull-request refs (‘+refs/pull/*/head:refs/pullreqs/*’ for Github) to be
|
|||
|
|
fetched by Git.
|
|||
|
|
|
|||
|
|
Note that it is possible to use the same command to add any
|
|||
|
|
repository from a supported forge to the database, without cloning the
|
|||
|
|
Git repository first.
|
|||
|
|
|
|||
|
|
The initial fetch can take a while but most of the work is done
|
|||
|
|
asynchronously. Storing the information in the database is done
|
|||
|
|
synchronously though, so there can be a noticeable hang at the end.
|
|||
|
|
Subsequent fetches are much faster.
|
|||
|
|
|
|||
|
|
Fetching issues from Github is much faster than fetching from other
|
|||
|
|
forges, because making a handful of GraphQL requests, is much faster
|
|||
|
|
than making hundreds of REST requests.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Getting Started, Next: Lists and Menus, Prev: Initial Pull, Up: Top
|
|||
|
|
|
|||
|
|
4 Getting Started
|
|||
|
|
*****************
|
|||
|
|
|
|||
|
|
Much like Git stores information in a local repository and does not
|
|||
|
|
require a constant internet connection, Forge retrieves additional
|
|||
|
|
information using a forge's API and stores that in a local database.
|
|||
|
|
|
|||
|
|
Forge's equivalent of ‘git clone’ is ‘forge-add-repository’, which
|
|||
|
|
has to be run, before most of Forges features become available in the
|
|||
|
|
local clone of a Git repository.
|
|||
|
|
|
|||
|
|
‘N / a’ (‘forge-add-repository’)
|
|||
|
|
This command guides the user through the process of adding a
|
|||
|
|
repository to the local database.
|
|||
|
|
|
|||
|
|
Note that it is possible to add a repository to the local database,
|
|||
|
|
without pulling all the data, which is useful if you just want to
|
|||
|
|
create a single issue or pull-request in a repository, but are not
|
|||
|
|
interested in existing topics, e.g., because you do not regularly
|
|||
|
|
contribute to that repository.
|
|||
|
|
|
|||
|
|
Also note that you can add a repository to the local database, even
|
|||
|
|
if no local Git clone exists.
|
|||
|
|
|
|||
|
|
Like with Git, you have to explicitly pull remote changes, at your
|
|||
|
|
leisure, using ‘forge-pull’.
|
|||
|
|
|
|||
|
|
‘f n’ (‘forge-pull’)
|
|||
|
|
‘N f f’
|
|||
|
|
This command uses a forge's API to fetch topics and other
|
|||
|
|
information about the current repository, and stores the fetched
|
|||
|
|
information in the database.
|
|||
|
|
|
|||
|
|
If the current repository isn't being tracked in the local database
|
|||
|
|
yet, then this command pivots to behave like
|
|||
|
|
‘forge-add-repository’.
|
|||
|
|
|
|||
|
|
Forge adds two additional sections to Magit's status buffer, which
|
|||
|
|
list open and/or pending issues and pull-requests. Typing ‘RET’, while
|
|||
|
|
the cursor is on a topic section, shows more information about that
|
|||
|
|
topic in a separate buffer. Typing ‘RET’ on a topic list section, shows
|
|||
|
|
that list in a separate buffer, where you can apply different filters.
|
|||
|
|
|
|||
|
|
The other main entry point to the functionality provided by Forge is
|
|||
|
|
the ‘forge-dispatch’ menu.
|
|||
|
|
|
|||
|
|
‘N’ (‘forge-dispatch’)
|
|||
|
|
This prefix command is available in all Magit buffers and provides
|
|||
|
|
access to most of the available Forge commands. See the following
|
|||
|
|
sections for information about the available commands.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Lists and Menus, Next: Visiting Topics, Prev: Getting Started, Up: Top
|
|||
|
|
|
|||
|
|
5 Lists and Menus
|
|||
|
|
*****************
|
|||
|
|
|
|||
|
|
Topics are listed in two sections in Magit's status buffer, but can also
|
|||
|
|
be listed in dedicated buffers. Likewise individual topics can be
|
|||
|
|
visited in separate buffers. In both cases this can be done by placing
|
|||
|
|
the cursor on the respective section in the status buffer and typing
|
|||
|
|
‘RET’, or by invoking the appropriate command from Forge's main menu, on
|
|||
|
|
‘N’ (‘forge-dispatch’).
|
|||
|
|
|
|||
|
|
List commands and corresponding menu commands exist for topics,
|
|||
|
|
notifications and repositories, but there isn't always an exclusive
|
|||
|
|
mapping from menu to buffer. The main menu (‘forge-dispatch’), the
|
|||
|
|
configuration menu (‘forge-configure’), the menu which controls the
|
|||
|
|
current topic or the topic at point (‘forge-topic-menu’), and the menu
|
|||
|
|
which controls the topics listed in the current buffer
|
|||
|
|
(‘forge-topics-menu’), are useful in more than one major mode.
|
|||
|
|
|
|||
|
|
All of these menus feature bindings to directly switch to the other
|
|||
|
|
appropriate menus. So it is enough to remember that ‘N’ always brings
|
|||
|
|
up the dispatch menu; you can always navigate to another menu from
|
|||
|
|
there.
|
|||
|
|
|
|||
|
|
‘C-c C-c’ brings up the most appropriate menu for the current buffer.
|
|||
|
|
In Magit's status buffer the most appropriate menu is Magit's own
|
|||
|
|
dispatch menu (‘magit-dispatch’), so here the quickest way to invoke
|
|||
|
|
Forge's dispatch menu is ‘N’. Even in Magit's status buffer, when the
|
|||
|
|
cursor is an individual topic or on a topic list section, ‘C-c C-c’
|
|||
|
|
opens the respective menu (‘forge-topics-menu’ or ‘forge-topic-menu’).
|
|||
|
|
|
|||
|
|
The following sections describe most of the available menu and list
|
|||
|
|
commands. For ‘forge-topic-menu’, see *note Editing Topics::.
|
|||
|
|
|
|||
|
|
Dispatch and configuration menus
|
|||
|
|
================================
|
|||
|
|
|
|||
|
|
‘N’ (‘forge-dispatch’)
|
|||
|
|
This prefix menu command is available in all Magit buffers and
|
|||
|
|
provides access to most of the available Forge commands. See the
|
|||
|
|
following sections for information about the available commands.
|
|||
|
|
|
|||
|
|
‘N m c’ (‘forge-configure’)
|
|||
|
|
This command displays a menu used to configure the current
|
|||
|
|
repository and some global settings as well.
|
|||
|
|
|
|||
|
|
Topic menu and list commands
|
|||
|
|
============================
|
|||
|
|
|
|||
|
|
‘N m f’ (‘forge-topics-menu’)
|
|||
|
|
‘C-c C-c [in topics list buffer/section]’
|
|||
|
|
This command displays a menu used to control the list of topics
|
|||
|
|
displayed in the current buffer.
|
|||
|
|
|
|||
|
|
Note that this command can not only be used in buffers dedicated to
|
|||
|
|
listing topics, but also in Magit's status buffer.
|
|||
|
|
|
|||
|
|
‘N l t’ (‘forge-list-topics’)
|
|||
|
|
This command lists the current repository's issues in a separate
|
|||
|
|
buffer. If the list buffer already exists, this command only
|
|||
|
|
ensures that all types of topics are listed. If any other filters
|
|||
|
|
are in effect, they are left intact.
|
|||
|
|
|
|||
|
|
‘<RET> [on "Issues" status section]’ (‘forge-list-issues’)
|
|||
|
|
This command lists the current repository's issues in a separate
|
|||
|
|
buffer. If the list buffer already exists, this command limits the
|
|||
|
|
list to issues. If any other filters are in effect, they are left
|
|||
|
|
intact.
|
|||
|
|
|
|||
|
|
‘<RET> [on "Pull requests" status section]’ (‘forge-list-pullreqs’)
|
|||
|
|
This command lists the current repository's pull-requests in a
|
|||
|
|
separate buffer. If the list buffer already exists, this command
|
|||
|
|
limits the list to pull-requests. If any other filters are in
|
|||
|
|
effect, they are left intact.
|
|||
|
|
|
|||
|
|
‘N l g’ (‘forge-list-global-topics’)
|
|||
|
|
This command lists topics across all tracked repository. If the
|
|||
|
|
list buffer already exists, filters except for the type filter are
|
|||
|
|
left in effect.
|
|||
|
|
|
|||
|
|
-- Command: forge-list-global-issues
|
|||
|
|
This command lists issues across all tracked repository. If the
|
|||
|
|
list buffer already exists, filters except for the type filter are
|
|||
|
|
left in effect.
|
|||
|
|
|
|||
|
|
-- Command: forge-list-global-pullreqs
|
|||
|
|
This command lists pull-requests across all tracked repository. If
|
|||
|
|
the list buffer already exists, filters except for the type filter
|
|||
|
|
are in effect.
|
|||
|
|
|
|||
|
|
Notification menu and list commands
|
|||
|
|
===================================
|
|||
|
|
|
|||
|
|
‘N m n’ (‘forge-notifications-menu’)
|
|||
|
|
‘C-c C-c [in notifications list buffer]’
|
|||
|
|
This command displays a menu used to control the list of
|
|||
|
|
notifications displayed in the current buffer.
|
|||
|
|
|
|||
|
|
‘N l n’ (‘forge-list-notifications’)
|
|||
|
|
This command lists all notifications for all forges in a separate
|
|||
|
|
buffer.
|
|||
|
|
|
|||
|
|
Repository menu and list commands
|
|||
|
|
=================================
|
|||
|
|
|
|||
|
|
‘N m r’ (‘forge-repositories-menu’)
|
|||
|
|
‘C-c C-c [in repositories list buffer]’
|
|||
|
|
This command displays a menu used to control the list of
|
|||
|
|
repositories displayed in the current buffer.
|
|||
|
|
|
|||
|
|
‘N l r’ (‘forge-list-repositories’)
|
|||
|
|
This command lists all known repositories in a separate buffer.
|
|||
|
|
Here "known" means that an entry exists in the local database.
|
|||
|
|
|
|||
|
|
‘<RET> [on repository]’ (‘forge-visit-this-repository’)
|
|||
|
|
This commands visits the repository at point in a separate buffer.
|
|||
|
|
|
|||
|
|
‘o [in forge-repositories-menu]’ (‘forge-list-owned-repositories’)
|
|||
|
|
This command lists all known repositories that belong to the user
|
|||
|
|
in a separate buffer. Here "known" means that an entry exists in
|
|||
|
|
the local database. Only Github is supported for now.
|
|||
|
|
|
|||
|
|
The below options controls which repositories are considered to be
|
|||
|
|
owned by the user. They are additionally used by ‘forge-fork’.
|
|||
|
|
|
|||
|
|
-- User Option: forge-owned-accounts
|
|||
|
|
This is an alist of accounts that are owned by you. This should
|
|||
|
|
include your username as well as any organization that you own.
|
|||
|
|
|
|||
|
|
Each element has the form ‘(ACCOUNT . PLIST)’. The following
|
|||
|
|
properties are currently being used:
|
|||
|
|
|
|||
|
|
• ‘remote-name’ The default name suggested by ‘forge-fork’ for a
|
|||
|
|
fork created within this account. If unspecified, then the
|
|||
|
|
name of the account is used.
|
|||
|
|
|
|||
|
|
Example: ‘(("tarsius") ("emacsmirror" remote-name "mirror"))’.
|
|||
|
|
|
|||
|
|
-- User Option: forge-owned-ignored
|
|||
|
|
This is a list of repository names that are considered to not be
|
|||
|
|
owned by you, even though they would have been considered to be
|
|||
|
|
owned by you based on ‘forge-owned-accounts’.
|
|||
|
|
|
|||
|
|
Exiting menus and lists
|
|||
|
|
=======================
|
|||
|
|
|
|||
|
|
To exit a menu, type ‘C-g’. If the menu was invoked from another menu
|
|||
|
|
and that menu is useful in the current buffer, then that menu becomes
|
|||
|
|
active again. If that happens and you actually want to quit all menus,
|
|||
|
|
then just type ‘C-g’ again. You can also directly exit all menus by
|
|||
|
|
using ‘C-q’, instead of ‘C-g’.
|
|||
|
|
|
|||
|
|
Type ‘q’ to quit not only the menu, but also the list or topic detail
|
|||
|
|
buffer. That binding is also available when no menu is active, in which
|
|||
|
|
case it will simply quit the buffer. When invoked from a menu, then
|
|||
|
|
this binding may return to another list buffer, in which case some menu
|
|||
|
|
may also remain active.
|
|||
|
|
|
|||
|
|
Default topic filters
|
|||
|
|
=====================
|
|||
|
|
|
|||
|
|
-- User Option: forge-list-buffer-default-topic-filters
|
|||
|
|
This option specifies the filters initially used to limit topics
|
|||
|
|
listed in topic list buffers.
|
|||
|
|
|
|||
|
|
-- User Option: forge-status-buffer-default-topic-filters
|
|||
|
|
This option specifies the filters initially used to limit topics
|
|||
|
|
listed in Magit status buffers.
|
|||
|
|
|
|||
|
|
Also see *note Topic sections in Magit status buffers::.
|
|||
|
|
|
|||
|
|
Topic sections in Magit status buffers
|
|||
|
|
======================================
|
|||
|
|
|
|||
|
|
Forge arranges for certain issues and pull-requests to be list in Magit
|
|||
|
|
status buffers, by adding the following functions to
|
|||
|
|
‘magit-status-sections-hook’.
|
|||
|
|
|
|||
|
|
Which topics are listed initially is customizable using option
|
|||
|
|
‘forge-status-buffer-default-topic-filters’ and can be changed
|
|||
|
|
temporarily for the current buffer, using ‘N m f’ (‘forge-topics-menu’).
|
|||
|
|
|
|||
|
|
-- Function: forge-insert-discussions
|
|||
|
|
This function inserts a list of discussions, by default a list of
|
|||
|
|
"active" discussions.
|
|||
|
|
|
|||
|
|
-- Function: forge-insert-issues
|
|||
|
|
This function inserts a list of issues, by default a list of
|
|||
|
|
"active" issues.
|
|||
|
|
|
|||
|
|
-- Function: forge-insert-pullreqs
|
|||
|
|
This function inserts a list of pull-requests, by default a list of
|
|||
|
|
"active" pull-requests.
|
|||
|
|
|
|||
|
|
Forge used to provide additional functions to insert hard-coded topic
|
|||
|
|
subsets, but they were removed in favor of the more flexible approach
|
|||
|
|
described above. If you miss the removed sections, you can use the new
|
|||
|
|
‘forge-insert-topics’ helper function to define your own section
|
|||
|
|
inserter functions. See its docstring for more information.
|
|||
|
|
|
|||
|
|
If you don't want any topic list sections to be displayed in Magit
|
|||
|
|
status buffers, set ‘forge-add-default-sections’ to ‘nil’ before ‘magit’
|
|||
|
|
is loaded.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Visiting Topics, Next: Creating Topics and Posts, Prev: Lists and Menus, Up: Top
|
|||
|
|
|
|||
|
|
6 Visiting Topics
|
|||
|
|
*****************
|
|||
|
|
|
|||
|
|
The commands, accessible from ‘forge-topic-menu’ (on ‘C-return’), act on
|
|||
|
|
the topic at point; so this menu is useful in buffers dedicated to
|
|||
|
|
listing topics and notifications (which correspond to topics), but also
|
|||
|
|
in the status buffer (which also lists topics). In buffers dedicated to
|
|||
|
|
showing details about a single topic, these commands act on that topic;
|
|||
|
|
so this menu can be used there too.
|
|||
|
|
|
|||
|
|
To switch to this menu from another menu use ‘m s’. If the cursor is
|
|||
|
|
on a topic or the current buffer visits a topic.
|
|||
|
|
|
|||
|
|
To display details about a topic in a separate buffer and at the same
|
|||
|
|
time display the topic menu, invoke ‘forge-topic-menu’ with a prefix
|
|||
|
|
argument, i.e., ‘C-u RET’.
|
|||
|
|
|
|||
|
|
‘<RET> [on topic]’ (‘forge-visit-this-topic’)
|
|||
|
|
This commands visits the topic at point in a separate buffer. When
|
|||
|
|
invoked with a prefix argument then it not only visits the topic in
|
|||
|
|
a separate buffer, it at the same time displays
|
|||
|
|
|
|||
|
|
‘N v t’ (‘forge-visit-topic’)
|
|||
|
|
‘N v i’ (‘forge-visit-issue’)
|
|||
|
|
‘N v p’ (‘forge-visit-pullreq’)
|
|||
|
|
These commands read a topic, issue or pull-request and visit it in
|
|||
|
|
a separate buffer.
|
|||
|
|
|
|||
|
|
‘N v u’ (‘forge-visit-topic-from-url’)
|
|||
|
|
This commands reads an URL and visits the corresponding topic.
|
|||
|
|
Normally users would yank that URL into the minibuffer, after
|
|||
|
|
having copied it from an email or a browser's address bar.
|
|||
|
|
|
|||
|
|
This command is disabled in the menu by default.
|
|||
|
|
|
|||
|
|
‘C-c C-o’ (‘forge-browse’)
|
|||
|
|
‘o [on topic in topic list]’ (‘forge-browse-this-topic’)
|
|||
|
|
‘o [on repository in repository list]’ (‘forge-browse-this-repository’)
|
|||
|
|
These commands visit the topic, issue(s), pull-request(s), post,
|
|||
|
|
branch, commit, remote, repository or blob at point in a browser.
|
|||
|
|
|
|||
|
|
-- Command: forge-browse-commit
|
|||
|
|
-- Command: forge-browse-branch
|
|||
|
|
-- Command: forge-browse-repository
|
|||
|
|
‘N b t’ (‘forge-browse-topic’)
|
|||
|
|
‘N b i’ (‘forge-browse-issue’)
|
|||
|
|
‘N b p’ (‘forge-browse-pullreq’)
|
|||
|
|
‘N b r’ (‘forge-browse-remote’)
|
|||
|
|
‘N b I’ (‘forge-browse-issues’)
|
|||
|
|
‘N b P’ (‘forge-browse-pullreqs’)
|
|||
|
|
These commands read a topic, issue(s), pull-request(s), branch,
|
|||
|
|
commit, remote or repository, and open it in a browser.
|
|||
|
|
|
|||
|
|
-- Command: forge-browse-commit
|
|||
|
|
This command visit a blob in a browser.
|
|||
|
|
|
|||
|
|
When invoked from a blob- or file-visiting buffer, visit that blob
|
|||
|
|
without prompting. If the region is active, try to jump to the
|
|||
|
|
marked line or lines, and highlight them in the browser. To what
|
|||
|
|
extend that is possible depends on the forge. When the region is
|
|||
|
|
not active just visit the blob, without trying to jump to the
|
|||
|
|
current line. When jumping to a line, always use a commit hash as
|
|||
|
|
part of the URL. From a file in the worktree with no active
|
|||
|
|
region, instead use the branch name as part of the URL, unless a
|
|||
|
|
prefix argument is used.
|
|||
|
|
|
|||
|
|
When invoked from a Dired buffer, visit the blob at point without
|
|||
|
|
prompting. If a prefix argument is used, the commit hash is
|
|||
|
|
included in the URL.
|
|||
|
|
|
|||
|
|
When invoked from any other buffer, prompt the user for a branch or
|
|||
|
|
commit, and for a file.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Creating Topics and Posts, Next: Editing Topics, Prev: Visiting Topics, Up: Top
|
|||
|
|
|
|||
|
|
7 Creating Topics and Posts
|
|||
|
|
***************************
|
|||
|
|
|
|||
|
|
We call both issues and pull-requests "topics". The contributions to
|
|||
|
|
the conversation are called "posts". The initial topic description is
|
|||
|
|
also called a post.
|
|||
|
|
|
|||
|
|
Creating a new topic or post and editing an existing post work
|
|||
|
|
similarly to now creating a new commit or editing the message of an
|
|||
|
|
existing commit works in Magit. In both cases the message has to be
|
|||
|
|
written in a separate buffer and then the process has to be finished or
|
|||
|
|
canceled using a separate command. The following commands drop you into
|
|||
|
|
such a buffer.
|
|||
|
|
|
|||
|
|
‘N c p’ (‘forge-create-pullreq’)
|
|||
|
|
‘C-c C-n [on "Pull requests" section]’
|
|||
|
|
This command creates a new pull-request for the current repository.
|
|||
|
|
|
|||
|
|
‘N c i’ (‘forge-create-issue’)
|
|||
|
|
‘C-c C-n [on "Issues" section]’
|
|||
|
|
This command creates a new issue for the current repository.
|
|||
|
|
|
|||
|
|
‘C-c C-n’ (‘forge-create-post’)
|
|||
|
|
‘C-c C-r’
|
|||
|
|
This command creates a new post on an existing topic. It is only
|
|||
|
|
available in buffers that visit an existing topic.
|
|||
|
|
|
|||
|
|
If the region is active and marks part of an existing post, then
|
|||
|
|
that part of the post is quoted. When a prefix argument is used,
|
|||
|
|
then the complete post, which point is currently on, is quoted.
|
|||
|
|
|
|||
|
|
The following commands are available in buffers used to edit posts:
|
|||
|
|
|
|||
|
|
‘C-c C-c’ (‘forge-post-submit’)
|
|||
|
|
This command submits the post that is being edited in the current
|
|||
|
|
buffer.
|
|||
|
|
|
|||
|
|
‘C-c C-k’ (‘forge-post-cancel’)
|
|||
|
|
This command cancels the post that is being edited in the current
|
|||
|
|
buffer.
|
|||
|
|
|
|||
|
|
‘C-c C-e’ (‘forge-post-dispatch’)
|
|||
|
|
This prefix command features the above two commands as suffixes,
|
|||
|
|
and when creating a pull-request also the following command. More
|
|||
|
|
suffix commands will likely be added in the future.
|
|||
|
|
|
|||
|
|
‘C-c C-e d’ (‘forge-post-toggle-draft’)
|
|||
|
|
This command toggles whether the pull-request being created is a
|
|||
|
|
draft.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Editing Topics, Next: Pulling, Prev: Creating Topics and Posts, Up: Top
|
|||
|
|
|
|||
|
|
8 Editing Topics
|
|||
|
|
****************
|
|||
|
|
|
|||
|
|
Many details about a topic can be changed from the buffer that visits
|
|||
|
|
that topic, but also from topic lists, if the cursor is placed on the
|
|||
|
|
topic to be edited. However, to edit the posts on a topic, the topic
|
|||
|
|
has to be visited in its own buffer.
|
|||
|
|
|
|||
|
|
‘C-c C-e [on a post section]’ (‘forge-edit-post’)
|
|||
|
|
This command visits an existing post in a separate buffer, it can
|
|||
|
|
only be invoked from a topic buffer, when the cursor is on the post
|
|||
|
|
to be edited.
|
|||
|
|
|
|||
|
|
Editing an existing post is similar to creating a new post, as
|
|||
|
|
described in the previous section.
|
|||
|
|
|
|||
|
|
‘C-c C-k [on a post section]’ (‘forge-delete-comment’)
|
|||
|
|
This command deletes the post the cursor is on. The initial
|
|||
|
|
message that was written when the topic was created, cannot be
|
|||
|
|
deleted, only replies to that.
|
|||
|
|
|
|||
|
|
‘N m s’ (‘forge-topic-menu’)
|
|||
|
|
‘C-<return> [on a topic section]’
|
|||
|
|
This command displays a menu used to edit details about the topic
|
|||
|
|
the cursor is on or that is being visited in the current buffer.
|
|||
|
|
E.g., it can be used to change the status of the topic or to apply
|
|||
|
|
labels to it. Additionally it features a few commands that act on
|
|||
|
|
that topic.
|
|||
|
|
|
|||
|
|
With a prefix argument, this additionally visits the topic.
|
|||
|
|
|
|||
|
|
Details about a topic, such as its status and labels, can
|
|||
|
|
alternatively be edited by visiting the topic in its own buffer,
|
|||
|
|
navigating to the header that displays the detail and then typing ‘C-c
|
|||
|
|
C-e’. This older approach is still available, but it is usually much
|
|||
|
|
faster to use the menu.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Pulling, Next: Branching, Prev: Editing Topics, Up: Top
|
|||
|
|
|
|||
|
|
9 Pulling
|
|||
|
|
*********
|
|||
|
|
|
|||
|
|
The commands that fetch forge data are available the Forge's main menu
|
|||
|
|
(‘forge-dispatch’ on ‘N’) and from the same menu (‘magit-fetch’ on ‘f’)
|
|||
|
|
that is used to fetch Git data. If ‘magit-pull-or-fetch’ is non-‘nil’,
|
|||
|
|
then they are also available from the ‘magit-pull’ menu (on ‘F’).
|
|||
|
|
|
|||
|
|
With Git you have to explicitly pull Git data to make it available in
|
|||
|
|
the local repository. Forge works the same; you have to explicitly pull
|
|||
|
|
to pull data using the forge's API and storing in the local database.
|
|||
|
|
This is less disruptive, more reliable, familiar and easier to
|
|||
|
|
understand than if Forge pulled by itself at random intervals. It might
|
|||
|
|
however mean that you occasionally invoke a command expecting the most
|
|||
|
|
recent data to be available and then have to abort and pull first. The
|
|||
|
|
same can happen with Git, e.g., you might attempt to merge a branch that
|
|||
|
|
you know exists but haven't actually pulled yet.
|
|||
|
|
|
|||
|
|
‘f n’ (‘forge-pull’)
|
|||
|
|
‘N f f’
|
|||
|
|
This command uses a forge's API to fetch topics and other
|
|||
|
|
information about the current repository and stores the fetched
|
|||
|
|
information in the database.
|
|||
|
|
|
|||
|
|
If the current repository is still untracked locally, or the
|
|||
|
|
current repository cannot be determined, this command instead
|
|||
|
|
behaves like ‘forge-add-repository’, i.e., it adds the repository
|
|||
|
|
to the database and then performs the initial pull.
|
|||
|
|
|
|||
|
|
‘f N’ (‘forge-pull-notifications’)
|
|||
|
|
‘N f n’
|
|||
|
|
This command uses a forge's API to fetch all notifications from
|
|||
|
|
that forge, including, but not limited to, the notifications for
|
|||
|
|
the current repository.
|
|||
|
|
|
|||
|
|
Fetching notifications fetches associated topics even for
|
|||
|
|
repositories that you have not yet explicitly added to the local
|
|||
|
|
database.
|
|||
|
|
|
|||
|
|
‘N f t’ (‘forge-pull-topic’)
|
|||
|
|
This command uses a forge's API to fetch a single pull-request and
|
|||
|
|
stores it in the database. This is useful if you chose to not
|
|||
|
|
fetch all topics when you added the repository using
|
|||
|
|
‘forge-add-repository’.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Branching, Next: Miscellaneous Commands, Prev: Pulling, Up: Top
|
|||
|
|
|
|||
|
|
10 Branching
|
|||
|
|
************
|
|||
|
|
|
|||
|
|
Forge provides commands for creating and checking out a new branch or
|
|||
|
|
work tree from a pull-request. These commands are available from the
|
|||
|
|
same transient prefix commands as the suffix commands, used to create
|
|||
|
|
and check out branches and work trees in a more generic fashion
|
|||
|
|
(‘magit-branch’ on ‘b’ and ‘magit-worktree’ on ‘%’).
|
|||
|
|
|
|||
|
|
‘b F’ (‘forge-branch-pullreq’)
|
|||
|
|
This command creates and configures a new branch from a
|
|||
|
|
pull-request, creating and configuring a new remote if necessary.
|
|||
|
|
|
|||
|
|
The name of the local branch is the same as the name of the remote
|
|||
|
|
branch that you are being asked to merge, unless the contributor
|
|||
|
|
could not be bothered to properly name the branch before opening
|
|||
|
|
the pull-request. The most likely such case is when you are being
|
|||
|
|
asked to merge something like "fork/master" into "origin/master".
|
|||
|
|
In such cases the local branch will be named "pr-N", where ‘N’ is
|
|||
|
|
the pull-request number.
|
|||
|
|
|
|||
|
|
These variables are always set by this command:
|
|||
|
|
|
|||
|
|
• ‘branch.<name>.pullRequest’ is set to the pull-request number.
|
|||
|
|
• ‘branch.<name>.pullRequestRemote’ is set to the remote on
|
|||
|
|
which the pull-request branch is located.
|
|||
|
|
• ‘branch.<name>.pushRemote’ is set to the same remote as
|
|||
|
|
‘branch.<name>.pullRequestRemote’ if that is possible,
|
|||
|
|
otherwise it is set to the upstream remote.
|
|||
|
|
• ‘branch.<name>.description’ is set to the pull-request title.
|
|||
|
|
• ‘branch.<name>.rebase’ is set to ‘true’ because there should
|
|||
|
|
be no merge commits among the commits in a pull-request.
|
|||
|
|
|
|||
|
|
This command also configures the upstream and the push-remote of
|
|||
|
|
the local branch that it creates.
|
|||
|
|
|
|||
|
|
The branch against which the pull-request was opened is always used
|
|||
|
|
as the upstream. This makes it easy to see what commits you are
|
|||
|
|
being asked to merge in the section titled something like "Unmerged
|
|||
|
|
into origin/master".
|
|||
|
|
|
|||
|
|
Like for other commands that create a branch, it depends on the
|
|||
|
|
option ‘magit-branch-prefer-remote-upstream’ whether the remote
|
|||
|
|
branch itself or the respective local branch is used as the
|
|||
|
|
upstream, so this section may also be titled, e.g., "Unmerged into
|
|||
|
|
master".
|
|||
|
|
|
|||
|
|
When necessary and possible, the remote pull-request branch is
|
|||
|
|
configured to be used as the push-target. This makes it easy to
|
|||
|
|
see what further changes the contributor has made since you last
|
|||
|
|
reviewed their changes in the section titled something like
|
|||
|
|
"Unpulled from origin/new-feature" or "Unpulled from
|
|||
|
|
fork/new-feature".
|
|||
|
|
|
|||
|
|
• If the pull-request branch is located in the upstream
|
|||
|
|
repository, then you probably have set ‘remote.pushDefault’ to
|
|||
|
|
that repository. However some users like to set that variable
|
|||
|
|
to their personal fork, even if they have push access to the
|
|||
|
|
upstream, so ‘branch.<name>.pushRemote’ is set anyway.
|
|||
|
|
|
|||
|
|
• The push-remote is configured using
|
|||
|
|
‘branch.<name>.pushRemote’, even if the used value is
|
|||
|
|
identical to that of ‘remote.pushDefault’, just in case you
|
|||
|
|
change the value of the latter later on. Additionally the
|
|||
|
|
variable ‘branch.<name>.pullRequestRemote’ is set to the
|
|||
|
|
remote on which the pull-request branch is located.
|
|||
|
|
|
|||
|
|
• If the pull-request branch is located on the contributor's
|
|||
|
|
fork, then you, as a maintainer of the upstream repository,
|
|||
|
|
are usually allowed to push to that branch anyway. (However,
|
|||
|
|
the contributor could explicitly disallow this, but in my
|
|||
|
|
experience that rarely happens.)
|
|||
|
|
|
|||
|
|
• As mentioned above, contributors sometimes fail to use a
|
|||
|
|
dedicated branch for their pull-requests and this command is
|
|||
|
|
thus forced to make up a branch name such as "pr-313".
|
|||
|
|
|
|||
|
|
Usually a maintainer would use
|
|||
|
|
‘magit-push-current-to-pushremote’ (on ‘p’) to push to the
|
|||
|
|
contributor's pull-request branch on their fork. For a branch
|
|||
|
|
named "pr-313" that does not work. (Instead of pushing to
|
|||
|
|
"fork/main", it would unsuccessfully attempt to create a new
|
|||
|
|
branch "pr-313" on the fork.) In such situations the
|
|||
|
|
‘magit-push’ menu offers an alternative command for pushing to
|
|||
|
|
the pull-request branch: ‘forge-push-to-unnamed-pullreq’ (on
|
|||
|
|
‘N’).
|
|||
|
|
|
|||
|
|
‘b f’ (‘forge-checkout-pullreq’)
|
|||
|
|
This command creates and configures a new branch from a
|
|||
|
|
pull-request the same way ‘forge-branch-pullreq’ does.
|
|||
|
|
Additionally it checks out the new branch.
|
|||
|
|
|
|||
|
|
‘Z n’ (‘forge-checkout-worktree’)
|
|||
|
|
This command creates and configures a new branch from a
|
|||
|
|
pull-request the same way ‘forge-branch-pullreq’ does.
|
|||
|
|
Additionally it checks out the new branch, using a new working
|
|||
|
|
tree.
|
|||
|
|
|
|||
|
|
-- User Option: forge-checkout-worktree-read-directory-function
|
|||
|
|
This function is used by ‘forge-checkout-worktree’, to read the new
|
|||
|
|
worktree directory where it checks out the pull-request. It takes
|
|||
|
|
the pull-request as the only argument and must return a directory.
|
|||
|
|
|
|||
|
|
When you delete a pull-request branch, which was created using one of
|
|||
|
|
the above three commands, then ‘magit-branch-delete’ usually offers to
|
|||
|
|
also delete the corresponding remote. It does not offer to delete a
|
|||
|
|
remote if (1) the remote is the upstream remote, and/or (2) if other
|
|||
|
|
branches are being fetched from the remote.
|
|||
|
|
|
|||
|
|
Note that you have to delete the local branch (e.g., "feature") for
|
|||
|
|
this to work. If you delete the tracking branch (e.g., "fork/feature"),
|
|||
|
|
then the remote is never removed.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Miscellaneous Commands, Next: Miscellaneous Options, Prev: Branching, Up: Top
|
|||
|
|
|
|||
|
|
11 Miscellaneous Commands
|
|||
|
|
*************************
|
|||
|
|
|
|||
|
|
‘N M’ (‘forge-merge’)
|
|||
|
|
‘m M [if enabled]’
|
|||
|
|
This command merges the current pull-request using the forge's API.
|
|||
|
|
If there is no current pull-request or with a prefix argument, then
|
|||
|
|
it reads a pull-request to visit instead.
|
|||
|
|
|
|||
|
|
The "merge method" to be used is read from the user.
|
|||
|
|
|
|||
|
|
Use of this command is discouraged. Unless the remote repository
|
|||
|
|
is configured to disallow that, you should instead merge locally
|
|||
|
|
and then push the target branch. Forges detect that you have done
|
|||
|
|
that and respond by automatically marking the pull-request as
|
|||
|
|
merged.
|
|||
|
|
|
|||
|
|
‘N c f’ (‘forge-fork’)
|
|||
|
|
This command adds an additional remote to the current repository.
|
|||
|
|
The remote can either point at an existing repository or one that
|
|||
|
|
has to be created first by forking it to an account the user has
|
|||
|
|
access to.
|
|||
|
|
|
|||
|
|
Currently this only supports Github and Gitlab.
|
|||
|
|
|
|||
|
|
With a prefix argument, fork all branches, not just the default
|
|||
|
|
branch. On Gitlab it is not possible to fork only the default.
|
|||
|
|
|
|||
|
|
‘N - H’ (‘forge-toggle-topic-legend’)
|
|||
|
|
This command toggle whether to show a legend for faces used in
|
|||
|
|
topic menus and lists.
|
|||
|
|
|
|||
|
|
‘N - S’ (‘forge-toggle-display-in-status-buffer’)
|
|||
|
|
This command toggles whether any topics are displayed in the
|
|||
|
|
current Magit status buffer.
|
|||
|
|
|
|||
|
|
‘C-c C-w’ (‘forge-copy-url-at-point-as-kill’)
|
|||
|
|
This command copies the url for the topic, issue(s),
|
|||
|
|
pull-request(s), post, branch, commit, remote or repository to the
|
|||
|
|
kill-ring.
|
|||
|
|
|
|||
|
|
This determines the url the same way as ‘forge-browse’ does, but
|
|||
|
|
then adds it to the kill-ring, instead of visiting it in a browser.
|
|||
|
|
|
|||
|
|
‘M b r’ (‘forge-rename-default-branch’)
|
|||
|
|
This command rename the default branch to a new name read from the
|
|||
|
|
user.
|
|||
|
|
|
|||
|
|
This changes the name on the upstream remotely and locally, and
|
|||
|
|
update the upstream remotes of local branches accordingly.
|
|||
|
|
|
|||
|
|
-- Command: forge-add-pullreq-refspec
|
|||
|
|
This command configures Git to fetch all pull-requests.
|
|||
|
|
|
|||
|
|
This is done by adding ‘+refs/pull/*/head:refs/pullreqs/*’ to the
|
|||
|
|
value of ‘remote.REMOTE.fetch’, where REMOTE is the upstream
|
|||
|
|
remote.
|
|||
|
|
|
|||
|
|
-- Command: forge-add-user-repositories
|
|||
|
|
This command reads a host and a username from the user and adds all
|
|||
|
|
of that user's repositories on that host to the local database.
|
|||
|
|
|
|||
|
|
This may take a while. Only Github is supported at the moment.
|
|||
|
|
|
|||
|
|
-- Command: forge-add-organization-repositories
|
|||
|
|
This command reads a host and an organization from the user and
|
|||
|
|
adds all the organization's repositories on that host to the local
|
|||
|
|
database.
|
|||
|
|
|
|||
|
|
This may take a while. Only Github is supported at the moment.
|
|||
|
|
|
|||
|
|
-- Command: forge-remove-repository
|
|||
|
|
This command reads a repository and removes it from the local
|
|||
|
|
database.
|
|||
|
|
|
|||
|
|
-- Command: forge-remove-topic-locally
|
|||
|
|
This command reads a topic and removes it from the local database.
|
|||
|
|
When the region marks multiple topics, then offer to remove them
|
|||
|
|
all.
|
|||
|
|
|
|||
|
|
The topic is not removed from the forge and, if it is later
|
|||
|
|
modified, then it will be added to the database again when fetching
|
|||
|
|
all topics.
|
|||
|
|
|
|||
|
|
This is useful for users who only fetch individual topics and want
|
|||
|
|
to remove the topics they are no longer interested in. This can
|
|||
|
|
also be used to remove topics locally, which have already been
|
|||
|
|
removed on the forge (the service). Forge (the package) cannot
|
|||
|
|
automatically detect when that happens, because given how the APIs
|
|||
|
|
work, this would be too expensive.
|
|||
|
|
|
|||
|
|
-- Command: forge-reset-database
|
|||
|
|
This command moves the current database file to the trash and
|
|||
|
|
creates a new empty database.
|
|||
|
|
|
|||
|
|
This is useful after the database's table schemata have changed,
|
|||
|
|
which will happen a few times while the Forge functionality is
|
|||
|
|
still under heavy development.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Miscellaneous Options, Next: How Forge Detection Works, Prev: Miscellaneous Commands, Up: Top
|
|||
|
|
|
|||
|
|
12 Miscellaneous Options
|
|||
|
|
************************
|
|||
|
|
|
|||
|
|
-- User Option: forge-database-file
|
|||
|
|
This option specifies the file used to store the forge database.
|
|||
|
|
|
|||
|
|
-- User Option: forge-topic-wash-title-hook
|
|||
|
|
Functions used to highlight parts of each individual topic title.
|
|||
|
|
|
|||
|
|
These functions are called in order, in a buffer that containing
|
|||
|
|
the topic title. They should set text properties as they see fit,
|
|||
|
|
usually just ‘font-lock-face’. Before each function is called,
|
|||
|
|
point is at the beginning of the buffer.
|
|||
|
|
|
|||
|
|
-- User Option: forge-topic-repository-slug-width
|
|||
|
|
This option specifies the width of repository slugs (i.e.,
|
|||
|
|
"OWNER/NAME").
|
|||
|
|
|
|||
|
|
-- User Option: forge-buffer-draft-p
|
|||
|
|
This option controls whether new pull-requests start out as drafts
|
|||
|
|
by default.
|
|||
|
|
|
|||
|
|
The buffer-local value of this variable is used to keep track of
|
|||
|
|
the draft status of the current pull-request.
|
|||
|
|
|
|||
|
|
-- User Option: forge-repository-list-columns
|
|||
|
|
This option specifies the list of columns displayed when listing
|
|||
|
|
repositories.
|
|||
|
|
|
|||
|
|
Each element has the form ‘(HEADER SOURCE WIDTH SORT PROPS)’.
|
|||
|
|
|
|||
|
|
HEADER is the string displayed in the header. WIDTH is the width
|
|||
|
|
of the column. SOURCE is used to get the value, it has to be the
|
|||
|
|
name of a slot of ‘forge-repository’ or a function that takes such
|
|||
|
|
an object as argument. SORT is a boolean or a function used to
|
|||
|
|
sort by this column. Supported PROPS include ‘:right-align’ and
|
|||
|
|
‘:pad-right’.
|
|||
|
|
|
|||
|
|
-- User Option: forge-limit-topic-choices
|
|||
|
|
This option controls whether to initially limit completion
|
|||
|
|
candidates to active topics.
|
|||
|
|
|
|||
|
|
-- User Option: forge-post-heading-format
|
|||
|
|
This option specifies the format for post headings in topic view.
|
|||
|
|
|
|||
|
|
The following ‘%’-sequences are supported:
|
|||
|
|
|
|||
|
|
• ‘%a’ The forge nickname of the author.
|
|||
|
|
• ‘%c’ The absolute creation date.
|
|||
|
|
• ‘%C’ The relative creation date.
|
|||
|
|
|
|||
|
|
-- User Option: forge-post-fill-region
|
|||
|
|
This option controls whether to call ‘fill-region’ before
|
|||
|
|
displaying forge posts.
|
|||
|
|
|
|||
|
|
-- User Option: forge-bug-reference-hooks
|
|||
|
|
This option lists the hooks to which ‘forge-bug-reference-setup’ is
|
|||
|
|
added. It has to be customized before ‘forge’ is loaded, or it
|
|||
|
|
won't take effect.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: How Forge Detection Works, Next: Supported Forges and Hosts, Prev: Miscellaneous Options, Up: Top
|
|||
|
|
|
|||
|
|
Appendix A How Forge Detection Works
|
|||
|
|
************************************
|
|||
|
|
|
|||
|
|
Forge uses the Ghub package to communicate with forge APIs. For more
|
|||
|
|
information about Ghub, see *note (ghub)Top::.
|
|||
|
|
|
|||
|
|
Ghub does *not* associate a given local repository with a repository
|
|||
|
|
on a forge. The Forge package itself takes care of this. In doing so
|
|||
|
|
it ignores the Git variable ‘ghub.host’ and other ‘*.host’ variables
|
|||
|
|
used by Ghub. (But ‘github.user’, and other variables used to specify
|
|||
|
|
the user, are honored).
|
|||
|
|
|
|||
|
|
Forge associates the local repository with a forge repository, by
|
|||
|
|
first determining which remote is associated with the upstream
|
|||
|
|
repository, and then looking that up in ‘forge-alist’.
|
|||
|
|
|
|||
|
|
If only one remote exists, then Forge uses that unconditionally. To
|
|||
|
|
reduce the number of support requests, this is even the case if the Git
|
|||
|
|
variable ‘forge.remote’ names another, non-existent, remote.
|
|||
|
|
|
|||
|
|
If several remotes exist, then a remote may be selected based on its
|
|||
|
|
name. Almost always we want to fetch the data associated with the
|
|||
|
|
upstream repository, so that is what the logic described here tries to
|
|||
|
|
achieve. The convention is to name the upstream remote "origin", and if
|
|||
|
|
that convention were universally followed, then things would be trivial.
|
|||
|
|
However many people name the upstream remote "upstream", which also
|
|||
|
|
makes sense.
|
|||
|
|
|
|||
|
|
Note, however, that even though a surprising number of people do
|
|||
|
|
just that, it does not make any sense to use the name "origin" to
|
|||
|
|
refer to a fork; not even to your own fork. A fork is a *copy* of
|
|||
|
|
the original, "copy" is an antonym for "original", and the word
|
|||
|
|
"origin" is not only closely related to but is even contained in
|
|||
|
|
the word "original". Naming a fork the "origin" is at best
|
|||
|
|
extremely confusing.
|
|||
|
|
|
|||
|
|
copy
|
|||
|
|
a thing made to be similar or identical to another.
|
|||
|
|
|
|||
|
|
original
|
|||
|
|
the earliest form of something, from which copies may be made.
|
|||
|
|
|
|||
|
|
origin
|
|||
|
|
the point or place where something begins, arises, or is
|
|||
|
|
derived.
|
|||
|
|
|
|||
|
|
If several remotes exist, then the following remote names are tried
|
|||
|
|
in order and the first remote thus named that exists in the repository
|
|||
|
|
is used.
|
|||
|
|
|
|||
|
|
1. The value of the Git variable ‘forge.remote’, if set. If the
|
|||
|
|
variable has a value but no remote by the specified name exists,
|
|||
|
|
then a warning is shown, but otherwise this conflict is ignored.
|
|||
|
|
This behavior is arguably odd, but due to historic and pragmatic
|
|||
|
|
reasons it is the least painful path forward.
|
|||
|
|
|
|||
|
|
2. The remote named ‘upstream’, if it exists.
|
|||
|
|
|
|||
|
|
3. The remote named ‘origin’, if it exists.
|
|||
|
|
|
|||
|
|
The remote named "upstream" is preferred over the remote named
|
|||
|
|
"origin" because the existence of the former strongly suggests that the
|
|||
|
|
latter is either not used in this repository (in which case the order
|
|||
|
|
does not matter) or else it is abused as the name of a fork (in which
|
|||
|
|
case "upstream" must be preferred).
|
|||
|
|
|
|||
|
|
-- Variable: forge.remote
|
|||
|
|
The value of this variable specifies the remote from which Forge
|
|||
|
|
fetches data. It is usually best to leave this unspecified and to
|
|||
|
|
rely on the behavior described above.
|
|||
|
|
|
|||
|
|
If the remote has to be specified explicitly, then this should be
|
|||
|
|
done locally, for a single repository.
|
|||
|
|
|
|||
|
|
Only ever set this globally, if you consistently use a certain name
|
|||
|
|
to refer to the upstream repository and it isn't one of "upstream"
|
|||
|
|
or "origin", and you *never* use that name to refer to a repository
|
|||
|
|
that does *not* refer to the upstream repository.
|
|||
|
|
|
|||
|
|
‘N r’ (‘forge-forge.remote’)
|
|||
|
|
This command changes the value of the ‘forge.remote’ Git variable
|
|||
|
|
in the current repository.
|
|||
|
|
|
|||
|
|
If this variable is set, then Forge uses the remote by that name, if
|
|||
|
|
it exists, the same way it may have used ‘origin’ if the variable were
|
|||
|
|
undefined. I.e., it does not fall through to try ‘origin’ if no remote
|
|||
|
|
by your chosen name exists.
|
|||
|
|
|
|||
|
|
Once the upstream remote has been determined, Forge looks it up in
|
|||
|
|
‘forge-alist’, using the host part of the URL as the key. For example,
|
|||
|
|
the key for ‘git@github.com:magit/forge.git’ is ‘github.com’.
|
|||
|
|
|
|||
|
|
-- User Option: forge-alist
|
|||
|
|
This option defines forge hosts known to Forge.
|
|||
|
|
|
|||
|
|
Each entry has the form ‘(GITHOST APIHOST WEBHOST CLASS)’.
|
|||
|
|
|
|||
|
|
• GITHOST is the host used to access repositories on the forge
|
|||
|
|
using Git.
|
|||
|
|
|
|||
|
|
• APIHOST is the host used to access the forge's API. For some
|
|||
|
|
forges the isn't just a host, but a host followed by the path
|
|||
|
|
to the API's endpoint.
|
|||
|
|
|
|||
|
|
• WEBHOST is the host used to access repositories on this forge
|
|||
|
|
using a browser. The IDs used to identify repositories from
|
|||
|
|
the forge in the local database also derives from this value.
|
|||
|
|
|
|||
|
|
• CLASS is the class to be used for repositories from the forge.
|
|||
|
|
|
|||
|
|
Complications:
|
|||
|
|
|
|||
|
|
• When connecting to a Github Enterprise edition whose REST
|
|||
|
|
API's end point is "<host>/v3" and whose GraphQL API's end
|
|||
|
|
point is "<host>/graphql", then use "<host>/v3" as APIHOST.
|
|||
|
|
This is a historic accident. See issue #174.
|
|||
|
|
|
|||
|
|
• WEBHOST and CLASS cannot be changed once you have added one or
|
|||
|
|
more repositories from a forge. Changing GITHOST and/or
|
|||
|
|
APIHOST may be possible, but should seldom be necessary.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Supported Forges and Hosts, Next: FAQ, Prev: How Forge Detection Works, Up: Top
|
|||
|
|
|
|||
|
|
Appendix B Supported Forges and Hosts
|
|||
|
|
*************************************
|
|||
|
|
|
|||
|
|
Currently Forge supports two forges and three more forges partially.
|
|||
|
|
Additionally it supports four semi-forges. Support for more forges and
|
|||
|
|
semi-forges can and will be added.
|
|||
|
|
|
|||
|
|
Both forges and semi-forges provide web interfaces for Git
|
|||
|
|
repositories. Forges additionally support pull-requests and issues and
|
|||
|
|
make those and other information available using an API.
|
|||
|
|
|
|||
|
|
When a forge is only partially supported, then that means that only
|
|||
|
|
the functionality that does not require the API is implemented, or in
|
|||
|
|
other words, that the forge is only supported as a semi-forge.
|
|||
|
|
|
|||
|
|
A host is a particular instance of a forge. For example the hosts
|
|||
|
|
<https://gitlab.com> and <https://salsa.debian.org> are both instances
|
|||
|
|
of the Gitlab forge. Forge supports some well known hosts out of the
|
|||
|
|
box and additional hosts can easily be supported by adding entries to
|
|||
|
|
the option ‘forge-alist’ (see *note How Forge Detection Works::).
|
|||
|
|
|
|||
|
|
For more details about the caveats mentioned below (and some others)
|
|||
|
|
see also *note Getting Started::.
|
|||
|
|
|
|||
|
|
* Menu:
|
|||
|
|
|
|||
|
|
* Supported Forges::
|
|||
|
|
* Partially Supported Forges::
|
|||
|
|
* Supported Semi-Forges::
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Supported Forges, Next: Partially Supported Forges, Up: Supported Forges and Hosts
|
|||
|
|
|
|||
|
|
B.1 Supported Forges
|
|||
|
|
====================
|
|||
|
|
|
|||
|
|
B.1.1 Github
|
|||
|
|
------------
|
|||
|
|
|
|||
|
|
Forge's support for Github can be considered the "reference
|
|||
|
|
implementation". Support for other forges can lag behind a bit.
|
|||
|
|
|
|||
|
|
B.1.1.1 Github Caveats
|
|||
|
|
......................
|
|||
|
|
|
|||
|
|
• Forge uses the Github GraphQL API when possible but has to fall
|
|||
|
|
back to use the REST API in many cases because the former is still
|
|||
|
|
rather incomplete.
|
|||
|
|
|
|||
|
|
• The Github GraphQL API has a hard-coded timeout on queries. The
|
|||
|
|
only solution is to reduce the number of entities we query at once,
|
|||
|
|
which can be done by adjusting either the ‘forge.graphqlItemLimit’
|
|||
|
|
git variable or the field "GQL entity limit" in a status buffer.
|
|||
|
|
|
|||
|
|
• Forge depends on the ‘updated_at’ field being updated when
|
|||
|
|
appropriate. For Github pull-requests at least, that is not always
|
|||
|
|
done.
|
|||
|
|
|
|||
|
|
B.1.1.2 Github Hosts
|
|||
|
|
....................
|
|||
|
|
|
|||
|
|
• <https://github.com>
|
|||
|
|
|
|||
|
|
B.1.2 Gitlab
|
|||
|
|
------------
|
|||
|
|
|
|||
|
|
B.1.2.1 Gitlab Caveats
|
|||
|
|
......................
|
|||
|
|
|
|||
|
|
• Forge cannot provide notifications because the Gitlab API does not
|
|||
|
|
expose those.
|
|||
|
|
|
|||
|
|
B.1.2.2 Gitlab Hosts
|
|||
|
|
....................
|
|||
|
|
|
|||
|
|
• <https://gitlab.com>
|
|||
|
|
• <https://salsa.debian.org>
|
|||
|
|
• <https://framagit.org>
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Partially Supported Forges, Next: Supported Semi-Forges, Prev: Supported Forges, Up: Supported Forges and Hosts
|
|||
|
|
|
|||
|
|
B.2 Partially Supported Forges
|
|||
|
|
==============================
|
|||
|
|
|
|||
|
|
B.2.1 Forgejo https://forgejo.org
|
|||
|
|
---------------------------------
|
|||
|
|
|
|||
|
|
This is the next forge whose API will be supported.
|
|||
|
|
|
|||
|
|
B.2.1.1 Forgejo Hosts
|
|||
|
|
.....................
|
|||
|
|
|
|||
|
|
• <https://codeberg.org>
|
|||
|
|
|
|||
|
|
B.2.2 Gitea https://gitea.io
|
|||
|
|
----------------------------
|
|||
|
|
|
|||
|
|
Once Forgejo is supported it might be fairly simple to support Gitea
|
|||
|
|
too, because the former is a fork of the latter, and their APIs might
|
|||
|
|
still be similar enough.
|
|||
|
|
|
|||
|
|
B.2.3 Gogs https://gogs.io
|
|||
|
|
--------------------------
|
|||
|
|
|
|||
|
|
Once Forgejo is supported it might be fairly simple to support Gogs too,
|
|||
|
|
because the Forgejo is a fork of Gitea, which is a fork of Gogs, and
|
|||
|
|
their APIs might still be similar enough.
|
|||
|
|
|
|||
|
|
B.2.4 Bitbucket https://bitbucket.org
|
|||
|
|
-------------------------------------
|
|||
|
|
|
|||
|
|
I don't plan to support Bitbucket's API any time soon, and it gets less
|
|||
|
|
likely that I will every do it every time I look at it.
|
|||
|
|
|
|||
|
|
B.2.4.1 Bitbucket Caveats
|
|||
|
|
.........................
|
|||
|
|
|
|||
|
|
• The API documentation is poor and initial tests indicated that the
|
|||
|
|
implementation is buggy.
|
|||
|
|
|
|||
|
|
• Atlassian's offering contains two very distinct implementations
|
|||
|
|
that are both called "Bitbucket". Forge only supports the
|
|||
|
|
implementation whose only instance is available at
|
|||
|
|
<https://bitbucket.org>, because I only have access to that.
|
|||
|
|
|
|||
|
|
• Unlike all other forges, Bitbucket does not expose pull-requests as
|
|||
|
|
references in the upstream repository. For that reason Forge
|
|||
|
|
actually treats it as a semi-forge, not as forge whose API is not
|
|||
|
|
supported yet. This means that you cannot checkout pull-requests
|
|||
|
|
locally. There is little hope that this will ever get fixed; the
|
|||
|
|
respective issue was opened six years ago and there has been no
|
|||
|
|
progress since: <https://bitbucket.org/site/master/issues/5814>.
|
|||
|
|
|
|||
|
|
B.2.4.2 Bitbucket Hosts
|
|||
|
|
.......................
|
|||
|
|
|
|||
|
|
• <https://bitbucket.org>
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Supported Semi-Forges, Prev: Partially Supported Forges, Up: Supported Forges and Hosts
|
|||
|
|
|
|||
|
|
B.3 Supported Semi-Forges
|
|||
|
|
=========================
|
|||
|
|
|
|||
|
|
B.3.1 Gitweb https://git-scm.com/docs/gitweb
|
|||
|
|
--------------------------------------------
|
|||
|
|
|
|||
|
|
B.3.1.1 Gitweb Caveats
|
|||
|
|
......................
|
|||
|
|
|
|||
|
|
• I could find only one public installation
|
|||
|
|
(<https://git.savannah.gnu.org>), which gives users the choice
|
|||
|
|
between Gitweb and Cgit. The latter seems more popular (not just
|
|||
|
|
on this site).
|
|||
|
|
|
|||
|
|
B.3.2 Cgit https://git.zx2c4.com/cgit/about
|
|||
|
|
-------------------------------------------
|
|||
|
|
|
|||
|
|
B.3.2.1 Cgit Caveats
|
|||
|
|
....................
|
|||
|
|
|
|||
|
|
• Different sites use different URL schemata and some of the bigger
|
|||
|
|
sites use a fork. For this reason Forge has to provide several
|
|||
|
|
classes to support different variations of Cgit and you have to
|
|||
|
|
look at their definitions to figure out which one is the correct
|
|||
|
|
one for a particular installation.
|
|||
|
|
|
|||
|
|
B.3.2.2 Cgit Hosts
|
|||
|
|
..................
|
|||
|
|
|
|||
|
|
• <https://git.savannah.gnu.org/cgit>
|
|||
|
|
• <https://git.kernel.org>
|
|||
|
|
• <https://repo.or.cz>
|
|||
|
|
|
|||
|
|
B.3.3 Stgit https://codemadness.org/git/stagit/file/README.html
|
|||
|
|
---------------------------------------------------------------
|
|||
|
|
|
|||
|
|
B.3.3.1 Stgit Caveats
|
|||
|
|
.....................
|
|||
|
|
|
|||
|
|
• Stgit cannot show logs for branches beside "master". For that
|
|||
|
|
reason Forge takes users to a page listing the branches when they
|
|||
|
|
request the log for a particular branch (even for "master" whose
|
|||
|
|
log is just one click away from there).
|
|||
|
|
|
|||
|
|
B.3.3.2 Stgit Hosts
|
|||
|
|
...................
|
|||
|
|
|
|||
|
|
• <https://git.suckless.org>
|
|||
|
|
|
|||
|
|
B.3.4 Srht https://meta.sr.ht
|
|||
|
|
-----------------------------
|
|||
|
|
|
|||
|
|
B.3.4.1 Srht Caveats
|
|||
|
|
....................
|
|||
|
|
|
|||
|
|
• Srht cannot show logs for branches beside "master". For that
|
|||
|
|
reason Forge takes users to a page listing the branches when they
|
|||
|
|
request the log for a particular branch (even for "master" whose
|
|||
|
|
log is just one click away from there).
|
|||
|
|
|
|||
|
|
B.3.4.2 Srht Hosts
|
|||
|
|
..................
|
|||
|
|
|
|||
|
|
• <https://git.sr.ht>
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: FAQ, Next: Keystroke Index, Prev: Supported Forges and Hosts, Up: Top
|
|||
|
|
|
|||
|
|
Appendix C FAQ
|
|||
|
|
**************
|
|||
|
|
|
|||
|
|
This section lists some frequently asked questions. Please see also
|
|||
|
|
<https://github.com/magit/forge/wiki/FAQ> for an extended list of common
|
|||
|
|
issues.
|
|||
|
|
|
|||
|
|
* Menu:
|
|||
|
|
|
|||
|
|
* ‘error in process filter HTTP Error 502, "Bad gateway"’: error in process filter HTTP Error 502 "Bad gateway".
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: error in process filter HTTP Error 502 "Bad gateway", Up: FAQ
|
|||
|
|
|
|||
|
|
C.1 ‘error in process filter: HTTP Error: 502, "Bad gateway"’
|
|||
|
|
=============================================================
|
|||
|
|
|
|||
|
|
This is a frequently occurring error. Adding some formatting, the full
|
|||
|
|
error is:
|
|||
|
|
|
|||
|
|
error in process filter: ghub--signal-error: HTTP Error: 502,
|
|||
|
|
"Bad gateway", "/graphql",
|
|||
|
|
((data . "null")
|
|||
|
|
(errors ((message . "Something went wrong while executing your query.
|
|||
|
|
This may be the result of a timeout, or it could be a GitHub bug.
|
|||
|
|
Please include `CC2C:4FEA:A1771C1:CBF40CE:5C33F7E5`
|
|||
|
|
when reporting this issue."))))
|
|||
|
|
|
|||
|
|
This indicates that something went wrong within Github's network.
|
|||
|
|
Unfortunately the reason given is rather vague, but I believe this
|
|||
|
|
usually happens when there are topics with one or two magnitudes more
|
|||
|
|
posts than usual, which can cause GraphQL responses to become huge.
|
|||
|
|
|
|||
|
|
This can be countered in the affected repository by setting the Git
|
|||
|
|
variable ‘forge.graphqlItemLimit’:
|
|||
|
|
|
|||
|
|
git config --local forge.graphqlItemLimit 20
|
|||
|
|
|
|||
|
|
The default is specified using the ‘ghub-graphql-items-per-request’,
|
|||
|
|
which defaults to 50 (down from Github's default and maximum of 100).
|
|||
|
|
|
|||
|
|
Fetching less items per request results in more requests, which slows
|
|||
|
|
down the process, which is why the default should not be too small, but
|
|||
|
|
for some repositories a more aggressive limit is needed.
|
|||
|
|
|
|||
|
|
|
|||
|
|
File: forge.info, Node: Keystroke Index, Next: Function and Command Index, Prev: FAQ, Up: Top
|
|||
|
|
|
|||
|
|
Appendix D Keystroke Index
|
|||
|
|
**************************
|
|||
|
|
|
|||
|
|
|