Dlaczego otrzymuję komunikat „krytyczna: ta operacja musi zostać uruchomiona w drzewie roboczym?”

89

Właśnie zainstalowałem git w systemie Windows. Ustawiłem zmienną GIT_DIR na c: \ git \ i zweryfikowałem, że ta zmienna środowiskowa jest utrzymywana przez cygwin (tj. Echo $ GIT_DIR jest tym, czym powinno być). Poszedłem do folderu, dla którego chciałem utworzyć repozytorium git, powiedzmy c: \ www, a następnie uruchomiłem:

git init
git add .

Wtedy pojawia się błąd:

fatal: This operation must be run in a work tree

Nie jestem pewien, co poszło nie tak, ale katalog c: \ git zawiera plik konfiguracyjny, który mówi:

[core]
    repositoryformatversion = 0
    filemode = false
    bare = true
    symlinks = false
    ignorecase = true

Jestem prawie pewien, że to nie powinno być nagie i to jest nasz problem.

Białeckiego
źródło
1
GIT_DIR to zupełnie inna koncepcja niż CVSROOT!
innaM

Odpowiedzi:

55

Bezpośrednim powodem błędu jest to, że tak, nie można go używać git-addz czystym repozytorium. Surowe repozytorium z definicji nie ma drzewa roboczego. git-addpobiera pliki z drzewa roboczego i dodaje je do indeksu, przygotowując się do zatwierdzenia.

Być może będziesz musiał trochę przemyśleć swoją konfigurację tutaj. GIT_DIR to katalog repozytorium używany dla wszystkich poleceń git. Czy naprawdę próbujesz utworzyć jedno repozytorium dla wszystkiego, co śledzisz, może rzeczy w całym systemie? Repozytorium git z natury śledzi zawartość pojedynczego katalogu. Musisz ustawić GIT_WORK_TREEścieżkę zawierającą wszystko, co chcesz śledzić, a następnie musisz .gitignorezablokować wszystko, czego nie chcesz śledzić.

Może próbujesz stworzyć repozytorium, które będzie tylko śledzić c:\www? Następnie powinieneś go umieścić c:\www(nie ustawiaj GIT_DIR). Jest to normalne użycie git, z repozytorium w katalogu .git katalogu najwyższego poziomu twojego "modułu".

Jeśli nie masz naprawdę dobrego powodu, radzę trzymać się sposobu, w jaki git lubi działać. Jeśli masz kilka rzeczy do śledzenia, prawdopodobnie potrzebujesz kilku repozytoriów!

Cascabel
źródło
10
1. Po prostu śledzimy „Codzienny GIT w 20 poleceniach” i stronę podręcznika git-init (1) autorstwa Linusa T. (która niestety może być nieaktualna?) 2. Twój post tylko sugeruje, co jest nie tak, ale nie daje nam podpowiedź, co z tym zrobić
55
Po prostu git config --unset core.bare.
Matthias Urlichs
Mój problem został rozwiązany przez odpowiedź blj, ale w tym podfolderze, za pomocą git branchpolecenia, mogłem wyświetlić listę gałęzi, ale nie byłem w stanie tego zrobić git checkout -b feature22. Czy to oznacza, że ​​aby wyświetlić listę gałęzi, nie jest potrzebne drzewo robocze, ale aby je sprawdzić?
Kochanie,
206

Ponadto prawdopodobnie znajdujesz się w podfolderze .git, przenieś jeden folder w górę do katalogu głównego projektu.

blj
źródło
7
Najlepsza odpowiedź, jaką widziałem! Powinna być zaakceptowana odpowiedź.
GeertVc
To najlepsza odpowiedź. Jakie kiedykolwiek widziałem. mały problem. małe rozwiązanie. kocham to.
Ariful Islam
2
Czy istnieje sposób, aby ukryć tę wiadomość?
roachsinai
19

Na wypadek, gdyby to, co mi się przydarzyło, dzieje się z kimś innym, muszę powiedzieć:
byłem w swoim .gitkatalogu w moim projekcie, kiedy otrzymywałem ten błąd.
Szukałem i szukałem odpowiedzi, ale nic nie działało.
Wszystko, co musiałem zrobić, to wrócić do właściwego katalogu ( cd .. ).
To była dla mnie chwila z dłonią.
Jeśli jest ktoś tak głupi jak ja, mam nadzieję, że ta odpowiedź okazała się pomocna.

