diff --git a/src/ui/zcl_abapgit_gui_page_merge.clas.abap b/src/ui/zcl_abapgit_gui_page_merge.clas.abap index 563b353dd..bf88b8990 100644 --- a/src/ui/zcl_abapgit_gui_page_merge.clas.abap +++ b/src/ui/zcl_abapgit_gui_page_merge.clas.abap @@ -1,31 +1,39 @@ CLASS zcl_abapgit_gui_page_merge DEFINITION PUBLIC + INHERITING FROM zcl_abapgit_gui_page FINAL - CREATE PUBLIC INHERITING FROM zcl_abapgit_gui_page. + CREATE PUBLIC . PUBLIC SECTION. - METHODS: - constructor - IMPORTING io_repo TYPE REF TO zcl_abapgit_repo_online - iv_source TYPE string - iv_target TYPE string - RAISING zcx_abapgit_exception, - zif_abapgit_gui_page~on_event REDEFINITION. + METHODS constructor + IMPORTING + !io_repo TYPE REF TO zcl_abapgit_repo_online + !iv_source TYPE string + !iv_target TYPE string + RAISING + zcx_abapgit_exception . + + METHODS zif_abapgit_gui_page~on_event + REDEFINITION. PROTECTED SECTION. METHODS render_content REDEFINITION. PRIVATE SECTION. - DATA: mo_repo TYPE REF TO zcl_abapgit_repo_online, - ms_merge TYPE zif_abapgit_definitions=>ty_merge. - CONSTANTS: BEGIN OF c_actions, - merge TYPE string VALUE 'merge' ##NO_TEXT, - END OF c_actions. + DATA mo_repo TYPE REF TO zcl_abapgit_repo_online . + DATA mo_merge TYPE REF TO zcl_abapgit_merge . + CONSTANTS: + BEGIN OF c_actions, + merge TYPE string VALUE 'merge' ##NO_TEXT, + res_conflicts TYPE string VALUE 'res_conflicts' ##NO_TEXT, + END OF c_actions . - METHODS: - build_menu - RETURNING VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar. + METHODS build_menu + IMPORTING + VALUE(iv_with_conflict) TYPE boolean OPTIONAL + RETURNING + VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar . ENDCLASS. @@ -37,7 +45,11 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_MERGE IMPLEMENTATION. CREATE OBJECT ro_menu. - ro_menu->add( iv_txt = 'Merge' iv_act = c_actions-merge ) ##NO_TEXT. + ro_menu->add( iv_txt = 'Merge' iv_act = c_actions-merge iv_cur = abap_false ) ##NO_TEXT. + + IF iv_with_conflict EQ abap_true. + ro_menu->add( iv_txt = 'Resolve Conflicts' iv_act = c_actions-res_conflicts ) ##NO_TEXT. + ENDIF. ENDMETHOD. @@ -45,15 +57,18 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_MERGE IMPLEMENTATION. METHOD constructor. super->constructor( ). - ms_control-page_title = 'MERGE'. - ms_control-page_menu = build_menu( ). mo_repo = io_repo. - ms_merge = zcl_abapgit_merge=>run( - io_repo = io_repo - iv_source = iv_source - iv_target = iv_target ). + CREATE OBJECT mo_merge + EXPORTING + io_repo = io_repo + iv_source_branch = iv_source + iv_target_branch = iv_target. + mo_merge->run( ). + + ms_control-page_title = 'MERGE'. + ms_control-page_menu = build_menu( iv_with_conflict = mo_merge->has_conflicts( ) ). ENDMETHOD. @@ -78,12 +93,17 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_MERGE IMPLEMENTATION. ENDIF. END-OF-DEFINITION. - DATA: lt_files LIKE ms_merge-stree, - ls_result LIKE LINE OF ms_merge-result. + DATA: ls_merge TYPE zif_abapgit_definitions=>ty_merge, + lt_files LIKE ls_merge-stree, + ls_result LIKE LINE OF ls_merge-result. FIELD-SYMBOLS: LIKE LINE OF lt_files, LIKE LINE OF lt_files. + ls_merge = mo_merge->get_result( ). + + "If now exists no conflicts anymore, conflicts button should disappear + ms_control-page_menu = build_menu( iv_with_conflict = mo_merge->has_conflicts( ) ). CREATE OBJECT ro_html. @@ -95,27 +115,27 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_MERGE IMPLEMENTATION. ro_html->add( '' ). ro_html->add( '' ). - ro_html->add( '' ). + ro_html->add( '' ). ro_html->add( '' ). ro_html->add( '' ). - ro_html->add( '' ). + ro_html->add( '' ). ro_html->add( '' ). ro_html->add( '' ). - ro_html->add( '' ). + ro_html->add( '' ). ro_html->add( '' ). ro_html->add( '
Source:Source' ). - ro_html->add( ms_merge-source-name ). + ro_html->add( ls_merge-source-name ). ro_html->add( '
Target:Target' ). - ro_html->add( ms_merge-target-name ). + ro_html->add( ls_merge-target-name ). ro_html->add( '
Ancestor:Ancestor' ). - ro_html->add( ms_merge-common-commit ). + ro_html->add( ls_merge-common-commit ). ro_html->add( '
' ). ro_html->add( '
' ). - APPEND LINES OF ms_merge-stree TO lt_files. - APPEND LINES OF ms_merge-ttree TO lt_files. - APPEND LINES OF ms_merge-ctree TO lt_files. + APPEND LINES OF ls_merge-stree TO lt_files. + APPEND LINES OF ls_merge-ttree TO lt_files. + APPEND LINES OF ls_merge-ctree TO lt_files. SORT lt_files BY path DESCENDING name ASCENDING. DELETE ADJACENT DUPLICATES FROM lt_files COMPARING path name. @@ -132,20 +152,20 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_MERGE IMPLEMENTATION. ro_html->add( '' ). LOOP AT lt_files ASSIGNING . CLEAR ls_result. - READ TABLE ms_merge-result INTO ls_result + READ TABLE ls_merge-result INTO ls_result WITH KEY path = -path name = -name. ro_html->add( '' ). - _show_file ms_merge-stree. - _show_file ms_merge-ttree. - _show_file ms_merge-ctree. - _show_file ms_merge-result. + _show_file ls_merge-stree. + _show_file ls_merge-ttree. + _show_file ls_merge-ctree. + _show_file ls_merge-result. ro_html->add( '' ). ENDLOOP. ro_html->add( '' ). ro_html->add( '
' ). ro_html->add( '' ). - ro_html->add( ms_merge-conflict ). + ro_html->add( ls_merge-conflict ). ro_html->add( '' ). ro_html->add( '' ). @@ -156,15 +176,28 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_MERGE IMPLEMENTATION. CASE iv_action. WHEN c_actions-merge. - IF ms_merge-stage->count( ) = 0. + IF mo_merge->has_conflicts( ) EQ abap_true. + zcx_abapgit_exception=>raise( 'conflicts exists' ). + ENDIF. + + IF mo_merge->get_result( )-stage->count( ) EQ 0. zcx_abapgit_exception=>raise( 'nothing to merge' ). ENDIF. CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_commit EXPORTING io_repo = mo_repo - io_stage = ms_merge-stage. + io_stage = mo_merge->get_result( )-stage. ev_state = zif_abapgit_definitions=>gc_event_state-new_page. + + WHEN c_actions-res_conflicts. + CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_merge_res + EXPORTING + io_repo = mo_repo + io_merge_page = me + io_merge = mo_merge. + ev_state = zif_abapgit_definitions=>gc_event_state-new_page. + ENDCASE. ENDMETHOD. diff --git a/src/ui/zcl_abapgit_gui_page_merge.clas.xml b/src/ui/zcl_abapgit_gui_page_merge.clas.xml index 4a0726f7a..ca88d2e5f 100644 --- a/src/ui/zcl_abapgit_gui_page_merge.clas.xml +++ b/src/ui/zcl_abapgit_gui_page_merge.clas.xml @@ -14,6 +14,14 @@ X X + + + ZCL_ABAPGIT_GUI_PAGE_MERGE + MO_MERGE + E + Merge logic + + diff --git a/src/ui/zcl_abapgit_gui_page_merge_res.clas.abap b/src/ui/zcl_abapgit_gui_page_merge_res.clas.abap new file mode 100644 index 000000000..87fa95729 --- /dev/null +++ b/src/ui/zcl_abapgit_gui_page_merge_res.clas.abap @@ -0,0 +1,583 @@ +CLASS zcl_abapgit_gui_page_merge_res DEFINITION + PUBLIC + INHERITING FROM zcl_abapgit_gui_page + FINAL + CREATE PUBLIC . + + PUBLIC SECTION. + + METHODS constructor + IMPORTING + !io_repo TYPE REF TO zcl_abapgit_repo_online + !io_merge_page TYPE REF TO zcl_abapgit_gui_page_merge + !io_merge TYPE REF TO zcl_abapgit_merge + RAISING + zcx_abapgit_exception . + + METHODS zif_abapgit_gui_page~on_event + REDEFINITION . + PROTECTED SECTION. + METHODS render_content REDEFINITION. + + PRIVATE SECTION. + + TYPES: + BEGIN OF ty_file_diff, + path TYPE string, + filename TYPE string, + lstate TYPE char1, + rstate TYPE char1, + fstate TYPE char1, " FILE state - Abstraction for shorter ifs + o_diff TYPE REF TO zcl_abapgit_diff, + changed_by TYPE xubname, + type TYPE string, + END OF ty_file_diff . + TYPES: + tt_file_diff TYPE STANDARD TABLE OF ty_file_diff . + + CONSTANTS: + BEGIN OF c_actions, + toggle_mode TYPE string VALUE 'toggle_mode' ##NO_TEXT, + apply_merge TYPE string VALUE 'apply_merge' ##NO_TEXT, + apply_source TYPE string VALUE 'apply_source' ##NO_TEXT, + apply_target TYPE string VALUE 'apply_target' ##NO_TEXT, + cancel TYPE string VALUE 'cancel' ##NO_TEXT, + END OF c_actions . + CONSTANTS: + BEGIN OF c_merge_mode, + selection TYPE string VALUE 'selection' ##NO_TEXT, + merge TYPE string VALUE 'merge' ##NO_TEXT, + END OF c_merge_mode . + DATA mo_merge TYPE REF TO zcl_abapgit_merge . + DATA mo_merge_page TYPE REF TO zcl_abapgit_gui_page_merge . + DATA mo_repo TYPE REF TO zcl_abapgit_repo_online . + DATA ms_diff_file TYPE ty_file_diff . + DATA mv_current_conflict_index TYPE sytabix . + DATA mv_merge_mode TYPE string . + DATA mt_conflicts TYPE zif_abapgit_definitions=>tt_merge_conflict . + + METHODS apply_merged_content + IMPORTING + !it_postdata TYPE cnht_post_data_tab + RAISING + zcx_abapgit_exception . + METHODS build_menu + IMPORTING + VALUE(iv_with_conflict) TYPE boolean OPTIONAL + RETURNING + VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar . + METHODS is_binary + IMPORTING + !iv_d1 TYPE xstring + !iv_d2 TYPE xstring + RETURNING + VALUE(rv_yes) TYPE abap_bool . + METHODS render_beacon + IMPORTING + !is_diff_line TYPE zif_abapgit_definitions=>ty_diff + !is_diff TYPE ty_file_diff + RETURNING + VALUE(ro_html) TYPE REF TO zcl_abapgit_html . + METHODS render_diff + IMPORTING + !is_diff TYPE ty_file_diff + RETURNING + VALUE(ro_html) TYPE REF TO zcl_abapgit_html + RAISING + zcx_abapgit_exception . + METHODS render_diff_head + IMPORTING + !is_diff TYPE ty_file_diff + RETURNING + VALUE(ro_html) TYPE REF TO zcl_abapgit_html . + METHODS render_lines + IMPORTING + !is_diff TYPE ty_file_diff + RETURNING + VALUE(ro_html) TYPE REF TO zcl_abapgit_html . + METHODS render_line_split + IMPORTING + !is_diff_line TYPE zif_abapgit_definitions=>ty_diff + !iv_fstate TYPE char1 + RETURNING + VALUE(ro_html) TYPE REF TO zcl_abapgit_html . + METHODS render_table_head + RETURNING + VALUE(ro_html) TYPE REF TO zcl_abapgit_html . + METHODS resolve_diff + RAISING + zcx_abapgit_exception . + METHODS toggle_merge_mode . +ENDCLASS. + + + +CLASS ZCL_ABAPGIT_GUI_PAGE_MERGE_RES IMPLEMENTATION. + + + METHOD apply_merged_content. + + CONSTANTS: lc_replace TYPE string VALUE '<>'. + + DATA: BEGIN OF filedata, + merge_content TYPE string, + END OF filedata. + + DATA: lv_string TYPE string, + lt_fields TYPE tihttpnvp, + lv_new_file_content TYPE xstring. + + FIELD-SYMBOLS: LIKE LINE OF it_postdata, + TYPE zif_abapgit_definitions=>ty_merge_conflict. + + LOOP AT it_postdata ASSIGNING . + lv_string = |{ lv_string }{ }|. + ENDLOOP. + REPLACE ALL OCCURRENCES OF zif_abapgit_definitions=>gc_crlf IN lv_string WITH lc_replace. + REPLACE ALL OCCURRENCES OF zif_abapgit_definitions=>gc_newline IN lv_string WITH lc_replace. + + lt_fields = zcl_abapgit_html_action_utils=>parse_fields_upper_case_name( lv_string ). + zcl_abapgit_html_action_utils=>get_field( EXPORTING name = 'MERGE_CONTENT' + it = lt_fields + CHANGING cv = filedata ). + filedata-merge_content = cl_http_utility=>unescape_url( escaped = filedata-merge_content ). + REPLACE ALL OCCURRENCES OF lc_replace IN filedata-merge_content WITH zif_abapgit_definitions=>gc_newline. + + lv_new_file_content = zcl_abapgit_convert=>string_to_xstring_utf8( iv_string = filedata-merge_content ). + + READ TABLE mt_conflicts ASSIGNING INDEX mv_current_conflict_index. + -result_sha1 = zcl_abapgit_hash=>sha1( iv_type = zif_abapgit_definitions=>gc_type-blob + iv_data = lv_new_file_content ). + -result_data = lv_new_file_content. + mo_merge->resolve_conflict( is_conflict = ). + + ENDMETHOD. + + + METHOD build_menu. + + CREATE OBJECT ro_menu. + ro_menu->add( iv_txt = 'Toggle merge mode' iv_act = c_actions-toggle_mode ) ##NO_TEXT. + ro_menu->add( iv_txt = 'Cancel' iv_act = c_actions-cancel ) ##NO_TEXT. + + ENDMETHOD. + + + METHOD constructor. + + super->constructor( ). + + mo_repo = io_repo. + ms_control-page_title = 'Resolve Conflicts'. + ms_control-page_menu = build_menu( ). + + mo_merge_page = io_merge_page. + mo_merge = io_merge. + mv_merge_mode = c_merge_mode-selection. + mv_current_conflict_index = 1. + mt_conflicts = io_merge->get_conflicts( ). + + ENDMETHOD. + + + METHOD is_binary. + + DATA: lv_len TYPE i, + lv_idx TYPE i, + lv_x TYPE x. + + FIELD-SYMBOLS LIKE iv_d1. + + + IF iv_d1 IS NOT INITIAL. " One of them might be new and so empty + ASSIGN iv_d1 TO . + ELSE. + ASSIGN iv_d2 TO . + ENDIF. + + lv_len = xstrlen( ). + IF lv_len = 0. + RETURN. + ENDIF. + + IF lv_len > 100. + lv_len = 100. + ENDIF. + + " Simple char range test + " stackoverflow.com/questions/277521/how-to-identify-the-file-content-as-ascii-or-binary + DO lv_len TIMES. " I'm sure there is more efficient way ... + lv_idx = sy-index - 1. + lv_x = +lv_idx(1). + + IF NOT ( lv_x BETWEEN 9 AND 13 OR lv_x BETWEEN 32 AND 126 ). + rv_yes = abap_true. + EXIT. + ENDIF. + ENDDO. + + ENDMETHOD. " is_binary. + + + METHOD render_beacon. + + DATA: lv_beacon TYPE string. + + CREATE OBJECT ro_html. + + IF is_diff_line-beacon > 0. + READ TABLE is_diff-o_diff->mt_beacons INTO lv_beacon INDEX is_diff_line-beacon. + ELSE. + lv_beacon = '---'. + ENDIF. + + + ro_html->add( '' ). + ro_html->add( '' ). + + ro_html->add( '' ). + ro_html->add( |@@ { is_diff_line-new_num } @@ { lv_beacon }| ). + + ro_html->add( '' ). + ro_html->add( '' ). + + ENDMETHOD. " render_beacon. + + + METHOD render_content. + + resolve_diff( ). + IF ms_diff_file IS INITIAL. + zcx_abapgit_exception=>raise( 'no conflict found' ). + ENDIF. + + CREATE OBJECT ro_html. + ro_html->add( |
| ). + ro_html->add( render_diff( ms_diff_file ) ). + ro_html->add( '
' ). + + ENDMETHOD. "render_content + + + METHOD render_diff. + + DATA: lv_target_content TYPE string. + FIELD-SYMBOLS: TYPE zif_abapgit_definitions=>ty_merge_conflict. + + CREATE OBJECT ro_html. + + ro_html->add( |
| ). "#EC NOTEXT + ro_html->add( render_diff_head( is_diff ) ). + + " Content + IF is_diff-type <> 'binary'. + + IF mv_merge_mode EQ c_merge_mode-selection. + ro_html->add( '
' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( render_table_head( ) ). + ro_html->add( render_lines( is_diff ) ). + ro_html->add( '
' ). "#EC NOTEXT + ro_html->add( '
' ). "#EC NOTEXT + ELSE. + + "Table for Div-Table and textarea + ro_html->add( '
' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( ' ' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '
CodeMerge - ' ). "#EC NOTEXT + ro_html->add_a( iv_act = 'submitFormById(''merge_form'');' "#EC NOTEXT + iv_txt = 'Apply' + iv_typ = zif_abapgit_definitions=>gc_action_type-onclick + iv_opt = zif_abapgit_definitions=>gc_html_opt-strong ). + ro_html->add( '
' ). + + "Diff-Table of source and target file + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( render_table_head( ) ). + ro_html->add( render_lines( is_diff ) ). + ro_html->add( '
' ). "#EC NOTEXT + + READ TABLE mt_conflicts ASSIGNING INDEX mv_current_conflict_index. + IF sy-subrc EQ 0. + lv_target_content = zcl_abapgit_convert=>xstring_to_string_utf8( -target_data ). + lv_target_content = escape( val = lv_target_content format = cl_abap_format=>e_html_text ). + ENDIF. + + ro_html->add( '
' ). "#EC NOTEXT + ro_html->add( '
' ). + ro_html->add( |
add( |method="post" action="sapevent:apply_merge">| ). + ro_html->add( || ). + ro_html->add( '' ). + ro_html->add( '
' ). "#EC NOTEXT + ro_html->add( '
' ). "#EC NOTEXT + ro_html->add( '
' ). "#EC NOTEXT + ro_html->add( '
' ). "#EC NOTEXT + ENDIF. + ELSE. + ro_html->add( '
' ). "#EC NOTEXT + ro_html->add( 'The content seems to be binary.' ). "#EC NOTEXT + ro_html->add( 'Cannot display as diff.' ). "#EC NOTEXT + ro_html->add( '
' ). "#EC NOTEXT + ENDIF. + + ro_html->add( '
' ). "#EC NOTEXT + + ENDMETHOD. " render_diff + + + METHOD render_diff_head. + + DATA: ls_stats TYPE zif_abapgit_definitions=>ty_count. + + CREATE OBJECT ro_html. + + ro_html->add( '
' ). "#EC NOTEXT + + IF is_diff-type <> 'binary' AND is_diff-o_diff IS NOT INITIAL. + ls_stats = is_diff-o_diff->stats( ). + ro_html->add( |+ { ls_stats-insert }| ). + ro_html->add( |- { ls_stats-delete }| ). + ro_html->add( |~ { ls_stats-update }| ). + ENDIF. + + ro_html->add( |{ is_diff-filename }| ). "#EC NOTEXT + ro_html->add( '
' ). "#EC NOTEXT + + ENDMETHOD. + + + METHOD render_lines. + + DATA: lo_highlighter TYPE REF TO zcl_abapgit_syntax_highlighter, + lt_diffs TYPE zif_abapgit_definitions=>ty_diffs_tt, + lv_insert_nav TYPE abap_bool. + + FIELD-SYMBOLS LIKE LINE OF lt_diffs. + + lo_highlighter = zcl_abapgit_syntax_highlighter=>create( is_diff-filename ). + CREATE OBJECT ro_html. + + lt_diffs = is_diff-o_diff->get( ). + + LOOP AT lt_diffs ASSIGNING . + IF -short = abap_false. + lv_insert_nav = abap_true. + CONTINUE. + ENDIF. + + IF lv_insert_nav = abap_true. " Insert separator line with navigation + ro_html->add( render_beacon( is_diff_line = is_diff = is_diff ) ). + lv_insert_nav = abap_false. + ENDIF. + + IF lo_highlighter IS BOUND. + -new = lo_highlighter->process_line( -new ). + -old = lo_highlighter->process_line( -old ). + ELSE. + -new = escape( val = -new format = cl_abap_format=>e_html_attr ). + -old = escape( val = -old format = cl_abap_format=>e_html_attr ). + ENDIF. + + CONDENSE -new_num. "get rid of leading spaces + CONDENSE -old_num. + + ro_html->add( render_line_split( is_diff_line = + iv_fstate = is_diff-fstate ) ). + + ENDLOOP. + + ENDMETHOD. "render_lines + + + METHOD render_line_split. + + DATA: lv_new TYPE string, + lv_old TYPE string, + lv_merge TYPE string, + lv_mark TYPE string, + lv_bg TYPE string. + + CREATE OBJECT ro_html. + + " New line + lv_mark = ` `. + IF is_diff_line-result = zif_abapgit_definitions=>c_diff-update. + lv_bg = ' diff_upd'. + lv_mark = `~`. + ELSEIF is_diff_line-result = zif_abapgit_definitions=>c_diff-insert. + lv_bg = ' diff_ins'. + lv_mark = `+`. + ENDIF. + lv_new = || + && |{ lv_mark }{ is_diff_line-new }|. + + " Old line + CLEAR lv_bg. + lv_mark = ` `. + IF is_diff_line-result = zif_abapgit_definitions=>c_diff-update. + lv_bg = ' diff_upd'. + lv_mark = `~`. + ELSEIF is_diff_line-result = zif_abapgit_definitions=>c_diff-delete. + lv_bg = ' diff_del'. + lv_mark = `-`. + ENDIF. + lv_old = || + && |{ lv_mark }{ is_diff_line-old }|. + + " render line, inverse sides if remote is newer + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( lv_old ). " Target + ro_html->add( lv_new ). " Source + ro_html->add( '' ). "#EC NOTEXT + + ENDMETHOD. "render_line_split + + + METHOD render_table_head. + + CREATE OBJECT ro_html. + IF mv_merge_mode EQ c_merge_mode-selection. + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '
' ). "#EC NOTEXT + ro_html->add( 'Target - ' && mo_merge->get_target_branch( ) && ' - ' ). "#EC NOTEXT + ro_html->add_a( iv_act = 'submitFormById(''target_form'');' "#EC NOTEXT + iv_txt = 'Apply' + iv_typ = zif_abapgit_definitions=>gc_action_type-onclick + iv_opt = zif_abapgit_definitions=>gc_html_opt-strong ). + ro_html->add( ' ' ). "#EC NOTEXT + ro_html->add( '
' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '
' ). "#EC NOTEXT + ro_html->add( 'Source - ' && mo_merge->get_source_branch( ) &&' - ' ). "#EC NOTEXT + ro_html->add_a( iv_act = 'submitFormById(''source_form'');' "#EC NOTEXT + iv_txt = 'Apply' + iv_typ = zif_abapgit_definitions=>gc_action_type-onclick + iv_opt = zif_abapgit_definitions=>gc_html_opt-strong ). + ro_html->add( ' ' ). "#EC NOTEXT + ro_html->add( '
' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ELSE. + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( 'Target - ' && mo_merge->get_target_branch( ) &&' ' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( 'Source - ' && mo_merge->get_source_branch( ) &&' ' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ENDIF. + + ENDMETHOD. " render_table_head. + + + METHOD resolve_diff. + + DATA: lv_offs TYPE i. + FIELD-SYMBOLS: TYPE zif_abapgit_definitions=>ty_merge_conflict. + + CLEAR ms_diff_file. + + READ TABLE mt_conflicts ASSIGNING INDEX mv_current_conflict_index. + IF sy-subrc NE 0. + RETURN. + ENDIF. + + ms_diff_file-path = -path. + ms_diff_file-filename = -filename. + ms_diff_file-type = reverse( -filename ). + + FIND FIRST OCCURRENCE OF '.' IN ms_diff_file-type MATCH OFFSET lv_offs. + ms_diff_file-type = reverse( substring( val = ms_diff_file-type len = lv_offs ) ). + IF ms_diff_file-type <> 'xml' AND ms_diff_file-type <> 'abap'. + ms_diff_file-type = 'other'. + ENDIF. + + IF ms_diff_file-type = 'other' + AND is_binary( iv_d1 = -source_data iv_d2 = -target_data ) = abap_true. + ms_diff_file-type = 'binary'. + ENDIF. + + IF ms_diff_file-type <> 'binary'. + CREATE OBJECT ms_diff_file-o_diff + EXPORTING + iv_new = -source_data + iv_old = -target_data. + ENDIF. + + ENDMETHOD. + + + METHOD toggle_merge_mode. + + IF mv_merge_mode EQ c_merge_mode-selection. + mv_merge_mode = c_merge_mode-merge. + ELSE. + mv_merge_mode = c_merge_mode-selection. + ENDIF. + + ENDMETHOD. + + + METHOD zif_abapgit_gui_page~on_event. + + FIELD-SYMBOLS: TYPE zif_abapgit_definitions=>ty_merge_conflict. + + CASE iv_action. + WHEN c_actions-apply_merge + OR c_actions-apply_source + OR c_actions-apply_target + OR c_actions-cancel. + + CASE iv_action. + WHEN c_actions-apply_merge. + apply_merged_content( it_postdata = it_postdata ). + + WHEN c_actions-apply_source. + READ TABLE mt_conflicts ASSIGNING INDEX mv_current_conflict_index. + -result_sha1 = -source_sha1. + -result_data = -source_data. + mo_merge->resolve_conflict( is_conflict = ). + + WHEN c_actions-apply_target. + READ TABLE mt_conflicts ASSIGNING INDEX mv_current_conflict_index. + -result_sha1 = -target_sha1. + -result_data = -target_data. + mo_merge->resolve_conflict( is_conflict = ). + + ENDCASE. + + mv_current_conflict_index = mv_current_conflict_index + 1. + IF mv_current_conflict_index > lines( mt_conflicts ). + CLEAR mv_current_conflict_index. + ENDIF. + + IF mv_current_conflict_index IS NOT INITIAL. + ev_state = zif_abapgit_definitions=>gc_event_state-re_render. + ELSE. + ei_page = mo_merge_page. + ev_state = zif_abapgit_definitions=>gc_event_state-go_back. + ENDIF. + + WHEN c_actions-toggle_mode. + toggle_merge_mode( ). + ev_state = zif_abapgit_definitions=>gc_event_state-re_render. + + ENDCASE. + + ENDMETHOD. +ENDCLASS. diff --git a/src/ui/zcl_abapgit_gui_page_merge_res.clas.xml b/src/ui/zcl_abapgit_gui_page_merge_res.clas.xml new file mode 100644 index 000000000..ee6d9a501 --- /dev/null +++ b/src/ui/zcl_abapgit_gui_page_merge_res.clas.xml @@ -0,0 +1,45 @@ + + + + + + ZCL_ABAPGIT_GUI_PAGE_MERGE_RES + 1 + E + GUI - Resolving Conflicts page + 2 + 1 + X + X + X + X + + + + ZCL_ABAPGIT_GUI_PAGE_MERGE_RES + MO_MERGE + E + Merge logic + + + ZCL_ABAPGIT_GUI_PAGE_MERGE_RES + MO_MERGE_PAGE + E + GUI - Merging page + + + ZCL_ABAPGIT_GUI_PAGE_MERGE_RES + MO_REPO + E + Online Repository + + + ZCL_ABAPGIT_GUI_PAGE_MERGE_RES + MV_CURRENT_CONFLICT_INDEX + E + Row Index of Internal Tables + + + + + diff --git a/src/zcl_abapgit_merge.clas.abap b/src/zcl_abapgit_merge.clas.abap index c33f10774..14fb52563 100644 --- a/src/zcl_abapgit_merge.clas.abap +++ b/src/zcl_abapgit_merge.clas.abap @@ -1,37 +1,78 @@ -CLASS zcl_abapgit_merge DEFINITION PUBLIC FINAL CREATE PUBLIC. +CLASS zcl_abapgit_merge DEFINITION + PUBLIC + FINAL + CREATE PUBLIC . PUBLIC SECTION. - CLASS-METHODS: - run - IMPORTING io_repo TYPE REF TO zcl_abapgit_repo_online - iv_source TYPE string - iv_target TYPE string - RETURNING VALUE(rs_merge) TYPE zif_abapgit_definitions=>ty_merge - RAISING zcx_abapgit_exception. + + METHODS constructor + IMPORTING + !io_repo TYPE REF TO zcl_abapgit_repo_online + !iv_source_branch TYPE string + !iv_target_branch TYPE string + RAISING + zcx_abapgit_exception . + METHODS get_conflicts + RETURNING + VALUE(rt_conflicts) TYPE zif_abapgit_definitions=>tt_merge_conflict . + METHODS get_result + RETURNING + VALUE(rs_merge) TYPE zif_abapgit_definitions=>ty_merge . + METHODS get_source_branch + RETURNING + VALUE(rv_source_branch) TYPE string . + METHODS get_target_branch + RETURNING + VALUE(rv_target_branch) TYPE string . + METHODS has_conflicts + RETURNING + VALUE(rv_conflicts_exists) TYPE boolean . + METHODS resolve_conflict + IMPORTING + !is_conflict TYPE zif_abapgit_definitions=>ty_merge_conflict + RAISING + zcx_abapgit_exception . + METHODS run + RAISING + zcx_abapgit_exception . PRIVATE SECTION. - CLASS-DATA: gs_merge TYPE zif_abapgit_definitions=>ty_merge, - gt_objects TYPE zif_abapgit_definitions=>ty_objects_tt. - TYPES: ty_ancestor_tt TYPE STANDARD TABLE OF zif_abapgit_definitions=>ty_ancestor WITH DEFAULT KEY. + TYPES: + ty_ancestor_tt TYPE STANDARD TABLE OF zif_abapgit_definitions=>ty_ancestor WITH DEFAULT KEY . - CLASS-METHODS: - all_files - RETURNING VALUE(rt_files) TYPE zif_abapgit_definitions=>ty_expanded_tt, - calculate_result - RAISING zcx_abapgit_exception, - find_ancestors - IMPORTING iv_commit TYPE zif_abapgit_definitions=>ty_sha1 - RETURNING VALUE(rt_ancestors) TYPE ty_ancestor_tt - RAISING zcx_abapgit_exception, - find_first_common - IMPORTING it_list1 TYPE ty_ancestor_tt - it_list2 TYPE ty_ancestor_tt - RETURNING VALUE(rs_common) TYPE zif_abapgit_definitions=>ty_ancestor - RAISING zcx_abapgit_exception, - fetch_git - IMPORTING iv_source TYPE string - iv_target TYPE string - RAISING zcx_abapgit_exception. + DATA mo_repo TYPE REF TO zcl_abapgit_repo_online . + DATA ms_merge TYPE zif_abapgit_definitions=>ty_merge . + DATA mt_conflicts TYPE zif_abapgit_definitions=>tt_merge_conflict . + DATA mt_objects TYPE zif_abapgit_definitions=>ty_objects_tt . + DATA mv_source_branch TYPE string . + DATA mv_target_branch TYPE string . + + METHODS all_files + RETURNING + VALUE(rt_files) TYPE zif_abapgit_definitions=>ty_expanded_tt . + METHODS calculate_result + RAISING + zcx_abapgit_exception . + METHODS fetch_git + RETURNING + VALUE(rt_objects) TYPE zif_abapgit_definitions=>ty_objects_tt + RAISING + zcx_abapgit_exception . + METHODS find_ancestors + IMPORTING + !iv_commit TYPE zif_abapgit_definitions=>ty_sha1 + RETURNING + VALUE(rt_ancestors) TYPE ty_ancestor_tt + RAISING + zcx_abapgit_exception . + METHODS find_first_common + IMPORTING + !it_list1 TYPE ty_ancestor_tt + !it_list2 TYPE ty_ancestor_tt + RETURNING + VALUE(rs_common) TYPE zif_abapgit_definitions=>ty_ancestor + RAISING + zcx_abapgit_exception . ENDCLASS. @@ -41,9 +82,9 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION. METHOD all_files. - APPEND LINES OF gs_merge-stree TO rt_files. - APPEND LINES OF gs_merge-ttree TO rt_files. - APPEND LINES OF gs_merge-ctree TO rt_files. + APPEND LINES OF ms_merge-stree TO rt_files. + APPEND LINES OF ms_merge-ttree TO rt_files. + APPEND LINES OF ms_merge-ctree TO rt_files. SORT rt_files BY path DESCENDING name ASCENDING. DELETE ADJACENT DUPLICATES FROM rt_files COMPARING path name. @@ -53,12 +94,12 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION. METHOD calculate_result. DEFINE _from_source. - READ TABLE gt_objects ASSIGNING + READ TABLE mt_objects ASSIGNING WITH KEY type = zif_abapgit_definitions=>gc_type-blob sha1 = -sha1. ASSERT sy-subrc = 0. - gs_merge-stage->add( iv_path = -path + ms_merge-stage->add( iv_path = -path iv_filename = -name iv_data = -data ). END-OF-DEFINITION. @@ -68,21 +109,21 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION. lv_found_target TYPE abap_bool, lv_found_common TYPE abap_bool. - FIELD-SYMBOLS: LIKE LINE OF lt_files, - LIKE LINE OF lt_files, - LIKE LINE OF lt_files, - LIKE LINE OF lt_files, - LIKE LINE OF gs_merge-result, - LIKE LINE OF gt_objects. - + FIELD-SYMBOLS: LIKE LINE OF lt_files, + LIKE LINE OF lt_files, + LIKE LINE OF lt_files, + LIKE LINE OF lt_files, + LIKE LINE OF ms_merge-result, + LIKE LINE OF mt_objects, + LIKE LINE OF mt_conflicts. lt_files = all_files( ). - CREATE OBJECT gs_merge-stage + CREATE OBJECT ms_merge-stage EXPORTING - iv_branch_name = gs_merge-target-name - iv_branch_sha1 = gs_merge-target-sha1 - iv_merge_source = gs_merge-source-sha1. + iv_branch_name = ms_merge-target-name + iv_branch_sha1 = ms_merge-target-sha1 + iv_merge_source = ms_merge-source-sha1. LOOP AT lt_files ASSIGNING . @@ -90,11 +131,11 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION. UNASSIGN . UNASSIGN . - READ TABLE gs_merge-stree ASSIGNING + READ TABLE ms_merge-stree ASSIGNING WITH KEY path = -path name = -name. "#EC CI_SUBRC - READ TABLE gs_merge-ttree ASSIGNING + READ TABLE ms_merge-ttree ASSIGNING WITH KEY path = -path name = -name. "#EC CI_SUBRC - READ TABLE gs_merge-ctree ASSIGNING + READ TABLE ms_merge-ctree ASSIGNING WITH KEY path = -path name = -name. "#EC CI_SUBRC lv_found_source = boolc( IS ASSIGNED ). @@ -109,7 +150,7 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION. AND lv_found_common = abap_true AND -sha1 = -sha1. * deleted in source, skip - gs_merge-stage->rm( iv_path = -path + ms_merge-stage->rm( iv_path = -path iv_filename = -name ). CONTINUE. ELSEIF lv_found_target = abap_false @@ -119,7 +160,7 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION. CONTINUE. ENDIF. - APPEND INITIAL LINE TO gs_merge-result ASSIGNING . + APPEND INITIAL LINE TO ms_merge-result ASSIGNING . -path = -path. -name = -name. @@ -135,15 +176,32 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION. AND -sha1 = -sha1. * added in source and target -sha1 = -sha1. + ELSEIF lv_found_common = abap_false + AND -sha1 <> -sha1. + + INSERT INITIAL LINE INTO TABLE mt_conflicts ASSIGNING . + -path = -path. + -filename = -name. + -source_sha1 = -sha1. + READ TABLE mt_objects ASSIGNING WITH KEY type = zif_abapgit_definitions=>gc_type-blob + sha1 = -sha1. + -source_data = -data. + + -target_sha1 = -sha1. + READ TABLE mt_objects ASSIGNING WITH KEY type = zif_abapgit_definitions=>gc_type-blob + sha1 = -sha1. + -target_data = -data. + +* added in source and target, but different, merge conflict must be resolved + ms_merge-conflict = |{ -name } merge conflict|. + CONTINUE. ENDIF. IF lv_found_source = abap_false - OR lv_found_target = abap_false - OR lv_found_common = abap_false. - CLEAR gs_merge-result. - gs_merge-conflict = |{ -name - } merge conflict, not found anywhere|. - RETURN. + OR lv_found_target = abap_false + OR lv_found_common = abap_false. + ms_merge-conflict = |{ -name } merge conflict, not found anywhere|. + CONTINUE. ENDIF. IF -sha1 = -sha1. @@ -158,40 +216,62 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION. -sha1 = -sha1. ELSE. * changed in source and target, conflict - CLEAR gs_merge-result. - gs_merge-conflict = |{ -name - } merge conflict, changed in source and target branch|. - RETURN. - ENDIF. +* conflict must be resolved before merge + INSERT INITIAL LINE INTO TABLE mt_conflicts ASSIGNING . + -path = -path. + -filename = -name. + -source_sha1 = -sha1. + READ TABLE mt_objects ASSIGNING WITH KEY type = zif_abapgit_definitions=>gc_type-blob + sha1 = -sha1. + -source_data = -data. + -target_sha1 = -sha1. + READ TABLE mt_objects ASSIGNING WITH KEY type = zif_abapgit_definitions=>gc_type-blob + sha1 = -sha1. + -target_data = -data. + + ms_merge-conflict = |{ -name } merge conflict, changed in source and target branch|. + ENDIF. ENDLOOP. ENDMETHOD. + METHOD constructor. + + IF iv_source_branch EQ iv_target_branch. + zcx_abapgit_exception=>raise( 'source = target' ). + ENDIF. + + mo_repo = io_repo. + mv_source_branch = iv_source_branch. + mv_target_branch = iv_target_branch. + + ENDMETHOD. + + METHOD fetch_git. DATA: lo_branch_list TYPE REF TO zcl_abapgit_git_branch_list, lt_upload TYPE zif_abapgit_definitions=>ty_git_branch_list_tt. + lo_branch_list = zcl_abapgit_git_transport=>branches( ms_merge-repo->get_url( ) ). + ms_merge-source = lo_branch_list->find_by_name( + zcl_abapgit_git_branch_list=>complete_heads_branch_name( mv_source_branch ) ). + ms_merge-target = lo_branch_list->find_by_name( + zcl_abapgit_git_branch_list=>complete_heads_branch_name( mv_target_branch ) ). - lo_branch_list = zcl_abapgit_git_transport=>branches( gs_merge-repo->get_url( ) ). - gs_merge-source = lo_branch_list->find_by_name( - zcl_abapgit_git_branch_list=>complete_heads_branch_name( iv_source ) ). - gs_merge-target = lo_branch_list->find_by_name( - zcl_abapgit_git_branch_list=>complete_heads_branch_name( iv_target ) ). - - APPEND gs_merge-source TO lt_upload. - APPEND gs_merge-target TO lt_upload. + APPEND ms_merge-source TO lt_upload. + APPEND ms_merge-target TO lt_upload. zcl_abapgit_git_transport=>upload_pack( EXPORTING - iv_url = gs_merge-repo->get_url( ) - iv_branch_name = gs_merge-repo->get_branch_name( ) + iv_url = ms_merge-repo->get_url( ) + iv_branch_name = ms_merge-repo->get_branch_name( ) iv_deepen = abap_false it_branches = lt_upload IMPORTING - et_objects = gt_objects ). + et_objects = rt_objects ). ENDMETHOD. @@ -212,13 +292,13 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION. lv_commit LIKE LINE OF lt_visit. FIELD-SYMBOLS: LIKE LINE OF rt_ancestors, - LIKE LINE OF gt_objects. + LIKE LINE OF mt_objects. APPEND iv_commit TO lt_visit. LOOP AT lt_visit INTO lv_commit. - READ TABLE gt_objects ASSIGNING + READ TABLE mt_objects ASSIGNING WITH KEY type = zif_abapgit_definitions=>gc_type-commit sha1 = lv_commit. ASSERT sy-subrc = 0. @@ -231,9 +311,11 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION. -commit = lv_commit. -tree = ls_commit-tree. -body = ls_commit-body. - FIND REGEX zif_abapgit_definitions=>gc_author_regex IN ls_commit-author - SUBMATCHES -time ##NO_TEXT. - ASSERT sy-subrc = 0. + -time = ls_commit-author. + + "Strip Author entry of all but the time component + REPLACE ALL OCCURRENCES OF REGEX '[a-zA-Z<>@.-]*' IN -time WITH ''. + CONDENSE -time. ENDLOOP. SORT rt_ancestors BY time DESCENDING. @@ -246,7 +328,6 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION. FIELD-SYMBOLS: LIKE LINE OF it_list1, LIKE LINE OF it_list2. - LOOP AT it_list1 ASSIGNING . LOOP AT it_list2 ASSIGNING . IF -tree = -tree. @@ -261,42 +342,107 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION. ENDMETHOD. + METHOD get_conflicts. + + rt_conflicts = mt_conflicts. + + ENDMETHOD. + + + METHOD get_result. + + rs_merge = ms_merge. + + ENDMETHOD. + + + METHOD get_source_branch. + + rv_source_branch = mv_source_branch. + + ENDMETHOD. + + + METHOD get_target_branch. + + rv_target_branch = mv_target_branch. + + ENDMETHOD. + + + METHOD has_conflicts. + + IF lines( mt_conflicts ) > 0. + rv_conflicts_exists = abap_true. + ELSE. + rv_conflicts_exists = abap_false. + ENDIF. + + ENDMETHOD. + + + METHOD resolve_conflict. + + FIELD-SYMBOLS: TYPE zif_abapgit_definitions=>ty_merge_conflict, + LIKE LINE OF ms_merge-result. + + IF is_conflict-result_sha1 IS NOT INITIAL + AND is_conflict-result_data IS NOT INITIAL. + READ TABLE mt_conflicts ASSIGNING WITH KEY path = is_conflict-path + filename = is_conflict-filename. + IF sy-subrc EQ 0. + READ TABLE ms_merge-result ASSIGNING WITH KEY path = is_conflict-path + name = is_conflict-filename. + IF sy-subrc EQ 0. + -sha1 = is_conflict-result_sha1. + + ms_merge-stage->add( iv_path = -path + iv_filename = -filename + iv_data = is_conflict-result_data ). + + DELETE mt_conflicts WHERE path EQ is_conflict-path + AND filename EQ is_conflict-filename. + ENDIF. + + READ TABLE ms_merge-result ASSIGNING WITH KEY sha1 = space. + IF sy-subrc EQ 0. + ms_merge-conflict = |{ -name } merge conflict, changed in source and target branch|. + ELSE. + CLEAR ms_merge-conflict. + ENDIF. + ENDIF. + ENDIF. + + ENDMETHOD. + + METHOD run. DATA: lt_asource TYPE ty_ancestor_tt, lt_atarget TYPE ty_ancestor_tt. + CLEAR: ms_merge, mt_objects, mt_conflicts. - IF iv_source = iv_target. - zcx_abapgit_exception=>raise( 'source = target' ). - ENDIF. + ms_merge-repo = mo_repo. + mt_objects = fetch_git( ). - CLEAR gs_merge. + lt_asource = find_ancestors( ms_merge-source-sha1 ). + lt_atarget = find_ancestors( ms_merge-target-sha1 ). - gs_merge-repo = io_repo. - - fetch_git( iv_source = iv_source - iv_target = iv_target ). - - lt_asource = find_ancestors( gs_merge-source-sha1 ). - lt_atarget = find_ancestors( gs_merge-target-sha1 ). - - gs_merge-common = find_first_common( it_list1 = lt_asource + ms_merge-common = find_first_common( it_list1 = lt_asource it_list2 = lt_atarget ). - gs_merge-stree = zcl_abapgit_git_porcelain=>full_tree( - it_objects = gt_objects - iv_branch = gs_merge-source-sha1 ). - gs_merge-ttree = zcl_abapgit_git_porcelain=>full_tree( - it_objects = gt_objects - iv_branch = gs_merge-target-sha1 ). - gs_merge-ctree = zcl_abapgit_git_porcelain=>full_tree( - it_objects = gt_objects - iv_branch = gs_merge-common-commit ). + ms_merge-stree = zcl_abapgit_git_porcelain=>full_tree( + it_objects = mt_objects + iv_branch = ms_merge-source-sha1 ). + ms_merge-ttree = zcl_abapgit_git_porcelain=>full_tree( + it_objects = mt_objects + iv_branch = ms_merge-target-sha1 ). + ms_merge-ctree = zcl_abapgit_git_porcelain=>full_tree( + it_objects = mt_objects + iv_branch = ms_merge-common-commit ). calculate_result( ). - rs_merge = gs_merge. - ENDMETHOD. ENDCLASS. diff --git a/src/zcl_abapgit_merge.clas.xml b/src/zcl_abapgit_merge.clas.xml index 9d5433be3..174d6efe0 100644 --- a/src/zcl_abapgit_merge.clas.xml +++ b/src/zcl_abapgit_merge.clas.xml @@ -14,6 +14,20 @@ X X + + + ZCL_ABAPGIT_MERGE + CONSTRUCTOR + E + CONSTRUCTOR + + + ZCL_ABAPGIT_MERGE + MO_REPO + E + Online Repository + + diff --git a/src/zif_abapgit_definitions.intf.abap b/src/zif_abapgit_definitions.intf.abap index 27a980792..7469bb532 100644 --- a/src/zif_abapgit_definitions.intf.abap +++ b/src/zif_abapgit_definitions.intf.abap @@ -272,6 +272,18 @@ INTERFACE zif_abapgit_definitions PUBLIC. conflict TYPE string, END OF ty_merge. + TYPES: BEGIN OF ty_merge_conflict, + path TYPE string, + filename TYPE string, + source_sha1 TYPE zif_abapgit_definitions=>ty_sha1, + source_data TYPE xstring, + target_sha1 TYPE zif_abapgit_definitions=>ty_sha1, + target_data TYPE xstring, + result_sha1 TYPE zif_abapgit_definitions=>ty_sha1, + result_data TYPE xstring, + END OF ty_merge_conflict, + tt_merge_conflict TYPE STANDARD TABLE OF ty_merge_conflict WITH DEFAULT KEY. + TYPES: BEGIN OF ty_repo_item, obj_type TYPE tadir-object, obj_name TYPE tadir-obj_name,