[PATCH] rev-list: print missing object type with --missing=print-type

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Handling of missing objects encounted by git-rev-list(1) can be
configured with the `--missing=<action>` option and specifying the
desired action. Of the available missing actions, none provide a way to
print additional information about the missing object such as its type.

Add a new missing action called `print-type`. Similar to `print`, this
action prints a list of missing objects but also includes the object
type if available in the form: `?<oid> [type]`.

Signed-off-by: Justin Tobler <jltobler@xxxxxxxxx>
---
Instead of adding an additional missing action type for the explicit
purpose of printing type info, I also considered a separate option
(something like `--object-types`, or maybe a `--missing-format`) that
could be used in combination with the `--missing=print` option to
achieve the same result. The main intent is for the missing object type
and I wasn't sure if type info would be useful in the general case so I
opted to choose the former approach.

Thanks,
-Justin
---
 Documentation/rev-list-options.txt |  3 ++
 builtin/rev-list.c                 | 74 +++++++++++++++++++++++++-----
 t/t6022-rev-list-missing.sh        | 13 +++++-
 3 files changed, 77 insertions(+), 13 deletions(-)

diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index 459e5a02f5..277a0b645e 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -1024,6 +1024,9 @@ Unexpected missing objects will raise an error.
 The form '--missing=print' is like 'allow-any', but will also print a
 list of the missing objects.  Object IDs are prefixed with a ``?'' character.
 +
+The form '--missing=print-type' is like 'print', but will also print the
+missing object type information if available in the form `?<oid> [type]`.
++
 If some tips passed to the traversal are missing, they will be
 considered as missing too, and the traversal will ignore them. In case
 we cannot get their Object ID though, an error will be raised.
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index 3196da7b2d..ee473da52c 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -22,6 +22,7 @@
 #include "progress.h"
 #include "reflog-walk.h"
 #include "oidset.h"
+#include "oidmap.h"
 #include "packfile.h"
 
 static const char rev_list_usage[] =
@@ -73,11 +74,16 @@ static unsigned progress_counter;
 static struct oidset omitted_objects;
 static int arg_print_omitted; /* print objects omitted by filter */
 
-static struct oidset missing_objects;
+struct missing_objects_map_entry {
+	struct oidmap_entry entry;
+	unsigned type : TYPE_BITS;
+};
+static struct oidmap missing_objects;
 enum missing_action {
 	MA_ERROR = 0,    /* fail if any missing objects are encountered */
 	MA_ALLOW_ANY,    /* silently allow ALL missing objects */
 	MA_PRINT,        /* print ALL missing objects in special section */
+	MA_PRINT_TYPE,   /* same as MA_PRINT but includes available type info */
 	MA_ALLOW_PROMISOR, /* silently allow all missing PROMISOR objects */
 };
 static enum missing_action arg_missing_action;
