Browse Source

relocate folder in repo to targetrepo

master
pb 3 years ago
parent
commit
31595b7283
2 changed files with 252 additions and 8 deletions
  1. 5
    1
      cliverse.js
  2. 247
    7
      index.js

+ 5
- 1
cliverse.js View File

@@ -21,11 +21,15 @@ function nodeShellExec() {
if(opts.stdio !== 'ignore') {
child.stdout.setEncoding('utf8');
child.stderr.setEncoding('utf8');
child.stdout.on('data', (chunk) => { chunk.trim() === '' ? null : messages.push(chunk); /* console.log('d: ' + chunk) */ });
child.stdout.on('data', (chunk) => {
chunk.trim() === '' ? null : messages.push(chunk); /* console.log('d: ' + chunk) */
process.stdout.write( chunk )
});
child.on('error', (chunk) => { success = false; messages.push(chunk); /* console.error('e: ' + chunk) */ } );
child.stderr.on('data', (chunk) => {
if(messages.join('').indexOf('fatal: not a git repository') > -1) opts.haserrors = true;
messages.push(chunk);
process.stdout.write( chunk )
// console.error('stderr e: ' + chunk)
});
}

+ 247
- 7
index.js View File

@@ -63,6 +63,10 @@ var getShellTask = (command, args, options) => {
}

var callsheltask = (args) => { return () => { return nodeShellExec.apply(null, args) } }
var callgitbashtask = (args) => { return () => {
return nodeShellExec( `"${gitbash}"`, ['-c', `"${args[0]} ${args[1].join(' ')}"`], args[2]) }
}


var getTaskCheckExists = (command, options) => {
options = options || {}
@@ -516,6 +520,7 @@ var op = {
// git branch --set-upstream-to=elixir-unc/master master
// git push --set-upstream elixir-unc branch..
, 'set-url': (remotename, url) => {
// git remote set-url elixir-unc //10.10.5.60/gitrepo/chess/bbhverse
var pushable = processedArgs.pushable || false;
remotename = remotename || processedArgs._[1]
url = url || processedArgs._[2]
@@ -525,6 +530,7 @@ var op = {
if (pushable) {
return [
['git', ['remote', 'set-url', remotename, url + '/' + repo], { cwd: instanceroot + '/' + repo }]
, ['git', ['remote', `set-url`, '--push', remotename, url + '/' + repo], { cwd: instanceroot + '/' + repo }]
]
}
else {
@@ -533,6 +539,13 @@ var op = {

}

var x = (args) => {
return () => {
// console.log(args)
return nodeShellExec.apply(null, args)
}
// return Promise.resolve(true)
}
var perform_git_seturl = (dir) => {
op['is-git-repo'](dir).then((logEntry) => {
any(serial_perform_git_seturl(dir.name).map(x))
@@ -616,17 +629,17 @@ var op = {
var perform_git_remove = (dir) => {
op['is-git-repo'](dir).then((logEntry) => {
// console.log(code)
// if (code) {
if (logEntry.success) {
nodeShellExec('git', ['remote', 'get-url', remotename], { cwd: dir.name, stdio: 'ignore' }).then(() => {
any(serial_perform_git_remove(dir.name).map(x))
})
.catch((e) => {
console.log('skipped : ' + dir.name + ', reason : No remote named origin')
})
// }
}
// else console.log('Skipped : Not a Git Repo : ' + dir.name)
}).catch((e) => {
console.log('Failed : ' + dir.name)
// console.log('Failed : ' + dir.name)
})
}

@@ -693,6 +706,227 @@ var op = {
else return op['runas']()
}

, 'repo-relocate' : function(args){
// relocate a subfolder in source repo to same subfolder in target repo with history.

var args = args || {
remotebase : processedArgs._[4] || 'http://git.bbh/chess/'
, folder : processedArgs._[3] || 'server'
, sourcerepo : processedArgs._[2] || 'client'
, targetrepo : processedArgs._[1] || 'elixir-server'
}
var sourcerepooptions = { cwd: `${instanceroot}/relocate/${args.sourcerepo}`
// , stdio: ['pipe', process.stdout, process.stderr]
, inherit: true,
shell: true,
env: process.env
, runas: processedArgs.runas
}

return op['repo-split'](args).then(()=>{
return op['repo-merge'](args).then(()=>{
// cleanup folder from source.
var cmdseq = [
['rm', ['-rf', `${args.folder}`], sourcerepooptions ]
// commits have to intentional...
// , ['git', ['commit', '-a', '-m', `relocate folder ${args.folder} to ${targetrepo}`], sourcerepooptions ]
]

return any(cmdseq.map(callsheltask))
})
}).catch(e=>{console.error(e)})
}

, 'repo-split' : function(args) {
// https://gist.github.com/smdabdoub/17065c348289158277b5
/**
* Eg : folder, remotebase, sourcerepo, targetrepo
* args.folder = 'server'
* args.remotebase = 'https://git.bbh/chess/'
* args.sourcerepo = 'client'
* args.targetrepo = 'elixir-server'
*/

var args = args || {
folder : 'server'
, remotebase : 'http://git.bbh/chess/'
, sourcerepo : 'client'
, targetrepo : 'elixir-server'
}

var options = { cwd: `${instanceroot}/relocate`
// , stdio: ['pipe', process.stdout, process.stderr]
, inherit: true,
shell: true,
env: process.env
, runas: processedArgs.runas
}
var cmdseq = [
// create a temporary working dir in current folder where we started execution.
['mkdir', [ '-p', 'relocate']]
, ['git', ['clone', `${args.remotebase}${args.sourcerepo}`], options ]
, ['git', ['clone', `${args.sourcerepo}`, `relocate-${args.sourcerepo}-${args.folder}`], options]
, ['git', ['clone', `${args.remotebase}${args.targetrepo}`, `relocate-${args.targetrepo}-${args.folder}`], options]
]
return any(cmdseq.map(callsheltask)).then(() => {
// , ['git', ['subtree', 'split', '-P', `${args.folder}`, '-b', `relocate-${args.sourcerepo}-${args.folder}`], sourcerepooptions]
// split doesnt retain folder structure we need to move and commit ourselves through a branch to retain history...
// , ['git', [`checkout relocate-${args.sourcerepo}-${args.folder}`], sourcerepooptions]
// , ['mkdir', [`${args.folder}`], sourcerepooptions]
// , ['git', ['mv', `!(${args.folder})`, `${args.folder}`], sourcerepooptions ] // requires shopt -s extglob
// , ['git', ['commit', `-m`, 'Moved to same subfolder after subtree split in branch'] , sourcerepooptions]
// subtree split and filter-branch are options. We currently use repo-filter.
return op['filter-repo'](args)
}).catch(e=>{console.error(e); throw 'failed'})
}

, 'repo-merge' : function(args) {
// Merge source repo into target repo
var args = args || {
folder : 'server'
, remotebase : 'http://git.bbh/chess/'
, sourcerepo : 'client'
, targetrepo : 'elixir-server'
}

var sourcerepooptions = { cwd: `${instanceroot}/relocate/relocate-${args.sourcerepo}-${args.folder}`
// , stdio: ['pipe', process.stdout, process.stderr]
, inherit: true,
shell: true,
env: process.env
, runas: processedArgs.runas
}
var targetrepooptions = { cwd: `${instanceroot}/relocate/relocate-${args.targetrepo}-${args.folder}`
// , stdio: ['pipe', process.stdout, process.stderr]
, inherit: true,
shell: true,
env: process.env
, runas: processedArgs.runas
}

var cmdseq = [
['git', ['pull', `../relocate-${args.sourcerepo}-${args.folder}`, `master`, '--allow-unrelated-histories']
, targetrepooptions ]
// , ['git', ['push', targetrepooptions ] // manual push for now..
]
return any(cmdseq.map(callsheltask)).catch(e=>{console.error(e)})
}

, 'filter-repo' : function(args){
// Merge source repo into target repo
var args = args || {
folder : 'server'
, remotebase : 'http://git.bbh/chess/'
, targetrepo : 'elixir-server'
}
var targetrepooptions = { cwd: `${instanceroot}/relocate/relocate-${args.sourcerepo}-${args.folder}`
, inherit: true, shell: true
, env: process.env
, runas: processedArgs.runas
}

var cmdseq = [
// git checkout -b feature/merge-old-project
// git remote add src-project ../src-project
['git', ['filter-repo', '--path', `${args.folder}`], targetrepooptions ]
]
return any(cmdseq.map(callsheltask)).catch(e=>{console.error(e); throw 'failed' })
}

, 'filter-branch' : function(preservefolder, repo){
// https://stackoverflow.com/questions/359424/detach-move-subdirectory-into-separate-git-repository
// git subtree split -P <name-of-folder> -b <name-of-new-branch>
// Preserve a specific folder.
// PB : TODO -- filter-branch has known issues. Explore subtree and filter-repo...
/*
git clone repo reposplit
git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter {{folder}} -- --all
git remote rm origin
*/

throw 'filter-repo-history not yet implmented pls refer to manual commands in code.'
}

// , 'repo-merge-folder' : function(mergetarget, mergesource, mergefolder){
// // Merge repo2 into a subfolder in repo1
// // https://alexharv074.github.io/puppet/2017/10/04/merge-a-git-repository-and-its-history-into-a-subdirectory-of-a-second-git-repository.html
// // https://thoughts.t37.net/merging-2-different-git-repositories-without-losing-your-history-de7a06bba804
// /*
// cd repo1
// git remote add -f tempmergesource ../{{mergesource}}/.git
// git merge -s ours --no-commit tempmergesource/master --allow-unrelated-histories
// git read-tree --prefix={{mergefolder}} -u tempmergesource/master:
// git commit

// // Repair History
// // === git filter-branch --tree-filter '(echo === $GIT_COMMIT:; git ls-tree $GIT_COMMIT) >> /tmp/tree.log'
// #!/usr/bin/env bash

// first=ed4f16becc2f03820c164e0617bb98f12ff49ef0
// last=038e26e21bd60fa265d6637261f3bc918780d2e8
// subdir=server

// git filter-branch --tree-filter '
// first='"$first"'
// last='"$last"'

// subdir='"$subdir"'
// log_file=/tmp/filter.log

// [ "$GIT_COMMIT" = "$first" ] && seen_first=true

// if [ "$seen_first" = "true" ] && [ "$seen_last" != "true" ]; then
// echo "=== $GIT_COMMIT: making changes"
// files=$(git ls-tree --name-only $GIT_COMMIT)
// mkdir -p $subdir
// for i in $files; do
// mv $i $subdir || echo "ERR: mv $i $subdir failed"
// done
// else
// echo "=== $GIT_COMMIT: ignoring"
// fi \
// >> $log_file

// [ "$GIT_COMMIT" = "$last" ] && seen_last=true

// status=0 # tell tree-filter never to fail
// '

// git remote rm tempmergesource
// */
// // better alternative for history
// /**
// *
// git clone git@server.com:old-project.git
// git clone git@server.com:new-project.git
// cd old-project
// mkdir old-project
// git mv !(old-project) old-project
// ls -la and gt mv hidden files ....
// git commit -a -S -m “Moving old project into its own subdirectory”
// cd ../new-project
// git remote add old-project ../old-project
// git fetch old-project
// git checkout -b feature/merge-old-project
// git merge -S --allow-unrelated-histories old-project/master
// git push origin feature/merge-old-project
// git remote rm old-project
// */

// throw 'merge-repos not yet implmented pls refer to manual commands in code.'
// }

, 'pull' : (label) => {
// Usage :
// elxr pull -- Defaults to run config
@@ -1022,8 +1256,7 @@ var op = {

var performCloneAndCheckout = null;
// cant use git checkout -b it fails when branch already exists.
var performCheckout = performCloneAndCheckout = (def) => {
if (excludeCheckouts[def.repo]) return Promise.resolve({ 'skipped': true })
var performCheckout = performCloneAndCheckout = (def) => {if (excludeCheckouts[def.repo]) return Promise.resolve({ 'skipped': true })
return performPullOrCloneForBranch(def).then(()=>{
nodeShellExec('git', ['checkout', def.branch || checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV], {
@@ -1252,6 +1485,8 @@ var op = {

var g = {
'client': () => {
// ember new --skip-bower --no-welcome --skip-git -b {{blueprint}}

console.info('Creating new ember client named : ' + processedArgs._[2]);
var step1 = nodeShellExec('cmd', ['/c', 'ember', 'new', processedArgs._[2]], {
stdio: ['pipe', process.stdout, process.stderr],
@@ -1315,7 +1550,7 @@ var op = {
}
}

var util = require('util')
var util = require('util');
var cliname = 'elxr';
var ver = '1.1';
var help = `# list of commands... please refer dveloper documentation for ${cliname}
@@ -1911,7 +2146,7 @@ acquireElevationState().then(() => {


var noprerequisites = {
add : true
add : true, 'set-url' : true, 'repo-relocate' : true
}
var skipprereqs = {}
var maintask = () => {
@@ -1948,6 +2183,11 @@ acquireElevationState().then(() => {
var min = runtimestamp;
var collect = []
if(noprerequisites[processedArgs._[0]]
|| skipprereqs[processedArgs._[0]]
) {
return op[processedArgs._[0]]()
}

return detectInstance().then((detectedInstance)=>{


Loading…
Cancel
Save