2012-04-26 11 views
8

Chciałbym zrozumieć, co Git faktycznie przechowuje podczas przenoszenia plików do stanu "przemieszczania".W jaki sposób obszar przechowywania git zapisuje pliki?

Rozważmy następującą sekwencję:

nowy plik zostanie dodany i zobowiązała się do lokalnego repozytorium:

touch file.txt 
git add file.txt 
git commit 

dokonać zmian w pliku:

echo text1 > file.txt 
git add file.txt 

I wtedy edytuj plik ponownie, zanim go popełnisz:

echo text2 > file.txt 

status git pokazuje:

# On branch master 
# Changes to be committed: 
# (use "git reset HEAD <file>..." to unstage) 
# 
#  modified: file.txt 
# 
# Changed but not updated: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
#  modified: file.txt 
# 

I wtedy popełnić plik:

git commit file.txt 

Jak jest git stanie obsłużyć wystawiając nową, drugą aktualizację do plik.txt bez powiedział? Wyjście "status" wygląda tak, jakby próbowało sprawdzić pierwszą wersję, ale wstrzymaj zmiany nieobjęte postepem bez ich sprawdzania.

Czy jest w tym przypadku domniemany etap?

Odpowiedz

7

Pomyśl o Git jako dwóch rzeczach - commitach (migawkach plików) i etykietach (gałęziach, między innymi).

Git faktycznie tworzy zatwierdzenie, gdy git add, a nie po git commit. Tak więc po wykonaniu git add zmienionego pliku, utworzono zatwierdzenie z tymi zmianami i przypisano etykietę "przemieszczania" do tego konkretnego zatwierdzenia.

Kiedy zmienił plik ponownie przed wykonaniem git commit, to teraz ma „wystawił popełnić” (który nie miał git commit wykonywane na nim jeszcze), a nowe zmiany w pliku, który został ani dodanej ani popełnione. W ten sposób git status może pokazać ci oba.

Kiedy jesteś git commit, faktycznie przesuwasz swoją bieżącą etykietę oddziału do tego konkretnego zatwierdzenia (i usuwasz etykietę "postoju"), więc zatwierdzenie nie jest już oznaczone jako "przemieszczanie", ale "master" (lub jakakolwiek gałąź, którą obecnie jest włączony).

+0

Zachowanie, które obserwuję po uruchomieniu testu opisanego powyżej, polega na tym, że przesyła on również niezarejestrowaną zawartość pliku ("text2") do repozytorium. Czy ta interpretacja jest poprawna? Sądzę, że przesłałby "zainscenizowaną" wersję pliku ("text1"). Potwierdzam, że to jest to, co jest w repot, robiąc "git checkout file.txt". –

+1

Po prostu wykonałem test, ale nie otrzymałem wyników. 'mkdir gittest'' cd gittest' 'git init'' echo tekst 1> test.txt' 'git add.' 'git commit -m 'Początkowy commit''' echo text 2> test.txt' 'git add .' 'echo text 3> test.txt' W tym momencie istnieje zmiana etapowa (" tekst 2 ") i zmiana nieskasowana (" tekst 3 "). Teraz 'git checkout test.txt' i' cat test.txt'. Dostaję "tekst 2".Lokalna zmiana została odrzucona ze zmianą etapową. – redhotvengeance

+0

Otrzymuję te same wyniki co twoja sekwencja testowa. Ale jeśli zrobię "zatwierdzenie git" po kroku "echo text 3> test.txt" (podobnie jak moje kroki w oryginalnym wpisie), wtedy obserwuję gita, w którym implicite inscenizuje się treść "tekstu 3" i przesyła ją do repo. Dla jasności, następująca tu sekwencja to: 'mkdir gittest'' cd gittest' 'git init'' echo text 1> test.txt'' git add. '' Git commit -m 'Initial commit'' 'echo text 2 > test.txt' 'git add .'' echo text 3> test.txt' 'git commit -m 'new''' git checkout test.txt' 'cat test.txt', czego wynikiem jest wynik" text 3 ". –

4

git commit <somefiles> jest odpowiednikiem git add <somefiles>, po której następuje git commit. Jeśli po prostu wykonasz git commit, git pokaże wszystkie zmiany etapowe, ale nie wprowadzi zmian wprowadzonych od ostatniego wystawienia danego pliku.

Powiązane problemy