On Mon, Apr 01, 2013 at 07:22:42PM +0200, Adam Osuchowski wrote:
Nie do końca rozumiem się jeszcze z tym narzędziem więc mam parę pytań
z prośbą o wyjaśnienie. Zauważyłem w PLDowych repozytoriach, że
w poszczególnych modułach istnieje po kilka initial commitów (bez parenta).
Część z nich jest przypisana do branchy ale niektóre nie. Np. dla coreutils:
$ git rev-list --max-parents=0 --all
9cf1593a28075883f1880131ea15f9c6e046986b
5a006e8adf4446d30b3681b146cdb35f914ef29b
a30b82d494633d30a65fa15f06b33724068ba98e
$ git branch -a --contains 9cf1593a28075883f1880131ea15f9c6e046986b
* master
remotes/origin/DEVEL
remotes/origin/HEAD - origin/master
remotes/origin/RA-branch
remotes/origin/master
$ git branch -a --contains 5a006e8adf4446d30b3681b146cdb35f914ef29b
remotes/origin/AC-branch
$ git branch -a --contains a30b82d494633d30a65fa15f06b33724068ba98e
$
Zastanawiałem się, jak stworzyć takiego commita bez parenta i bez brancha
i udało mi się to zrobić za pomocą git-commit-tree, rzeczywiście nie ma
parenta, jednakże nie jest on pokazywany przez git-rev-list, a git-fsck
znajduje go jako sierotę:
$ git write-tree
d936ff7c9b575ca10f16a26b6ec7ec4087f1dd44
$ git commit-tree -m test d936ff7c9b575ca10f16a26b6ec7ec4087f1dd44
bb2ef6a355614ee670a230264711a2dc53676434
$ git log --format=raw bb2ef6a355614ee670a230264711a2dc53676434 | grep
parent
$ git rev-list --all | grep bb2ef6a355614ee670a230264711a2dc53676434
$ git fsck
Checking object directories: 100% (256/256), done.
Checking objects: 100% (1225/1225), done.
dangling commit bb2ef6a355614ee670a230264711a2dc53676434
$
Mam więc w związku z tym następujące pytania:
1. Czy legalne dla gita jest wiele initial commitów w obrębie jednego brancha?
Tak. Legalny jest każdy DAG. Nie ma żadnego wymagania, że 'root' ma być
tylko jeden (co więcej nie ma też wymagania, że graf ma być spójny). Dla
przykładu są dwa repozytoria rozwijane przez jakiś czas osobno. I w
pewnym momencie ktoś dochodzi do wniosku, że jednak warto je scalić w
jedno. Naturalnie powstaje repozytorium o dwóch korzeniach.
2. Czy legalne dla gita jest istnienie commitów poza branchami?
I tak i nie. Na początku trzeba wprowadzić pojęcie 'ref' czyli tych
commitów pokazywanych przez git show-ref. W PLD należą do nich:
refs/heads/* - commity leżąc na czubkach branchy
refs/remotes/origin/* - commity leżące na czubkach branchy służących do
śledzenia zmian w innym repozytorium (na
serwerze, u innego developera itp.)
refs/tags/* - commity otagowane
refs/notes/* - tak jakby osobne branche służące do dodawania notatek do
istniejących commitów. W PLD używane np. do poprawiania
literówek lub dodania informacji o CVE do commitów już
istniejących na serwerze
Do repozytorium należy każdy commit osiągalny z któregoś z ref. Inne
commity są legalne pod tym względem, że git potrafi na nich operować.
Ale mogą one zniknąć w wyniku wykonania git gc (to jest pewne
uproszczenie, że względu na istnienie jeszcze reflog).
3. Czy taka sytuacja, że jest wiele initial commitów i niektóre nie są
przypisane do żadnego z branchy, a wszystkie pokazywane są przez git-rev-list
jest skutkiem migracji z cvsa (cvs2git zainicjował w taki dziwny sposób
repo) czy można ją uzyskać również normalnie?
W tym wypadku jest to wynik migracji z CVS a konkretnie:
9cf1593a28075883f1880131ea15f9c6e046986b
Pierwszy commit w repozytorium
5a006e8adf4446d30b3681b146cdb35f914ef29b
Ten jest dziwny. Problemem był, że w CVS na gałęzi AC-branch istniał
plik coreutils-jm2gl.patch, którego nie było na gałęzi głównej.
Dodatkowo istniał on na tej gałęzi wcześniej niż inne pliki istniejące
jednocześnie na AC-branch i master. W tym momencie skrypt konwertujący
nie wiedział, w którym momencie odgałęzić AC-branch od master. Sam bym
się spodziewał, że zrobi to po datach. Możliwe, że to wynik jednej z
moich poprawek do cvs2git - rzecz do sprawdzenia.
a30b82d494633d30a65fa15f06b33724068ba98e
Pierwszy commit na refs/notes/commits czyli notatkach rejestrujących
zmiany w commit logach.
4. Dlaczego git-rev-list --all nie pokazuje ręcznie stworzonego commita bez
parenta
Bo nie jest on przodkiem żadnego z commitu pokazywanego przez któreś z
ref.
i co zrobić, żeby pokazywał?
Otagować go lub założyć brancha na nim: git tag sha1 lub git branch
sha1.
5. Czy da się wylistować faktycznie wszystkie commity w repozytorium?
Zależy jak zdefiniujesz wszystkie w repozytorium. Jeżeli jako te,
które należą do grafu to: git rev-list --all. Jeżeli chodz Ci o naprawdę
wszystkie to tutaj jest cos:
http://stackoverflow.com/questions/7348698/git-how-to-list-all-objects-in-the-database
Ale osobiście nie widzę powodu, dla którego generować taką listę.
--
Kacper
___
pld-devel-pl