|
529e873c
|
2017-05-23T11:51:00
|
|
config: pass repository when opening config files
Our current configuration logic is completely oblivious of any
repository, but only cares for actual file paths. Unfortunately, we are
forced to break this assumption by the introduction of conditional
includes, which are evaluated in the context of a repository. Right now,
only one conditional exists with "gitdir:" -- it will only include the
configuration if the current repository's git directory matches the
value passed to "gitdir:".
To support these conditionals, we have to break our API and make the
repository available when opening a configuration file. This commit
extends the `open` call of configuration backends to include another
repository and adjusts existing code to have it available. This includes
the user-visible functions `git_config_add_file_ondisk` and
`git_config_add_backend`.
|
|
37841317
|
2017-07-31T00:38:28
|
|
Remove unused 'sys/remote.h' header
|
|
a78441bc
|
2017-06-13T11:05:40
|
|
Adding git_filter_init for initializing `git_filter` struct + unit test
|
|
7f7dabda
|
2017-06-12T13:40:47
|
|
adding GIT_FILTER_VERSION to GIT_FILTER_INIT as part of convention
|
|
5c760960
|
2017-04-17T13:03:03
|
|
transport: provide a getter for the proxy options
As with the callbacks, third-party implementations of smart subtransports cannot
reach into the opaque struct and thus cannot know what options the user set.
Add a getter for these options to copy the proxy options into something external
implementors can use.
|
|
bb342159
|
2017-03-15T11:46:15
|
|
merge_driver: fix const-correctness for source getters
|
|
4d99c4cf
|
2016-11-23T18:32:48
|
|
Allow for caching of submodules.
Added `git_repository_submodule_cache_all` to initialze a cache of
submodules on the repository so that operations looking up N
submodules are O(N) and not O(N^2). Added a
`git_repository_submodule_cache_clear` function to remove the cache.
Also optimized the function that loads all submodules as it was itself
O(N^2) w.r.t the number of submodules, having to loop through the
`.gitmodules` file once per submodule. I changed it to process the
`.gitmodules` file once, into a map.
Signed-off-by: David Turner <dturner@twosigma.com>
|
|
2749ff46
|
2016-09-13T15:52:43
|
|
time: Export `git_time_monotonic`
|
|
8f09a98e
|
2016-07-14T16:23:24
|
|
odb: freshen existing objects when writing
When writing an object, we calculate its OID and see if it exists in the
object database. If it does, we need to freshen the file that contains
it.
|
|
60d717c6
|
2015-10-02T10:10:13
|
|
proxy: add a payload field for the proxy options
I don't quite recall what we do in the other places where we use this,
but we should pass this payload to the callbacks.
|
|
b373e9a6
|
2015-09-21T22:38:50
|
|
net: use proxy options struct in the stream config
|
|
07bd3e57
|
2015-05-07T12:57:56
|
|
proxy: ask the user for credentials if necessary
|
|
6d8b2cdb
|
2016-02-28T09:34:11
|
|
merge driver: remove `check` callback
Since the `apply` callback can defer, the `check` callback is not
necessary. Removing the `check` callback further makes the `payload`
unnecessary along with the `cleanup` callback.
|
|
3f7d3df1
|
2016-02-27T16:57:12
|
|
merge driver: improve inline documentation
|
|
3f04219f
|
2015-12-23T10:23:08
|
|
merge driver: introduce custom merge drivers
Consumers can now register custom merged drivers with
`git_merge_driver_register`. This allows consumers to support the
merge drivers, as configured in `.gitattributes`. Consumers will be
asked to perform the file-level merge when a custom driver is
configured.
|
|
0f1e2d20
|
2016-02-23T11:23:26
|
|
index: fix contradicting comparison
The overflow check in `read_reuc` tries to verify if the
`git__strtol32` parses an integer bigger than UINT_MAX. The `tmp`
variable is casted to an unsigned int for this and then checked
for being greater than UINT_MAX, which obviously can never be
true.
Fix this by instead fixing the `mode` field's size in `struct
git_index_reuc_entry` to `uint32_t`. We can now parse the int
with `git__strtol64`, which can never return a value bigger than
`UINT32_MAX`, and additionally checking if the returned value is
smaller than zero.
We do not need to handle overflows explicitly here, as
`git__strtol64` returns an error when the returned value would
overflow.
|
|
82abd40d
|
2016-02-07T13:35:16
|
|
filter: clean up documentation around custom filters
|
|
7fafde63
|
2015-10-13T11:25:41
|
|
stream: allow registering a user-provided TLS constructor
This allows the application to use their own TLS stream, regardless of
the capabilities of libgit2 itself.
|
|
bf28da47
|
2015-10-30T14:12:19
|
|
Fix build for custom transport users
We should explicitly include the declaration of git_strarray
from "include/git2/sys/transport.h"
|
|
d3b29fb9
|
2015-10-01T00:50:37
|
|
refdb and odb backends must provide `free` function
As refdb and odb backends can be allocated by client code, libgit2
can’t know whether an alternative memory allocator was used, and thus
should not try to call `git__free` on those objects.
Instead, odb and refdb backend implementations must always provide
their own `free` functions to ensure memory gets freed correctly.
|
|
4f2b6093
|
2015-09-08T13:53:41
|
|
Tell the git_transport about the custom_headers
|
|
47ed7e5a
|
2015-08-18T20:55:59
|
|
transport: provide a way to get the callbacks
libgit2 implementations of smart subtransports can simply reach through
the structure, but external implementors cannot.
Add these two functions as a way for the smart subtransports to get the
callbacks as set by the user.
|
|
b1667039
|
2015-06-01T19:17:03
|
|
config: implement basic transactional support
When a configuration file is locked, any updates made to it will be done
to the in-memory copy of the file. This allows for multiple updates to
happen while we hold the lock, preventing races during complex
config-file manipulation.
|
|
c400bac4
|
2015-08-01T15:38:04
|
|
Merge pull request #3332 from phatblat/ben/doc-warnings
Resolve documentation warnings
|
|
08afd227
|
2015-07-27T18:32:55
|
|
Fix remaining documentation warnings
|
|
f90fbb8d
|
2015-07-27T17:42:08
|
|
Use correct Doxygen trailing comment syntax
|
|
41808d04
|
2015-07-27T14:46:50
|
|
Fix @param names in doc comments
|
|
01d0c02d
|
2015-07-12T19:08:06
|
|
refdb: delete a ref's reflog upon deletion
Removing a reflog upon ref deletion is something which only some
backends might wish to do. Backends which are database-backed may wish
to archive a reflog, log-based ones may not need to do anything.
|
|
63924435
|
2015-07-01T09:40:11
|
|
filters: custom filters with wildcard attributes
Allow custom filters with wildcard attributes, so that clients
can support some random `filter=foo` in a .gitattributes and look
up the corresponding smudge/clean commands in the configuration file.
|
|
1376e784
|
2015-06-07T14:42:13
|
|
stream: add support for setting a proxy
If the stream claims to support this feature, we can let the transport
set the proxy.
We also set HTTPPROXYTUNNEL option so curl can create a tunnel through
the proxy which lets us create our own TLS session (if needed).
|
|
a6f2ceaf
|
2015-05-13T12:11:55
|
|
Merge pull request #3118 from libgit2/cmn/stream-size
odb: make the writestream's size a git_off_t
|
|
058b753c
|
2015-04-22T15:45:21
|
|
remote: move the transport ctor to the callbacks
Instead of having it set in a different place from every other callback,
put it the main structure. This removes some state from the remote and
makes it behave more like clone, where the constructors are passed via
the options.
|
|
8f0104ec
|
2015-04-21T22:10:36
|
|
Remove the callbacks struct from the remote
Having the setting be different from calling its actions was not a great
idea and made for the sake of the wrong convenience.
Instead of that, accept either fetch options, push options or the
callbacks when dealing with the remote. The fetch options are currently
only the callbacks, but more options will be moved from setters and
getters on the remote to the options.
This does mean passing the same struct along the different functions but
the typical use-case will only call git_remote_fetch() or
git_remote_push() and so won't notice much difference.
|
|
77b339f7
|
2015-05-12T13:06:33
|
|
odb: make the writestream's size a git_off_t
Restricting files to size_t is a silly limitation. The loose backend
writes to a file directly, so there is no issue in using 63 bits for the
size.
We still assume that the header is going to fit in 64 bytes, which does
mean quite a bit smaller files due to the run-length encoding, but it's
still a much larger size than you would want Git to handle.
|
|
142e5379
|
2015-03-17T12:49:33
|
|
Add a custom param to git_smart_subtransport_definition
The smart transport has already take the payload param. For the
sub transport a payload param is useful for the implementer.
|
|
9a97f49e
|
2014-12-21T15:31:03
|
|
config: borrow refcounted references
This changes the get_entry() method to return a refcounted version of
the config entry, which you have to free when you're done.
This allows us to avoid freeing the memory in which the entry is stored
on a refresh, which may happen at any time for a live config.
For this reason, get_string() has been forbidden on live configs and a
new function get_string_buf() has been added, which stores the string in
a git_buf which the user then owns.
The functions which parse the string value takea advantage of the
borrowing to parse safely and then release the entry.
|
|
795eaccd
|
2015-02-19T11:09:54
|
|
git_filter_opt_t -> git_filter_flag_t
For consistency with the rest of the library, where an opt is an
options *structure*.
|
|
b75f15aa
|
2015-02-18T09:25:32
|
|
git_writestream: from git_filter_stream
|
|
fbdc9db3
|
2015-01-22T16:10:06
|
|
filters: introduce streaming filters
Add structures and preliminary functions to take a buffer, file or
blob and write the contents in chunks through an arbitrary number
of chained filters, finally writing into a user-provided function
accept the contents.
|
|
a36486ef
|
2015-02-11T10:31:54
|
|
Fixed error when including git2/include/sys/stream.h
|
|
f483720c
|
2015-01-26T11:25:16
|
|
Merge pull request #2839 from swisspol/typo
Fixed typo in git_repository_reinit_filesystem() documentation
|
|
86815dca
|
2015-01-23T16:04:23
|
|
Make sure sys/repository.h includes the required headers
It was missing "common.h" and "types.h" like other system headers.
This generated compilation errors if including it directly.
|
|
22b6a923
|
2015-01-23T15:59:54
|
|
Fixed typo in git_repository_reinit_filesystem() documentation
|
|
85880693
|
2015-01-14T10:19:28
|
|
Merge branch 'pr/2740'
|
|
36fc5497
|
2014-12-02T05:11:12
|
|
Added GIT_HASHSIG_ALLOW_SMALL_FILES to allow computing signatures for small files
The implementation of the hashsig API disallows computing a signature on
small files containing only a few lines. This new flag disables this
behavior.
git_diff_find_similar() sets this flag by default which means that rename
/ copy detection of small files will now work. This in turn affects the
behavior of the git_status and git_blame APIs which will now detect rename
of small files assuming the right options are passed.
|
|
d76e9df9
|
2015-01-02T15:56:03
|
|
Include git2/common.h in sys/openssl.h.
|
|
2fe8157e
|
2014-12-22T18:42:03
|
|
index: reuc and name entrycounts should be size_t
For the REUC and NAME entries, we use size_t internally, and we take
size_t for the get_byindex() functions, but the entrycount() functions
strangely cast to an unsigned int instead.
|
|
d147900e
|
2014-12-20T21:24:45
|
|
Merge pull request #2759 from libgit2/cmn/openssl-sys
Make OpenSSL locking warnings more severe
|
|
ceb651c9
|
2014-12-19T15:31:49
|
|
Fix public header on sys/refs.h
GIT_BEGIN/END_DECL were missing from sys/refs.h and preventing
compilation with g++ as the symbol were mangled.
|
|
263b1d6e
|
2014-12-12T08:29:43
|
|
Make the OpenSSL locking function warnings more severe
Our git_openssl_set_locking() would ideally not exist. Make it clearer
that we provide it as a last resort and you should prefer anything else.
|
|
cd305c2f
|
2014-12-10T11:30:28
|
|
Merge pull request #2678 from libgit2/cmn/io-stream
Introduce stackable IO streams
|
|
49ae22ba
|
2014-12-10T01:38:52
|
|
stream: constify the write buffer
|
|
dd4ff2c9
|
2014-11-01T12:35:54
|
|
Introduce stackable IO streams
We currently have gitno for talking over TCP, but this needs to know
about both plaintext and OpenSSL connections and the code has gotten
somewhat messy with ifdefs determining which version of the function
should be called.
In order to clean this up and abstract away the details of sending over
the different types of streams, we can instead use an interface and
stack stream implementations.
We may not be able to use the stackability with all streams, but we
are definitely be able to use the abstraction which is currently spread
between different bits of gitno.
|
|
a295bd2d
|
2014-12-06T03:36:18
|
|
doc: add documentation to all the public structs and enums
This makes them show up in the reference, even if the text itself isn't
the most descriptive.
These have been found with
grep -Przon '\n\ntypedef struct.*?\{' -- include
grep -Przon '\n\ntypedef enum.*?\{' -- include
|
|
b874629b
|
2014-12-04T21:06:59
|
|
Spelling fixes
|
|
55cb4999
|
2014-10-23T19:05:02
|
|
config: remove the refresh function and backend field
We have been refreshing on read and write for a while now, so
git_config_refresh() is at best a no-op, and might just end up wasting
cycles.
|
|
10cf4b26
|
2014-10-09T10:49:37
|
|
Merge pull request #2448 from libgit2/cmn/reference-transaction
Introduce reference transactions
|
|
737b5051
|
2014-10-01T12:03:24
|
|
hashsig: Export as a `sys` header
|
|
ab8d9242
|
2014-06-28T06:39:38
|
|
Introduce reference transactions
A transaction allows you to lock multiple references and set up changes
for them before applying the changes all at once (or as close as the
backend supports).
This can be used for replication purposes, or for making sure some
operations run when the reference is locked and thus cannot be changed.
|
|
1312f87b
|
2014-09-17T14:56:39
|
|
Merge pull request #2464 from libgit2/cmn/host-cert-info
Provide a callback for certificate validation
|
|
41698f22
|
2014-09-11T10:04:05
|
|
net: remove support for outright ignoring certificates
This option make it easy to ignore anything about the server we're
connecting to, which is bad security practice. This was necessary as we
didn't use to expose detailed information about the certificate, but now
that we do, we should get rid of this.
If the user wants to ignore everything, they can still provide a
callback which ignores all the information passed.
|
|
9b940586
|
2014-07-04T12:45:43
|
|
Provide a callback for certificate validation
If the certificate validation fails (or always in the case of ssh),
let the user decide whether to allow the connection.
The data structure passed to the user is the native certificate
information from the underlying implementation, namely OpenSSL or
WinHTTP.
|
|
1fbeb2f0
|
2014-09-15T21:59:23
|
|
Fix attribute lookup in index for bare repos
When using a bare repo with an index, libgit2 attempts to read
files from the index. It caches those files based on the path
to the file, specifically the path to the directory that contains
the file.
If there is no working directory, we use `git_path_dirname_r` to
get the path to the containing directory. However, for the
`.gitattributes` file in the root of the repository, this ends up
normalizing the containing path to `"."` instead of the empty
string and the lookup the `.gitattributes` data fails.
This adds a test of attribute lookups on bare repos and also
fixes the problem by simply rewriting `"."` to be `""`.
|
|
c180c065
|
2014-07-09T17:58:39
|
|
Custom transport: minor cleanups
* Move the transport registration mechanisms into a new header under
'sys/' because this is advanced stuff.
* Remove the 'priority' argument from the registration as it adds
unnecessary complexity. (Since transports cannot decline to operate,
only the highest priority transport is ever executed.) Users who
require per-priority transports can implement that in their custom
transport themselves.
* Simplify registration further by taking a scheme (eg "http") instead
of a prefix (eg "http://").
|
|
d2c4d1c6
|
2014-05-12T10:04:52
|
|
Merge pull request #2188 from libgit2/cmn/config-snapshot
Configuration snapshotting
|
|
45c53eb6
|
2014-05-08T10:46:04
|
|
Use unsigned type for APIs with opt flag mask
|
|
5269008c
|
2014-05-06T16:01:49
|
|
Add filter options and ALLOW_UNSAFE
Diff and status do not want core.safecrlf to actually raise an
error regardless of the setting, so this extends the filter API
with an additional options flags parameter and adds a flag so that
filters can be applied with GIT_FILTER_OPT_ALLOW_UNSAFE, indicating
that unsafe filter application should be downgraded from a failure
to a warning.
|
|
bc91347b
|
2014-04-30T11:16:31
|
|
Fix remaining init_options inconsistencies
There were a couple of "init_opts()" functions a few more cases
of structure initialization that I somehow missed.
|
|
9c8ed499
|
2014-04-29T15:05:58
|
|
Remove trace / add git_diff_perfdata struct + api
|
|
48e60ae7
|
2014-04-21T11:23:29
|
|
Don't redefine the same callback types, their signatures may change
|
|
523032cd
|
2014-03-31T09:58:44
|
|
config: refresh before reading a value
With the isolation of complex reads, we can now try to refresh the
on-disk file before reading a value from it.
This changes the semantics a bit, as before we could be sure that a
string we got from the configuration was valid until we wrote or
refreshed. This is no longer the case, as a read can also invalidate the
pointer.
|
|
55ebd7d3
|
2014-03-13T17:11:34
|
|
config: implement config snapshotting
In order to have consistent views of the config files for remotes,
submodules et al. and a configuration that represents what is currently
stored on-disk, we need a way to provide a view of the configuration
that does not change.
The goal here is to provide the snapshotting part by creating a
read-only copy of the state of the configuration at a particular point
in time, which does not change when a repository's main config changes.
|
|
27e54bcf
|
2014-02-07T14:17:19
|
|
Add public diff print helpers
The usefulness of these helpers came up for me while debugging
some of the iterator changes that I was making, so since they
have also been requested (albeit indirectly) I thought I'd include
them.
|
|
6105d597
|
2014-03-26T18:17:08
|
|
In-memory packing backend
|
|
b9f81997
|
2014-03-05T21:49:23
|
|
Added function-based initializers for every options struct.
The basic structure of each function is courtesy of arrbee.
|
|
f5753999
|
2014-03-04T15:34:23
|
|
Add exists_prefix to ODB backend and ODB API
|
|
80c29fe9
|
2014-01-17T10:45:11
|
|
Add git_commit_amend API
This adds an API to amend an existing commit, basically a shorthand
for creating a new commit filling in missing parameters from the
values of an existing commit. As part of this, I also added a new
"sys" API to create a commit using a callback to get the parents.
This allowed me to rewrite all the other commit creation APIs so
that temporary allocations are no longer needed.
|
|
7ee8c7e6
|
2014-02-05T11:07:34
|
|
refs: placeholder conditional delete
We don't actually pass the old value yet.
|
|
91123661
|
2014-02-04T22:04:00
|
|
refdb: add conditional symbolic updates
Add a parameter to the backend to allow checking for the old symbolic
target.
|
|
9b148098
|
2013-12-18T19:58:16
|
|
refs: conditional ref updates
Allow updating references if the old value matches the given one.
|
|
47e28349
|
2014-01-24T12:01:34
|
|
commit: remvoe legacy 'oid' naming
|
|
4e1f517c
|
2013-12-18T09:33:45
|
|
Merge pull request #1920 from libgit2/cmn/ref-with-log
Reference operations with log
|
|
9cfce273
|
2013-12-12T12:11:38
|
|
Cleanups, renames, and leak fixes
This renames git_vector_free_all to the better git_vector_free_deep
and also contains a couple of memory leak fixes based on valgrind
checks. The fixes are specifically: failure to free global dir
path variables when not compiled with threading on and failure to
free filters from the filter registry that had not be initialized
fully.
|
|
f2105129
|
2013-11-23T14:39:53
|
|
refs: expose has_log() on the backend
The frontend used to look at the file directly, but that's obviously not
the right thing to do. Expose it on the backend and use that function
instead.
|
|
8d5ec910
|
2013-11-23T14:13:01
|
|
refs: expose a way to ensure a ref has a log
Sometimes (e.g. stash) we want to make sure that a log will be written,
even if it's not in one of the standard locations. Let's make that
easier.
|
|
a57dd3b7
|
2013-11-13T18:15:20
|
|
reflog: integrate into the ref writing
Whenever a reference is created or updated, we need to write to the
reflog regardless of whether the user gave us a message, so we shouldn't
leave that to the ref frontend, but integrate it into the backend.
This also eliminates the race between ref update and writing to the
reflog, as we protect the reflog with the ref lock.
As an additional benefit, this reflog append on the backend happens by
appending to the file instead of parsing and rewriting it.
|
|
110df893
|
2013-11-13T13:36:37
|
|
refdb: add a `message` parameter for appending to the log
This is as yet unused.
|
|
3793fa9b
|
2013-10-31T01:08:50
|
|
Fix saving remotes with several fetch/push ref specs.
At some moment git_config_delete_entry lost the ability to delete one entry of
a multivar configuration. The moment you had more than one fetch or push
ref spec for a remote you will not be able to save that remote anymore. The
changes in network::remote::remotes::save show that problem.
I needed to create a new git_config_delete_multivar because I was not able to
remove one or several entries of a multivar config with the current API.
Several tries modifying how git_config_set_multivar(..., NULL) behaved were
not successful.
git_config_delete_multivar is very similar to git_config_set_multivar, and
delegates into config_delete_multivar of config_file. This function search
for the cvar_t that will be deleted, storing them in a temporal array, and
rebuilding the linked list. After calling config_write to delete the entries,
the cvar_t stored in the temporal array are freed.
There is a little fix in config_write, it avoids an infinite loop when using
a regular expression (case for the multivars). This error was found by the
test network::remote::remotes::tagopt.
|
|
5c50f22a
|
2013-10-28T09:25:44
|
|
Merge pull request #1891 from libgit2/cmn/fix-thin-packs
Add support for thin packs
|
|
8f4a8b09
|
2013-10-28T06:20:28
|
|
Merge pull request #1802 from libgit2/cmn/reflog-backend
Make reflog part of refdb
|
|
867f7c9b
|
2013-10-08T16:59:59
|
|
Rename new fn to git_repository_reinit_filesystem
|
|
92dac975
|
2013-10-08T16:35:57
|
|
Make reference lookups apply precomposeunicode
Before these changes, looking up a reference would return the
same precomposed or decomposed form of the reference name that
was used to look it up, so on MacOS which ignores the difference
between the two, a single reference could be looked up either way
and git_reference_name would return the form of the name that was
used to look it up! This change makes lookup always return the
precomposed name if core.precomposeunicode is set regardless of
which version was used to look it up. The reference iterator was
already returning the precomposed form from earlier work.
This also updates the CMakeLists.txt rules for enabling iconv
usage because the clar tests for this code were actually not being
activated properly with the old version.
Finally, this moves git_repository_reset_filesystem from include/
git2/repository.h to include/git2/sys/repository.h since it is not
really a function that normal library users should have to think
about very often.
|
|
0b33fca0
|
2013-10-02T13:39:35
|
|
indexer: fix thin packs
When given an ODB from which to read objects, the indexer will attempt
to inject the missing bases at the end of the pack and update the
header and trailer to reflect the new contents.
|
|
0174794a
|
2013-08-21T05:12:49
|
|
reflog: bring _append and _drop back to the frontend
These functions act purely on the reflog data structure.
|
|
b976f3c2
|
2013-08-19T13:01:49
|
|
reflog: move the reflog implementation into refdb_fs
References and their logs are logically coupled, let's make it so in
the code by moving the fs-based reflog implementation to live next to
the fs-based refs one.
As part of the change, make the function take names rather than
references, as only the names are relevant when looking up and
handling reflogs.
|
|
e0b267af
|
2013-09-25T10:49:25
|
|
That's the refdb, it's not the odb...
|
|
e3f3868a
|
2013-09-24T11:04:14
|
|
'del' instead of 'delete' for the poor C++ users
|
|
eefc32d5
|
2013-09-16T12:54:40
|
|
Bug fixes and cleanups
This contains a few bug fixes and some header and API cleanups.
The main API change is that filters should now use GIT_PASSTHROUGH
to indicate that they wish to skip processing a file instead of
GIT_ENOTFOUND.
The bug fixes include a possible out-of-range buffer access in
the ident filter, a filter ordering problem I introduced into the
custom filter tests on Windows, and a filter buf NUL termination
issue that was coming up on Linux.
|
|
eab3746b
|
2013-09-15T22:23:39
|
|
More filtering tests including order
This adds more tests of filters, including the ident filter when
mixed with custom filters. I was able to combine with the reverse
filter and demonstrate that the order of filter application with
the default priority constants matches the order of core Git.
Also, this fixes two issues in the ident filter: preventing ident
expansion on binary files and avoiding a NULL dereference when
dollar sign characters are found without Id.
|
|
b47349b8
|
2013-09-12T14:48:24
|
|
Port tests from PR 1683
This ports over some of the tests from
https://github.com/libgit2/libgit2/pull/1683
by @yorah and @ethomson
|