@matheusbsbs / matheus-bagliano / commits / 777f80d742
Fork 0

fast-import: Allow cat-blob requests at arbitrary points in stream

The new rule: a "cat-blob" can be inserted wherever a comment is allowed, which means at the start of any line except in the middle of a "data" command. This saves frontends from having to loop over everything they want to commit in the next commit and cat-ing the necessary objects in advance. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: David Barr <david.barr@cordelta.com> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Nieder committed Nov 28, 2010 at 13:45 UTC 777f80d7429b0f2687cb9ff40f82b196b78384ff
3 files changed +86 -12
Documentation/git-fast-import.txt
+4
@@ -912,6 +912,10 @@ output uses the same format as `git cat-file --batch`:
912 <contents> LF
913 ====
914
915 +This command can be used anywhere in the stream that comments are
916 +accepted. In particular, the `cat-blob` command can be used in the
917 +middle of a commit but not in the middle of a `data` command.
918 +
919 `feature`
920 ~~~~~~~~~
921 Require that fast-import supports the specified feature, or abort if
fast-import.c
+16 -12
@@ -55,8 +55,6 @@ Format of STDIN stream:
55 ('from' sp committish lf)?
56 lf?;
57
58 - cat_blob ::= 'cat-blob' sp (hexsha1 | idnum) lf;
59 -
58 checkpoint ::= 'checkpoint' lf
59 lf?;
60
@@ -134,14 +132,17 @@ Format of STDIN stream:
132 ts ::= # time since the epoch in seconds, ascii base10 notation;
133 tz ::= # GIT style timezone;
134
137 - # note: comments may appear anywhere in the input, except
138 - # within a data command. Any form of the data command
139 - # always escapes the related input from comment processing.
135 + # note: comments and cat requests may appear anywhere
136 + # in the input, except within a data command. Any form
137 + # of the data command always escapes the related input
138 + # from comment processing.
139 #
140 # In case it is not clear, the '#' that starts the comment
141 # must be the first character on that line (an lf
142 # preceded it).
143 #
144 + cat_blob ::= 'cat-blob' sp (hexsha1 | idnum) lf;
145 +
146 comment ::= '#' not_lf* lf;
147 not_lf ::= # Any byte that is not ASCII newline (LF);
148 */
@@ -367,6 +368,7 @@ static int seen_data_command;
368 static int cat_blob_fd = STDOUT_FILENO;
369
370 static void parse_argv(void);
371 +static void parse_cat_blob(void);
372
373 static void write_branch_report(FILE *rpt, struct branch *b)
374 {
@@ -1785,7 +1787,6 @@ static void read_marks(void)
1787 fclose(f);
1788 }
1789
1788 -
1790 static int read_next_command(void)
1791 {
1792 static int stdin_eof = 0;
@@ -1795,7 +1796,7 @@ static int read_next_command(void)
1796 return EOF;
1797 }
1798
1798 - do {
1799 + for (;;) {
1800 if (unread_command_buf) {
1801 unread_command_buf = 0;
1802 } else {
@@ -1828,9 +1829,14 @@ static int read_next_command(void)
1829 rc->prev->next = rc;
1830 cmd_tail = rc;
1831 }
1831 - } while (command_buf.buf[0] == '#');
1832 -
1833 - return 0;
1832 + if (!prefixcmp(command_buf.buf, "cat-blob ")) {
1833 + parse_cat_blob();
1834 + continue;
1835 + }
1836 + if (command_buf.buf[0] == '#')
1837 + continue;
1838 + return 0;
1839 + }
1840 }
1841
1842 static void skip_optional_lf(void)
@@ -3066,8 +3072,6 @@ int main(int argc, const char **argv)
3072 parse_new_tag();
3073 else if (!prefixcmp(command_buf.buf, "reset "))
3074 parse_reset_branch();
3069 - else if (!prefixcmp(command_buf.buf, "cat-blob "))
3070 - parse_cat_blob();
3075 else if (!strcmp("checkpoint", command_buf.buf))
3076 parse_checkpoint();
3077 else if (!prefixcmp(command_buf.buf, "progress "))
t/t9300-fast-import.sh
+66
@@ -1823,6 +1823,72 @@ test_expect_success PIPE 'R: copy using cat-file' '
1823 test_cmp big actual
1824 '
1825
1826 +test_expect_success PIPE 'R: print blob mid-commit' '
1827 + rm -f blobs &&
1828 + echo "A blob from _before_ the commit." >expect &&
1829 + mkfifo blobs &&
1830 + (
1831 + exec 3<blobs &&
1832 + cat <<-EOF &&
1833 + feature cat-blob
1834 + blob
1835 + mark :1
1836 + data <<BLOB
1837 + A blob from _before_ the commit.
1838 + BLOB
1839 + commit refs/heads/temporary
1840 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1841 + data <<COMMIT
1842 + Empty commit
1843 + COMMIT
1844 + cat-blob :1
1845 + EOF
1846 +
1847 + read blob_id type size <&3 &&
1848 + dd if=/dev/stdin of=actual bs=$size count=1 <&3 &&
1849 + read newline <&3 &&
1850 +
1851 + echo
1852 + ) |
1853 + git fast-import --cat-blob-fd=3 3>blobs &&
1854 + test_cmp expect actual
1855 +'
1856 +
1857 +test_expect_success PIPE 'R: print staged blob within commit' '
1858 + rm -f blobs &&
1859 + echo "A blob from _within_ the commit." >expect &&
1860 + mkfifo blobs &&
1861 + (
1862 + exec 3<blobs &&
1863 + cat <<-EOF &&
1864 + feature cat-blob
1865 + commit refs/heads/within
1866 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1867 + data <<COMMIT
1868 + Empty commit
1869 + COMMIT
1870 + M 644 inline within
1871 + data <<BLOB
1872 + A blob from _within_ the commit.
1873 + BLOB
1874 + EOF
1875 +
1876 + to_get=$(
1877 + echo "A blob from _within_ the commit." |
1878 + git hash-object --stdin
1879 + ) &&
1880 + echo "cat-blob $to_get" &&
1881 +
1882 + read blob_id type size <&3 &&
1883 + dd if=/dev/stdin of=actual bs=$size count=1 <&3 &&
1884 + read newline <&3 &&
1885 +
1886 + echo deleteall
1887 + ) |
1888 + git fast-import --cat-blob-fd=3 3>blobs &&
1889 + test_cmp expect actual
1890 +'
1891 +
1892 cat >input << EOF
1893 option git quiet
1894 blob