diff --git a/acmc/main.py b/acmc/main.py
index b702518e204a56d92a09bd97d0102cde67a78200..cf7ffbbfe88a9afb6fbeb7cd4405b59dc8034e25 100644
--- a/acmc/main.py
+++ b/acmc/main.py
@@ -53,7 +53,7 @@ def phen_export(args):
 
 def phen_publish(args):
     """Handle the `phen publish` command."""
-    phen.publish(args.phen_dir)
+    phen.publish(args.phen_dir, args.remote_url)
 
 
 def phen_copy(args):
@@ -203,6 +203,9 @@ def main():
         default=str(phen.DEFAULT_PHEN_PATH.resolve()),
         help="Phenotype workspace directory",
     )
+    phen_publish_parser.add_argument(
+        "-r", "--remote_url", help="URL to remote git repository"
+    )
     phen_publish_parser.set_defaults(func=phen_publish)
 
     # phen copy
diff --git a/acmc/phen.py b/acmc/phen.py
index a9131b59ba704088478d7e697401707edb472468..50b166b06832a79651d2cef352a1eb5c6c3f5771 100644
--- a/acmc/phen.py
+++ b/acmc/phen.py
@@ -285,6 +285,9 @@ def init(phen_dir, remote_url):
 # Ignore SQLite journal and metadata files
 *.db-journal
 *.sqlite3-journal
+
+# python
+.ipynb_checkpoints
  """
     ignore_path = phen_path / ".gitignore"
     with open(ignore_path, "w") as file:
@@ -749,7 +752,7 @@ def map_target_code_type(phen_path, phenotype, target_code_type):
     logger.info(f"Phenotype processed target code type {target_code_type}")
 
 
-def publish(phen_dir):
+def publish(phen_dir, remote_url):
     """Publishes updates to the phenotype by commiting all changes to the repo directory"""
 
     # Validate config
@@ -801,13 +804,24 @@ def publish(phen_dir):
     logger.info(f"New version: {version}")
 
     # push to origin if a remote repo
+    if remote_url is not None and "origin" not in repo.remotes:
+        repo.create_remote("origin", remote_url)
+
     try:
-        origin = repo.remotes.origin
-        origin.push("main")
-        origin.push(tags=True)
-        logger.debug("Changes pushed to 'origin'.")
-    except AttributeError:
-        logger.debug("No remote named 'origin' found, local repo.")
+        if "origin" in repo.remotes:
+            logger.debug(f"Remote 'origin' is already set {repo.remotes.origin.url}")
+            origin = repo.remotes.origin
+            logger.info(f"Pushing main branch to {repo.remotes.origin.url}")
+            origin.push("main")
+            logger.info(f"Pushing tags to {repo.remotes.origin.url}")
+            origin.push(tags=True)
+            logger.debug("Changes pushed to 'origin'")
+        else:
+            logger.debug("Remote 'origin' is not set")
+    except Exception as e:
+        repo.delete_tag(version)
+        repo.git.reset("--soft", "HEAD~1")
+        raise e
 
     logger.info(f"Phenotype published successfully")
 
diff --git a/docs/usage.md b/docs/usage.md
index 57271cf0f12b54054159c184e56c0e00d38da5f4..29c1ba7410afb354285e395debc9cc41c8169cc2 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -108,6 +108,7 @@ The `phen` command is used phenotype-related operations.
   ```
 
   - `-d`, `--phen-dir`: (Optional) Directory of phenotype configuration (the default is ./build/phen).
+  - `-r`, `--remote_url`: (Optional) URL to a remote git repository, only supports an empty repo without existing commits
 
 - **Copy Phenotype Configuration**