Come convertire un normale repository Git in uno nudo?


603

Come posso convertire un repository Git 'normale' in uno nudo?

La differenza principale sembra essere:

  • nel normale repository Git, .gitall'interno del repository è presente una cartella contenente tutti i dati rilevanti e tutti gli altri file che compongono la copia di lavoro

  • in un repository Git nudo, non esiste una copia funzionante e la cartella (chiamiamola repo.git) contiene i dati effettivi del repository


16
Presumibilmente questo è un metodo più breve:mv repo/.git repo.git; rm -rf repo
jameshfisher,

Sì vero. Quando ho scritto la domanda, questo era solo il frammento della mia storia, che ho eseguito l'altro minuto.
Boldewyn,

54
@eegg Usa &&invece che ;nel caso mvfallisca!

Risposte:


610

In breve: sostituire il contenuto di repocon il contenuto di repo/.git, quindi dire al repository che ora è un repository nudo.

Per fare ciò, eseguire i seguenti comandi:

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

Si noti che questo è diverso dal fare un git clone --barein una nuova posizione (vedi sotto).


9
Grazie per il suggerimento a core.bare. Ora, dopo aver cercato su
Google

14
Grazie! Questo mi sembra più pulito: mv repo / .git repo.git && rm -rf repo && cd repo.git && git config --bool core.bare true
JasonWoof

56
Questo è molto più complicato e fragile della risposta di seguito ( git clone --bare /path/to/repo).
DJ

7
rmPotrebbe essere necessario quel comando * \.[!.]*piuttosto che *per rimuovere dot-file e dot-directory.
minopret,

6
@Ciantic: Ancora una volta, come ho già spiegato nel mio commento sopra, la mia risposta è stata data 3 anni fa, ma 5 mesi fa qualcuno ha modificato la domanda in qualcosa di completamente diverso. Nessuno delle risposte in questa pagina farà qualsiasi più senso. Quella sequenza di comandi è stata copiata direttamente dalla domanda, ho appena aggiunto le ultime due righe.
Jörg W Mittag,

244

Il tuo metodo sembra funzionare; la struttura dei file di un repository nudo è esattamente ciò che si trova all'interno della directory .git. Ma non so se qualcuno dei file sia effettivamente cambiato, quindi se ciò fallisce, puoi semplicemente farlo

git clone --bare /path/to/repo

Probabilmente dovrai farlo in una directory diversa per evitare un conflitto di nomi, quindi puoi semplicemente spostarlo di nuovo nel punto desiderato. E potrebbe essere necessario modificare il file di configurazione in modo che punti ovunque sia il repository di origine.


50
Sbagliato, questo metodo non è l'equivalente. Fare un clone non conserva le opzioni di configurazione, che possono essere fondamentali per il corretto funzionamento come se si utilizzasse git-p4. Inoltre, un clone distrugge i telecomandi, sempre con qualcosa come git-p4 perdi il ramo p4 / master quando cloni, quindi è preferibile l'approccio sopra.
nosataliano,

26
Ma puoi trasferire facilmente le opzioni di configurazione copiando le rispettive parti del file di configurazione. Considererei comunque questo metodo più pulito rispetto alla copia e alla ridenominazione manuale dei file.
Philipp,

6
Questo è perfetto dopo una migrazione di sovversione poiché git-svn non ha il supporto per --bare.
Keyo,

11
Per evitare il conflitto di nomi ---git clone --bare /path/to/repo.git /path/to/newbarerepo.git
raksja,

Funziona finché si esegue git update-server-infoil repository nudo dopo la creazione.
ACK_stoverflow il

116

Penso che il seguente link sarebbe utile

GitFaq: Come posso rendere nudo il repository non nudo esistente?

$ mv repo/.git repo.git
$ git --git-dir=repo.git config core.bare true
$ rm -rf repo

2
Sì, è proprio quello che ho cercato, grazie! Tuttavia, la loro seconda proposta ( git clone) presenta gli svantaggi che il nosatalian ha menzionato sopra.
Boldewyn,

