|  | package com.mirantis.mk | 
|  |  | 
|  | /** | 
|  | * | 
|  | * Git functions | 
|  | * | 
|  | */ | 
|  |  | 
|  | /** | 
|  | * Checkout single git repository | 
|  | * | 
|  | * @param path            Directory to checkout repository to | 
|  | * @param url             Source Git repository URL | 
|  | * @param branch          Source Git repository branch | 
|  | * @param credentialsId   Credentials ID to use for source Git | 
|  | * @param poll            Enable git polling (default true) | 
|  | * @param timeout         Set checkout timeout (default 10) | 
|  | * @param depth           Git depth param (default 0 means no depth) | 
|  | */ | 
|  | def checkoutGitRepository(path, url, branch, credentialsId = null, poll = true, timeout = 10, depth = 0){ | 
|  | dir(path) { | 
|  | checkout( | 
|  | changelog:true, | 
|  | poll: poll, | 
|  | scm: [ | 
|  | $class: 'GitSCM', | 
|  | branches: [[name: "*/${branch}"]], | 
|  | doGenerateSubmoduleConfigurations: false, | 
|  | extensions: [ | 
|  | [$class: 'CheckoutOption', timeout: timeout], | 
|  | [$class: 'CloneOption', depth: depth, noTags: false, reference: '', shallow: depth > 0, timeout: timeout]], | 
|  | submoduleCfg: [], | 
|  | userRemoteConfigs: [[url: url, credentialsId: credentialsId]]] | 
|  | ) | 
|  | sh(returnStdout: true, script: 'git rev-parse HEAD').trim() | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Parse HEAD of current directory and return commit hash | 
|  | */ | 
|  | def getGitCommit() { | 
|  | git_commit = sh ( | 
|  | script: 'git rev-parse HEAD', | 
|  | returnStdout: true | 
|  | ).trim() | 
|  | return git_commit | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Get remote URL | 
|  | * | 
|  | * @param name  Name of remote (default any) | 
|  | * @param type  Type (fetch or push, default fetch) | 
|  | */ | 
|  | def getGitRemote(name = '', type = 'fetch') { | 
|  | gitRemote = sh ( | 
|  | script: "git remote -v | grep '${name}' | grep ${type} | awk '{print \$2}' | head -1", | 
|  | returnStdout: true | 
|  | ).trim() | 
|  | return gitRemote | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Change actual working branch of repo | 
|  | * | 
|  | * @param path            Path to the git repository | 
|  | * @param branch          Branch desired to switch to | 
|  | */ | 
|  | def changeGitBranch(path, branch) { | 
|  | dir(path) { | 
|  | git_cmd = sh ( | 
|  | script: "git checkout -b ${branch}", | 
|  | returnStdout: true | 
|  | ).trim() | 
|  | } | 
|  | return git_cmd | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Commit changes to the git repo | 
|  | * | 
|  | * @param path            Path to the git repository | 
|  | * @param message         A commit message | 
|  | */ | 
|  | def commitGitChanges(path, message) { | 
|  | dir(path) { | 
|  | sh( | 
|  | script: 'git add -A', | 
|  | returnStdout: true | 
|  | ).trim() | 
|  | git_cmd = sh( | 
|  | script: "git commit -m '${message}'", | 
|  | returnStdout: true | 
|  | ).trim() | 
|  | } | 
|  | return git_cmd | 
|  | } | 
|  |  | 
|  |  | 
|  | /** | 
|  | * Push git changes to remote repo | 
|  | * | 
|  | * @param path            Path to the git repository | 
|  | * @param branch          Branch on the remote git repository | 
|  | * @param remote          Name of the remote repository | 
|  | */ | 
|  | def pushGitChanges(path, branch = 'master', remote = 'origin') { | 
|  | dir(path) { | 
|  | git_cmd = sh( | 
|  | script: "git push ${remote} ${branch}", | 
|  | returnStdout: true | 
|  | ).trim() | 
|  | } | 
|  | return git_cmd | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Mirror git repository, merge target changes (downstream) on top of source | 
|  | * (upstream) and push target or both if pushSource is true | 
|  | * | 
|  | * @param sourceUrl      Source git repository | 
|  | * @param targetUrl      Target git repository | 
|  | * @param credentialsId  Credentials id to use for accessing source/target | 
|  | *                       repositories | 
|  | * @param branches       List or comma-separated string of branches to sync | 
|  | * @param followTags     Mirror tags | 
|  | * @param pushSource     Push back into source branch, resulting in 2-way sync | 
|  | * @param pushSourceTags Push target tags into source or skip pushing tags | 
|  | * @param gitEmail       Email for creation of merge commits | 
|  | * @param gitName        Name for creation of merge commits | 
|  | */ | 
|  | def mirrorGit(sourceUrl, targetUrl, credentialsId, branches, followTags = false, pushSource = false, pushSourceTags = false, gitEmail = 'jenkins@localhost', gitName = 'Jenkins') { | 
|  | if (branches instanceof String) { | 
|  | branches = branches.tokenize(',') | 
|  | } | 
|  |  | 
|  | def ssh = new com.mirantis.mk.Ssh() | 
|  | ssh.prepareSshAgentKey(credentialsId) | 
|  | ssh.ensureKnownHosts(targetUrl) | 
|  | sh "git config user.email '${gitEmail}'" | 
|  | sh "git config user.name '${gitName}'" | 
|  |  | 
|  | sh "git remote | grep target || git remote add target ${TARGET_URL}" | 
|  | ssh.agentSh "git remote update --prune" | 
|  |  | 
|  | for (i=0; i < branches.size; i++) { | 
|  | branch = branches[i] | 
|  | sh "git branch | grep ${branch} || git checkout -b ${branch} origin/${branch}" | 
|  | sh "git branch | grep ${branch} && git checkout ${branch} && git reset --hard origin/${branch}" | 
|  |  | 
|  | sh "git ls-tree target/${branch} && git merge --no-edit --ff target/${branch} || echo 'Target repository is empty, skipping merge'" | 
|  | followTagsArg = followTags ? "--follow-tags" : "" | 
|  | ssh.agentSh "git push ${followTagsArg} target HEAD:${branch}" | 
|  |  | 
|  | if (pushSource == true) { | 
|  | followTagsArg = followTags && pushSourceTags ? "--follow-tags" : "" | 
|  | ssh.agentSh "git push ${followTagsArg} origin HEAD:${branch}" | 
|  | } | 
|  | } | 
|  |  | 
|  | if (followTags == true) { | 
|  | ssh.agentSh "git push target --tags" | 
|  |  | 
|  | if (pushSourceTags == true) { | 
|  | ssh.agentSh "git push origin --tags" | 
|  | } | 
|  | } | 
|  | } |