Chcę użyć czegoś podobnego do:
git checkout -- <path>/<file>
ale chcę wyrejestrować plik do wybranego przeze mnie folderu, zamiast nadpisywać lokalny <path>/<file>.
Dowolny pomysł?
Odpowiedzi:
Jak w Czy „eksport git” (np. „Eksport svn”)?
Możesz git checkout-indexdo tego użyć , jest to polecenie niskiego poziomu, jeśli chcesz wyeksportować wszystko, możesz użyć -a,
git checkout-index -a -f --prefix=/destination/path/
Aby zacytować strony podręcznika:
Końcowy znak „/” [na przedrostku] jest ważny. Wyeksportowana nazwa jest dosłownie po prostu poprzedzona określonym ciągiem.
Jeśli chcesz wyeksportować określony katalog, jest kilka sztuczek. Polecenie pobiera tylko pliki, a nie katalogi. Aby zastosować go do katalogów, użyj polecenia „find” i potokuj wyjście do git.
find dirname -print0 | git checkout-index --prefix=/path-to/dest/ -f -z --stdin
Również ze stron podręcznika:
Intuicyjność nie jest tutaj celem. Powtarzalność jest.
GIT_WORK_TREE=../path/to/place git checkout
git worktree(patrz poniżej) imho jest dzisiaj kanoniczną odpowiedzią i można ją tutaj dodać.
Kolejne rozwiązanie, które jest nieco czystsze - wystarczy określić inne drzewo robocze.
Aby sprawdzić wszystko, od HEAD (nie indeksu) do określonego katalogu wyjściowego:
git --work-tree=/path/to/outputdir checkout HEAD -- .
Aby pobrać podkatalog lub plik z HEAD do określonego katalogu:
git --work-tree=/path/to/outputdir checkout HEAD -- subdirname
--work-tree=/home/thomasg/okcopyRaczej niż --work-tree=~/okcopy(prawdopodobnie użycie ścieżki względnej podczas siedzenia w tym samym drzewie git również działa, ale w ten sposób leży szaleństwo i git statuswyjścia w R'lyehian)
git statuswtedy pokazuje wiele modów (prawdopodobnie dlatego, że indeks pasuje teraz do innego katalogu, a nie do nietkniętego normalnego drzewa roboczego). git resetprzywrócił go do dobrego stanu.
git statuspokazuje wiele modów i git resetnie pomaga. Musiałem git checkout -f HEADprzywrócić stan mojego repozytorium.
fatal: This operation must be run in a work tree
git resetwystarczy przywrócić główne drzewo robocze do zdrowia. Aby bezpiecznie eksportować podkatalogi repozytorium w dowolnym SHA1, gałęzi lub tagu bez modyfikowania głównego drzewa roboczego, zobacz niesławne rozwiązanie Charlesa Baileya . Podobnie, aby bezpiecznie płacić za wiele oddziałów w tym samym czasie, nowa podkomenda jest Twoim przyjacielem. git archivegit worktree add
Dla pojedynczego pliku:
git show HEAD:abspath/to/file > file.copy
SHA1 IDktóre można łatwo znaleźć poprzez gitk. Gdybym tylko potrzebował "wyewidencjonować" ten plik do tymczasowej lokalizacji (tj. Nie przywracać), showgit show 82e54378856215ef96c5db1ff1160a741b5dcd70:MyProj/proguard/mapping.txt > myproj_mapping.txt
Jeśli pracujesz w ramach swojej funkcji i nie chcesz wracać do kasy, możesz uruchomić:
cd ./myrepo
git worktree add ../myrepo_master master
git worktree remove ../myrepo_master
Stworzy ../myrepo_masterkatalog z masterzatwierdzeniami gałęzi, w którym możesz kontynuować pracę
git --work-tree=/path/to/outputdir checkout HEAD -- .tego nie robi nic z indeksem, po prostu kopiuje wybraną gałąź do określonej lokalizacji (z dodatkiem pliku .git).
myrepo_masterkatalog
git worktree remove ../myrepo_master
Powyższe rozwiązania nie zadziałały, ponieważ musiałem sprawdzić konkretną otagowaną wersję drzewa. Nawiasem cvs exportmówiąc , tak ma być używany. git checkout-indexnie przyjmuje argumentu znacznika, ponieważ pobiera pliki z indeksu. git checkout <tag>zmieniłby indeks niezależnie od drzewa roboczego, więc musiałbym zresetować oryginalne drzewo. Rozwiązaniem, które działało dla mnie, było sklonowanie repozytorium. Udostępniony klon jest dość szybki i nie zajmuje dużo dodatkowej przestrzeni. W .gitrazie potrzeby katalog można usunąć.
git clone --shared --no-checkout <repository> <destination>
cd <destination>
git checkout <tag>
rm -rf .git
Nowsze wersje git powinny obsługiwać git clone --branch <tag>automatyczne pobieranie określonego tagu:
git clone --shared --branch <tag> <repository> <destination>
rm -rf <destination>/.git
git --work-tree=/path/to/outputdir checkout <tag> -- .nie działa dla Ciebie?
Odpowiedź Adriana brzmiała „fatalna: ta operacja musi być przeprowadzona w drzewie roboczym”. Oto, co zadziałało dla nas.
git worktree add <new-dir> --no-checkout --detach
cd <new-dir>
git checkout <some-ref> -- <existing-dir>
Uwagi:
--no-checkout Nie wypisuj niczego do nowego drzewa roboczego.--detach Nie twórz nowej gałęzi dla nowego drzewa roboczego.<some-ref>działa z każdym ref, na przykład, z którym działa HEAD~1.git worktree prune.Używam tego aliasu do wyewidencjonowywania gałęzi w katalogu tymczasowym:
[alias]
cot = "!TEMP=$(mktemp -d); f() { git worktree prune && git worktree add $TEMP $1 && zsh -c \"cd $TEMP; zsh\";}; f" # checkout branch in temporary directory
Stosowanie:
git cot mybranch
Następnie zostaniesz przeniesiony do nowej powłoki w katalogu tymczasowym, w którym możesz pracować na gałęzi. Możesz nawet użyć poleceń git w tym katalogu.
Kiedy skończysz, usuń katalog i uruchom:
git worktree prune
Odbywa się to również automatycznie w aliasie, przed dodaniem nowego drzewa roboczego.
Dodatek do odpowiedzi @ hasen . Aby wyświetlić listę plików do pobrania , możesz użyć git ls-fileszamiast find:
git ls-files -z *.txt | git checkout-index --prefix=/path-to/dest/ -f -z --stdin
-z! Fajnie, że udostępniasz skrypt, który nie jest podatny na niektóre rodzaje ataków polegających na wstrzykiwaniu.
Zdefiniowałem alias git, aby to osiągnąć (zanim znalazłem to pytanie).
Jest to krótka funkcja bash, która zapisuje bieżącą ścieżkę, przełącza się do repozytorium git, wykonuje wyewidencjonowanie i wraca tam, gdzie się zaczęła.
git checkto develop ~ / my_project_git
To np. Wyewidencjonowałoby gałąź deweloperską do katalogu "~ / my_project_git".
To jest kod aliasu w środku ~/.gitconfig:
[alias]
checkTo = "!f(){ [ -z \"$1\" ] && echo \"Need to specify branch.\" && \
exit 1; [ -z \"$2\" ] && echo \"Need to specify target\
dir\" && exit 2; cDir=\"$(pwd)\"; cd \"$2\"; \
git checkout \"$1\"; cd \"$cDir\"; };f"