Skip to content

Instantly share code, notes, and snippets.

@tijn
Forked from ChrisLundquist/splitter.rb
Last active December 15, 2015 18:09
Show Gist options
  • Save tijn/5301258 to your computer and use it in GitHub Desktop.
Save tijn/5301258 to your computer and use it in GitHub Desktop.
split off subdirectories of a git repo to their own repo.
#!/usr/bin/env ruby
# preliminary:
#
# git clone remote_repo repo
# cd repo
# for remote in `git branch -r | grep -v master `; do git checkout --track $remote ; done
def git_repo(subdir)
if File.directory?(subdir + "/.git")
File.absolute_path(subdir)
else
git_repo(subdir + "/..")
end
end
def subdirectory(origin, subdir)
o = File.absolute_path(origin).split("/")
s = File.absolute_path(subdir).split("/")
while o.first == s.first
o.shift
s.shift
end
s.join('/') + '/'
end
def track_all_branches!
system 'for remote in `git branch -r | grep -v master `; do git checkout --track $remote ; done'
system 'git checkout master'
end
# remove merged branches
# the current directory needs to be a git repo
def remove_merged_branches!
`git checkout master`
`git branch --merged`.each_line do |merged_branch|
next if merged_branch.include?("*") # * designates the branch we're on
puts "\tdeleting merged branch '#{merged_branch.strip}'..."
`git branch -d #{merged_branch.strip}`
end
end
folders = ARGV
pwd = Dir.pwd
folders.each do |folder|
repo = git_repo(folder)
name = folder.split("/").last
name = name.gsub("-","_")
puts "-" * 80, "Cloning #{folder}, #{name}..."
clone_command = "git clone #{repo} #{name}"
puts clone_command
system clone_command
subdir = subdirectory(repo, folder)
puts "-" * 80, "Filtering... #{subdir}"
Dir.chdir name
filter_command = "git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter #{subdir} -- --all"
# system filter_command
`#{filter_command} 2>&1`.each_line do |line|
# for all branches that look like
# WARNING: Ref 'refs/remotes/origin/photo_bouncing' is unchanged
# we should delete that branch.
puts "\n"
if line =~ /Ref \'refs\/remotes\/origin\/([\w\_\-]+)\' was rewritten/
puts "Keeping '#{$1}':\t(#{line.strip})"
system "git checkout #{$1}"
else
puts "Ignoring (#{line.strip})"
end
end
puts "-" * 80, "Cleaning..."
remove_merged_branches!
`git reset --hard`
`git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d`
`git reflog expire --expire=now --all`
`git gc --aggressive --prune=now`
`git remote rm origin`
# # origin_command = "git remote add origin #{BASE_REMOTE_URL}/#{name}.git"
# # system origin_command
# # `git push origin master`
puts "Done."
Dir.chdir pwd
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment