0

I'm currently learning about the power of git rebase, but I'm also aware of its potential dangers.

Now, after reading a lot of online resources, I'm really confused:

First of all, I read the advice "never use rebase on a public branch", yet at the same time, I read another piece of advice saying "git pull --rebase" (git pull --rebase on public branches) is not dangerous. Isn't that contradicting?

Now, I'm trying to think of 2 possible scenarios here:

1. Developing on a private feature branch as a solo developer

In this case, I can always do "git rebase master" to get new changes from main branch without changing/breaking the commit history. Concerning "git pull --rebase", I think it isn't necessary for this use case.

2. Developing on a public feature branch with other developers

This one seems tricky to me. As far as I can tell "git pull --rebase" shouldn't be a problem, because only the hash codes of my local commits will be changed.

However, what about doing "git rebase master" on a public feature branch? Is this dangerous for my colleagues/the public commit history?

Finally, as a last security mechanism, I'm trying to think of rules that help me to be on the safe side with rebasing:

Rule 1: As long as I don't have to "force push", everything is fine with my rebase and I didn't break the commit history.

Rule 2: As long as I didn't change the hash codes of public (already pushed) commits, everything is fine with my rebase and I didn't break the commit history.

I'm not so sure about rule 1, but I think rule 2 is correct (the question here is how to check that rule).

rob_87
  • 45
  • 1
  • 1
  • 8
  • 3
    `git pull --rebase` rebases your local branch onto the remote branch but leaves the remote branch alone. – mkrieger1 May 15 '23 at 09:45
  • 2
    The advice you are citing should be "never rebase a public branch", not "never rebase **on** a public branch". – mkrieger1 May 15 '23 at 09:47
  • In other words, `git pull --rebase` will rebase your _local_ changes so they fit into whatever happened remotely. – tripleee May 15 '23 at 09:55
  • Ok thank you, so git pull --rebase is safe even on a shared feature branch ? – rob_87 May 15 '23 at 10:39

1 Answers1

2

I think the most useful rule of thumb is do I "own" the current branch, or is it shared?

Rather than thinking about "local", "remote", or "public", all you need to think about is whether other people already have these commits. If they don't, then you can rebase, amend, and generally rewrite history, without affecting anyone else.

For instance, a branch's lifetime might look like this:

  1. Check out the latest state of main (or some other shared branch)
  2. Create a branch for a specific task
  3. Make some commits
  4. Push to GitHub, and preview the PR
  5. Amend those commits, e.g. to fix a typo that doesn't need to be visible in history
  6. Force push to GitHub
  7. Run git pull --rebase origin develop to rebase on top of somebody else's changes
  8. Force push to GitHub
  9. Merge via Pull Request onto main

Unless somebody else is directly collaborating on the task with you, they shouldn't be basing anything on your changes until step 9. Even though they can see your commits, it shouldn't matter if you completely rewrite them with new hashes.

After step 9, you can think of the commits as "published" to the shared branch, and assume that other branches will include those commits in their history. At that point, they must not be rewritten except in an emergency.

GitHub has a "protected branches" feature (and I'm sure GitLab, BitBucket, etc have something similar) so that it's not even possible to force push to certain branches. If you sometimes collaborate on feature branches, you can have a naming convention like "shared/123" vs "joebloggs/123" to identify at a glance which branches are safe for you to rewrite the history of, and enforce this with a protected branch rule.

IMSoP
  • 89,526
  • 13
  • 117
  • 169
  • Thanks so much for your detailed answer. So based on your explanation, "git rebase master" is dangerous when I do it on a public feature branch (because other devs have access to the commits/work with these commits)? – rob_87 May 15 '23 at 10:05
  • @rob_87 Yes, the simple thing to look at is *what branch you have checked out*. If you're on a branch called "shared/project-nemesis", you don't "own" that branch, so you shouldn't run any commands that rewrite history (`git rebase`, `git commit --amend`, etc); and ideally your remote server should reject your push if you do (i.e. `git push --force` or `--force-with-lease` will give you a permission error). – IMSoP May 15 '23 at 10:15
  • @rob_87 it's not the rebasing that's dangerous, it's the force-push. But if you don't plan on pushing your new commits, there's usually no sense in rebasing them in the first place. – knittl May 15 '23 at 11:26
  • @knittl Even without a force push, it can be dangerous (or at least confusing), because now you have a local branch that doesn't match the remote branch with the same name. Next time you start a task branch from it, you'll end up with your rewritten commits, which will then look "new" when you raise a PR, causing a confusing series of conflicts. – IMSoP May 15 '23 at 11:54
  • @IMSoP Confusing yes, dangerous no. Anything you do locally does not interfere with the work of other devs. But if you never plan on publishing (pushing) your work, why bother performing a rebase? – knittl May 15 '23 at 11:57
  • @knittl The "danger" is 90% about confusion either way, since restoring the old history is generally straight-forward. Either way, I think we're basically agreeing, that it's the force push that causes the *most* problems, because now you're causing problems for *other people*, not just yourself. – IMSoP May 15 '23 at 14:56