This file is indexed.

/usr/bin/stg-cvs is in stgit-contrib 0.17.1-1.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#!/bin/bash
set -e

# stg-cvs - helper script to manage a mixed cvs/stgit working copy.

# Allows quick synchronization of a cvs mirror branch (does not try to
# reconstruct patchsets, creates "jumbo" commits), and commits stgit
# patches to CVS.

# Copyright (c) 2007 Yann Dirson <ydirson@altern.org>
# Subject to the GNU GPL, version 2.

# NOTES
# - you want to add a "CVS" line to .git/info/exclude
# - you may want to add a ".git" line to the top .cvsignore

# BRANCH INIT
# - ensure the cvs wc is clean (eg. with "cvsco")
# $ git init
# $ echo CVS >> .git/info/exclude
# $ git add .
# $ git commit -m "Initial import."
# $ git branch -m master cvs
# $ stg branch -c master cvs
# $ git config branch.master.stgit.parentbranch cvs (0.12.1 and earlier only)
# $ git config branch.cvs.description "CVS $(cat CVS/Root) $(cat CVS/Repository) $(cat CVS/Tag 2>/dev/null | echo HEAD)"
# $ git config branch.master.description "Changes for $(cat CVS/Repository) $(cat CVS/Tag 2>/dev/null | echo HEAD)"

# LIMITATIONS
# - this is only a proof-of-concept prototype
# - lacks an "init" command (see above)
# - "commit" does not ensure the base is uptodate before trying to
#   commit (but hey, it's CVS ;): better "stg-cvs pull" first
# - "commit" can only commit a single patch
# - not much robustness here
# - still no support for files removed in cvs (should catch "no
#   longer in the repository" message)
# - this only deals with CVS but could surely be extended to any other
#   VCS
# - lacks synchronisation of .cvsignore <-> .gitignore
# - no support for filenames with spaces (stg lacks --zero output format)
# - git commit is too chatty when it finds nothing to commit
# - lacks a "quick cvs commit" feature

# DESIGN FLAWS
# - while fetching, if a file change was not git update-index'd when
#   cvs-update'd (eg. because of a stg-cvs bug), it is not seen on further
#   fetches until it changes again, since we scan "cvs update" output.
#   This yields possible inconsistencies with CVS.
# - similarly, any conflict while cvs-updating (whether due to illegal
#   changes to the cvs-mirror-branch, or due to files added to cvs but
#   already-existing in working copy, or to directory moves inside the
#   cvs repository, or <fill here>) has to be dealt with by hand (although
#   the situation is better here: cvs sees the conflict on subsequent tries)
# - bad/no support for cvsutils:
#   - stg push/pop operations confuse cvsu because of timestamp changes
#   - cvspurge/cvsco would nuke .git => does not make it easy to ensure
#     synchronisation
# - should use a separate workspace for cvs branch like tailor does
# - confused by cvs keyword substitution

usage()
{
    [ "$#" = 0 ] || echo "ERROR: $*"
    echo "Usage: $(basename $0) <command>"
    echo " commands: $(do_commands)"
    exit 1
}

do_commands()
{
    echo $(grep '^[a-z-]*)' $0 | cut -d')' -f1)
}

do_fetch()
{
    local return=0
    local path

    local parent="$1"
    local branch="$2"

    # record changes from cvs into index
    stg branch "$parent" || exit $?
    cvs -fq update -dP | grep -v '^\? ' | tee /dev/tty | while read status path; do
	if [ -e "$path" ]; then
	    git update-index --add "$path" || exit $?
	else
	    git update-index --remove "$path" || exit $?
	fi
	# cvs update: `FELIN1_PEP/src/java/com/sagem/felin/ui/widget/PEPRifStateIcon.java' is no longer in the repository
    done

    # create commit
    if git commit -m "stg-cvs sync"; then
	:
    else
	return=$?
    fi

    # back to branch
    stg branch "$branch" || exit $?

    return $return
}

cvs_add_dir()
{
    local parent=$(dirname "$1")
    if [ ! -e "$parent/CVS" ]; then
	cvs_add_dir "$parent"
    fi

    cvs add "$1"
}

# get context
branch=$(stg branch)
parent=$(git config "branch.${branch}.stgit.parentbranch") || 
    usage "no declared parent for '$branch' - set branch.${branch}.stgit.parentbranch"

# extract command

[ "$#" -ge 1 ] || usage
command="$1"
shift

case "$command" in
fetch)
    do_fetch "$parent" "$branch"
    ;;

pull)
    if do_fetch "$parent" "$branch"; then
	# update
	#  --merged
	stg rebase "$parent"
	stg clean --applied
    fi
    ;;

commit)
    # sanity asserts
    [ $(stg applied | wc -l) = 1 ] ||
	usage "you don't have exactly one patch applied"

    # context
    patch=$(stg top)
    
    # adds
    stg files | grep ^A | cut -c3- | while read file; do
	parent=$(dirname "$file")
	if [ ! -e "$parent/CVS" ]; then
	    cvs_add_dir "$parent"
	fi
	cvs -f add "$file"
    done

    # removes
    stg files | grep ^D | cut -c3- | xargs -r cvs -f remove

    # commit
    stg files --bare | xargs -r cvs -fq commit \
	-F ".git/patches/$branch/patches/$patch/description"

    # sync the parent branch
    stg branch "$parent"
    git cherry-pick "patches/${branch}/${patch}"
    stg branch "${branch}"

    # update
    # --merged
    stg rebase "$parent"
    stg clean --applied
    ;;

_commands)
    # hint for bash-completion people :)
    do_commands
    ;;

*)
    usage "unknown command '$command'"
    ;;
esac