- Learn
- AI Code Editors
- GitHub Copilot
- Copilot Edits
Use GitHub Copilot Edits for multi-file modifications, refactoring, and coordinated changes across your codebase.
Copilot Edits
Copilot Edits extends beyond single-file suggestions to make coordinated changes across multiple files. This feature brings agentic capabilities to GitHub Copilot.
What is Copilot Edits?
Unlike inline completions or chat, Copilot Edits can:
- Modify multiple files simultaneously
- Create new files
- Make coordinated changes
- Apply refactoring patterns
- Generate related code across files
Traditional Completions:
One file → One suggestion
Copilot Edits:
Your request → Multiple file changes
├── Create new files
├── Modify existing files
└── Coordinated updates
Accessing Copilot Edits
Via Chat
Use /edit in Copilot Chat:
/edit Add error handling to all API routes
Via Command Palette
Cmd/Ctrl+Shift+P → "GitHub Copilot: Edit"
Via Context Menu
Right-click selected code → "Copilot: Edit..."
Edit Session Workflow
Starting an Edit Session
1. Open Copilot Edits panel
2. Describe your change
3. Optionally reference files
4. Submit request
Reviewing Changes
Copilot shows proposed changes:
┌────────────────────────────────────────────────────────────┐
│ Copilot Edits │
├────────────────────────────────────────────────────────────┤
│ │
│ Your request: "Add logging to all service methods" │
│ │
│ Proposed changes: │
│ │
│ ✓ src/services/user.service.ts [View diff] │
│ + Added console.log at method entry/exit │
│ │
│ ✓ src/services/order.service.ts [View diff] │
│ + Added console.log at method entry/exit │
│ │
│ ✓ src/services/payment.service.ts [View diff] │
│ + Added console.log at method entry/exit │
│ │
│ [Accept All] [Reject] [Modify] │
└────────────────────────────────────────────────────────────┘
Accepting or Rejecting
For each file, you can:
- Accept: Apply the change
- Reject: Discard the change
- Modify: Edit before applying
- Accept All: Apply all changes
Common Edit Operations
Adding Features
Add user authentication to all protected routes.
Use the authMiddleware from lib/auth.
Result:
// routes/users.ts - Before
export async function GET(request: Request) {
const users = await getUsers()
return Response.json(users)
}
// routes/users.ts - After
import { authMiddleware } from '@/lib/auth'
export const GET = authMiddleware(async (request: Request) => {
const users = await getUsers()
return Response.json(users)
})
Refactoring Patterns
Refactor all useState + useEffect patterns to use useSWR for data fetching
Before:
const [users, setUsers] = useState([])
const [loading, setLoading] = useState(true)
useEffect(() => {
fetch('/api/users')
.then(res => res.json())
.then(setUsers)
.finally(() => setLoading(false))
}, [])
After:
const { data: users, isLoading: loading } = useSWR('/api/users', fetcher)
Adding Types
Add TypeScript types to all functions in lib/utils.ts
Standardizing Patterns
Update all form submissions to use react-hook-form instead of controlled inputs
Adding Tests
Create unit tests for all functions in src/lib/calculations.ts
Creates:
src/
├── lib/
│ └── calculations.ts (existing)
└── tests/
└── lib/
└── calculations.test.ts (new)
Working with Multiple Files
Specifying Scope
Reference specific files:
Add error handling to #file:src/services/user.ts
and #file:src/services/order.ts
Pattern Matching
Describe patterns to target:
Add JSDoc comments to all exported functions in the services folder
Creating Related Files
Create a new ProductCard component with:
- Component file
- Styles file
- Test file
- Storybook story
Creates:
components/
└── ProductCard/
├── ProductCard.tsx
├── ProductCard.module.css
├── ProductCard.test.tsx
└── ProductCard.stories.tsx
Edit Strategies
Incremental Edits
Build up changes step by step:
Step 1: "Add the base logger utility"
Review → Accept
Step 2: "Use the logger in user service"
Review → Accept
Step 3: "Use the logger in remaining services"
Review → Accept
Scoped Edits
Limit scope for precision:
❌ "Add validation everywhere"
✅ "Add Zod validation to the checkout API route"
Preview First
Use /explain before /edit:
/explain What files would be affected by changing the User type?
[Review list]
/edit Update User type to include lastLoginAt field
Reviewing Changes
Diff View
Each file shows a diff:
// src/services/user.ts
+ import { logger } from '@/lib/logger'
export async function createUser(data: CreateUserInput) {
+ logger.info('Creating user', { email: data.email })
const user = await prisma.user.create({ data })
+ logger.info('User created', { id: user.id })
return user
}
Understanding Changes
Before accepting, verify:
- Correctness: Does the code do what you want?
- Consistency: Does it match project patterns?
- Completeness: Are all necessary changes included?
- Side effects: Any unexpected modifications?
Partial Acceptance
Accept some files, reject others:
✓ Accept: user.service.ts - Looks good
✓ Accept: order.service.ts - Looks good
✗ Reject: payment.service.ts - Needs different approach
Then make a follow-up request for the rejected file.
Advanced Edit Patterns
Conditional Logic
Add rate limiting to all POST endpoints, but not GET endpoints
Cross-Cutting Concerns
Add audit logging that tracks:
- Who made the change (userId)
- What changed (before/after values)
- When it changed (timestamp)
Apply to all database write operations.
Architecture Changes
Convert all API routes from REST to tRPC.
Keep the same functionality but use the tRPC patterns
shown in #file:src/trpc/routers/example.ts
Migration Patterns
Migrate from Moment.js to date-fns.
Update all date formatting and manipulation.
Best Practices
Clear Instructions
❌ "Make it better"
✅ "Add error handling with try/catch blocks and proper error types"
❌ "Update the code"
✅ "Update useState to useReducer for complex state management"
Reference Examples
Use the same pattern as #file:src/services/user.service.ts
for the new product service
Verify Before Accepting
Always review diffs:
1. Check each file's changes
2. Look for unintended modifications
3. Verify imports are correct
4. Ensure tests still pass
Small Batches
❌ "Refactor the entire codebase"
✅ "Refactor the user module to use the repository pattern"
Then: "Refactor the order module"
Then: "Refactor the product module"
Limitations
Current Constraints
- File count: May struggle with very large change sets
- Complexity: Very complex refactors may need multiple passes
- Context: Large files may exceed context limits
- External deps: Can't install packages (use terminal)
When to Use Alternatives
| Scenario | Use |
|---|---|
| Simple completion | Inline Copilot |
| Single file changes | Inline Chat |
| Questions | Chat |
| Understanding code | @workspace |
| Complex refactors | Copilot Edits |
| Very complex changes | Multiple edit sessions |
Troubleshooting
Changes Not Applying
1. Check if file is read-only
2. Verify file path is correct
3. Try smaller change set
4. Reload VS Code
Unexpected Changes
1. Reject the changes
2. Be more specific in request
3. Reference example files
4. Break into smaller edits
Incomplete Edits
If edits seem incomplete:
1. Make follow-up request
2. Specify missing files
3. Provide more context
Summary
- Copilot Edits: Multi-file modifications
- Access:
/editcommand, command palette, context menu - Workflow: Request → Review diffs → Accept/Reject
- Scope: Reference files with
#file: - Best practices: Clear instructions, small batches, review carefully
- Incremental: Build up changes step by step
What's Next
You've completed the GitHub Copilot module. You can now:
- Use completions for fast coding
- Ask questions with Chat
- Understand projects with @workspace
- Make multi-file changes with Edits
Consider exploring Windsurf for another AI editor experience, or Claude Code for terminal-based agentic development.