aboutsummaryrefslogtreecommitdiffstats
path: root/repository.go
diff options
context:
space:
mode:
authorPaulo Gomes <paulo.gomes@suse.com>2024-03-09 09:00:21 +0000
committerPaulo Gomes <paulo.gomes@suse.com>2024-03-09 09:00:21 +0000
commit3ee5bc9dd308a5503d60cc26d17d7f10df28c37a (patch)
treecdc736274162b804e12d4bd55617b5811d470248 /repository.go
parent4bed23037f0e374d85bce1506e9df98ce0cfcd32 (diff)
downloadgo-git-3ee5bc9dd308a5503d60cc26d17d7f10df28c37a.tar.gz
git: Implement Merge function with initial FastForwardMerge support
Introduces the Merge function for merging branches in the codebase. Currently, the function only supports FastForwardMerge strategy, meaning it can efficiently update the target branch pointer if the source branch history is a linear descendant. Support for additional merge strategies (e.g., three-way merge) will be added in future commits. Signed-off-by: Paulo Gomes <paulo.gomes@suse.com>
Diffstat (limited to 'repository.go')
-rw-r--r--repository.go54
1 files changed, 36 insertions, 18 deletions
diff --git a/repository.go b/repository.go
index 6ab40c0..d5e4f2f 100644
--- a/repository.go
+++ b/repository.go
@@ -51,19 +51,21 @@ var (
// ErrFetching is returned when the packfile could not be downloaded
ErrFetching = errors.New("unable to fetch packfile")
- ErrInvalidReference = errors.New("invalid reference, should be a tag or a branch")
- ErrRepositoryNotExists = errors.New("repository does not exist")
- ErrRepositoryIncomplete = errors.New("repository's commondir path does not exist")
- ErrRepositoryAlreadyExists = errors.New("repository already exists")
- ErrRemoteNotFound = errors.New("remote not found")
- ErrRemoteExists = errors.New("remote already exists")
- ErrAnonymousRemoteName = errors.New("anonymous remote name must be 'anonymous'")
- ErrWorktreeNotProvided = errors.New("worktree should be provided")
- ErrIsBareRepository = errors.New("worktree not available in a bare repository")
- ErrUnableToResolveCommit = errors.New("unable to resolve commit")
- ErrPackedObjectsNotSupported = errors.New("packed objects not supported")
- ErrSHA256NotSupported = errors.New("go-git was not compiled with SHA256 support")
- ErrAlternatePathNotSupported = errors.New("alternate path must use the file scheme")
+ ErrInvalidReference = errors.New("invalid reference, should be a tag or a branch")
+ ErrRepositoryNotExists = errors.New("repository does not exist")
+ ErrRepositoryIncomplete = errors.New("repository's commondir path does not exist")
+ ErrRepositoryAlreadyExists = errors.New("repository already exists")
+ ErrRemoteNotFound = errors.New("remote not found")
+ ErrRemoteExists = errors.New("remote already exists")
+ ErrAnonymousRemoteName = errors.New("anonymous remote name must be 'anonymous'")
+ ErrWorktreeNotProvided = errors.New("worktree should be provided")
+ ErrIsBareRepository = errors.New("worktree not available in a bare repository")
+ ErrUnableToResolveCommit = errors.New("unable to resolve commit")
+ ErrPackedObjectsNotSupported = errors.New("packed objects not supported")
+ ErrSHA256NotSupported = errors.New("go-git was not compiled with SHA256 support")
+ ErrAlternatePathNotSupported = errors.New("alternate path must use the file scheme")
+ ErrUnsupportedMergeStrategy = errors.New("unsupported merge strategy")
+ ErrFastForwardMergeNotPossible = errors.New("not possible to fast-forward merge changes")
)
// Repository represents a git repository
@@ -1769,10 +1771,22 @@ func (r *Repository) RepackObjects(cfg *RepackConfig) (err error) {
return nil
}
-// Merge attempts to merge ref onto HEAD. Currently only supports fast-forward merges
+// Merge merges the reference branch into the current branch.
+//
+// If the merge is not possible (or supported) returns an error without changing
+// the HEAD for the current branch. Possible errors include:
+// - The merge strategy is not supported.
+// - The specific strategy cannot be used (e.g. using FastForwardMerge when one is not possible).
func (r *Repository) Merge(ref plumbing.Reference, opts MergeOptions) error {
- if !opts.FFOnly {
- return errors.New("non fast-forward merges are not supported yet")
+ if opts.Strategy != FastForwardMerge {
+ return ErrUnsupportedMergeStrategy
+ }
+
+ // Ignore error as not having a shallow list is optional here.
+ shallowList, _ := r.Storer.Shallow()
+ var earliestShallow *plumbing.Hash
+ if len(shallowList) > 0 {
+ earliestShallow = &shallowList[0]
}
head, err := r.Head()
@@ -1780,9 +1794,13 @@ func (r *Repository) Merge(ref plumbing.Reference, opts MergeOptions) error {
return err
}
- ff, err := IsFastForward(r.Storer, head.Hash(), ref.Hash())
+ ff, err := isFastForward(r.Storer, head.Hash(), ref.Hash(), earliestShallow)
+ if err != nil {
+ return err
+ }
+
if !ff {
- return errors.New("fast forward is not possible")
+ return ErrFastForwardMergeNotPossible
}
return r.Storer.SetReference(plumbing.NewHashReference(head.Name(), ref.Hash()))