Commit Graph

9588 Commits

Author SHA1 Message Date
Junio C Hamano
a58a8e3f71 Merge branch 'jk/push-progress'
"git push" and "git clone" learned to give better progress meters
to the end user who is waiting on the terminal.

* jk/push-progress:
  receive-pack: send keepalives during quiet periods
  receive-pack: turn on connectivity progress
  receive-pack: relay connectivity errors to sideband
  receive-pack: turn on index-pack resolving progress
  index-pack: add flag for showing delta-resolution progress
  clone: use a real progress meter for connectivity check
  check_connected: add progress flag
  check_connected: relay errors to alternate descriptor
  check_everything_connected: use a struct with named options
  check_everything_connected: convert to argv_array
  rev-list: add optional progress reporting
  check_everything_connected: always pass --quiet to rev-list
2016-08-03 15:10:28 -07:00
Junio C Hamano
cf27c7996e Merge branch 'sb/push-options'
"git push" learned to accept and pass extra options to the
receiving end so that hooks can read and react to them.

* sb/push-options:
  add a test for push options
  push: accept push options
  receive-pack: implement advertising and receiving push options
  push options: {pre,post}-receive hook learns about push options
2016-08-03 15:10:24 -07:00
Junio C Hamano
f8f7adce9f Sync with maint
* maint:
  Some fixes for 2.9.3
2016-07-28 14:21:18 -07:00
Junio C Hamano
8213178c86 Eighth batch of topics for 2.10
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-28 14:20:48 -07:00
Junio C Hamano
0f3d855efc Merge branch 'master' of git://git.bogomips.org/git-svn
* 'master' of git://git.bogomips.org/git-svn:
  git-svn: allow --version to work anywhere
  git-svn: document svn.authorsProg in config
2016-07-28 13:13:53 -07:00
Junio C Hamano
08df31eecc Some fixes for 2.9.3
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-28 11:28:32 -07:00
Junio C Hamano
dcfb9d7d30 Merge branch 'nd/doc-new-command' into maint
Typofix in a doc.

* nd/doc-new-command:
  new-command.txt: correct the command description file
2016-07-28 11:25:57 -07:00
Junio C Hamano
1032eb9c2a Merge branch 'mm/doc-tt' into maint
More mark-up updates to typeset strings that are expected to
literally typed by the end user in fixed-width font.

* mm/doc-tt:
  doc: typeset HEAD and variants as literal
  CodingGuidelines: formatting HEAD in documentation
  doc: typeset long options with argument as literal
  doc: typeset '--' as literal
  doc: typeset long command-line options as literal
  doc: typeset short command-line options as literal
  Documentation/git-mv.txt: fix whitespace indentation
2016-07-28 11:25:54 -07:00
Junio C Hamano
2c608e0f7c Merge branch 'nd/worktree-lock'
"git worktree prune" protected worktrees that are marked as
"locked" by creating a file in a known location.  "git worktree"
command learned a dedicated command pair to create and remove such
a file, so that the users do not have to do this with editor.

* nd/worktree-lock:
  worktree.c: find_worktree() search by path suffix
  worktree: add "unlock" command
  worktree: add "lock" command
  worktree.c: add is_worktree_locked()
  worktree.c: add is_main_worktree()
  worktree.c: add find_worktree()
2016-07-28 10:34:42 -07:00
Junio C Hamano
8c6d1f9807 Seventh batch of topics for 2.10
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-25 14:17:28 -07:00
Junio C Hamano
9db3979784 Merge branch 'js/fsck-name-object'
When "git fsck" reports a broken link (e.g. a tree object contains
a blob that does not exist), both containing object and the object
that is referred to were reported with their 40-hex object names.
The command learned the "--name-objects" option to show the path to
the containing object from existing refs (e.g. "HEAD~24^2:file.txt").

