abapGit XML Metadata — XML-Only Objects (TABL, STRU, DTEL, TTYP, DOMA, MSAG, SUSO, PINF)
XML templates for ABAP Dictionary objects that have no .abap source file — TABL, STRU, DTEL, TTYP, DOMA, message classes (MSAG), authorization objects (SUSO), and package interfaces (PINF).
CRITICAL: Always write XML files with a UTF-8 BOM (
\ufeff) as the very first character, before<?xml .... Without the BOM, abapGit shows the object as “M” (modified) after every pull.
CRITICAL: Only include fields that abapGit’s serializer actually writes. Never add fields with default values. Extra fields cause a permanent “M” (modified) diff.
For CLAS, INTF, PROG, DDLS, DCLS, FUGR (have source files): see
abapgit-agent ref --topic abapgitFor DDLS, DCLS (CDS — have source files): also seeabapgit-agent ref --topic abapgit
Searchable keywords: table xml, structure xml, data element xml, table type xml, domain xml, message class xml, tabl, stru, dtel, ttyp, doma, msag, suso, authorization object, dictionary, pinf, package interface
Table (TABL)
Filename: src/zmy_table.tabl.xml
Pull with:
pull --files src/zmy_table.tabl.xml
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_TABL" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DD02V>
<TABNAME>ZMY_TABLE</TABNAME>
<DDLANGUAGE>E</DDLANGUAGE>
<TABCLASS>TRANSP</TABCLASS>
<DDTEXT>Description of the table</DDTEXT>
<CONTFLAG>A</CONTFLAG>
</DD02V>
</asx:values>
</asx:abap>
</abapGit>
Key Fields:
TABNAME: Table nameDDTEXT: Description (notDESCRIPT)TABCLASS:TRANSP=Transparent (most common),POOL,CLUSTERCONTFLAG: Delivery class —A=Application,C=Customizing,S=System,G=Customizing protected
Note: When abapGit serializes a table it also writes <DD09L> (technical settings) and <DD03P_TABLE> (field definitions). You only need the <DD02V> header when creating a new table; the rest is generated on pull.
DD03P field-level rules (apply when editing an existing table XML that includes <DD03P_TABLE>): include <SHLPORIGIN>D</SHLPORIGIN> on fields where the Dictionary provides value help (domain with fixed values or search help); omit otherwise. For raw-type fields (no ROLLNAME, e.g. CHAR, NUMC), the serializer writes <MASK> before <DDTEXT>. For fields with a ROLLNAME, only ROLLNAME appears. Wrong order or missing SHLPORIGIN causes a permanent diff.
Text Tables and Foreign Keys
A text table stores translatable texts for another table (the “main table”). It shares the same key fields plus a language field (SPRAS/LANGU).
Recognition markers: <DD09L><UEBERSETZ>X</UEBERSETZ> (text table) and <DD08V><FRKART>TEXT</FRKART> (text-table FK). Three required sections: DD03P_TABLE (fields), DD05M_TABLE (FK field mappings — one per main-table key, all anchored to MANDT), DD08V_TABLE (FK relationship).
Example — text table ZMY_TABLE_T for main table ZMY_TABLE (keys: MANDT, ID1, ID2):
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_TABL" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DD02V>
<TABNAME>ZMY_TABLE_T</TABNAME>
<DDLANGUAGE>E</DDLANGUAGE>
<TABCLASS>TRANSP</TABCLASS>
<CLIDEP>X</CLIDEP>
<DDTEXT>My Table: Texts</DDTEXT>
<CONTFLAG>C</CONTFLAG>
</DD02V>
<DD09L>
<TABNAME>ZMY_TABLE_T</TABNAME>
<AS4LOCAL>A</AS4LOCAL>
<TABKAT>0</TABKAT>
<TABART>APPL0</TABART>
<UEBERSETZ>X</UEBERSETZ>
<BUFALLOW>N</BUFALLOW>
</DD09L>
<DD03P_TABLE>
<DD03P>
<FIELDNAME>MANDT</FIELDNAME>
<KEYFLAG>X</KEYFLAG>
<ROLLNAME>MANDT</ROLLNAME>
<CHECKTABLE>ZMY_TABLE</CHECKTABLE>
<ADMINFIELD>0</ADMINFIELD>
<NOTNULL>X</NOTNULL>
<SHLPORIGIN>P</SHLPORIGIN>
<COMPTYPE>E</COMPTYPE>
</DD03P>
<DD03P>
<FIELDNAME>ID1</FIELDNAME>
<KEYFLAG>X</KEYFLAG>
<ROLLNAME>ZMY_ID1</ROLLNAME>
<ADMINFIELD>0</ADMINFIELD>
<NOTNULL>X</NOTNULL>
<COMPTYPE>E</COMPTYPE>
</DD03P>
<DD03P>
<FIELDNAME>SPRAS</FIELDNAME>
<KEYFLAG>X</KEYFLAG>
<ROLLNAME>SPRAS</ROLLNAME>
<ADMINFIELD>0</ADMINFIELD>
<NOTNULL>X</NOTNULL>
<COMPTYPE>E</COMPTYPE>
</DD03P>
<DD03P>
<FIELDNAME>DESCRIPTION</FIELDNAME>
<ROLLNAME>ZMY_DESCRIPTION</ROLLNAME>
<ADMINFIELD>0</ADMINFIELD>
<COMPTYPE>E</COMPTYPE>
</DD03P>
</DD03P_TABLE>
<DD05M_TABLE>
<DD05M>
<FIELDNAME>MANDT</FIELDNAME>
<FORTABLE>ZMY_TABLE_T</FORTABLE>
<FORKEY>MANDT</FORKEY>
<CHECKTABLE>ZMY_TABLE</CHECKTABLE>
<CHECKFIELD>MANDT</CHECKFIELD>
<PRIMPOS>0001</PRIMPOS>
<DOMNAME>MANDT</DOMNAME>
<DATATYPE>CLNT</DATATYPE>
</DD05M>
<DD05M>
<FIELDNAME>MANDT</FIELDNAME>
<FORTABLE>ZMY_TABLE_T</FORTABLE>
<FORKEY>ID1</FORKEY>
<CHECKTABLE>ZMY_TABLE</CHECKTABLE>
<CHECKFIELD>ID1</CHECKFIELD>
<PRIMPOS>0002</PRIMPOS>
<DATATYPE>CHAR</DATATYPE>
</DD05M>
<!-- repeat for each remaining key field (ID2, etc.) -->
</DD05M_TABLE>
<DD08V_TABLE>
<DD08V>
<FIELDNAME>MANDT</FIELDNAME>
<CHECKTABLE>ZMY_TABLE</CHECKTABLE>
<FRKART>TEXT</FRKART>
<CARD>CN</CARD>
<CARDLEFT>1</CARDLEFT>
</DD08V>
</DD08V_TABLE>
</asx:values>
</asx:abap>
</abapGit>
Key rules:
- Always activate the main table before the text table — foreign key check requires the main table to exist
- Language field can be
SPRAS(data elementSPRAS) orLANGU(data elementLANGU) - For an ordinary foreign key: same structure, but omit
<FRKART>TEXT</FRKART>fromDD08V
Data Element (DTEL)
Filename: src/zmy_dtel.dtel.xml
Pull with:
pull --files src/zmy_dtel.dtel.xml
Two variants — choose based on whether the DTEL defines its own type or references a domain:
Variant 1: Built-in type (no domain)
Use when the data element directly defines DATATYPE and LENG without referencing a domain.
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DTEL" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DD04V>
<ROLLNAME>ZMY_DTEL</ROLLNAME>
<DDLANGUAGE>E</DDLANGUAGE>
<DDTEXT>Description of data element</DDTEXT>
<REPTEXT>Description</REPTEXT>
<SCRTEXT_S>Short text</SCRTEXT_S>
<SCRTEXT_M>Medium text</SCRTEXT_M>
<SCRTEXT_L>Long description text</SCRTEXT_L>
<DTELMASTER>E</DTELMASTER>
<DATATYPE>CHAR</DATATYPE>
<LENG>000010</LENG>
</DD04V>
</asx:values>
</asx:abap>
</abapGit>
Variant 2: Domain reference
Use when the data element’s type and length come from an existing domain (DOMNAME). Do not include DATATYPE or LENG — the domain owns those.
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DTEL" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DD04V>
<ROLLNAME>ZMY_DTEL</ROLLNAME>
<DDLANGUAGE>E</DDLANGUAGE>
<DDTEXT>Description of data element</DDTEXT>
<REPTEXT>Description</REPTEXT>
<SCRTEXT_S>Short text</SCRTEXT_S>
<SCRTEXT_M>Medium text</SCRTEXT_M>
<SCRTEXT_L>Long description text</SCRTEXT_L>
<DTELMASTER>E</DTELMASTER>
<DOMNAME>ZMY_DOMAIN</DOMNAME>
</DD04V>
</asx:values>
</asx:abap>
</abapGit>
Key Fields:
ROLLNAME: Data element nameDDTEXT: Description (notDESCRIPT)REPTEXT/SCRTEXT_S/SCRTEXT_M/SCRTEXT_L: Field labels (report heading, short, medium, long)DTELMASTER: Language key for label master (Efor English)DATATYPE+LENG: Use for built-in type variant only (e.g.CHAR+000010)DOMNAME: Use for domain-reference variant only — omitDATATYPEandLENGentirely
Omit <PARAMID> unless you specifically need a SET/GET parameter ID — the serializer omits it when empty.
⚠️ SCRLEN vs SCRTEXT lengths: if you include explicit
<SCRLEN1>/<SCRLEN2>/<SCRLEN3>tags, every corresponding<SCRTEXT_S>/<SCRTEXT_M>/<SCRTEXT_L>value MUST fit within its declared SCRLEN. Otherwise DDIC’sDD_MASS_ACT_C3silently cancels activation (rc>4) with no error log.pullwill surface this as a structureddtel_label_too_longviolation; the local pre-flight also catches it before the HTTP round trip. Either shorten the label or raise the SCRLEN value. If you omit the SCRLEN tags entirely, DDIC auto-sizes from the supplied SCRTEXTs — no constraint to violate.
Structure (STRU)
Filename: src/zmy_struct.tabl.xml
⚠️ Use
.tabl.xmlextension, NOT.stru.xml— abapGit serializes structures with the TABL serializer and registers them as object typeTABL. A.stru.xmlfilename causes “Step DDIC is only for DDIC objects” because abapGit treats it as object typeSTRU, which is not in its DDIC activation list.Pull with:
pull --files src/zmy_struct.tabl.xml
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_TABL" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DD02V>
<TABNAME>ZMY_STRUCT</TABNAME>
<DDLANGUAGE>E</DDLANGUAGE>
<TABCLASS>INTTAB</TABCLASS>
<DDTEXT>Description of the structure</DDTEXT>
<EXCLASS>1</EXCLASS>
</DD02V>
<DD03P_TABLE>
<DD03P>
<FIELDNAME>FIELD1</FIELDNAME>
<ROLLNAME>S_CARR_ID</ROLLNAME>
<ADMINFIELD>0</ADMINFIELD>
<SHLPORIGIN>D</SHLPORIGIN>
<COMPTYPE>E</COMPTYPE>
</DD03P>
<DD03P>
<FIELDNAME>FIELD2</FIELDNAME>
<ROLLNAME>S_CARRNAME</ROLLNAME>
<ADMINFIELD>0</ADMINFIELD>
<COMPTYPE>E</COMPTYPE>
</DD03P>
</DD03P_TABLE>
</asx:values>
</asx:abap>
</abapGit>
Key differences from TABL:
TABCLASSisINTTABinstead ofTRANSP- No
<CONTFLAG>— omit it (not written by serializer for structures) <EXCLASS>1</EXCLASS>— include it- Include
<DD03P_TABLE>with field definitions from the start (unlike TABL where it is optional on creation)
DD03P field rules (same as TABL):
- Fields with
ROLLNAME(data element): includeROLLNAME,ADMINFIELD>0,SHLPORIGIN(when domain provides value help —Dfor domain fixed values),COMPTYPE>E - Fields with raw type (no data element): include
ADMINFIELD>0,INTTYPE,INTLEN,DATATYPE,MASK(before any text fields)
Table Type (TTYP)
Filename: src/zmy_ttyp.ttyp.xml
Pull with:
pull --files src/zmy_ttyp.ttyp.xml
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_TTYP" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DD40V>
<TYPENAME>ZMY_TTYP</TYPENAME>
<DDLANGUAGE>E</DDLANGUAGE>
<ROWTYPE>ZMY_STRUCT</ROWTYPE>
<ROWKIND>S</ROWKIND>
<DATATYPE>STRU</DATATYPE>
<ACCESSMODE>T</ACCESSMODE>
<KEYDEF>D</KEYDEF>
<KEYKIND>N</KEYKIND>
<DDTEXT>Description of table type</DDTEXT>
</DD40V>
</asx:values>
</asx:abap>
</abapGit>
Key Fields:
TYPENAME: Table type nameROWTYPE: Row type (a structure or data element name)ROWKIND: Row kind —S=Structure/Type,D=Data element,R=ReferenceDATATYPE:STRUwhen row type is a structure (ROWKIND=S);TABLE_Tonly for elementary-type row typesACCESSMODE: Table kind —T=Standard,S=Sorted,H=HashedKEYDEF: Key definition —D=Default (standard key),K=User-definedKEYKIND: Key uniqueness —N=Non-unique,U=Unique
Note: After the first pull abapGit may expand the XML with <DD42V> (key field definitions).
Domain (DOMA)
Filename: src/zmy_domain.doma.xml
Pull with:
pull --files src/zmy_domain.doma.xml
abapGit uses the view DD01V as the root element (not DD01L). The serializer reads from the system view.
Simple domain (no fixed values):
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DOMA" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DD01V>
<DOMNAME>ZMY_DOMAIN</DOMNAME>
<DDLANGUAGE>E</DDLANGUAGE>
<DATATYPE>CHAR</DATATYPE>
<LENG>000030</LENG>
<OUTPUTLEN>000030</OUTPUTLEN>
<DDTEXT>My domain description</DDTEXT>
</DD01V>
</asx:values>
</asx:abap>
</abapGit>
Domain with fixed values (add <VALEXI>X</VALEXI> and <DD07V_TAB>):
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DOMA" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DD01V>
<DOMNAME>ZMY_STATUS</DOMNAME>
<DDLANGUAGE>E</DDLANGUAGE>
<DATATYPE>CHAR</DATATYPE>
<LENG>000001</LENG>
<OUTPUTLEN>000001</OUTPUTLEN>
<VALEXI>X</VALEXI>
<DDTEXT>Status</DDTEXT>
</DD01V>
<DD07V_TAB>
<DD07V>
<VALPOS>0001</VALPOS>
<DDLANGUAGE>E</DDLANGUAGE>
<DOMVALUE_L>A</DOMVALUE_L>
<DDTEXT>Active</DDTEXT>
</DD07V>
<DD07V>
<VALPOS>0002</VALPOS>
<DDLANGUAGE>E</DDLANGUAGE>
<DOMVALUE_L>I</DOMVALUE_L>
<DDTEXT>Inactive</DDTEXT>
</DD07V>
</DD07V_TAB>
</asx:values>
</asx:abap>
</abapGit>
Key Fields:
DOMNAME: Domain nameDDTEXT: Description (notDESCRIPT)DATATYPE: ABAP data type (CHAR,NUMC,DATS,TIMS,INT4,STRG, etc.)LENG: Length padded to 6 digits (omit forSTRG/INT4— no fixed length)OUTPUTLEN: Output length (usually same asLENG; omit forSTRG)LOWERCASE:Xif lowercase input is allowed (omit if not)VALEXI:Xif the domain has fixed values — required whenDD07V_TABis presentENTITYTAB: Value table name (check table for valid values — omit if none)
Note: After pull the serializer may add <I18N_LANGS>, <DD01_TEXTS>, <DD07_TEXTS> for translations — do not write these manually.
Message Class (MSAG)
Filename: src/zmy_msgs.msag.xml
Pull with:
pull --files src/zmy_msgs.msag.xml
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_MSAG" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<T100A>
<ARBGB>ZMY_MSGS</ARBGB>
<MASTERLANG>E</MASTERLANG>
<STEXT>My message class description</STEXT>
</T100A>
<T100>
<T100>
<SPRSL>E</SPRSL>
<ARBGB>ZMY_MSGS</ARBGB>
<MSGNR>000</MSGNR>
<TEXT>Object &1 not found</TEXT>
</T100>
<T100>
<SPRSL>E</SPRSL>
<ARBGB>ZMY_MSGS</ARBGB>
<MSGNR>001</MSGNR>
<TEXT>Operation completed successfully</TEXT>
</T100>
</T100>
</asx:values>
</asx:abap>
</abapGit>
Key Fields:
T100A/ARBGB: Message class name (same as filename stem)T100A/MASTERLANG: Master language (Efor English)T100A/STEXT: Short description of the message classT100/SPRSL: Language keyT100/MSGNR: 3-digit message number (000–999)T100/TEXT: Message text — use&1–&4for placeholders (serialized as&1–&4in XML)
Note: The <T100> wrapper contains repeated <T100> child elements — one per message.
Authorization Object (SUSO)
Filename: src/zmy_suso.suso.xml
Pull with:
pull --files src/zmy_suso.suso.xmlView with:
view --objects ZMY_SUSO --type SUSO
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_SUSO" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<TOBJ>
<OBJCT>ZMY_SUSO</OBJCT>
<FIEL1>ACTVT</FIEL1>
<FIEL2>ZMY_FIELD</FIEL2>
<OCLSS>ZMY</OCLSS>
</TOBJ>
<TOBJT>
<LANGU>E</LANGU>
<OBJECT>ZMY_SUSO</OBJECT>
<TTEXT>My authorization object description</TTEXT>
</TOBJT>
<TOBJVORFLG>
<OBJCT>ZMY_SUSO</OBJCT>
</TOBJVORFLG>
<TACTZ>
<TACTZ>
<BROBJ>ZMY_SUSO</BROBJ>
<ACTVT>01</ACTVT>
</TACTZ>
<TACTZ>
<BROBJ>ZMY_SUSO</BROBJ>
<ACTVT>02</ACTVT>
</TACTZ>
<TACTZ>
<BROBJ>ZMY_SUSO</BROBJ>
<ACTVT>03</ACTVT>
</TACTZ>
</TACTZ>
</asx:values>
</asx:abap>
</abapGit>
Key Fields:
TOBJ/OBJCT: Authorization object name — same as the filename stemTOBJ/FIEL1–FIEL0: Up to 10 authorization fields (from SU20) that make up this objectTOBJ/OCLSS: Object class (4 chars) — groups related authorization objects (e.g.AAAB,BC_A)TOBJT/TTEXT: Description textTOBJVORFLG: Flags record — include with justOBJCTwhen no flags are setTACTZ: Allowed activity values — one<TACTZ>entry per permittedACTVTvalue
Note: Authorization objects (SUSO) are the SU21 objects that group authorization fields (AUTH/SU20)
together. An object like AUD_SCOPEM uses fields ACTVT, BO_SERVICE, and AUD_GROUP.
Package Interface (PINF)
Filename: src/zmy_pinf.pinf.xml
Pull with:
pull --files src/zmy_pinf.pinf.xmlView with:
view --objects ZMY_PINF --type PINF
A package interface declares which objects a package makes visible to other packages — it is the “API” of an ABAP package. Packages that use these objects must depend on the package that owns the interface.
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_PINF" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<PINF>
<ATTRIBUTES>
<INTF_NAME>ZMY_PINF</INTF_NAME>
<DESCRIPT>Package interface for ZMY</DESCRIPT>
</ATTRIBUTES>
<ELEMENTS>
<SCOMELDTLN>
<INTF_NAME>ZMY_PINF</INTF_NAME>
<ELEM_TYPE>CLAS</ELEM_TYPE>
<ELEM_KEY>ZCL_MY_CLASS</ELEM_KEY>
</SCOMELDTLN>
<SCOMELDTLN>
<INTF_NAME>ZMY_PINF</INTF_NAME>
<ELEM_TYPE>INTF</ELEM_TYPE>
<ELEM_KEY>ZIF_MY_INTERFACE</ELEM_KEY>
</SCOMELDTLN>
</ELEMENTS>
</PINF>
</asx:values>
</asx:abap>
</abapGit>
Key Fields:
ATTRIBUTES/INTF_NAME: Package interface name (max 30 chars, stored inSCOMPARAMET.INTF_NAME)ATTRIBUTES/DESCRIPT: Description textELEMENTS/SCOMELDTLN: One entry per exported object; each has:INTF_NAME: Same as the interface name (repeated on every row)ELEM_TYPE: Object type —CLAS,INTF,DTEL,TABL,STRU,TTYP,DOMA,SUSO,ENQU,STOB,VIEWELEM_KEY: Object name
Note: No UTF-8 BOM — unlike TABL/DTEL/MSAG, the PINF serializer (LCL_OBJECT_PINF) does not write a BOM. Do not add \ufeff before <?xml ...>.