Wie konvertiere ich ein normales Git-Repository in ein nacktes?

602

Wie kann ich ein "normales" Git-Repository in ein nacktes konvertieren?

Der Hauptunterschied scheint zu sein:

  • Im normalen Git-Repository befindet sich ein .gitOrdner im Repository, der alle relevanten Daten und alle anderen Dateien enthält, aus denen Ihre Arbeitskopie besteht

  • In einem nackten Git-Repository gibt es keine Arbeitskopie und der Ordner (nennen wir es repo.git) enthält die tatsächlichen Repository-Daten

Boldewyn
quelle
16
Vermutlich ist dies eine kürzere Methode:mv repo/.git repo.git; rm -rf repo
Jameshfisher
Ja stimmt. Als ich die Frage schrieb, war dies nur ein Ausschnitt meiner Geschichte, den ich in der anderen Minute ausgeführt habe.
Boldewyn
54
@eegg Verwendung &&statt für den ;Fall, dass dies mvfehlschlägt!

Antworten:

609

Kurz gesagt: Ersetzen Sie den Inhalt von repodurch den Inhalt von repo/.gitund teilen Sie dem Repository mit, dass es sich jetzt um ein nacktes Repository handelt.

Führen Sie dazu die folgenden Befehle aus:

cd repo
mv .git ../repo.git # renaming just for clarity
cd ..
rm -fr repo
cd repo.git
git config --bool core.bare true

Beachten Sie, dass sich dies von git clone --bareeinem neuen Standort unterscheidet (siehe unten).

Jörg W Mittag
quelle
9
Danke für den Hinweis auf core.bare. Jetzt, nachdem ich diese Option gegoogelt
Boldewyn
14
Vielen Dank! Dies scheint mir sauberer zu sein: mv repo / .git repo.git && rm -rf repo && cd repo.git && git config --bool core.bare true
JasonWoof
56
Dies ist so viel komplizierter und fragiler als die Antwort unten ( git clone --bare /path/to/repo).
DJ
7
Dieser rmBefehl benötigt möglicherweise * \.[!.]*nicht *, um Punktdateien und Punktverzeichnisse zu entfernen.
Minopret
6
@Ciantic: Wie ich bereits in meinem obigen Kommentar erklärt habe, wurde meine Antwort vor 3 Jahren gegeben, aber vor 5 Monaten hat jemand die Frage in etwas völlig anderes bearbeitet . Keine der Antworten auf dieser Seite ergibt mehr Sinn. Diese Befehlsfolge wurde direkt aus der Frage kopiert. Ich habe gerade die letzten beiden Zeilen hinzugefügt.
Jörg W Mittag
244

Ihre Methode sieht so aus, als würde sie funktionieren. Die Dateistruktur eines Bare-Repositorys entspricht genau dem, was sich im .git-Verzeichnis befindet. Aber ich weiß nicht, ob eine der Dateien tatsächlich geändert wurde. Wenn dies fehlschlägt, können Sie dies einfach tun

git clone --bare /path/to/repo

Sie müssen dies wahrscheinlich in einem anderen Verzeichnis tun, um einen Namenskonflikt zu vermeiden. Anschließend können Sie es einfach wieder an den gewünschten Ort verschieben. Möglicherweise müssen Sie die Konfigurationsdatei so ändern, dass sie darauf verweist, wo sich Ihr Ursprungs-Repo befindet.

jonescb
quelle
50
Falsch, diese Methode ist nicht das Äquivalent. Beim Ausführen eines Klons bleiben die Konfigurationsoptionen nicht erhalten, was für den ordnungsgemäßen Betrieb von entscheidender Bedeutung sein kann, z. B. wenn Sie git-p4 verwenden. Außerdem zerstört ein Klon Fernbedienungen. Mit etwas wie git-p4 verlieren Sie den p4 / master-Zweig, wenn Sie klonen. Daher ist der obige Ansatz vorzuziehen.
Nosatalian
26
Sie können Konfigurationsoptionen jedoch einfach übertragen, indem Sie die entsprechenden Teile der Konfigurationsdatei kopieren. Ich würde diese Methode immer noch als sauberer betrachten, als Dateien manuell zu kopieren und umzubenennen.
Philipp
6
Dies ist nach einer Subversion-Migration perfekt, da git-svn --bare nicht unterstützt.
Keyo
11
Um den Namenskonflikt zu vermeiden ---git clone --bare /path/to/repo.git /path/to/newbarerepo.git
Raksja
Dies funktioniert so lange, wie Sie git update-server-infonach der Erstellung auf dem Bare Repo ausgeführt werden.
ACK_stoverflow
116

