diff --git a/Documents/bin/git-manage b/Documents/bin/git-manage
index f413e74dad0f43c9ae99fd7ed1fefae8d79cb088..69269e43286ac968360ed9760ad06112d7f259ff 100755
--- a/Documents/bin/git-manage
+++ b/Documents/bin/git-manage
@@ -9,6 +9,7 @@ import sys
 import github3.exceptions  # pylint: disable=import-error
 import gitlab.exceptions  # pylint: disable=import-error
 import passhole.passhole  # pylint: disable=import-error
+import sh  # pylint: disable=import-error
 
 sys.path.append(os.path.expanduser("~/Documents/bin"))
 
@@ -140,7 +141,7 @@ def guess_name(args, gh_conn=None, gl_conn=None):
     """Try to guess the name from the arguments and the repository remotes."""
     if args.name is None:
         if not rcfiles.git.in_repo():
-            parser.error("Name not provided and not in a Git repo.")
+            arg_parser.error("Name not provided and not in a Git repo.")
 
         remote = guess_remote(
             remote_type="github"
@@ -150,11 +151,11 @@ def guess_name(args, gh_conn=None, gl_conn=None):
         )
         if remote is None:
             if "github" in args and args.github:
-                parser.error(
+                arg_parser.error(
                     "Name not provided and could not find a GitHub remote."
                 )
             else:
-                parser.error(
+                arg_parser.error(
                     "Name not provided and could not find a GitLab remote."
                 )
         else:
@@ -197,13 +198,15 @@ def create_github_repo(args):
     - Commits an initial empty commit.
     """
     if "/" in args.name:
-        parser.error("Can't specify an organization.")
+        arg_parser.error("Can't specify an organization.")
     if args.internal or args.private:
-        parser.error("Can't create internal or private GitHub repositories.")
+        arg_parser.error(
+            "Can't create internal or private GitHub repositories."
+        )
     try:
         conn = rcfiles.github.connect()
     except Exception as e:  # pylint: disable=broad-except
-        parser.error(f"Failed to connect to GitHub: {e}")
+        arg_parser.error(f"Failed to connect to GitHub: {e}")
 
     repo = conn.create_repository(
         args.name,
@@ -235,11 +238,11 @@ def create_gitlab_repo(args):
     - Adds the mirror remote.
     """
     if args.private and args.internal:
-        parser.error("Repository can be internal or private, not both.")
+        arg_parser.error("Repository can be internal or private, not both.")
     try:
         conn = rcfiles.gitlab.connect()
     except Exception as e:  # pylint: disable=broad-except
-        parser.error(f"Failed to connect to GitLab: {e}")
+        arg_parser.error(f"Failed to connect to GitLab: {e}")
 
     if args.private:
         visibility = "private"
@@ -293,7 +296,7 @@ def create_gitlab_repo(args):
 def create_repo(args):
     """Create a new repository."""
     if args.mirror and args.github:
-        parser.error("Can't mirror from GitHub to GitLab.")
+        arg_parser.error("Can't mirror from GitHub to GitLab.")
     if args.github:
         create_github_repo(args)
     else:
@@ -310,18 +313,18 @@ def mirror_repo(args):
     try:
         gh_conn = rcfiles.github.connect()
     except Exception as e:  # pylint: disable=broad-except
-        parser.error(f"Failed to connect to GitHub: {e}")
+        arg_parser.error(f"Failed to connect to GitHub: {e}")
     try:
         gl_conn = rcfiles.gitlab.connect()
     except Exception as e:  # pylint: disable=broad-except
-        parser.error(f"Failed to connect to GitLab: {e}")
+        arg_parser.error(f"Failed to connect to GitLab: {e}")
 
     name = guess_name(args, gh_conn, gl_conn)
 
     try:
         project = gl_conn.projects.get(name)
     except gitlab.exceptions.GitlabGetError:
-        parser.error(f"Could not find GitLab project {name}.")
+        arg_parser.error(f"Could not find GitLab project {name}.")
 
     gh_repo = mirror_project(project, gh_conn, get_mirror_token())
     print(
@@ -346,12 +349,12 @@ def archive_repo(args):
     try:
         gh_conn = rcfiles.github.connect()
     except Exception as e:  # pylint: disable=broad-except
-        parser.error(f"Failed to connect to GitHub: {e}")
+        arg_parser.error(f"Failed to connect to GitHub: {e}")
     if not args.github:
         try:
             gl_conn = rcfiles.gitlab.connect()
         except Exception as e:  # pylint: disable=broad-except
-            parser.error(f"Failed to connect to GitLab: {e}")
+            arg_parser.error(f"Failed to connect to GitLab: {e}")
 
     if args.github:
         owner, name = guess_name(args, gh_conn=gh_conn, gl_conn=None).split(
@@ -375,7 +378,40 @@ def archive_repo(args):
             )
 
 
-if __name__ == "__main__":
+def fork_repo(args):
+    """Forks a GitHub repository.
+
+    Does the following:
+    - Forks the GitHub repository.
+    - Clones the repository.
+    - Adds the upstream remote.
+    """
+    try:
+        conn = rcfiles.github.connect()
+    except Exception as e:  # pylint: disable=broad-except
+        arg_parser.error(f"Failed to connect to GitHub: {e}")
+
+    if "/" not in args.name:
+        arg_parser.error("Must provide a full repository name.")
+
+    org, name = args.name.split("/")
+    upstream = conn.repository(org, name)
+    fork = upstream.create_fork()
+    print(
+        f"Forked GitHub repo {upstream.full_name} to {fork.full_name}.",
+        file=sys.stderr,
+    )
+
+    with sh.pushd(os.path.expanduser("~/Repositories/GitHub")):
+        rcfiles.git.git.clone(fork.ssh_url)
+        print("Cloned repository.", file=sys.stderr)
+
+        rcfiles.git.add_remote(upstream.name, "upstream", upstream.ssh_url)
+        print("Added an upstream remote.", file=sys.stderr)
+
+
+def build_arg_parser():
+    """Builds the argument parser."""
     parser = argparse.ArgumentParser(description=__doc__)
     subparsers = parser.add_subparsers(
         title="Commands", required=True, dest="command"
@@ -428,5 +464,15 @@ if __name__ == "__main__":
         "--github", help="The repository is in GitHub.", action="store_true"
     )
 
-    _args = parser.parse_args()
+    parser_fork = subparsers.add_parser(
+        "fork", help="Forks a GitHub repository."
+    )
+    parser_fork.set_defaults(func=fork_repo)
+    parser_fork.add_argument("name", help="Name of the repository.")
+    return parser
+
+
+if __name__ == "__main__":
+    arg_parser = build_arg_parser()
+    _args = arg_parser.parse_args()
     _args.func(_args)
diff --git a/Documents/bin/rcfiles/git.py b/Documents/bin/rcfiles/git.py
index a26c6b3678e39f68d59c21960c3a9c25e8107515..f186f0d67b4b19ba8eb43e39c102e8c51da0eaae 100644
--- a/Documents/bin/rcfiles/git.py
+++ b/Documents/bin/rcfiles/git.py
@@ -53,6 +53,7 @@ def add_remote(repo, name, url):
             git.remote("add", name, url)
         except sh.ErrorReturnCode_3:
             git.remote("set-url", name, url)
+        git.fetch("name")
 
 
 def author_name():