Question

I have two repos. Origin is a fork of Upstream. What I'm trying to do is replay a specific sequence of commits from the upstream branch back onto my origin/master. From what I've been reading, while cherry-pick does allow for ranges -- it does not have a way to control what branch you're pulling the ranges from So, I'm attempting to do this using rebase --onto. Here's how I'm going about it.

  1. I checkout the upstream branch (git checkout upstream/feature). This sends me to a headless state.

  2. I then create a temporary branch from this headless state (git checkout -b temp).

  3. Now I want to replay all the commits on the upstream/feature branch from HEAD back to a tag. I'm doing this running the command: git rebase --onto master start_tag^.

It seems like this should replay all the commits starting from start_tag upto head of upstream/feature (now branch temp). The rebase runs and even says it's replaying the correct commits in the output and finishes with no error. However, when I checked back over on master the new commits weren't there. Looking at my temp branch, it looks like it just replayed the commits back over themselves. They're all still there, but they now have new commit IDs.

Any idea how to get a range of commits from an upstream branch onto a local branch? I can't tell why the rebase --onto isn't playing them on top of master.

Edit: So why am I doing this?

The question has come up of why I'm trying to do it this way. Basically, I've fallen down the rabbit hole and am doing my best to manage the mess I've made. Here's the story.

We started out with an original Joomla site (call it repo A). All was going along well and the client decided they wanted 3 more sites that were supposedly going to be the same with just some minor styling changes. So, I forked three repos (repo B, repo C, repo D) off of my original repo A.

As time went along, there were some changes to Repo A the were unique to it and others I wanted to send down to the forks. To share changes among all repos I created a shared branch. Then on my downstream repos I could just pull the shared branch from upstream repo A.

More time passed and these sites moved further and further apart. What I wound up running into was there were components used in repo B that weren't needed in repo C. Similarly, some of the components were needed in repo B AND repo C, etc. In my naivety I decided it would be easier to manage if I could just pull individual components into the forks. In a dream world git submodules would have been the way I went, but I can't use those in Joomla because of they way it's directory is structured (there isn't just one folder I can jump into that houses all the component files). I ultimately decided that I'd spin off my individual components into their own branches (branch componentY, branch componentZ). I had to branch off of repoA master because there were ancestor commits that were needed in the component branches that weren't over in the repoA shared branch.

In my downstream fork repo B I now pull in generic changes from the repoA shared branch. I also need to pull in new changes from the repoA component branches. The problem I'm running into is that I can't simply merge in repoA componentZ because that will bring in all the commits that were on master prior to when I created the repoA componentZ branch. I tagged the first componentZ commit that was from when I branched off as start_tag.

Circling back to my original question, so I'm now down on repo B. I've successfully pulled in repoA shared branch and merged. Now I'm looking to pull in (merge would be ideal, but I don't think it works in this situation) the commits on repoA componentZ branch from the HEAD of that branch to the commit I've tagged as start_tag.

So, yeah, quite the mess; but that's what I'm working with right now.

Was it helpful?

Solution 2

I doubt anyone out there is going to get themselves into quite the same mess as me, but here's how I handled this situation if it helps others out there. I found that patching allows me to take a range of commits on a branch and apply them elsewhere. Definitely not pretty, but it's what I had to do to get the result I needed.

  1. Checkout upstream feature branch git checkout upstream/feature
  2. Create a patch for the range of commits I'm looking for git format-patch last_pull_tag^..HEAD
  3. Switch back to master git checkout master
  4. Apply patches on top of master git am --3way *.patch

If using this command make sure you delete the patches after you've applied them so you don't apply them at a later date.

OTHER TIPS

You really shouldn't rebase work from an upstream repo on top of your own work, because that basically overwrites the work from the upstream repo, so they can no longer accept any pull-requests that you make if those pull-requests contain their overwritten commits.

If you want to sync your local work with new changes from upstream, you either need to merge that work in, or rebase your own work on top of the upstream work.

Merging:

git checkout master
git merge upstream/feature
git push origin master

Rebasing:

git checkout myFeatureBranch
git rebase upstream/feature
git push origin myFeatureBranch
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top