Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2022-11-28Merge branch 'pw/config-int-parse-fixes'Junio C Hamano
Assorted fixes of parsing end-user input as integers. * pw/config-int-parse-fixes: git_parse_signed(): avoid integer overflow config: require at least one digit when parsing numbers git_parse_unsigned: reject negative values
2022-11-10git_parse_signed(): avoid integer overflowPhillip Wood
git_parse_signed() checks that the absolute value of the parsed string is less than or equal to a caller supplied maximum value. When calculating the absolute value there is a integer overflow if `val == INTMAX_MIN`. To fix this avoid negating `val` when it is negative by having separate overflow checks for positive and negative values. An alternative would be to special case INTMAX_MIN before negating `val` as it is always out of range. That would enable us to keep the existing code but I'm not sure that the current two-stage check is any clearer than the new version. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-10config: require at least one digit when parsing numbersPhillip Wood
If the input to strtoimax() or strtoumax() does not contain any digits then they return zero and set `end` to point to the start of the input string. git_parse_[un]signed() do not check `end` and so fail to return an error and instead return a value of zero if the input string is a valid units factor without any digits (e.g "k"). Tests are added to check that 'git config --int' and OPT_MAGNITUDE() reject a units specifier without a leading digit. Helped-by: Jeff King <peff@peff.net> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-10git_parse_unsigned: reject negative valuesPhillip Wood
git_parse_unsigned() relies on strtoumax() which unfortunately parses negative values as large positive integers. Fix this by rejecting any string that contains '-' as we do in strtoul_ui(). I've chosen to treat negative numbers as invalid input and set errno to EINVAL rather than ERANGE one the basis that they are never acceptable if we're looking for a unsigned integer. This is also consistent with the existing behavior of rejecting "1–2" with EINVAL. As we do not have unit tests for this function it is tested indirectly by checking that negative values of reject for core.bigFileThreshold are rejected. As this function is also used by OPT_MAGNITUDE() a test is added to check that rejects negative values too. Helped-by: Jeff King <peff@peff.net> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-10-31Merge branch 'ds/bundle-uri-3'Taylor Blau
Define the logical elements of a "bundle list", data structure to store them in-core, format to transfer them, and code to parse them. * ds/bundle-uri-3: bundle-uri: suppress stderr from remote-https bundle-uri: quiet failed unbundlings bundle: add flags to verify_bundle() bundle-uri: fetch a list of bundles bundle: properly clear all revision flags bundle-uri: limit recursion depth for bundle lists bundle-uri: parse bundle list in config format bundle-uri: unit test "key=value" parsing bundle-uri: create "key=value" line parsing bundle-uri: create base key-value pair parsing bundle-uri: create bundle_list struct and helpers bundle-uri: use plain string in find_temp_filename()
2022-10-26Merge branch 'gc/bare-repo-discovery'Junio C Hamano
Allow configuration files in "protected" scopes to include other configuration files. * gc/bare-repo-discovery: config: respect includes in protected config
2022-10-13config: respect includes in protected configGlen Choo
Protected config is implemented by reading a fixed set of paths, which ignores config [include]-s. Replace this implementation with a call to config_with_options(), which handles [include]-s and saves us from duplicating the logic of 1) identifying which paths to read and 2) reading command line config. As a result, git_configset_add_parameters() is unused, so remove it. It was introduced alongside protected config in 5b3c650777 (config: learn `git_protected_config()`, 2022-07-14) as a way to handle command line config. Signed-off-by: Glen Choo <chooglen@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-10-12bundle-uri: create base key-value pair parsingDerrick Stolee
There will be two primary ways to advertise a bundle list: as a list of packet lines in Git's protocol v2 and as a config file served from a bundle URI. Both of these fundamentally use a list of key-value pairs. We will use the same set of key-value pairs across these formats. Create a new bundle_list_update() method that is currently unusued, but will be used in the next change. It inspects each key to see if it is understood and then applies it to the given bundle_list. Here are the keys that we teach Git to understand: * bundle.version: This value should be an integer. Git currently understands only version 1 and will ignore the list if the version is any other value. This version can be increased in the future if we need to add new keys that Git should not ignore. We can add new "heuristic" keys without incrementing the version. * bundle.mode: This value should be one of "all" or "any". If this mode is not understood, then Git will ignore the list. This mode indicates whether Git needs all of the bundle list items to make a complete view of the content or if any single item is sufficient. The rest of the keys use a bundle identifier "<id>" as part of the key name. Keys using the same "<id>" describe a single bundle list item. * bundle.<id>.uri: This stores the URI of the bundle item. This currently is expected to be an absolute URI, but will be relaxed to be a relative URI in the future. While parsing, return an error if a URI key is repeated, since we can make that restriction with bundle lists. Make the git_parse_int() method global so we can parse the integer version value carefully. Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-09-01git-compat-util.h: use "UNUSED", not "UNUSED(var)"Ævar Arnfjörð Bjarmason
As reported in [1] the "UNUSED(var)" macro introduced in 2174b8c75de (Merge branch 'jk/unused-annotation' into next, 2022-08-24) breaks coccinelle's parsing of our sources in files where it occurs. Let's instead partially go with the approach suggested in [2] of making this not take an argument. As noted in [1] "coccinelle" will ignore such tokens in argument lists that it doesn't know about, and it's less of a surprise to syntax highlighters. This undoes the "help us notice when a parameter marked as unused is actually use" part of 9b240347543 (git-compat-util: add UNUSED macro, 2022-08-19), a subsequent commit will further tweak the macro to implement a replacement for that functionality. 1. https://lore.kernel.org/git/220825.86ilmg4mil.gmgdl@evledraar.gmail.com/ 2. https://lore.kernel.org/git/220819.868rnk54ju.gmgdl@evledraar.gmail.com/ Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-08-19hashmap: mark unused callback parametersJeff King
Hashmap comparison functions must conform to a particular callback interface, but many don't use all of their parameters. Especially the void cmp_data pointer, but some do not use keydata either (because they can easily form a full struct to pass when doing lookups). Let's mark these to make -Wunused-parameter happy. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-08-19config: mark unused callback parametersJeff King
The callback passed to git_config() must conform to a particular interface. But most callbacks don't actually look at the extra "void *data" parameter. Let's mark the unused parameters to make -Wunused-parameter happy. Note there's one unusual case here in get_remote_default() where we actually ignore the "value" parameter. That's because it's only checking whether the option is found at all, and not parsing its value. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-07-27config.c: NULL check when reading protected configGlen Choo
In read_protected_config(), check whether each file name is NULL before attempting to read it, and add a BUG() call to git_config_from_file_with_options() to make this error easier to catch in the future. The NULL checks mirror what do_git_config_sequence() does (which read_protected_config() is modeled after). Without these NULL checks, multiple tests fail with "make SANITIZE=address", e.g. in the final test of t4010, xdg_config is NULL causing us to call fopen(NULL). Reported-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Glen Choo <chooglen@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-07-15config: learn `git_protected_config()`Glen Choo
`uploadpack.packObjectsHook` is the only 'protected configuration only' variable today, but we've noted that `safe.directory` and the upcoming `safe.bareRepository` should also be 'protected configuration only'. So, for consistency, we'd like to have a single implementation for protected configuration. The primary constraints are: 1. Reading from protected configuration should be fast. Nearly all "git" commands inside a bare repository will read both `safe.directory` and `safe.bareRepository`, so we cannot afford to be slow. 2. Protected configuration must be readable when the gitdir is not known. `safe.directory` and `safe.bareRepository` both affect repository discovery and the gitdir is not known at that point [1]. The chosen implementation in this commit is to read protected configuration and cache the values in a global configset. This is similar to the caching behavior we get with the_repository->config. Introduce git_protected_config(), which reads protected configuration and caches them in the global configset protected_config. Then, refactor `uploadpack.packObjectsHook` to use git_protected_config(). The protected configuration functions are named similarly to their non-protected counterparts, e.g. git_protected_config_check_init() vs git_config_check_init(). In light of constraint 1, this implementation can still be improved. git_protected_config() iterates through every variable in protected_config, which is wasteful, but it makes the conversion simple because it matches existing patterns. We will likely implement constant time lookup functions for protected configuration in a future series (such functions already exist for non-protected configuration, i.e. repo_config_get_*()). An alternative that avoids introducing another configset is to continue to read all config using git_config(), but only accept values that have the correct config scope [2]. This technically fulfills constraint 2, because git_config() simply ignores the local and worktree config when the gitdir is not known. However, this would read incomplete config into the_repository->config, which would need to be reset when the gitdir is known and git_config() needs to read the local and worktree config. Resetting the_repository->config might be reasonable while we only have these 'protected configuration only' variables, but it's not clear whether this extends well to future variables. [1] In this case, we do have a candidate gitdir though, so with a little refactoring, it might be possible to provide a gitdir. [2] This is how `uploadpack.packObjectsHook` was implemented prior to this commit. Signed-off-by: Glen Choo <chooglen@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-06-04Merge branch 'ns/batch-fsync'Junio C Hamano
Introduce a filesystem-dependent mechanism to optimize the way the bits for many loose object files are ensured to hit the disk platter. * ns/batch-fsync: core.fsyncmethod: performance tests for batch mode t/perf: add iteration setup mechanism to perf-lib core.fsyncmethod: tests for batch mode test-lib-functions: add parsing helpers for ls-files and ls-tree core.fsync: use batch mode and sync loose objects by default on Windows unpack-objects: use the bulk-checkin infrastructure update-index: use the bulk-checkin infrastructure builtin/add: add ODB transaction around add_files_to_cache cache-tree: use ODB transaction around writing a tree core.fsyncmethod: batched disk flushes for loose-objects bulk-checkin: rebrand plug/unplug APIs as 'odb transactions' bulk-checkin: rename 'state' variable and separate 'plugged' boolean
2022-05-27Merge branch 'tk/simple-autosetupmerge'Junio C Hamano
"git -c branch.autosetupmerge=simple branch $A $B" will set the $B as $A's upstream only when $A and $B shares the same name, and "git -c push.default=simple" on branch $A would push to update the branch $A at the remote $B came from. Also more places use the sole remote, if exists, before defaulting to 'origin'. * tk/simple-autosetupmerge: push: new config option "push.autoSetupRemote" supports "simple" push push: default to single remote even when not named origin branch: new autosetupmerge option 'simple' for matching branches
2022-05-21Merge branch 'ep/maint-equals-null-cocci'Junio C Hamano
Introduce and apply coccinelle rule to discourage an explicit comparison between a pointer and NULL, and applies the clean-up to the maintenance track. * ep/maint-equals-null-cocci: tree-wide: apply equals-null.cocci tree-wide: apply equals-null.cocci contrib/coccinnelle: add equals-null.cocci
2022-05-02Merge branch 'ep/maint-equals-null-cocci' for maint-2.35Junio C Hamano
* ep/maint-equals-null-cocci: tree-wide: apply equals-null.cocci contrib/coccinnelle: add equals-null.cocci
2022-05-02tree-wide: apply equals-null.cocciJunio C Hamano
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-04-29branch: new autosetupmerge option 'simple' for matching branchesTao Klerks
With the default push.default option, "simple", beginners are protected from accidentally pushing to the "wrong" branch in centralized workflows: if the remote tracking branch they would push to does not have the same name as the local branch, and they try to do a "default push", they get an error and explanation with options. There is a particular centralized workflow where this often happens: a user branches to a new local topic branch from an existing remote branch, eg with "checkout -b feature1 origin/master". With the default branch.autosetupmerge configuration (value "true"), git will automatically add origin/master as the upstream tracking branch. When the user pushes with a default "git push", with the intention of pushing their (new) topic branch to the remote, they get an error, and (amongst other things) a suggestion to run "git push origin HEAD". If they follow this suggestion the push succeeds, but on subsequent default pushes they continue to get an error - so eventually they figure out to add "-u" to change the tracking branch, or they spelunk the push.default config doc as proposed and set it to "current", or some GUI tooling does one or the other of these things for them. When one of their coworkers later works on the same topic branch, they don't get any of that "weirdness". They just "git checkout feature1" and everything works exactly as they expect, with the shared remote branch set up as remote tracking branch, and push and pull working out of the box. The "stable state" for this way of working is that local branches have the same-name remote tracking branch (origin/feature1 in this example), and multiple people can work on that remote feature branch at the same time, trusting "git pull" to merge or rebase as required for them to be able to push their interim changes to that same feature branch on that same remote. (merging from the upstream "master" branch, and merging back to it, are separate more involved processes in this flow). There is a problem in this flow/way of working, however, which is that the first user, when they first branched from origin/master, ended up with the "wrong" remote tracking branch (different from the stable state). For a while, before they pushed (and maybe longer, if they don't use -u/--set-upstream), their "git pull" wasn't getting other users' changes to the feature branch - it was getting any changes from the remote "master" branch instead (a completely different class of changes!) An experienced git user might say "well yeah, that's what it means to have the remote tracking branch set to origin/master!" - but the original user above didn't *ask* to have the remote master branch added as remote tracking branch - that just happened automatically when they branched their feature branch. They didn't necessarily even notice or understand the meaning of the "set up to track 'origin/master'" message when they created the branch - especially if they are using a GUI. Looking at how to fix this, you might think "OK, so disable auto setup of remote tracking - set branch.autosetupmerge to false" - but that will inconvenience the *second* user in this story - the one who just wanted to start working on the topic branch. The first and second users swap roles at different points in time of course - they should both have a sane configuration that does the right thing in both situations. Make this "branches have the same name locally as on the remote" workflow less painful / more obvious by introducing a new branch.autosetupmerge option called "simple", to match the same-name "push.default" option that makes similar assumptions. This new option automatically sets up tracking in a *subset* of the current default situations: when the original ref is a remote tracking branch *and* has the same branch name on the remote (as the new local branch name). Update the error displayed when the 'push.default=simple' configuration rejects a mismatching-upstream-name default push, to offer this new branch.autosetupmerge option that will prevent this class of error. With this new configuration, in the example situation above, the first user does *not* get origin/master set up as the tracking branch for the new local branch. If they "git pull" in their new local-only branch, they get an error explaining there is no upstream branch - which makes sense and is helpful. If they "git push", they get an error explaining how to push *and* suggesting they specify --set-upstream - which is exactly the right thing to do for them. This new option is likely not appropriate for users intentionally implementing a "triangular workflow" with a shared upstream tracking branch, that they "git pull" in and a "private" feature branch that they push/force-push to just for remote safe-keeping until they are ready to push up to the shared branch explicitly/separately. Such users are likely to prefer keeping the current default merge.autosetupmerge=true behavior, and change their push.default to "current". Also extend the existing branch tests with three new cases testing this option - the obvious matching-name and non-matching-name cases, and also a non-matching-ref-type case. The matching-name case needs to temporarily create an independent repo to fetch from, as the general strategy of using the local repo as the remote in these tests precludes locally branching with the same name as in the "remote". Signed-off-by: Tao Klerks <tao@klerks.biz> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-04-06core.fsync: use batch mode and sync loose objects by default on WindowsNeeraj Singh
Git for Windows has defaulted to core.fsyncObjectFiles=true since September 2017. We turn on syncing of loose object files with batch mode in upstream Git so that we can get broad coverage of the new code upstream. We don't actually do fsyncs in the most of the test suite, since GIT_TEST_FSYNC is set to 0. However, we do exercise all of the surrounding batch mode code since GIT_TEST_FSYNC merely makes the maybe_fsync wrapper always appear to succeed. Signed-off-by: Neeraj Singh <neerajsi@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-04-06core.fsyncmethod: batched disk flushes for loose-objectsNeeraj Singh
When adding many objects to a repo with `core.fsync=loose-object`, the cost of fsync'ing each object file can become prohibitive. One major source of the cost of fsync is the implied flush of the hardware writeback cache within the disk drive. This commit introduces a new `core.fsyncMethod=batch` option that batches up hardware flushes. It hooks into the bulk-checkin odb-transaction functionality, takes advantage of tmp-objdir, and uses the writeout-only support code. When the new mode is enabled, we do the following for each new object: 1a. Create the object in a tmp-objdir. 2a. Issue a pagecache writeback request and wait for it to complete. At the end of the entire transaction when unplugging bulk checkin: 1b. Issue an fsync against a dummy file to flush the log and hardware writeback cache, which should by now have seen the tmp-objdir writes. 2b. Rename all of the tmp-objdir files to their final names. 3b. When updating the index and/or refs, we assume that Git will issue another fsync internal to that operation. This is not the default today, but the user now has the option of syncing the index and there is a separate patch series to implement syncing of refs. On a filesystem with a singular journal that is updated during name operations (e.g. create, link, rename, etc), such as NTFS, HFS+, or XFS we would expect the fsync to trigger a journal writeout so that this sequence is enough to ensure that the user's data is durable by the time the git command returns. This sequence also ensures that no object files appear in the main object store unless they are fsync-durable. Batch mode is only enabled if core.fsync includes loose-objects. If the legacy core.fsyncObjectFiles setting is enabled, but core.fsync does not include loose-objects, we will use file-by-file fsyncing. In step (1a) of the sequence, the tmp-objdir is created lazily to avoid work if no loose objects are ever added to the ODB. We use a tmp-objdir to maintain the invariant that no loose-objects are visible in the main ODB unless they are properly fsync-durable. This is important since future ODB operations that try to create an object with specific contents will silently drop the new data if an object with the target hash exists without checking that the loose-object contents match the hash. Only a full git-fsck would restore the ODB to a functional state where dataloss doesn't occur. In step (1b) of the sequence, we issue a fsync against a dummy file created specifically for the purpose. This method has a little higher cost than using one of the input object files, but makes adding new callers of this mechanism easier, since we don't need to figure out which object file is "last" or risk sharing violations by caching the fd of the last object file. _Performance numbers_: Linux - Hyper-V VM running Kernel 5.11 (Ubuntu 20.04) on a fast SSD. Mac - macOS 11.5.1 running on a Mac mini on a 1TB Apple SSD. Windows - Same host as Linux, a preview version of Windows 11. Adding 500 files to the repo with 'git add' Times reported in seconds. object file syncing | Linux | Mac | Windows --------------------|-------|-------|-------- disabled | 0.06 | 0.35 | 0.61 fsync | 1.88 | 11.18 | 2.47 batch | 0.15 | 0.41 | 1.53 Signed-off-by: Neeraj Singh <neerajsi@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-04-06Merge branch 'ns/core-fsyncmethod' into ns/batch-fsyncJunio C Hamano
* ns/core-fsyncmethod: configure.ac: fix HAVE_SYNC_FILE_RANGE definition core.fsyncmethod: correctly camel-case warning message core.fsync: fix incorrect expression for default configuration core.fsync: documentation and user-friendly aggregate options core.fsync: new option to harden the index core.fsync: add configuration parsing core.fsync: introduce granular fsync control infrastructure core.fsyncmethod: add writeout-only mode wrapper: make inclusion of Windows csprng header tightly scoped
2022-04-04Merge branch 'jh/builtin-fsmonitor-part2'Junio C Hamano
Built-in fsmonitor (part 2). * jh/builtin-fsmonitor-part2: (30 commits) t7527: test status with untracked-cache and fsmonitor--daemon fsmonitor: force update index after large responses fsmonitor--daemon: use a cookie file to sync with file system fsmonitor--daemon: periodically truncate list of modified files t/perf/p7519: add fsmonitor--daemon test cases t/perf/p7519: speed up test on Windows t/perf/p7519: fix coding style t/helper/test-chmtime: skip directories on Windows t/perf: avoid copying builtin fsmonitor files into test repo t7527: create test for fsmonitor--daemon t/helper/fsmonitor-client: create IPC client to talk to FSMonitor Daemon help: include fsmonitor--daemon feature flag in version info fsmonitor--daemon: implement handle_client callback compat/fsmonitor/fsm-listen-darwin: implement FSEvent listener on MacOS compat/fsmonitor/fsm-listen-darwin: add MacOS header files for FSEvent compat/fsmonitor/fsm-listen-win32: implement FSMonitor backend on Windows fsmonitor--daemon: create token-based changed path cache fsmonitor--daemon: define token-ids fsmonitor--daemon: add pathname classification fsmonitor--daemon: implement 'start' command ...
2022-04-04Merge branch 'ns/core-fsyncmethod'Junio C Hamano
A couple of fix-up to a topic that is now in 'master'. * ns/core-fsyncmethod: core.fsyncmethod: correctly camel-case warning message core.fsync: fix incorrect expression for default configuration
2022-03-31core.fsyncmethod: correctly camel-case warning messageNeeraj Singh
The warning for an unrecognized fsyncMethod was not camel-cased. Reported-by: Jiang Xin <worldhello.net@gmail.com> Signed-off-by: Neeraj Singh <neerajsi@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-03-26fsmonitor: config settings are repository-specificJeff Hostetler
Move fsmonitor config settings to a new and opaque `struct fsmonitor_settings` structure. Add a lazily-loaded pointer to this into `struct repo_settings` Create an `enum fsmonitor_mode` type in `struct fsmonitor_settings` to represent the state of fsmonitor. This lets us represent which, if any, fsmonitor provider (hook or IPC) is enabled. Create `fsm_settings__get_*()` getters to lazily look up fsmonitor- related config settings. Get rid of the `core_fsmonitor` global variable. Move the code to lookup the existing `core.fsmonitor` config value into the fsmonitor settings. Create a hook pathname variable in `struct fsmonitor-settings` and only set it when in hook mode. Extend the definition of `core.fsmonitor` to be either a boolean or a hook pathname. When true, the builtin FSMonitor is used. When false or unset, no FSMonitor (neither builtin nor hook) is used. The existing `core_fsmonitor` global variable was used to store the pathname to the fsmonitor hook *and* it was used as a boolean to see if fsmonitor was enabled. This dual usage and global visibility leads to confusion when we add the IPC-based provider. So lets hide the details in fsmonitor-settings.c and let it decide which provider to use in the case of multiple settings. This avoids cluttering up repo-settings.c with these private details. A future commit in builtin-fsmonitor series will add the ability to disqualify worktrees for various reasons, such as being mounted from a remote volume, where fsmonitor should not be started. Having the config settings hidden in fsmonitor-settings.c allows such worktree restrictions to override the config values used. Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-03-15core.fsync: new option to harden referencesPatrick Steinhardt
When writing both loose and packed references to disk we first create a lockfile, write the updated values into that lockfile, and on commit we rename the file into place. According to filesystem developers, this behaviour is broken because applications should always sync data to disk before doing the final rename to ensure data consistency [1][2][3]. If applications fail to do this correctly, a hard crash of the machine can easily result in corrupted on-disk data. This kind of corruption can in fact be easily observed with Git when the machine hard-resets shortly after writing references to disk. On machines with ext4, this will likely lead to the "empty files" problem: the file has been renamed, but its data has not been synced to disk. The result is that the reference is corrupt, and in the worst case this can lead to data loss. Implement a new option to harden references so that users and admins can avoid this scenario by syncing locked loose and packed references to disk before we rename them into place. [1]: https://thunk.org/tytso/blog/2009/03/15/dont-fear-the-fsync/ [2]: https://btrfs.wiki.kernel.org/index.php/FAQ (What are the crash guarantees of overwrite-by-rename) [3]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/ext4.rst (see auto_da_alloc) Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-03-15Merge branch 'ns/core-fsyncmethod' into ps/fsync-refsJunio C Hamano
* ns/core-fsyncmethod: core.fsync: documentation and user-friendly aggregate options core.fsync: new option to harden the index core.fsync: add configuration parsing core.fsync: introduce granular fsync control infrastructure core.fsyncmethod: add writeout-only mode wrapper: make inclusion of Windows csprng header tightly scoped
2022-03-15core.fsync: documentation and user-friendly aggregate optionsNeeraj Singh
This commit adds aggregate options for the core.fsync setting that are more user-friendly. These options are specified in terms of 'levels of safety', indicating which Git operations are considered to be sync points for durability. The new documentation is also included here in its entirety for ease of review. Signed-off-by: Neeraj Singh <neerajsi@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-03-11core.fsync: new option to harden the indexNeeraj Singh
This commit introduces the new ability for the user to harden the index. In the event of a system crash, the index must be durable for the user to actually find a file that has been added to the repo and then deleted from the working tree. We use the presence of the COMMIT_LOCK flag and absence of the alternate_index_output as a proxy for determining whether we're updating the persistent index of the repo or some temporary index. We don't sync these temporary indexes. Signed-off-by: Neeraj Singh <neerajsi@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-03-11core.fsync: add configuration parsingNeeraj Singh
This change introduces code to parse the core.fsync setting and configure the fsync_components variable. core.fsync is configured as a comma-separated list of component names to sync. Each time a core.fsync variable is encountered in the configuration heirarchy, we start off with a clean state with the platform default value. Passing 'none' resets the value to indicate nothing will be synced. We gather all negative and positive entries from the comma separated list and then compute the new value by removing all the negative entries and adding all of the positive entries. We issue a warning for components that are not recognized so that the configuration code is compatible with configs from future versions of Git with more repo components. Complete documentation for the new setting is included in a later patch in the series so that it can be reviewed once in final form. Signed-off-by: Neeraj Singh <neerajsi@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-03-11core.fsyncmethod: add writeout-only modeNeeraj Singh
This commit introduces the `core.fsyncMethod` configuration knob, which can currently be set to `fsync` or `writeout-only`. The new writeout-only mode attempts to tell the operating system to flush its in-memory page cache to the storage hardware without issuing a CACHE_FLUSH command to the storage controller. Writeout-only fsync is significantly faster than a vanilla fsync on common hardware, since data is written to a disk-side cache rather than all the way to a durable medium. Later changes in this patch series will take advantage of this primitive to implement batching of hardware flushes. When git_fsync is called with FSYNC_WRITEOUT_ONLY, it may fail and the caller is expected to do an ordinary fsync as needed. On Apple platforms, the fsync system call does not issue a CACHE_FLUSH directive to the storage controller. This change updates fsync to do fcntl(F_FULLFSYNC) to make fsync actually durable. We maintain parity with existing behavior on Apple platforms by setting the default value of the new core.fsyncMethod option. Signed-off-by: Neeraj Singh <neerajsi@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-03-10Merge branch 'en/present-despite-skipped'Junio C Hamano
In sparse-checkouts, files mis-marked as missing from the working tree could lead to later problems. Such files were hard to discover, and harder to correct. Automatically detecting and correcting the marking of such files has been added to avoid these problems. * en/present-despite-skipped: repo_read_index: add config to expect files outside sparse patterns Accelerate clear_skip_worktree_from_present_files() by caching Update documentation related to sparsity and the skip-worktree bit repo_read_index: clear SKIP_WORKTREE bit from files present in worktree unpack-trees: fix accidental loss of user changes t1011: add testcase demonstrating accidental loss of user modifications
2022-03-02repo_read_index: add config to expect files outside sparse patternsElijah Newren
Typically with sparse checkouts, we expect files outside the sparsity patterns to be marked as SKIP_WORKTREE and be missing from the working tree. Sometimes this expectation would be violated however; including in cases such as: * users grabbing files from elsewhere and writing them to the worktree (perhaps by editing a cached copy in an editor, copying/renaming, or even untarring) * various git commands having incomplete or no support for the SKIP_WORKTREE bit[1,2] * users attempting to "abort" a sparse-checkout operation with a not-so-early Ctrl+C (updating $GIT_DIR/info/sparse-checkout and the working tree is not atomic)[3]. When the SKIP_WORKTREE bit in the index did not reflect the presence of the file in the working tree, it traditionally caused confusion and was difficult to detect and recover from. So, in a sparse checkout, since af6a51875a (repo_read_index: clear SKIP_WORKTREE bit from files present in worktree, 2022-01-14), Git automatically clears the SKIP_WORKTREE bit at index read time for entries corresponding to files that are present in the working tree. There is another workflow, however, where it is expected that paths outside the sparsity patterns appear to exist in the working tree and that they do not lose the SKIP_WORKTREE bit, at least until they get modified. A Git-aware virtual file system[4] takes advantage of its position as a file system driver to expose all files in the working tree, fetch them on demand using partial clone on access, and tell Git to pay attention to them on demand by updating the sparse checkout pattern on writes. This means that commands like "git status" only have to examine files that have potentially been modified, whereas commands like "ls" are able to show the entire codebase without requiring manual updates to the sparse checkout pattern. Thus since af6a51875a, Git with such Git-aware virtual file systems unsets the SKIP_WORKTREE bit for all files and commands like "git status" have to fetch and examine them all. Introduce a configuration setting sparse.expectFilesOutsideOfPatterns to allow limiting the tracked set of files to a small set once again. A Git-aware virtual file system or other application that wants to maintain files outside of the sparse checkout can set this in a repository to instruct Git not to check for the presence of SKIP_WORKTREE files. The setting defaults to false, so most users of sparse checkout will still get the benefit of an automatically updating index to recover from the variety of difficult issues detailed in af6a51875a for paths with SKIP_WORKTREE set despite the path being present. [1] https://lore.kernel.org/git/xmqqbmb1a7ga.fsf@gitster-ct.c.googlers.com/ [2] The three long paragraphs in the middle of https://lore.kernel.org/git/CABPp-BH9tju7WVm=QZDOvaMDdZbpNXrVWQdN-jmfN8wC6YVhmw@mail.gmail.com/ [3] https://lore.kernel.org/git/CABPp-BFnFpzwGC11TLoLs8YK5yiisA5D5-fFjXnJsbESVDwZsA@mail.gmail.com/ [4] such as the vfsd described in https://lore.kernel.org/git/20220207190320.2960362-1-jonathantanmy@google.com/ Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Elijah Newren <newren@gmail.com> Reviewed-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-26Merge branch 'ab/date-mode-release'Junio C Hamano
Plug (some) memory leaks around parse_date_format(). * ab/date-mode-release: date API: add and use a date_mode_release() date API: add basic API docs date API: provide and use a DATE_MODE_INIT date API: create a date.h, split from cache.h cache.h: remove always unused show_date_human() declaration
2022-02-26Merge branch 'ds/sparse-checkout-requires-per-worktree-config'Junio C Hamano
"git sparse-checkout" wants to work with per-worktree configuration, but did not work well in a worktree attached to a bare repository. * ds/sparse-checkout-requires-per-worktree-config: config: make git_configset_get_string_tmp() private worktree: copy sparse-checkout patterns and config on add sparse-checkout: set worktree-config correctly config: add repo_config_set_worktree_gently() worktree: create init_worktree_config() Documentation: add extensions.worktreeConfig details
2022-02-16date API: create a date.h, split from cache.hÆvar Arnfjörð Bjarmason
Move the declaration of the date.c functions from cache.h, and adjust the relevant users to include the new date.h header. The show_ident_date() function belonged in pretty.h (it's defined in pretty.c), its two users outside of pretty.c didn't strictly need to include pretty.h, as they get it indirectly, but let's add it to them anyway. Similarly, the change to "builtin/{fast-import,show-branch,tag}.c" isn't needed as far as the compiler is concerned, but since they all use the "DATE_MODE()" macro we now define in date.h, let's have them include it. We could simply include this new header in "cache.h", but as this change shows these functions weren't common enough to warrant including in it in the first place. By moving them out of cache.h changes to this API will no longer cause a (mostly) full re-build of the project when "make" is run. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-10Merge branch 'jt/conditional-config-on-remote-url'Junio C Hamano
The conditional inclusion mechanism of configuration files using "[includeIf <condition>]" learns to base its decision on the URL of the remote repository the repository interacts with. * jt/conditional-config-on-remote-url: config: include file if remote URL matches a glob config: make git_config_include() static
2022-02-08config: make git_configset_get_string_tmp() privateDerrick Stolee
This method was created in f1de981e8 (config: fix leaks from git_config_get_string_const(), 2020-08-14) but its only use was in the repo_config_get_string_tmp() method, also declared in config.h and implemented in config.c. Since this is otherwise unused and is a very similar implementation to git_configset_get_value(), let's remove this declaration. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Reviewed-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-08config: add repo_config_set_worktree_gently()Derrick Stolee
Some config settings, such as those for sparse-checkout, are likely intended to only apply to one worktree at a time. To make this write easier, add a new config API method, repo_config_set_worktree_gently(). This method will attempt to write to the worktree-specific config, but will instead write to the common config file if worktree config is not enabled. The next change will introduce a consumer of this method. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Reviewed-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-19config: include file if remote URL matches a globJonathan Tan
This is a feature that supports config file inclusion conditional on whether the repo has a remote with a URL that matches a glob. Similar to my previous work on remote-suggested hooks [1], the main motivation is to allow remote repo administrators to provide recommended configs in a way that can be consumed more easily (e.g. through a package installable by a package manager - it could, for example, contain a file to be included conditionally and a post-install script that adds the include directive to the system-wide config file). In order to do this, Git reruns the config parsing mechanism upon noticing the first URL-conditional include in order to find all remote URLs, and these remote URLs are then used to determine if that first and all subsequent includes are executed. Remote URLs are not allowed to be configued in any URL-conditionally-included file. [1] https://lore.kernel.org/git/cover.1623881977.git.jonathantanmy@google.com/ Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Acked-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-19config: make git_config_include() staticJonathan Tan
It is not used from outside the file in which it is declared. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Acked-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-01-10Merge branch 'js/branch-track-inherit'Junio C Hamano
"git -c branch.autosetupmerge=inherit branch new old" makes "new" to have the same upstream as the "old" branch, instead of marking "old" itself as its upstream. * js/branch-track-inherit: config: require lowercase for branch.*.autosetupmerge branch: add flags and config to inherit tracking branch: accept multiple upstream branches for tracking
2021-12-21config: require lowercase for branch.*.autosetupmergeJosh Steadmon
Although we only documented that branch.*.autosetupmerge would accept "always" as a value, the actual implementation would accept any combination of upper- or lower-case. Fix this to be consistent with documentation and with other values of this config variable. Signed-off-by: Josh Steadmon <steadmon@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-21branch: add flags and config to inherit trackingJosh Steadmon
It can be helpful when creating a new branch to use the existing tracking configuration from the branch point. However, there is currently not a method to automatically do so. Teach git-{branch,checkout,switch} an "inherit" argument to the "--track" option. When this is set, creating a new branch will cause the tracking configuration to default to the configuration of the branch point, if set. For example, if branch "main" tracks "origin/main", and we run `git checkout --track=inherit -b feature main`, then branch "feature" will track "origin/main". Thus, `git status` will show us how far ahead/behind we are from origin, and `git pull` will pull from origin. This is particularly useful when creating branches across many submodules, such as with `git submodule foreach ...` (or if running with a patch such as [1], which we use at $job), as it avoids having to manually set tracking info for each submodule. Since we've added an argument to "--track", also add "--track=direct" as another way to explicitly get the original "--track" behavior ("--track" without an argument still works as well). Finally, teach branch.autoSetupMerge a new "inherit" option. When this is set, "--track=inherit" becomes the default behavior. [1]: https://lore.kernel.org/git/20180927221603.148025-1-sbeller@google.com/ Signed-off-by: Josh Steadmon <steadmon@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-12-08config API: use get_error_routine(), not vreportf()Ævar Arnfjörð Bjarmason
Change the git_die_config() function added in 5a80e97c827 (config: add `git_die_config()` to the config-set API, 2014-08-07) to use the public callbacks in the usage.[ch] API instead of the the underlying vreportf() function. In preceding commits the rest of the vreportf() users outside of usage.c was migrated to die_message(), so we can now make it "static". Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-10-22config.c: don't leak memory in handle_path_include()Ævar Arnfjörð Bjarmason
Fix a memory leak in the error() path in handle_path_include(), this allows us to run t1305-config-include.sh under SANITIZE=leak, previously 4 tests there would fail. This fixes up a leak in 9b25a0b52e0 (config: add include directive, 2012-02-06). Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-29config.c: remove unused git_config_key_is_valid()Ævar Arnfjörð Bjarmason
The git_config_key_is_valid() function got left behind in a refactoring in a9bcf6586d1 (alias: use the early config machinery to expand aliases, 2017-06-14), It previously had two users when it was added in 9e9de18f1ad (config: silence warnings for command names with invalid keys, 2015-08-24), and after 6a1e1bc0a15 (pager: use callbacks instead of configset, 2016-09-12) only one remained. By removing it we can get rid of the "quiet" branches in this function, as well as cases where "store_key" is NULL, for which there are no other users. Out of the 5 callers of git_config_parse_key() only one needs to pass a non-NULL "size_t *baselen_", so we could remove the third parameter from the public interface. I did not find that potential simplification to be worthwhile. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-23Merge branch 'rs/drop-core-compression-vars'Junio C Hamano
Code clean-up. * rs/drop-core-compression-vars: compression: drop write-only core_compression_* variables
2021-09-21Merge branch 'jt/grep-wo-submodule-odb-as-alternate'Junio C Hamano
The code to make "git grep" recurse into submodules has been updated to migrate away from the "add submodule's object store as an alternate object store" mechanism (which is suboptimal). * jt/grep-wo-submodule-odb-as-alternate: t7814: show lack of alternate ODB-adding submodule-config: pass repo upon blob config read grep: add repository to OID grep sources grep: allocate subrepos on heap grep: read submodule entry with explicit repo grep: typesafe versions of grep_source_init grep: use submodule-ODB-as-alternate lazy-addition submodule: lazily add submodule ODBs as alternates