@@ -37,6 +37,8 @@ static struct used_atom {
3737 union {
3838 char color [COLOR_MAXLEN ];
3939 struct align align ;
40+ enum { RR_NORMAL , RR_SHORTEN , RR_TRACK , RR_TRACKSHORT }
41+ remote_ref ;
4042 } u ;
4143} * used_atom ;
4244static int used_atom_cnt , need_tagged , need_symref ;
@@ -50,6 +52,20 @@ static void color_atom_parser(struct used_atom *atom, const char *color_value)
5052 die (_ ("unrecognized color: %%(color:%s)" ), color_value );
5153}
5254
55+ static void remote_ref_atom_parser (struct used_atom * atom , const char * arg )
56+ {
57+ if (!arg )
58+ atom -> u .remote_ref = RR_NORMAL ;
59+ else if (!strcmp (arg , "short" ))
60+ atom -> u .remote_ref = RR_SHORTEN ;
61+ else if (!strcmp (arg , "track" ))
62+ atom -> u .remote_ref = RR_TRACK ;
63+ else if (!strcmp (arg , "trackshort" ))
64+ atom -> u .remote_ref = RR_TRACKSHORT ;
65+ else
66+ die (_ ("unrecognized format: %%(%s)" ), atom -> name );
67+ }
68+
5369static align_type parse_align_position (const char * s )
5470{
5571 if (!strcmp (s , "right" ))
@@ -132,8 +148,8 @@ static struct {
132148 { "subject" },
133149 { "body" },
134150 { "contents" },
135- { "upstream" },
136- { "push" },
151+ { "upstream" , FIELD_STR , remote_ref_atom_parser },
152+ { "push" , FIELD_STR , remote_ref_atom_parser },
137153 { "symref" },
138154 { "flag" },
139155 { "HEAD" },
@@ -840,6 +856,43 @@ static const char *strip_ref_components(const char *refname, const char *nr_arg)
840856 return start ;
841857}
842858
859+ static void fill_remote_ref_details (struct used_atom * atom , const char * refname ,
860+ struct branch * branch , const char * * s )
861+ {
862+ int num_ours , num_theirs ;
863+ if (atom -> u .remote_ref == RR_SHORTEN )
864+ * s = shorten_unambiguous_ref (refname , warn_ambiguous_refs );
865+ else if (atom -> u .remote_ref == RR_TRACK ) {
866+ if (stat_tracking_info (branch , & num_ours ,
867+ & num_theirs , NULL ))
868+ return ;
869+
870+ if (!num_ours && !num_theirs )
871+ * s = "" ;
872+ else if (!num_ours )
873+ * s = xstrfmt ("[behind %d]" , num_theirs );
874+ else if (!num_theirs )
875+ * s = xstrfmt ("[ahead %d]" , num_ours );
876+ else
877+ * s = xstrfmt ("[ahead %d, behind %d]" ,
878+ num_ours , num_theirs );
879+ } else if (atom -> u .remote_ref == RR_TRACKSHORT ) {
880+ if (stat_tracking_info (branch , & num_ours ,
881+ & num_theirs , NULL ))
882+ return ;
883+
884+ if (!num_ours && !num_theirs )
885+ * s = "=" ;
886+ else if (!num_ours )
887+ * s = "<" ;
888+ else if (!num_theirs )
889+ * s = ">" ;
890+ else
891+ * s = "<>" ;
892+ } else /* RR_NORMAL */
893+ * s = refname ;
894+ }
895+
843896/*
844897 * Parse the object referred by ref, and grab needed value.
845898 */
@@ -891,8 +944,9 @@ static void populate_value(struct ref_array_item *ref)
891944 branch = branch_get (branch_name );
892945
893946 refname = branch_get_upstream (branch , NULL );
894- if (!refname )
895- continue ;
947+ if (refname )
948+ fill_remote_ref_details (atom , refname , branch , & v -> s );
949+ continue ;
896950 } else if (starts_with (name , "push" )) {
897951 const char * branch_name ;
898952 if (!skip_prefix (ref -> refname , "refs/heads/" ,
@@ -903,6 +957,8 @@ static void populate_value(struct ref_array_item *ref)
903957 refname = branch_get_push (branch , NULL );
904958 if (!refname )
905959 continue ;
960+ fill_remote_ref_details (atom , refname , branch , & v -> s );
961+ continue ;
906962 } else if (starts_with (name , "color:" )) {
907963 v -> s = atom -> u .color ;
908964 continue ;
@@ -944,7 +1000,6 @@ static void populate_value(struct ref_array_item *ref)
9441000
9451001 formatp = strchr (name , ':' );
9461002 if (formatp ) {
947- int num_ours , num_theirs ;
9481003 const char * arg ;
9491004
9501005 formatp ++ ;
@@ -953,43 +1008,7 @@ static void populate_value(struct ref_array_item *ref)
9531008 warn_ambiguous_refs );
9541009 else if (skip_prefix (formatp , "strip=" , & arg ))
9551010 refname = strip_ref_components (refname , arg );
956- else if (!strcmp (formatp , "track" ) &&
957- (starts_with (name , "upstream" ) ||
958- starts_with (name , "push" ))) {
959-
960- if (stat_tracking_info (branch , & num_ours ,
961- & num_theirs , NULL ))
962- continue ;
963-
964- if (!num_ours && !num_theirs )
965- v -> s = "" ;
966- else if (!num_ours )
967- v -> s = xstrfmt ("[behind %d]" , num_theirs );
968- else if (!num_theirs )
969- v -> s = xstrfmt ("[ahead %d]" , num_ours );
970- else
971- v -> s = xstrfmt ("[ahead %d, behind %d]" ,
972- num_ours , num_theirs );
973- continue ;
974- } else if (!strcmp (formatp , "trackshort" ) &&
975- (starts_with (name , "upstream" ) ||
976- starts_with (name , "push" ))) {
977- assert (branch );
978-
979- if (stat_tracking_info (branch , & num_ours ,
980- & num_theirs , NULL ))
981- continue ;
982-
983- if (!num_ours && !num_theirs )
984- v -> s = "=" ;
985- else if (!num_ours )
986- v -> s = "<" ;
987- else if (!num_theirs )
988- v -> s = ">" ;
989- else
990- v -> s = "<>" ;
991- continue ;
992- } else
1011+ else
9931012 die ("unknown %.*s format %s" ,
9941013 (int )(formatp - name ), name , formatp );
9951014 }
0 commit comments