Skip to content

Instantly share code, notes, and snippets.

@rsaporta
Last active April 16, 2018 05:44
Show Gist options
  • Save rsaporta/aa4a5ffd5a4f0b075aff5cfa8880788a to your computer and use it in GitHub Desktop.
Save rsaporta/aa4a5ffd5a4f0b075aff5cfa8880788a to your computer and use it in GitHub Desktop.
## --------------------------------------------------------------------------------------------------- ##
## AUTHOR: Rick Saporta ##
## ##
## This code accompanies the medium article ##
## https://medium.com/@RickSaporta/git-when-dangling-branches-become-pesky-open-loops-697931b65118 ##
## ##
## --------------------------------------------------------------------------------------------------- ##
## these are all of the branches you have identified as stale
array_of_stale_branches=("branch_one" "branch_two" "branch_three" "etc")
## dev_branch is where the *final* clean version will live.
## for most repos, this is `master`
dev_branch=master
## We will be creating some temporary branches
## each of these serves a different purpose
## although all of them are safety precautions
tmp_DESTINATION=temp_cleaning/DESTINATION
tmp_STAGING=temp_cleaning/STAGING
tmp_master_copy=temp_cleaning/COPY_OF_MASTER
# BEGIN
## create and checkout a brand new branch from your dev_branch (we are going to call this new branch ${tmp_DESTINATION} to keep it organized)
git checkout -b ${tmp_DESTINATION} ${dev_branch}
# ITERATE. For each stale branch
stale_branch=${array_of_stale_branches[0]}
echo "------==== Beginning branch '${stale_branch}' ====------"
## create and checkout the STAGING branch, starting from the DESTINATION branch
git checkout -b ${tmp_STAGING} ${tmp_DESTINATION}
## see what files are going to be checked out
git diff --diff-filter=DMTUXB --name-status ${stale_branch}
## CHECKOUT the files from ${stale_branch}, but DO NOT COMMIT them
git diff --diff-filter=DMTUXB --name-only ${stale_branch} | tr '\n' '\0' | xargs -0 git checkout ${stale_branch}
# ---------------------------------------------------------------- #
# The Manual Part
# COMPARE the changes manually.
# In your favorite diff tool, confirm or discard the changes.
# It's likely that you will discard most changes (Otherwise, you would have merged them already)
#
# REMEMBER: If the changes you want are in RED (or -), then you should `Discard Local Changes` for that file or chunk.
## Then:
# COMMIT your changes. You can do this all at once, or piece-wise. I suggest the latter.
git commit -m 'Cleaning up ${stale_branch} - I copied and pasted'
# ---------------------------------------------------------------- #
# Back in the command line
## CHECK WHAT FILES HAVE BEEN RENAMED AND ADDED.
## More than likely there is no action that is needed from this, but it is good to double check.
### RENAMED
git diff --diff-filter=R --name-status ${stale_branch}
### ADDED (at times, this might be many, many files)
git diff --diff-filter=A --name-status ${stale_branch}
## MERGE the changes into the DESTINATION branch.
git checkout ${tmp_DESTINATION}
git merge --squash ${tmp_STAGING}
git commit -m 'Dangling ${stale_branch}'
## DELETE the staging branch
git branch -D ${tmp_STAGING}
## REMOVE the original stale_branch
git branch -d ${stale_branch} ## you might have to use `-D` instead of `-d`
## LOOK AT YOUR BRANCHES
git branch
# ITERATE --- repeat the abovefor next value of stale_branch
## ------------------------------------------- ##
# Final Cleanup
## Once you are all done cleaning up the different stale branches
## it’s time to merge them into master
## (or whichever branch you identify as your development branch)
## safety first: Create one more staging branch.
## This branch will take in all the merges in place of master.
git checkout -b ${tmp_master_copy} ${dev_branch}
stale_branch=${tmp_DESTINATION}
## repeat the itaretive process as above
## checkout the files. then confirm one last time that everything being added is correct.
# BEGIN FINAL ITERATION
## see what files are going to be checked out
## then CHECKOUT the files from ${stale_branch}, but DO NOT COMMIT them
git diff --diff-filter=DMTUXB --name-status ${stale_branch}
git diff --diff-filter=DMTUXB --name-only ${stale_branch} | tr '\n' '\0' | xargs -0 git checkout ${stale_branch}
# ---------------------------------------------------------------- #
# The Manual Part
# COMPARE the changes manually.
## Then:
# COMMIT your changes. You can do this all at once, or piece-wise. I suggest the latter.
git commit -m 'Cleaned up sevearl dangling branches'
# ---------------------------------------------------------------- #
# Back in the command line
## CHECK WHAT FILES HAVE BEEN RENAMED AND ADDED.
## More than likely there is no action that is needed from this, but it is good to double check.
## If your repo is large, there will be *many* files added
### RENAMED
git diff --diff-filter=R --name-status ${stale_branch}
### ADDED (at times, this might be many, many files)
git diff --diff-filter=A --name-status ${stale_branch}
# ---------------------------------------------------------------- #
# Almost done, go back to `master` and merge in the final changes
git checkout ${dev_branch}
git merge --no-ff ${tmp_master_copy}
## Lastly, clean up the branches
git branch
git branch -d ${tmp_master_copy}
git branch -D ${tmp_DESTINATION} ## needs to be forced, if you squashed the earlier commits
## Checkout your branches
git branch
git branch -r
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment