@@ -15,6 +15,10 @@ func FindRenames(dir string, oldCommit string, newCommit string) (map[string]str
1515 repo := & GitRepo {Dir : dir }
1616 return repo .FindRenames (oldCommit , newCommit )
1717}
18+ func FindRenamesV2 (dir string , oldCommit string , newCommit string , fn func (newFile string , oldFile string , percent string )) error {
19+ repo := & GitRepo {Dir : dir }
20+ return repo .FindRenamesV2 (oldCommit , newCommit , fn )
21+ }
1822
1923func FindUpdate (dir string , oldCommit string , newCommit string ) ([]string , error ) {
2024 repo := & GitRepo {Dir : dir }
@@ -121,6 +125,89 @@ func (c *GitRepo) FindRenames(oldCommit string, newCommit string) (map[string]st
121125 return m , nil
122126}
123127
128+ func (c * GitRepo ) FindRenamesV2 (oldCommit string , newCommit string , fn func (newFile string , oldFile string , percent string )) error {
129+ cmd := fmt .Sprintf (`git -C %s diff --diff-filter=R --summary %s %s || true` , sh .Quote (c .Dir ), sh .Quote (getRef (oldCommit )), sh .Quote (getRef (newCommit )))
130+ stdout , stderr , err := sh .RunBashCmdOpts (cmd , sh.RunBashOptions {
131+ // Verbose: true,
132+ NeedStdOut : true ,
133+ // NeedStdErr: true,
134+ })
135+ // fmt.Printf("stderr:%v", stderr)
136+ _ = stderr
137+ if err != nil {
138+ return err
139+ }
140+ parseRenames (stdout , fn )
141+ return nil
142+ }
143+
144+ func parseRenames (renamedFilesWithSummary string , fn func (newFile string , oldFile string , percent string )) {
145+ renames := splitLinesFilterEmpty (renamedFilesWithSummary )
146+ for _ , line := range renames {
147+ line = strings .TrimSpace (line )
148+ if ! strings .HasPrefix (line , "rename " ) {
149+ continue
150+ }
151+ s := strings .TrimSpace (line [len ("rename " ):])
152+
153+ // parse percent
154+ // rename src/{module_funder/id/submodule_funder_seabank/cl => module_funder_bke/id}/bcl/task/repair_clawback_task.go (64%)
155+ var percent string
156+ pEidx := strings .LastIndex (s , ")" )
157+ if pEidx >= 0 {
158+ s = strings .TrimSpace (s [:pEidx ])
159+ pIdx := strings .LastIndex (s , "(" )
160+ if pIdx >= 0 {
161+ percent = strings .TrimSpace (s [pIdx + 1 :])
162+ s = strings .TrimSpace (s [:pIdx ])
163+ }
164+ }
165+
166+ bIdx := strings .Index (s , "{" )
167+ if bIdx < 0 {
168+ continue
169+ }
170+ bEIdx := strings .LastIndex (s , "}" )
171+ if bEIdx < 0 {
172+ continue
173+ }
174+ prefix := s [:bIdx ]
175+ var suffix string
176+ if bEIdx + 1 < len (s ) {
177+ suffix = s [bEIdx + 1 :]
178+ }
179+ s = s [bIdx + 1 : bEIdx ]
180+ sep := " => "
181+ toIdx := strings .Index (s , sep )
182+ if toIdx < 0 {
183+ continue
184+ }
185+ oldPath := s [:toIdx ]
186+ var newPath string
187+ if toIdx + len (sep ) < len (s ) {
188+ newPath = s [toIdx + len (sep ):]
189+ }
190+
191+ file := joinPath (prefix , newPath , suffix )
192+ oldFile := joinPath (prefix , oldPath , suffix )
193+
194+ fn (file , oldFile , percent )
195+ }
196+ }
197+
198+ func joinPath (p ... string ) string {
199+ j := 0
200+ for i := 0 ; i < len (p ); i ++ {
201+ e := strings .TrimPrefix (p [i ], "/" )
202+ e = strings .TrimSuffix (e , "/" )
203+ if e != "" {
204+ p [j ] = e
205+ j ++
206+ }
207+ }
208+ return strings .Join (p [:j ], "/" )
209+ }
210+
124211type GitSnapshot struct {
125212 Dir string
126213 Commit string
0 commit comments