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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
.Dd October 17, 2026
.Dt PORTS 8
.Os
.Sh NAME
.Nm ports
.Nd sync, list, compare and clean port collections
.Sh SYNOPSIS
.Nm
.Fl u
.Op Ar name ...
.Nm
.Fl l
.Op Ar collection ...
.Nm
.Fl d
.Op Ar collection ...
.Nm
.Fl x Ns Op Ar dfsw
.Op Ar collection ...
.Nm
.Fl h | v
.Sh DESCRIPTION
.Nm
keeps the port collections up to date and reports on them.
Collections are configured by files in
.Pa /etc/ports/
ending in
.Pa .rsync
or
.Pa .git ;
see
.Sx CONFIGURATION .
Files with any other name, such as the shipped
.Pa ports.rsync.inactive ,
are ignored.
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl d
Compare the port tree with the package database.
For every installed package whose port has a different
.Ar version Ns - Ns Ar release ,
print the collection, port, installed version and port version.
.It Fl h , Fl Fl help
Print a usage summary.
.It Fl l
List every port, as
.Ar collection Ns / Ns Ar port .
.It Fl u Op Ar name ...
Sync the collections from their remotes.
A
.Ar name
may be a configuration file without its extension, which syncs all of
its collections, or a collection name.
Without a
.Ar name ,
everything is synced.
Requires root.
.It Fl v , Fl Fl version
Print the version.
.It Fl x Ns Op Ar dfsw
Clean the port directories: remove package files other than the one
the port's recipe would build.
Further letters remove more:
.Bl -tag -width Ds
.It Cm d
Source archives that the recipe does not list.
.It Cm f
.Pa .footprint
files.
.It Cm s
.Pa .signature
files.
.It Cm w
.Pa work
directories.
.El
.Pp
Requires root.
.El
.Pp
.Fl l ,
.Fl d
and
.Fl x
work on every configured collection: each collection of an rsync
configuration, under its key, and each git configuration, under its
file name.
If no configuration is active they use
.Pa /ports/core ,
.Pa /usr/ports/libs ,
.Pa /usr/ports/devel ,
.Pa /usr/ports/python ,
.Pa /usr/ports/perl
and
.Pa /usr/ports/opt
instead.
Every directory in
.Pa /usr/local/ports/
is a collection as well.
Naming one or more
.Ar collection Ns s
restricts them to those.
.Pp
A directory is a port if it holds a
.Pa MAKEPKG
or a
.Pa MAKEPKG.lock .
The recipe of a port is
.Pa MAKEPKG.lock
if there is one, else
.Pa MAKEPKG ,
as for
.Xr mkpkg 8 .
.Sh SYNCING
Only the recipes and the files that belong with them are synced.
Package archives,
.Pa work/
directories and
.Pa *.lock
files are never transferred and never deleted, so locked ports keep
their lock; see
.Xr mkpkg 8 .
Neither are the sources a port downloaded: the usual archive names are
excluded outright, and every other file a recipe lists in
.Va source
is protected by name, whatever it is called.
An update never removes a download; the sources a recipe no longer
lists are removed by
.Fl xd .
File owners are not copied, and modes become 755 for directories and
644 for files.
.Pp
With rsync, a port directory that exists upstream is made identical to
it.
Nothing else in the destination is deleted by the transfer, so a
collection may live in a directory it shares with other files, such as
.Pa /usr/src .
.Pp
In a directory the collection owns, a port that upstream no longer has
is removed after the transfer, but only if its directory holds a
.Pa MAKEPKG
and no
.Pa MAKEPKG.lock ;
a locked port is kept and reported.
Other directories and files are never touched.
A port that was never upstream is indistinguishable from one upstream
dropped, so in a directory marked
.Cm shared
this pass is skipped altogether and nothing at the top level is
removed; see
.Sx CONFIGURATION .
.Pp
With git, the destination is cloned if it is not a git checkout yet,
and otherwise updated with
.Ic git pull --ff-only .
.Sh CONFIGURATION
An rsync configuration,
.Pa /etc/ports/ Ns Ar name Ns Pa .rsync ,
has
.Ar key Ns = Ns Ar value
lines:
.Bl -tag -width Ds
.It Cm host
The rsync server.
.It Cm module
The rsync module.
.It Cm token
Optional.
Used as user name and, through
.Ev RSYNC_PASSWORD ,
as password.
.It Ar collection Ns = Ns Ar directory Op Ar flag ...
Any other key is a collection: the remote directory
.Ar module Ns / Ns Ar collection Ns /
is synced into
.Ar directory .
The flags are
.Cm strict ,
the default, for a directory that belongs to the collection, where a
port upstream retired is removed, and
.Cm shared
for a directory that holds more than this collection's ports, where
nothing at the top level is ever removed.
Use
.Cm shared
for a collection syncing into
.Pa /usr/src
beside kernel trees and ports of your own.
.El
.Pp
A git configuration,
.Pa /etc/ports/ Ns Ar name Ns Pa .git ,
has
.Cm url ,
.Cm branch ,
which defaults to
.Li main ,
and
.Cm destination .
.Pp
Empty lines and lines starting with
.Ql #
are ignored.
.Sh FILES
.Bl -tag -width Ds -compact
.It Pa /etc/ports/*.rsync , /etc/ports/*.git
Collection configuration.
.It Pa /var/lib/pkg/db
Package database, read by
.Fl d .
.El
.Sh EXIT STATUS
.Ex -std
.Fl u
fails if any collection failed to sync.
.Sh EXAMPLES
An rsync configuration with two collections:
.Bd -literal -offset indent
host=rsync.rawnix.org
module=ports
token=YOUR_TOKEN
core=/ports/core
linux=/usr/src shared
.Ed
.Pp
Sync only the
.Li core
collection:
.Pp
.Dl # ports -u core
.Sh SEE ALSO
.Xr rsync 1 ,
.Xr MAKEPKG 5 ,
.Xr bulk 8 ,
.Xr mkpkg 8
|