public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
From: jkratoch@sourceware.org
To: archer-commits@sourceware.org
Subject: [SCM]  archer-jankratochvil-python: Merge commit 'origin/archer-tromey-python' into archer-jankratochvil-python
Date: Sat, 28 Feb 2009 19:26:00 -0000	[thread overview]
Message-ID: <20090228192645.18378.qmail@sourceware.org> (raw)

The branch, archer-jankratochvil-python has been updated
       via  8cfb53175964b36c34f54147a3ea057c9a7fd728 (commit)
       via  960557011f37ee49ac8109c9090e1f8ac5df41a9 (commit)
       via  73864473aa5f3f47d681c6a1d95e04c2ecff2180 (commit)
       via  745c2e91d30f0ee78c2a9e2779b807f382be51d1 (commit)
       via  8d7cda5302bef3e53337906e3ac3f5dffaa372ca (commit)
       via  2206b86f85f03bf20dbe642703bc02ad58a35e61 (commit)
       via  6dd3e965ad875563547f5d36ae74e3940050c706 (commit)
       via  d19d9fde47e23944526327e3c7942b93c4ac4277 (commit)
      from  ebadcf6e954061122d1c6d0a1e79de5cf23b85b8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
-----------------------------------------------------------------------

Summary of changes:
 gdb/doc/gdb.texinfo                     |   16 +++-
 gdb/python/python-cmd.c                 |   12 ++-
 gdb/python/python-frame.c               |  136 +++++++++++++++++++++++++------
 gdb/python/python-internal.h            |    2 +-
 gdb/python/python-symbol.c              |   18 +++--
 gdb/python/python-value.c               |   16 +++--
 gdb/python/python.c                     |   37 +++++---
 gdb/testsuite/gdb.python/find.exp       |   43 +++++++---
 gdb/testsuite/gdb.python/python-cmd.exp |   26 ++++++
 9 files changed, 229 insertions(+), 77 deletions(-)

First 500 lines of diff:
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 4f27cdf..be22f07 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -18157,6 +18157,14 @@ auto-loading is disabled.
 @cindex python api
 @cindex programming in python
 
+You can get quick online help for @value{GDBN}'s Python API by issuing
+the command @w{@kbd{python help (gdb)}}.
+
+Functions and methods which have two or more optional arguments allow
+them to be specified using keyword syntax.  This allows passing some
+optional arguments while skipping others.  Example:
+@w{@code{gdb.some_function ('foo', bar = 1, baz = 2)}}.
+
 @cindex python stdout
 @cindex python pagination
 At startup, @value{GDBN} overrides Python's @code{sys.stdout} and
@@ -18476,7 +18484,7 @@ The result @code{bar} will be a @code{gdb.Value} object holding the
 value pointed to by @code{foo}.
 @end defmethod
 
-@defmethod Value string @r{[}encoding @r{[}errors@r{]}@r{]}
+@defmethod Value string @r{[}encoding@r{]} @r{[}errors@r{]}
 If this @code{gdb.Value} represents a string, then this method
 converts the contents to a Python string.  Otherwise, this method will
 throw an exception.
@@ -18976,7 +18984,7 @@ You can implement new @value{GDBN} CLI commands in Python.  A CLI
 command is implemented using an instance of the @code{gdb.Command}
 class, most commonly using a subclass.
 
-@defmethod Command __init__ name @var{command-class} @r{[}@var{completer-class} @var{prefix}@r{]}
+@defmethod Command __init__ name @var{command_class} @r{[}@var{completer_class}@r{]} @r{[}@var{prefix}@r{]}
 The object initializer for @code{Command} registers the new command
 with @value{GDBN}.  This initializer is normally invoked from the
 subclass' own @code{__init__} method.
@@ -18988,11 +18996,11 @@ an exception is raised.
 
 There is no support for multi-line commands.
 
-@var{command-class} should be one of the @samp{COMMAND_} constants
+@var{command_class} should be one of the @samp{COMMAND_} constants
 defined below.  This argument tells @value{GDBN} how to categorize the
 new command in the help system.
 
