-
Notifications
You must be signed in to change notification settings - Fork 81
gh add: better tracking of added/modified files #34
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
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
ce89169
Initial plan
Copilot 96f9788
Initial analysis and planning for file tracking in add --pr command
Copilot c4d8383
Implement comprehensive file tracking and rollback for add --pr command
Copilot 6ad646b
Move FileTracker to separate file and enhance rollback for modified f…
Copilot 994d831
Apply console formatting and remove backward compatibility layer
Copilot f2dfa83
Replace defer rollback with explicit rollback calls
Copilot 5e88ce7
Merge remote-tracking branch 'origin/main' into copilot/fix-33
pelikhan 64c92bf
Refactor job summary documentation and enhance dependency copying fun…
pelikhan 7b4981b
Remove integration tests for the CLI compile command
fd46889
Add integration tests for the CLI compile command
e59a312
Fix formatting in setupIntegrationTest by removing unnecessary blank …
e7aaea6
Merge branch 'main' into copilot/fix-33
dsyme 7eb29b8
Fix indentation in setupIntegrationTest for binary executable permission
pelikhan 2fb3ff5
Merge branch 'main' into copilot/fix-33
dsyme File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,175 @@ | ||
| package cli | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "os" | ||
| "os/exec" | ||
| "path/filepath" | ||
| "strings" | ||
| ) | ||
|
|
||
| // FileTracker keeps track of files created or modified during workflow operations | ||
| // to enable proper staging and rollback functionality | ||
| type FileTracker struct { | ||
| CreatedFiles []string | ||
| ModifiedFiles []string | ||
| OriginalContent map[string][]byte // Store original content for rollback | ||
| gitRoot string | ||
| } | ||
|
|
||
| // NewFileTracker creates a new file tracker | ||
| func NewFileTracker() (*FileTracker, error) { | ||
| gitRoot, err := findGitRoot() | ||
| if err != nil { | ||
| return nil, fmt.Errorf("file tracker requires being in a git repository: %w", err) | ||
| } | ||
| return &FileTracker{ | ||
| CreatedFiles: make([]string, 0), | ||
| ModifiedFiles: make([]string, 0), | ||
| OriginalContent: make(map[string][]byte), | ||
| gitRoot: gitRoot, | ||
| }, nil | ||
| } | ||
|
|
||
| // TrackCreated adds a file to the created files list | ||
| func (ft *FileTracker) TrackCreated(filePath string) { | ||
| absPath, err := filepath.Abs(filePath) | ||
| if err != nil { | ||
| absPath = filePath | ||
| } | ||
| ft.CreatedFiles = append(ft.CreatedFiles, absPath) | ||
| } | ||
|
|
||
| // TrackModified adds a file to the modified files list and stores its original content | ||
| func (ft *FileTracker) TrackModified(filePath string) { | ||
| absPath, err := filepath.Abs(filePath) | ||
| if err != nil { | ||
| absPath = filePath | ||
| } | ||
|
|
||
| // Store original content if not already stored | ||
| if _, exists := ft.OriginalContent[absPath]; !exists { | ||
| if content, err := os.ReadFile(absPath); err == nil { | ||
| ft.OriginalContent[absPath] = content | ||
| } | ||
| } | ||
|
|
||
| ft.ModifiedFiles = append(ft.ModifiedFiles, absPath) | ||
| } | ||
|
|
||
| // GetAllFiles returns all tracked files (created and modified) | ||
| func (ft *FileTracker) GetAllFiles() []string { | ||
| all := make([]string, 0, len(ft.CreatedFiles)+len(ft.ModifiedFiles)) | ||
| all = append(all, ft.CreatedFiles...) | ||
| all = append(all, ft.ModifiedFiles...) | ||
| return all | ||
| } | ||
|
|
||
| // StageAllFiles stages all tracked files using git add | ||
| func (ft *FileTracker) StageAllFiles(verbose bool) error { | ||
| allFiles := ft.GetAllFiles() | ||
| if len(allFiles) == 0 { | ||
| if verbose { | ||
| fmt.Println("No files to stage") | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| if verbose { | ||
| fmt.Printf("Staging %d files...\n", len(allFiles)) | ||
| for _, file := range allFiles { | ||
| fmt.Printf(" - %s\n", file) | ||
| } | ||
| } | ||
|
|
||
| // Stage all files in a single git add command | ||
| args := append([]string{"add"}, allFiles...) | ||
| cmd := exec.Command("git", args...) | ||
| cmd.Dir = ft.gitRoot | ||
| if err := cmd.Run(); err != nil { | ||
| return fmt.Errorf("failed to stage files: %w", err) | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| // RollbackCreatedFiles deletes all files that were created during the operation | ||
| func (ft *FileTracker) RollbackCreatedFiles(verbose bool) error { | ||
| if len(ft.CreatedFiles) == 0 { | ||
| return nil | ||
| } | ||
|
|
||
| if verbose { | ||
| fmt.Printf("Rolling back %d created files...\n", len(ft.CreatedFiles)) | ||
| } | ||
|
|
||
| var errors []string | ||
| for _, file := range ft.CreatedFiles { | ||
| if verbose { | ||
| fmt.Printf(" - Deleting %s\n", file) | ||
| } | ||
| if err := os.Remove(file); err != nil && !os.IsNotExist(err) { | ||
| errors = append(errors, fmt.Sprintf("failed to delete %s: %v", file, err)) | ||
| } | ||
| } | ||
|
|
||
| if len(errors) > 0 { | ||
| return fmt.Errorf("rollback errors: %s", strings.Join(errors, "; ")) | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| // RollbackModifiedFiles restores all modified files to their original state | ||
| func (ft *FileTracker) RollbackModifiedFiles(verbose bool) error { | ||
| if len(ft.ModifiedFiles) == 0 { | ||
| return nil | ||
| } | ||
|
|
||
| if verbose { | ||
| fmt.Printf("Rolling back %d modified files...\n", len(ft.ModifiedFiles)) | ||
| } | ||
|
|
||
| var errors []string | ||
| for _, file := range ft.ModifiedFiles { | ||
| if verbose { | ||
| fmt.Printf(" - Restoring %s\n", file) | ||
| } | ||
|
|
||
| // Restore original content if we have it | ||
| if originalContent, exists := ft.OriginalContent[file]; exists { | ||
| if err := os.WriteFile(file, originalContent, 0644); err != nil { | ||
| errors = append(errors, fmt.Sprintf("failed to restore %s: %v", file, err)) | ||
| } | ||
| } else { | ||
| if verbose { | ||
| fmt.Printf(" Warning: No original content stored for %s\n", file) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if len(errors) > 0 { | ||
| return fmt.Errorf("rollback errors: %s", strings.Join(errors, "; ")) | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| // RollbackAllFiles rolls back both created and modified files | ||
| func (ft *FileTracker) RollbackAllFiles(verbose bool) error { | ||
| var errors []string | ||
|
|
||
| if err := ft.RollbackCreatedFiles(verbose); err != nil { | ||
| errors = append(errors, fmt.Sprintf("created files rollback: %v", err)) | ||
| } | ||
|
|
||
| if err := ft.RollbackModifiedFiles(verbose); err != nil { | ||
| errors = append(errors, fmt.Sprintf("modified files rollback: %v", err)) | ||
| } | ||
|
|
||
| if len(errors) > 0 { | ||
| return fmt.Errorf("rollback errors: %s", strings.Join(errors, "; ")) | ||
| } | ||
|
|
||
| return nil | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.