Как перемещать файлы из одного репозитория git в другой (не клон), сохраняя историю
Наши репозитории Git начинались как часть единственного репозитория SVN-монстра, в котором каждый отдельный проект имел свое собственное дерево:
project1/branches
/tags
/trunk
project2/branches
/tags
/trunk
Очевидно, было довольно легко перемещать файлы из одного в другое с помощью svn mv
. Но в Git каждый проект находится в собственном репозитории, и сегодня меня попросили переместить подкаталог из project2
в project1
. Я сделал что-то вроде этого:
$ 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
Но это кажется довольно запутанным. Есть ли лучший способ сделать это вообще? Или я принял правильный подход?
Обратите внимание, что это связано с объединением истории в существующий репозиторий, а не просто созданием нового автономного репозитория из части другого (как в более раннем вопросе).
Ответы
Ответ 1
Да, нажатие на --subdirectory-filter
of filter-branch
было ключевым. Тот факт, что вы его использовали, по существу не доказывает, что нет более простого способа - у вас не было выбора, кроме как переписать историю, поскольку вы хотели получить только (переименованное) подмножество файлов, и это по определению изменяет хеши. Поскольку ни одна из стандартных команд (например, pull
) не переписывает историю, вы не можете использовать их для достижения этой цели.
Вы могли бы уточнить детали, конечно - некоторые из ваших клонирования и разветвления не были абсолютно необходимы, но общий подход хорош! Стыдно, что это сложно, но, конечно, точка git не позволяет легко переписать историю.
Ответ 2
Если ваша история работоспособна, вы можете взять коммиты в качестве патча и применить их в новом репозитории:
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
Или в одной строке
git log --pretty=email --patch-with-stat --reverse -- path/to/file_or_folder | (cd /path/to/new_repository && git am)
(взято из Документов Exherbos)
Ответ 3
Перепробовав различные подходы для перемещения файла или папки из одного Git-репозитория в другой, единственный, который, кажется, работает надежно, описан ниже.
Это включает в себя клонирование репозитория, из которого вы хотите переместить файл или папку, перемещение этого файла или папки в корень, переписывание истории Git, клонирование целевого репозитория и извлечение файла или папки с историей непосредственно в этот целевой репозиторий.
Первый этап
-
Сделайте копию хранилища A, так как следующие шаги вносят существенные изменения в эту копию, которые вам не следует нажимать!
git clone --branch <branch> --origin origin --progress \
-v <git repository A url>
# eg. git clone --branch master --origin origin --progress \
# -v https://[email protected]/scm/projects/myprojects.git
# (assuming myprojects is the repository you want to copy from)
-
CD в это
cd <git repository A directory>
# eg. cd /c/Working/GIT/myprojects
-
Удалите ссылку на исходный репозиторий, чтобы избежать случайного внесения каких-либо удаленных изменений (например, путем нажатия)
git remote rm origin
-
Просматривайте свою историю и файлы, удаляя все, что не находится в каталоге 1. В результате содержимое каталога 1 выливается в базу хранилища А.
git filter-branch --subdirectory-filter <directory> -- --all
# eg. git filter-branch --subdirectory-filter subfolder1/subfolder2/FOLDER_TO_KEEP -- --all
-
Только для перемещения одного файла: пройдите через то, что осталось, и удалите все, кроме нужного файла. (Вам может понадобиться удалить файлы, которые вы не хотите, с тем же именем и зафиксировать.)
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
# eg. FILE_TO_KEEP = pom.xml to keep only the pom.xml file from FOLDER_TO_KEEP
Второй этап
-
Шаг очистки
git reset --hard
-
Шаг очистки
git gc --aggressive
-
Шаг очистки
git prune
Вы можете импортировать эти файлы в хранилище B в каталоге, а не в корне:
-
Сделать этот каталог
mkdir <base directory> eg. mkdir FOLDER_TO_KEEP
-
Переместить файлы в этот каталог
git mv * <base directory> eg. git mv * FOLDER_TO_KEEP
-
Добавить файлы в этот каталог
git add .
-
Зафиксируйте ваши изменения и были готовы объединить эти файлы в новый репозиторий
git commit
Этап третий
-
Сделайте копию хранилища B, если у вас ее еще нет
git clone <git repository B url>
# eg. git clone https://[email protected]/scm/projects/FOLDER_TO_KEEP.git
(при условии, что FOLDER_TO_KEEP - это имя нового репозитория, в который вы копируете)
-
CD в это
cd <git repository B directory>
# eg. cd /c/Working/GIT/FOLDER_TO_KEEP
-
Создайте удаленное соединение с хранилищем A как ветвь в хранилище B
git remote add repo-A-branch <git repository A directory>
# (repo-A-branch can be anything - it just an arbitrary name)
# eg. git remote add repo-A-branch /c/Working/GIT/myprojects
-
Извлеките эту ветку (содержащую только каталог, который вы хотите переместить) в хранилище B.
git pull repo-A-branch master --allow-unrelated-histories
Тяга копирует как файлы, так и историю. Примечание: вы можете использовать слияние вместо вытягивания, но вытягивание работает лучше.
-
Наконец, вы, вероятно, хотите немного очиститься, удалив удаленное соединение с хранилищем A
git remote rm repo-A-branch
-
Нажмите и вы все готово.
git push
Ответ 4
Я нашел это очень полезным. Это очень простой подход, при котором вы создаете патчи, которые применяются к новому репо. Смотрите связанную страницу для более подробной информации.
Он содержит только три шага (скопировано из блога):
# 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
Единственной проблемой, с которой я столкнулся, было то, что я не мог применить все патчи одновременно, используя
git am --3way <patch-directory>/*.patch
Под Windows я получил ошибку InvalidArgument. Поэтому мне пришлось применять все патчи один за другим.
Ответ 5
СОХРАНЕНИЕ ИМЯ СПИСКА
Подкаталог-фильтр (или более короткая команда git поддерево) работает хорошо, но не работает для меня, так как они удаляют имя каталога из информации о фиксации. В моем сценарии я просто хочу объединить части одного репозитория в другой и сохранить историю с полным именем пути.
Моим решением было использовать древовидный фильтр и просто удалить ненужные файлы и каталоги из временного клонирования исходного репозитория, а затем вытащить из этого клона в мой целевой репозиторий за 5 простых шагов.
# 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
В этом ответе представлены интересные команды на основе git am
и представлены с использованием примеров, шаг за шагом.
Цель
- Вы хотите переместить некоторые или все файлы из одного репозитория в другой.
- Вы хотите сохранить свою историю.
- Но вы не заботитесь о сохранении тегов и ветвей.
- Вы принимаете ограниченную историю переименованных файлов (и файлов в переименованных каталогах).
Процедура
- Извлечь историю в формате электронной почты, используя
git log --pretty=email -p --reverse --full-index --binary
- Реорганизовать дерево файлов и изменить имя файла в истории [необязательно]
- Применить новую историю с помощью
git am
1. Извлечение истории в формате электронной почты
Пример. Извлеките историю file3
, file4
и file5
my_repo
├── dirA
│ ├── file1
│ └── file2
├── dirB ^
│ ├── subdir | To be moved
│ │ ├── file3 | with history
│ │ └── file4 |
│ └── file5 v
└── dirC
├── file6
└── file7
Очистить временную папку
export historydir=/tmp/mail/dir # Absolute path
rm -rf "$historydir" # Caution when cleaning
Очистите источник репо
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
Извлечь историю каждого файла в формате электронной почты
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 -- "$0" > "$historydir/$0"' {} ';'
К сожалению, параметр --follow
или --find-copies-harder
нельзя комбинировать с --reverse
. Вот почему история вырезается, когда файл переименовывается (или когда родительский каталог переименовывается).
После: временная история в формате электронной почты
/tmp/mail/dir
├── subdir
│ ├── file3
│ └── file4
└── file5
2. Реорганизовать дерево файлов и изменить имя файла в истории [необязательно]
Предположим, вы хотите переместить эти три файла в этом другом репо (может быть такое же репо).
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
Поэтому реорганизуйте свои файлы:
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
Ваша временная история теперь:
/tmp/mail/dir
└── dirB
├── dirB1
│ ├── file33
│ └── file44
└── dirB2
└── file5
Измените также имена файлов в истории:
cd "$historydir"
find * -type f -exec bash -c 'sed "/^diff --git a\|^--- a\|^+++ b/s:\( [ab]\)/[^ ]*:\1/$0:g" -i "$0"' {} ';'
Примечание.. Это переписывает историю, чтобы отобразить изменение пути и имени файла.
& ЕПРС; & ЕПРС; (т.е. изменение нового местоположения/имени в новом репо)
3. Применить новую историю
Другое ваше репо:
my_other_repo
├── dirF
│ ├── file55
│ └── file56
└── dirH
└── file77
Применить фиксации из временных файлов истории:
cd my_other_repo
find "$historydir" -type f -exec cat {} + | git am
Теперь ваше другое репо:
my_other_repo
├── dirF
│ ├── file55
│ └── file56
├── dirB ^
│ ├── dirB1 | New files
│ │ ├── file33 | with
│ │ └── file44 | history
│ └── dirB2 | kept
│ └── file5 v
└── dirH
└── file77
Используйте git status
, чтобы увидеть количество коммитов, готовых к нажатию: -)
Примечание.. Поскольку история была переписана для изменения пути и имени файла:
& ЕПРС; & ЕПРС; (т.е. по сравнению с местоположением/именем в предыдущем репо)
- Не нужно
git mv
изменять местоположение/имя файла.
- Не нужно
git log --follow
для доступа к полной истории.
Дополнительный трюк: обнаружение переименованных/перемещенных файлов в вашем репо
Чтобы перечислить файлы, которые были переименованы:
find -name .git -prune -o -exec git log --pretty=tformat:'' --numstat --follow {} ';' | grep '=>'
Дополнительные настройки: вы можете выполнить команду git log
с помощью опций --find-copies-harder
или --reverse
. Вы также можете удалить первые два столбца с помощью cut -f3-
и grepping complete pattern '{. * = > . *}'.
find -name .git -prune -o -exec git log --pretty=tformat:'' --numstat --follow --find-copies-harder --reverse {} ';' | cut -f3- | grep '{.* => .*}'
Ответ 7
Я всегда использую http://blog.neutrino.es/2012/git-copy-a-file-or-directory-from-another-repository-preserving-history/. Простой и быстрый.
Для соответствия стандартам stackoverflow, выполните следующие действия:
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 $2}')^..HEAD $reposrc
cd ~/repo/dest
git am /tmp/mergepatchs/*.patch
Ответ 8
Имея аналогичный зуд для царапин (хотя и для некоторых файлов данного репозитория), этот script оказался действительно полезным: git-import
Короткий вариант состоит в том, что он создает файлы исправлений данного файла или каталога ($object
) из существующего репозитория:
cd old_repo
git format-patch --thread -o "$temp" --root -- "$object"
которые затем применяются к новому репозиторию:
cd new_repo
git am "$temp"/*.patch
Подробнее см.
Ответ 9
Попробуй это
cd repo1
Это удалит все каталоги, кроме упомянутых, сохраняя историю только для этих каталогов.
git filter-branch --index-filter 'git rm --ignore-unmatch --cached -qr -- . && git reset -q $GIT_COMMIT -- dir1/ dir2/ dir3/ ' --prune-empty -- --all
Теперь вы можете добавить свой новый репозиторий в свой git remote и добавить его к этому
git remote remove origin <old-repo>
git remote add origin <new-repo>
git push origin <current-branch>
добавить -f
для перезаписи
Ответ 10
Используя вдохновение из http://blog.neutrino.es/2012/git-copy-a-file-or-directory-from-another-repository-preserving-history/, я создал эту функцию Powershell для того, чтобы сделать то же самое, что до сих пор отлично работало для меня:
# 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 }
}
Использование для этого примера:
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"
После этого вы можете перенастроить файлы в ветке migrate-from-project2
до слияния.
Ответ 11
Я хотел что-то надежное и многоразовое (одна-команда-и-go + функция отмены), поэтому я написал следующее bash script. Работал для меня несколько раз, поэтому я подумал, что поделюсь им здесь.
Он может перемещать произвольную папку /path/to/foo
из repo1
в /some/other/folder/bar
в repo2
(пути к папкам могут быть одинаковыми или разными, расстояние от корневой папки может быть разным).
Так как он перехватывает только те коммиты, которые касаются файлов в папке ввода (но не во всех компиляторах исходного репо), он должен быть довольно быстрым даже в больших исходных репозиториях, если вы просто извлекаете глубоко вложенную подпапку, которая не была затронуты каждой фиксацией.
Так как это делает, так это создать сиротскую ветвь со всей старой историей репо, а затем объединить ее с HEAD, она даже будет работать в случае конфликтов имен файлов (тогда вам придется разрешить слияние в конце конечно).
Если нет конфликтов имен файлов, вам просто нужно git commit
в конце, чтобы завершить слияние.
Недостатком является то, что он, скорее всего, не будет следовать переименованиям файлов (за пределами REWRITE_FROM
) в исходном репо - запросы на перенос приветствуются в GitHub для размещения для этого.
Ссылка GitHub: git-move-folder-between-repos-keep-history
#!/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
Ответ 12
В моем случае мне не нужно было сохранять репо, в которое я переходил или сохранял предыдущую историю. У меня был патч той же ветки, с другого пульта
#Source directory
git remote rm origin
#Target directory
git remote add branch-name-from-old-repo ../source_directory
В этих двух шагах я смог заставить другую ветку репо появиться в том же репо.
Наконец, я установил эту ветку (которую я импортировал из другого репо), чтобы следить за главной сетью репо (чтобы я мог точно их различать)
git br --set-upstream-to=origin/mainline
Теперь он вел себя так: если бы это была просто еще одна ветка, я толкнул ее против того же репо.
Ответ 13
Если пути для файлов, о которых идет речь, одинаковы в двух репозиториях, и вы хотите перенести только один файл или небольшой набор связанных файлов, один простой способ сделать это - использовать git cherry-pick
.
Первым шагом является передача коммитов из другого репо в ваше собственное локальное репо с помощью git fetch <remote-url>
. Это приведет к тому, что FETCH_HEAD
укажет на фиксацию головы из другого репо; если вы хотите сохранить ссылку на эту фиксацию после того, как вы сделали другие выборки, вы можете пометить ее с помощью git tag other-head FETCH_HEAD
.
Затем вам нужно будет создать начальную фиксацию для этого файла (если она не существует) или фиксация, чтобы привести файл в состояние, которое может быть исправлено с первым фиксацией из другого репо, которое вы хотите ввести. вы можете сделать это с помощью git cherry-pick <commit-0>
если commit-0
представил нужные вам файлы, или вам может понадобиться построить commit "вручную". Добавьте -n
к вариантам вишневого выбора, если вам нужно изменить первоначальную фиксацию, например, удалить файлы из этого коммита, который вы не хотите вводить.
После этого вы можете продолжать git cherry-pick
последующие коммиты, используя снова -n
где это необходимо. В простейшем случае (все коммиты - это именно то, что вы хотите и применяете чисто), вы можете дать полный список git cherry-pick <commit-1> <commit-2> <commit-3>...
командной строке git cherry-pick <commit-1> <commit-2> <commit-3>...
: git cherry-pick <commit-1> <commit-2> <commit-3>...
Ответ 14
Приведенный ниже метод переноса моего GIT Stash в GitLab с сохранением всех веток и сохранением истории.
Клонировать старый репозиторий на локальный.
git clone --bare <STASH-URL>
Создайте пустой репозиторий в GitLab.
git push --mirror <GitLab-URL>
Выше я выполнил, когда мы перенесли наш код из stash в GitLab, и он работал очень хорошо.