Source:
<code>public Attributes getAttributes() { if (attrs != null) return attrs; if (attributesNodeProvider == null) { throw new IllegalStateException( "The tree walk should have one AttributesNodeProvider set in order to compute the git attributes."); } WorkingTreeIterator workingTreeIterator = getTree(WorkingTreeIterator.class); DirCacheIterator dirCacheIterator = getTree(DirCacheIterator.class); CanonicalTreeParser other = getTree(CanonicalTreeParser.class); if (workingTreeIterator == null && dirCacheIterator == null && other == null) { return new Attributes(); } String path = currentHead.getEntryPathString(); final boolean isDir = FileMode.TREE.equals(currentHead.mode); Attributes attributes = new Attributes(); try { AttributesNode globalNodeAttr = attributesNodeProvider .getGlobalAttributesNode(); AttributesNode infoNodeAttr = attributesNodeProvider .getInfoAttributesNode(); <START> AttributesNode rootNodeAttr = getRootAttributesNode(operationType, <END> workingTreeIterator, dirCacheIterator, other); macroExpander.updateWhenDifferent(globalNodeAttr, infoNodeAttr, rootNodeAttr); if (infoNodeAttr != null) { infoNodeAttr.getAttributes(macroExpander, path, isDir, attributes); } getPerDirectoryEntryAttributes(path, isDir, operationType, workingTreeIterator, dirCacheIterator, other, attributes); if (globalNodeAttr != null) { globalNodeAttr.getAttributes(macroExpander, path, isDir, attributes); } } catch (IOException e) { throw new JGitInternalException("Error while parsing attributes", e); } for (Attribute a : attributes.getAll()) { if (a.getState() == State.UNSPECIFIED) attributes.remove(a.getKey()); } return attributes; }</code><technical_language>do get rootNodeAttr? assume changes happen .gitattributes files treewalk detected us. need attributes for time merge global/info/root-work-tree .gitattributes field in field rootAttributesNode. In search for macro definitions. traversing tree do touch global/info files merge rootAttributesNode .gitattributes files find while traversing worktree</technical_language>

Target:
public Attributes getAttributes() { if (attrs != null) return attrs; if (attributesNodeProvider == null) { throw new IllegalStateException( "The tree walk should have one AttributesNodeProvider set in order to compute the git attributes."); } WorkingTreeIterator workingTreeIterator = getCurrentTreeNode( WorkingTreeIterator.class); DirCacheIterator dirCacheIterator = getCurrentTreeNode( DirCacheIterator.class); CanonicalTreeParser other = getCurrentTreeNode( CanonicalTreeParser.class); if (workingTreeIterator == null && dirCacheIterator == null && other == null) { return new Attributes(); } String path = currentHead.getEntryPathString(); final boolean isDir = FileMode.TREE.equals(currentHead.mode); Attributes attributes = new Attributes(); try { if (macroExpander == null) { AttributesNode globalNode = attributesNodeProvider .getGlobalAttributesNode(); AttributesNode infoNode = attributesNodeProvider .getInfoAttributesNode(); AttributesNode rootNode = getRootAttributesNode(); macroExpander = new MacroExpander(globalNode, infoNode, rootNode); } macroExpander.mergeInfoAttributes(path, isDir, attributes); getPerDirectoryEntryAttributes(path, isDir, operationType, workingTreeIterator, dirCacheIterator, other, attributes); macroExpander.mergeGlobalAttributes(path, isDir, attributes); } catch (IOException e) { throw new JGitInternalException("Error while parsing attributes", e); } for (Attribute a : attributes.getAll()) { if (a.getState() == State.UNSPECIFIED) attributes.remove(a.getKey()); } return attributes; }