splitsh / lite

Split a repository to read-only standalone repositories
MIT License
1.55k stars 69 forks source link

Pull request / CI workflow #24

Open aslakhellesoy opened 8 years ago

aslakhellesoy commented 8 years ago

Hi all,

Has anyone figured out how to combine mono/manyrepos with GitHub pull requests and CI? For my non-monorepo projects, each PR automatically gets built by Travis, which helps a lot with screening of pull requests.

I've got CI for all the manyrepos, but nothing in the monorepo where all PRs are received. Are there any tricks to automatically migrate monorepo PRs/branches to manyrepo PRs/branches? Any smart git hacks?

Cheers, Aslak

aslakhellesoy commented 8 years ago

Hi @fabpot - do you have any suggestions here? Is this something the non-lite version of splitsh does?

fabpot commented 7 years ago

This is out of the scope of this project. The full version helps moving PRs from the many repositories to the main one (not the other way around though). I might open source this feature as another command in the future if there is enough demand for it.

brianespinosa commented 6 years ago

@fabpot is there a centralized place you are keeping track of interest for this other than just emailing you? I've seen your talks on what appears to be a "full" version of split.sh and it looks exciting.

SpainTrain commented 6 years ago

@fabpot Would you be willing to describe at a high level how this command works? Perhaps with guidance an interested party could develop a PR for this feature. Thanks!

matthijsthoolen commented 5 years ago

@fabpot any updates on open-sourcing the full version or at least the feature for moving PRs from the many repo's to the main one?

mxr576 commented 5 years ago

Requesting update also :)

Mike-Dax commented 5 years ago

This works in theory because splitsh is stable in its resulting commit hashes. A commit made to a sub-repo moved up to the monorepo then back again should retain the same hash.

I'll document the progress I've made with this.

Split the mono-repo into two repositories and add them as remotes to the original monorepo. Pushing the branches to their respective remotes.

splitsh-lite --path ~/monorepo \
--prefix packages/subrepo-1 \
--target refs/heads/subrepo-1 

splitsh-lite --path ~/monorepo \
--prefix packages/subrepo-2 \
--target refs/heads/subrepo-2 

git remote add subrepo-1 https://github.com/Mike-Dax/monorepo-subrepo-1.git
git remote add subrepo-2 https://github.com/Mike-Dax/monorepo-subrepo-2.git

A PR will happen against subrepo-1.

From the monorepo's context (with subrepo-1 added as a remote so it has access to the commits), iterate over each commit of the PR in order.

Cherry pick the commit with the subtree option set, fastforwarding.

git cherry-pick -Xsubtree=packages/subrepo-1 2474879291a1770c42c87dc60aa00a8fc3d64c54 --ff

Explicitly grab all the data of the original commit and 'transfer' it to the cherry picked commit.

export GIT_AUTHOR_NAME=$(git --no-pager show -s --format='%an' 2474879291a1770c42c87dc60aa00a8fc3d64c54)
export GIT_AUTHOR_EMAIL=$(git --no-pager show -s --format='%ae' 2474879291a1770c42c87dc60aa00a8fc3d64c54)
export GIT_AUTHOR_DATE=$(git --no-pager show -s --format='%ai' 2474879291a1770c42c87dc60aa00a8fc3d64c54)
export GIT_COMMITTER_NAME=$(git --no-pager show -s --format='%cn' 2474879291a1770c42c87dc60aa00a8fc3d64c54)
export GIT_COMMITTER_EMAIL=$(git --no-pager show -s --format='%ce' 2474879291a1770c42c87dc60aa00a8fc3d64c54)
export GIT_COMMITTER_DATE=$(git --no-pager show -s --format='%ci' 2474879291a1770c42c87dc60aa00a8fc3d64c54)

git commit --amend --no-edit

This works as described in the slides with single commit PRs, the commit hash collides and the PR is automatically 'merged' by github.


When the commits are signed this doesn't work.

You can view how the commit hash is generated with:

(printf "commit %s\0" $(git cat-file commit 2474879291a1770c42c87dc60aa00a8fc3d64c54 | wc -c); git cat-file commit 2474879291a1770c42c87dc60aa00a8fc3d64c54)

Pass the output to that with | shasum to regenerate the commit hash.

If the commit is signed the gpg signature will be embedded in there.

I feel like it should be possible to keep that around? But it would have to survive a round-trip through splitsh. The signing signature would then fail in your monorepo but be valid in the public one?


It also doesn't seem to work properly if there are multiple commits in the PR.

Hitting 'rebase and merge' in the github UI doesn't create any new commits and marks it as merged however?