I would like to use git to track changes in crontab.

I have initialized a new git repository in /var/spool/cron/crontabs/

Now the problem is, when crontab is saved, the second line of the header changes because it contains timestamp.

# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/tmp/crontab.ubNueW/crontab installed on Thu Aug  1 06:29:24 2019)

What would be the easiest way to ignore these irrelevant changes ?

The possible duplicate question does not address the main point of my question: How to ignore the first 2 irrelevant lines from crontab. Instead, it addresses some other questions which I have not asked, such as some hooks.

  • 2
    If you're calling git from a script, you could simply delete the line by running sed -i "s/^# (.*installed on.*)/d" on the file before committing the changes to the repository.
    – larsks
    Aug 15 '19 at 17:23
  • this may help depending on what you want to achieve github.com/Intika-Linux-Apps/Startup-Watcher
    – intika
    Aug 21 '19 at 16:37

You should never manually touch the files in the cron spool directory. Making changes to the files there would not notify the cron daemon properly, and updates to schedules would not become active until the daemon is restarted. (Some cron daemon implementations may periodically check the spool to see if there are updated files in there, but this behaviour is not universal; check your cron(8) manual).

The cron(8) manual on Ubuntu says

Note that crontabs in this directory should not be accessed directly - the crontab command should be used to access and update them.

You should always use the crontab command to load new schedules, or to delete existing ones.

As for keeping crontabs in Git, I see no issue with this, but, as I mentioned above, you should not make /var/spool/cron/crontabs a checkout of that repository. Instead, let it live elsewhere and manually load crontabs with e.g.

crontab my-crontab.txt

where my-crontab.txt is a file managed with Git.

This would additionally avoid the issue that you have with the files getting modified by your cron daemon.

  • looking back at your answer, it does not address my qestion at all, and I feel you did not earn the bounty (which was autoawarded in my absense). Amos has actually addressed my question much better. You answer irrelevant points, which I did not ask about, such as editing files in cron spool directory directly. Jun 2 '20 at 6:29
  • @MartinVegter You should accept the answer that is most helpful to you. It's is not possible to refund bounties unfortunately.
    – Kusalananda
    Jun 2 '20 at 6:39
  • @Kusalananda - appreciate the answer - helped me out!
    – schuess
    Feb 6 at 16:19

You could use a filter:

git config filter.dropSecondLine.clean "sed '2d'"

Edit/create .git/info/attributes and add:

* filter=dropSecondLine

If you don't want the filter acting on all the files in the repo, modify the * to match an appropriate pattern or filename.

The effect will be the working directory will remain the same, but the repo blobs will not have the second line in the files. So if you pull it down elsewhere the second line would not appear (the result of the sed 'd2'). And if you change the second line of your log file you will be able to add it, but not commit it, as the change to the blob happens on add, at which point it will be the same file as the one in the repo.

  • 2
    Could I suggest, based on git-scm.com/docs/gitattributes "clean should not alter its output further if it is run twice", that the sed command use a regex to match a commented timestamp (ala larsks' comment /^# (.*installed on.*)) instead of blindly deleting line 2?
    – Jeff Schaller
    Aug 16 '19 at 19:13
  • If a regex is desired it can be edited to match. Though as the docs say, the output won't be altered past the first time. The second line is deleted, the resulting text is what is used for the commit. The working directory doesn't change, so if the second line (but no other line) changes in the working dir you can do a git add again but the commit will show "already up to date". As after the add, the filter triggers and the resulting file is the same as the one already committed
    – Amos
    Aug 16 '19 at 19:17

You could use git blame ("Show what revision and author last modified each line of a file - Annotates each line in the given file with information from the revision which last modified the line. Optionally, start annotating from the given revision.") See also this.

In particular, using the -L option:

-L <start>,<end>
<start> and <end> are optional. “-L <start>” or “-L <start>,” spans from <start> to end of file. “-L ,<end>” spans from start of file to <end>.

This way, you can have the best of both worlds... keeping the info (which perhaps you don't really care about) and ignore it whenever you want.

Otherwise, for configuring, it seems git filter can do it. See links below and another answer here.



Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.