This post is aimed for people who want to learn how to use commands such as rebase & learn a few tricks to have a nicer Git experience.
Al...
For further actions, you may consider blocking this person and/or reporting abuse
Rewriting history on solo projects is fine but as soon as you work with another person you should consider it extremely harmful to do so on non-local branches.
From git-scm.com/book/en/v2/Git-Tools-R...
Correct me if I'm wrong, but I didn't get the impression from reading this article that the author suggests we should be editing the history of the
master
branch or any other shared branch. I'm more under the impression that it's about tidying up your own fix or feature branch shortly before it goes into master, and I do not see any harm or problem with that, even in a team.To the contrary, the benefit of a cleaner, more readable history that removes all clutter such as quick and dirty in-between commits and iterations that didn't end up in the final result, should bring all contributions into a sensible timeline that is easier to follow.
Talking about big teams, here's the stance from Phabricator's development team, a development and collaboration tool that originated from Facebook and turned into an Open Source project:
"One idea = one commit" means that the entirety of the fix or feature branch should be squashed into a single commit in the mainline branch. A single commit that easy to apply and revert if necessary. All in-between steps should be removed. The proposed solution to this issue is:
Source
Several other articles online give the same idea that squashing and rebasing is the way to go, especially when you work in teams:
Editing the history is only problematic when the editor doesn't 100% know what they are doing, and even then, destructive changes can be prevented by simply setting up the git repository server to reject destructive changes to the shared mainline / development branches.
On GitHub you can set up branch protection rules to prevent any
push --force
to any branch of your choice from being accepted. Phabricator doesn't allow "destructive changes" to any branch by default. Bitbucket offers the same protection under "branch permissions".Practically speaking there is nothing to worry about with proper repository configuration and with the right education. And articles like this one are helpful
Absolutely, that was not my intention, if it wasn't clear then that's my bad.
Yeah, I don't see an instance where force pushing to
master
would be recommended, glad you mentioned these protections for others to know about.And thanks for sharing some resources, I'm glad you commented 😄
Hi yes I agree there's nothing in the article that says rewriting master is a good idea, however I felt it was important to state that there are problems. Rewriting history and rebasing are not silver bullets and can cause issues without proper procedure.
Admittedly reading my comment back it sounds like I've dismissed the whole article on that basis but that was absolutely not my intention!
I totally agree with your statement, all these manipulations should be done locally before pushing your work. 😀
"Fixing" history is a misguided (and dishonest) effort--a waste of time. Rebase is a powerful git tool and should be learned and used appropriately, but maintaining a useful git log should be accomplished with forethought and disciplined adherence to good commit practices. That said, I'd rather have an imperfect but unmolested git history. A "clean" history is just a lie.
Bs. Clean history represent a step by step application growing and not how u or u team work. So isnt lie. No sense of blame anybody only the log of the build from first line to current.
Thanks for the article! It was a nice read/refresher. Since the audience is for people wanting to up their git game, I would suggest adding some messaging around the dangers of "force push" and maybe reference force push with care which leverages
--force-with-lease
so people don't accidentally overwrite team pushes. :)Another noteworthy thing might be to
git rebase --abort
if things go unexpectedly sideways during a rebase (conflicts or other strange/unexpected behavior). It's nice to know, especially when getting started, how to back out of a command safely.Thanks again!
Great points Nick, thank you for sharing them. I did not know of
--force-with-lease
.I've added a section called "On the dangers of force pushing & other things to note" which mentions your comment.
Thanks again 🙂
Nice walkthrough. Rebasing is often painted as advanced, but I think it's best to play with it early on, and not fear it later.
Technically true, but I wouldn't phrase it like that. IMO, taken together these risk implying untrue things — that a branch's history can be arbitrarily rewritten with a plain rebase, that it's why rebase exists, and that
--interactive
just changes the UI.I'd instead say:
git rebase
allows you to replay the changes introduced in a set of commits on top of a specified base. It works by repeated cherry-picking (i.e. applying changes introduced by a commit on top of a different one).--interactive
allows you to edit the changes before they're applied.This leads to a special form of rebase — interactive rebase where the source branch is also the target — where you can arbitrarily rewrite a branch's history.
git-scm.com: Rewriting History
Just to add context: rebasing works here, but merging master is likely better for PRs on a team.
I'd say only the first two are potentially serious, but I can't think of an upside that'd make it worth dealing with them.
Thanks for the post, very good practical examples to try rebasing.
I'm just curious how did you achieve this lonely commit? 😀
I think interactive rebase in this example is overkill.
git commit -- amend -m "new message"
will do the work.But changing a message for commit head~2 is impossible with
amend
, so interactive rebase withreword
will solve such tasks perfectly.With pleasure, super glad it helped.
This last commit is just an automatic commit made to deploy to Github Pages
A whole different thing, so don't worry about it !
Thanks for mentioning
amend
😄Bro, thank you. This article has been a great help for me today.
I messed things up with
git reset HEAD~
. Luckily, gitlense(vscode ext) had a copy of the files that vanished. After doing the necessary changes, i did a rebase to fix up the previous commit as you mentioned. 👍Hi Christopher,
Nice article, many thx!
If I may suggest, instead of fetch remote parent branch, I used to use
git pull --rebase
cmd.For example, if I need to rebase 'develop' branch from master, I'll do
git pull --rebase origin master
.This prevent me to forget about fetching the HEAD of master every time I need to rebase.
Another point, if you really need to rewrite history of a project, I would suggest to learn
git reflog
cmd also. It's really convenient to recover deleted commit for example, or to cancel a mishandling rebase...Thx again
More often than not I've got one of those commit histories that look like the "OH LORD WHAT HAVE I DONE" graph, and even
rebase
is hard to use to clean up -- this happens most often when I have something that fixes one thing, but needed two or more changes. (I really should get into the habit of committing after each file change, even if it leaves HEAD broken.)In those cases, I use a process of checking out
master
into a cleanup branch,git cherry-pick -n
(i.e., don't commit) the changes from the branch I'm cleaning up onto the cleanup branch, and thengit reset
. Now all of the commits are squashed on a per-file basis. I then repeatedly usegit add -p
to build a new set of per-file commits that catch me up by replyingy
until the next change would go into a new file. Thencommit
and repeat until all the changes have been built into commits.It loses the commit order, but very nicely collects the changes into per-file changes. Hm. This might have been better as a post instead of a comment!
Hey man, great article and especially great title choice! I came from a dev.to mail and upon reading it I immediately thought: this is about rebasing.
The Table of Contents anchors don't work though, had to scroll manually
Thanks for the great article! Is rebasing/squashing only useful for auditing your git history and/or making it easier to read?
I guess what I'm asking is - if I recommend doing this to my team, what are some of the practical applications I can mention to get them on board?
Isn't the combo of
git fetch
andgit rebase origin/master
equivalent togit pull --rebase origin/master
?Many thanks for this excellent article, something I needed to get more comfortable with Rebase. Much appreciated!
This was very helpful thank you
Thank you Christopher Kade !