fix(status): detect and report uncommitted changes in repository status, fixes #5

This commit is contained in:
Yar Kravtsov
2025-05-25 07:35:16 +03:00
parent d02f112200
commit 84c507828d
5 changed files with 157 additions and 29 deletions

View File

@@ -350,6 +350,7 @@ type StatusInfo struct {
Ahead int
Behind int
Remote string
Dirty bool
}
// Status returns the repository sync status
@@ -368,6 +369,7 @@ func (l *Lnk) Status() (*StatusInfo, error) {
Ahead: gitStatus.Ahead,
Behind: gitStatus.Behind,
Remote: gitStatus.Remote,
Dirty: gitStatus.Dirty,
}, nil
}

View File

@@ -480,6 +480,42 @@ func (suite *CoreTestSuite) TestSameBasenameSequentialAdd() {
suite.Require().NoError(err, "Second .bashrc should be removable")
}
// Test dirty repository status detection
func (suite *CoreTestSuite) TestStatusDetectsDirtyRepo() {
err := suite.lnk.Init()
suite.Require().NoError(err)
// Add and commit a file
testFile := filepath.Join(suite.tempDir, "a")
err = os.WriteFile(testFile, []byte("abc"), 0644)
suite.Require().NoError(err)
err = suite.lnk.Add(testFile)
suite.Require().NoError(err)
// Add a remote so status works
err = suite.lnk.AddRemote("origin", "https://github.com/test/dotfiles.git")
suite.Require().NoError(err)
// Check status - should be clean but ahead of remote
status, err := suite.lnk.Status()
suite.Require().NoError(err)
suite.Equal(1, status.Ahead)
suite.Equal(0, status.Behind)
suite.False(status.Dirty, "Repository should not be dirty after commit")
// Now edit the managed file (simulating the issue scenario)
err = os.WriteFile(testFile, []byte("def"), 0644)
suite.Require().NoError(err)
// Check status again - should detect dirty state
status, err = suite.lnk.Status()
suite.Require().NoError(err)
suite.Equal(1, status.Ahead)
suite.Equal(0, status.Behind)
suite.True(status.Dirty, "Repository should be dirty after editing managed file")
}
func TestCoreSuite(t *testing.T) {
suite.Run(t, new(CoreTestSuite))
}

View File

@@ -305,6 +305,7 @@ type StatusInfo struct {
Ahead int
Behind int
Remote string
Dirty bool
}
// GetStatus returns the repository status relative to remote
@@ -315,6 +316,12 @@ func (g *Git) GetStatus() (*StatusInfo, error) {
return nil, err
}
// Check for uncommitted changes
dirty, err := g.HasChanges()
if err != nil {
return nil, fmt.Errorf("failed to check for uncommitted changes: %w", err)
}
// Get the remote tracking branch
cmd := exec.Command("git", "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}")
cmd.Dir = g.repoPath
@@ -327,6 +334,7 @@ func (g *Git) GetStatus() (*StatusInfo, error) {
Ahead: g.getAheadCount(remoteBranch),
Behind: 0, // Can't be behind if no upstream
Remote: remoteBranch,
Dirty: dirty,
}, nil
}
@@ -336,6 +344,7 @@ func (g *Git) GetStatus() (*StatusInfo, error) {
Ahead: g.getAheadCount(remoteBranch),
Behind: g.getBehindCount(remoteBranch),
Remote: remoteBranch,
Dirty: dirty,
}, nil
}