Jak sklonować do niepustego katalogu?


572

Mam katalog A z plikami pasującymi do katalogu B. Katalog A może zawierać inne potrzebne pliki. Katalog B to repozytorium git.

Chcę sklonować katalog B do katalogu A, ale git-clone nie pozwoli mi na to, ponieważ katalog nie jest pusty.

Miałem nadzieję, że po prostu sklonuje .git, a ponieważ wszystkie pliki pasują, mogę stąd przejść?

Nie mogę sklonować do pustego katalogu, ponieważ mam pliki w katalogu A, których nie ma w katalogu B i chcę je zachować.

Kopiowanie .git nie jest opcją, ponieważ chcę, żeby referencje pchały / ciągnęły i nie chcę konfigurować ich ręcznie.

Czy jest na to sposób?

Aktualizacja: Myślę, że to działa, czy ktoś może zobaczyć jakieś problemy? ->

cd a
git clone --no-hardlinks --no-checkout ../b a.tmp 
mv a.tmp/.git .
rm -rf a.tmp
git unstage # apparently git thinks all the files are deleted if you don't do this

5
może mógłbyś zmienić przyjętą odpowiedź?
— Bastiaan Quast

Odpowiedzi:


724

To działało dla mnie:

git init
git remote add origin PATH/TO/REPO
git fetch
git reset origin/master  # Required when the versioned files existed in path before "git init" of this repo.
git checkout -t origin/master

UWAGA: -t ustawi dla ciebie odgałęzienie, jeśli tego właśnie chcesz, i zwykle tak jest.


70
Nie działa to w niepustym katalogu, gdy przychodzące pliki już istnieją (jak opisano w pierwotnym pytaniu). Ale jeśli git reset origin/masterpo tym git fetch, będzie działać (zachowując również wszelkie lokalne zmiany).
— Araxia

8
fatal: Nie można zaktualizować ścieżek i jednocześnie przejść do gałęzi „master”.
— Arnold Roa,

7
Ta odpowiedź nie działa dla mnie. Kiedy to robię, git checkout ...git skarży się, że wszystkie moje pliki zostaną nadpisane i powinienem je najpierw przenieść. Kiedy robię najpierw `git reset origin / master /`, polecenie kasowania skarży się, że gałąź o nazwie master już istnieje.
— Saskia,

4
git checkout masterbył dla mnie wystarczającym ostatnim krokiem.
— yoyo

16
Wszystkie etapy działało idealnie, ale ten ostatni dostał mnie: fatal: A branch named 'master' already exists. Myślę, że tak naprawdę tego nie potrzebowałem.
— Shadi

164

W poniższych poleceniach powłoki existing-dirznajduje się katalog, którego zawartość jest zgodna ze śledzonymi plikami w plikurepo-to-clone repozytorium git.

# Clone just the repository's .git folder (excluding files as they are already in
# `existing-dir`) into an empty temporary directory
git clone --no-checkout repo-to-clone existing-dir/existing-dir.tmp # might want --no-hardlinks for cloning local repo

# Move the .git folder to the directory with the files.
# This makes `existing-dir` a git repo.
mv existing-dir/existing-dir.tmp/.git existing-dir/

# Delete the temporary directory
rmdir existing-dir/existing-dir.tmp
cd existing-dir

# git thinks all files are deleted, this reverts the state of the repo to HEAD.
# WARNING: any local changes to the files will be lost.
git reset --hard HEAD

5
Musiałem to zrobić git reset --hard HEAD, inaczej nie zrezygnuje z „usuniętych” plików.
— Dimitar

18
git reset HEADdziałało dobrze dla mnie. git reset --hard HEADniszczy wszelkie zmiany w plikach, więc jeśli nie są dokładnie takie same jak pliki w repozytorium, nie powinieneś tego robić.
— Tgr

1
git reset HEADnie wydaje się mieć dla mnie żadnego wpływu. git reset --hard HEADrobi - ale powoduje to utratę wszelkich zmian wprowadzonych w plikach. Czy jest lepsze rozwiązanie?
— Jacob Dorman

1
Odpowiedź Caseya - git init / remote add / fetch / checkout - jest czystsza i prostsza i nie wymaga żadnych folderów tymczasowych.
— yoyo

1
@ Odpowiedź Casey nie działała dla mnie, gdy w folderach były już pliki, które musiały pozostać, ale nie były w repozytorium git. Jest to przydatne do aktualizowania konfiguracji po uruchomieniu skryptów instalacyjnych, w których tworzone są pliki i katalogi, ale należy zaktualizować / dodać pliki nad zainstalowanymi elementami.
— soulston

