Repository: Rapptz/discord.py

Issue:
Context.reinvoke improperly assigns invoked_with
**Summary**

title

**Reproduction Steps**

code:
```py
@bot.group(aliases=['fooo', 'foooo'])
async def foo(c):
  await c.send(f"foo invoked_with: ({c.invoked_with})")

@foo.group(aliases=['barr', 'barrr'])
async def bar(c):
  await c.send(f"bar invoked_with: ({c.invoked_with})")

@bar.command()
async def baz(c):
  await c.send(f"baz invoked_with: ({c.invoked_with})")
```
Run the command `?fooo barr baz` then reinvoke the context with `restart=True`

**Expected Results**

```
foo invoked_with: (foooo)
bar invoked_with: (barr)
baz invoked_with: (baz)
foo invoked_with: (foooo) 
bar invoked_with: (barr)
baz invoked_with: (baz)
```

**Actual Results**

```
foo invoked_with: (foooo)
bar invoked_with: (barr)
baz invoked_with: (baz)
foo invoked_with: (baz) 
bar invoked_with: (barr)
baz invoked_with: (baz)
```

**Intents**

Not applicable

**System Information**

Not applicable

**Checklist**

- [X] I have searched the open issues for duplicates.
- [X] I have shown the entire traceback, if possible.
- [X] I have removed my token from display, if visible.




Discussion:

Resolving patch:
diff --git a/discord/ext/commands/context.py b/discord/ext/commands/context.py
--- a/discord/ext/commands/context.py
+++ b/discord/ext/commands/context.py
@@ -57,6 +57,14 @@ class Context(discord.abc.Messageable):
     invoked_with: :class:`str`
         The command name that triggered this invocation. Useful for finding out
         which alias called the command.
+    invoked_parents: List[:class:`str`]
+        The command names of the parents that triggered this invocation. Useful for
+        finding out which aliases called the command.
+
+        For example in commands ``?a b c test``, the invoked parents are ``['a', 'b', 'c']``.
+
+        .. versionadded:: 1.7
+
     invoked_subcommand: :class:`Command`
         The subcommand that was invoked.
         If no valid subcommand was invoked then this is equal to ``None``.
@@ -79,6 +87,7 @@ def __init__(self, **attrs):
         self.command = attrs.pop('command', None)
         self.view = attrs.pop('view', None)
         self.invoked_with = attrs.pop('invoked_with', None)
+        self.invoked_parents = attrs.pop('invoked_parents', [])
         self.invoked_subcommand = attrs.pop('invoked_subcommand', None)
         self.subcommand_passed = attrs.pop('subcommand_passed', None)
         self.command_failed = attrs.pop('command_failed', False)
@@ -180,7 +189,8 @@ async def reinvoke(self, *, call_hooks=False, restart=True):
             to_call = cmd.root_parent or cmd
             view.index = len(self.prefix)
             view.previous = 0
-            view.get_word() # advance to get the root command
+            self.invoked_parents = []
+            self.invoked_with = view.get_word() # advance to get the root command
         else:
             to_call = cmd
 
@@ -192,6 +202,7 @@ async def reinvoke(self, *, call_hooks=False, restart=True):
             view.previous = previous
             self.invoked_with = invoked_with
             self.invoked_subcommand = invoked_subcommand
+            self.invoked_parents = invoked_parents
             self.subcommand_passed = subcommand_passed
 
     @property
diff --git a/discord/ext/commands/core.py b/discord/ext/commands/core.py
--- a/discord/ext/commands/core.py
+++ b/discord/ext/commands/core.py
@@ -1342,6 +1342,8 @@ async def invoke(self, ctx):
             injected = hooked_wrapped_callback(self, ctx, self.callback)
             await injected(*ctx.args, **ctx.kwargs)
 
+        ctx.invoked_parents.append(ctx.invoked_with)
+
         if trigger and ctx.invoked_subcommand:
             ctx.invoked_with = trigger
             await ctx.invoked_subcommand.invoke(ctx)
@@ -1380,6 +1382,8 @@ async def reinvoke(self, ctx, *, call_hooks=False):
                 if call_hooks:
                     await self.call_after_hooks(ctx)
 
+        ctx.invoked_parents.append(ctx.invoked_with)
+
         if trigger and ctx.invoked_subcommand:
             ctx.invoked_with = trigger
             await ctx.invoked_subcommand.reinvoke(ctx, call_hooks=call_hooks)


Test patch: