diff --git a/acmc/parse.py b/acmc/parse.py
index a2996eddcdd982fe2335b8ccca559c850226b69a..ca5b3e1dc847994cab714142d1bfc946eb15bc64 100644
--- a/acmc/parse.py
+++ b/acmc/parse.py
@@ -39,14 +39,15 @@ class Proto:
         tuple[
             str,  # The description, e.g., "Not Empty"
             Callable[
-                [list], pd.Series,
+                [list],
+                pd.Series,
             ],  # The first lambda function: takes a list and returns a pd.Series of booleans
             Callable[
-                [list, str], None,
+                [list, str],
+                None,
             ],  # The second lambda function: takes a list and a string, and returns nothing
         ]
     ]
-	
 
     def __init__(self, name, trud_codes_path=None):
         if trud_codes_path is not None:
diff --git a/acmc/phen.py b/acmc/phen.py
index fa94e75b3face24e5afb2a1e39843ce0b2cc86b6..dd2b6ff5017e922257b08f3d4e7ba0414e4b8836 100644
--- a/acmc/phen.py
+++ b/acmc/phen.py
@@ -136,7 +136,6 @@ def init(phen_dir, remote_url):
         repo.clone(git_url, phen_path)
         # open repo
         repo = git.Repo(phen_path)
-
         # check if there are any commits (new repo has no commits)
         if (
             len(repo.branches) == 0 or repo.head.is_detached
@@ -202,16 +201,23 @@ def init(phen_dir, remote_url):
         },
         "codes": [],
     }
+
     config_path = phen_path / CONFIG_FILE
     with open(config_path, "w", encoding="utf-8") as f:
         json.dump(config, f, indent=4)
 
-    # TODO: add gitignore
-
-    # Ignore all SQLite database files
-    # *.db
-    # *.sqlite
-    # *.sqlite3
+    # add git ignore
+    ignore_content = """# Ignore SQLite database files
+ *.db
+ *.sqlite3
+ 
+ # Ignore SQLite journal and metadata files
+ *.db-journal
+ *.sqlite3-journal
+ """
+    ignore_path = phen_path / ".gitignore"
+    with open(ignore_path, "w") as file:
+        file.write(ignore_content)
 
     # add to git repo and commit
     for d in DEFAULT_PHEN_DIR_LIST: