Git Misconceptions: Rewriting History

Git Misconceptions: Rewriting History

For sure one in every of Git’s core features is “rewriting historic previous”, i.e., “altering” current commits. I’m the make use of of quotation marks, as a result of — regardless of the look — the Git historic previous is immutable. It is a methods by create now not doable to modify an current commit with distinctive Git instructions.

And but, amongst many Git clients there exists this dread of dropping some changes or merely constructing a multitude. In reality, any commited swap also can moreover be regarded as as purchase, i.e., it’s going to additionally moreover be retrieved even after “altering” the historic previous.

What does rewriting actually point out?

Why would you ever need to change the Git historic previous anyway? Let’s think about you’ve made a typo inside essentially the most up-to-date commit:

5c7a782 - (HEAD -> grasp) Repair deefct 47

fb2546f - Add checkout net web page

Usually, that you just simply may maybe maybe maybe be able to make use of instructions deal with reset or rebase (-i) to “rewrite” the Git historic previous. Nonetheless, correcting the pleasant commit is relatively distinctive, so there’s the following completely different:

$ git commit --amend -m "Repair defect 47"

One different gaze into the Git historic previous reveals essentially the most attention-grabbing message:

2b049ea - (HEAD -> grasp) Repair defect 47

fb2546f - Add checkout net web page

It seems as if now we take up horny altered the pleasant commit. Nonetheless, the hash has modified from 5c7a782 to 2b049ea, that suggests that now we take up created a distinctive commit. The motive being relatively simple:

For each commit a diversified hash is being generated and assigned to the commit. It is a methods in conserving with the commit message, instruct materials, creator, father or mom commit and so forth. Altering any of these properties ends in a novel hash and as a consequence of this actuality a novel commit.

Since we’ve horny modified the commit message, a novel commit with a transparent hash was created. Identical factor occurs when “interesting” (e.g. rebasing) commits, given that father or mom commit changes.

Nonetheless the place did the alternative commit speed up? By default, git log hides each commit that’s now not reachable from HEAD or any named department. These unreachable commits also can moreover be displayed with the --reflog flag:

$ git log --graph --oneline --reflog

2b049ea - (HEAD -> grasp) Repair defect 47

| 5c7a782 - Repair deefct 47


fb2546f - Add checkout net web page

As we’re capable of peep, “altering” historic previous is nothing else than establishing distinctive commits and interesting the HEAD and grasp pointers. Attributable to this actuality, the time period “completely different historic previous” is extra exact. It moreover implies that we’re capable of with out issues revert our “damaging” commit --amend prepare if required:

$ git reset --onerous 5c7a782

Garbage collection

Beforehand, I’ve claimed that each commits also can moreover be regarded as as purchase. Nonetheless, there’s a limitation:

The Git rubbish collector will protect away all unreachable commits mechanically after a sure size of time (30 days by default).

Severely in a rebase journey, that you just simply may maybe maybe maybe obtain and copy change commits. The garbage collector does some housekeeping and eliminates all abandoned commits after a sure time. In my each single day work, I occasionally need to keep up these commits. If you happen to occur to achieve, merely place a department to it:

$ git department my-branch 5c7a782

Altering public historic previous

So long as we’re “altering” commits which might be now not public (i.e. they’d been under no situations pushed to a distant repository), you’re free to achieve no matter you need. Issues purchase refined as quickly as we need to go a public department spherical.

A novel Git best put collectively states:

Develop now not alter public historic previous.

I mediate this is astronomical recommendation for Git newbies, on the alternative hand it’s going to additionally moreover be limiting whereas you occur to and your collegues know what you’re doing.

Let’s first peep the penalties of rewriting public Git historic previous. Let’s protect the fallacious commit from the pleasant share had been already pushed to the beginning place distant. After working git commit --amend the log would gaze deal with this:

2b049ea - (HEAD -> grasp) Repair defect 47

| 5c7a782 - (beginning place/grasp) Repair deefct 47


fb2546f - Add checkout net web page

If we attempt to push our corrected determine to beginning place, we’ll purchase an error:

$ git push

To ../beginning place/

! [rejected] grasp -> grasp (non-immediate-forward)

error: did not push some refs to '../beginning place/'

trace: Updates had been rejected given that tip of your most traditional department is throughout the attend of

trace: its distant counterpart. Combine the distant changes (e.g.

trace: 'git pull ...') sooner than pushing once more.

trace: Conception the 'Cloak about immediate-forwards' in 'git push --help' for particulars.

Here is the anticipated conduct, as a result of by default a git push is just allowed so as to add distinctive commits onto essentially the most normal “tip” of the distant (beginning place). Git suggests an easy answer: “integrating the distant changes”. In our case, git pull is a akin to git merge beginning place/grasp, which is now not what we need. As a change, we need to change the distant commit. It goes to be carried out with a stress push:

$ git push -f

Now the whole lot seems to be like stunning:

2b049ea - (HEAD -> grasp, beginning place/grasp) Repair defect 47

fb2546f - Add checkout net web page

However now Janet and Steve and all your different collegues will purchase the an identical educate as you’ve had sooner than. That’s why duties assuredly disallow a stress push for essentially the most foremost branches (e.g. grasp, keep).

How will we deal with this self-discipline?

When doubtful, comply with the suitable put collectively “Develop now not alter public historic previous”. A typo seems to be like execrable, nonetheless obtain you actually need to go throughout the full trouble to restore it?

If you happen to occur to obtain have to stress push a public department, the primary and most indispensable step is Dialog. Your full collegues engaged on the an identical department should aloof know to demand a educate of affairs when interacting with the shared repository. They moreover should aloof know restore this self-discipline. For amended changes the answer is simple:

$ git pull --rebase

This prepare will purchase the distant department and rebase all native commits on prime of it. Amended commits may maybe effectively be resolved mechanically (so the typo commit may maybe effectively be skipped).

Different make use of instances may maybe effectively be harder to restore, together with (interactive) rebasing and cherry-selecting. Repeatedly possess in ideas the alternate-offs sooner than pressure-pushing.

What whereas you occur to’re working on my own on a public department? You then’re assuredly free to pressure-push as highly effective as you deal with. Once more, dialog is a necessity to soak up right here.


Mannequin alter is an underrated potential. Most instrument engineers make use of it each single day, and but, many are now not prepared to speculate greater than necessary to be taught it. That’s stunning, nonetheless gleaming greater than commit/push/pull will at the least purchase you extra setting plentiful. It goes to moreover permit you to remedy issues you (and your collegues) also can attain all through.

I hope this textual content explains Git’s default “security purchase” conduct and motivates you to check out out some righteous features.


Please enter your comment!
Please enter your name here