Comment importer un référentiel Git existant dans un autre?


477

J'ai un référentiel Git dans un dossier appelé XXX et j'ai un deuxième référentiel Git appelé YYY .

Je souhaite importer le référentiel XXX dans le référentiel YYY en tant que sous-répertoire nommé ZZZ et ajouter tout l' historique des modifications de XXX à YYY .

Structure des dossiers avant:

├── XXX
│   ├── .git
│   └── (project files)
└── YYY
    ├── .git
    └── (project files)

Structure des dossiers après:

YYY
├── .git  <-- This now contains the change history from XXX
├──  ZZZ  <-- This was originally XXX
│    └── (project files)
└──  (project files)

Cela peut-il être fait ou dois-je recourir à des sous-modules?


2
Sur Github, il est désormais possible de le faire à partir de l'interface Web lorsque vous créez un nouveau
référentiel

Réponses:


430

La façon la plus simple serait probablement de tirer le truc XXX dans une branche en YYY puis de le fusionner dans master:

En AAAA :

git remote add other /path/to/XXX
git fetch other
git checkout -b ZZZ other/master
mkdir ZZZ
git mv stuff ZZZ/stuff                      # repeat as necessary for each file/dir
git commit -m "Moved stuff to ZZZ"
git checkout master                
git merge ZZZ --allow-unrelated-histories   # should add ZZZ/ to master
git commit
git remote rm other
git branch -d ZZZ                           # to get rid of the extra branch before pushing
git push                                    # if you have a remote, that is

En fait, je viens d'essayer cela avec quelques-uns de mes repos et cela fonctionne. Contrairement à la réponse de Jörg, cela ne vous permettra pas de continuer à utiliser l'autre dépôt, mais je ne pense pas que vous l'ayez spécifié de toute façon.

Remarque: Puisque cela a été écrit à l'origine en 2009, git a ajouté la fusion de sous-arborescence mentionnée dans la réponse ci-dessous. J'utiliserais probablement cette méthode aujourd'hui, même si bien sûr cette méthode fonctionne toujours.


1
Merci. J'ai utilisé une version légèrement modifiée de votre technique: j'ai créé une branche de «mise en scène» sur XXX où j'ai créé le dossier ZZZ et y ai déplacé le «truc». Puis j'ai fusionné XXX en YYY.
Vijay Patel

