@@ -11,7 +11,6 @@ import (
1111 "github.com/MichaelMure/git-bug-migration/migration1/after/entity"
1212 "github.com/MichaelMure/git-bug-migration/migration1/after/identity"
1313 "github.com/MichaelMure/git-bug-migration/migration1/after/repository"
14- "github.com/MichaelMure/git-bug-migration/migration1/after/util/git"
1514 "github.com/MichaelMure/git-bug-migration/migration1/after/util/lamport"
1615)
1716
@@ -57,11 +56,11 @@ type Bug struct {
5756 // Id used as unique identifier
5857 id entity.Id
5958
60- lastCommit git .Hash
61- rootPack git .Hash
59+ lastCommit repository .Hash
60+ rootPack repository .Hash
6261
6362 // all the committed operations
64- packs []OperationPack
63+ Packs []OperationPack
6564
6665 // a temporary pack of operations used for convenience to pile up new operations
6766 // before a commit
@@ -75,48 +74,32 @@ func NewBug() *Bug {
7574 return & Bug {}
7675}
7776
78- // FindLocalBug find an existing Bug matching a prefix
79- func FindLocalBug (repo repository.ClockedRepo , prefix string ) (* Bug , error ) {
80- ids , err := ListLocalIds (repo )
81-
82- if err != nil {
83- return nil , err
84- }
85-
86- // preallocate but empty
87- matching := make ([]entity.Id , 0 , 5 )
88-
89- for _ , id := range ids {
90- if id .HasPrefix (prefix ) {
91- matching = append (matching , id )
92- }
93- }
94-
95- if len (matching ) == 0 {
96- return nil , errors .New ("no matching bug found." )
97- }
98-
99- if len (matching ) > 1 {
100- return nil , NewErrMultipleMatchBug (matching )
101- }
102-
103- return ReadLocalBug (repo , matching [0 ])
77+ // ReadLocal will read a local bug from its hash
78+ func ReadLocal (repo repository.ClockedRepo , id entity.Id ) (* Bug , error ) {
79+ ref := bugsRefPattern + id .String ()
80+ return read (repo , identity .NewSimpleResolver (repo ), ref )
10481}
10582
106- // ReadLocalBug will read a local bug from its hash
107- func ReadLocalBug (repo repository.ClockedRepo , id entity.Id ) (* Bug , error ) {
83+ // ReadLocalWithResolver will read a local bug from its hash
84+ func ReadLocalWithResolver (repo repository.ClockedRepo , identityResolver identity. Resolver , id entity.Id ) (* Bug , error ) {
10885 ref := bugsRefPattern + id .String ()
109- return readBug (repo , ref )
86+ return read (repo , identityResolver , ref )
87+ }
88+
89+ // ReadRemote will read a remote bug from its hash
90+ func ReadRemote (repo repository.ClockedRepo , remote string , id entity.Id ) (* Bug , error ) {
91+ ref := fmt .Sprintf (bugsRemoteRefPattern , remote ) + id .String ()
92+ return read (repo , identity .NewSimpleResolver (repo ), ref )
11093}
11194
112- // ReadRemoteBug will read a remote bug from its hash
113- func ReadRemoteBug (repo repository.ClockedRepo , remote string , id string ) (* Bug , error ) {
114- ref := fmt .Sprintf (bugsRemoteRefPattern , remote ) + id
115- return readBug (repo , ref )
95+ // ReadRemoteWithResolver will read a remote bug from its hash
96+ func ReadRemoteWithResolver (repo repository.ClockedRepo , identityResolver identity. Resolver , remote string , id entity. Id ) (* Bug , error ) {
97+ ref := fmt .Sprintf (bugsRemoteRefPattern , remote ) + id . String ()
98+ return read (repo , identityResolver , ref )
11699}
117100
118- // readBug will read and parse a Bug from git
119- func readBug (repo repository.ClockedRepo , ref string ) (* Bug , error ) {
101+ // read will read and parse a Bug from git
102+ func read (repo repository.ClockedRepo , identityResolver identity. Resolver , ref string ) (* Bug , error ) {
120103 refSplit := strings .Split (ref , "/" )
121104 id := entity .Id (refSplit [len (refSplit )- 1 ])
122105
@@ -230,42 +213,97 @@ func readBug(repo repository.ClockedRepo, ref string) (*Bug, error) {
230213 // tag the pack with the commit hash
231214 opp .commitHash = hash
232215
233- bug .packs = append (bug .packs , * opp )
216+ bug .Packs = append (bug .Packs , * opp )
234217 }
235218
236219 // Make sure that the identities are properly loaded
237- resolver := identity .NewSimpleResolver (repo )
238- err = bug .EnsureIdentities (resolver )
220+ err = bug .EnsureIdentities (identityResolver )
239221 if err != nil {
240222 return nil , err
241223 }
242224
243225 return & bug , nil
244226}
245227
246- func RemoveLocalBug (repo repository.ClockedRepo , id entity.Id ) error {
247- ref := bugsRefPattern + id .String ()
248- return repo .RemoveRef (ref )
228+ // RemoveBug will remove a local bug from its entity.Id
229+ func RemoveBug (repo repository.ClockedRepo , id entity.Id ) error {
230+ var fullMatches []string
231+
232+ refs , err := repo .ListRefs (bugsRefPattern + id .String ())
233+ if err != nil {
234+ return err
235+ }
236+ if len (refs ) > 1 {
237+ return NewErrMultipleMatchBug (refsToIds (refs ))
238+ }
239+ if len (refs ) == 1 {
240+ // we have the bug locally
241+ fullMatches = append (fullMatches , refs [0 ])
242+ }
243+
244+ remotes , err := repo .GetRemotes ()
245+ if err != nil {
246+ return err
247+ }
248+
249+ for remote := range remotes {
250+ remotePrefix := fmt .Sprintf (bugsRemoteRefPattern + id .String (), remote )
251+ remoteRefs , err := repo .ListRefs (remotePrefix )
252+ if err != nil {
253+ return err
254+ }
255+ if len (remoteRefs ) > 1 {
256+ return NewErrMultipleMatchBug (refsToIds (refs ))
257+ }
258+ if len (remoteRefs ) == 1 {
259+ // found the bug in a remote
260+ fullMatches = append (fullMatches , remoteRefs [0 ])
261+ }
262+ }
263+
264+ if len (fullMatches ) == 0 {
265+ return ErrBugNotExist
266+ }
267+
268+ for _ , ref := range fullMatches {
269+ err = repo .RemoveRef (ref )
270+ if err != nil {
271+ return err
272+ }
273+ }
274+
275+ return nil
249276}
250277
251278type StreamedBug struct {
252279 Bug * Bug
253280 Err error
254281}
255282
256- // ReadAllLocalBugs read and parse all local bugs
257- func ReadAllLocalBugs (repo repository.ClockedRepo ) <- chan StreamedBug {
258- return readAllBugs (repo , bugsRefPattern )
283+ // ReadAllLocal read and parse all local bugs
284+ func ReadAllLocal (repo repository.ClockedRepo ) <- chan StreamedBug {
285+ return readAll (repo , identity .NewSimpleResolver (repo ), bugsRefPattern )
286+ }
287+
288+ // ReadAllLocalWithResolver read and parse all local bugs
289+ func ReadAllLocalWithResolver (repo repository.ClockedRepo , identityResolver identity.Resolver ) <- chan StreamedBug {
290+ return readAll (repo , identityResolver , bugsRefPattern )
291+ }
292+
293+ // ReadAllRemote read and parse all remote bugs for a given remote
294+ func ReadAllRemote (repo repository.ClockedRepo , remote string ) <- chan StreamedBug {
295+ refPrefix := fmt .Sprintf (bugsRemoteRefPattern , remote )
296+ return readAll (repo , identity .NewSimpleResolver (repo ), refPrefix )
259297}
260298
261- // ReadAllRemoteBugs read and parse all remote bugs for a given remote
262- func ReadAllRemoteBugs (repo repository.ClockedRepo , remote string ) <- chan StreamedBug {
299+ // ReadAllRemoteWithResolver read and parse all remote bugs for a given remote
300+ func ReadAllRemoteWithResolver (repo repository.ClockedRepo , identityResolver identity. Resolver , remote string ) <- chan StreamedBug {
263301 refPrefix := fmt .Sprintf (bugsRemoteRefPattern , remote )
264- return readAllBugs (repo , refPrefix )
302+ return readAll (repo , identityResolver , refPrefix )
265303}
266304
267305// Read and parse all available bug with a given ref prefix
268- func readAllBugs (repo repository.ClockedRepo , refPrefix string ) <- chan StreamedBug {
306+ func readAll (repo repository.ClockedRepo , identityResolver identity. Resolver , refPrefix string ) <- chan StreamedBug {
269307 out := make (chan StreamedBug )
270308
271309 go func () {
@@ -278,7 +316,7 @@ func readAllBugs(repo repository.ClockedRepo, refPrefix string) <-chan StreamedB
278316 }
279317
280318 for _ , ref := range refs {
281- b , err := readBug (repo , ref )
319+ b , err := read (repo , identityResolver , ref )
282320
283321 if err != nil {
284322 out <- StreamedBug {Err : err }
@@ -306,22 +344,26 @@ func refsToIds(refs []string) []entity.Id {
306344 ids := make ([]entity.Id , len (refs ))
307345
308346 for i , ref := range refs {
309- split := strings .Split (ref , "/" )
310- ids [i ] = entity .Id (split [len (split )- 1 ])
347+ ids [i ] = refToId (ref )
311348 }
312349
313350 return ids
314351}
315352
353+ func refToId (ref string ) entity.Id {
354+ split := strings .Split (ref , "/" )
355+ return entity .Id (split [len (split )- 1 ])
356+ }
357+
316358// Validate check if the Bug data is valid
317359func (bug * Bug ) Validate () error {
318360 // non-empty
319- if len (bug .packs ) == 0 && bug .staging .IsEmpty () {
361+ if len (bug .Packs ) == 0 && bug .staging .IsEmpty () {
320362 return fmt .Errorf ("bug has no operations" )
321363 }
322364
323365 // check if each pack and operations are valid
324- for _ , pack := range bug .packs {
366+ for _ , pack := range bug .Packs {
325367 if err := pack .Validate (); err != nil {
326368 return err
327369 }
@@ -341,7 +383,7 @@ func (bug *Bug) Validate() error {
341383 }
342384
343385 // The bug Id should be the hash of the first commit
344- if len (bug .packs ) > 0 && string (bug .packs [0 ].commitHash ) != bug .id .String () {
386+ if len (bug .Packs ) > 0 && string (bug .Packs [0 ].commitHash ) != bug .id .String () {
345387 return fmt .Errorf ("bug id should be the first commit hash" )
346388 }
347389
@@ -372,7 +414,7 @@ func (bug *Bug) Append(op Operation) {
372414 bug .staging .Append (op )
373415}
374416
375- // Commit write the staging area in Git and move the operations to the packs
417+ // Commit write the staging area in Git and move the operations to the Packs
376418func (bug * Bug ) Commit (repo repository.ClockedRepo ) error {
377419
378420 if ! bug .NeedCommit () {
@@ -494,7 +536,7 @@ func (bug *Bug) Commit(repo repository.ClockedRepo) error {
494536 }
495537
496538 bug .staging .commitHash = hash
497- bug .packs = append (bug .packs , bug .staging )
539+ bug .Packs = append (bug .Packs , bug .staging )
498540 bug .staging = OperationPack {}
499541
500542 return nil
@@ -514,7 +556,7 @@ func (bug *Bug) NeedCommit() bool {
514556func makeMediaTree (pack OperationPack ) []repository.TreeEntry {
515557 var tree []repository.TreeEntry
516558 counter := 0
517- added := make (map [git .Hash ]interface {})
559+ added := make (map [repository .Hash ]interface {})
518560
519561 for _ , ops := range pack .Operations {
520562 for _ , file := range ops .GetFiles () {
@@ -564,10 +606,10 @@ func (bug *Bug) Merge(repo repository.Repo, other Interface) (bool, error) {
564606 }
565607
566608 ancestorIndex := 0
567- newPacks := make ([]OperationPack , 0 , len (bug .packs ))
609+ newPacks := make ([]OperationPack , 0 , len (bug .Packs ))
568610
569611 // Find the root of the rebase
570- for i , pack := range bug .packs {
612+ for i , pack := range bug .Packs {
571613 newPacks = append (newPacks , pack )
572614
573615 if pack .commitHash == ancestor {
@@ -576,23 +618,23 @@ func (bug *Bug) Merge(repo repository.Repo, other Interface) (bool, error) {
576618 }
577619 }
578620
579- if len (otherBug .packs ) == ancestorIndex + 1 {
621+ if len (otherBug .Packs ) == ancestorIndex + 1 {
580622 // Nothing to rebase, return early
581623 return false , nil
582624 }
583625
584- // get other bug's extra packs
585- for i := ancestorIndex + 1 ; i < len (otherBug .packs ); i ++ {
626+ // get other bug's extra Packs
627+ for i := ancestorIndex + 1 ; i < len (otherBug .Packs ); i ++ {
586628 // clone is probably not necessary
587- newPack := otherBug .packs [i ].Clone ()
629+ newPack := otherBug .Packs [i ].Clone ()
588630
589631 newPacks = append (newPacks , newPack )
590632 bug .lastCommit = newPack .commitHash
591633 }
592634
593- // rebase our extra packs
594- for i := ancestorIndex + 1 ; i < len (bug .packs ); i ++ {
595- pack := bug .packs [i ]
635+ // rebase our extra Packs
636+ for i := ancestorIndex + 1 ; i < len (bug .Packs ); i ++ {
637+ pack := bug .Packs [i ]
596638
597639 // get the referenced git tree
598640 treeHash , err := repo .GetTreeHash (pack .commitHash )
@@ -617,7 +659,7 @@ func (bug *Bug) Merge(repo repository.Repo, other Interface) (bool, error) {
617659 bug .lastCommit = hash
618660 }
619661
620- bug .packs = newPacks
662+ bug .Packs = newPacks
621663
622664 // Update the git ref
623665 err = repo .UpdateRef (bugsRefPattern + bug .id .String (), bug .lastCommit )
@@ -651,7 +693,7 @@ func (bug *Bug) EditLamportTime() lamport.Time {
651693// Lookup for the very first operation of the bug.
652694// For a valid Bug, this operation should be a CreateOp
653695func (bug * Bug ) FirstOp () Operation {
654- for _ , pack := range bug .packs {
696+ for _ , pack := range bug .Packs {
655697 for _ , op := range pack .Operations {
656698 return op
657699 }
@@ -671,11 +713,11 @@ func (bug *Bug) LastOp() Operation {
671713 return bug .staging .Operations [len (bug .staging .Operations )- 1 ]
672714 }
673715
674- if len (bug .packs ) == 0 {
716+ if len (bug .Packs ) == 0 {
675717 return nil
676718 }
677719
678- lastPack := bug .packs [len (bug .packs )- 1 ]
720+ lastPack := bug .Packs [len (bug .Packs )- 1 ]
679721
680722 if len (lastPack .Operations ) == 0 {
681723 return nil
0 commit comments