Comment déplacer des fichiers d'un git repo à un autre (pas un clone), préserver l'histoire

au départ, nos dépôts Git faisaient partie d'un seul dépôt monster SVN où les projets individuels avaient chacun leur propre arborescence:

project1/branches
        /tags
        /trunk
project2/branches
        /tags
        /trunk

évidemment, il était assez facile de déplacer des fichiers de l'un à l'autre avec svn mv . Mais en Git, chaque projet est dans son propre dépôt, et aujourd'hui on m'a demandé de déplacer un sous-répertoire de project2 à project1 . J'ai fait quelque chose comme ceci:

$ git clone project2 
$ cd project2
$ git filter-branch --subdirectory-filter deeply/buried/java/source/directory/A -- --all
$ git remote rm origin  # so I don't accidentally the repo ;-)
$ mkdir -p deeply/buried/different/java/source/directory/B
$ for f in *.java; do 
>  git mv $f deeply/buried/different/java/source/directory/B
>  done
$ git commit -m "moved files to new subdirectory"
$ cd ..
$
$ git clone project1
$ cd project1
$ git remote add p2 ../project2
$ git fetch p2
$ git branch p2 remotes/p2/master
$ git merge p2 # --allow-unrelated-histories for git 2.9
$ git remote rm p2
$ git push

mais cela semble assez alambiquée. Est-il une meilleure façon de faire ce genre de chose en général? Ou ai-je adopté la bonne approche?

notez que cela implique de fusionner l'Historique Dans un dépôt existant, plutôt que de simplement créer un nouveau dépôt autonome à partir d'une partie d'un autre ( comme dans une question précédente ).

374
demandé sur ebneter 2009-09-02 06:04:31

12 réponses

Yep, frapper sur le --subdirectory-filter de filter-branch était la clé. Le fait que vous l'utilisiez prouve essentiellement qu'il n'y a pas de moyen plus simple - vous n'aviez pas d'autre choix que de réécrire l'histoire, puisque vous vouliez finir avec seulement un sous-ensemble (renommé) des fichiers, et cela par définition change les hachages. Puisque aucune des commandes standard (par exemple pull ) ne réécrit l'histoire, il n'y a aucun moyen que vous puissiez les utiliser pour accomplir ceci.

vous pourriez affiner les détails, bien sûr - une partie de votre clonage et branchement n'était pas strictement nécessaire - mais l'approche générale est bonne! C'est dommage que ce soit compliqué, mais bien sûr, le but de git n'est pas de faciliter la réécriture de l'histoire.

46
répondu Cascabel 2015-10-10 08:11:27

si votre histoire est saine, vous pouvez prendre les propagations en patch et les appliquer dans le nouveau dépôt:

cd repository
git log --pretty=email --patch-with-stat --reverse --full-index --binary -- path/to/file_or_folder > patch
cd ../another_repository
git am < ../repository/patch 

ou sur une ligne

git log --pretty=email --patch-with-stat --reverse -- path/to/file_or_folder | (cd /path/to/new_repository && git am)

