| Commit message (Collapse) | Author | Age | Files | Lines |
| | |
|
| | |
|
| | |
|
| |
|
|
|
| |
Since we're returning a boolean about validation, the name is more
properly "is valid".
|
| |
|
|
|
|
| |
Introduce `git_fs_path`, which operates on generic filesystem paths.
`git_path` will be kept for only git-specific path functionality (for
example, checking for `.git` in a path).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
libgit2 has two distinct requirements that were previously solved by
`git_buf`. We require:
1. A general purpose string class that provides a number of utility APIs
for manipulating data (eg, concatenating, truncating, etc).
2. A structure that we can use to return strings to callers that they
can take ownership of.
By using a single class (`git_buf`) for both of these purposes, we have
confused the API to the point that refactorings are difficult and
reasoning about correctness is also difficult.
Move the utility class `git_buf` to be called `git_str`: this represents
its general purpose, as an internal string buffer class. The name also
is an homage to Junio Hamano ("gitstr").
The public API remains `git_buf`, and has a much smaller footprint. It
is generally only used as an "out" param with strict requirements that
follow the documentation. (Exceptions exist for some legacy APIs to
avoid breaking callers unnecessarily.)
Utility functions exist to convert a user-specified `git_buf` to a
`git_str` so that we can call internal functions, then converting it
back again.
|
| |
|
|
| |
Make some syntax change to follow coding style.
|
| |\
| |
| | |
Introduce GIT_WARN_UNUSED_RESULT
|
| | |
| |
| |
| |
| |
| | |
This adds a `-Wunused-result`-proof `GIT_UNUSED()`, just to demonstrate
that it works. With this, sortedcache.h is now completely
`GIT_WARN_UNUSED_RESULT`-annotated!
|
| |/ |
|
| |\
| |
| |
| | |
Manually merging #5842
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
This is pretty useful in avoiding races: I want to create a ref only if
it doesn't already exist. I can't check first because of TOCTOU -- by
the time I finish the check, someone else might have already created
the ref. And I can't take a lock because then I can't do the create,
since the create expects to take the lock.
The semantics are inspired by git update-ref, which allows an all-zero old
value to mean that the ref must not exist.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| | |
On Windows, we need to enforce MAX_PATH for loose references and their
reflogs. Ensure that any path - including the lock file - would fit
within the 260 character maximum.
We do not honor core.longpaths for loose reference files or reflogs.
core.longpaths only applies to paths in the working directory.
|
| |/
|
|
|
|
|
| |
If we want to validate more and different types of paths, the name
`git_path_validate` makes that easier and more expressive. We can add,
for example, `git_path_validate_foo` while the current name makes that
less ergonomic.
|
| |
|
|
|
| |
To prevent a race condition, these wlock/rlock calls should probably be checked
for errors.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The logic to determine whether a reflog entry should be for the HEAD
reference is non-trivial. Currently, the only user of this is the
filesystem-based refdb, but with the advent of the reftable refdb we're
going to add a second user that's interested in having the same
behaviour.
Let's pull out a new function that checks whether a given reference
should cause a entry to be written to the HEAD reflog as a preparatory
step.
|
| |
|
|
|
|
|
|
|
|
| |
The logic to determine whether a reflog should be written is
non-trivial. Currently, the only user of this is the filesystem-based
refdb, but with the advent of the reftable refdb we're going to add a
second user that's interested in having the same behaviour.
Let's pull out a new function that checks whether a given reference
should cause a reflog to be written as a preparatory step.
|
| |
|
|
| |
Propagate failures caused by pool initialization errors.
|
| |
|
|
|
|
| |
The "refdb_fs.h" header contains a single struct `git_refcache` that is
not used anywhere. As a result, we can just delete the header altogether
as it doesn't have any purpose and may confuse readers.
|
| |
|
|
|
|
| |
While the `git_refdb_backend()` struct has a version, we do not
initialize it correctly when calling `git_refdb_backend_fs()`. Fix this
by adding the call to `git_refdb_init_backend()`.
|
| |
|
|
|
|
|
|
|
|
|
| |
As git_reference__name will reallocate storage to account for longer
names (it's actually allocator-dependent), it will cause all existing
pointers to the old object to become dangling, as they now point to
freed memory.
Fix the issue by renaming to a more descriptive name, and pass a pointer
to the actual reference that can safely be invalidated if the realloc
succeeds.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
In previous versions, libgit2 could be coerced into writing reflog
messages with embedded newlines into the reflog by using
`git_stash_save` with a message containing newlines. While the root
cause is fixed now, it was noticed that upstream git is in fact able to
read such corrupted reflog messages just fine.
Make the reflog parser more lenient in order to just skip over
malformatted reflog lines to bring us in line with git. This requires us
to change an existing test that verified that we do indeed _fail_ to
parse such logs.
|
| |
|
|
|
| |
The refdb_fs code to parse the reflog currently uses a hand-rolled
parser. Convert it to use our `git_parse_ctx` structure instead.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Currently, the reflog disallows any entries that have a message with
newlines, as that would effectively break the reflog format, which may
contain a single line per entry, only. Upstream git behaves a bit
differently, though, especially when considering stashes: instead of
rejecting any reflog entry with newlines, git will simply replace
newlines with spaces. E.g. executing 'git stash push -m "foo\nbar"' will
create a reflog entry with "foo bar" as entry message.
This commit adjusts our own logic to stop rejecting commit messages with
newlines. Previously, this logic was part of `git_reflog_append`, only.
There is a second place though where we add reflog entries, which is the
serialization code in the filesystem refdb. As it didn't contain any
sanity checks whatsoever, the refdb would have been perfectly happy to
write malformatted reflog entries to the disk. This is being fixed with
the same logic as for the reflog itself.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The flag GIT_FILEBUF_FORCE currently does two things:
1. It will cause the filebuf to create non-existing leading
directories for the file that is about to be written.
2. It will forcibly remove any pre-existing locks.
While most call sites actually do want (1), they do not want to
remove pre-existing locks, as that renders the locking mechanisms
effectively useless.
Introduce a new flag `GIT_FILEBUF_CREATE_LEADING_DIRS` to
separate both behaviours cleanly from each other and convert
callers to use it instead of `GIT_FILEBUF_FORCE` to have them
honor locked files correctly.
As this conversion removes all current users of `GIT_FILEBUF_FORCE`,
this commit removes the flag altogether.
|
| |
|
|
|
| |
This fixes part of the issue where, given a concurrent `git pack-refs`,
a ref lookup could return an old, vestigial value from the packed file,
as the valid loose one would have been deleted.
|
| | |
|
| | |
|
| |
|
|
|
| |
In the case of a failed lookup, we'd paper over that by writing back
the packed-refs successfully.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
| |
Our file utils functions all have a "futils" prefix, e.g.
`git_futils_touch`. One would thus naturally guess that their
definitions and implementation would live in files "futils.h" and
"futils.c", respectively, but in fact they live in "fileops.h".
Rename the files to match expectations.
|
| |
|
|
|
| |
`cvar` is an unhelpful name. Refactor its usage to `configmap` for more
clarity.
|
| |
|
|
|
|
|
|
|
|
| |
Upstream git.git has converted its codebase to use wildcard in
favor of fnmatch in commit 70a8fc999d (stop using fnmatch (either
native or compat), 2014-02-15). To keep our own regex-matching in
line with what git does, convert all trivial instances of
`fnmatch` usage to use `wildcard`, instead. Trivial usage is
defined to be use of `fnmatch` with either no flags or flags that
have a 1:1 equivalent in wildmatch (PATHNAME, IGNORECASE).
|
| |
|
|
|
|
|
|
| |
We're about to phase out our bundled fnmatch implementation as
git.git has moved to wildmatch long ago in 2014. To make it
easier to spot which files are stilll using fnmatch, remove the
implicit "fnmatch.h" include in "posix.h" and instead include it
explicitly.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| | |
|