🔒 TouchQuill jest w fazie zamkniętych testów.Chcesz go wypróbować? Napisz do nas →

Jak myśleć o TouchQuill

Zanim wpiszesz pierwszą komendę, warto złapać trzy idee, na których stoi cały system. Reszta dokumentacji będzie się do nich odwoływać.

1. Treść ma adres, nie nazwę

Każdy plik, drzewo katalogów i commit jest przechowywany pod adresem wyliczonym z jego zawartości (hash BLAKE3). Konsekwencje są praktyczne: identyczna tekstura w dwóch miejscach zajmuje miejsce raz; serwer wysyła tylko obiekty, których naprawdę nie masz; a jeśli cokolwiek przekłamie się w transferze, klient to wykryje, bo hash się nie zgodzi. Nie musisz w to wierzyć na słowo, możesz to policzyć.

2. Binariów się nie merguje, bierze się je na wyłączność

Tekstury, meshe i blueprinty nie mają sensownego merge'a. Zamiast udawać, że mają, TouchQuill wbudowuje lock w sam rdzeń: kto trzyma lock, ten commituje; serwer odrzuci push zmiany w zablokowanym pliku od kogokolwiek innego. Kolejka sprawia, że „czekanie na plik” nie wymaga pisania na Slacku.

3. Zmiana jest ważniejsza niż commit

Commit to techniczny zapis; logiczna zmiana (Change ID, ch-…) żyje dłużej: przetrwa poprawki (amend), zmianę opisu i rebase. Dzięki temu review, locki i historia odwołują się do czegoś stabilnego. Do tego dochodzi dziennik operacji: prawie wszystko da się cofnąć przez tq undo, łącznie z odzyskaniem niezapisanej pracy po omyłkowym restore.

Instalacja i pierwszy commit

Klient to jedna binarka tq (Linux, Windows, macOS). Serwer, tq-server, potrzebny dopiero, gdy chcesz współdzielić pracę.

# Linux: paczka rpm · Windows: instalator · albo build ze źródeł:
cargo build --release -p tq-cli
tq init MojaGra
echo "asset" > Content/hero.txt
tq commit -m "pierwszy asset"
tq log        # ch-4f2a91  rev:1  pierwszy asset  (ty)
tq status     # co się zmieniło od ostatniego commitu

Pomyłka? Nic straconego:

tq restore    # wróć do stanu z ostatniego commitu
tq undo       # ...a jeśli restore był pomyłką, odzyskaj to, co nadpisał
To nie jest zwykły „undo z edytora”: TouchQuill przed każdą operacją zapisuje stan roboczy do magazynu, więc undo potrafi przywrócić nawet niezacommitowane pliki.

Praca z zespołem

tq clone https://vcs.studio.com MojaGra    # świeży klon
tq login --user ola                          # pyta o hasło (ustawia je admin)
tq push
tq pull

Logujesz się po ludzku: nazwą użytkownika i hasłem. Pod spodem serwer wymienia hasło na token sesyjny, którego nigdy nie oglądasz; jawne tokeny (tq login tqt_…) zostają dla CI i skryptów. Tożsamość na serwerze wynika z logowania, nie z tego, co zadeklaruje klient. Dlatego w historii i audycie nie da się podszyć pod kolegę. Push jest zawsze fast-forward: jeśli ktoś Cię wyprzedził, najpierw pull.

Wolisz klikać? TouchQuill Studio, graficzny klient (Windows/Linux/macOS), prowadzi przez to samo kreatorem: adres serwera → login i hasło → wybór projektu → pobranie kopii roboczej z paskiem postępu. Do tego widok zmian, historii, locków, konfliktów i Lens. A jeśli żyjesz w edytorze, jest też rozszerzenie do VS Code (status, locki, commit i historia Lens wprost z okna kodu).

Artyści: wszystko klikasz w Studio

Artysta nie musi znać ani jednej komendy. Cała codzienna praca to trzy kliknięcia w aplikacji Studio, a wszystko, co poniżej dzieje się „pod spodem”, robi się samo.

1. Sync

Otwierasz Studio i klikasz Sync. Pobiera najnowszy stan projektu od zespołu. Jeśli studio pilnuje buildów, jednym przełącznikiem bierzesz zamiast najnowszej ostatnią stabilną wersję, taką, która na pewno się otworzy w edytorze.

2. Bierzesz plik do edycji

Zanim ruszysz plik, zaznaczasz go i klikasz Zarezerwuj. Od tej chwili jest tylko Twój, nikt Ci go nie nadpisze. Jeśli ktoś już go trzyma, widzisz kto i jednym kliknięciem wchodzisz do kolejki, a Studio powiadomi Cię, gdy plik się zwolni.

