pull Command Requirements
Overview
Pull and activate ABAP objects from git repository.
Command
# Auto-detect git remote and branch from current directory
abapgit-agent pull
# Pull specific files only (fast)
abapgit-agent pull --files src/zcl_my_class.clas.abap,src/zcl_other.clas.abap
# Pull enhancement (ENHO) object by XML metadata file
abapgit-agent pull --files src/zfoo.enho.xml
# Pull enhancement (ENHO) object by hash source file — activates whole ENHO
abapgit-agent pull --files src/zfoo.enho.28bbfe2f.abap
# Pull from specific branch
abapgit-agent pull --branch develop
# Pull from specific URL
abapgit-agent pull --url https://github.com/org/repo.git
# With transport request
abapgit-agent pull --transport DEVK900001
# Combined options
abapgit-agent pull --branch develop --files src/zcl_my_class.clas.abap --transport DEVK900001
# Using transport from config/environment (no --transport flag needed)
abapgit-agent pull
# Sync serializer XML to git after pull (see XML Sync below)
abapgit-agent pull --files src/zcl_my_class.clas.abap --sync-xml
Prerequisite
- Current folder is git repo root (unless
--urlspecified) - Git remote is configured (unless
--urlspecified) .abapGitAgentexists with valid credentials
Project-Level Safeguards
Project maintainers can configure safeguards and conflict detection defaults in .abapgit-agent.json (checked into repository). See Project Configuration reference for the full schema.
{
"safeguards": {
"requireFilesForPull": true,
"disablePull": false,
"reason": "Large project with 500+ objects"
},
"conflictDetection": {
"mode": "ignore",
"reason": "Single-developer project"
}
}
When requireFilesForPull: true:
abapgit-agent pull→ ❌ Error: –files is requiredabapgit-agent pull --files ...→ ✅ Works
When disablePull: true:
- All
pullcommands are disabled - Error message directs users to project maintainer
conflictDetection.mode:
"abort"(default) — pull aborts when conflicts are detected"ignore"— conflict detection disabled project-wide
CLI --conflict-mode flag always takes precedence over project config.
Example Error Message:
❌ Error: --files parameter is required for this project
Reason: Large project with 500+ objects
Usage: abapgit-agent pull --files <file1>,<file2>
This safeguard is configured in .abapgit-agent.json
Contact the project maintainer if you need to change this setting.
Parameters
| Parameter | Required | Description |
|---|---|---|
--url |
No | Git repository URL (auto-detected if not specified) |
--branch |
No | Branch name (default: current branch) |
--files |
No | Comma-separated list of files to pull |
--transport |
No | Transport request (config/env takes priority if not specified) |
--conflict-mode |
No | abort (default) or ignore — see Conflict Detection |
--sync-xml |
No | Accept serializer XML output and amend last commit (see XML Sync) |
Local Pre-flight Checks
Before sending the request to ABAP, the CLI runs cheap local validations on any --files passed in. Failed pre-flight checks exit 1 with an actionable error and never reach the network.
| Check | Applies to | What it catches |
|---|---|---|
| File exists on disk | all | Typos in the --files path. |
DTEL SCRTEXT ≤ SCRLEN |
.dtel.xml |
SCRTEXT_S/M/L exceeds the explicitly declared SCRLEN1/2/3. DDIC’s DD_MASS_ACT_C3 silently cancels activation when this is violated, with no log message — pre-flight surfaces the violation locally so you don’t waste a round trip. When the XML omits SCRLENn, DDIC auto-sizes from the supplied text — no constraint, no check. |
Pre-flight is skipped when --url is set: the files belong to a different repository and aren’t present in the current working directory.
→ Full reference: DTEL Label Too Long for SCRLEN (abapgit-agent ref --topic common-errors).
Transport Request Precedence
The transport request is determined in this order:
| Priority | Source | Example |
|---|---|---|
| 1 | CLI --transport argument |
--transport DEVK900001 |
| 2 | Config file transport |
"transport": "DEVK900001" in .abapGitAgent |
| 3 | Environment variable ABAP_TRANSPORT |
export ABAP_TRANSPORT="DEVK900001" |
| 4 (default) | Not set | abapGit creates/uses default |
Async Execution (Large Pulls)
When pulling more than 10 files, the ABAP backend automatically runs the pull as a background job to avoid HTTP timeouts. The Node.js CLI handles this transparently — the user experience is identical to a synchronous pull, but with a real-time progress bar during activation.
How it works
- Node.js POSTs the pull request as usual
- ABAP detects >10 files → schedules a background job (
ABGAGT_PULL_<timestamp>) → returns HTTP 202 Accepted with a job number - Node.js detects 202, switches to polling mode:
GET /pull?jobNumber=<N>every 2 seconds - Progress bar updates in real time as ABAP reports activation milestones
- When the job completes, Node.js reads the final result and displays the same output as a synchronous pull
Progress stages
| Stage | Progress | Message |
|---|---|---|
| INITIALIZATION | 10% | Initializing pull… |
| FIND_REPO | 30% | Finding repository… |
| ACTIVATE | 50–90% | Activating objects (N of total) |
| COMPLETE | 100% | Pull completed |
Output during async pull
Pulling from https://github.com/org/repo.git (branch: main)
Activating 47 file(s) as background job...
[==================== ] Activating objects (23 of 47)
✅ Pull completed successfully!
Message: Pull completed successfully
📦 Activated Objects (47):
...
HTTP 202 response (job scheduled)
{
"success": "X",
"jobName": "ABGAGT_PULL_20260509082234",
"jobNumber": "08223400",
"status": "scheduled",
"message": "Pull job started"
}
Polling response (job running)
{
"jobNumber": "08223400",
"status": "running",
"stage": "ACTIVATE",
"message": "Activating objects (23 of 47)",
"progress": 65,
"current": 23,
"total": 47
}
XML Sync
After a successful pull, abapGit’s serializer may produce slightly different XML than the hand-crafted metadata files in git (different field presence, field order, BOM, extra sections). This causes abapGit to show the object as M (modified) even though the code itself was not changed.
The pull command detects this automatically by comparing the serializer output (get_files_local()) against the git remote files (get_files_remote()) byte-for-byte in ABAP — only files where bytes actually differ are reported.
Default (no flag): report only
⚠️ 1 XML file(s) differ from serializer output:
src/zif_my_intf.intf.xml
Run with --sync-xml to accept serializer output and amend the last commit
--sync-xml: accept + amend + re-pull
abapgit-agent pull --files src/zif_my_intf.intf.abap --sync-xml
When --sync-xml is passed:
- Writes the serializer XML bytes to local files (overwrite)
- Stages the changed XML files:
git add <files> - Amends the last commit:
git commit --amend --no-edit - Pushes:
git push --force-with-lease(sets upstream automatically if not yet set) - Re-pulls the same files so the ABAP system matches the amended commit
✅ Pull completed successfully!
...
🔄 Syncing 1 XML file(s) to match serializer output:
src/zif_my_intf.intf.xml
Re-pulling so ABAP system matches the amended commit...
...
✅ Synced 1 XML file(s), amended commit, re-pulled
Notes
- Only XML metadata files (
.xml) are written back — ABAP source files are untouched - Only files that already exist on disk are overwritten (no new files are created)
- When
--filesis used, only XML files for the specified objects are compared - AI agents should always pass
--sync-xmlafter creating or modifying ABAP objects to keep git and the ABAP system in sync
Tasks
1. Detect Git Remote URL
git remote get-url origin
2. Detect Current Branch
git branch --show-current
Or from .git/HEAD
3. Load Configuration
Read .abapGitAgent for credentials
4. Fetch CSRF Token
GET /health (with X-CSRF-Token: fetch)
5. Make Pull Request
Endpoint: POST /pull
Request Body:
{
"url": "https://github.com/org/repo.git",
"branch": "main",
"username": "git-user",
"password": "git-token",
"files": ["zcl_my_class.clas.abap"],
"transport_request": "DEVK900001",
"conflict_mode": "abort"
}
6. Handle Response
If HTTP 200 (synchronous — ≤10 files): parse result and display directly.
If HTTP 202 (async — >10 files):
- Read
jobNumberfrom response body - Print
Activating N file(s) as background job... - Poll
GET /pull?jobNumber=<N>every 2 seconds - Update progress bar on each poll using
progress,message,current,total - When
status = "completed": parseresult(JSON string) and display as normal - When
status = "error": print error and exit 1
7. Display Results
Output
Success (synchronous)
✅ Pull completed successfully!
Message: Pull completed successfully
📋 Pull Log (N messages):
────────────────────────────────────────────────────────────────────────────────
Icon │Object │Message
─────┼────────────────────────────┼─────────────────────────────────────────
✅ │CLAS ZCL_MY_CLASS │Object ZCL_MY_CLASS imported
...
📦 Activated Objects (N):
────────────────────────────────────────────────────────────────────────────────
✅ CLAS ZCL_MY_CLASS
...
Success (async — >10 files)
Pulling from https://github.com/org/repo.git (branch: main)
Activating 47 file(s) as background job...
[==================== ] Activating objects (23 of 47)
✅ Pull completed successfully!
Message: Pull completed successfully
📋 Pull Log (N messages):
...
📦 Activated Objects (47):
...
With Errors
❌ Pull completed with errors!
Message: Pull completed with errors
📋 Error Details:
────────────────────────────────────────────────────────────────────────────────
CLAS ZCL_MY_CLASS: Error updating where-used list
📋 Pull Log (N messages):
...
❌ Failed Objects Log (M entries):
────────────────────────────────────────────────────────────────────────────────
❌ CLAS ZCL_MY_CLASS: Error message text
Exception: Exception details
File Format
Files are parsed to extract (obj_type, obj_name):
| File Pattern | Object Type | Object Name |
|---|---|---|
zcl_my_class.clas.abap |
CLAS | ZCL_MY_CLASS |
zif_my_intf.intf.abap |
INTF | ZIF_MY_INTF |
src/zcl_my_class.clas.abap |
CLAS | ZCL_MY_CLASS |
ztable.tabl.xml |
TABL | ZTABLE |
zdtel.dtel.xml |
DTEL | ZDTEL |
zstru.stru.xml |
STRU | ZSTRU |
src/ztable.tabl.xml |
TABL | ZTABLE |
Response Structure
Synchronous (HTTP 200)
{
"success": "X",
"message": "Pull completed successfully",
"activated_count": 15,
"failed_count": 1,
"activated_objects": [
{ "obj_type": "CLAS", "obj_name": "ZCL_MY_CLASS" }
],
"failed_objects": [
{ "obj_type": "CLAS", "obj_name": "ZCL_OTHER", "text": "Error message" }
],
"log_messages": [...],
"conflict_report": "",
"conflict_count": 0,
"local_xml_files": [
{ "filename": "zcl_my_class.clas.xml", "path": "/src/", "data": "<base64>" }
]
}
local_xml_files contains only XML files where the serializer output differs from the git remote — empty array means all XML files are in sync.
Async job scheduled (HTTP 202)
{
"success": "X",
"jobName": "ABGAGT_PULL_20260509082234",
"jobNumber": "08223400",
"status": "scheduled",
"message": "Pull job started"
}
Async job completed (GET poll — final)
{
"jobNumber": "08223400",
"status": "completed",
"progress": 100,
"result": "{...same structure as synchronous response...}"
}
Key Behaviors
- Activated Objects - Only includes objects that completed successfully (no errors in log)
- Failed Objects Log - Shows all error messages (duplicates allowed for multiple errors per object)
- Error Details - When errors occur, displays error detail section at the top
- Conflict Detection - Enabled by default (
abortmode); aborts pull if local ADT edits or branch divergence detected — see Conflict Detection - Partial Download -
--filesperformance depends on the abapGit version installed — see Partial Download - Missing
.abapgit.xmlwarning - If the repository root contains no.abapgit.xml, pull prints a warning on stderr. Without this file, abapGit may use an incorrectSTARTING_FOLDERfrom ABAP-side persistence, causingACTIVATED_COUNT=0with an empty log. In--jsonmode the result object includes"missing_abapgit_xml": trueinstead. Runabapgit-agent initto create the file. - XML Sync - After every successful pull, the ABAP serializer output is compared byte-for-byte against the git remote files. Differing XML files are reported as a warning;
--sync-xmlrewrites, amends, and re-pulls automatically. - Async for large pulls - Pulls with >10 files run as ABAP background jobs automatically. Node.js detects the 202 response and polls for completion, showing a progress bar. The final output is identical to a synchronous pull.
- Silent activation cancellation enrichment - When DDIC cancels activation without writing any log messages (e.g. DTEL
SCRTEXTexceeds declaredSCRLEN), the ABAP backend introspects the rejectedDD04L/DD04Trows and injects a structuredE-type entry intoLOG_MESSAGESnaming the field, value, length, and declared limit. The CLI then classifies the pull as failure (exit 1, ❌) instead of the historical false-success behavior. Currently covers DTEL SCRLEN violations; other DDIC error modes fall through unchanged to the existing “no-op cancel” classification.
Example
# Full pull
abapgit-agent pull
# Fast pull - specific files
abapgit-agent pull --files src/zcl_my_class.clas.abap
# With transport
abapgit-agent pull --files src/zcl_my_class.clas.abap --transport DEVK900001
# Force pull through a conflict (e.g. deliberate branch switch)
abapgit-agent pull --files src/zcl_my_class.clas.abap --conflict-mode ignore
# Sync serializer XML after creating a new object
abapgit-agent pull --files src/zif_my_intf.intf.abap --sync-xml
# Large pull — runs as background job automatically, progress bar shown
abapgit-agent pull --files src/zcl_a.clas.abap,src/zcl_b.clas.abap,... # >10 files