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

`git bundle create -` may not write to `stdout`

From
MHMichael Henry <git@drmikehenry.com>
Date
Feb 25, 2023, 12:58 UTC
Message-ID
<80beb487-cd93-06ed-88cf-87a96a829ff6@drmikehenry.com>
All,
I've encountered some unexpected behavior with `git bundle create -`.

Summary =======

Using `-` to create a bundle file on `stdout` works only when the current working directory is at the root of the repository; when in a subdirectory, `-` is treated as the name of a file instead.

What did you do before the bug happened? (Steps to reproduce your issue) ========================================================================

The below steps are using Git's `next` branch (cloned today) to demonstrate.
- Bundle creation to `stdout` works in the repository root:
      $ ./git bundle create -q - HEAD ^HEAD~ > head.bundle
      $ ./git bundle list-heads head.bundle
      a93b1961839a603a8ac2df08fd80c48bd140fe02 HEAD
- From the `Documentation` directory, `-` is treated like a filename:
      $ cd Documentation/
      $ ../git bundle create -q - HEAD ^HEAD~ > head.bundle
      $ ../git bundle list-heads head.bundle
      error: 'Documentation/head.bundle' does not look like a v2 or v3
bundle file
      $ ../git bundle list-heads ./-
      a93b1961839a603a8ac2df08fd80c48bd140fe02 HEAD
- Consider this patch to display the bundle file path:
      diff --git a/bundle.c b/bundle.c
      index 6ab6cd7378..05be3ed520 100644
      --- a/bundle.c
      +++ b/bundle.c
      @@ -524,6 +524,7 @@ int create_bundle(struct repository *r, const
char *path,
                      goto err;
              }
       
      +    fprintf(stderr, "create_bundle(): path=\"%s\"\n", path);
              bundle_to_stdout = !strcmp(path, "-");
              if (bundle_to_stdout)
                      bundle_fd = 1;
  When in a subdirectory, it seems that the current working directory is
being
  changed to the root, and the bundle file's path is being adjusted
accordingly:
      $ ../git bundle create -q - HEAD ^HEAD~ > head.bundle
      create_bundle(): path="Documentation/-"

What did you expect to happen? (Expected behavior) ==================================================

I expected `-` to be treated as `stdout` in subdirectories as well as in the repository root directory.

What happened instead? (Actual behavior) ========================================

When in a subdirectory `some/subdir`, `-` is converted to `some/subdir/-` and treated like a regular file instead of `stdout`.

What's different between what you expected and what actually happened? ======================================================================

I expected the bundle file to appear on `stdout`; instead, it was written to a file named `-` in the current directory.

Anything else you want to add: ==============================

It's unclear to me whether creating a bundle file to `stdout` is documented behavior.  I can't find direct mention of it in `Documentation/git-bundle.txt`, though that document does have this text:

    --all-progress::
            When --stdout is specified then progress report is
            displayed during the object count and compression phases
            but inhibited during the write-out phase. The reason is
            that in some cases the output stream is directly linked
            to another command which may wish to display progress
            status of its own as it processes incoming pack data.
            This flag is like --progress except that it forces progress
            report for the write-out phase as well even if --stdout is
            used.

The switch `--stdout` doesn't seem to exist, though; perhaps it was a past feature that got removed but the documentation hung around?

I find the ability to create a bundle to `stdout` a useful feature, though a niche use case: I'm post-processing the bundle file's contents before writing to a file, and bundling to `stdout` saves the creation of a potentially large temporary file.  I'm currently using the temporary file approach, however, because I'm not sure that bundling to `stdout` is intended as a supported feature; I'll leave that for you to determine.

Thanks, Michael Henry

==============================================================================

[System Info] git version: git version 2.40.0.rc0.245.ga93b196183 cpu: x86_64 built from commit: a93b1961839a603a8ac2df08fd80c48bd140fe02 sizeof-long: 8 sizeof-size_t: 8 shell-path: /bin/sh uname: Linux 5.15.0-52-generic #58-Ubuntu SMP Thu Oct 13 08:03:55 UTC 2022 x86_64 compiler info: gnuc: 11.3 libc info: glibc: 2.35 $SHELL (typically, interactive shell): /bin/bash

[Enabled Hooks]
Next: Jeff King
Message 1 of 24 in “`git bundle create -` may not write to `stdout`”
  1. Michael HenryFeb 25, 2023
  2. Jeff KingFeb 26, 2023
  3. Junio C HamanoMar 3, 2023
  4. Jeff KingMar 3, 2023
  5. Junio C HamanoMar 3, 2023
  6. Jeff KingMar 4, 2023
  7. Jeff KingMar 4, 2023
  8. 0/5 handling "-" as stdin/stdout in git bundleJeff King, Mar 4, 2023
  9. 1/5 bundle: let "-" mean stdin for reading operationsJeff King, Mar 4, 2023
  10. 2/5 bundle: document handling of "-" as stdinJeff King, Mar 4, 2023
  11. 3/5 bundle: don't blindly apply prefix_filename() to "-"Jeff King, Mar 4, 2023
  12. 4/5 parse-options: consistently allocate memory in fix_filename()Jeff King, Mar 4, 2023
  13. 5/5 parse-options: use prefix_filename_except_for_dash() helperJeff King, Mar 4, 2023
  14. bundle: turn on --all-progress-implied by defaultJeff King, Mar 4, 2023
  15. Robin H. JohnsonMar 6, 2023
  16. Jeff KingMar 6, 2023
  17. Jeff KingMar 6, 2023
  18. Junio C HamanoMar 6, 2023
  19. Junio C HamanoMar 6, 2023
  20. Junio C HamanoMar 4, 2023
  21. Jeff KingMar 4, 2023
  22. Michael HenryMar 3, 2023
  23. Jeff KingMar 4, 2023
  24. Michael HenryMar 4, 2023

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.