12

I already added receive.denyNonFastforwards and receive.denyDeletes on my git central repo server. Now I would like to block local history modifcation if the commit was already pushed to the central repo (just like mercurial does by default), I suppose I can use a hook but I couldn't find any example.

Is this a strange configuration?

It sounds like a basic safeguard that anyone using git should have activated and I'm quite surprised for the lack of example hooks.

angelodiego
  • 245
  • 1
  • 16

3 Answers3

3

You can prevent local history modification by using Client-Side Hooks, much like you would with Server-Side Hooks.

Here are some examples of client-side hook code. Near the end of that page is a pre-rebase script that does something close to what you're looking for.

Note that client-side hooks cannot be added to a repository in such a way that they will automatically be set up in downstream repos:

Because hooks aren’t transferred with a clone of a project, you must distribute these scripts some other way and then have your users copy them to their .git/hooks directory and make them executable. You can distribute these hooks within the project or in a separate project, but Git won’t set them up automatically.

Tyler Hoppe
  • 438
  • 3
  • 11
  • I'm aware of Client-side hooks, I was looking for an example of no public history modification hook – angelodiego Apr 08 '15 at 13:12
  • The link provided in the answer refers to a page that has an example pre-rebase hook that checks to see if the commits have already been pushed to the remote. – Tyler Hoppe Apr 08 '15 at 21:32
0

Mercurial offers some way to deal with mutable chagenset (changesets that you can reorder/rewrite). For instance with the ChangeSet Evolution plugin.

The possibility is more limited on the server side with git (you can deny the push --force with the two config mentioned in the question)

You cannot easily enforce a hook on the client side, since it needs to be activated, and can be bypassed with git commit --no-verify.

But before Git 1.8.5, there was a pre-rebase client hook called .

After Git 1.8.5, you can do as a client a git push --force-with-lease:

You assume you took the lease on the ref when you fetched to decide what the rebased history should be, and you can push back only if the lease has not been broken.

That allows some freedom on the client side, and a safer forced push on the server side.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
0

This looks very close, if not the same question as Strategy for Preventing or Catching Git History Rewrite

To sum it up you can enable

git config --system receive.denyNonFastforwards true

and

git config --system receive.denyDeletes true

Or write a post receive hook to reject anything you determine is a rewrite

Uttam Panara
  • 541
  • 2
  • 10
  • 28