1
La documentazione che hai suggerito prosegue dicendo: "Un metodo più sicuro è lasciare che Git gestisca tutte le impostazioni interne per te facendo qualcosa del genere ... git clone --bare -l <path_to_repos> <new_dir>"
dafunker

74

A meno che non si desideri o non sia necessario modificare i bit nel filesystem, è davvero semplice creare una versione non elaborata di un repository non bare (menzionato in molti altri post qui). Fa parte delle funzionalità principali di git:

git clone --bare existing_repo_path bare_repo_path


6
È sorprendente che la risposta migliore in assoluto abbia 0 voti dopo> 4 mesi. La "risposta accettata" non molto buona ma pericolosa ha 200!
Stabledog,

36
Non è affatto sorprendente - questa risposta non fa ciò che la domanda originale ha posto. Non converte un repository, ne clona uno, perdendo informazioni nel processo (ad esempio filiali remote).
GreenAsJade l'

15

Si prega di considerare anche di usare

git clone --mirror path_to_source_repository

Dalla documentazione :

Imposta un mirror del repository di origine. Questo implica --bare. Rispetto a --bare, --mirror non solo mappa i rami locali della sorgente sui rami locali del bersaglio, ma mappa tutti i riferimenti (inclusi rami di rilevamento remoto, note ecc.) E imposta una configurazione refspec in modo tale che tutti questi riferimenti vengono sovrascritti da un aggiornamento remoto git nel repository di destinazione.


Sembra che questo sia il modo più conciso, completo e sicuro per fare ciò che l'OP vuole (piuttosto che giusto clone). Mi sto perdendo qualcosa? È stata --mirrorun'aggiunta relativamente recente?
Craig Silver,

@CraigSilver: No, come vedo nella cronologia della documentazione in una forma del genere --mirrorè disponibile dalla versione 1.7, quindi già piuttosto lunga. Puoi dare un'occhiata qui
Jacek Krawczyk il

7

Volevo solo passare a un repository su un percorso di rete, ma git non mi avrebbe permesso di farlo a meno che quel repository non fosse contrassegnato come nudo. Tutto ciò di cui avevo bisogno era di cambiarne la configurazione:

git config --bool core.bare true

Non è necessario giocherellare con i file a meno che non si desideri mantenerlo pulito.


3
Ciò è pericoloso quando si desidera lavorare anche sull'albero di lavoro del repository remoto. È probabile che prima o poi ripristini una modifica semplicemente perché l'albero di lavoro e l'indice remoti non erano sincronizzati con il repository. Non consiglio questa soluzione, se non sai esattamente cosa stai facendo.
Boldewyn,

È vero, non dovresti lavorare sull'albero del repository nudo remoto.
Slion

6

ho letto le risposte e ho fatto questo:

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

questo lascerà il contenuto di repos/.gitcome nudorepos.git


4

Ecco cosa penso sia il più sicuro e semplice. Non c'è nulla qui non indicato sopra. Voglio solo vedere una risposta che mostri una procedura passo-passo sicura. Si avvia una cartella dal repository (repository) che si desidera mettere a nudo. Ho adottato la convenzione implicita sopra che le cartelle di repository nude hanno un'estensione .git.

(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

1
questo non è molto più sicuro da quando hai effettuato il backup usando git clone. Il backup mediante clonazione comporta la perdita di alcune configurazioni, che in alcuni casi potrebbero essere fondamentali per il repository.
Lie Ryan,

Notato. Le uniche configurazioni che mi sono mai preoccupate sono globali per tutti i miei repository locali.
sdesciencelover,

4

Basta leggere

Pro Git Book: 4.2 Git sul server - Ottenere Git su un server

che si riduce a

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

Quindi metti my_project.git sul server

Che è principalmente, quale risposta # 42 ha cercato di sottolineare. Sicuramente si potrebbe reinventare la ruota ;-)


Non riesco a vedere cosa aggiunge questa risposta, che non è stata discussa in modo arbitrario in nessuna delle altre risposte in circolazione (incluso il voto negativo). Potresti chiarire, per favore? (A proposito: il Pro Git Book dice "Questo è approssimativamente equivalente a qualcosa di simile a ..." , e anche questa esatta equivalenza approssimativa è già discussa qui.)
Boldewyn,

3

Ecco una piccola funzione BASH che puoi aggiungere al tuo .bashrc o .profile su un sistema basato su UNIX. Una volta aggiunto e la shell viene riavviata o il file viene ricaricato tramite una chiamata a source ~/.profileo 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
}

