Rich Freeman on 16 Nov 2017 07:08:18 -0800

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [PLUG] Revision Control for the Rest of Us

On Wed, Nov 15, 2017 at 9:16 PM, JP Vossen <> wrote:
> And damn it, mutable
> history is a BUG not a feature (unless your project is at the scope and
> scale of the Linux kernel)!

While accidentally mutable history is a bug, I'm not sure that it is
wise to leave the option closed.  I'll give some use cases:

There are other solutions to this one, but bisecting is a case where
broken commits can cause pain.  If you have a known-bad commit
somewhere in the history it might be desirable to merge it with a fix,
or remove it entirely, so that you don't land on it when bisecting.
An alternative to modifying history would be to be able to go back and
tag these commits as broken so that they get skipped when bisecting.
Whether that counts as modifying history I'll leave to others to

There are commits that can make a repository useless or extremely
painful to use.  Maybe I accidentally do a commit that includes a 50GB
file in a project whose repository previously totaled 1MB in size.  If
you can't go back and remove that commit, then anybody cloning that
repository is going to be stuck with 50GB of data in the history that
was never really used.  Now as an added bonus imagine that the 50GB
file is not legal to redistribute, and thus the repository can't be
hosted anywhere.  The unredistributable file could also have been 2kb
and the problem might have been discovered six months after the fact.

All that said, git actually makes changing history pretty painful,
because it is content-hashed.  If you want to go back and change a
commit that happened a year ago, the hash of every subsequent commit
in the repository will change.  If those commits are signed then they
all need to be re-signed, probably by somebody other than the person
who did the original signing.  If you go into a repository and pull up
commit abc12345 it will have the exact same history it ever had,
assuming it wasn't garbage collected (which will happen if it no
longer is in the history of a head/tag/etc).

Now, git does offer something a bit more like a symlink where you can
replace one commit with another without changing its hash.  In this
situation the old commit remains in place, but the new commit gets
stored alongside it and whenever git goes to read the old one it will
substitute a new one.  This is a good way to graft the tail of one
repository onto the head of another.  It isn't really suitable for
fixing the second problem I listed above as the old commit remains
there.  Also, these kinds of substitutions don't get cloned by default
unless somebody explicitly pulls them in - a clone will show the old
commit (which makes it pretty lousy for solving the first use case as

Philadelphia Linux Users Group         --
Announcements -
General Discussion  --