0

I want to Deny or Prevent history rewrite on a local git repository. I know I can achieve this in the remote repository using:

git config --system receive.denyNonFastforwards true
git config --system receive.denyDeletes true

But it only works on git server (not local repo).

How can I disable amend and rebase on git local repo? Something like:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    denyRebase = true <--
    denyAmend = true <---
[receive]
    denyNonFastforwards = true
    denyDeletes = true

Updade: My intentions

We develop the app that kinda like plagiarism prevention. It will record all file history at certain interval and other info during work assignments. So we can analyze with some formula on that history then decide suspected student that plagiarized. .git repo will be zipped along with assignment and send to us. Now we are re-searching the best approach to prevent any ability on history rewriting. Some of our candidate: 1. Pushing the local commit to our remote repo at certain interval 2: fork git and drop those feature.

Thank you

azzamsa
  • 1,805
  • 2
  • 20
  • 28
  • Why would you want that? Amend and rebase are useful and convenient. – ElpieKay Mar 18 '19 at 11:37
  • We develop a research app that use git as our core. amend and rebase will ruin the entire research workflow. if git didn't support this. maybe we have to fork git, drop those feature or we push local commit each time it's created. Any suggestion ? – azzamsa Mar 18 '19 at 11:52
  • Not sure how git is used in your app. If the user runs git commands in the shell or other interfaces of your app, you can detect which commands they run. If it's `git commit --amend`, `git rebase`, `git filter-branch` or some low level commands that can rewrite the history, return errors and tell them the commands are not supported. – ElpieKay Mar 18 '19 at 12:12
  • My real advice is : do write down your needs, and look if there isn't another alternative to git. – LeGEC Mar 18 '19 at 16:34
  • @LeGEC thanks will look into this. So far we need all git (distributed vc) capability to store those history, unfortunately git power also come with price. – azzamsa Mar 18 '19 at 16:36

2 Answers2

0

Preventing rebase is easy. Create pre-rebase hook that always does exit 1.

Preventing amend is harder as there is no direct hook. You can try to abuse prepare-commit-msg, verify that the second argument is commit and exit with error:

test "$2" = commit && exit 1

Or you can try to do this at push time. Both amend and rebase require force-push so you can detect forced push.

Update. Oh, you want to stop hostile collaborators (students). That's nearly impossible. Hostile students can do almost anything in their local repositories. They can disable hooks, They can have two repositories — one for dirty work and one clean; the workflow is: edit in the dirty repo, pull to clean, push to server. There is no way you can detect anything in the local repo and there is no way you can detect amend even getting the entire .git/. Regular pushes to the server with disabled forced push slightly increase your chances to catch a hostile student but not much.

phd
  • 82,685
  • 13
  • 120
  • 165
  • for a temporary solution, I think this is applicable. I have updated the question to describe my intentions. – azzamsa Mar 18 '19 at 16:29
0

I'd be curious to have more details about your usage of git ; especially, what feaures are useful to your use case.


On a local repo : git stores all of its database in the local filesystem. So any user who can write to the .git/ directory can do virtually anything, including creating commits without using any of the regular git commands.

You can read the "Git Internals" chapters of the git book (for example : 10.2 Git Internals - Git Objects), or this link : Write yourself a Git!, where the author guides you through reimplementing the basic functionalities of git through external scripting.

  • if you just need to be reasonably sure that people do not commit --amend or rebase on this repo, I would recommend you provide a set of scripts, which describe the actions people should be allowed to do, and indicate that these should be the only ways to use this repo ;

  • if you want to absolutely make sure that no one does it, I would say that git is not geared towards this goal ; you can at least have people interact with a remote repo, and have some better control over what happens on that remote repo.

LeGEC
  • 46,477
  • 5
  • 57
  • 104
  • I have updated my question to add the intentions. I also prefer your second suggestion. *Yes, I want to absolutely make sure that no one does it.* maybe there is no other way except pushing those commit to remote at certain interval, so we have complete control over them. – azzamsa Mar 18 '19 at 16:34
  • So yes : do use a remote repo, served through a server with access control functionnalities (example of free possibilities : gitolite or gitlab ce) – LeGEC Mar 18 '19 at 17:04
  • also : enable the reflog on your central repository : https://stackoverflow.com/questions/3876206/how-do-i-view-a-git-repos-receive-history This will not track the date of the pushes, but will give you a view of all the pushes that happened. – LeGEC Mar 18 '19 at 17:06