It is often said that, you should not rebase commits that you have already pushed. What could be meaning of that?
4 Answers
To understand this, we need to understand a bit about how git works. A git repository is a tree structure, where the nodes of the tree are commits. Here's an example of a very simple repository:
it has four commits on the master branch, and each commit has an ID (in this case, a, b, c, and d). You'll notice that d is currently the latest commit (or HEAD) of the master branch.
Here, we have two branches: master and my-branch. You can see that master and my-branch both contain commits a and b, but then they start to diverge: master contains c and d, while my-branch contains e and f. b is said to be the "merge base" of my-branch in comparison to master -- or more commonly, just the "base". It makes sense: you can see that my-branch was based on a previous version of master.
So let's say that my-branch has gone stale, and you want to bring it up to date with the latest version of master. To put it another way, my-branch needs to contain c and d. You could do a merge, but that causes the branch to contain weird merge commits that make reviewing the pull request much more difficult. Instead, you can do a rebase.
When you rebase, git finds the base of your branch (in this case, b), finds all the commits between that base and HEAD (in this case, e and f), and re-plays those commits on the HEAD of the branch you're rebasing onto (in this case, master). Git actually creates new commits that represent what your changes look like on top of master: in the diagram, these commits are called e′ and f′. Git doesn't erase your previous commits: e and f are left untouched, and if something goes wrong with the rebase, you can go right back to the way things used to be.
When many different people are working on a project simulateously, pull requests can go stale quickly. A "stale" pull request is one that is no longer up to date with the main line of development, and it needs to be updated before it can be merged into the project. The most common reason why pull requests go stale is due to conflicts: if two pull requests both modify similar lines in the same file, and one pull request gets merged, the unmerged pull request will now have a conflict. Sometimes, a pull request can go stale without conflicts: perhaps changes in a different file in the codebase require corresponding changes in your pull request to conform to the new architecture, or perhaps the branch was created when someone had accidentally merged failing unit tests to the master branch. Regardless of the reason, if your pull request has gone stale, you will need to rebase your branch onto the latest version of the master branch before it can be merged.

- 3,364
- 4
- 16
- 17
The ProGit book has a good explanation.
The specific answer to your question can be found in the section titled "The Perils of Rebasing". A quote from that section:
When you rebase stuff, you’re abandoning existing commits and creating new ones that are similar but different. If you push commits somewhere and others pull them down and base work on them, and then you rewrite those commits with git rebase and push them up again, your collaborators will have to re-merge their work and things will get messy when you try to pull their work back into yours.
Update:
Based on your comment below, it sounds like your are having difficulty with your Git workflow. Here are some references that may help:
- The
gitworkflows
man page: See "Merging Upwards" and "Topic Branches" - ProGit: See "Private Managed Team"
- Jarrod Spillers blog: See "git merge vs git rebase: Avoiding Rebase Hell"

- 60,452
- 11
- 85
- 78
-
Thanks for the explanation. So, just to make my understanding clearer, after I push certain changes, I should not use `git rebase` ( --interactive ?) to rewrite that history, this is sure recipe of fail.On the other hand, if I have rebased certain changes to topic branch (from branch X) and push it, its perfectly normal to rebase again after another developer changes topic branch. Essentially, I have been using `merge` for quite sometime, but we are in same boat as, http://darwinweb.net/articles/86 and the history is almost unusable. – Hemant Kumar Apr 26 '10 at 18:13
-
@Hemant: Rebasing commits after pushing to a public repo is generally a bad idea. That being said, the advice from the darwinweb article you cited sounds reasonable if your workflow resembles theirs. See my updated response for a list of other references which might help. – Tim Henigan Apr 26 '10 at 19:24
-
Please update a link to "ProGit" page about "Private Managed Team" to http://git-scm.com/book/en/Distributed-Git-Contributing-to-a-Project#Private-Small-Team – Eimantas Sep 29 '14 at 06:20
-
So technically, git commits stays same but "abondoning existing commits and creating new ones that are simmilar but different" are just the same commit with different sha1 id ? well that would be the only obvious way I can think of why collaborators woudl have to re-merge their own work ! – Ciasto piekarz Mar 07 '18 at 09:37
-
@Ciastopiekarz, this is because you're rewriting history in the upstream repo, and other developer's local repos may have pointers to that. Now their pointers are stale: the git client has no alternative but to use older pointers and rely upon the human to sort the rest out. This is a re-merge, and it can be VERY messy with a lot of confusing changes that must be manually sorted out! Thus the recommendation never to rebase anything that's already been pushed to an upstream repo. This is good advice and it shouldn't be ignored unless you're an expert with deep knowledge. – Forbin Nov 27 '19 at 18:34
Rebasing rewrites history. If nobody knows about that history, then that is perfectly fine. If, however, that history is publicly known, then rewriting history in Git works just the way it does in the real world: you need a conspiracy.
Conspiracies are really hard keep together, so you better avoid rebasing public branches in the first place.
Note that there are examples of successful conspiracies: the pu
branch of Junio C. Hamano's git repository (the official repository of the Git SCM) is rebased frequently. The way that this works is that pretty much everybody who uses pu
is also subscribed to the Git developer mailinglist, and the fact that the pu
branch is rebased is widely publicized on the mailinglist and the Git website.

- 363,080
- 75
- 446
- 653
-
4+1. I think the `pu` branch of git.git is an extremely helpful example of how to use rebase in a (public) workflow. For those not familiar with it, the general idea is to rebase topic branches which don't have any commits in `next` (the unstable branch just before merging to master), then rebuild the `pu` branch by resetting to `next`, and merging all the topic branches. (Source: Documentation/howto/maintain-git.txt http://git.kernel.org/?p=git/git.git;a=blob;f=Documentation/howto/maintain-git.txt;h=d527b307707c676e82a08f18cb9fdd7d3abcb228;hb=HEAD ) – Cascabel Apr 26 '10 at 18:46
-
25+1 for "rewriting history in Git works just the way it does in the real world: you need a conspiracy" – Sleeper Smith Aug 25 '13 at 23:34
-
"A public announcement is not necessary since pu is a throw-away branch, as described above." https://git-scm.com/docs/gitworkflows We do something similar at work, "TEMP-something-latest" is a throw away branch that is a combination of the latest changes, it could be a merge of multiple feature branches, may be deleted and recreated at any point in time and should not be developed on. – pilkch Aug 26 '16 at 03:34
A rebase alters the history of your repository. If you push commits out to the world, i.e., make them available to others, and then you change your view of the commit history, it becomes difficult to work with anyone who has your old history.
Rebase considered harmful is a good overview, I think.

- 8,870
- 3
- 48
- 63