Ich denke der folgende Link wäre hilfreich

GitFaq: Wie mache ich ein vorhandenes nicht nacktes Repository bloß?

$ mv repo/.git repo.git
$ git --git-dir=repo.git config core.bare true
$ rm -rf repo
xhh
quelle
2
Ja, genau das habe ich gesucht, danke! Ihr zweiter Vorschlag ( git clone) weist jedoch die oben erwähnten Nachteile des Nosatalian auf.
Boldewyn
1
In der von Ihnen vorgeschlagenen Dokumentation heißt es weiter: "Eine sicherere Methode besteht darin, Git alle internen Einstellungen für Sie vornehmen zu lassen, indem Sie so etwas tun ... git clone --bare -l <path_to_repos> <new_dir>"
dafunker
74

Es ist wirklich kinderleicht, eine Bare-Version eines nicht-Bare-Repositorys zu erstellen (siehe mehrere andere Beiträge hier), es sei denn, Sie möchten oder müssen speziell Bits im Dateisystem drehen. Es ist Teil der Kernfunktionalität von git:

git clone --bare existing_repo_path bare_repo_path

Chip Kaye
quelle
6
Ein bisschen erstaunlich, dass die mit Abstand beste Antwort nach> 4 Monaten 0 Stimmen hat. Die nicht sehr gute, aber gefährliche "akzeptierte Antwort" hat 200!
Stabledog
36
Überhaupt nicht erstaunlich - diese Antwort entspricht nicht der ursprünglichen Frage. Es konvertiert kein Repo, es klont eines und verliert dabei Informationen (z. B. entfernte Zweige).
GreenAsJade
15

Bitte beachten Sie auch die Verwendung

git clone --mirror path_to_source_repository

Aus der Dokumentation :

Richten Sie einen Spiegel des Quell-Repositorys ein. Dies impliziert --bar. Im Vergleich zu --bare ordnet --mirror nicht nur lokale Zweige der Quelle lokalen Zweigen des Ziels zu, sondern ordnet alle Refs (einschließlich Remote-Tracking-Zweige, Notizen usw.) zu und richtet eine Refspec-Konfiguration ein, sodass alle diese Refs werden durch ein Git-Remote-Update im Ziel-Repository überschrieben.

Jacek Krawczyk
quelle
Dies scheint der prägnanteste, vollständigste und sicherste Weg zu sein, um das zu tun, was das OP will (im Gegensatz zu nur clone). Vermisse ich etwas War --mirroreine relativ neue Ergänzung?
Craig Silver
@CraigSilver: Nein, wie ich im Dokumentationsverlauf in einer solchen Form sehe, --mirrorist die ab Version 1.7 verfügbar, also schon ziemlich lange. Sie können hier
auschecken
7

Ich wollte nur auf ein Repository in einem Netzwerkpfad pushen, aber Git ließ mich das nicht tun, es sei denn, dieses Repository wurde als nackt markiert. Ich musste nur die Konfiguration ändern:

git config --bool core.bare true

Sie müssen nicht mit den Dateien herumspielen, es sei denn, Sie möchten sie sauber halten.

Slion
quelle
3
Dies ist gefährlich, wenn Sie auch am Arbeitsbaum des Remote-Repos arbeiten möchten. Es besteht die Möglichkeit, dass Sie früher oder später eine Änderung einfach zurücksetzen, weil Ihr Remote-Arbeitsbaum und Ihr Index nicht mit dem Repository synchronisiert waren. Ich empfehle diese Lösung nicht, wenn Sie nicht genau wissen, was Sie tun.
Boldewyn
Sie sollten zwar nicht am Baum des Remote-Bare-Repo arbeiten.
Slion
6

Ich habe die Antworten gelesen und dies getan:

cd repos
mv .git repos.git
cd repos.git
git config --bool core.bare true # from another answer
cd ../
mv repos.git ../
cd ../
rm -rf repos/ # or delete using a file manager if you like

Dadurch bleibt der Inhalt repos/.gitunverändertrepos.git

Dan D.
quelle
4

