644 votes

Comment cloner dans un répertoire non vide ?

J'ai un répertoire A avec des fichiers correspondant au répertoire B. Le répertoire A peut contenir d'autres fichiers nécessaires. Le répertoire B est un dépôt git.

Je veux cloner le répertoire B vers le répertoire A mais git-clone ne me le permet pas car le répertoire n'est pas vide.

J'espérais qu'il suffirait de cloner .git et que, puisque tous les fichiers correspondent, je pourrais partir de là ?

Je ne peux pas cloner dans un répertoire vide car j'ai des fichiers dans le répertoire A qui ne sont pas dans le répertoire B et je veux les garder.

Copier .git n'est pas une option puisque je veux des références pour pousser/tirer avec et je ne veux pas les configurer manuellement.

Y a-t-il un moyen de le faire ?

Mise à jour : Je pense que cela fonctionne, quelqu'un peut-il voir des problèmes ? -->

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

7 votes

Peut-être pourriez-vous modifier la réponse acceptée ?

0 votes

Je me demande ce qui se passerait si l'option '--no-checkout' était omise, sauf que le clone temporaire consomme plus d'espace disque et de temps. Est-ce que "git unstage" ou autre chose serait toujours nécessaire ?

799voto

Casey Points 19286

Cela a marché pour moi :

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

NOTE : -t va définir la branche amont pour vous, si c'est ce que vous voulez, et c'est généralement le cas.

2 votes

J'utilise cette méthode, elle fonctionne très bien ! Une remarque, l'option -t devrait être --track, qui n'est pas dans l'aperçu mais dans les détails de ; git help checkout. git-scm.com/docs/git-checkout

77 votes

Cela ne fonctionne pas dans un répertoire non vide lorsque les fichiers entrants existent déjà (comme le décrit la question originale). Mais si vous git reset origin/master après le git fetch il fonctionnera (en préservant également toutes les modifications locales).

2 votes

C'est la réponse la plus sûre et la plus logique.

177voto

Dale Forester Points 2542

Dans les commandes shell suivantes existing-dir est un répertoire dont le contenu correspond aux fichiers suivis dans le fichier repo-to-clone Dépôt 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 votes

J'avais besoin de faire git reset --hard HEAD ou il ne voulait pas abandonner les fichiers "supprimés".

20 votes

git reset HEAD a bien fonctionné pour moi. git reset --hard HEAD détruit toutes les modifications de vos fichiers, donc s'ils ne sont pas exactement les mêmes que ceux du dépôt, vous ne devriez pas le faire.

1 votes

git reset HEAD ne semble pas avoir d'effet pour moi. git reset --hard HEAD le fait - mais cela perd toutes les modifications que vous avez apportées aux fichiers. Existe-t-il une meilleure solution ?

26voto

BjornSnoen Points 193

Voici ce que j'ai fini par faire lorsque j'ai eu le même problème (du moins je pense que c'est le même problème). Je suis allé dans le répertoire A et j'ai exécuté git init .

Comme je ne voulais pas que les fichiers du répertoire A soient suivis par git, j'ai édité .gitignore et j'y ai ajouté les fichiers existants. Après cela, j'ai lancé git remote add origin '<url>' && git pull origin master et voíla, B est "cloné" en A sans le moindre accroc.

3 votes

Cette technique ne fonctionne pas dans un répertoire non vide lorsque les fichiers entrants existent déjà (comme le décrit la question originale).

5voto

Roberto Aloi Points 13132

Peut-être ai-je mal compris votre question, mais ne serait-il pas plus simple de copier/déplacer les fichiers de A vers le dépôt git B et d'ajouter les fichiers nécessaires avec git add ?

MISE À JOUR : De la doc git :

Le clonage dans un répertoire existant n'est autorisé que si le répertoire est vide.

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

2 votes

Non, le propriétaire et les fichiers pourraient être arbitraires. Ceci est pour une situation avec plusieurs développeurs. Nous avons tous des répertoires existants et un seul a actuellement un checkout git. Nous avons tous largement le même sous-ensemble de fichiers et nous voulons que les autres développeurs puissent cloner tout en conservant leurs fichiers. Et cela doit être aussi élégant et pratique que possible.

0 votes

Honnêtement, je ne vois pas l'intérêt de se développer dans de telles conditions. Ne pouvez-vous pas utiliser les branches et les opérations de fusion ? Ou avoir des sous-référentiels avec des dépendances externes ? Pourquoi vouloir se reposer sur un seul "git checkout" ?

5 votes

Un "single git checkout" n'est pas le but de tout cela. C'est juste que c'est comme ça et que nous avons besoin d'un moyen d'avancer. J'ai mis à jour la question originale avec une solution qui semble fonctionner. J'apprécie les commentaires, cependant.

3voto

Lendrick Points 762

Je cherchais quelque chose de similaire, et voici ce que j'ai trouvé :

Dans ma situation, j'ai une arborescence web active et j'essaie de créer un référentiel distant pour celle-ci sans déplacer aucun des fichiers de l'arborescence web actuelle. Voici ce que j'ai fait :

  1. Allez dans l'arbre web et exécutez git init
  2. Allez à l'emplacement prévu du référentiel et exécutez : git clone --bare /path/to/web/repo
  3. Modifiez le fichier de configuration dans mon dépôt distant et supprimez l'élément suivant [remote "origin"] section.
  4. Ajouter un [remote "origin"] à .git/config dans l'arborescence web pointant vers le nouveau dépôt distant.

0 votes

J'aime beaucoup cette recette.

0 votes

Le site git clone --bare ici est superflue et détournée. Pourquoi ne pas simplement git remote add origin <URL> en premier lieu ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X