+
Skip to content

cat-file: force flush of stdout on empty string #1124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 312 commits into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
312 commits
Select commit Hold shift + click to select a range
2440a8a
Merge branch 'ps/fetch-omit-formatting-under-quiet' into next
gitster Sep 2, 2021
66b0f85
Merge branch 'tb/add-objects-in-unpacked-packs-simplify' into next
gitster Sep 2, 2021
73719be
Merge branch 'es/walken-tutorial-fix' into next
gitster Sep 2, 2021
5ee2615
Merge branch 'jh/sparse-index-resize-fix' into next
gitster Sep 2, 2021
5378ce3
Merge branch 'sg/set-ceiling-during-tests' into next
gitster Sep 2, 2021
3052b89
Merge branch 'rs/more-fspathcmp' into next
gitster Sep 2, 2021
3a60892
Merge branch 'mh/send-email-reset-in-reply-to' into next
gitster Sep 3, 2021
2254ea1
Merge branch 'ab/commit-graph-usage' into next
gitster Sep 3, 2021
6d47f59
Merge branch 'ba/object-info' into next
gitster Sep 3, 2021
15ce1ab
Merge branch 'tk/fast-export-anonymized-tag-fix' into next
gitster Sep 3, 2021
5c9eb65
Merge branch 'uk/userdiff-php-enum' into next
gitster Sep 3, 2021
24c51e3
Merge branch 'ab/gc-log-rephrase' into next
gitster Sep 3, 2021
348fe07
Merge branch 'ab/mailmap-leakfix' into next
gitster Sep 3, 2021
eed4e81
Merge branch 'fs/ssh-signing' into next
gitster Sep 3, 2021
9787178
Merge branch 'mk/clone-recurse-submodules' into next
gitster Sep 3, 2021
0045df3
Merge branch 'ab/retire-advice-config' into next
gitster Sep 3, 2021
a47f44c
Merge branch 'cb/remote-ndebug-fix' into next
gitster Sep 3, 2021
be952f7
Sync with master
gitster Sep 3, 2021
193ad0f
Sync with master
gitster Sep 8, 2021
56fe25c
Merge branch 'jk/log-warn-on-bogus-encoding' into next
gitster Sep 8, 2021
047750a
Merge branch 'rs/show-branch-simplify' into next
gitster Sep 8, 2021
02899d8
Merge branch 'rs/archive-use-object-id' into next
gitster Sep 8, 2021
99f8651
Merge branch 'ps/fetch-optim' into next
gitster Sep 8, 2021
f2b7415
Merge branch 'tb/multi-pack-bitmaps' into next
gitster Sep 8, 2021
ca17912
Merge branch 'so/diff-index-regression-fix' into next
gitster Sep 8, 2021
c2000e9
Merge branch 'ab/send-email-config-fix' into next
gitster Sep 8, 2021
4fddb38
Merge branch 'ab/no-more-check-bindir' into next
gitster Sep 8, 2021
5ea3df2
Merge branch 'bs/doc-bugreport-outdir' into next
gitster Sep 8, 2021
a51cf7e
Merge branch 'gh/gitweb-branch-sort' into next
gitster Sep 8, 2021
67612d0
Merge branch 'jt/grep-wo-submodule-odb-as-alternate' into next
gitster Sep 8, 2021
d6ba073
Merge branch 'jc/trivial-threeway-binary-merge' into next
gitster Sep 8, 2021
c47fb2d
Merge branch 'cb/ci-build-pedantic' into next
gitster Sep 8, 2021
e9e130d
Merge branch 'ab/help-autocorrect-prompt' into next
gitster Sep 8, 2021
6fa5d96
Merge branch 'pb/test-use-user-env' into next
gitster Sep 8, 2021
40cfa71
Merge branch 'bs/install-strip' into next
gitster Sep 8, 2021
1972c59
Merge branch 'ab/reverse-midx-optim' into next
gitster Sep 8, 2021
14f0dd5
Merge branch 'ab/tr2-leaks-and-fixes' into next
gitster Sep 10, 2021
b27d720
Merge branch 'lh/systemd-timers' into next
gitster Sep 10, 2021
c31d871
Merge branch 'jv/pkt-line-batch' into next
gitster Sep 10, 2021
21b773f
Merge branch 'dt/submodule-diff-fixes' into next
gitster Sep 10, 2021
b50c37a
Merge branch 'ab/progress-users-adjust-counters' into next
gitster Sep 10, 2021
4ae19a5
Merge branch 'ps/update-ref-batch-flush' into next
gitster Sep 10, 2021
b8df102
Merge branch 'cb/pedantic-build-for-developers' into next
gitster Sep 10, 2021
e8bac5f
Merge branch 'rs/range-diff-avoid-segfault-with-I' into next
gitster Sep 10, 2021
a5221ea
Merge branch 'jc/prefix-filename-allocates' into next
gitster Sep 10, 2021
f645ffd
Merge branch 'js/retire-preserve-merges' into next
gitster Sep 10, 2021
7b39c39
Merge branch 'tb/pack-finalize-ordering' into next
gitster Sep 10, 2021
71559ef
Merge branch 'tb/multi-pack-bitmaps' into next
gitster Sep 10, 2021
dc202c5
Sync with master
gitster Sep 10, 2021
5e29049
Revert "Merge branch 'fs/ssh-signing' into next"
gitster Sep 10, 2021
d7bacb3
Merge branch 'ab/unbundle-progress' into next
gitster Sep 13, 2021
fdabb4f
Merge branch 'ar/submodule-add-config' into next
gitster Sep 13, 2021
efebf6d
Merge branch 'ar/submodule-add-more' into next
gitster Sep 13, 2021
ea87ede
Merge branch 'ab/serve-cleanup' into next
gitster Sep 13, 2021
79584f3
Merge branch 'ab/make-tags-cleanup' into next
gitster Sep 13, 2021
fbe4177
Merge branch 'ar/submodule-run-update-procedure' into next
gitster Sep 13, 2021
6993c73
Merge branch 'ds/sparse-index-ignored-files' into next
gitster Sep 13, 2021
1535fa2
Merge branch 'ds/mergies-with-sparse-index' into next
gitster Sep 13, 2021
97c3614
Merge branch 'js/run-command-close-packs' into next
gitster Sep 13, 2021
544b481
Merge branch 'rs/setup-use-xopen-and-xdup' into next
gitster Sep 13, 2021
a3ea25c
Merge branch 'rs/no-mode-to-open-when-appending' into next
gitster Sep 13, 2021
22d4bfa
Merge branch 'jk/t5562-racefix' into next
gitster Sep 13, 2021
11f3d2d
Merge branch 'en/am-abort-fix' into next
gitster Sep 14, 2021
80e72f5
Merge branch 'rs/packfile-bad-object-list-in-oidset' into next
gitster Sep 14, 2021
3bd0662
Merge branch 'rs/drop-core-compression-vars' into next
gitster Sep 14, 2021
e078585
Merge branch 'jk/strvec-typefix' into next
gitster Sep 14, 2021
cf38118
Merge branch 'en/tests-cleanup-leftover-untracked' into next
gitster Sep 14, 2021
086310d
Merge branch 'ab/test-tool-run-command-cleanup' into next
gitster Sep 14, 2021
14f69ed
Merge branch 'ab/gc-remove-unused-call' into next
gitster Sep 14, 2021
9174cd6
Merge branch 'jk/http-server-protocol-versions' into next
gitster Sep 14, 2021
bddbd5c
Merge branch 'po/git-config-doc-mentions-help-c' into next
gitster Sep 14, 2021
39a6914
Merge branch 'ps/update-ref-batch-flush' into next
gitster Sep 15, 2021
16aaab3
Merge branch 'ab/http-drop-old-curl-plus' into next
gitster Sep 15, 2021
14e6b0f
Merge branch 'ab/unused-script-helpers' into next
gitster Sep 15, 2021
2af7f04
Merge branch 'mr/bisect-in-c-4' into next
gitster Sep 15, 2021
0bd7ce1
Merge branch 'ab/retire-option-argument' into next
gitster Sep 15, 2021
46640ce
Sync with master
gitster Sep 15, 2021
05cdcab
Merge branch 'js/pull-release-packs-before-fetching' into next
gitster Sep 13, 2021
e292133
Merge branch 'cb/unix-sockets-with-windows' into next
gitster Sep 16, 2021
292dd71
Merge branch 'ma/help-w-check-for-requested-page' into next
gitster Sep 16, 2021
54a6a3f
Merge branch 'ma/doc-git-version' into next
gitster Sep 16, 2021
40cfe41
Merge branch 'jk/reduce-malloc-in-v2-servers' into next
gitster Sep 16, 2021
c658fbf
Merge branch 'jt/submodule-name-to-gitdir' into next
gitster Sep 16, 2021
2eecae2
Merge branch 'cb/plug-leaks-in-alloca-emu-users' into next
gitster Sep 16, 2021
b4797ad
Merge branch 'kz/revindex-comment-fix' into next
gitster Sep 16, 2021
186eaaa
Merge branch 'rs/use-xopen-in-index-pack' into next
gitster Sep 16, 2021
513c11f
Merge branch 'en/stash-df-fix' into next
gitster Sep 20, 2021
7873b31
Merge branch 'cb/unicode-14' into next
gitster Sep 20, 2021
48648da
Merge branch 'en/typofixes' into next
gitster Sep 20, 2021
93c93b8
Merge branch 'jk/clone-unborn-head-in-bare' into next
gitster Sep 20, 2021
d22421f
Sync with master
gitster Sep 20, 2021
b2d7f5e
Merge branch 'jx/ci-l10n' into next
gitster Sep 23, 2021
98f5f3f
Merge branch 'cb/cvsserver' into next
gitster Sep 23, 2021
eb56685
Merge branch 'ab/refs-files-cleanup' into next
gitster Sep 23, 2021
502e6b6
Merge branch 'hn/refs-errno-cleanup' into next
gitster Sep 23, 2021
4c38ced
Sync with master
gitster Sep 23, 2021
4d84344
Merge branch 'jt/add-submodule-odb-clean-up' into next
gitster Sep 28, 2021
980add2
Merge branch 'pw/rebase-of-a-tag-fix' into next
gitster Sep 28, 2021
f021339
Merge branch 'tb/commit-graph-usage-fix' into next
gitster Sep 28, 2021
e2170ed
Merge branch 'da/difftool-dir-diff-symlink-fix' into next
gitster Sep 28, 2021
1660a6b
Merge branch 'jk/grep-haystack-is-read-only' into next
gitster Sep 28, 2021
d27c228
Merge branch 'bs/ls-files-opt-help-text-update' into next
gitster Sep 28, 2021
ef4570a
Merge branch 'jk/http-redact-fix' into next
gitster Sep 28, 2021
43d70c3
Merge branch 'ab/repo-settings-cleanup' into next
gitster Sep 28, 2021
18a2148
Merge branch 'ds/perf-test-built-path-fix' into next
gitster Sep 28, 2021
20483ad
Merge branch 'ab/make-clean-depend-dirs' into next
gitster Sep 28, 2021
f2cbe59
Merge branch 'ew/midx-doc-update' into next
gitster Sep 28, 2021
532f2aa
Merge branch 'ab/auto-depend-with-pedantic' into next
gitster Sep 28, 2021
8251d26
Merge branch 'ab/bundle-remove-verbose-option' into next
gitster Sep 28, 2021
c67d5e3
Merge branch 'pw/rebase-reread-todo-after-editing' into next
gitster Sep 28, 2021
b14502f
Merge branch 'rs/close-pack-leakfix' into next
gitster Sep 28, 2021
4870655
Sync with master
gitster Sep 28, 2021
24732fc
Merge branch 'tb/midx-write-propagate-namehash' into next
gitster Sep 29, 2021
b7dea55
Merge branch 'gc/doc-first-contribution-reroll' into next
gitster Sep 29, 2021
22d485e
Merge branch 'bs/difftool-msg-tweak' into next
gitster Sep 29, 2021
661ae75
Merge branch 'sg/test-split-index-fix' into next
gitster Sep 29, 2021
49181ea
Merge branch 'ws/refer-to-forkpoint-config-in-rebase-doc' into next
gitster Sep 29, 2021
b343975
Merge branch 'ab/make-compdb-fix' into next
gitster Sep 29, 2021
93a4572
Merge branch 'ah/connect-parse-feature-v0-fix' into next
gitster Sep 29, 2021
26802e5
Merge branch 'js/win-lazyload-buildfix' into next
gitster Oct 4, 2021
cd67328
Merge branch 'ab/http-pinned-public-key-mismatch' into next
gitster Oct 4, 2021
8c2cb6a
Merge branch 'jk/ref-paranoia' into next
gitster Oct 4, 2021
a130199
Merge branch 'os/status-docfix' into next
gitster Oct 4, 2021
f91e74f
Merge branch 'ab/retire-refs-unused-funcs' into next
gitster Oct 4, 2021
fc7a0a5
Merge branch 'ab/retire-git-config-key-is-valid' into next
gitster Oct 4, 2021
4834949
Merge branch 'ab/retire-string-list-init' into next
gitster Oct 4, 2021
dcd62a3
Merge branch 'ab/sanitize-leak-ci' into next
gitster Oct 4, 2021
8183460
Merge branch 'lh/systemd-timers' into next
gitster Oct 4, 2021
179f652
Merge branch 'ab/designated-initializers' into next
gitster Oct 4, 2021
3ba0335
Merge branch 'da/difftool' into next
gitster Oct 4, 2021
29a6725
Merge branch 'rs/mergesort' into next
gitster Oct 4, 2021
a49287e
Merge branch 'ab/retire-decl-of-missing-unused-funcs' into next
gitster Oct 4, 2021
a309979
Sync with master
gitster Oct 4, 2021
03b6d62
tmp-objdir: new API for creating temporary writable databases
neerajsi-msft Oct 4, 2021
50741b1
tmp-objdir: disable ref updates when replacing the primary odb
neerajsi-msft Oct 4, 2021
80a9cda
Merge branch 'ds/add-rm-with-sparse-index' into next
gitster Oct 6, 2021
1950944
Merge branch 'mt/grep-submodule-textconv' into next
gitster Oct 6, 2021
fc4e387
Merge branch 'en/removing-untracked-fixes' into next
gitster Oct 6, 2021
e8fa261
Merge branch 'ab/lib-subtest' into next
gitster Oct 6, 2021
d05325e
Merge branch 'ab/config-based-hooks-1' into next
gitster Oct 6, 2021
c13c142
Merge branch 'mr/bisect-in-c-4' into next
gitster Oct 6, 2021
021f633
Merge branch 'jh/builtin-fsmonitor-part1' into next
gitster Oct 6, 2021
bf9538c
Merge branch 'ab/help-config-vars' into next
gitster Oct 6, 2021
e22da7e
Merge branch 'ab/align-parse-options-help' into next
gitster Oct 6, 2021
10e3c31
Merge branch 'ab/make-sparse-for-real' into next
gitster Oct 6, 2021
ccdd5aa
Merge branch 'tb/repack-write-midx' into next
gitster Oct 6, 2021
688dc71
Merge branch 'rs/p3400-lose-tac' into next
gitster Oct 6, 2021
619a7db
Merge branch 'tb/aggregate-ignore-leading-whitespaces' into next
gitster Oct 6, 2021
4de6571
Merge branch 'ja/doc-status-types-and-copies' into next
gitster Oct 6, 2021
6e70778
Sync with 'master'
gitster Oct 6, 2021
0388352
Merge branch 'ns/tmp-objdir' into ns/batched-fsync
gitster Oct 8, 2021
4780496
bulk-checkin: rename 'state' variable and separate 'plugged' boolean
neerajsi-msft Oct 4, 2021
ec983eb
core.fsyncobjectfiles: batched disk flushes
neerajsi-msft Oct 4, 2021
d11da09
core.fsyncobjectfiles: add windows support for batch mode
neerajsi-msft Oct 4, 2021
085d914
update-index: use the bulk-checkin infrastructure
neerajsi-msft Oct 4, 2021
2881e3e
unpack-objects: use the bulk-checkin infrastructure
neerajsi-msft Oct 4, 2021
e058d35
core.fsyncobjectfiles: tests for batch mode
neerajsi-msft Oct 4, 2021
e2d7493
core.fsyncobjectfiles: performance tests for add and stash
neerajsi-msft Oct 4, 2021
2e83706
Merge branch 'rs/mergesort' into next
gitster Oct 8, 2021
ff8fec2
Merge branch 'tb/repack-write-midx' into next
gitster Oct 8, 2021
b456b95
Merge branch 'fs/ssh-signing' into next
gitster Oct 11, 2021
9b9836c
Merge branch 'ab/designated-initializers-more' into next
gitster Oct 11, 2021
962bb3e
Merge branch 'cm/save-restore-terminal' into next
gitster Oct 11, 2021
9415f7c
Merge branch 'jk/cat-file-batch-all-wo-replace' into next
gitster Oct 11, 2021
2f90c87
Merge branch 'pw/sparse-cache-tree-verify-fix' into next
gitster Oct 11, 2021
6b43588
Merge branch 'rs/make-verify-path-really-verify-again' into next
gitster Oct 11, 2021
a2cb776
Merge branch 'bs/doc-blame-color-lines' into next
gitster Oct 11, 2021
b88fcb3
Sync with master
gitster Oct 11, 2021
ecbd560
Sync with master
gitster Oct 13, 2021
3047fe5
Merge branch 'js/windows-ci-path-fix' into next
gitster Oct 14, 2021
dee8053
Merge branch 'tz/doc-link-to-bundle-format-fix' into next
gitster Oct 14, 2021
10edc78
Merge branch 'ab/fsck-unexpected-type' into next
gitster Oct 14, 2021
473a261
Merge branch 'jh/perf-remove-test-times' into next
gitster Oct 14, 2021
bb54827
Merge branch 'ab/unpack-trees-leakfix' into next
gitster Oct 14, 2021
ae49a2c
Merge branch 'jt/no-abuse-alternate-odb-for-submodules' into next
gitster Oct 14, 2021
e0dd4b9
Merge branch 'rs/disable-gc-during-perf-tests' into next
gitster Oct 14, 2021
a42928e
Merge branch 'rs/add-dry-run-without-objects' into next
gitster Oct 14, 2021
08c52f5
Merge branch 'ab/fix-commit-error-message-upon-unwritable-object-stor…
gitster Oct 14, 2021
97735c6
Merge branch 'fs/ssh-signing-fix' into next
gitster Oct 14, 2021
3337906
Sync with master
gitster Oct 14, 2021
0186a64
Merge branch 'pw/sparse-cache-tree-verify-fix' into next
gitster Oct 18, 2021
5ffa706
Merge branch 'fs/ssh-signing-fix' into next
gitster Oct 18, 2021
0dd8a08
Merge branch 'da/mergetools-special-case-xxdiff-exit-128' into next
gitster Oct 18, 2021
fea77f6
Merge branch 'js/userdiff-cpp' into next
gitster Oct 18, 2021
305d339
Merge branch 'ab/parse-options-cleanup' into next
gitster Oct 18, 2021
c522807
Merge branch 'ab/mark-leak-free-tests' into next
gitster Oct 18, 2021
fe798f7
Merge branch 'ab/mark-leak-free-tests-more' into next
gitster Oct 18, 2021
99b71c0
Merge branch 'jc/doc-commit-header-continuation-line' into next
gitster Oct 18, 2021
6fdb439
Merge branch 'ab/test-cleanly-recreate-trash-directory' into next
gitster Oct 18, 2021
52e552c
Merge branch 'tb/fix-midx-rename-while-mapped' into next
gitster Oct 18, 2021
79b0766
Merge branch 'ab/pkt-line-cleanup' into next
gitster Oct 18, 2021
22ebb32
Merge branch 'ab/fix-make-lint-docs' into next
gitster Oct 18, 2021
5229c5d
Merge branch 'ab/test-lib-diff-cleanup' into next
gitster Oct 18, 2021
d3b4e01
Sync with master
gitster Oct 18, 2021
4da10a5
Merge branch 'bs/doc-blame-color-lines' into next
gitster Oct 23, 2021
f7a8389
Merge branch 'ab/make-sparse-for-real' into next
gitster Oct 23, 2021
4a16ebd
Merge branch 'ab/test-bail' into next
gitster Oct 23, 2021
358d376
Merge branch 'ns/tmp-objdir' into next
gitster Oct 23, 2021
9704ff2
Merge branch 'jk/http-push-status-fix' into next
gitster Oct 23, 2021
8066971
Merge branch 'ab/ref-filter-leakfix' into next
gitster Oct 23, 2021
6be5d7b
Merge branch 'ab/plug-handle-path-exclude-leak' into next
gitster Oct 23, 2021
9c04a95
Merge branch 'ab/plug-random-leaks' into next
gitster Oct 23, 2021
f1fede7
Merge branch 'ab/sh-retire-rebase-preserve-merges' into next
gitster Oct 23, 2021
2158813
Merge branch 'js/userdiff-cpp' into next
gitster Oct 25, 2021
e45c907
Merge branch 'ns/batched-fsync' into next
gitster Oct 25, 2021
f66ca39
Merge branch 'jk/loosen-urlmatch' into next
gitster Oct 25, 2021
e3edea3
Merge branch 'hm/paint-hits-in-log-grep' into next
gitster Oct 25, 2021
5ed4266
Merge branch 'ab/ignore-replace-while-working-on-commit-graph' into next
gitster Oct 25, 2021
68b88e3
Merge branch 'so/stash-staged' into next
gitster Oct 25, 2021
3d38c09
Merge branch 'gc/use-repo-settings' into next
gitster Oct 25, 2021
377e759
Merge branch 'ks/submodule-add-message-fix' into next
gitster Oct 25, 2021
9360d86
Merge branch 'bs/archive-doc-compression-level' into next
gitster Oct 25, 2021
7ff05e8
Merge branch 'js/expand-runtime-prefix' into next
gitster Oct 25, 2021
9f74afe
Merge branch 'ma/doc-git-version' into next
gitster Oct 25, 2021
c40950c
Sync with master
gitster Oct 25, 2021
cb443df
fixup! tmp-objdir: new API for creating temporary writable databases
neerajsi-msft Oct 26, 2021
a082404
fixup! tmp-objdir: new API for creating temporary writable databases
neerajsi-msft Oct 26, 2021
ece0c98
Merge branch 'ns/tmp-objdir' into ns/batched-fsync
gitster Oct 28, 2021
04f0be2
Merge branch 'ab/fix-make-lint-docs' into next
gitster Oct 28, 2021
001a18c
Merge branch 'ns/tmp-objdir' into next
gitster Oct 28, 2021
eb2a3af
Merge branch 'ns/batched-fsync' into next
gitster Oct 28, 2021
4fc7c47
Merge branch 'ks/submodule-add-message-fix' into next
gitster Oct 28, 2021
020dc42
Merge branch 'sg/sparse-index-not-that-common-a-command' into next
gitster Oct 28, 2021
9920009
Merge branch 'ma/doc-folder-to-directory' into next
gitster Oct 28, 2021
32c2273
Merge branch 'jc/doc-format-patch-clarify-auto-base' into next
gitster Oct 28, 2021
efc3d30
Merge branch 'jc/branch-copy-doc' into next
gitster Oct 28, 2021
a6ec5e5
Merge branch 'ab/unbundle-progress' into next
gitster Oct 28, 2021
1a01b88
Merge branch 'ow/stash-count-in-status-porcelain-output' into next
gitster Oct 29, 2021
3f57147
Merge branch 'ab/refs-errno-cleanup' into next
gitster Oct 29, 2021
67ff1a5
Merge branch 'jc/tutorial-format-patch-base' into next
gitster Oct 29, 2021
50335e8
Merge branch 'so/stash-staged' into next
gitster Oct 29, 2021
ad4753e
Merge branch 'jc/fix-pull-ff-only-when-already-up-to-date' into next
gitster Oct 29, 2021
e3ec6e8
Merge branch 'jc/fix-ref-sorting-parse' into next
gitster Oct 29, 2021
b3d2360
Merge branch 'ab/test-lib' into next
gitster Oct 29, 2021
7fa61a8
Merge branch 'jk/log-warn-on-bogus-encoding' into next
gitster Oct 29, 2021
3004dd0
Merge branch 'cm/drop-xunsetenv' into next
gitster Oct 29, 2021
06f21a4
Merge branch 'mt/fix-add-rm-with-sparse-index' into next
gitster Oct 29, 2021
78decd1
Merge branch 're/completion-fix-test-equality' into next
gitster Oct 29, 2021
81b53c2
Sync with Git 2.34-rc0
gitster Oct 29, 2021
f50e78f
Merge branch 'rs/ssh-signing-fix' into next
gitster Nov 2, 2021
f27cf92
Merge branch 'jx/message-fixes' into next
gitster Nov 2, 2021
74677b0
Merge branch 'ar/fix-git-pull-no-verify' into next
gitster Nov 2, 2021
f6809a9
Merge branch 'ar/no-verify-doc' into next
gitster Nov 2, 2021
a11670a
Merge branch 'jc/unsetenv-returns-an-int' into next
gitster Nov 2, 2021
7104356
Merge branch 'tp/send-email-completion' into next
gitster Nov 2, 2021
47d2188
Merge branch 'tb/plug-pack-bitmap-leaks' into next
gitster Nov 2, 2021
f45b338
Merge branch 'rd/http-backend-code-simplification' into next
gitster Nov 2, 2021
6d82a21
Sync with master
gitster Nov 2, 2021
2d687ba
cat-file: force flush of stdout on empty string
john-cai Nov 5, 2021
18d6c28
docs: update behavior of git-cat-file --buffer
john-cai Nov 5, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 28 additions & 13 deletions Documentation/MyFirstContribution.txt
Original file line number Diff line number Diff line change
Expand Up @@ -905,19 +905,34 @@ Sending emails with Git is a two-part process; before you can prepare the emails
themselves, you'll need to prepare the patches. Luckily, this is pretty simple:

