anchor.diff:  
     METHOD push.
   
  -* todo, only works with root files
  -
  -    DATA:
  -      lt_nodes TYPE lcl_git_pack=>ty_nodes_tt,
  -      lt_files TYPE ty_files_tt,
  -      lv_sha1  TYPE ty_sha1,
  -      lt_stage TYPE lcl_stage=>ty_stage_tt,
  -      lv_index TYPE i.
  -
  -    FIELD-SYMBOLS: <ls_file>  LIKE LINE OF lt_files,
  -                   <ls_stage> LIKE LINE OF lt_stage,
  -                   <ls_node>  LIKE LINE OF lt_nodes.
  -
  -
  -    lt_nodes = root_tree( it_objects = io_repo->get_objects( )
  -                          iv_branch  = io_repo->get_sha1_remote( ) ).
  -
  -* todo, can only handle add
  +    DATA: lt_expanded TYPE ty_expanded_tt,
  +          lt_blobs    TYPE ty_files_tt,
  +          lv_sha1     TYPE ty_sha1,
  +          lt_trees    TYPE ty_trees_tt,
  +          lt_stage    TYPE lcl_stage=>ty_stage_tt.
  +
  +    FIELD-SYMBOLS: <ls_stage> LIKE LINE OF lt_stage,
  +                   <ls_exp>   LIKE LINE OF lt_expanded.
  +
  +
  +    lt_expanded = full_tree( it_objects = io_repo->get_objects( )
  +                             iv_branch  = io_repo->get_sha1_remote( ) ).
  +
       lt_stage = io_stage->get_all( ).
       LOOP AT lt_stage ASSIGNING <ls_stage>.
         CASE <ls_stage>-method.
           WHEN lcl_stage=>c_method-add.
  -          APPEND <ls_stage>-file TO lt_files.
  +          APPEND <ls_stage>-file TO lt_blobs.
  +
  +          READ TABLE lt_expanded ASSIGNING <ls_exp> WITH KEY
  +            name = <ls_stage>-file-filename
  +            path = <ls_stage>-file-path.
  +          IF sy-subrc <> 0. " new files
  +            APPEND INITIAL LINE TO lt_expanded ASSIGNING <ls_exp>.
  +            <ls_exp>-name = <ls_stage>-file-filename.
  +            <ls_exp>-path = <ls_stage>-file-path.
  +          ENDIF.
  +
  +          lv_sha1 = lcl_hash=>sha1( iv_type = gc_type-blob iv_data = <ls_stage>-file-data ).
  +          IF <ls_exp>-sha1 <> lv_sha1.
  +            <ls_exp>-sha1 = lv_sha1.
  +          ENDIF.
  +        WHEN lcl_stage=>c_method-rm.
  +          DELETE lt_expanded
  +            WHERE name = <ls_stage>-file-filename
  +            AND path = <ls_stage>-file-path.
  +          ASSERT sy-subrc = 0.
           WHEN OTHERS.
  -* todo, work in progress see issue #5 on github
             _raise 'stage method not supported, todo'.
         ENDCASE.
       ENDLOOP.
   
  -    LOOP AT lt_files ASSIGNING <ls_file>.
  -      lv_index = sy-tabix.
  -      READ TABLE lt_nodes ASSIGNING <ls_node> WITH KEY name = <ls_file>-filename.
  -      IF sy-subrc <> 0.
  -* new files
  -        APPEND INITIAL LINE TO lt_nodes ASSIGNING <ls_node>.
  -        <ls_node>-chmod = gc_chmod-file.
  -        <ls_node>-name = <ls_file>-filename.
  -      ENDIF.
  -
  -      lv_sha1 = lcl_hash=>sha1( iv_type = gc_type-blob iv_data = <ls_file>-data ).
  -      IF <ls_node>-sha1 <> lv_sha1.
  -        <ls_node>-sha1 = lv_sha1.
  -      ELSE.
  -        DELETE lt_files INDEX lv_index.
  -      ENDIF.
  -    ENDLOOP.
  -
  -    IF lt_files[] IS INITIAL.
  -      _raise 'no files'.
  -    ENDIF.
  +    lt_trees = build_trees( lt_expanded ).
   
       rv_branch = receive_pack( is_comment = is_comment
                                 io_repo    = io_repo
  -                              it_nodes   = lt_nodes
  -                              it_files   = lt_files
  +                              it_trees   = lt_trees
  +                              it_blobs   = lt_blobs
                                 iv_branch  = io_repo->get_sha1_remote( ) ).
   
     ENDMETHOD.                    "push
   
  -  METHOD root_tree.
  +  METHOD walk_tree.
  +
  +    DATA: ls_object   LIKE LINE OF it_objects,
  +          lt_expanded LIKE rt_expanded,
  +          lt_nodes    TYPE lcl_git_pack=>ty_nodes_tt.
  +
  +    FIELD-SYMBOLS: <ls_exp>  LIKE LINE OF rt_expanded,
  +                   <ls_node> LIKE LINE OF lt_nodes.
  +
  +
  +    READ TABLE it_objects INTO ls_object
  +      WITH KEY sha1 = iv_tree
  +      type = gc_type-tree.
  +    IF sy-subrc <> 0.
  +      _raise 'tree not found'.
  +    ENDIF.
  +    lt_nodes = lcl_git_pack=>decode_tree( ls_object-data ).
  +
  +    LOOP AT lt_nodes ASSIGNING <ls_node>.
  +      CASE <ls_node>-chmod.
  +        WHEN gc_chmod-file.
  +          APPEND INITIAL LINE TO rt_expanded ASSIGNING <ls_exp>.
  +          <ls_exp>-path = iv_base.
  +          <ls_exp>-name = <ls_node>-name.
  +          <ls_exp>-sha1 = <ls_node>-sha1.
  +        WHEN gc_chmod-dir.
  +          lt_expanded = walk_tree(
  +            it_objects = it_objects
  +            iv_tree    = <ls_node>-sha1
  +            iv_base    = iv_base && <ls_node>-name && '/' ).
  +          APPEND LINES OF lt_expanded TO rt_expanded.
  +        WHEN OTHERS.
  +          _raise 'walk_tree: unknown chmod'.
  +      ENDCASE.
  +    ENDLOOP.
  +
  +  ENDMETHOD.
  +
  +  METHOD full_tree.
   
       DATA: ls_object LIKE LINE OF it_objects,
             ls_commit TYPE lcl_git_pack=>ty_commit.
  
positive.code:       CHANGING  ct_files   TYPE ty_files_tt
        RAISING   lcx_exception.
  
      CLASS-METHODS root_tree
        IMPORTING it_objects      TYPE lcl_git_pack=>ty_objects_tt
                  iv_branch       TYPE ty_sha1
        RETURNING VALUE(rt_nodes) TYPE lcl_git_pack=>ty_nodes_tt
        RAISING   lcx_exception.
  
      CLASS-METHODS receive_pack
        IMPORTING is_comment       TYPE ty_comment
                  io_repo          TYPE REF TO lcl_repo_online
                  it_nodes         TYPE lcl_git_pack=>ty_nodes_tt
                  it_files         TYPE ty_files_tt
                  iv_branch        TYPE ty_sha1
        RETURNING VALUE(rv_branch) TYPE ty_sha1
        RAISING   lcx_exception.
  
negative.code: 
    METHOD compare_files.
  
      READ TABLE it_repo WITH KEY
        filename = is_gen-filename
        data = is_gen-data
        TRANSPORTING NO FIELDS.
      IF sy-subrc <> 0.
        rv_match = abap_false.
  