plugins: only flag updates when remote head is not contained in local history (#3778)

* plugins: only flag updates when remote head is not contained in local history

* meta: remove inline comments
This commit is contained in:
Bernardo Gomes
2026-10-13 20:52:04 -04:00
committed by GitHub
parent 35041d03e1
commit 66ffc133ca
2 changed files with 56 additions and 4 deletions
+22 -4
View File
@@ -62,7 +62,7 @@ func (g *realGitClient) Pull(path string) error {
}
err = worktree.Pull(&git.PullOptions{})
if err != nil && err.Error() != "already up-to-date" {
if err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) {
return err
}
@@ -116,12 +116,30 @@ func (g *realGitClient) HasUpdates(path string) (bool, string, string, error) {
}
}
localHash := head.Hash().String()
localHash := head.Hash()
if remoteHead == "" {
return false, localHash, "", nil
return false, localHash.String(), "", nil
}
if localHash.String() == remoteHead {
return false, localHash.String(), remoteHead, nil
}
return localHash != remoteHead, localHash, remoteHead, nil
remoteCommit, err := repo.CommitObject(plumbing.NewHash(remoteHead))
if errors.Is(err, plumbing.ErrObjectNotFound) {
return true, localHash.String(), remoteHead, nil
}
if err != nil {
return false, "", "", err
}
headCommit, err := repo.CommitObject(localHash)
if err != nil {
return false, "", "", err
}
contained, err := remoteCommit.IsAncestor(headCommit)
if err != nil {
return false, "", "", err
}
return !contained, localHash.String(), remoteHead, nil
}
func (g *realGitClient) CurrentRevision(path string) (string, error) {
+34
View File
@@ -652,3 +652,37 @@ func TestRealGitClientChecksUpdatesWithoutFetching(t *testing.T) {
_, _, _, err = client.HasUpdates(localPath)
assert.Error(t, err)
}
func TestRealGitClientHasUpdatesIgnoresLocalAheadAfterRemoteRewind(t *testing.T) {
t.Setenv("GIT_CONFIG_GLOBAL", "")
t.Setenv("GIT_CONFIG_SYSTEM", "")
remotePath := t.TempDir()
remote, err := git.PlainInit(remotePath, false)
require.NoError(t, err)
worktree, err := remote.Worktree()
require.NoError(t, err)
signature := &object.Signature{Name: "DMS Test", Email: "[email protected]", When: time.Unix(1, 0)}
commit := func(content string) plumbing.Hash {
t.Helper()
require.NoError(t, os.WriteFile(filepath.Join(remotePath, "value.txt"), []byte(content), 0o644))
_, err := worktree.Add("value.txt")
require.NoError(t, err)
hash, err := worktree.Commit(content, &git.CommitOptions{Author: signature})
require.NoError(t, err)
return hash
}
first := commit("one")
second := commit("two")
localPath := t.TempDir()
_, err = git.PlainClone(localPath, &git.CloneOptions{URL: remotePath})
require.NoError(t, err)
require.NoError(t, remote.Storer.SetReference(plumbing.NewHashReference(plumbing.NewBranchReferenceName("master"), first)))
client := &realGitClient{}
updated, localHash, remoteHash, err := client.HasUpdates(localPath)
require.NoError(t, err)
assert.False(t, updated)
assert.Equal(t, second.String(), localHash)
assert.Equal(t, first.String(), remoteHash)
}