aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src/org/eclipse
Commit message (Collapse)AuthorAgeFilesLines
* Throw IndexReadException if existing index can't be readChristian Halstrick2015-11-193-0/+90
| | | | | | | | | If the index file exists but can't be read for example because of wrong filesystem permissions we should throw a specific exception. This allows EGit to handle this error situation. Bug: 482607 Change-Id: I50bfcb719c45caac3cb5550a8b16307c2ea9def4 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
* Fix pre-push hook to not set null remoteName as first argumentMatthias Sohn2015-11-181-0/+3
| | | | | | | | | | | | | | | According to [1] the pre-push hook expects two parameters which provide the name and location of the destination remote, if a named remote is not being used both values should be the same. We did set the first parameter to null in that case which caused ProcessBuilder to throw a NullPointerException since its start() method doesn't accept null arguments. [1] https://git-scm.com/docs/githooks#_pre_push Bug: 482393 Change-Id: Idb9b0a48cefac01abfcfdf00f6d173f8fa1d9a7b Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
* Introduce FS.execute() to execute a command defined by a ProcessBuilderChristian Halstrick2015-11-181-3/+75
| | | | | Change-Id: I2ad2c71ad30b969455bdea89637b8e996b1dad8c Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
* Add an attribute accessor to CanonicalTreeParser and use it in TreewalkChristian Halstrick2015-11-185-74/+110
| | | | | | | | | When checking out a branch we need to access the attributes stored in the tree to be checked out. E.g. directly after a clone we checkout the remote HEAD. In this case index and workingtree are still empty. So we have to search the tree to be checked out for attributes. Change-Id: I6d96f5d095ed2e3c259d4b12124e404f5215bd9f
* Adds the git attributes computation on the treewalkArthur Daussy2015-11-1814-77/+708
| | | | | | | | | | | | Adds the getAttributes feature to the tree walk. The computation of attributes needs to be done by the TreeWalk since it needs both a WorkingTreeIterator and a DirCacheIterator. Bug: 342372 CQ: 9120 Change-Id: I5e33257fd8c9895869a128bad3fd1e720409d361 Signed-off-by: Arthur Daussy <arthur.daussy@obeo.fr> Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
* Make jgit annotations accessible to other pluginsAndrey Loskutov2015-11-172-0/+4
| | | | | | | | | | | | | | | Other plugins which want to use JGit nullness annotations in their code cannot do this if the annotations aren't part of the published API. Unfortunately it looks like although Eclipse JDT allows to use custom nullness annotation types per project, it does not understand if those annotations are used mixed with other nullness annotations in other projects. E.g. EGit can either configure JGit annotations for NPE analysis and so "understand" nullness from JGit API but so it loses the ability to use any other nullness annotations to annotate its own code. Change-Id: Ieeeb578c2fe35223a7561d668dce8e767dc89ef0 Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
* Added jgit own NonNull annotation typeAndrey Loskutov2015-11-171-0/+67
| | | | | | | | | | | The annotation is required for example in Repository case (patch follows), where almost all non-void return methods return Nullable except few returning NonNull. I definitely do not favor this style, but it is a nightmare to clients to guess if the null check is needed or not. Change-Id: Ib2a778a246c6d84b7c32565f54df2385b59f6498 Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
* Merge "Fix MissingObjectException in RenameDetector"Christian Halstrick2015-11-171-1/+5
|\
| * Fix MissingObjectException in RenameDetectorRĂ¼diger Herrmann2015-11-121-1/+5
| | | | | | | | | | | | | | | | | | | | | | When attempting to determine the size of a blob that does not exist, the RenameDetector throws a MissingObjectException. The fix is to return a size of zero if the size is requested for a blob id that doesn't exist. Bug: 481577 Change-Id: I4e86276039c630617610cc51d0eefa56d7d3952f Signed-off-by: RĂ¼diger Herrmann <ruediger.herrmann@gmx.de>
* | Handle InternalError during symlink support detection on WindowsMatthias Sohn2015-11-151-1/+2
| | | | | | | | | | | | | | | | | | | | | | When JGit tries to detect symlink support the attempt to create a symlink may fail with a java.lang.InternalError. This was reported for a case where the application using JGit runs in Windows XP compatibility mode using Oracle JDK 1.8. Handle this by assuming symlinks are not supported in this case. Bug: 471027 Change-Id: I978288754dea0c6fffd3457fad7d4d971e27c6c2 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
* | Merge branch 'stable-4.1'Matthias Sohn2015-11-142-13/+28
|\ \ | |/ |/| | | | | | | | | | | | | | | * stable-4.1: Prepare 4.1.2-SNAPSHOT builds JGit v4.1.1.201511131810-r Fallback exactRef: Do not ignore symrefs to unborn branch RefDirectory.exactRef: Do not ignore symrefs to unborn branch Change-Id: I66afb303f355aad8a7eaa7a6dff06de70ae9c490 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
| * Fallback exactRef: Do not ignore symrefs to unborn branchJonathan Nieder2015-11-121-13/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When asked to read a symref pointing to a branch-yet-to-be-born (such as HEAD in a newly initialized repository), getRef and getRefs provide different results. getRef: SymbolicRef[HEAD -> refs/heads/master=00000000] getRefs and getAdditionalRefs: nothing exactRef should match the getRef behavior: it is meant to be a simpler, faster version of getRef that lets you search for a ref without resolving it using the search path without other semantic changes. But the fallback implementation of exactRef relies on getRefs and produces null for this case. Luckily the in-tree RefDatabase implementations override exactRef and get the correct behavior. But any out-of-tree storage backend that doesn't inherit from DfsRefDatabase or RefDirectory would still return null when it shouldn't. Let the fallback implementation use getRef instead to avoid this. This means that exactRef would waste some effort traversing the ref search path when the named ref is not found --- but subclasses tend to override exactRef for performance already, so in the default implementation correctness is more important. Bug: 478865 Change-Id: I60f04e3ce3bf4731640ffd2433d329e621330029
| * RefDirectory.exactRef: Do not ignore symrefs to unborn branchJonathan Nieder2015-11-111-0/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When asked to read a symref pointing to a branch-yet-to-be-born (such as HEAD in a newly initialized repository), DfsRepository and FileRepository return different results. FileRepository: exactRef("HEAD") => null DfsRepository: exactRef("HEAD") => SymbolicRef[HEAD -> refs/heads/master=00000000] getRef("HEAD") returns the same as DfsRepository's exactRef in both backends. The intended behavior is the DfsRepository one: exactRef() is supposed to be like getRef(), but more exact because it doesn't need to traverse the search path. The discrepancy is because DfsRefDatabase implements exactRef() directly with the intended semantics, while RefDirectory uses a fallback implementation built on top of getRefs(). getRefs() skips symrefs to an unborn branch. Override the fallback implementation with a correct implementation that is similar to getRef() to avoid this. A followup change will fix the fallback. Change-Id: Ic138a5564a099ebf32248d86b93e2de9ab3c94ee Reported-by: David Pursehouse <david.pursehouse@sonymobile.com> Improved-by: Christian Halstrick <christian.halstrick@sap.com> Bug: 478865
* | Merge "Revert "Remove PackWriter.Statistics and other deprecated classes""Jonathan Nieder2015-11-104-0/+497
|\ \
| * | Revert "Remove PackWriter.Statistics and other deprecated classes"Jonathan Nieder2015-11-104-0/+497
| | | | | | | | | | | | | | | | | | | | | | | | This reverts commit bbcbcab8d39dd4bdf194cdba02c97a9eb70b2379. These classes were part of the public API and should not be removed until JGit 5.0. Change-Id: Ife4bee69f82151de6ef8ea1a4c6c146d91bbf0d5
* | | Merge "Remove PackWriter.Statistics and other deprecated classes"Jonathan Nieder2015-11-104-497/+0
|\| |
| * | Remove PackWriter.Statistics and other deprecated classesTerry Parker2015-11-094-497/+0
| | | | | | | | | | | | | | | | | | | | | | | | These classes make improper use of internal classes in the public API and were replaced by corresponding classes in the JGit 4.1 release. Change-Id: I3d474210e49089aa788314b4e08f505f0d26619b Signed-off-by: Terry Parker <tparker@google.com>
* | | Add missing javadoc to bitmap index classesMatthias Sohn2015-11-102-1/+9
|/ / | | | | | | Change-Id: Ib9fd230c9465a719df53cfcb314d8b5015743928 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
* | Merge changes from topic 'nullable'Jonathan Nieder2015-11-092-3/+72
|\ \ | | | | | | | | | | | | | | | | | | * changes: Update dependencies to use the JGit-internal @Nullable Use the JGit-internal @Nullable annotation Add a JGit-internal Nullable type
| * | Use the JGit-internal @Nullable annotationTerry Parker2015-11-091-3/+5
| | | | | | | | | | | | | | | | | | | | | | | | Update existing @Nullable uses to use the JGit-internal version of the annotation. Change-Id: I95234ffad4c3110f9597fbd3a2760f653e22ecf7 Signed-off-by: Terry Parker <tparker@google.com>
| * | Add a JGit-internal Nullable typeTerry Parker2015-11-091-0/+67
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit 847b3d1 enabled annotation-based NPE analysis to JGit. In so doing, it introduced a new dependency on the org.eclipse.jdt that is undesirable. Follow Gerrit's lead by adding an internal Nullable type (see https://gerrit.googlesource.com/gerrit/+/stable-2.11/gerrit-common/src/main/java/com/google/gerrit/common/Nullable.java). The javax.annotations.Nullable class uses a retention policy of RUNTIME, whereas the org.eclipse.jdt.annotation.Nullable class used a policy of CLASS. Since I'm not aware of tools that make use of the annotation at runtime I chose the CLASS policy. If in the future there is a benefit to retaining the annotations in the running binary we can update this class. Change-Id: I63dc8f9a6dc46b517cbde211bb5e2f8521a54d04 Signed-off-by: Terry Parker <tparker@google.com>
* | | Make BitmapIndexImpl.CompressedBitmap publicJonathan Nieder2015-11-092-14/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | PackWriterBitmapPreparer (which is in another package) is already well aware of the mapping between EWAHCompressedBitmaps and the higher-level CompressedBitmap objects of the BitmapIndexImpl API. Making the CompressedBitmap type public makes the translation more obvious and wouldn't break any abstractions that aren't already broken. So expose it. This is all under org.eclipse.jgit.internal so there are no API stability guarantees --- we can change the API if internals change (for example if some day there are bitmaps spanning multiple packs). In particular this means the confusing toBitmap helper can be removed. Change-Id: Ifb2e8804a6d5ee46e82a76d276c4f8507eaa2a4c
* | | Make BitmapIndexImpl.CompressedBitmap, CompressedBitmapBuilder staticJonathan Nieder2015-11-091-78/+71
|/ / | | | | | | | | | | | | | | | | | | | | | | | | | | | | A CompressedBitmap represents a pair (EWAH bit vector, PackIndex assigning bit positions to git objects). The bit vector is a member field and the PackIndex is implicit via the 'this' reference to the outer class. Make this clearer by making CompressedBitmap a static class and replacing the 'this' reference by an explicit field. Likewise for CompressedBitmapBuilder. Change-Id: Id85659fc4fc3ad82034db3370cce4cdbe0c5492c Suggested-by: Terry Parker <tparker@google.com>
* | Skip redundant 'OR-reuse' step in tip commit bitmap setupJonathan Nieder2015-11-081-8/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When creating bitmaps during gc, the bitmaps in tipCommitBitmaps are built in setupTipCommitBitmaps using the following procedure: 0. create a bitmap ('reuse') that lists all ancestors of commits whose existing bitmaps will be reused. I will call this the reused part of history. 1. initialize a bitmap for each of the pack's "want"s by taking a copy of the 'reuse' bitmap and setting the bit corresponding to the one wanted commit. 2. walk through ancestors of wants, excluding the reused part of history. Add parents of visited commits to bitmaps that have those commits. 3. AND-NOT each tipCommitBitmap against the 'reuse' bitmap 4. Sort the bitmaps and AND-NOT each against the previous so they partition the new commits. The OR against 'reuse' in step 1 and the AND-NOT against 'reuse' cancel each other out, except when commits from the reused part of history are added to a bitmap in step 2. So avoid adding commits from the reused part of history in step 2 and skip the OR and AND-NOT. Performance impact (thanks to Terry for measuring): The initial "selecting bitmaps" phase of garbage collection decreased from (83 + 81 + 85) / 3 = 83 to (56 + 57 + 56) / 3 = 56.3, meaning nearly a ~50% speedup of that phase. Tested-by: Terry Parker <tparker@google.com> Change-Id: I26ea695809594347575d14a1d8e6721b8608eb9c
* | Avoid repeated sort of tipCommitBitmapsJonathan Nieder2015-11-071-5/+6
| | | | | | | | Change-Id: I0feb2003f58776d50fab2d31d46ac98ae863bea8
* | [style] Shorten line lengths and import order in bitmap codeTerry Parker2015-11-072-3/+5
| | | | | | | | | | Change-Id: I420fcd308a97e30b8c74026d74b93ed3ec74bb3f Signed-off-by: Terry Parker <tparker@google.com>
* | Inline PackWriterBitmapWalker.newRevFilter into callersJonathan Nieder2015-11-052-12/+10
| | | | | | | | | | | | | | | | Instead of using the newRevFilter helper, call the appropriate RevFilter constructor directly. This means one less hop to find documentation about what the RevFilter will do. Change-Id: Ida6ff1c0457a47a1bd1e4ed0fd1dd42a616d214f
* | Convert remaining callers of BitmapBuilder.add to use .addObjectJonathan Nieder2015-11-052-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | When setupTipCommitBitmaps is called, writeBitmaps does not have any bitmaps saved, so these calls to .add always add a single commit and do not OR in a bitmap. The objects returned by nextObject after a commit walk is finished are trees and blobs. Non-commit objects do not have bitmaps associated so the call to .add also can only add a single object. Change-Id: I7b816145251a7fa4f1fffe0d03644257ea7f5440
* | Merge changes I57b1d7c1,I590ac460Jonathan Nieder2015-11-051-20/+84
|\ \ | | | | | | | | | | | | | | | * changes: Use .addObject and .or instead of .add in AddToBitmapFilter Replace anonymous BitmapRevFilter subclasses with explicit classes
| * | Use .addObject and .or instead of .add in AddToBitmapFilterJonathan Nieder2015-11-051-2/+18
| | | | | | | | | | | | | | | | | | | | | | | | This is the caller that the BitmapBuilder.add method was designed around. Moving away from .add makes it more verbose but hopefully clearer. Change-Id: I57b1d7c1dc8fb800b242b76c606922b5aa36b9b2
| * | Replace anonymous BitmapRevFilter subclasses with explicit classesJonathan Nieder2015-11-051-20/+68
| | | | | | | | | | | | | | | | | | | | | | | | This puts the code for include() in each RevFilter returned by newRevFilter in one place and should make the code easier to understand and modify. Change-Id: I590ac4604b61fc1ffe7aba2ed89f8139847ccac3
* | | Merge changes Ia95da478,I2773aa94,Ib745645f,I92c65f34,Ibb714002, ...Jonathan Nieder2015-11-054-25/+124
|\| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * changes: Remove BitmapRevFilter.getCountOfLoadedCommits Make BitmapBuilder.getBitmapIndex public Deprecate BitmapBuilder.add and introduce simpler addObject method Add @Override annotations to BitmapIndexImpl Rely on bitmap RevFilter to filter walk during bitmap selection Use 'reused' bitmap to filter walk during bitmap selection Rely on bitmap RevFilter to filter tip commit setup walk Use 'reused' bitmap to filter tip commit setup walk Include ancestors of reused bitmap commits in reuse bitmap again
| * | Remove BitmapRevFilter.getCountOfLoadedCommitsJonathan Nieder2015-11-051-8/+8
| | | | | | | | | | | | | | | | | | | | | The count of loaded commits is equal to the number of commits returned by the walk. Simplify BitmapRevFilter by counting them in the caller. Change-Id: Ia95da47831d9e89d6f8068470ec4529aaabfa7dd
| * | Make BitmapBuilder.getBitmapIndex publicJonathan Nieder2015-11-052-1/+9
| | | | | | | | | | | | | | | | | | | | | | | | Every Bitmap in current JGit code has an associated BitmapIndex. Make it public in BitmapBuilder to make retrieving bitmaps to OR in from that index easier. Change-Id: I2773aa94d8b67f12194608e6317c0792a5de21e2
| * | Deprecate BitmapBuilder.add and introduce simpler addObject methodJonathan Nieder2015-11-052-4/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The BitmapIndex.BitmapBuilder.add API is subtle: /** * Adds the id and the existing bitmap for the id, if one * exists, to the bitmap. * * @return true if the value was not contained or able to be * loaded. */ boolean add(AnyObjectId objectId, int type); Reading the name of the method does not make it obvious what it will do. Does it add the named object to the bitmap, or all objects reachable from it? It depends on whether the BitmapIndex owns an existing bitmap for that object. I did not notice this subtlety when skimming the javadoc, either. This resulted in enough confusion to subtly break the bitmap building code (see change I30844134bfde0cbabdfaab884c84b9809dd8bdb8 for details). So discourage use of the add() API by deprecating it. To replace it, provide a addObject() method that adds a single object. This way, callers can decide whether to use addObject() or or() based on the context. For example, if (bitmap.add(c, OBJ_COMMIT)) { for (RevCommit p : c.getParents()) { rememberToAlsoHandle(p); } } can be replaced with if (bitmap.contains(c)) { // already included } else if (index.getBitmap(c) != null) { bitmap.or(index.getBitmap(c)); } else { bitmap.addObject(c, OBJ_COMMIT); for (RevCommit p : c.getParents()) { rememberToAlsoHandle(p); } } which is more verbose but makes it clearer that the behavior depends on the content of index.getBitmaps(). Change-Id: Ib745645f187e1b1483f8587e99501dfcb7b867a5
| * | Add @Override annotations to BitmapIndexImplJonathan Nieder2015-11-051-0/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | This makes it easier to distinguish between implementations of methods from the interface from helpers internal to org.eclipse.jgit.internal.storage.*. This was illegal in Java 5 but JGit requires newer Java these days. Change-Id: I92c65f3407a334acddd32ec9e09ab7d1d39c4dc6
| * | Rely on bitmap RevFilter to filter walk during bitmap selectionJonathan Nieder2015-11-051-3/+0
| | | | | | | | | | | | | | | | | | | | | | | | This RevWalk filters out reused bitmap commits via the 'reuse' bitmap. Avoid possible wasted time and complexity by not also redundantly marking them UNINTERESTING. Change-Id: Ibb714002ddac599963d148a9aab90645fcc73141
| * | Use 'reused' bitmap to filter walk during bitmap selectionJonathan Nieder2015-11-051-3/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When building fullBitmap in order to determine which ancestor chain to add this commit to, we were excluding the ancestors of reusedCommits using markUninteresting. This use of markUninteresting is a bit wasteful because we already have a bitmap indicating exactly which commits should be excluded (which can save some walking). Use it. A separate commit will remove the now-redundant markUninteresting call. No behavior change intended (except for performance improvement). Change-Id: I1112641852d72aa05c9a8bd08a552c70342ccedb
| * | Rely on bitmap RevFilter to filter tip commit setup walkJonathan Nieder2015-11-051-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | This RevWalk filters out reused bitmap commits via the 'reuse' bitmap. Avoid possible wasted time and complexity by not redundantly marking them UNINTERESTING any more. Change-Id: If467ccd1d75e17cf9367b2a0399fca3f9d52adf9
| * | Use 'reused' bitmap to filter tip commit setup walkJonathan Nieder2015-11-051-0/+42
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When garbage collecting, we decide to reuse some bitmaps in older history from the previous pack to save time. The remainder of commit selection only involves commits not covered by those bitmaps. Currently we carry that out in two ways: 1. by building a bitmap representing the already-covered commits, for easy containment checks and AND-NOT-ing against 2. by marking the reused bitmap commits as uninteresting in the RevWalk that finds new commits The mechanism in (2) is less efficient than (1): rw.next() will walk back from reused bitmap commits to check whether the commit it is about to emit is an ancestor of them, when using the bitmap from (1) would let us perform the same check with a single contains() call. Add a RevFilter teaching the RevWalk to perform that same check directly using the bitmap from (1). The next time the RevWalk is used, a different RevFilter is installed so this does not break that. A later commit will drop the markUninteresting calls. No functional change intended except a possible speedup. Change-Id: Ic375210fa69330948be488bf9dbbe4cb0d069ae6
| * | Include ancestors of reused bitmap commits in reuse bitmap againJonathan Nieder2015-11-032-5/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Until 320a4142 (Update bitmap selection throttling to fully span active branches, 2015-10-20), setupTipCommitBitmaps contained code along the following lines: for (PackBitmapIndexRemapper.Entry entry : bitmapRemapper) { if (!reuse(entry)) continue; RevCommit rc = (RevCommit) rw.peel(rw.parseAny(entry)); reuseCommits.add(new BitmapCommit(rc)); EWAHCompressedBitmap bitmap = remap.ofObjectType(remap.getBitmap(rc), OBJ_COMMIT); writeBitmaps.addBitmap(rc, bitmap, 0); reuse.add(rc, OBJ_COMMIT); } writeBitmaps.clearBitmaps(); // Remove temporary bitmaps This loop OR-ed together bitmaps for commits whose bitmaps would be reused. A subtle point is the use of the add() method, which ORs in a bitmap from the BitmapIndex when it exists and falls back to OR-ing in a single bit when that bitmap does not exist in the BitmapIndex. Commit 320a4142 removed the addBitmap step, so the bitmap does not exist in the BitmapIndex and the fallback behavior is triggered. Simplify and restore the intended behavior by avoiding use of the subtle use of the add() method --- use or() directly instead. Change-Id: I30844134bfde0cbabdfaab884c84b9809dd8bdb8
* | | Insert duplicate objects to prevent race during garbage collection.Mike Williams2015-11-042-1/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Prior to this change, DfsInserter would not insert an object into a pack if it already existed in another pack in the repository, even if that pack was unreachable. Consider this sequence of events: - Object FOO is pushed to a repository. - Subsequent ref changes make FOO UNREACHABLE_GARBAGE. - FOO is subsequently re-inserted using a DfsInserter, but skipped due to existing in UNREACHABLE_GARBAGE. - The repository is repacked; FOO will not be written into a new pack because it is not yet reachable from a reference. If the UNREACHABLE_GARBAGE packs are deleted, FOO disappears. - A reference is updated to reference FOO. This reference is now broken as FOO was removed when the repacking process deleted the UNREACHABLE_GARBAGE pack that stored the only copy of FOO. The garbage collector can't safely delete the UNREACHABLE_GARBAGE pack because FOO might be in the middle of being re-inserted/re-packed. This change writes a duplicate copy of an object if it only exists in UNREACHABLE_GARBAGE. This "freshens" the object to give it a chance to survive long enough to be made reachable through a reference. Change-Id: I20f2062230f3af3bccd6f21d3b7342f1152a5532 Signed-off-by: Mike Williams <miwilliams@google.com>
* | | Merge "Delta compression: reuse DeltaTask.getAdjustedWeight()"Jonathan Nieder2015-11-042-3/+2
|\ \ \
| * | | Delta compression: reuse DeltaTask.getAdjustedWeight()Terry Parker2015-11-032-3/+2
| | | | | | | | | | | | | | | | | | | | Change-Id: I07ed5207b175735b4e2c46edf652cc35908dad02 Signed-off-by: Terry Parker <tparker@google.com>
* | | | Merge "[performance] Speed up delta packing"Shawn Pearce2015-11-041-8/+15
|\| | | | |/ / |/| |
| * | [performance] Speed up delta packingTerry Parker2015-11-031-8/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When packing is able to reuse lots of deltas from existing packs, those objects are marked as "doNotAttemptDelta" and do not contribute to DeltaTask's computeTopPaths() "totalWeight" calculation. In the extreme case when all packs are reusable, "totalWeight" will be zero. DeltaTask.partitionTasks() uses "totalWeight" to determine a "weightPerThread" size it uses to set up DeltaTasks. When "totalWeight" is small, partitionTasks() ends up creating a DeltaTask for every unique path. For a large repository, the small "weightPerThread" can result in the creation of >100k tasks (for the MSM 3.10 Linux repository, the count was ~150k). This makes the "task stealing" mechanism in DeltaTask very inefficient, because every attempt to steal work does a linear walk through all tasks, searching for the one with the most work remaining, which is O(N^2) comparisons. For the MSM 3.10 repository when all deltas were reusable, PackWriter.parallelDeltaSearch() took (1615+1633+1458)/3 = 1568 seconds. The error is that DeltaTask treats the weights of objects marked as "doNotAttemptDelta" inconsistently. It ignores the weights when calculating "totalWeight" but uses them when partitioning the tasks. The fix is to also ignore them when partitioning the tasks. With this patch applied, PackWriter.parallelDeltaSearch() on the MSM 3.10 repository when all deltas are reused went from taking 1568 seconds to 62ms (>25k speedup). This patch also fixes a totalWeight initialization error in DeltaTask.computeTopPaths(). Change-Id: I2ae37efa83bca42b0e716266ae6aa9d182e76d9c Signed-off-by: Terry Parker <tparker@google.com>
* | | Merge "Decrease indentation in setupTipCommitBitmaps"Jonathan Nieder2015-11-031-23/+27
|\ \ \
| * | | Decrease indentation in setupTipCommitBitmapsJonathan Nieder2015-11-031-23/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Avoid leaving the reader in suspense by handling the unusual (!RevCommit) case first. As a nice side effect, there is less nesting to keep track of in the rest of the loop body. No functional change intended. Change-Id: I1580de444fccde08070f696218c12041151a924a
* | | | Merge "[style] Add braces to DeltaTask"Jonathan Nieder2015-11-031-15/+29
|\ \ \ \ | | |/ / | |/| |
| * | | [style] Add braces to DeltaTaskTerry Parker2015-11-031-15/+29
| | | | | | | | | | | | | | | | | | | | Change-Id: I3306cc77544dec6d9273b2c35b8db0ed43799992 Signed-off-by: Terry Parker <tparker@google.com>