Class VcsOperations
java.lang.Object
network.ike.plugin.ws.vcs.VcsOperations
Git and VCS state operations for the IKE VCS Bridge.
All git commands use ProcessBuilder. Commands that modify
state (commit, push, branch creation) set IKE_VCS_CONTEXT
in the subprocess environment so that the pre-commit and pre-push
hooks allow the operation through.
-
Method Summary
Modifier and TypeMethodDescriptionstatic voidStage all files.static StringbranchLastCommitDate(File dir, String branch) Get the date of the last commit on a branch (ISO format).static voidCatch-up preamble: sync if needed, otherwise report that we're current.static voidCheckout an existing branch.static voidcheckoutNew(File dir, org.apache.maven.api.plugin.Log log, String branch) Create and checkout a new branch.static voidCommit the currently-staged changes with the given message viagit commit -F -(message piped on stdin, no shell quoting issues, no argument-length limits).static voidcommitStaged(File dir, org.apache.maven.api.plugin.Log log, String message) Alias forcommit(File, Log, String); retained for callers that emphasize the "files are already staged" reading.conflictingFiles(File dir) List files with unresolved merge conflicts.static StringcurrentBranch(File dir) Get the current branch name.static voiddeleteBranch(File dir, org.apache.maven.api.plugin.Log log, String branch) Delete a local branch.static voiddeleteLocalRef(File dir, org.apache.maven.api.plugin.Log log, String ref) Delete a local ref (git update-ref -d <ref>).static voiddeleteRemoteBranch(File dir, org.apache.maven.api.plugin.Log log, String remote, String branch) Delete a remote branch.static voiddeleteRemoteRef(File dir, org.apache.maven.api.plugin.Log log, String remote, String ref) Delete a ref from a remote (git push <remote> :<ref>).static voidFetch from all remotes.static voidFetch a remote ref into a local ref of the same name (git fetch <remote> <ref>:<ref>).static booleanhasStagedChanges(File dir) Check whether there are staged changes ready to commit.static booleanhasUnstagedChanges(File dir) Check whether there are modified but unstaged changes in the working tree.static StringGet the 8-character short SHA of HEAD.static booleanisAncestor(File dir, String maybeAncestor, String descendant) Check whether one commit is an ancestor of (or equal to) another.static booleanCheck whether the working tree is clean (no staged or unstaged changes).localBranches(File dir, String prefix) List all local branches matching a prefix.static booleanlocalBranchExists(File dir, String branch) Check whether a local branch exists.static voidmergeAbortQuiet(File dir, org.apache.maven.api.plugin.Log log) Abort an in-progress merge (git merge --abort).mergedBranches(File dir, String target, String prefix) List local branches matching a prefix that are fully merged into the given target branch.static voidmergeFfOnly(File dir, org.apache.maven.api.plugin.Log log, String ref) Fast-forward-only merge.static voidNo-fast-forward merge with a merge commit.static voidmergeSquash(File dir, org.apache.maven.api.plugin.Log log, String branch) Squash-merge a branch into the current branch (does not commit).static intmodifiedTrackedCount(File dir) Count tracked files with modifications (staged or unstaged), excluding untracked files.static booleanCheck whether the local HEAD has fallen behind the VCS state file written by a coordinated workspace operation.predictConflicts(File dir, String branch, String other) Predict merge conflicts without touching the index or working tree.static voidPush to remote.static voidpushIfRemoteExists(File dir, org.apache.maven.api.plugin.Log log, String remote, String branch) Push to remote if it exists.static voidPush a ref to a remote under the same name (git push <remote> <ref>:<ref>).static voidPush to remote, ignoring failures (no remote, offline, etc.).static voidpushWithUpstream(File dir, org.apache.maven.api.plugin.Log log, String remote, String branch) Push to remote with upstream tracking.static booleanremoteRefExists(File dir, String remote, String ref) Check whether a remote ref exists by shelling out togit ls-remote.Get the 8-character short SHA of a remote branch, or empty if unreachable.static voidHard reset — updates HEAD, index, and working tree to matchref, discarding uncommitted changes.static voidSoft reset (no --hard) — updates HEAD and index, leaves working tree.static voidstashApply(File dir, org.apache.maven.api.plugin.Log log, String ref) Apply a stash identified by its ref (git stash apply <ref>).static voidDrop the top of the stash stack (git stash drop).static voidstashPushUntracked(File dir, org.apache.maven.api.plugin.Log log, String message) Stash the working tree including untracked files (git stash push -u -m <message>).static StringSynchronize local git state to match the VCS state file.static StringuncommittedStatus(File dir) List files with any uncommitted changes (staged, unstaged, or untracked).static StringunstagedFiles(File dir) List files with unstaged modifications in the working tree.untrackedFiles(File dir) List untracked, non-ignored files in the working tree.static voidPoint a ref at a given target (git update-ref <ref> <target>).static StringReadgit config user.emailfor the repository.static StringDerive an ASCII-safe slug from a git email address.static voidwriteVcsState(File dir, VcsState.Action action) Write the VCS state file for the given directory.
-
Method Details
-
headSha
-
currentBranch
-
remoteSha
public static Optional<String> remoteSha(File dir, String remote, String branch) throws org.apache.maven.api.plugin.MojoException Get the 8-character short SHA of a remote branch, or empty if unreachable.- Parameters:
dir- the repository root directoryremote- the remote name (e.g., "origin")branch- the branch name to query- Returns:
- the short SHA, or empty if the remote branch is unreachable
- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
isClean
Check whether the working tree is clean (no staged or unstaged changes).- Parameters:
dir- the repository root directory- Returns:
- true if the working tree has no changes
-
hasStagedChanges
Check whether there are staged changes ready to commit.- Parameters:
dir- the repository root directory- Returns:
- true if the index has staged changes
-
hasUnstagedChanges
Check whether there are modified but unstaged changes in the working tree.- Parameters:
dir- the repository root directory- Returns:
- true if there are unstaged modifications
-
unstagedFiles
-
uncommittedStatus
List files with any uncommitted changes (staged, unstaged, or untracked). Returns the raw porcelain output suitable for detailed error messages.- Parameters:
dir- the repository root directory- Returns:
- porcelain status output, or empty string if clean
-
modifiedTrackedCount
Count tracked files with modifications (staged or unstaged), excluding untracked files. UseuntrackedFiles(File)for the new-file list.- Parameters:
dir- the repository root directory- Returns:
- count of modified tracked files; zero if clean or on error
-
untrackedFiles
-
conflictingFiles
-
predictConflicts
Predict merge conflicts without touching the index or working tree.Uses
git merge-tree --write-tree(git 2.38+) to perform a trial merge in memory. Returns the list of conflicting file paths, or an empty list if the merge would be clean.Falls back gracefully on older git versions — returns an empty list (conflict prediction unavailable).
- Parameters:
dir- the repository root directorybranch- the branch to merge into (e.g., current feature branch)other- the branch to merge from (e.g., "main")- Returns:
- list of file paths that would conflict, empty if clean or unknown
-
commitLog
public static List<String> commitLog(File dir, String base, String head) throws org.apache.maven.api.plugin.MojoException - Parameters:
dir- the repository root directorybase- the starting ref (exclusive)head- the ending ref (inclusive)- Returns:
- list of one-line commit summaries between the two refs
- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
fetch
public static void fetch(File dir, org.apache.maven.api.plugin.Log log) throws org.apache.maven.api.plugin.MojoException Fetch from all remotes.- Parameters:
dir- the repository root directorylog- Maven logger- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
resetSoft
public static void resetSoft(File dir, org.apache.maven.api.plugin.Log log, String ref) throws org.apache.maven.api.plugin.MojoException Soft reset (no --hard) — updates HEAD and index, leaves working tree.- Parameters:
dir- the repository root directorylog- Maven loggerref- the ref to reset to (e.g., "origin/main")- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
resetHard
public static void resetHard(File dir, org.apache.maven.api.plugin.Log log, String ref) throws org.apache.maven.api.plugin.MojoException Hard reset — updates HEAD, index, and working tree to matchref, discarding uncommitted changes. Also clears any in-progress merge state (.git/SQUASH_MSG,.git/MERGE_MSG), which is useful after agit merge --squashwhose squashed diff turned out to be empty — see issue #162.- Parameters:
dir- the repository root directorylog- Maven loggerref- the ref to reset to (e.g.,"HEAD")- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
isAncestor
public static boolean isAncestor(File dir, String maybeAncestor, String descendant) throws org.apache.maven.api.plugin.MojoException Check whether one commit is an ancestor of (or equal to) another.Uses
git merge-base --is-ancestor: exit 0 means yes, exit 1 means no, any other exit is an error (e.g., unknown ref).- Parameters:
dir- the repository root directorymaybeAncestor- candidate ancestor commit (ref or sha)descendant- candidate descendant commit (ref or sha)- Returns:
trueiffmaybeAncestoris reachable fromdescendantvia parent edges (or is equal)- Throws:
org.apache.maven.api.plugin.MojoException- if either ref is unknown or the git command fails
-
checkout
public static void checkout(File dir, org.apache.maven.api.plugin.Log log, String branch) throws org.apache.maven.api.plugin.MojoException Checkout an existing branch.- Parameters:
dir- the repository root directorylog- Maven loggerbranch- the branch to check out- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
checkoutNew
public static void checkoutNew(File dir, org.apache.maven.api.plugin.Log log, String branch) throws org.apache.maven.api.plugin.MojoException Create and checkout a new branch.- Parameters:
dir- the repository root directorylog- Maven loggerbranch- the new branch name to create- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
commit
public static void commit(File dir, org.apache.maven.api.plugin.Log log, String message) throws org.apache.maven.api.plugin.MojoException Commit the currently-staged changes with the given message viagit commit -F -(message piped on stdin, no shell quoting issues, no argument-length limits). Does not stage — callers stage first viaaddAll(File, Log)or per-pathgit add. SetsIKE_VCS_CONTEXTto bypass the pre-commit hook.- Parameters:
dir- the repository root directorylog- Maven loggermessage- the commit message; must not benullor blank- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
commitStaged
public static void commitStaged(File dir, org.apache.maven.api.plugin.Log log, String message) throws org.apache.maven.api.plugin.MojoException Alias forcommit(File, Log, String); retained for callers that emphasize the "files are already staged" reading. Editor-mode (null-message) was removed in #277 — Maven's non-interactive child process cannot open an editor, so the path was never reachable in practice.- Parameters:
dir- the repository root directorylog- Maven loggermessage- the commit message; must not benullor blank- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
addAll
public static void addAll(File dir, org.apache.maven.api.plugin.Log log) throws org.apache.maven.api.plugin.MojoException Stage all files.- Parameters:
dir- the repository root directorylog- Maven logger- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
push
public static void push(File dir, org.apache.maven.api.plugin.Log log, String remote, String branch) throws org.apache.maven.api.plugin.MojoException Push to remote. SetsIKE_VCS_CONTEXTto bypass the pre-push hook.- Parameters:
dir- the repository root directorylog- Maven loggerremote- the remote name (e.g., "origin")branch- the branch to push- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
pushSafe
public static void pushSafe(File dir, org.apache.maven.api.plugin.Log log, String remote, String branch) Push to remote, ignoring failures (no remote, offline, etc.). Logs a warning on failure instead of throwing.- Parameters:
dir- the repository root directorylog- Maven loggerremote- the remote name (e.g., "origin")branch- the branch to push
-
pushIfRemoteExists
public static void pushIfRemoteExists(File dir, org.apache.maven.api.plugin.Log log, String remote, String branch) Push to remote if it exists. If no remote is configured, logs a helpful message instead of failing with a cryptic git error.- Parameters:
dir- the repository root directorylog- Maven loggerremote- the remote name (e.g., "origin")branch- the branch to push
-
pushWithUpstream
public static void pushWithUpstream(File dir, org.apache.maven.api.plugin.Log log, String remote, String branch) throws org.apache.maven.api.plugin.MojoException Push to remote with upstream tracking. SetsIKE_VCS_CONTEXTto bypass the pre-push hook.- Parameters:
dir- the repository root directorylog- Maven loggerremote- the remote name (e.g., "origin")branch- the branch to push- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
deleteBranch
public static void deleteBranch(File dir, org.apache.maven.api.plugin.Log log, String branch) throws org.apache.maven.api.plugin.MojoException Delete a local branch. Uses-D(force) because squash-merged branches are not recognized as "fully merged" by git.- Parameters:
dir- the repository root directorylog- Maven loggerbranch- the branch to delete- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
deleteRemoteBranch
public static void deleteRemoteBranch(File dir, org.apache.maven.api.plugin.Log log, String remote, String branch) throws org.apache.maven.api.plugin.MojoException Delete a remote branch.- Parameters:
dir- the repository root directorylog- Maven loggerremote- the remote name (e.g., "origin")branch- the branch to delete on the remote- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
mergeSquash
public static void mergeSquash(File dir, org.apache.maven.api.plugin.Log log, String branch) throws org.apache.maven.api.plugin.MojoException Squash-merge a branch into the current branch (does not commit).- Parameters:
dir- the repository root directorylog- Maven loggerbranch- the branch to squash-merge- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
mergeNoFf
public static void mergeNoFf(File dir, org.apache.maven.api.plugin.Log log, String branch, String message) throws org.apache.maven.api.plugin.MojoException No-fast-forward merge with a merge commit.- Parameters:
dir- the repository root directorylog- Maven loggerbranch- the branch to mergemessage- the merge commit message- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
mergeFfOnly
public static void mergeFfOnly(File dir, org.apache.maven.api.plugin.Log log, String ref) throws org.apache.maven.api.plugin.MojoException Fast-forward-only merge. Used to advance the currently-checked-out branch to a ref that is a strict descendant; fails if a real merge (or rebase) would be required.- Parameters:
dir- the repository root directorylog- Maven loggerref- the ref to fast-forward to- Throws:
org.apache.maven.api.plugin.MojoException- if the merge is not fast-forwardable or git fails
-
mergeAbortQuiet
Abort an in-progress merge (git merge --abort). Used as a cleanup safety net after a merge attempt fails unexpectedly. Does not throw if no merge is in progress.- Parameters:
dir- the repository root directorylog- Maven logger
-
localBranchExists
-
mergedBranches
List local branches matching a prefix that are fully merged into the given target branch.- Parameters:
dir- the repository root directorytarget- the branch to check merge status against (e.g., "main")prefix- the branch name prefix to filter (e.g., "feature/")- Returns:
- list of merged branch names (trimmed, without leading
*)
-
localBranches
-
branchLastCommitDate
-
userEmail
Readgit config user.emailfor the repository.- Parameters:
dir- the repository root directory- Returns:
- the configured email address
- Throws:
org.apache.maven.api.plugin.MojoException- if no email is configured
-
userSlug
Derive an ASCII-safe slug from a git email address. Used as the per-user component of therefs/ws-stash/<slug>/<branch>ref naming scheme. Lowercases, replaces@with--, and.with-.- Parameters:
email- the email address (typically fromuserEmail(File))- Returns:
- an ASCII slug safe for ref names and cross-platform shells
-
remoteRefExists
public static boolean remoteRefExists(File dir, String remote, String ref) throws org.apache.maven.api.plugin.MojoException Check whether a remote ref exists by shelling out togit ls-remote. Distinguishes "ref absent" from "remote unreachable": a zero-exit with empty stdout means absent, a zero-exit with output means present, and a non-zero exit surfaces the network/auth error to the caller.- Parameters:
dir- the repository root directoryremote- the remote name (e.g.,"origin")ref- the full ref to probe (e.g.,"refs/ws-stash/kec--knowledge-design/feature/A")- Returns:
trueif the ref exists on the remote,falseif absent- Throws:
org.apache.maven.api.plugin.MojoException- if the remote is unreachable or the probe fails
-
stashPushUntracked
public static void stashPushUntracked(File dir, org.apache.maven.api.plugin.Log log, String message) throws org.apache.maven.api.plugin.MojoException Stash the working tree including untracked files (git stash push -u -m <message>). Ignored files are skipped.- Parameters:
dir- the repository root directorylog- Maven loggermessage- the stash message- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
stashApply
public static void stashApply(File dir, org.apache.maven.api.plugin.Log log, String ref) throws org.apache.maven.api.plugin.MojoException Apply a stash identified by its ref (git stash apply <ref>). Unlikegit stash applywith a numbered index, this form accepts a full ref path (e.g.refs/ws-stash/slug/branch).- Parameters:
dir- the repository root directorylog- Maven loggerref- the stash ref to apply- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
stashDrop
public static void stashDrop(File dir, org.apache.maven.api.plugin.Log log) throws org.apache.maven.api.plugin.MojoException Drop the top of the stash stack (git stash drop).- Parameters:
dir- the repository root directorylog- Maven logger- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
updateRef
public static void updateRef(File dir, org.apache.maven.api.plugin.Log log, String ref, String target) throws org.apache.maven.api.plugin.MojoException Point a ref at a given target (git update-ref <ref> <target>).- Parameters:
dir- the repository root directorylog- Maven loggerref- the ref to update (full path, e.g."refs/ws-stash/slug/branch")target- the ref or SHA to point at- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
deleteLocalRef
public static void deleteLocalRef(File dir, org.apache.maven.api.plugin.Log log, String ref) throws org.apache.maven.api.plugin.MojoException Delete a local ref (git update-ref -d <ref>).- Parameters:
dir- the repository root directorylog- Maven loggerref- the ref to delete- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
pushRef
public static void pushRef(File dir, org.apache.maven.api.plugin.Log log, String remote, String ref) throws org.apache.maven.api.plugin.MojoException Push a ref to a remote under the same name (git push <remote> <ref>:<ref>).- Parameters:
dir- the repository root directorylog- Maven loggerremote- the remote nameref- the ref to push- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
deleteRemoteRef
public static void deleteRemoteRef(File dir, org.apache.maven.api.plugin.Log log, String remote, String ref) throws org.apache.maven.api.plugin.MojoException Delete a ref from a remote (git push <remote> :<ref>).- Parameters:
dir- the repository root directorylog- Maven loggerremote- the remote nameref- the ref to delete on the remote- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
fetchRef
public static void fetchRef(File dir, org.apache.maven.api.plugin.Log log, String remote, String ref) throws org.apache.maven.api.plugin.MojoException Fetch a remote ref into a local ref of the same name (git fetch <remote> <ref>:<ref>).- Parameters:
dir- the repository root directorylog- Maven loggerremote- the remote nameref- the ref to fetch- Throws:
org.apache.maven.api.plugin.MojoException- if the git command fails
-
writeVcsState
public static void writeVcsState(File dir, VcsState.Action action) throws org.apache.maven.api.plugin.MojoException Write the VCS state file for the given directory.- Parameters:
dir- the repository root directoryaction- the action being performed- Throws:
org.apache.maven.api.plugin.MojoException- if writing the state file fails
-
needsSync
Check whether the local HEAD has fallen behind the VCS state file written by a coordinated workspace operation. Returnsfalsewhen the state file is simply stale relative to later local commits — this is the common case aftergit commit --amendor any subsequent commit that didn't route through aws:*goal (ike-issues#232).Decision table:
- No state file →
false(nothing to sync against). - Branch mismatch →
true(state file expects a different branch). state.sha == localSha→false.state.shais a strict ancestor oflocalSha→false(state file is stale, but HEAD is just ahead — no cross-machine pull needed).- Anything else (state.sha unknown, descendant of HEAD, or
diverged) →
true(genuine catch-up required).
- Parameters:
dir- the repository root directory- Returns:
truewhensyncshould run,falsewhen the working tree is already current- Throws:
org.apache.maven.api.plugin.MojoException- if reading basic git state fails
- No state file →
-
sync
public static String sync(File dir, org.apache.maven.api.plugin.Log log) throws org.apache.maven.api.plugin.MojoException Synchronize local git state to match the VCS state file. Fetches from all remotes, switches branch if needed, and soft-resets.- Parameters:
dir- the repository root directorylog- Maven logger- Returns:
- the resulting HEAD SHA after sync
- Throws:
org.apache.maven.api.plugin.MojoException- if a git command or state file read fails
-
catchUp
public static void catchUp(File dir, org.apache.maven.api.plugin.Log log) throws org.apache.maven.api.plugin.MojoException Catch-up preamble: sync if needed, otherwise report that we're current. Used by all goals that modify state (commit, push, feature-start, etc.).- Parameters:
dir- the repository root directorylog- Maven logger- Throws:
org.apache.maven.api.plugin.MojoException- if sync fails
-