Folgendes halte ich für am sichersten und einfachsten. Es gibt hier nichts, was oben nicht angegeben ist. Ich möchte nur eine Antwort sehen, die ein sicheres schrittweises Verfahren zeigt. Sie starten einen Ordner aus dem Repository (Repo), das Sie entblößen möchten. Ich habe die oben implizierte Konvention übernommen, dass nackte Repository-Ordner die Erweiterung .git haben.

(1) Backup, just in case.
    (a) > mkdir backup
    (b) > cd backup
    (c) > git clone ../repo
(2) Make it bare, then move it
    (a) > cd ../repo
    (b) > git config --bool core.bare true
    (c) > mv .git ../repo.git
(3) Confirm the bare repository works (optional, since we have a backup)
    (a) > cd ..
    (b) > mkdir test
    (c) > cd test
    (d) > git clone ../repo.git
(4) Clean up
    (a) > rm -Rf repo
    (b) (optional) > rm -Rf backup/repo
    (c) (optional) > rm -Rf test/repo
sdesciencelover
quelle
1
Dies ist nicht wirklich sicherer, da Sie Ihr Backup mit dem Git-Klon erstellt haben. Durch das Sichern durch Klonen gehen einige Konfigurationen verloren, die in bestimmten Fällen für das Repository von entscheidender Bedeutung sein können.
Lie Ryan
Notiert. Die einzigen Konfigurationen, die mir jemals wichtig waren, sind global für alle meine lokalen Repositorys.
Sdesciencelover
4

Einfach lesen

Pro Git Book: 4.2 Git auf dem Server - Git auf einem Server herunterladen

was darauf hinausläuft

$ git clone --bare my_project my_project.git
Cloning into bare repository 'my_project.git'...
done.

Dann lege my_project.git auf den Server

Was hauptsächlich ist, welche Antwort # 42 versuchte darauf hinzuweisen. Sicher könnte man das Rad neu erfinden ;-)

apos
quelle
Ich verstehe nicht, was diese Antwort hinzufügt, was in keiner der anderen Antworten (einschließlich der herabgestimmten) in beliebiger Länge diskutiert wurde . Kannst du das bitte klären? (Übrigens: Im Pro Git Book heißt es: "Dies entspricht in etwa etwas wie ..." , und diese genaue grobe Äquivalenz wird auch hier bereits erörtert.)
Boldewyn,
3

Hier ist eine kleine BASH-Funktion, die Sie Ihrem .bashrc- oder .profile auf einem UNIX-basierten System hinzufügen können. Nach dem Hinzufügen wird die Shell entweder neu gestartet oder die Datei wird über einen Aufruf von source ~/.profileoder neu geladen source ~/.bashrc.

