Skip to content

Instantly share code, notes, and snippets.

@mnemnion
Last active January 28, 2020 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mnemnion/3f039e5831e9bd7022e68ac429a91046 to your computer and use it in GitHub Desktop.
Save mnemnion/3f039e5831e9bd7022e68ac429a91046 to your computer and use it in GitHub Desktop.
Move files to a different repo with history
#! /bin/bash
# Usage:
# ./git-move.sh path1/ path2/... path/to/destination/repo
args=("$@")
# All but last argument:
paths=("${args[@]::${#args[@]}-1}")
# Last argument:
dest="${args[${#args[@]}-1]}"
echo "creating patch for paths: ${paths[@]}"
echo "moving to destination: $dest"
# Iterate path arguments and append to tmpfile:
for p in "${paths[@]}"
do
git log --name-only --pretty="format:" --follow -- "$p" >> __LOGNAMES_TMP1290
done
cat __LOGNAMES_TMP1290 | sort -u | \
xargs git log --pretty=email --patch-with-stat --reverse --full-index --binary -m --first-parent -- > "$dest/_patch_"
trash __LOGNAMES_TMP1290
echo "moving to destination repo at $dest"
cd "$dest"
echo "applying patch"
git am -s --committer-date-is-author-date < _patch_
trash _patch_
echo "OK"
@mnemnion
Copy link
Author

mnemnion commented Jan 7, 2020

Based on this answer on Stack.

Notes:

  • This preserves the date of each commit, but:
    • git log will show commits in the order they are made, not date order
    • This can be solved with a rebase, I think
    • Possibly with some sort of flag? log is monstrously complex...
  • Best behaved copying onto a clean repo, so useful for breaking out some code into its own project
    • If you're copying it onto an existing repo, make sure you don't have any name collisions, or things will get messy
    • Probably a good idea to make a branch if copying onto an existing repo, at a bare minimum.
    • If there are name collisions, move them out of the way with git mv, commit, run script, hope for the best
    • This script has been tried onto a clean git init repo only
  • Results not guaranteed!
  • trash can be replaced with rm, or better yet, install it. Nondestructive removal is a nice thing to have.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment