@matheusbsbs / matheus-bagliano / commits / dded4f12a4
Fork 0

fast-import: Introduce --import-marks-if-exists

When a frontend uses a marks file to ensure its state persists between runs, it may represent "clean slate" when bootstrapping with "no marks yet". In such a case, feeding the last state with --import-marks and saving the state after the current run with --export-marks would be a natural thing to do. The --import-marks option however errors out when the specified marks file doesn't exist; this makes bootstrapping a bit difficult. The location of the marks file becomes backend-dependent when --relative-marks is in effect, and the frontend cannot check for the existence of the file in such a case. The --import-marks-if-exists option does the same thing as --import-marks but does not flag an error if the named file does not exist yet to help these frontends. Helped-by: Junio C Hamano <gitster@pobox.com> Helped-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ramkumar Ramachandra committed Jan 15, 2011 at 12:01 UTC dded4f12a46274753439e3a8fa4eb756c5d14ae1
3 files changed +72 -3
Documentation/git-fast-import.txt
+4
@@ -78,6 +78,10 @@ OPTIONS
78 set of marks. If a mark is defined to different values,
79 the last file wins.
80
81 +--import-marks-if-exists=<file>::
82 + Like --import-marks but instead of erroring out, silently
83 + skips the file if it does not exist.
84 +
85 --relative-marks::
86 After specifying --relative-marks= the paths specified
87 with --import-marks= and --export-marks= are relative
fast-import.c
+13 -3
@@ -329,6 +329,7 @@ static struct mark_set *marks;
329 static const char *export_marks_file;
330 static const char *import_marks_file;
331 static int import_marks_file_from_stream;
332 +static int import_marks_file_ignore_missing;
333 static int relative_marks_paths;
334
335 /* Our last blob */
@@ -1795,7 +1796,11 @@ static void read_marks(void)
1796 {
1797 char line[512];
1798 FILE *f = fopen(import_marks_file, "r");
1798 - if (!f)
1799 + if (f)
1800 + ;
1801 + else if (import_marks_file_ignore_missing && errno == ENOENT)
1802 + return; /* Marks file does not exist */
1803 + else
1804 die_errno("cannot read '%s'", import_marks_file);
1805 while (fgets(line, sizeof(line), f)) {
1806 uintmax_t mark;
@@ -2861,7 +2866,8 @@ static char* make_fast_import_path(const char *path)
2866 return strbuf_detach(&abs_path, NULL);
2867 }
2868
2864 -static void option_import_marks(const char *marks, int from_stream)
2869 +static void option_import_marks(const char *marks,
2870 + int from_stream, int ignore_missing)
2871 {
2872 if (import_marks_file) {
2873 if (from_stream)
@@ -2875,6 +2881,7 @@ static void option_import_marks(const char *marks, int from_stream)
2881 import_marks_file = make_fast_import_path(marks);
2882 safe_create_leading_directories_const(import_marks_file);
2883 import_marks_file_from_stream = from_stream;
2884 + import_marks_file_ignore_missing = ignore_missing;
2885 }
2886
2887 static void option_date_format(const char *fmt)
@@ -2974,7 +2981,10 @@ static int parse_one_feature(const char *feature, int from_stream)
2981 if (!prefixcmp(feature, "date-format=")) {
2982 option_date_format(feature + 12);
2983 } else if (!prefixcmp(feature, "import-marks=")) {
2977 - option_import_marks(feature + 13, from_stream);
2984 + option_import_marks(feature + 13, from_stream, 0);
2985 + } else if (!prefixcmp(feature, "import-marks-if-exists=")) {
2986 + option_import_marks(feature + strlen("import-marks-if-exists="),
2987 + from_stream, 1);
2988 } else if (!prefixcmp(feature, "export-marks=")) {
2989 option_export_marks(feature + 13);
2990 } else if (!strcmp(feature, "cat-blob")) {
t/t9300-fast-import.sh
+55
@@ -1706,6 +1706,61 @@ test_expect_success \
1706 'cat input | git fast-import --export-marks=other.marks &&
1707 grep :1 other.marks'
1708
1709 +test_expect_success 'R: catch typo in marks file name' '
1710 + test_must_fail git fast-import --import-marks=nonexistent.marks </dev/null &&
1711 + echo "feature import-marks=nonexistent.marks" |
1712 + test_must_fail git fast-import
1713 +'
1714 +
1715 +test_expect_success 'R: import and output marks can be the same file' '
1716 + rm -f io.marks &&
1717 + blob=$(echo hi | git hash-object --stdin) &&
1718 + cat >expect <<-EOF &&
1719 + :1 $blob
1720 + :2 $blob
1721 + EOF
1722 + git fast-import --export-marks=io.marks <<-\EOF &&
1723 + blob
1724 + mark :1
1725 + data 3
1726 + hi
1727 +
1728 + EOF
1729 + git fast-import --import-marks=io.marks --export-marks=io.marks <<-\EOF &&
1730 + blob
1731 + mark :2
1732 + data 3
1733 + hi
1734 +
1735 + EOF
1736 + test_cmp expect io.marks
1737 +'
1738 +
1739 +test_expect_success 'R: --import-marks=foo --output-marks=foo to create foo fails' '
1740 + rm -f io.marks &&
1741 + test_must_fail git fast-import --import-marks=io.marks --export-marks=io.marks <<-\EOF
1742 + blob
1743 + mark :1
1744 + data 3
1745 + hi
1746 +
1747 + EOF
1748 +'
1749 +
1750 +test_expect_success 'R: --import-marks-if-exists' '
1751 + rm -f io.marks &&
1752 + blob=$(echo hi | git hash-object --stdin) &&
1753 + echo ":1 $blob" >expect &&
1754 + git fast-import --import-marks-if-exists=io.marks --export-marks=io.marks <<-\EOF &&
1755 + blob
1756 + mark :1
1757 + data 3
1758 + hi
1759 +
1760 + EOF
1761 + test_cmp expect io.marks
1762 +'
1763 +
1764 cat >input << EOF
1765 feature import-marks=marks.out
1766 feature export-marks=marks.new