Search code examples
gitrebaseformat-patch

format-patch works reasonably well, looking for a better way


I have two branches that are different enough that rebasing seems to not work -- or I don't know how to do it.

I have a "public" branch with a bunch of files removed (using filter-branch). Even though most of the commits match up in terms of deltas, the commit ids are all different. I've tried quite a few methods to pull changes from my dev branch to my public branch... I find it hard to believe it can do what I want it to do -- but I suspect I just don't know how to do it. In any case, this works fine, but seems wrong.

git checkout dev
git format-patch --stdout last_sync_tag > catchup.mbox
git checkout public
git am catchup.mbox
git --skip # talks about a missing file
git --skip # talks about a missing file
git --skip # talks about a missing file

Any tips or suggestions, which will probably include not filter-branching out files you don't want on the public branch (though, how do you then get rid of them?), are welcome.

My tree(s) look more or less like this:

dev: a-b-c-d-e-f-g-h-i-j-k
pub: t-u-v-w-x

t ≅ a, u ≅ c, v ≅ d, w ≅ e, x ≅ g. i,j,k are new patches I'd like to move over.

checkout pub
rebase --onto pub i  # I really expected this to work

Solution

  • Git's cherry-pick command may be useful. I haven't used it in your situation but I think it should work. The only pain is that it's not designed to work over a range of commits so if you want to script/automate it you'd have to use something like git rev-list.

    Again, I haven't tried this but a bash script like this may give you a good starting point

    git checkout public
    for rev in $(git rev-list --reverse last_sync_tag..dev) ; do
       git cherry-pick $rev && git tag -f last_sync_tag $rev || exit 1
    done