git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v4 3/5] revision.[ch]: add a "handle_stdin_line" API

From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Date
Jul 9, 2021, 11:06 UTC
Message-ID
<patch-3.5-60ef49df3b8-20210709T105851Z-avarab@gmail.com>
In-Reply-To
<cover-0.5-00000000000-20210709T105850Z-avarab@gmail.com>

Extend the rev_info stdin parsing API to support hooking into its read_revisions_from_stdin() function, in the next commit we'll change the the custom stdin parsing in pack-objects.c to use it..

For that use-case adding API is barely justified. We'll be able to make the handle_revision_arg() static in exchange for it, and we'll avoid the duplicate dance around setting "save_warning" and "warn_on_object_refname_ambiguity", but we could just continue to do that ourselves in builtin/pack-objects.c

The real reason to add this is for a change not part of this series. We'll soon teach "git bundle create" to accept revision/refname pairs on stdin, and thus do away with the limitation of it being impossible to create bundles with ref tips that don't correspond to the state of the current repository. I.e. this will work:

    $ printf "e83c5163316f89bfbde7\trefs/heads/first-git-dot-git-commit\n" |
    git bundle create initial.bundle --stdin
As well as things like:
    $ git for-each-ref 'refs/remotes/origin' |
    sed 's!\trefs/remotes/origin/!\trefs/heads/!' |
    git bundle create origin.bundle --stdin

In order to do that we'll need to modify the lines we consume on stdin revision.c (which bundle.c uses already), and be assured that that stripping extra bundle-specific data from them is the only change in behavior.

That change will be much more complex if bundle.c needs to start doing its own stdin parsing again outside of revision.c, it was recently converted to use revision.c's parsing in 5bb0fd2cab5 (bundle: arguments can be read from stdin, 2021-01-11)

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 revision.c | 22 ++++++++++++++++++++++
 revision.h | 30 ++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)