@@ -103,6 +109,8 @@ static off_t get_object_disk_usage(struct object *obj)
 
 static inline void finish_object__ma(struct object *obj)
 {
+	struct missing_objects_map_entry *entry, *old;
+
 	/*
 	 * Whether or not we try to dynamically fetch missing objects
 	 * from the server, we currently DO NOT have the object.  We
@@ -119,7 +127,12 @@ static inline void finish_object__ma(struct object *obj)
 		return;
 
 	case MA_PRINT:
-		oidset_insert(&missing_objects, &obj->oid);
+	case MA_PRINT_TYPE:
+		CALLOC_ARRAY(entry, 1);
+		entry->entry.oid = obj->oid;
+		entry->type = obj->type;
+		old = oidmap_put(&missing_objects, entry);
+		free(old);
 		return;
 
 	case MA_ALLOW_PROMISOR:
@@ -414,6 +427,12 @@ static inline int parse_missing_action_value(const char *value)
 		return 1;
 	}
 
+	if (!strcmp(value, "print-type")) {
+		arg_missing_action = MA_PRINT_TYPE;
+		fetch_if_missing = 0;
+		return 1;
+	}
+
 	if (!strcmp(value, "allow-promisor")) {
 		arg_missing_action = MA_ALLOW_PROMISOR;
 		fetch_if_missing = 0;
@@ -781,10 +800,26 @@ int cmd_rev_list(int argc,
 
 	if (arg_print_omitted)
 		oidset_init(&omitted_objects, DEFAULT_OIDSET_SIZE);
-	if (arg_missing_action == MA_PRINT) {
-		oidset_init(&missing_objects, DEFAULT_OIDSET_SIZE);
-		/* Add missing tips */
-		oidset_insert_from_set(&missing_objects, &revs.missing_commits);
+	if (arg_missing_action == MA_PRINT ||
+	    arg_missing_action == MA_PRINT_TYPE) {
+		struct oidset_iter iter;
+		struct object_id *oid;
+
+		oidmap_init(&missing_objects, DEFAULT_OIDSET_SIZE);
+		oidset_iter_init(&revs.missing_commits, &iter);
+
+		/*
+		 * Revisions pointing to missing objects lack the context
+		 * required to determine object type.
+		 */
+		while ((oid = oidset_iter_next(&iter))) {
+			struct missing_objects_map_entry *entry;
+
+			CALLOC_ARRAY(entry, 1);
+			oidcpy(&entry->entry.oid, oid);
+			oidmap_put(&missing_objects, entry);
+		}
+
 		oidset_clear(&revs.missing_commits);
 	}
 
@@ -801,12 +836,27 @@ int cmd_rev_list(int argc,
 		oidset_clear(&omitted_objects);
 	}
 	if (arg_missing_action == MA_PRINT) {
-		struct oidset_iter iter;
-		struct object_id *oid;
-		oidset_iter_init(&missing_objects, &iter);
-		while ((oid = oidset_iter_next(&iter)))
-			printf("?%s\n", oid_to_hex(oid));
-		oidset_clear(&missing_objects);
+		struct missing_objects_map_entry *entry;
+		struct oidmap_iter iter;
+
+		oidmap_iter_init(&missing_objects, &iter);
+
+		while ((entry = oidmap_iter_next(&iter)))
+			printf("?%s\n", oid_to_hex(&entry->entry.oid));
+
+		oidmap_free(&missing_objects, true);
+	}
+	if (arg_missing_action == MA_PRINT_TYPE) {
+		struct missing_objects_map_entry *entry;
+		struct oidmap_iter iter;
+
+		oidmap_iter_init(&missing_objects, &iter);
+
+		while ((entry = oidmap_iter_next(&iter)))
+			printf("?%s %s\n", oid_to_hex(&entry->entry.oid),
+			       entry->type ? type_name(entry->type) : "");
+
+		oidmap_free(&missing_objects, true);
 	}
 
 	stop_progress(&progress);
diff --git a/t/t6022-rev-list-missing.sh b/t/t6022-rev-list-missing.sh
index 7553a9cca2..1606082d4b 100755
--- a/t/t6022-rev-list-missing.sh
+++ b/t/t6022-rev-list-missing.sh
@@ -37,7 +37,7 @@ done
 
 for obj in "HEAD~1" "HEAD~1^{tree}" "HEAD:1.t"
 do
-	for action in "allow-any" "print"
+	for action in "allow-any" "print" "print-type"
 	do
 		test_expect_success "rev-list --missing=$action with missing $obj" '
 			oid="$(git rev-parse $obj)" &&
@@ -48,6 +48,13 @@ do
 			git rev-list --objects --no-object-names \
 				HEAD ^$obj >expect.raw &&
 
+			# When the action is to print the type, we should also
+			# record the expected type of the missing object.
+			if test "$action" = "print-type"
+			then
+				type="$(git cat-file -t $obj)"
+			fi &&
+
 			# Blobs are shared by all commits, so even though a commit/tree
 			# might be skipped, its blob must be accounted for.
 			if test $obj != "HEAD:1.t"
@@ -71,6 +78,10 @@ do
 				grep ?$oid actual.raw &&
 				echo ?$oid >>expect.raw
 				;;
+			print-type)
+				grep "?$oid $type" actual.raw &&
+				echo "?$oid $type" >>expect.raw
+				;;
 			esac &&
 
 			sort actual.raw >actual &&

base-commit: b74ff38af58464688b211140b90ec90598d340c6
-- 
2.47.1





[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux