public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
To: git-commits@fedoraproject.org
Subject: [rpms/fedpkg] 1.48-1: A few patches:
Date: Mon, 10 Aug 2026 21:46:14 GMT	[thread overview]
Message-ID: <178639837439.1.10684596848327907647.rpms-fedpkg-6c63bce5bb44@fedoraproject.org> (raw)

            A new commit has been pushed.

            Repo   : rpms/fedpkg
            Branch : 1.48-1
            Commit : 6c63bce5bb444e16de5465431185c0b9a6aed58b
            Author : Ondřej Nosek <onosek@redhat.com>
            Date   : 2025-02-26T01:43:35+00:00
            Stats  : +462/-1 in 4 file(s)
            URL    : https://src.fedoraproject.org/rpms/fedpkg/c/6c63bce5bb444e16de5465431185c0b9a6aed58b?branch=1.48-1

            Log:
            A few patches:

- Dynamically exclude Rawhide branch from fedpkg branching
- Do not auto-request EPEL x.y modules
- Don't allow to request repositories in modules/ namespace

Signed-off-by: Ondřej Nosek <onosek@redhat.com>

---
diff --git a/0038-Dynamically-exclude-Rawhide-branch-from-fedpkg-branc.patch b/0038-Dynamically-exclude-Rawhide-branch-from-fedpkg-branc.patch
new file mode 100644
index 0000000..a747965
--- /dev/null
+++ b/0038-Dynamically-exclude-Rawhide-branch-from-fedpkg-branc.patch
@@ -0,0 +1,368 @@
+From ffe82116bf3bc01ea8a6bd57d7b1cac995e3b906 Mon Sep 17 00:00:00 2001
+From: Samyak Jain <samyak.jn11@gmail.com>
+Date: Thu, 3 Oct 2024 12:58:50 +0530
+Subject: [PATCH 1/3] Dynamically exclude Rawhide branch from fedpkg branching
+
+JIRA: RHELCMP-14182
+Fixes: #566
+Relates: https://pagure.io/releng/issue/12311
+Merges: https://pagure.io/fedpkg/pull-request/573
+
+Signed-off-by: Samyak Jain <samyak.jn11@gmail.com>
+---
+ fedpkg/cli.py      |   4 +-
+ fedpkg/utils.py    |  55 ++++++++++-----
+ test/test_utils.py | 165 ++++++++++++++++++++++++++++++++++-----------
+ test/utils.py      |   1 -
+ 4 files changed, 170 insertions(+), 55 deletions(-)
+
+diff --git a/fedpkg/cli.py b/fedpkg/cli.py
+index a4381a7..aa57451 100644
+--- a/fedpkg/cli.py
++++ b/fedpkg/cli.py
+@@ -1427,7 +1427,9 @@ class fedpkgClient(cliClient):
+             'Package %s has stream branches: %r',
+             self.cmd.repo_name, [item for item in stream_branches])
+ 
+-        if not self.is_stream_branch(stream_branches, self.cmd.branch_merge):
++        # rawhide was removed from the list of stream branches, but for rawhide branch
++        # the local config should be checked and therefore it has to skip this condition
++        if not self.is_stream_branch(stream_branches + ['rawhide'], self.cmd.branch_merge):
+             return super(fedpkgClient, self)._build(sets)
+ 
+         self.log.debug('Current branch %s is a stream branch.',
+diff --git a/fedpkg/utils.py b/fedpkg/utils.py
+index 4595c44..1ce9177 100644
+--- a/fedpkg/utils.py
++++ b/fedpkg/utils.py
+@@ -23,10 +23,10 @@ from urllib.parse import urlparse
+ 
+ 
+ def query_bodhi(server_url, timeout=60):
+-    query_arg = '/?exclude_archived=True'
++    query_arg = '?exclude_archived=True'
+     api_url = '{0}/releases/{1}'.format(server_url.rstrip('/'), query_arg)
+     try:
+-        rv = requests.get(api_url, timeout=60)
++        rv = requests.get(api_url, timeout=timeout)
+     except ConnectionError as error:
+         error_msg = ('The connection to BODHI failed while trying to get '
+                      'the active release branches. The error was: {0}'
+@@ -39,9 +39,19 @@ def query_bodhi(server_url, timeout=60):
+         raise rpkgError(base_error_msg.format(rv.text))
+ 
+     rv_json = rv.json()
+-    if rv_json['releases']:
+-        for branch in rv_json['releases']:
+-            yield branch['branch']
++    branches = []
++
++    # Collect all branches, maintaining order
++    seen_branches = set()
++    for release in rv_json['releases']:
++        branch = release['branch']
++        if branch == 'rawhide':
++            branch = "f{0}".format(release['version'])  # Replace 'rawhide' with the version
++        if branch not in seen_branches:
++            branches.append(branch)
++            seen_branches.add(branch)
++
++    return branches
+ 
+ 
+ def new_pagure_issue(logger, url, token, title, body, cli_name):
+@@ -244,20 +254,35 @@ def get_pagure_branches(logger, url, namespace, repo_name):
+ 
+ def get_release_branches(server_url):
+     """
+-    Get the active Fedora release branches from Bodhi
++    Get the active Fedora release branches from Bodhi.
+ 
+-    :param  str url: a string of the URL to Bodhi
+-    :return: a mapping containing the active Fedora releases and EPEL branches.
++    :param str server_url: The URL to Bodhi API.
++    :return: A mapping containing the active Fedora releases and EPEL branches, excluding rawhide.
+     :rtype: dict
+     """
++    # Fetch all branches from Bodhi
++    all_branches = query_bodhi(server_url)
++
+     releases = {}
+-    for product_version in query_bodhi(server_url):
+-        if product_version == "rawhide":
++    rawhide_branch = None
++
++    # Traverse the branches once to categorize and find the rawhide branch
++    for branch in all_branches:
++        # Assume the rawhide branch is the latest f-version branch
++        if branch.startswith('f') and branch[1:].isdigit():
++            # Check if this is the highest f-version, hence rawhide
++            if rawhide_branch is None or int(branch[1:]) > int(rawhide_branch[1:]):
++                rawhide_branch = branch
++
++    # Categorize branches into Fedora and EPEL, excluding rawhide
++    for branch in all_branches:
++        if branch == rawhide_branch:
+             continue
+-        short_name = "fedora" if product_version.startswith("f") else "epel"
+-        releases.setdefault(short_name, set()).add(product_version)
+ 
+-    return {key: sorted(list(value)) for key, value in releases.items()}
++        short_name = "fedora" if branch.startswith("f") else "epel"
++        releases.setdefault(short_name, set()).add(branch)
++
++    return {key: sorted(value) for key, value in releases.items()}
+ 
+ 
+ def sl_list_to_dict(sls):
+@@ -454,7 +479,7 @@ def get_stream_branches(server_url, package_name, apibaseurl, logger):
+     release branch name.
+     :rtype: list
+     """
+-    active_branches = set(query_bodhi(server_url))
++    active_branches = query_bodhi(server_url)
+ 
+     package_branches = get_pagure_branches(logger, apibaseurl, "rpms", package_name)
+ 
+@@ -464,7 +489,7 @@ def get_stream_branches(server_url, package_name, apibaseurl, logger):
+ 
+     stream_branches = []
+     for item in intersection:
+-        if re.match(r'^(f|el)\d+$', item):
++        if re.match(r'^f\d+$', item):
+             continue
+         # epel7 is regular release branch
+         # epel8 and above should be considered a stream branch to use
+diff --git a/test/test_utils.py b/test/test_utils.py
+index 19ad2f8..051e813 100644
+--- a/test/test_utils.py
++++ b/test/test_utils.py
+@@ -14,12 +14,11 @@ from configparser import NoOptionError, NoSectionError
+ import json
+ import unittest
+ from unittest.mock import Mock, patch
+-
+ from requests.exceptions import ConnectionError
+-
+ from fedpkg import utils
+ from freezegun import freeze_time
+ from pyrpkg.errors import rpkgError
++import requests
+ 
+ 
+ class TestUtils(unittest.TestCase):
+@@ -100,11 +99,18 @@ class TestUtils(unittest.TestCase):
+             {'name': 'F39', 'branch': 'f39'},
+             {'name': 'F39C', 'branch': 'f39'},
+             {'name': 'F39F', 'branch': 'f39'},
++            {'name': 'F40', 'branch': 'f40'},
++            {'name': 'F40C', 'branch': 'f40'},
++            {'name': 'F40F', 'branch': 'f40'},
++            {'name': 'F41', 'branch': 'f41'},
++            {'name': 'F41C', 'branch': 'f41'},
++            {'name': 'F41F', 'branch': 'f41'},
++            {'name': 'F42', 'branch': 'f42'},
+             ], 'page': 1, 'pages': 1, 'rows_per_page': 20, 'total': 12}
+         mock_request_get.return_value = mock_rv
+         expected = {
+             'epel': ['epel7', 'epel8', 'epel8-next', 'epel9', 'epel9-next'],
+-            'fedora': ['f38', 'f38m', 'f39'],
++            'fedora': ['f38', 'f38m', 'f39', 'f40', 'f41'],
+         }
+         actual = utils.get_release_branches('http://src.local')
+         actual_sorted = {key: sorted(value) for key, value in sorted(actual.items())}
+@@ -434,43 +440,101 @@ class TestNewPagureIssue(unittest.TestCase):
+ 
+ @patch("requests.get")
+ class TestQueryBodhi(unittest.TestCase):
+-    """Test utils.query_bodhi"""
++    """Test suite for utils.query_bodhi"""
+ 
+-    def test_connection_error(self, get):
+-        get.side_effect = ConnectionError
++    def test_connection_error(self, mock_get):
++        """Test that a ConnectionError raises an rpkgError with the correct message."""
++        # Simulate a connection error when making the get request
++        mock_get.side_effect = requests.exceptions.ConnectionError('Mocked connection error')
++
++        with self.assertRaises(rpkgError) as cm:
++            utils.query_bodhi('http://localhost/')
++
++        self.assertIn(
++            'The connection to BODHI failed while trying to get the active release branches. '
++            'The error was: Mocked connection error',
++            str(cm.exception),
++            "Expected error message is missing or incorrect"
++        )
++
++    def test_response_not_ok(self, mock_get):
++        """Test that a non-OK response raises an rpkgError with the correct message."""
++        # Mock a response with .ok as False and a text message
++        mock_rv = Mock()
++        mock_rv.ok = False
++        mock_rv.text = 'Mocked error message'
++        mock_get.return_value = mock_rv
++
++        with self.assertRaises(rpkgError) as cm:
++            utils.query_bodhi('http://localhost/')
+ 
++        self.assertIn(
++            'The following error occurred while trying to get the active release '
++            'branches in Bodhi: Mocked error message',
++            str(cm.exception),
++            "Expected error message is missing or incorrect"
++        )
++
++    def test_read_data_normally(self, mock_get):
++        """Test that query_bodhi returns the correct branch list from a normal response."""
++        # Mock a valid response from the Bodhi API
++        mock_rv = Mock()
++        mock_rv.ok = True
++        mock_rv.json.return_value = {
++            'releases': [
++                {'name': 'F40', 'branch': 'f40'},
++                {'name': 'F41', 'branch': 'f41'},
++                {'name': 'Rawhide Release', 'branch': 'rawhide', 'version': '42'},
++                {'name': 'EPEL9', 'branch': 'epel9'},
++                {'name': 'EPEL8', 'branch': 'epel8'}
++            ]
++        }
++        mock_get.return_value = mock_rv
++
++        # The expected branch list to be returned by query_bodhi
++        expected = ['f40', 'f41', 'f42', 'epel9', 'epel8']
++
++        # Call query_bodhi and compare the result to the expected list
+         result = utils.query_bodhi('http://localhost/')
+-        self.assertRaisesRegex(
+-            rpkgError, 'The connection to BODHI failed',
+-            list, result)
++        self.assertEqual(result, expected, f"Expected branches {expected}, but got {result}")
+ 
+-    def test_response_not_ok(self, get):
+-        get.return_value.ok = False
++    def test_rawhide_not_present(self, mock_get):
++        """Test that if rawhide is not present in the releases,
++        it does not construct a rawhide branch."""
++        # Mock a response without a rawhide entry
++        mock_rv = Mock()
++        mock_rv.ok = True
++        mock_rv.json.return_value = {
++            'releases': [
++                {'name': 'F40', 'branch': 'f40'},
++                {'name': 'F41', 'branch': 'f41'},
++                {'name': 'EPEL9', 'branch': 'epel9'},
++                {'name': 'EPEL8', 'branch': 'epel8'}
++            ]
++        }
++        mock_get.return_value = mock_rv
++
++        # The expected branch list without a rawhide branch
++        expected = ['f40', 'f41', 'epel9', 'epel8']
+ 
++        # Call query_bodhi and compare the result to the expected list
+         result = utils.query_bodhi('http://localhost/')
+-        self.assertRaisesRegex(
+-            rpkgError, 'The following error occurred',
+-            list, result)
++        self.assertEqual(result, expected, f"Expected branches {expected}, but got {result}")
+ 
+-    def test_read_yield_data_normally(self, get):
+-        rv = Mock()
+-        rv.ok = True
+-        rv.json.side_effect = [
+-            {'releases': [
+-                {'name': 'item1', 'branch': 'item2'},
+-                {'name': 'item5', 'branch': 'item6'},
+-                {'name': 'item3', 'branch': 'item4'},
+-                ]}
+-        ]
+-        get.return_value = rv
++    def test_empty_releases(self, mock_get):
++        """Test that an empty releases list returns an empty branches list."""
++        # Mock a response with no releases
++        mock_rv = Mock()
++        mock_rv.ok = True
++        mock_rv.json.return_value = {'releases': []}
++        mock_get.return_value = mock_rv
++
++        # Expected branches should be an empty list
++        expected = []
+ 
++        # Call query_bodhi and compare the result to the expected empty list
+         result = utils.query_bodhi('http://localhost/')
+-        v = next(result)
+-        self.assertEqual('item2', v)
+-        v = next(result)
+-        self.assertEqual('item6', v)
+-        v = next(result)
+-        self.assertEqual('item4', v)
++        self.assertEqual(result, expected, "Expected an empty list of branches, but got some")
+ 
+ 
+ class TestGetStreamBranches(unittest.TestCase):
+@@ -482,13 +546,18 @@ class TestGetStreamBranches(unittest.TestCase):
+         logger = Mock()
+         apibaseurl = "https://bodhiurl"
+         rv = Mock(ok=True)
+-        rv.json.return_value = {'releases': [
+-            {'name': 'ELN', 'branch': 'eln'},
+-            {'name': 'F40', 'branch': 'rawhide'},
+-            {'name': 'F40C', 'branch': 'f40'},
+-            {'name': 'epel8', 'branch': 'epel8'},
+-            ], 'page': 1, 'pages': 1, 'rows_per_page': 20, 'total': 3}
+-        {'releases': [], 'page': 1, 'pages': 0, 'rows_per_page': 20, 'total': 0}
++        rv.json.return_value = {
++            'releases': [
++                {'name': 'ELN', 'branch': 'eln', 'version': '8'},
++                {'name': 'F40', 'branch': 'rawhide', 'version': '40'},
++                {'name': 'F40C', 'branch': 'f40', 'version': '40'},
++                {'name': 'epel8', 'branch': 'epel8', 'version': '8'},
++            ],
++            'page': 1,
++            'pages': 1,
++            'rows_per_page': 20,
++            'total': 4
++        }
+         get.return_value = rv
+         pagure_branches.return_value = ["epel7", "epel8", "epel9", "f38", "f39"]
+ 
+@@ -573,3 +642,23 @@ class TestGetFedoraReleaseState(unittest.TestCase):
+         self.assertRaisesRegex(rpkgError, r"Could not get release state for Fedora \(F30M\): "
+                                "No option 'releases_service' in section: 'fedpkg.bodhi'.",
+                                utils.get_fedora_release_state, config, 'fedpkg', 'F30M')
++
++
++class TestGetReleaseBranches(unittest.TestCase):
++    """Test utils.get_release_branches"""
++
++    @patch('fedpkg.utils.query_bodhi')
++    def test_get_release_branches_excludes_rawhide(self, mock_query_bodhi):
++        """Test that get_release_branches correctly excludes the rawhide branch."""
++        # Mocking the branches returned by query_bodhi
++        mock_query_bodhi.return_value = ['f40', 'f41', 'f42', 'epel9', 'epel8']  # f42 is rawhide
++
++        expected_output = {
++            'fedora': ['f40', 'f41'],
++            'epel': ['epel8', 'epel9']
++        }
++
++        # Run the method and assert that rawhide branch (f42) is excluded
++        result = utils.get_release_branches('https://bodhi.fedoraproject.org/releases/')
++        self.assertEqual(result, expected_output,
++                         msg=f"Expected branches {expected_output}, but got {result}")
+diff --git a/test/utils.py b/test/utils.py
+index b4ce20c..f4e71f3 100644
+--- a/test/utils.py
++++ b/test/utils.py
+@@ -17,7 +17,6 @@ import shutil
+ import subprocess
+ import tempfile
+ import unittest
+-
+ import fedpkg.cli
+ import pyrpkg
+ from fedpkg import Commands
+-- 
+2.48.1
+

diff --git a/0039-Do-not-auto-request-EPEL-x.y-modules.patch b/0039-Do-not-auto-request-EPEL-x.y-modules.patch
new file mode 100644
index 0000000..76a92fc
--- /dev/null
+++ b/0039-Do-not-auto-request-EPEL-x.y-modules.patch
@@ -0,0 +1,40 @@
+From d8df43d8e7a2bbd0ad82318b173d00ffe0b55c3b Mon Sep 17 00:00:00 2001
+From: Carl George <carlwgeorge@gmail.com>
+Date: Wed, 19 Feb 2025 02:00:27 -0600
+Subject: [PATCH 2/3] Do not auto-request EPEL x.y modules
+
+After the EPEL 10.0 mass branching, we discovered that running `fedpkg
+request-branch epel10.0` would file SCM requests for:
+
+- New Branch "epel10.0" for "rpms/<name>"
+- New Repo for "modules/<name>"
+- New Branch "epel10.0" for "modules/<name>"
+
+The second two are invalid and unwanted.  Thankfully Fabio Valentini
+(@decathorpe) noticed that this was similar to what was happening for
+ELN a while back, an pointed me to RELEASE_BRANCH_REGEX.  This adjust
+that regex to also accept EPEL minor version branches.
+
+Related: #564
+
+Signed-off-by: Carl George <carlwgeorge@gmail.com>
+---
+ fedpkg/cli.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fedpkg/cli.py b/fedpkg/cli.py
+index aa57451..33dbd91 100644
+--- a/fedpkg/cli.py
++++ b/fedpkg/cli.py
+@@ -46,7 +46,7 @@ from fedpkg.utils import (assert_new_tests_repo, assert_valid_epel_package,
+                           get_release_branches, get_stream_branches, is_epel,
+                           new_pagure_issue, sl_list_to_dict, verify_sls)
+ 
+-RELEASE_BRANCH_REGEX = r'^(f\d+|el\d+|eln|epel\d+)$'
++RELEASE_BRANCH_REGEX = r'^(f\d+|el\d+|eln|epel\d+|epel\d+\.\d+)$'
+ LOCAL_PACKAGE_CONFIG = 'package.cfg'
+ 
+ BODHI_TEMPLATE = """\
+-- 
+2.48.1
+

diff --git a/0040-Don-t-allow-to-request-repositories-in-modules-names.patch b/0040-Don-t-allow-to-request-repositories-in-modules-names.patch
new file mode 100644
index 0000000..7d7c52f
--- /dev/null
+++ b/0040-Don-t-allow-to-request-repositories-in-modules-names.patch
@@ -0,0 +1,45 @@
+From d3db72608e395720857d2eb91fe81627991c1454 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro@hroncok.cz>
+Date: Sat, 22 Feb 2025 19:17:10 +0100
+Subject: [PATCH 3/3] Don't allow to request repositories in modules/ namespace
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There are no new modules in Fedora distgit.
+
+Signed-off-by: Miro Hrončok <miro@hroncok.cz>
+---
+ conf/etc/rpkg/fedpkg-stage.conf | 2 +-
+ conf/etc/rpkg/fedpkg.conf       | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/conf/etc/rpkg/fedpkg-stage.conf b/conf/etc/rpkg/fedpkg-stage.conf
+index e6f6f15..d33b4cc 100644
+--- a/conf/etc/rpkg/fedpkg-stage.conf
++++ b/conf/etc/rpkg/fedpkg-stage.conf
+@@ -26,7 +26,7 @@ clone_config_container =
+   bz.default-component %(repo)s
+   sendemail.to container-%(repo)s-maintainers@fedoraproject.org
+ distgit_namespaced = True
+-distgit_namespaces = rpms container modules flatpaks
++distgit_namespaces = rpms container flatpaks
+ lookaside_namespaced = True
+ kerberos_realms = STG.FEDORAPROJECT.ORG
+ oidc_id_provider = https://id.stg.fedoraproject.org/openidc/
+diff --git a/conf/etc/rpkg/fedpkg.conf b/conf/etc/rpkg/fedpkg.conf
+index d7da904..fa08a8a 100644
+--- a/conf/etc/rpkg/fedpkg.conf
++++ b/conf/etc/rpkg/fedpkg.conf
+@@ -26,7 +26,7 @@ clone_config_container =
+   bz.default-component %(repo)s
+   sendemail.to container-%(repo)s-maintainers@fedoraproject.org
+ distgit_namespaced = True
+-distgit_namespaces = rpms container modules flatpaks
++distgit_namespaces = rpms container flatpaks
+ lookaside_namespaced = True
+ kerberos_realms = FEDORAPROJECT.ORG
+ oidc_id_provider = https://id.fedoraproject.org/openidc/
+-- 
+2.48.1
+

diff --git a/fedpkg.spec b/fedpkg.spec
index 33ea85c..a4dab3a 100644
--- a/fedpkg.spec
+++ b/fedpkg.spec
@@ -5,7 +5,7 @@
 
 Name:           fedpkg
 Version:        1.45
-Release:        9%{?dist}
+Release:        10%{?dist}
 Summary:        Fedora utility for working with dist-git
 
 # Automatically converted from old format: GPLv2+ - review is highly recommended.
@@ -51,6 +51,9 @@ Patch34:        0034-Update-expired-token-exception-instructions.patch
 Patch35:        0035-releases-info-should-always-show-the-same-order.patch
 Patch36:        0036-Python-3.13-environment-and-renew-testing-image.patch
 Patch37:        0037-Fix-unittests-when-building-for-ELN-target.patch
+Patch38:        0038-Dynamically-exclude-Rawhide-branch-from-fedpkg-branc.patch
+Patch39:        0039-Do-not-auto-request-EPEL-x.y-modules.patch
+Patch40:        0040-Don-t-allow-to-request-repositories-in-modules-names.patch
 
 BuildRequires:  pkgconfig
 BuildRequires:  bash-completion
@@ -133,6 +136,11 @@ mv %{buildroot}%{compdir}/fedpkg.bash %{buildroot}%{compdir}/fedpkg
 
 
 %changelog
+* Wed Feb 26 2025 Ondřej Nosek <onosek@redhat.com> - 1.45-10
+- Dynamically exclude Rawhide branch from fedpkg branching
+- Do not auto-request EPEL x.y modules
+- Don't allow to request repositories in modules/ namespace
+
 * Tue Feb 18 2025 Ondřej Nosek <onosek@redhat.com> - 1.45-9
 - `releases-info` should always show the same order
 - Python 3.13 environment and renew testing image

             reply	other threads:[~2026-08-10 21:46 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-10 21:46  [this message]
  -- strict thread matches above, loose matches on Subject: below --
2026-08-10 21:46 [rpms/fedpkg] 1.48-1: A few patches: 
2026-08-10 21:46 
2026-08-10 21:46 

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=178639837439.1.10684596848327907647.rpms-fedpkg-6c63bce5bb44@fedoraproject.org \
    --to=git-commits@fedoraproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox