11# GitHub-to-ADO Sync Pipeline
22# Syncs main branch from public GitHub to internal Azure DevOps daily at 5pm IST
3+ #
4+ # SYNC STRATEGY RATIONALE:
5+ # This pipeline uses a "replace-all" approach rather than traditional git merge/rebase because:
6+ # 1. DIVERGENT HISTORY: ADO repository contains commits from early development that don't exist
7+ # in GitHub. These historical commits were made before GitHub became the source of truth.
8+ # 2. AVOIDING CONFLICTS: Standard git operations (merge, rebase, reset --hard) fail when
9+ # repositories have divergent commit histories. Attempting to merge results in conflicts
10+ # that cannot be automatically resolved.
11+ # 3. IMPLEMENTATION: We use 'git fetch + git rm + git checkout' to completely replace ADO's
12+ # working tree with GitHub's files without attempting to reconcile git history. This creates
13+ # a clean sync commit that updates all files to match GitHub exactly.
14+ # 4. CHANGE DETECTION: The pipeline checks if any files actually differ before creating PRs,
15+ # avoiding unnecessary sync operations when repositories are already aligned.
316
417name : GitHub-Sync-$(Date:yyyyMMdd)$(Rev:.r)
518
@@ -21,25 +34,15 @@ jobs:
2134 vmImage : ' windows-latest'
2235
2336 steps :
24- - checkout : none
37+ - checkout : self
38+ persistCredentials : true
2539
2640 - task : CmdLine@2
27- displayName : ' Clone GitHub repo '
41+ displayName : ' Add GitHub remote '
2842 inputs :
29- script : git clone https://github.com/microsoft/mssql-python.git repo-dir -b main
30- workingDirectory : $(Agent.TempDirectory)
31-
32- - task : CmdLine@2
33- displayName : ' Add Azure DevOps remote'
34- inputs :
35- script : git remote add azdo-mirror https://$(System.AccessToken)@sqlclientdrivers.visualstudio.com/mssql-python/_git/mssql-python
36- workingDirectory : $(Agent.TempDirectory)/repo-dir
37-
38- - task : CmdLine@2
39- displayName : ' Fetch ADO repo'
40- inputs :
41- script : git fetch azdo-mirror
42- workingDirectory : $(Agent.TempDirectory)/repo-dir
43+ script : |
44+ git remote add github https://github.com/microsoft/mssql-python.git
45+ git fetch github main
4346
4447 - task : CmdLine@2
4548 displayName : ' Create timestamped sync branch'
@@ -51,26 +54,35 @@ jobs:
5154 set SYNC_BRANCH=github-sync-%TIMESTAMP%
5255 echo %SYNC_BRANCH% > branchname.txt
5356 echo Creating sync branch: %SYNC_BRANCH%
54- git fetch azdo-mirror
55- git show-ref --verify --quiet refs/remotes/azdo-mirror/main
56- if %ERRORLEVEL% EQU 0 (
57- git checkout -b %SYNC_BRANCH% -t azdo-mirror/main
58- ) else (
59- echo azdo-mirror/main does not exist. Exiting.
60- exit /b 1
61- )
57+ git checkout -b %SYNC_BRANCH%
6258 echo ##vso[task.setvariable variable=SYNC_BRANCH;isOutput=true]%SYNC_BRANCH%
63- workingDirectory : $(Agent.TempDirectory)/repo-dir
6459
6560 - task : CmdLine@2
66- displayName : ' Reset branch to match GitHub main exactly '
61+ displayName : ' Sync with GitHub main'
6762 inputs :
6863 script : |
69- git -c user.email="sync@microsoft.com" -c user.name="ADO Sync Bot" reset --hard origin/main
70- workingDirectory : $(Agent.TempDirectory)/repo-dir
64+ echo Syncing with GitHub main...
65+ git config user.email "sync@microsoft.com"
66+ git config user.name "ADO Sync Bot"
67+
68+ git fetch github main
69+ git rm -rf .
70+ git checkout github/main -- .
71+ echo timestamp.txt >> .git\info\exclude
72+ echo branchname.txt >> .git\info\exclude
73+ git diff --cached --quiet
74+ if %ERRORLEVEL% EQU 0 (
75+ echo No changes detected. Skipping commit.
76+ echo ##vso[task.setvariable variable=HAS_CHANGES]false
77+ ) else (
78+ echo Changes detected. Creating commit...
79+ git add . && git commit -m "Sync from GitHub main"
80+ echo ##vso[task.setvariable variable=HAS_CHANGES]true
81+ )
7182
7283 - task : CmdLine@2
7384 displayName : ' Push branch to Azure DevOps'
85+ condition : eq(variables['HAS_CHANGES'], 'true')
7486 inputs :
7587 script : |
7688 set /p SYNC_BRANCH=<branchname.txt
@@ -79,18 +91,18 @@ jobs:
7991 git config user.email "sync@microsoft.com"
8092 git config user.name "ADO Sync Bot"
8193
82- git push azdo-mirror %SYNC_BRANCH% --set-upstream
94+ git push origin %SYNC_BRANCH% --set-upstream
8395
8496 if %ERRORLEVEL% EQU 0 (
8597 echo Branch pushed successfully!
8698 ) else (
8799 echo ERROR: Push failed!
88100 exit /b 1
89101 )
90- workingDirectory : $(Agent.TempDirectory)/repo-dir
91102
92103 - task : CmdLine@2
93104 displayName : ' Create pull request'
105+ condition : eq(variables['HAS_CHANGES'], 'true')
94106 inputs :
95107 script : |
96108 echo Installing Azure DevOps extension...
@@ -124,4 +136,3 @@ jobs:
124136
125137 if exist timestamp.txt del timestamp.txt
126138 if exist branchname.txt del branchname.txt
127- workingDirectory : $(Agent.TempDirectory)/repo-dir
0 commit comments