----
$ git format-patch --cover-letter -o psuh/ master..psuh
----

The `--cover-letter` parameter tells `format-patch` to create a cover letter
template for you. You will need to fill in the template before you're ready
to send - but for now, the template will be next to your other patches.

The `-o psuh/` parameter tells `format-patch` to place the patch files into a
directory. This is useful because `git send-email` can take a directory and
send out all the patches from there.

`master..psuh` tells `format-patch` to generate patches for the difference
between `master` and `psuh`. It will make one patch file per commit. After you
$ git format-patch --cover-letter -o psuh/ --base=auto psuh@{u}..psuh
----

. The `--cover-letter` option tells `format-patch` to create a
cover letter template for you. You will need to fill in the
template before you're ready to send - but for now, the template
will be next to your other patches.

. The `-o psuh/` option tells `format-patch` to place the patch
files into a directory. This is useful because `git send-email`
can take a directory and send out all the patches from there.

. The `--base=auto` option tells the command to record the "base
commit", on which the recipient is expected to apply the patch
series. The `auto` value will cause `format-patch` to compute
the base commit automatically, which is the merge base of tip
commit of the remote-tracking branch and the specified revision
range.

. The `psuh@{u}..psuh` option tells `format-patch` to generate
patches for the commits you created on the `psuh` branch since it
forked from its upstream (which is `origin/master` if you
followed the example in the "Set up your workspace" section). If
you are already on the `psuh` branch, you can just say `@{u}`,
which means "commits on the current branch since it forked from
its upstream", which is the same thing.

