Was ist die beste Vorgehensweise, um einen Klon in einen vorhandenen Ordner zu "git klonen"?

479

Ich habe eine Arbeitskopie des Projekts ohne Metadaten zur Quellcodeverwaltung. Jetzt möchte ich das Äquivalent von git-clone in diesen Ordner einfügen und meine lokalen Änderungen beibehalten.

Mit git-clone kann ich nicht in einen vorhandenen Ordner klonen. Was ist hier die beste Vorgehensweise?

ripper234
quelle
4
Bessere Diskussion ist hier .
cdunn2001
1
@MEM Ich mag diese Antwort mehr, aber entweder funktioniert ... stackoverflow.com/a/5377989/11236
ripper234
2
@ ripper234 - Ja. Ich war in der gleichen Situation und habe nur diese Schritte gemacht, und keine Probleme. Alles sauber und schön. Ich denke, es ist eine Frage der Präferenz, unter dem Strich, dass beide funktionieren, wie Sie sagen. Prost.
MEM
1
Das ist so verrückt, dass es keinen sauberen Weg gibt, dies zu erreichen. So nützlich, wenn Sie ein Projekt in einen bereitgestellten Freigabeordner klonen möchten.
Thomas Decaux
1
Mögliches Duplikat von Wie klone ich in ein nicht leeres Verzeichnis?
Tobias Kienzler

Antworten:

558

Dies kann durch Klonen in ein neues Verzeichnis und anschließendes Verschieben des .gitVerzeichnisses in Ihr vorhandenes Verzeichnis erfolgen.

Wenn Ihr vorhandenes Verzeichnis "Code" heißt.

git clone https://myrepo.com/git.git temp
mv temp/.git code/.git
rm -rf temp

Dies kann auch ohne Auschecken während des Klonbefehls erfolgen. Weitere Informationen finden Sie hier .

Amicitas
quelle
25
Beachten Sie, dass dies genau der Vorschlag von @ChrisJohnsen ist, den er in den Kommentaren hinterlassen hat. Ich fand es nützlich und wollte daraus eine tatsächliche Antwort machen. Chris, wenn du am Ende eine Antwort gibst, werde ich diese gerne löschen.
Amicitas
2
Vielen Dank! Dabei fehlt ein Schritt wie "git checkout -". wie es denkt, sind alle Dateien gelöscht, oder?
mrooney
2
Nein, solange Sie git cloneden ersten Befehl verwenden, ist kein weiterer Checkout-Befehl erforderlich. Wenn Sie stattdessen so etwas wie git clone --no-checkoutin diesem ersten Schritt verwenden, müssen Sie nach dem Verschieben des .git-Verzeichnisses git git reset HEADmitteilen, dass die Dateien nicht gelöscht wurden.
Amicitas
3
Ich würde dies als dritten Schritt hinzufügen: mv temp / .gitignore code / .gitignore
Daniel Aranda
1
@KalpeshSoni, ja, git kennt die geänderten Dateien und es ist möglich, die Änderungen mit den normalen git-Befehlen wie z git status.
Amicitas
284

Nicht klonen, sondern holen. Im Repo:

git init
git remote add origin $url_of_clone_source
git fetch origin
git checkout -b master --track origin/master # origin/master is clone's default

Anschließend können Sie den Baum zurücksetzen, um das gewünschte Commit zu erhalten:

git reset origin/master # or whatever commit you think is proper...

und du bist wie du geklont hast.

Die interessante Frage hier (und die ohne Antwort): Wie Sie herausfinden können, auf welchem ​​Commit Ihr nackter Baum basiert, auf welche Position Sie zurücksetzen müssen.

