@@ -146,3 +146,202 @@ func RepoRemoveRemote(repoPath, name string, opts ...RemoveRemoteOptions) error
146146func (r * Repository ) RemoveRemote (name string , opts ... RemoveRemoteOptions ) error {
147147 return RepoRemoveRemote (r .path , name , opts ... )
148148}
149+
150+ // RemotesOptions contains arguments for listing remotes of the repository.
151+ // Docs: https://git-scm.com/docs/git-remote#_commands
152+ type RemotesOptions struct {
153+ // The timeout duration before giving up for each shell command execution.
154+ // The default timeout duration will be used when not supplied.
155+ Timeout time.Duration
156+ }
157+
158+ // Remotes lists remotes of the repository in given path.
159+ func Remotes (repoPath string , opts ... RemotesOptions ) ([]string , error ) {
160+ var opt RemotesOptions
161+ if len (opts ) > 0 {
162+ opt = opts [0 ]
163+ }
164+
165+ stdout , err := NewCommand ("remote" ).RunInDirWithTimeout (opt .Timeout , repoPath )
166+ if err != nil {
167+ return nil , err
168+ }
169+
170+ return bytesToStrings (stdout ), nil
171+ }
172+
173+ // Remotes lists remotes of the repository.
174+ func (r * Repository ) Remotes (opts ... RemotesOptions ) ([]string , error ) {
175+ return Remotes (r .path , opts ... )
176+ }
177+
178+ // RemoteGetURLOptions contains arguments for retrieving URL(s) of a remote of
179+ // the repository.
180+ //
181+ // Docs: https://git-scm.com/docs/git-remote#Documentation/git-remote.txt-emget-urlem
182+ type RemoteGetURLOptions struct {
183+ // Indicates whether to get push URLs instead of fetch URLs.
184+ Push bool
185+ // Indicates whether to get all URLs, including lists that are not part of main
186+ // URLs. This option is independent of the Push option.
187+ All bool
188+ // The timeout duration before giving up for each shell command execution.
189+ // The default timeout duration will be used when not supplied.
190+ Timeout time.Duration
191+ }
192+
193+ // RemoteGetURL retrieves URL(s) of a remote of the repository in given path.
194+ func RemoteGetURL (repoPath , name string , opts ... RemoteGetURLOptions ) ([]string , error ) {
195+ var opt RemoteGetURLOptions
196+ if len (opts ) > 0 {
197+ opt = opts [0 ]
198+ }
199+
200+ cmd := NewCommand ("remote" , "get-url" )
201+ if opt .Push {
202+ cmd .AddArgs ("--push" )
203+ }
204+ if opt .All {
205+ cmd .AddArgs ("--all" )
206+ }
207+
208+ stdout , err := cmd .AddArgs (name ).RunInDirWithTimeout (opt .Timeout , repoPath )
209+ if err != nil {
210+ return nil , err
211+ }
212+ return bytesToStrings (stdout ), nil
213+ }
214+
215+ // RemoteGetURL retrieves URL(s) of a remote of the repository in given path.
216+ func (r * Repository ) RemoteGetURL (name string , opts ... RemoteGetURLOptions ) ([]string , error ) {
217+ return RemoteGetURL (r .path , name , opts ... )
218+ }
219+
220+ // RemoteSetURLOptions contains arguments for setting an URL of a remote of the
221+ // repository.
222+ //
223+ // Docs: https://git-scm.com/docs/git-remote#Documentation/git-remote.txt-emset-urlem
224+ type RemoteSetURLOptions struct {
225+ // Indicates whether to get push URLs instead of fetch URLs.
226+ Push bool
227+ // The regex to match existing URLs to replace (instead of first).
228+ Regex string
229+ // The timeout duration before giving up for each shell command execution.
230+ // The default timeout duration will be used when not supplied.
231+ Timeout time.Duration
232+ }
233+
234+ // RemoteSetURL sets first URL of the remote with given name of the repository in given path.
235+ func RemoteSetURL (repoPath , name , newurl string , opts ... RemoteSetURLOptions ) error {
236+ var opt RemoteSetURLOptions
237+ if len (opts ) > 0 {
238+ opt = opts [0 ]
239+ }
240+
241+ cmd := NewCommand ("remote" , "set-url" )
242+ if opt .Push {
243+ cmd .AddArgs ("--push" )
244+ }
245+
246+ cmd .AddArgs (name , newurl )
247+
248+ if opt .Regex != "" {
249+ cmd .AddArgs (opt .Regex )
250+ }
251+
252+ _ , err := cmd .RunInDirWithTimeout (opt .Timeout , repoPath )
253+ if err != nil {
254+ if strings .Contains (err .Error (), "No such URL found" ) {
255+ return ErrURLNotExist
256+ } else if strings .Contains (err .Error (), "No such remote" ) {
257+ return ErrRemoteNotExist
258+ }
259+ return err
260+ }
261+ return nil
262+ }
263+
264+ // RemoteSetURL sets the first URL of the remote with given name of the repository.
265+ func (r * Repository ) RemoteSetURL (name , newurl string , opts ... RemoteSetURLOptions ) error {
266+ return RemoteSetURL (r .path , name , newurl , opts ... )
267+ }
268+
269+ // RemoteSetURLAddOptions contains arguments for appending an URL to a remote
270+ // of the repository.
271+ //
272+ // Docs: https://git-scm.com/docs/git-remote#Documentation/git-remote.txt-emset-urlem
273+ type RemoteSetURLAddOptions struct {
274+ // Indicates whether to get push URLs instead of fetch URLs.
275+ Push bool
276+ // The timeout duration before giving up for each shell command execution.
277+ // The default timeout duration will be used when not supplied.
278+ Timeout time.Duration
279+ }
280+
281+ // RemoteSetURLAdd appends an URL to the remote with given name of the repository in
282+ // given path. Use RemoteSetURL to overwrite the URL(s) instead.
283+ func RemoteSetURLAdd (repoPath , name , newurl string , opts ... RemoteSetURLAddOptions ) error {
284+ var opt RemoteSetURLAddOptions
285+ if len (opts ) > 0 {
286+ opt = opts [0 ]
287+ }
288+
289+ cmd := NewCommand ("remote" , "set-url" , "--add" )
290+ if opt .Push {
291+ cmd .AddArgs ("--push" )
292+ }
293+
294+ cmd .AddArgs (name , newurl )
295+
296+ _ , err := cmd .RunInDirWithTimeout (opt .Timeout , repoPath )
297+ if err != nil && strings .Contains (err .Error (), "Will not delete all non-push URLs" ) {
298+ return ErrNotDeleteNonPushURLs
299+ }
300+ return err
301+ }
302+
303+ // RemoteSetURLAdd appends an URL to the remote with given name of the repository.
304+ // Use RemoteSetURL to overwrite the URL(s) instead.
305+ func (r * Repository ) RemoteSetURLAdd (name , newurl string , opts ... RemoteSetURLAddOptions ) error {
306+ return RemoteSetURLAdd (r .path , name , newurl , opts ... )
307+ }
308+
309+ // RemoteSetURLDeleteOptions contains arguments for deleting an URL of a remote
310+ // of the repository.
311+ //
312+ // Docs: https://git-scm.com/docs/git-remote#Documentation/git-remote.txt-emset-urlem
313+ type RemoteSetURLDeleteOptions struct {
314+ // Indicates whether to get push URLs instead of fetch URLs.
315+ Push bool
316+ // The timeout duration before giving up for each shell command execution.
317+ // The default timeout duration will be used when not supplied.
318+ Timeout time.Duration
319+ }
320+
321+ // RemoteSetURLDelete deletes the remote with given name of the repository in
322+ // given path.
323+ func RemoteSetURLDelete (repoPath , name , regex string , opts ... RemoteSetURLDeleteOptions ) error {
324+ var opt RemoteSetURLDeleteOptions
325+ if len (opts ) > 0 {
326+ opt = opts [0 ]
327+ }
328+
329+ cmd := NewCommand ("remote" , "set-url" , "--delete" )
330+ if opt .Push {
331+ cmd .AddArgs ("--push" )
332+ }
333+
334+ cmd .AddArgs (name , regex )
335+
336+ _ , err := cmd .RunInDirWithTimeout (opt .Timeout , repoPath )
337+ if err != nil && strings .Contains (err .Error (), "Will not delete all non-push URLs" ) {
338+ return ErrNotDeleteNonPushURLs
339+ }
340+ return err
341+ }
342+
343+ // RemoteSetURLDelete deletes all URLs matching regex of the remote with given
344+ // name of the repository.
345+ func (r * Repository ) RemoteSetURLDelete (name , regex string , opts ... RemoteSetURLDeleteOptions ) error {
346+ return RemoteSetURLDelete (r .path , name , regex , opts ... )
347+ }
0 commit comments