I am using the Aurelia skeleton which contains various project setups for different purposes, but it is more of a general question of how you would do something with git lik
My usual workflow is to create a dedicated branch from which to track the upstream project. You can cherry pick what you want onto that branch and create a pull request without muddying the template with your project specifics.
First thing, go ahead and fork aurelia/skeleton-navigation
so you can easily issue a pull request through Github's GUI.
Clone your fork of the project with remote named upstream
in a new folder called skeleton-typescript
git clone -o upstream git@github.com:YOUR_GITHUB_USERNAME/skeleton-navigation.git skeleton-typescript
cd skeleton-typescript
Rename master branch.
git branch -m asmaster
Create a new repository for skeleton-typescript
Tip: You can do this right from the command line using Github's API with something like curl
curl --data '{"name":"skeleton-typescript"}' -u YOUR_GITHUB_USERNAME https://api.github.com/user/repos
Add the remote.
git remote add origin git@github.com:YOUR_GITHUB_USERNAME/skeleton-typescript.git
Split the repo into a subtree (see source code for man page) which will contain a new tree with all the commit history of files in the prefix
directory.
git subtree split --prefix=skeleton-typescript
This will print out a single commit ID which is the HEAD
of the subtree.
539d913a8cf9b34b644273b5cdb480359553247c
Create your master branch from that commit.
git checkout -b master 539d913a8cf9b34b644273b5cdb480359553247c
Push to and track your new repo.
git push -u origin master
Commit some work on skeleton-typescript
echo "notable contribution" >> file.txt
git add .
git commit -m "backport test commit"
git push origin master
Checkout the upstream super-project branch, and cherry-pick the subtree commits.
git checkout asmaster
git cherry-pick -x --strategy=subtree master
git push upstream asmaster:master
Now you can issue a pull request from your upstream fork YOUR_GITHUB_USERNAME/skeleton-navigation:master
branch to their aurelia/skeleton-navigation:master
branch.
Now there's going to be updates no doubt to your upstream's upstream (aurelia/skeleton-navigation:master
) which will include updates to your subtree's skeleton-typescript
folder.
Add another remote to track the original project.
git remote add upupstream git@github.com:aurelia/skeleton-navigation.git
Note that you now have 3 remotes in your local repository.
git remote -v
origin git@github.com:YOUR_GITHUB_USERNAME/skeleton-typescript.git (fetch) origin git@github.com:YOUR_GITHUB_USERNAME/skeleton-typescript.git (push) upstream git@github.com:YOUR_GITHUB_USERNAME/skeleton-navigation.git (fetch) upstream git@github.com:YOUR_GITHUB_USERNAME/skeleton-navigation.git (push) upupstream git@github.com:aurelia/skeleton-navigation.git (fetch) upupstream git@github.com:aurelia/skeleton-navigation.git (push)
Pull down updates.
git checkout asmaster
git pull upupstream master
Split off the subtree again and grab the HEAD commit.
git subtree split --prefix=skeleton-typescript
095c0c9f7ed06726e9413030eca4050a969ad0af
Switch back to subproject.
git checkout master
If you have never backported changes, then a notable attribute of git subtree split
is that you'll have the exact same hash commit history, so you can fast forward merges without rewriting history. From the docs:
Repeated splits of exactly the same history are guaranteed to be identical (i.e. to produce the same commit ids). Because of this, if you add new commits and then re-split, the new commits will be attached as commits on top of the history you generated last time, so git merge and friends will work as expected.
git merge 095c0c9f7ed06726e9413030eca4050a969ad0af
However, if you have already backported cherry-picked updates, or any other changes to the subtree history, then you'll want to rebase changes, otherwise you'll have duplicate commits.
git rebase 095c0c9f7ed06726e9413030eca4050a969ad0af