Home > Software engineering >  How to prevent force-pushing to a GitHub Wiki repo?
How to prevent force-pushing to a GitHub Wiki repo?

Time:10-19

For those who don't know, every GitHub repo with a wiki automatically has a wiki repo. It's just a regular git repo dedicated to the wiki content! Ex: https://github.com/junegunn/fzf/wiki. You can see this at the bottom-right:

Clone this wiki locally
https://github.com/junegunn/fzf.wiki.git

It looks like there's a way to prevent force-pushing to a particular branch on your code repo, but how can you prevent force-pushing to the wiki repo?

Being unable to block this is dangerous! Let's say you pull the wiki and add a page locally. Other people spend all day editing the wiki via the web interface. At the end of the day, you go to push your new page and it fails. Without thinking you do git push -f, force-pushing to the wiki repo and permanently overwriting and deleting all other wiki content added that day! It's gone forever! You can't recover it, since it was only stored on the GitHub servers (since they were editing the wiki via the web interface only), not on anyone's local machine, again, since the other wiki editors did their edits only from the web interface. That's a problem.

See also:

  1. Elegant solution to prevent force push on master only
  2. GitHub - prevent collaborators from using push -f
  3. Preventing others from force-pushing to my Git repository

CodePudding user response:

Since this is not possible for now, I would:

  • keep only one page in the Wiki, instructing reader to go to a separate regular repository
  • protect the main branch of that separate repository, preventing any force push.

This is not what you want, but it seems the only "sure" way to control who pushes what in a wiki-like repository.

Another option is to use that separate repository as a source to update, through GitHub Action, your actual wiki.
But you would need a warning on each page stating that wiki contribution must be done through that separate repository.

CodePudding user response:

Another non-ideal work-around is this: simply back up the repo at a fixed interval, such as every 10 minutes, using a cron job, and have it look for force pushes and email and text you if it finds any.

My personal cronjob notes to remind myself how to use cron are in my eRCaGuy_dotfiles repo here: eRCaGuy_dotfiles/useful_scripts/cronjobs.

How to make a cron job to automatically back up your repo and look for force pushes every 10 minutes

Here is a potential set of steps that would work. Program these into your cron job script named back_up_wiki_repo.sh or something.

  1. Every 10 minutes:
  2. Git fetch the latest wiki repo to retrieve all changes locally, placing them into your origin/master locally-stored remote-tracking hidden branch. This captures changes added remotely to the web interface by others, so now you have a local backup.
    git fetch origin
    
  3. Append to a log file the current date and time and a list of all commits added since the last time the script ran the current hash the origin/master branch now points to.
  4. Search for any indicators someone ran a git push -f force push, wiping out commits. This can be done by comparing your new origin/master branch to your old master branch. If any commits are on master but not on the freshly-fetched origin/master, then it's because someone did a force push and wiped them out!
    1. A comparison command might look like this:
      # show changes that are in the old `master` but NOT on the
      # freshly-pulled `origin/master`. If this output is not clean it means
      # that someone recently force-pushed to the remote wiki, wiping out
      # changes you had backed up locally! 
      # `^` here means "not on this branch".
      git diff --name-only master ^origin/master
      # OR
      git log --oneline master ^origin/master
      
    2. Log such instances to the log file.
    3. Have your script email you a warning. See my instructions on How to configure and use git send-email with gmail to get started configuring a command-line email client.
    4. Have your script text you a warning. You can text yourself using email, which you just configured above. Virtually all cell phone carriers (in the US at least) allow texting to yourself via an email address. Ex: if your Verizon number is 333-444-5555, then your Verizon email address to send a text to that phone is "[email protected]".
  5. Hard reset your old master branch onto your freshly-fetched locally-stored remote-tracking hiddenorigin/master branch to update master to what you just fetched, preparing for the next iteration:
    git checkout master
    # WARNING WARNING WARNING: hard resets wipe out changes, so you should run
    # the script in a dedicated backup repo location only, not in a place you
    # do active development on the wiki.
    git reset --hard origin/master
    

Sample of what your log file might look like:

back_up_wiki_repo.log:

Date                            Latest hash     Subject
----                            -----------     -------

Tue Oct 18 23:20:00 MST 2022    123456789a      Edited file1
Tue Oct 18 23:30:00 MST 2022    abcdef1234      Did something
Tue Oct 18 23:40:00 MST 2022    1038082872      Did something else
    WARNING! Force push detected!
    LOST COMMITS:
    1038083332
    1108130838
    08283883aa
Tue Oct 18 23:50:00 MST 2022    1011112872      Edited this thing
Tue Oct 19 00:00:00 MST 2022    1019999972      Edited this thing2
  • Related