| Commit message (Collapse) | Author | Age | Files | Lines |
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
| |
Refactor the error handling in `refdb_fs_backend__iterator` to always return the
correct error code returned by the failing function.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
| |
Move to the `git_error` name in the internal API for error-related
functions.
|
| |
|
|
| |
Update internal usage to use the `git_reference` names for constants.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |\
| |
| | |
Remove empty (sub-)directories when deleting refs
|
| | |
| |
| |
| | |
Signed-off-by: Sven Strickroth <email@cs-ware.de>
|
| | |
| |
| |
| | |
Use the new object_type enumeration names within the codebase.
|
| |/
|
|
|
|
|
| |
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.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |\
| |
| | |
Fixes for CVE 2018-11235
|
| | |
| |
| |
| |
| |
| |
| |
| | |
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.
|
| |\ \
| | |
| | | |
refdb_fs: enhance performance of globbing
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | | |
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.
|
| | | |
| | |
| | |
| | |
| | | |
Instead of a hardcoded "refs", we may choose a different directory
within the git directory as the root from which we look for references.
|
| |\ \ \
| |_|/
|/| | |
Fix deletion of unrelated branch on worktree
|
| | |/
| |
| |
| | |
Signed-off-by: Sven Strickroth <email@cs-ware.de>
|
| |/
|
|
| |
Signed-off-by: Sven Strickroth <email@cs-ware.de>
|
| |
|
|
| |
Perform some error checking when examining symlink directories.
|
| |
|
|
|
|
|
|
| |
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>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
| |
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.
|
| | |
|
| |\
| |
| | |
Worktree fixes
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
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.
|
| |\ \
| |/
|/| |
fsync all the things
|
| | | |
|
| | |
| |
| |
| |
| | |
Rename `GIT_OPT_ENABLE_SYNCHRONIZED_OBJECT_CREATION` ->
`GIT_OPT_ENABLE_SYNCHRONOUS_OBJECT_CREATION`.
|
| | | |
|
| | | |
|
| |/ |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
| |
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
|
| |
|
|
|
| |
Failure to bubble up this error means some locking errors do not get reported as
such on Windows.
|
| | |
|
| |
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
| |
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.
|
| |
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
| |
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.
|