Code

[PATCH] Better error reporting for "git status"
authorLinus Torvalds <torvalds@osdl.org>
Sat, 1 Oct 2005 20:24:27 +0000 (13:24 -0700)
committerJunio C Hamano <junkio@cox.net>
Sun, 2 Oct 2005 06:55:47 +0000 (23:55 -0700)
Instead of "git status" ignoring (and hiding) potential errors from the
"git-update-index" call, make it exit if it fails, and show the error.

In order to do this, use the "-q" flag (to ignore not-up-to-date files)
and add a new "--unmerged" flag that allows unmerged entries in the index
without any errors.

This also avoids marking the index "changed" if an entry isn't actually
modified, and makes sure that we exit with an understandable error message
if the index is corrupt or unreadable. "read_cache()" no longer returns an
error for the caller to check.

Finally, make die() and usage() exit with recognizable error codes, if we
ever want to check the failure reason in scripts.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
git-status.sh
read-cache.c
update-index.c
usage.c

index ca9a15459fc55c8a03aabf2bed85bc34817df450..44398d760c4b212bfebbbe09c4bb11d2068ad49d 100755 (executable)
@@ -37,7 +37,7 @@ refs/heads/master) ;;
 *)     echo "# On branch $branch" ;;
 esac
 
-git-update-index --refresh >/dev/null 2>&1
+git-update-index -q --unmerged --refresh || exit
 
 if GIT_DIR="$GIT_DIR" git-rev-parse --verify HEAD >/dev/null 2>&1
 then
index 0e345bdb2fac523c677c73a1f86ef2b44083c3bf..d2aebdd6bc6dbf7ae40f3a7600d76765f31b9a15 100644 (file)
@@ -464,11 +464,15 @@ int read_cache(void)
 
        errno = EBUSY;
        if (active_cache)
-               return error("more than one cachefile");
+               return active_nr;
+
        errno = ENOENT;
        fd = open(get_index_file(), O_RDONLY);
-       if (fd < 0)
-               return (errno == ENOENT) ? 0 : error("open failed");
+       if (fd < 0) {
+               if (errno == ENOENT)
+                       return 0;
+               die("index file open failed (%s)", strerror(errno));
+       }
 
        size = 0; // avoid gcc warning
        map = MAP_FAILED;
@@ -480,7 +484,7 @@ int read_cache(void)
        }
        close(fd);
        if (map == MAP_FAILED)
-               return error("mmap failed");
+               die("index file mmap failed (%s)", strerror(errno));
 
        hdr = map;
        if (verify_hdr(hdr, size) < 0)
@@ -501,7 +505,7 @@ int read_cache(void)
 unmap:
        munmap(map, size);
        errno = EINVAL;
-       return error("verify header failed");
+       die("index file corrupt");
 }
 
 #define WRITE_BUFFER_SIZE 8192
index 01eaa1a984c606b3e5566a3aec588a394fd10e22..ade1ee72ebbe5e6b84a0c6645ff2043b831bdfef 100644 (file)
@@ -13,7 +13,7 @@
  * like "git-update-index *" and suddenly having all the object
  * files be revision controlled.
  */
-static int allow_add = 0, allow_remove = 0, allow_replace = 0, not_new = 0, quiet = 0, info_only = 0;
+static int allow_add = 0, allow_remove = 0, allow_replace = 0, allow_unmerged = 0, not_new = 0, quiet = 0, info_only = 0;
 static int force_remove;
 
 /* Three functions to allow overloaded pointer return; see linux/err.h */
@@ -135,7 +135,7 @@ static struct cache_entry *refresh_entry(struct cache_entry *ce)
 
        changed = ce_match_stat(ce, &st);
        if (!changed)
-               return ce;
+               return NULL;
 
        if (ce_modified(ce, &st))
                return ERR_PTR(-EINVAL);
@@ -156,16 +156,20 @@ static int refresh_cache(void)
                struct cache_entry *ce, *new;
                ce = active_cache[i];
                if (ce_stage(ce)) {
-                       printf("%s: needs merge\n", ce->name);
-                       has_errors = 1;
                        while ((i < active_nr) &&
                               ! strcmp(active_cache[i]->name, ce->name))
                                i++;
                        i--;
+                       if (allow_unmerged)
+                               continue;
+                       printf("%s: needs merge\n", ce->name);
+                       has_errors = 1;
                        continue;
                }
 
                new = refresh_entry(ce);
+               if (!new)
+                       continue;
                if (IS_ERR(new)) {
                        if (not_new && PTR_ERR(new) == -ENOENT)
                                continue;
@@ -335,6 +339,10 @@ int main(int argc, const char **argv)
                                allow_remove = 1;
                                continue;
                        }
+                       if (!strcmp(path, "--unmerged")) {
+                               allow_unmerged = 1;
+                               continue;
+                       }
                        if (!strcmp(path, "--refresh")) {
                                has_errors |= refresh_cache();
                                continue;
diff --git a/usage.c b/usage.c
index 86211c9141b788f6dbdf7b192f0ac4f4e2527d64..dfa87fe1191862b2c650e55fdd727802ef00cf34 100644 (file)
--- a/usage.c
+++ b/usage.c
@@ -15,7 +15,7 @@ static void report(const char *prefix, const char *err, va_list params)
 void usage(const char *err)
 {
        fprintf(stderr, "usage: %s\n", err);
-       exit(1);
+       exit(129);
 }
 
 void die(const char *err, ...)
@@ -25,7 +25,7 @@ void die(const char *err, ...)
        va_start(params, err);
        report("fatal: ", err, params);
        va_end(params);
-       exit(1);
+       exit(128);
 }
 
 int error(const char *err, ...)