Andreas Krey
quelle
7
Ich bin kein Fan davon - per Github-Setup "Tipp: Der Helfer für Anmeldeinformationen funktioniert nur, wenn Sie eine HTTPS-Repository-URL klonen." Ich benutzte einen Beglaubigungshelfer und dieser schickte mich in ein langes, ziemlich fruchtloses Kaninchenloch.
Andrew
5
'git checkout --track origin / master' funktioniert auch gut anstelle von 'git checkout -b master --track origin / master'. Der Reset ist nicht erforderlich.
Felipecrp
1
Ich habe die Fehlermeldung "Git-Fehler: Die folgenden nicht verfolgten Arbeitsbaumdateien werden beim Auschecken überschrieben" erhalten, daher füge ich diesen Befehl hinzu: git clean -d -fx ""
shakaran
1
definitiv nicht in allen Situationen ratsam, aber genau das brauchte ich.
Chaim Eliyah
1
@AndreasKrey Ihre ursprüngliche Antwort (die ich im Bearbeitungsverlauf gesehen habe) macht genau das, was die Frage (und ich) benötigt. Die geänderten Antwortbalken an der Kasse ohne Verwendung von -f, wodurch die lokalen Änderungen verworfen werden und genau das ist, was ich nicht möchte. Wenn ich Sie wäre, würde ich in Betracht ziehen, zu Ihrer ursprünglichen Antwort zurückzukehren.
Ajean
77

Folgendes habe ich getan, um den Hauptzweig in einem vorhandenen Verzeichnis auszuchecken:

git init
git remote add origin [my-repo]
git fetch
git checkout origin/master -ft
alexwenzel
quelle
2
Dies ist eine großartige Antwort und vermeidet jegliches Finagling des Dateisystems.
user151841
1
Dies sollte die akzeptierte Antwort sein, da es sich nicht um einen Hack handelt.
php_nub_qq
5
Tatsächlich macht dies genau das, was das OP (und ich) nicht wollen, nämlich lokale Änderungen zu überschreiben.
Ajean
Meine Gegenstimme zeigt, dass dies ME geholfen hat, nicht dass dies die beste Antwort auf die Frage des OP ist.
TecBrat
2
Kann jemand erklären, warum die -tFlagge hier verwendet wird?
Jfowkes
38

Ich würde git clonein ein neues Verzeichnis wechseln und den Inhalt des vorhandenen Verzeichnisses in den neuen Klon kopieren.

jhwist
quelle
4
Wenn Sie dies tun, stellen Sie sicher, dass Sie den Diff überprüfen, bevor Sie ihn sorgfältig festlegen. Dies ist ein absoluter klassischer Fall, in dem Sie versehentlich Änderungen rückgängig machen können, die im Quell-Repo vorgenommen wurden, seit Sie Ihre Arbeitskopie erhalten haben - da nicht genügend Informationen vorhanden sind in der Arbeitskopie, um herauszufinden, welche Änderungen Sie vorgenommen haben und wie sie waren, bevor Sie Änderungen vorgenommen haben, um sie mit anderen im Repo vorgenommenen Änderungen zusammenzuführen. Ich habe dies in dieser Situation immer wieder gesehen, bis zu dem Punkt, an dem ich mich und die Menschen, mit denen ich zusammengearbeitet habe, "stark entmutigt" habe, es jemals zu tun.
Ben Clifford
72
git clone wherever tmp && git mv tmp/.git . && rm -rf tmpMit anderen Worten, das Verschieben des .gitVerzeichnisses aus einem temporären Klon scheint einfacher zu sein, als den Arbeitsbaum des Klons zu bereinigen und die vorhandenen Dateien dort zu kopieren.
Chris Johnsen
1
@ ChrisJohnsen: Sie hätten es zu einer Antwort machen sollen, das ist definitiv der beste Weg, es imho zu tun
Stefano
2
@ ChrisJohnsen git mv tmp/.git .kehrt fatal: cannot move directory over file, source=tmp/.git, destination=.gitfür mich zurück. Weiß jemand, worum es geht?
Dennis
6
@ Tennis, Es ist ein Tippfehler: Dieser Befehl sollte einfach sein mv, nicht git mv; Dies erklärt jedoch nicht, warum Sie bereits eine .gitDatei dort haben (die gitdir: some/path/to/a/git-direine „Git- Datei “ enthält; wenn sie nicht vorhanden wäre, hätten Sie sie fatal: Not a git repository (or any of the parent directories): .gitstattdessen gesehen ).
Chris Johnsen
34

