#NEWLINE# def read_file( self , sha , file_path , diff = None ) : #NEWLINE# #INDENT# "Read the content of a file at a given revision.\n\n        Args:\n            sha (str): the sha identifying the revision\n            file_path (str): the path to the file from the root of the repo\n            diff (str): the optional patch to apply before reading the config\n        Returns:\n            str - the content of the file\n        Raises:\n            CommandError - if the git invocation fails.\n            ContentReadError - if the content can't be read because the named file is missing,\n                links to something outside the tree, links to an absent file, or links to itself.\n        " #NEWLINE# cmd = [ 'cat-file' , '--batch' , '--follow-symlinks' ] #NEWLINE# obj_key = '{revision}:{file_path}' . format ( revision = sha , file_path = file_path ) #NEWLINE# content = self . run ( cmd , input = obj_key ) #NEWLINE# ( info , content ) = content . split ( '\n' , 1 ) #NEWLINE# if info . endswith ( 'missing' ) : #NEWLINE# #INDENT# raise ContentReadError ( 'No such file at revision: {}' . format ( obj_key ) ) #NEWLINE# #UNINDENT# if any ( ( info . startswith ( s ) for s in ( 'symlink' , 'dangling' , 'loop' ) ) ) : #NEWLINE# #INDENT# raise ContentReadError ( 'Unable to read file contents: {}' . format ( info . split ( ) [ 0 ] ) ) #NEWLINE# #UNINDENT# if ( not re . match ( '^[a-f0-9]+ blob \\d+$' , info ) ) : #NEWLINE# #INDENT# raise ContentReadError ( 'Unrecognized metadata for {}: {!r}' . format ( obj_key , info ) ) #NEWLINE# #UNINDENT# assert content . endswith ( '\n' ) #NEWLINE# content = content [ : ( - 1 ) ] #NEWLINE# if ( diff is None ) : #NEWLINE# #INDENT# return content #NEWLINE# #UNINDENT# return self . _selectively_apply_diff ( file_path , content , diff )