@@ -610,6 +610,90 @@ describe("git patch integration tests", () => {
610610 }
611611 } ) ;
612612
613+ /**
614+ * Sets GITHUB_WORKSPACE, DEFAULT_BRANCH, GITHUB_TOKEN, and GITHUB_SERVER_URL for
615+ * a test, then restores the original values (or deletes them if they were unset).
616+ * Returns a restore function to call in `finally`.
617+ */
618+ function setTestEnv ( workspaceDir ) {
619+ const saved = {
620+ GITHUB_WORKSPACE : process . env . GITHUB_WORKSPACE ,
621+ DEFAULT_BRANCH : process . env . DEFAULT_BRANCH ,
622+ GITHUB_TOKEN : process . env . GITHUB_TOKEN ,
623+ GITHUB_SERVER_URL : process . env . GITHUB_SERVER_URL ,
624+ } ;
625+ process . env . GITHUB_WORKSPACE = workspaceDir ;
626+ process . env . DEFAULT_BRANCH = "main" ;
627+ process . env . GITHUB_TOKEN = "ghs_test_token_for_cleanup_verification" ;
628+ process . env . GITHUB_SERVER_URL = "https://github.example.com" ;
629+ return ( ) => {
630+ for ( const [ key , value ] of Object . entries ( saved ) ) {
631+ if ( value === undefined ) {
632+ delete process . env [ key ] ;
633+ } else {
634+ process . env [ key ] = value ;
635+ }
636+ }
637+ } ;
638+ }
639+
640+ it ( "should remove auth extraheader from git config after a successful fetch" , async ( ) => {
641+ // Set up a feature branch, push a first commit, then add a second commit so
642+ // incremental mode has something new to patch.
643+ execGit ( [ "checkout" , "-b" , "auth-cleanup-success" ] , { cwd : workingRepo } ) ;
644+ fs . writeFileSync ( path . join ( workingRepo , "auth.txt" ) , "auth test\n" ) ;
645+ execGit ( [ "add" , "auth.txt" ] , { cwd : workingRepo } ) ;
646+ execGit ( [ "commit" , "-m" , "Auth cleanup base commit" ] , { cwd : workingRepo } ) ;
647+ execGit ( [ "push" , "-u" , "origin" , "auth-cleanup-success" ] , { cwd : workingRepo } ) ;
648+
649+ // Add a second commit that will become the incremental patch
650+ fs . writeFileSync ( path . join ( workingRepo , "auth2.txt" ) , "auth test 2\n" ) ;
651+ execGit ( [ "add" , "auth2.txt" ] , { cwd : workingRepo } ) ;
652+ execGit ( [ "commit" , "-m" , "Auth cleanup new commit" ] , { cwd : workingRepo } ) ;
653+
654+ // Delete the tracking ref so generateGitPatch has to re-fetch
655+ execGit ( [ "update-ref" , "-d" , "refs/remotes/origin/auth-cleanup-success" ] , { cwd : workingRepo } ) ;
656+
657+ const restore = setTestEnv ( workingRepo ) ;
658+ try {
659+ const result = await generateGitPatch ( "auth-cleanup-success" , "main" , { mode : "incremental" } ) ;
660+
661+ expect ( result . success ) . toBe ( true ) ;
662+
663+ // Verify the extraheader was removed from git config
664+ const configCheck = spawnSync ( "git" , [ "config" , "--local" , "--get" , "http.https://github.example.com/.extraheader" ] , { cwd : workingRepo , encoding : "utf8" } ) ;
665+ // exit status 1 means the key does not exist — that is what we want
666+ expect ( configCheck . status ) . toBe ( 1 ) ;
667+ } finally {
668+ restore ( ) ;
669+ }
670+ } ) ;
671+
672+ it ( "should remove auth extraheader from git config even when fetch fails" , async ( ) => {
673+ // Create a local-only branch (fetch will fail because it's not on origin)
674+ execGit ( [ "checkout" , "-b" , "auth-cleanup-failure" ] , { cwd : workingRepo } ) ;
675+ fs . writeFileSync ( path . join ( workingRepo , "auth-fail.txt" ) , "auth fail test\n" ) ;
676+ execGit ( [ "add" , "auth-fail.txt" ] , { cwd : workingRepo } ) ;
677+ execGit ( [ "commit" , "-m" , "Auth cleanup failure test commit" ] , { cwd : workingRepo } ) ;
678+ // Do NOT push — so the fetch fails
679+
680+ const restore = setTestEnv ( workingRepo ) ;
681+ try {
682+ const result = await generateGitPatch ( "auth-cleanup-failure" , "main" , { mode : "incremental" } ) ;
683+
684+ // The fetch must fail since origin/auth-cleanup-failure doesn't exist
685+ expect ( result . success ) . toBe ( false ) ;
686+ expect ( result . error ) . toContain ( "Cannot generate incremental patch" ) ;
687+
688+ // Verify the extraheader was removed even though the fetch failed
689+ const configCheck = spawnSync ( "git" , [ "config" , "--local" , "--get" , "http.https://github.example.com/.extraheader" ] , { cwd : workingRepo , encoding : "utf8" } ) ;
690+ // exit status 1 means the key does not exist — that is what we want
691+ expect ( configCheck . status ) . toBe ( 1 ) ;
692+ } finally {
693+ restore ( ) ;
694+ }
695+ } ) ;
696+
613697 it ( "should include all commits in full mode even when origin/branch exists" , async ( ) => {
614698 // Create a feature branch with first commit
615699 execGit ( [ "checkout" , "-b" , "full-mode-branch" ] , { cwd : workingRepo } ) ;
0 commit comments