Die Verwendung eines temporären Verzeichnisses ist in Ordnung, funktioniert jedoch, wenn Sie diesen Schritt vermeiden möchten. Aus dem Stammverzeichnis Ihres Arbeitsverzeichnisses:

$ rm -fr .git
$ git init
$ git remote add origin your-git-url
$ git fetch
$ git reset --mixed origin/master
user1055643
quelle
20
git reset --hard origin/masterentfernt alle lokalen Dateien.
Mouad Debbar
1
hinzuzufügen , was bereits oben erwähnt, ist der Unterschied zwischen hardund mixedist , dass gemischte lokale Änderungen halten wird (also wenn Sie später versuchen , es Ihnen zu ziehen würde zeigen , zB kann mit dem Fütterungsmaterial nicht ziehen. Sie unstaged Änderungen haben Bitte begehen oder bunkern sie ) , während schwer wird diese lokalen Änderungen verwerfen
aexl
Sie haben fern falsch geschrieben.
Glenn Dayton
10
git clone your_repo tmp && mv tmp/.git . && rm -rf tmp && git reset --mixed
return1.at
quelle
7
Durch git reset --harddie Verwendung werden die lokalen Dateiänderungen zerstört, insbesondere NICHT, was dieses OP angefordert hat. --mixedsollte stattdessen verwendet werden.
Caleb
4

Gehen Sie wie folgt vor, um ein Git-Repo in ein leeres vorhandenes Verzeichnis zu klonen:

cd myfolder
git clone https://myrepo.com/git.git . 

Beachten Sie das .am Ende Ihres git cloneBefehls. Dadurch wird das Repo in das aktuelle Arbeitsverzeichnis heruntergeladen.

okay Rede
quelle
4
fatal: destination path '.' already exists and is not an empty directory.
Roland Kofler
Das Verzeichnis muss leer sein.
OKTalk
4
Das OP fragt, wie in ein bestehendes Projekt geklont werden soll, und gibt an, dass sich der Git-Klon beschwert. Falsche Antwort.
mix3d
Dies funktioniert nur, wenn Sie ein neues Verzeichnis erstellen und die obigen Befehle ausführen, ohne "git init" zu verwenden
Bilal Ahmed
3

Viele Antworten, um es so zu machen, wie es das OP verlangt hat. Es ist jedoch erwähnenswert, dass es viel einfacher ist, das Gegenteil zu tun:

git clone repo-url tmp/
cp -R working/ tmp/

Sie haben jetzt den gewünschten Zielstatus - neuer Klon + lokale Änderungen.

Andrew
quelle
2

Hierfür gibt es zwei Ansätze. Wenn möglich, würde ich mit einem sauberen Ordner für Ihr neues Git-Arbeitsverzeichnis beginnen und dann Ihre Version der Dinge später kopieren. Das könnte ungefähr so ​​aussehen wie *:

mv $dir $dir.orig
git clone $url $dir
rsync -av --delete --exclude '.git' $dir.orig/ $dir/
rm -rf $dir.orig

Zu diesem Zeitpunkt sollten Sie eine ziemlich saubere Arbeitskopie mit Ihrem vorherigen Arbeitsordner als aktuellem Arbeitsverzeichnis haben, damit alle Änderungen, einschließlich Dateilöschungen, auf dem Radar angezeigt werden, wenn Sie ausgeführt werden git status.

Auf der anderen Seite, wenn Sie es wirklich umgekehrt machen müssen, können Sie mit so etwas das gleiche Ergebnis erzielen:

cd $dir
git clone --no-checkout $url tempdir
mv tempdir/.git .
rmdir tempdir
git reset --mixed HEAD

In jedem Fall würde ich als Erstes so etwas wie git stasheine Kopie aller Ihrer lokalen Änderungen ausführen, die beiseite gelegt werden. Dann können Sie sie erneut anwenden und herausfinden, welche Sie festschreiben möchten.

