Wie klone ich in ein nicht leeres Verzeichnis?

573

Ich habe Verzeichnis A mit Dateien, die mit Verzeichnis B übereinstimmen. Verzeichnis A enthält möglicherweise andere benötigte Dateien. Verzeichnis B ist ein Git-Repo.

Ich möchte Verzeichnis B in Verzeichnis A klonen, aber Git-Clone erlaubt es mir nicht, da das Verzeichnis nicht leer ist.

Ich hatte gehofft, es würde nur .git klonen und da alle Dateien übereinstimmen, könnte ich von dort aus gehen?

Ich kann nicht in ein leeres Verzeichnis klonen, da ich Dateien in Verzeichnis A habe, die sich nicht in Verzeichnis B befinden, und ich möchte sie behalten.

Das Kopieren von .git ist keine Option, da Refs gedrückt / gezogen werden sollen und nicht manuell eingerichtet werden sollen.

Gibt es eine Möglichkeit, dies zu tun?

Update: Ich denke das funktioniert, kann jemand irgendwelche Probleme sehen? ->

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
Dale Forester
quelle
5
Vielleicht könnten Sie die akzeptierte Antwort ändern?
Bastiaan Quast

Antworten:

724

Das hat bei mir funktioniert:

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

HINWEIS: Legt -t den Upstream-Zweig für Sie fest, wenn Sie dies wünschen und dies normalerweise der Fall ist.

cmcginty
quelle
70
Dies funktioniert nicht in einem nicht leeren Verzeichnis, wenn die eingehenden Dateien bereits vorhanden sind (wie in der ursprünglichen Frage beschrieben). Aber wenn Sie git reset origin/masternach dem git fetch, wird es funktionieren (auch alle lokalen Änderungen beibehalten).
Araxia
8
Schwerwiegend: Es können keine Pfade aktualisiert und gleichzeitig zum Zweig 'Master' gewechselt werden.
Arnold Roa
7
Diese Antwort funktioniert bei mir nicht. Wenn ich mich git checkout ...beschwere, dass alle meine Dateien überschrieben werden und ich sie zuerst verschieben sollte. Wenn ich zuerst "git reset origin / master /" mache, beschwert sich der Checkout-Befehl darüber, dass bereits ein Zweig mit dem Namen master existiert.
Saskia
4
git checkout masterwar ein ausreichender letzter Schritt für mich.
Yooy
16
Alle Schritte haben perfekt funktioniert, aber der letzte hat mich erwischt : fatal: A branch named 'master' already exists. Ich glaube, ich habe es nicht wirklich gebraucht.
Shadi
164

In den folgenden Shell-Befehlen existing-dirbefindet sich ein Verzeichnis, dessen Inhalt mit den verfolgten Dateien im repo-to-cloneGit-Repository übereinstimmt .

# 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
Dale Forester
quelle
5
Ich musste es tun git reset --hard HEADoder es würde die "gelöschten" Dateien nicht aufgeben.
Dimitar
18
git reset HEADhat gut für mich funktioniert. git reset --hard HEADzerstört alle Änderungen in Ihren Dateien. Wenn sie also nicht genau mit den Dateien im Repository übereinstimmen, sollten Sie dies nicht tun.
Tgr
1
git reset HEADscheint keinen Einfluss auf mich zu haben. git reset --hard HEADtut - aber das verliert alle Änderungen, die Sie an den Dateien vorgenommen haben. Gibt es eine bessere Lösung?
Jacob Dorman
1
Die Antwort von @ Casey - git init / remote add / fetch / checkout - ist sauberer und einfacher und erfordert keine temporären Ordner.
Yooy
1
@ Caseys Antwort hat bei mir nicht funktioniert, als sich bereits Dateien in Ordnern befanden, die verbleiben mussten, aber nicht im Git-Repo waren. Dies ist nützlich, um die Konfiguration nach dem Ausführen von Installationsskripten zu aktualisieren, in denen Dateien und Verzeichnisse erstellt werden. Sie müssen jedoch Dateien zusätzlich zu den installierten Elementen aktualisieren / hinzufügen.
Soulston
104

Eine kleine Änderung an einer der Antworten, die für mich funktioniert haben:

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

um sofort mit der Arbeit an der Hauptniederlassung zu beginnen.