diff --git a/revision.c b/revision.c
index f30b9d40af4..557b7f113a9 100644
--- a/revision.c
+++ b/revision.c
@@ -2120,6 +2120,19 @@ static void read_revisions_from_stdin(struct rev_info *revs,
 		int len = sb.len;
 		if (!len)
 			break;
+
+		if (revs->handle_stdin_line) {
+			enum rev_info_stdin_line ret = revs->handle_stdin_line(
+				revs, &sb, revs->stdin_line_priv);
+
+			switch (ret) {
+			case REV_INFO_STDIN_LINE_PROCESS:
+				break;
+			case REV_INFO_STDIN_LINE_CONTINUE:
+				continue;
+			}
+		}
+
 		if (sb.buf[0] == '-') {
 			if (len == 2 && sb.buf[1] == '-') {
 				seen_dashdash = 1;
@@ -2743,6 +2756,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 
 			if (!strcmp(arg, "--stdin")) {
 				switch (revs->stdin_handling) {
+				case REV_INFO_STDIN_ALWAYS_READ:
 				case REV_INFO_STDIN_IGNORE:
 					argv[left++] = arg;
 					continue;
@@ -2791,6 +2805,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 		}
 	}
 
+	/*
+	 * We're asked to ALWAYS_READ from stdin, but no --stdin
+	 * option (or "consumed_stdin" would be set).
+	 */
+	if (!revs->consumed_stdin &&
+	    revs->stdin_handling == REV_INFO_STDIN_ALWAYS_READ)
+		read_revisions_from_stdin(revs, &prune_data);
+
 	if (prune_data.nr) {
 		/*
 		 * If we need to introduce the magic "a lone ':' means no
diff --git a/revision.h b/revision.h
index a942b1250ad..52241c84c5b 100644
--- a/revision.h
+++ b/revision.h
@@ -89,8 +89,17 @@ struct topo_walk_info;
 enum rev_info_stdin {
 	REV_INFO_STDIN_CONSUME_ON_OPTION,
 	REV_INFO_STDIN_IGNORE,
+	REV_INFO_STDIN_ALWAYS_READ,
 };
 
+enum rev_info_stdin_line {
+	REV_INFO_STDIN_LINE_PROCESS,
+	REV_INFO_STDIN_LINE_CONTINUE,
+};
+
+typedef enum rev_info_stdin_line (*rev_info_stdin_line_func)(
+	struct rev_info *revs, struct strbuf *line, void *stdin_line_priv);
+
 struct rev_info {
 	/* Starting list */
 	struct commit_list *commits;
@@ -126,6 +135,9 @@ struct rev_info {
 	 *
 	 * Can be set to REV_INFO_STDIN_IGNORE to ignore the --stdin
 	 * option.
+	 *
+	 * Set it to REV_INFO_STDIN_ALWAYS_READ if there's always data
+	 * on stdin to be read, even if no --stdin option is provided.
 	 */
 	enum rev_info_stdin stdin_handling;
 
@@ -136,6 +148,24 @@ struct rev_info {
 	 */
 	int consumed_stdin:1;
 
+	/*
+	 * When reading from stdin (see "stdin_handling" above) define
+	 * a handle_stdin_line function to consume the lines.
+	 *
+	 * - Return REV_INFO_STDIN_LINE_PROCESS to continue
+	 *   revision.c's normal processing of the line (after
+	 *   possibly munging the provided strbuf).
+	 *
+	 * - Return REV_INFO_STDIN_LINE_CONTINUE to indicate that the
+	 *   line is fully processed, moving onto the next line (if
+	 *   any)
+	 *
+	 * Use the "stdin_line_priv" to optionally pass your own data
+	 * around.
+	 */
+	rev_info_stdin_line_func handle_stdin_line;
+	void *stdin_line_priv;
+
 	/* topo-sort */
 	enum rev_sort_order sort_order;
 
-- 
2.32.0.636.g43e71d69cff
Previous: Ævar Arnfjörð BjarmasonNext: Ævar Arnfjörð Bjarmason
Message 29 of 35 in “pack-objects: use revision.c's --stdin parsing”
  1. 0/4 pack-objects: use revision.c's --stdin parsingÆvar Arnfjörð Bjarmason, Jun 8, 2021
  2. 2/4 revision.h: unify "disable_stdin" and "read_from_stdin"Ævar Arnfjörð Bjarmason, Jun 8, 2021
  3. 3/4 pack-objects.c: do stdin parsing via revision.c's APIÆvar Arnfjörð Bjarmason, Jun 8, 2021
  4. Junio C HamanoJun 9, 2021
  5. 1/4 upload-pack: run is_repository_shallow() before setup_revisions()Ævar Arnfjörð Bjarmason, Jun 8, 2021
  6. 4/4 pack-objects.c: make use of REV_INFO_STDIN_LINE_PROCESSÆvar Arnfjörð Bjarmason, Jun 8, 2021
  7. 0/4 pack-objects: use revision.c's --stdin parsingÆvar Arnfjörð Bjarmason, Jun 17, 2021
  8. 1/4 upload-pack: run is_repository_shallow() before setup_revisions()Ævar Arnfjörð Bjarmason, Jun 17, 2021
  9. 2/4 revision.h: unify "disable_stdin" and "read_from_stdin"Ævar Arnfjörð Bjarmason, Jun 17, 2021
  10. Emily ShafferJun 17, 2021
  11. Jonathan TanJun 18, 2021
  12. 3/4 pack-objects.c: do stdin parsing via revision.c's APIÆvar Arnfjörð Bjarmason, Jun 17, 2021
  13. Jonathan TanJun 18, 2021
  14. 4/4 pack-objects.c: make use of REV_INFO_STDIN_LINE_PROCESSÆvar Arnfjörð Bjarmason, Jun 17, 2021
  15. 0/4 pack-objects: use revision.c's --stdin parsingÆvar Arnfjörð Bjarmason, Jun 21, 2021
  16. 1/4 upload-pack: run is_repository_shallow() before setup_revisions()Ævar Arnfjörð Bjarmason, Jun 21, 2021
  17. 3/4 pack-objects.c: do stdin parsing via revision.c's APIÆvar Arnfjörð Bjarmason, Jun 21, 2021
  18. Junio C HamanoJul 8, 2021
  19. 2/4 revision.h: refactor "disable_stdin" and "read_from_stdin"Ævar Arnfjörð Bjarmason, Jun 21, 2021
  20. Junio C HamanoJul 8, 2021
  21. 4/4 pack-objects.c: make use of REV_INFO_STDIN_LINE_PROCESSÆvar Arnfjörð Bjarmason, Jun 21, 2021
  22. Junio C HamanoJul 8, 2021
  23. 0/5 revision.[ch]: add --stdin parsing API, use in pack-objectsÆvar Arnfjörð Bjarmason, Jul 9, 2021
  24. 1/5 upload-pack: run is_repository_shallow() before setup_revisions()Ævar Arnfjörð Bjarmason, Jul 9, 2021
  25. 2/5 revision.h: refactor "disable_stdin" and "read_from_stdin"Ævar Arnfjörð Bjarmason, Jul 9, 2021
  26. Junio C HamanoJul 9, 2021
  27. 4/5 pack-objects.c: do stdin parsing via revision.c's APIÆvar Arnfjörð Bjarmason, Jul 9, 2021
  28. 5/5 pack-objects.c: make use of REV_INFO_STDIN_LINE_PROCESSÆvar Arnfjörð Bjarmason, Jul 9, 2021
  29. 3/5 revision.[ch]: add a "handle_stdin_line" APIÆvar Arnfjörð Bjarmason, Jul 9, 2021
  30. 0/5 add --stdin parsing API, use in pack-objectsÆvar Arnfjörð Bjarmason, Jul 26, 2021
  31. 1/5 upload-pack: run is_repository_shallow() before setup_revisions()Ævar Arnfjörð Bjarmason, Jul 26, 2021
  32. 5/5 pack-objects.c: make use of REV_INFO_STDIN_LINE_PROCESSÆvar Arnfjörð Bjarmason, Jul 26, 2021
  33. 2/5 revision.h: refactor "disable_stdin" and "read_from_stdin"Ævar Arnfjörð Bjarmason, Jul 26, 2021
  34. 4/5 pack-objects.c: do stdin parsing via revision.c's APIÆvar Arnfjörð Bjarmason, Jul 26, 2021
  35. 3/5 revision.[ch]: add a "handle_stdin_line" APIÆvar Arnfjörð Bjarmason, Jul 26, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.