@@ -23,34 +23,18 @@ import (
2323
2424 "github.com/google/git-appraise/fork"
2525 "github.com/google/git-appraise/repository"
26+ "github.com/google/git-appraise/review"
2627 "golang.org/x/sync/errgroup"
2728)
2829
2930var (
30- pullFlagSet = flag .NewFlagSet ("pull" , flag .ExitOnError )
31+ pullFlagSet = flag .NewFlagSet ("pull" , flag .ExitOnError )
32+ pullVerify = pullFlagSet .Bool ("verify-signatures" , false ,
33+ "verify the signatures of pulled reviews" )
3134 pullIncludeForks = pullFlagSet .Bool ("include-forks" , true , "Also pull reviews and comments from forks." )
3235)
3336
34- // pull updates the local git-notes used for reviews with those from a remote repo.
35- func pull (repo repository.Repo , args []string ) error {
36- pullFlagSet .Parse (args )
37- args = pullFlagSet .Args ()
38-
39- if len (args ) > 1 {
40- return errors .New ("Only pulling from one remote at a time is supported." )
41- }
42-
43- remote := "origin"
44- if len (args ) == 1 {
45- remote = args [0 ]
46- }
47-
48- if ! * pullIncludeForks {
49- return repo .PullNotesAndArchive (remote , notesRefPattern , archiveRefPattern )
50- }
51- if err := repo .PullNotesForksAndArchive (remote , notesRefPattern , fork .Ref , archiveRefPattern ); err != nil {
52- return fmt .Errorf ("failure pulling review metadata from the remote %q: %v" , remote , err )
53- }
37+ func pullFromForks (repo repository.Repo ) error {
5438 forks , err := fork .List (repo )
5539 if err != nil {
5640 return fmt .Errorf ("failure listing the forks: %v" , err )
@@ -86,6 +70,68 @@ func pull(repo repository.Repo, args []string) error {
8670 return nil
8771}
8872
73+ // pull updates the local git-notes used for reviews with those from a remote
74+ // repo.
75+ func pull (repo repository.Repo , args []string ) error {
76+ pullFlagSet .Parse (args )
77+ pullArgs := pullFlagSet .Args ()
78+
79+ if len (pullArgs ) > 1 {
80+ return errors .New (
81+ "Only pulling from one remote at a time is supported." )
82+ }
83+
84+ remote := "origin"
85+ if len (pullArgs ) == 1 {
86+ remote = pullArgs [0 ]
87+ }
88+
89+ if ! * pullVerify {
90+ if ! * pullIncludeForks {
91+ return repo .PullNotesAndArchive (remote , notesRefPattern , archiveRefPattern )
92+ }
93+ if err := repo .PullNotesForksAndArchive (remote , notesRefPattern , fork .Ref , archiveRefPattern ); err != nil {
94+ return fmt .Errorf ("failure pulling review metadata from the remote %q: %v" , remote , err )
95+ }
96+ return pullFromForks (repo )
97+ }
98+
99+ // We collect the fetched reviewed revisions (their hashes), get
100+ // their reviews, and then one by one, verify them. If we make it through
101+ // the set, _then_ we merge the remote reference into the local branch.
102+ revisions , err := repo .FetchAndReturnNewReviewHashes (remote ,
103+ notesRefPattern , archiveRefPattern )
104+ if err != nil {
105+ return err
106+ }
107+ for _ , revision := range revisions {
108+ rvw , err := review .GetSummaryViaRefs (repo ,
109+ "refs/notes/" + remote + "/devtools/reviews" ,
110+ "refs/notes/" + remote + "/devtools/discuss" , revision )
111+ if err != nil {
112+ return err
113+ }
114+ err = rvw .Verify ()
115+ if err != nil {
116+ return err
117+ }
118+ fmt .Println ("verified review:" , revision )
119+ }
120+ if err := repo .MergeNotes (remote , notesRefPattern ); err != nil {
121+ return err
122+ }
123+ if err := repo .MergeArchives (remote , archiveRefPattern ); err != nil {
124+ return err
125+ }
126+ if ! * pullIncludeForks {
127+ return nil
128+ }
129+ if err := repo .MergeForks (remote , fork .Ref ); err != nil {
130+ return err
131+ }
132+ return pullFromForks (repo )
133+ }
134+
89135var pullCmd = & Command {
90136 Usage : func (arg0 string ) {
91137 fmt .Printf ("Usage: %s pull [<option>...] [<remote>]\n \n Options:\n " , arg0 )
0 commit comments