mohsaied
quelle
1
musste HEAD zurücksetzen - hart, um das schmutzige vorhandene Verzeichnis zu bereinigen, ohne irrelevante Dateien zu entfernen, die in gitignore angegeben sind
Ray Foss
1
Dies ist diejenige, die tatsächlich für mich funktioniert hat, im Gegensatz zur Antwort von @ cmcginty.
sicherlich
4
Dies ist nicht ganz gleichbedeutend mit einem Git-Klon - es fehlen die Upstream-Informationen für den Master-Zweig. Dies kann durch Hinzufügen behoben werden git branch --set-upstream-to=origin/master master.
Slaven Rezic
Diese Version funktionierte für mich, musste nur einen Git-Reset durchführen
Frédéric Klee
29

Warnung - Dies könnte möglicherweise Dateien überschreiben.

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

Geändert von der Antwort von @ cmcginty - ohne das -f hat es bei mir nicht funktioniert

JohnFF
quelle
Sicherlich müssen Sie danach alle Dateien mit git checkout .auschecken?
Chris Stryczynski
25

Folgendes habe ich getan, als ich das gleiche Problem hatte (zumindest denke ich, dass es das gleiche Problem ist). Ich ging in Verzeichnis A und rannte git init.

Da ich nicht wollte, dass auf die Dateien in Verzeichnis A git folgt, habe ich .gitignore bearbeitet und die vorhandenen Dateien hinzugefügt. Danach lief ich git remote add origin '<url>' && git pull origin masteret voíla, B wird ohne einen einzigen Schluckauf in A "geklont".

BjörnSnoen
quelle
2
Diese Technik funktioniert nicht in einem nicht leeren Verzeichnis, wenn die eingehenden Dateien bereits vorhanden sind (wie in der ursprünglichen Frage beschrieben).
Araxie
11

Ich habe dies vor ein paar Augenblicken verwendet, erfordert die am wenigsten potenziell zerstörerischen Befehle:

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

Und voilá!

KuttKatrea
quelle
10

Ein anderes einfaches Rezept scheint für mich gut zu funktionieren:

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

Mein Hauptanwendungsfall beim Auschecken in ein Verzeichnis mit vorhandenen Dateien ist die Steuerung meiner Unix-Punktedateien mit Git. In einem neuen Konto enthält das Home-Verzeichnis bereits einige Dateien, möglicherweise sogar diejenigen, die ich von Git erhalten möchte.

Ken Williams
quelle
1
Bare-Repositorys sind etwas anders eingerichtet, und obwohl dies funktioniert, würde ich es nicht empfehlen. :)
ThorSummoner
1
Kannst du genauer sein? Was ist anders?
Ken Williams
1
Nur zwei Unterschiede: 1.) Die .git/configDatei zeigt an, dass die Repos leer sind. 2.) Dateien, die normalerweise in gespeichert .gitsind, werden im Stammverzeichnis (das Sie aufgerufen haben .git) gespeichert
mozey
4
Das sind genau die Veränderungen , die zu klonen .gitund Einstellung core.barezu falsekümmern, so dass ich immer noch gut über diese Methode fühlen.
Ken Williams
10

Das hat bei mir funktioniert:

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

Ich hatte ein ähnliches Problem mit einem neuen Apache-Webverzeichnis (mit WHM erstelltes Konto), das ich als Staging-Webserver verwenden wollte. Ich musste mein neues Projekt zunächst mit der dortigen Codebasis klonen und regelmäßig Änderungen durch Abrufen aus dem Repository bereitstellen.

Das Problem war, dass das Konto bereits Webserver-Dateien enthielt wie:

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

... dass ich mein Repository weder löschen noch festschreiben wollte. Ich brauchte sie, um einfach ungestuft und ohne Spur dort zu bleiben.

Was ich getan habe:

Ich ging zu meinem Webordner (existierender_Ordner):

cd /home/existing_folder

und dann:

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

Es wurde (wie erwartet) eine Liste vieler nicht bereitgestellter Dateien angezeigt - diejenigen, die ursprünglich bereits in meinem cPanel-Webkonto vorhanden waren.

Dann habe ich dank dieses Artikels die Liste dieser Dateien hinzugefügt zu:

**.git/info/exclude**

Diese Datei .gitignoreermöglicht es Ihnen , fast wie die Datei, das Bereitstellen von Dateien zu ignorieren. Danach hatte ich nichts mehr im .git / -Verzeichnis festzuschreiben - es funktioniert wie ein persönliches.gitignore , das niemand sonst sehen kann.

Überprüfen Sie nun die git statusRetouren:

On branch master
nothing to commit, working tree clean

