@@ -1815,6 +1815,289 @@ static void wt_porcelain_print(struct wt_status *s)
1815
1815
wt_shortstatus_print (s );
1816
1816
}
1817
1817
1818
+ /*
1819
+ * Convert various submodule status values into a
1820
+ * fixed-length string of characters in the buffer provided.
1821
+ */
1822
+ static void wt_porcelain_v2_submodule_state (
1823
+ struct wt_status_change_data * d ,
1824
+ char sub [5 ])
1825
+ {
1826
+ if (S_ISGITLINK (d -> mode_head ) ||
1827
+ S_ISGITLINK (d -> mode_index ) ||
1828
+ S_ISGITLINK (d -> mode_worktree )) {
1829
+ sub [0 ] = 'S' ;
1830
+ sub [1 ] = d -> new_submodule_commits ? 'C' : '.' ;
1831
+ sub [2 ] = (d -> dirty_submodule & DIRTY_SUBMODULE_MODIFIED ) ? 'M' : '.' ;
1832
+ sub [3 ] = (d -> dirty_submodule & DIRTY_SUBMODULE_UNTRACKED ) ? 'U' : '.' ;
1833
+ } else {
1834
+ sub [0 ] = 'N' ;
1835
+ sub [1 ] = '.' ;
1836
+ sub [2 ] = '.' ;
1837
+ sub [3 ] = '.' ;
1838
+ }
1839
+ sub [4 ] = 0 ;
1840
+ }
1841
+
1842
+ /*
1843
+ * Fix-up changed entries before we print them.
1844
+ */
1845
+ static void wt_porcelain_v2_fix_up_changed (
1846
+ struct string_list_item * it ,
1847
+ struct wt_status * s )
1848
+ {
1849
+ struct wt_status_change_data * d = it -> util ;
1850
+
1851
+ if (!d -> index_status ) {
1852
+ /*
1853
+ * This entry is unchanged in the index (relative to the head).
1854
+ * Therefore, the collect_updated_cb was never called for this
1855
+ * entry (during the head-vs-index scan) and so the head column
1856
+ * fields were never set.
1857
+ *
1858
+ * We must have data for the index column (from the
1859
+ * index-vs-worktree scan (otherwise, this entry should not be
1860
+ * in the list of changes)).
1861
+ *
1862
+ * Copy index column fields to the head column, so that our
1863
+ * output looks complete.
1864
+ */
1865
+ assert (d -> mode_head == 0 );
1866
+ d -> mode_head = d -> mode_index ;
1867
+ oidcpy (& d -> oid_head , & d -> oid_index );
1868
+ }
1869
+
1870
+ if (!d -> worktree_status ) {
1871
+ /*
1872
+ * This entry is unchanged in the worktree (relative to the index).
1873
+ * Therefore, the collect_changed_cb was never called for this entry
1874
+ * (during the index-vs-worktree scan) and so the worktree column
1875
+ * fields were never set.
1876
+ *
1877
+ * We must have data for the index column (from the head-vs-index
1878
+ * scan).
1879
+ *
1880
+ * Copy the index column fields to the worktree column so that
1881
+ * our output looks complete.
1882
+ *
1883
+ * Note that we only have a mode field in the worktree column
1884
+ * because the scan code tries really hard to not have to compute it.
1885
+ */
1886
+ assert (d -> mode_worktree == 0 );
1887
+ d -> mode_worktree = d -> mode_index ;
1888
+ }
1889
+ }
1890
+
1891
+ /*
1892
+ * Print porcelain v2 info for tracked entries with changes.
1893
+ */
1894
+ static void wt_porcelain_v2_print_changed_entry (
1895
+ struct string_list_item * it ,
1896
+ struct wt_status * s )
1897
+ {
1898
+ struct wt_status_change_data * d = it -> util ;
1899
+ struct strbuf buf_index = STRBUF_INIT ;
1900
+ struct strbuf buf_head = STRBUF_INIT ;
1901
+ const char * path_index = NULL ;
1902
+ const char * path_head = NULL ;
1903
+ char key [3 ];
1904
+ char submodule_token [5 ];
1905
+ char sep_char , eol_char ;
1906
+
1907
+ wt_porcelain_v2_fix_up_changed (it , s );
1908
+ wt_porcelain_v2_submodule_state (d , submodule_token );
1909
+
1910
+ key [0 ] = d -> index_status ? d -> index_status : '.' ;
1911
+ key [1 ] = d -> worktree_status ? d -> worktree_status : '.' ;
1912
+ key [2 ] = 0 ;
1913
+
1914
+ if (s -> null_termination ) {
1915
+ /*
1916
+ * In -z mode, we DO NOT C-quote pathnames. Current path is ALWAYS first.
1917
+ * A single NUL character separates them.
1918
+ */
1919
+ sep_char = '\0' ;
1920
+ eol_char = '\0' ;
1921
+ path_index = it -> string ;
1922
+ path_head = d -> head_path ;
1923
+ } else {
1924
+ /*
1925
+ * Path(s) are C-quoted if necessary. Current path is ALWAYS first.
1926
+ * The source path is only present when necessary.
1927
+ * A single TAB separates them (because paths can contain spaces
1928
+ * which are not escaped and C-quoting does escape TAB characters).
1929
+ */
1930
+ sep_char = '\t' ;
1931
+ eol_char = '\n' ;
1932
+ path_index = quote_path (it -> string , s -> prefix , & buf_index );
1933
+ if (d -> head_path )
1934
+ path_head = quote_path (d -> head_path , s -> prefix , & buf_head );
1935
+ }
1936
+
1937
+ if (path_head )
1938
+ fprintf (s -> fp , "2 %s %s %06o %06o %06o %s %s %c%d %s%c%s%c" ,
1939
+ key , submodule_token ,
1940
+ d -> mode_head , d -> mode_index , d -> mode_worktree ,
1941
+ oid_to_hex (& d -> oid_head ), oid_to_hex (& d -> oid_index ),
1942
+ key [0 ], d -> score ,
1943
+ path_index , sep_char , path_head , eol_char );
1944
+ else
1945
+ fprintf (s -> fp , "1 %s %s %06o %06o %06o %s %s %s%c" ,
1946
+ key , submodule_token ,
1947
+ d -> mode_head , d -> mode_index , d -> mode_worktree ,
1948
+ oid_to_hex (& d -> oid_head ), oid_to_hex (& d -> oid_index ),
1949
+ path_index , eol_char );
1950
+
1951
+ strbuf_release (& buf_index );
1952
+ strbuf_release (& buf_head );
1953
+ }
1954
+
1955
+ /*
1956
+ * Print porcelain v2 status info for unmerged entries.
1957
+ */
1958
+ static void wt_porcelain_v2_print_unmerged_entry (
1959
+ struct string_list_item * it ,
1960
+ struct wt_status * s )
1961
+ {
1962
+ struct wt_status_change_data * d = it -> util ;
1963
+ const struct cache_entry * ce ;
1964
+ struct strbuf buf_index = STRBUF_INIT ;
1965
+ const char * path_index = NULL ;
1966
+ int pos , stage , sum ;
1967
+ struct {
1968
+ int mode ;
1969
+ struct object_id oid ;
1970
+ } stages [3 ];
1971
+ char * key ;
1972
+ char submodule_token [5 ];
1973
+ char unmerged_prefix = 'u' ;
1974
+ char eol_char = s -> null_termination ? '\0' : '\n' ;
1975
+
1976
+ wt_porcelain_v2_submodule_state (d , submodule_token );
1977
+
1978
+ switch (d -> stagemask ) {
1979
+ case 1 : key = "DD" ; break ; /* both deleted */
1980
+ case 2 : key = "AU" ; break ; /* added by us */
1981
+ case 3 : key = "UD" ; break ; /* deleted by them */
1982
+ case 4 : key = "UA" ; break ; /* added by them */
1983
+ case 5 : key = "DU" ; break ; /* deleted by us */
1984
+ case 6 : key = "AA" ; break ; /* both added */
1985
+ case 7 : key = "UU" ; break ; /* both modified */
1986
+ default :
1987
+ die ("BUG: unhandled unmerged status %x" , d -> stagemask );
1988
+ }
1989
+
1990
+ /*
1991
+ * Disregard d.aux.porcelain_v2 data that we accumulated
1992
+ * for the head and index columns during the scans and
1993
+ * replace with the actual stage data.
1994
+ *
1995
+ * Note that this is a last-one-wins for each the individual
1996
+ * stage [123] columns in the event of multiple cache entries
1997
+ * for same stage.
1998
+ */
1999
+ memset (stages , 0 , sizeof (stages ));
2000
+ sum = 0 ;
2001
+ pos = cache_name_pos (it -> string , strlen (it -> string ));
2002
+ assert (pos < 0 );
2003
+ pos = - pos - 1 ;
2004
+ while (pos < active_nr ) {
2005
+ ce = active_cache [pos ++ ];
2006
+ stage = ce_stage (ce );
2007
+ if (strcmp (ce -> name , it -> string ) || !stage )
2008
+ break ;
2009
+ stages [stage - 1 ].mode = ce -> ce_mode ;
2010
+ hashcpy (stages [stage - 1 ].oid .hash , ce -> sha1 );
2011
+ sum |= (1 << (stage - 1 ));
2012
+ }
2013
+ if (sum != d -> stagemask )
2014
+ die ("BUG: observed stagemask 0x%x != expected stagemask 0x%x" , sum , d -> stagemask );
2015
+
2016
+ if (s -> null_termination )
2017
+ path_index = it -> string ;
2018
+ else
2019
+ path_index = quote_path (it -> string , s -> prefix , & buf_index );
2020
+
2021
+ fprintf (s -> fp , "%c %s %s %06o %06o %06o %06o %s %s %s %s%c" ,
2022
+ unmerged_prefix , key , submodule_token ,
2023
+ stages [0 ].mode , /* stage 1 */
2024
+ stages [1 ].mode , /* stage 2 */
2025
+ stages [2 ].mode , /* stage 3 */
2026
+ d -> mode_worktree ,
2027
+ oid_to_hex (& stages [0 ].oid ), /* stage 1 */
2028
+ oid_to_hex (& stages [1 ].oid ), /* stage 2 */
2029
+ oid_to_hex (& stages [2 ].oid ), /* stage 3 */
2030
+ path_index ,
2031
+ eol_char );
2032
+
2033
+ strbuf_release (& buf_index );
2034
+ }
2035
+
2036
+ /*
2037
+ * Print porcelain V2 status info for untracked and ignored entries.
2038
+ */
2039
+ static void wt_porcelain_v2_print_other (
2040
+ struct string_list_item * it ,
2041
+ struct wt_status * s ,
2042
+ char prefix )
2043
+ {
2044
+ struct strbuf buf = STRBUF_INIT ;
2045
+ const char * path ;
2046
+ char eol_char ;
2047
+
2048
+ if (s -> null_termination ) {
2049
+ path = it -> string ;
2050
+ eol_char = '\0' ;
2051
+ } else {
2052
+ path = quote_path (it -> string , s -> prefix , & buf );
2053
+ eol_char = '\n' ;
2054
+ }
2055
+
2056
+ fprintf (s -> fp , "%c %s%c" , prefix , path , eol_char );
2057
+
2058
+ strbuf_release (& buf );
2059
+ }
2060
+
2061
+ /*
2062
+ * Print porcelain V2 status.
2063
+ *
2064
+ * [<v2_changed_items>]*
2065
+ * [<v2_unmerged_items>]*
2066
+ * [<v2_untracked_items>]*
2067
+ * [<v2_ignored_items>]*
2068
+ *
2069
+ */
2070
+ static void wt_porcelain_v2_print (struct wt_status * s )
2071
+ {
2072
+ struct wt_status_change_data * d ;
2073
+ struct string_list_item * it ;
2074
+ int i ;
2075
+
2076
+ for (i = 0 ; i < s -> change .nr ; i ++ ) {
2077
+ it = & (s -> change .items [i ]);
2078
+ d = it -> util ;
2079
+ if (!d -> stagemask )
2080
+ wt_porcelain_v2_print_changed_entry (it , s );
2081
+ }
2082
+
2083
+ for (i = 0 ; i < s -> change .nr ; i ++ ) {
2084
+ it = & (s -> change .items [i ]);
2085
+ d = it -> util ;
2086
+ if (d -> stagemask )
2087
+ wt_porcelain_v2_print_unmerged_entry (it , s );
2088
+ }
2089
+
2090
+ for (i = 0 ; i < s -> untracked .nr ; i ++ ) {
2091
+ it = & (s -> untracked .items [i ]);
2092
+ wt_porcelain_v2_print_other (it , s , '?' );
2093
+ }
2094
+
2095
+ for (i = 0 ; i < s -> ignored .nr ; i ++ ) {
2096
+ it = & (s -> ignored .items [i ]);
2097
+ wt_porcelain_v2_print_other (it , s , '!' );
2098
+ }
2099
+ }
2100
+
1818
2101
void wt_status_print (struct wt_status * s )
1819
2102
{
1820
2103
switch (s -> status_format ) {
@@ -1825,7 +2108,7 @@ void wt_status_print(struct wt_status *s)
1825
2108
wt_porcelain_print (s );
1826
2109
break ;
1827
2110
case STATUS_FORMAT_PORCELAIN_V2 :
1828
- /* TODO */
2111
+ wt_porcelain_v2_print ( s );
1829
2112
break ;
1830
2113
case STATUS_FORMAT_UNSPECIFIED :
1831
2114
die ("BUG: finalize_deferred_config() should have been called" );
0 commit comments