2

So far, I have been doing interactive git rebasing fairly often on either: unpushed work, or on pushed work that I knew for sure I was the only one to work on.

I know squashing commits and overall rewriting history can be tricky when it gets to collaborative work.

What is the best practice to do it with as little pain as possible?

If I squash some commits and push, how will the repo look like on a colleague's station when he pulls?

  1. When he has done no change and just needs to update?
  2. When he did do some changes, and wants the update before committing himself?

I know that the very concept of rewriting history is a never-ending debate, but here I am just looking for a technical solution to handle this.

FullStackDeveloper
  • 910
  • 1
  • 16
  • 40
ptpdlc
  • 2,373
  • 6
  • 22
  • 33
  • 1
    Maintain a release branch and multiple development branches. You are the only one who's allowed to update the release branch. Other team members work on the development branches. When a development branch is done, you squash-merge it back to the release branch. They can do whaterver to the development branches as long as they assure you that the code of the last commit of a development branch is okay before it's to be merged. – ElpieKay Jul 30 '17 at 06:04
  • Thanks. My use case is precisely a feature branch on which I have been working my a teammate, and both of us were doing commits. And possibly even more that we would have been doing had we been alone on the branch since we meant to be able to sync as much as possible. And since the dev is getting to an end I was planning to merge but with cleaning the history a bit. – ptpdlc Jul 31 '17 at 02:18

1 Answers1

3

What is the best practice to do it with as little pain as possible?

The best practice is to avoid it.

As ElpieKay suggested, it's a good practice to have a "release branch", where the history is safe and things are stable, but also to have "development/feature branches" where you can do whatever you want until you merge/rebase them into your stable master branch again.

To answer your questions:

  1. When he has done no change and just needs to update?

When didn't change anything and pulls, git will take the remote's history as the correct one (because someone obviously --force-pushed, so it has to be right.) So it will just overwrite your collaborators work and make the commit history match the history on the remote server. It will show this with an additional message like force update just as it does when you force push something.

Note that the old commits won't really be deleted - Just "hidden", as they are unlinked from the rest of the commit graph. So if you suddenly needed access again to the "deleted" commits, that would maybe be possible as long as you have the SHA hash of the lost commits somewhere. The git garbage cleaner deletes unreachable objects after a certain amount of operations on the repository.

  1. When he did do some changes, and wants the update before committing himself?

That's the worst case obviously. Anyway, make sure you have a backup copy of all your changes and your branch by committing your changes (even if you want to apply them afterwards!), creating a temporary, new one

git add . ; git commit -am "Describe all my changes here" ; git branch backup

Now that your changes are safely stored in the backup branch, you can remove the commit again.

git reset --hard HEAD~

Then pull the current branch

git pull

This should work without any merge conflicts as it basically represents case #1, where no changes have been made and it will just make the local history match the remote one. Now you might be able to apply your changes again, by applying your changes ( = the latest commit on the backup branch) again.

git cherry-pick backup

Obviously, this might lead to a merge conflict, when the remote repository updated the same lines of the code. If there were no conflicts then you can delete the backup branch. Your repository is up-to-date and your changes are applied on top of it.

But again, try to avoid these situations. Either squash/rebase in a separate feature branch before merging or let the commits be as they are after they are merged.

0xpentix
  • 732
  • 9
  • 22