Using Git to Pull Single Files From a Remote

Maintaining public and private versions of a repository

Posted by Nate Eckerson on July 18, 2019 · 2 mins read

I had finished laying out all pages of the Shopify/starter-theme with Bootstrap 4. The finished project represented many hours of work, and I wanted to share the new slate-bootstrap-theme with other members of the Shopify community.

A number of changes had been made for a specific storefront. To make the theme available to the public, I had to strip these changes out and create a separate repository with its own commit history. Going forward, I wanted to make it possible for updates in one theme to be copied over to the other.

Here’s how to set this up in Git!

Disclaimer: Setting up this workflow was straightforward, since both repositories had an identical directory structure with many of the same files. This would not work if you were trying to pull in files that did not exist in both repositories, or had diverging directory structures.

Setup

First, I created a new repository and set up the theme files. Changes specific to the private storefront were removed. When this process was finished, I pushed the repo up to Github.

Next I added the private theme as a remote.

git remote add private-theme git@github.com:neckerson/private-theme.git

Workflow

When a change is made to the private theme, I cd into the public theme directory and fetch the theme files.

git fetch private-theme

At this point the files have been copied into the private-theme/master branch, but none of them have been applied. Differences can be compared by running git diff, like so:

git diff private-theme/master master

You could create a new branch for merging the changes. For the sake of brevity, I’ll merge them into master. In this example, I’m grabbing changes made to theme.js. Use git checkout with the --patch flag. This lets you use the interactive interface to show the “diff” output and choose which hunks to use in the result.

git checkout private-theme/master -p src/scripts/layout/theme.js

After completing checkout, the changes have been staged and are ready to be committed.

git commit

Final Thoughts

With another project, it might have been possible to duplicate the private theme repository and add it as a remote. In this scenario, pulling changes from the private theme into the public version would be as simple as running…

git fetch private-theme
git merge private-theme/master

This cannot be done when the two commit histories diverge, as in this instance.