-@var{completer-class} is an optional argument.  If given, it should be
+@var{completer_class} is an optional argument.  If given, it should be
 one of the @samp{COMPLETE_} constants defined below.  This argument
 tells @value{GDBN} how to perform completion for this command.  If not
 given, @value{GDBN} will attempt to complete using the object's
diff --git a/gdb/python/python-cmd.c b/gdb/python/python-cmd.c
index 90cc780..e6e3ac0 100644
--- a/gdb/python/python-cmd.c
+++ b/gdb/python/python-cmd.c
@@ -337,16 +337,16 @@ gdbpy_parse_command_name (char *text, struct cmd_list_element ***base_list,
 
 /* Object initializer; sets up gdb-side structures for command.
 
-   Use: __init__(NAME, CMDCLASS, [COMPLETERCLASS, [PREFIX]]).
+   Use: __init__(NAME, COMMAND_CLASS, [COMPLETER_CLASS, [PREFIX]]).
 
    NAME is the name of the command.  It may consist of multiple words,
    in which case the final word is the name of the new command, and
    earlier words must be prefix commands.
 
-   CMDCLASS is the kind of command.  It should be one of the COMMAND_*
+   COMMAND_CLASS is the kind of command.  It should be one of the COMMAND_*
    constants defined in the gdb module.
 
-   COMPLETERCLASS is the kind of completer.  If not given, the
+   COMPLETER_CLASS is the kind of completer.  If not given, the
    "complete" method will be used.  Otherwise, it should be one of the
    COMPLETE_* constants defined in the gdb module.
 
@@ -357,7 +357,7 @@ gdbpy_parse_command_name (char *text, struct cmd_list_element ***base_list,
    
 */
 static int
-cmdpy_init (PyObject *self, PyObject *args, PyObject *kwds)
+cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
 {
   cmdpy_object *obj = (cmdpy_object *) self;
   char *name;
@@ -367,6 +367,8 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kwds)
   volatile struct gdb_exception except;
   struct cmd_list_element **cmd_list;
   char *cmd_name, *pfx_name;
+  static char *keywords[] = { "name", "command_class", "completer_class",
+			      "prefix", NULL };
   PyObject *is_prefix = NULL;
   int cmp;
 
@@ -379,7 +381,7 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kwds)
       return -1;
     }
 
