0

I was expecting git reset --soft or git rebase to squash several commits into one, but it's not really working at all in my case.

I have this bash script. It is intended to checkout a branch from the dev branch, squash commits, then we checkout another branch, delete some private files, then we push the result to the public remote.

I was advised to use tags to create places in the git history to squash back to, I think this makes sense, but for some reason the following script is not accomplishing its goal at all - no commit squashing seems to be happening at all.

npm version patch --force -m "Upgrade for several reasons" &&    # bump version
git add . &&
git add -A &&
git commit --allow-empty -am "publish/release:$1" &&
git push &&                                                      # push to private/dev remote repo
git checkout dev_squash &&                                       # we do squashing on this branch
git merge dev -m "squashing" &&
# git reset --soft $(git describe --tags) &&
git rebase $(git describe --tags) &&
git add . &&
git add -A &&
git commit --allow-empty -am "publish/release:$1" &&
git tag xyz`date "+production-%Y%m%d%H%M%S"` &&
git checkout -b temp  &&                                          # we checkout this branch to run deletes on private files
./delete-internal-paths.sh &&
git rm delete-internal-paths.sh -f &&
git add . &&
git add -A &&
git commit --allow-empty -am "publish/release:$1" &&
git push public HEAD:master -f &&
git checkout dev &&
git branch -D temp &&
npm publish .

as you can see I tried both git rebase and git reset --soft and neither did it for me. Any idea why it might not be working as intended?

Here's a visual:

enter image description here

Alexander Mills
  • 1
  • 80
  • 344
  • 642

1 Answers1

1

Try instead:

git checkout -b dev_squash $(git describe --tags --abbrev=0)

(note that --abbrev=0 is needed to get back the latest tag on develop)

Actually, as discussed below, it is best to create once the dev_squash branch from where dev is starting:

git checkout -b dev_squash `(git merge-base dev master)`

Then keep that dev_squash as a long-lived branch, and make git merge --squash dev any time you need it: dev-squash branch will accumulate squashed commits.

And then:

git merge --squash dev

See also "In git, what is the difference between merge --squash and rebase?".

Community
  • 1
  • 1
VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283
  • thanks, can you describe what this is doing differently than the above? Note that my dev_squash branch is intended to have accumulated only the squashed history, while the dev branch is intended to have all commits (nothing squashed in dev). I designed it this way, (perhaps it's flawed), so that we don't get any un-squashing of old squashes, if that makes sense. – Alexander Mills Nov 21 '16 at 05:43
  • @AlexanderMills what is different is that I start dev_squash from the tag instead of from dev's HEAD. – VonC Nov 21 '16 at 05:43
  • My fear is that if I use your strategy, old squashes will become unsquashed, no? – Alexander Mills Nov 21 '16 at 05:44
  • But in my original script, the dev branch does not have any tags? – Alexander Mills Nov 21 '16 at 05:45
  • @AlexanderMills Then: you only need to start dev_squash from the latest tag for the first squash (if dev_squash does not exist yet). After that, you can checkout dev_squash (existing branch): each merge --squash will add a squash commit to it. – VonC Nov 21 '16 at 05:46
  • Okay thanks, I think I understand, do you have any idea why my script doesn't work? It's really annoying me! – Alexander Mills Nov 21 '16 at 05:47
  • @AlexanderMills if there is no tag, then is `git merge-base` for the initial creation of the `dev_squash` branch: `git checkout -b dev_squash (git merge-base dev master)` – VonC Nov 21 '16 at 05:48
  • honestly, I was just going to use "git checkout -b dev_squash" to create the dev_squash branch initially. There is no master branch (locally). The only master branch is on the public remote. And we don't want to merge with that (in my system). – Alexander Mills Nov 21 '16 at 05:49
  • @AlexanderMills I don't see rebase or reset effective here. And you are creating dev_squash from dev HEAD: it needs to start from where dev is starting itself, in order to accumulate merge --squash commits. – VonC Nov 21 '16 at 05:50
  • I see what you are saying, makes sense now – Alexander Mills Nov 21 '16 at 05:51
  • Ok, one last question- do you see anything wrong with "git push public HEAD:master -f "? Maybe I could just do "git push public master -f " – Alexander Mills Nov 21 '16 at 06:01
  • Ughhh, the git checkout command does not seem to like tags as https://git-scm.com/docs/git-checkout, do you think tags are recognized by git as "start points"? – Alexander Mills Nov 21 '16 at 06:12
  • @AlexanderMills Try instead the merge-base option instead of the tag: if the branch does not exist, dev_squash should strart from where dev is starting. – VonC Nov 21 '16 at 06:16
  • Your answer seems to work. I don't even need tags. I just keep dev_squash as a long-term branch, and always run git merge --squash dev. That way dev_squash will always have squashed history only. – Alexander Mills Nov 21 '16 at 06:26
  • @AlexanderMills Great! I have included the conclusion of our discussion in the answer for more visibility. – VonC Nov 21 '16 at 07:00