104

Drobna modyfikacja jednej z odpowiedzi, która działała dla mnie:

git init
git remote add origin PATH/TO/REPO
git pull origin master

aby od razu rozpocząć pracę nad gałęzią master.


1
musiał zresetować HEAD - twardy, aby wyczyścić brudny istniejący katalog, bez usuwania niepotrzebnych plików określonych w gitignore
— Ray Foss

1
Jest to ten, który faktycznie dla mnie zadziałał, w przeciwieństwie do odpowiedzi @ cmcginty.
— pewno

4
Nie jest to do końca równoważne z git-clone - brakuje tylko informacji upstream dla gałęzi master. Można to naprawić, dodając git branch --set-upstream-to=origin/master master.
— Slaven Rezic,

Ta wersja działała dla mnie, po prostu musiałem zresetować git - twardy HEAD
— Frédéric Klee

29

Ostrzeżenie - może to potencjalnie zastąpić pliki.

git init     
git remote add origin PATH/TO/REPO     
git fetch     
git checkout -t origin/master -f

Zmodyfikowano z odpowiedzi @ cmcginty - bez opcji -f nie działało to dla mnie


Na pewno musisz po tym sprawdzić wszystkie pliki git checkout .?
— Chris Stryczyński

25

Oto, co skończyłem, gdy miałem ten sam problem (przynajmniej myślę, że to ten sam problem). Wszedłem do katalogu A i pobiegłemgit init .

Ponieważ nie chciałem, aby po plikach w katalogu A pojawił się git, edytowałem .gitignore i dodałem do niego istniejące pliki. Po tym, jak uruchomiłem git remote add origin '<url>' && git pull origin masteret voíla, B zostaje „sklonowany” do A bez jednego czknięcia.


2
Ta technika nie działa w niepustym katalogu, gdy przychodzące pliki już istnieją (jak opisano w pierwotnym pytaniu).
— Araxia

11

Użyłem tego kilka chwil temu, wymaga najmniej potencjalnie destrukcyjnych poleceń:

cd existing-dir
git clone --bare repo-to-clone .git
git config --unset core.bare
git remote rm origin
git remote add origin repo-to-clone
git reset

I voilá!


10

Kolejny prosty przepis wydaje mi się odpowiedni dla mnie:

git clone --bare $URL .git
git config core.bare false

Moim głównym przypadkiem użycia do wyewidencjonowania do katalogu z istniejącymi plikami jest kontrolowanie moich plików dotx z Uniksem za pomocą Git. Na nowym koncie katalog domowy będzie już zawierał niektóre pliki, być może nawet te, które chcę uzyskać z Git.


1
Nagie repozytoria są konfigurowane nieco inaczej i chociaż to działa, nie polecam tego. :)
— ThorSummoner,

1
Czy mógłbyś to sprecyzować? Co jest inne
— Ken Williams

