Skip to main content

Adopting Git for Existing Projects

Guide for teams with existing NetSuite customizations who want to start using Git version control.


Which Scenario Are You?

ScenarioDescriptionGo To
A: Fresh StartNo Git repository exists. Production is the only source of code.Scenario A
B: Partial RepositoryGit repository exists but is missing some scripts/objects from Production.Scenario B

Scenario A: Fresh Start

Situation: Your team has been deploying directly to NetSuite. No Git repository exists. Production has all the code.

Step 1: Set Up Tools (All 6 Developers)

Each developer installs:

  1. Open VSCode
  2. Go to Extensions (Ctrl+Shift+X)
  3. Search for "SuiteCloud"
  4. Install Oracle SuiteCloud Extension for VS Code
┌─────────────────────────────────────────────────────────────────┐
│ VSCODE SUITECLOUD EXTENSION │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Features: │
│ • Visual project creation and management │
│ • IntelliSense for SuiteScript APIs │
│ • Integrated import/deploy commands │
│ • Account management UI │
│ • Built-in CLI (no separate installation needed) │
│ │
│ Access Commands: │
│ Press Ctrl+Shift+P → Type "SuiteCloud" │
│ │
└─────────────────────────────────────────────────────────────────┘

Option B: CLI Only

# Check if already installed
node --version # Need v18+
git --version # Need 2.x

# Install SuiteCloud CLI
npm install -g @oracle/suitecloud-cli
Recommendation

Use VSCode Extension for day-to-day development (visual interface, IntelliSense). Use CLI for automation, scripts, and CI/CD pipelines.

Step 2: Create GitHub Repository

IT Lead does this once:

  1. Go to github.com → New Repository
  2. Name: netsuite-customizations
  3. Private repository
  4. Do NOT initialize with README

Step 3: Import Everything from Production

IT Lead does this once:

# Create project folder
mkdir netsuite-customizations
cd netsuite-customizations

# Initialize SDF project
suitecloud project:create -i
# Select: Account Customization Project (ACP)

# Connect to Production
suitecloud account:setup
# Select Production account

# Import ALL script definitions (XML records → Objects folder)
suitecloud object:import --scriptid "customscript_*" --destinationfolder "Objects"

# Import ALL custom record definitions (XML records → Objects folder)
suitecloud object:import --scriptid "customrecord_*" --destinationfolder "Objects"

# Import ALL script files (.js files → FileCabinet/SuiteScripts folder)
suitecloud file:import --paths "/SuiteScripts/*" --excludeproperties

# If scripts are in subfolders, also run:
suitecloud file:import --paths "/SuiteScripts/**/*" --excludeproperties

Step 4: Validate Import

# Make sure everything imported correctly
suitecloud project:validate

Check your folder structure:

netsuite-customizations/
├── src/
│ ├── FileCabinet/
│ │ └── SuiteScripts/
│ │ └── (all your .js files)
│ └── Objects/
│ └── (all your .xml files)
├── manifest.xml
└── project.json

Step 5: Initialize Git

# Create .gitignore file first

Create .gitignore:

node_modules/
.suitecloud-sdk/
suitecloud.config.json
.suitecloud/
.DS_Store
Thumbs.db
.vscode/
*.log
# Initialize and commit
git init
git add .
git commit -m "Initial commit: Import all Production customizations [$(date +%Y-%m-%d)]"

# Push to GitHub
git remote add origin https://github.com/YOUR-ORG/netsuite-customizations.git
git push -u origin main

# Create develop branch
git checkout -b develop
git push -u origin develop

Step 6: Team Clones Repository

Each of the 6 developers:

# Clone
git clone https://github.com/YOUR-ORG/netsuite-customizations.git
cd netsuite-customizations

# Set up identity
git config user.name "Your Name"
git config user.email "your.email@company.com"

# Connect to Sandbox
suitecloud account:setup
# Select Sandbox account for development

Done! Skip to Go Live Checklist


Scenario B: Partial Repository

Situation: Git repository exists but Production has scripts/objects that are NOT in Git. Need to sync.

Step 1: Identify What's Missing

Compare Production vs Git:

# Clone existing repo (if not already)
git clone https://github.com/YOUR-ORG/netsuite-customizations.git
cd netsuite-customizations

# List what's currently in Git
ls src/Objects/
ls src/FileCabinet/SuiteScripts/

In NetSuite Production:

Customization → Scripting → Scripts → Export list to CSV

Create a comparison:

Script IDIn Production?In Git?Action
customscript_invoice_ueNone
customscript_customer_csImport
customscript_old_unusedIgnore (deprecated)

Step 2: Create Sync Branch

# Start from develop
git checkout develop
git pull origin develop

# Create sync branch
git checkout -b sync/import-missing-from-production

Step 3: Import Missing Objects

# Connect to Production
suitecloud account:setup
# Select Production

# Import specific missing script definitions (XML → Objects folder)
suitecloud object:import --scriptid "customscript_customer_cs" --destinationfolder "Objects"
suitecloud object:import --scriptid "customscript_report_mr" --destinationfolder "Objects"

# Import the actual script files (.js → FileCabinet/SuiteScripts folder)
suitecloud file:import --paths "/SuiteScripts/customer_cs.js" --excludeproperties
suitecloud file:import --paths "/SuiteScripts/report_mr.js" --excludeproperties

Or import ALL and let Git show what's new:

