Copy File and Preserve Path

Two bash solutions


While making changes to a theme for a static site generator, I changed files under a Git submodule included in the repo for my blog. (e.g. themes/beautifulhugo) That’s ideal for local testing, but not for version control. As a result, I cloned the repo for the theme to a directory separate from the one for my bloge (say, ~/beautifulhugo), and commit the changes there, then performed a Git submodule update so as to make the workflow clean.


To add proper support for TOC on Hugo sites, the following files in the Git submodule for my site theme have been created/edited.

  • layouts/partials/footer.html
  • static/js/fix-toc.js

At the root level of the repo for this site, Git views the modified submodule as dirty—to get things done, we have to get our hands dirty. To clean that up, copy the files to the separate repo (~/beautifulhugo) and reset the submodule to HEAD will do.

$ pwd
$ cp layouts/partials/footer.html ~/beautifulhugo/layouts/partials
$ cp static/js/fix-toc.js ~/beautifulhugo/static/js/fix-toc.js
$ git reset --hard HEAD

The problem with the above cp command is that we have to input the names of the directories in the relative path for each affected file twice. That’s inefficient and succumb to typos.


Server Fault question 180853 contains two feasible solutions.

  1. cp --parents: Mac OSX’s cp doesn’t offer this option.

    $ cp --parents layouts/partials/footer.html \
    > static/js/fix-toc.js ~/beautifulhugo
  2. rsync -R

    $ rsync -auvzR layouts/partials/footer.html \
    > static/js/fix-toc.js ~/beautifulhugo

No comment