* In beiden Beispielen wird davon ausgegangen, dass Sie mit der Shell im übergeordneten Verzeichnis Ihres Projekts beginnen.

Caleb
quelle
2

Dies ist die beste aller Methoden, die mir begegnet sind

Klonen Sie nur den .git-Ordner des Repositorys (mit Ausnahme der Dateien, in denen sie sich bereits befinden existing-dir) in ein leeres temporäres Verzeichnis

  1. git clone --no-checkout repo-path-to-clone existing-dir/existing-dir.tmp // möchte vielleicht --no-hardlinks zum Klonen von lokalem Repo

Verschieben Sie den Ordner .git in das Verzeichnis mit den Dateien. Das macht existing-direin Git Repo.

  1. mv existing-dir/existing-dir.tmp/.git existing-dir/

Löschen Sie das temporäre Verzeichnis

  1. rmdir existing-dir/existing-dir.tmp

  2. cd existing-dir

Git glaubt, dass alle Dateien gelöscht wurden. Dadurch wird der Status des Repos auf HEAD zurückgesetzt.

WARNUNG: Alle lokalen Änderungen an den Dateien gehen verloren.

  1. git reset --mixed HEAD
Amirtha Rajan
quelle
1
Ein Hard-Reset scheint in 99% der Fälle, in denen Sie dies tun müssen, unerwünscht zu sein.
Stefan Fabian
0

Wenn Sie mindestens git 1.7.7 verwenden (was clonedie --configOption gelehrt hat ), um das aktuelle Verzeichnis in eine Arbeitskopie umzuwandeln:

git clone example.com/my.git ./.git --mirror --config core.bare=false

Dies funktioniert durch:

  • Klonen des Repositorys in einen neuen .gitOrdner
  • --mirrormacht den neuen Klon nach .gitBedarf zu einem reinen Metadatenordner
  • --config core.bare=falsewiderspricht dem Impliziten bare=trueder --mirrorOption, wodurch das Repository über ein zugeordnetes Arbeitsverzeichnis verfügt und sich wie ein normaler Klon verhält

Dies funktioniert offensichtlich nicht, wenn .gitin dem Verzeichnis, das Sie in eine Arbeitskopie umwandeln möchten, bereits ein Metadatenverzeichnis vorhanden ist.

ThorSummoner
quelle
1
Beachten Sie, dass diese Technik dazu führt, dass der [core]Abschnitt der lokalen Konfiguration sowohl bare = true als auch enthält bare = false . Problematischer ist, dass es die falschen Werte für die originFernbedienung hat, [remote "origin"]einschließlich des Abschnitts mirror = trueund einer Abrufspezifikation, die mit einer Arbeitskopie nicht richtig funktioniert. Nachdem diese Probleme behoben wurden, war das normale Klonen und Verschieben der neuen Arbeitskopien .giteffizienter.
Araxia
0

Normalerweise klone ich zuerst das anfängliche Repository und verschiebe dann alles im vorhandenen Ordner in das anfängliche Repository. Es funktioniert jedes Mal.

Der Vorteil dieser Methode ist, dass Sie nichts vom anfänglichen Repository verpassen, einschließlich README oder .gitignore.

Sie können auch den folgenden Befehl verwenden, um die Schritte abzuschließen:

$ git clone https://github.com/your_repo.git && mv existing_folder/* your_repo
Mike Chen
quelle
0

Sie können dies tun, indem Sie die folgenden Befehlszeilen rekursiv eingeben:

mkdir temp_dir   //  Create new temporary dicetory named temp_dir
git clone https://www...........git temp_dir // Clone your git repo inside it
mv temp_dir/* existing_dir // Move the recently cloned repo content from the temp_dir to your existing_dir
rm -rf temp_dir // Remove the created temporary directory
MUSTAPHA GHLISSI
quelle
0

Verwenden Sie einfach die. am Ende des git cloneBefehls (in diesem Verzeichnis) wie folgt:

cd your_dir_to_clone_in/
git clone [email protected]/somerepo/ .
John F.
quelle