summaryrefslogtreecommitdiff
path: root/src/refdb_fs.c
Commit message (Collapse)AuthorAgeFilesLines
* refdb_fs: make use of the `GIT_CONTAINER_OF` macroEtienne Samson2019-04-161-22/+22
|
* refdb_fs: fix race when migrating loose to packed refs in iterationPatrick Steinhardt2019-02-151-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | Right now, we first load the packed refs cache and only afterwards load the loose references. This is susceptible to a race when the loose ref is being migrated to a packed cache by e.g. git-pack-refs(1): libgit2 git-pack-refs 1. We load the packed ref, which does not yet have the migrated reference. 2. git-pack-refs updates the packed ref file to have the migrated ref. 3. git-pack-refs deletes the old loose ref. 4. We look up the loose ref. So we now do not find the reference at all and will never iterate over it. Fix the issue by reversing the order: instead of first loading the packed refs, we will now look up the loose reference first. If it has already been deleted, then it must already be present in the packed-refs by definition, as git.git will only delete the reference after updating the packed refs file.
* refdb_fs: remove ordering dependency on loose/packed refs loadingPatrick Steinhardt2019-02-151-8/+11
| | | | | | | | | | | | | | | | Right now, loading loose refs has the side-effect of setting the `PACKREF_SHADOWED` flag for references that exist both in the loose and the packed refs. Because of this, we are force do first look up packed refs and only afterwards loading the packed refs. This is susceptible to a race, though, when refs are being repacked: when first loading the packed cache, then it may not yet have the migrated loose ref. But when now trying to look up the loose reference afterwards, then it may already have been migrated. Thus, we would fail to find this reference in this scenario. Remove this ordering dependency to allow fixing the above race. Instead of setting the flag when loading loose refs, we will now instead set it lazily when iterating over the loose refs. This even has the added benefit of not requiring us to lock the packed refs cache, as we already have an owned copy of it.
* refdb_fs: do not lazily copy packed ref cachePatrick Steinhardt2019-02-151-13/+6
| | | | | | | | | | | | | | | When creating a new iterator, we eagerly load loose refs but only lazily create a copy of packed refs. The lazy load only happens as soon as we have iterated over all loose refs, opening up a potentially wide window for races. This may lead to an inconsistent view e.g. when the caller decides to reload packed references somewhen between iterating the loose refs, which is unexpected. Fix the issue by eagerly copying the sorted cache. Note that right now, we are heavily dependent on ordering here: we first need to reload packed refs, then we have to load loose refs and only as a last step are we allowed to copy the cache. This is because loading loose refs has the side-effect of setting the `PACKED_SHADOWED` flag in the packed refs cache, which we require to avoid outputting packed refs that already exist as loose refs.
* refdb_fs: refactor error handling in iterator creationPatrick Steinhardt2019-02-151-15/+16
| | | | | Refactor the error handling in `refdb_fs_backend__iterator` to always return the correct error code returned by the failing function.
* refdb_fs: fix potential race with ref repacking in `exists` callbackPatrick Steinhardt2019-02-151-6/+18
| | | | | | | | | | | | | When repacking references, git.git will first update the packed refs and only afterwards delete any existing loose references that have now been moved to the new packed refs file. Due to this, there is a potential for racing if one first reads the packfile (which has not been updated yet) and only then trying to read the loose reference (which has just been deleted). In this case, one will incorrectly fail to lookup the reference and it will be reported as missing. Naturally, this is exactly what we've been doing in `refdb_fs_backend__exists`. Fix the race by reversing the lookup: we will now first check if the loose reference exists and only afterwards refresh the packed file.
* git_error: use new names in internal APIs and usageEdward Thomson2019-01-221-32/+32
| | | | | Move to the `git_error` name in the internal API for error-related functions.
* references: use new names in internal usageethomson/git_refEdward Thomson2019-01-171-12/+12
| | | | Update internal usage to use the `git_reference` names for constants.
* refdb_fs: refactor error handling in `refdb_reflog_fs__delete`Patrick Steinhardt2018-12-191-12/+11
| | | | | | | | | | | | | | | The function `refdb_reflog_fs__delete` uses the `if (!error && foobar())` pattern of checking, where error conditions are being checked by following calls to different code. This does not match our current style, where the call-site of a function is usually directly responsible for checking the return value. Convert the function to use `if ((error = foobar()) < 0) goto out;` style. Note that this changes the code flow a bit: previously, we were always trying to delete empty reference hierarchies even if deleting the reflog entry has failed. This wasn't much of a problem -- if deletion failed, the hierarchy will still contain at least one file and thus the function call was an expensive no-op. Now, we will only perform this deletion if we have successfully removed the reflog.
* Merge pull request #4833 from csware/drop-empty-dirsPatrick Steinhardt2018-12-191-2/+42
|\ | | | | Remove empty (sub-)directories when deleting refs
| * Remove empty directories when deleting refsSven Strickroth2018-10-131-2/+42
| | | | | | | | Signed-off-by: Sven Strickroth <email@cs-ware.de>
* | object_type: use new enumeration namesethomson/index_fixesEdward Thomson2018-12-011-2/+2
| | | | | | | | Use the new object_type enumeration names within the codebase.
* | refs: add support for core.logAllRefUpdates=alwaysEtienne Samson2018-11-181-12/+20
|/ | | | | | | Since we were not expecting this config entry to contain a string, we would fail as soon as its (cached) value would be accessed. Hence, provide some constants for the 4 states we use, and account for "always" when we decide to reflog changes.
* Convert usage of `git_buf_free` to new `git_buf_dispose`Patrick Steinhardt2018-06-101-30/+30
|
* refdb_fs: test whether the base directory exists when globbingJulian Ganz2018-06-011-2/+6
| | | | | | | | | | | | | | | | | | | This commit fixes a regression introduced by 20a2b02d9a1bcb4825ec49605146223c565dcacf The commit introduced an optimization for finding references using a glob: rather than iterating over all references and matching each one against the glob, we would iterate only over references within the directory common to all possible references which may match against the glob. However, contrary to the `ref/` directory, which was the previous entry point for the iteration, this directory may not exist. In this case, the optimization causes an error (`ENOENT`) rather than the iterator simply yielding no references. This patch fixes the regression by checkign for this specific case.
* Merge pull request #4660 from libgit2/cmn/submodule-traversalCarlos Martín Nieto2018-05-291-2/+2
|\ | | | | Fixes for CVE 2018-11235
| * path: reject .gitmodules as a symlinkCarlos Martín Nieto2018-05-231-2/+2
| | | | | | | | | | | | | | | | Any part of the library which asks the question can pass in the mode to have it checked against `.gitmodules` being a symlink. This is particularly relevant for adding entries to the index from the worktree and for checking out files.
* | Merge pull request #4629 from neithernut/enhance-glob-perfPatrick Steinhardt2018-05-091-3/+30
|\ \ | | | | | | refdb_fs: enhance performance of globbing
| * | refdb_fs: enable root arbitration for fixed portion of globsJulian Ganz2018-04-271-0/+24
| | | | | | | | | | | | | | | | | | | | | A glob used for iteration may start with an entire path containing no special characters. If we start scanning for references within that path rather than in `refs/`, we may end up scanning only a small fraction of all references.
| * | refdb_fs: prepare arbitration of the root used for ref iterationJulian Ganz2018-04-271-3/+6
| | | | | | | | | | | | | | | Instead of a hardcoded "refs", we may choose a different directory within the git directory as the root from which we look for references.
* | | Merge pull request #4633 from csware/worktree-delererefPatrick Steinhardt2018-04-261-1/+1
|\ \ \ | |_|/ |/| | Fix deletion of unrelated branch on worktree
| * | Fix deletion of unrelated branch on worktreeSven Strickroth2018-04-201-1/+1
| |/ | | | | | | Signed-off-by: Sven Strickroth <email@cs-ware.de>
* | worktree: Read worktree specific reflog for HEADSven Strickroth2018-03-271-0/+2
|/ | | | Signed-off-by: Sven Strickroth <email@cs-ware.de>
* iterator: cleanups with symlink dir handlingEdward Thomson2017-12-301-1/+1
| | | | Perform some error checking when examining symlink directories.
* branches: Check symlinked subdirectoriesAndy Doan2017-12-291-0/+1
| | | | | | | | Native Git allows symlinked directories under .git/refs. This change allows libgit2 to also look for references that live under symlinked directories. Signed-off-by: Andy Doan <andy@opensourcefoundries.com>
* Make sure to always include "common.h" firstPatrick Steinhardt2017-07-031-1/+2
| | | | | | | | | | | | | | | | | | | | | | Next to including several files, our "common.h" header also declares various macros which are then used throughout the project. As such, we have to make sure to always include this file first in all implementation files. Otherwise, we might encounter problems or even silent behavioural differences due to macros or defines not being defined as they should be. So in fact, our header and implementation files should make sure to always include "common.h" first. This commit does so by establishing a common include pattern. Header files inside of "src" will now always include "common.h" as its first other file, separated by a newline from all the other includes to make it stand out as special. There are two cases for the implementation files. If they do have a matching header file, they will always include this one first, leading to "common.h" being transitively included as first file. If they do not have a matching header file, they instead include "common.h" as first file themselves. This fixes the outlined problems and will become our standard practice for header and source files inside of the "src/" from now on.
* settings: rename `GIT_OPT_ENABLE_SYNCHRONOUS_OBJECT_CREATION`Patrick Steinhardt2017-06-081-1/+1
| | | | | | | | | | | Initially, the setting has been solely used to enable the use of `fsync()` when creating objects. Since then, the use has been extended to also cover references and index files. As the option is not yet part of any release, we can still correct this by renaming the option to something more sensible, indicating not only correlation to objects. This commit renames the option to `GIT_OPT_ENABLE_FSYNC_GITDIR`. We also move the variable from the object to repository source code.
* refdb_fs: be explicit about using null-OID if we cannot resolve refPatrick Steinhardt2017-06-081-2/+3
|
* Merge pull request #4163 from pks-t/pks/submodules-with-worktreesEdward Thomson2017-03-221-2/+8
|\ | | | | Worktree fixes
| * refdb: create references in commondirPatrick Steinhardt2017-03-171-2/+8
| | | | | | | | | | | | | | | | | | | | | | References for a repository are usually created inside of its gitdir. When using worktrees, though, these references are not to be created inside the worktree gitdir, but instead inside the gitdir of its parent repository, which is the commondir. Like this, branches will still be available after the worktree itself has been deleted. The filesystem refdb currently still creates new references inside of the gitdir. Fix this and have it create references in commondir.
* | Merge pull request #4030 from libgit2/ethomson/fsyncEdward Thomson2017-03-221-6/+22
|\ \ | |/ |/| fsync all the things
| * Honor `core.fsyncObjectFiles`ethomson/fsyncEdward Thomson2017-03-021-3/+7
| |
| * fsync: call it "synchronous" object writingEdward Thomson2017-02-281-3/+3
| | | | | | | | | | Rename `GIT_OPT_ENABLE_SYNCHRONIZED_OBJECT_CREATION` -> `GIT_OPT_ENABLE_SYNCHRONOUS_OBJECT_CREATION`.
| * refdb_fs: optionally fsync packed refsEdward Thomson2017-02-281-2/+5
| |
| * refdb_fs: optionally fsync loose referencesEdward Thomson2017-02-281-4/+13
| |
* | refdb_fs: honor the namespaceethomson/namespacesEdward Thomson2017-03-061-26/+35
|/
* strmap: remove GIT__USE_STRMAP macroPatrick Steinhardt2017-02-171-2/+0
|
* refdb: catch additional per-worktree refsPatrick Steinhardt2017-02-151-4/+9
| | | | | | | | | | | | | | | | | | | The upstream git.git project currently identifies all references inside of `refs/bisect/` as well as `HEAD` as per-worktree references. This is already incorrect and is currently being fixed by an in-flight topic [1]. The new behavior will be to match all pseudo-references outside of the `refs/` hierarchy as well as `refs/bisect/`. Our current behavior is to mark a selection of pseudo-references as per-worktree, only. This matches more pseudo-references than current git, but forgets about `refs/bisect/`. Adjust behavior to match the in-flight topic, that is classify the following references as per-worktree: - everything outside of `refs/` - everything inside of `refs/bisect/` [1]: <20170213152011.12050-1-pclouds@gmail.com>
* repository: rename `path_repository` and `path_gitlink`Patrick Steinhardt2017-02-131-3/+3
| | | | | | | | | | | | | The `path_repository` variable is actually confusing to think about, as it is not always clear what the repository actually is. It may either be the path to the folder containing worktree and .git directory, the path to .git itself, a worktree or something entirely different. Actually, the intent of the variable is to hold the path to the gitdir, which is either the .git directory or the bare repository. Rename the variable to `gitdir` to avoid confusion. While at it, also rename `path_gitlink` to `gitlink` to improve consistency.
* refdb: look for reflog in commondirPatrick Steinhardt2017-02-131-1/+1
|
* refdb: introduce commondir awarenessPatrick Steinhardt2017-02-131-6/+28
| | | | | | | | | | | The refdb_fs_backend is not aware of the git commondir, which stores common objects like the o bject database and packed/loose refereensces when worktrees are used. Make refdb_fs_backend aware of the common directory by introducing a new commonpath variable that points to the actual common path of the database and using it instead of the gitdir for the mentioned objects.
* refdb: rename refdb_fs_backend's .path to .gitpathPatrick Steinhardt2017-02-131-29/+30
| | | | | | | | | | | | The variable '.path' of the refdb_fs_backend struct becomes confusing regarding the introduction of the git commondir. It does not immediatly become obvious what it should point to. Fix this problem by renaming the variable to `gitpath`, clarifying that it acutally points to the `.git` directory of the repository, in contrast to the commonpath directory, which points to the directory containing shared objects like references and the object store.
* giterr_set: consistent error messagesEdward Thomson2016-12-291-12/+12
| | | | | | | | Error messages should be sentence fragments, and therefore: 1. Should not begin with a capital letter, 2. Should not conclude with punctuation, and 3. Should not end a sentence and begin a new one
* refdb: bubble up recursive rm when locking a refcmn/refdb-fs-errorsCarlos Martín Nieto2016-12-161-2/+2
| | | | | Failure to bubble up this error means some locking errors do not get reported as such on Windows.
* Plug a leak in the refs compressorcmn/compress-buf-freeCarlos Martín Nieto2016-11-141-0/+2
|
* refdb: bubble up locked files on the read sideCarlos Martín Nieto2016-11-141-17/+21
| | | | | | On Windows we can find locked files even when reading a reference or the packed-refs file. Bubble up the error in this case as well to allow callers on Windows to retry more intelligently.
* refdb: remove a check-delete race when removing a loose refCarlos Martín Nieto2016-11-141-7/+7
| | | | | | | | It does not help us to check whether the file exists before trying to unlink it since it might be gone by the time unlink is called. Instead try to remove it and handle the resulting error if it did not exist.
* refdb: bubble up the error code when compressing the dbCarlos Martín Nieto2016-11-141-4/+5
| | | | | This allows the caller to know the errors was e.g. due to the packed-refs file being already locked and they can try again later.
* refdb: refactor the lockfile cleanupCarlos Martín Nieto2016-11-141-15/+9
| | | | | We can reduce the duplication by cleaning up at the beginning of the loop, since it's something we want to do every time we continue.
* refdb: don't report failure for expected errorsCarlos Martín Nieto2016-11-141-20/+9
| | | | | | | | | | There might be a few threads or processes working with references concurrently, so fortify the code to ignore errors which come from concurrent access which do not stop us from continuing the work. This includes ignoring an unlinking error. Either someone else removed it or we leave the file around. In the former case the job is done, and in the latter case, the ref is still in a valid state.