-
Notifications
You must be signed in to change notification settings - Fork 5.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: fetch syncedRevision in UpdateRevisionForPaths (#21014) #21015
Changes from all commits
948464c
4d4dc17
706625e
6c50dfa
41d8400
35963d3
79e6e26
a7aa687
05e2df0
4bfdc13
f7b1388
70e550d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2507,6 +2507,50 @@ func (s *Service) checkoutRevision(gitClient git.Client, revision string, submod | |
return closer, err | ||
} | ||
|
||
// fetch is a convenience function to fetch revisions | ||
// We assumed that the caller has already initialized the git repo, i.e. gitClient.Init() has been called | ||
func (s *Service) fetch(gitClient git.Client, targetRevisions []string) error { | ||
err := fetch(gitClient, targetRevisions) | ||
if err != nil { | ||
for _, revision := range targetRevisions { | ||
s.metricsServer.IncGitFetchFail(gitClient.Root(), revision) | ||
} | ||
} | ||
return err | ||
} | ||
|
||
func fetch(gitClient git.Client, targetRevisions []string) error { | ||
revisionPresent := true | ||
for _, revision := range targetRevisions { | ||
revisionPresent = gitClient.IsRevisionPresent(revision) | ||
if !revisionPresent { | ||
break | ||
} | ||
} | ||
// Fetching can be skipped if the revision is already present locally. | ||
if revisionPresent { | ||
return nil | ||
} | ||
// Fetching with no revision first. Fetching with an explicit version can cause repo bloat. https://github.com/argoproj/argo-cd/issues/8845 | ||
err := gitClient.Fetch("") | ||
if err != nil { | ||
return err | ||
} | ||
for _, revision := range targetRevisions { | ||
if !gitClient.IsRevisionPresent(revision) { | ||
// When fetching with no revision, only refs/heads/* and refs/remotes/origin/* are fetched. If fetch fails | ||
// for the given revision, try explicitly fetching it. | ||
log.Infof("Failed to fetch revision %s: %v", revision, err) | ||
log.Infof("Fallback to fetching specific revision %s. ref might not have been in the default refspec fetched.", revision) | ||
|
||
if err := gitClient.Fetch(revision); err != nil { | ||
return status.Errorf(codes.Internal, "Failed to fetch revision %s: %v", revision, err) | ||
} | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func checkoutRevision(gitClient git.Client, revision string, submoduleEnabled bool) error { | ||
err := gitClient.Init() | ||
if err != nil { | ||
|
@@ -2847,6 +2891,10 @@ func (s *Service) UpdateRevisionForPaths(_ context.Context, request *apiclient.U | |
} | ||
defer io.Close(closer) | ||
|
||
if err := s.fetch(gitClient, []string{syncedRevision}); err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We lock on revision above, but use syncedRevision here. Should it be consistent? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To exec There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. Maybe we can release the lock earlier then. |
||
return nil, status.Errorf(codes.Internal, "unable to fetch git repo %s with syncedRevisions %s: %v", repo.Repo, syncedRevision, err) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How would locking above work with both revisions being used here? Can we lock for multiple revisions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we take a lock to fetch from the remote? If we checkout we need to take a lock, but for fetch I think we don't need to lock. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know |
||
|
||
files, err := gitClient.ChangedFiles(syncedRevision, revision) | ||
if err != nil { | ||
return nil, status.Errorf(codes.Internal, "unable to get changed files for repo %s with revision %s: %v", repo.Repo, revision, err) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a specific reason behind using the same func name as
fetch
? If not, we can probably change the func name to avoid confusion.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not being particular, but it is the same naming convention as
checkoutRevision
.https://github.com/toyamagu-2021/argo-cd/blob/514df2c77c58c8bc5f4da1000e09af0e8e4fb552/reposerver/repository/repository.go#L2554