Jetzt kann ich Änderungen auf diesem Webserver bereitstellen, indem ich sie einfach aus meinem Git-Repository ziehe. Ich hoffe, dies hilft einigen Webentwicklern, auf einfache Weise einen Staging-Server zu erstellen.

Vlado
quelle
5

Folgendes mache ich:

git clone repo /tmp/folder
cp -rf /tmp/folder/.git /dest/folder/
cd /dest/folder
git checkout -f master
Philip Kirkbride
quelle
4

Vielleicht habe ich Ihre Frage falsch verstanden, aber wäre es nicht einfacher, wenn Sie die Dateien von A in das Git-Repo B kopieren / verschieben und die benötigten mit git add hinzufügen ?

UPDATE: Aus dem Git-Dokument:

Das Klonen in ein vorhandenes Verzeichnis ist nur zulässig, wenn das Verzeichnis leer ist.

QUELLE: http://git-scm.com/docs/git-clone

Roberto Aloi
quelle
2
Nein, der Eigentümer und die Dateien können beliebig sein. Dies ist für eine Situation mit mehreren Entwicklern. Wir haben alle vorhandene Verzeichnisse und nur eines hat derzeit eine Git-Kasse. Wir haben alle größtenteils die gleiche Teilmenge von Dateien, daher möchten wir, dass die anderen Entwickler klonen können, während ihre Dateien erhalten bleiben. Und es sollte so elegant und bequem wie möglich sein.
Dale Forester
Ehrlich gesagt sehe ich keinen Sinn darin, mich in einem solchen Zustand zu entwickeln. Können Sie keine Zweige und Zusammenführungsvorgänge verwenden? Oder Unter-Repositorys mit externen Abhängigkeiten? Warum sollten Sie sich auf eine einzige "Git Checkout" verlassen wollen?
Roberto Aloi
5
Ein "Single Git Checkout" ist nicht der Punkt der ganzen Tortur. Es ist nur so, wie es ist und wir brauchen einen Weg, um vorwärts zu kommen. Ich habe die ursprüngliche Frage mit einer Lösung aktualisiert, die anscheinend funktioniert. Ich freue mich jedoch über das Feedback.
Dale Forester
3
Hierfür gibt es viele legitime Fälle: Ich habe einen komplexen Ordnerbaum, der eingerichtet werden muss, bevor die Quelle meines Projekts eingerichtet werden kann, und dieser Ordnerbaum enthält lizenzierte Werke, die beispielsweise nicht auf GitHub gespeichert werden können.
BrainSlugs83
3

Ich habe nach etwas Ähnlichem gesucht und mir Folgendes ausgedacht:

In meiner Situation habe ich einen aktiven Webbaum und habe versucht, ein Remote-Repository dafür zu erstellen, ohne eine der Dateien im aktuellen Webbaum zu verschieben. Folgendes habe ich getan:

  1. Gehen Sie zum Webbaum und führen Sie es aus git init
  2. Gehen Sie zum vorgesehenen Speicherort des Repositorys und führen Sie Folgendes aus: git clone --bare /path/to/web/repo
  3. Bearbeiten Sie die Konfigurationsdatei in meinem Remote-Repo und entfernen Sie die [remote "origin"] Abschnitt.
  4. Fügen Sie [remote "origin"]im Webbaum einen Abschnitt zu .git / config hinzu, der auf das neue Remote-Repo verweist.
Lendrick
quelle
Ich mag dieses Rezept sehr.
Dland
Das git clone --barehier ist überflüssig und umständlich. Warum nicht gleich git remote add origin <URL>?
Araxia
3

Dies ist Arbeit für mich, aber Sie sollten Remote-Repository-Dateien mit den lokalen Dateien zusammenführen:

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

Ich mochte Dales Antwort und fügte hinzu

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

Durch die geringe Tiefe wurden viele zusätzliche frühe Entwickler-Commits vermieden. Der neue Zweig hat uns eine gute visuelle Geschichte gegeben, dass ein neuer Code von diesem Server eingefügt wurde. Das ist meiner Meinung nach der Zweig mit der perfekten Verwendung. Mein Dank geht an die großartigen Einblicke aller Leute, die hier gepostet haben.

Dmitri R117
quelle
0

Ich habe die gleichen Probleme beim Versuch, auf c / code zu klonen

Dieser Ordner enthält jedoch eine ganze Reihe von Projekten.

Ich habe einen neuen Ordner in c / code / newproject erstellt und meinen Klon diesem Ordner zugeordnet.

Git für Desktop dann von meinem Benutzer gefragt und dann gut geklont.

Tom
quelle