mirror of
https://github.com/abapGit/abapGit.git
synced 2025-04-30 20:03:20 +08:00
Possible solution to zabapgit merge functionality to resolve conflicts (#1407)
* Merging per Textfile * Add files via upload * Delete WolfTreak_ABAPGIT_Merging * Refactoring vom Coding, Darstellung verbessert * Merging page changed and also merging class extended to instance and conflict methods added * Refactoring for Travis * Refactoring for Travis * Escaping of merged content functions now correct
This commit is contained in:
parent
174f9eafa7
commit
0aecdf7255
|
@ -1,31 +1,39 @@
|
||||||
CLASS zcl_abapgit_gui_page_merge DEFINITION
|
CLASS zcl_abapgit_gui_page_merge DEFINITION
|
||||||
PUBLIC
|
PUBLIC
|
||||||
|
INHERITING FROM zcl_abapgit_gui_page
|
||||||
FINAL
|
FINAL
|
||||||
CREATE PUBLIC INHERITING FROM zcl_abapgit_gui_page.
|
CREATE PUBLIC .
|
||||||
|
|
||||||
PUBLIC SECTION.
|
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.
|
PROTECTED SECTION.
|
||||||
METHODS render_content REDEFINITION.
|
METHODS render_content REDEFINITION.
|
||||||
|
|
||||||
PRIVATE SECTION.
|
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,
|
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,
|
merge TYPE string VALUE 'merge' ##NO_TEXT,
|
||||||
|
res_conflicts TYPE string VALUE 'res_conflicts' ##NO_TEXT,
|
||||||
END OF c_actions .
|
END OF c_actions .
|
||||||
|
|
||||||
METHODS:
|
METHODS build_menu
|
||||||
build_menu
|
IMPORTING
|
||||||
RETURNING VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar.
|
VALUE(iv_with_conflict) TYPE boolean OPTIONAL
|
||||||
|
RETURNING
|
||||||
|
VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar .
|
||||||
ENDCLASS.
|
ENDCLASS.
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,7 +45,11 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_MERGE IMPLEMENTATION.
|
||||||
|
|
||||||
CREATE OBJECT ro_menu.
|
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.
|
ENDMETHOD.
|
||||||
|
|
||||||
|
@ -45,15 +57,18 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_MERGE IMPLEMENTATION.
|
||||||
METHOD constructor.
|
METHOD constructor.
|
||||||
|
|
||||||
super->constructor( ).
|
super->constructor( ).
|
||||||
ms_control-page_title = 'MERGE'.
|
|
||||||
ms_control-page_menu = build_menu( ).
|
|
||||||
|
|
||||||
mo_repo = io_repo.
|
mo_repo = io_repo.
|
||||||
|
|
||||||
ms_merge = zcl_abapgit_merge=>run(
|
CREATE OBJECT mo_merge
|
||||||
|
EXPORTING
|
||||||
io_repo = io_repo
|
io_repo = io_repo
|
||||||
iv_source = iv_source
|
iv_source_branch = iv_source
|
||||||
iv_target = iv_target ).
|
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.
|
ENDMETHOD.
|
||||||
|
|
||||||
|
@ -78,12 +93,17 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_MERGE IMPLEMENTATION.
|
||||||
ENDIF.
|
ENDIF.
|
||||||
END-OF-DEFINITION.
|
END-OF-DEFINITION.
|
||||||
|
|
||||||
DATA: lt_files LIKE ms_merge-stree,
|
DATA: ls_merge TYPE zif_abapgit_definitions=>ty_merge,
|
||||||
ls_result LIKE LINE OF ms_merge-result.
|
lt_files LIKE ls_merge-stree,
|
||||||
|
ls_result LIKE LINE OF ls_merge-result.
|
||||||
|
|
||||||
FIELD-SYMBOLS: <ls_show> LIKE LINE OF lt_files,
|
FIELD-SYMBOLS: <ls_show> LIKE LINE OF lt_files,
|
||||||
<ls_file> LIKE LINE OF lt_files.
|
<ls_file> 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.
|
CREATE OBJECT ro_html.
|
||||||
|
|
||||||
|
@ -95,27 +115,27 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_MERGE IMPLEMENTATION.
|
||||||
|
|
||||||
ro_html->add( '<table>' ).
|
ro_html->add( '<table>' ).
|
||||||
ro_html->add( '<tr>' ).
|
ro_html->add( '<tr>' ).
|
||||||
ro_html->add( '<td>Source:</td>' ).
|
ro_html->add( '<td>Source</td>' ).
|
||||||
ro_html->add( '<td>' ).
|
ro_html->add( '<td>' ).
|
||||||
ro_html->add( ms_merge-source-name ).
|
ro_html->add( ls_merge-source-name ).
|
||||||
ro_html->add( '</td></tr>' ).
|
ro_html->add( '</td></tr>' ).
|
||||||
ro_html->add( '<tr>' ).
|
ro_html->add( '<tr>' ).
|
||||||
ro_html->add( '<td>Target:</td>' ).
|
ro_html->add( '<td>Target</td>' ).
|
||||||
ro_html->add( '<td>' ).
|
ro_html->add( '<td>' ).
|
||||||
ro_html->add( ms_merge-target-name ).
|
ro_html->add( ls_merge-target-name ).
|
||||||
ro_html->add( '</td></tr>' ).
|
ro_html->add( '</td></tr>' ).
|
||||||
ro_html->add( '<tr>' ).
|
ro_html->add( '<tr>' ).
|
||||||
ro_html->add( '<td>Ancestor:</td>' ).
|
ro_html->add( '<td>Ancestor</td>' ).
|
||||||
ro_html->add( '<td>' ).
|
ro_html->add( '<td>' ).
|
||||||
ro_html->add( ms_merge-common-commit ).
|
ro_html->add( ls_merge-common-commit ).
|
||||||
ro_html->add( '</td></tr>' ).
|
ro_html->add( '</td></tr>' ).
|
||||||
ro_html->add( '</table>' ).
|
ro_html->add( '</table>' ).
|
||||||
|
|
||||||
ro_html->add( '<br>' ).
|
ro_html->add( '<br>' ).
|
||||||
|
|
||||||
APPEND LINES OF ms_merge-stree TO lt_files.
|
APPEND LINES OF ls_merge-stree TO lt_files.
|
||||||
APPEND LINES OF ms_merge-ttree TO lt_files.
|
APPEND LINES OF ls_merge-ttree TO lt_files.
|
||||||
APPEND LINES OF ms_merge-ctree TO lt_files.
|
APPEND LINES OF ls_merge-ctree TO lt_files.
|
||||||
SORT lt_files BY path DESCENDING name ASCENDING.
|
SORT lt_files BY path DESCENDING name ASCENDING.
|
||||||
DELETE ADJACENT DUPLICATES FROM lt_files COMPARING path name.
|
DELETE ADJACENT DUPLICATES FROM lt_files COMPARING path name.
|
||||||
|
|
||||||
|
@ -132,20 +152,20 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_MERGE IMPLEMENTATION.
|
||||||
ro_html->add( '</tr>' ).
|
ro_html->add( '</tr>' ).
|
||||||
LOOP AT lt_files ASSIGNING <ls_file>.
|
LOOP AT lt_files ASSIGNING <ls_file>.
|
||||||
CLEAR ls_result.
|
CLEAR ls_result.
|
||||||
READ TABLE ms_merge-result INTO ls_result
|
READ TABLE ls_merge-result INTO ls_result
|
||||||
WITH KEY path = <ls_file>-path name = <ls_file>-name.
|
WITH KEY path = <ls_file>-path name = <ls_file>-name.
|
||||||
|
|
||||||
ro_html->add( '<tr>' ).
|
ro_html->add( '<tr>' ).
|
||||||
_show_file ms_merge-stree.
|
_show_file ls_merge-stree.
|
||||||
_show_file ms_merge-ttree.
|
_show_file ls_merge-ttree.
|
||||||
_show_file ms_merge-ctree.
|
_show_file ls_merge-ctree.
|
||||||
_show_file ms_merge-result.
|
_show_file ls_merge-result.
|
||||||
ro_html->add( '</tr>' ).
|
ro_html->add( '</tr>' ).
|
||||||
ENDLOOP.
|
ENDLOOP.
|
||||||
ro_html->add( '</table>' ).
|
ro_html->add( '</table>' ).
|
||||||
ro_html->add( '<br>' ).
|
ro_html->add( '<br>' ).
|
||||||
ro_html->add( '<b>' ).
|
ro_html->add( '<b>' ).
|
||||||
ro_html->add( ms_merge-conflict ).
|
ro_html->add( ls_merge-conflict ).
|
||||||
ro_html->add( '</b>' ).
|
ro_html->add( '</b>' ).
|
||||||
ro_html->add( '</div>' ).
|
ro_html->add( '</div>' ).
|
||||||
|
|
||||||
|
@ -156,15 +176,28 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_MERGE IMPLEMENTATION.
|
||||||
|
|
||||||
CASE iv_action.
|
CASE iv_action.
|
||||||
WHEN c_actions-merge.
|
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' ).
|
zcx_abapgit_exception=>raise( 'nothing to merge' ).
|
||||||
ENDIF.
|
ENDIF.
|
||||||
|
|
||||||
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_commit
|
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_commit
|
||||||
EXPORTING
|
EXPORTING
|
||||||
io_repo = mo_repo
|
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.
|
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.
|
ENDCASE.
|
||||||
|
|
||||||
ENDMETHOD.
|
ENDMETHOD.
|
||||||
|
|
|
@ -14,6 +14,14 @@
|
||||||
<FIXPT>X</FIXPT>
|
<FIXPT>X</FIXPT>
|
||||||
<UNICODE>X</UNICODE>
|
<UNICODE>X</UNICODE>
|
||||||
</VSEOCLASS>
|
</VSEOCLASS>
|
||||||
|
<DESCRIPTIONS>
|
||||||
|
<SEOCOMPOTX>
|
||||||
|
<CLSNAME>ZCL_ABAPGIT_GUI_PAGE_MERGE</CLSNAME>
|
||||||
|
<CMPNAME>MO_MERGE</CMPNAME>
|
||||||
|
<LANGU>E</LANGU>
|
||||||
|
<DESCRIPT>Merge logic</DESCRIPT>
|
||||||
|
</SEOCOMPOTX>
|
||||||
|
</DESCRIPTIONS>
|
||||||
</asx:values>
|
</asx:values>
|
||||||
</asx:abap>
|
</asx:abap>
|
||||||
</abapGit>
|
</abapGit>
|
||||||
|
|
583
src/ui/zcl_abapgit_gui_page_merge_res.clas.abap
Normal file
583
src/ui/zcl_abapgit_gui_page_merge_res.clas.abap
Normal file
|
@ -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 '<<new>>'.
|
||||||
|
|
||||||
|
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: <postdata_line> LIKE LINE OF it_postdata,
|
||||||
|
<ls_conflict> TYPE zif_abapgit_definitions=>ty_merge_conflict.
|
||||||
|
|
||||||
|
LOOP AT it_postdata ASSIGNING <postdata_line>.
|
||||||
|
lv_string = |{ lv_string }{ <postdata_line> }|.
|
||||||
|
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 <ls_conflict> INDEX mv_current_conflict_index.
|
||||||
|
<ls_conflict>-result_sha1 = zcl_abapgit_hash=>sha1( iv_type = zif_abapgit_definitions=>gc_type-blob
|
||||||
|
iv_data = lv_new_file_content ).
|
||||||
|
<ls_conflict>-result_data = lv_new_file_content.
|
||||||
|
mo_merge->resolve_conflict( is_conflict = <ls_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 <lv_data> LIKE iv_d1.
|
||||||
|
|
||||||
|
|
||||||
|
IF iv_d1 IS NOT INITIAL. " One of them might be new and so empty
|
||||||
|
ASSIGN iv_d1 TO <lv_data>.
|
||||||
|
ELSE.
|
||||||
|
ASSIGN iv_d2 TO <lv_data>.
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
lv_len = xstrlen( <lv_data> ).
|
||||||
|
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_data>+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( '<thead class="nav_line">' ).
|
||||||
|
ro_html->add( '<tr>' ).
|
||||||
|
|
||||||
|
ro_html->add( '<th class="num"></th>' ).
|
||||||
|
ro_html->add( |<th colspan="3">@@ { is_diff_line-new_num } @@ { lv_beacon }</th>| ).
|
||||||
|
|
||||||
|
ro_html->add( '</tr>' ).
|
||||||
|
ro_html->add( '</thead>' ).
|
||||||
|
|
||||||
|
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( |<div id="diff-list" data-repo-key="{ mo_repo->get_key( ) }">| ).
|
||||||
|
ro_html->add( render_diff( ms_diff_file ) ).
|
||||||
|
ro_html->add( '</div>' ).
|
||||||
|
|
||||||
|
ENDMETHOD. "render_content
|
||||||
|
|
||||||
|
|
||||||
|
METHOD render_diff.
|
||||||
|
|
||||||
|
DATA: lv_target_content TYPE string.
|
||||||
|
FIELD-SYMBOLS: <ls_conflict> TYPE zif_abapgit_definitions=>ty_merge_conflict.
|
||||||
|
|
||||||
|
CREATE OBJECT ro_html.
|
||||||
|
|
||||||
|
ro_html->add( |<div class="diff" data-type="{ is_diff-type
|
||||||
|
}" data-changed-by="{ is_diff-changed_by
|
||||||
|
}" data-file="{ is_diff-path && is_diff-filename }">| ). "#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( '<div class="diff_content">' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<table class="diff_tab syntax-hl">' ). "#EC NOTEXT
|
||||||
|
ro_html->add( render_table_head( ) ).
|
||||||
|
ro_html->add( render_lines( is_diff ) ).
|
||||||
|
ro_html->add( '</table>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '</div>' ). "#EC NOTEXT
|
||||||
|
ELSE.
|
||||||
|
|
||||||
|
"Table for Div-Table and textarea
|
||||||
|
ro_html->add( '<div class="diff_content">' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<table>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<thead class="header">' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<tr>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<th>Code</th>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<th>Merge - ' ). "#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( '</th> ' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '</tr>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '</thead>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<td>' ).
|
||||||
|
|
||||||
|
"Diff-Table of source and target file
|
||||||
|
ro_html->add( '<table class="diff_tab syntax-hl">' ). "#EC NOTEXT
|
||||||
|
ro_html->add( render_table_head( ) ).
|
||||||
|
ro_html->add( render_lines( is_diff ) ).
|
||||||
|
ro_html->add( '</table>' ). "#EC NOTEXT
|
||||||
|
|
||||||
|
READ TABLE mt_conflicts ASSIGNING <ls_conflict> INDEX mv_current_conflict_index.
|
||||||
|
IF sy-subrc EQ 0.
|
||||||
|
lv_target_content = zcl_abapgit_convert=>xstring_to_string_utf8( <ls_conflict>-target_data ).
|
||||||
|
lv_target_content = escape( val = lv_target_content format = cl_abap_format=>e_html_text ).
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
ro_html->add( '</td>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<td>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<div class="form-container">' ).
|
||||||
|
ro_html->add( |<form id="merge_form" class="aligned-form" accept-charset="UTF-8"| ).
|
||||||
|
ro_html->add( |method="post" action="sapevent:apply_merge">| ).
|
||||||
|
ro_html->add( |<textarea id="merge_content" name="merge_content" | ).
|
||||||
|
ro_html->add( |rows="{ lines( is_diff-o_diff->get( ) ) }">{ lv_target_content }</textarea>| ).
|
||||||
|
ro_html->add( '<input type="submit" class="hidden-submit">' ).
|
||||||
|
ro_html->add( '</form>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '</div>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '</td>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '</table>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '</div>' ). "#EC NOTEXT
|
||||||
|
ENDIF.
|
||||||
|
ELSE.
|
||||||
|
ro_html->add( '<div class="diff_content paddings center grey">' ). "#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( '</div>' ). "#EC NOTEXT
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
ro_html->add( '</div>' ). "#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( '<div class="diff_head">' ). "#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( |<span class="diff_banner diff_ins">+ { ls_stats-insert }</span>| ).
|
||||||
|
ro_html->add( |<span class="diff_banner diff_del">- { ls_stats-delete }</span>| ).
|
||||||
|
ro_html->add( |<span class="diff_banner diff_upd">~ { ls_stats-update }</span>| ).
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
ro_html->add( |<span class="diff_name">{ is_diff-filename }</span>| ). "#EC NOTEXT
|
||||||
|
ro_html->add( '</div>' ). "#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 <ls_diff> 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 <ls_diff>.
|
||||||
|
IF <ls_diff>-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 = <ls_diff> is_diff = is_diff ) ).
|
||||||
|
lv_insert_nav = abap_false.
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
IF lo_highlighter IS BOUND.
|
||||||
|
<ls_diff>-new = lo_highlighter->process_line( <ls_diff>-new ).
|
||||||
|
<ls_diff>-old = lo_highlighter->process_line( <ls_diff>-old ).
|
||||||
|
ELSE.
|
||||||
|
<ls_diff>-new = escape( val = <ls_diff>-new format = cl_abap_format=>e_html_attr ).
|
||||||
|
<ls_diff>-old = escape( val = <ls_diff>-old format = cl_abap_format=>e_html_attr ).
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
CONDENSE <ls_diff>-new_num. "get rid of leading spaces
|
||||||
|
CONDENSE <ls_diff>-old_num.
|
||||||
|
|
||||||
|
ro_html->add( render_line_split( is_diff_line = <ls_diff>
|
||||||
|
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 = |<td class="num" line-num="{ is_diff_line-new_num }"></td>|
|
||||||
|
&& |<td class="code{ lv_bg }">{ lv_mark }{ is_diff_line-new }</td>|.
|
||||||
|
|
||||||
|
" 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 = |<td class="num" line-num="{ is_diff_line-old_num }"></td>|
|
||||||
|
&& |<td class="code{ lv_bg }">{ lv_mark }{ is_diff_line-old }</td>|.
|
||||||
|
|
||||||
|
" render line, inverse sides if remote is newer
|
||||||
|
ro_html->add( '<tr>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( lv_old ). " Target
|
||||||
|
ro_html->add( lv_new ). " Source
|
||||||
|
ro_html->add( '</tr>' ). "#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( '<thead class="header">' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<tr>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<th class="num"></th>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<form id="target_form" method="post" action="sapevent:apply_target">' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<th>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( '</th> ' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '</form>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<th class="num"></th>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<form id="source_form" method="post" action="sapevent:apply_source">' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<th>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( '</th> ' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '</form>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '</tr>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '</thead>' ). "#EC NOTEXT
|
||||||
|
ELSE.
|
||||||
|
ro_html->add( '<thead class="header">' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<tr>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<th class="num"></th>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<th>Target - ' && mo_merge->get_target_branch( ) &&'</th> ' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<th class="num"></th>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '<th>Source - ' && mo_merge->get_source_branch( ) &&'</th> ' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '</tr>' ). "#EC NOTEXT
|
||||||
|
ro_html->add( '</thead>' ). "#EC NOTEXT
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
ENDMETHOD. " render_table_head.
|
||||||
|
|
||||||
|
|
||||||
|
METHOD resolve_diff.
|
||||||
|
|
||||||
|
DATA: lv_offs TYPE i.
|
||||||
|
FIELD-SYMBOLS: <ls_conflict> TYPE zif_abapgit_definitions=>ty_merge_conflict.
|
||||||
|
|
||||||
|
CLEAR ms_diff_file.
|
||||||
|
|
||||||
|
READ TABLE mt_conflicts ASSIGNING <ls_conflict> INDEX mv_current_conflict_index.
|
||||||
|
IF sy-subrc NE 0.
|
||||||
|
RETURN.
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
ms_diff_file-path = <ls_conflict>-path.
|
||||||
|
ms_diff_file-filename = <ls_conflict>-filename.
|
||||||
|
ms_diff_file-type = reverse( <ls_conflict>-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 = <ls_conflict>-source_data iv_d2 = <ls_conflict>-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 = <ls_conflict>-source_data
|
||||||
|
iv_old = <ls_conflict>-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: <ls_conflict> 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 <ls_conflict> INDEX mv_current_conflict_index.
|
||||||
|
<ls_conflict>-result_sha1 = <ls_conflict>-source_sha1.
|
||||||
|
<ls_conflict>-result_data = <ls_conflict>-source_data.
|
||||||
|
mo_merge->resolve_conflict( is_conflict = <ls_conflict> ).
|
||||||
|
|
||||||
|
WHEN c_actions-apply_target.
|
||||||
|
READ TABLE mt_conflicts ASSIGNING <ls_conflict> INDEX mv_current_conflict_index.
|
||||||
|
<ls_conflict>-result_sha1 = <ls_conflict>-target_sha1.
|
||||||
|
<ls_conflict>-result_data = <ls_conflict>-target_data.
|
||||||
|
mo_merge->resolve_conflict( is_conflict = <ls_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.
|
45
src/ui/zcl_abapgit_gui_page_merge_res.clas.xml
Normal file
45
src/ui/zcl_abapgit_gui_page_merge_res.clas.xml
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
|
||||||
|
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
||||||
|
<asx:values>
|
||||||
|
<VSEOCLASS>
|
||||||
|
<CLSNAME>ZCL_ABAPGIT_GUI_PAGE_MERGE_RES</CLSNAME>
|
||||||
|
<VERSION>1</VERSION>
|
||||||
|
<LANGU>E</LANGU>
|
||||||
|
<DESCRIPT>GUI - Resolving Conflicts page</DESCRIPT>
|
||||||
|
<EXPOSURE>2</EXPOSURE>
|
||||||
|
<STATE>1</STATE>
|
||||||
|
<CLSFINAL>X</CLSFINAL>
|
||||||
|
<CLSCCINCL>X</CLSCCINCL>
|
||||||
|
<FIXPT>X</FIXPT>
|
||||||
|
<UNICODE>X</UNICODE>
|
||||||
|
</VSEOCLASS>
|
||||||
|
<DESCRIPTIONS>
|
||||||
|
<SEOCOMPOTX>
|
||||||
|
<CLSNAME>ZCL_ABAPGIT_GUI_PAGE_MERGE_RES</CLSNAME>
|
||||||
|
<CMPNAME>MO_MERGE</CMPNAME>
|
||||||
|
<LANGU>E</LANGU>
|
||||||
|
<DESCRIPT>Merge logic</DESCRIPT>
|
||||||
|
</SEOCOMPOTX>
|
||||||
|
<SEOCOMPOTX>
|
||||||
|
<CLSNAME>ZCL_ABAPGIT_GUI_PAGE_MERGE_RES</CLSNAME>
|
||||||
|
<CMPNAME>MO_MERGE_PAGE</CMPNAME>
|
||||||
|
<LANGU>E</LANGU>
|
||||||
|
<DESCRIPT>GUI - Merging page</DESCRIPT>
|
||||||
|
</SEOCOMPOTX>
|
||||||
|
<SEOCOMPOTX>
|
||||||
|
<CLSNAME>ZCL_ABAPGIT_GUI_PAGE_MERGE_RES</CLSNAME>
|
||||||
|
<CMPNAME>MO_REPO</CMPNAME>
|
||||||
|
<LANGU>E</LANGU>
|
||||||
|
<DESCRIPT>Online Repository</DESCRIPT>
|
||||||
|
</SEOCOMPOTX>
|
||||||
|
<SEOCOMPOTX>
|
||||||
|
<CLSNAME>ZCL_ABAPGIT_GUI_PAGE_MERGE_RES</CLSNAME>
|
||||||
|
<CMPNAME>MV_CURRENT_CONFLICT_INDEX</CMPNAME>
|
||||||
|
<LANGU>E</LANGU>
|
||||||
|
<DESCRIPT>Row Index of Internal Tables</DESCRIPT>
|
||||||
|
</SEOCOMPOTX>
|
||||||
|
</DESCRIPTIONS>
|
||||||
|
</asx:values>
|
||||||
|
</asx:abap>
|
||||||
|
</abapGit>
|
|
@ -1,37 +1,78 @@
|
||||||
CLASS zcl_abapgit_merge DEFINITION PUBLIC FINAL CREATE PUBLIC.
|
CLASS zcl_abapgit_merge DEFINITION
|
||||||
|
PUBLIC
|
||||||
|
FINAL
|
||||||
|
CREATE PUBLIC .
|
||||||
|
|
||||||
PUBLIC SECTION.
|
PUBLIC SECTION.
|
||||||
CLASS-METHODS:
|
|
||||||
run
|
METHODS constructor
|
||||||
IMPORTING io_repo TYPE REF TO zcl_abapgit_repo_online
|
IMPORTING
|
||||||
iv_source TYPE string
|
!io_repo TYPE REF TO zcl_abapgit_repo_online
|
||||||
iv_target TYPE string
|
!iv_source_branch TYPE string
|
||||||
RETURNING VALUE(rs_merge) TYPE zif_abapgit_definitions=>ty_merge
|
!iv_target_branch TYPE string
|
||||||
RAISING zcx_abapgit_exception.
|
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.
|
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:
|
DATA mo_repo TYPE REF TO zcl_abapgit_repo_online .
|
||||||
all_files
|
DATA ms_merge TYPE zif_abapgit_definitions=>ty_merge .
|
||||||
RETURNING VALUE(rt_files) TYPE zif_abapgit_definitions=>ty_expanded_tt,
|
DATA mt_conflicts TYPE zif_abapgit_definitions=>tt_merge_conflict .
|
||||||
calculate_result
|
DATA mt_objects TYPE zif_abapgit_definitions=>ty_objects_tt .
|
||||||
RAISING zcx_abapgit_exception,
|
DATA mv_source_branch TYPE string .
|
||||||
find_ancestors
|
DATA mv_target_branch TYPE string .
|
||||||
IMPORTING iv_commit TYPE zif_abapgit_definitions=>ty_sha1
|
|
||||||
RETURNING VALUE(rt_ancestors) TYPE ty_ancestor_tt
|
METHODS all_files
|
||||||
RAISING zcx_abapgit_exception,
|
RETURNING
|
||||||
find_first_common
|
VALUE(rt_files) TYPE zif_abapgit_definitions=>ty_expanded_tt .
|
||||||
IMPORTING it_list1 TYPE ty_ancestor_tt
|
METHODS calculate_result
|
||||||
it_list2 TYPE ty_ancestor_tt
|
RAISING
|
||||||
RETURNING VALUE(rs_common) TYPE zif_abapgit_definitions=>ty_ancestor
|
zcx_abapgit_exception .
|
||||||
RAISING zcx_abapgit_exception,
|
METHODS fetch_git
|
||||||
fetch_git
|
RETURNING
|
||||||
IMPORTING iv_source TYPE string
|
VALUE(rt_objects) TYPE zif_abapgit_definitions=>ty_objects_tt
|
||||||
iv_target TYPE string
|
RAISING
|
||||||
RAISING zcx_abapgit_exception.
|
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.
|
ENDCLASS.
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,9 +82,9 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
|
||||||
|
|
||||||
METHOD all_files.
|
METHOD all_files.
|
||||||
|
|
||||||
APPEND LINES OF gs_merge-stree TO rt_files.
|
APPEND LINES OF ms_merge-stree TO rt_files.
|
||||||
APPEND LINES OF gs_merge-ttree TO rt_files.
|
APPEND LINES OF ms_merge-ttree TO rt_files.
|
||||||
APPEND LINES OF gs_merge-ctree TO rt_files.
|
APPEND LINES OF ms_merge-ctree TO rt_files.
|
||||||
SORT rt_files BY path DESCENDING name ASCENDING.
|
SORT rt_files BY path DESCENDING name ASCENDING.
|
||||||
DELETE ADJACENT DUPLICATES FROM rt_files COMPARING path name.
|
DELETE ADJACENT DUPLICATES FROM rt_files COMPARING path name.
|
||||||
|
|
||||||
|
@ -53,12 +94,12 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
|
||||||
METHOD calculate_result.
|
METHOD calculate_result.
|
||||||
|
|
||||||
DEFINE _from_source.
|
DEFINE _from_source.
|
||||||
READ TABLE gt_objects ASSIGNING <ls_object>
|
READ TABLE mt_objects ASSIGNING <ls_object>
|
||||||
WITH KEY type = zif_abapgit_definitions=>gc_type-blob
|
WITH KEY type = zif_abapgit_definitions=>gc_type-blob
|
||||||
sha1 = <ls_source>-sha1.
|
sha1 = <ls_source>-sha1.
|
||||||
ASSERT sy-subrc = 0.
|
ASSERT sy-subrc = 0.
|
||||||
|
|
||||||
gs_merge-stage->add( iv_path = <ls_file>-path
|
ms_merge-stage->add( iv_path = <ls_file>-path
|
||||||
iv_filename = <ls_file>-name
|
iv_filename = <ls_file>-name
|
||||||
iv_data = <ls_object>-data ).
|
iv_data = <ls_object>-data ).
|
||||||
END-OF-DEFINITION.
|
END-OF-DEFINITION.
|
||||||
|
@ -72,17 +113,17 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
|
||||||
<ls_target> LIKE LINE OF lt_files,
|
<ls_target> LIKE LINE OF lt_files,
|
||||||
<ls_common> LIKE LINE OF lt_files,
|
<ls_common> LIKE LINE OF lt_files,
|
||||||
<ls_file> LIKE LINE OF lt_files,
|
<ls_file> LIKE LINE OF lt_files,
|
||||||
<ls_result> LIKE LINE OF gs_merge-result,
|
<ls_result> LIKE LINE OF ms_merge-result,
|
||||||
<ls_object> LIKE LINE OF gt_objects.
|
<ls_object> LIKE LINE OF mt_objects,
|
||||||
|
<ls_conflict> LIKE LINE OF mt_conflicts.
|
||||||
|
|
||||||
lt_files = all_files( ).
|
lt_files = all_files( ).
|
||||||
|
|
||||||
CREATE OBJECT gs_merge-stage
|
CREATE OBJECT ms_merge-stage
|
||||||
EXPORTING
|
EXPORTING
|
||||||
iv_branch_name = gs_merge-target-name
|
iv_branch_name = ms_merge-target-name
|
||||||
iv_branch_sha1 = gs_merge-target-sha1
|
iv_branch_sha1 = ms_merge-target-sha1
|
||||||
iv_merge_source = gs_merge-source-sha1.
|
iv_merge_source = ms_merge-source-sha1.
|
||||||
|
|
||||||
LOOP AT lt_files ASSIGNING <ls_file>.
|
LOOP AT lt_files ASSIGNING <ls_file>.
|
||||||
|
|
||||||
|
@ -90,11 +131,11 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
|
||||||
UNASSIGN <ls_target>.
|
UNASSIGN <ls_target>.
|
||||||
UNASSIGN <ls_common>.
|
UNASSIGN <ls_common>.
|
||||||
|
|
||||||
READ TABLE gs_merge-stree ASSIGNING <ls_source>
|
READ TABLE ms_merge-stree ASSIGNING <ls_source>
|
||||||
WITH KEY path = <ls_file>-path name = <ls_file>-name. "#EC CI_SUBRC
|
WITH KEY path = <ls_file>-path name = <ls_file>-name. "#EC CI_SUBRC
|
||||||
READ TABLE gs_merge-ttree ASSIGNING <ls_target>
|
READ TABLE ms_merge-ttree ASSIGNING <ls_target>
|
||||||
WITH KEY path = <ls_file>-path name = <ls_file>-name. "#EC CI_SUBRC
|
WITH KEY path = <ls_file>-path name = <ls_file>-name. "#EC CI_SUBRC
|
||||||
READ TABLE gs_merge-ctree ASSIGNING <ls_common>
|
READ TABLE ms_merge-ctree ASSIGNING <ls_common>
|
||||||
WITH KEY path = <ls_file>-path name = <ls_file>-name. "#EC CI_SUBRC
|
WITH KEY path = <ls_file>-path name = <ls_file>-name. "#EC CI_SUBRC
|
||||||
|
|
||||||
lv_found_source = boolc( <ls_source> IS ASSIGNED ).
|
lv_found_source = boolc( <ls_source> IS ASSIGNED ).
|
||||||
|
@ -109,7 +150,7 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
|
||||||
AND lv_found_common = abap_true
|
AND lv_found_common = abap_true
|
||||||
AND <ls_target>-sha1 = <ls_common>-sha1.
|
AND <ls_target>-sha1 = <ls_common>-sha1.
|
||||||
* deleted in source, skip
|
* deleted in source, skip
|
||||||
gs_merge-stage->rm( iv_path = <ls_file>-path
|
ms_merge-stage->rm( iv_path = <ls_file>-path
|
||||||
iv_filename = <ls_file>-name ).
|
iv_filename = <ls_file>-name ).
|
||||||
CONTINUE.
|
CONTINUE.
|
||||||
ELSEIF lv_found_target = abap_false
|
ELSEIF lv_found_target = abap_false
|
||||||
|
@ -119,7 +160,7 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
|
||||||
CONTINUE.
|
CONTINUE.
|
||||||
ENDIF.
|
ENDIF.
|
||||||
|
|
||||||
APPEND INITIAL LINE TO gs_merge-result ASSIGNING <ls_result>.
|
APPEND INITIAL LINE TO ms_merge-result ASSIGNING <ls_result>.
|
||||||
<ls_result>-path = <ls_file>-path.
|
<ls_result>-path = <ls_file>-path.
|
||||||
<ls_result>-name = <ls_file>-name.
|
<ls_result>-name = <ls_file>-name.
|
||||||
|
|
||||||
|
@ -135,15 +176,32 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
|
||||||
AND <ls_target>-sha1 = <ls_source>-sha1.
|
AND <ls_target>-sha1 = <ls_source>-sha1.
|
||||||
* added in source and target
|
* added in source and target
|
||||||
<ls_result>-sha1 = <ls_source>-sha1.
|
<ls_result>-sha1 = <ls_source>-sha1.
|
||||||
|
ELSEIF lv_found_common = abap_false
|
||||||
|
AND <ls_target>-sha1 <> <ls_source>-sha1.
|
||||||
|
|
||||||
|
INSERT INITIAL LINE INTO TABLE mt_conflicts ASSIGNING <ls_conflict>.
|
||||||
|
<ls_conflict>-path = <ls_file>-path.
|
||||||
|
<ls_conflict>-filename = <ls_file>-name.
|
||||||
|
<ls_conflict>-source_sha1 = <ls_source>-sha1.
|
||||||
|
READ TABLE mt_objects ASSIGNING <ls_object> WITH KEY type = zif_abapgit_definitions=>gc_type-blob
|
||||||
|
sha1 = <ls_source>-sha1.
|
||||||
|
<ls_conflict>-source_data = <ls_object>-data.
|
||||||
|
|
||||||
|
<ls_conflict>-target_sha1 = <ls_target>-sha1.
|
||||||
|
READ TABLE mt_objects ASSIGNING <ls_object> WITH KEY type = zif_abapgit_definitions=>gc_type-blob
|
||||||
|
sha1 = <ls_target>-sha1.
|
||||||
|
<ls_conflict>-target_data = <ls_object>-data.
|
||||||
|
|
||||||
|
* added in source and target, but different, merge conflict must be resolved
|
||||||
|
ms_merge-conflict = |{ <ls_file>-name } merge conflict|.
|
||||||
|
CONTINUE.
|
||||||
ENDIF.
|
ENDIF.
|
||||||
|
|
||||||
IF lv_found_source = abap_false
|
IF lv_found_source = abap_false
|
||||||
OR lv_found_target = abap_false
|
OR lv_found_target = abap_false
|
||||||
OR lv_found_common = abap_false.
|
OR lv_found_common = abap_false.
|
||||||
CLEAR gs_merge-result.
|
ms_merge-conflict = |{ <ls_file>-name } merge conflict, not found anywhere|.
|
||||||
gs_merge-conflict = |{ <ls_file>-name
|
CONTINUE.
|
||||||
} merge conflict, not found anywhere|.
|
|
||||||
RETURN.
|
|
||||||
ENDIF.
|
ENDIF.
|
||||||
|
|
||||||
IF <ls_target>-sha1 = <ls_source>-sha1.
|
IF <ls_target>-sha1 = <ls_source>-sha1.
|
||||||
|
@ -158,13 +216,36 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
|
||||||
<ls_result>-sha1 = <ls_target>-sha1.
|
<ls_result>-sha1 = <ls_target>-sha1.
|
||||||
ELSE.
|
ELSE.
|
||||||
* changed in source and target, conflict
|
* changed in source and target, conflict
|
||||||
CLEAR gs_merge-result.
|
* conflict must be resolved before merge
|
||||||
gs_merge-conflict = |{ <ls_file>-name
|
INSERT INITIAL LINE INTO TABLE mt_conflicts ASSIGNING <ls_conflict>.
|
||||||
} merge conflict, changed in source and target branch|.
|
<ls_conflict>-path = <ls_file>-path.
|
||||||
RETURN.
|
<ls_conflict>-filename = <ls_file>-name.
|
||||||
|
<ls_conflict>-source_sha1 = <ls_source>-sha1.
|
||||||
|
READ TABLE mt_objects ASSIGNING <ls_object> WITH KEY type = zif_abapgit_definitions=>gc_type-blob
|
||||||
|
sha1 = <ls_source>-sha1.
|
||||||
|
<ls_conflict>-source_data = <ls_object>-data.
|
||||||
|
|
||||||
|
<ls_conflict>-target_sha1 = <ls_target>-sha1.
|
||||||
|
READ TABLE mt_objects ASSIGNING <ls_object> WITH KEY type = zif_abapgit_definitions=>gc_type-blob
|
||||||
|
sha1 = <ls_target>-sha1.
|
||||||
|
<ls_conflict>-target_data = <ls_object>-data.
|
||||||
|
|
||||||
|
ms_merge-conflict = |{ <ls_file>-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.
|
ENDIF.
|
||||||
|
|
||||||
ENDLOOP.
|
mo_repo = io_repo.
|
||||||
|
mv_source_branch = iv_source_branch.
|
||||||
|
mv_target_branch = iv_target_branch.
|
||||||
|
|
||||||
ENDMETHOD.
|
ENDMETHOD.
|
||||||
|
|
||||||
|
@ -174,24 +255,23 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
|
||||||
DATA: lo_branch_list TYPE REF TO zcl_abapgit_git_branch_list,
|
DATA: lo_branch_list TYPE REF TO zcl_abapgit_git_branch_list,
|
||||||
lt_upload TYPE zif_abapgit_definitions=>ty_git_branch_list_tt.
|
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( ) ).
|
APPEND ms_merge-source TO lt_upload.
|
||||||
gs_merge-source = lo_branch_list->find_by_name(
|
APPEND ms_merge-target TO lt_upload.
|
||||||
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.
|
|
||||||
|
|
||||||
zcl_abapgit_git_transport=>upload_pack(
|
zcl_abapgit_git_transport=>upload_pack(
|
||||||
EXPORTING
|
EXPORTING
|
||||||
iv_url = gs_merge-repo->get_url( )
|
iv_url = ms_merge-repo->get_url( )
|
||||||
iv_branch_name = gs_merge-repo->get_branch_name( )
|
iv_branch_name = ms_merge-repo->get_branch_name( )
|
||||||
iv_deepen = abap_false
|
iv_deepen = abap_false
|
||||||
it_branches = lt_upload
|
it_branches = lt_upload
|
||||||
IMPORTING
|
IMPORTING
|
||||||
et_objects = gt_objects ).
|
et_objects = rt_objects ).
|
||||||
|
|
||||||
ENDMETHOD.
|
ENDMETHOD.
|
||||||
|
|
||||||
|
@ -212,13 +292,13 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
|
||||||
lv_commit LIKE LINE OF lt_visit.
|
lv_commit LIKE LINE OF lt_visit.
|
||||||
|
|
||||||
FIELD-SYMBOLS: <ls_ancestor> LIKE LINE OF rt_ancestors,
|
FIELD-SYMBOLS: <ls_ancestor> LIKE LINE OF rt_ancestors,
|
||||||
<ls_object> LIKE LINE OF gt_objects.
|
<ls_object> LIKE LINE OF mt_objects.
|
||||||
|
|
||||||
|
|
||||||
APPEND iv_commit TO lt_visit.
|
APPEND iv_commit TO lt_visit.
|
||||||
|
|
||||||
LOOP AT lt_visit INTO lv_commit.
|
LOOP AT lt_visit INTO lv_commit.
|
||||||
READ TABLE gt_objects ASSIGNING <ls_object>
|
READ TABLE mt_objects ASSIGNING <ls_object>
|
||||||
WITH KEY type = zif_abapgit_definitions=>gc_type-commit sha1 = lv_commit.
|
WITH KEY type = zif_abapgit_definitions=>gc_type-commit sha1 = lv_commit.
|
||||||
ASSERT sy-subrc = 0.
|
ASSERT sy-subrc = 0.
|
||||||
|
|
||||||
|
@ -231,9 +311,11 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
|
||||||
<ls_ancestor>-commit = lv_commit.
|
<ls_ancestor>-commit = lv_commit.
|
||||||
<ls_ancestor>-tree = ls_commit-tree.
|
<ls_ancestor>-tree = ls_commit-tree.
|
||||||
<ls_ancestor>-body = ls_commit-body.
|
<ls_ancestor>-body = ls_commit-body.
|
||||||
FIND REGEX zif_abapgit_definitions=>gc_author_regex IN ls_commit-author
|
<ls_ancestor>-time = ls_commit-author.
|
||||||
SUBMATCHES <ls_ancestor>-time ##NO_TEXT.
|
|
||||||
ASSERT sy-subrc = 0.
|
"Strip Author entry of all but the time component
|
||||||
|
REPLACE ALL OCCURRENCES OF REGEX '[a-zA-Z<>@.-]*' IN <ls_ancestor>-time WITH ''.
|
||||||
|
CONDENSE <ls_ancestor>-time.
|
||||||
ENDLOOP.
|
ENDLOOP.
|
||||||
|
|
||||||
SORT rt_ancestors BY time DESCENDING.
|
SORT rt_ancestors BY time DESCENDING.
|
||||||
|
@ -246,7 +328,6 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
|
||||||
FIELD-SYMBOLS: <ls_list1> LIKE LINE OF it_list1,
|
FIELD-SYMBOLS: <ls_list1> LIKE LINE OF it_list1,
|
||||||
<ls_list2> LIKE LINE OF it_list2.
|
<ls_list2> LIKE LINE OF it_list2.
|
||||||
|
|
||||||
|
|
||||||
LOOP AT it_list1 ASSIGNING <ls_list1>.
|
LOOP AT it_list1 ASSIGNING <ls_list1>.
|
||||||
LOOP AT it_list2 ASSIGNING <ls_list2>.
|
LOOP AT it_list2 ASSIGNING <ls_list2>.
|
||||||
IF <ls_list1>-tree = <ls_list2>-tree.
|
IF <ls_list1>-tree = <ls_list2>-tree.
|
||||||
|
@ -261,42 +342,107 @@ CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
|
||||||
ENDMETHOD.
|
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: <ls_conflict> TYPE zif_abapgit_definitions=>ty_merge_conflict,
|
||||||
|
<ls_result> 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 <ls_conflict> WITH KEY path = is_conflict-path
|
||||||
|
filename = is_conflict-filename.
|
||||||
|
IF sy-subrc EQ 0.
|
||||||
|
READ TABLE ms_merge-result ASSIGNING <ls_result> WITH KEY path = is_conflict-path
|
||||||
|
name = is_conflict-filename.
|
||||||
|
IF sy-subrc EQ 0.
|
||||||
|
<ls_result>-sha1 = is_conflict-result_sha1.
|
||||||
|
|
||||||
|
ms_merge-stage->add( iv_path = <ls_conflict>-path
|
||||||
|
iv_filename = <ls_conflict>-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 <ls_result> WITH KEY sha1 = space.
|
||||||
|
IF sy-subrc EQ 0.
|
||||||
|
ms_merge-conflict = |{ <ls_result>-name } merge conflict, changed in source and target branch|.
|
||||||
|
ELSE.
|
||||||
|
CLEAR ms_merge-conflict.
|
||||||
|
ENDIF.
|
||||||
|
ENDIF.
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
ENDMETHOD.
|
||||||
|
|
||||||
|
|
||||||
METHOD run.
|
METHOD run.
|
||||||
|
|
||||||
DATA: lt_asource TYPE ty_ancestor_tt,
|
DATA: lt_asource TYPE ty_ancestor_tt,
|
||||||
lt_atarget TYPE ty_ancestor_tt.
|
lt_atarget TYPE ty_ancestor_tt.
|
||||||
|
|
||||||
|
CLEAR: ms_merge, mt_objects, mt_conflicts.
|
||||||
|
|
||||||
IF iv_source = iv_target.
|
ms_merge-repo = mo_repo.
|
||||||
zcx_abapgit_exception=>raise( 'source = target' ).
|
mt_objects = fetch_git( ).
|
||||||
ENDIF.
|
|
||||||
|
|
||||||
CLEAR gs_merge.
|
lt_asource = find_ancestors( ms_merge-source-sha1 ).
|
||||||
|
lt_atarget = find_ancestors( ms_merge-target-sha1 ).
|
||||||
|
|
||||||
gs_merge-repo = io_repo.
|
ms_merge-common = find_first_common( it_list1 = lt_asource
|
||||||
|
|
||||||
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
|
|
||||||
it_list2 = lt_atarget ).
|
it_list2 = lt_atarget ).
|
||||||
|
|
||||||
gs_merge-stree = zcl_abapgit_git_porcelain=>full_tree(
|
ms_merge-stree = zcl_abapgit_git_porcelain=>full_tree(
|
||||||
it_objects = gt_objects
|
it_objects = mt_objects
|
||||||
iv_branch = gs_merge-source-sha1 ).
|
iv_branch = ms_merge-source-sha1 ).
|
||||||
gs_merge-ttree = zcl_abapgit_git_porcelain=>full_tree(
|
ms_merge-ttree = zcl_abapgit_git_porcelain=>full_tree(
|
||||||
it_objects = gt_objects
|
it_objects = mt_objects
|
||||||
iv_branch = gs_merge-target-sha1 ).
|
iv_branch = ms_merge-target-sha1 ).
|
||||||
gs_merge-ctree = zcl_abapgit_git_porcelain=>full_tree(
|
ms_merge-ctree = zcl_abapgit_git_porcelain=>full_tree(
|
||||||
it_objects = gt_objects
|
it_objects = mt_objects
|
||||||
iv_branch = gs_merge-common-commit ).
|
iv_branch = ms_merge-common-commit ).
|
||||||
|
|
||||||
calculate_result( ).
|
calculate_result( ).
|
||||||
|
|
||||||
rs_merge = gs_merge.
|
|
||||||
|
|
||||||
ENDMETHOD.
|
ENDMETHOD.
|
||||||
ENDCLASS.
|
ENDCLASS.
|
||||||
|
|
|
@ -14,6 +14,20 @@
|
||||||
<FIXPT>X</FIXPT>
|
<FIXPT>X</FIXPT>
|
||||||
<UNICODE>X</UNICODE>
|
<UNICODE>X</UNICODE>
|
||||||
</VSEOCLASS>
|
</VSEOCLASS>
|
||||||
|
<DESCRIPTIONS>
|
||||||
|
<SEOCOMPOTX>
|
||||||
|
<CLSNAME>ZCL_ABAPGIT_MERGE</CLSNAME>
|
||||||
|
<CMPNAME>CONSTRUCTOR</CMPNAME>
|
||||||
|
<LANGU>E</LANGU>
|
||||||
|
<DESCRIPT>CONSTRUCTOR</DESCRIPT>
|
||||||
|
</SEOCOMPOTX>
|
||||||
|
<SEOCOMPOTX>
|
||||||
|
<CLSNAME>ZCL_ABAPGIT_MERGE</CLSNAME>
|
||||||
|
<CMPNAME>MO_REPO</CMPNAME>
|
||||||
|
<LANGU>E</LANGU>
|
||||||
|
<DESCRIPT>Online Repository</DESCRIPT>
|
||||||
|
</SEOCOMPOTX>
|
||||||
|
</DESCRIPTIONS>
|
||||||
</asx:values>
|
</asx:values>
|
||||||
</asx:abap>
|
</asx:abap>
|
||||||
</abapGit>
|
</abapGit>
|
||||||
|
|
|
@ -272,6 +272,18 @@ INTERFACE zif_abapgit_definitions PUBLIC.
|
||||||
conflict TYPE string,
|
conflict TYPE string,
|
||||||
END OF ty_merge.
|
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,
|
TYPES: BEGIN OF ty_repo_item,
|
||||||
obj_type TYPE tadir-object,
|
obj_type TYPE tadir-object,
|
||||||
obj_name TYPE tadir-obj_name,
|
obj_name TYPE tadir-obj_name,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user