* js/fsck-name-object:
  fsck: optionally show more helpful info for broken links
  fsck: give the error function a chance to see the fsck_options
  fsck_walk(): optionally name objects on the go
  fsck: refactor how to describe objects
2016-07-25 14:13:44 -07:00
Junio C Hamano
c3531e0385 Merge branch 'jc/doc-diff-filter-exclude'
Belated doc update for a feature added in v1.8.5.

* jc/doc-diff-filter-exclude:
  diff: document diff-filter exclusion
2016-07-25 14:13:41 -07:00
Junio C Hamano
21bed620cd Merge branch 'jc/renormalize-merge-kill-safer-crlf'
"git merge" with renormalization did not work well with
merge-recursive, due to "safer crlf" conversion kicking in when it
shouldn't.

* jc/renormalize-merge-kill-safer-crlf:
  merge: avoid "safer crlf" during recording of merge results
  convert: unify the "auto" handling of CRLF
2016-07-25 14:13:39 -07:00
Jeff King
83558686ce receive-pack: send keepalives during quiet periods
After a client has sent us the complete pack, we may spend
some time processing the data and running hooks. If the
client asked us to be quiet, receive-pack won't send any
progress data during the index-pack or connectivity-check
steps. And hooks may or may not produce their own progress
output. In these cases, the network connection is totally
silent from both ends.

Git itself doesn't care about this (it will wait forever),
but other parts of the system (e.g., firewalls,
load-balancers, etc) might hang up the connection. So we'd
like to send some sort of keepalive to let the network and
the client side know that we're still alive and processing.

We can use the same trick we did in 05e9515 (upload-pack:
send keepalive packets during pack computation, 2013-09-08).
Namely, we will send an empty sideband data packet every `N`
seconds that we do not relay any stderr data over the
sideband channel. As with 05e9515, this means that we won't
bother sending keepalives when there's actual progress data,
but will kick in when it has been disabled (or if there is a
lull in the progress data).

The concept is simple, but the details are subtle enough
that they need discussing here.

Before the client sends us the pack, we don't want to do any
keepalives. We'll have sent our ref advertisement, and we're
waiting for them to send us the pack (and tell us that they
support sidebands at all).

