dejagnu
[Top][All Lists]
Advanced

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

Fixing problems reported by "git fsck"


From: Shahab Vahedi
Subject: Fixing problems reported by "git fsck"
Date: Thu, 30 Nov 2023 18:38:15 +0000

TL;DR;
There are problems in internal structure of DejaGnu's git repo. A
POSIX shell script is proposed at the end of this message that fixes
them. During this fix, no commit is touched, so the history remains
intact. Please continue reading for further details.

I have cloned DejaGnu's codebase from the official repo. When I
wanted to push it to a Github account, it got rejected. I looked
further into the matter and noticed that "git fsck" is detecting
some errors in the repo:
----------------------------------------------------------------------
$ git --version
  git version 2.42.0

$ git clone git://git.sv.gnu.org/dejagnu.git 
$ cd dejagnu
$ git fsck
  error in tag 0d2d0605443b24b470155111fc695a73c962173f:
    missingSpaceBeforeDate: invalid author/committer line
    - missing space before date
  error in tag acdc1784d37050d3945c8fb5258fc0e50cbc40db:
    [ditto]
  error in tag 94fbb053f944416569221e1de7ff91fd48e6ebde:
    [ditto]
  error in tag 4dbe11b30f3e573058f30664e70ee08b56ef5292:
    [ditto]
  error in tag ca14993ef275ae7d0f0218ef59048373ee6dfe18:
    [ditto]
----------------------------------------------------------------------
 
According to Git's fsck, there are 5 corrupted tag objects. Let's
check which tags they are exactly:
----------------------------------------------------------------------
$ git for-each-ref | grep "refs/tags"
  0d2d0605443b24b470155... tag  refs/tags/dejagnu-1.4.1-release
  acdc1784d37050d3945c8... tag  refs/tags/dejagnu-1.4.2-release
  94fbb053f944416569221... tag  refs/tags/dejagnu-1.4.3-release
  4dbe11b30f3e573058f30... tag  refs/tags/dejagnu-1.4.4-release
  ...
  ca14993ef275ae7d0f021... tag  refs/tags/from-devo
  ...
----------------------------------------------------------------------

And inspecting them, say the second one (acdc178), reveals:
----------------------------------------------------------------------
$ git show acdc178 | head
  tag release_1_4_2   ---> The tag is called "release_1_4_2",
                           while the name is "dejagnu-1.4.2-release"
                           (cross checked with "git for-each-ref").
  Tagger: Rob Savoye <rob@welcomehome.org>
  Date:   Thu Jan 1 00:00:00 1970 +0000
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                      |
                      `--> epoch time!

  commit 56a71936f9f95d480cfca7766df89e73f200d081
  Author: Rob Savoye <rob@welcomehome.org>
  Date:   Thu Sep 13 02:34:49 2001 +0000
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                      |
                      `--> commit date (good candidate).

      Change the version number to 1.4.2.
----------------------------------------------------------------------

The date property of the tag is not correct.

DejaGnu is not the first software project that suffers from this.
Apparently, the same problem was observed in X.org repo. In this blog
post [1] a plausible solution was discussed.

[1] Pushing X.org Git repos to Github et al.
https://sunweavers.net/blog/node/36

The idea is to remove the faulty tags and replace them with new ones
that has the same property plus the date coming from the commit that
they point to. The proposed script did not work out of the box in
DejaGnu's case and needed to be adjusted. I couldn't have done this
without the help of "osse" in #git IRC channel on LiberaChat.

Finally the POSIX shell script:
----------------------------------------------------------------------
#! /bin/sh
# shellcheck disable=SC2250

set -e

git fsck 2>&1 |
grep "error in tag" |
sed -r -e "s/error in tag ([0-9a-f]+):.*/\1/" |
while read -r broken
do
  # extracting tag info: ID, commit it points to, name, and the message
  tag=$(git cat-file tag "$broken" | sed -n 's/^tag //p')
  commit=$(git rev-parse "$broken^{commit}")
  tag_name=$(git for-each-ref | grep "$broken" | cut -d '/' -f 3)
  tag_msg=$(git cat-file tag "$broken" | sed -n '/^$/,$p' | tail -n +2)

  # print the tag SHA1 and its ID (not the same as its name)
  echo; echo "$broken  --  $tag"

  # rebuild the information for the "git tag" command ensuing
  GIT_COMMITTER_NAME=$(git log -1 --format='%cn' "$commit")
  GIT_COMMITTER_EMAIL=$(git log -1 --format='%ce' "$commit")
  GIT_COMMITTER_DATE=$(git log -1 --format='%cD' "$commit")
  export GIT_COMMITTER_NAME
  export GIT_COMMITTER_EMAIL
  export GIT_COMMITTER_DATE

  git tag -d "$tag_name"  # without this, the faulty $tag won't go away.
  git tag -a -f -m "$tag_msg" "$tag_name" "$commit"
done
echo

# drop all old content...
git reflog expire --expire=all --all
git gc --prune=all

# no more errors should be reported...
git fsck
----------------------------------------------------------------------

Caveat Emptor: I'm not sure of the impact of "git gc --prune=all" on
DejaGnu's code base as it has some branches. So please double check
that doesn't remove things that it shouldn't.


Cheers,
Shahab

reply via email to

[Prev in Thread] Current Thread [Next in Thread]