Jacob Zimmerman
źródło
1
Podobne doświadczenie. W moim przypadku używałem GitExtensions (dla Windows) i próbując otworzyć repozytorium, kliknąłem, aby otworzyć plik .git zamiast folderu zawierającego. Na początku wyglądało dobrze, ale pokazał mi błąd drzewa, kiedy zacząłem cokolwiek robić.
grzmot
1
Podoba mi się, że ma to kilkanaście pozytywnych głosów. Cieszę się, że opublikowałem tę odpowiedź, mimo że wydawało się to oczywiste.
Jacob Zimmerman
13

To powinno rozwiązać problem:

git config --unset core.bare
Babajide M. Moibi
źródło
5
Jeśli podasz rozwiązanie. Proszę również wyjaśnić dlaczego.
swój ślad
2
To rozwiązało problem.
bpanulla
1
Pomogło mi. Nie obchodzi mnie dlaczego :)
Jarda Pavlíček
12

Wystarczy sklonować ten sam projekt w innym folderze i skopiuj do .git / folder do projektu.

Przykład

Utwórz folder tymczasowy:

mkdir temp

przejdź do folderu tymczasowego

cd temp/

sklonuj ten sam projekt w folderze tymczasowym :

git clone [-b branchName] git@path_to_your_git_repository

skopiuj folder .git do swojego projektu:

cp -R .git/ path/to/your/project/

przejdź do swojego projektu i uruchom git status

usuwać z temp folder, jeśli są zakończone.

mam nadzieję, że to komuś pomoże

Festus Tamakloe
źródło
1
Uznałem to za przydatne, ale muszę powiedzieć, że wystarczył pierwszy wiersz, aby uświadomić sobie, co było nie tak. Reszta trochę mnie zdezorientowała. W każdym razie bardzo dziękuję :)
randombee
@randombee To zadziałało dla mnie. . . ale dlaczego? Co to robi?
Yatharth Agarwal
8

Jawne ustawienie GIT_DIRzmiennej środowiskowej zmusza git do używania podanego katalogu jako repozytorium git. Nigdy nie jest potrzebny podczas normalnego użytkowania.

W twoim przykładzie, ponieważ określiłeś a GIT_DIRi nie jest on nazwany .git(wiodąca kropka jest ważna) i nie podałeś --work-treeopcji ani nie ustawiłeś GIT_WORK_TREEzmiennej środowiskowej, że chcesz mieć czyste repozytorium, kiedy powiedziałeś git init.

Ponieważ nagie repozytorium nie ma działającego drzewa, duży wybór poleceń nie ma sensu w przypadku czystego repozytorium. git addjest tylko jeden.

Czy jest jakiś szczególny powód, dla którego musisz użyć niestandardowej lokalizacji dla swojego repozytorium git zamiast w .gitpodfolderze w katalogu głównym drzewa roboczego? Chociaż można to zorganizować, zwykle wymaga to więcej pracy i jest bardziej podatne na błędy użytkowników.

CB Bailey
źródło
Ustawienie GIT_WORK_TREE rozwiązało to za mnie. Powodem, dla którego używam GIT_DIR, jest to, że chcę osobnego repozytorium git dla mojej kopii roboczej, w którym mam zadanie w tle, które po prostu dodaje / zatwierdza co kilka minut. Ten proces ustawia GIT_DIR na .gitsave. Moja aktualna praca repozytorium jest w .git. Teraz mam lokalne repozytorium śledzenia na żywo, więc mam wersje wszystkich plików, gdy je zmieniam.
MikeJansen
6

Utwórz czyste repozytorium GIT

Mały rant: git nie jest w stanie samodzielnie utworzyć normalnego czystego repozytorium. Rzeczywiście głupi dupek.

Mówiąc dokładniej, nie jest możliwe klonowanie pustych repozytoriów. Zatem puste repozytorium jest bezużytecznym repozytorium. Rzeczywiście, zwykle tworzysz puste repozytorium i natychmiast je wypełniasz:

git init
git add .

Jednak dodanie git nie jest możliwe podczas tworzenia czystego repozytorium:

git --bare init
git add .

wyświetla błąd „krytyczny: ta operacja musi być wykonana w drzewie roboczym”.

Nie możesz tego sprawdzić:

Initialized empty Git repository in /home/user/myrepos/.git/
fatal: http://repository.example.org/projects/myrepos.git/info/refs not found: did you run git update-server-info on the server?

git --bare init
git update-server-info # this creates the info/refs file
chown -R <user>:<group> . # make sure others can update the repository

Rozwiązaniem jest utworzenie innego repozytorium w innym miejscu, dodanie pliku w tym repozytorium i wypchnięcie go do samego repozytorium.

