Parę pytań do znawców o branche i initial commity w gicie

Kacper Kornet draenog at pld-linux.org
Mon Apr 1 21:18:08 CEST 2013


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


More information about the pld-devel-pl mailing list