diff --git a/crates/moon/tests/test_cases/mod.rs b/crates/moon/tests/test_cases/mod.rs
index cc047c39f..0dcf8b81f 100644
--- a/crates/moon/tests/test_cases/mod.rs
+++ b/crates/moon/tests/test_cases/mod.rs
@@ -6215,3 +6215,57 @@ fn test_failed_to_fill_whole_buffer() {
         "#]],
     );
 }
+
+#[test]
+fn test_moon_update_failed() {
+    if std::env::var("CI").is_err() {
+        return;
+    }
+    let tmp = tempfile::tempdir().unwrap();
+    let dir = tmp.path();
+    let moon_home = dir;
+    let out = std::process::Command::new(moon_bin())
+        .current_dir(dir)
+        .env("MOON_HOME", moon_home)
+        .stdout(std::process::Stdio::piped())
+        .stderr(std::process::Stdio::piped())
+        .args(["update"])
+        .output()
+        .unwrap();
+    let out = String::from_utf8(out.stderr).unwrap();
+    check(
+        &out,
+        expect![[r#"
+        Registry index cloned successfully
+    "#]],
+    );
+
+    let _ = std::process::Command::new("git")
+        .args([
+            "-C",
+            dir.join("registry").join("index").to_str().unwrap(),
+            "remote",
+            "set-url",
+            "origin",
+            "whatever",
+        ])
+        .output()
+        .unwrap();
+
+    let out = std::process::Command::new(moon_bin())
+        .current_dir(dir)
+        .env("MOON_HOME", moon_home)
+        .stdout(std::process::Stdio::piped())
+        .stderr(std::process::Stdio::piped())
+        .args(["update"])
+        .output()
+        .unwrap();
+    let out = String::from_utf8(out.stderr).unwrap();
+    check(
+        &out,
+        expect![[r#"
+            Registry index is not cloned from the same URL, re-cloning
+            Registry index re-cloned successfully
+        "#]],
+    );
+}
diff --git a/crates/moonutil/src/git.rs b/crates/moonutil/src/git.rs
index ca62f3273..02024669f 100644
--- a/crates/moonutil/src/git.rs
+++ b/crates/moonutil/src/git.rs
@@ -118,3 +118,28 @@ pub fn git_init_repo(path: &Path) -> Result<(), GitCommandError> {
     }
     Ok(())
 }
+
+#[test]
+fn test_bad_git_command() {
+    pub fn fake_git_command(
+        args: &[&str],
+        stdios: Stdios,
+    ) -> Result<std::process::Child, GitCommandError> {
+        std::process::Command::new("fake_git")
+            .args(args)
+            .stdin(stdios.stdin)
+            .stdout(stdios.stdout)
+            .stderr(stdios.stderr)
+            .spawn()
+            .map_err(|e| GitCommandError {
+                cmd: format!("git {}", args.join(" ")),
+                source: GitCommandErrorKind::IO(e),
+            })
+    }
+    let child = fake_git_command(&["pull"], Stdios::inherit());
+    let e = child.unwrap_err();
+    let err = anyhow::anyhow!(e);
+    let err_msg = format!("{:?}", err);
+    assert!(err_msg.contains("git command failed: `git pull`"));
+    assert!(err_msg.contains("Caused by:"));
+}