do_for_each_ref(): only iterate over the subtree that was requested

If the base argument has a "/" chararacter, then only iterate over the reference subdir whose name is the part up to the last "/". Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Michael Haggerty committed Apr 10, 2012 at 07:30 UTC 933ac036d29e65e1b3d71332d9ade8edd1e8a89b
1 file changed +28 -7
refs.c
+28 -7
@@ -1143,13 +1143,34 @@ static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn
1143 int trim, int flags, void *cb_data)
1144 {
1145 struct ref_cache *refs = get_ref_cache(submodule);
1146 - struct ref_dir *packed_refs = get_packed_refs(refs);
1147 - struct ref_dir *loose_refs = get_loose_refs(refs);
1148 - sort_ref_dir(packed_refs);
1149 - sort_ref_dir(loose_refs);
1150 - return do_for_each_ref_in_dirs(packed_refs,
1151 - loose_refs,
1152 - base, fn, trim, flags, cb_data);
1146 + struct ref_dir *packed_dir = get_packed_refs(refs);
1147 + struct ref_dir *loose_dir = get_loose_refs(refs);
1148 + int retval = 0;
1149 +
1150 + if (base && *base) {
1151 + packed_dir = find_containing_dir(packed_dir, base, 0);
1152 + loose_dir = find_containing_dir(loose_dir, base, 0);
1153 + }
1154 +
1155 + if (packed_dir && loose_dir) {
1156 + sort_ref_dir(packed_dir);
1157 + sort_ref_dir(loose_dir);
1158 + retval = do_for_each_ref_in_dirs(
1159 + packed_dir, loose_dir,
1160 + base, fn, trim, flags, cb_data);
1161 + } else if (packed_dir) {
1162 + sort_ref_dir(packed_dir);
1163 + retval = do_for_each_ref_in_dir(
1164 + packed_dir, 0,
1165 + base, fn, trim, flags, cb_data);
1166 + } else if (loose_dir) {
1167 + sort_ref_dir(loose_dir);
1168 + retval = do_for_each_ref_in_dir(
1169 + loose_dir, 0,
1170 + base, fn, trim, flags, cb_data);
1171 + }
1172 +
1173 + return retval;
1174 }
1175
1176 static int do_head_ref(const char *submodule, each_ref_fn fn, void *cb_data)