mkdir temp; cd temp
git init
touch .gitignore
git add .gitignore
git commit -m "Initial commit"
git push (url or path of bare repository) master
cd ..; rm -rf temp

mam nadzieję, że to może ci pomóc

user1329261
źródło
1
To jest po prostu nieprawda. Możesz utworzyć czyste repozytorium i sklonować je. Nawet jeśli to prawda, nadal nie odpowiada na to pytanie. (Np.$ git --bare init bare.git Initialized empty Git repository in /home18/cbailey/gittest8/bare.git/ $ git clone bare.git non-bare Cloning into 'non-bare'... \\ done. \\ warning: You appear to have cloned an empty repository.
CB Bailey,
Przepraszam, jeśli użyję "<>" do spakowania "url lub ścieżki czystego repozytorium", będzie to niewidoczne. a to, co powiedziałem na plusie, jest naprawdę przydatne. Mam test i weryfikację.
user1329261
6

Miałem ten problem, ponieważ .git/configzawierał worktree = D:/git-repositories/OldName. Po prostu zmieniłem to naworktree = D:/git-repositories/NewName

Odkryłem to, ponieważ użyłem git gui , który pokazał bardziej szczegółowy komunikat o błędzie:

Błąd git gui

koppor
źródło
1
Użyłem git bash i otrzymałem wiadomość fatal: this operation must be run in a work tree. Modyfikacja pliku konfiguracyjnego naprawiła to za mnie.
pawellipowczan
4

W moim przypadku byłem w tym samym folderze co plik „.git” dla mojego repozytorium. Musiałem przejść o jeden poziom w górę, rozwiązałem to.

chethan jain
źródło
2

Jeśli nic innego nie działa, sprawdź dokładnie ścieżkę git config core.worktree. Jeśli ta ścieżka nie wskazuje na katalog roboczy, może być konieczne zaktualizowanie go.

Sposób, w jaki otrzymałem ten błąd, polegał na utworzeniu repozytorium Git na dysku sieciowym. Działał dobrze na jednym komputerze, ale zwrócił ten błąd na innym. Okazało się, że miałem dysk zmapowany na literę dysku Windows na komputerze, na którym go utworzyłem, ale nie na innym komputerze, a Git zapisał ścieżkę do drzewa roboczego jako zmapowaną ścieżkę, a nie ścieżkę UNC.

Soren Bjornstad
źródło
1

Jeśli istniejący (nie-czysty) checkout zaczyna wyświetlać ten błąd, sprawdź plik .git / config; jeśli core.bareto prawda, usuń tę linię konfiguracji

ThorSummoner
źródło
0

Jeśli żaden z powyższych zwykłych sposobów nie pomaga, spójrz na ślad wywołania pod tym komunikatem o błędzie ( "fatal: This operation . . .") i znajdź skrypt i linię, które powodują rzeczywisty błąd. Po zlokalizowaniu tego wywołania error () wyłącz je i sprawdź, czy operacja, którą próbujesz, kończy się nawet z niektórymi ostrzeżeniami / komunikatami - na razie je zignoruj. Jeśli tak, w końcu po zakończeniu może wspomnieć o części operacji, która nie została pomyślnie zakończona. Teraz zajmij się tą częścią oddzielnie, jeśli ma to zastosowanie.

W odniesieniu do powyższej logiki do mojego przypadku, otrzymałem ten komunikat o błędzie, "fatal: This operation . . ."gdy próbowałem uzyskać kod Androida-x86 za pomocą repo sync . . .. a śledzenie wywołania pokazane raise GitError("cannot initialize work tree")jako wywołanie error () powodujące powyższy komunikat o błędzie ( "fatal: . . ."). Tak więc, po skomentowaniu tego GitError()w .repo/repo/project.py, repo sync . . .kontynuowałem i ostatecznie wskazałem błąd dla trzech projektów, które nie zostały poprawnie zsynchronizowane. Właśnie usunąłem ich *.gitfoldery z odpowiednich ścieżek w drzewie źródłowym Androida-x86 lokalnie i uruchomiłem repo sync . . .ponownie i zasmakowałem sukcesu!

geekie12
źródło
0

Ten sam problem, który mam, wykonałem następujące kroki,

  1. git init
  2. git add.
  3. git commit -m "inital setup"
  4. git push -f wzorzec pochodzenia

wtedy zaczyna działać.

raghavendra
źródło
0

Edytowano plik konfiguracyjny i zmieniono bare = true na bare = false

Murt Moriarty
źródło
0

Ponadto najwyraźniej ten błąd wystąpi, jeśli sklonujesz na dysk NTFS Ram Drive.

Mendi Barel
źródło