2011-10-26 17 views
11

Rozważmy następujący "historię":W jaki sposób katalog roboczy jest aktualizowany w "git checkout"?

$ mkdir my_project 
$ cd my_project 
$ git init 
Initialized empty Git repository in /home/misha/misha/my_project/.git/ 

$ echo "first line" > hello.txt 
$ git add hello.txt 
$ git commit -m "first commit" 
[master (root-commit) 9c913a1] first commit 
1 files changed, 1 insertions(+), 0 deletions(-) 
create mode 100644 hello.txt 

$ git branch new_feature 
$ git checkout new_feature 
Switched to branch 'new_feature' 
$ echo "second line" >> hello.txt 
$ cat hello.txt 
first line 
second line 

$ git checkout master 
M hello.txt 
Switched to branch 'master' 
$ cat hello.txt 
first line 
second line 

Dlaczego hello.txt ma dwie linie na oddział mistrza? (Myślałem, że git checkout przywróci katalog roboczy do poprzedniego stanu, tj. hello.txt będzie miał tylko jedną linię.)

Co tak naprawdę dzieje się za kulisami w katalogu roboczym pod numerem git checkout? Jak jest aktualizowany?

Odpowiedz

15

Twoje zamówienie git na master zapobiega utracie niezatwierdzonych zmian. To dlatego wciąż masz drugą linię w swoim pliku hello.txt. Jeśli naprawdę chcesz stracić niezatwierdzone zmiany, musisz użyć parametru -f.

Wreszcie Twój kasa będzie wyglądać następująco:

git checkout -f master 
+2

Wygląda na to, że git domyślnie łączy bieżący katalog roboczy z nowym odgałęzieniem (_master_ w moim przypadku): http://www.gitguys.com/topics/switching-branches- bez -zakresu: –

+0

To samo zachowanie, jeśli plik został dodany do indeks, ale nie został zatwierdzony. –

+0

Myślę, że oddziały przechowują tylko zatwierdzenia, a nie zmiany. Po przełączeniu do gałęzi i wykonaniu pracy, musisz zatwierdzić te zmiany przed przejściem do innej gałęzi, lub te zmiany nie będą powiązane z tą gałęzią. Innym sposobem obsługi gałęzi jest sklonowanie repozytorium do nowego katalogu. Następnie możesz pracować na dwóch gałęziach w dwóch różnych katalogach bez konieczności zatwierdzania, dopóki nie będziesz gotowy. Ułatwia to unikanie błędów. –

2

Git checkout (luźno) zaktualizuje kopię roboczą wraz z zawartością repozytorium przy zatwierdzeniu, które określa. Twój oddział new_feature nie ma drugiego wiersza, który został dodany do pliku (ponieważ nie został jeszcze zatwierdzony). W tej chwili ta dodatkowa linia to po prostu nieskrępowana zmiana w twojej kopii roboczej i zostanie dodana do oddziału, w którym ją zatwierdziłeś.

+2

Jeśli 'git checkout' aktualizuje katalog roboczy z zawartością repozytorium Pod popełnić który podany przeze mnie (_master_ w moim przypadku), a tam jest tylko jedną linię w 'hello.txt' w gałęzi _master_, a następnie' git checkout master' oczekiwałbym, że 'hello.txt' w katalogu roboczym będzie miał tylko jedną linię (dokładnie tak, jak w gałęzi _master_). Czego tu mi brakuje? –

+0

Fakt, że masz lokalne niezatwierdzone zmiany w swoim katalogu roboczym. Jeśli kasie nadpisze te zmiany, git ostrzeże Cię i odmawia zmiany gałęzi. –

+1

Jeśli te zmiany nie są w konflikcie z wzorcem, git po prostu przeniesie te zmiany do katalogu roboczego mistrza (ale pozwoli ci przełączać gałęzie). Właśnie tego doświadcza OP. Jeśli te zmiany były w konflikcie z mistrzem, to nie pozwoliłoby ci się przełączyć. Wreszcie, jeśli katalog roboczy jest czysty przy kasie, zaktualizuje katalog roboczy do mastera. Ta odpowiedź pozostawia zbyt wiele informacji, aby była poprawna. Ponadto, ponieważ OP stwierdził już, że katalog roboczy NIE jest czysty, ta odpowiedź nie rozwiązuje tego scenariusza. – Despertar