Version 0.08 of Skybuck's Gitflow is now available, all source code below: Save program 1 as "git-back-to.dpr": program git_back_to; { Skybuck's GitFlow version 0.08 created on 29 august 2025 by Skybuck Flying and Gemini (AI) and Co-Pilot (AI). credits: Almost all code by Google Gemini 2.5 Pro. GetBranchVersionDigits code by Microsoft Co-Pilot. Software Idea and Prompting and Overwatching the AI: Skybuck Flying. improvements for version 0.08: + local git support + better contribution number Delphi code developed for Delphi 12.3 and Windows 11. } {$APPTYPE CONSOLE} uses System.SysUtils, System.Classes, System.RegularExpressions, System.IOUtils, Winapi.Windows, ActiveX, MSXML; function ExecuteCommand(const Command: string; out Output: TStringList): Integer; var SA: TSecurityAttributes; SI: TStartupInfo; PI: TProcessInformation; hRead, hWrite: THandle; Buffer: array[0..1023] of AnsiChar; BytesRead: DWord; Cmd: string; FullOutput: AnsiString; begin Output := TStringList.Create; Result := -1; FullOutput := ''; SA.nLength := SizeOf(TSecurityAttributes); SA.bInheritHandle := True; SA.lpSecurityDescriptor := nil; if not CreatePipe(hRead, hWrite, @SA, 0) then begin Exit; end; try FillChar(SI, SizeOf(TStartupInfo), 0); SI.cb := SizeOf(TStartupInfo); SI.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW; SI.hStdInput := GetStdHandle(STD_INPUT_HANDLE); SI.hStdOutput := hWrite; SI.hStdError := hWrite; SI.wShowWindow := SW_HIDE; Cmd := 'cmd.exe /C ' + Command; if not CreateProcess(nil, PChar(Cmd), nil, nil, True, 0, nil, nil, SI, PI) then begin Exit; end; CloseHandle(hWrite); try while True do begin if not ReadFile(hRead, Buffer, SizeOf(Buffer) - 1, BytesRead, nil) or (BytesRead = 0) then begin break; end; Buffer[BytesRead] := #0; FullOutput := FullOutput + AnsiString(Buffer); end; WaitForSingleObject(PI.hProcess, INFINITE); GetExitCodeProcess(PI.hProcess, Cardinal(Result)); finally CloseHandle(PI.hProcess); CloseHandle(PI.hThread); end; finally CloseHandle(hRead); end; Output.Text := string(FullOutput); end; function GetBranchVersionDigits: Integer; var XMLDoc: IXMLDOMDocument2; Node: IXMLDOMNode; ConfigPath: string; CoInitResult: HRESULT; begin Result := 4; // Default value ConfigPath := ExtractFilePath(ParamStr(0)) + 'SkybuckGitflow.cfg'; if FileExists(ConfigPath) then begin // Initialize COM for this thread CoInitResult := CoInitialize(nil); try try XMLDoc := CoDOMDocument60.Create; if not Assigned(XMLDoc) then begin raise Exception.Create('Failed to create MSXML 6.0 document'); end; XMLDoc.async := False; if not XMLDoc.load(ConfigPath) then begin // Check for a parse error object before accessing its properties if Assigned(XMLDoc.parseError) then begin raise Exception.Create('XML load failed: ' + XMLDoc.parseError.reason) end else begin raise Exception.Create('XML load failed with an unknown error.'); end; end; Node := XMLDoc.selectSingleNode('//BranchVersionDigits'); if Assigned(Node) then begin Result := StrToIntDef(Node.text, 4); end; except on E: Exception do begin Writeln('Error processing config file: ', E.Message); end; end; finally // *** THE FIX IS HERE *** // Release COM objects BEFORE CoUninitialize is called. Node := nil; XMLDoc := nil; // Uninitialize COM only if it was successfully initialized on this call. if SUCCEEDED(CoInitResult) then // Use SUCCEEDED for robustness begin CoUninitialize; end; end; end; end; function RemoteOriginExists: boolean; var Output: TStringList; begin Output := TStringList.Create; try Result := ExecuteCommand('git remote get-url origin > NUL 2>&1', Output) = 0; finally Output.Free; end; end; function GetGitConfigValue(const ConfigKey: string): string; var Output: TStringList; begin Result := ''; Output := TStringList.Create; try if ExecuteCommand('git config ' + ConfigKey, Output) = 0 then begin if Output.Count > 0 then begin Result := Trim(Output.Text); end; end; finally Output.Free; end; end; function Slugify(const Input: string): string; begin Result := Input.ToLower; Result := TRegEx.Replace(Result, '[^a-z0-9]+', '-'); Result := TRegEx.Replace(Result, '^-+|-+$', ''); if Length(Result) > 50 then begin Result := Copy(Result, 1, 50); end; end; function GetNextContributionNumber(const UserPrefix: string; ParaRemoteExists: boolean): Integer; var Output: TStringList; MaxNum: Integer; Match: TMatch; Num: Integer; S, vRefs: string; begin MaxNum := 0; Output := TStringList.Create; try if ParaRemoteExists then begin ExecuteCommand('git fetch origin --prune', Output); // Sync with remote Output.Clear; vRefs := 'refs/heads refs/remotes/origin'; end else begin vRefs := 'refs/heads'; end; if ExecuteCommand('git for-each-ref --format="%(refname:short)" ' + vRefs, Output) = 0 then begin S := Output.Text; for Match in TRegEx.Matches(S, '^' + UserPrefix + 'Contribution(\d+)-') do begin if Match.Success then begin Num := StrToIntDef(Match.Groups[1].Value, 0); if Num > MaxNum then begin MaxNum := Num; end; end; end; end; finally Output.Free; end; Result := MaxNum + 1; end; function TagExists(const ParaTagName: string; ParaRemoteExists: boolean): boolean; var vOutput: TStringList; begin Result := False; vOutput := TStringList.Create; try if ExecuteCommand('git show-ref --verify "refs/tags/' + ParaTagName + '"', vOutput) = 0 then begin Result := True; Exit; end; if ParaRemoteExists then begin vOutput.Clear; if ExecuteCommand('git ls-remote --tags origin "refs/tags/' + ParaTagName + '"', vOutput) = 0 then begin Result := vOutput.Text <> ''; end; end; finally vOutput.Free; end; end; function BranchExists(const ParaBranchName: string; ParaRemoteExists: boolean): boolean; var vOutput: TStringList; begin Result := False; vOutput := TStringList.Create; try if ExecuteCommand('git show-ref --verify "refs/heads/' + ParaBranchName + '"', vOutput) = 0 then begin Result := True; Exit; end; if ParaRemoteExists then begin vOutput.Clear; if ExecuteCommand('git show-ref --verify "refs/remotes/origin/' + ParaBranchName + '"', vOutput) = 0 then begin Result := True; end; end; finally vOutput.Free; end; end; var vOldTagName, vDescription, vUserPrefix, vSlug, vNewBranchName, vFormatStr: string; vNextNum, vBranchVersionDigits: Integer; vOutput: TStringList; vRemoteExists: Boolean; begin try vBranchVersionDigits := GetBranchVersionDigits; if ParamCount <> 2 then begin Writeln('Usage: git-back-to <tagname_of_old_commit> "<new_branch_description>"'); Writeln('Example: git-back-to merged/AI0001Contribution007-OldAPIDesign "Re-evaluate V1 API for performance"'); ExitCode := 1; Exit; end; vOldTagName := ParamStr(1); vDescription := ParamStr(2); vRemoteExists := RemoteOriginExists; vUserPrefix := GetGitConfigValue('user.contributionPrefix'); if vUserPrefix = '' then begin vUserPrefix := GetGitConfigValue('user.name'); if vUserPrefix <> '' then begin vUserPrefix := TRegEx.Replace(vUserPrefix, '[^a-zA-Z0-9]', ''); end else begin Writeln('Error: Git user.name or user.contributionPrefix not set.'); Writeln('Run: git config --global user.name "Your Name"'); Writeln('Or: git config --global user.contributionPrefix "YourPrefix"'); ExitCode := 1; Exit; end; end; vSlug := Slugify(vDescription); if vSlug = '' then begin Writeln('Error: Description resulted in empty slug.'); ExitCode := 1; Exit; end; if not TagExists(vOldTagName, vRemoteExists) then begin Writeln('Error: Tag ''' + vOldTagName + ''' does not exist locally or remotely.'); ExitCode := 1; Exit; end; vNextNum := GetNextContributionNumber(vUserPrefix, vRemoteExists); vFormatStr := Format('%%sContribution%%0.%dd-%%s', [vBranchVersionDigits]); vNewBranchName := Format(vFormatStr, [vUserPrefix, vNextNum, vSlug]); if BranchExists(vNewBranchName, vRemoteExists) then begin Writeln('Error: Branch ''' + vNewBranchName + ''' already exists.'); ExitCode := 1; Exit; end; vOutput := TStringList.Create; try Writeln('Creating new branch ''' + vNewBranchName + ''' from tag ''' + vOldTagName + '''...'); if ExecuteCommand('git checkout -b "' + vNewBranchName + '" "' + vOldTagName + '"', vOutput) <> 0 then begin Writeln('Error: Failed to create branch from tag.'); ExitCode := 1; Exit; end; vOutput.Clear; if vRemoteExists then begin Writeln('Pushing ''' + vNewBranchName + ''' to remote...'); if ExecuteCommand('git push -u origin "' + vNewBranchName + '"', vOutput) <> 0 then begin Writeln('Error: Failed to push branch to origin.'); ExitCode := 1; Exit; end; vOutput.Clear; end; Writeln('---'); Writeln('Calling git-set-active to mark as active...'); if ExecuteCommand('cmd.exe /c "' + ExtractFilePath(ParamStr(0)) + 'git-set-active.exe" ' + vNewBranchName, vOutput) <> 0 then begin Writeln('Warning: Could not mark branch active. Run manually: git-set-active ' + vNewBranchName); end; Writeln(vOutput.Text); finally vOutput.Free; end; Writeln(''); Writeln('Branch ''' + vNewBranchName + ''' successfully created and activated from tag ''' + vOldTagName + '''.'); Writeln('To upgrade it against latest master, use: git-the-future'); except on E: Exception do begin Writeln(E.ClassName, ': ', E.Message); ExitCode := 1; end; end; end. Save program 2 as "git-new-contribution.dpr": program git_new_contribution; { Skybuck's GitFlow version 0.08 created on 29 august 2025 by Skybuck Flying and Gemini (AI) and Co-Pilot (AI). credits: Almost all code by Google Gemini 2.5 Pro. GetBranchVersionDigits code by Microsoft Co-Pilot. Software Idea and Prompting and Overwatching the AI: Skybuck Flying. improvements for version 0.08: + local git support + better contribution number Delphi code developed for Delphi 12.3 and Windows 11. } {$APPTYPE CONSOLE} uses System.SysUtils, System.Classes, System.RegularExpressions, System.IOUtils, Winapi.Windows, ActiveX, MSXML; function ExecuteCommand( const ParaCommand : string; out ParaOutput : TStringList ) : Integer; var vSA : TSecurityAttributes; vSI : TStartupInfo; vPI : TProcessInformation; vhRead, vhWrite : THandle; vBuffer : array[0..255] of AnsiChar; vBytesRead : DWord; vCmd : string; begin ParaOutput := TStringList.Create; Result := -1; vSA.nLength := SizeOf(TSecurityAttributes); vSA.bInheritHandle := True; vSA.lpSecurityDescriptor := nil; if not CreatePipe(vhRead, vhWrite, @vSA, 0) then begin Exit; end; FillChar(vSI, SizeOf(TStartupInfo), 0); vSI.cb := SizeOf(TStartupInfo); vSI.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW; vSI.hStdInput := GetStdHandle(STD_INPUT_HANDLE); vSI.hStdOutput := vhWrite; vSI.hStdError := vhWrite; vSI.wShowWindow := SW_HIDE; vCmd := 'cmd.exe /C ' + ParaCommand; if not CreateProcess(nil, PChar(vCmd), nil, nil, True, 0, nil, nil, vSI, vPI) then begin CloseHandle(vhRead); CloseHandle(vhWrite); Exit; end; CloseHandle(vhWrite); while True do begin if not ReadFile(vhRead, vBuffer, SizeOf(vBuffer) - 1, vBytesRead, nil) or (vBytesRead = 0) then begin break; end; vBuffer[vBytesRead] := #0; ParaOutput.Add(string(vBuffer)); end; WaitForSingleObject(vPI.hProcess, INFINITE); GetExitCodeProcess(vPI.hProcess, Cardinal(Result)); CloseHandle(vhRead); CloseHandle(vPI.hProcess); CloseHandle(vPI.hThread); end; function GetBranchVersionDigits: Integer; var XMLDoc: IXMLDOMDocument2; Node: IXMLDOMNode; ConfigPath: string; CoInitResult: HRESULT; begin Result := 4; // Default value ConfigPath := ExtractFilePath(ParamStr(0)) + 'SkybuckGitflow.cfg'; if FileExists(ConfigPath) then begin // Initialize COM for this thread CoInitResult := CoInitialize(nil); try try XMLDoc := CoDOMDocument60.Create; if not Assigned(XMLDoc) then begin raise Exception.Create('Failed to create MSXML 6.0 document'); end; XMLDoc.async := False; if not XMLDoc.load(ConfigPath) then begin // Check for a parse error object before accessing its properties if Assigned(XMLDoc.parseError) then begin raise Exception.Create('XML load failed: ' + XMLDoc.parseError.reason) end else begin raise Exception.Create('XML load failed with an unknown error.'); end; end; Node := XMLDoc.selectSingleNode('//BranchVersionDigits'); if Assigned(Node) then begin Result := Abs(StrToIntDef(Node.text, 4)); end; except on E: Exception do begin Writeln('Error processing config file: ', E.Message); end; end; finally // *** THE FIX IS HERE *** // Release COM objects BEFORE CoUninitialize is called. Node := nil; XMLDoc := nil; // Uninitialize COM only if it was successfully initialized on this call. if SUCCEEDED(CoInitResult) then // Use SUCCEEDED for robustness begin CoUninitialize; end; end; end; end; function RemoteOriginExists: boolean; var Output: TStringList; begin Output := TStringList.Create; try Result := ExecuteCommand('git remote get-url origin > NUL 2>&1', Output) = 0; finally Output.Free; end; end; function GetGitConfigValue( const ParaConfigKey : string ) : string; var vOutput : TStringList; begin Result := ''; vOutput := TStringList.Create; try if ExecuteCommand('git config ' + ParaConfigKey, vOutput) = 0 then begin if vOutput.Count > 0 then begin Result := Trim(vOutput.Text); end; end; finally vOutput.Free; end; end; function Slugify( const ParaInput : string ) : string; begin Result := ParaInput.ToLower; Result := TRegEx.Replace(Result, '[^a-z0-9]+', '-'); Result := TRegEx.Replace(Result, '^-+|-+$', ''); if Length(Result) > 50 then begin Result := Copy(Result, 1, 50); end; end; function GetNextContributionNumber( const ParaUserPrefix : string; ParaRemoteExists: boolean ) : Integer; var vOutput : TStringList; vMaxNum : Integer; vMatch : TMatch; vNum : Integer; vS, vRefs: string; vRegex: TRegEx; begin vMaxNum := 0; vOutput := TStringList.Create; try if ParaRemoteExists then begin ExecuteCommand('git fetch origin --prune', vOutput); // Sync with remote vOutput.Clear; vRefs := 'refs/heads refs/remotes/origin'; end else begin vRefs := 'refs/heads'; end; if ExecuteCommand('git for-each-ref --format="%(refname:short)" ' + vRefs, vOutput) = 0 then begin vS := vOutput.Text; vRegex := TRegEx.Create('^' + ParaUserPrefix + 'Contribution(\d+)-', [roMultiLine]); for vMatch in vRegex.Matches(vS) do begin if vMatch.Success then begin vNum := StrToIntDef(vMatch.Groups[1].Value, 0); if vNum > vMaxNum then begin vMaxNum := vNum; end; end; end; end; finally vOutput.Free; end; Result := vMaxNum + 1; end; var vUserPrefix, vDescription, vSlug, vNewBranchName, vFormatStr : string; vNextNum, vBranchVersionDigits : Integer; vOutput : TStringList; vRemoteExists: Boolean; begin try vBranchVersionDigits := GetBranchVersionDigits; if ParamCount = 1 then begin vDescription := ParamStr(1); vUserPrefix := ''; end else if ParamCount >= 2 then begin vUserPrefix := ParamStr(1); vDescription := ParamStr(2); end else begin Writeln('Usage: git-new-contribution [<UserPrefix>] "<Description/Goal...>"'); ExitCode := 1; Exit; end; if vUserPrefix = '' then begin vUserPrefix := GetGitConfigValue('user.contributionPrefix'); if vUserPrefix = '' then begin vUserPrefix := GetGitConfigValue('user.name'); if vUserPrefix <> '' then begin vUserPrefix := TRegEx.Replace(vUserPrefix, '[^a-zA-Z0-9]', ''); end else begin Writeln('Error: User prefix not provided and not found in git config.'); ExitCode := 1; Exit; end; end; end; vSlug := Slugify(vDescription); if vSlug = '' then begin Writeln('Error: Description resulted in empty slug.'); ExitCode := 1; Exit; end; vOutput := TStringList.Create; try vRemoteExists := RemoteOriginExists; Writeln('Switching to master branch...'); if ExecuteCommand('git checkout master', vOutput) <> 0 then begin Writeln('Error: Failed to checkout master.'); Writeln(vOutput.Text); ExitCode := 1; Exit; end; vOutput.Clear; if vRemoteExists then begin Writeln('Fetching latest master...'); if ExecuteCommand('git pull origin master', vOutput) <> 0 then begin Writeln('Warning: Failed to pull latest master. Proceeding with local master.'); Writeln(vOutput.Text); end; vOutput.Clear; end; vNextNum := GetNextContributionNumber(vUserPrefix, vRemoteExists); vFormatStr := Format('%%sContribution%%0.%dd-%%s', [vBranchVersionDigits]); vNewBranchName := Format(vFormatStr, [vUserPrefix, vNextNum, vSlug]); if ExecuteCommand('git show-ref --verify refs/heads/' + vNewBranchName, vOutput) = 0 then begin Writeln('Error: Local branch already exists.'); ExitCode := 1; Exit; end; vOutput.Clear; Writeln('Creating new branch: ' + vNewBranchName); if ExecuteCommand('git checkout -b ' + vNewBranchName + ' master', vOutput) <> 0 then begin Writeln('Error: Failed to create local branch.'); Writeln(vOutput.Text); ExitCode := 1; Exit; end; vOutput.Clear; if vRemoteExists then begin Writeln('Pushing new branch to origin...'); if ExecuteCommand('git push -u origin ' + vNewBranchName, vOutput) <> 0 then begin Writeln('Error: Failed to push new branch.'); Writeln(vOutput.Text); ExitCode := 1; Exit; end; vOutput.Clear; end; if ExecuteCommand('cmd.exe /c "' + ExtractFilePath(ParamStr(0)) + 'git-set-active.exe" ' + vNewBranchName, vOutput) <> 0 then begin Writeln('Warning: Failed to mark branch active.'); Writeln(vOutput.Text); end; vOutput.Clear; Writeln(''); Writeln('Successfully created and activated new contribution branch:'); Writeln('-> **' + vNewBranchName + '**'); Writeln('You are now on this branch. Start coding!'); finally vOutput.Free; end; except on E : Exception do begin Writeln(E.ClassName, ': ', E.Message); ExitCode := 1; end; end; end. Save program 3 as "git-set-active.dpr": program git_set_active; { Skybuck's GitFlow version 0.08 created on 29 august 2025 by Skybuck Flying and Gemini (AI) and Co-Pilot (AI). credits: Almost all code by Google Gemini 2.5 Pro. GetBranchVersionDigits code by Microsoft Co-Pilot. Software Idea and Prompting and Overwatching the AI: Skybuck Flying. improvements for version 0.08: + local git support + better contribution number Delphi code developed for Delphi 12.3 and Windows 11. } {$APPTYPE CONSOLE} uses System.SysUtils, System.Classes, System.IOUtils, Winapi.Windows; function ExecuteCommand(const Command: string; out Output: TStringList): Integer; var SA: TSecurityAttributes; SI: TStartupInfo; PI: TProcessInformation; hRead, hWrite: THandle; Buffer: array[0..1023] of AnsiChar; BytesRead: DWord; Cmd: string; FullOutput: AnsiString; begin Output := TStringList.Create; Result := -1; FullOutput := ''; SA.nLength := SizeOf(TSecurityAttributes); SA.bInheritHandle := True; SA.lpSecurityDescriptor := nil; if not CreatePipe(hRead, hWrite, @SA, 0) then begin Exit; end; try FillChar(SI, SizeOf(TStartupInfo), 0); SI.cb := SizeOf(TStartupInfo); SI.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW; SI.hStdInput := GetStdHandle(STD_INPUT_HANDLE); SI.hStdOutput := hWrite; SI.hStdError := hWrite; SI.wShowWindow := SW_HIDE; Cmd := 'cmd.exe /C ' + Command; if not CreateProcess(nil, PChar(Cmd), nil, nil, True, 0, nil, nil, SI, PI) then begin Exit; end; CloseHandle(hWrite); try while True do begin if not ReadFile(hRead, Buffer, SizeOf(Buffer) - 1, BytesRead, nil) or (BytesRead = 0) then begin break; end; Buffer[BytesRead] := #0; FullOutput := FullOutput + AnsiString(Buffer); end; WaitForSingleObject(PI.hProcess, INFINITE); GetExitCodeProcess(PI.hProcess, Cardinal(Result)); finally CloseHandle(PI.hProcess); CloseHandle(PI.hThread); end; finally CloseHandle(hRead); end; Output.Text := string(FullOutput); end; function RemoteOriginExists: boolean; var Output: TStringList; begin Output := TStringList.Create; try Result := ExecuteCommand('git remote get-url origin > NUL 2>&1', Output) = 0; finally Output.Free; end; end; function BranchExists(const ParaBranchName: string; ParaRemoteExists: boolean): boolean; var vOutput: TStringList; begin Result := False; vOutput := TStringList.Create; try if ExecuteCommand('git show-ref --verify "refs/heads/' + ParaBranchName + '"', vOutput) = 0 then begin Result := True; Exit; end; if ParaRemoteExists then begin vOutput.Clear; if ExecuteCommand('git show-ref --verify "refs/remotes/origin/' + ParaBranchName + '"', vOutput) = 0 then begin Result := True; end; end; finally vOutput.Free; end; end; function GetBranchHash(const ParaBranchName: string; ParaRemoteExists: boolean): string; var vOutput: TStringList; begin Result := ''; vOutput := TStringList.Create; try if ParaRemoteExists then begin if ExecuteCommand('git rev-parse "refs/remotes/origin/' + ParaBranchName + '^{commit}"', vOutput) = 0 then begin Result := Trim(vOutput.Text); if Result <> '' then begin Exit; end; end; end; vOutput.Clear; if ExecuteCommand('git rev-parse "refs/heads/' + ParaBranchName + '^{commit}"', vOutput) = 0 then begin Result := Trim(vOutput.Text); end; finally vOutput.Free; end; end; procedure DeleteTagIfExists(const ParaTagName: string; ParaRemoteExists: boolean); var vOutput: TStringList; begin vOutput := TStringList.Create; try if ExecuteCommand('git show-ref --verify "refs/tags/' + ParaTagName + '"', vOutput) = 0 then begin Writeln('Removing existing local tag: ' + ParaTagName + '...'); vOutput.Clear; if ExecuteCommand('git tag -d "' + ParaTagName + '"', vOutput) <> 0 then begin Writeln('Warning: Failed to delete local tag ' + ParaTagName + '.'); end; end; if ParaRemoteExists then begin vOutput.Clear; if ExecuteCommand('git ls-remote --tags origin "refs/tags/' + ParaTagName + '"', vOutput) = 0 then begin if vOutput.Text <> '' then begin Writeln('Removing existing remote tag: ' + ParaTagName + '...'); vOutput.Clear; if ExecuteCommand('git push origin --delete "' + ParaTagName + '"', vOutput) <> 0 then begin Writeln('Warning: Failed to delete remote tag ' + ParaTagName + '.'); end; end; end; end; finally vOutput.Free; end; end; var vBranchName, vActiveTag, vBranchHash: string; vOutput: TStringList; vRemoteExists: Boolean; begin try if ParamCount <> 1 then begin Writeln('Usage: git-set-active <branchname>'); Writeln('Example: git-set-active SkybuckContribution001-ImplementLogin'); ExitCode := 1; Exit; end; vBranchName := ParamStr(1); vActiveTag := 'active/' + vBranchName; vRemoteExists := RemoteOriginExists; if not BranchExists(vBranchName, vRemoteExists) then begin Writeln('Error: Branch ''' + vBranchName + ''' not found locally or remotely.'); ExitCode := 1; Exit; end; vBranchHash := GetBranchHash(vBranchName, vRemoteExists); if vBranchHash = '' then begin Writeln('Error: Unable to determine commit hash for branch ''' + vBranchName + '''.'); ExitCode := 1; Exit; end; DeleteTagIfExists('merged/' + vBranchName, vRemoteExists); DeleteTagIfExists('rejected/' + vBranchName, vRemoteExists); Writeln('Creating active tag: ' + vActiveTag); vOutput := TStringList.Create; try if ExecuteCommand('git tag -f "' + vActiveTag + '" "' + vBranchHash + '"', vOutput) <> 0 then begin Writeln('Error: Failed to create tag ' + vActiveTag); ExitCode := 1; Exit; end; vOutput.Clear; if vRemoteExists then begin Writeln('Pushing active tag to origin...'); if ExecuteCommand('git push -f origin "' + vActiveTag + '"', vOutput) <> 0 then begin Writeln('Error: Failed to push tag ' + vActiveTag + ' to origin'); ExitCode := 1; Exit; end; end; finally vOutput.Free; end; Writeln(''); Writeln('Branch ' + vBranchName + ' is now marked as ACTIVE.'); Writeln('To view active branches: git tag --list "active/*"'); except on E: Exception do begin Writeln(E.ClassName, ': ', E.Message); ExitCode := 1; end; end; end. Save program 4 as "git-set-merged.dpr": program git_set_merged; { Skybuck's GitFlow version 0.08 created on 29 august 2025 by Skybuck Flying and Gemini (AI) and Co-Pilot (AI). credits: Almost all code by Google Gemini 2.5 Pro. GetBranchVersionDigits code by Microsoft Co-Pilot. Software Idea and Prompting and Overwatching the AI: Skybuck Flying. improvements for version 0.08: + local git support + better contribution number Delphi code developed for Delphi 12.3 and Windows 11. } {$APPTYPE CONSOLE} uses System.SysUtils, System.Classes, System.IOUtils, Winapi.Windows; function ExecuteCommand(const Command: string; out Output: TStringList): Integer; var SA: TSecurityAttributes; SI: TStartupInfo; PI: TProcessInformation; hRead, hWrite: THandle; Buffer: array[0..1023] of AnsiChar; BytesRead: DWord; Cmd: string; FullOutput: AnsiString; begin Output := TStringList.Create; Result := -1; FullOutput := ''; SA.nLength := SizeOf(TSecurityAttributes); SA.bInheritHandle := True; SA.lpSecurityDescriptor := nil; if not CreatePipe(hRead, hWrite, @SA, 0) then begin Exit; end; try FillChar(SI, SizeOf(TStartupInfo), 0); SI.cb := SizeOf(TStartupInfo); SI.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW; SI.hStdInput := GetStdHandle(STD_INPUT_HANDLE); SI.hStdOutput := hWrite; SI.hStdError := hWrite; SI.wShowWindow := SW_HIDE; Cmd := 'cmd.exe /C ' + Command; if not CreateProcess(nil, PChar(Cmd), nil, nil, True, 0, nil, nil, SI, PI) then begin Exit; end; CloseHandle(hWrite); try while True do begin if not ReadFile(hRead, Buffer, SizeOf(Buffer) - 1, BytesRead, nil) or (BytesRead = 0) then begin break; end; Buffer[BytesRead] := #0; FullOutput := FullOutput + AnsiString(Buffer); end; WaitForSingleObject(PI.hProcess, INFINITE); GetExitCodeProcess(PI.hProcess, Cardinal(Result)); finally CloseHandle(PI.hProcess); CloseHandle(PI.hThread); end; finally CloseHandle(hRead); end; Output.Text := string(FullOutput); end; function RemoteOriginExists: boolean; var Output: TStringList; begin Output := TStringList.Create; try Result := ExecuteCommand('git remote get-url origin > NUL 2>&1', Output) = 0; finally Output.Free; end; end; function BranchExists(const ParaBranchName: string; ParaRemoteExists: boolean): boolean; var vOutput: TStringList; begin Result := False; vOutput := TStringList.Create; try if ExecuteCommand('git show-ref --verify "refs/heads/' + ParaBranchName + '"', vOutput) = 0 then begin Result := True; Exit; end; if ParaRemoteExists then begin vOutput.Clear; if ExecuteCommand('git show-ref --verify "refs/remotes/origin/' + ParaBranchName + '"', vOutput) = 0 then begin Result := True; end; end; finally vOutput.Free; end; end; function GetBranchHash(const ParaBranchName: string; ParaRemoteExists: boolean): string; var vOutput: TStringList; begin Result := ''; vOutput := TStringList.Create; try if ParaRemoteExists then begin if ExecuteCommand('git rev-parse "refs/remotes/origin/' + ParaBranchName + '^{commit}"', vOutput) = 0 then begin Result := Trim(vOutput.Text); if Result <> '' then begin Exit; end; end; end; vOutput.Clear; if ExecuteCommand('git rev-parse "refs/heads/' + ParaBranchName + '^{commit}"', vOutput) = 0 then begin Result := Trim(vOutput.Text); end; finally vOutput.Free; end; end; procedure DeleteTagIfExists(const ParaTagName: string; ParaRemoteExists: boolean); var vOutput: TStringList; begin vOutput := TStringList.Create; try if ExecuteCommand('git show-ref --verify "refs/tags/' + ParaTagName + '"', vOutput) = 0 then begin Writeln('Removing existing local tag: ' + ParaTagName + '...'); vOutput.Clear; if ExecuteCommand('git tag -d "' + ParaTagName + '"', vOutput) <> 0 then begin Writeln('Warning: Failed to delete local tag ' + ParaTagName + '.'); end; end; if ParaRemoteExists then begin vOutput.Clear; if ExecuteCommand('git ls-remote --tags origin "refs/tags/' + ParaTagName + '"', vOutput) = 0 then begin if vOutput.Text <> '' then begin Writeln('Removing existing remote tag: ' + ParaTagName + '...'); vOutput.Clear; if ExecuteCommand('git push origin --delete "' + ParaTagName + '"', vOutput) <> 0 then begin Writeln('Warning: Failed to delete remote tag ' + ParaTagName + '.'); end; end; end; end; finally vOutput.Free; end; end; var vBranchName, vMergedTag, vBranchHash: string; vOutput: TStringList; vRemoteExists: Boolean; begin try if ParamCount <> 1 then begin Writeln('Usage: git-set-merged <branchname>'); Writeln('Example: git-set-merged SkybuckContribution001-MyFeature'); ExitCode := 1; Exit; end; vBranchName := ParamStr(1); vMergedTag := 'merged/' + vBranchName; vRemoteExists := RemoteOriginExists; if not BranchExists(vBranchName, vRemoteExists) then begin Writeln('Error: Branch ''' + vBranchName + ''' does not exist locally or remotely.'); ExitCode := 1; Exit; end; vBranchHash := GetBranchHash(vBranchName, vRemoteExists); if vBranchHash = '' then begin Writeln('Error: Unable to determine commit hash for branch ''' + vBranchName + '''.'); ExitCode := 1; Exit; end; DeleteTagIfExists('active/' + vBranchName, vRemoteExists); DeleteTagIfExists('rejected/' + vBranchName, vRemoteExists); Writeln('Creating merged tag: ' + vMergedTag); vOutput := TStringList.Create; try if ExecuteCommand('git tag -f "' + vMergedTag + '" "' + vBranchHash + '"', vOutput) <> 0 then begin Writeln('Error: Failed to create tag ' + vMergedTag + '.'); ExitCode := 1; Exit; end; vOutput.Clear; if vRemoteExists then begin Writeln('Pushing merged tag to origin...'); if ExecuteCommand('git push -f origin "' + vMergedTag + '"', vOutput) <> 0 then begin Writeln('Error: Failed to push tag ' + vMergedTag + ' to origin.'); ExitCode := 1; Exit; end; end; finally vOutput.Free; end; Writeln(''); Writeln('Branch ' + vBranchName + ' successfully marked as MERGED.'); Writeln('It remains in your repository history.'); except on E: Exception do begin Writeln(E.ClassName, ': ', E.Message); ExitCode := 1; end; end; end. Save program 5 as "git-set-rejected.dpr": program git_set_rejected; { Skybuck's GitFlow version 0.08 created on 29 august 2025 by Skybuck Flying and Gemini (AI) and Co-Pilot (AI). credits: Almost all code by Google Gemini 2.5 Pro. GetBranchVersionDigits code by Microsoft Co-Pilot. Software Idea and Prompting and Overwatching the AI: Skybuck Flying. improvements for version 0.08: + local git support + better contribution number Delphi code developed for Delphi 12.3 and Windows 11. } {$APPTYPE CONSOLE} uses System.SysUtils, System.Classes, System.IOUtils, Winapi.Windows; function ExecuteCommand(const Command: string; out Output: TStringList): Integer; var SA: TSecurityAttributes; SI: TStartupInfo; PI: TProcessInformation; hRead, hWrite: THandle; Buffer: array[0..1023] of AnsiChar; BytesRead: DWord; Cmd: string; FullOutput: AnsiString; begin Output := TStringList.Create; Result := -1; FullOutput := ''; SA.nLength := SizeOf(TSecurityAttributes); SA.bInheritHandle := True; SA.lpSecurityDescriptor := nil; if not CreatePipe(hRead, hWrite, @SA, 0) then begin Exit; end; try FillChar(SI, SizeOf(TStartupInfo), 0); SI.cb := SizeOf(TStartupInfo); SI.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW; SI.hStdInput := GetStdHandle(STD_INPUT_HANDLE); SI.hStdOutput := hWrite; SI.hStdError := hWrite; SI.wShowWindow := SW_HIDE; Cmd := 'cmd.exe /C ' + Command; if not CreateProcess(nil, PChar(Cmd), nil, nil, True, 0, nil, nil, SI, PI) then begin Exit; end; CloseHandle(hWrite); try while True do begin if not ReadFile(hRead, Buffer, SizeOf(Buffer) - 1, BytesRead, nil) or (BytesRead = 0) then begin break; end; Buffer[BytesRead] := #0; FullOutput := FullOutput + AnsiString(Buffer); end; WaitForSingleObject(PI.hProcess, INFINITE); GetExitCodeProcess(PI.hProcess, Cardinal(Result)); finally CloseHandle(PI.hProcess); CloseHandle(PI.hThread); end; finally CloseHandle(hRead); end; Output.Text := string(FullOutput); end; function RemoteOriginExists: boolean; var Output: TStringList; begin Output := TStringList.Create; try Result := ExecuteCommand('git remote get-url origin > NUL 2>&1', Output) = 0; finally Output.Free; end; end; function BranchExists(const ParaBranchName: string; ParaRemoteExists: boolean): boolean; var vOutput: TStringList; begin Result := False; vOutput := TStringList.Create; try if ExecuteCommand('git show-ref --verify "refs/heads/' + ParaBranchName + '"', vOutput) = 0 then begin Result := True; Exit; end; if ParaRemoteExists then begin vOutput.Clear; if ExecuteCommand('git show-ref --verify "refs/remotes/origin/' + ParaBranchName + '"', vOutput) = 0 then begin Result := True; end; end; finally vOutput.Free; end; end; function GetBranchHash(const ParaBranchName: string; ParaRemoteExists: boolean): string; var vOutput: TStringList; begin Result := ''; vOutput := TStringList.Create; try if ParaRemoteExists then begin if ExecuteCommand('git rev-parse "refs/remotes/origin/' + ParaBranchName + '^{commit}"', vOutput) = 0 then begin Result := Trim(vOutput.Text); if Result <> '' then begin Exit; end; end; end; vOutput.Clear; if ExecuteCommand('git rev-parse "refs/heads/' + ParaBranchName + '^{commit}"', vOutput) = 0 then begin Result := Trim(vOutput.Text); end; finally vOutput.Free; end; end; procedure DeleteTagIfExists(const ParaTagName: string; ParaRemoteExists: boolean); var vOutput: TStringList; begin vOutput := TStringList.Create; try if ExecuteCommand('git show-ref --verify "refs/tags/' + ParaTagName + '"', vOutput) = 0 then begin Writeln('Removing existing local tag: ' + ParaTagName + '...'); vOutput.Clear; if ExecuteCommand('git tag -d "' + ParaTagName + '"', vOutput) <> 0 then begin Writeln('Warning: Failed to delete local tag ' + ParaTagName + '.'); end; end; if ParaRemoteExists then begin vOutput.Clear; if ExecuteCommand('git ls-remote --tags origin "refs/tags/' + ParaTagName + '"', vOutput) = 0 then begin if vOutput.Text <> '' then begin Writeln('Removing existing remote tag: ' + ParaTagName + '...'); vOutput.Clear; if ExecuteCommand('git push origin --delete "' + ParaTagName + '"', vOutput) <> 0 then begin Writeln('Warning: Failed to delete remote tag ' + ParaTagName + '.'); end; end; end; end; finally vOutput.Free; end; end; var vBranchName, vRejectedTag, vBranchHash: string; vOutput: TStringList; vRemoteExists: Boolean; begin try if ParamCount <> 1 then begin Writeln('Usage: git-set-rejected <branchname>'); Writeln('Example: git-set-rejected AI0001Contribution002-ExperimentalAlgorithm'); ExitCode := 1; Exit; end; vBranchName := ParamStr(1); vRejectedTag := 'rejected/' + vBranchName; vRemoteExists := RemoteOriginExists; if not BranchExists(vBranchName, vRemoteExists) then begin Writeln('Error: Branch ''' + vBranchName + ''' does not exist locally or remotely.'); ExitCode := 1; Exit; end; vBranchHash := GetBranchHash(vBranchName, vRemoteExists); if vBranchHash = '' then begin Writeln('Error: Could not determine commit hash for branch ''' + vBranchName + '''.'); ExitCode := 1; Exit; end; DeleteTagIfExists('active/' + vBranchName, vRemoteExists); DeleteTagIfExists('merged/' + vBranchName, vRemoteExists); Writeln('Creating rejected tag: ' + vRejectedTag); vOutput := TStringList.Create; try if ExecuteCommand('git tag -f "' + vRejectedTag + '" "' + vBranchHash + '"', vOutput) <> 0 then begin Writeln('Error: Could not create tag ''' + vRejectedTag + ''''); ExitCode := 1; Exit; end; vOutput.Clear; if vRemoteExists then begin Writeln('Pushing rejected tag to origin...'); if ExecuteCommand('git push -f origin "' + vRejectedTag + '"', vOutput) <> 0 then begin Writeln('Error: Could not push tag ''' + vRejectedTag + ''' to origin'); ExitCode := 1; Exit; end; end; finally vOutput.Free; end; Writeln(''); Writeln('Branch ' + vBranchName + ' marked as REJECTED.'); Writeln('Tag ''' + vRejectedTag + ''' added for reference.'); except on E: Exception do begin Writeln(E.ClassName, ': ', E.Message); ExitCode := 1; end; end; end. Save program 6 as "git-set-revive.dpr": program git_set_revive; { Skybuck's GitFlow version 0.08 created on 29 august 2025 by Skybuck Flying and Gemini (AI) and Co-Pilot (AI). credits: Almost all code by Google Gemini 2.5 Pro. GetBranchVersionDigits code by Microsoft Co-Pilot. Software Idea and Prompting and Overwatching the AI: Skybuck Flying. improvements for version 0.08: + local git support + better contribution number Delphi code developed for Delphi 12.3 and Windows 11. } {$APPTYPE CONSOLE} uses System.SysUtils, System.Classes, System.IOUtils, Winapi.Windows; function ExecuteCommand(const Command: string; out Output: TStringList): Integer; var SA: TSecurityAttributes; SI: TStartupInfo; PI: TProcessInformation; hRead, hWrite: THandle; Buffer: array[0..1023] of AnsiChar; BytesRead: DWord; Cmd: string; FullOutput: AnsiString; begin Output := TStringList.Create; Result := -1; FullOutput := ''; SA.nLength := SizeOf(TSecurityAttributes); SA.bInheritHandle := True; SA.lpSecurityDescriptor := nil; if not CreatePipe(hRead, hWrite, @SA, 0) then begin Exit; end; try FillChar(SI, SizeOf(TStartupInfo), 0); SI.cb := SizeOf(TStartupInfo); SI.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW; SI.hStdInput := GetStdHandle(STD_INPUT_HANDLE); SI.hStdOutput := hWrite; SI.hStdError := hWrite; SI.wShowWindow := SW_HIDE; Cmd := 'cmd.exe /C ' + Command; if not CreateProcess(nil, PChar(Cmd), nil, nil, True, 0, nil, nil, SI, PI) then begin Exit; end; CloseHandle(hWrite); try while True do begin if not ReadFile(hRead, Buffer, SizeOf(Buffer) - 1, BytesRead, nil) or (BytesRead = 0) then begin break; end; Buffer[BytesRead] := #0; FullOutput := FullOutput + AnsiString(Buffer); end; WaitForSingleObject(PI.hProcess, INFINITE); GetExitCodeProcess(PI.hProcess, Cardinal(Result)); finally CloseHandle(PI.hProcess); CloseHandle(PI.hThread); end; finally CloseHandle(hRead); end; Output.Text := string(FullOutput); end; function RemoteOriginExists: boolean; var Output: TStringList; begin Output := TStringList.Create; try Result := ExecuteCommand('git remote get-url origin > NUL 2>&1', Output) = 0; finally Output.Free; end; end; function BranchExists(const ParaBranchName: string; ParaRemoteExists: boolean): boolean; var vOutput: TStringList; begin Result := False; vOutput := TStringList.Create; try if ExecuteCommand('git show-ref --verify "refs/heads/' + ParaBranchName + '"', vOutput) = 0 then begin Result := True; Exit; end; if ParaRemoteExists then begin vOutput.Clear; if ExecuteCommand('git show-ref --verify "refs/remotes/origin/' + ParaBranchName + '"', vOutput) = 0 then begin Result := True; end; end; finally vOutput.Free; end; end; function HasTag(const ParaTagName: string; ParaRemoteExists: boolean): boolean; var vOutput: TStringList; begin Result := False; vOutput := TStringList.Create; try if ExecuteCommand('git show-ref --verify "refs/tags/' + ParaTagName + '"', vOutput) = 0 then begin Result := True; Exit; end; if ParaRemoteExists then begin vOutput.Clear; if ExecuteCommand('git ls-remote --tags origin "refs/tags/' + ParaTagName + '"', vOutput) = 0 then begin Result := vOutput.Text <> ''; end; end; finally vOutput.Free; end; end; procedure DeleteTagIfExists(const ParaTagName: string; ParaRemoteExists: boolean); var vOutput: TStringList; begin vOutput := TStringList.Create; try if ExecuteCommand('git show-ref --verify "refs/tags/' + ParaTagName + '"', vOutput) = 0 then begin Writeln('Removing existing local tag: ' + ParaTagName + '...'); vOutput.Clear; if ExecuteCommand('git tag -d "' + ParaTagName + '"', vOutput) <> 0 then begin Writeln('Warning: Failed to delete local tag ' + ParaTagName + '.'); end; end; if ParaRemoteExists then begin vOutput.Clear; if ExecuteCommand('git ls-remote --tags origin "refs/tags/' + ParaTagName + '"', vOutput) = 0 then begin if vOutput.Text <> '' then begin Writeln('Removing existing remote tag: ' + ParaTagName + '...'); vOutput.Clear; if ExecuteCommand('git push origin --delete "' + ParaTagName + '"', vOutput) <> 0 then begin Writeln('Warning: Failed to delete remote tag ' + ParaTagName + '.'); end; end; end; end; finally vOutput.Free; end; end; var vBranchName: string; vHasTag: boolean; vOutput: TStringList; vRemoteExists: Boolean; begin try if ParamCount <> 1 then begin Writeln('Usage: git-set-revive <branchname>'); Writeln('Example: git-set-revive SkybuckContribution005-BugfixRethink'); ExitCode := 1; Exit; end; vBranchName := ParamStr(1); vRemoteExists := RemoteOriginExists; if not BranchExists(vBranchName, vRemoteExists) then begin Writeln('Error: Branch ''' + vBranchName + ''' not found locally or remotely.'); ExitCode := 1; Exit; end; vHasTag := HasTag('merged/' + vBranchName, vRemoteExists) or HasTag('rejected/' + vBranchName, vRemoteExists); if not vHasTag then begin Writeln('Error: Branch ''' + vBranchName + ''' is not marked as merged or rejected.'); Writeln('If it''s active, run: git-set-active ' + vBranchName); ExitCode := 1; Exit; end; Writeln('Attempting to revive branch ''' + vBranchName + '''...'); DeleteTagIfExists('merged/' + vBranchName, vRemoteExists); DeleteTagIfExists('rejected/' + vBranchName, vRemoteExists); Writeln('---'); Writeln('Calling git-set-active to apply active tag...'); vOutput := TStringList.Create; try if ExecuteCommand('cmd.exe /c "' + ExtractFilePath(ParamStr(0)) + 'git-set-active.exe" ' + vBranchName, vOutput) <> 0 then begin Writeln(vOutput.Text); Writeln('Error: git-set-active failed. Try running manually: git-set-active ' + vBranchName); ExitCode := 1; Exit; end; Writeln(vOutput.Text); finally vOutput.Free; end; Writeln(''); Writeln('Branch ' + vBranchName + ' successfully REVIVED and marked as ACTIVE.'); Writeln('This does not rebase history onto master.'); Writeln('To switch to it: git checkout ' + vBranchName); except on E: Exception do begin Writeln(E.ClassName, ': ', E.Message); ExitCode := 1; end; end; end. Save program 7 as "git-the-future.dpr": program git_the_future; { Skybuck's GitFlow version 0.08 created on 29 august 2025 by Skybuck Flying and Gemini (AI) and Co-Pilot (AI). credits: Almost all code by Google Gemini 2.5 Pro. GetBranchVersionDigits code by Microsoft Co-Pilot. Software Idea and Prompting and Overwatching the AI: Skybuck Flying. improvements for version 0.08: + local git support + better contribution number Delphi code developed for Delphi 12.3 and Windows 11. } {$APPTYPE CONSOLE} uses System.SysUtils, System.Classes, System.IOUtils, Winapi.Windows; function ExecuteCommand(const Command: string; out Output: TStringList; PassThrough: Boolean = False): Integer; var SA: TSecurityAttributes; SI: TStartupInfo; PI: TProcessInformation; hRead, hWrite: THandle; Buffer: array[0..1023] of AnsiChar; BytesRead: DWord; Cmd: string; FullOutput: AnsiString; StdOut, StdErr: THandle; begin Output := TStringList.Create; Result := -1; FullOutput := ''; SA.nLength := SizeOf(TSecurityAttributes); SA.bInheritHandle := True; SA.lpSecurityDescriptor := nil; if not CreatePipe(hRead, hWrite, @SA, 0) then begin Exit; end; try FillChar(SI, SizeOf(TStartupInfo), 0); SI.cb := SizeOf(TStartupInfo); if PassThrough then begin StdOut := GetStdHandle(STD_OUTPUT_HANDLE); StdErr := GetStdHandle(STD_ERROR_HANDLE); SI.dwFlags := STARTF_USESTDHANDLES; SI.hStdInput := GetStdHandle(STD_INPUT_HANDLE); SI.hStdOutput := StdOut; SI.hStdError := StdErr; end else begin SI.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW; SI.hStdInput := GetStdHandle(STD_INPUT_HANDLE); SI.hStdOutput := hWrite; SI.hStdError := hWrite; SI.wShowWindow := SW_HIDE; end; Cmd := 'cmd.exe /C ' + Command; if not CreateProcess(nil, PChar(Cmd), nil, nil, True, 0, nil, nil, SI, PI) then begin Exit; end; if not PassThrough then begin CloseHandle(hWrite); end; try if not PassThrough then begin while True do begin if not ReadFile(hRead, Buffer, SizeOf(Buffer) - 1, BytesRead, nil) or (BytesRead = 0) then begin break; end; Buffer[BytesRead] := #0; FullOutput := FullOutput + AnsiString(Buffer); end; end; WaitForSingleObject(PI.hProcess, INFINITE); GetExitCodeProcess(PI.hProcess, Cardinal(Result)); finally CloseHandle(PI.hProcess); CloseHandle(PI.hThread); end; finally if not PassThrough then begin CloseHandle(hRead); end; end; Output.Text := string(FullOutput); end; function RemoteOriginExists: boolean; var Output: TStringList; begin Output := TStringList.Create; try Result := ExecuteCommand('git remote get-url origin > NUL 2>&1', Output) = 0; finally Output.Free; end; end; function GetCurrentBranch: string; var vOutput: TStringList; begin Result := ''; vOutput := TStringList.Create; try if ExecuteCommand('git rev-parse --abbrev-ref HEAD', vOutput) = 0 then begin Result := Trim(vOutput.Text); end; finally vOutput.Free; end; end; var vCurrentBranch: string; vRebaseStatus: Integer; vOutput: TStringList; vRemoteExists: Boolean; begin try vCurrentBranch := GetCurrentBranch; if (vCurrentBranch = '') or (vCurrentBranch = 'HEAD') then begin Writeln('Error: You are not on a branch (detached HEAD). Checkout a branch first.'); ExitCode := 1; Exit; end; if vCurrentBranch.ToLower = 'master' then begin Writeln('Error: You''re on ''master''. This command is meant for feature branches.'); ExitCode := 1; Exit; end; Writeln('Preparing to rebase branch ''' + vCurrentBranch + ''' onto latest ''master''...'); vOutput := TStringList.Create; try vRemoteExists := RemoteOriginExists; Writeln('Updating ''master''...'); if ExecuteCommand('git checkout master', vOutput) <> 0 then begin Writeln('Error: Could not checkout master.'); ExitCode := 1; Exit; end; vOutput.Clear; if vRemoteExists then begin if ExecuteCommand('git pull origin master', vOutput) <> 0 then begin Writeln('Warning: Could not pull from origin master. Continuing with local master.'); end; vOutput.Clear; end; if ExecuteCommand('git checkout "' + vCurrentBranch + '"', vOutput) <> 0 then begin Writeln('Error: Could not checkout back to ''' + vCurrentBranch + '''.'); ExitCode := 1; Exit; end; vOutput.Clear; Writeln(''); Writeln('Starting rebase of ''' + vCurrentBranch + ''' onto ''master''...'); Writeln('----------------------------------------'); vRebaseStatus := ExecuteCommand('git rebase master', vOutput, True); if vRebaseStatus = 0 then begin Writeln('----------------------------------------'); Writeln('Rebase completed successfully!'); Writeln('Your branch ''' + vCurrentBranch + ''' is now on top of master.'); if vRemoteExists then begin Writeln('To update remote:'); Writeln(' git push --force-with-lease origin ' + vCurrentBranch); end; end else if vRebaseStatus = 1 then begin Writeln('----------------------------------------'); Writeln('Rebase paused due to conflicts.'); Writeln('Resolve conflicts manually, then run:'); Writeln(' git add .'); Writeln(' git rebase --continue'); Writeln('Or to abort:'); Writeln(' git rebase --abort'); ExitCode := 1; end else begin Writeln('----------------------------------------'); Writeln('Rebase failed with unexpected exit code: ' + IntToStr(vRebaseStatus)); ExitCode := 1; end; finally vOutput.Free; end; except on E: Exception do begin Writeln(E.ClassName, ': ', E.Message); ExitCode := 1; end; end; end. Testing: git-new-contribution has been tested and works ok. git-set-active.exe is used by git-new-contribution seems to work ok. The rest of the programs still need to be tested more rigorously/better, for now posting this update so it's more workable and testable (locally). Bye for now, Skybuck Flying.