11#! /usr/bin/env bash
22
3- # / ==============================================================================
3+ # = ==============================================================================
44# @TODO: Use named parameters instead of relying on parameter order
55# ------------------------------------------------------------------------------
66# @TODO: Add parameter to set author
1212# @FIXME: Add "aggressive" mode that creates a commit on the source branch (?before/after? merge)
1313# of the source file with all of the lines from the split file removed.
1414# - Using grep?
15- # - Programatically creating a git patch?
15+ # - Programmatically creating a git patch?
1616# - Doing a "reverse" patch? (http://stackoverflow.com/questions/16059771/reverse-apply-a-commit-to-working-copy)
1717# - Creating a reverse diff? (http://stackoverflow.com/a/3902431/153049)
1818# - Use patch created with GNU diff and use patch --reverse? (http://www.gnu.org/software/diffutils/manual/html_node/Reversed-Patches.html)
1919# So many options.
2020#
2121# grep -Fvxf <remove> <all-lines>
22- # / ==============================================================================
22+ # = ==============================================================================
2323
2424# /==============================================================================
2525# / GIT SPLIT FILE
3737# # Call --help for more details
3838# #
3939# / Usually when you want to split a file into several files under git, you would
40- # / lose the git history of this file. Often this is not desirable. The goal of
40+ # / loose the git history of this file. Often this is not desirable. The goal of
4141# / this script is to enable splitting one file under Git revision control into
42- # / multiple files whilst keeping the files git history intact.
42+ # / multiple files whilst keeping the file's git history intact.
4343# /
4444# / For this script to work, you need to first create a folder that contains the
4545# / end result you want. This means you need to manually split the content of the
5656# / ------------------------------------------------------------------------------
5757# / The following ExitCodes are used:
5858# /
59- # / 0 : Everything OK
60- # / 64 : Undefined Error
59+ # / 0 : Everything OK
60+ # / 64 : Undefined Error
6161# /
6262# / 65 : Not enough parameters given
6363# / 66 : The given root file does not exist
@@ -128,7 +128,7 @@ error() {
128128# ==============================================================================
129129# sed -l basically makes sed replace and buffer through stdin to stdout
130130# so you get updates while the command runs and dont wait for the end
131- # e.g. npm install | indent
131+ # e.g. npm install
132132# ------------------------------------------------------------------------------
133133indent () {
134134 # if an arg is given it's a flag indicating we shouldn't indent the first line,
@@ -233,6 +233,8 @@ shortUsage() {
233233# ------------------------------------------------------------------------------
234234fullUsage () {
235235 grep ' ^#/' < " $0 " | cut -c4-
236+
237+ shortUsage
236238}
237239# ==============================================================================
238240
@@ -342,7 +344,7 @@ getCurrentBranch() {
342344
343345commit () {
344346 printStatus ' Creating commit'
345- git commit --author=" ${g_sAuthor} " --message=" ${1} ." | indent
347+ git commit --author=" ${g_sAuthor} " --message=" ${1} ."
346348}
347349
348350createBranch () {
@@ -351,8 +353,8 @@ createBranch() {
351353 sBranchName=" ${1} "
352354 sStartBranch=" ${2} "
353355
354- # git checkout -b "${sBranchName}" "${sStartBranch}" | indent
355- git branch " ${sBranchName} " " ${sStartBranch} " | indent
356+ # git checkout -b "${sBranchName}" "${sStartBranch}"
357+ git branch " ${sBranchName} " " ${sStartBranch} "
356358}
357359
358360createSourceBranch () {
@@ -375,7 +377,7 @@ createSplitBranch() {
375377
376378checkoutBranch () {
377379 printStatus " Switching to ${2} branch"
378- git checkout " ${1} " | indent
380+ git checkout " ${1} "
379381}
380382
381383checkoutSplitBranch () {
@@ -408,16 +410,19 @@ mergeSplitBranch() {
408410 # shellcheck disable=SC2086
409411 if [[ -n " $( git show-ref refs/heads/${sBranchName} ) " ]]; then
410412 printStatus " Branch '${sBranchName} ' exists"
411- git merge --no-ff --no-edit -X theirs " ${sBranchName} " | indent || iResult=" $? "
412413
413- if [[ " ${iResult} " -eq 0 ]]; then
414- printStatus ' No merge conflict'
415- else
414+ (
415+ git merge --no-ff --no-edit -X theirs " ${sBranchName} " \
416+ && printStatus ' No merge conflict'
417+ ) || (
416418 printStatus ' Merge conflict occurred. Attempting to resolve.'
417- git add -- " ${g_sSourceFilePath} " | indent
418-
419- commit " Merging split file '${g_sSourceFileName} '"
420- fi
419+ git add -- " ${g_sSourceFilePath} " \
420+ && commit " Merging split file '${g_sSourceFileName} '"
421+ ) || (
422+ printStatus ' Merge conflict remains. Attempting to resolve more aggressively.'
423+ git add $( cat git-status.log | grep -o -E ' added by us: .*' | cut -d ' :' -f 2) \
424+ && commit " Merging split file '${g_sSourceFileName} '"
425+ )
421426 else
422427 printStatus " Branch does not exist. No need to merge"
423428 fi
@@ -430,7 +435,7 @@ renameFile() {
430435
431436 if [[ ! -f " ${g_sSourceFilePath} " ]]; then
432437 printStatus " File '${g_sSourceFilePath} ' does not exist. Checking out from '${g_sRootBranch} '"
433- git checkout " ${g_sRootBranch} " -- " ${g_sSourceFilePath} " | indent
438+ git checkout " ${g_sRootBranch} " -- " ${g_sSourceFilePath} "
434439 fi
435440
436441 if [[ ! -d " ${g_sTargetDirectory} " ]]; then
@@ -443,7 +448,7 @@ renameFile() {
443448 printStatus " File is root file '${g_sSourceFileName} ', no need to rename"
444449 else
445450 printStatus " Creating separate file for '${sFile} '"
446- git mv " ${g_sSourceFilePath} " " ${g_sTargetDirectory} /${sFile} " | indent
451+ git mv " ${g_sSourceFilePath} " " ${g_sTargetDirectory} /${sFile} "
447452 commit " Adds separate file for '${sFile} '"
448453 fi
449454}
@@ -464,15 +469,15 @@ commitFileContent() {
464469 fi
465470
466471 cat " ${g_sSplitDirectory} /${sFile} " > " ${sTargetFile} "
467- git add " ${sTargetFile} " | indent
472+ git add " ${sTargetFile} "
468473 commit " ${sMessage} "
469474}
470475
471476createSubBranches () {
472477 local sFile
473478
474479 printTopic ' Creating sub-branches'
475- for sFile in ${g_sSplitDirectory} /* ; do
480+ for sFile in " ${g_sSplitDirectory} /" * ; do
476481 # if [[ "${sFile}" = "${g_sSourceFileName}" ]];then
477482 # printStatus "Skipping branch for source file '${g_sSourceFileName}'"
478483 # else
@@ -484,11 +489,11 @@ createSubBranches() {
484489splitFiles () {
485490 local sFile sFileName
486491
487- for sFile in ${g_sSplitDirectory} /* ; do
492+ for sFile in " ${g_sSplitDirectory} /" * ; do
488493 sFileName=$( basename " ${sFile} " )
489- # if [[ "${sFile }" = "${g_sSourceFileName}" ]];then
490- # printStatus "Skipping source file '${g_sSourceFileName}'"
491- # else
494+ if [[ " ${sFileName } " = " ${g_sSourceFileName} " ]]; then
495+ printTopic " Skipping source file '${g_sSourceFileName} '"
496+ else
492497 printTopic " Running split processing for file '${sFile} '"
493498
494499 printDebug " sFile = ${sFile} "
@@ -497,7 +502,7 @@ splitFiles() {
497502 checkoutSplitBranch " ${sFile} "
498503 renameFile " ${sFileName} "
499504 commitFileContent " ${sFileName} "
500- # fi
505+ fi
501506 done
502507}
503508
@@ -508,8 +513,8 @@ mergeSplitBranches() {
508513
509514 checkoutSourceBranch
510515
511- for sFile in ${g_sSplitDirectory} /* ; do
512- if [[ " ${sFile} " = " ${g_sSourceFileName} " ]]; then
516+ for sFile in " ${g_sSplitDirectory} /" * ; do
517+ if [[ " $( basename $ {sFile}) " = " $( basename $ {g_sSourceFileName}) " ]]; then
513518 printTopic " Skipping source file '${g_sSourceFileName} '"
514519 else
515520 printTopic " Running merge processing for file '${sFile} '"
@@ -524,33 +529,38 @@ runCleanup() {
524529 local sBranchName sFile
525530
526531 if [[ " ${g_sSourceBranch:- } " && " ${g_sSplitDirectory:- } " ]]; then
527- read -n1 -p ' Remove all created branches ? (y/n) ' sContinue
532+ read -n1 -p ' Cleanup all the things ? (y/n) ' sContinue
528533 echo " "
529534
530535 if [[ " ${sContinue} " = ' y' ]]; then
531536 printStatus ' Removing all the split branches that were created'
532537
533- git branch -D " ${g_sSourceBranch} " | indent
538+ if [[ ${g_bInsideGitRepo} = true && " ${g_sRootBranch} " != " $( getCurrentBranch) " ]]; then
539+ git merge --abort
540+ checkoutRootBranch
541+ fi
542+
543+ git branch -D " ${g_sSourceBranch} "
534544
535- for sFile in ${g_sSplitDirectory} /* ; do
545+ for sFile in " ${g_sSplitDirectory} /" * ; do
536546 sBranchName=$( createBranchName " ${sFile} " )
537547
538548 # shellcheck disable=SC2086
539549 if [[ -n " $( git show-ref refs/heads/${sBranchName} ) " ]]; then
540550 # Branch exists
541- git branch -D " ${sBranchName} " | indent
551+ git branch -D " ${sBranchName} "
542552 fi
543553 done
544554 sBranchName=$( createBranchName " ${g_sSourceFileName} " )
545555
546556 # shellcheck disable=SC2086
547557 if [[ -n " $( git show-ref refs/heads/${sBranchName} ) " ]]; then
548558 # Branch exists
549- git branch -D " ${sBranchName} " | indent
559+ git branch -D " ${sBranchName} "
550560 fi
551561
552562 else
553- printStatus ' Leaving all branches in place .'
563+ printStatus ' Leaving everything as-is .'
554564 fi
555565 fi
556566
@@ -559,7 +569,7 @@ runCleanup() {
559569
560570printHeader () {
561571
562- printMessage " running $0 "
572+ printMessage " running $( basename $0 ) "
563573 printMessage " for source file ${g_sSourceFilePath} "
564574 printMessage " with source directory ${g_sSplitDirectory} "
565575 printMessage " to target directory ${g_sTargetDirectory} "
@@ -591,21 +601,27 @@ run() {
591601 # Process all non-source files
592602 createSubBranches
593603 splitFiles
594-
595- # ---
596- # @TODO: Utilize the strategy flag.
597- # ---
598- # printTopic "Running split process for source file '${g_sSourceFileName}'"
599- # checkoutSourceBranch
600- # commitFileContent "${g_sSourceFileName}"
601-
602604 mergeSplitBranches
603- # @NOTE: If a branch for g_sSourceFileName is present we need to merge that last
605+
606+ # Process the source file
607+ printTopic " Running split process for source file '${g_sSourceFileName} '"
608+ checkoutSourceBranch
609+
610+ if [[ ${g_sStrategy} = ' KEEP' ]]; then
611+ echo ' @CHECKME: Nothing to do?'
612+ elif [[ ${g_sStrategy} = ' MOVE' ]]; then
613+ commitFileContent " ${g_sSourceFileName} "
614+ elif [[ ${g_sStrategy} = ' DELETE' ]]; then
615+ git rm " ${g_sSourceFilePath} "
616+ commit " Removes '${g_sSourceFilePath} ' file that has been split."
617+ else
618+ error " Unsupported merge strategy '${g_sStrategy} '" 70
619+ fi
604620 mergeSplitBranch " ${g_sSourceFileName} "
605621
606622 printTopic " Merging source branch '${g_sSourceBranch} ' into the root branch '${g_sRootBranch} '"
607623 checkoutRootBranch
608- git merge --no-ff --no-edit " ${g_sSourceBranch} " | indent
624+ git merge --no-ff --no-edit " ${g_sSourceBranch} "
609625 else
610626 printMessage ' Aborting.'
611627 fi
@@ -633,10 +649,6 @@ finish() {
633649 printDebug " Not in a git repo"
634650 fi
635651
636- if [[ ${g_bInsideGitRepo} = true && " ${g_sRootBranch} " != " $( getCurrentBranch) " ]]; then
637- checkoutRootBranch
638- fi
639-
640652 runCleanup
641653
642654 printMessage ' Done.'
@@ -671,7 +683,7 @@ export PS4='$(printf "%04d: " $LINENO)'
671683
672684registerTraps
673685
674- handleParams " ${@:- } "
686+ handleParams " ${@ } "
675687
676688registerDebugTrap
677689
0 commit comments