Una volta chiamato in una directory contenente una directory .git, apporterà le modifiche appropriate per convertire il repository. Se non è presente alcuna directory .git quando viene chiamato, verrà visualizzato un messaggio FAILURE e non si verificheranno modifiche al file system.


1

I metodi che dicono di rimuovere i file e di muoversi con lo spostamento della directory .git non sono puliti e non usare il metodo "git" per fare qualcosa che dovrebbe essere semplice. Questo è il metodo più pulito che ho trovato per convertire un normale repository in un repository nudo.

Primo clone / percorso / a / normale / repository in un repository nudo chiamato repo.git

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

Quindi rimuovere l'origine che punta a / path / to / normal / repo

cd repo.git
git remote rm origin

Finalmente puoi rimuovere il tuo repository originale. A quel punto potresti rinominare repo.git in repo, ma la convenzione standard per indicare un repository git è qualcosa di git, quindi lo lascerei personalmente in quel modo.

Una volta fatto tutto ciò, puoi clonare il tuo nuovo repository nudo (che in effetti crea un repository normale, ed è anche il modo in cui lo convertiresti da nudo a normale)

Naturalmente se hai altri upstream, ti consigliamo di prenderne nota e aggiornare il tuo repository nudo per includerlo. Ma ancora una volta, tutto può essere fatto con il comando git. Ricorda che le pagine man sono tue amiche.


1
Ti sei preso la briga di leggere le altre risposte? Soprattutto il commento di @ jonescb e @ nosatalian? Il metodo "git" è questo: "Fai il più possibile con file di testo semplice". Dovresti iniziare a esaminare gli interni di una .gitcartella. È altamente istruttivo imparare come si adattano le parti.
Boldewyn,

1

Nel caso in cui si disponga di un repository con poche filiali / refs / heads / * di checkout locali e pochi telecomandi / origini / filiali di filiali remote e * se si desidera convertirlo in un repository BARE con tutte le filiali in / refs / heads / *

puoi fare quanto segue per salvare la cronologia.

  1. creare un repository nudo
  2. cd nel repository locale che ha filiali di checkout locali e filiali remote
  3. git push / path / to / bare / repo + refs / telecomandi / origin / : refs / heads /

0

Ho usato il seguente script per leggere un file di testo che ha un elenco di tutti i miei repository SVN e convertirli in GIT, e successivamente utilizzare git clone --bare per convertire in un repository git nudo

#!/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 ha il formato

repo1_name
repo2_name

e users.txt ha il formato

(no author) = Prince Rogers <prince.rogers.nelson@payesley.park.org>

www-data è l'utente del web server Apache, è necessaria l'autorizzazione per inviare le modifiche su HTTP


0

Ecco la definizione di un repository nudo da gitglossary :

Un repository nudo è normalmente una directory denominata in modo appropriato con un suffisso .git che non ha una copia estratta localmente di nessuno dei file sotto controllo di revisione. Cioè, tutti i file amministrativi e di controllo di Git che normalmente sarebbero presenti nella sottodirectory nascosta .git sono invece direttamente presenti nella directory repository.git e nessun altro file è presente e estratto. Di solito gli editori di repository pubblici rendono disponibili repository nudi.

