private Ref resolve( final Ref ref, int depth, String prefix, RefList<LooseRef> loose, RefList<Ref> packed) throws IOException { if (ref.isSymbolic()) { Ref dst = ref.getTarget(); if (MAX_SYMBOLIC_REF_DEPTH <= depth) return null; // claim it doesn't exist // If the cached value can be assumed to be current due to a // recent scan of the loose directory, use it. if (loose != null && dst.getName().startsWith(prefix)) { int idx; if (0 <= (idx = loose.find(dst.getName()))) dst = loose.get(idx); else if (0 <= (idx = packed.find(dst.getName()))) dst = packed.get(idx); else return ref; } else { dst = readRef(dst.getName(), packed); if (dst == null) return ref; } dst = resolve(dst, depth + 1, prefix, loose, packed); if (dst == null) return null; return new SymbolicRef(ref.getName(), dst); } return ref; }
@Override public String apply(ProjectResource rsrc) throws AuthException, ResourceNotFoundException, IOException { try (Repository repo = repoManager.openRepository(rsrc.getNameKey())) { Ref head = repo.getRefDatabase().exactRef(Constants.HEAD); if (head == null) { throw new ResourceNotFoundException(Constants.HEAD); } else if (head.isSymbolic()) { String n = head.getTarget().getName(); if (rsrc.getControl().controlForRef(n).isVisible()) { return n; } throw new AuthException("not allowed to see HEAD"); } else if (head.getObjectId() != null) { try (RevWalk rw = new RevWalk(repo)) { RevCommit commit = rw.parseCommit(head.getObjectId()); if (rsrc.getControl().canReadCommit(db.get(), repo, commit)) { return head.getObjectId().name(); } throw new AuthException("not allowed to see HEAD"); } catch (MissingObjectException | IncorrectObjectTypeException e) { if (rsrc.getControl().isOwner()) { return head.getObjectId().name(); } throw new AuthException("not allowed to see HEAD"); } } throw new ResourceNotFoundException(Constants.HEAD); } catch (RepositoryNotFoundException e) { throw new ResourceNotFoundException(rsrc.getName()); } }
private static Ref recreate(final Ref old, final ObjectIdRef leaf) { if (old.isSymbolic()) { Ref dst = recreate(old.getTarget(), leaf); return new SymbolicRef(old.getName(), dst); } return leaf; }
/** * Adds a set of refs to the set of packed-refs. Only non-symbolic refs are added. If a ref with * the given name already existed in packed-refs it is updated with the new value. Each loose ref * which was added to the packed-ref file is deleted. If a given ref can't be locked it will not * be added to the pack file. * * @param refs the refs to be added. Must be fully qualified. * @throws IOException */ public void pack(List<String> refs) throws IOException { if (refs.size() == 0) return; FS fs = parent.getFS(); // Lock the packed refs file and read the content LockFile lck = new LockFile(packedRefsFile); if (!lck.lock()) throw new IOException(MessageFormat.format(JGitText.get().cannotLock, packedRefsFile)); try { final PackedRefList packed = getPackedRefs(); RefList<Ref> cur = readPackedRefs(); // Iterate over all refs to be packed for (String refName : refs) { Ref ref = readRef(refName, cur); if (ref.isSymbolic()) continue; // can't pack symbolic refs // Add/Update it to packed-refs int idx = cur.find(refName); if (idx >= 0) cur = cur.set(idx, peeledPackedRef(ref)); else cur = cur.add(idx, peeledPackedRef(ref)); } // The new content for packed-refs is collected. Persist it. commitPackedRefs(lck, cur, packed); // Now delete the loose refs which are now packed for (String refName : refs) { // Lock the loose ref File refFile = fileFor(refName); if (!fs.exists(refFile)) continue; LockFile rLck = new LockFile(refFile); if (!rLck.lock()) continue; try { LooseRef currentLooseRef = scanRef(null, refName); if (currentLooseRef == null || currentLooseRef.isSymbolic()) continue; Ref packedRef = cur.get(refName); ObjectId clr_oid = currentLooseRef.getObjectId(); if (clr_oid != null && clr_oid.equals(packedRef.getObjectId())) { RefList<LooseRef> curLoose, newLoose; do { curLoose = looseRefs.get(); int idx = curLoose.find(refName); if (idx < 0) break; newLoose = curLoose.remove(idx); } while (!looseRefs.compareAndSet(curLoose, newLoose)); int levels = levelsIn(refName) - 2; delete(refFile, levels, rLck); } } finally { rLck.unlock(); } } // Don't fire refsChanged. The refs have not change, only their // storage. } finally { lck.unlock(); } }
@Override protected boolean tryLock(boolean deref) throws IOException { dstRef = getRef(); if (deref) dstRef = dstRef.getLeaf(); if (dstRef.isSymbolic()) setOldObjectId(null); else setOldObjectId(dstRef.getObjectId()); return true; }
/** * Obtain a modified copy of the cache with a ref stored. * * <p>This cache instance is not modified by this method. * * @param ref reference to add or replace. * @return a copy of this cache, with the reference added or replaced. */ public RefCache put(Ref ref) { RefList<Ref> newIds = this.ids.put(ref); RefList<Ref> newSym = this.sym; if (ref.isSymbolic()) { newSym = newSym.put(ref); } else { int p = newSym.find(ref.getName()); if (0 <= p) newSym = newSym.remove(p); } return new RefCache(newIds, newSym); }
public RefDirectoryUpdate newUpdate(String name, boolean detach) throws IOException { boolean detachingSymbolicRef = false; final RefList<Ref> packed = getPackedRefs(); Ref ref = readRef(name, packed); if (ref != null) ref = resolve(ref, 0, null, null, packed); if (ref == null) ref = new ObjectIdRef.Unpeeled(NEW, name, null); else { detachingSymbolicRef = detach && ref.isSymbolic(); } RefDirectoryUpdate refDirUpdate = new RefDirectoryUpdate(this, ref); if (detachingSymbolicRef) refDirUpdate.setDetachingSymbolicRef(); return refDirUpdate; }
/** @return all refs which were advertised to the client. */ public final Map<String, Ref> getAdvertisedRefs() { if (refs == null) { refs = refFilter.filter(db.getAllRefs()); Ref head = refs.get(Constants.HEAD); if (head != null && head.isSymbolic()) refs.remove(Constants.HEAD); for (Ref ref : refs.values()) { if (ref.getObjectId() != null) advertisedHaves.add(ref.getObjectId()); } advertisedHaves.addAll(db.getAdditionalHaves()); } return refs; }
private Ref resolve(Ref ref, int depth, RefList<Ref> loose) throws IOException { if (!ref.isSymbolic()) return ref; Ref dst = ref.getTarget(); if (MAX_SYMBOLIC_REF_DEPTH <= depth) return null; // claim it doesn't exist dst = loose.get(dst.getName()); if (dst == null) return ref; dst = resolve(dst, depth + 1, loose); if (dst == null) return null; return new SymbolicRef(ref.getName(), dst); }
@Override public RefUpdate newUpdate(String refName, boolean detach) throws IOException { boolean detachingSymbolicRef = false; Ref ref = getOneRef(refName); if (ref == null) ref = new ObjectIdRef.Unpeeled(NEW, refName, null); else detachingSymbolicRef = detach && ref.isSymbolic(); if (detachingSymbolicRef) { ref = new ObjectIdRef.Unpeeled(NEW, refName, ref.getObjectId()); } DfsRefUpdate update = new DfsRefUpdate(this, ref); if (detachingSymbolicRef) update.setDetachingSymbolicRef(); return update; }
void schedule(Project.NameKey project, String ref, URIish uri, ReplicationState state) { repLog.info("scheduling replication {}:{} => {}", project, ref, uri); if (!shouldReplicate(project, ref, state)) { return; } if (!config.replicatePermissions()) { PushOne e; synchronized (stateLock) { e = pending.get(uri); } if (e == null) { try (Repository git = gitManager.openRepository(project)) { try { Ref head = git.exactRef(Constants.HEAD); if (head != null && head.isSymbolic() && RefNames.REFS_CONFIG.equals(head.getLeaf().getName())) { return; } } catch (IOException err) { stateLog.error(String.format("cannot check type of project %s", project), err, state); return; } } catch (IOException err) { stateLog.error(String.format("source project %s not available", project), err, state); return; } } } synchronized (stateLock) { PushOne e = pending.get(uri); if (e == null) { e = opFactory.create(project, uri); pool.schedule(e, config.getDelay(), TimeUnit.SECONDS); pending.put(uri, e); } e.addRef(ref); state.increasePushTaskCount(project.get(), ref); e.addState(ref, state); repLog.info("scheduled {}:{} => {} to run after {}s", project, ref, e, config.getDelay()); } }
private void fillBranches() { Repository repository = getCommit().getRepository(); RevCommit commit = getCommit().getRevCommit(); RevWalk revWalk = new RevWalk(repository); List<Ref> result = new ArrayList<Ref>(); try { Map<String, Ref> refsMap = new HashMap<String, Ref>(); refsMap.putAll(repository.getRefDatabase().getRefs(Constants.R_HEADS)); refsMap.putAll(repository.getRefDatabase().getRefs(Constants.R_REMOTES)); for (Ref ref : refsMap.values()) { if (ref.isSymbolic()) continue; RevCommit headCommit = revWalk.parseCommit(ref.getObjectId()); RevCommit base = revWalk.parseCommit(commit); if (revWalk.isMergedInto(base, headCommit)) result.add(ref); } } catch (IOException ignored) { // Ignored } branchViewer.setInput(result); branchSection.setText( MessageFormat.format( UIText.CommitEditorPage_SectionBranches, Integer.valueOf(result.size()))); }
private String getSimpleText(RepositoryTreeNode node) { switch (node.getType()) { case REPO: File directory = ((Repository) node.getObject()).getDirectory(); StringBuilder sb = new StringBuilder(); sb.append(directory.getParentFile().getName()); sb.append(" - "); // $NON-NLS-1$ sb.append(directory.getAbsolutePath()); return sb.toString(); case FILE: // fall through case FOLDER: return ((File) node.getObject()).getName(); case BRANCHES: return UIText.RepositoriesView_Branches_Nodetext; case LOCAL: return UIText.RepositoriesViewLabelProvider_LocalNodetext; case REMOTETRACKING: return UIText.RepositoriesViewLabelProvider_RemoteTrackingNodetext; case BRANCHHIERARCHY: IPath fullPath = (IPath) node.getObject(); return fullPath.lastSegment(); case TAGS: return UIText.RepositoriesViewLabelProvider_TagsNodeText; case ADDITIONALREFS: return UIText.RepositoriesViewLabelProvider_SymbolicRefNodeText; case REMOTES: return UIText.RepositoriesView_RemotesNodeText; case REF: // fall through case TAG: { Ref ref = (Ref) node.getObject(); // shorten the name String refName = Repository.shortenRefName(ref.getName()); if (node.getParent().getType() == RepositoryTreeNodeType.BRANCHHIERARCHY) { int index = refName.lastIndexOf('/'); refName = refName.substring(index + 1); } return refName; } case ADDITIONALREF: { Ref ref = (Ref) node.getObject(); // shorten the name String refName = Repository.shortenRefName(ref.getName()); if (ref.isSymbolic()) { refName = refName + " - " //$NON-NLS-1$ + ref.getLeaf().getName() + " - " + ObjectId.toString(ref.getLeaf().getObjectId()); // $NON-NLS-1$ } else { refName = refName + " - " //$NON-NLS-1$ + ObjectId.toString(ref.getObjectId()); } return refName; } case WORKINGDIR: if (node.getRepository().isBare()) return UIText.RepositoriesView_WorkingDir_treenode + " - " //$NON-NLS-1$ + UIText.RepositoriesViewLabelProvider_BareRepositoryMessage; else return UIText.RepositoriesView_WorkingDir_treenode + " - " //$NON-NLS-1$ + node.getRepository().getWorkTree().getAbsolutePath(); case REMOTE: // fall through case PUSH: // fall through case FETCH: // fall through case ERROR: return (String) node.getObject(); } return null; }
public StyledString getStyledText(Object element) { if (!(element instanceof RepositoryTreeNode)) return null; RepositoryTreeNode node = (RepositoryTreeNode) element; try { switch (node.getType()) { case REPO: Repository repository = (Repository) node.getObject(); File directory = repository.getDirectory(); StyledString string = new StyledString(directory.getParentFile().getName()); string.append( " - " + directory.getAbsolutePath(), StyledString.QUALIFIER_STYLER); // $NON-NLS-1$ String branch = repository.getBranch(); if (repository.getRepositoryState() != RepositoryState.SAFE) branch += " - " + repository.getRepositoryState().getDescription(); // $NON-NLS-1$ string.append( " [" + branch + "]", StyledString.DECORATIONS_STYLER); // $NON-NLS-1$//$NON-NLS-2$ return string; case ADDITIONALREF: Ref ref = (Ref) node.getObject(); // shorten the name StyledString refName = new StyledString(Repository.shortenRefName(ref.getName())); if (ref.isSymbolic()) { refName.append(" - ", StyledString.QUALIFIER_STYLER); // $NON-NLS-1$ refName.append(ref.getLeaf().getName(), StyledString.QUALIFIER_STYLER); refName.append(" - ", StyledString.QUALIFIER_STYLER); // $NON-NLS-1$ refName.append( ObjectId.toString(ref.getLeaf().getObjectId()), StyledString.QUALIFIER_STYLER); } else { refName.append(" - ", StyledString.QUALIFIER_STYLER); // $NON-NLS-1$ refName.append(ObjectId.toString(ref.getObjectId()), StyledString.QUALIFIER_STYLER); } return refName; case WORKINGDIR: StyledString dirString = new StyledString(UIText.RepositoriesView_WorkingDir_treenode); dirString.append(" - ", StyledString.QUALIFIER_STYLER); // $NON-NLS-1$ if (node.getRepository().isBare()) { dirString.append( UIText.RepositoriesViewLabelProvider_BareRepositoryMessage, StyledString.QUALIFIER_STYLER); } else { dirString.append( node.getRepository().getWorkTree().getAbsolutePath(), StyledString.QUALIFIER_STYLER); } return dirString; case PUSH: // fall through case FETCH: // fall through case FILE: // fall through case FOLDER: // fall through case BRANCHES: // fall through case LOCAL: // fall through case REMOTETRACKING: // fall through case BRANCHHIERARCHY: // fall through case TAGS: // fall through; case ADDITIONALREFS: // fall through case REMOTES: // fall through case REMOTE: // fall through case ERROR: // fall through case REF: // fall through case TAG: { String label = getSimpleText(node); if (label != null) return new StyledString(label); } } } catch (IOException e) { Activator.logError(e.getMessage(), e); } return null; }