(tiré de Exherbo's docs )

223
répondu Smar 2014-03-06 08:28:14

après avoir essayé diverses approches pour déplacer un fichier ou un dossier d'un dépôt Git à un autre, le seul qui semble fonctionner de manière fiable est décrit ci-dessous.

il s'agit de cloner le dépôt à partir duquel vous voulez déplacer le fichier ou le dossier, de déplacer ce fichier ou ce dossier à la racine, de réécrire l'histoire Git, de cloner le dépôt cible et de tirer le fichier ou le dossier avec l'histoire directement dans ce dépôt cible.

Première Étape

  1. faites une copie du dépôt A comme les étapes suivantes rendent majeure modifications à cette copie que vous ne devriez pas pousser!

    git clone --branch <branch> --origin origin --progress -v <git repository A url>
    eg. git clone --branch master --origin origin --progress -v https://username@giturl/scm/projects/myprojects.git
    

    (en supposant que myprojects est le dépôt à partir duquel vous voulez copier)

  2. cd

    cd <git repository A directory>          eg. cd /c/Working/GIT/myprojects
    
  3. supprimer le lien vers le dépôt original pour éviter accidentellement faire une télécommande des changements (par exemple. en poussant)

    git remote rm origin
    
  4. parcourez votre histoire et vos fichiers, en supprimant tout ce qui n'est pas dans directory 1. Le résultat est le contenu du répertoire 1 vomie vers la base du dépôt A.

    git filter-branch --subdirectory-filter <directory> -- --all
    eg. git filter-branch --subdirectory-filter subfolder1/subfolder2/FOLDER_TO_KEEP -- --all
    
  5. Pour seul fichier seulement se déplacer: ce que la gauche et retirez tout, sauf le fichier désiré. (Vous pourriez avoir besoin de supprimer des fichiers vous ne voulez pas le même nom et de s'engager.)

    git filter-branch -f --index-filter \
    'git ls-files -s | grep $'\t'FILE_TO_KEEP$ |
    GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
    git update-index --index-info && \
    mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE || echo "Nothing to do"' --prune-empty -- --all
    

    par exemple. FILE_TO_KEEP = pom.xml pour garder seulement le pom.fichier xml de FOLDER_TO_KEEP

Phase Deux

  1. étape de Nettoyage

    git reset --hard
    
  2. étape de Nettoyage

    git gc --aggressive
    
  3. étape de Nettoyage

    git prune
    

vous pouvez vouloir importer ces fichiers dans le dépôt B dans un répertoire pas la racine:

  1. Faire ce répertoire

    mkdir <base directory>             eg. mkdir FOLDER_TO_KEEP
    
  2. déplacer des fichiers dans ce répertoire

    git mv * <base directory>          eg. git mv * FOLDER_TO_KEEP
    
  3. ajouter des fichiers à ce répertoire

    git add .
    
  4. commettez vos modifications et nous sommes prêts à fusionner ces fichiers dans le nouveau référentiel

    git commit
    

Phase Trois

  1. faites une copie du dépôt B Si vous n'en avez pas déjà un

    git clone <git repository B url>
    eg. git clone https://username@giturl/scm/projects/FOLDER_TO_KEEP.git
    

    (en supposant que FOLDER_TO_KEEP est le nom du nouveau dépôt vers lequel vous copiez)

  2. cd

    cd <git repository B directory>          eg. cd /c/Working/GIT/FOLDER_TO_KEEP
    
  3. Créer une connexion à distance à Un référentiel comme une branche dans le dépôt B

    git remote add repo-A-branch <git repository A directory>
    

    (repo-Une-branche peut être n'importe quoi - c'est juste un nom arbitraire)

    eg. git remote add repo-A-branch /c/Working/GIT/myprojects
    
  4. Tirer de cette branche (contenant uniquement le répertoire que vous voulez transfert) vers le dépôt B.

    git pull repo-A-branch master --allow-unrelated-histories
    

    le pull copie à la fois les dossiers et l'histoire. Remarque: Vous pouvez utiliser une fusion au lieu d'un tirez, mais tirez fonctionne mieux.

  5. enfin, vous voulez probablement nettoyer un peu en enlevant la télécommande connexion au dépôt A

    git remote rm repo-A-branch
    
  6. tout est prêt.

    git push
    
54
répondu mcarans 2017-06-21 14:30:39

j'ai trouvé ce très utile. C'est une approche très simple où vous créez des patches qui sont appliqués au nouveau repo. Voir la page liée pour plus de détails.

Il contient seulement trois étapes (copié sur le blog):

# Setup a directory to hold the patches
mkdir <patch-directory>

# Create the patches
git format-patch -o <patch-directory> --root /path/to/copy

# Apply the patches in the new repo using a 3 way merge in case of conflicts
# (merges from the other repo are not turned into patches). 
# The 3way can be omitted.
git am --3way <patch-directory>/*.patch

le seul problème que j'ai eu était que je ne pouvais pas appliquer tous les correctifs à la fois en utilisant

git am --3way <patch-directory>/*.patch

sous Windows j'ai eu une erreur InvalidArgument. Donc j'ai dû appliquer tout les patchs l'un après l'autre.

14
répondu anhoppe 2018-07-29 01:41:11

CONSERVER LE NOM DU RÉPERTOIRE

le sous-répertoire-filter (ou la commande plus courte git subtree) fonctionne bien mais ne fonctionnait pas pour moi car ils suppriment le nom de répertoire de l'info de propagation. Dans mon scénario, je veux juste fusionner des parties d'un dépôt dans un autre et conserver l'historique avec le nom complet du chemin.

ma solution a été d'utiliser l'arbre-filtre et de simplement supprimer les fichiers et répertoires indésirables à partir d'un clone temporaire de la source dépôt, puis tirer de ce clone dans mon dépôt cible en 5 étapes simples.

# 1. clone the source
git clone ssh://<user>@<source-repo url>
cd <source-repo>
# 2. remove the stuff we want to exclude
git filter-branch --tree-filter "rm -rf <files to exclude>" --prune-empty HEAD
# 3. move to target repo and create a merge branch (for safety)
cd <path to target-repo>
git checkout -b <merge branch>
# 4. Add the source-repo as remote 
git remote add source-repo <path to source-repo>
# 5. fetch it
git pull source-repo master
# 6. check that you got it right (better safe than sorry, right?)
gitk
6
répondu Joachim Nilsson 2015-08-21 14:06:07

cette réponse fournit des commandes intéressantes basées sur git am et présentées en utilisant des exemples, étape par étape.

objectif

  • vous voulez déplacer une partie ou la totalité des fichiers d'un dépôt à un autre.
  • Vous voulez garder leur histoire.
  • Mais vous ne vous souciez pas de garder les étiquettes et les branches.
  • vous acceptez l'histoire limitée pour les fichiers renommés (et les fichiers dans les répertoires renommés).

procédure

  1. extraire l'historique dans le format de courriel en utilisant

    git log --pretty=email -p --reverse --full-index --binary
  2. réorganiser l'arborescence des fichiers et mettre à jour le changement de nom de fichier dans l'historique [optionnel]
  3. appliquer la nouvelle histoire en utilisant git am

1. Historique d'extrait dans le format de courrier électronique

exemple: extrait de l'histoire de file3 , file4 et file5

my_repo
├── dirA
│   ├── file1
│   └── file2
├── dirB            ^
│   ├── subdir      | To be moved
│   │   ├── file3   | with history
│   │   └── file4   | 
│   └── file5       v
└── dirC
    ├── file6
    └── file7

nettoyer l'annuaire temporaire destination

export historydir=/tmp/mail/dir  # Absolute path
rm -rf "$historydir"             # Caution when cleaning

nettoyer votre the repo source

git commit ...           # Commit your working files
rm .gitignore            # Disable gitignore
git clean -n             # Simulate removal
git clean -f             # Remove untracked file
git checkout .gitignore  # Restore gitignore

extrait historique de chaque fichier dans le format de courriel

cd my_repo/dirB
find -name .git -prune -o -type d -o -exec bash -c 'mkdir -p "$historydir/${0%/*}" && git log --pretty=email -p --stat --reverse --full-index --binary -- ""151930920"" > "$historydir/"151930920""' {} ';'

malheureusement option --follow ou --find-copies-harder ne peut pas être combiné avec --reverse . C'est pourquoi l'histoire est coupée lorsque le fichier est renommé (ou lorsqu'un parent directory est renommé).

après: Histoire temporaire en format email

/tmp/mail/dir
    ├── subdir
    │   ├── file3
    │   └── file4
    └── file5

2. Réorganiser l'arborescence des fichiers et mettre à jour le changement de nom de fichier dans l'historique [optionnel]

Supposons que vous souhaitez déplacer ces trois fichiers dans ce repo (peut être le même repo).

my_other_repo
├── dirF
│   ├── file55
│   └── file56
├── dirB              # New tree
│   ├── dirB1         # was subdir
│   │   ├── file33    # was file3
│   │   └── file44    # was file4
│   └── dirB2         # new dir
│        └── file5    # = file5
└── dirH
    └── file77

donc réorganisez vos fichiers:

cd /tmp/mail/dir
mkdir     dirB
mv subdir dirB/dirB1
mv dirB/dirB1/file3 dirB/dirB1/file33
mv dirB/dirB1/file4 dirB/dirB1/file44
mkdir    dirB/dirB2
mv file5 dirB/dirB2

votre histoire temporaire est maintenant:

/tmp/mail/dir
    └── dirB
        ├── dirB1
        │   ├── file33
        │   └── file44
        └── dirB2
             └── file5

Changement des noms de fichiers dans l'histoire:

cd "$historydir"
find * -type f -exec bash -c 'sed "/^diff --git a\|^--- a\|^+++ b/s:\( [ab]\)/[^ ]*:/"151980920":g" -i ""151980920""' {} ';'

Note: ceci réécrit l'historique pour refléter le changement de chemin et de nom de fichier.

      (c.-à-d. le changement du nouveau lieu/nom dans la nouvelle déclaration)


3. Appliquer la nouvelle histoire

votre autre pension est:

my_other_repo
├── dirF
│   ├── file55
│   └── file56
└── dirH
    └── file77

Appliquer s'engage temporaires, l'historique des fichiers:

cd my_other_repo
find "$historydir" -type f -exec cat {} + | git am 

votre autre pension est maintenant:

my_other_repo
├── dirF
│   ├── file55
│   └── file56
├── dirB            ^
│   ├── dirB1       | New files
│   │   ├── file33  | with
│   │   └── file44  | history
│   └── dirB2       | kept
│        └── file5  v
└── dirH
    └── file77

utiliser git status pour voir la quantité de commits prêts à être poussés: -)

Note: comme l'histoire a été réécrite à refléter le changement de chemin et de nom de fichier:

      (c.-à-d. comparé à l'emplacement/au nom dans le rapport précédent)

  • Pas besoin de git mv pour modifier l'emplacement/nom de fichier.
  • Pas besoin de git log --follow pour avoir accès à la totalité de l'histoire.

astuce supplémentaire: détectez les fichiers renommés / déplacés dans votre rapport

Pour lister les fichiers ayant été renommés:

find -name .git -prune -o -exec git log --pretty=tformat:'' --numstat --follow {} ';' | grep '=>'

plus de personnalisations: vous pouvez compléter la commande git log en utilisant les options --find-copies-harder ou --reverse . Vous pouvez également supprimer les deux premières colonnes en utilisant cut -f3- et gropping complete pattern '{.* = > .*}'.

find -name .git -prune -o -exec git log --pretty=tformat:'' --numstat --follow --find-copies-harder --reverse {} ';' | cut -f3- | grep '{.* => .*}'
4
répondu olibre 2016-03-08 22:18:51

ayant eu une démangeaison similaire à scratch (seulement pour certains fichiers d'un dépôt donné) ce script s'est avéré être vraiment utile: git-import

la version courte est qu'elle crée des fichiers de correctifs du fichier ou du répertoire donné ( $object ) à partir du dépôt existant:

cd old_repo
git format-patch --thread -o "$temp" --root -- "$object"

qui s'applique alors à un nouveau dépôt:

cd new_repo
git am "$temp"/*.patch 

Pour plus de détails veuillez consulter:

2
répondu ViToni 2017-04-21 23:30:09

celui que j'utilise toujours est ici http://blog.neutrino.es/2012/git-copy-a-file-or-directory-from-another-repository-preserving-history / . Il est Simple et rapide.

pour la conformité aux normes de débordement des piles, voici la procédure:

mkdir /tmp/mergepatchs
cd ~/repo/org
export reposrc=myfile.c #or mydir
git format-patch -o /tmp/mergepatchs $(git log $reposrc|grep ^commit|tail -1|awk '{print }')^..HEAD $reposrc
cd ~/repo/dest
git am /tmp/mergepatchs/*.patch
2
répondu Hugh Perkins 2017-06-04 18:23:49

utilisant l'inspiration de http://blog.neutrino.es/2012/git-copy-a-file-or-directory-from-another-repository-preserving-history / , j'ai créé cette fonction Powershell pour faire la même chose, qui a bien fonctionné pour moi jusqu'à présent:

# Migrates the git history of a file or directory from one Git repo to another.
# Start in the root directory of the source repo.
# Also, before running this, I recommended that $destRepoDir be on a new branch that the history will be migrated to.
# Inspired by: http://blog.neutrino.es/2012/git-copy-a-file-or-directory-from-another-repository-preserving-history/
function Migrate-GitHistory
{
    # The file or directory within the current Git repo to migrate.
    param([string] $fileOrDir)
    # Path to the destination repo
    param([string] $destRepoDir)
    # A temp directory to use for storing the patch file (optional)
    param([string] $tempDir = "\temp\migrateGit")

    mkdir $tempDir

    # git log $fileOrDir -- to list commits that will be migrated
    Write-Host "Generating patch files for the history of $fileOrDir ..." -ForegroundColor Cyan
    git format-patch -o $tempDir --root -- $fileOrDir

    cd $destRepoDir
    Write-Host "Applying patch files to restore the history of $fileOrDir ..." -ForegroundColor Cyan
    ls $tempDir -Filter *.patch  `
        | foreach { git am $_.FullName }
}

utilisation pour cet exemple:

git clone project2
git clone project1
cd project1
# Create a new branch to migrate to
git checkout -b migrate-from-project2
cd ..\project2
Migrate-GitHistory "deeply\buried\java\source\directory\A" "..\project1"

après avoir fait cela, vous pouvez réorganiser les fichiers sur la branche migrate-from-project2 avant de la fusionner.

1
répondu crimbo 2016-03-18 06:05:49

je voulais quelque chose de robuste et réutilisable (fonction one-command-and-go + undo) donc j'ai écrit le script bash suivant. J'ai travaillé pour moi à plusieurs reprises, alors j'ai pensé le partager ici.

il est capable de déplacer un dossier arbitraire /path/to/foo de repo1 dans /some/other/folder/bar à repo2 (les chemins de dossier peuvent être identiques ou différents, la distance du dossier racine peut être différente).

Puisqu'il ne va au-dessus des commit qui touchent le les fichiers dans le dossier d'Entrée (pas sur toutes les propagations du rapport source), il devrait être assez rapide, même sur les gros repos sources, Si vous extrayez juste un sous-dossier profondément imbriqué qui n'a pas été touché dans chaque commit.

puisque ce que cela fait est de créer une branche orpheline avec toute l'histoire de l'ancien repo et ensuite la fusionner à la tête, il fonctionnera même en cas de conflits de nom de fichier (alors vous devrez résoudre une fusion à la fin de cours).

S'il n'y a pas de fichier nom affrontements, vous avez juste besoin de git commit à la fin pour finaliser la fusion.

L'inconvénient est qu'il ne sera probablement pas suivre renomme de fichier (en dehors de REWRITE_FROM dossier) dans la source repo - pull demandes bienvenue sur GitHub pour l'accueillir.

GitHub lien: git-move-dossier-entre-repos-garder-histoire

#!/bin/bash

# Copy a folder from one git repo to another git repo,
# preserving full history of the folder.

SRC_GIT_REPO='/d/git-experimental/your-old-webapp'
DST_GIT_REPO='/d/git-experimental/your-new-webapp'
SRC_BRANCH_NAME='master'
DST_BRANCH_NAME='import-stuff-from-old-webapp'
# Most likely you want the REWRITE_FROM and REWRITE_TO to have a trailing slash!
REWRITE_FROM='app/src/main/static/'
REWRITE_TO='app/src/main/static/'

verifyPreconditions() {
    #echo 'Checking if SRC_GIT_REPO is a git repo...' &&
      { test -d "${SRC_GIT_REPO}/.git" || { echo "Fatal: SRC_GIT_REPO is not a git repo"; exit; } } &&
    #echo 'Checking if DST_GIT_REPO is a git repo...' &&
      { test -d "${DST_GIT_REPO}/.git" || { echo "Fatal: DST_GIT_REPO is not a git repo"; exit; } } &&
    #echo 'Checking if REWRITE_FROM is not empty...' &&
      { test -n "${REWRITE_FROM}" || { echo "Fatal: REWRITE_FROM is empty"; exit; } } &&
    #echo 'Checking if REWRITE_TO is not empty...' &&
      { test -n "${REWRITE_TO}" || { echo "Fatal: REWRITE_TO is empty"; exit; } } &&
    #echo 'Checking if REWRITE_FROM folder exists in SRC_GIT_REPO' &&
      { test -d "${SRC_GIT_REPO}/${REWRITE_FROM}" || { echo "Fatal: REWRITE_FROM does not exist inside SRC_GIT_REPO"; exit; } } &&
    #echo 'Checking if SRC_GIT_REPO has a branch SRC_BRANCH_NAME' &&
      { cd "${SRC_GIT_REPO}"; git rev-parse --verify "${SRC_BRANCH_NAME}" || { echo "Fatal: SRC_BRANCH_NAME does not exist inside SRC_GIT_REPO"; exit; } } &&
    #echo 'Checking if DST_GIT_REPO has a branch DST_BRANCH_NAME' &&
      { cd "${DST_GIT_REPO}"; git rev-parse --verify "${DST_BRANCH_NAME}" || { echo "Fatal: DST_BRANCH_NAME does not exist inside DST_GIT_REPO"; exit; } } &&
    echo '[OK] All preconditions met'
}

# Import folder from one git repo to another git repo, including full history.
#
# Internally, it rewrites the history of the src repo (by creating
# a temporary orphaned branch; isolating all the files from REWRITE_FROM path
# to the root of the repo, commit by commit; and rewriting them again
# to the original path).
#
# Then it creates another temporary branch in the dest repo,
# fetches the commits from the rewritten src repo, and does a merge.
#
# Before any work is done, all the preconditions are verified: all folders
# and branches must exist (except REWRITE_TO folder in dest repo, which
# can exist, but does not have to).
#
# The code should work reasonably on repos with reasonable git history.
# I did not test pathological cases, like folder being created, deleted,
# created again etc. but probably it will work fine in that case too.
#
# In case you realize something went wrong, you should be able to reverse
# the changes by calling `undoImportFolderFromAnotherGitRepo` function.
# However, to be safe, please back up your repos just in case, before running
# the script. `git filter-branch` is a powerful but dangerous command.
importFolderFromAnotherGitRepo(){
    SED_COMMAND='s-\t\"*-\t'${REWRITE_TO}'-'

    verifyPreconditions &&
    cd "${SRC_GIT_REPO}" &&
      echo "Current working directory: ${SRC_GIT_REPO}" &&
      git checkout "${SRC_BRANCH_NAME}" &&
      echo 'Backing up current branch as FILTER_BRANCH_BACKUP' &&
      git branch -f FILTER_BRANCH_BACKUP &&
      SRC_BRANCH_NAME_EXPORTED="${SRC_BRANCH_NAME}-exported" &&
      echo "Creating temporary branch '${SRC_BRANCH_NAME_EXPORTED}'..." &&
      git checkout -b "${SRC_BRANCH_NAME_EXPORTED}" &&
      echo 'Rewriting history, step 1/2...' &&
      git filter-branch -f --prune-empty --subdirectory-filter ${REWRITE_FROM} &&
      echo 'Rewriting history, step 2/2...' &&
      git filter-branch -f --index-filter \
       "git ls-files -s | sed \"$SED_COMMAND\" |
        GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info &&
        mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE" HEAD &&
    cd - &&
    cd "${DST_GIT_REPO}" &&
      echo "Current working directory: ${DST_GIT_REPO}" &&
      echo "Adding git remote pointing to SRC_GIT_REPO..." &&
      git remote add old-repo ${SRC_GIT_REPO} &&
      echo "Fetching from SRC_GIT_REPO..." &&
      git fetch old-repo "${SRC_BRANCH_NAME_EXPORTED}" &&
      echo "Checking out DST_BRANCH_NAME..." &&
      git checkout "${DST_BRANCH_NAME}" &&
      echo "Merging SRC_GIT_REPO/" &&
      git merge "old-repo/${SRC_BRANCH_NAME}-exported" --no-commit &&
    cd -
}

# If something didn't work as you'd expect, you can undo, tune the params, and try again
undoImportFolderFromAnotherGitRepo(){
  cd "${SRC_GIT_REPO}" &&
    SRC_BRANCH_NAME_EXPORTED="${SRC_BRANCH_NAME}-exported" &&
    git checkout "${SRC_BRANCH_NAME}" &&
    git branch -D "${SRC_BRANCH_NAME_EXPORTED}" &&
  cd - &&
  cd "${DST_GIT_REPO}" &&
    git remote rm old-repo &&
    git merge --abort
  cd -
}

importFolderFromAnotherGitRepo
#undoImportFolderFromAnotherGitRepo
1
répondu jakub.g 2017-11-02 21:30:17

dans mon cas, je n'avais pas besoin de préserver le repo que j'étais en train de migrer ou de préserver une histoire antérieure. J'ai eu un patch de la même branche, d'une télécommande différente

#Source directory
git remote rm origin
#Target directory
git remote add branch-name-from-old-repo ../source_directory

dans ces deux étapes, j'ai pu faire apparaître la branche de l'autre banque de pension dans la même banque de pension.

enfin, j'ai placé cette branche (que j'ai importée de l'autre pension) pour suivre la ligne principale de la pension cible (afin que je puisse les différencier avec précision)

git br --set-upstream-to=origin/mainline

maintenant il s'est comporté comme-si c'était juste une autre branche que j'avais poussée contre ce même repo.

0
répondu Jason D 2017-12-22 23:26:55

si les chemins pour les fichiers en question sont les mêmes dans les deux repos et que vous voulez apporter un seul fichier ou un petit ensemble de fichiers associés, une façon facile de le faire est d'utiliser git cherry-pick .

la première étape consiste à introduire les propagations de l'autre pension dans votre propre pension locale en utilisant git fetch <remote-url> . Cela laissera FETCH_HEAD pointant vers la tête de la propagation de l'autre rapport; si vous voulez conserver une référence à cette propagation après avoir fait autres fetches vous pouvez vouloir l'étiqueter avec git tag other-head FETCH_HEAD .

ensuite, Vous devrez créer un premier de s'engager pour que le fichier s'il n'existe pas) ou s'engager à apporter le fichier à un état qui peut être corrigé avec le premier commit de l'autre dépôt que vous souhaitez apporter. Vous pouvez être en mesure de le faire avec un git cherry-pick <commit-0> si commit-0 introduit les fichiers que vous voulez, ou vous pouvez avoir besoin de construire la propagation 'à la main'. Ajouter -n aux options de sélection Si vous avez besoin pour modifier la propagation initiale, par exemple, supprimer des fichiers de la propagation que vous ne voulez pas introduire.

après cela, vous pouvez continuer à git cherry-pick par la suite, en utilisant à nouveau -n si nécessaire. Dans le cas le plus simple (toutes les commits sont exactement ce que vous voulez et appliquez proprement) vous pouvez donner la liste complète des commits sur la ligne de commande de sélection: git cherry-pick <commit-1> <commit-2> <commit-3> ... .

0
répondu Curt J. Sampson 2018-08-08 02:51:48