@@ -13,8 +13,8 @@ import (
1313)
1414
1515type SyncSourceWorktreeWithServiceBranchOptions struct {
16- ServiceBranchPrefix string
17- GlobExcludeList []string
16+ ServiceBranch string
17+ GlobExcludeList []string
1818}
1919
2020func SyncSourceWorktreeWithServiceBranch (ctx context.Context , gitDir , sourceWorktreeDir , worktreeCacheDir , commit string , opts SyncSourceWorktreeWithServiceBranchOptions ) (string , error ) {
@@ -39,10 +39,9 @@ func SyncSourceWorktreeWithServiceBranch(ctx context.Context, gitDir, sourceWork
3939 return fmt .Errorf ("unable to remove %s: %s" , currentCommitPath , err )
4040 }
4141
42- branchName := fmt .Sprintf ("%s%s" , opts .ServiceBranchPrefix , commit )
43- resultCommit , err = syncWorktreeWithServiceWorktreeBranch (ctx , sourceWorktreeDir , serviceWorktreeDir , commit , branchName , opts .GlobExcludeList )
42+ resultCommit , err = syncWorktreeWithServiceWorktreeBranch (ctx , sourceWorktreeDir , serviceWorktreeDir , commit , opts .ServiceBranch , opts .GlobExcludeList )
4443 if err != nil {
45- return fmt .Errorf ("unable to sync worktree with service branch %q: %s" , branchName , err )
44+ return fmt .Errorf ("unable to sync worktree with service branch %q: %s" , opts . ServiceBranch , err )
4645 }
4746
4847 return nil
@@ -54,14 +53,13 @@ func SyncSourceWorktreeWithServiceBranch(ctx context.Context, gitDir, sourceWork
5453}
5554
5655func syncWorktreeWithServiceWorktreeBranch (ctx context.Context , sourceWorktreeDir , serviceWorktreeDir , sourceCommit , branchName string , globExcludeList []string ) (string , error ) {
57- serviceBranchHeadCommit , err := getOrPrepareServiceBranchHeadCommit (ctx , serviceWorktreeDir , sourceCommit , branchName )
58- if err != nil {
56+ if err := prepareAndCheckoutServiceBranch (ctx , serviceWorktreeDir , sourceCommit , branchName ); err != nil {
5957 return "" , fmt .Errorf ("unable to get or prepare service branch head commit: %s" , err )
6058 }
6159
62- checkoutCmd := NewGitCmd (ctx , & GitCmdOptions { RepoDir : serviceWorktreeDir }, "checkout" , branchName )
63- if err = checkoutCmd . Run ( ctx ); err != nil {
64- return "" , fmt .Errorf ("git checkout command failed : %s" , err )
60+ serviceBranchHeadCommit , err := GetLastBranchCommitSHA (ctx , serviceWorktreeDir , branchName )
61+ if err != nil {
62+ return "" , fmt .Errorf ("unable to get service worktree commit SHA : %s" , err )
6563 }
6664
6765 revertedChangesExist , err := revertExcludedChangesInServiceWorktreeIndex (ctx , sourceWorktreeDir , serviceWorktreeDir , sourceCommit , serviceBranchHeadCommit , globExcludeList )
@@ -90,31 +88,44 @@ func syncWorktreeWithServiceWorktreeBranch(ctx context.Context, sourceWorktreeDi
9088 return newCommit , nil
9189}
9290
93- func getOrPrepareServiceBranchHeadCommit (ctx context.Context , serviceWorktreeDir string , sourceCommit string , branchName string ) ( string , error ) {
91+ func prepareAndCheckoutServiceBranch (ctx context.Context , serviceWorktreeDir string , sourceCommit string , branchName string ) error {
9492 branchListCmd := NewGitCmd (ctx , & GitCmdOptions {RepoDir : serviceWorktreeDir }, "branch" , "--list" , branchName )
9593 if err := branchListCmd .Run (ctx ); err != nil {
96- return "" , fmt .Errorf ("git branch list command failed: %s" , err )
94+ return fmt .Errorf ("git branch list command failed: %s" , err )
9795 }
9896
99- var isServiceBranchExist bool
100- isServiceBranchExist = branchListCmd .OutBuf .Len () != 0
101-
102- if ! isServiceBranchExist {
97+ if branchListCmd .OutBuf .Len () == 0 {
10398 checkoutCmd := NewGitCmd (ctx , & GitCmdOptions {RepoDir : serviceWorktreeDir }, "checkout" , "-b" , branchName , sourceCommit )
10499 if err := checkoutCmd .Run (ctx ); err != nil {
105- return "" , fmt .Errorf ("git checkout command failed: %s" , err )
100+ return fmt .Errorf ("git checkout command failed: %s" , err )
106101 }
107102
108- return sourceCommit , nil
103+ return nil
109104 }
110105
111- revParseCmd := NewGitCmd (ctx , & GitCmdOptions {RepoDir : serviceWorktreeDir }, "rev-parse" , branchName )
112- if err := revParseCmd .Run (ctx ); err != nil {
113- return "" , fmt .Errorf ("git rev parse branch command failed: %s" , err )
106+ checkoutCmd := NewGitCmd (ctx , & GitCmdOptions {RepoDir : serviceWorktreeDir }, "checkout" , branchName )
107+ if err := checkoutCmd .Run (ctx ); err != nil {
108+ return fmt .Errorf ("git checkout command failed: %s" , err )
109+ }
110+
111+ isSourceCommitInServiceBranch , err := IsAncestor (ctx , sourceCommit , branchName , serviceWorktreeDir )
112+ if err != nil {
113+ return fmt .Errorf ("unable to detect whether sourceCommit %q is in service branch: %s" , sourceCommit , err )
114+ }
115+ if isSourceCommitInServiceBranch {
116+ return nil
117+ }
118+
119+ mergeCmd := NewGitCmd (
120+ ctx , & GitCmdOptions {RepoDir : serviceWorktreeDir },
121+ "-c" , "user.email=werf@werf.io" , "-c" , "user.name=werf" ,
122+ "merge" , "--no-edit" , "--no-ff" , "--allow-unrelated-histories" , "-s" , "recursive" , "-X" , "theirs" , sourceCommit ,
123+ )
124+ if err = mergeCmd .Run (ctx ); err != nil {
125+ return fmt .Errorf ("git merge of source commit %q into service branch failed: %s" , sourceCommit , err )
114126 }
115127
116- serviceBranchHeadCommit := strings .TrimSpace (revParseCmd .OutBuf .String ())
117- return serviceBranchHeadCommit , nil
128+ return nil
118129}
119130
120131func revertExcludedChangesInServiceWorktreeIndex (ctx context.Context , sourceWorktreeDir string , serviceWorktreeDir string , sourceCommit string , serviceBranchHeadCommit string , globExcludeList []string ) (bool , error ) {
0 commit comments