Johannes Carlsson identified a race condition[1] that can lead to
spurious MissingObjectExceptions at read time. If two threads are
active inside of ObjectDirectory looking for a packed object and the
packList is currently the empty NO_PACKS list, thread A will find
no object and eventually consider tryAgain1(). If thread A is put
to sleep and this point and thread B also does not find the object,
loads the packs, when thread A wakes up its tryAgain1 would return
false and the thread never considers the packs.
Rework the internal API of ObjectDirectory to keep a handle on the
exact PackList that was iterated by thread A, allowing it to always
retry walking through the packs if the new PackList is different.
This had some ripple effect into the CachedObjectDirectory and
the shared FileObjectDatabase interface. The new code should be
slightly easier to follow, especially from the perspective of the
CachedObjectDirectory trying to minimize the number of open system
calls it makes to files matching "$GIT_DIR/objects/??/?x{38}".
[1] http://dev.eclipse.org/mhonarc/lists/jgit-dev/msg02401.html
Change-Id: I9a1c9d6ad6cb38404b7b9178167b714077561353
This version does not attempt to unsmudge, unlike the first attempt
in Idafad150553df14827eccfde2e3b95760e16a8b6.
Bug: 372834
Change-Id: I9300e735cb16d6208e1df963abb1ff69f688155d
Also-by: Robin Stocker <robin@nibor.org>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Signed-off-by: Robin Stocker <robin@nibor.org>
In certain cases a JGit server updating an existing shallow client
selected a common ancestor that was behind the shallow edge of
the client. This allowed the server to assume the client had some
objects it did not have and allowed creation of pack deltas the
client could never inflate.
Any commit the client has advertised as shallow must be treated
by UploadPack server as though it has no parents. With no parents
the walker cannot visit graph history the client does not have,
and PackWriter cannot consider delta base candidates the client
is lacking.
Change-Id: I4922b9354df9f490966a586fb693762e897345a2
The folder .git/rebase-merge was not removed in this case. The
repository was then still in rebase state, but neither abort nor
continue worked.
Bug: 425742
Change-Id: I43cea6c9e5f3cef9d6b15643722fddecb40632d9
To correspond to the behavior of "git branch", also return HEAD in case
it is detached.
Bug: 425678
Change-Id: Ie615731434d70b99bd18c7a02e832c0a2c3ceef3
Signed-off-by: Robin Stocker <robin@nibor.org>
Package was renamed, so I had to update the imports. Also, I verified
bitmap serialization was still compatible.
Change-Id: I161ad3875b963b56001beab477ef8d072accee4f
When encountering a submodule entry, "jgit archive" tries to write its
content verbatim as an entry to the archive, which fails with a
JGitInternalException wrapping a MissingObjectException because the
submodule repository commits are typically not part of the
superproject.
When a subproject is available (for example because it has been
checked out as a subdirectory of a superproject worktree), it would be
nice to recurse into it and make one archive recording the state of
the entire project. Unfortunately sometimes the subproject is not
available or it can be hard to find (e.g., it can be on another
server). Even when some subprojects are available, "jgit archive"
should not produce different output for the same tree depending on
which subprojects it has easy access to, so there is no obvious good
default behavior that recurses without relying on access to all
subprojects.
Instead, replace each submodule entry with a placeholder empty
directory. "git archive" does the same.
Change-Id: I1295086037b77fc948b3f93c21d47341e25483e5
Signed-off-by: Jonathan Nieder <jrn@google.com>
Entries for directories are optional and mostly wasted space in most
archive formats (except as a place to hang ownership and filesystem
permissions), but "git archive" includes them. Follow suit.
This will make it easier in a later change to include empty
directories as placeholders for missing submodules.
Change-Id: I1810c686bcc9eb4d73498e4d3e763e18787b088a
Signed-off-by: Jonathan Nieder <jrn@google.com>
This reverts commit 1def0a1257.
We found this fix uncovers problems with unsmudged DirCacheEntry's. This
surfaced because egit's ui test CreatePatchActionTest failed since jgit
computes a wrong status. JGit doesn't detect modified content in now
unsmudged entries. Hence revert this change until these problems are
fixed.
Change-Id: Ia04277ce316d35fc5b0d82c93d2078b856af24bb
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
Common practice when distributing tarballs is to prefix all entries
with a single directory name so when the tarball is extracted it all
falls neatly into a single directory. Add a setPrefix() method to
ArchiveCommand to support this.
Change-Id: I16b2832ef98c30977f6b77b646728b83d93c196f
Signed-off-by: Jonathan Nieder <jrn@google.com>
This is the case for submodules in .git/modules, which typically have a
worktree config of "../../../dir". This can confuse callers, which e.g.
try to call Repository.stripWorkDir with it.
Bug: 423644
Change-Id: I0c00953f73f9316a66d0fc10eab52d8779c88f00
Signed-off-by: Robin Stocker <robin@nibor.org>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This came up while testing the proposed buck build for jgit. With buck
we can introduce smaller modules to allow for more concurrency during
build and to better control inner structure of jgit. Trying to put the
porcelain API into a different module than lower level implementation
classes failed since RebaseTodoLine used a porcelain API exception
causing a dependency cycle on the proposed modules. Using an exception
defined on the same abstraction level fixes this problem.
Change-Id: I26a5353e1a8fc23e67d8ce61309bd964f7665bcb
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
These methods allow to find all configuration entry names for a given
section or section/subsection searching recursively through all base
configurations of the given configuration.
These methods are needed to calculate the names for the effective
configuration of a git repository which combines the configuration entry
names found in the repository, global and system configuration files
Bug: 396659
Change-Id: Ie3731b5e877f8686aadad3f1a46b2e583ad3b7c6
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This feature was introduced in native git with version 1.8.4.
Bug: 422951
Change-Id: I42f194174d64d7ada6631e2156c2a7bf93b5e91c
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Instead of just a generic "Invalid path: $path", add a reason for the
cases where it's not obvious what the problem is (e.g. "aux" being
reserved on Windows).
Bug: 413915
Change-Id: Ia6436bd2560e4f049c92d9aac907cb87348605e0
Signed-off-by: Robin Stocker <robin@nibor.org>
The matcher has to be reset before using it, as was already done in the
other cases.
Bug: 423039
Change-Id: I87abaa7ad7f0aac8651db6e88d41427cacb4d776
Also-by: Ondrej Vrabec <ovrabec@netbeans.org>
Signed-off-by: Robin Stocker <robin@nibor.org>
When there are conflicts with a recursive merge, the conflicting paths
are stored in unmergedPaths (field in ResolveMerger). Later, when the
MergeResult is constructed in MergeCommand, getBaseCommit is called,
which computes the merge base a second time.
In case of RecursiveMerger, getBaseCommit merges the multiple merge
bases into one. It does this not by creating a new ResolveMerger but
instead calling mergeTrees. The problem with mergeTrees is that at the
end, it checks if unmergedPaths is non-empty and returns false in that
case.
Because unmergedPaths was already non-empty because of the real merge,
it thinks that there were conflicts when computing the merge base again,
when there really were none.
This can be fixed by storing the base commit when computing it and then
returning that instead of computing it a second time.
Note that another possible fix would be to just use a new ResolveMerger
for merging the merge bases instead. This would also remove the need to
remember the old value of dircache, inCore and workingTreeIterator (see
RecursiveMerger#getBaseCommit).
Bug: 419641
Change-Id: Ib2ebf4e177498c22a9098aa225e3cfcf16bbd958
Signed-off-by: Robin Stocker <robin@nibor.org>
Bad files from symbolic links were being generated on Cygwin and
required resolution by the appropriate FS. Pass FS to getSymRef and call
FS.resolve before asking if the file is absolute.
Bug: 419494
Change-Id: I74aa7a285954cade77f41df6f813b6dafb5d6cd7
Signed-off-by: John Ross <jwross@us.ibm.com>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
With this change jgit checks for uncommitted changes before a rebase is
started. This is also done by native git. One reason is that an abort
would override such changes. The check is skipped for a non-interactive
rebase when it will result in a fast-forward. In this case there can be
only checkout conflicts but no merge conflicts, so there cannot be an
abort which overrides uncommitted changes.
Bug: 422352
Change-Id: I1e0b59b2a4d80a686b67a6729e441924362b1236
Signed-off-by: Stefan Lay <stefan.lay@sap.com>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
JGit was not handling certain file/folder conflicts during a checkout
correctly. This was reported by Axel Richard in
http://dev.eclipse.org/mhonarc/lists/jgit-dev/msg02358.html.
This commit fixes this problem.
Still JGit behaves intentionally different than native git.
If HEAD contains a tree, and workingtree, Index and Merge contain a file
with same content ... then JGit allows a conflict free checkout of
Merge. Native git always complains that it doesn't want to overwrite
local changes. But there is no need to update the working tree because
Index and Merge are already equal.
A shell script which shows how native git behaves can be found here.
https://gist.github.com/chalstrick/7694959#file-gistfile1-sh
Change-Id: Ifd6a68974d61cd4fa23bc575f3a40773db66cafc
Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
Applying a stash on another commit failed because the merge base for the
cherry-pick of the stashed index state was not corectly set.
Bug: 422684
Change-Id: I9355352b2b9a7abefa3248ca3c17a9301177d0d6
Signed-off-by: Stefan Lay <stefan.lay@sap.com>
Otherwise switching to another locale yields wrong results when parsing
date strings in GitDateParser. Since the MockSystemReader explicitly
uses english locale the tests need to specify the locale to be used when
parsing date strings.
Bug: 420772
Change-Id: I313ef6b1e9ef3bfb43d929ce34712ebd21f2cd9c
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Empty lines of discarded commit messages were added to the commit
message because they were not commented out properly.
Bug: 422246
Change-Id: I263e8a6b30a3392d8b4f09c0695505068a0a485d
Signed-off-by: Stefan Lay <stefan.lay@sap.com>
The API in org.eclipse.jgit.api does allow to open repositories but it
did not allow to close them. This commit fixes this and allows
API users to close a repository without having to use lower-level
classes.
Bug: 420502
Change-Id: I866225cc8534ae5916113fa24eb1c7513fd4472e
Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
DfsPackFile.isIndexLoaded() uses the DfsBlockCache.Ref.get() method
to check if the index loaded. However, using the get() method marks
a hot bit in the cache, which can cause the index to never be unloaded
and seem hotter than it really is. Add a has() method which only
checks if the value is not null and does not update the hot bit.
Change-Id: I7e9ed216f6e273e8f5d79ae573973197654419b4
If during an garbage collection old packfiles are deleted it could
happen that on certain platforms the index file can be deleted but the
packfile can't be deleted (because someone locked the file). This led
to repositories with packfiles without corresponding index files. Those
zombie-packfiles potentially consume a lot of space on disk and it is
never tried to delete them again. Try to avoid this situation by
deleting packfiles first and don't try to delete the other files if we
can't delete the packfile. This gives us the chance to delete the
packfile during next GC.
This commit only improves the situation - there is still the chance for
orphan files during packfile deletion. We don't have an atomic delete
of multiple files .
Change-Id: I0a19ae630186f07d0cc7fe9df246fa1cedeca8f6
This silences some discouraged access warnings issued since
TestRepository uses PackWriter which is in an internal package.
Change-Id: Ic9c4631e237c2fe1996c518328ecc2a9ab5c348b
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>