function gitToBare() {
  if [ -d ".git" ]; then
    DIR="`pwd`"
    mv .git ..
    rm -fr *
    mv ../.git .
    mv .git/* .
    rmdir .git

    git config --bool core.bare true
    cd ..
    mv "${DIR}" "${DIR}.git"

    printf "[\x1b[32mSUCCESS\x1b[0m] Git repository converted to "
    printf "bare and renamed to\n  ${DIR}.git\n"
    cd "${DIR}.git"
  else
    printf "[\x1b[31mFAILURE\x1b[0m] Cannot find a .git directory\n"
  fi
}

Nach dem Aufruf in einem Verzeichnis mit einem .git-Verzeichnis werden die entsprechenden Änderungen vorgenommen, um das Repository zu konvertieren. Wenn beim Aufruf kein .git-Verzeichnis vorhanden ist, wird eine FAILURE-Meldung angezeigt und es werden keine Änderungen am Dateisystem vorgenommen.

Nyteshade
quelle
1

Die Methoden zum Entfernen von Dateien und zum Verschieben des .git-Verzeichnisses sind nicht sauber und verwenden nicht die "git" -Methode, um etwas zu tun, das einfach sein sollte. Dies ist die sauberste Methode, die ich gefunden habe, um ein normales Repo in ein nacktes Repo umzuwandeln.

Klonen Sie zuerst / path / to / normal / repo in ein nacktes Repo namens repo.git

git clone --bare /path/to/normal/repo

Entfernen Sie als Nächstes den Ursprung, der auf / path / to / normal / repo zeigt

cd repo.git
git remote rm origin

Schließlich können Sie Ihr ursprüngliches Repo entfernen. Sie könnten repo.git an diesem Punkt in repo umbenennen, aber die Standardkonvention zur Kennzeichnung eines git-Repositorys ist etwas.git, also würde ich es persönlich so lassen.

Sobald Sie dies alles getan haben, können Sie Ihr neues Bare-Repo klonen (wodurch praktisch ein normales Repo erstellt wird und Sie es auch von Bare in Normal konvertieren würden).

Wenn Sie andere Upstreams haben, sollten Sie diese natürlich notieren und Ihr Bare-Repo aktualisieren, um es einzuschließen. Aber auch hier kann alles mit dem Befehl git erledigt werden. Denken Sie daran, die Manpages sind Ihr Freund.

krux
quelle
1
Haben Sie sich die Mühe gemacht, die anderen Antworten zu lesen? Besonders der Kommentar von @ jonescb und @ nosatalian dazu? Die "git" -Methode lautet: "Machen Sie so viel wie möglich mit Klartextdateien". Sie sollten die Interna eines .gitOrdners untersuchen. Es ist sehr lehrreich zu lernen, wie die Teile zusammenpassen.
Boldewyn
1

Falls Sie ein Repository mit wenigen lokal ausgecheckten Zweigen / refs / Heads / * und wenigen Remote-Zweigstellen-Remotes / origin / * haben UND dies in ein BARE-Repository mit allen Zweigen in / refs / Heads / * konvertieren möchten.

Sie können Folgendes tun, um den Verlauf zu speichern.

  1. Erstellen Sie ein nacktes Repository
  2. CD in das lokale Repository mit lokalen ausgecheckten Zweigen und entfernten Zweigen
  3. Git Push / Pfad / zu / Bare / Repo + Refs / Fernbedienungen / Ursprung / : Refs / Köpfe /
Senthil A Kumar
quelle
0

Ich habe das folgende Skript verwendet, um eine Textdatei zu lesen, die eine Liste aller meiner SVN-Repos enthält, und sie in GIT zu konvertieren. Später habe ich git clone --bare verwendet, um sie in ein nacktes Git-Repo zu konvertieren

#!/bin/bash
file="list.txt"
while IFS= read -r repo_name
do
 printf '%s\n' "$repo_name"
 sudo git svn clone --shared --preserve-empty-dirs --authors-file=users.txt file:///programs/svn/$repo_name 
 sudo git clone --bare /programs/git/$repo_name $repo_name.git
 sudo chown -R www-data:www-data $repo_name.git
 sudo rm -rf $repo_name
done <"$file"

list.txt hat das Format

repo1_name
repo2_name

und users.txt hat das Format

(no author) = Prince Rogers <[email protected]>

www-data ist der Benutzer des Apache-Webservers. Zum Übertragen von Änderungen über HTTP ist eine Berechtigung erforderlich

Pedro Vicente
quelle
0

Hier ist die Definition eines nackten Repositorys aus gitglossary :

Ein nacktes Repository ist normalerweise ein Verzeichnis mit dem entsprechenden Namen und dem Suffix .git, das keine lokal ausgecheckte Kopie einer der Dateien enthält, die der Revisionskontrolle unterliegen. Das heißt, alle Git-Verwaltungs- und Steuerdateien, die normalerweise im versteckten .git-Unterverzeichnis vorhanden sind, befinden sich stattdessen direkt im Verzeichnis repository.git, und es sind keine anderen Dateien vorhanden und werden ausgecheckt. Normalerweise stellen Herausgeber öffentlicher Repositories nackte Repositories zur Verfügung.

Ich bin hier angekommen, weil ich mit einem "lokalen Repository" herumgespielt habe und in der Lage sein wollte, alles zu tun, was ich wollte, als wäre es ein Remote-Repository. Ich habe nur rumgespielt und versucht, etwas über Git zu lernen. Ich gehe davon aus, dass dies die Situation für jeden ist, der diese Antwort lesen möchte.

Ich würde für ein Gutachten lieben oder einige spezifische Gegenbeispiele, jedoch scheint es , dass (nach durch einige git - Quellcode wühlen , dass ich gefunden) einfach in die Datei gehen .git/configund Einstellung der Kern Attribut entblößen zu wahren , git lassen Sie tun was auch immer Sie möchten remote mit dem Repository arbeiten. Dh die folgenden Zeilen sollten existieren in .git/config:

[core]
    ...
    bare = true
...

(Dies ist ungefähr das, was der Befehl git config --bool core.bare truetun wird, was wahrscheinlich empfohlen wird, um kompliziertere Situationen zu behandeln.)

Meine Rechtfertigung für diese Behauptung ist, dass es im Git-Quellcode zwei verschiedene Möglichkeiten zu geben scheint, zu testen, ob ein Repo nackt ist oder nicht. Zum einen wird eine globale Variable überprüft is_bare_repository_cfg. Dies wird während einer Einrichtungsphase der Ausführung festgelegt und spiegelt den in der .git/configDatei gefundenen Wert wider . Der andere ist eine Funktion is_bare_repository(). Hier ist die Definition dieser Funktion:

int is_bare_repository(void)
{
    /* if core.bare is not 'false', let's see if there is a work tree */
    return is_bare_repository_cfg && !get_git_work_tree();
} 