Sono arrivato qui perché stavo giocando con un "repository locale" e volevo essere in grado di fare tutto quello che volevo come se fosse un repository remoto. Stavo solo giocando, provando a conoscere git. Presumo che questa sia la situazione per chiunque voglia leggere questa risposta.

Mi piacerebbe per una perizia o alcuni specifici esempi contrari, tuttavia sembra che (dopo rovistando tra qualche codice sorgente git che ho trovato) semplicemente andando al file .git/confige l'impostazione del nucleo attributo nudo al vero , git vi permetterà di fare tutto ciò che vuoi fare da remoto sul repository. Vale a dire le seguenti righe dovrebbero esistere in .git/config:

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

(Questo è approssimativamente ciò che git config --bool core.bare truefarà il comando , che è probabilmente raccomandato per affrontare situazioni più complicate)

La mia giustificazione per questa affermazione è che, nel codice sorgente di git, sembrano esserci due modi diversi di testare se un repository è nudo o no. Uno è controllando una variabile globale is_bare_repository_cfg. Questo viene impostato durante alcune fasi di configurazione dell'esecuzione e riflette il valore trovato nel .git/configfile. L'altra è una funzione is_bare_repository(). Ecco la definizione di questa funzione:

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();
} 

Non ho il tempo né le competenze per dirlo con assoluta sicurezza, ma per quanto ho potuto dire se avete la bareset di attributi a truein .git/config, questo deve sempre tornare 1. Il resto della funzione è probabilmente per la seguente situazione:

  1. core.bare non è definito (ovvero né vero né falso)
  2. Non esiste worktree (ovvero la sottodirectory .git è la directory principale)

Ci proverò quando potrò più tardi, ma questo sembrerebbe indicare che l'impostazione core.bare = true equivale a rimuovere core.bare dal file di configurazione e impostare correttamente le directory.

Ad ogni modo, l'impostazione di core.bare = true certamente ti consentirà di spingerlo verso di esso, ma non sono sicuro che la presenza di file di progetto causerà alcune altre operazioni. È interessante e suppongo che sia istruttivo spingere nel repository e vedere cosa è successo a livello locale (ovvero eseguire git statuse dare un senso ai risultati).


-1

Innanzitutto, il backuptuo repository esistente:

(a)  mkdir backup

(b)  cd backup

(c)  git clone non_bare_repo

In secondo luogo, eseguire quanto segue:

git clone --bare -l non_bare_repo new_bare_repo

A cosa serve il clone intermedio?
Stabledog,

-4

Oneliner per eseguire tutte le operazioni di cui sopra:

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

(non incolparmi se qualcosa esplode e non hai avuto i backup: P)


-9

Wow, è semplicemente incredibile quante persone hanno reagito, soprattutto considerando che non sembra che nessuno si sia fermato a chiedere perché questa persona sta facendo quello che sta facendo.

L'unica differenza tra un repository git nudo e non nudo è che la versione non nuda ha una copia funzionante. Il motivo principale per cui avresti bisogno di un repository nudo è se volevi renderlo disponibile a una terza parte, non puoi effettivamente lavorarci direttamente, quindi a un certo punto dovrai clonarlo a quel punto tornando a una normale versione di copia funzionante.

Detto questo, per convertire in un repository nudo tutto ciò che devi fare è assicurarti di non avere impegni in sospeso e quindi solo:

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

Ecco qua, nudo repo.


11
Questo non lo renderà abbastanza nudo. Prova a spingerti dentro. Devi fare git config core.bare trueanche tu .
Antony Hatchkins,

Non ho votato in negativo, ma volevo solo sottolineare che la prima parte di questa risposta che spiega il motivo per cui si vorrebbe un repository nudo vs uno non nudo è ok , sebbene non contenga dettagli tecnici sufficienti e potrebbe essere leggermente impreciso. Tuttavia , per la seconda parte della tua risposta, mentre quei comandi configurano il tuo repository in modo che sia nudo, Anthony ha ragione , devi comunque impostare git config core.bare true, proprio come in questa risposta .
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.