3. Wyślij zmiany

Skończone? Wpisujesz krótki opis i klikasz Wyślij. Studio zapisuje zmianę, wysyła ją na serwer i zwalnia rezerwację, wszystko w jednym ruchu. Następna osoba z kolejki dostaje plik automatycznie.

Przerwa w połowie roboty? Niedokończoną zmianę odkładasz przyciskiem Odłóż na później, bez zaśmiecania historii, i wracasz do niej kiedy chcesz. Wszystkie te kliknięcia to pod spodem te same operacje, które programista robi komendami tq (patrz niżej), tyle że artysta nie musi ich w ogóle widzieć.

Programiści

Osobny channel na zadanie

Task channel dziedziczy stan z main, ale Twoje commity nie ruszają nikogo, dopóki nie skończysz.

tq channel create task/GROM-447 --type task
tq channel switch task/GROM-447

Commituj swobodnie, poprawiaj śmiało

amend dokleja poprawkę do ostatniego commitu, reword zmienia opis. Change ID zostaje ten sam, więc nic się nie gubi.

tq commit -m "system dodge"
tq amend                    # poprawka do tej samej zmiany

Bądź na bieżąco z main

integrate wciąga zmiany z parenta. Konflikt? Nie zatrzyma Cię, zostanie zapisany, a Ty decydujesz kiedy i jak go rozwiązać.

tq integrate
tq conflicts                # co wisi do rozwiązania
tq conflict resolve cfl-a1 --take theirs

Zamknij zadanie

complete scala channel do parenta i go zamyka. Historia zadania zostaje czytelna.

tq complete

Kierownicy: release i porządek

Release channel z ostrą polityką

Na release nie wchodzą commity z nierozwiązanymi konfliktami, a pushować może tylko wskazany krąg. Polityka mieszka w wersjonowanym pliku. Jej zmiana też przechodzi przez historię.

tq channel create release/1.0 --type release
# tq-channel.toml:
[permissions]
write = ["lead", "server-admin"]
integrate = ["lead"]

Spory o locki

Ktoś zostawił lock i pojechał na urlop? Poproś o oddanie, a w razie potrzeby przejmij. Każde takie działanie zostaje w dzienniku audytu, z powodem.

tq lock --request Content/Boss.uasset
tq steal Content/Boss.uasset     # wymaga uprawnienia lock.steal

Review przed domknięciem

Channel może wymagać zatwierdzeń, zanim complete przejdzie. Recenzenci komentują i dają approve/reject, z CLI albo w panelu WWW. Approve wiąże się z konkretnym stanem: nowy push unieważnia stare zatwierdzenia, żeby nikt nie przepchnął zmian po cichu.

# tq-channel.toml:
[review]
require-approvals = 2
# recenzent:
tq review approve
tq review comment "popraw nazwę zmiennej" --path Combat.cpp --line 42

Konflikty pod kontrolą

Konflikty można przypisywać osobom i nadawać im terminy. Nierozwiązane po terminie eskalują. Nic nie ginie w szumie.

tq conflict assign cfl-a1 marta
tq conflict defer cfl-b2 --deadline 48h

Kto co zrobił

Dziennik audytu rejestruje działania administracyjne i próby przekroczenia uprawnień. Integralność sprawdzisz jedną komendą.

tq-server audit log --denied
tq-server audit verify

CI i buildy

Konto tylko do tego, co trzeba

CI dostaje token PAT ograniczony do konkretnych uprawnień. Nawet jeśli wycieknie, nie zrobi nic ponad swój zakres.

tq-server user pat ci-build --user ci --scopes repo.read,build-flag.set

Buduj i oznaczaj

Po udanym buildzie CI ustawia flagę na rewizji. To jest sygnał „ta wersja działa”.

tq build-flag set --rev rev:128 --flag ci --state ok

Zespół bierze stabilne

Artysta nie musi trafić na zepsuty commit programisty: get stable pobiera ostatnią rewizję ze wszystkimi wymaganymi flagami na zielono.

tq get stable

Channele

Channel to linia pracy, odpowiednik brancha, ale z typem i polityką. Typ niesie sensowne domyślne zachowania: na release nie wejdzie commit z konfliktem, task ma właściciela i cykl życia (create → integrate → complete), personal to Twoja piaskownica.

Wart poznania jest channel wirtualny: widok na wycinek repo. Zespół grafików może dostać samo Content/, kod dla nich „nie istnieje”, ale ich commity trafiają do wspólnej historii, z zachowaniem plików, których nie widzą.

tq channel create widok --type virtual --include "Content/..." --exclude "Source/..."

