3

When I work in a team and must push my local branch to the remote main, I rebase firstly my local branch to master with this simple command:

git fetch && git rebase origin/main

But when I do that, all my local commits are applied and conflicts occur because the code of these previous commits are different to my last local state (saved in my last commit). And solving conflicts of my own commits takes a lot of (useless) time...

I’m afraid to do a mishandle, so I search for some help here. My question:

How can I merge all my local commit into one before a rebase ? And thanks that, when I rebase, there is just one commit to apply

I don't know if its the better approach, feel free to give my advise. :) Thank you!

Guildenstern
  • 2,179
  • 1
  • 17
  • 39
okli
  • 33
  • 4
  • 1
    Does this answer your question? [How do I squash my last N commits together?](https://stackoverflow.com/questions/5189560/how-do-i-squash-my-last-n-commits-together) – teapot418 May 03 '23 at 06:04
  • It's not elegant (and not the answer), but on GitHub, I often push to a separate fork, create a pull request against a branch that matches the main, squash and merge and then `git cherry-pick...` from that commit hash. The reason I do this is because the merging strategy from GitHub's Pull Requests often solves this problem in times when local squashing does not or is too much work, especially for branches that have been diverging for a long time. It also has the added benefit of a side-by-side merge conflict resolver, for those files that actually do conflict after a squash. – tresf May 03 '23 at 06:12
  • thanks for yours helps ! @teapot418 if I understand, I "flat" all my commit with the squash command and, then, when I `git fetch && git rebase origin/main`, there will be only one commit to merge ? – okli May 03 '23 at 09:36
  • 1
    Yes, "squash" is the usual term for merging multiple commits into one. (I mostly use the `git rebase -i` variant described in the accepted answer over there) – teapot418 May 03 '23 at 10:10

2 Answers2

1
#!/bin/sh
## Usage: ./script <branch>
git fetch origin main
git checkout origin/main
git merge --squash $1
# You’ll want to modify the commit message here
git commit
git branch --force $1 HEAD
# Return
git checkout -

Testing

I compared this with running git rebase <upstream> on a feature branch and I got the same tree ids from the two approaches.

The squash also squashed the range that I expected it to, according to the default commit message (it is quite verbose).

Caveat about the commit message

The default commit message of git merge --squash is much less nice than the one you get from git rebase --interactive with squash.

Misc.: reapplying conflicts

If you are just tired of fixing the same merge conflicts over and over again when using git-rebase(1) then you might want to look into git-rerere(1).

Guildenstern
  • 2,179
  • 1
  • 17
  • 39
0

You can easily do that in the following way:

  1. git rebase -i HEAD~n (where n the number of commits you have above main)
  2. An editor will open where you will have to leave pick on the top commit and then replace the pick in the following lines with an s, which stands for squash.
  3. In the next editor, edit the commit messages as you wish
  4. You will see a message that ways "Successfully rebased..."
  5. Then run git pull --rebase origin main to put that commit above the commits on the remote branch