1
Cela a très bien fonctionné pour moi. Les seules modifications que j'ai apportées ont été: 1) "git branch -d ZZZ" avant le push car je ne voulais pas que cette branche temporaire traîne. 2) "git push" me donnait l'erreur: "Aucune référence en commun et aucune spécifiée; ne rien faire. Peut-être devriez-vous spécifier une branche telle que 'master'." (L'origine vers laquelle je poussais était un référentiel vide vide.) Mais "git push --all" fonctionnait comme un champion.
CrazyPyro

1
Je voulais me retrouver avec uniquement le dossier ZZZ plus l'historique dans le repo YYY: je voulais supprimer le repo XXX d'origine et la branche ZZZ dans le repo YYY. J'ai trouvé la suppression de la branche ZZZ car @CrazyPyro a suggéré de supprimer l'historique - pour le conserver, j'ai fusionné la branche ZZZ en maître avant de la supprimer.
Oli Studholme

4
@SebastianBlask Je viens de déconner avec deux de mes repos et j'ai réalisé qu'il y avait une étape manquante que personne n'a jamais semblé remarquer, malgré mes votes positifs depuis des années. :-) J'ai mentionné sa fusion en master, mais je ne l'ai pas montré. Le
modifier

2
vous pouvez ajouter quelque chose comme ça, lorsque vous déplacez des fichiers vers votre sous-dossier: git mv $(ls|grep -v <your foldername>) <your foldername>/ cela copiera tous les fichiers et dossiers dans votre nouveau dossier
serup

367

Si vous souhaitez conserver l'historique de validation exact du deuxième référentiel et donc conserver la possibilité de fusionner facilement les modifications en amont à l'avenir, voici la méthode que vous souhaitez. Il en résulte un historique non modifié de la sous-arborescence importée dans votre référentiel plus un commit de fusion pour déplacer le référentiel fusionné vers le sous-répertoire.

git remote add XXX_remote <path-or-url-to-XXX-repo>
git fetch XXX_remote
git merge -s ours --no-commit --allow-unrelated-histories XXX_remote/master
git read-tree --prefix=ZZZ/ -u XXX_remote/master
git commit -m "Imported XXX as a subtree."

Vous pouvez suivre les modifications en amont comme suit:

git pull -s subtree XXX_remote master

Git détermine par lui-même où se trouvent les racines avant d'effectuer la fusion, vous n'avez donc pas besoin de spécifier le préfixe lors des fusions suivantes.

L' inconvénient est que dans l'historique fusionné, les fichiers ne sont pas préfixés (pas dans un sous-répertoire). En conséquence git log ZZZ/a, vous montrera toutes les modifications (le cas échéant), sauf celles de l'historique fusionné. Tu peux faire:

git log --follow -- a

mais cela ne montrera pas les changements autres que dans l'historique fusionné.

En d'autres termes, si vous ne changez pas ZZZles fichiers dans le référentiel XXX, vous devez spécifier --followet un chemin non préfixé. Si vous les modifiez dans les deux référentiels, vous disposez de 2 commandes, dont aucune ne montre toutes les modifications.

Versions Git antérieures à 2.9 : vous n'avez pas besoin de passer l' --allow-unrelated-historiesoption à git merge.

La méthode de l'autre réponse qui utilise read-treeet ignore l' merge -s oursétape n'est en fait pas différente de la copie des fichiers avec cp et de la validation du résultat.

La source d'origine était tirée de l'article d'aide de "Subtree Merge" de github . Et un autre lien utile .


9
cela ne semble pas avoir conservé l'historique ... si je fais un git logsur l'un des fichiers que j'ai récupérés, je vois juste le commit de fusion unique et rien de sa vie précédente dans l'autre dépôt? Git 1.8.0
Anentropic

8
aha! si j'utilise l'ancien chemin du fichier importé, c'est-à-dire en omettant le sous-répertoire dans lequel il a été importé, alors git log me donnera l'historique des validations, par exemple git log -- myfileau lieu degit log -- rack/myfile
Anentropic

2
@FrancescoFrassinelli, n'est-ce pas souhaitable? L'intégration de l'historique est une caractéristique de cette méthode.
patrickvacek

4
@FrancescoFrassinelli, si vous ne voulez pas d'histoire, pourquoi ne pas simplement faire une copie régulière? J'essaie de comprendre ce qui pourrait vous attirer vers cette méthode si ce n'est pour l'histoire - c'est la seule raison pour laquelle j'ai utilisé cette méthode!
patrickvacek

7
Depuis Git 2.9, vous avez besoin de l'option --allow-unrelated-historieslors de la fusion.
stuXnet

113

git-subtreeest un script conçu exactement pour ce cas d'utilisation de fusion de plusieurs référentiels en un seul tout en préservant l'historique (et / ou le fractionnement de l'historique des sous-arbres, bien que cela semble être sans rapport avec cette question). Il est distribué dans le cadre de l'arbre git depuis la version 1.7.11 .

Pour fusionner un référentiel <repo>à la révision en <rev>tant que sous <prefix>- répertoire , utilisez git subtree addcomme suit:

git subtree add -P <prefix> <repo> <rev>

git-subtree implémente la stratégie de fusion des sous-arbres de manière plus conviviale.

Pour votre cas, dans le référentiel YYY, vous exécuteriez:

git subtree add -P ZZZ /path/to/XXX.git master

L' inconvénient est que dans l'historique fusionné, les fichiers ne sont pas préfixés (pas dans un sous-répertoire). En conséquence git log ZZZ/a, vous montrera toutes les modifications (le cas échéant), sauf celles de l'historique fusionné. Tu peux faire:

git log --follow -- a

mais cela ne montrera pas les changements autres que dans l'historique fusionné.

En d'autres termes, si vous ne changez pas ZZZles fichiers dans le référentiel XXX, vous devez spécifier --followet un chemin non préfixé. Si vous les modifiez dans les deux référentiels, vous disposez de 2 commandes, dont aucune ne montre toutes les modifications.

Plus d'informations ici .


4
Si vous avez un répertoire à fusionner au lieu d'un référentiel nu ou distant,git subtree add -P name-of-desired-prefix ~/location/of/git/repo-without-.git branch-name
Tatsh

2
Expérience Noob: git (version 2.9.0.windows.1) répond "fatal: argument ambigu 'HEAD': révision inconnue ou chemin d'accès absent de l'arborescence de travail" lorsque j'ai essayé cela dans un référentiel local, non nu, fraîchement initialisé, Mais cela a bien fonctionné après avoir vraiment lancé le nouveau référentiel, c'est-à-dire après avoir ajouté un fichier brut et validé la manière habituelle.
Stein

A parfaitement fonctionné pour mon scénario.
Johnny Utahh

Oh, c'est fantastique.
dwjohnston

J'ai utilisé la suggestion @Tatsh et cela a fonctionné pour moi
Carmine Tambascia

49

Il existe un exemple bien connu de cela dans le référentiel Git lui-même, qui est collectivement connu dans la communauté Git comme " la fusion la plus cool jamais " (après la ligne d'objet Linus Torvalds utilisée dans l'e-mail à la liste de diffusion Git qui décrit cela fusionner). Dans ce cas, l' gitkinterface graphique Git qui fait maintenant partie de Git proprement dit, était en fait un projet distinct. Linus a réussi à fusionner ce référentiel dans le référentiel Git d'une manière qui

  • il apparaît dans le référentiel Git comme s'il avait toujours été développé dans le cadre de Git,
  • toute l'histoire est conservée intacte et
  • il peut encore être développé indépendamment dans son ancien référentiel, avec des modifications simplement git pulléditées.

L'e-mail contient les étapes nécessaires pour se reproduire, mais ce n'est pas pour les âmes sensibles: premièrement, Linus a écrit Git, donc il en sait probablement un peu plus à ce sujet que vous ou moi, et deuxièmement, c'était il y a presque 5 ans et Git s'est considérablement amélioré depuis lors, alors c'est peut-être maintenant beaucoup plus facile.

En particulier, je suppose que de nos jours, on utiliserait un sous-module gitk, dans ce cas spécifique.


3
BTW. la stratégie utilisée pour les fusions ultérieures (s'il y en a) s'appelle fusion de sous-arborescence , et il existe un git-subtreeoutil tiers qui peut vous aider avec ceci: github.com/apenwarr/git-subtree
Jakub Narębski

Merci, j'ai oublié ça. La subtreestratégie de fusion, en particulier conjointement avec l' git-subtreeoutil, est une alternative intéressante, voire supérieure aux sous-modules.
Jörg W Mittag

12

Le moyen le plus simple est d'utiliser git format-patch.

Supposons que nous ayons 2 référentiels git foo et bar .

foo contient:

  • foo.txt
  • .git

la barre contient:

  • bar.txt
  • .git

et nous voulons finir avec foo contenant l' historique de la barre et ces fichiers:

  • foo.txt
  • .git
  • foobar / bar.txt

Donc, pour ce faire:

 1. create a temporary directory eg PATH_YOU_WANT/patch-bar
 2. go in bar directory
 3. git format-patch --root HEAD --no-stat -o PATH_YOU_WANT/patch-bar --src-prefix=a/foobar/ --dst-prefix=b/foobar/
 4. go in foo directory
 5. git am PATH_YOU_WANT/patch-bar/*

Et si nous voulons réécrire toutes les validations de messages à partir de la barre, nous pouvons le faire, par exemple sous Linux:

git filter-branch --msg-filter 'sed "1s/^/\[bar\] /"' COMMIT_SHA1_OF_THE_PARENT_OF_THE_FIRST_BAR_COMMIT..HEAD

Cela ajoutera "[bar]" au début de chaque message de validation.


Si le référentiel d'origine contenait des branches et des fusions, git améchouera probablement.
Adam Monsen

1
Gotcha mineur: git am retire tout ce qui se trouve dans [ ]le message de validation. Vous devez donc utiliser un marqueur différent de celui de[bar]
HRJ

N'a pas travaillé pour moi. Got "error: foobar / mySubDir / test_host1: n'existe pas dans l'index. La copie du correctif qui a échoué se trouve dans: /home/myuser/src/proj/.git/rebase-apply/patch Lorsque vous avez résolu ce problème , exécutez "git am --continue". Ce fut après avoir appliqué 11 patchs (sur 60).
oligofren

1
Ce blog a une réponse similaire à une question quelque peu différente (déplacer uniquement les fichiers sélectionnés).
Jesse Glick

Je vois un inconvénient, tous les commits sont ajoutés à la tête du référentiel cible.
CSchulz

8

Cette fonction clonera le dépôt distant dans le répertoire de dépôt local, après la fusion de tous les validations seront enregistrées, git logaffichera les validations d'origine et les chemins d'accès appropriés:

function git-add-repo
{
    repo="$1"
    dir="$(echo "$2" | sed 's/\/$//')"
    path="$(pwd)"

    tmp="$(mktemp -d)"
    remote="$(echo "$tmp" | sed 's/\///g'| sed 's/\./_/g')"

    git clone "$repo" "$tmp"
    cd "$tmp"

    git filter-branch --index-filter '
        git ls-files -s |
        sed "s,\t,&'"$dir"'/," |
        GIT_INDEX_FILE="$GIT_INDEX_FILE.new" git update-index --index-info &&
        mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"
    ' HEAD

    cd "$path"
    git remote add -f "$remote" "file://$tmp/.git"
    git pull "$remote/master"
    git merge --allow-unrelated-histories -m "Merge repo $repo into master" --edit "$remote/master"
    git remote remove "$remote"
    rm -rf "$tmp"
}

Comment utiliser:

cd current/package
git-add-repo https://github.com/example/example dir/to/save

Si vous apportez quelques modifications, vous pouvez même déplacer les fichiers / répertoires du référentiel fusionné dans différents chemins, par exemple:

repo="https://github.com/example/example"
path="$(pwd)"

tmp="$(mktemp -d)"
remote="$(echo "$tmp" | sed 's/\///g' | sed 's/\./_/g')"

git clone "$repo" "$tmp"
cd "$tmp"

GIT_ADD_STORED=""

function git-mv-store
{
    from="$(echo "$1" | sed 's/\./\\./')"
    to="$(echo "$2" | sed 's/\./\\./')"

    GIT_ADD_STORED+='s,\t'"$from"',\t'"$to"',;'
}

# NOTICE! This paths used for example! Use yours instead!
git-mv-store 'public/index.php' 'public/admin.php'
git-mv-store 'public/data' 'public/x/_data'
git-mv-store 'public/.htaccess' '.htaccess'
git-mv-store 'core/config' 'config/config'
git-mv-store 'core/defines.php' 'defines/defines.php'
git-mv-store 'README.md' 'doc/README.md'
git-mv-store '.gitignore' 'unneeded/.gitignore'

git filter-branch --index-filter '
    git ls-files -s |
    sed "'"$GIT_ADD_STORED"'" |
    GIT_INDEX_FILE="$GIT_INDEX_FILE.new" git update-index --index-info &&
    mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"
' HEAD

GIT_ADD_STORED=""

cd "$path"
git remote add -f "$remote" "file://$tmp/.git"
git pull "$remote/master"
git merge --allow-unrelated-histories -m "Merge repo $repo into master" --edit "$remote/master"
git remote remove "$remote"
rm -rf "$tmp"

Avis
Paths remplace via sed, alors assurez-vous qu'il s'est déplacé dans les chemins appropriés après la fusion.
Le --allow-unrelated-historiesparamètre n'existe que depuis git> = 2.9.


2
Pour les utilisateurs d'OS X, installez-le gnu-sedpour que la git-add-repofonction fonctionne. Merci encore Andrey!
ptaylor

7

Sur la base de cet article , l'utilisation de sous-arbre est ce qui a fonctionné pour moi et seul l'historique applicable a été transféré. Publier ici au cas où quelqu'un aurait besoin des étapes (assurez-vous de remplacer les espaces réservés par des valeurs qui vous concernent):

dans votre sous-dossier de partage de référentiel source dans une nouvelle branche

git subtree split --prefix=<source-path-to-merge> -b subtree-split-result

dans votre référentiel de destination fusionner dans la branche de résultat fractionnée

git remote add merge-source-repo <path-to-your-source-repository>
git fetch merge-source-repo
git merge -s ours --no-commit merge-source-repo/subtree-split-result
git read-tree --prefix=<destination-path-to-merge-into> -u merge-source-repo/subtree-split-result

vérifier vos modifications et vous engager

git status
git commit

N'oubliez pas

Nettoyer en supprimant la subtree-split-resultbranche

git branch -D subtree-split-result

Supprimez la télécommande que vous avez ajoutée pour récupérer les données du référentiel source

git remote rm merge-source-repo


3

Ajouter une autre réponse car je pense que c'est un peu plus simple. Une extraction de repo_dest est effectuée dans repo_to_import puis une URL push --set-upstream: repo_dest master est effectuée.

Cette méthode a fonctionné pour moi en important plusieurs dépôts plus petits dans un plus grand.

Comment importer: repo1_to_import vers repo_dest

# checkout your repo1_to_import if you don't have it already 
git clone url:repo1_to_import repo1_to_import
cd repo1_to_import

# now. pull all of repo_dest
git pull url:repo_dest
ls 
git status # shows Your branch is ahead of 'origin/master' by xx commits.
# now push to repo_dest
git push --set-upstream url:repo_dest master

# repeat for other repositories you want to import

Renommez ou déplacez les fichiers et les répertoires dans la position souhaitée dans le référentiel d'origine avant de procéder à l'importation. par exemple

cd repo1_to_import
mkdir topDir
git add topDir
git mv this that and the other topDir/
git commit -m"move things into topDir in preparation for exporting into new repo"
# now do the pull and push to import

La méthode décrite au lien suivant a inspiré cette réponse. Je l'ai aimé car cela semblait plus simple. Mais méfiez-vous! Il y a des dragons! https://help.github.com/articles/importing-an-external-git-repository git push --mirror url:repo_dest pousse votre historique et état de dépôt local à distance (url: repo_dest). MAIS il supprime l'ancien historique et l'état de la télécommande. Le plaisir s'ensuit! : -E


1

Je voulais importer uniquement certains fichiers de l'autre référentiel (XXX) dans mon cas. Le sous-arbre était trop compliqué pour moi et les autres solutions ne fonctionnaient pas. C'est ce que j'ai fait:

ALL_COMMITS=$(git log --reverse --pretty=format:%H -- ZZZ | tr '\n' ' ')

Cela vous donne une liste séparée par des espaces de toutes les validations qui affectent les fichiers que je voulais importer (ZZZ) dans l'ordre inverse (vous devrez peut-être ajouter --follow pour capturer les renommages également). Je suis ensuite allé dans le référentiel cible (YYY), j'ai ajouté l'autre référentiel (XXX) en tant que distant, j'ai fait une recherche et enfin:

git cherry-pick $ALL_COMMITS

qui ajoute tous les commits à votre branche, vous aurez donc tous les fichiers avec leur historique et pourrez faire ce que vous voudrez avec eux comme s'ils avaient toujours été dans ce référentiel.


1

Voir l' exemple de base dans cet article et envisagez un tel mappage sur les référentiels:

  • A<-> YYY,
  • B <-> XXX

Après toutes les activités décrites dans ce chapitre (après la fusion), supprimez la branche B-master:

$ git branch -d B-master

Ensuite, appuyez sur les modifications.

Ça marche pour moi.


0

J'étais dans une situation où je cherchais -s theirsmais bien sûr, cette stratégie n'existe pas. Mon histoire était que j'avais bifurqué un projet sur GitHub, et maintenant pour une raison quelconque, ma section locale masterne pouvait pas être fusionnée upstream/mastermême si je n'avais apporté aucune modification locale à cette branche. (Je ne sais vraiment pas ce qui s'est passé là-bas - je suppose que l'amont avait fait de grosses poussées en coulisse, peut-être?)

J'ai fini par faire

# as per https://help.github.com/articles/syncing-a-fork/
git fetch upstream
git checkout master
git merge upstream/master
....
# Lots of conflicts, ended up just abandonging this approach
git reset --hard   # Ditch failed merge
git checkout upstream/master
# Now in detached state
git branch -d master # !
git checkout -b master   # create new master from upstream/master

Alors maintenant, my masterest à nouveau synchronisé avec upstream/master(et vous pouvez répéter ce qui précède pour toute autre branche que vous souhaitez également synchroniser de la même manière).


1
Un git reset --hard upstream/mastersur votre masterbranche locale ferait le travail. De cette façon, vous ne perdez pas le conflg de branche locale - des choses comme l'amont par défaut.
tomekwi

0

Je peux suggérer une autre solution (alternative aux sous-modules git ) pour votre problème - outil gil (liens git)

Il permet de décrire et de gérer les dépendances complexes des référentiels git.

Il fournit également une solution au problème de dépendance des sous-modules récursifs git .

Considérez que vous avez les dépendances de projet suivantes: exemple de graphique de dépendance de référentiel git

Ensuite, vous pouvez définir un .gitlinksfichier avec la description de la relation des référentiels:

# Projects
CppBenchmark CppBenchmark https://github.com/chronoxor/CppBenchmark.git master
CppCommon CppCommon https://github.com/chronoxor/CppCommon.git master
CppLogging CppLogging https://github.com/chronoxor/CppLogging.git master

# Modules
Catch2 modules/Catch2 https://github.com/catchorg/Catch2.git master
cpp-optparse modules/cpp-optparse https://github.com/weisslj/cpp-optparse.git master
fmt modules/fmt https://github.com/fmtlib/fmt.git master
HdrHistogram modules/HdrHistogram https://github.com/HdrHistogram/HdrHistogram_c.git master
zlib modules/zlib https://github.com/madler/zlib.git master

# Scripts
build scripts/build https://github.com/chronoxor/CppBuildScripts.git master
cmake scripts/cmake https://github.com/chronoxor/CppCMakeScripts.git master

Chaque ligne décrit le lien git dans le format suivant:

  1. Nom unique du référentiel
  2. Chemin relatif du référentiel (démarré à partir du chemin du fichier .gitlinks)
  3. Référentiel Git qui sera utilisé dans la commande git clone Branche de référentiel pour passer à la caisse
  4. La ligne vide ou la ligne commencée par # n'est pas analysée (traitée comme un commentaire).

Enfin, vous devez mettre à jour votre référentiel racine:

# Clone and link all git links dependencies from .gitlinks file
gil clone
gil link

# The same result with a single command
gil update

En conséquence, vous clonerez tous les projets requis et les lierez les uns aux autres de manière appropriée.

Si vous souhaitez valider toutes les modifications dans un référentiel avec toutes les modifications dans les référentiels liés aux enfants, vous pouvez le faire avec une seule commande:

gil commit -a -m "Some big update"

Les commandes Pull, Push fonctionnent de la même manière:

gil pull
gil push

L'outil Gil (liens git) prend en charge les commandes suivantes:

usage: gil command arguments
Supported commands:
    help - show this help
    context - command will show the current git link context of the current directory
    clone - clone all repositories that are missed in the current context
    link - link all repositories that are missed in the current context
    update - clone and link in a single operation
    pull - pull all repositories in the current directory
    push - push all repositories in the current directory
    commit - commit all repositories in the current directory

En savoir plus sur le problème de dépendance des sous-modules récursifs git .


0

Permettez-moi d'utiliser des noms a(à la place de XXXet ZZZ) et b(à la place de YYY), car cela rend la description un peu plus facile à lire.

Dites que vous souhaitez fusionner dépôt adans b(je suppose qu'ils sont situés à côté de l'autre):

cd a
git filter-repo --to-subdirectory-filter a
cd ..
cd b
git remote add a ../a
git fetch a
git merge --allow-unrelated-histories a/master
git remote remove a

Pour cela, vous devez git-filter-repoinstaller ( filter-branchest déconseillé ).

Un exemple de fusion de 2 grands référentiels, en plaçant l'un d'entre eux dans un sous-répertoire: https://gist.github.com/x-yuri/9890ab1079cf4357d6f269d073fd9731

Plus d'informations ici .


-1

Je ne connais pas de moyen facile de le faire. Vous POUVEZ faire ceci:

  1. Utilisez git filter-branch pour ajouter un super-répertoire ZZZ sur le référentiel XXX
  2. Poussez la nouvelle branche vers le référentiel YYY
  3. Fusionnez la branche poussée avec le tronc de YYY.

Je peux éditer avec des détails si cela semble attrayant.


-2

Je pense que vous pouvez le faire en utilisant «git mv» et «git pull».

Je suis un bon git noob - alors soyez prudent avec votre référentiel principal - mais je viens de l'essayer dans un répertoire temporaire et cela semble fonctionner.

Tout d'abord - renommez la structure de XXX pour qu'elle corresponde à ce que vous voulez qu'elle apparaisse lorsqu'elle se trouve dans YYY:

cd XXX
mkdir tmp
git mv ZZZ tmp/ZZZ
git mv tmp ZZZ

Maintenant, XXX ressemble à ceci:

XXX
 |- ZZZ
     |- ZZZ

Utilisez maintenant 'git pull' pour récupérer les modifications:

cd ../YYY
git pull ../XXX

Maintenant, YYY ressemble à ceci:

YYY
 |- ZZZ
     |- ZZZ
 |- (other folders that already were in YYY)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.