Ich habe nicht die Zeit noch Know - how , das zu sagen mit absoluter Sicherheit, aber soweit ich könnte sagen , wenn Sie das haben bareAttribut Satz truein .git/config, soll dies immer wieder zurückkehren 1. Der Rest der Funktion ist wahrscheinlich für die folgende Situation:

  1. core.bare ist undefiniert (dh weder wahr noch falsch)
  2. Es gibt keinen Arbeitsbaum (dh das Unterverzeichnis .git ist das Hauptverzeichnis).

Ich werde später damit experimentieren, aber dies scheint darauf hinzudeuten, dass das Setzen von core.bare = true dem Entfernen von core.bare aus der Konfigurationsdatei und dem ordnungsgemäßen Einrichten der Verzeichnisse entspricht.

Wenn Sie core.bare = true setzen , können Sie auf jeden Fall darauf zugreifen , aber ich bin mir nicht sicher, ob das Vorhandensein von Projektdateien dazu führen wird, dass einige andere Vorgänge schief gehen. Es ist interessant und ich nehme an, lehrreich, in das Repository zu pushen und zu sehen, was lokal passiert ist (dh ausführen git statusund die Ergebnisse verstehen).

Nathan Chappell
quelle
-1

Zunächst backupIhr bestehendes Repo:

(a)  mkdir backup

(b)  cd backup

(c)  git clone non_bare_repo

Führen Sie zweitens Folgendes aus:

git clone --bare -l non_bare_repo new_bare_repo
Shaks
quelle
Wofür ist der Zwischenklon?
Stabledog
-4

Oneliner für alle oben genannten Vorgänge:

for i in `ls -A .`; do if [ $i != ".git" ]; then rm -rf $i; fi; done; mv .git/* .; rm -rf .git; git config --bool core.bare true

(Beschuldige mich nicht, wenn etwas explodiert und du keine Backups hattest: P)

Tarmo
quelle
-9

Wow, es ist einfach erstaunlich, wie viele Leute sich darauf eingelassen haben, besonders wenn man bedenkt, dass es nicht so aussieht, als würde kein einziger aufhören zu fragen, warum diese Person tut, was sie tut.

Der EINZIGE Unterschied zwischen einem nackten und einem nicht nackten Git-Repository besteht darin, dass die nicht nackte Version eine Arbeitskopie enthält. Der Hauptgrund, warum Sie ein nacktes Repo benötigen würden, ist, wenn Sie es einem Dritten zur Verfügung stellen möchten, können Sie nicht direkt daran arbeiten, sodass Sie es irgendwann klonen müssen, an welchem ​​Punkt Sie sich befinden gleich wieder zu einer regulären Arbeitskopie.

Um in ein nacktes Repo umzuwandeln, müssen Sie lediglich sicherstellen, dass keine Commits ausstehen, und dann einfach:

rm -R * && mv .git/* . && rm -R .git

Los geht's, nacktes Repo.

Justin Buser
quelle
11
Dies wird es nicht bloß genug machen. Versuchen Sie es hineinzuschieben. Sie müssen auch tun git config core.bare true.
Antony Hatchkins
Ich habe nicht downvote, aber ich nur , dass der erste Teil dieser Antwort darauf hin wollte, der erklärt , warum Sie mit einem nackten Repo wollen würde gegen eine nicht-bare ist ok , aber es ist nicht genug , um technische Details enthält, und kann leicht ungenau sein. Jedoch , für den zweiten Teil Ihrer Antwort, während die Befehle Ihre Repo richteten bis sein bloß, Anthony ist richtig , Sie noch festlegen müssen git config core.bare true, so wie in dieser Antwort .