Skip to Content
Technical Articles
Author's profile photo Enno Wulff

Data exchange with your github repository using abapGit

For a project idea I wanted to send plain text files to my github repository. With the help of Lars Hvam I managed to write a little program to download, change and upload a text file to github, namely an asciidoc file (extension .adoc).

Lars told me about an old report of him to transfer code inspector variants that needed some adaptions.

Report

In the first step I build a report where I could upload a raw file into my test repository. As I wanted to know a bit more about the abapgit mechanisms I build a small application to load single files and update or even create them.

Repository key

The abapGit repositories have a sequential numbering that can only be seen in table ZABAPGIT. But the information about the underlying repository is serialized and therefore hard to identify.

For proper usage I created two search helps:

  • Search help for abapGit repositories
  • Search help for files of selected repository

Selecting repositories

The repository list can be retrieved by one simple line of code:

DATA(lt_list) = zcl_abapgit_persist_factory=>get_repo( )->list( ).

Some useful data will be transferred to the search help result via a search help exit function module:

The files structure is divided in a main part and an embedded structure with local settings.

I first transferred the fields of the directory to the result list using function module F4UT_PARAMETER_RESULTS_PUT. Unfortunately this didn’t work for fields of the embedded structure local_settings. So I transferred the data into a local table that fits the fields of the search help and directly copied them.

Selecting a file from the repository

Once you know the internal key of the repository you can load the files of that repository:

DATA(lo_online) = CAST zcl_abapgit_repo_online( 
  zcl_abapgit_repo_srv=>get_instance( )->get( my_repokey ) ).
DATA(lt_files) = lo_online->get_files_remote( ).

In the follwing screenshot you can see the search help for the selected repository:

 

Get data from github

The main coding to get files from github consists of two lines of code:

DATA(lo_online) = CAST zcl_abapgit_repo_online( 
                    zcl_abapgit_repo_srv=>get_instance( )->get( p_repo ) ).
DATA(lt_files) = lo_online->get_files_remote( ).

No user or password iis needed for this action.

Put data to github

Updating data into github is a bit more complex and I do not understand every detail of it, but it works.

One important detail I didn’t find out exactly is how to get the id of the parent parameter of the push command. Maybe someone can help here?

DATA(lo_online) = CAST zcl_abapgit_repo_online( 
  zcl_abapgit_repo_srv=>get_instance( )->get( p_repo ) ).

DATA(lt_files) = lo_online->get_files_remote( ).
DATA(lv_data) = zcl_abapgit_convert=>string_to_xstring_utf8( lv_adoc ).
DATA(lv_filename) = |{ file }|.
READ TABLE lt_files WITH KEY filename = lv_filename data = lv_data TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
  DATA(ls_comment) = VALUE zif_abapgit_definitions=>ty_comment(
    committer-name  = sy-uname
    committer-email = |{ sy-uname }@localhost|
    comment         = 'Updated' ).
ELSE.
  ls_comment = VALUE zif_abapgit_definitions=>ty_comment(
    committer-name  = sy-uname
    committer-email = |{ sy-uname }@localhost|
    comment         = 'Created' ).
ENDIF.

DATA(lo_stage) = NEW zcl_abapgit_stage(
  iv_merge_source = lo_online->get_current_remote( ) ).

lo_stage->add(
  iv_path     = conv #( path )
  iv_filename = lv_filename
  iv_data     = lv_data ).

DATA(lt_objects) = lo_online->get_objects( ).
DATA(lv_parent)  = lt_objects[ type = 'commit' ]-sha1.

zcl_abapgit_git_porcelain=>push(
  EXPORTING
    is_comment     = ls_comment
    io_stage       = lo_stage
    it_old_objects = lt_objects
    iv_parent      = lv_parent
    iv_url         = lo_online->get_url( )
    iv_branch_name = lo_online->get_selected_branch( ) ).

 

Old Dynpro stuff

to get the help value requests work properly I had to do some things that I didn’t to for many years: reading and updating field values of the dynpro and within the search help interface. This coding uses a lot of coding space.

In a normal project I would have defined a proper structure and set the search helps to the appropriate fields, what means much less coding.

Adding and changing files

Using the CL_GUI_TEXTEDIT control I am now capable of loading an existing file from my repository, change it and write it back. I can also create new files including new directories.

In this example I created a new file:

And this is the proof that it exists within my repository:

Conclusion

thanks to this great community and the wonderful work of all abapgit contributors the transfer of other files than repository data is easy and reliable. Thanks to all!

My proof of concept files can be found at github of course.

 

Have fun!

~Enno

Assigned tags

      8 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Andrea Borgia
      Andrea Borgia

      Ahah, nice, I guess once you can write to GH, you're off to the races 🙂

      I had a quick test using the development version of abapGit and I get this error:

      activation%20error

      activation error

       

      FWIW I'm using AS ABAP 7.52 SP04; I haven't had a closer look at the error, just checking out cool stuff from dotAbap. If the error above is not a glitch and you'd like a proper bugreport, I can file an issue in GH, as you like.

       

      Author's profile photo Enno Wulff
      Enno Wulff
      Blog Post Author

      Hey Andrea Borgia ! thanks for your comment. The exceptions come from an old repository of Lars Hvam that I used as template. I corrected it.

       

      Author's profile photo Andrea Borgia
      Andrea Borgia

      Another small change:

       

      Author's profile photo Enno Wulff
      Enno Wulff
      Blog Post Author

      Thanks Andrea Borgia ! I had an old version of abapGit... corrected.

      Author's profile photo Christian Guenter
      Christian Guenter

      Hi Enno,

       

      nice stuff as always ?

      You don’t need the porcellain push. Just do a

            lo_online->push(
                is_comment = ls_comment
                io_stage   = lo_stage ).
      

      instead and abapGit will take care of parent determination. Porcellain is the low level/internal API of abapGit (same principle as in git) which usually needn’t to be invoked directly.

      Christian

      Author's profile photo Enno Wulff
      Enno Wulff
      Blog Post Author

      Thanks Christian Guenter for your comment! Works perfectly...!

      Author's profile photo Christian Guenter
      Christian Guenter

      Btw. your program works also with other git hosting platforms like gitlab, bitbucket, ect. It isn’t restricted to github as the title and parameter labels might suggest ?

      Author's profile photo Enno Wulff
      Enno Wulff
      Blog Post Author

      Hey Christian Guenter ! that's right! thanks for clarifying. I chose the most common platform. Otherwise the title would have been to long... 🙂