2

I think the answer to this is scattered somewhere in the docs and in other questions here, but I couldn't find something that related exactly to my situation, so I am posting this. Please feel free to point me to any relevant answers elsewhere.

I have three branches: wip, deploy-dev, client.

  • wip is the working branch internally for our team. It includes 3rd party keys/secrets and some local environment config.

  • deploy-dev is also internal, but it has different config to test a deployed version.

  • client is the branch that gets pushed to the client's remote. It removes 3rd party keys/secrets that we use for testing.

The problem

My wip branch has lots of commits. For the first release to the client, I would like to squash them into a single commit. So I did this:

  • git checkout -b client
  • git reset --soft <first commit>
  • git add .
  • git commit -m "v1.0 release to client"

After this first commit in the client branch, I would like to checkout wip again and continue working on v1.1. Then I should be able to checkout deploy-dev and client respectively and merge wip into them.

But when I checkout client and git merge wip, I am getting the entire commit history back into client.

I'm missing something easy, but I don't know how to describe it without describing the whole situation. Thanks for the help.

mehulkar
  • 4,895
  • 5
  • 35
  • 55

2 Answers2

1

It sounds like you need to learn the magic of git rebase. See, for example, When would one need git-rebase? and git rebase vs git merge to start with.

After you squash client, you should have something like this.

  A--B--C--D[wip]
 /
X--E--F--G[deploy-dev]
 \ 
  Z[client]

Run

git checkout wip
git rebase client

and also, presumably,

git checkout deploy-dev
git rebase client

Now your DAG will look like this:

  A--B--C--D
 /
X--E--F--G
 \ 
  Z[client]--E'--F'--G'[deploy-dev]
   \
    A'--B'--C'--D'[wip]

Of course, you will need to resolve any conflicts, just as if you'd done a merge.

Community
  • 1
  • 1
neirbowj
  • 635
  • 5
  • 17
0

This is going to be a gigantic pain. You cannot merge anything with client any more; the history is completely different as far as git is concerned. You effectively have two unrelated projects that happen to live in the same repository and produce the same files.

You'll have to juggle resets, or use rebasing in creative ways. With reset (I think!):

git checkout wip
git reset --soft client
git add .
git commit...

git reset --soft will change the branch git thinks you're on, without changing any of your files. So you'll have the files in wip and git will think you're on the client branch, and then you can just mass-commit it all again.

You could also use rebase:

git rebase --onto client X wip

where X is the last commit on wip that has already been squashed into client. This will take all the new commits and recreate them, one at a time, on top of client. You can also use -i to get interactive mode, which will let you squash them together or rewrite the commit messages as you go.

You'll have to do this for every release, and you'll get some even wackier results if you make a mistake. Ideally, you should either:

  1. Write your commit history from the start so it can be made public at any time—keep secrets out of band, etc. Bit late for this now, though. Or:

  2. Use some other mechanism to deliver code to your client, like tagging the commit and then just emailing them a tarball. If they want to track diffs, you can generate one with git diff v1.0..v1.1, or they can do it themselves.

Eevee
  • 47,412
  • 11
  • 95
  • 127