-  if (! PyArg_ParseTuple (args, "si|iO", &name, &cmdtype,
+  if (! PyArg_ParseTupleAndKeywords (args, kw, "si|iO", keywords, &name, &cmdtype,
 			  &completetype, &is_prefix))
     return -1;
 
diff --git a/gdb/python/python-frame.c b/gdb/python/python-frame.c
index c2224cf..ef1c178 100644
--- a/gdb/python/python-frame.c
+++ b/gdb/python/python-frame.c
@@ -1,6 +1,6 @@
 /* Python interface to stack frames
 
-   Copyright (C) 2008 Free Software Foundation, Inc.
+   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -54,6 +54,9 @@ typedef struct {
 
 static PyTypeObject frame_object_type;
 
+/* Returns the frame_info object corresponding to the given Python Frame
+   object.  If the frame doesn't exist anymore (the frame id doesn't
+   correspond to any frame in the inferior), returns NULL.  */
 
 static struct frame_info *
 frame_object_to_frame_info (frame_object *frame_obj)
@@ -70,6 +73,9 @@ frame_object_to_frame_info (frame_object *frame_obj)
   return frame;
 }
 
+/* Called by the Python interpreter to obtain string representation
+   of the object.  */
+
 static PyObject *
 frapy_str (PyObject *self)
 {
@@ -87,6 +93,10 @@ frapy_str (PyObject *self)
   return result;
 }
 
+/* Implementation of gdb.Frame.is_valid (self) -> Boolean.
+   Returns True if the frame corresponding to the frame_id of this
+   object still exists in the inferior.  */
+
 static PyObject *
 frapy_is_valid (PyObject *self, PyObject *args)
 {
@@ -99,6 +109,8 @@ frapy_is_valid (PyObject *self, PyObject *args)
   Py_RETURN_TRUE;
 }
 
+/* Implementation of gdb.Frame.equals (self, other) -> Boolean. */
+
 static PyObject *
 frapy_equal_p (PyObject *self, PyObject *args)
 {
@@ -122,6 +134,9 @@ frapy_equal_p (PyObject *self, PyObject *args)
   Py_RETURN_FALSE;
 }
 
+/* Implementation of gdb.Frame.name (self) -> String.
+   Returns the name of the function corresponding to this frame.  */
+
 static PyObject *
 frapy_name (PyObject *self, PyObject *args)
 {
@@ -150,6 +165,9 @@ frapy_name (PyObject *self, PyObject *args)
   return result;
 }
 
+/* Implementation of gdb.Frame.type (self) -> Integer.
+   Returns the frame type, namely one of the gdb.*_FRAME constants.  */
+
 static PyObject *
 frapy_type (PyObject *self, PyObject *args)
 {
@@ -168,6 +186,9 @@ frapy_type (PyObject *self, PyObject *args)
   return PyInt_FromLong (type);
 }
 
+/* Implementation of gdb.Frame.unwind_stop_reason (self) -> Integer.
+   Returns one of the gdb.FRAME_UNWIND_* constants.  */
+
 static PyObject *
 frapy_unwind_stop_reason (PyObject *self, PyObject *args)
 {
@@ -186,6 +207,9 @@ frapy_unwind_stop_reason (PyObject *self, PyObject *args)
   return PyInt_FromLong (stop_reason);
 }
 
+/* Implementation of gdb.Frame.pc (self) -> Long.
+   Returns the frame's resume address.  */
+
 static PyObject *
 frapy_pc (PyObject *self, PyObject *args)
 {
@@ -204,6 +228,9 @@ frapy_pc (PyObject *self, PyObject *args)
   return PyLong_FromUnsignedLongLong (pc);
 }
 
+/* Implementation of gdb.Frame.block (self) -> gdb.Block.
+   Returns the frame's code block.  */
+
 static PyObject *
 frapy_block (PyObject *self, PyObject *args)
 {
@@ -225,6 +252,10 @@ frapy_block (PyObject *self, PyObject *args)
   Py_RETURN_NONE;
 }
 
+
+/* Implementation of gdb.Frame.addr_in_block (self) -> Long.
+   Returns an address which falls within the frame's code block.  */
+
 static PyObject *
 frapy_addr_in_block (PyObject *self, PyObject *args)
 {
@@ -243,6 +274,9 @@ frapy_addr_in_block (PyObject *self, PyObject *args)
   return PyLong_FromUnsignedLongLong (pc);
 }
 
+/* Convert a frame_info struct to a Python Frame object.
+   Sets a Python exception and returns NULL on error.  */
+
 static frame_object *
 frame_info_to_frame_object (struct frame_info *frame)
 {
@@ -276,6 +310,10 @@ frame_info_to_frame_object (struct frame_info *frame)
   return frame_obj;
 }
 
+/* Implementation of gdb.Frame.older (self) -> gdb.Frame.
+   Returns the frame immediately older (outer) to this frame, or None if
+   there isn't one.  */
+
 static PyObject *
 frapy_older (PyObject *self, PyObject *args)
 {
@@ -301,6 +339,10 @@ frapy_older (PyObject *self, PyObject *args)
   return prev_obj;
 }
 
+/* Implementation of gdb.Frame.newer (self) -> gdb.Frame.
+   Returns the frame immediately newer (inner) to this frame, or None if
+   there isn't one.  */
+
 static PyObject *
 frapy_newer (PyObject *self, PyObject *args)
 {
@@ -326,6 +368,9 @@ frapy_newer (PyObject *self, PyObject *args)
   return next_obj;
 }
 
+/* Implementation of gdb.Frame.find_sal (self) -> gdb.Symtab_and_line.
+   Returns the frame's symtab and line.  */
+
 static PyObject *
 frapy_find_sal (PyObject *self, PyObject *args)
 {
@@ -346,6 +391,11 @@ frapy_find_sal (PyObject *self, PyObject *args)
   return sal_obj;
 }
 
+/* Implementation of gdb.Frame.read_var_value (self, variable) -> gdb.Value.
+   Returns the value of the given variable in this frame.  The argument can be
+   either a gdb.Symbol or a string.  Returns None if GDB can't find the
+   specified variable.  */
+
 static PyObject *
 frapy_read_var_value (PyObject *self, PyObject *args)
 {
@@ -355,13 +405,33 @@ frapy_read_var_value (PyObject *self, PyObject *args)
   struct value *val = NULL;
   volatile struct gdb_exception except;
 
-  if (!PyArg_ParseTuple (args, "O!", &symbol_object_type, &sym_obj))
+  if (!PyArg_ParseTuple (args, "O", &sym_obj))
     return NULL;
 
-  var = symbol_object_to_symbol (sym_obj);
-  if (! var)
+  if (PyObject_TypeCheck (sym_obj, &symbol_object_type))
+    var = symbol_object_to_symbol (sym_obj);
+  else if (gdbpy_is_string (sym_obj))
     {
-      PyErr_SetString (PyExc_RuntimeError, "second argument must be symbol");
+      char *var_name;
+      struct block *block;
+      volatile struct gdb_exception except;
+
+      TRY_CATCH (except, RETURN_MASK_ALL)
+	{
+	  struct block *block;
+
+	  FRAPY_REQUIRE_VALID ((frame_object *) self, frame);
+
+	  block = block_for_pc (get_frame_address_in_block (frame));
+	  var = lookup_symbol (python_string_to_target_string (sym_obj), block,
+			       VAR_DOMAIN, NULL);
+	}
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  else
+    {
+      PyErr_SetString (PyExc_TypeError,
+		       _("argument must be a symbol or string"));
       return NULL;
     }
 
@@ -379,6 +449,9 @@ frapy_read_var_value (PyObject *self, PyObject *args)
   Py_RETURN_NONE;
 }
 
+/* Implementation of gdb.frames () -> (gdb.Frame, ...).
+   Returns a tuple of all frame objects.  */
+
 PyObject *
 gdbpy_frames (PyObject *self, PyObject *args)
 {
@@ -429,6 +502,9 @@ gdbpy_frames (PyObject *self, PyObject *args)
   return tuple;
 }
 
+/* Implementation of gdb.newest_frame () -> gdb.Frame.
+   Returns the newest frame object.  */
+
 PyObject *
 gdbpy_newest_frame (PyObject *self, PyObject *args)
 {
@@ -446,6 +522,9 @@ gdbpy_newest_frame (PyObject *self, PyObject *args)
   return (PyObject *) frame_obj;
 }
 
+/* Implementation of gdb.selected_frame () -> gdb.Frame.
+   Returns the selected frame object.  */
+
 PyObject *
 gdbpy_selected_frame (PyObject *self, PyObject *args)
 {
@@ -463,6 +542,9 @@ gdbpy_selected_frame (PyObject *self, PyObject *args)
   return (PyObject *) frame_obj;
 }
 
+/* Implementation of gdb.stop_reason_string (Integer) -> String.
+   Return a string explaining the unwind stop reason.  */
+
 PyObject *
 gdbpy_frame_stop_reason_string (PyObject *self, PyObject *args)
 {
@@ -482,6 +564,8 @@ gdbpy_frame_stop_reason_string (PyObject *self, PyObject *args)
   return PyUnicode_Decode (str, strlen (str), host_charset (), NULL);
 }
 
+/* Sets up the Frame API in the gdb module.  */
+
 void
 gdbpy_initialize_frames (void)
 {
@@ -523,7 +607,7 @@ static PyMethodDef frame_object_methods[] = {
     "Return the function name of the frame." },
   { "type", frapy_type, METH_NOARGS, "Return the type of the frame." },
   { "unwind_stop_reason", frapy_unwind_stop_reason, METH_NOARGS,
-    "Return the function name of the frame." },
+    "Return the reason why it's not possible to find frames older than this." },
   { "pc", frapy_pc, METH_NOARGS, "Return the frame's resume address." },
   { "block", frapy_block, METH_NOARGS, "Return the frame's code block." },
   { "addr_in_block", frapy_addr_in_block, METH_NOARGS,
@@ -541,26 +625,26 @@ static PyMethodDef frame_object_methods[] = {
 
 static PyTypeObject frame_object_type = {
   PyObject_HEAD_INIT (NULL)
-  0,				  /*ob_size*/
-  "gdb.Frame",			  /*tp_name*/
-  sizeof (frame_object),	  /*tp_basicsize*/
-  0,				  /*tp_itemsize*/
-  0,				  /*tp_dealloc*/
-  0,				  /*tp_print*/
-  0,				  /*tp_getattr*/
-  0,				  /*tp_setattr*/
-  0,				  /*tp_compare*/
-  0,				  /*tp_repr*/
-  0,				  /*tp_as_number*/
-  0,				  /*tp_as_sequence*/
-  0,				  /*tp_as_mapping*/
-  0,				  /*tp_hash */
-  0,				  /*tp_call*/
-  frapy_str,			  /*tp_str*/
-  0,				  /*tp_getattro*/
-  0,				  /*tp_setattro*/
-  0,				  /*tp_as_buffer*/
-  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
+  0,				  /* ob_size */
+  "gdb.Frame",			  /* tp_name */
+  sizeof (frame_object),	  /* tp_basicsize */
+  0,				  /* tp_itemsize */
+  0,				  /* tp_dealloc */
+  0,				  /* tp_print */
+  0,				  /* tp_getattr */
+  0,				  /* tp_setattr */
+  0,				  /* tp_compare */
+  0,				  /* tp_repr */
+  0,				  /* tp_as_number */
+  0,				  /* tp_as_sequence */
+  0,				  /* tp_as_mapping */
+  0,				  /* tp_hash  */
+  0,				  /* tp_call */
+  frapy_str,			  /* tp_str */
+  0,				  /* tp_getattro */
+  0,				  /* tp_setattro */
+  0,				  /* tp_as_buffer */
+  Py_TPFLAGS_DEFAULT,		  /* tp_flags */
   "GDB frame object",		  /* tp_doc */
   0,				  /* tp_traverse */
   0,				  /* tp_clear */
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 12422af..4aae0aa 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -78,7 +78,7 @@ PyObject *gdbpy_breakpoints (PyObject *, PyObject *);
 PyObject *gdbpy_frames (PyObject *, PyObject *);
 PyObject *gdbpy_newest_frame (PyObject *, PyObject *);
 PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
-PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args);
+PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw);
 PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args);
 PyObject *gdbpy_block_for_pc (PyObject *self, PyObject *args);
 PyObject *gdbpy_read_memory (PyObject *self, PyObject *args);
diff --git a/gdb/python/python-symbol.c b/gdb/python/python-symbol.c
index 223e6d3..c7fda5c 100644
--- a/gdb/python/python-symbol.c
+++ b/gdb/python/python-symbol.c
@@ -166,21 +166,23 @@ symbol_object_to_symbol (PyObject *obj)
   return ((symbol_object *) obj)->symbol;
 }
 
-/* This function has less arguments than its C counterpart, to simplify the
-   Python interface: name, block and domain. The other two arguments are always
-   assumed to be set, and a tuple with 2 elements is always returned. The first
-   is the symbol object or None, the second is a boolean with the value of
-   is_a_field_of_this.  */
-PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args)
+/* Implementation of
+   gdb.lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this)
+   A tuple with 2 elements is always returned.  The first is the symbol
+   object or None, the second is a boolean with the value of
+   is_a_field_of_this (see comment in lookup_symbol_in_language).  */
+
+PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw)
 {
   int domain = VAR_DOMAIN, is_a_field_of_this = 0;
   const char *name;
+  static char *keywords[] = { "name", "block", "domain", NULL };
   struct symbol *symbol;
   PyObject *block_obj = NULL, *ret_tuple, *sym_obj, *bool_obj;
   struct block *block = NULL;
 
-  if (! PyArg_ParseTuple (args, "s|O!i", &name, &block_object_type, &block_obj,
-			  &domain))
+  if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O!i", keywords, &name,
+				     &block_object_type, &block_obj, &domain))
     return NULL;
 
   if (block_obj)
