Skip to content

Commit 4068b55

Browse files
committed
Adds the ability to declare a merge stategy.
1 parent 5147cdb commit 4068b55

File tree

1 file changed

+65
-53
lines changed

1 file changed

+65
-53
lines changed

src/git-split-file.sh

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
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
@@ -12,14 +12,14 @@
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
@@ -37,9 +37,9 @@
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
@@ -56,8 +56,8 @@
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
# ------------------------------------------------------------------------------
133133
indent() {
134134
# if an arg is given it's a flag indicating we shouldn't indent the first line,
@@ -233,6 +233,8 @@ shortUsage() {
233233
# ------------------------------------------------------------------------------
234234
fullUsage() {
235235
grep '^#/' <"$0" | cut -c4-
236+
237+
shortUsage
236238
}
237239
# ==============================================================================
238240

@@ -342,7 +344,7 @@ getCurrentBranch() {
342344

343345
commit() {
344346
printStatus 'Creating commit'
345-
git commit --author="${g_sAuthor}" --message="${1}." | indent
347+
git commit --author="${g_sAuthor}" --message="${1}."
346348
}
347349

348350
createBranch() {
@@ -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

358360
createSourceBranch() {
@@ -375,7 +377,7 @@ createSplitBranch() {
375377

376378
checkoutBranch() {
377379
printStatus "Switching to ${2} branch"
378-
git checkout "${1}" | indent
380+
git checkout "${1}"
379381
}
380382

381383
checkoutSplitBranch() {
@@ -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

471476
createSubBranches() {
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() {
484489
splitFiles() {
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

560570
printHeader() {
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

672684
registerTraps
673685

674-
handleParams "${@:-}"
686+
handleParams "${@}"
675687

676688
registerDebugTrap
677689

0 commit comments

Comments
 (0)