Commits

Jakob Kramer committed a0b960a Merge

merged upstream

Comments (0)

Files changed (4)

File contents unchanged.
 #include <arpa/inet.h>
 #endif
 
+#include "capture.h"
 #include "common.h"
 #include "hg.h"
 
     free(last_line);
 }
 
+static void
+read_modified_unknown(vccontext_t *context, result_t *result)
+{
+    // No easy way that we know to get the modified or unknown status
+    // without forking an hg process. Replace this with a more efficient version
+    // if you ever figure it out.
+    if (!context->options->show_modified && !context->options->show_unknown)
+        return;
+
+    char *argv[] = {"hg", "--quiet", "status",
+                    "--modified", "--added", "--removed",
+                    "--unknown", NULL};
+    if (!context->options->show_unknown) {
+        // asking hg to search for unknown files can be expensive, so
+        // skip it unless the user wants it
+        argv[6] = NULL;
+    }
+    capture_t *capture = capture_child("hg", argv);
+    if (capture == NULL) {
+        debug("unable to execute 'hg status'");
+        return;
+    }
+    char *cstdout = capture->childout.buf;
+    for (char *ch = cstdout; *ch != 0; ch++) {
+        if (ch == cstdout || *(ch-1) == '\n') {
+            // at start of output or start of line: look for ?, M, etc.
+            if (context->options->show_unknown && *ch == '?') {
+                result->unknown = 1;
+            }
+            if (context->options->show_modified &&
+                (*ch == 'M' || *ch == 'A' || *ch == 'R')) {
+                result->modified = 1;
+            }
+        }
+    }
+
+    cstdout = NULL;
+    free_capture(capture);
+}
+
 static result_t*
 hg_get_info(vccontext_t *context)
 {
 
     read_parents(context, result);
     read_patch_name(context, result);
+    read_modified_unknown(context, result);
 
     return result;
 }
 
 posttest()
 {
-    :
+    cd $tmpdir
+    rm -rf hg-repo
 }
 
 # default prompt format in test repo
 test_basics()
 {
+    echo "test_basics:"
     pretest
     assert_vcprompt "show branch 1" "default" "%b"
     assert_vcprompt "show rev 1" "[1]" "[%r]"
     assert_vcprompt "show branch 2" "stable" "%b"
     assert_vcprompt "show rev 2" "[2]" "[%r]"
 
-    # not implemented yet
-    #echo foo >> b
-    #echo junk > junk
-    #assert_vcprompt "show modified" "+" "%m"
-    #assert_vcprompt "show unknown" "?" "%u"
-
     hg -q update default
     hg -q merge --tool internal:other stable
     assert_vcprompt "show branch 3" "default" "%b"
     posttest
 }
 
+test_status()
+{
+    echo "test_status:"
+    pretest
+    assert_vcprompt "clean 1" "" "%m"
+    assert_vcprompt "clean 2" "" "%u"
+    assert_vcprompt "clean 3" "" "%m%u"
+
+    echo foo >> b
+    assert_vcprompt "mod only 1" "+" "%m"
+    assert_vcprompt "mod only 2" "" "%u"
+    assert_vcprompt "mod only 3" "+" "%m%u"
+
+    echo junk > junk
+    assert_vcprompt "mod+unknown 1" "+" "%m"
+    assert_vcprompt "mod+unknown 2" "?" "%u"
+    assert_vcprompt "mod+unknown 3" "+?" "%m%u"
+
+    hg -q update --clean .
+    assert_vcprompt "unknown only 1" "" "%m"
+    assert_vcprompt "unknown only 2" "?" "%u"
+    assert_vcprompt "unknown only 3" "?" "%m%u"
+
+    posttest
+}
+
+test_status_add_remove()
+{
+    # files that are hg add'ed or hg remove'd count as local modifications
+    echo "test_status_add_remove:"
+    pretest
+
+    echo hello > new
+    hg add new
+    assert_vcprompt "added 1" "+" "%m"
+    assert_vcprompt "added 2" "" "%u"
+    assert_vcprompt "added 3" "+" "%m%u"
+
+    hg -q remove b
+    assert_vcprompt "added + removed 1" "+" "%m"
+    assert_vcprompt "added + removed 2" "" "%u"
+    assert_vcprompt "added + removed 3" "+" "%m%u"
+
+    hg -q revert new
+    assert_vcprompt "removed + unknown 1" "+" "%m"
+    assert_vcprompt "removed + unknown 2" "?" "%u"
+    assert_vcprompt "removed + unknown 3" "+?" "%m%u"
+
+    # missing files do *not* count as local modifications: user has
+    # not said they're planning to remove them with "hg remove"
+    hg -q revert --all --no-backup
+    rm new
+    rm a
+    assert_vcprompt "missing 1" "" "%m"
+    assert_vcprompt "missing 2" "" "%u"
+    assert_vcprompt "missing 3" "" "%m%u"
+}
+
+test_status_goofy_filenames()
+{
+    echo "test_status_goofy_filenames:"
+    pretest
+
+    # goofy filenames to test parsing of "? " and "M "
+    echo junk > "junk M junk"
+    assert_vcprompt "no modified 2" "" "%m"
+    assert_vcprompt "no modified, 1 unknown" "?" "%u"
+    assert_vcprompt "no modified, 1 unknown" "?" "%m%u"
+    rm -f "junk M junk"
+
+    fn="crazy? filename"
+    echo "not junk" > "$fn"
+    hg -q add "$fn" 2>&1 | grep -iv "reserved on windows"
+    hg -q commit -m"yes, it's a crazy filename"
+    assert_vcprompt "no modified files" "" "%m"
+    assert_vcprompt "no unknown files" "" "%u"
+    assert_vcprompt "no modified/unknown files" "" "%m%u"
+
+    echo x >> "$fn"
+    assert_vcprompt "1 modified" "+" "%m"
+    assert_vcprompt "no unknown files" "" "%u"
+    assert_vcprompt "1 modified, no unknown" "+" "%m%u"
+    posttest
+}
+
 check_hg
 find_vcprompt
 find_hgrepo
 setup
 
 test_basics
+test_status
+test_status_add_remove
+test_status_goofy_filenames
 
 report
 .B %u
 and
 .B %m
-are not implemented.
+are implemented by running "hg status", so they can be expensive in a
+large working dir. Mercurial has to work harder to find unknown files
+than it does to find uncommitted changes, so using
+.B %u
+can be considerably more expensive than just
+.B %m.
 
 .SH SUBVERSION (SVN) SUPPORT