If you’ve spent your career in ISPF, you already have the instincts that matter for DevOps — you just need to remap them. You know how to manage change through a controlled process, you know why naming conventions matter, and you know that a job either runs clean or it doesn’t. Unix and Git-based DevOps aren’t a different mindset. They’re the same mindset with a different keyboard.
This is Part 1 of a series translating the ISPF/Endevor world into Unix and Git terms. This installment covers the concepts and the small set of commands you need to get moving. Part 2 builds on it with the commands you’ll reach for once you’re doing real work day to day.
Your new 3.4 is ls and cd
In ISPF, option 3.4 gave you a dataset list you could browse, filter, and act on. In Unix, that’s a combination of two commands:
ls -lalists the contents of a directory, including hidden files (anything starting with a dot, like.gitignore)cd path/to/directorymoves you into a directory, the rough equivalent of opening a PDS member’s containing dataset
There’s no member list with a fixed 8-character name limit. Directories nest freely, and file names can be long and descriptive — deploy-prod.sh instead of DEPLOYP. We recommend getting comfortable with pwd (print working directory) early; it answers “where am I?” the same way the top of an ISPF panel used to.
PDS members become files in a directory
This is the mental shift that unlocks everything else. A partitioned dataset with its members maps to a directory with its files. cd into the directory, and every file in it is a “member.” There’s no member list panel — ls is the panel.
Editing works the same way conceptually: you open a file, change it, save it. The tools are just different:
viorvim— the Unix native editor, available almost everywhere, worth learning even if you never love itnano— friendlier for quick edits, less powerful- A modern IDE like VS Code, connected over SSH — closer to what you’re used to visually, and what we recommend once you’re past the basics
Endevor’s change control becomes Git
This is the biggest conceptual leap, so take it slowly. Endevor tracked change through environments and stages — you promoted an element from Dev to QA to Prod, and Endevor kept the history. Git does the same job, but the unit of change is different, and the history lives with the code instead of in a separate control system.
| Endevor concept | Git equivalent |
|---|---|
| Element | File tracked in a repository |
| Package | Commit (or a set of commits) |
| Stage / environment | Branch |
| Approval / promotion | Pull request / merge |
| Element history | git log |
| Retrieve | git clone or git pull |
A few commands to internalize first:
git clone <url>— pulls a full copy of a repository to your machine, roughly like retrieving an entire dataset’s worth of elements at oncegit status— shows what’s changed since your last commit; check this constantly, the way you’d check a job’s return codegit add <file>thengit commit -m "message"— stages and records a change, similar to generating a packagegit push— sends your committed changes to the shared repositorygit pull— brings down changes others have pushed
The habit worth building immediately: commit small, commit often, and write a commit message that explains why, not just what. Endevor’s package descriptions did the same job.
Branches replace stages, but they’re cheaper
In Endevor, moving between Dev and QA meant a formal promotion step. In Git, a branch is just a lightweight, personal line of development — you can create one in seconds, work on it, and merge it back when ready. git branch feature-x creates one; git checkout feature-x (or the combined git checkout -b feature-x) switches you into it.
We recommend treating your first few branches as disposable practice. Unlike an Endevor package, a branch mistake is cheap to throw away — git branch -d feature-x deletes it, no approval chain required.
Jenkins is your new job scheduler
Think of a Jenkins pipeline as a JCL job stream that runs on a trigger — a code push — instead of on a schedule or an operator submitting it. Where JCL steps run programs in sequence with condition codes gating the next step, a Jenkins pipeline runs stages (build, test, deploy) in sequence, and a failure in one stage stops the pipeline the same way a bad return code stops a job stream.
The pipeline definition itself typically lives as code, in a file called a Jenkinsfile, checked into the same Git repository as everything else. That’s a habit shift worth naming explicitly: the process that builds and deploys your code is treated as code too, versioned right alongside it.
Permissions: RACF becomes file modes
RACF profiles controlled who could read, update, or alter a dataset. Unix permissions do the same job at the file level, expressed as three sets of read/write/execute bits — owner, group, and everyone else. Running ls -l shows them as a string like -rwxr-xr--. chmod changes them; chown changes ownership. It’s less centralized than RACF and more per-object, so get in the habit of checking permissions with ls -l before assuming a script will run.
Shell scripting is your new JCL
A shell script (typically a .sh file, run with bash) is doing the same job JCL used to do: sequencing commands, checking results, and handling errors. A few translation points:
$?in bash holds the exit code of the last command, the direct equivalent of a step’s condition codeif,for, andwhilegive you the conditional and looping logic that JCL made you fake with condition codes and IEBGENER tricks- Environment variables (
export VAR=value) play a role similar to symbolic parameters, but they’re process-scoped, not job-scoped
Start by reading other people’s scripts before writing your own — the syntax is unforgiving about whitespace in ways ISPF never was, and pattern-matching from working examples will save you real frustration early on.
A short glossary for the transition
- Repository (repo) — the Git equivalent of a project’s full set of datasets and their history combined
- Clone — your local working copy, closest analog to retrieving elements for edit
- Commit — a recorded, described change; the closest thing to a package
- Merge — combining changes from one branch into another; roughly a promotion
- Pipeline — an automated job stream triggered by a code change
- SSH — how you log into a Unix system remotely; think of it as your 3270 session’s replacement
Where to start this week
Pick one small, low-stakes file and take it through the full cycle: clone the repo, edit the file in vi or VS Code, check git status, commit it, push it, and watch a Jenkins pipeline pick it up if one’s attached. Doing that loop once, deliberately, will teach you more than reading ten more explanations like this one.
You already know how to think about controlled, auditable change — that instinct doesn’t need to be relearned, just re-pointed at a new toolset.
Next in this series: Part 2 covers the commands you’ll reach for once you’re past day one — searching across files, checking what’s eating space, tracing a running process, and more, all confirmed to run in z/OS UNIX System Services.
If you’re looking for professional training for your team we’ve got a full courseware on most items around Mainframe DevOps.