1
Tylko dwie różnice: 1.) .git/configPlik wskazuje, że repozytorium jest puste. 2.) Pliki normalnie przechowywane .gitsą przechowywane w katalogu głównym (który .git
— nazwałeś

4
Są to dokładnie te zmiany, które do klonowania .giti ustawianie core.baresię falsezajmie, więc nadal czuć się dobrze o tej metodzie.
— Ken Williams

10

To działało dla mnie:

cd existing_folder
git init
git remote add origin path_to_your_repo.git
git add .
git commit
git push -u origin master

6

Miałem podobny problem z nowym katalogiem internetowym Apache (konto utworzone w WHM), którego planowałem użyć jako tymczasowego serwera WWW. Musiałem początkowo sklonować mój nowy projekt z tamtejszą bazą kodu i okresowo wdrażać zmiany, wyciągając z repozytorium.

Problem polegał na tym, że konto zawierało już pliki serwera WWW, takie jak:

.bash_history
.bash_logout
.bash_profile
.bashrc
.contactemail
.cpanel/
...

... że nie chcę ani usuwać ani zatwierdzać mojego repozytorium. Potrzebowałem ich, aby pozostali tam bez sceny i bez śledzenia.

Co ja zrobiłem:

Poszedłem do mojego folderu internetowego (istniejący_folder):

cd /home/existing_folder

i wtedy:

git init
git remote add origin PATH/TO/REPO
git pull origin master
git status

Wyświetliła (zgodnie z oczekiwaniami) listę wielu plików, które nie były przemieszczane - te, które już istniały początkowo z mojego konta internetowego cPanel.

Następnie, dzięki temu artykułowi , właśnie dodałem listę tych plików do:

**.git/info/exclude**

Ten plik, podobnie jak .gitignoreplik, pozwala zignorować pliki przed przemieszczeniem. Po tym nie miałem nic do zatwierdzenia w katalogu .git / - działa jak osobisty.gitignore którego nikt inny nie widzi.

Teraz sprawdzanie git statuszwrotów:

On branch master
nothing to commit, working tree clean

Teraz mogę wdrożyć zmiany na tym serwerze WWW, po prostu pobierając z mojego repozytorium git. Mam nadzieję, że pomoże to niektórym twórcom stron internetowych łatwo stworzyć serwer pomostowy.


5

Oto co robię:

git clone repo /tmp/folder
cp -rf /tmp/folder/.git /dest/folder/
cd /dest/folder
git checkout -f master

4

Może źle zrozumiałem twoje pytanie, ale czy nie byłoby łatwiej, jeśli skopiujesz / przeniesiesz pliki z A do git repo B i dodasz potrzebne za pomocą git add ?

AKTUALIZACJA: Z git doc:

Klonowanie do istniejącego katalogu jest dozwolone tylko wtedy, gdy katalog jest pusty.

ŹRÓDŁO: http://git-scm.com/docs/git-clone


2
Nie, właściciel i pliki mogą być dowolne. Dotyczy to sytuacji wielu programistów. Wszyscy mamy istniejące katalogi i tylko jeden ma obecnie kasę git. Wszyscy w dużej mierze mamy ten sam podzbiór plików, więc chcemy, aby inni programiści mogli klonować, zachowując swoje pliki. I powinno być tak eleganckie i wygodne, jak to możliwe.
— Dale Forester,

Szczerze mówiąc, nie widzę sensu rozwijania się w takim stanie. Nie możesz używać oddziałów i scalać operacji? Czy posiadanie sub-repozytoriów z zewnętrznymi zależnościami? Dlaczego miałbyś polegać na pojedynczym „kasie git”?
— Roberto Aloi,

5
„Zamówienie pojedynczego gita” nie jest celem całej próby. Tyle, że tak już jest i potrzebujemy sposobu, aby iść naprzód. Zaktualizowałem oryginalne pytanie o rozwiązanie, które wydaje się działać. Doceniam jednak opinie.
— Dale Forester

3
Istnieje wiele uzasadnionych przypadków - mam złożone drzewo folderów, które należy skonfigurować PRZED skonfigurowaniem źródła mojego projektu, a to drzewo folderów zawiera licencjonowane prace, których nie można na przykład przechowywać w GitHub.
— BrainSlugs83,

3

Szukałem czegoś podobnego i oto, co wymyśliłem:

Moja sytuacja dotyczy sytuacji, w której mam aktywne drzewo sieciowe i próbowałem utworzyć dla niego zdalne repozytorium bez przenoszenia jakichkolwiek plików w bieżącym drzewie internetowym. Oto co zrobiłem:

  1. Przejdź do drzewa i uruchom git init
  2. Przejdź do zamierzonej lokalizacji repozytorium i uruchom: git clone --bare /path/to/web/repo
  3. Edytuj plik konfiguracyjny w moim zdalnym repozytorium i usuń [remote "origin"]sekcję.
  4. Dodaj [remote "origin"]sekcję do .git / config w drzewie sieci, wskazując na nowe zdalne repozytorium.

Bardzo podoba mi się ten przepis.
— dland

git clone --bareTutaj jest zbędne i okrężną. Dlaczego nie po git remote add origin <URL>pierwsze?
— Araxia

3

to działa dla mnie, ale powinieneś połączyć pliki repozytorium zdalnego z plikami lokalnymi:

git init
git remote add origin url-to-git
git branch --set-upstream-to=origin/master master
git fetch
git status

1

Podobała mi się odpowiedź Dale'a , a także dodałem

git clone --depth 2 --no-checkout repo-to-clone existing-dir/existing-dir.tmp
git branch dev_new214
git checkout dev_new214
git add .
git commit
git checkout dev
git merge dev_new214

Płytka głębokość pozwoliła uniknąć wielu dodatkowych wczesnych zobowiązań deweloperów. Nowa gałąź dała nam dobrą wizualną historię, że został wstawiony nowy kod z tego serwera. To moim zdaniem idealne gałęzie. Moje podziękowania za świetny wgląd wszystkich ludzi, którzy tutaj pisali.


0

Te same problemy występowały podczas próby sklonowania do kodu c /

Ale ten folder zawiera całą masę projektów.

Utworzyłem nowy folder w c / code / newproject i zmapowałem klon do tego folderu.

git na pulpit następnie zapytał mojego użytkownika, a następnie sklonował dobrze.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.