Thread (14 messages) 14 messages, 2 authors, 2025-09-05

Was "Re: [RFC] Proposed Git Workflow for Permanent History, Explicit Branch Status, and Developer Continuity" now "Skybuck's GitFlow"

From: Skybuck Flying <hidden>
Date: 2025-08-29 19:42:53

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.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help