# Import everything - Git will show only new/changed files
suitecloud object:import --scriptid "customscript_*" --destinationfolder "Objects" # XML definitions
suitecloud file:import --paths "/SuiteScripts/*" --excludeproperties # .js files

Step 4: Review and Commit

# See what's new/changed
git status

# Review changes carefully
git diff

# Stage and commit
git add .
git commit -m "Sync: Import missing scripts from Production

Added scripts that were in Production but not in Git:
- customscript_customer_cs
- customscript_report_mr
- [list others]

These scripts were deployed before Git adoption."

Step 5: Create Pull Request

# Push sync branch
git push origin sync/import-missing-from-production

On GitHub:

  1. Create Pull Request: sync/import-missing-from-productiondevelop
  2. Have team review the imported code
  3. Merge after approval

Step 6: Update Main Branch

# After merging to develop, sync to main
git checkout main
git pull origin main
git merge develop
git push origin main

Now Git matches Production!


Go Live Checklist

For a team of 6 developers:

Before Go Live

TaskOwnerStatus
All 6 developers have Git installedEach dev
All 6 developers cloned the repositoryEach dev
All 6 developers connected to SandboxEach dev
Git repository matches ProductionIT Lead
Team completed Practice GuideEach dev

Announce to Team

Git Workflow Goes Live: [DATE]

Starting [DATE], all NetSuite changes must go through Git:

  1. Create branch from develop
  2. Make changes locally
  3. Test using Upload File to Sandbox
  4. Push and create Pull Request
  5. After review, merge to develop

No more direct editing in NetSuite UI!

Questions? Ask [IT Lead Name]


Daily Workflow After Migration

EVERY DAY - Before starting work:
git checkout develop
git pull origin develop

STARTING NEW TASK:
git checkout -b feature/NS-XXX-description

SAVING WORK:
git add .
git commit -m "[NS-XXX] What you did"
git push origin feature/NS-XXX-description

TESTING:
Right-click file → Upload File to Account → Sandbox

FINISHING:
Create Pull Request on GitHub
After approval → Merge to develop

Handling Special Cases

Case 1: Someone Made Direct Production Changes

If someone edited Production directly (emergency fix):

git checkout develop
git checkout -b sync/emergency-fix-[date]

# Import the changed script definition (XML) and file (.js)
suitecloud object:import --scriptid "customscript_that_changed" --destinationfolder "Objects"
suitecloud file:import --paths "/SuiteScripts/that_changed.js" --excludeproperties

git add .
git commit -m "Sync: Emergency Production fix by [Name] on [Date]

Fix: [Description of what was fixed]
Reason: [Why it was done directly in Production]"

git push origin sync/emergency-fix-[date]
# Create PR to merge to develop, then main

Case 2: Script Exists in Production but Not Needed in Git

Some scripts might be:

  • Deprecated/unused
  • One-time migration scripts
  • Test scripts that shouldn't be version controlled

Decision: Document in a file what's intentionally excluded:

Create docs/EXCLUDED_SCRIPTS.md:

# Scripts Intentionally Not in Git

| Script ID | Reason | Date Excluded |
|-----------|--------|---------------|
| customscript_old_migration | One-time use, completed | 2024-01-15 |
| customscript_test_sandbox | Sandbox testing only | 2024-01-15 |

Case 3: Two Developers Working on Same File

Prevention:

  • Keep branches short (1-3 days max)
  • Communicate: "I'm working on invoice_ue.js today"
  • Pull develop frequently

If conflict happens:


Quick Commands Reference

┌─────────────────────────────────────────────────────────────┐
│ GIT COMMANDS FOR DAILY WORK │
├─────────────────────────────────────────────────────────────┤
│ │
│ START OF DAY │
│ git checkout develop │
│ git pull origin develop │
│ │
│ NEW TASK │
│ git checkout -b feature/NS-XXX-description │
│ │
│ SAVE WORK │
│ git add . │
│ git commit -m "[NS-XXX] Description" │
│ git push origin feature/NS-XXX-description │
│ │
│ SEE STATUS │
│ git status │
│ │
│ UNDO LAST COMMIT (before push) │
│ git reset --soft HEAD~1 │
│ │
│ DISCARD ALL LOCAL CHANGES │
│ git checkout . │
│ │
├─────────────────────────────────────────────────────────────┤
│ SDF COMMANDS │
├─────────────────────────────────────────────────────────────┤
│ │
│ VALIDATE PROJECT │
│ Ctrl+Shift+P → SuiteCloud: Validate Project │
│ │
│ UPLOAD SINGLE FILE (quick test) │
│ Right-click file → Upload File to Account │
│ │
│ DEPLOY PROJECT │
│ Ctrl+Shift+P → SuiteCloud: Deploy Project │
│ │
│ IMPORT FROM NETSUITE │
│ suitecloud object:import --scriptid "ID" --destinationfolder "Objects" │
│ suitecloud file:import --paths "/path" --excludeproperties│
│ │
└─────────────────────────────────────────────────────────────┘

Timeline for 6-Person Team

DayActivityWho
Day 1Scenario A or B setupIT Lead
Day 2All 6 developers clone & set upEveryone
Day 3Team practices with Practice GuideEveryone
Day 4First real task using Git1-2 developers
Day 5All developers using GitEveryone
Week 2Stabilization, answer questionsIT Lead supports