diff --git a/gdb/python/python-value.c b/gdb/python/python-value.c
index ca29f46..de54b9d 100644
--- a/gdb/python/python-value.c
+++ b/gdb/python/python-value.c
@@ -155,10 +155,11 @@ valpy_type (PyObject *self, PyObject *args)
   return type_to_type_object (value_type (value));
 }
 
-/* Return Unicode string with value contents (assumed to be encoded in the
-   target's charset).  */
+/* Implementation of gdb.Value.string ([encoding] [, errors]) -> string
+   Return Unicode string with value contents.  If ENCODING is not given,
+   the string is assumed to be encoded in the target's charset.  */
 static PyObject *
-valpy_string (PyObject *self, PyObject *args)
+valpy_string (PyObject *self, PyObject *args, PyObject *kw)
 {
   int length, ret = 0;
   gdb_byte *buffer;
@@ -169,8 +170,10 @@ valpy_string (PyObject *self, PyObject *args)
   const char *errors = NULL;
   const char *user_encoding = NULL;
   const char *la_encoding = NULL;
+  static char *keywords[] = { "encoding", "errors" };
 
-  if (!PyArg_ParseTuple (args, "|ss", &user_encoding, &errors))
+  if (!PyArg_ParseTupleAndKeywords (args, kw, "|ss", keywords,
+				    &user_encoding, &errors))
     return NULL;
 
   TRY_CATCH (except, RETURN_MASK_ALL)
@@ -915,8 +918,9 @@ static PyMethodDef value_object_methods[] = {
   { "cast", valpy_cast, METH_VARARGS, "Cast the value to the supplied type." },
   { "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." },
   { "type", valpy_type, METH_NOARGS, "Return type of the value." },
-  { "string", valpy_string, METH_VARARGS,
-    "Return Unicode string representation of the value." },
+  { "string", (PyCFunction) valpy_string, METH_VARARGS | METH_KEYWORDS,
+    "string ([encoding] [, errors]) -> string\n\


hooks/post-receive
--
Repository for Project Archer.


             reply	other threads:[~2009-02-28 19:26 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-02-28 19:26 jkratoch [this message]
  -- strict thread matches above, loose matches on Subject: below --
2009-06-26 13:51 jkratoch
2009-03-30 17:22 jkratoch
2009-03-29 22:42 jkratoch
2009-03-27  0:35 jkratoch
2009-03-25 19:00 jkratoch
2009-03-24 17:33 jkratoch
2009-03-09 17:05 jkratoch
2009-03-06 16:59 jkratoch
2009-03-06 14:26 jkratoch
2009-03-05 21:53 jkratoch
2009-03-05 21:15 jkratoch
2009-03-04 23:54 jkratoch
2009-03-04 22:34 jkratoch
2009-03-04 15:02 jkratoch
2009-03-03 21:46 jkratoch
2009-03-03 21:45 jkratoch
2009-03-02 20:46 jkratoch
2009-03-01 14:38 jkratoch
2009-02-26 23:01 jkratoch

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=20090228192645.18378.qmail@sourceware.org \
    --to=jkratoch@sourceware.org \
    --cc=archer-commits@sourceware.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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).