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