The command will make one patch file per commit. After you
run, you can go have a look at each of the patches with your favorite text
editor and make sure everything looks alright; however, it's not recommended to
make code fixups via the patch file. It's a better idea to make the change the
Expand Down
29 changes: 23 additions & 6 deletions Documentation/config/core.txt
Original file line number Diff line number Diff line change
Expand Up @@ -548,12 +548,29 @@ core.whitespace::
errors. The default tab width is 8. Allowed values are 1 to 63.

core.fsyncObjectFiles::
This boolean will enable 'fsync()' when writing object files.
+
This is a total waste of time and effort on a filesystem that orders
data writes properly, but can be useful for filesystems that do not use
journalling (traditional UNIX filesystems) or that only journal metadata
and not file contents (OS X's HFS+, or Linux ext3 with "data=writeback").
A value indicating the level of effort Git will expend in
trying to make objects added to the repo durable in the event
of an unclean system shutdown. This setting currently only
controls loose objects in the object store, so updates to any
refs or the index may not be equally durable.
+
* `false` allows data to remain in file system caches according to
operating system policy, whence it may be lost if the system loses power
or crashes.
* `true` triggers a data integrity flush for each loose object added to the
object store. This is the safest setting that is likely to ensure durability
across all operating systems and file systems that honor the 'fsync' system
call. However, this setting comes with a significant performance cost on
common hardware. Git does not currently fsync parent directories for
newly-added files, so some filesystems may still allow data to be lost on
system crash.
* `batch` enables an experimental mode that uses interfaces available in some
operating systems to write loose object data with a minimal set of FLUSH
CACHE (or equivalent) commands sent to the storage controller. If the
operating system interfaces are not available, this mode behaves the same as
`true`. This mode is expected to be as safe as `true` on macOS for repos
stored on HFS+ or APFS filesystems and on Windows for repos stored on NTFS or
ReFS.

core.preloadIndex::
Enable parallel index preload for operations like 'git diff'
Expand Down
3 changes: 2 additions & 1 deletion Documentation/git-cat-file.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ OPTIONS
that a process can interactively read and write from
`cat-file`. With this option, the output uses normal stdio
buffering; this is much more efficient when invoking
`--batch-check` on a large number of objects.
`--batch-check` on a large number of objects. An empty string will
force a flush of stdout.

--unordered::
When `--batch-all-objects` is in use, visit objects in an
Expand Down
5 changes: 3 additions & 2 deletions Documentation/git-commit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,9 @@ include::signoff-option.txt[]
each trailer would appear, and other details.

-n::
--no-verify::
This option bypasses the pre-commit and commit-msg hooks.
--[no-]verify::
By default, the pre-commit and commit-msg hooks are run.
When any of `--no-verify` or `-n` is given, these are bypassed.
See also linkgit:githooks[5].

--allow-empty::
Expand Down
6 changes: 4 additions & 2 deletions Documentation/git-send-email.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ git-send-email - Send a collection of patches as emails
SYNOPSIS
--------
[verse]
'git send-email' [<options>] <file|directory|rev-list options>...
'git send-email' [<options>] <file|directory>...
'git send-email' [<options>] <format-patch options>
'git send-email' --dump-aliases


Expand All @@ -19,7 +20,8 @@ Takes the patches given on the command line and emails them out.
Patches can be specified as files, directories (which will send all
files in the directory), or directly as a revision list. In the
last case, any format accepted by linkgit:git-format-patch[1] can
be passed to git send-email.
be passed to git send-email, as well as options understood by
linkgit:git-format-patch[1].

The header of the email is configurable via command-line options. If not
specified on the command line, the user will be prompted with a ReadLine
Expand Down
34 changes: 31 additions & 3 deletions Documentation/git-stash.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ SYNOPSIS
'git stash' drop [-q|--quiet] [<stash>]
'git stash' ( pop | apply ) [--index] [-q|--quiet] [<stash>]
'git stash' branch <branchname> [<stash>]
'git stash' [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
'git stash' [push [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--quiet]
[-u|--include-untracked] [-a|--all] [-m|--message <message>]
[--pathspec-from-file=<file> [--pathspec-file-nul]]
[--] [<pathspec>...]]
Expand Down Expand Up @@ -47,7 +47,7 @@ stash index (e.g. the integer `n` is equivalent to `stash@{n}`).
COMMANDS
--------

push [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [-m|--message <message>] [--pathspec-from-file=<file> [--pathspec-file-nul]] [--] [<pathspec>...]::
push [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [-m|--message <message>] [--pathspec-from-file=<file> [--pathspec-file-nul]] [--] [<pathspec>...]::

Save your local modifications to a new 'stash entry' and roll them
back to HEAD (in the working tree and in the index).
Expand All @@ -60,7 +60,7 @@ subcommand from making an unwanted stash entry. The two exceptions to this
are `stash -p` which acts as alias for `stash push -p` and pathspec elements,
which are allowed after a double hyphen `--` for disambiguation.

save [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>]::
save [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>]::

This option is deprecated in favour of 'git stash push'. It
differs from "stash push" in that it cannot take pathspec.
Expand Down Expand Up @@ -205,6 +205,16 @@ to learn how to operate the `--patch` mode.
The `--patch` option implies `--keep-index`. You can use
`--no-keep-index` to override this.

-S::
--staged::
This option is only valid for `push` and `save` commands.
+
Stash only the changes that are currently staged. This is similar to
basic `git commit` except the state is committed to the stash instead
of current branch.
+
The `--patch` option has priority over this one.

--pathspec-from-file=<file>::
This option is only valid for `push` command.
+
Expand Down Expand Up @@ -341,6 +351,24 @@ $ edit/build/test remaining parts
$ git commit foo -m 'Remaining parts'
----------------------------------------------------------------

Saving unrelated changes for future use::

When you are in the middle of massive changes and you find some
unrelated issue that you don't want to forget to fix, you can do the
change(s), stage them, and use `git stash push --staged` to stash them
out for future use. This is similar to committing the staged changes,
only the commit ends-up being in the stash and not on the current branch.
+
----------------------------------------------------------------
# ... hack hack hack ...
$ git add --patch foo # add unrelated changes to the index
$ git stash push --staged # save these changes to the stash
# ... hack hack hack, finish curent changes ...
$ git commit -m 'Massive' # commit fully tested changes
$ git switch fixup-branch # switch to another branch
$ git stash pop # to finish work on the saved changes
----------------------------------------------------------------

Recovering stash entries that were cleared/dropped erroneously::

If you mistakenly drop or clear stash entries, they cannot be recovered
Expand Down
8 changes: 8 additions & 0 deletions Documentation/git-status.txt
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,14 @@ Line Notes
------------------------------------------------------------
....

Stash Information
^^^^^^^^^^^^^^^^^

If `--show-stash` is given, one line is printed showing the number of stash
entries if non-zero:

# stash <N>

Changed Tracked Entries
^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
5 changes: 3 additions & 2 deletions Documentation/merge-options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,9 @@ ifdef::git-pull[]
Only useful when merging.
endif::git-pull[]

--no-verify::
This option bypasses the pre-merge and commit-msg hooks.
--[no-]verify::
By default, the pre-merge and commit-msg hooks are run.
When `--no-verify` is given, these are bypassed.
See also linkgit:githooks[5].
ifdef::git-pull[]
Only useful when merging.
Expand Down
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,8 @@ all::
#
# Define HAVE_CLOCK_MONOTONIC if your platform has CLOCK_MONOTONIC.
#
# Define HAVE_SYNC_FILE_RANGE if your platform has sync_file_range.
#
# Define NEEDS_LIBRT if your platform requires linking with librt (glibc version
# before 2.17) for clock_gettime and CLOCK_MONOTONIC.
#
Expand Down Expand Up @@ -1884,6 +1886,10 @@ ifdef HAVE_CLOCK_MONOTONIC
BASIC_CFLAGS += -DHAVE_CLOCK_MONOTONIC
endif

ifdef HAVE_SYNC_FILE_RANGE
BASIC_CFLAGS += -DHAVE_SYNC_FILE_RANGE
endif

ifdef NEEDS_LIBRT
EXTLIBS += -lrt
endif
Expand Down
13 changes: 6 additions & 7 deletions builtin/branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,11 @@ define_list_config_array(color_branch_slots);
static int git_branch_config(const char *var, const char *value, void *cb)
{
const char *slot_name;
struct ref_sorting **sorting_tail = (struct ref_sorting **)cb;

if (!strcmp(var, "branch.sort")) {
if (!value)
return config_error_nonbool(var);
parse_ref_sorting(sorting_tail, value);
string_list_append(cb, value);
return 0;
}

Expand Down Expand Up @@ -625,7 +624,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
enum branch_track track;
struct ref_filter filter;
int icase = 0;
static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
static struct ref_sorting *sorting;
struct string_list sorting_options = STRING_LIST_INIT_DUP;
struct ref_format format = REF_FORMAT_INIT;

struct option options[] = {
Expand Down Expand Up @@ -666,7 +666,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
OPT_MERGED(&filter, N_("print only branches that are merged")),
OPT_NO_MERGED(&filter, N_("print only branches that are not merged")),
OPT_COLUMN(0, "column", &colopts, N_("list branches in columns")),
OPT_REF_SORT(sorting_tail),
OPT_REF_SORT(&sorting_options),
OPT_CALLBACK(0, "points-at", &filter.points_at, N_("object"),
N_("print only branches of the object"), parse_opt_object_name),
OPT_BOOL('i', "ignore-case", &icase, N_("sorting and filtering are case insensitive")),
Expand All @@ -683,7 +683,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
if (argc == 2 && !strcmp(argv[1], "-h"))
usage_with_options(builtin_branch_usage, options);

git_config(git_branch_config, sorting_tail);
git_config(git_branch_config, &sorting_options);

track = git_branch_track;

Expand Down Expand Up @@ -749,8 +749,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
* local branches 'refs/heads/...' and finally remote-tracking
* branches 'refs/remotes/...'.
*/
if (!sorting)
sorting = ref_default_sorting();
sorting = ref_sorting_options(&sorting_options);
ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase);
ref_sorting_set_sort_flags_all(
sorting, REF_SORTING_DETACHED_HEAD_FIRST, 1);
Expand Down
11 changes: 10 additions & 1 deletion builtin/cat-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,11 @@ static void batch_one_object(const char *obj_name,
int flags = opt->follow_symlinks ? GET_OID_FOLLOW_SYMLINKS : 0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Git mailing list, Junio C Hamano wrote (reply to this):

"John Cai via GitGitGadget" <gitgitgadget@gmail.com> writes:

> @@ -405,6 +405,11 @@ static void batch_one_object(const char *obj_name,
>  	int flags = opt->follow_symlinks ? GET_OID_FOLLOW_SYMLINKS : 0;
>  	enum get_oid_result result;
>  
> +	if (opt->buffer_output && obj_name[0] == '\0') {
> +		fflush(stdout);
> +		return;
> +	}
> +

This might work in practice, but it a bad design taste to add this
change here.  The function is designed to take an object name
string, and it even prepares a flag variable needed to make a call
to turn that object name into object data.  We do not need to
contaminate the interface with "usually this takes an object name,
but there are these other special cases ...".  The higher in the
callchain we place special cases, the better the lower level
functions become, as that allows them to concentrate on doing one
single thing well.

>  	result = get_oid_with_context(the_repository, obj_name,
>  				      flags, &data->oid, &ctx);
>  	if (result != FOUND) {
> @@ -609,7 +614,11 @@ static int batch_objects(struct batch_options *opt)
>  			data.rest = p;
>  		}
>  
> -		batch_one_object(input.buf, &output, opt, &data);
> +		 /*
> +		  * When in buffer mode and input.buf is an empty string,
> +		  * flush to stdout.
> +		  */

Checking "do we have the flush instruction (in which case we'd do
the flush here), or do we have textual name of an object (in which
case we'd call batch_one_object())?" here would be far cleaner and
results in an easier-to-explain code.  With a cleanly written code
to do so, it probably does not even need a new comment here.

This brings up another issue.  Is "flushing" the *ONLY* special
thing we would ever do in this codepath in the future?  I doubt so.
Squatting on an "empty string" is a selfish design that hurts those
who will come after you in the future, as they need to find other
ways to ask for a "special thing".

If we are inventing a special syntax that allows us to spell
commands that are distinguishable from a validly-spelled object name
to cause something special (like "flushing the output stream"),
perhaps we want to use a bit more extensible and explicit syntax and
use it from day one?

For example, if no string that begins with three dots can ever be a
valid way to spell an object name, perhaps "...flush" might be a
better "please do this special thing" syntax than an empty string.
It is easily extensible (the next special thing can follow suit to
say "...$verb" to tell the machinery to $verb the input).  When we
compare between an empty string and "...flush", the latter clearly
is more descriptive, too.

Note that I offhand do not know if "a valid string that name an
object would never begin with three-dot" is true.  Please check
if that is true if you choose to use it, or you can find and use
another convention that allows us to clearly distinguish the
"special" instruction and object names.

Thanks.

> +		 batch_one_object(input.buf, &output, opt, &data);
>  	}
>  
>  	strbuf_release(&input);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Git mailing list, Ævar Arnfjörð Bjarmason wrote (reply to this):


On Fri, Nov 05 2021, Junio C Hamano wrote:

> "John Cai via GitGitGadget" <gitgitgadget@gmail.com> writes:
>
>> @@ -405,6 +405,11 @@ static void batch_one_object(const char *obj_name,
>>  	int flags = opt->follow_symlinks ? GET_OID_FOLLOW_SYMLINKS : 0;
>>  	enum get_oid_result result;
>>  
>> +	if (opt->buffer_output && obj_name[0] == '\0') {
>> +		fflush(stdout);
>> +		return;
>> +	}
>> +
>
> This might work in practice, but it a bad design taste to add this
> change here.  The function is designed to take an object name
> string, and it even prepares a flag variable needed to make a call
> to turn that object name into object data.  We do not need to
> contaminate the interface with "usually this takes an object name,
> but there are these other special cases ...".  The higher in the
> callchain we place special cases, the better the lower level
> functions become, as that allows them to concentrate on doing one
> single thing well.
>
>>  	result = get_oid_with_context(the_repository, obj_name,
>>  				      flags, &data->oid, &ctx);
>>  	if (result != FOUND) {
>> @@ -609,7 +614,11 @@ static int batch_objects(struct batch_options *opt)
>>  			data.rest = p;
>>  		}
>>  
>> -		batch_one_object(input.buf, &output, opt, &data);
>> +		 /*
>> +		  * When in buffer mode and input.buf is an empty string,
>> +		  * flush to stdout.
>> +		  */
>
> Checking "do we have the flush instruction (in which case we'd do
> the flush here), or do we have textual name of an object (in which
> case we'd call batch_one_object())?" here would be far cleaner and
> results in an easier-to-explain code.  With a cleanly written code
> to do so, it probably does not even need a new comment here.
>
> This brings up another issue.  Is "flushing" the *ONLY* special
> thing we would ever do in this codepath in the future?  I doubt so.
> Squatting on an "empty string" is a selfish design that hurts those
> who will come after you in the future, as they need to find other
> ways to ask for a "special thing".
>
> If we are inventing a special syntax that allows us to spell
> commands that are distinguishable from a validly-spelled object name
> to cause something special (like "flushing the output stream"),
> perhaps we want to use a bit more extensible and explicit syntax and
> use it from day one?
>
> For example, if no string that begins with three dots can ever be a
> valid way to spell an object name, perhaps "...flush" might be a
> better "please do this special thing" syntax than an empty string.
> It is easily extensible (the next special thing can follow suit to
> say "...$verb" to tell the machinery to $verb the input).  When we
> compare between an empty string and "...flush", the latter clearly
> is more descriptive, too.
>
> Note that I offhand do not know if "a valid string that name an
> object would never begin with three-dot" is true.  Please check
> if that is true if you choose to use it, or you can find and use
> another convention that allows us to clearly distinguish the
> "special" instruction and object names.

I had much the same thought, this is a useful feature, but let's not
squat on the one bit of open syntax we have.

John: I think a better direction here is to add a mode to cat-file to
emulate what "git update-ref --stdin" supports. Here's a demo of that
(also quoted below):
https://github.com/git/git/commit/7794f6cfdbdca0dd6bab0dea16193ebf018b86a9

That's on top of some general UI improvements to cat-file I've got
locally:
https://github.com/git/git/compare/master...avar:avar/cat-file-usage-and-options-handling

That WIP patch on top follows below, of course it's a *lot* more initial
scaffolding, but I think once we get past that initial step it's a much
better path forward. As noted the code is also almost entirely
copy/pasted from update-ref.c, and perhaps some of the shared parts
could be moved to some library both could use.

I couldn't think of a better name than --stdin-cmd, suggestions most
welcome.

From 7794f6cfdbdca0dd6bab0dea16193ebf018b86a9 Mon Sep 17 00:00:00 2001
Message-Id: <patch-1.1-7794f6cfdbd-20211106T040307Z-avarab@gmail.com>
From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?=
 <avarab@gmail.com>
Date: Sat, 6 Nov 2021 04:54:04 +0100
Subject: [PATCH] WIP cat-file: add a --stdin-cmd mode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This WIP patch is mostly stealing code from builtin/update-ref.c and
implementing the same sort of prefixed command-mode that it
supports. I.e. in addition to --batch now supporting:

    <object> LF

It'll support with --stdin-cmd, with and without -z, respectively:

    object <object> NL
    object <object> NUL

The plus being that we can now implement additional commands. Let's
start that by scratching the itch John Cai wanted to address in [1]
and implement a (with and without -z):

    fflush NL
    fflush NUL

That command simply calls fflush(stdout), which could be done as an
emergent effect before by feeding the input a "NL".

I think this will be useful for other things, e.g. I've observed in
the past that a not-trivial part of "cat-file --batch" time is spent
on parsing its <object> argument and seeing if it's a revision, ref
etc.

So we could e.g. add a command that only accepts a full-length 40
character SHA-1, or switch the --format output mid-request etc.

1. https://lore.kernel.org/git/pull.1124.git.git.1636149400.gitgitgadget@gmail.com/

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/cat-file.c | 116 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 115 insertions(+), 1 deletion(-)

diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index b76f2a00046..afdb976c6e7 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -26,7 +26,10 @@ struct batch_options {
 	int unordered;
 	int cmdmode; /* may be 'w' or 'c' for --filters or --textconv */
 	const char *format;
+	int stdin_cmd;
+	int end_null;
 };
+static char line_termination = '\n';
 
 static const char *force_path;
 
@@ -507,6 +510,106 @@ static int batch_unordered_packed(const struct object_id *oid,
 				      data);
 }
 
+enum batch_state {
+	/* Non-transactional state open for commands. */
+	BATCH_STATE_OPEN,
+};
+
+static void parse_cmd_object(struct batch_options *opt,
+			     const char *next, const char *end,
+			     struct strbuf *output,
+			     struct expand_data *data)
+{
+	size_t len = end - next - 1;
+	char *p = (char *)next;
+	char old = p[len];
+
+	p[len] = '\0';
+	batch_one_object(next, output, opt, data);
+	p[len] = old;
+}
+
+static void parse_cmd_fflush(struct batch_options *opt,
+			     const char *next, const char *end,
+			     struct strbuf *output,
+			     struct expand_data *data)
+{
+	if (*next != line_termination)
+		die("fflush: extra input: %s", next);
+	fflush(stdout);
+}
+
+static const struct parse_cmd {
+	const char *prefix;
+	void (*fn)(struct batch_options *, const char *, const char *, struct strbuf *, struct expand_data *);
+	unsigned args;
+	enum batch_state state;
+} command[] = {
+	{ "object", parse_cmd_object, 1, BATCH_STATE_OPEN },
+	{ "fflush", parse_cmd_fflush, 0, BATCH_STATE_OPEN },
+};
+
+static void batch_objects_stdin_cmd(struct batch_options *opt,
+				    struct strbuf *output,
+				    struct expand_data *data)
+{
+	struct strbuf input = STRBUF_INIT;
+	enum batch_state state = BATCH_STATE_OPEN;
+
+	/* Read each line dispatch its command */
+	while (!strbuf_getwholeline(&input, stdin, line_termination)) {
+		size_t i, j;
+		const struct parse_cmd *cmd = NULL;
+
+		if (*input.buf == line_termination)
+			die("empty command in input");
+		else if (isspace(*input.buf))
+			die("whitespace before command: %s", input.buf);
+
+		for (i = 0; i < ARRAY_SIZE(command); i++) {
+			const char *prefix = command[i].prefix;
+			char c;
+
+			if (!starts_with(input.buf, prefix))
+				continue;
+
+			/*
+			 * If the command has arguments, verify that it's
+			 * followed by a space. Otherwise, it shall be followed
+			 * by a line terminator.
+			 */
+			c = command[i].args ? ' ' : line_termination;
+			if (input.buf[strlen(prefix)] != c)
+				continue;
+
+			cmd = &command[i];
+			break;
+		}
+		if (!cmd)
+			die("unknown command: %s", input.buf);
+
+		/*
+		 * Read additional arguments if NUL-terminated. Do not raise an
+		 * error in case there is an early EOF to let the command
+		 * handle missing arguments with a proper error message.
+		 */
+		for (j = 1; line_termination == '\0' && j < cmd->args; j++)
+			if (strbuf_appendwholeline(&input, stdin, line_termination))
+				break;
+
+		switch (state) {
+		case BATCH_STATE_OPEN:
+			/* TODO: command state management */
+			break;
+		}
+
+		cmd->fn(opt, input.buf + strlen(cmd->prefix) + !!cmd->args,
+			input.buf + input.len, output, data);
+	}
+
+	strbuf_release(&input);
+}
+
 static int batch_objects(struct batch_options *opt)
 {
 	struct strbuf input = STRBUF_INIT;
@@ -514,6 +617,7 @@ static int batch_objects(struct batch_options *opt)
 	struct expand_data data;
 	int save_warning;
 	int retval = 0;
+	const int stdin_cmd = opt->stdin_cmd;
 
 	if (!opt->format)
 		opt->format = "%(objectname) %(objecttype) %(objectsize)";
@@ -589,7 +693,8 @@ static int batch_objects(struct batch_options *opt)
 	save_warning = warn_on_object_refname_ambiguity;
 	warn_on_object_refname_ambiguity = 0;
 
-	while (strbuf_getline(&input, stdin) != EOF) {
+	while (!stdin_cmd &&
+	       strbuf_getline(&input, stdin) != EOF) {
 		if (data.split_on_whitespace) {
 			/*
 			 * Split at first whitespace, tying off the beginning
@@ -607,6 +712,9 @@ static int batch_objects(struct batch_options *opt)
 		batch_one_object(input.buf, &output, opt, &data);
 	}
 
+	if (stdin_cmd)
+		batch_objects_stdin_cmd(opt, &output, &data);
+
 	strbuf_release(&input);
 	strbuf_release(&output);
 	warn_on_object_refname_ambiguity = save_warning;
@@ -684,6 +792,10 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
 			batch_option_callback),
 		OPT_CMDMODE(0, "batch-all-objects", &opt,
 			    N_("with --batch[-check]: ignores stdin, batches all known objects"), 'b'),
+		OPT_BOOL(0, "stdin-cmd", &batch.stdin_cmd,
+			 N_("with --batch[-check]: enters stdin 'command mode")),
+		OPT_BOOL('z', NULL, &batch.end_null, N_("with --stdin-cmd, use NUL termination")),
+
 		/* Batch-specific options */
 		OPT_GROUP(N_("Change or optimize batch output")),
 		OPT_BOOL(0, "buffer", &batch.buffer_output, N_("buffer --batch output")),
@@ -737,6 +849,8 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
 	/* Batch defaults */
 	if (batch.buffer_output < 0)
 		batch.buffer_output = batch.all_objects;
+	if (batch.end_null)
+		line_termination = '\0';
 
 	/* Return early if we're in batch mode? */
 	if (batch.enabled) {
-- 
2.34.0.rc1.741.gab7bfd97031

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Git mailing list, John Cai wrote (reply to this):

O Sat, Nov 06, 2021 at 05:01:10AM +0100, �var Arnfj�r� Bjarmason wrote:
> 
> On Fri, Nov 05 2021, Junio C Hamano wrote:
> 
> > "John Cai via GitGitGadget" <gitgitgadget@gmail.com> writes:
> >
> >> @@ -405,6 +405,11 @@ static void batch_one_object(const char *obj_name,
> >>  	int flags = opt->follow_symlinks ? GET_OID_FOLLOW_SYMLINKS : 0;
> >>  	enum get_oid_result result;
> >>  
> >> +	if (opt->buffer_output && obj_name[0] == '\0') {
> >> +		fflush(stdout);
> >> +		return;
> >> +	}
> >> +
> >
> > This might work in practice, but it a bad design taste to add this
> > change here.  The function is designed to take an object name
> > string, and it even prepares a flag variable needed to make a call
> > to turn that object name into object data.  We do not need to
> > contaminate the interface with "usually this takes an object name,
> > but there are these other special cases ...".  The higher in the
> > callchain we place special cases, the better the lower level
> > functions become, as that allows them to concentrate on doing one
> > single thing well.
> >
> >>  	result = get_oid_with_context(the_repository, obj_name,
> >>  				      flags, &data->oid, &ctx);
> >>  	if (result != FOUND) {
> >> @@ -609,7 +614,11 @@ static int batch_objects(struct batch_options *opt)
> >>  			data.rest = p;
> >>  		}
> >>  
> >> -		batch_one_object(input.buf, &output, opt, &data);
> >> +		 /*
> >> +		  * When in buffer mode and input.buf is an empty string,
> >> +		  * flush to stdout.
> >> +		  */
> >
> > Checking "do we have the flush instruction (in which case we'd do
> > the flush here), or do we have textual name of an object (in which
> > case we'd call batch_one_object())?" here would be far cleaner and
> > results in an easier-to-explain code.  With a cleanly written code
> > to do so, it probably does not even need a new comment here.
> >
> > This brings up another issue.  Is "flushing" the *ONLY* special
> > thing we would ever do in this codepath in the future?  I doubt so.
> > Squatting on an "empty string" is a selfish design that hurts those
> > who will come after you in the future, as they need to find other
> > ways to ask for a "special thing".
> >
> > If we are inventing a special syntax that allows us to spell
> > commands that are distinguishable from a validly-spelled object name
> > to cause something special (like "flushing the output stream"),
> > perhaps we want to use a bit more extensible and explicit syntax and
> > use it from day one?
> >
> > For example, if no string that begins with three dots can ever be a
> > valid way to spell an object name, perhaps "...flush" might be a
> > better "please do this special thing" syntax than an empty string.
> > It is easily extensible (the next special thing can follow suit to
> > say "...$verb" to tell the machinery to $verb the input).  When we
> > compare between an empty string and "...flush", the latter clearly
> > is more descriptive, too.
> >
> > Note that I offhand do not know if "a valid string that name an
> > object would never begin with three-dot" is true.  Please check
> > if that is true if you choose to use it, or you can find and use
> > another convention that allows us to clearly distinguish the
> > "special" instruction and object names.
> 
> I had much the same thought, this is a useful feature, but let's not
> squat on the one bit of open syntax we have.
> 
> John: I think a better direction here is to add a mode to cat-file to
> emulate what "git update-ref --stdin" supports. Here's a demo of that
> (also quoted below):
> https://github.com/git/git/commit/7794f6cfdbdca0dd6bab0dea16193ebf018b86a9
> 
> That's on top of some general UI improvements to cat-file I've got
> locally:
> https://github.com/git/git/compare/master...avar:avar/cat-file-usage-and-options-handling
> 
> That WIP patch on top follows below, of course it's a *lot* more initial
> scaffolding, but I think once we get past that initial step it's a much
> better path forward. As noted the code is also almost entirely
> copy/pasted from update-ref.c, and perhaps some of the shared parts
> could be moved to some library both could use.
> 
> I couldn't think of a better name than --stdin-cmd, suggestions most
> welcome.
> 
> From 7794f6cfdbdca0dd6bab0dea16193ebf018b86a9 Mon Sep 17 00:00:00 2001
> Message-Id: <patch-1.1-7794f6cfdbd-20211106T040307Z-avarab@gmail.com>
> From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?=
>  <avarab@gmail.com>
> Date: Sat, 6 Nov 2021 04:54:04 +0100
> Subject: [PATCH] WIP cat-file: add a --stdin-cmd mode
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
> 
> This WIP patch is mostly stealing code from builtin/update-ref.c and
> implementing the same sort of prefixed command-mode that it
> supports. I.e. in addition to --batch now supporting:
> 
>     <object> LF
> 
> It'll support with --stdin-cmd, with and without -z, respectively:
> 
>     object <object> NL
>     object <object> NUL
> 
> The plus being that we can now implement additional commands. Let's
> start that by scratching the itch John Cai wanted to address in [1]
> and implement a (with and without -z):
> 
>     fflush NL
>     fflush NUL
> 
> That command simply calls fflush(stdout), which could be done as an
> emergent effect before by feeding the input a "NL".
> 
> I think this will be useful for other things, e.g. I've observed in
> the past that a not-trivial part of "cat-file --batch" time is spent
> on parsing its <object> argument and seeing if it's a revision, ref
> etc.
> 
> So we could e.g. add a command that only accepts a full-length 40
> character SHA-1, or switch the --format output mid-request etc.
> 
> 1. https://lore.kernel.org/git/pull.1124.git.git.1636149400.gitgitgadget@gmail.com/
> 
> Signed-off-by: �var Arnfj�r� Bjarmason <avarab@gmail.com>
> ---
>  builtin/cat-file.c | 116 ++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 115 insertions(+), 1 deletion(-)
> 
> diff --git a/builtin/cat-file.c b/builtin/cat-file.c
> index b76f2a00046..afdb976c6e7 100644
> --- a/builtin/cat-file.c
> +++ b/builtin/cat-file.c
> @@ -26,7 +26,10 @@ struct batch_options {
>  	int unordered;
>  	int cmdmode; /* may be 'w' or 'c' for --filters or --textconv */
>  	const char *format;
> +	int stdin_cmd;
> +	int end_null;
>  };
> +static char line_termination = '\n';
>  
>  static const char *force_path;
>  
> @@ -507,6 +510,106 @@ static int batch_unordered_packed(const struct object_id *oid,
>  				      data);
>  }
>  
> +enum batch_state {
> +	/* Non-transactional state open for commands. */
> +	BATCH_STATE_OPEN,
> +};
> +
> +static void parse_cmd_object(struct batch_options *opt,
> +			     const char *next, const char *end,
> +			     struct strbuf *output,
> +			     struct expand_data *data)
> +{
> +	size_t len = end - next - 1;
> +	char *p = (char *)next;
> +	char old = p[len];
> +
> +	p[len] = '\0';
> +	batch_one_object(next, output, opt, data);
> +	p[len] = old;
> +}
> +
> +static void parse_cmd_fflush(struct batch_options *opt,
> +			     const char *next, const char *end,
> +			     struct strbuf *output,
> +			     struct expand_data *data)
> +{
> +	if (*next != line_termination)
> +		die("fflush: extra input: %s", next);
> +	fflush(stdout);
> +}
> +
> +static const struct parse_cmd {
> +	const char *prefix;
> +	void (*fn)(struct batch_options *, const char *, const char *, struct strbuf *, struct expand_data *);
> +	unsigned args;
> +	enum batch_state state;
> +} command[] = {
> +	{ "object", parse_cmd_object, 1, BATCH_STATE_OPEN },
> +	{ "fflush", parse_cmd_fflush, 0, BATCH_STATE_OPEN },
> +};
I think overall this approach is cleaner and makes sense. My only
question is, are there more commands in the future that will need some
special command syntax? Just wondering whether YAGNI applies here.
> +
> +static void batch_objects_stdin_cmd(struct batch_options *opt,
> +				    struct strbuf *output,
> +				    struct expand_data *data)
> +{
> +	struct strbuf input = STRBUF_INIT;
> +	enum batch_state state = BATCH_STATE_OPEN;
> +
> +	/* Read each line dispatch its command */
> +	while (!strbuf_getwholeline(&input, stdin, line_termination)) {
> +		size_t i, j;
> +		const struct parse_cmd *cmd = NULL;
> +
> +		if (*input.buf == line_termination)
> +			die("empty command in input");
> +		else if (isspace(*input.buf))
> +			die("whitespace before command: %s", input.buf);
> +
> +		for (i = 0; i < ARRAY_SIZE(command); i++) {
> +			const char *prefix = command[i].prefix;
> +			char c;
> +
> +			if (!starts_with(input.buf, prefix))
> +				continue;
> +
> +			/*
> +			 * If the command has arguments, verify that it's
> +			 * followed by a space. Otherwise, it shall be followed
> +			 * by a line terminator.
> +			 */
> +			c = command[i].args ? ' ' : line_termination;
> +			if (input.buf[strlen(prefix)] != c)
> +				continue;
> +
> +			cmd = &command[i];
> +			break;
> +		}
> +		if (!cmd)
> +			die("unknown command: %s", input.buf);
> +
> +		/*
> +		 * Read additional arguments if NUL-terminated. Do not raise an
> +		 * error in case there is an early EOF to let the command
> +		 * handle missing arguments with a proper error message.
> +		 */
> +		for (j = 1; line_termination == '\0' && j < cmd->args; j++)
> +			if (strbuf_appendwholeline(&input, stdin, line_termination))
> +				break;
> +
> +		switch (state) {
> +		case BATCH_STATE_OPEN:
> +			/* TODO: command state management */
> +			break;
> +		}
> +
> +		cmd->fn(opt, input.buf + strlen(cmd->prefix) + !!cmd->args,
> +			input.buf + input.len, output, data);
> +	}
> +
> +	strbuf_release(&input);
> +}
> +
>  static int batch_objects(struct batch_options *opt)
>  {
>  	struct strbuf input = STRBUF_INIT;
> @@ -514,6 +617,7 @@ static int batch_objects(struct batch_options *opt)
>  	struct expand_data data;
>  	int save_warning;
>  	int retval = 0;
> +	const int stdin_cmd = opt->stdin_cmd;
>  
>  	if (!opt->format)
>  		opt->format = "%(objectname) %(objecttype) %(objectsize)";
> @@ -589,7 +693,8 @@ static int batch_objects(struct batch_options *opt)
>  	save_warning = warn_on_object_refname_ambiguity;
>  	warn_on_object_refname_ambiguity = 0;
>  
> -	while (strbuf_getline(&input, stdin) != EOF) {
> +	while (!stdin_cmd &&
> +	       strbuf_getline(&input, stdin) != EOF) {
>  		if (data.split_on_whitespace) {
>  			/*
>  			 * Split at first whitespace, tying off the beginning
> @@ -607,6 +712,9 @@ static int batch_objects(struct batch_options *opt)
>  		batch_one_object(input.buf, &output, opt, &data);
>  	}
>  
> +	if (stdin_cmd)
> +		batch_objects_stdin_cmd(opt, &output, &data);
> +
>  	strbuf_release(&input);
>  	strbuf_release(&output);
>  	warn_on_object_refname_ambiguity = save_warning;
> @@ -684,6 +792,10 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
>  			batch_option_callback),
>  		OPT_CMDMODE(0, "batch-all-objects", &opt,
>  			    N_("with --batch[-check]: ignores stdin, batches all known objects"), 'b'),
> +		OPT_BOOL(0, "stdin-cmd", &batch.stdin_cmd,
> +			 N_("with --batch[-check]: enters stdin 'command mode")),
> +		OPT_BOOL('z', NULL, &batch.end_null, N_("with --stdin-cmd, use NUL termination")),
> +
>  		/* Batch-specific options */
>  		OPT_GROUP(N_("Change or optimize batch output")),
>  		OPT_BOOL(0, "buffer", &batch.buffer_output, N_("buffer --batch output")),
> @@ -737,6 +849,8 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
>  	/* Batch defaults */
>  	if (batch.buffer_output < 0)
>  		batch.buffer_output = batch.all_objects;
> +	if (batch.end_null)
> +		line_termination = '\0';
>  
>  	/* Return early if we're in batch mode? */
>  	if (batch.enabled) {
> -- 
> 2.34.0.rc1.741.gab7bfd97031
> 

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Git mailing list, Ævar Arnfjörð Bjarmason wrote (reply to this):


On Sun, Nov 07 2021, John Cai wrote:

> O Sat, Nov 06, 2021 at 05:01:10AM +0100, Ævar Arnfjörð Bjarmason wrote:
>> 
>> On Fri, Nov 05 2021, Junio C Hamano wrote:
>> 
>> > "John Cai via GitGitGadget" <gitgitgadget@gmail.com> writes:
>> >
>> >> @@ -405,6 +405,11 @@ static void batch_one_object(const char *obj_name,
>> >>  	int flags = opt->follow_symlinks ? GET_OID_FOLLOW_SYMLINKS : 0;
>> >>  	enum get_oid_result result;
>> >>  
>> >> +	if (opt->buffer_output && obj_name[0] == '\0') {
>> >> +		fflush(stdout);
>> >> +		return;
>> >> +	}
>> >> +
>> >
>> > This might work in practice, but it a bad design taste to add this
>> > change here.  The function is designed to take an object name
>> > string, and it even prepares a flag variable needed to make a call
>> > to turn that object name into object data.  We do not need to
>> > contaminate the interface with "usually this takes an object name,
>> > but there are these other special cases ...".  The higher in the
>> > callchain we place special cases, the better the lower level
>> > functions become, as that allows them to concentrate on doing one
>> > single thing well.
>> >
>> >>  	result = get_oid_with_context(the_repository, obj_name,
>> >>  				      flags, &data->oid, &ctx);
>> >>  	if (result != FOUND) {
>> >> @@ -609,7 +614,11 @@ static int batch_objects(struct batch_options *opt)
>> >>  			data.rest = p;
>> >>  		}
>> >>  
>> >> -		batch_one_object(input.buf, &output, opt, &data);
>> >> +		 /*
>> >> +		  * When in buffer mode and input.buf is an empty string,
>> >> +		  * flush to stdout.
>> >> +		  */
>> >
>> > Checking "do we have the flush instruction (in which case we'd do
>> > the flush here), or do we have textual name of an object (in which
>> > case we'd call batch_one_object())?" here would be far cleaner and
>> > results in an easier-to-explain code.  With a cleanly written code
>> > to do so, it probably does not even need a new comment here.
>> >
>> > This brings up another issue.  Is "flushing" the *ONLY* special
>> > thing we would ever do in this codepath in the future?  I doubt so.
>> > Squatting on an "empty string" is a selfish design that hurts those
>> > who will come after you in the future, as they need to find other
>> > ways to ask for a "special thing".
>> >
>> > If we are inventing a special syntax that allows us to spell
>> > commands that are distinguishable from a validly-spelled object name
>> > to cause something special (like "flushing the output stream"),
>> > perhaps we want to use a bit more extensible and explicit syntax and
>> > use it from day one?
>> >
>> > For example, if no string that begins with three dots can ever be a
>> > valid way to spell an object name, perhaps "...flush" might be a
>> > better "please do this special thing" syntax than an empty string.
>> > It is easily extensible (the next special thing can follow suit to
>> > say "...$verb" to tell the machinery to $verb the input).  When we
>> > compare between an empty string and "...flush", the latter clearly
>> > is more descriptive, too.
>> >
>> > Note that I offhand do not know if "a valid string that name an
>> > object would never begin with three-dot" is true.  Please check
>> > if that is true if you choose to use it, or you can find and use
>> > another convention that allows us to clearly distinguish the
>> > "special" instruction and object names.
>> 
>> I had much the same thought, this is a useful feature, but let's not
>> squat on the one bit of open syntax we have.
>> 
>> John: I think a better direction here is to add a mode to cat-file to
>> emulate what "git update-ref --stdin" supports. Here's a demo of that
>> (also quoted below):
>> https://github.com/git/git/commit/7794f6cfdbdca0dd6bab0dea16193ebf018b86a9
>> 
>> That's on top of some general UI improvements to cat-file I've got
>> locally:
>> https://github.com/git/git/compare/master...avar:avar/cat-file-usage-and-options-handling
>> 
>> That WIP patch on top follows below, of course it's a *lot* more initial
>> scaffolding, but I think once we get past that initial step it's a much
>> better path forward. As noted the code is also almost entirely
>> copy/pasted from update-ref.c, and perhaps some of the shared parts
>> could be moved to some library both could use.
>> 
>> I couldn't think of a better name than --stdin-cmd, suggestions most
>> welcome.
>> 
>> From 7794f6cfdbdca0dd6bab0dea16193ebf018b86a9 Mon Sep 17 00:00:00 2001
>> Message-Id: <patch-1.1-7794f6cfdbd-20211106T040307Z-avarab@gmail.com>
>> From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?=
>>  <avarab@gmail.com>
>> Date: Sat, 6 Nov 2021 04:54:04 +0100
>> Subject: [PATCH] WIP cat-file: add a --stdin-cmd mode
>> MIME-Version: 1.0
>> Content-Type: text/plain; charset=UTF-8
>> Content-Transfer-Encoding: 8bit
>> 
>> This WIP patch is mostly stealing code from builtin/update-ref.c and
>> implementing the same sort of prefixed command-mode that it
>> supports. I.e. in addition to --batch now supporting:
>> 
>>     <object> LF
>> 
>> It'll support with --stdin-cmd, with and without -z, respectively:
>> 
>>     object <object> NL
>>     object <object> NUL
>> 
>> The plus being that we can now implement additional commands. Let's
>> start that by scratching the itch John Cai wanted to address in [1]
>> and implement a (with and without -z):
>> 
>>     fflush NL
>>     fflush NUL
>> 
>> That command simply calls fflush(stdout), which could be done as an
>> emergent effect before by feeding the input a "NL".
>> 
>> I think this will be useful for other things, e.g. I've observed in
>> the past that a not-trivial part of "cat-file --batch" time is spent
>> on parsing its <object> argument and seeing if it's a revision, ref
>> etc.
>> 
>> So we could e.g. add a command that only accepts a full-length 40
>> character SHA-1, or switch the --format output mid-request etc.
>> 
>> 1. https://lore.kernel.org/git/pull.1124.git.git.1636149400.gitgitgadget@gmail.com/
>> 
>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>> ---
>>  builtin/cat-file.c | 116 ++++++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 115 insertions(+), 1 deletion(-)
>> 
>> diff --git a/builtin/cat-file.c b/builtin/cat-file.c
>> index b76f2a00046..afdb976c6e7 100644
>> --- a/builtin/cat-file.c
>> +++ b/builtin/cat-file.c
>> @@ -26,7 +26,10 @@ struct batch_options {
>>  	int unordered;
>>  	int cmdmode; /* may be 'w' or 'c' for --filters or --textconv */
>>  	const char *format;
>> +	int stdin_cmd;
>> +	int end_null;
>>  };
>> +static char line_termination = '\n';
>>  
>>  static const char *force_path;
>>  
>> @@ -507,6 +510,106 @@ static int batch_unordered_packed(const struct object_id *oid,
>>  				      data);
>>  }
>>  
>> +enum batch_state {
>> +	/* Non-transactional state open for commands. */
>> +	BATCH_STATE_OPEN,
>> +};
>> +
>> +static void parse_cmd_object(struct batch_options *opt,
>> +			     const char *next, const char *end,
>> +			     struct strbuf *output,
>> +			     struct expand_data *data)
>> +{
>> +	size_t len = end - next - 1;
>> +	char *p = (char *)next;
>> +	char old = p[len];
>> +
>> +	p[len] = '\0';
>> +	batch_one_object(next, output, opt, data);
>> +	p[len] = old;
>> +}
>> +
>> +static void parse_cmd_fflush(struct batch_options *opt,
>> +			     const char *next, const char *end,
>> +			     struct strbuf *output,
>> +			     struct expand_data *data)
>> +{
>> +	if (*next != line_termination)
>> +		die("fflush: extra input: %s", next);
>> +	fflush(stdout);
>> +}
>> +
>> +static const struct parse_cmd {
>> +	const char *prefix;
>> +	void (*fn)(struct batch_options *, const char *, const char *, struct strbuf *, struct expand_data *);
>> +	unsigned args;
>> +	enum batch_state state;
>> +} command[] = {
>> +	{ "object", parse_cmd_object, 1, BATCH_STATE_OPEN },
>> +	{ "fflush", parse_cmd_fflush, 0, BATCH_STATE_OPEN },
>> +};
> I think overall this approach is cleaner and makes sense. My only
> question is, are there more commands in the future that will need some
> special command syntax? Just wondering whether YAGNI applies here.

An obvious addition is to at least add the ability to set the various
options on the fly, i.e. now you need to use --batch-check, and then
kill it and restart if you'd like the content with --batch, ditto for
--textconv.

E.g. the gitaly backend for gitlab.com keeps two cat-filfe processes
around just to flip-flop between those two, sometimes you want the
content, sometimes you're just checking if the object exists.

I'd also like to add something to expose the likes of -e and -t
directly, i.e. even with --batch-check you often want to just check
existence, but get the size too, you could supply a format, but like the
above you sometimes want the size or whatever, and killing/starting a
new process just for that is a hassle...

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Git mailing list, Junio C Hamano wrote (reply to this):

Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

>> I think overall this approach is cleaner and makes sense. My only
>> question is, are there more commands in the future that will need some
>> special command syntax? Just wondering whether YAGNI applies here.
>
> An obvious addition is to at least add the ability to set the various
> options on the fly, i.e. now you need to use --batch-check, and then
> kill it and restart if you'd like the content with --batch, ditto for
> --textconv.
>
> E.g. the gitaly backend for gitlab.com keeps two cat-filfe processes
> around just to flip-flop between those two, sometimes you want the
> content, sometimes you're just checking if the object exists.
>
> I'd also like to add something to expose the likes of -e and -t
> directly, i.e. even with --batch-check you often want to just check
> existence, but get the size too, you could supply a format, but like the
> above you sometimes want the size or whatever, and killing/starting a
> new process just for that is a hassle...

Yeah, with "plug" and "unplug" instruction you do not have to keep
issuing "flush" when you want to go interactive, and other things
become easy to do, so even though it would make it a bit more
verbose to require "object " prefix for the kind of lines that were
historically the only ones accepted by the command, I think it is a
good direction to go in.

Thanks.

enum get_oid_result result;

if (opt->buffer_output && obj_name[0] == '\0') {
fflush(stdout);
return;
}

result = get_oid_with_context(the_repository, obj_name,
flags, &data->oid, &ctx);
if (result != FOUND) {
Expand Down Expand Up @@ -609,7 +614,11 @@ static int batch_objects(struct batch_options *opt)
data.rest = p;
}

batch_one_object(input.buf, &output, opt, &data);
/*
* When in buffer mode and input.buf is an empty string,
* flush to stdout.
*/
batch_one_object(input.buf, &output, opt, &data);
}

strbuf_release(&input);
Expand Down
8 changes: 4 additions & 4 deletions builtin/for-each-ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ static char const * const for_each_ref_usage[] = {
int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
{
int i;
struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
struct ref_sorting *sorting;
struct string_list sorting_options = STRING_LIST_INIT_DUP;
int maxcount = 0, icase = 0;
struct ref_array array;
struct ref_filter filter;
Expand All @@ -39,7 +40,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
OPT_INTEGER( 0 , "count", &maxcount, N_("show only <n> matched refs")),
OPT_STRING( 0 , "format", &format.format, N_("format"), N_("format to use for the output")),
OPT__COLOR(&format.use_color, N_("respect format colors")),
OPT_REF_SORT(sorting_tail),
OPT_REF_SORT(&sorting_options),
OPT_CALLBACK(0, "points-at", &filter.points_at,
N_("object"), N_("print only refs which points at the given object"),
parse_opt_object_name),
Expand Down Expand Up @@ -70,8 +71,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
if (verify_ref_format(&format))
usage_with_options(for_each_ref_usage, opts);

if (!sorting)
sorting = ref_default_sorting();
sorting = ref_sorting_options(&sorting_options);
ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase);
filter.ignore_case = icase;

Expand Down
2 changes: 1 addition & 1 deletion builtin/index-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -1486,7 +1486,7 @@ static void rename_tmp_packfile(const char **final_name,
if (!*final_name)
*final_name = odb_pack_name(name, hash, ext);
if (finalize_object_file(curr_name, *final_name))
die(_("unable to rename temporary '*.%s' file to '%s"),
die(_("unable to rename temporary '*.%s' file to '%s'"),
ext, *final_name);
} else if (make_read_only_if_same) {
chmod(*final_name, 0444);
Expand Down
13 changes: 8 additions & 5 deletions builtin/ls-remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
struct transport *transport;
const struct ref *ref;
struct ref_array ref_array;
static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
struct string_list sorting_options = STRING_LIST_INIT_DUP;

struct option options[] = {
OPT__QUIET(&quiet, N_("do not print remote URL")),
Expand All @@ -68,7 +68,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
OPT_BIT(0, "refs", &flags, N_("do not show peeled tags"), REF_NORMAL),
OPT_BOOL(0, "get-url", &get_url,
N_("take url.<base>.insteadOf into account")),
OPT_REF_SORT(sorting_tail),
OPT_REF_SORT(&sorting_options),
OPT_SET_INT_F(0, "exit-code", &status,
N_("exit with exit code 2 if no matching refs are found"),
2, PARSE_OPT_NOCOMPLETE),
Expand All @@ -86,8 +86,6 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)

packet_trace_identity("ls-remote");

UNLEAK(sorting);

if (argc > 1) {
int i;
CALLOC_ARRAY(pattern, argc);
Expand Down Expand Up @@ -139,8 +137,13 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
item->symref = xstrdup_or_null(ref->symref);
}

if (sorting)
if (sorting_options.nr) {
struct ref_sorting *sorting;

sorting = ref_sorting_options(&sorting_options);
ref_array_sort(sorting, &ref_array);
ref_sorting_release(sorting);
}

for (i = 0; i < ref_array.nr; i++) {
const struct ref_array_item *ref = ref_array.items[i];
Expand Down
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载