While we're receiving the pack from the client (or waiting
for it to start), there's no need for keepalives; it's up to
them to keep the connection active by sending data.
Moreover, it would be wrong for us to do so. When we are the
server in the smart-http protocol, we must treat our
connection as half-duplex. So any keepalives we send while
receiving the pack would potentially be buffered by the
webserver. Not only does this make them useless (since they
would not be delivered in a timely manner), but it could
actually cause a deadlock if we fill up the buffer with
keepalives. (It wouldn't be wrong to send keepalives in this
phase for a full-duplex connection like ssh; it's simply
pointless, as it is the client's responsibility to speak).

As soon as we've gotten all of the pack data, then the
client is waiting for us to speak, and we should start
keepalives immediately. From here until the end of the
connection, we send one any time we are not otherwise
sending data.

But there's a catch. Receive-pack doesn't know the moment
we've gotten all the data. It passes the descriptor to
index-pack, who reads all of the data, and then starts
resolving the deltas. We have to communicate that back.

To make this work, we instruct the sideband muxer to enable
keepalives in three phases:

  1. In the beginning, not at all.

  2. While reading from index-pack, wait for a signal
     indicating end-of-input, and then start them.

  3. Afterwards, always.

The signal from index-pack in phase 2 has to come over the
stderr channel which the muxer is reading. We can't use an
extra pipe because the portable run-command interface only
gives us stderr and stdout.

Stdout is already used to pass the .keep filename back to
receive-pack. We could also send a signal there, but then we
would find out about it in the main thread. And the
keepalive needs to be done by the async muxer thread (since
it's the one writing sideband data back to the client). And
we can't reliably signal the async thread from the main
thread, because the async code sometimes uses threads and
sometimes uses forked processes.

Therefore the signal must come over the stderr channel,
where it may be interspersed with other random
human-readable messages from index-pack. This patch makes
the signal a single NUL byte.  This is easy to parse, should
not appear in any normal stderr output, and we don't have to
worry about any timing issues (like seeing half the signal
bytes in one read(), and half in a subsequent one).

This is a bit ugly, but it's simple to code and should work
reliably.

Another option would be to stop using an async thread for
muxing entirely, and just poll() both stderr and stdout of
index-pack from the main thread. This would work for
index-pack (because we aren't doing anything useful in the
main thread while it runs anyway). But it would make the
connectivity check and the hook muxers much more
complicated, as they need to simultaneously feed the
sub-programs while reading their stderr.

The index-pack phase is the only one that needs this
signaling, so it could simply behave differently than the
other two. That would mean having two separate
implementations of copy_to_sideband (and the keepalive
code), though. And it still doesn't get rid of the
signaling; it just means we can write a nicer message like
"END_OF_INPUT" or something on stdout, since we don't have
to worry about separating it from the stderr cruft.

One final note: this signaling trick is only done with
index-pack, not with unpack-objects. There's no point in
doing it for the latter, because by definition it only kicks
in for a small number of objects, where keepalives are not
as useful (and this conveniently lets us avoid duplicating
the implementation).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-20 12:11:11 -07:00
Jeff King
434ea3cdad rev-list: add optional progress reporting
It's easy to ask rev-list to do a traversal that may takes
many seconds (e.g., by calling "--objects --all"). In theory
you can monitor its progress by the output you get to
stdout, but this isn't always easy.

Some operations, like "--count", don't make any output until
the end.

And some callers, like check_everything_connected(), are
using it just for the error-checking of the traversal, and
throw away stdout entirely.

This patch adds a "--progress" option which can be used to
give some eye-candy for a user waiting for a long traversal.
This is just a rev-list option and not a regular traversal
option, because it needs cooperation from the callbacks in
builtin/rev-list.c to do the actual count.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-20 12:10:44 -07:00
Junio C Hamano
08bb3500a2 Sixth batch of topics for 2.10
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-19 13:26:16 -07:00
Junio C Hamano
566fdaf611 Merge branch 'nd/fetch-ref-summary'
Improve the look of the way "git fetch" reports what happened to
each ref that was fetched.

* nd/fetch-ref-summary:
  fetch: reduce duplicate in ref update status lines with placeholder
  fetch: align all "remote -> local" output
  fetch: change flag code for displaying tag update and deleted ref
  fetch: refactor ref update status formatting code
  git-fetch.txt: document fetch output
2016-07-19 13:22:21 -07:00
Junio C Hamano
dc21164e66 Merge branch 'nd/connect-ssh-command-config'
A new configuration variable core.sshCommand has been added to
specify what value for GIT_SSH_COMMAND to use per repository.

* nd/connect-ssh-command-config:
  connect: read $GIT_SSH_COMMAND from config file
2016-07-19 13:22:12 -07:00
Eric Wong
cec9264f17 git-svn: document svn.authorsProg in config
This has always been supported since we read config variables
based on the command-line option parser.  Document it explicitly
since users usually want to maintain the same program across
invocations.

Signed-off-by: Eric Wong <e@80x24.org>
2016-07-19 10:07:19 +00:00
Johannes Schindelin
90cf590f53 fsck: optionally show more helpful info for broken links
When reporting broken links between commits/trees/blobs, it would be
quite helpful at times if the user would be told how the object is
supposed to be reachable.

With the new --name-objects option, git-fsck will try to do exactly
that: name the objects in a way that shows how they are reachable.

For example, when some reflog got corrupted and a blob is missing that
should not be, the user might want to remove the corresponding reflog
entry. This option helps them find that entry: `git fsck` will now
report something like this:

	broken link from    tree b5eb6ff...  (refs/stash@{<date>}~37:)
	              to    blob ec5cf80...

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-18 15:15:59 -07:00
Junio C Hamano
82246e075e Sync with 2.9.2
* maint:
  Git 2.9.2
  t0006: skip "far in the future" test when unsigned long is not long enough
2016-07-15 10:49:23 -07:00
Junio C Hamano
e634160bf4 Git 2.9.2
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-15 10:48:16 -07:00
Stefan Beller
f6a4e61fbb push: accept push options
This implements everything that is required on the client side to make use
of push options from the porcelain push command.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-14 15:50:41 -07:00
Stefan Beller
c714e45f87 receive-pack: implement advertising and receiving push options
The pre/post receive hook may be interested in more information from the
user. This information can be transmitted when both client and server
support the "push-options" capability, which when used is a phase directly
after update commands ended by a flush pkt.

Similar to the atomic option, the server capability can be disabled via
the `receive.advertisePushOptions` config variable. While documenting
this, fix a nit in the `receive.advertiseAtomic` wording.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-14 15:50:40 -07:00
Stefan Beller
77a9745d19 push options: {pre,post}-receive hook learns about push options
The environment variable GIT_PUSH_OPTION_COUNT is set to the number of
push options sent, and GIT_PUSH_OPTION_{0,1,..} is set to the transmitted
option.

The code is not executed as the push options are set to NULL, nor is the
new capability advertised.

There was some discussion back and forth how to present these push options
to the user as there are some ways to do it:

Keep all options in one environment variable
============================================
+ easiest way to implement in Git
- This would make things hard to parse correctly in the hook.

Put the options in files instead,
filenames are in GIT_PUSH_OPTION_FILES
======================================
+ After a discussion about environment variables and shells, we may not
  want to put user data into an environment variable (see [1] for example).
+ We could transmit binaries, i.e. we're not bound to C strings as
  we are when using environment variables to the user.
+ Maybe easier to parse than constructing environment variable names
  GIT_PUSH_OPTION_{0,1,..} yourself
- cleanup of the temporary files is hard to do reliably
- we have race conditions with multiple clients pushing, hence we'd need
  to use mkstemp. That's not too bad, but still.

Use environment variables, but restrict to key/value pairs
==========================================================
(When the user pushes a push option `foo=bar`, we'd
GIT_PUSH_OPTION_foo=bar)
+ very easy to parse for a simple model of push options
- it's not sufficient for more elaborate models, e.g.
  it doesn't allow doubles (e.g. cc=reviewer@email)

Present the options in different environment variables
======================================================
(This is implemented)
* harder to parse as a user, but we have a sample hook for that.
- doesn't allow binary files
+ allows the same option twice, i.e. is not restrictive about
  options, except for binary files.
+ doesn't clutter a remote directory with (possibly stale)
  temporary files

As we first want to focus on getting simple strings to work
reliably, we go with the last option for now. If we want to
do transmission of binaries later, we can just attach a
'side-channel', e.g. "any push option that contains a '\0' is
put into a file instead of the environment variable and we'd
have new GIT_PUSH_OPTION_FILES, GIT_PUSH_OPTION_FILENAME_{0,1,..}
environment variables".

[1] 'Shellshock' https://lwn.net/Articles/614218/

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-14 15:50:17 -07:00
Junio C Hamano
16726cfa0c diff: document diff-filter exclusion
In v1.8.5 days, 7f2ea5f0 (diff: allow lowercase letter to specify
what change class to exclude, 2013-07-17) taught the "--diff-filter"
mechanism to take lowercase letters as exclusion, but we forgot to
document it.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-14 12:17:47 -07:00
Junio C Hamano
79ed43c28f Fifth batch of topics for 2.10
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-13 11:30:25 -07:00
Junio C Hamano
ce18123cec Merge branch 'mm/doc-tt'
More mark-up updates to typeset strings that are expected to
literally typed by the end user in fixed-width font.

* mm/doc-tt:
  doc: typeset HEAD and variants as literal
  CodingGuidelines: formatting HEAD in documentation
  doc: typeset long options with argument as literal
  doc: typeset '--' as literal
  doc: typeset long command-line options as literal
  doc: typeset short command-line options as literal
  Documentation/git-mv.txt: fix whitespace indentation
2016-07-13 11:24:14 -07:00
Junio C Hamano
7aa46d2bc8 Merge branch 'nd/doc-new-command'
Typofix in a doc.

* nd/doc-new-command:
  new-command.txt: correct the command description file
2016-07-13 11:24:12 -07:00
Junio C Hamano
b1ec08fda8 Sync with v2.9.1
* maint:
  Git 2.9.1
2016-07-11 10:46:39 -07:00
Junio C Hamano
5c9159de87 Git 2.9.1
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-11 10:45:50 -07:00
Junio C Hamano
9f0aa036e9 Merge branch 'jn/preformatted-doc-url' into maint
The top level documentation "git help git" still pointed at the
documentation set hosted at now-defunct google-code repository.
Update it to point to https://git.github.io/htmldocs/git.html
instead.

* jn/preformatted-doc-url:
  doc: git-htmldocs.googlecode.com is no more
2016-07-11 10:44:16 -07:00
Junio C Hamano
1a88ca99db Merge branch 'sb/clone-shallow-passthru' into maint
Fix an unintended regression in v2.9 that breaks "clone --depth"
that recurses down to submodules by forcing the submodules to also
be cloned shallowly, which many server instances that host upstream
of the submodules are not prepared for.

* sb/clone-shallow-passthru:
  clone: do not let --depth imply --shallow-submodules
2016-07-11 10:44:12 -07:00
Junio C Hamano
4212e483a9 Merge branch 'mg/signature-doc' into maint
Formats of the various data (and how to validate them) where we use
GPG signature have been documented.

* mg/signature-doc:
  Documentation/technical: signed merge tag format
  Documentation/technical: signed commit format
  Documentation/technical: signed tag format
  Documentation/technical: describe signature formats
2016-07-11 10:44:11 -07:00
Junio C Hamano
d0ccc82ad8 Fourth batch of topics for 2.10
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-11 10:36:29 -07:00
Junio C Hamano
369dc4081c Merge branch 'mj/log-show-signature-conf'
"git log" learns log.showSignature configuration variable, and a
command line option "--no-show-signature" to countermand it.

* mj/log-show-signature-conf:
  log: add log.showSignature configuration variable
  log: add "--no-show-signature" command line option
  t4202: refactor test
2016-07-11 10:31:08 -07:00
Junio C Hamano
493ddea54d Merge branch 'jn/preformatted-doc-url'
The top level documentation "git help git" still pointed at the
documentation set hosted at now-defunct google-code repository.
Update it to point to https://git.github.io/htmldocs/git.html
instead.

* jn/preformatted-doc-url:
  doc: git-htmldocs.googlecode.com is no more
2016-07-11 10:31:07 -07:00
Junio C Hamano
3c5de5c77b Merge branch 'jk/ansi-color'
The output coloring scheme learned two new attributes, italic and
strike, in addition to existing bold, reverse, etc.

* jk/ansi-color:
  color: support strike-through attribute
  color: support "italic" attribute
  color: allow "no-" for negating attributes
  color: refactor parse_attr
  add skip_prefix_mem helper
  doc: refactor description of color format
  color: fix max-size comment
2016-07-11 10:31:05 -07:00
Nguyễn Thái Ngọc Duy
080739ba1d worktree.c: find_worktree() search by path suffix
This allows the user to do something like "worktree lock foo" or
"worktree lock to/foo" instead of "worktree lock /long/path/to/foo" if
it's unambiguous.

With completion support it could be quite convenient. While this base
name search can be done in the same worktree iteration loop, the code is
split into a separate function for clarity.

Suggested-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-08 15:31:04 -07:00
Nguyễn Thái Ngọc Duy
6d308627ca worktree: add "unlock" command
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-08 15:31:04 -07:00
Nguyễn Thái Ngọc Duy
58142c09a4 worktree: add "lock" command
Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-08 15:31:04 -07:00
Nguyễn Thái Ngọc Duy
3c8ede3ff3 connect: read $GIT_SSH_COMMAND from config file
Similar to $GIT_ASKPASS or $GIT_PROXY_COMMAND, we also read from
config file first then fall back to $GIT_SSH_COMMAND.

This is useful for selecting different private keys targetting the
same host (e.g. github)

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-06 14:04:09 -07:00
Junio C Hamano
5c589a73de Third batch of topics for 2.10
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-06 13:42:58 -07:00
Junio C Hamano
789808fe48 Sync with maint
* maint:
  More fixes for 2.9.1
  mailmap: use main email address for dturner
2016-07-06 13:42:37 -07:00
Junio C Hamano
9f1027d18a Merge branch 'sb/clone-shallow-passthru'
Fix an unintended regression in v2.9 that breaks "clone --depth"
that recurses down to submodules by forcing the submodules to also
be cloned shallowly, which many server instances that host upstream
of the submodules are not prepared for.

* sb/clone-shallow-passthru:
  clone: do not let --depth imply --shallow-submodules
2016-07-06 13:38:13 -07:00
Junio C Hamano
1d77bed8b0 Merge branch 'mg/signature-doc'
Formats of the various data (and how to validate them) where we use
GPG signature have been documented.

* mg/signature-doc:
  Documentation/technical: signed merge tag format
  Documentation/technical: signed commit format
  Documentation/technical: signed tag format
  Documentation/technical: describe signature formats
2016-07-06 13:38:12 -07:00
Junio C Hamano
979f030359 Merge branch 'jk/repack-keep-unreachable'
"git repack" learned the "--keep-unreachable" option, which sends
loose unreachable objects to a pack instead of leaving them loose.
This helps heuristics based on the number of loose objects
(e.g. "gc --auto").

* jk/repack-keep-unreachable:
  repack: extend --keep-unreachable to loose objects
  repack: add --keep-unreachable option
  repack: document --unpack-unreachable option
2016-07-06 13:38:11 -07:00
Junio C Hamano
e25a4ded8a Merge branch 'ew/mboxrd-format-am'
Teach format-patch and mailsplit (hence "am") how a line that
happens to begin with "From " in the e-mail message is quoted with
">", so that these lines can be restored to their original shape.

* ew/mboxrd-format-am:
  am: support --patch-format=mboxrd
  mailsplit: support unescaping mboxrd messages
  pretty: support "mboxrd" output format
2016-07-06 13:38:11 -07:00
Junio C Hamano
1e4bf90789 Merge branch 'jk/upload-pack-hook'
"upload-pack" allows a custom "git pack-objects" replacement when
responding to "fetch/clone" via the uploadpack.packObjectsHook.

* jk/upload-pack-hook:
  upload-pack: provide a hook for running pack-objects
  t1308: do not get fooled by symbolic links to the source tree
  config: add a notion of "scope"
  config: return configset value for current_config_ functions
  config: set up config_source for command-line config
  git_config_parse_parameter: refactor cleanup code
  git_config_with_options: drop "found" counting
2016-07-06 13:38:11 -07:00
Junio C Hamano
7a738b40f6 Merge branch 'nd/worktree-cleanup-post-head-protection'
Further preparatory clean-up for "worktree" feature continues.

* nd/worktree-cleanup-post-head-protection:
  worktree: simplify prefixing paths
  worktree: avoid 0{40}, too many zeroes, hard to read
  worktree.c: use is_dot_or_dotdot()
  git-worktree.txt: keep subcommand listing in alphabetical order
  worktree.c: rewrite mark_current_worktree() to avoid strbuf
  completion: support git-worktree
2016-07-06 13:38:11 -07:00