Do pracy na wycinku dużego repo służy też sparse checkout: pobierasz i materializujesz tylko pasujące ścieżki, a reszta nie schodzi w ogóle na dysk. Artysta postaci nie musi ściągać wszystkich map.

tq clone https://vcs.studio.com Gra --sparse "Content/Characters/...,Content/Shared/..."
tq sparse set "Content/Characters/..."   # zawęź/poszerz w istniejącym klonie

Locki

Model jest prosty: jeden właściciel, reszta w kolejce. Lock ma timeout bezczynności (domyślnie 4 h). Jak zapomnisz zwolnić i pójdziesz do domu, system nie zablokuje zespołu na noc. Możesz poprosić właściciela o oddanie (--request) albo przekazać lock konkretnej osobie (--give).

Serwer egzekwuje locki przy push: jeśli polityka channela mówi, że *.uasset wymaga locka, push zmiany bez locka zostanie odrzucony z czytelnym komunikatem. Praca offline też jest przewidziana: deklarujesz lock lokalnie, a po powrocie system synchronizuje; jeśli dwie osoby wzięły ten sam plik offline, powstaje spór, który blokuje obie strony do decyzji leada. Nikt nikomu cicho nie nadpisze pracy.

Konflikty

W większości systemów konflikt to ściana: merge staje, a Ty rzucasz wszystko, żeby go rozbroić. W TouchQuill konflikt to zapisany obiekt (cfl-…) z pełnym kontekstem: obie wersje, wspólny przodek, kto i kiedy. Integracja przechodzi zawsze; konflikty rozwiązujesz, kiedy masz na to przestrzeń, albo deleguje je lead.

tq conflict resolve cfl-a1 --take theirs   # przyjmij ich wersję
tq conflict resolve cfl-a1 --merge         # scal pluginem (jeśli format ma differ)

Change ID

Hash commitu zmienia się przy każdej poprawce, Change ID nie. To rozróżnienie brzmi subtelnie, ale w praktyce oznacza, że komentarz z review „popraw to w ch-4f2a91” pozostaje trafny po Twoim amend i rebase. Historia operacji (tq op log) dopełnia obraz: każda operacja zostawia ślad i większość da się cofnąć.

Lens

Klasyczny blame odpowiada na pytanie „kto zmienił linijkę 40 w pliku X”. Lens odpowiada na pytanie, które naprawdę zadajesz: „co się działo z tą funkcją?”, także wtedy, gdy plik zmieniał nazwę, a funkcja wędrowała między modułami. Obejmuje to też Blueprinty Unreala (funkcje, eventy i makra z plików .uasset). Zmiany czysto kosmetyczne (formatowanie, komentarze) nie zaśmiecają wyniku.

tq lens blame --symbol calculate_damage
CREATED       ch-6f9  rev:1   krzysztof  „pierwsza wersja”
MODIFIED      ch-a12  rev:3   marta      „buff obrażeń”
MOVED+RENAMED ch-c73  rev:5   krzysztof  (compute_damage z Weapon.rs)  [~86%]

Symbole wyciąga prawdziwy parser (tree-sitter) dla C++, C#, C, Rust, Pythona, Lua, Go, Javy, JS/TS, z metodami klas i nazwą kwalifikowaną (Enemy::TakeDamage), plus ekstraktor zapasowy dla Verse (UEFN), GDScriptu i shaderów. Dla formatów binarnych jest mechanizm wtyczek (host WASM), a obsługa Blueprintów jest w planach rozwoju. Dopasowanie jest rozmyte: rename razem z edycją ciała dostaje ocenę pewności ([~86%]), a przenosiny rozjechane na kilka commitów w ciągu tygodnia zszywają się w jedną historię. Kiedy heurystyka się waha, oznacza wynik jako niejednoznaczny. Rozstrzygasz sam przez tq lens link, albo w Studio jednym kliknięciem. tq lens trace pokazuje pełny żywot bytu przez wszystkie nazwy. Pełny opis Lens: języki, dopasowanie i granice →

Lens w edytorze. Rozszerzenie VS Code pokazuje CodeLens „Lens: nazwa" nad każdą funkcją i klasą. Klik otwiera jej historię. To samo z menu kontekstowego na symbolu pod kursorem. Napędza to tq lens blame --json. W planach rozwoju: Lens dla Blueprintów (symbole w grafach i plikach .uasset) oraz wtyczki do pełnego Visual Studio i JetBrains Rider.

Dobre praktyki

Kilka nawyków, które w praktyce robią największą różnicę:

Migracja z Git i Perforce

