Git and GitHub for AI engineers: branches, pull requests and review
Save every change with Git, put the course folder on GitHub privately, and ship changes through branches and reviewed pull requests, the way SAP teams move transports.
Git is a tool that keeps a history of every saved change to a set of files. Each saved change, a commit, records what changed, who changed it, when and why. You can compare any two versions and go back to any of them.
GitHub is a website that stores a copy of that history online and adds teamwork on top. The most important teamwork feature is the pull request: a proposal to add a set of changes to the main version, which other people read, comment on and approve before it goes in.
For SAP people, the idea is familiar. A transport request bundles changes, gets released, and moves from development to quality to production under control. Git and pull requests give AI code the same discipline: nothing reaches the main line without being visible, reviewable and reversible.
An AI solution is more than a model. It is code, prompts, configuration, test cases and evaluation results. Each one changes behavior. A one-word edit to a prompt can change which blocked sales orders get escalated to a credit analyst.
Without version control, nobody can answer basic questions after an incident: what changed, who approved it, and how do we go back? With Git and pull requests, those answers are a click away.
Three business outcomes follow:
Audit trail. Every change to the logic carries an author, a timestamp, a reason and a reviewer. That matters for internal controls, especially for anything that touches finance or credit decisions.
Safe rollback. If a new prompt or threshold makes things worse, the team returns to the last good version in minutes instead of rebuilding from memory.
Faster, safer teamwork. Several engineers can work at once on separate branches. Review catches mistakes, leaked keys and real customer data before they spread.
Example. A forward deployed engineer (FDE) changes the rule that decides which blocked sales orders a person must look at, from 50,000 EUR to 60,000 EUR. In a pull request, the credit team lead sees the exact line that changed, asks why, and approves. Three weeks later an auditor asks who approved the change. The answer is on the pull request.
SAP's own development tools already work this way, with SAP names. As of October 2026:
Change and Transport System (CTS). The classic tool for ABAP development and Customizing. Changes are recorded in transport requests and moved through the system landscape, typically development, quality and production.
Git-enabled CTS (gCTS). Lets ABAP teams use Git as the version store for their transports, which opens the door to automated build and test pipelines for ABAP.
SAP BTP, ABAP environment. Code is organized in software components, each tied to one Git repository. SAP's learning material describes releasing a transport request as pushing the objects to that repository.
SAP Continuous Integration and Delivery. A BTP service that watches a Git repository, such as one on GitHub, and runs a build, test and deploy pipeline on every change. It can hand the result to SAP Cloud Transport Management to move it through development, test and production accounts.
The AI side-by-side extensions you build in this course (Python services, CAP apps) live in Git repositories from day one. Knowing Git is how you plug into these pipelines later.
"Git is only for developers." Prompts, test cases and decision thresholds are business logic. Product owners and functional consultants review pull requests too; GitHub shows changes in plain text.
"A private repository keeps secrets safe." Private limits who can see it today. Anyone with access, and every copy they made, keeps the full history. A key committed once must be replaced.
"Review slows us down." A small pull request reviewed in minutes is faster than finding the same mistake in production.
"GitHub replaces SAP transports." For ABAP and Customizing, CTS or gCTS still moves changes between SAP systems. Git and GitHub cover the code around them, and gCTS connects the two.
Pick one answer for each question. The explanation appears after you choose.
1Why should prompts and decision thresholds for an AI solution be in Git, not only the code?
Answer: B. A one-word prompt edit or a new threshold changes which orders get escalated. Keeping them in Git gives the same audit trail, review and rollback as code. Nothing in SAP or the model forces this; it is a control the team chooses.
2What does a pull request give a business that a direct change to the main version does not?
Answer: D. A pull request shows the exact lines that changed, lets others comment and approve, and keeps that record. That answers "who approved this?" months later. It does not deploy anything by itself and does not guarantee correctness.
3An API key was committed to a private repository and pushed. What must happen first?
Answer: C. Anyone with access, and every copy they made, keeps the full history, so a deleted file is still there. GitHub's guidance is to revoke or rotate the secret first. Cleaning history comes after, and does not reach existing copies.
4How do Git and GitHub relate to SAP's Change and Transport System?
Answer: B. CTS still moves ABAP and Customizing changes through the landscape. gCTS lets ABAP teams use Git as the version store and enables pipelines. The Python and CAP extensions in this course live in Git repositories directly.
5Which SAP BTP service runs a build, test and deploy pipeline when a change is pushed to a Git repository?
Answer: D. SAP Continuous Integration and Delivery connects to a repository, is triggered by a webhook on push, and runs stages such as build, test and deploy. It can hand the result to SAP Cloud Transport Management to move it through accounts.
6Your team says reviews are "agreed" but not enforced. What is the right follow-up question?
Answer: A. An agreed rule can be skipped under pressure; a platform rule cannot. GitHub can require a pull request, approvals and passing checks before merging, depending on the plan. Prompt changes need review as much as code.
Ask a question
Testing: only staff see this
Stuck on something in this layer? Ask it here. Questions are answered in the order they arrive, and the answer appears under My questions.
Sign in (free) to ask a question. You can ask anonymously.
Deep layer · 40 min read
#Mental model: snapshots, pointers, and a proposal to move a pointer
Git stores your project as a chain of snapshots. Each commit is a full picture of the tracked files, plus a pointer to the commit before it, an author and a message. Nothing in the chain is ever edited; new commits are added on top.
A branch is just a name that points at one commit. When you commit on a branch, the name moves forward to the new commit. main is the branch everyone agrees is the working version. HEAD is the pointer to the branch you are on right now.
So a pull request is a proposal: "move main forward to include the commits on my branch." Review is the conversation before that pointer moves. Once you see it that way, branches stop being scary. They are cheap labels, and the history underneath is safe.
flowchart LR
A[commit A<br/>set up folder] --> B[commit B<br/>add triage.py]
B --> C[commit C<br/>raise threshold]
M([main]) -.-> B
F([raise-threshold]) -.-> C
H([HEAD]) -.-> F
In the picture, main still points at B. Your branch raise-threshold points at C. Merging the pull request moves main to include C.
Every change passes through three places on your computer, then one online:
Working folder. The files you edit in VS Code.
Staging area (also called the index). The changes you have chosen for the next commit, with git add.
Local history. Commits, created with git commit, stored in the hidden .git folder.
Remote. A copy of the history on GitHub, updated with git push and read with git pull.
flowchart LR
W[Working folder] -->|git add| S[Staging area]
S -->|git commit| L[Local history]
L -->|git push| R[GitHub remote]
R -->|git pull| L
L -->|git restore| W
Staging exists so you can commit part of your work. You can fix a bug and tidy a comment, then commit them separately with clear messages.
A team workflow on GitHub has the same shape every time:
sequenceDiagram
participant You
participant GitHub
participant Reviewer
You->>You: git switch -c raise-threshold
You->>You: edit, git add, git commit
You->>GitHub: git push -u origin raise-threshold
You->>GitHub: open pull request into main
GitHub->>Reviewer: request review
Reviewer->>GitHub: comment or approve
GitHub->>GitHub: merge, main moves forward
You->>You: git switch main, git pull
GitHub's pull request page shows the conversation, the commits and the changed files, line by line. A merge box tells you whether the PR can be merged: whether required reviews and checks are satisfied, and whether there are conflicts.
Git combines changes automatically when they touch different lines. When two branches change the same lines differently, Git stops and asks you. It writes both versions into the file between markers:
<<<<<<< HEAD
ESCALATE_ABOVE = 40000 # the version on your current branch
=======
ESCALATE_ABOVE = 55000 # the version on the branch you are merging in
>>>>>>> main
You edit the file to the version you want, delete all three marker lines, then git add and git commit. A conflict is not an error. It is Git refusing to guess a business decision.
Model behavior depends on things that look like text, not code: prompts, few-shot examples, thresholds, tool descriptions, evaluation sets. A changed sentence in a prompt is a changed business rule. Treat these files exactly like code: one change per pull request, a message saying why, and the evaluation result in the PR description. Unit 8 (evaluation) and Unit 10 (production) build on this when you version evaluation sets and track regressions.
#Build it yourself: put your course on GitHub and ship a reviewed change
Before you start: complete Set up your computer for this course. You need the orchestrate-course folder with Git installed, a .gitignore and at least one commit (its Step 7).
You will add a small blocked-orders script, learn the daily Git loop, put your course folder on GitHub as a private repository, change the script on a branch, review and merge it with a pull request, and then resolve a merge conflict on purpose. A check script makes sure no key ever reaches GitHub.
flowchart LR
E[Edit on a branch] --> C[Commit]
C --> P[Push to GitHub]
P --> PR[Pull request]
PR --> R[Review]
R --> M[Merge into main]
M --> E
In VS Code, create a folder unit01 in the course folder if it isn't there already.
Create a new file, paste the code below, and save it as unit01/triage.py.
"""Decide which blocked sales orders to escalate today.
Made-up, SAP-shaped sample data; no SAP access or key needed.
SalesOrder, SoldToParty and TotalNetAmount are field names from SAP's Sales Order API;
"block" is a simplified label for this exercise, not an SAP field.
Run it from your course folder: python unit01/triage.py
"""
ESCALATE_ABOVE = 50000 # net value (EUR) above which a blocked order goes to a person
ORDERS = [
{"SalesOrder": "5000001", "SoldToParty": "17100001", "TotalNetAmount": 72000.00, "block": "credit"},
{"SalesOrder": "5000002", "SoldToParty": "17100002", "TotalNetAmount": 8400.00, "block": "credit"},
{"SalesOrder": "5000003", "SoldToParty": "17100003", "TotalNetAmount": 51500.00, "block": "delivery"},
{"SalesOrder": "5000004", "SoldToParty": "17100001", "TotalNetAmount": 23900.00, "block": "delivery"},
]
def main() -> None:
print(f"Escalate blocked orders above {ESCALATE_ABOVE:,.0f} EUR\n")
for order in ORDERS:
action = "ESCALATE" if order["TotalNetAmount"] > ESCALATE_ABOVE else "queue"
print(f" {order['SalesOrder']} {order['TotalNetAmount']:>10,.2f} {order['block']:<8} {action}")
if __name__ == "__main__":
main()
Open unit01/triage.py and change 50000 to 5. Save. Run python unit01/triage.py: every order is now escalated.
See the change, then throw it away:
git diff
git restore unit01/triage.py
git status
On branch master
nothing to commit, working tree clean
The file is back to the last committed version. git restore only discards changes you haven't committed, so use it with care: there is no undo for the undo.
#Step 5: Add the repository safety check, then install GitHub's CLI
Before anything goes online, prove that no key will go with it.
Create a new file in the course folder (next to check_setup.py), paste the script below and save it as check_repo.py.
"""Check that your course folder is safe and ready to share on GitHub.
Run it from your course folder: python check_repo.py
It only reads; it changes nothing and sends nothing anywhere.
"""
import re
import shutil
import subprocess
import sys
problems = 0
# Text that looks like a real secret. A match means "look at this line", not proof.
SECRET_PATTERNS = [
re.compile(r"sk-ant-[A-Za-z0-9_-]{10,}"), # Anthropic-style key
re.compile(r"gh[pousr]_[A-Za-z0-9]{20,}"), # GitHub token
re.compile(r"-----BEGIN [A-Z ]*PRIVATE KEY-----"), # private key file
re.compile(r"(?i)(api_?key|secret|password|token)\s*[=:]\s*[\"'][^\"'\s]{16,}[\"']"),
]
def report(ok: bool, label: str, fix: str = "", optional: bool = False) -> None:
"""Print one line: OK, MISSING (must fix) or LATER (optional for now)."""
global problems
if ok:
print(f" OK {label}")
elif optional:
print(f" LATER {label} -> {fix}")
else:
problems += 1
print(f" MISSING {label} -> {fix}")
def git(*args: str) -> subprocess.CompletedProcess:
"""Run one git command in this folder and capture its output as text."""
return subprocess.run(["git", *args], capture_output=True, text=True)
print("\n1. Git")
if shutil.which("git") is None:
report(False, "git is installed", "install Git (see Set up your computer)")
sys.exit(1)
report(True, "git is installed")
in_repo = git("rev-parse", "--is-inside-work-tree").returncode == 0
report(in_repo, "this folder is a Git repository", "run: git init")
if not in_repo:
sys.exit(1)
branch = git("branch", "--show-current").stdout.strip() or "(none)"
report(True, f"current branch: {branch}")
print("\n2. Secrets stay out")
report(git("check-ignore", "-q", "--no-index", ".env").returncode == 0, ".env is ignored",
"add the line .env to .gitignore")
report(git("ls-files", "--error-unmatch", ".env").returncode != 0, ".env is not tracked",
"run: git rm --cached .env, commit, and rotate any key that was pushed")
report(git("ls-files", ".venv").stdout.strip() == "", ".venv is not tracked",
"add .venv/ to .gitignore, then run: git rm -r --cached .venv")
hits = []
for path in git("ls-files").stdout.splitlines():
try:
with open(path, encoding="utf-8") as f:
for number, line in enumerate(f, start=1):
if any(p.search(line) for p in SECRET_PATTERNS):
hits.append(f"{path}:{number}")
except (UnicodeDecodeError, OSError):
continue # skip binary or unreadable files
report(not hits, "no secret-looking text in tracked files",
"check and remove: " + ", ".join(hits[:5]))
print("\n3. Work saved")
dirty = git("status", "--porcelain").stdout.strip()
report(not dirty, "no uncommitted changes", "review with git status, then commit", optional=True)
report(git("log", "-1").returncode == 0, "at least one commit", "run: git add . and git commit -m \"...\"")
print("\n4. GitHub")
remote = git("remote", "get-url", "origin")
report(remote.returncode == 0, "remote 'origin': " + (remote.stdout.strip() or "not set"),
"create the GitHub repository (Step 6)", optional=True)
if remote.returncode == 0:
counts = git("rev-list", "--left-right", "--count", "@{upstream}...HEAD")
if counts.returncode == 0:
behind, ahead = counts.stdout.split()
report(ahead == "0", f"all commits pushed ({ahead} not on GitHub yet)", "run: git push", optional=True)
report(behind == "0", f"up to date with GitHub ({behind} new there)", "run: git pull", optional=True)
else:
report(False, f"branch {branch} pushed to GitHub", f"run: git push -u origin {branch}", optional=True)
print()
if problems:
print(f"{problems} item(s) to fix before you push. Fix them, then run this again.")
sys.exit(1)
print("Safe to share. Nothing secret is tracked by Git.")
1. Git
OK git is installed
OK this folder is a Git repository
OK current branch: master
2. Secrets stay out
OK .env is ignored
OK .env is not tracked
OK .venv is not tracked
OK no secret-looking text in tracked files
3. Work saved
LATER no uncommitted changes -> review with git status, then commit
OK at least one commit
4. GitHub
LATER remote 'origin': not set -> create the GitHub repository (Step 6)
Safe to share. Nothing secret is tracked by Git.
That is the output of the first run, before the commit: check_repo.py itself is the uncommitted change. Any MISSING line in section 2 must be fixed before Step 6. LATER under GitHub is expected until the next step.
Create a GitHub account if you don't have one: go to github.com, click Sign up, and follow the prompts. The free plan is enough.
Install the GitHub CLI:
Windows (PowerShell):
winget install --id GitHub.cli --source winget
Then close the terminal window completely and open a new one. A new tab is not enough for the new command to be found.
Without Homebrew, use the macOS download on cli.github.com.
Linux: follow the instructions for your distribution linked from cli.github.com.
Check it works with gh --version.
Sign in:
gh auth login
Answer the questions with the arrow keys and Enter: GitHub.com, then HTTPS, then Yes to authenticate Git with your GitHub credentials, then Login with a web browser. Copy the one-time code it shows and press Enter. In the browser page that opens, sign in if asked, paste the code, and approve the access it asks for. The terminal then confirms you are logged in.
gh stores the resulting token in your system's credential store. You never paste it into a file.
✓ Created repository your-name/orchestrate-course on github.com
✓ Added remote https://github.com/your-name/orchestrate-course.git
✓ Pushed commits to https://github.com/your-name/orchestrate-course.git
The exact wording may differ between gh versions. What matters is that it created, added a remote, and pushed.
Open the repository in your browser:
gh repo view --web
You see your files and commits. Check two things: there is a Private label next to the name, and there is no.env file and no .venv folder in the list.
Run python check_repo.py again. The GitHub section now shows OK lines.
gh pr create --base main --title "Raise escalation threshold to 60,000 EUR" --body "Credit team asked for fewer escalations. Effect on sample data: order 5000003 (51,500 EUR) moves from ESCALATE to queue."
It prints a link to the new pull request.
Open it with gh pr view --web. On the web you could also have used the yellow Compare & pull request banner on the repository page.
Review it as a reviewer would. Click the Files changed tab. You see one red line (old) and one green line (new). Click the + next to the green line and leave a comment, for example "Agreed with credit team lead?".
On a team, a colleague does this review. In your own course repository, you review your own work; the habit is what counts.
Merge it. Back in the terminal:
gh pr merge --squash --delete-branch
--squash turns the branch's commits into one commit on main. --delete-branch removes the branch locally and on GitHub, since its work is now in main.
Make sure your local main has the merged change:
git switch main
git pull
git log --oneline
The top commit is your squashed change, on main. On GitHub, the Pull requests tab, filter Closed, keeps the whole conversation for later.
Two people changed the same rule. You'll play both.
On a new branch, lower the threshold:
git switch -c lower-threshold
Change ESCALATE_ABOVE = 60000 to ESCALATE_ABOVE = 40000, save, then:
git commit -am "Lower threshold to 40,000 EUR"
(-a stages every already-tracked file that changed, so you can skip git add here.)
Go back to main and make a different change to the same line:
git switch main
Change ESCALATE_ABOVE = 60000 to ESCALATE_ABOVE = 55000, save, then:
git commit -am "Set threshold to 55,000 EUR after review with credit team"
Switch to your branch and bring main into it, as you would before opening a pull request:
git switch lower-threshold
git merge main
Auto-merging unit01/triage.py
CONFLICT (content): Merge conflict in unit01/triage.py
Automatic merge failed; fix conflicts and then commit the result.
Open unit01/triage.py. VS Code highlights the conflict:
<<<<<<< HEAD
ESCALATE_ABOVE = 40000 # net value (EUR) above which a blocked order goes to a person
=======
ESCALATE_ABOVE = 55000 # net value (EUR) above which a blocked order goes to a person
>>>>>>> main
HEAD is your branch's version. Below ======= is the version from main.
5. Decide. The 55,000 EUR value was agreed with the credit team, so keep it. Delete the 40,000 line and all three marker lines, so one ESCALATE_ABOVE = 55000 line remains. VS Code's Accept Incoming Change link above the conflict does the same. Save.
6. Prove the file works, then finish the merge:
* adf8e4b Resolve conflict: keep 55,000 EUR agreed with credit team
|\
| * 1a6d083 Set threshold to 55,000 EUR after review with credit team
* | 21d373d Lower threshold to 40,000 EUR
|/
* 05dbb70 Raise escalation threshold to 60,000 EUR (#1)
Your hashes differ. The graph shows two lines of work joining.
Tidy up. The commit on main from step 2 went in without a pull request; that is fine in a practice repository, and Production concerns explains how teams prevent it. Push main, and delete the practice branch:
git switch main
git push
git branch -D lower-threshold
Run python check_repo.py one last time. Every line should be OK.
CTS organizes development in the ABAP Workbench and in Customizing and transports changes between the systems of a landscape. A classic three-system landscape moves a transport from development to quality to production. Each import is controlled, and the transport is the unit of change, approval and audit.
Most AI projects still touch CTS. If your AI service needs a new custom field, a CDS view or a released API configured in S/4HANA, that change travels by transport, on the ABAP team's schedule. Plan for it in the solution design, as covered in Writing a solution design document for an AI use case.
gCTS lets ABAP teams manage change and transport processes with Git as the external version store. SAP's sample repository SAP-samples/s4hana-gcts shows task-based committing tied to releasing tasks in the Transport Organizer, and SAP positions gCTS as the way to set up CI/CD for ABAP.
In the ABAP environment, code is grouped into software components. SAP's learning material describes each one as tied to exactly one Git repository and one transport layer, managed in the Manage Software Components app (create or clone, branches, tags). Two models exist:
SAP-managed gCTS: SAP runs the Git repository; you don't access it directly.
Bring Your Own Git (BYOG): the software component connects to your own GitHub, GitLab or Bitbucket repository, so it fits your existing pipelines.
Releasing a transport request in the ABAP development tools for Eclipse pushes the objects to the associated repository. abapGit is a separate open-source tool, which SAP's material names for migrating code from on-premise to cloud and between cloud systems.
#SAP Continuous Integration and Delivery and Cloud Transport Management
For the side-by-side apps you build in Python or CAP, the repository lives on GitHub or a similar host. SAP Continuous Integration and Delivery, a BTP service, connects to that repository. A webhook (GitHub calling the service on every push) triggers a job. The job runs stages such as build, test and deploy, made of steps; each run is a build. A step can hand the built application to SAP Cloud Transport Management, which moves it through development, test and production subaccounts with transport-style control. Unit 6's Deploying AI apps on SAP BTP covers the deployment itself; pipelines come back in the production units.
Git on GitHub (or the customer's Git host), pull requests
It's plain files; review and history are what you need
Deploying that service to SAP BTP with controls
SAP Continuous Integration and Delivery + Cloud Transport Management, or the customer's own pipeline
Repeatable deploys and transport-style promotion between accounts
ABAP objects and Customizing in S/4HANA on-premise or private cloud
CTS; gCTS where the team runs it
SAP systems import changes by transport; Git adds history and pipelines
ABAP in SAP BTP, ABAP environment
Software components with SAP-managed gCTS or BYOG
Built into the environment's lifecycle
One-time move of ABAP code between systems or to the cloud
abapGit
Named by SAP for migration scenarios
The practical rule for an FDE: your own code is in Git from the first hour; the customer's SAP changes follow the customer's transport process. The solution design names where the two meet.
Branch protection. On a team, nobody should be able to push to main directly. GitHub branch protection can require a pull request, a number of approvals, passing status checks and up-to-date branches before merging. Availability depends on the plan: protected branches work on public repositories with GitHub Free, and on private repositories with GitHub Pro, Team or Enterprise. Your free private course repository can't enforce it, which is why Step 9 could commit to main directly. Customer repositories should enforce it.
Secrets. Keys live in .env locally and in the platform's secret store or service bindings in production, never in the repository. A leaked key is handled in this order: revoke or rotate it, then clean history. Rewriting history doesn't reach clones, forks or cached views. Run a check like check_repo.py before every push, and enable your Git host's secret scanning where the plan offers it.
Data. Never commit real customer or company data, including extracts "just for testing". Use made-up, SAP-shaped samples, as triage.py does. Large files, model weights and datasets don't belong in a normal Git repository either; store them in object storage and commit a reference.
Review that means something. Keep pull requests small: one decision per PR. Put the "why" and the evaluation result in the description. For AI changes, a reviewer should see the before and after on the evaluation set, not only the diff. Ask a business owner to approve changes to business rules, like the escalation threshold.
Traceability to SAP. Link the pull request to the change ticket and, where SAP objects change too, to the transport request. An auditor can then follow one change from the business request to the code to the import into production.
Clean core. Keep AI logic in side-by-side extensions under Git, and keep changes inside S/4HANA to released APIs and extension points, moved by transport. The repository then documents exactly what sits outside the core.
Committing .env once. The key stays in history. Check .gitignore before the first push and run check_repo.py.
git add . without looking. It stages everything, including stray exports and logs. Run git status and git diff --staged first.
Huge pull requests. A 2,000-line PR gets a rubber stamp, not a review. Split it.
Messages like "fix" or "update". Write why: "Raise threshold to 60,000 EUR to cut credit team workload".
Working on main. Start every change with git switch -c <name>.
Long-lived branches. The longer a branch lives, the bigger its conflicts. Merge main into it often, or finish it quickly.
Resolving conflicts by picking "mine" blindly. A conflict is a business question when the lines hold rules. Ask the other author.
Assuming a private repository is a vault. Access changes over time and copies outlive it.
#Exercise: ship one reviewed improvement to your Unit 1 code
Open your course folder and run python check_repo.py. Fix anything marked MISSING.
Create a branch named add-readme:
git switch -c add-readme
Create README.md in the course folder with three short sections: What this is (your Orchestrate course portfolio), How to run (activate .venv, python check_setup.py, python unit01/triage.py) and Rules (no keys, no real customer data).
Commit it with a message that says why, and push the branch:
git add README.md
git commit -m "Add README so reviewers know how to run the course code"
git push -u origin add-readme
Open a pull request with gh pr create --fill. (--fill uses your commit message as the title and body.)
On GitHub, open Files changed and leave at least one review comment on your own README. Then fix what you commented on, commit and git push again. Watch the pull request update with the new commit.
Merge with gh pr merge --squash --delete-branch, then run git switch main and git pull.
Done when: your private GitHub repository shows README.md on main, the Closed pull requests list shows at least two merged pull requests (the threshold change and the README), and python check_repo.py prints Safe to share. Every later unit adds its code to this repository through a branch and a pull request, and Unit 15's portfolio projects start from it.
Pick one answer for each question. The explanation appears after you choose.
1In Git, what is a branch?
Answer: B. A branch is a lightweight pointer to a commit, and it moves forward each time you commit on it. That is why creating one is instant and cheap. Copies and backups are what remotes and clones are for.
2You edited triage.py, haven't committed, and the change is wrong. What do you run?
Answer: C. git restore <file> throws away uncommitted edits to the working file. --staged only unstages and keeps your edits. Committing would save the mistake, and deleting a branch is unrelated.
3What does git push -u origin raise-threshold do the first time you run it?
Answer: D. Push sends your commits to the remote named origin. -u links the local branch to the GitHub branch, so later git push and git pull need no extra words. Merging happens only through the pull request.
4git merge main stops with CONFLICT (content) in triage.py. What is the right next move?
Answer: B. Both branches changed the same line, so Git refuses to guess. You edit the file to the intended version, remove the <<<<<<<, ======= and >>>>>>> lines, stage and commit. When the line is a business rule, the right value is a business decision, so ask the other author if unsure.
5In check_repo.py, why does the .env check use ls-files --error-unmatch, and what should you do if it reports MISSING?
Answer: C. The command fails when .env is not tracked, which is the safe case. If it is tracked, git rm --cached .env stops tracking it, but the key remains in history. GitHub's guidance is to revoke or rotate the secret first.
6A customer wants every change to main reviewed, in a private repository on GitHub Free. What do you tell them?
Answer: D. GitHub documents protected branches for public repositories on Free, and for private repositories on Pro, Team and Enterprise. Pull requests work everywhere, but only protection enforces "no merge without approval". Without it, review is just an agreement.
7In SAP BTP, ABAP environment, how does a software component relate to Git?
Answer: A. SAP's learning material describes a 1:1 link between a software component, a Git repository and a transport layer. The repository is SAP-managed or your own (Bring Your Own Git). abapGit is a separate tool named for migration.
8Your AI service is a Python app on GitHub. How do pushes reach BTP with transport-style control using SAP services?
Answer: B. SAP Continuous Integration and Delivery connects to the repository; a webhook on push starts a job with build, test and deploy stages. A step can pass the result to SAP Cloud Transport Management, which moves it between development, test and production subaccounts.
9Why should a change to the escalation threshold or a prompt go through its own small pull request?
Answer: C. A threshold or a prompt is a business rule. A small, focused pull request lets a reviewer, ideally the business owner, see exactly what changes and why, and leaves an audit record. Large mixed PRs get rubber-stamped.
Ask a question
Testing: only staff see this
Stuck on something in this layer? Ask it here. Questions are answered in the order they arrive, and the answer appears under My questions.
Sign in (free) to ask a question. You can ask anonymously.
About pull requests (GitHub Docs)— a PR proposes merging changes from one branch into another; line-by-line review; merge box; required reviews and checks
Managing a branch protection rule (GitHub Docs)— protected branches available for public repos on GitHub Free, and for private repos on Pro, Team and Enterprise; require PR, approvals, status checks
Change and Transport System (SAP Support Portal)— CTS organizes ABAP Workbench and Customizing changes and transports them between systems; gCTS uses Git as external version management and enables CI/CD for ABAP
Introducing DevOps for SAP BTP ABAP Environment (learning.sap.com)— software components map 1:1 to a Git repository and a transport layer; SAP-managed gCTS vs. Bring Your Own Git; abapGit for migration; Manage Software Components app; releasing a transport pushes objects to Git