{"thread":{"id":"27770","subject":"pull from stdin","startedAt":"2011-07-07T15:23:04Z","lastAt":"2011-07-07T19:28:13Z","messageCount":2,"participants":["miket99@safe-mail.net","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"170978","messageId":"N1B-u7I8PJ0byN@Safe-mail.net","threadId":"27770","inReplyTo":null,"subject":"pull from stdin","fromName":"","fromEmail":"miket99@safe-mail.net","sentAt":"2011-07-07T15:23:04Z","receivedAt":"2011-07-07T15:23:04Z","isPatch":false,"sender":{"key":"miket99@safe-mail.net","avatar":null},"body":"Hello,\n\nI am using a rather complicated distributed workflow to keep various git repositories in sync. Basically I am creating bundles, pushing them to a server, and pull them again using a special application which output the bundle content to stdin. Unfortunately git-fetch and friends do not like /dev/stdin as input. Is there any way to pass the bundle contents via stdin to git?\n\nMinimal sample:\n~$ mkdir test\n~$ cd test\n~/test$ git init\nInitialized empty Git repository in /home/test/test/.git/\n~/test$ echo a > a\n~/test$ git add -A\n~/test$ git commit -m test\n[master (root-commit) 4ed639a] test\n 1 files changed, 1 insertions(+), 0 deletions(-)\n create mode 100644 a\n~/test$ git bundle create b --all\nCounting objects: 3, done.\nWriting objects: 100% (3/3), 193 bytes, done.\nTotal 3 (delta 0), reused 0 (delta 0)\n~/test$ cat b | git pull -- /dev/stdin\nfatal: '/dev/stdin' does not appear to be a git repository\nfatal: The remote end hung up unexpectedly\n"},{"id":"170989","messageId":"20110707192813.GE12044@sigill.intra.peff.net","threadId":"27770","inReplyTo":"N1B-u7I8PJ0byN@Safe-mail.net","subject":"Re: pull from stdin","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-07-07T19:28:13Z","receivedAt":"2011-07-07T19:28:13Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jul 07, 2011 at 11:23:04AM -0400, miket99@Safe-mail.net wrote:\n\n> I am using a rather complicated distributed workflow to keep various\n> git repositories in sync. Basically I am creating bundles, pushing\n> them to a server, and pull them again using a special application\n> which output the bundle content to stdin. Unfortunately git-fetch and\n> friends do not like /dev/stdin as input. Is there any way to pass the\n> bundle contents via stdin to git?\n> [...]\n> ~/test$ cat b | git pull -- /dev/stdin\n> fatal: '/dev/stdin' does not appear to be a git repository\n> fatal: The remote end hung up unexpectedly\n\nI think the problem is that \"git fetch\" tests for a bundle by checking\nwhether the argument is a regular file, which /dev/stdin is not. We\ncould perhaps fix that, but I think it still wouldn't work. The\nbundle-reading code calls lseek, and your pipe will not be seekable.\n\nSo this works:\n\n  $ git bundle unbundle /dev/stdin <b\n  1c0138bbb920cdbf8e80bea38c4f77b0d01c3763 refs/heads/master\n  1c0138bbb920cdbf8e80bea38c4f77b0d01c3763 HEAD\n\nbut this doesn't:\n\n  $ cat b | git bundle unbundle /dev/stdin\n  fatal: early EOF\n  error: index-pack died\n\nI don't think the problem is in the bundle format. I think it is simply\nan issue that we read the bundle header in one process via buffered I/O,\nand then use seek to pass the rest on to index-pack in another process.\nSo you could solve it by either:\n\n  1. Using unbuffered I/O and reading a character at a time from the\n     bundle when the input is not seekable. This will involve many more\n     syscalls, of course, but we would only have to do it for the list\n     of refs, not for the actual pack data.\n\n  2. Instead of passing the descriptor to index-pack, open a pipe to\n     index-pack and pass the data through the original process. For\n     the sake of efficiency, we could enable this only when the input\n     isn't seekable.\n\n-Peff\n"}]}