Obie migracje zachowują historię: autorów, czasy, wiadomości. Change ID są wyliczane deterministycznie ze źródła, a Lens działa na zaimportowanej historii od pierwszego dnia. Sensowna kolejność: zmigruj kopię repo, zweryfikuj, przełącz zespół, a stare repo zostaw w trybie tylko-do-odczytu na okres przejściowy.

tq migrate from-git --repo /sciezka/repo --branch main
tq migrate from-p4  --port perforce:1666 --user krzysztof --path //depot/...
tq migrate verify   --repo /sciezka/repo

Przejście dużego studia nie musi być skokiem na raz. Po pierwszym imporcie tq migrate p4-sync dociąga wyłącznie nowe changelisty z Perforce. Na czas migracji P4 zostaje źródłem prawdy, a TouchQuill go mirroruje.

Serwer i uprawnienia

Serwer wystawia gRPC (klienci), REST (integracje) i SSE (live feed zdarzeń). Uwierzytelnianie włącza się z pierwszym dodanym użytkownikiem. Wcześniej działa tryb otwarty, wygodny na testy.

tq-server --data /var/tq --listen 0.0.0.0:7470 --tls-cert cert.pem --tls-key key.pem
tq-server user add krzysztof --role developer
Panel administracyjny w przeglądarce, odpowiednik P4Admin, wbudowany w serwer: http://serwer:7480/admin. Logujesz się hasłem i masz w jednym miejscu użytkowników (dodawanie, role, hasła, PAT-y), przegląd repozytoriów (historię rewizji, channele, locki z kolejkami i konflikty) oraz dziennik audytu z przyciskiem weryfikacji hash-chaina. Jest też przeglądarka repozytorium (drzewo plików dowolnej rewizji, podgląd treści i diff), dostępna dla każdego z prawem odczytu, bez klonowania. Te same uprawnienia co w CLI; każda zmiana ląduje w audycie.

Siedem ról wbudowanych (od viewer po server-admin), custom role przez klonowanie z odjęciem uprawnień, ograniczenia ścieżek dla kontraktorów („tylko Content/Weapons/..."), tablica protections w stylu Perforce (reguły per repo × ścieżka, np. „artyści nie zapisują do Content/Code/..."). Reguły odczytu działają też na transferze: plik, którego nie wolno Ci czytać, po prostu nie zejdzie na dysk. PAT-y ze scope'ami dla automatów, override per channel, a przy logowaniu hasłem: polityka złożoności, blokada po serii nieudanych prób i opcjonalne 2FA (TOTP).

Skalę obsługuje się stopniowo, bez przepisywania. Małe studio startuje na jednym pliku (SQLite) i kopii katalogu raz dziennie. Większe przełącza metadane na PostgreSQL (jedną zmienną środowiskową, dane w CAS zostają bez zmian), a zdalne biuro stawia Edge Proxy: read-through cache obiektów w lokalnej sieci. Do tego replikacja na regiony (locki zostają na primary, jedno źródło prawdy), mTLS między serwerami, kopie zapasowe jedną komendą i podpisane cyfrowo wydania.

Referencja komend

KomendaOpis
tq init / clone / setuputwórz / sklonuj / skonfiguruj repo
tq login --user / remotelogowanie hasłem (tokeny dla CI), adres serwera
tq add / edit / status / diffzmiany w worktree
tq commit / amend / rewordzapis rewizji (Change ID stabilny)
tq log / show / cat / restorehistoria i nawigacja
tq rebase / revertprzebazowanie / rewizja-odwrotność
tq op log / undo / redodziennik operacji i cofanie
tq channel …create / switch / list / policy
tq integrate / completeintegracja i domknięcie channela
tq lock / unlock / lockslocki z kolejką, request / give
tq conflict(s) …resolve / assign / defer
tq shelf …odkładanie pracy, udostępnianie, TTL
tq lens blame / trace / symbolshistoria i pełny lineage symbolu
tq lens link / reindex / indexręczne zszycie, przebudowa i domiar indeksu
tq review comment / approve / rejectkomentarze i zatwierdzenia (bramka na complete)
tq sparse set / show / clearpraca na wycinku repo
tq renamezmiana nazwy repozytorium
tq build-flag / get stableflagi buildów i stabilna wersja
tq workspace …save / sync / offline / mount / presence
tq migrate from-git / from-p4 / p4-syncimport historii i inkrementalny mirror z P4
tq fsmonitor start / stop / statusdemon zmian plików (Linux / Windows / macOS)
tq notify …powiadomienia, DND, digest
tq plugin …pluginy WASM: extractor / differ
tq admin obliterate / channeltrwałe usuwanie treści, override uprawnień

Pełną specyfikację techniczną i decyzje architektoniczne (ADR) udostępniamy na życzenie.