Skip to content

Instantly share code, notes, and snippets.

@psmay
Created November 21, 2014 15:08
Show Gist options
  • Save psmay/09da9c805a5493119ad8 to your computer and use it in GitHub Desktop.
Save psmay/09da9c805a5493119ad8 to your computer and use it in GitHub Desktop.
Crude subdir to repository bridge
#!/bin/bash
# For our convenience since this is repeated
github_user="someuser"
our_label="loose-repo-name"
# Our local clone of the parent repo will be configured as a sparse checkout
# to check out only the specified subdir
parent_url=https://github.com/somebody/something.git
parent_branch=master
parent_dir="$HOME/src/${our_label}_parent"
parent_subdir="subdir/Something/"
# The child repo's basic layout is intended to mimic what would happen if
# you checked out the parent repo, copied its subdir to a new location, and
# started a new repo inside that copy.
child_url=git@github.com:$github_user/${our_label}.git
child_dir="$HOME/prj/${our_label}"
child_branch=upstream-master
bq='`'
create_empty_repo () {
local_dir="$1"
origin_url="$2"
git init "$local_dir" &&
(
cd "$local_dir" &&
git remote add origin "$origin_url"
)
}
create_and_switch_to_branch () {
local_dir="$1"
branch="$2"
(
cd "$local_dir" &&
git checkout -b "$branch"
)
}
switch_to_branch () {
local_dir="$1"
branch="$2"
(
cd "$local_dir" &&
git checkout "$branch"
)
}
add_dir_to_sparse_checkout () {
local_dir="$1"
subdir="$2"
(
cd "$local_dir" &&
git config core.sparsecheckout true &&
echo "$subdir" >> .git/info/sparse-checkout
)
}
clone_child_repo () {
# Clone the child repo.
# This will only work if the repo and branch both already exist.
git clone -b "$child_branch" "$child_url" "$child_dir"
}
new_child_repo () {
# Create a new repo for the child.
# Avoid doing this if the repo and branch already exist.
create_empty_repo "$child_dir" "$child_url" &&
create_and_switch_to_branch "$child_dir" "$child_branch"
}
setup_parent_repo () {
create_empty_repo "$parent_dir" "$parent_url" &&
add_dir_to_sparse_checkout "$parent_dir" "$parent_subdir"
}
# To be run at least every time the child is updated in the parent
update () {
# Update the parent repo
echo "Updating local copy of parent repo" &&
(
cd "$parent_dir" &&
git checkout "$parent_branch" &&
git pull origin "$parent_branch" &&
git clean -f -d -x
) &&
# Replace child repo's files with the parent repo
echo "Copying local parent over local child" &&
switch_to_branch "$child_dir" "$child_branch" &&
rsync -avz \
--exclude README.md \
--exclude .git \
--delete "$parent_dir/$parent_subdir" "$child_dir/" &&
# Think of a commit message
current_date="`date -u -Iseconds`" &&
commit_msg="Refreshed from $bq$parent_url$bq @ $bq$current_date$bq" &&
# Check in and push the changes
# (If nothing changed, no commit will occur)
echo "Committing local child" &&
(
cd "$child_dir" &&
git add -A &&
git commit -m "$commit_msg" &&
echo "Pushing local child" &&
git push -u origin "$child_branch"
)
}
# First run, if the child repo or branch doesn't exist yet remotely
#setup_parent_repo && new_child_repo && update
# First run, if the child repo or branch both exist remotely
#setup_parent_repo && clone_child_repo && update
# Subsequent runs
update
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment