/** * Update any smudged entries with information from the working tree. * * @throws IOException */ private void updateSmudgedEntries() throws IOException { TreeWalk walk = new TreeWalk(repository); List<String> paths = new ArrayList<String>(128); try { for (int i = 0; i < entryCnt; i++) if (sortedEntries[i].isSmudged()) paths.add(sortedEntries[i].getPathString()); if (paths.isEmpty()) return; walk.setFilter(PathFilterGroup.createFromStrings(paths)); DirCacheIterator iIter = new DirCacheIterator(this); FileTreeIterator fIter = new FileTreeIterator(repository); walk.addTree(iIter); walk.addTree(fIter); walk.setRecursive(true); while (walk.next()) { iIter = walk.getTree(0, DirCacheIterator.class); if (iIter == null) continue; fIter = walk.getTree(1, FileTreeIterator.class); if (fIter == null) continue; DirCacheEntry entry = iIter.getDirCacheEntry(); if (entry.isSmudged() && iIter.idEqual(fIter)) { entry.setLength(fIter.getEntryLength()); entry.setLastModified(fIter.getEntryLastModified()); } } } finally { walk.release(); } }
/** * Open a tree walk and filter to exactly one path. * * <p>The returned tree walk is already positioned on the requested path, so the caller should not * need to invoke {@link #next()} unless they are looking for a possible directory/file name * conflict. * * @param db repository to read tree object data from. * @param path single path to advance the tree walk instance into. * @param trees one or more trees to walk through, all with the same root. * @return a new tree walk configured for exactly this one path; null if no path was found in any * of the trees. * @throws IOException reading a pack file or loose object failed. * @throws CorruptObjectException an tree object could not be read as its data stream did not * appear to be a tree, or could not be inflated. * @throws IncorrectObjectTypeException an object we expected to be a tree was not a tree. * @throws MissingObjectException a tree object was not found. */ public static TreeWalk forPath(final Repository db, final String path, final AnyObjectId... trees) throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException, IOException { final TreeWalk r = new TreeWalk(db); r.setFilter(PathFilterGroup.createFromStrings(Collections.singleton(path))); r.setRecursive(r.getFilter().shouldBeRecursive()); r.reset(trees); return r.next() ? r : null; }
/** * Retrieve file status * * @param path * @return file status * @throws IOException */ private Status getFileStatus(String path) throws IOException { AdaptableFileTreeIterator fileTreeIterator = new AdaptableFileTreeIterator(repository, ResourcesPlugin.getWorkspace().getRoot()); IndexDiff indexDiff = new IndexDiff(repository, Constants.HEAD, fileTreeIterator); Set<String> repositoryPaths = Collections.singleton(path); indexDiff.setFilter(PathFilterGroup.createFromStrings(repositoryPaths)); indexDiff.diff(null, 0, 0, ""); // $NON-NLS-1$ return getFileStatus(path, indexDiff); }
/** * Returns a list of commits for the repository or a path within the repository. Caller may * specify ending revision with objectId. Caller may specify offset and maxCount to achieve * pagination of results. If the repository does not exist or is empty, an empty list is returned. * * @param repository * @param objectId if unspecified, HEAD is assumed. * @param path if unspecified, commits for repository are returned. If specified, commits for the * path are returned. * @param offset * @param maxCount if < 0, all commits are returned. * @return a paged list of commits */ public static List<RevCommit> getRevLog( Repository repository, String objectId, String path, int offset, int maxCount) { List<RevCommit> list = new ArrayList<RevCommit>(); if (maxCount == 0) { return list; } if (!hasCommits(repository)) { return list; } try { // resolve branch ObjectId branchObject; if (objectId == null) { branchObject = getDefaultBranch(repository); } else { branchObject = repository.resolve(objectId); } RevWalk rw = new RevWalk(repository); rw.markStart(rw.parseCommit(branchObject)); if (!(path == null)) { TreeFilter filter = AndTreeFilter.create( PathFilterGroup.createFromStrings(Collections.singleton(path)), TreeFilter.ALL); // TreeFilter.ANY_DIFF rw.setTreeFilter(filter); } Iterable<RevCommit> revlog = rw; if (offset > 0) { int count = 0; for (RevCommit rev : revlog) { count++; if (count > offset) { list.add(rev); if (maxCount > 0 && list.size() == maxCount) { break; } } } } else { for (RevCommit rev : revlog) { list.add(rev); if (maxCount > 0 && list.size() == maxCount) { break; } } } rw.dispose(); } catch (Throwable t) { // todo Logger.error(t, t.getMessage()); } return list; }
private KidWalk buildWalk() { final RepositoryMapping rm = RepositoryMapping.getMapping(resource); if (rm == null) { Activator.logError( NLS.bind(CoreText.GitFileHistory_gitNotAttached, resource.getProject().getName()), null); return null; } final KidWalk w = new KidWalk(rm.getRepository()); gitPath = rm.getRepoRelativePath(resource); w.setTreeFilter( AndTreeFilter.create( PathFilterGroup.createFromStrings(Collections.singleton(gitPath)), TreeFilter.ANY_DIFF)); return w; }
/** * Lookup an entry stored in a tree, failing if not present. * * @param tree the tree to search. * @param path the path to find the entry of. * @return the parsed object entry at this path, never null. * @throws Exception */ public RevObject get(final RevTree tree, final String path) throws Exception { final TreeWalk tw = new TreeWalk(pool.getObjectReader()); tw.setFilter(PathFilterGroup.createFromStrings(Collections.singleton(path))); tw.reset(tree); while (tw.next()) { if (tw.isSubtree() && !path.equals(tw.getPathString())) { tw.enterSubtree(); continue; } final ObjectId entid = tw.getObjectId(0); final FileMode entmode = tw.getFileMode(0); return pool.lookupAny(entid, entmode.getObjectType()); } fail("Can't find " + path + " in tree " + tree.name()); return null; // never reached. }
private IndexDiffData calcIndexDiffDataIncremental( IProgressMonitor monitor, String jobName, Collection<String> filesToUpdate, Collection<IResource> resourcesToUpdate) throws IOException { if (indexDiffData == null) // Incremental update not possible without prior indexDiffData // -> do full refresh instead return calcIndexDiffDataFull(monitor, jobName); EclipseGitProgressTransformer jgitMonitor = new EclipseGitProgressTransformer(monitor); List<String> treeFilterPaths = calcTreeFilterPaths(filesToUpdate); WorkingTreeIterator iterator = IteratorService.createInitialIterator(repository); if (iterator == null) return null; // workspace is closed IndexDiff diffForChangedResources = new IndexDiff(repository, Constants.HEAD, iterator); diffForChangedResources.setFilter(PathFilterGroup.createFromStrings(treeFilterPaths)); diffForChangedResources.diff(jgitMonitor, 0, 0, jobName); return new IndexDiffData( indexDiffData, filesToUpdate, resourcesToUpdate, diffForChangedResources); }
private boolean handleGetCommitBody( HttpServletRequest request, HttpServletResponse response, Repository db, String ref, String pattern) throws IOException, ServletException, CoreException { ObjectId refId = db.resolve(ref); if (refId == null) { String msg = NLS.bind("Failed to get commit body for ref {0}", ref); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); } RevWalk walk = new RevWalk(db); walk.setTreeFilter( AndTreeFilter.create( PathFilterGroup.createFromStrings(Collections.singleton(pattern)), TreeFilter.ANY_DIFF)); RevCommit revCommit = walk.parseCommit(refId); walk.dispose(); Commit commit = new Commit(null /* not needed */, db, revCommit, pattern); ObjectStream stream = commit.toObjectStream(); if (stream == null) { String msg = NLS.bind("Commit body for ref {0} not found", ref); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null)); } IOUtilities.pipe(stream, response.getOutputStream(), true, false); return true; }
public HistoryPanel( String wicketId, final String repositoryName, final String objectId, final String path, Repository r, int limit, int pageOffset, boolean showRemoteRefs) { super(wicketId); boolean pageResults = limit <= 0; int itemsPerPage = GitBlit.getInteger(Keys.web.itemsPerPage, 50); if (itemsPerPage <= 1) { itemsPerPage = 50; } RevCommit commit = JGitUtils.getCommit(r, objectId); List<PathChangeModel> paths = JGitUtils.getFilesInCommit(r, commit); Map<String, SubmoduleModel> submodules = new HashMap<String, SubmoduleModel>(); for (SubmoduleModel model : JGitUtils.getSubmodules(r, commit.getTree())) { submodules.put(model.path, model); } PathModel matchingPath = null; for (PathModel p : paths) { if (p.path.equals(path)) { matchingPath = p; break; } } if (matchingPath == null) { // path not in commit // manually locate path in tree TreeWalk tw = new TreeWalk(r); tw.reset(); tw.setRecursive(true); try { tw.addTree(commit.getTree()); tw.setFilter(PathFilterGroup.createFromStrings(Collections.singleton(path))); while (tw.next()) { if (tw.getPathString().equals(path)) { matchingPath = new PathChangeModel( tw.getPathString(), tw.getPathString(), 0, tw.getRawMode(0), tw.getObjectId(0).getName(), commit.getId().getName(), ChangeType.MODIFY); } } } catch (Exception e) { } finally { tw.release(); } } final boolean isTree = matchingPath == null ? true : matchingPath.isTree(); final boolean isSubmodule = matchingPath == null ? true : matchingPath.isSubmodule(); // submodule SubmoduleModel submodule = getSubmodule(submodules, repositoryName, matchingPath.path); final String submodulePath; final boolean hasSubmodule; if (submodule != null) { submodulePath = submodule.gitblitPath; hasSubmodule = submodule.hasSubmodule; } else { submodulePath = ""; hasSubmodule = false; } final Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(r, showRemoteRefs); List<RevCommit> commits; if (pageResults) { // Paging result set commits = JGitUtils.getRevLog(r, objectId, path, pageOffset * itemsPerPage, itemsPerPage); } else { // Fixed size result set commits = JGitUtils.getRevLog(r, objectId, path, 0, limit); } // inaccurate way to determine if there are more commits. // works unless commits.size() represents the exact end. hasMore = commits.size() >= itemsPerPage; add(new CommitHeaderPanel("commitHeader", repositoryName, commit)); // breadcrumbs add(new PathBreadcrumbsPanel("breadcrumbs", repositoryName, path, objectId)); final int hashLen = GitBlit.getInteger(Keys.web.shortCommitIdLength, 6); ListDataProvider<RevCommit> dp = new ListDataProvider<RevCommit>(commits); DataView<RevCommit> logView = new DataView<RevCommit>("commit", dp) { private static final long serialVersionUID = 1L; int counter; public void populateItem(final Item<RevCommit> item) { final RevCommit entry = item.getModelObject(); final Date date = JGitUtils.getCommitDate(entry); item.add( WicketUtils.createDateLabel("commitDate", date, getTimeZone(), getTimeUtils())); // author search link String author = entry.getAuthorIdent().getName(); LinkPanel authorLink = new LinkPanel( "commitAuthor", "list", author, GitSearchPage.class, WicketUtils.newSearchParameter( repositoryName, objectId, author, Constants.SearchType.AUTHOR)); setPersonSearchTooltip(authorLink, author, Constants.SearchType.AUTHOR); item.add(authorLink); // merge icon if (entry.getParentCount() > 1) { item.add(WicketUtils.newImage("commitIcon", "commit_merge_16x16.png")); } else { item.add(WicketUtils.newBlankImage("commitIcon")); } String shortMessage = entry.getShortMessage(); String trimmedMessage = shortMessage; if (allRefs.containsKey(entry.getId())) { trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG_REFS); } else { trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG); } LinkPanel shortlog = new LinkPanel( "commitShortMessage", "list subject", trimmedMessage, CommitPage.class, WicketUtils.newObjectParameter(repositoryName, entry.getName())); if (!shortMessage.equals(trimmedMessage)) { WicketUtils.setHtmlTooltip(shortlog, shortMessage); } item.add(shortlog); item.add(new RefsPanel("commitRefs", repositoryName, entry, allRefs)); if (isTree) { // tree item.add(new Label("hashLabel", getString("gb.tree") + "@")); LinkPanel commitHash = new LinkPanel( "hashLink", null, entry.getName().substring(0, hashLen), TreePage.class, WicketUtils.newObjectParameter(repositoryName, entry.getName())); WicketUtils.setCssClass(commitHash, "shortsha1"); WicketUtils.setHtmlTooltip(commitHash, entry.getName()); item.add(commitHash); Fragment links = new Fragment("historyLinks", "treeLinks", this); links.add( new BookmarkablePageLink<Void>( "commitdiff", CommitDiffPage.class, WicketUtils.newObjectParameter(repositoryName, entry.getName()))); item.add(links); } else if (isSubmodule) { // submodule item.add(new Label("hashLabel", submodulePath + "@")); Repository repository = GitBlit.self().getRepository(repositoryName); String submoduleId = JGitUtils.getSubmoduleCommitId(repository, path, entry); repository.close(); LinkPanel commitHash = new LinkPanel( "hashLink", null, submoduleId.substring(0, hashLen), TreePage.class, WicketUtils.newObjectParameter(submodulePath, submoduleId)); WicketUtils.setCssClass(commitHash, "shortsha1"); WicketUtils.setHtmlTooltip(commitHash, submoduleId); item.add(commitHash.setEnabled(hasSubmodule)); Fragment links = new Fragment("historyLinks", "treeLinks", this); links.add( new BookmarkablePageLink<Void>( "commitdiff", CommitDiffPage.class, WicketUtils.newObjectParameter(repositoryName, entry.getName()))); item.add(links); } else { // commit item.add(new Label("hashLabel", getString("gb.blob") + "@")); LinkPanel commitHash = new LinkPanel( "hashLink", null, entry.getName().substring(0, hashLen), BlobPage.class, WicketUtils.newPathParameter(repositoryName, entry.getName(), path)); WicketUtils.setCssClass(commitHash, "sha1"); WicketUtils.setHtmlTooltip(commitHash, entry.getName()); item.add(commitHash); Fragment links = new Fragment("historyLinks", "blobLinks", this); links.add( new BookmarkablePageLink<Void>( "commitdiff", CommitDiffPage.class, WicketUtils.newObjectParameter(repositoryName, entry.getName()))); links.add( new BookmarkablePageLink<Void>( "difftocurrent", BlobDiffPage.class, WicketUtils.newBlobDiffParameter( repositoryName, entry.getName(), objectId, path)) .setEnabled(counter > 0)); item.add(links); } WicketUtils.setAlternatingBackground(item, counter); counter++; } }; add(logView); // determine to show pager, more, or neither if (limit <= 0) { // no display limit add(new Label("moreHistory", "").setVisible(false)); } else { if (pageResults) { // paging add(new Label("moreHistory", "").setVisible(false)); } else { // more if (commits.size() == limit) { // show more add( new LinkPanel( "moreHistory", "link", new StringResourceModel("gb.moreHistory", this, null), HistoryPage.class, WicketUtils.newPathParameter(repositoryName, objectId, path))); } else { // no more add(new Label("moreHistory", "").setVisible(false)); } } } }
@Override public List<CommitInfo> history( String objectId, String path, int limit, int pageOffset, boolean showRemoteRefs, int itemsPerPage) { try { if (itemsPerPage <= 1) { itemsPerPage = 50; } boolean pageResults = limit <= 0; Repository r = git.getRepository(); // TODO not sure if this is the right String we should use for the sub module stuff... String repositoryName = getConfigDirectory().getPath(); objectId = defaultObjectId(objectId); RevCommit commit = JGitUtils.getCommit(r, objectId); List<PathModel.PathChangeModel> paths = JGitUtils.getFilesInCommit(r, commit); Map<String, SubmoduleModel> submodules = new HashMap<String, SubmoduleModel>(); for (SubmoduleModel model : JGitUtils.getSubmodules(r, commit.getTree())) { submodules.put(model.path, model); } PathModel matchingPath = null; for (PathModel p : paths) { if (p.path.equals(path)) { matchingPath = p; break; } } if (matchingPath == null) { // path not in commit // manually locate path in tree TreeWalk tw = new TreeWalk(r); tw.reset(); tw.setRecursive(true); try { tw.addTree(commit.getTree()); tw.setFilter(PathFilterGroup.createFromStrings(Collections.singleton(path))); while (tw.next()) { if (tw.getPathString().equals(path)) { matchingPath = new PathModel.PathChangeModel( tw.getPathString(), tw.getPathString(), 0, tw.getRawMode(0), tw.getObjectId(0).getName(), commit.getId().getName(), ChangeType.MODIFY); } } } catch (Exception e) { } finally { tw.release(); } } final boolean isTree = matchingPath == null ? true : matchingPath.isTree(); final boolean isSubmodule = matchingPath == null ? true : matchingPath.isSubmodule(); // submodule SubmoduleModel submodule = null; if (matchingPath != null) { submodule = getSubmodule(submodules, repositoryName, matchingPath.path); } final String submodulePath; final boolean hasSubmodule; if (submodule != null) { submodulePath = submodule.gitblitPath; hasSubmodule = submodule.hasSubmodule; } else { submodulePath = ""; hasSubmodule = false; } final Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(r, showRemoteRefs); List<RevCommit> commits; if (pageResults) { // Paging result set commits = JGitUtils.getRevLog(r, objectId, path, pageOffset * itemsPerPage, itemsPerPage); } else { // Fixed size result set commits = JGitUtils.getRevLog(r, objectId, path, 0, limit); } // inaccurate way to determine if there are more commits. // works unless commits.size() represents the exact end. boolean hasMore = commits.size() >= itemsPerPage; List<CommitInfo> results = new ArrayList<CommitInfo>(); for (RevCommit entry : commits) { final Date date = JGitUtils.getCommitDate(entry); String author = entry.getAuthorIdent().getName(); boolean merge = entry.getParentCount() > 1; String shortMessage = entry.getShortMessage(); String trimmedMessage = shortMessage; if (allRefs.containsKey(entry.getId())) { trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG_REFS); } else { trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG); } String name = entry.getName(); String commitHashText = getShortCommitHash(name); String kind; if (isTree) { kind = "tree"; } else if (isSubmodule) { kind = "submodule"; } else kind = "file"; results.add( new CommitInfo( commitHashText, name, kind, author, date, merge, trimmedMessage, shortMessage)); } return results; } catch (Exception e) { throw new RuntimeIOException(e); } }
/** * Process the EGit history associated with a given project. * * @param selectedProject selected project, presumably an object contribution selection * @throws CoreException * @throws IOException */ public void processHistory(IProject selectedProject, IProgressMonitor monitor) throws CoreException, IOException { // find the repository mapping for the project // if none found, return RepositoryMapping repositoryMapping = RepositoryMapping.getMapping((IResource) selectedProject); if (repositoryMapping == null) { CertWareLog.logWarning( String.format("%s %s", "Missing repository for project", selectedProject.getName())); return; } // build the commit history model, load it from the tree walk final CommitHistory commitHistory = ScoFactory.eINSTANCE.createCommitHistory(); Repository repo = repositoryMapping.getRepository(); RevWalk revWalk = new RevWalk(repo); ObjectId headObject = repo.resolve("HEAD"); revWalk.markStart(revWalk.parseCommit(headObject)); final Set<String> repositoryPaths = Collections.singleton(repositoryMapping.getRepoRelativePath(selectedProject)); revWalk.setTreeFilter(PathFilterGroup.createFromStrings(repositoryPaths)); for (RevCommit commit : revWalk) { String commitName = commit.getName(); ArtifactCommit artifactCommit = ScoFactory.eINSTANCE.createArtifactCommit(); artifactCommit.setCommitIdentifier(commitName); commitHistory.getCommitRecord().add(artifactCommit); } revWalk.dispose(); // use the Git provider to find the file history, then converge into the model GitProvider provider = (GitProvider) RepositoryProvider.getProvider(selectedProject); IFileHistoryProvider fileHistoryProvider = provider.getFileHistoryProvider(); IResource[] projectMembers = selectedProject.members(); monitor.beginTask("Processing project resources", projectMembers.length); for (IResource resource : projectMembers) { processResource(resource, fileHistoryProvider, commitHistory, monitor); monitor.worked(1); if (monitor.isCanceled()) { return; } } // model complete with commit history and associated file sizes // write the resulting model to an SCO file // expecting preference to have no extension, so add it if necessary IPreferenceStore store = Activator.getDefault().getPreferenceStore(); String fileName = store.getString(PreferenceConstants.P_FILENAME_SCO); if (fileName.endsWith(ICertWareConstants.SCO_EXTENSION) == false) { fileName = fileName + '.' + ICertWareConstants.SCO_EXTENSION; } // fully specify the path to the new file given the container project final String modelFile = selectedProject.getFullPath().toPortableString() + IPath.SEPARATOR + fileName; // create the resource in a workspace modify operation WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { @Override protected void execute(IProgressMonitor progressMonitor) { try { // create a resource set and resource for a new file ResourceSet resourceSet = new ResourceSetImpl(); URI fileURI = URI.createPlatformResourceURI(modelFile, true); Resource resource = resourceSet.createResource(fileURI); resource.getContents().add(commitHistory); // save the contents of the resource to the file system Map<Object, Object> options = new HashMap<Object, Object>(); options.put(XMLResource.OPTION_ENCODING, FILE_ENCODING); resource.save(options); } catch (Exception e) { CertWareLog.logError(String.format("%s %s", "Saving SCO file", modelFile), e); } } }; // modify the workspace try { operation.run(monitor); } catch (Exception e) { CertWareLog.logError( String.format("%s %s", "Modifying workspace for", selectedProject.getName()), e); } monitor.done(); }
/** * Execute the SubmoduleUpdateCommand command. * * @return a collection of updated submodule paths * @throws ConcurrentRefUpdateException * @throws CheckoutConflictException * @throws InvalidMergeHeadsException * @throws InvalidConfigurationException * @throws NoHeadException * @throws NoMessageException * @throws RefNotFoundException * @throws WrongRepositoryStateException * @throws GitAPIException */ public Collection<String> call() throws InvalidConfigurationException, NoHeadException, ConcurrentRefUpdateException, CheckoutConflictException, InvalidMergeHeadsException, WrongRepositoryStateException, NoMessageException, NoHeadException, RefNotFoundException, GitAPIException { checkCallable(); try { SubmoduleWalk generator = SubmoduleWalk.forIndex(repo); if (!paths.isEmpty()) generator.setFilter(PathFilterGroup.createFromStrings(paths)); List<String> updated = new ArrayList<String>(); while (generator.next()) { // Skip submodules not registered in .gitmodules file if (generator.getModulesPath() == null) continue; // Skip submodules not registered in parent repository's config String url = generator.getConfigUrl(); if (url == null) continue; Repository submoduleRepo = generator.getRepository(); // Clone repository is not present if (submoduleRepo == null) { CloneCommand clone = Git.cloneRepository(); configure(clone); clone.setURI(url); clone.setDirectory(generator.getDirectory()); clone.setGitDir( new File(new File(repo.getDirectory(), Constants.MODULES), generator.getPath())); if (monitor != null) clone.setProgressMonitor(monitor); submoduleRepo = clone.call().getRepository(); } try { RevWalk walk = new RevWalk(submoduleRepo); RevCommit commit = walk.parseCommit(generator.getObjectId()); String update = generator.getConfigUpdate(); if (ConfigConstants.CONFIG_KEY_MERGE.equals(update)) { MergeCommand merge = new MergeCommand(submoduleRepo); merge.include(commit); merge.setStrategy(strategy); merge.call(); } else if (ConfigConstants.CONFIG_KEY_REBASE.equals(update)) { RebaseCommand rebase = new RebaseCommand(submoduleRepo); rebase.setUpstream(commit); rebase.setStrategy(strategy); rebase.call(); } else { // Checkout commit referenced in parent repository's // index as a detached HEAD DirCacheCheckout co = new DirCacheCheckout(submoduleRepo, submoduleRepo.lockDirCache(), commit.getTree()); co.setFailOnConflict(true); co.checkout(); RefUpdate refUpdate = submoduleRepo.updateRef(Constants.HEAD, true); refUpdate.setNewObjectId(commit); refUpdate.forceUpdate(); } } finally { submoduleRepo.close(); } updated.add(generator.getPath()); } return updated; } catch (IOException e) { throw new JGitInternalException(e.getMessage(), e); } catch (ConfigInvalidException e) { throw new InvalidConfigurationException(e.getMessage(), e); } }