1

I'm working in a multi-developer environment on a repository which has a branch called "develop", which is updated frequently. However, there's a few issues with develop, and I'd like to create a branch on my local machine, say "custom_develop", where I can make a couple of commits I don't intend to push back to the main repository.

When I work on a feature branch, I'd like to start off by creating a branch of custom_develop called "feature/ticket-123", and create a couple of commits. Then, when I think I've finished my work on ticket 123, I want to make "feature/ticket-123" become a branch of "develop" rather than a branch of "custom_develop", so that I can create a pull request which will merge into develop on the remote server.

How can I do this in git?

If I try doing

git checkout develop

git checkout -b custom_develop

git commit -m "Commit I don't want to share"

git checkout -b feature/ticket-123

git commit -m "Ticket-123: Refactor"

git rebase develop

I get

Current branch feature/ticket-123 is up to date.

and the git log still includes the "Commit I don't want to share" commit.

Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
  • git rebase is what you need. See this for more details: http://stackoverflow.com/questions/14893399/rebase-feature-branch-onto-another-feature-branch – MadDoctor5813 Jun 03 '15 at 03:06
  • @MadDoctor5813 I tried what was suggested in that answer, and it doesn't do what I've asked for in this question. See the edited version of the question. – Andrew Grimm Jun 03 '15 at 08:07

1 Answers1

2

I will use a diagram to describe your question visually.

This is what you currently have:

A <- develop
 \-- B (don't share) <- custom_develop
      \--C <- feature/ticket-123

This is what you want:

A <- develop
 \-- C' <- feature/ticket-123
  \-- B (don't share) <- custom_develop    
       \--C <- no branch

The problem is that by default rebase will try to replay all commits that have occurred from the merge-base of your current commit and the commit you are rebasing onto. In your case the merge-base (last common parent) is A. Therefore, there is nothing to replay, there are no commits that have diverged from A on the develop branch. That is why you are getting the "up to date" message. However, even if develop had progressed, you would still have a problem because Git would replay all of your commits onto wherever develop currently is including commit B, which you want to ignore.

Therefore, you will have to use the --onto option of rebase:

git rebase --onto develop B

This will replay all commits in the current branch that are NOT parents of B (or B itself) "onto" develop.

The syntax can be confusing. In the default case you only specify the "onto" commit, but without the --onto keyword. In the non-default case where you are specifying an "ignore" commit you need to specify the --onto keyword even though you are really adding an "ignored" commit. It would be better if Git allowed you to specify this with git rebase develop --ignore B.

Another option, which is required if the commits that you wish to ignore are not all at the bottom of you branch i.e., the commits following the merge-base, is to use interactive rebase.

git rebase -i develop.

Then, when the interactive window shows up comment out the commits you wish to ignore.

Lastly, it is probably not such a good idea to have a permanent custom branch. It would be better to put environment specific properties in a file that is ignored using .gitignore.

Joseph K. Strauss
  • 4,683
  • 1
  • 23
  • 40