From: Christian Couder <christian.couder@gmail.com>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>,
Patrick Steinhardt <ps@pks.im>, John Cai <johncai86@gmail.com>,
Christian Couder <christian.couder@gmail.com>,
Christian Couder <chriscool@tuxfamily.org>
Subject: [PATCH 3/3] rev-list: add --allow-missing-tips to be used with --missing=...
Date: Thu, 1 Feb 2024 12:58:09 +0100 [thread overview]
Message-ID: <20240201115809.1177064-4-christian.couder@gmail.com> (raw)
In-Reply-To: <20240201115809.1177064-1-christian.couder@gmail.com>
In 9830926c7d (rev-list: add commit object support in `--missing`
option, 2023-10-27) we fixed the `--missing` option in `git rev-list`
so that it now works with commits too.
Unfortunately, such a command would still fail with a "fatal: bad
object <oid>" if it is passed a missing commit, blob or tree as an
argument.
When such a command is used to find the dependencies of some objects,
for example the dependencies of quarantined objects, it would be
better if the command would instead consider such missing objects,
especially commits, in the same way as other missing objects.
If, for example `--missing=print` is used, it would be nice for some
use cases if the missing tips passed as arguments were reported in
the same way as other missing objects instead of the command just
failing.
Let's introduce a new `--allow-missing-tips` option to make it work
like this.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin/rev-list.c | 24 ++++++++++++++++-
revision.c | 9 ++++---
revision.h | 8 ++++++
t/t6022-rev-list-missing.sh | 51 +++++++++++++++++++++++++++++++++++++
4 files changed, 88 insertions(+), 4 deletions(-)
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index b3f4783858..ae7bb15478 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -562,6 +562,16 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
break;
}
}
+ for (i = 1; i < argc; i++) {
+ const char *arg = argv[i];
+ if (!strcmp(arg, "--allow-missing-tips")) {
+ if (arg_missing_action == MA_ERROR)
+ die(_("option '%s' only makes sense with '%s' set to '%s' or '%s'"),
+ "--allow-missing-tips", "--missing=", "allow-*", "print");
+ revs.do_not_die_on_missing_tips = 1;
+ break;
+ }
+ }
if (arg_missing_action)
revs.do_not_die_on_missing_objects = 1;
@@ -627,6 +637,8 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
continue; /* already handled above */
if (skip_prefix(arg, "--missing=", &arg))
continue; /* already handled above */
+ if (!strcmp(arg, "--allow-missing-tips"))
+ continue; /* already handled above */
if (!strcmp(arg, ("--no-object-names"))) {
arg_show_object_names = 0;
@@ -753,9 +765,19 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
if (arg_print_omitted)
oidset_init(&omitted_objects, DEFAULT_OIDSET_SIZE);
- if (arg_missing_action == MA_PRINT)
+ if (arg_missing_action == MA_PRINT) {
+ struct oidset_iter iter;
+ struct object_id *oid;
+
oidset_init(&missing_objects, DEFAULT_OIDSET_SIZE);
+ /* Already add missing commits */
+ oidset_iter_init(&revs.missing_commits, &iter);
+ while ((oid = oidset_iter_next(&iter)))
+ oidset_insert(&missing_objects, oid);
+ oidset_clear(&revs.missing_commits);
+ }
+
traverse_commit_list_filtered(
&revs, show_commit, show_object, &info,
(arg_print_omitted ? &omitted_objects : NULL));
diff --git a/revision.c b/revision.c
index 4c5cd7c3ce..9f25faa249 100644
--- a/revision.c
+++ b/revision.c
@@ -388,6 +388,10 @@ static struct object *get_reference(struct rev_info *revs, const char *name,
return NULL;
if (revs->exclude_promisor_objects && is_promisor_object(oid))
return NULL;
+ if (revs->do_not_die_on_missing_tips) {
+ oidset_insert(&revs->missing_commits, oid);
+ return NULL;
+ }
die("bad object %s", name);
}
object->flags |= flags;
@@ -1947,6 +1951,7 @@ void repo_init_revisions(struct repository *r,
init_display_notes(&revs->notes_opt);
list_objects_filter_init(&revs->filter);
init_ref_exclusions(&revs->ref_excludes);
+ oidset_init(&revs->missing_commits, 0);
}
static void add_pending_commit_list(struct rev_info *revs,
@@ -2184,7 +2189,7 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl
verify_non_filename(revs->prefix, arg);
object = get_reference(revs, arg, &oid, flags ^ local_flags);
if (!object)
- return revs->ignore_missing ? 0 : -1;
+ return (revs->ignore_missing || revs->do_not_die_on_missing_tips) ? 0 : -1;
add_rev_cmdline(revs, object, arg_, REV_CMD_REV, flags ^ local_flags);
add_pending_object_with_path(revs, object, arg, oc.mode, oc.path);
free(oc.path);
@@ -3830,8 +3835,6 @@ int prepare_revision_walk(struct rev_info *revs)
FOR_EACH_OBJECT_PROMISOR_ONLY);
}
- oidset_init(&revs->missing_commits, 0);
-
if (!revs->reflog_info)
prepare_to_use_bloom_filter(revs);
if (!revs->unsorted_input)
diff --git a/revision.h b/revision.h
index 94c43138bc..67435a5d8a 100644
--- a/revision.h
+++ b/revision.h
@@ -227,6 +227,14 @@ struct rev_info {
*/
do_not_die_on_missing_objects:1,
+ /*
+ * When the do_not_die_on_missing_objects flag above is set,
+ * a rev walk could still die with "fatal: bad object <oid>"
+ * if one of the tips it is passed is missing. With this flag
+ * such a tip will be reported as missing too.
+ */
+ do_not_die_on_missing_tips:1,
+
/* for internal use only */
exclude_promisor_objects:1;
diff --git a/t/t6022-rev-list-missing.sh b/t/t6022-rev-list-missing.sh
index 527aa94f07..283e8fc2c2 100755
--- a/t/t6022-rev-list-missing.sh
+++ b/t/t6022-rev-list-missing.sh
@@ -77,4 +77,55 @@ do
done
done
+for obj in "HEAD~1" "HEAD~1^{tree}" "HEAD:1.t"
+do
+ for tip in "" "HEAD"
+ do
+ for action in "allow-any" "print"
+ do
+ test_expect_success "--missing=$action --allow-missing-tips with tip '$obj' missing and tip '$tip'" '
+ oid="$(git rev-parse $obj)" &&
+ path=".git/objects/$(test_oid_to_path $oid)" &&
+
+ # Before the object is made missing, we use rev-list to
+ # get the expected oids.
+ if [ "$tip" = "HEAD" ]; then
+ git rev-list --objects --no-object-names \
+ HEAD ^$obj >expect.raw
+ else
+ >expect.raw
+ fi &&
+
+ # Blobs are shared by all commits, so even though a commit/tree
+ # might be skipped, its blob must be accounted for.
+ if [ "$tip" = "HEAD" ] && [ $obj != "HEAD:1.t" ]; then
+ echo $(git rev-parse HEAD:1.t) >>expect.raw &&
+ echo $(git rev-parse HEAD:2.t) >>expect.raw
+ fi &&
+
+ mv "$path" "$path.hidden" &&
+ test_when_finished "mv $path.hidden $path" &&
+
+ git rev-list --missing=$action --allow-missing-tips \
+ --objects --no-object-names $oid $tip >actual.raw &&
+
+ # When the action is to print, we should also add the missing
+ # oid to the expect list.
+ case $action in
+ allow-any)
+ ;;
+ print)
+ grep ?$oid actual.raw &&
+ echo ?$oid >>expect.raw
+ ;;
+ esac &&
+
+ sort actual.raw >actual &&
+ sort expect.raw >expect &&
+ test_cmp expect actual
+ '
+ done
+ done
+done
+
test_done
--
2.43.0.496.gd667eb0d7d.dirty
next prev parent reply other threads:[~2024-02-01 11:58 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-01 11:58 [PATCH 0/3] rev-list: allow missing tips with --missing Christian Couder
2024-02-01 11:58 ` [PATCH 1/3] revision: clarify a 'return NULL' in get_reference() Christian Couder
2024-02-01 14:53 ` Eric Sunshine
2024-02-01 16:49 ` Christian Couder
2024-02-01 11:58 ` [PATCH 2/3] t6022: fix 'even though' typo in comment Christian Couder
2024-02-01 11:58 ` Christian Couder [this message]
2024-02-01 20:20 ` [PATCH 3/3] rev-list: add --allow-missing-tips to be used with --missing= Junio C Hamano
2024-02-02 11:29 ` Christian Couder
2024-02-02 16:47 ` Junio C Hamano
2024-02-01 21:27 ` Junio C Hamano
2024-02-02 11:29 ` Christian Couder
2024-02-02 16:54 ` Junio C Hamano
2024-02-07 9:57 ` Linus Arver
2024-02-07 16:34 ` Junio C Hamano
2024-02-07 16:38 ` Christian Couder
2024-02-07 9:40 ` Linus Arver
2024-02-07 16:11 ` Christian Couder
2024-02-07 20:48 ` Linus Arver
2024-02-08 15:03 ` Christian Couder
2024-02-08 20:42 ` Linus Arver
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240201115809.1177064-4-christian.couder@gmail.com \
--to=christian.couder@gmail.com \
--cc=chriscool@tuxfamily.org \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=johncai86@gmail.com \
--cc=ps@pks.im \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).