fast-import: add feature command
authorSverre Rabbelier <srabbelier@gmail.com>
Fri, 4 Dec 2009 17:06:56 +0000 (18:06 +0100)
committerJunio C Hamano <gitster@pobox.com>
Sat, 5 Dec 2009 00:08:55 +0000 (16:08 -0800)
This allows the fronted to require a specific feature to be supported
by the backend, or abort.

Also add support for four initial feature, date-format=, force=,
import-marks=, export-marks=.

Signed-off-by: Sverre Rabbelier <srabbelier@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-fast-import.txt
fast-import.c
t/t9300-fast-import.sh
index 288032c7b88f2f43a2965d5bdbffc8472f0ca281..4357c213edeca1ccf8751864a9cbf3bb846426bd 100644 (file)
@@ -303,6 +303,10 @@ and control the current import process.  More detailed discussion
        standard output.  This command is optional and is not needed
        to perform an import.
 
        standard output.  This command is optional and is not needed
        to perform an import.
 
+`feature`::
+       Require that fast-import supports the specified feature, or
+       abort if it does not.
+
 `commit`
 ~~~~~~~~
 Create or update a branch with a new commit, recording one logical
 `commit`
 ~~~~~~~~
 Create or update a branch with a new commit, recording one logical
@@ -846,6 +850,27 @@ Placing a `progress` command immediately after a `checkpoint` will
 inform the reader when the `checkpoint` has been completed and it
 can safely access the refs that fast-import updated.
 
 inform the reader when the `checkpoint` has been completed and it
 can safely access the refs that fast-import updated.
 
+`feature`
+~~~~~~~~~
+Require that fast-import supports the specified feature, or abort if
+it does not.
+
+....
+       'feature' SP <feature> LF
+....
+
+The <feature> part of the command may be any string matching
+^[a-zA-Z][a-zA-Z-]*$ and should be understood by fast-import.
+
+Feature work identical as their option counterparts.
+
+The following features are currently supported:
+
+* date-format
+* import-marks
+* export-marks
+* force
+
 Crash Reports
 -------------
 If fast-import is supplied invalid input it will terminate with a
 Crash Reports
 -------------
 If fast-import is supplied invalid input it will terminate with a
index 0458b03a2a45d7c16335d83b93dba1c33a6766b7..ce0cd4e68a4a086f12d576f1fcb8fdf60f466acb 100644 (file)
@@ -353,6 +353,7 @@ static struct recent_command *rc_free;
 static unsigned int cmd_save = 100;
 static uintmax_t next_mark;
 static struct strbuf new_data = STRBUF_INIT;
 static unsigned int cmd_save = 100;
 static uintmax_t next_mark;
 static struct strbuf new_data = STRBUF_INIT;
+static int seen_data_command;
 
 static void write_branch_report(FILE *rpt, struct branch *b)
 {
 
 static void write_branch_report(FILE *rpt, struct branch *b)
 {
@@ -1704,6 +1705,11 @@ static int read_next_command(void)
                        if (stdin_eof)
                                return EOF;
 
                        if (stdin_eof)
                                return EOF;
 
+                       if (!seen_data_command
+                               && prefixcmp(command_buf.buf, "feature ")) {
+                               seen_data_command = 1;
+                       }
+
                        rc = rc_free;
                        if (rc)
                                rc_free = rc->next;
                        rc = rc_free;
                        if (rc)
                                rc_free = rc->next;
@@ -2533,6 +2539,36 @@ static void parse_one_option(const char *option)
        }
 }
 
        }
 }
 
+static int parse_one_feature(const char *feature)
+{
+       if (!prefixcmp(feature, "date-format=")) {
+               option_date_format(feature + 12);
+       } else if (!prefixcmp(feature, "import-marks=")) {
+               option_import_marks(feature + 13);
+       } else if (!prefixcmp(feature, "export-marks=")) {
+               option_export_marks(feature + 13);
+       } else if (!prefixcmp(feature, "force")) {
+               force_update = 1;
+       } else {
+               return 0;
+       }
+
+       return 1;
+}
+
+static void parse_feature(void)
+{
+       char *feature = command_buf.buf + 8;
+
+       if (seen_data_command)
+               die("Got feature command '%s' after data command", feature);
+
+       if (parse_one_feature(feature))
+               return;
+
+       die("This version of fast-import does not support feature %s.", feature);
+}
+
 static int git_pack_config(const char *k, const char *v, void *cb)
 {
        if (!strcmp(k, "pack.depth")) {
 static int git_pack_config(const char *k, const char *v, void *cb)
 {
        if (!strcmp(k, "pack.depth")) {
@@ -2612,6 +2648,8 @@ int main(int argc, const char **argv)
                        parse_checkpoint();
                else if (!prefixcmp(command_buf.buf, "progress "))
                        parse_progress();
                        parse_checkpoint();
                else if (!prefixcmp(command_buf.buf, "progress "))
                        parse_progress();
+               else if (!prefixcmp(command_buf.buf, "feature "))
+                       parse_feature();
                else
                        die("Unsupported command: %s", command_buf.buf);
        }
                else
                        die("Unsupported command: %s", command_buf.buf);
        }
index b49815d10806a57461bb98ffd89031680f84715a..b2c521f557e03e3115346dbcab806f40f559a55a 100755 (executable)
@@ -1254,4 +1254,74 @@ test_expect_success \
        'Q: verify note for third commit' \
        'git cat-file blob refs/notes/foobar:$commit3 >actual && test_cmp expect actual'
 
        'Q: verify note for third commit' \
        'git cat-file blob refs/notes/foobar:$commit3 >actual && test_cmp expect actual'
 
+###
+### series R (feature)
+###
+
+cat >input <<EOF
+feature no-such-feature-exists
+EOF
+
+test_expect_success 'R: abort on unsupported feature' '
+       test_must_fail git fast-import <input
+'
+
+cat >input <<EOF
+feature date-format=now
+EOF
+
+test_expect_success 'R: supported feature is accepted' '
+       git fast-import <input
+'
+
+cat >input << EOF
+blob
+data 3
+hi
+feature date-format=now
+EOF
+
+test_expect_success 'R: abort on receiving feature after data command' '
+       test_must_fail git fast-import <input
+'
+
+cat >input << EOF
+feature export-marks=git.marks
+blob
+mark :1
+data 3
+hi
+
+EOF
+
+test_expect_success \
+    'R: export-marks feature results in a marks file being created' \
+    'cat input | git fast-import &&
+    grep :1 git.marks'
+
+test_expect_success \
+    'R: export-marks options can be overriden by commandline options' \
+    'cat input | git fast-import --export-marks=other.marks &&
+    grep :1 other.marks'
+
+cat >input << EOF
+feature import-marks=marks.out
+feature export-marks=marks.new
+EOF
+
+test_expect_success \
+    'R: import to output marks works without any content' \
+    'cat input | git fast-import &&
+    test_cmp marks.out marks.new'
+
+cat >input <<EOF
+feature import-marks=nonexistant.marks
+feature export-marks=marks.new
+EOF
+
+test_expect_success \
+    'R: import marks prefers commandline marks file over the stream' \
+    'cat input | git fast-import --import-marks=marks.out &&
+    test_cmp marks.out marks.new'
+
 test_done
 test_done